summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Oltean <olteanv@gmail.com>2019-05-05 06:19:27 -0400
committerDavid S. Miller <davem@davemloft.net>2019-05-06 00:52:42 -0400
commit227d07a07ef126272ea2eed97fd136cd7a803d81 (patch)
treed5004e1438e81abf29266b349005ae3a945f7e72
parentc362beb072e14b929eb657dc174d83ccdd9b0eed (diff)
net: dsa: sja1105: Add support for traffic through standalone ports
In order to support this, we are creating a make-shift switch tag out of a VLAN trunk configured on the CPU port. Termination of normal traffic on switch ports only works when not under a vlan_filtering bridge. Termination of management (PTP, BPDU) traffic works under all circumstances because it uses a different tagging mechanism (incl_srcpt). We are making use of the generic CONFIG_NET_DSA_TAG_8021Q code and leveraging it from our own CONFIG_NET_DSA_TAG_SJA1105. There are two types of traffic: regular and link-local. The link-local traffic received on the CPU port is trapped from the switch's regular forwarding decisions because it matched one of the two DMAC filters for management traffic. On transmission, the switch requires special massaging for these link-local frames. Due to a weird implementation of the switching IP, by default it drops link-local frames that originate on the CPU port. It needs to be told where to forward them to, through an SPI command ("management route") that is valid for only a single frame. So when we're sending link-local traffic, we are using the dsa_defer_xmit mechanism. Signed-off-by: Vladimir Oltean <olteanv@gmail.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/dsa/sja1105/Kconfig1
-rw-r--r--drivers/net/dsa/sja1105/sja1105.h6
-rw-r--r--drivers/net/dsa/sja1105/sja1105_main.c138
-rw-r--r--include/linux/dsa/sja1105.h35
-rw-r--r--include/net/dsa.h2
-rw-r--r--net/dsa/Kconfig9
-rw-r--r--net/dsa/Makefile1
-rw-r--r--net/dsa/tag_sja1105.c131
8 files changed, 308 insertions, 15 deletions
diff --git a/drivers/net/dsa/sja1105/Kconfig b/drivers/net/dsa/sja1105/Kconfig
index 038685bb9d57..757751a89819 100644
--- a/drivers/net/dsa/sja1105/Kconfig
+++ b/drivers/net/dsa/sja1105/Kconfig
@@ -1,6 +1,7 @@
1config NET_DSA_SJA1105 1config NET_DSA_SJA1105
2tristate "NXP SJA1105 Ethernet switch family support" 2tristate "NXP SJA1105 Ethernet switch family support"
3 depends on NET_DSA && SPI 3 depends on NET_DSA && SPI
4 select NET_DSA_TAG_SJA1105
4 select PACKING 5 select PACKING
5 select CRC32 6 select CRC32
6 help 7 help
diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h
index b0a155b57e17..b043bfc408f2 100644
--- a/drivers/net/dsa/sja1105/sja1105.h
+++ b/drivers/net/dsa/sja1105/sja1105.h
@@ -7,6 +7,7 @@
7 7
8#include <linux/dsa/sja1105.h> 8#include <linux/dsa/sja1105.h>
9#include <net/dsa.h> 9#include <net/dsa.h>
10#include <linux/mutex.h>
10#include "sja1105_static_config.h" 11#include "sja1105_static_config.h"
11 12
12#define SJA1105_NUM_PORTS 5 13#define SJA1105_NUM_PORTS 5
@@ -65,6 +66,11 @@ struct sja1105_private {
65 struct gpio_desc *reset_gpio; 66 struct gpio_desc *reset_gpio;
66 struct spi_device *spidev; 67 struct spi_device *spidev;
67 struct dsa_switch *ds; 68 struct dsa_switch *ds;
69 struct sja1105_port ports[SJA1105_NUM_PORTS];
70 /* Serializes transmission of management frames so that
71 * the switch doesn't confuse them with one another.
72 */
73 struct mutex mgmt_lock;
68}; 74};
69 75
70#include "sja1105_dynamic_config.h" 76#include "sja1105_dynamic_config.h"
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index 74f8ff9e17e0..785bb42cb993 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -20,6 +20,7 @@
20#include <linux/netdevice.h> 20#include <linux/netdevice.h>
21#include <linux/if_bridge.h> 21#include <linux/if_bridge.h>
22#include <linux/if_ether.h> 22#include <linux/if_ether.h>
23#include <linux/dsa/8021q.h>
23#include "sja1105.h" 24#include "sja1105.h"
24 25
25static void sja1105_hw_reset(struct gpio_desc *gpio, unsigned int pulse_len, 26static void sja1105_hw_reset(struct gpio_desc *gpio, unsigned int pulse_len,
@@ -406,11 +407,14 @@ static int sja1105_init_general_params(struct sja1105_private *priv)
406 .tpid2 = ETH_P_SJA1105, 407 .tpid2 = ETH_P_SJA1105,
407 }; 408 };
408 struct sja1105_table *table; 409 struct sja1105_table *table;
409 int i; 410 int i, k = 0;
410 411
411 for (i = 0; i < SJA1105_NUM_PORTS; i++) 412 for (i = 0; i < SJA1105_NUM_PORTS; i++) {
412 if (dsa_is_dsa_port(priv->ds, i)) 413 if (dsa_is_dsa_port(priv->ds, i))
413 default_general_params.casc_port = i; 414 default_general_params.casc_port = i;
415 else if (dsa_is_user_port(priv->ds, i))
416 priv->ports[i].mgmt_slot = k++;
417 }
414 418
415 table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS]; 419 table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS];
416 420
@@ -1146,10 +1150,27 @@ static int sja1105_vlan_apply(struct sja1105_private *priv, int port, u16 vid,
1146 return 0; 1150 return 0;
1147} 1151}
1148 1152
1153static int sja1105_setup_8021q_tagging(struct dsa_switch *ds, bool enabled)
1154{
1155 int rc, i;
1156
1157 for (i = 0; i < SJA1105_NUM_PORTS; i++) {
1158 rc = dsa_port_setup_8021q_tagging(ds, i, enabled);
1159 if (rc < 0) {
1160 dev_err(ds->dev, "Failed to setup VLAN tagging for port %d: %d\n",
1161 i, rc);
1162 return rc;
1163 }
1164 }
1165 dev_info(ds->dev, "%s switch tagging\n",
1166 enabled ? "Enabled" : "Disabled");
1167 return 0;
1168}
1169
1149static enum dsa_tag_protocol 1170static enum dsa_tag_protocol
1150sja1105_get_tag_protocol(struct dsa_switch *ds, int port) 1171sja1105_get_tag_protocol(struct dsa_switch *ds, int port)
1151{ 1172{
1152 return DSA_TAG_PROTO_NONE; 1173 return DSA_TAG_PROTO_SJA1105;
1153} 1174}
1154 1175
1155/* This callback needs to be present */ 1176/* This callback needs to be present */
@@ -1173,7 +1194,11 @@ static int sja1105_vlan_filtering(struct dsa_switch *ds, int port, bool enabled)
1173 if (rc) 1194 if (rc)
1174 dev_err(ds->dev, "Failed to change VLAN Ethertype\n"); 1195 dev_err(ds->dev, "Failed to change VLAN Ethertype\n");
1175 1196
1176 return rc; 1197 /* Switch port identification based on 802.1Q is only passable
1198 * if we are not under a vlan_filtering bridge. So make sure
1199 * the two configurations are mutually exclusive.
1200 */
1201 return sja1105_setup_8021q_tagging(ds, !enabled);
1177} 1202}
1178 1203
1179static void sja1105_vlan_add(struct dsa_switch *ds, int port, 1204static void sja1105_vlan_add(struct dsa_switch *ds, int port,
@@ -1276,7 +1301,98 @@ static int sja1105_setup(struct dsa_switch *ds)
1276 */ 1301 */
1277 ds->vlan_filtering_is_global = true; 1302 ds->vlan_filtering_is_global = true;
1278 1303
1279 return 0; 1304 /* The DSA/switchdev model brings up switch ports in standalone mode by
1305 * default, and that means vlan_filtering is 0 since they're not under
1306 * a bridge, so it's safe to set up switch tagging at this time.
1307 */
1308 return sja1105_setup_8021q_tagging(ds, true);
1309}
1310
1311static int sja1105_mgmt_xmit(struct dsa_switch *ds, int port, int slot,
1312 struct sk_buff *skb)
1313{
1314 struct sja1105_mgmt_entry mgmt_route = {0};
1315 struct sja1105_private *priv = ds->priv;
1316 struct ethhdr *hdr;
1317 int timeout = 10;
1318 int rc;
1319
1320 hdr = eth_hdr(skb);
1321
1322 mgmt_route.macaddr = ether_addr_to_u64(hdr->h_dest);
1323 mgmt_route.destports = BIT(port);
1324 mgmt_route.enfport = 1;
1325
1326 rc = sja1105_dynamic_config_write(priv, BLK_IDX_MGMT_ROUTE,
1327 slot, &mgmt_route, true);
1328 if (rc < 0) {
1329 kfree_skb(skb);
1330 return rc;
1331 }
1332
1333 /* Transfer skb to the host port. */
1334 dsa_enqueue_skb(skb, ds->ports[port].slave);
1335
1336 /* Wait until the switch has processed the frame */
1337 do {
1338 rc = sja1105_dynamic_config_read(priv, BLK_IDX_MGMT_ROUTE,
1339 slot, &mgmt_route);
1340 if (rc < 0) {
1341 dev_err_ratelimited(priv->ds->dev,
1342 "failed to poll for mgmt route\n");
1343 continue;
1344 }
1345
1346 /* UM10944: The ENFPORT flag of the respective entry is
1347 * cleared when a match is found. The host can use this
1348 * flag as an acknowledgment.
1349 */
1350 cpu_relax();
1351 } while (mgmt_route.enfport && --timeout);
1352
1353 if (!timeout) {
1354 /* Clean up the management route so that a follow-up
1355 * frame may not match on it by mistake.
1356 */
1357 sja1105_dynamic_config_write(priv, BLK_IDX_MGMT_ROUTE,
1358 slot, &mgmt_route, false);
1359 dev_err_ratelimited(priv->ds->dev, "xmit timed out\n");
1360 }
1361
1362 return NETDEV_TX_OK;
1363}
1364
1365/* Deferred work is unfortunately necessary because setting up the management
1366 * route cannot be done from atomit context (SPI transfer takes a sleepable
1367 * lock on the bus)
1368 */
1369static netdev_tx_t sja1105_port_deferred_xmit(struct dsa_switch *ds, int port,
1370 struct sk_buff *skb)
1371{
1372 struct sja1105_private *priv = ds->priv;
1373 struct sja1105_port *sp = &priv->ports[port];
1374 int slot = sp->mgmt_slot;
1375
1376 /* The tragic fact about the switch having 4x2 slots for installing
1377 * management routes is that all of them except one are actually
1378 * useless.
1379 * If 2 slots are simultaneously configured for two BPDUs sent to the
1380 * same (multicast) DMAC but on different egress ports, the switch
1381 * would confuse them and redirect first frame it receives on the CPU
1382 * port towards the port configured on the numerically first slot
1383 * (therefore wrong port), then second received frame on second slot
1384 * (also wrong port).
1385 * So for all practical purposes, there needs to be a lock that
1386 * prevents that from happening. The slot used here is utterly useless
1387 * (could have simply been 0 just as fine), but we are doing it
1388 * nonetheless, in case a smarter idea ever comes up in the future.
1389 */
1390 mutex_lock(&priv->mgmt_lock);
1391
1392 sja1105_mgmt_xmit(ds, port, slot, skb);
1393
1394 mutex_unlock(&priv->mgmt_lock);
1395 return NETDEV_TX_OK;
1280} 1396}
1281 1397
1282/* The MAXAGE setting belongs to the L2 Forwarding Parameters table, 1398/* The MAXAGE setting belongs to the L2 Forwarding Parameters table,
@@ -1324,6 +1440,7 @@ static const struct dsa_switch_ops sja1105_switch_ops = {
1324 .port_mdb_prepare = sja1105_mdb_prepare, 1440 .port_mdb_prepare = sja1105_mdb_prepare,
1325 .port_mdb_add = sja1105_mdb_add, 1441 .port_mdb_add = sja1105_mdb_add,
1326 .port_mdb_del = sja1105_mdb_del, 1442 .port_mdb_del = sja1105_mdb_del,
1443 .port_deferred_xmit = sja1105_port_deferred_xmit,
1327}; 1444};
1328 1445
1329static int sja1105_check_device_id(struct sja1105_private *priv) 1446static int sja1105_check_device_id(struct sja1105_private *priv)
@@ -1367,7 +1484,7 @@ static int sja1105_probe(struct spi_device *spi)
1367 struct device *dev = &spi->dev; 1484 struct device *dev = &spi->dev;
1368 struct sja1105_private *priv; 1485 struct sja1105_private *priv;
1369 struct dsa_switch *ds; 1486 struct dsa_switch *ds;
1370 int rc; 1487 int rc, i;
1371 1488
1372 if (!dev->of_node) { 1489 if (!dev->of_node) {
1373 dev_err(dev, "No DTS bindings for SJA1105 driver\n"); 1490 dev_err(dev, "No DTS bindings for SJA1105 driver\n");
@@ -1418,6 +1535,15 @@ static int sja1105_probe(struct spi_device *spi)
1418 ds->priv = priv; 1535 ds->priv = priv;
1419 priv->ds = ds; 1536 priv->ds = ds;
1420 1537
1538 /* Connections between dsa_port and sja1105_port */
1539 for (i = 0; i < SJA1105_NUM_PORTS; i++) {
1540 struct sja1105_port *sp = &priv->ports[i];
1541
1542 ds->ports[i].priv = sp;
1543 sp->dp = &ds->ports[i];
1544 }
1545 mutex_init(&priv->mgmt_lock);
1546
1421 return dsa_register_switch(priv->ds); 1547 return dsa_register_switch(priv->ds);
1422} 1548}
1423 1549
diff --git a/include/linux/dsa/sja1105.h b/include/linux/dsa/sja1105.h
index abf3977e34fd..603a02e5a8cb 100644
--- a/include/linux/dsa/sja1105.h
+++ b/include/linux/dsa/sja1105.h
@@ -2,22 +2,39 @@
2 * Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com> 2 * Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com>
3 */ 3 */
4 4
5/* Included by drivers/net/dsa/sja1105/sja1105.h */ 5/* Included by drivers/net/dsa/sja1105/sja1105.h and net/dsa/tag_sja1105.c */
6 6
7#ifndef _NET_DSA_SJA1105_H 7#ifndef _NET_DSA_SJA1105_H
8#define _NET_DSA_SJA1105_H 8#define _NET_DSA_SJA1105_H
9 9
10#include <linux/skbuff.h>
10#include <linux/etherdevice.h> 11#include <linux/etherdevice.h>
12#include <net/dsa.h>
11 13
12#define ETH_P_SJA1105 ETH_P_DSA_8021Q 14#define ETH_P_SJA1105 ETH_P_DSA_8021Q
13 15
14/* The switch can only be convinced to stay in unmanaged mode and not trap any 16/* IEEE 802.3 Annex 57A: Slow Protocols PDUs (01:80:C2:xx:xx:xx) */
15 * link-local traffic by actually telling it to filter frames sent at the 17#define SJA1105_LINKLOCAL_FILTER_A 0x0180C2000000ull
16 * 00:00:00:00:00:00 destination MAC. 18#define SJA1105_LINKLOCAL_FILTER_A_MASK 0xFFFFFF000000ull
17 */ 19/* IEEE 1588 Annex F: Transport of PTP over Ethernet (01:1B:19:xx:xx:xx) */
18#define SJA1105_LINKLOCAL_FILTER_A 0x000000000000ull 20#define SJA1105_LINKLOCAL_FILTER_B 0x011B19000000ull
19#define SJA1105_LINKLOCAL_FILTER_A_MASK 0xFFFFFFFFFFFFull 21#define SJA1105_LINKLOCAL_FILTER_B_MASK 0xFFFFFF000000ull
20#define SJA1105_LINKLOCAL_FILTER_B 0x000000000000ull 22
21#define SJA1105_LINKLOCAL_FILTER_B_MASK 0xFFFFFFFFFFFFull 23enum sja1105_frame_type {
24 SJA1105_FRAME_TYPE_NORMAL = 0,
25 SJA1105_FRAME_TYPE_LINK_LOCAL,
26};
27
28struct sja1105_skb_cb {
29 enum sja1105_frame_type type;
30};
31
32#define SJA1105_SKB_CB(skb) \
33 ((struct sja1105_skb_cb *)DSA_SKB_CB_PRIV(skb))
34
35struct sja1105_port {
36 struct dsa_port *dp;
37 int mgmt_slot;
38};
22 39
23#endif /* _NET_DSA_SJA1105_H */ 40#endif /* _NET_DSA_SJA1105_H */
diff --git a/include/net/dsa.h b/include/net/dsa.h
index e20be1ceb306..6aaaadd6a413 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -43,6 +43,7 @@ struct phylink_link_state;
43#define DSA_TAG_PROTO_QCA_VALUE 10 43#define DSA_TAG_PROTO_QCA_VALUE 10
44#define DSA_TAG_PROTO_TRAILER_VALUE 11 44#define DSA_TAG_PROTO_TRAILER_VALUE 11
45#define DSA_TAG_PROTO_8021Q_VALUE 12 45#define DSA_TAG_PROTO_8021Q_VALUE 12
46#define DSA_TAG_PROTO_SJA1105_VALUE 13
46 47
47enum dsa_tag_protocol { 48enum dsa_tag_protocol {
48 DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE, 49 DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE,
@@ -58,6 +59,7 @@ enum dsa_tag_protocol {
58 DSA_TAG_PROTO_QCA = DSA_TAG_PROTO_QCA_VALUE, 59 DSA_TAG_PROTO_QCA = DSA_TAG_PROTO_QCA_VALUE,
59 DSA_TAG_PROTO_TRAILER = DSA_TAG_PROTO_TRAILER_VALUE, 60 DSA_TAG_PROTO_TRAILER = DSA_TAG_PROTO_TRAILER_VALUE,
60 DSA_TAG_PROTO_8021Q = DSA_TAG_PROTO_8021Q_VALUE, 61 DSA_TAG_PROTO_8021Q = DSA_TAG_PROTO_8021Q_VALUE,
62 DSA_TAG_PROTO_SJA1105 = DSA_TAG_PROTO_SJA1105_VALUE,
61}; 63};
62 64
63struct packet_type; 65struct packet_type;
diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
index fc15a7e1a6df..cf855352a440 100644
--- a/net/dsa/Kconfig
+++ b/net/dsa/Kconfig
@@ -102,6 +102,15 @@ config NET_DSA_TAG_LAN9303
102 Say Y or M if you want to enable support for tagging frames for the 102 Say Y or M if you want to enable support for tagging frames for the
103 SMSC/Microchip LAN9303 family of switches. 103 SMSC/Microchip LAN9303 family of switches.
104 104
105config NET_DSA_TAG_SJA1105
106 tristate "Tag driver for NXP SJA1105 switches"
107 select NET_DSA_TAG_8021Q
108 help
109 Say Y or M if you want to enable support for tagging frames with the
110 NXP SJA1105 switch family. Both the native tagging protocol (which
111 is only for link-local traffic) as well as non-native tagging (based
112 on a custom 802.1Q VLAN header) are available.
113
105config NET_DSA_TAG_TRAILER 114config NET_DSA_TAG_TRAILER
106 tristate "Tag driver for switches using a trailer tag" 115 tristate "Tag driver for switches using a trailer tag"
107 help 116 help
diff --git a/net/dsa/Makefile b/net/dsa/Makefile
index e97c794ec57b..c342f54715ba 100644
--- a/net/dsa/Makefile
+++ b/net/dsa/Makefile
@@ -13,4 +13,5 @@ obj-$(CONFIG_NET_DSA_TAG_KSZ_COMMON) += tag_ksz.o
13obj-$(CONFIG_NET_DSA_TAG_LAN9303) += tag_lan9303.o 13obj-$(CONFIG_NET_DSA_TAG_LAN9303) += tag_lan9303.o
14obj-$(CONFIG_NET_DSA_TAG_MTK) += tag_mtk.o 14obj-$(CONFIG_NET_DSA_TAG_MTK) += tag_mtk.o
15obj-$(CONFIG_NET_DSA_TAG_QCA) += tag_qca.o 15obj-$(CONFIG_NET_DSA_TAG_QCA) += tag_qca.o
16obj-$(CONFIG_NET_DSA_TAG_SJA1105) += tag_sja1105.o
16obj-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o 17obj-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o
diff --git a/net/dsa/tag_sja1105.c b/net/dsa/tag_sja1105.c
new file mode 100644
index 000000000000..969402c7dbf1
--- /dev/null
+++ b/net/dsa/tag_sja1105.c
@@ -0,0 +1,131 @@
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com>
3 */
4#include <linux/if_vlan.h>
5#include <linux/dsa/sja1105.h>
6#include <linux/dsa/8021q.h>
7#include <linux/packing.h>
8#include "dsa_priv.h"
9
10/* Similar to is_link_local_ether_addr(hdr->h_dest) but also covers PTP */
11static inline bool sja1105_is_link_local(const struct sk_buff *skb)
12{
13 const struct ethhdr *hdr = eth_hdr(skb);
14 u64 dmac = ether_addr_to_u64(hdr->h_dest);
15
16 if ((dmac & SJA1105_LINKLOCAL_FILTER_A_MASK) ==
17 SJA1105_LINKLOCAL_FILTER_A)
18 return true;
19 if ((dmac & SJA1105_LINKLOCAL_FILTER_B_MASK) ==
20 SJA1105_LINKLOCAL_FILTER_B)
21 return true;
22 return false;
23}
24
25/* This is the first time the tagger sees the frame on RX.
26 * Figure out if we can decode it, and if we can, annotate skb->cb with how we
27 * plan to do that, so we don't need to check again in the rcv function.
28 */
29static bool sja1105_filter(const struct sk_buff *skb, struct net_device *dev)
30{
31 if (sja1105_is_link_local(skb)) {
32 SJA1105_SKB_CB(skb)->type = SJA1105_FRAME_TYPE_LINK_LOCAL;
33 return true;
34 }
35 if (!dsa_port_is_vlan_filtering(dev->dsa_ptr)) {
36 SJA1105_SKB_CB(skb)->type = SJA1105_FRAME_TYPE_NORMAL;
37 return true;
38 }
39 return false;
40}
41
42static struct sk_buff *sja1105_xmit(struct sk_buff *skb,
43 struct net_device *netdev)
44{
45 struct dsa_port *dp = dsa_slave_to_port(netdev);
46 struct dsa_switch *ds = dp->ds;
47 u16 tx_vid = dsa_8021q_tx_vid(ds, dp->index);
48 u8 pcp = skb->priority;
49
50 /* Transmitting management traffic does not rely upon switch tagging,
51 * but instead SPI-installed management routes. Part 2 of this
52 * is the .port_deferred_xmit driver callback.
53 */
54 if (unlikely(sja1105_is_link_local(skb)))
55 return dsa_defer_xmit(skb, netdev);
56
57 /* If we are under a vlan_filtering bridge, IP termination on
58 * switch ports based on 802.1Q tags is simply too brittle to
59 * be passable. So just defer to the dsa_slave_notag_xmit
60 * implementation.
61 */
62 if (dsa_port_is_vlan_filtering(dp))
63 return skb;
64
65 return dsa_8021q_xmit(skb, netdev, ETH_P_SJA1105,
66 ((pcp << VLAN_PRIO_SHIFT) | tx_vid));
67}
68
69static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
70 struct net_device *netdev,
71 struct packet_type *pt)
72{
73 struct ethhdr *hdr = eth_hdr(skb);
74 u64 source_port, switch_id;
75 struct sk_buff *nskb;
76 u16 tpid, vid, tci;
77 bool is_tagged;
78
79 nskb = dsa_8021q_rcv(skb, netdev, pt, &tpid, &tci);
80 is_tagged = (nskb && tpid == ETH_P_SJA1105);
81
82 skb->priority = (tci & VLAN_PRIO_MASK) >> VLAN_PRIO_SHIFT;
83 vid = tci & VLAN_VID_MASK;
84
85 skb->offload_fwd_mark = 1;
86
87 if (SJA1105_SKB_CB(skb)->type == SJA1105_FRAME_TYPE_LINK_LOCAL) {
88 /* Management traffic path. Switch embeds the switch ID and
89 * port ID into bytes of the destination MAC, courtesy of
90 * the incl_srcpt options.
91 */
92 source_port = hdr->h_dest[3];
93 switch_id = hdr->h_dest[4];
94 /* Clear the DMAC bytes that were mangled by the switch */
95 hdr->h_dest[3] = 0;
96 hdr->h_dest[4] = 0;
97 } else {
98 /* Normal traffic path. */
99 source_port = dsa_8021q_rx_source_port(vid);
100 switch_id = dsa_8021q_rx_switch_id(vid);
101 }
102
103 skb->dev = dsa_master_find_slave(netdev, switch_id, source_port);
104 if (!skb->dev) {
105 netdev_warn(netdev, "Couldn't decode source port\n");
106 return NULL;
107 }
108
109 /* Delete/overwrite fake VLAN header, DSA expects to not find
110 * it there, see dsa_switch_rcv: skb_push(skb, ETH_HLEN).
111 */
112 if (is_tagged)
113 memmove(skb->data - ETH_HLEN, skb->data - ETH_HLEN - VLAN_HLEN,
114 ETH_HLEN - VLAN_HLEN);
115
116 return skb;
117}
118
119static struct dsa_device_ops sja1105_netdev_ops = {
120 .name = "sja1105",
121 .proto = DSA_TAG_PROTO_SJA1105,
122 .xmit = sja1105_xmit,
123 .rcv = sja1105_rcv,
124 .filter = sja1105_filter,
125 .overhead = VLAN_HLEN,
126};
127
128MODULE_LICENSE("GPL v2");
129MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_SJA1105);
130
131module_dsa_tag_driver(sja1105_netdev_ops);