]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
net: dsa: add master helper to look up slaves
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>
Fri, 29 Sep 2017 21:19:15 +0000 (17:19 -0400)
committerDavid S. Miller <davem@davemloft.net>
Sun, 1 Oct 2017 03:15:07 +0000 (04:15 +0100)
The DSA tagging code does not need to know about the DSA architecture,
it only needs to return the slave device corresponding to the source
port index (and eventually the source device index for cascade-capable
switches) parsed from the frame received on the master device.

For this purpose, provide an inline dsa_master_get_slave helper which
validates the device and port indexes and look up the slave device.

This makes the tagging rcv functions more concise and robust, and also
makes dsa_get_cpu_port obsolete.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/dsa/dsa_priv.h
net/dsa/tag_brcm.c
net/dsa/tag_dsa.c
net/dsa/tag_edsa.c
net/dsa/tag_ksz.c
net/dsa/tag_lan9303.c
net/dsa/tag_mtk.c
net/dsa/tag_qca.c
net/dsa/tag_trailer.c

index eccc6277628374ffd24adc1484adf54447e28ce4..d429505dc4e71e21ce02f201e898635c4403bf27 100644 (file)
@@ -113,6 +113,25 @@ int dsa_legacy_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
 int dsa_master_ethtool_setup(struct net_device *dev);
 void dsa_master_ethtool_restore(struct net_device *dev);
 
+static inline struct net_device *dsa_master_get_slave(struct net_device *dev,
+                                                     int device, int port)
+{
+       struct dsa_switch_tree *dst = dev->dsa_ptr;
+       struct dsa_switch *ds;
+
+       if (device < 0 || device >= DSA_MAX_SWITCHES)
+               return NULL;
+
+       ds = dst->ds[device];
+       if (!ds)
+               return NULL;
+
+       if (port < 0 || port >= ds->num_ports)
+               return NULL;
+
+       return ds->ports[port].netdev;
+}
+
 /* port.c */
 int dsa_port_set_state(struct dsa_port *dp, u8 state,
                       struct switchdev_trans *trans);
@@ -182,9 +201,4 @@ static inline struct net_device *dsa_master_netdev(struct dsa_slave_priv *p)
        return p->dp->cpu_dp->netdev;
 }
 
-static inline struct dsa_port *dsa_get_cpu_port(struct dsa_switch_tree *dst)
-{
-       return dst->cpu_dp;
-}
-
 #endif
index dbb016434ace8e3952d707c57f41b9e9eab48dd3..8e4bdb9d9ae365da792e52c1f13adb432a20dfeb 100644 (file)
@@ -92,9 +92,6 @@ static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev
 static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev,
                                    struct packet_type *pt)
 {
-       struct dsa_switch_tree *dst = dev->dsa_ptr;
-       struct dsa_port *cpu_dp = dsa_get_cpu_port(dst);
-       struct dsa_switch *ds = cpu_dp->ds;
        int source_port;
        u8 *brcm_tag;
 
@@ -117,8 +114,8 @@ static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev,
        /* Locate which port this is coming from */
        source_port = brcm_tag[3] & BRCM_EG_PID_MASK;
 
-       /* Validate port against switch setup, either the port is totally */
-       if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
+       skb->dev = dsa_master_get_slave(dev, 0, source_port);
+       if (!skb->dev)
                return NULL;
 
        /* Remove Broadcom tag and update checksum */
@@ -129,8 +126,6 @@ static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev,
                skb->data - ETH_HLEN - BRCM_TAG_LEN,
                2 * ETH_ALEN);
 
-       skb->dev = ds->ports[source_port].netdev;
-
        return skb;
 }
 
