]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net: mscc: ocelot: introduce conversion helpers between port and netdev
authorVladimir Oltean <vladimir.oltean@nxp.com>
Fri, 2 Oct 2020 12:02:21 +0000 (15:02 +0300)
committerDavid S. Miller <davem@davemloft.net>
Fri, 2 Oct 2020 22:40:30 +0000 (15:40 -0700)
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: Vladimir Oltean <vladimir.oltean@nxp.com>
Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/ocelot/felix.c
drivers/net/dsa/ocelot/felix.h
drivers/net/dsa/ocelot/felix_vsc9959.c
drivers/net/dsa/ocelot/seville_vsc9953.c
drivers/net/ethernet/mscc/ocelot.h
drivers/net/ethernet/mscc/ocelot_net.c
drivers/net/ethernet/mscc/ocelot_vsc7514.c
include/soc/mscc/ocelot.h

index da54363b5c92170b0235a6c05d2e7f8d306840e6..552b1f7bde17b7153f6865fb3065c70670b02655 100644 (file)
@@ -810,3 +810,25 @@ const struct dsa_switch_ops felix_switch_ops = {
        .cls_flower_stats       = felix_cls_flower_stats,
        .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;
+}
index d5f46784306e21523a0f77ade38c7d1fdeb747e9..4c717324ac2f723e96be676c937cfc1f61ed2b41 100644 (file)
@@ -52,4 +52,7 @@ struct felix {
        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
index 738e61820ccb0687676d2802289695718ef42242..bfbf811b060fd3ddd8630dc81f0e8b02e576b353 100644 (file)
@@ -1006,6 +1006,8 @@ static u16 vsc9959_wm_enc(u16 value)
 static const struct ocelot_ops vsc9959_ops = {
        .reset                  = vsc9959_reset,
        .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)
index 579eb7f2a71b06604328e2df134d01e6aaf9404e..f9b7507a4eb3c0f533579165f0f47ffed1b3285c 100644 (file)
@@ -1058,6 +1058,8 @@ static u16 vsc9953_wm_enc(u16 value)
 static const struct ocelot_ops vsc9953_ops = {
        .reset                  = vsc9953_reset,
        .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)
index dc29e05103a11a03839f09537cf61c3c8a8eeabe..abb407dff93c96d79f5630f04ebf5ea19e38df92 100644 (file)
@@ -98,6 +98,8 @@ int ocelot_port_lag_join(struct ocelot *ocelot, int port,
                         struct net_device *bond);
 void ocelot_port_lag_leave(struct ocelot *ocelot, int port,
                           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);
 void ocelot_port_writel(struct ocelot_port *port, u32 val, u32 reg);
index 028a0150f97d5efcfacd984184194325f77dfc24..64e619f0f5b22289570e231998537c6174284ab3 100644 (file)
@@ -656,6 +656,36 @@ static const struct net_device_ops ocelot_port_netdev_ops = {
        .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,
                                    u8 *data)
 {
index 086cddef319f059149ca4ff870b711b835876a89..f3e54589e6d665141a833f2b2033e25c2d771343 100644 (file)
@@ -763,6 +763,8 @@ static u16 ocelot_wm_enc(u16 value)
 static const struct ocelot_ops ocelot_ops = {
        .reset                  = ocelot_reset,
        .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[] = {
index 0c40122dcb88d1451e48807eaeebac8aac32e353..424256fa531b89b6abfe857133b7c54516524ce3 100644 (file)
@@ -559,6 +559,8 @@ enum ocelot_tag_prefix {
 struct ocelot;
 
 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);
        u16 (*wm_enc)(u16 value);
 };