ipq40xx: fix ethernet vlan double tagging
[openwrt/openwrt.git] / target / linux / ipq40xx / patches-4.14 / 716-essedma-vlan-double-tag.patch
1 From: Sven Eckelmann <sven@narfation.org>
2 Date: Wed, 8 Feb 2017 16:26:00 +0100
3 Subject: [PATCH] ipq40xx: Fix ar40xx port separation
4
5 It is currently not possible to submit (or receive) VLAN tagged frames over
6 the ar40xx PHY switch and the edma ethernet device.
7
8 This can be worked around by disabling enable_vlan. The separation of the
9 eth0 and eth1 ports is then done by the vlan_tag information from the
10 device tree. But the ar40xx PHY switch then also has to parse the word3
11 port bitmap (word3) from the TDP when data was received from the CPU port
12 (0).
13
14 IssueID: #2857
15
16 Forwarded: no
17 The ar40xx.c change was forwarded to Xiaofei Shen <xiaofeis@codeaurora.org>
18 (QCA). But John Crispin will rewrite the driver anyway and we have to check
19 later if this change is required in his driver too.
20 ---
21 drivers/net/phy/ar40xx.c | 6 +++++-
22 1 file changed, 5 insertions(+), 1 deletion(-)
23
24 diff --git a/drivers/net/phy/ar40xx.c b/drivers/net/phy/ar40xx.c
25 index e408e8f7312f749aeb29c73a589047856e9479c7..421399b9b33e6f42d4e38db3f90b0c1d514a0b79 100644
26 --- a/drivers/net/phy/ar40xx.c
27 +++ b/drivers/net/phy/ar40xx.c
28 @@ -1200,7 +1200,11 @@ ar40xx_init_port(struct ar40xx_priv *priv, int port)
29 ar40xx_rmw(priv, AR40XX_REG_PORT_STATUS(port),
30 AR40XX_PORT_AUTO_LINK_EN, 0);
31
32 - ar40xx_write(priv, AR40XX_REG_PORT_HEADER(port), 0);
33 + /* CPU port is setting headers to limit output ports */
34 + if (port == 0)
35 + ar40xx_write(priv, AR40XX_REG_PORT_HEADER(port), 0x8);
36 + else
37 + ar40xx_write(priv, AR40XX_REG_PORT_HEADER(port), 0);
38
39 ar40xx_write(priv, AR40XX_REG_PORT_VLAN0(port), 0);
40
41 From: Sven Eckelmann <sven@narfation.org>
42 Date: Fri, 17 Mar 2017 11:00:40 +0100
43 Subject: [PATCH] ipq40xx: Disable CTAG TX VLAN offloading
44
45 The driver requires the offloading to set the VLAN specific header for the
46 port selection. It can therefore not be used at the same time to offload
47 the setting of the VLAN header on top of essedma interface.
48
49 Forwarded: no
50 ---
51 drivers/net/ethernet/qualcomm/essedma/edma_axi.c | 1 -
52 1 file changed, 1 deletion(-)
53
54 diff --git a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
55 index 81fc1e1b64daa41b15f21634ac1f08de0f5822a7..db184b82769f53e1554a1c51c53414ef7cadd7f6 100644
56 --- a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
57 +++ b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
58 @@ -970,7 +970,6 @@ static int edma_axi_probe(struct platform_device *pdev)
59 edma_netdev[i]->netdev_ops = &edma_axi_netdev_ops;
60 edma_netdev[i]->max_mtu = 9000;
61 edma_netdev[i]->features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM
62 - | NETIF_F_HW_VLAN_CTAG_TX
63 | NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_SG |
64 NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_GRO;
65 edma_netdev[i]->hw_features = NETIF_F_HW_CSUM | NETIF_F_RXCSUM |
66 From: Sven Eckelmann <sven@narfation.org>
67 Date: Fri, 17 Mar 2017 11:04:50 +0100
68 Subject: [PATCH] ar40xx: Enable QinQ on the switch
69
70 The switch used in by IPQ40xx is using VLANs by default to select the
71 outgoing port. It was therefore not possible to sent or receive 802.1q
72 tagged frames over the CPU port. This can be allowed by changing the port
73 configuration and lookup configuration.
74
75 The resulting VLAN-tagged frames send or received by the CPU will therefore
76 look like QinQ frames. The outer VLAN tag is the port-VLAN of the port from
77 which the data was received or towards which the data has to be sent. The
78 inner VLAN tag (when it exists) is the VLAN which was configrued on top of
79 the ethernet device.
80
81 Forwarded: no
82 ---
83 drivers/net/phy/ar40xx.c | 23 ++++++++++++++++++++---
84 drivers/net/phy/ar40xx.h | 5 +++++
85 2 files changed, 25 insertions(+), 3 deletions(-)
86
87 diff --git a/drivers/net/phy/ar40xx.c b/drivers/net/phy/ar40xx.c
88 index 421399b9b33e6f42d4e38db3f90b0c1d514a0b79..4af26638d542a9ab5ca27454ce557233bcb64575 100644
89 --- a/drivers/net/phy/ar40xx.c
90 +++ b/drivers/net/phy/ar40xx.c
91 @@ -1247,6 +1247,10 @@ ar40xx_init_globals(struct ar40xx_priv *priv)
92 t = (AR40XX_PORT0_FC_THRESH_ON_DFLT << 16) |
93 AR40XX_PORT0_FC_THRESH_OFF_DFLT;
94 ar40xx_write(priv, AR40XX_REG_PORT_FLOWCTRL_THRESH(0), t);
95 +
96 + /* set service tag to 802.1q */
97 + t = ETH_P_8021Q | AR40XX_ESS_SERVICE_TAG_STAG;
98 + ar40xx_write(priv, AR40XX_ESS_SERVICE_TAG, t);
99 }
100
101 static void
102 @@ -1572,7 +1576,11 @@ ar40xx_setup_port(struct ar40xx_priv *priv, int port, u32 members)
103 u32 pvid = priv->vlan_id[priv->pvid[port]];
104
105 if (priv->vlan) {
106 - egress = AR40XX_PORT_VLAN1_OUT_MODE_UNMOD;
107 + if (priv->vlan_tagged & BIT(port))
108 + egress = AR40XX_PORT_VLAN1_OUT_MODE_TAG;
109 + else
110 + egress = AR40XX_PORT_VLAN1_OUT_MODE_UNMOD;
111 +
112 ingress = AR40XX_IN_SECURE;
113 } else {
114 egress = AR40XX_PORT_VLAN1_OUT_MODE_UNTOUCH;
115 @@ -1583,8 +1591,17 @@ ar40xx_setup_port(struct ar40xx_priv *priv, int port, u32 members)
116 t |= pvid << AR40XX_PORT_VLAN0_DEF_CVID_S;
117 ar40xx_write(priv, AR40XX_REG_PORT_VLAN0(port), t);
118
119 - t = AR40XX_PORT_VLAN1_PORT_VLAN_PROP;
120 - t |= egress << AR40XX_PORT_VLAN1_OUT_MODE_S;
121 + t = egress << AR40XX_PORT_VLAN1_OUT_MODE_S;
122 +
123 + /* set CPU port to core port */
124 + if (port == 0)
125 + t |= AR40XX_PORT_VLAN1_CORE_PORT;
126 +
127 + if (priv->vlan_tagged & BIT(port))
128 + t |= AR40XX_PORT_VLAN1_PORT_VLAN_PROP;
129 + else
130 + t |= AR40XX_PORT_VLAN1_PORT_TLS_MODE;
131 +
132 ar40xx_write(priv, AR40XX_REG_PORT_VLAN1(port), t);
133
134 t = members;
135 diff --git a/drivers/net/phy/ar40xx.h b/drivers/net/phy/ar40xx.h
136 index 722bf6ae4b32fcefa33e007ae34a3202315a3fe1..7ba40ccf753fe833e6a01b32cfe1407a317d92ee 100644
137 --- a/drivers/net/phy/ar40xx.h
138 +++ b/drivers/net/phy/ar40xx.h
139 @@ -151,6 +151,9 @@ struct ar40xx_mib_desc {
140 #define AR40XX_MIB_FUNC_NO_OP 0x0
141 #define AR40XX_MIB_FUNC_FLUSH 0x1
142
143 +#define AR40XX_ESS_SERVICE_TAG 0x48
144 +#define AR40XX_ESS_SERVICE_TAG_STAG BIT(17)
145 +
146 #define AR40XX_REG_PORT_STATUS(_i) (0x07c + (_i) * 4)
147 #define AR40XX_PORT_SPEED BITS(0, 2)
148 #define AR40XX_PORT_STATUS_SPEED_S 0
149 @@ -179,6 +182,8 @@ struct ar40xx_mib_desc {
150 #define AR40XX_PORT_VLAN0_DEF_CVID_S 16
151
152 #define AR40XX_REG_PORT_VLAN1(_i) (0x424 + (_i) * 0x8)
153 +#define AR40XX_PORT_VLAN1_CORE_PORT BIT(9)
154 +#define AR40XX_PORT_VLAN1_PORT_TLS_MODE BIT(7)
155 #define AR40XX_PORT_VLAN1_PORT_VLAN_PROP BIT(6)
156 #define AR40XX_PORT_VLAN1_OUT_MODE BITS(12, 2)
157 #define AR40XX_PORT_VLAN1_OUT_MODE_S 12
158 From: Sven Eckelmann <sven@narfation.org>
159 Date: Wed, 29 Mar 2017 16:05:26 +0200
160 Subject: [PATCH] ipq40xx: Disable NETIF_F_RXHASH support in essedma
161
162 The NETIF_F_RXHASH requires that each skb set the hash correctly with
163 skb_set_hash. essedma tries to do that but the set hash always results in
164 only used CPU when RPS is allowed for all CPUs.
165
166 Disabling RXHASH works around this problem for now.
167
168 IssueID: #5477
169 Forwarded: no
170 Upstream author was informed via e-mail about the problem
171 ---
172 drivers/net/ethernet/qualcomm/essedma/edma_axi.c | 8 ++++----
173 1 file changed, 4 insertions(+), 4 deletions(-)
174
175 diff --git a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
176 index db184b82769f53e1554a1c51c53414ef7cadd7f6..975e119cfe6f1a8cfe54ac0eb8f8752aa4bf22af 100644
177 --- a/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
178 +++ b/drivers/net/ethernet/qualcomm/essedma/edma_axi.c
179 @@ -984,10 +984,10 @@ static int edma_axi_probe(struct platform_device *pdev)
180 NETIF_F_GRO;
181
182 #ifdef CONFIG_RFS_ACCEL
183 - edma_netdev[i]->features |= NETIF_F_RXHASH | NETIF_F_NTUPLE;
184 - edma_netdev[i]->hw_features |= NETIF_F_RXHASH | NETIF_F_NTUPLE;
185 - edma_netdev[i]->vlan_features |= NETIF_F_RXHASH | NETIF_F_NTUPLE;
186 - edma_netdev[i]->wanted_features |= NETIF_F_RXHASH | NETIF_F_NTUPLE;
187 + edma_netdev[i]->features |= NETIF_F_NTUPLE;
188 + edma_netdev[i]->hw_features |= NETIF_F_NTUPLE;
189 + edma_netdev[i]->vlan_features |= NETIF_F_NTUPLE;
190 + edma_netdev[i]->wanted_features |= NETIF_F_NTUPLE;
191 #endif
192 edma_set_ethtool_ops(edma_netdev[i]);
193