index fbf9ca954773d1b0b616f9e3f2ef2f70a1370e86..c77218f173d1b9c68ab55463623845b41166e00a 100644 (file)
@@ -67,8 +67,6 @@ static struct sk_buff *dsa_xmit(struct sk_buff *skb, struct net_device *dev)
 static struct sk_buff *dsa_rcv(struct sk_buff *skb, struct net_device *dev,
                               struct packet_type *pt)
 {
-       struct dsa_switch_tree *dst = dev->dsa_ptr;
-       struct dsa_switch *ds;
        u8 *dsa_header;
        int source_device;
        int source_port;
@@ -93,18 +91,8 @@ static struct sk_buff *dsa_rcv(struct sk_buff *skb, struct net_device *dev,
        source_device = dsa_header[0] & 0x1f;
        source_port = (dsa_header[1] >> 3) & 0x1f;
 
-       /*
-        * Check that the source device exists and that the source
-        * port is a registered DSA port.
-        */
-       if (source_device >= DSA_MAX_SWITCHES)
-               return NULL;
-
-       ds = dst->ds[source_device];
-       if (!ds)
-               return NULL;
-
-       if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
+       skb->dev = dsa_master_get_slave(dev, source_device, source_port);
+       if (!skb->dev)
                return NULL;
 
        /*
@@ -153,8 +141,6 @@ static struct sk_buff *dsa_rcv(struct sk_buff *skb, struct net_device *dev,
                        2 * ETH_ALEN);
        }
 
-       skb->dev = ds->ports[source_port].netdev;
-
        return skb;
 }
 
index 76367ba1b2e2433466fb56040e775637a6b41a8f..0b83cbe0c9e8acc6e703c7daebdb55ea67b07516 100644 (file)
@@ -80,8 +80,6 @@ static struct sk_buff *edsa_xmit(struct sk_buff *skb, struct net_device *dev)
 static struct sk_buff *edsa_rcv(struct sk_buff *skb, struct net_device *dev,
                                struct packet_type *pt)
 {
-       struct dsa_switch_tree *dst = dev->dsa_ptr;
-       struct dsa_switch *ds;
        u8 *edsa_header;
        int source_device;
        int source_port;
@@ -106,18 +104,8 @@ static struct sk_buff *edsa_rcv(struct sk_buff *skb, struct net_device *dev,
        source_device = edsa_header[0] & 0x1f;
        source_port = (edsa_header[1] >> 3) & 0x1f;
 
-       /*
-        * Check that the source device exists and that the source
-        * port is a registered DSA port.
-        */
-       if (source_device >= DSA_MAX_SWITCHES)
-               return NULL;
-
-       ds = dst->ds[source_device];
-       if (!ds)
-               return NULL;
-
-       if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
+       skb->dev = dsa_master_get_slave(dev, source_device, source_port);
+       if (!skb->dev)
                return NULL;
 
        /*
@@ -172,8 +160,6 @@ static struct sk_buff *edsa_rcv(struct sk_buff *skb, struct net_device *dev,
                        2 * ETH_ALEN);
        }
 
-       skb->dev = ds->ports[source_port].netdev;
-
        return skb;
 }
 
index 010ca0a336c46a34f6a89d8c6975ca4b00642e6e..b241c990cde08a8e4e166270b8dbff693ee268b0 100644 (file)
@@ -80,22 +80,19 @@ static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev)
 static struct sk_buff *ksz_rcv(struct sk_buff *skb, struct net_device *dev,
                               struct packet_type *pt)
 {
-       struct dsa_switch_tree *dst = dev->dsa_ptr;
-       struct dsa_port *cpu_dp = dsa_get_cpu_port(dst);
-       struct dsa_switch *ds = cpu_dp->ds;
        u8 *tag;
        int source_port;
 
        tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN;
 
        source_port = tag[0] & 7;
-       if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
+
+       skb->dev = dsa_master_get_slave(dev, 0, source_port);
+       if (!skb->dev)
                return NULL;
 
        pskb_trim_rcsum(skb, skb->len - KSZ_EGRESS_TAG_LEN);
 
-       skb->dev = ds->ports[source_port].netdev;
-
        return skb;
 }
 
index 0b9826105e421b77a22f77b7d8d7686655580ddb..4f211e56c81feb5ee472757f4792c415d686347f 100644 (file)
@@ -71,17 +71,8 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev,
                        struct packet_type *pt)
 {
        u16 *lan9303_tag;
-       struct dsa_switch_tree *dst = dev->dsa_ptr;
-       struct dsa_switch *ds;
        unsigned int source_port;
 
-       ds = dst->ds[0];
-
-       if (unlikely(!ds)) {
-               dev_warn_ratelimited(&dev->dev, "Dropping packet, due to missing DSA switch device\n");
-               return NULL;
-       }
-
        if (unlikely(!pskb_may_pull(skb, LAN9303_TAG_LEN))) {
                dev_warn_ratelimited(&dev->dev,
                                     "Dropping packet, cannot pull\n");
@@ -103,16 +94,12 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev,
 
        source_port = ntohs(lan9303_tag[1]) & 0x3;
 
-       if (source_port >= ds->num_ports) {
+       skb->dev = dsa_master_get_slave(dev, 0, source_port);
+       if (!skb->dev) {
                dev_warn_ratelimited(&dev->dev, "Dropping packet due to invalid source port\n");
                return NULL;
        }
 
-       if (!ds->ports[source_port].netdev) {
-               dev_warn_ratelimited(&dev->dev, "Dropping packet due to invalid netdev or device\n");
-               return NULL;
-       }
-
        /* remove the special VLAN tag between the MAC addresses
         * and the current ethertype field.
         */
@@ -120,9 +107,6 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev,
        memmove(skb->data - ETH_HLEN, skb->data - (ETH_HLEN + LAN9303_TAG_LEN),
                2 * ETH_ALEN);
 
-       /* forward the packet to the dedicated interface */
-       skb->dev = ds->ports[source_port].netdev;
-
        return skb;
 }
 
index ec8ee5f43255e7d95ace5b44f3c04860bd0b8507..968586c5d40e8cdd6b6cdcdc2c680fbcb173d990 100644 (file)
@@ -46,8 +46,6 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
 static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev,
                                   struct packet_type *pt)
 {
-       struct dsa_switch_tree *dst = dev->dsa_ptr;
-       struct dsa_switch *ds;
        int port;
        __be16 *phdr, hdr;
 
@@ -68,20 +66,12 @@ static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev,
                skb->data - ETH_HLEN - MTK_HDR_LEN,
                2 * ETH_ALEN);
 
