History

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.

Vladimir Oltean committed 7 years ago

Commit 227d07a1 parent c362beb8 files · +308 −15Browse files

Unified · Split

8 files
  1. drivers/net/dsa/sja1105/Kconfig +1 −0
  2. drivers/net/dsa/sja1105/sja1105.h +6 −0
  3. drivers/net/dsa/sja1105/sja1105_main.c +132 −6
  4. include/linux/dsa/sja1105.h +26 −9
  5. include/net/dsa.h +2 −0
  6. net/dsa/Kconfig +9 −0
  7. net/dsa/Makefile +1 −0
  8. net/dsa/tag_sja1105.c +131 −0
drivers/net/dsa/sja1105/Kconfig+1−0
@@ -1,6 +1,7 @@
1config NET_DSA_SJA11051config NET_DSA_SJA1105
2tristate "NXP SJA1105 Ethernet switch family support"2tristate "NXP SJA1105 Ethernet switch family support"
3 depends on NET_DSA && SPI3 depends on NET_DSA && SPI
4 select NET_DSA_TAG_SJA1105
4 select PACKING5 select PACKING
5 select CRC326 select CRC32
6 help7 help
drivers/net/dsa/sja1105/sja1105.h+6−0
@@ -7,6 +7,7 @@ · 6 unmodified lines
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 513#define SJA1105_NUM_PORTS 5
@@ -65,6 +66,11 @@ struct sja1105_private { · 52 unmodified lines
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"
drivers/net/dsa/sja1105/sja1105_main.c+132−6
@@ -20,6 +20,7 @@ · 19 unmodified lines
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) · 380 unmodified lines
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, · 729 unmodified lines
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_protocol1170static 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) · 17 unmodified lines
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) · 96 unmodified lines
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 = { · 41 unmodified lines
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) · 37 unmodified lines
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) · 44 unmodified lines
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
include/linux/dsa/sja1105.h+26−9
@@ -2,22 +2,39 @@ · 1 unmodified line
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_H7#ifndef _NET_DSA_SJA1105_H
8#define _NET_DSA_SJA1105_H8#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_8021Q14#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 any16/* 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 the17#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 0x000000000000ull20#define SJA1105_LINKLOCAL_FILTER_B 0x011B19000000ull
19#define SJA1105_LINKLOCAL_FILTER_A_MASK 0xFFFFFFFFFFFFull21#define SJA1105_LINKLOCAL_FILTER_B_MASK 0xFFFFFF000000ull
20#define SJA1105_LINKLOCAL_FILTER_B 0x000000000000ull22
21#define SJA1105_LINKLOCAL_FILTER_B_MASK 0xFFFFFFFFFFFFull23enum 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 */
include/net/dsa.h+2−0
@@ -43,6 +43,7 @@ struct phylink_link_state; · 42 unmodified lines
43#define DSA_TAG_PROTO_QCA_VALUE 1043#define DSA_TAG_PROTO_QCA_VALUE 10
44#define DSA_TAG_PROTO_TRAILER_VALUE 1144#define DSA_TAG_PROTO_TRAILER_VALUE 11
45#define DSA_TAG_PROTO_8021Q_VALUE 1245#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 { · 9 unmodified lines
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;
net/dsa/Kconfig+9−0
@@ -102,6 +102,15 @@ config NET_DSA_TAG_LAN9303 · 101 unmodified lines
102 Say Y or M if you want to enable support for tagging frames for the102 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_TRAILER114config 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 help116 help
net/dsa/Makefile+1−0
@@ -13,4 +13,5 @@ obj-$(CONFIG_NET_DSA_TAG_KSZ_COMMON) += tag_ksz.o · 12 unmodified lines
13obj-$(CONFIG_NET_DSA_TAG_LAN9303) += tag_lan9303.o13obj-$(CONFIG_NET_DSA_TAG_LAN9303) += tag_lan9303.o
14obj-$(CONFIG_NET_DSA_TAG_MTK) += tag_mtk.o14obj-$(CONFIG_NET_DSA_TAG_MTK) += tag_mtk.o
15obj-$(CONFIG_NET_DSA_TAG_QCA) += tag_qca.o15obj-$(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.o17obj-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o
net/dsa/tag_sja1105.c+131−0
@@ -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);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t