blob: 03f8057fa18d08a6373a33158abae1cad65c42d7 [file] [log] [blame]
developerfd40db22021-04-29 10:08:25 +08001Index: linux-5.4.77/drivers/net/ethernet/mediatek/mtk_eth_soc.c
2===================================================================
3--- linux-5.4.77.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.c
4+++ linux-5.4.77/drivers/net/ethernet/mediatek/mtk_eth_soc.c
5@@ -1354,9 +1354,21 @@ static int mtk_poll_rx(struct napi_struc
6 skb_set_hash(skb, hash, PKT_HASH_TYPE_L4);
7
8 if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX &&
9- (trxd.rxd2 & RX_DMA_VTAG))
10- __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
11- RX_DMA_VID(trxd.rxd3));
12+ (trxd.rxd2 & RX_DMA_VTAG)) {
13+ __vlan_hwaccel_put_tag(skb,
14+ htons(RX_DMA_VPID(trxd.rxd3)),
15+ RX_DMA_TCI(trxd.rxd3));
16+
17+ /* If netdev is attached to dsa switch, the special
18+ * tag inserted in VLAN field by switch hardware can
19+ * be offload by RX HW VLAN offload. Clears the VLAN
20+ * information from @skb to avoid unexpected 8021d
21+ * handler before packet enter dsa framework.
22+ */
23+ if (netdev_uses_dsa(netdev))
24+ __vlan_hwaccel_clear_tag(skb);
25+ }
26+
27 if (mtk_offload_check_rx(eth, skb, trxd.rxd4) == 0) {
28 skb_record_rx_queue(skb, 0);
29 napi_gro_receive(napi, skb);
30@@ -2050,19 +2062,32 @@ static netdev_features_t mtk_fix_feature
31 }
32 }
33
34+ if ((features & NETIF_F_HW_VLAN_CTAG_TX) && netdev_uses_dsa(dev)) {
35+ netdev_info(dev, "TX vlan offload cannot be enabled when dsa is attached.\n");
36+
37+ features &= ~NETIF_F_HW_VLAN_CTAG_TX;
38+ }
39+
40 return features;
41 }
42
43 static int mtk_set_features(struct net_device *dev, netdev_features_t features)
44 {
45+ struct mtk_mac *mac = netdev_priv(dev);
46+ struct mtk_eth *eth = mac->hw;
47 int err = 0;
48
49- if (!((dev->features ^ features) & NETIF_F_LRO))
50+ if (!((dev->features ^ features) & MTK_SET_FEATURES))
51 return 0;
52
53 if (!(features & NETIF_F_LRO))
54 mtk_hwlro_netdev_disable(dev);
55
56+ if (!(features & NETIF_F_HW_VLAN_CTAG_RX))
57+ mtk_w32(eth, 0, MTK_CDMP_EG_CTRL);
58+ else
59+ mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
60+
61 return err;
62 }
63
64@@ -2326,6 +2351,15 @@ static int mtk_open(struct net_device *d
65
66 mtk_gdm_config(eth, gdm_config);
67
68+ /* Indicates CDM to parse the MTK special tag from CPU */
69+ if (netdev_uses_dsa(dev)) {
70+ u32 val;
71+ val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
72+ mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
73+ val = mtk_r32(eth, MTK_CDMP_IG_CTRL);
74+ mtk_w32(eth, val | MTK_CDMP_STAG_EN, MTK_CDMP_IG_CTRL);
75+ }
76+
77 napi_enable(&eth->tx_napi);
78 napi_enable(&eth->rx_napi);
79 mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
80@@ -2500,7 +2534,7 @@ static void mtk_dim_tx(struct work_struc
81
82 static int mtk_hw_init(struct mtk_eth *eth)
83 {
84- int i, val, ret;
85+ int i, ret;
86
87 if (test_and_set_bit(MTK_HW_INIT, &eth->state))
88 return 0;
89@@ -2555,12 +2589,6 @@ static int mtk_hw_init(struct mtk_eth *e
90 for (i = 0; i < MTK_MAC_COUNT; i++)
91 mtk_w32(eth, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(i));
92
93- /* Indicates CDM to parse the MTK special tag from CPU
94- * which also is working out for untag packets.
95- */
96- val = mtk_r32(eth, MTK_CDMQ_IG_CTRL);
97- mtk_w32(eth, val | MTK_CDMQ_STAG_EN, MTK_CDMQ_IG_CTRL);
98-
99 /* Enable RX VLan Offloading */
100 mtk_w32(eth, 1, MTK_CDMP_EG_CTRL);
101
102Index: linux-5.4.77/drivers/net/ethernet/mediatek/mtk_eth_soc.h
103===================================================================
104--- linux-5.4.77.orig/drivers/net/ethernet/mediatek/mtk_eth_soc.h
105+++ linux-5.4.77/drivers/net/ethernet/mediatek/mtk_eth_soc.h
106@@ -42,6 +42,8 @@
107 NETIF_F_SG | NETIF_F_TSO | \
108 NETIF_F_TSO6 | \
109 NETIF_F_IPV6_CSUM)
110+#define MTK_SET_FEATURES (NETIF_F_LRO | \
111+ NETIF_F_HW_VLAN_CTAG_RX)
112 #define MTK_HW_FEATURES_MT7628 (NETIF_F_SG | NETIF_F_RXCSUM)
113 #define NEXT_DESP_IDX(X, Y) (((X) + 1) & ((Y) - 1))
114
115@@ -78,6 +80,10 @@
116 #define MTK_CDMQ_IG_CTRL 0x1400
117 #define MTK_CDMQ_STAG_EN BIT(0)
118
119+/* CDMP Ingress Control Register */
120+#define MTK_CDMP_IG_CTRL 0x400
121+#define MTK_CDMP_STAG_EN BIT(0)
122+
123 /* CDMP Exgress Control Register */
124 #define MTK_CDMP_EG_CTRL 0x404
125
126@@ -307,7 +313,9 @@
127 #define RX_DMA_VTAG BIT(15)
128
129 /* QDMA descriptor rxd3 */
130-#define RX_DMA_VID(_x) ((_x) & 0xfff)
131+#define RX_DMA_VID(_x) ((_x) & VLAN_VID_MASK)
132+#define RX_DMA_TCI(_x) ((_x) & (VLAN_PRIO_MASK | VLAN_VID_MASK))
133+#define RX_DMA_VPID(_x) (((_x) >> 16) & 0xffff)
134
135 /* QDMA descriptor rxd4 */
136 #define MTK_RXD4_FOE_ENTRY GENMASK(13, 0)
137Index: linux-5.4.77/net/dsa/tag_mtk.c
138===================================================================
139--- linux-5.4.77.orig/net/dsa/tag_mtk.c
140+++ linux-5.4.77/net/dsa/tag_mtk.c
141@@ -73,22 +73,28 @@ static struct sk_buff *mtk_tag_rcv(struc
142 bool is_multicast_skb = is_multicast_ether_addr(dest) &&
143 !is_broadcast_ether_addr(dest);
144
145- if (unlikely(!pskb_may_pull(skb, MTK_HDR_LEN)))
146- return NULL;
147+ if (dev->features & NETIF_F_HW_VLAN_CTAG_RX) {
148+ hdr = ntohs(skb->vlan_proto);
149+ skb->vlan_proto = 0;
150+ skb->vlan_tci = 0;
151+ } else {
152+ if (unlikely(!pskb_may_pull(skb, MTK_HDR_LEN)))
153+ return NULL;
154
155- /* The MTK header is added by the switch between src addr
156- * and ethertype at this point, skb->data points to 2 bytes
157- * after src addr so header should be 2 bytes right before.
158- */
159- phdr = (__be16 *)(skb->data - 2);
160- hdr = ntohs(*phdr);
161+ /* The MTK header is added by the switch between src addr
162+ * and ethertype at this point, skb->data points to 2 bytes
163+ * after src addr so header should be 2 bytes right before.
164+ */
165+ phdr = (__be16 *)(skb->data - 2);
166+ hdr = ntohs(*phdr);
167
168- /* Remove MTK tag and recalculate checksum. */
169- skb_pull_rcsum(skb, MTK_HDR_LEN);
170+ /* Remove MTK tag and recalculate checksum. */
171+ skb_pull_rcsum(skb, MTK_HDR_LEN);
172
173- memmove(skb->data - ETH_HLEN,
174- skb->data - ETH_HLEN - MTK_HDR_LEN,
175- 2 * ETH_ALEN);
176+ memmove(skb->data - ETH_HLEN,
177+ skb->data - ETH_HLEN - MTK_HDR_LEN,
178+ 2 * ETH_ALEN);
179+ }
180
181 /* Get source port information */
182 port = (hdr & MTK_HDR_RECV_SOURCE_PORT_MASK);