-       /* This protocol doesn't support cascading multiple
-        * switches so it's safe to assume the switch is first
-        * in the tree.
-        */
-       ds = dst->ds[0];
-       if (!ds)
-               return NULL;
-
        /* Get source port information */
        port = (hdr & MTK_HDR_RECV_SOURCE_PORT_MASK);
-       if (!ds->ports[port].netdev)
-               return NULL;
 
-       skb->dev = ds->ports[port].netdev;
+       skb->dev = dsa_master_get_slave(dev, 0, port);
+       if (!skb->dev)
+               return NULL;
 
        return skb;
 }
index 1d4c70711c0f456e0bcb6f970954e3f1f45dc9b3..8d33d9ebf910d7206185a22da50944abc49eee2b 100644 (file)
@@ -65,9 +65,6 @@ static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev)
 static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, struct net_device *dev,
                                   struct packet_type *pt)
 {
-       struct dsa_switch_tree *dst = dev->dsa_ptr;
-       struct dsa_port *cpu_dp = dsa_get_cpu_port(dst);
-       struct dsa_switch *ds;
        u8 ver;
        int port;
        __be16 *phdr, hdr;
@@ -92,20 +89,12 @@ static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, struct net_device *dev,
        memmove(skb->data - ETH_HLEN, skb->data - ETH_HLEN - QCA_HDR_LEN,
                ETH_HLEN - QCA_HDR_LEN);
 
-       /* This protocol doesn't support cascading multiple switches so it's
-        * safe to assume the switch is first in the tree
-        */
-       ds = cpu_dp->ds;
-       if (!ds)
-               return NULL;
-
        /* Get source port information */
        port = (hdr & QCA_HDR_RECV_SOURCE_PORT_MASK);
-       if (!ds->ports[port].netdev)
-               return NULL;
 
-       /* Update skb & forward the frame accordingly */
-       skb->dev = ds->ports[port].netdev;
+       skb->dev = dsa_master_get_slave(dev, 0, port);
+       if (!skb->dev)
+               return NULL;
 
        return skb;
 }
index d2fd4923aa3eb3d1d56f20dd159d0ca87408b835..61668be267f5dd40e94fdfbccfea8b2bdef32999 100644 (file)
@@ -58,9 +58,6 @@ static struct sk_buff *trailer_xmit(struct sk_buff *skb, struct net_device *dev)
 static struct sk_buff *trailer_rcv(struct sk_buff *skb, struct net_device *dev,
                                   struct packet_type *pt)
 {
-       struct dsa_switch_tree *dst = dev->dsa_ptr;
-       struct dsa_port *cpu_dp = dsa_get_cpu_port(dst);
-       struct dsa_switch *ds = cpu_dp->ds;
        u8 *trailer;
        int source_port;
 
@@ -73,13 +70,13 @@ static struct sk_buff *trailer_rcv(struct sk_buff *skb, struct net_device *dev,
                return NULL;
 
        source_port = trailer[1] & 7;
-       if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
+
+       skb->dev = dsa_master_get_slave(dev, 0, source_port);
+       if (!skb->dev)
                return NULL;
 
        pskb_trim_rcsum(skb, skb->len - 4);
 
-       skb->dev = ds->ports[source_port].netdev;
-
        return skb;
 }