Commit 319e4dd1 authored by Vladimir Oltean's avatar Vladimir Oltean Committed by David S. Miller

net: mscc: ocelot: introduce conversion helpers between port and netdev

Since the mscc_ocelot_switch_lib is common between a pure switchdev and
a DSA driver, the procedure of retrieving a net_device for a certain
port index differs, as those are registered by their individual
front-ends.

Up to now that has been dealt with by always passing the port index to
the switch library, but now, we're going to need to work with net_device
pointers from the tc-flower offload, for things like indev, or mirred.
It is not desirable to refactor that, so let's make sure that the flower
offload core has the ability to translate between a net_device and a
port index properly.
Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Acked-by: default avatarAlexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ea9d1f30
...@@ -810,3 +810,25 @@ const struct dsa_switch_ops felix_switch_ops = { ...@@ -810,3 +810,25 @@ const struct dsa_switch_ops felix_switch_ops = {
.cls_flower_stats = felix_cls_flower_stats, .cls_flower_stats = felix_cls_flower_stats,
.port_setup_tc = felix_port_setup_tc, .port_setup_tc = felix_port_setup_tc,
}; };
struct net_device *felix_port_to_netdev(struct ocelot *ocelot, int port)
{
struct felix *felix = ocelot_to_felix(ocelot);
struct dsa_switch *ds = felix->ds;
if (!dsa_is_user_port(ds, port))
return NULL;
return dsa_to_port(ds, port)->slave;
}
int felix_netdev_to_port(struct net_device *dev)
{
struct dsa_port *dp;
dp = dsa_port_from_netdev(dev);
if (IS_ERR(dp))
return -EINVAL;
return dp->index;
}
...@@ -52,4 +52,7 @@ struct felix { ...@@ -52,4 +52,7 @@ struct felix {
resource_size_t imdio_base; resource_size_t imdio_base;
}; };
struct net_device *felix_port_to_netdev(struct ocelot *ocelot, int port);
int felix_netdev_to_port(struct net_device *dev);
#endif #endif
...@@ -1006,6 +1006,8 @@ static u16 vsc9959_wm_enc(u16 value) ...@@ -1006,6 +1006,8 @@ static u16 vsc9959_wm_enc(u16 value)
static const struct ocelot_ops vsc9959_ops = { static const struct ocelot_ops vsc9959_ops = {
.reset = vsc9959_reset, .reset = vsc9959_reset,
.wm_enc = vsc9959_wm_enc, .wm_enc = vsc9959_wm_enc,
.port_to_netdev = felix_port_to_netdev,
.netdev_to_port = felix_netdev_to_port,
}; };
static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot) static int vsc9959_mdio_bus_alloc(struct ocelot *ocelot)
......
...@@ -1058,6 +1058,8 @@ static u16 vsc9953_wm_enc(u16 value) ...@@ -1058,6 +1058,8 @@ static u16 vsc9953_wm_enc(u16 value)
static const struct ocelot_ops vsc9953_ops = { static const struct ocelot_ops vsc9953_ops = {
.reset = vsc9953_reset, .reset = vsc9953_reset,
.wm_enc = vsc9953_wm_enc, .wm_enc = vsc9953_wm_enc,
.port_to_netdev = felix_port_to_netdev,
.netdev_to_port = felix_netdev_to_port,
}; };
static int vsc9953_mdio_bus_alloc(struct ocelot *ocelot) static int vsc9953_mdio_bus_alloc(struct ocelot *ocelot)
......
...@@ -98,6 +98,8 @@ int ocelot_port_lag_join(struct ocelot *ocelot, int port, ...@@ -98,6 +98,8 @@ int ocelot_port_lag_join(struct ocelot *ocelot, int port,
struct net_device *bond); struct net_device *bond);
void ocelot_port_lag_leave(struct ocelot *ocelot, int port, void ocelot_port_lag_leave(struct ocelot *ocelot, int port,
struct net_device *bond); struct net_device *bond);
struct net_device *ocelot_port_to_netdev(struct ocelot *ocelot, int port);
int ocelot_netdev_to_port(struct net_device *dev);
u32 ocelot_port_readl(struct ocelot_port *port, u32 reg); u32 ocelot_port_readl(struct ocelot_port *port, u32 reg);
void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg); void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg);
......
...@@ -656,6 +656,36 @@ static const struct net_device_ops ocelot_port_netdev_ops = { ...@@ -656,6 +656,36 @@ static const struct net_device_ops ocelot_port_netdev_ops = {
.ndo_do_ioctl = ocelot_ioctl, .ndo_do_ioctl = ocelot_ioctl,
}; };
struct net_device *ocelot_port_to_netdev(struct ocelot *ocelot, int port)
{
struct ocelot_port *ocelot_port = ocelot->ports[port];
struct ocelot_port_private *priv;
if (!ocelot_port)
return NULL;
priv = container_of(ocelot_port, struct ocelot_port_private, port);
return priv->dev;
}
static bool ocelot_port_dev_check(const struct net_device *dev)
{
return dev->netdev_ops == &ocelot_port_netdev_ops;
}
int ocelot_netdev_to_port(struct net_device *dev)
{
struct ocelot_port_private *priv;
if (!dev || !ocelot_port_dev_check(dev))
return -EINVAL;
priv = netdev_priv(dev);
return priv->chip_port;
}
static void ocelot_port_get_strings(struct net_device *netdev, u32 sset, static void ocelot_port_get_strings(struct net_device *netdev, u32 sset,
u8 *data) u8 *data)
{ {
......
...@@ -763,6 +763,8 @@ static u16 ocelot_wm_enc(u16 value) ...@@ -763,6 +763,8 @@ static u16 ocelot_wm_enc(u16 value)
static const struct ocelot_ops ocelot_ops = { static const struct ocelot_ops ocelot_ops = {
.reset = ocelot_reset, .reset = ocelot_reset,
.wm_enc = ocelot_wm_enc, .wm_enc = ocelot_wm_enc,
.port_to_netdev = ocelot_port_to_netdev,
.netdev_to_port = ocelot_netdev_to_port,
}; };
static const struct vcap_field vsc7514_vcap_es0_keys[] = { static const struct vcap_field vsc7514_vcap_es0_keys[] = {
......
...@@ -559,6 +559,8 @@ enum ocelot_tag_prefix { ...@@ -559,6 +559,8 @@ enum ocelot_tag_prefix {
struct ocelot; struct ocelot;
struct ocelot_ops { struct ocelot_ops {
struct net_device *(*port_to_netdev)(struct ocelot *ocelot, int port);
int (*netdev_to_port)(struct net_device *dev);
int (*reset)(struct ocelot *ocelot); int (*reset)(struct ocelot *ocelot);
u16 (*wm_enc)(u16 value); u16 (*wm_enc)(u16 value);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment