2020 *
2121 */
2222
23- #ifndef LINUX_VERSION_CODE
24- #include <linux/version.h>
25- #else
26- #define KERNEL_VERSION (a , b , c ) (((a) << 16) + ((b) << 8) + (c))
27- #endif
28-
2923#include <linux/dsa/8021q.h>
30- #if (LINUX_VERSION_CODE > KERNEL_VERSION (6 , 1 , 0 ))
3124#include "tag_8021q.h"
32- #endif
33- #include <net/dsa.h>
34-
35- #if (LINUX_VERSION_CODE < KERNEL_VERSION (6 , 2 , 0 ))
36- #include "dsa_priv.h"
37- #else
3825#include "tag.h"
39- #endif
4026
4127
4228#define MXL862_NAME "mxl862xx"
5339
5440/* special tag in TX path header */
5541
56- #if (LINUX_VERSION_CODE < KERNEL_VERSION (5 , 14 , 0 ))
57- static void dsa_8021q_rcv (struct sk_buff * skb , int * source_port , int * switch_id )
58- {
59- u16 vid , tci ;
60-
61- skb_push_rcsum (skb , ETH_HLEN );
62- if (skb_vlan_tag_present (skb )) {
63- tci = skb_vlan_tag_get (skb );
64- __vlan_hwaccel_clear_tag (skb );
65- } else {
66- __skb_vlan_pop (skb , & tci );
67- }
68- skb_pull_rcsum (skb , ETH_HLEN );
69-
70- vid = tci & VLAN_VID_MASK ;
71-
72- * source_port = dsa_8021q_rx_source_port (vid );
73- * switch_id = dsa_8021q_rx_switch_id (vid );
74- skb -> priority = (tci & VLAN_PRIO_MASK ) >> VLAN_PRIO_SHIFT ;
75- }
76-
77- /* If the ingress port offloads the bridge, we mark the frame as autonomously
78- * forwarded by hardware, so the software bridge doesn't forward in twice, back
79- * to us, because we already did. However, if we're in fallback mode and we do
80- * software bridging, we are not offloading it, therefore the dp->bridge_dev
81- * pointer is not populated, and flooding needs to be done by software (we are
82- * effectively operating in standalone ports mode).
83- */
84- static inline void dsa_default_offload_fwd_mark (struct sk_buff * skb )
85- {
86- struct dsa_port * dp = dsa_slave_to_port (skb -> dev );
87-
88- skb -> offload_fwd_mark = !!(dp -> bridge_dev );
89- }
90- #endif
91-
9242static struct sk_buff * mxl862_8021q_tag_xmit (struct sk_buff * skb ,
9343 struct net_device * dev )
9444{
95- #if (LINUX_VERSION_CODE < KERNEL_VERSION (6 , 7 , 0 ))
96- struct dsa_port * dp = dsa_slave_to_port (dev );
97- #else
9845 struct dsa_port * dp = dsa_user_to_port (dev );
99- #endif
10046
101- #if (LINUX_VERSION_CODE < KERNEL_VERSION (5 , 16 , 0 ))
102- u16 tx_vid = dsa_8021q_tx_vid (dp -> ds , dp -> index );
103- #elif (LINUX_VERSION_CODE < KERNEL_VERSION (5 , 18 , 0 ))
104- u16 tx_vid = dsa_tag_8021q_tx_vid (dp );
105- #else
10647 u16 tx_vid = dsa_tag_8021q_standalone_vid (dp );
107- #endif
10848 u16 queue_mapping = skb_get_queue_mapping (skb );
10949 u8 pcp = netdev_txq_to_tc (dev , queue_mapping );
11050
@@ -114,36 +54,20 @@ static struct sk_buff *mxl862_8021q_tag_xmit(struct sk_buff *skb,
11454 return skb ;
11555}
11656
117- #if (LINUX_VERSION_CODE < KERNEL_VERSION (5 , 15 , 0 ))
118- static struct sk_buff * mxl862_8021q_tag_rcv (struct sk_buff * skb ,
119- struct net_device * dev ,
120- struct packet_type * pt )
121- #else
12257static struct sk_buff * mxl862_8021q_tag_rcv (struct sk_buff * skb ,
12358 struct net_device * dev )
124- #endif
12559{
12660 int src_port = -1 ;
12761 int switch_id = -1 ;
12862
12963 /* removes Outer VLAN tag */
130- #if (LINUX_VERSION_CODE < KERNEL_VERSION (5 , 18 , 0 ))
131- dsa_8021q_rcv (skb , & src_port , & switch_id );
132- #elif (LINUX_VERSION_CODE < KERNEL_VERSION (6 , 11 , 0 ))
133- dsa_8021q_rcv (skb , & src_port , & switch_id , NULL );
134- #else
13564 dsa_8021q_rcv (skb , & src_port , & switch_id , NULL , NULL );
136- #endif
13765 if (src_port == -1 || switch_id == -1 ) {
13866 dev_warn_ratelimited (& dev -> dev , "Dropping packet due to invalid outer 802.1Q tag: switch %d port %d\n" , switch_id , src_port );
13967 return NULL ;
14068 }
14169
142- #if (LINUX_VERSION_CODE < KERNEL_VERSION (6 , 7 , 0 ))
143- skb -> dev = dsa_master_find_slave (dev , switch_id , src_port );
144- #else
14570 skb -> dev = dsa_conduit_find_user (dev , switch_id , src_port );
146- #endif
14771 if (!skb -> dev ) {
14872 dev_warn_ratelimited (& dev -> dev , "Dropping packet due to invalid source port: %d\n" , src_port );
14973 return NULL ;
@@ -159,25 +83,10 @@ static const struct dsa_device_ops mxl862_8021q_netdev_ops = {
15983 .proto = DSA_TAG_PROTO_MXL862_8021Q ,
16084 .xmit = mxl862_8021q_tag_xmit ,
16185 .rcv = mxl862_8021q_tag_rcv ,
162- #if (LINUX_VERSION_CODE < KERNEL_VERSION (5 , 14 , 0 ))
163- .overhead = VLAN_HLEN ,
164- #else
16586 .needed_headroom = VLAN_HLEN ,
166- #endif
167- #if (LINUX_VERSION_CODE < KERNEL_VERSION (6 , 7 , 0 ) && \
168- LINUX_VERSION_CODE > KERNEL_VERSION (5 , 10 , 0 ))
169- .promisc_on_master = true,
170- #elif (LINUX_VERSION_CODE > KERNEL_VERSION (6 , 7 , 0 ))
17187 .promisc_on_conduit = true,
172- #endif
17388};
17489
175-
17690MODULE_LICENSE ("GPL" );
177- #if (LINUX_VERSION_CODE < KERNEL_VERSION (6 , 2 , 0 ))
178- MODULE_ALIAS_DSA_TAG_DRIVER (DSA_TAG_PROTO_MXL862_8021Q );
179- #else
18091MODULE_ALIAS_DSA_TAG_DRIVER (DSA_TAG_PROTO_MXL862_8021Q , MXL862_NAME );
181- #endif
182-
18392module_dsa_tag_driver (mxl862_8021q_netdev_ops );
0 commit comments