Fresh pull from upstream
[librecmc/librecmc.git] / target / linux / ramips / patches-4.4 / 0513-net-mediatek-add-swconfig-driver-for-gsw_mt762x.patch
1 From cf5a08f1f16913da8bb24a96afaa2969b29d0827 Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Mon, 14 Dec 2015 22:25:57 +0100
4 Subject: [PATCH 513/513] net: mediatek: add swconfig driver for gsw_mt762x
5
6 Signed-off-by: John Crispin <blogic@openwrt.org>
7 ---
8  drivers/net/ethernet/mediatek/Makefile      |   4 +-
9  drivers/net/ethernet/mediatek/gsw_mt7620.c  |   3 +
10  drivers/net/ethernet/mediatek/gsw_mt7620.h  |   3 +
11  drivers/net/ethernet/mediatek/mt7530.c      | 884 ++++++++++++++++++++++++++++
12  drivers/net/ethernet/mediatek/mt7530.h      | 186 ++++++
13  drivers/net/ethernet/mediatek/mtk_eth_soc.c |   9 +-
14  drivers/net/ethernet/mediatek/mtk_eth_soc.h |   1 +
15  drivers/net/ethernet/mediatek/soc_mt7620.c  |   1 +
16  8 files changed, 1087 insertions(+), 4 deletions(-)
17  create mode 100644 drivers/net/ethernet/mediatek/mt7530.c
18  create mode 100644 drivers/net/ethernet/mediatek/mt7530.h
19
20 --- a/drivers/net/ethernet/mediatek/Makefile
21 +++ b/drivers/net/ethernet/mediatek/Makefile
22 @@ -15,6 +15,6 @@ mtk-eth-soc-$(CONFIG_NET_MEDIATEK_MT7620
23  mtk-eth-soc-$(CONFIG_NET_MEDIATEK_MT7621)      += soc_mt7621.o
24  
25  obj-$(CONFIG_NET_MEDIATEK_ESW_RT3050)          += esw_rt3050.o
26 -obj-$(CONFIG_NET_MEDIATEK_GSW_MT7620)          += gsw_mt7620.o
27 -obj-$(CONFIG_NET_MEDIATEK_GSW_MT7621)          += gsw_mt7621.o
28 +obj-$(CONFIG_NET_MEDIATEK_GSW_MT7620)          += gsw_mt7620.o mt7530.o
29 +obj-$(CONFIG_NET_MEDIATEK_GSW_MT7621)          += gsw_mt7621.o mt7530.o
30  obj-$(CONFIG_NET_MEDIATEK_SOC)                 += mtk-eth-soc.o
31 --- a/drivers/net/ethernet/mediatek/gsw_mt7620.c
32 +++ b/drivers/net/ethernet/mediatek/gsw_mt7620.c
33 @@ -67,6 +67,9 @@ static void mt7620_hw_init(struct mt7620
34         rt_sysc_w32(rt_sysc_r32(SYSC_REG_CFG1) | BIT(8), SYSC_REG_CFG1);
35         mtk_switch_w32(gsw, mtk_switch_r32(gsw, GSW_REG_CKGCR) & ~(0x3 << 4), GSW_REG_CKGCR);
36  
37 +       /* Enable MIB stats */
38 +       mtk_switch_w32(gsw, mtk_switch_r32(gsw, GSW_REG_MIB_CNT_EN) | (1 << 1), GSW_REG_MIB_CNT_EN);
39 +
40         if (of_property_read_bool(np, "mediatek,mt7530")) {
41                 u32 val;
42  
43 --- a/drivers/net/ethernet/mediatek/gsw_mt7620.h
44 +++ b/drivers/net/ethernet/mediatek/gsw_mt7620.h
45 @@ -35,6 +35,8 @@
46  #define GSW_MDIO_ADDR_SHIFT    20
47  #define GSW_MDIO_REG_SHIFT     25
48  
49 +#define GSW_REG_MIB_CNT_EN     0x4000
50 +
51  #define GSW_REG_PORT_PMCR(x)   (0x3000 + (x * 0x100))
52  #define GSW_REG_PORT_STATUS(x) (0x3008 + (x * 0x100))
53  #define GSW_REG_SMACCR0                0x3fE4
54 @@ -76,6 +78,7 @@
55  #define PHY_PRE_EN             BIT(30)
56  #define PMY_MDC_CONF(_x)       ((_x & 0x3f) << 24)
57  
58 +
59  enum {
60         /* Global attributes. */
61         GSW_ATTR_ENABLE_VLAN,
62 --- /dev/null
63 +++ b/drivers/net/ethernet/mediatek/mt7530.c
64 @@ -0,0 +1,890 @@
65 +/*
66 + * This program is free software; you can redistribute it and/or
67 + * modify it under the terms of the GNU General Public License
68 + * as published by the Free Software Foundation; either version 2
69 + * of the License, or (at your option) any later version.
70 + *
71 + * This program is distributed in the hope that it will be useful,
72 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
73 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
74 + * GNU General Public License for more details.
75 + *
76 + * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
77 + * Copyright (C) 2016 Vitaly Chekryzhev <13hakta@gmail.com>
78 + */
79 +
80 +#include <linux/if.h>
81 +#include <linux/module.h>
82 +#include <linux/init.h>
83 +#include <linux/list.h>
84 +#include <linux/if_ether.h>
85 +#include <linux/skbuff.h>
86 +#include <linux/netdevice.h>
87 +#include <linux/netlink.h>
88 +#include <linux/bitops.h>
89 +#include <net/genetlink.h>
90 +#include <linux/switch.h>
91 +#include <linux/delay.h>
92 +#include <linux/phy.h>
93 +#include <linux/netdevice.h>
94 +#include <linux/etherdevice.h>
95 +#include <linux/lockdep.h>
96 +#include <linux/workqueue.h>
97 +#include <linux/of_device.h>
98 +
99 +#include "mt7530.h"
100 +
101 +#define MT7530_CPU_PORT                6
102 +#define MT7530_NUM_PORTS       8
103 +#ifdef CONFIG_SOC_MT7621
104 +#define MT7530_NUM_VLANS       4095
105 +#else
106 +#define MT7530_NUM_VLANS       16
107 +#endif
108 +#define MT7530_MAX_VID         4095
109 +#define MT7530_MIN_VID         0
110 +
111 +/* registers */
112 +#define REG_ESW_VLAN_VTCR              0x90
113 +#define REG_ESW_VLAN_VAWD1             0x94
114 +#define REG_ESW_VLAN_VAWD2             0x98
115 +#define REG_ESW_VLAN_VTIM(x)   (0x100 + 4 * ((x) / 2))
116 +
117 +#define REG_ESW_VLAN_VAWD1_IVL_MAC     BIT(30)
118 +#define REG_ESW_VLAN_VAWD1_VTAG_EN     BIT(28)
119 +#define REG_ESW_VLAN_VAWD1_VALID       BIT(0)
120 +
121 +/* vlan egress mode */
122 +enum {
123 +       ETAG_CTRL_UNTAG = 0,
124 +       ETAG_CTRL_TAG   = 2,
125 +       ETAG_CTRL_SWAP  = 1,
126 +       ETAG_CTRL_STACK = 3,
127 +};
128 +
129 +#define REG_ESW_PORT_PCR(x)    (0x2004 | ((x) << 8))
130 +#define REG_ESW_PORT_PVC(x)    (0x2010 | ((x) << 8))
131 +#define REG_ESW_PORT_PPBV1(x)  (0x2014 | ((x) << 8))
132 +
133 +#define REG_HWTRAP             0x7804
134 +
135 +#define MIB_DESC(_s , _o, _n)   \
136 +       {                       \
137 +               .size = (_s),   \
138 +               .offset = (_o), \
139 +               .name = (_n),   \
140 +       }
141 +
142 +struct mt7xxx_mib_desc {
143 +       unsigned int size;
144 +       unsigned int offset;
145 +       const char *name;
146 +};
147 +
148 +static const struct mt7xxx_mib_desc mt7620_mibs[] = {
149 +       MIB_DESC(1, MT7620_MIB_STATS_PPE_AC_BCNT0, "PPE_AC_BCNT0"),
150 +       MIB_DESC(1, MT7620_MIB_STATS_PPE_AC_PCNT0, "PPE_AC_PCNT0"),
151 +       MIB_DESC(1, MT7620_MIB_STATS_PPE_AC_BCNT63, "PPE_AC_BCNT63"),
152 +       MIB_DESC(1, MT7620_MIB_STATS_PPE_AC_PCNT63, "PPE_AC_PCNT63"),
153 +       MIB_DESC(1, MT7620_MIB_STATS_PPE_MTR_CNT0, "PPE_MTR_CNT0"),
154 +       MIB_DESC(1, MT7620_MIB_STATS_PPE_MTR_CNT63, "PPE_MTR_CNT63"),
155 +       MIB_DESC(1, MT7620_MIB_STATS_GDM1_TX_GBCNT, "GDM1_TX_GBCNT"),
156 +       MIB_DESC(1, MT7620_MIB_STATS_GDM1_TX_GPCNT, "GDM1_TX_GPCNT"),
157 +       MIB_DESC(1, MT7620_MIB_STATS_GDM1_TX_SKIPCNT, "GDM1_TX_SKIPCNT"),
158 +       MIB_DESC(1, MT7620_MIB_STATS_GDM1_TX_COLCNT, "GDM1_TX_COLCNT"),
159 +       MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_GBCNT1, "GDM1_RX_GBCNT1"),
160 +       MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_GPCNT1, "GDM1_RX_GPCNT1"),
161 +       MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_OERCNT, "GDM1_RX_OERCNT"),
162 +       MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_FERCNT, "GDM1_RX_FERCNT"),
163 +       MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_SERCNT, "GDM1_RX_SERCNT"),
164 +       MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_LERCNT, "GDM1_RX_LERCNT"),
165 +       MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_CERCNT, "GDM1_RX_CERCNT"),
166 +       MIB_DESC(1, MT7620_MIB_STATS_GDM1_RX_FCCNT, "GDM1_RX_FCCNT"),
167 +       MIB_DESC(1, MT7620_MIB_STATS_GDM2_TX_GBCNT, "GDM2_TX_GBCNT"),
168 +       MIB_DESC(1, MT7620_MIB_STATS_GDM2_TX_GPCNT, "GDM2_TX_GPCNT"),
169 +       MIB_DESC(1, MT7620_MIB_STATS_GDM2_TX_SKIPCNT, "GDM2_TX_SKIPCNT"),
170 +       MIB_DESC(1, MT7620_MIB_STATS_GDM2_TX_COLCNT, "GDM2_TX_COLCNT"),
171 +       MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_GBCNT, "GDM2_RX_GBCNT"),
172 +       MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_GPCNT, "GDM2_RX_GPCNT"),
173 +       MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_OERCNT, "GDM2_RX_OERCNT"),
174 +       MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_FERCNT, "GDM2_RX_FERCNT"),
175 +       MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_SERCNT, "GDM2_RX_SERCNT"),
176 +       MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_LERCNT, "GDM2_RX_LERCNT"),
177 +       MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_CERCNT, "GDM2_RX_CERCNT"),
178 +       MIB_DESC(1, MT7620_MIB_STATS_GDM2_RX_FCCNT, "GDM2_RX_FCCNT")
179 +};
180 +
181 +static const struct mt7xxx_mib_desc mt7620_port_mibs[] = {
182 +       MIB_DESC(1, MT7620_MIB_STATS_PORT_TGPCN,  "TxGPC"),
183 +       MIB_DESC(1, MT7620_MIB_STATS_PORT_TBOCN,  "TxBOC"),
184 +       MIB_DESC(1, MT7620_MIB_STATS_PORT_TGOCN,  "TxGOC"),
185 +       MIB_DESC(1, MT7620_MIB_STATS_PORT_TEPCN,  "TxEPC"),
186 +       MIB_DESC(1, MT7620_MIB_STATS_PORT_RGPCN,  "RxGPC"),
187 +       MIB_DESC(1, MT7620_MIB_STATS_PORT_RBOCN,  "RxBOC"),
188 +       MIB_DESC(1, MT7620_MIB_STATS_PORT_RGOCN,  "RxGOC"),
189 +       MIB_DESC(1, MT7620_MIB_STATS_PORT_REPC1N, "RxEPC1"),
190 +       MIB_DESC(1, MT7620_MIB_STATS_PORT_REPC2N, "RxEPC2")
191 +};
192 +
193 +static const struct mt7xxx_mib_desc mt7621_mibs[] = {
194 +       MIB_DESC(1, MT7621_STATS_TDPC, "TxDrop"),
195 +       MIB_DESC(1, MT7621_STATS_TCRC, "TxCRC"),
196 +       MIB_DESC(1, MT7621_STATS_TUPC, "TxUni"),
197 +       MIB_DESC(1, MT7621_STATS_TMPC, "TxMulti"),
198 +       MIB_DESC(1, MT7621_STATS_TBPC, "TxBroad"),
199 +       MIB_DESC(1, MT7621_STATS_TCEC, "TxCollision"),
200 +       MIB_DESC(1, MT7621_STATS_TSCEC, "TxSingleCol"),
201 +       MIB_DESC(1, MT7621_STATS_TMCEC, "TxMultiCol"),
202 +       MIB_DESC(1, MT7621_STATS_TDEC, "TxDefer"),
203 +       MIB_DESC(1, MT7621_STATS_TLCEC, "TxLateCol"),
204 +       MIB_DESC(1, MT7621_STATS_TXCEC, "TxExcCol"),
205 +       MIB_DESC(1, MT7621_STATS_TPPC, "TxPause"),
206 +       MIB_DESC(1, MT7621_STATS_TL64PC, "Tx64Byte"),
207 +       MIB_DESC(1, MT7621_STATS_TL65PC, "Tx65Byte"),
208 +       MIB_DESC(1, MT7621_STATS_TL128PC, "Tx128Byte"),
209 +       MIB_DESC(1, MT7621_STATS_TL256PC, "Tx256Byte"),
210 +       MIB_DESC(1, MT7621_STATS_TL512PC, "Tx512Byte"),
211 +       MIB_DESC(1, MT7621_STATS_TL1024PC, "Tx1024Byte"),
212 +       MIB_DESC(2, MT7621_STATS_TOC, "TxByte"),
213 +       MIB_DESC(1, MT7621_STATS_RDPC, "RxDrop"),
214 +       MIB_DESC(1, MT7621_STATS_RFPC, "RxFiltered"),
215 +       MIB_DESC(1, MT7621_STATS_RUPC, "RxUni"),
216 +       MIB_DESC(1, MT7621_STATS_RMPC, "RxMulti"),
217 +       MIB_DESC(1, MT7621_STATS_RBPC, "RxBroad"),
218 +       MIB_DESC(1, MT7621_STATS_RAEPC, "RxAlignErr"),
219 +       MIB_DESC(1, MT7621_STATS_RCEPC, "RxCRC"),
220 +       MIB_DESC(1, MT7621_STATS_RUSPC, "RxUnderSize"),
221 +       MIB_DESC(1, MT7621_STATS_RFEPC, "RxFragment"),
222 +       MIB_DESC(1, MT7621_STATS_ROSPC, "RxOverSize"),
223 +       MIB_DESC(1, MT7621_STATS_RJEPC, "RxJabber"),
224 +       MIB_DESC(1, MT7621_STATS_RPPC, "RxPause"),
225 +       MIB_DESC(1, MT7621_STATS_RL64PC, "Rx64Byte"),
226 +       MIB_DESC(1, MT7621_STATS_RL65PC, "Rx65Byte"),
227 +       MIB_DESC(1, MT7621_STATS_RL128PC, "Rx128Byte"),
228 +       MIB_DESC(1, MT7621_STATS_RL256PC, "Rx256Byte"),
229 +       MIB_DESC(1, MT7621_STATS_RL512PC, "Rx512Byte"),
230 +       MIB_DESC(1, MT7621_STATS_RL1024PC, "Rx1024Byte"),
231 +       MIB_DESC(2, MT7621_STATS_ROC, "RxByte"),
232 +       MIB_DESC(1, MT7621_STATS_RDPC_CTRL, "RxCtrlDrop"),
233 +       MIB_DESC(1, MT7621_STATS_RDPC_ING, "RxIngDrop"),
234 +       MIB_DESC(1, MT7621_STATS_RDPC_ARL, "RxARLDrop")
235 +};
236 +
237 +enum {
238 +       /* Global attributes. */
239 +       MT7530_ATTR_ENABLE_VLAN,
240 +};
241 +
242 +struct mt7530_port_entry {
243 +       u16     pvid;
244 +};
245 +
246 +struct mt7530_vlan_entry {
247 +       u16     vid;
248 +       u8      member;
249 +       u8      etags;
250 +};
251 +
252 +struct mt7530_priv {
253 +       void __iomem            *base;
254 +       struct mii_bus          *bus;
255 +       struct switch_dev       swdev;
256 +
257 +       bool                    global_vlan_enable;
258 +       struct mt7530_vlan_entry        vlan_entries[MT7530_NUM_VLANS];
259 +       struct mt7530_port_entry        port_entries[MT7530_NUM_PORTS];
260 +};
261 +
262 +struct mt7530_mapping {
263 +       char    *name;
264 +       u16     pvids[MT7530_NUM_PORTS];
265 +       u8      members[MT7530_NUM_VLANS];
266 +       u8      etags[MT7530_NUM_VLANS];
267 +       u16     vids[MT7530_NUM_VLANS];
268 +} mt7530_defaults[] = {
269 +       {
270 +               .name = "llllw",
271 +               .pvids = { 1, 1, 1, 1, 2, 1, 1 },
272 +               .members = { 0, 0x6f, 0x50 },
273 +               .etags = { 0, 0x40, 0x40 },
274 +               .vids = { 0, 1, 2 },
275 +       }, {
276 +               .name = "wllll",
277 +               .pvids = { 2, 1, 1, 1, 1, 1, 1 },
278 +               .members = { 0, 0x7e, 0x41 },
279 +               .etags = { 0, 0x40, 0x40 },
280 +               .vids = { 0, 1, 2 },
281 +       },
282 +};
283 +
284 +struct mt7530_mapping*
285 +mt7530_find_mapping(struct device_node *np)
286 +{
287 +       const char *map;
288 +       int i;
289 +
290 +       if (of_property_read_string(np, "mediatek,portmap", &map))
291 +               return NULL;
292 +
293 +       for (i = 0; i < ARRAY_SIZE(mt7530_defaults); i++)
294 +               if (!strcmp(map, mt7530_defaults[i].name))
295 +                       return &mt7530_defaults[i];
296 +
297 +       return NULL;
298 +}
299 +
300 +static void
301 +mt7530_apply_mapping(struct mt7530_priv *mt7530, struct mt7530_mapping *map)
302 +{
303 +       int i = 0;
304 +
305 +       for (i = 0; i < MT7530_NUM_PORTS; i++)
306 +               mt7530->port_entries[i].pvid = map->pvids[i];
307 +
308 +       for (i = 0; i < MT7530_NUM_VLANS; i++) {
309 +               mt7530->vlan_entries[i].member = map->members[i];
310 +               mt7530->vlan_entries[i].etags = map->etags[i];
311 +               mt7530->vlan_entries[i].vid = map->vids[i];
312 +       }
313 +}
314 +
315 +static int
316 +mt7530_reset_switch(struct switch_dev *dev)
317 +{
318 +       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
319 +       int i;
320 +
321 +       memset(priv->port_entries, 0, sizeof(priv->port_entries));
322 +       memset(priv->vlan_entries, 0, sizeof(priv->vlan_entries));
323 +
324 +       /* set default vid of each vlan to the same number of vlan, so the vid
325 +        * won't need be set explicitly.
326 +        */
327 +       for (i = 0; i < MT7530_NUM_VLANS; i++) {
328 +               priv->vlan_entries[i].vid = i;
329 +       }
330 +
331 +       return 0;
332 +}
333 +
334 +static int
335 +mt7530_get_vlan_enable(struct switch_dev *dev,
336 +                          const struct switch_attr *attr,
337 +                          struct switch_val *val)
338 +{
339 +       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
340 +
341 +       val->value.i = priv->global_vlan_enable;
342 +
343 +       return 0;
344 +}
345 +
346 +static int
347 +mt7530_set_vlan_enable(struct switch_dev *dev,
348 +                          const struct switch_attr *attr,
349 +                          struct switch_val *val)
350 +{
351 +       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
352 +
353 +       priv->global_vlan_enable = val->value.i != 0;
354 +
355 +       return 0;
356 +}
357 +
358 +static u32
359 +mt7530_r32(struct mt7530_priv *priv, u32 reg)
360 +{
361 +       u32 val;
362 +       if (priv->bus) {
363 +               u16 high, low;
364 +
365 +               mdiobus_write(priv->bus, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
366 +               low = mdiobus_read(priv->bus, 0x1f, (reg >> 2) & 0xf);
367 +               high = mdiobus_read(priv->bus, 0x1f, 0x10);
368 +
369 +               return (high << 16) | (low & 0xffff);
370 +       }
371 +
372 +       val = ioread32(priv->base + reg);
373 +       pr_debug("MT7530 MDIO Read [%04x]=%08x\n", reg, val);
374 +
375 +       return val;
376 +}
377 +
378 +static void
379 +mt7530_w32(struct mt7530_priv *priv, u32 reg, u32 val)
380 +{
381 +       if (priv->bus) {
382 +               mdiobus_write(priv->bus, 0x1f, 0x1f, (reg >> 6) & 0x3ff);
383 +               mdiobus_write(priv->bus, 0x1f, (reg >> 2) & 0xf,  val & 0xffff);
384 +               mdiobus_write(priv->bus, 0x1f, 0x10, val >> 16);
385 +               return;
386 +       }
387 +
388 +       pr_debug("MT7530 MDIO Write[%04x]=%08x\n", reg, val);
389 +       iowrite32(val, priv->base + reg);
390 +}
391 +
392 +static void
393 +mt7530_vtcr(struct mt7530_priv *priv, u32 cmd, u32 val)
394 +{
395 +       int i;
396 +
397 +       mt7530_w32(priv, REG_ESW_VLAN_VTCR, BIT(31) | (cmd << 12) | val);
398 +
399 +       for (i = 0; i < 20; i++) {
400 +               u32 val = mt7530_r32(priv, REG_ESW_VLAN_VTCR);
401 +
402 +               if ((val & BIT(31)) == 0)
403 +                       break;
404 +
405 +               udelay(1000);
406 +       }
407 +       if (i == 20)
408 +               printk("mt7530: vtcr timeout\n");
409 +}
410 +
411 +static int
412 +mt7530_get_port_pvid(struct switch_dev *dev, int port, int *val)
413 +{
414 +       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
415 +
416 +       if (port >= MT7530_NUM_PORTS)
417 +               return -EINVAL;
418 +
419 +       *val = mt7530_r32(priv, REG_ESW_PORT_PPBV1(port));
420 +       *val &= 0xfff;
421 +
422 +       return 0;
423 +}
424 +
425 +static int
426 +mt7530_set_port_pvid(struct switch_dev *dev, int port, int pvid)
427 +{
428 +       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
429 +
430 +       if (port >= MT7530_NUM_PORTS)
431 +               return -EINVAL;
432 +
433 +       if (pvid < MT7530_MIN_VID || pvid > MT7530_MAX_VID)
434 +               return -EINVAL;
435 +
436 +       priv->port_entries[port].pvid = pvid;
437 +
438 +       return 0;
439 +}
440 +
441 +static int
442 +mt7530_get_vlan_ports(struct switch_dev *dev, struct switch_val *val)
443 +{
444 +       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
445 +       u32 member;
446 +       u32 etags;
447 +       int i;
448 +
449 +       val->len = 0;
450 +
451 +       if (val->port_vlan < 0 || val->port_vlan >= MT7530_NUM_VLANS)
452 +               return -EINVAL;
453 +
454 +       mt7530_vtcr(priv, 0, val->port_vlan);
455 +
456 +       member = mt7530_r32(priv, REG_ESW_VLAN_VAWD1);
457 +       member >>= 16;
458 +       member &= 0xff;
459 +
460 +       etags = mt7530_r32(priv, REG_ESW_VLAN_VAWD2);
461 +
462 +       for (i = 0; i < MT7530_NUM_PORTS; i++) {
463 +               struct switch_port *p;
464 +               int etag;
465 +
466 +               if (!(member & BIT(i)))
467 +                       continue;
468 +
469 +               p = &val->value.ports[val->len++];
470 +               p->id = i;
471 +
472 +               etag = (etags >> (i * 2)) & 0x3;
473 +
474 +               if (etag == ETAG_CTRL_TAG)
475 +                       p->flags |= BIT(SWITCH_PORT_FLAG_TAGGED);
476 +               else if (etag != ETAG_CTRL_UNTAG)
477 +                       printk("vlan egress tag control neither untag nor tag.\n");
478 +       }
479 +
480 +       return 0;
481 +}
482 +
483 +static int
484 +mt7530_set_vlan_ports(struct switch_dev *dev, struct switch_val *val)
485 +{
486 +       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
487 +       u8 member = 0;
488 +       u8 etags = 0;
489 +       int i;
490 +
491 +       if (val->port_vlan < 0 || val->port_vlan >= MT7530_NUM_VLANS ||
492 +                       val->len > MT7530_NUM_PORTS)
493 +               return -EINVAL;
494 +
495 +       for (i = 0; i < val->len; i++) {
496 +               struct switch_port *p = &val->value.ports[i];
497 +
498 +               if (p->id >= MT7530_NUM_PORTS)
499 +                       return -EINVAL;
500 +
501 +               member |= BIT(p->id);
502 +
503 +               if (p->flags & BIT(SWITCH_PORT_FLAG_TAGGED))
504 +                       etags |= BIT(p->id);
505 +       }
506 +       priv->vlan_entries[val->port_vlan].member = member;
507 +       priv->vlan_entries[val->port_vlan].etags = etags;
508 +
509 +       return 0;
510 +}
511 +
512 +static int
513 +mt7530_set_vid(struct switch_dev *dev, const struct switch_attr *attr,
514 +               struct switch_val *val)
515 +{
516 +       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
517 +       int vlan;
518 +       u16 vid;
519 +
520 +       vlan = val->port_vlan;
521 +       vid = (u16)val->value.i;
522 +
523 +       if (vlan < 0 || vlan >= MT7530_NUM_VLANS)
524 +               return -EINVAL;
525 +
526 +       if (vid < MT7530_MIN_VID || vid > MT7530_MAX_VID)
527 +               return -EINVAL;
528 +
529 +       priv->vlan_entries[vlan].vid = vid;
530 +       return 0;
531 +}
532 +
533 +static int
534 +mt7530_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
535 +               struct switch_val *val)
536 +{
537 +       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
538 +       u32 vid;
539 +       int vlan;
540 +
541 +       vlan = val->port_vlan;
542 +
543 +       vid = mt7530_r32(priv, REG_ESW_VLAN_VTIM(vlan));
544 +       if (vlan & 1)
545 +               vid = vid >> 12;
546 +       vid &= 0xfff;
547 +
548 +       val->value.i = vid;
549 +       return 0;
550 +}
551 +
552 +static int
553 +mt7530_apply_config(struct switch_dev *dev)
554 +{
555 +       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
556 +       int i, j;
557 +       u8 tag_ports;
558 +       u8 untag_ports;
559 +
560 +       if (!priv->global_vlan_enable) {
561 +               for (i = 0; i < MT7530_NUM_PORTS; i++)
562 +                       mt7530_w32(priv, REG_ESW_PORT_PCR(i), 0x00400000);
563 +
564 +               mt7530_w32(priv, REG_ESW_PORT_PCR(MT7530_CPU_PORT), 0x00ff0000);
565 +
566 +               for (i = 0; i < MT7530_NUM_PORTS; i++)
567 +                       mt7530_w32(priv, REG_ESW_PORT_PVC(i), 0x810000c0);
568 +
569 +               return 0;
570 +       }
571 +
572 +       /* set all ports as security mode */
573 +       for (i = 0; i < MT7530_NUM_PORTS; i++)
574 +               mt7530_w32(priv, REG_ESW_PORT_PCR(i), 0x00ff0003);
575 +
576 +       /* check if a port is used in tag/untag vlan egress mode */
577 +       tag_ports = 0;
578 +       untag_ports = 0;
579 +
580 +       for (i = 0; i < MT7530_NUM_VLANS; i++) {
581 +               u8 member = priv->vlan_entries[i].member;
582 +               u8 etags = priv->vlan_entries[i].etags;
583 +
584 +               if (!member)
585 +                       continue;
586 +
587 +               for (j = 0; j < MT7530_NUM_PORTS; j++) {
588 +                       if (!(member & BIT(j)))
589 +                               continue;
590 +
591 +                       if (etags & BIT(j))
592 +                               tag_ports |= 1u << j;
593 +                       else
594 +                               untag_ports |= 1u << j;
595 +               }
596 +       }
597 +
598 +       /* set all untag-only ports as transparent and the rest as user port */
599 +       for (i = 0; i < MT7530_NUM_PORTS; i++) {
600 +               u32 pvc_mode = 0x81000000;
601 +
602 +               if (untag_ports & BIT(i) && !(tag_ports & BIT(i)))
603 +                       pvc_mode = 0x810000c0;
604 +
605 +               mt7530_w32(priv, REG_ESW_PORT_PVC(i), pvc_mode);
606 +       }
607 +
608 +       for (i = 0; i < MT7530_NUM_VLANS; i++) {
609 +               u16 vid = priv->vlan_entries[i].vid;
610 +               u8 member = priv->vlan_entries[i].member;
611 +               u8 etags = priv->vlan_entries[i].etags;
612 +               u32 val;
613 +
614 +               /* vid of vlan */
615 +               val = mt7530_r32(priv, REG_ESW_VLAN_VTIM(i));
616 +               if (i % 2 == 0) {
617 +                       val &= 0xfff000;
618 +                       val |= vid;
619 +               } else {
620 +                       val &= 0xfff;
621 +                       val |= (vid << 12);
622 +               }
623 +               mt7530_w32(priv, REG_ESW_VLAN_VTIM(i), val);
624 +
625 +               /* vlan port membership */
626 +               if (member)
627 +                       mt7530_w32(priv, REG_ESW_VLAN_VAWD1, REG_ESW_VLAN_VAWD1_IVL_MAC |
628 +                               REG_ESW_VLAN_VAWD1_VTAG_EN | (member << 16) |
629 +                               REG_ESW_VLAN_VAWD1_VALID);
630 +               else
631 +                       mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 0);
632 +
633 +               /* egress mode */
634 +               val = 0;
635 +               for (j = 0; j < MT7530_NUM_PORTS; j++) {
636 +                       if (etags & BIT(j))
637 +                               val |= ETAG_CTRL_TAG << (j * 2);
638 +                       else
639 +                               val |= ETAG_CTRL_UNTAG << (j * 2);
640 +               }
641 +               mt7530_w32(priv, REG_ESW_VLAN_VAWD2, val);
642 +
643 +               /* write to vlan table */
644 +               mt7530_vtcr(priv, 1, i);
645 +       }
646 +
647 +       /* Port Default PVID */
648 +       for (i = 0; i < MT7530_NUM_PORTS; i++) {
649 +               u32 val;
650 +               val = mt7530_r32(priv, REG_ESW_PORT_PPBV1(i));
651 +               val &= ~0xfff;
652 +               val |= priv->port_entries[i].pvid;
653 +               mt7530_w32(priv, REG_ESW_PORT_PPBV1(i), val);
654 +       }
655 +
656 +       return 0;
657 +}
658 +
659 +static int
660 +mt7530_get_port_link(struct switch_dev *dev,  int port,
661 +                       struct switch_port_link *link)
662 +{
663 +       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
664 +       u32 speed, pmsr;
665 +
666 +       if (port < 0 || port >= MT7530_NUM_PORTS)
667 +               return -EINVAL;
668 +
669 +       pmsr = mt7530_r32(priv, 0x3008 + (0x100 * port));
670 +
671 +       link->link = pmsr & 1;
672 +       link->duplex = (pmsr >> 1) & 1;
673 +       speed = (pmsr >> 2) & 3;
674 +
675 +       switch (speed) {
676 +       case 0:
677 +               link->speed = SWITCH_PORT_SPEED_10;
678 +               break;
679 +       case 1:
680 +               link->speed = SWITCH_PORT_SPEED_100;
681 +               break;
682 +       case 2:
683 +       case 3: /* forced gige speed can be 2 or 3 */
684 +               link->speed = SWITCH_PORT_SPEED_1000;
685 +               break;
686 +       default:
687 +               link->speed = SWITCH_PORT_SPEED_UNKNOWN;
688 +               break;
689 +       }
690 +
691 +       return 0;
692 +}
693 +
694 +static u64 get_mib_counter(struct mt7530_priv *priv, int i, int port)
695 +{
696 +       unsigned int port_base;
697 +       u64 lo;
698 +
699 +       port_base = MT7621_MIB_COUNTER_BASE +
700 +                   MT7621_MIB_COUNTER_PORT_OFFSET * port;
701 +
702 +       lo = mt7530_r32(priv, port_base + mt7621_mibs[i].offset);
703 +       if (mt7621_mibs[i].size == 2) {
704 +               u64 hi;
705 +
706 +               hi = mt7530_r32(priv, port_base + mt7621_mibs[i].offset + 4);
707 +               lo |= hi << 32;
708 +       }
709 +
710 +       return lo;
711 +}
712 +
713 +static int mt7621_sw_get_port_mib(struct switch_dev *dev,
714 +                                 const struct switch_attr *attr,
715 +                                 struct switch_val *val)
716 +{
717 +       static char buf[4096];
718 +       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
719 +       int i, len = 0;
720 +
721 +       if (val->port_vlan >= MT7530_NUM_PORTS)
722 +               return -EINVAL;
723 +
724 +       len += snprintf(buf + len, sizeof(buf) - len,
725 +                       "Port %d MIB counters\n", val->port_vlan);
726 +
727 +       for (i = 0; i < ARRAY_SIZE(mt7621_mibs); ++i) {
728 +               u64 counter;
729 +               len += snprintf(buf + len, sizeof(buf) - len,
730 +                               "%-11s: ", mt7621_mibs[i].name);
731 +               counter = get_mib_counter(priv, i, val->port_vlan);
732 +               len += snprintf(buf + len, sizeof(buf) - len, "%llu\n",
733 +                               counter);
734 +       }
735 +
736 +       val->value.s = buf;
737 +       val->len = len;
738 +       return 0;
739 +}
740 +
741 +static u64 get_mib_counter_7620(struct mt7530_priv *priv, int i)
742 +{
743 +       return mt7530_r32(priv, MT7620_MIB_COUNTER_BASE + mt7620_mibs[i].offset);
744 +}
745 +
746 +static u64 get_mib_counter_port_7620(struct mt7530_priv *priv, int i, int port)
747 +{
748 +       return mt7530_r32(priv,
749 +                       MT7620_MIB_COUNTER_BASE_PORT +
750 +                       (MT7620_MIB_COUNTER_PORT_OFFSET * port) +
751 +                       mt7620_port_mibs[i].offset);
752 +}
753 +
754 +static int mt7530_sw_get_mib(struct switch_dev *dev,
755 +                                 const struct switch_attr *attr,
756 +                                 struct switch_val *val)
757 +{
758 +       static char buf[4096];
759 +       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
760 +       int i, len = 0;
761 +
762 +       len += snprintf(buf + len, sizeof(buf) - len, "Switch MIB counters\n");
763 +
764 +       for (i = 0; i < ARRAY_SIZE(mt7620_mibs); ++i) {
765 +               u64 counter;
766 +               len += snprintf(buf + len, sizeof(buf) - len,
767 +                               "%-11s: ", mt7620_mibs[i].name);
768 +               counter = get_mib_counter_7620(priv, i);
769 +               len += snprintf(buf + len, sizeof(buf) - len, "%llu\n",
770 +                               counter);
771 +       }
772 +
773 +       val->value.s = buf;
774 +       val->len = len;
775 +       return 0;
776 +}
777 +
778 +static int mt7530_sw_get_port_mib(struct switch_dev *dev,
779 +                                 const struct switch_attr *attr,
780 +                                 struct switch_val *val)
781 +{
782 +       static char buf[4096];
783 +       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
784 +       int i, len = 0;
785 +
786 +       if (val->port_vlan >= MT7530_NUM_PORTS)
787 +               return -EINVAL;
788 +
789 +       len += snprintf(buf + len, sizeof(buf) - len,
790 +                       "Port %d MIB counters\n", val->port_vlan);
791 +
792 +       for (i = 0; i < ARRAY_SIZE(mt7620_port_mibs); ++i) {
793 +               u64 counter;
794 +               len += snprintf(buf + len, sizeof(buf) - len,
795 +                               "%-11s: ", mt7620_port_mibs[i].name);
796 +               counter = get_mib_counter_port_7620(priv, i, val->port_vlan);
797 +               len += snprintf(buf + len, sizeof(buf) - len, "%llu\n",
798 +                               counter);
799 +       }
800 +
801 +       val->value.s = buf;
802 +       val->len = len;
803 +       return 0;
804 +}
805 +
806 +static const struct switch_attr mt7530_global[] = {
807 +       {
808 +               .type = SWITCH_TYPE_INT,
809 +               .name = "enable_vlan",
810 +               .description = "VLAN mode (1:enabled)",
811 +               .max = 1,
812 +               .id = MT7530_ATTR_ENABLE_VLAN,
813 +               .get = mt7530_get_vlan_enable,
814 +               .set = mt7530_set_vlan_enable,
815 +       }, {
816 +               .type = SWITCH_TYPE_STRING,
817 +               .name = "mib",
818 +               .description = "Get MIB counters for switch",
819 +               .get = mt7530_sw_get_mib,
820 +               .set = NULL,
821 +       },
822 +};
823 +
824 +static const struct switch_attr mt7621_port[] = {
825 +       {
826 +               .type = SWITCH_TYPE_STRING,
827 +               .name = "mib",
828 +               .description = "Get MIB counters for port",
829 +               .get = mt7621_sw_get_port_mib,
830 +               .set = NULL,
831 +       },
832 +};
833 +
834 +static const struct switch_attr mt7530_port[] = {
835 +       {
836 +               .type = SWITCH_TYPE_STRING,
837 +               .name = "mib",
838 +               .description = "Get MIB counters for port",
839 +               .get = mt7530_sw_get_port_mib,
840 +               .set = NULL,
841 +       },
842 +};
843 +
844 +static const struct switch_attr mt7530_vlan[] = {
845 +       {
846 +               .type = SWITCH_TYPE_INT,
847 +               .name = "vid",
848 +               .description = "VLAN ID (0-4094)",
849 +               .set = mt7530_set_vid,
850 +               .get = mt7530_get_vid,
851 +               .max = 4094,
852 +       },
853 +};
854 +
855 +static const struct switch_dev_ops mt7621_ops = {
856 +       .attr_global = {
857 +               .attr = mt7530_global,
858 +               .n_attr = ARRAY_SIZE(mt7530_global),
859 +       },
860 +       .attr_port = {
861 +               .attr = mt7621_port,
862 +               .n_attr = ARRAY_SIZE(mt7621_port),
863 +       },
864 +       .attr_vlan = {
865 +               .attr = mt7530_vlan,
866 +               .n_attr = ARRAY_SIZE(mt7530_vlan),
867 +       },
868 +       .get_vlan_ports = mt7530_get_vlan_ports,
869 +       .set_vlan_ports = mt7530_set_vlan_ports,
870 +       .get_port_pvid = mt7530_get_port_pvid,
871 +       .set_port_pvid = mt7530_set_port_pvid,
872 +       .get_port_link = mt7530_get_port_link,
873 +       .apply_config = mt7530_apply_config,
874 +       .reset_switch = mt7530_reset_switch,
875 +};
876 +
877 +static const struct switch_dev_ops mt7530_ops = {
878 +       .attr_global = {
879 +               .attr = mt7530_global,
880 +               .n_attr = ARRAY_SIZE(mt7530_global),
881 +       },
882 +       .attr_port = {
883 +               .attr = mt7530_port,
884 +               .n_attr = ARRAY_SIZE(mt7530_port),
885 +       },
886 +       .attr_vlan = {
887 +               .attr = mt7530_vlan,
888 +               .n_attr = ARRAY_SIZE(mt7530_vlan),
889 +       },
890 +       .get_vlan_ports = mt7530_get_vlan_ports,
891 +       .set_vlan_ports = mt7530_set_vlan_ports,
892 +       .get_port_pvid = mt7530_get_port_pvid,
893 +       .set_port_pvid = mt7530_set_port_pvid,
894 +       .get_port_link = mt7530_get_port_link,
895 +       .apply_config = mt7530_apply_config,
896 +       .reset_switch = mt7530_reset_switch,
897 +};
898 +
899 +int
900 +mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus, int vlan)
901 +{
902 +       struct switch_dev *swdev;
903 +       struct mt7530_priv *mt7530;
904 +       struct mt7530_mapping *map;
905 +       int ret;
906 +
907 +       mt7530 = devm_kzalloc(dev, sizeof(struct mt7530_priv), GFP_KERNEL);
908 +       if (!mt7530)
909 +               return -ENOMEM;
910 +
911 +       mt7530->base = base;
912 +       mt7530->bus = bus;
913 +       mt7530->global_vlan_enable = vlan;
914 +
915 +       swdev = &mt7530->swdev;
916 +       if (bus) {
917 +               swdev->alias = "mt7530";
918 +               swdev->name = "mt7530";
919 +       } else if (IS_ENABLED(CONFIG_SOC_MT7621)) {
920 +               swdev->alias = "mt7621";
921 +               swdev->name = "mt7621";
922 +       } else {
923 +               swdev->alias = "mt7620";
924 +               swdev->name = "mt7620";
925 +       }
926 +       swdev->cpu_port = MT7530_CPU_PORT;
927 +       swdev->ports = MT7530_NUM_PORTS;
928 +       swdev->vlans = MT7530_NUM_VLANS;
929 +       if (IS_ENABLED(CONFIG_SOC_MT7621))
930 +               swdev->ops = &mt7621_ops;
931 +       else
932 +               swdev->ops = &mt7530_ops;
933 +
934 +       ret = register_switch(swdev, NULL);
935 +       if (ret) {
936 +               dev_err(dev, "failed to register mt7530\n");
937 +               return ret;
938 +       }
939 +
940 +
941 +       map = mt7530_find_mapping(dev->of_node);
942 +       if (map)
943 +               mt7530_apply_mapping(mt7530, map);
944 +       mt7530_apply_config(swdev);
945 +
946 +       /* magic vodoo */
947 +       if (!IS_ENABLED(CONFIG_SOC_MT7621) && bus && mt7530_r32(mt7530, REG_HWTRAP) !=  0x1117edf) {
948 +               dev_info(dev, "fixing up MHWTRAP register - bootloader probably played with it\n");
949 +               mt7530_w32(mt7530, REG_HWTRAP, 0x1117edf);
950 +       }
951 +       dev_info(dev, "loaded %s driver\n", swdev->name);
952 +
953 +       return 0;
954 +}
955 --- /dev/null
956 +++ b/drivers/net/ethernet/mediatek/mt7530.h
957 @@ -0,0 +1,186 @@
958 +/*
959 + * This program is free software; you can redistribute it and/or
960 + * modify it under the terms of the GNU General Public License
961 + * as published by the Free Software Foundation; either version 2
962 + * of the License, or (at your option) any later version.
963 + *
964 + * This program is distributed in the hope that it will be useful,
965 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
966 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
967 + * GNU General Public License for more details.
968 + *
969 + * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
970 + * Copyright (C) 2016 Vitaly Chekryzhev <13hakta@gmail.com>
971 + */
972 +
973 +#ifndef _MT7530_H__
974 +#define _MT7530_H__
975 +
976 +#define MT7620_MIB_COUNTER_BASE_PORT   0x4000
977 +#define MT7620_MIB_COUNTER_PORT_OFFSET 0x100
978 +#define MT7620_MIB_COUNTER_BASE        0x1010
979 +
980 +/* PPE Accounting Group #0 Byte Counter */
981 +#define MT7620_MIB_STATS_PPE_AC_BCNT0  0x000
982 +
983 +/* PPE Accounting Group #0 Packet Counter */
984 +#define MT7620_MIB_STATS_PPE_AC_PCNT0  0x004
985 +
986 +/* PPE Accounting Group #63 Byte Counter */
987 +#define MT7620_MIB_STATS_PPE_AC_BCNT63 0x1F8
988 +
989 +/* PPE Accounting Group #63 Packet Counter */
990 +#define MT7620_MIB_STATS_PPE_AC_PCNT63 0x1FC
991 +
992 +/* PPE Meter Group #0 */
993 +#define MT7620_MIB_STATS_PPE_MTR_CNT0  0x200
994 +
995 +/* PPE Meter Group #63 */
996 +#define MT7620_MIB_STATS_PPE_MTR_CNT63 0x2FC
997 +
998 +/* Transmit good byte count for CPU GDM */
999 +#define MT7620_MIB_STATS_GDM1_TX_GBCNT 0x300
1000 +
1001 +/* Transmit good packet count for CPU GDM (exclude flow control frames) */
1002 +#define MT7620_MIB_STATS_GDM1_TX_GPCNT 0x304
1003 +
1004 +/* Transmit abort count for CPU GDM */
1005 +#define MT7620_MIB_STATS_GDM1_TX_SKIPCNT       0x308
1006 +
1007 +/* Transmit collision count for CPU GDM */
1008 +#define MT7620_MIB_STATS_GDM1_TX_COLCNT        0x30C
1009 +
1010 +/* Received good byte count for CPU GDM */
1011 +#define MT7620_MIB_STATS_GDM1_RX_GBCNT1        0x320
1012 +
1013 +/* Received good packet count for CPU GDM (exclude flow control frame) */
1014 +#define MT7620_MIB_STATS_GDM1_RX_GPCNT1        0x324
1015 +
1016 +/* Received overflow error packet count for CPU GDM */
1017 +#define MT7620_MIB_STATS_GDM1_RX_OERCNT        0x328
1018 +
1019 +/* Received FCS error packet count for CPU GDM */
1020 +#define MT7620_MIB_STATS_GDM1_RX_FERCNT        0x32C
1021 +
1022 +/* Received too short error packet count for CPU GDM */
1023 +#define MT7620_MIB_STATS_GDM1_RX_SERCNT        0x330
1024 +
1025 +/* Received too long error packet count for CPU GDM */
1026 +#define MT7620_MIB_STATS_GDM1_RX_LERCNT        0x334
1027 +
1028 +/* Received IP/TCP/UDP checksum error packet count for CPU GDM */
1029 +#define MT7620_MIB_STATS_GDM1_RX_CERCNT        0x338
1030 +
1031 +/* Received flow control pkt count for CPU GDM */
1032 +#define MT7620_MIB_STATS_GDM1_RX_FCCNT 0x33C
1033 +
1034 +/* Transmit good byte count for PPE GDM */
1035 +#define MT7620_MIB_STATS_GDM2_TX_GBCNT 0x340
1036 +
1037 +/* Transmit good packet count for PPE GDM (exclude flow control frames) */
1038 +#define MT7620_MIB_STATS_GDM2_TX_GPCNT 0x344
1039 +
1040 +/* Transmit abort count for PPE GDM */
1041 +#define MT7620_MIB_STATS_GDM2_TX_SKIPCNT       0x348
1042 +
1043 +/* Transmit collision count for PPE GDM */
1044 +#define MT7620_MIB_STATS_GDM2_TX_COLCNT        0x34C
1045 +
1046 +/* Received good byte count for PPE GDM */
1047 +#define MT7620_MIB_STATS_GDM2_RX_GBCNT 0x360
1048 +
1049 +/* Received good packet count for PPE GDM (exclude flow control frame) */
1050 +#define MT7620_MIB_STATS_GDM2_RX_GPCNT 0x364
1051 +
1052 +/* Received overflow error packet count for PPE GDM */
1053 +#define MT7620_MIB_STATS_GDM2_RX_OERCNT        0x368
1054 +
1055 +/* Received FCS error packet count for PPE GDM */
1056 +#define MT7620_MIB_STATS_GDM2_RX_FERCNT        0x36C
1057 +
1058 +/* Received too short error packet count for PPE GDM */
1059 +#define MT7620_MIB_STATS_GDM2_RX_SERCNT        0x370
1060 +
1061 +/* Received too long error packet count for PPE GDM */
1062 +#define MT7620_MIB_STATS_GDM2_RX_LERCNT        0x374
1063 +
1064 +/* Received IP/TCP/UDP checksum error packet count for PPE GDM */
1065 +#define MT7620_MIB_STATS_GDM2_RX_CERCNT        0x378
1066 +
1067 +/* Received flow control pkt count for PPE GDM */
1068 +#define MT7620_MIB_STATS_GDM2_RX_FCCNT 0x37C
1069 +
1070 +/* Tx Packet Counter of Port n */
1071 +#define MT7620_MIB_STATS_PORT_TGPCN    0x10
1072 +
1073 +/* Tx Bad Octet Counter of Port n */
1074 +#define MT7620_MIB_STATS_PORT_TBOCN    0x14
1075 +
1076 +/* Tx Good Octet Counter of Port n */
1077 +#define MT7620_MIB_STATS_PORT_TGOCN    0x18
1078 +
1079 +/* Tx Event Packet Counter of Port n */
1080 +#define MT7620_MIB_STATS_PORT_TEPCN    0x1C
1081 +
1082 +/* Rx Packet Counter of Port n */
1083 +#define MT7620_MIB_STATS_PORT_RGPCN    0x20
1084 +
1085 +/* Rx Bad Octet Counter of Port n */
1086 +#define MT7620_MIB_STATS_PORT_RBOCN    0x24
1087 +
1088 +/* Rx Good Octet Counter of Port n */
1089 +#define MT7620_MIB_STATS_PORT_RGOCN    0x28
1090 +
1091 +/* Rx Event Packet Counter of Port n */
1092 +#define MT7620_MIB_STATS_PORT_REPC1N   0x2C
1093 +
1094 +/* Rx Event Packet Counter of Port n */
1095 +#define MT7620_MIB_STATS_PORT_REPC2N   0x30
1096 +
1097 +#define MT7621_MIB_COUNTER_BASE        0x4000
1098 +#define MT7621_MIB_COUNTER_PORT_OFFSET 0x100
1099 +#define MT7621_STATS_TDPC      0x00
1100 +#define MT7621_STATS_TCRC      0x04
1101 +#define MT7621_STATS_TUPC      0x08
1102 +#define MT7621_STATS_TMPC      0x0C
1103 +#define MT7621_STATS_TBPC      0x10
1104 +#define MT7621_STATS_TCEC      0x14
1105 +#define MT7621_STATS_TSCEC     0x18
1106 +#define MT7621_STATS_TMCEC     0x1C
1107 +#define MT7621_STATS_TDEC      0x20
1108 +#define MT7621_STATS_TLCEC     0x24
1109 +#define MT7621_STATS_TXCEC     0x28
1110 +#define MT7621_STATS_TPPC      0x2C
1111 +#define MT7621_STATS_TL64PC    0x30
1112 +#define MT7621_STATS_TL65PC    0x34
1113 +#define MT7621_STATS_TL128PC   0x38
1114 +#define MT7621_STATS_TL256PC   0x3C
1115 +#define MT7621_STATS_TL512PC   0x40
1116 +#define MT7621_STATS_TL1024PC  0x44
1117 +#define MT7621_STATS_TOC       0x48
1118 +#define MT7621_STATS_RDPC      0x60
1119 +#define MT7621_STATS_RFPC      0x64
1120 +#define MT7621_STATS_RUPC      0x68
1121 +#define MT7621_STATS_RMPC      0x6C
1122 +#define MT7621_STATS_RBPC      0x70
1123 +#define MT7621_STATS_RAEPC     0x74
1124 +#define MT7621_STATS_RCEPC     0x78
1125 +#define MT7621_STATS_RUSPC     0x7C
1126 +#define MT7621_STATS_RFEPC     0x80
1127 +#define MT7621_STATS_ROSPC     0x84
1128 +#define MT7621_STATS_RJEPC     0x88
1129 +#define MT7621_STATS_RPPC      0x8C
1130 +#define MT7621_STATS_RL64PC    0x90
1131 +#define MT7621_STATS_RL65PC    0x94
1132 +#define MT7621_STATS_RL128PC   0x98
1133 +#define MT7621_STATS_RL256PC   0x9C
1134 +#define MT7621_STATS_RL512PC   0xA0
1135 +#define MT7621_STATS_RL1024PC  0xA4
1136 +#define MT7621_STATS_ROC       0xA8
1137 +#define MT7621_STATS_RDPC_CTRL 0xB0
1138 +#define MT7621_STATS_RDPC_ING  0xB4
1139 +#define MT7621_STATS_RDPC_ARL  0xB8
1140 +
1141 +int mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus, int vlan);
1142 +
1143 +#endif
1144 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
1145 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
1146 @@ -1291,8 +1291,13 @@ static int __init fe_init(struct net_dev
1147         }
1148  
1149         err = fe_hw_init(dev);
1150 -       if (!err)
1151 -               return 0;
1152 +       if (err)
1153 +               goto err_phy_disconnect;
1154 +
1155 +       if ((priv->flags & FE_FLAG_HAS_SWITCH) && priv->soc->switch_config)
1156 +               priv->soc->switch_config(priv);
1157 +
1158 +       return 0;
1159  
1160  err_phy_disconnect:
1161         if (priv->phy)
1162 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
1163 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
1164 @@ -383,6 +383,7 @@ struct fe_soc_data {
1165         int (*fwd_config)(struct fe_priv *priv);
1166         void (*tx_dma)(struct fe_tx_dma *txd);
1167         int (*switch_init)(struct fe_priv *priv);
1168 +       int (*switch_config)(struct fe_priv *priv);
1169         void (*port_init)(struct fe_priv *priv, struct device_node *port);
1170         int (*has_carrier)(struct fe_priv *priv);
1171         int (*mdio_init)(struct fe_priv *priv);
1172 --- a/drivers/net/ethernet/mediatek/soc_mt7620.c
1173 +++ b/drivers/net/ethernet/mediatek/soc_mt7620.c
1174 @@ -313,6 +313,7 @@ static struct fe_soc_data mt7620_data =
1175         .fwd_config = mt7620_fwd_config,
1176         .tx_dma = mt7620_tx_dma,
1177         .switch_init = mtk_gsw_init,
1178 +       .switch_config = mt7620_gsw_config,
1179         .port_init = mt7620_port_init,
1180         .reg_table = mt7620_reg_table,
1181         .pdma_glo_cfg = FE_PDMA_SIZE_16DWORDS,