summaryrefslogtreecommitdiffstats
path: root/net/dsa
diff options
context:
space:
mode:
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>2017-09-29 17:19:15 -0400
committerDavid S. Miller <davem@davemloft.net>2017-09-30 23:15:07 -0400
commit3775b1b7f0c330e59c434d1852d7762ae0a9c164 (patch)
tree260da462218e9ef4823835cce47f1224a452c6e9 /net/dsa
parent075cfdd659cb1e86f948f11ba577f27706f0756e (diff)
net: dsa: add master helper to look up slaves
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>
Diffstat (limited to 'net/dsa')
-rw-r--r--net/dsa/dsa_priv.h24
-rw-r--r--net/dsa/tag_brcm.c9
-rw-r--r--net/dsa/tag_dsa.c18
-rw-r--r--net/dsa/tag_edsa.c18
-rw-r--r--net/dsa/tag_ksz.c9
-rw-r--r--net/dsa/tag_lan9303.c20
-rw-r--r--net/dsa/tag_mtk.c16
-rw-r--r--net/dsa/tag_qca.c17
-rw-r--r--net/dsa/tag_trailer.c9
9 files changed, 39 insertions, 101 deletions
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index eccc62776283..d429505dc4e7 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -113,6 +113,25 @@ int dsa_legacy_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
113int dsa_master_ethtool_setup(struct net_device *dev); 113int dsa_master_ethtool_setup(struct net_device *dev);
114void dsa_master_ethtool_restore(struct net_device *dev); 114void dsa_master_ethtool_restore(struct net_device *dev);
115 115
116static inline struct net_device *dsa_master_get_slave(struct net_device *dev,
117 int device, int port)
118{
119 struct dsa_switch_tree *dst = dev->dsa_ptr;
120 struct dsa_switch *ds;
121
122 if (device < 0 || device >= DSA_MAX_SWITCHES)
123 return NULL;
124
125 ds = dst->ds[device];
126 if (!ds)
127 return NULL;
128
129 if (port < 0 || port >= ds->num_ports)
130 return NULL;
131
132 return ds->ports[port].netdev;
133}
134
116/* port.c */ 135/* port.c */
117int dsa_port_set_state(struct dsa_port *dp, u8 state, 136int dsa_port_set_state(struct dsa_port *dp, u8 state,
118 struct switchdev_trans *trans); 137 struct switchdev_trans *trans);
@@ -182,9 +201,4 @@ static inline struct net_device *dsa_master_netdev(struct dsa_slave_priv *p)
182 return p->dp->cpu_dp->netdev; 201 return p->dp->cpu_dp->netdev;
183} 202}
184 203
185static inline struct dsa_port *dsa_get_cpu_port(struct dsa_switch_tree *dst)
186{
187 return dst->cpu_dp;
188}
189
190#endif 204#endif
diff --git a/net/dsa/tag_brcm.c b/net/dsa/tag_brcm.c
index dbb016434ace..8e4bdb9d9ae3 100644
--- a/net/dsa/tag_brcm.c
+++ b/net/dsa/tag_brcm.c
@@ -92,9 +92,6 @@ static struct sk_buff *brcm_tag_xmit(struct sk_buff *skb, struct net_device *dev
92static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev, 92static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev,
93 struct packet_type *pt) 93 struct packet_type *pt)
94{ 94{
95 struct dsa_switch_tree *dst = dev->dsa_ptr;
96 struct dsa_port *cpu_dp = dsa_get_cpu_port(dst);
97 struct dsa_switch *ds = cpu_dp->ds;
98 int source_port; 95 int source_port;
99 u8 *brcm_tag; 96 u8 *brcm_tag;
100 97
@@ -117,8 +114,8 @@ static struct sk_buff *brcm_tag_rcv(struct sk_buff *skb, struct net_device *dev,
117 /* Locate which port this is coming from */ 114 /* Locate which port this is coming from */
118 source_port = brcm_tag[3] & BRCM_EG_PID_MASK; 115 source_port = brcm_tag[3] & BRCM_EG_PID_MASK;
119 116
120 /* Validate port against switch setup, either the port is totally */ 117 skb->dev = dsa_master_get_slave(dev, 0, source_port);
121 if (source_port >= ds->num_ports || !ds->ports[source_port].netdev) 118 if (!skb->dev)
122 return NULL; 119 return NULL;
123 120
124 /* Remove Broadcom tag and update checksum */ 121 /* 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,
129 skb->data - ETH_HLEN - BRCM_TAG_LEN, 126 skb->data - ETH_HLEN - BRCM_TAG_LEN,
130 2 * ETH_ALEN); 127 2 * ETH_ALEN);
131 128
132 skb->dev = ds->ports[source_port].netdev;
133
134 return skb; 129 return skb;
135} 130}
136 131
diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c
index fbf9ca954773..c77218f173d1 100644
--- a/net/dsa/tag_dsa.c
+++ b/net/dsa/tag_dsa.c
@@ -67,8 +67,6 @@ static struct sk_buff *dsa_xmit(struct sk_buff *skb, struct net_device *dev)
67static struct sk_buff *dsa_rcv(struct sk_buff *skb, struct net_device *dev, 67static struct sk_buff *dsa_rcv(struct sk_buff *skb, struct net_device *dev,
68 struct packet_type *pt) 68 struct packet_type *pt)
69{ 69{
70 struct dsa_switch_tree *dst = dev->dsa_ptr;
71 struct dsa_switch *ds;
72 u8 *dsa_header; 70 u8 *dsa_header;
73 int source_device; 71 int source_device;
74 int source_port; 72 int source_port;
@@ -93,18 +91,8 @@ static struct sk_buff *dsa_rcv(struct sk_buff *skb, struct net_device *dev,
93 source_device = dsa_header[0] & 0x1f; 91 source_device = dsa_header[0] & 0x1f;
94 source_port = (dsa_header[1] >> 3) & 0x1f; 92 source_port = (dsa_header[1] >> 3) & 0x1f;
95 93
96 /* 94 skb->dev = dsa_master_get_slave(dev, source_device, source_port);
97 * Check that the source device exists and that the source 95 if (!skb->dev)
98 * port is a registered DSA port.
99 */
100 if (source_device >= DSA_MAX_SWITCHES)
101 return NULL;
102
103 ds = dst->ds[source_device];
104 if (!ds)
105 return NULL;
106
107 if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
108 return NULL; 96 return NULL;
109 97
110 /* 98 /*
@@ -153,8 +141,6 @@ static struct sk_buff *dsa_rcv(struct sk_buff *skb, struct net_device *dev,
153 2 * ETH_ALEN); 141 2 * ETH_ALEN);
154 } 142 }
155 143
156 skb->dev = ds->ports[source_port].netdev;
157
158 return skb; 144 return skb;
159} 145}
160 146
diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c
index 76367ba1b2e2..0b83cbe0c9e8 100644
--- a/net/dsa/tag_edsa.c
+++ b/net/dsa/tag_edsa.c
@@ -80,8 +80,6 @@ static struct sk_buff *edsa_xmit(struct sk_buff *skb, struct net_device *dev)
80static struct sk_buff *edsa_rcv(struct sk_buff *skb, struct net_device *dev, 80static struct sk_buff *edsa_rcv(struct sk_buff *skb, struct net_device *dev,
81 struct packet_type *pt) 81 struct packet_type *pt)
82{ 82{
83 struct dsa_switch_tree *dst = dev->dsa_ptr;
84 struct dsa_switch *ds;
85 u8 *edsa_header; 83 u8 *edsa_header;
86 int source_device; 84 int source_device;
87 int source_port; 85 int source_port;
@@ -106,18 +104,8 @@ static struct sk_buff *edsa_rcv(struct sk_buff *skb, struct net_device *dev,
106 source_device = edsa_header[0] & 0x1f; 104 source_device = edsa_header[0] & 0x1f;
107 source_port = (edsa_header[1] >> 3) & 0x1f; 105 source_port = (edsa_header[1] >> 3) & 0x1f;
108 106
109 /* 107 skb->dev = dsa_master_get_slave(dev, source_device, source_port);
110 * Check that the source device exists and that the source 108 if (!skb->dev)
111 * port is a registered DSA port.
112 */
113 if (source_device >= DSA_MAX_SWITCHES)
114 return NULL;
115
116 ds = dst->ds[source_device];
117 if (!ds)
118 return NULL;
119
120 if (source_port >= ds->num_ports || !ds->ports[source_port].netdev)
121 return NULL; 109 return NULL;
122 110
123 /* 111 /*
@@ -172,8 +160,6 @@ static struct sk_buff *edsa_rcv(struct sk_buff *skb, struct net_device *dev,
172 2 * ETH_ALEN); 160 2 * ETH_ALEN);
173 } 161 }
174 162
175 skb->dev = ds->ports[source_port].netdev;
176
177 return skb; 163 return skb;
178} 164}
179 165
diff --git a/net/dsa/tag_ksz.c b/net/dsa/tag_ksz.c
index 010ca0a336c4..b241c990cde0 100644
--- a/net/dsa/tag_ksz.c
+++ b/net/dsa/tag_ksz.c
@@ -80,22 +80,19 @@ static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev)
80static struct sk_buff *ksz_rcv(struct sk_buff *skb, struct net_device *dev, 80static struct sk_buff *ksz_rcv(struct sk_buff *skb, struct net_device *dev,
81 struct packet_type *pt) 81 struct packet_type *pt)
82{ 82{
83 struct dsa_switch_tree *dst = dev->dsa_ptr;
84 struct dsa_port *cpu_dp = dsa_get_cpu_port(dst);
85 struct dsa_switch *ds = cpu_dp->ds;
86 u8 *tag; 83 u8 *tag;
87 int source_port; 84 int source_port;
88 85
89 tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN; 86 tag = skb_tail_pointer(skb) - KSZ_EGRESS_TAG_LEN;
90 87
91 source_port = tag[0] & 7; 88 source_port = tag[0] & 7;
92 if (source_port >= ds->num_ports || !ds->ports[source_port].netdev) 89
90 skb->dev = dsa_master_get_slave(dev, 0, source_port);
91 if (!skb->dev)
93 return NULL; 92 return NULL;
94 93
95 pskb_trim_rcsum(skb, skb->len - KSZ_EGRESS_TAG_LEN); 94 pskb_trim_rcsum(skb, skb->len - KSZ_EGRESS_TAG_LEN);
96 95
97 skb->dev = ds->ports[source_port].netdev;
98
99 return skb; 96 return skb;
100} 97}
101 98
diff --git a/net/dsa/tag_lan9303.c b/net/dsa/tag_lan9303.c
index 0b9826105e42..4f211e56c81f 100644
--- a/net/dsa/tag_lan9303.c
+++ b/net/dsa/tag_lan9303.c
@@ -71,17 +71,8 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev,
71 struct packet_type *pt) 71 struct packet_type *pt)
72{ 72{
73 u16 *lan9303_tag; 73 u16 *lan9303_tag;
74 struct dsa_switch_tree *dst = dev->dsa_ptr;
75 struct dsa_switch *ds;
76 unsigned int source_port; 74 unsigned int source_port;
77 75
78 ds = dst->ds[0];
79
80 if (unlikely(!ds)) {
81 dev_warn_ratelimited(&dev->dev, "Dropping packet, due to missing DSA switch device\n");
82 return NULL;
83 }
84
85 if (unlikely(!pskb_may_pull(skb, LAN9303_TAG_LEN))) { 76 if (unlikely(!pskb_may_pull(skb, LAN9303_TAG_LEN))) {
86 dev_warn_ratelimited(&dev->dev, 77 dev_warn_ratelimited(&dev->dev,
87 "Dropping packet, cannot pull\n"); 78 "Dropping packet, cannot pull\n");
@@ -103,16 +94,12 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev,
103 94
104 source_port = ntohs(lan9303_tag[1]) & 0x3; 95 source_port = ntohs(lan9303_tag[1]) & 0x3;
105 96
106 if (source_port >= ds->num_ports) { 97 skb->dev = dsa_master_get_slave(dev, 0, source_port);
98 if (!skb->dev) {
107 dev_warn_ratelimited(&dev->dev, "Dropping packet due to invalid source port\n"); 99 dev_warn_ratelimited(&dev->dev, "Dropping packet due to invalid source port\n");
108 return NULL; 100 return NULL;
109 } 101 }
110 102
111 if (!ds->ports[source_port].netdev) {
112 dev_warn_ratelimited(&dev->dev, "Dropping packet due to invalid netdev or device\n");
113 return NULL;
114 }
115
116 /* remove the special VLAN tag between the MAC addresses 103 /* remove the special VLAN tag between the MAC addresses
117 * and the current ethertype field. 104 * and the current ethertype field.
118 */ 105 */
@@ -120,9 +107,6 @@ static struct sk_buff *lan9303_rcv(struct sk_buff *skb, struct net_device *dev,
120 memmove(skb->data - ETH_HLEN, skb->data - (ETH_HLEN + LAN9303_TAG_LEN), 107 memmove(skb->data - ETH_HLEN, skb->data - (ETH_HLEN + LAN9303_TAG_LEN),
121 2 * ETH_ALEN); 108 2 * ETH_ALEN);
122 109
123 /* forward the packet to the dedicated interface */
124 skb->dev = ds->ports[source_port].netdev;
125
126 return skb; 110 return skb;
127} 111}
128 112
diff --git a/net/dsa/tag_mtk.c b/net/dsa/tag_mtk.c
index ec8ee5f43255..968586c5d40e 100644
--- a/net/dsa/tag_mtk.c
+++ b/net/dsa/tag_mtk.c
@@ -46,8 +46,6 @@ static struct sk_buff *mtk_tag_xmit(struct sk_buff *skb,
46static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev, 46static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev,
47 struct packet_type *pt) 47 struct packet_type *pt)
48{ 48{
49 struct dsa_switch_tree *dst = dev->dsa_ptr;
50 struct dsa_switch *ds;
51 int port; 49 int port;
52 __be16 *phdr, hdr; 50 __be16 *phdr, hdr;
53 51
@@ -68,20 +66,12 @@ static struct sk_buff *mtk_tag_rcv(struct sk_buff *skb, struct net_device *dev,
68 skb->data - ETH_HLEN - MTK_HDR_LEN, 66 skb->data - ETH_HLEN - MTK_HDR_LEN,
69 2 * ETH_ALEN); 67 2 * ETH_ALEN);
70 68
71 /* This protocol doesn't support cascading multiple
72 * switches so it's safe to assume the switch is first
73 * in the tree.
74 */
75 ds = dst->ds[0];
76 if (!ds)
77 return NULL;
78
79 /* Get source port information */ 69 /* Get source port information */
80 port = (hdr & MTK_HDR_RECV_SOURCE_PORT_MASK); 70 port = (hdr & MTK_HDR_RECV_SOURCE_PORT_MASK);
81 if (!ds->ports[port].netdev)
82 return NULL;
83 71
84 skb->dev = ds->ports[port].netdev; 72 skb->dev = dsa_master_get_slave(dev, 0, port);
73 if (!skb->dev)
74 return NULL;
85 75
86 return skb; 76 return skb;
87} 77}
diff --git a/net/dsa/tag_qca.c b/net/dsa/tag_qca.c
index 1d4c70711c0f..8d33d9ebf910 100644
--- a/net/dsa/tag_qca.c
+++ b/net/dsa/tag_qca.c
@@ -65,9 +65,6 @@ static struct sk_buff *qca_tag_xmit(struct sk_buff *skb, struct net_device *dev)
65static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, struct net_device *dev, 65static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, struct net_device *dev,
66 struct packet_type *pt) 66 struct packet_type *pt)
67{ 67{
68 struct dsa_switch_tree *dst = dev->dsa_ptr;
69 struct dsa_port *cpu_dp = dsa_get_cpu_port(dst);
70 struct dsa_switch *ds;
71 u8 ver; 68 u8 ver;
72 int port; 69 int port;
73 __be16 *phdr, hdr; 70 __be16 *phdr, hdr;
@@ -92,20 +89,12 @@ static struct sk_buff *qca_tag_rcv(struct sk_buff *skb, struct net_device *dev,
92 memmove(skb->data - ETH_HLEN, skb->data - ETH_HLEN - QCA_HDR_LEN, 89 memmove(skb->data - ETH_HLEN, skb->data - ETH_HLEN - QCA_HDR_LEN,
93 ETH_HLEN - QCA_HDR_LEN); 90 ETH_HLEN - QCA_HDR_LEN);
94 91
95 /* This protocol doesn't support cascading multiple switches so it's
96 * safe to assume the switch is first in the tree
97 */
98 ds = cpu_dp->ds;
99 if (!ds)
100 return NULL;
101
102 /* Get source port information */ 92 /* Get source port information */
103 port = (hdr & QCA_HDR_RECV_SOURCE_PORT_MASK); 93 port = (hdr & QCA_HDR_RECV_SOURCE_PORT_MASK);
104 if (!ds->ports[port].netdev)
105 return NULL;
106 94
107 /* Update skb & forward the frame accordingly */ 95 skb->dev = dsa_master_get_slave(dev, 0, port);
108 skb->dev = ds->ports[port].netdev; 96 if (!skb->dev)
97 return NULL;
109 98
110 return skb; 99 return skb;
111} 100}
diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c
index d2fd4923aa3e..61668be267f5 100644
--- a/net/dsa/tag_trailer.c
+++ b/net/dsa/tag_trailer.c
@@ -58,9 +58,6 @@ static struct sk_buff *trailer_xmit(struct sk_buff *skb, struct net_device *dev)
58static struct sk_buff *trailer_rcv(struct sk_buff *skb, struct net_device *dev, 58static struct sk_buff *trailer_rcv(struct sk_buff *skb, struct net_device *dev,
59 struct packet_type *pt) 59 struct packet_type *pt)
60{ 60{
61 struct dsa_switch_tree *dst = dev->dsa_ptr;
62 struct dsa_port *cpu_dp = dsa_get_cpu_port(dst);
63 struct dsa_switch *ds = cpu_dp->ds;
64 u8 *trailer; 61 u8 *trailer;
65 int source_port; 62 int source_port;
66 63
@@ -73,13 +70,13 @@ static struct sk_buff *trailer_rcv(struct sk_buff *skb, struct net_device *dev,
73 return NULL; 70 return NULL;
74 71
75 source_port = trailer[1] & 7; 72 source_port = trailer[1] & 7;
76 if (source_port >= ds->num_ports || !ds->ports[source_port].netdev) 73
74 skb->dev = dsa_master_get_slave(dev, 0, source_port);
75 if (!skb->dev)
77 return NULL; 76 return NULL;
78 77
79 pskb_trim_rcsum(skb, skb->len - 4); 78 pskb_trim_rcsum(skb, skb->len - 4);
80 79
81 skb->dev = ds->ports[source_port].netdev;
82
83 return skb; 80 return skb;
84} 81}
85 82