1 /*-
2 * Copyright (c) 2016 Stanislav Galabov.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include <sys/param.h>
28 #include <sys/bus.h>
29 #include <sys/errno.h>
30 #include <sys/kernel.h>
31 #include <sys/lock.h>
32 #include <sys/malloc.h>
33 #include <sys/module.h>
34 #include <sys/mutex.h>
35 #include <sys/rman.h>
36 #include <sys/socket.h>
37 #include <sys/sockio.h>
38 #include <sys/sysctl.h>
39 #include <sys/systm.h>
40
41 #include <net/if.h>
42 #include <net/if_var.h>
43 #include <net/ethernet.h>
44 #include <net/if_media.h>
45 #include <net/if_types.h>
46
47 #include <machine/bus.h>
48 #include <dev/mii/mii.h>
49 #include <dev/mii/miivar.h>
50 #include <dev/mdio/mdio.h>
51
52 #include <dev/etherswitch/etherswitch.h>
53 #include <dev/etherswitch/mtkswitch/mtkswitchvar.h>
54 #include <dev/etherswitch/mtkswitch/mtkswitch_mt7620.h>
55
56 static int
mtkswitch_phy_read_locked(struct mtkswitch_softc * sc,int phy,int reg)57 mtkswitch_phy_read_locked(struct mtkswitch_softc *sc, int phy, int reg)
58 {
59 uint32_t data;
60
61 MTKSWITCH_WRITE(sc, MTKSWITCH_PIAC, PIAC_PHY_ACS_ST | PIAC_MDIO_ST |
62 (reg << PIAC_MDIO_REG_ADDR_OFF) | (phy << PIAC_MDIO_PHY_ADDR_OFF) |
63 PIAC_MDIO_CMD_READ);
64 while ((data = MTKSWITCH_READ(sc, MTKSWITCH_PIAC)) & PIAC_PHY_ACS_ST);
65
66 return ((int)(data & PIAC_MDIO_RW_DATA_MASK));
67 }
68
69 static int
mtkswitch_phy_read(device_t dev,int phy,int reg)70 mtkswitch_phy_read(device_t dev, int phy, int reg)
71 {
72 struct mtkswitch_softc *sc = device_get_softc(dev);
73 int data;
74
75 if ((phy < 0 || phy >= 32) || (reg < 0 || reg >= 32))
76 return (ENXIO);
77
78 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
79 MTKSWITCH_LOCK(sc);
80 data = mtkswitch_phy_read_locked(sc, phy, reg);
81 MTKSWITCH_UNLOCK(sc);
82
83 return (data);
84 }
85
86 static int
mtkswitch_phy_write_locked(struct mtkswitch_softc * sc,int phy,int reg,int val)87 mtkswitch_phy_write_locked(struct mtkswitch_softc *sc, int phy, int reg,
88 int val)
89 {
90
91 MTKSWITCH_WRITE(sc, MTKSWITCH_PIAC, PIAC_PHY_ACS_ST | PIAC_MDIO_ST |
92 (reg << PIAC_MDIO_REG_ADDR_OFF) | (phy << PIAC_MDIO_PHY_ADDR_OFF) |
93 (val & PIAC_MDIO_RW_DATA_MASK) | PIAC_MDIO_CMD_WRITE);
94 while (MTKSWITCH_READ(sc, MTKSWITCH_PIAC) & PIAC_PHY_ACS_ST);
95
96 return (0);
97 }
98
99 static int
mtkswitch_phy_write(device_t dev,int phy,int reg,int val)100 mtkswitch_phy_write(device_t dev, int phy, int reg, int val)
101 {
102 struct mtkswitch_softc *sc = device_get_softc(dev);
103 int res;
104
105 if ((phy < 0 || phy >= 32) || (reg < 0 || reg >= 32))
106 return (ENXIO);
107
108 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
109 MTKSWITCH_LOCK(sc);
110 res = mtkswitch_phy_write_locked(sc, phy, reg, val);
111 MTKSWITCH_UNLOCK(sc);
112
113 return (res);
114 }
115
116 static uint32_t
mtkswitch_reg_read32(struct mtkswitch_softc * sc,int reg)117 mtkswitch_reg_read32(struct mtkswitch_softc *sc, int reg)
118 {
119
120 return (MTKSWITCH_READ(sc, reg));
121 }
122
123 static uint32_t
mtkswitch_reg_write32(struct mtkswitch_softc * sc,int reg,uint32_t val)124 mtkswitch_reg_write32(struct mtkswitch_softc *sc, int reg, uint32_t val)
125 {
126
127 MTKSWITCH_WRITE(sc, reg, val);
128 return (0);
129 }
130
131 static uint32_t
mtkswitch_reg_read32_mt7621(struct mtkswitch_softc * sc,int reg)132 mtkswitch_reg_read32_mt7621(struct mtkswitch_softc *sc, int reg)
133 {
134 uint32_t low, hi;
135
136 mtkswitch_phy_write_locked(sc, MTKSWITCH_GLOBAL_PHY,
137 MTKSWITCH_GLOBAL_REG, MTKSWITCH_REG_ADDR(reg));
138 low = mtkswitch_phy_read_locked(sc, MTKSWITCH_GLOBAL_PHY,
139 MTKSWITCH_REG_LO(reg));
140 hi = mtkswitch_phy_read_locked(sc, MTKSWITCH_GLOBAL_PHY,
141 MTKSWITCH_REG_HI(reg));
142 return (low | (hi << 16));
143 }
144
145 static uint32_t
mtkswitch_reg_write32_mt7621(struct mtkswitch_softc * sc,int reg,uint32_t val)146 mtkswitch_reg_write32_mt7621(struct mtkswitch_softc *sc, int reg, uint32_t val)
147 {
148
149 mtkswitch_phy_write_locked(sc, MTKSWITCH_GLOBAL_PHY,
150 MTKSWITCH_GLOBAL_REG, MTKSWITCH_REG_ADDR(reg));
151 mtkswitch_phy_write_locked(sc, MTKSWITCH_GLOBAL_PHY,
152 MTKSWITCH_REG_LO(reg), MTKSWITCH_VAL_LO(val));
153 mtkswitch_phy_write_locked(sc, MTKSWITCH_GLOBAL_PHY,
154 MTKSWITCH_REG_HI(reg), MTKSWITCH_VAL_HI(val));
155 return (0);
156 }
157
158 static int
mtkswitch_reg_read(device_t dev,int reg)159 mtkswitch_reg_read(device_t dev, int reg)
160 {
161 struct mtkswitch_softc *sc = device_get_softc(dev);
162 uint32_t val;
163
164 val = sc->hal.mtkswitch_read(sc, MTKSWITCH_REG32(reg));
165 if (MTKSWITCH_IS_HI16(reg))
166 return (MTKSWITCH_HI16(val));
167 return (MTKSWITCH_LO16(val));
168 }
169
170 static int
mtkswitch_reg_write(device_t dev,int reg,int val)171 mtkswitch_reg_write(device_t dev, int reg, int val)
172 {
173 struct mtkswitch_softc *sc = device_get_softc(dev);
174 uint32_t tmp;
175
176 tmp = sc->hal.mtkswitch_read(sc, MTKSWITCH_REG32(reg));
177 if (MTKSWITCH_IS_HI16(reg)) {
178 tmp &= MTKSWITCH_LO16_MSK;
179 tmp |= MTKSWITCH_TO_HI16(val);
180 } else {
181 tmp &= MTKSWITCH_HI16_MSK;
182 tmp |= MTKSWITCH_TO_LO16(val);
183 }
184 sc->hal.mtkswitch_write(sc, MTKSWITCH_REG32(reg), tmp);
185
186 return (0);
187 }
188
189 static int
mtkswitch_reset(struct mtkswitch_softc * sc)190 mtkswitch_reset(struct mtkswitch_softc *sc)
191 {
192
193 /* We don't reset the switch for now */
194 return (0);
195 }
196
197 static int
mtkswitch_hw_setup(struct mtkswitch_softc * sc)198 mtkswitch_hw_setup(struct mtkswitch_softc *sc)
199 {
200
201 /*
202 * TODO: parse the device tree and see if we need to configure
203 * ports, etc. differently. For now we fallback to defaults.
204 */
205
206 /* Called early and hence unlocked */
207 return (0);
208 }
209
210 static int
mtkswitch_hw_global_setup(struct mtkswitch_softc * sc)211 mtkswitch_hw_global_setup(struct mtkswitch_softc *sc)
212 {
213 /* Currently does nothing */
214
215 /* Called early and hence unlocked */
216 return (0);
217 }
218
219 static void
mtkswitch_port_init(struct mtkswitch_softc * sc,int port)220 mtkswitch_port_init(struct mtkswitch_softc *sc, int port)
221 {
222 uint32_t val;
223
224 /* Called early and hence unlocked */
225
226 /* Set the port to secure mode */
227 val = sc->hal.mtkswitch_read(sc, MTKSWITCH_PCR(port));
228 val |= PCR_PORT_VLAN_SECURE;
229 sc->hal.mtkswitch_write(sc, MTKSWITCH_PCR(port), val);
230
231 /* Set port's vlan_attr to user port */
232 val = sc->hal.mtkswitch_read(sc, MTKSWITCH_PVC(port));
233 val &= ~PVC_VLAN_ATTR_MASK;
234 sc->hal.mtkswitch_write(sc, MTKSWITCH_PVC(port), val);
235
236 val = PMCR_CFG_DEFAULT;
237 if (port == sc->cpuport)
238 val |= PMCR_FORCE_LINK | PMCR_FORCE_DPX | PMCR_FORCE_SPD_1000 |
239 PMCR_FORCE_MODE;
240 /* Set port's MAC to default settings */
241 sc->hal.mtkswitch_write(sc, MTKSWITCH_PMCR(port), val);
242 }
243
244 static uint32_t
mtkswitch_get_port_status(struct mtkswitch_softc * sc,int port)245 mtkswitch_get_port_status(struct mtkswitch_softc *sc, int port)
246 {
247 uint32_t val, res, tmp;
248
249 MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
250 res = 0;
251 val = sc->hal.mtkswitch_read(sc, MTKSWITCH_PMSR(port));
252
253 if (val & PMSR_MAC_LINK_STS)
254 res |= MTKSWITCH_LINK_UP;
255 if (val & PMSR_MAC_DPX_STS)
256 res |= MTKSWITCH_DUPLEX;
257 tmp = PMSR_MAC_SPD(val);
258 if (tmp == 0)
259 res |= MTKSWITCH_SPEED_10;
260 else if (tmp == 1)
261 res |= MTKSWITCH_SPEED_100;
262 else if (tmp == 2)
263 res |= MTKSWITCH_SPEED_1000;
264 if (val & PMSR_TX_FC_STS)
265 res |= MTKSWITCH_TXFLOW;
266 if (val & PMSR_RX_FC_STS)
267 res |= MTKSWITCH_RXFLOW;
268
269 return (res);
270 }
271
272 static int
mtkswitch_atu_flush(struct mtkswitch_softc * sc)273 mtkswitch_atu_flush(struct mtkswitch_softc *sc)
274 {
275
276 MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
277
278 /* Flush all non-static MAC addresses */
279 while (sc->hal.mtkswitch_read(sc, MTKSWITCH_ATC) & ATC_BUSY);
280 sc->hal.mtkswitch_write(sc, MTKSWITCH_ATC, ATC_BUSY |
281 ATC_AC_MAT_NON_STATIC_MACS | ATC_AC_CMD_CLEAN);
282 while (sc->hal.mtkswitch_read(sc, MTKSWITCH_ATC) & ATC_BUSY);
283
284 return (0);
285 }
286
287 static int
mtkswitch_port_vlan_setup(struct mtkswitch_softc * sc,etherswitch_port_t * p)288 mtkswitch_port_vlan_setup(struct mtkswitch_softc *sc, etherswitch_port_t *p)
289 {
290 int err;
291
292 /*
293 * Port behaviour wrt tag/untag/stack is currently defined per-VLAN.
294 * So we say we don't support it here.
295 */
296 if ((p->es_flags & (ETHERSWITCH_PORT_DOUBLE_TAG |
297 ETHERSWITCH_PORT_ADDTAG | ETHERSWITCH_PORT_STRIPTAG)) != 0)
298 return (ENOTSUP);
299
300 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
301 MTKSWITCH_LOCK(sc);
302
303 /* Set the PVID */
304 if (p->es_pvid != 0) {
305 err = sc->hal.mtkswitch_vlan_set_pvid(sc, p->es_port,
306 p->es_pvid);
307 if (err != 0) {
308 MTKSWITCH_UNLOCK(sc);
309 return (err);
310 }
311 }
312
313 MTKSWITCH_UNLOCK(sc);
314
315 return (0);
316 }
317
318 static int
mtkswitch_port_vlan_get(struct mtkswitch_softc * sc,etherswitch_port_t * p)319 mtkswitch_port_vlan_get(struct mtkswitch_softc *sc, etherswitch_port_t *p)
320 {
321
322 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
323 MTKSWITCH_LOCK(sc);
324
325 /* Retrieve the PVID */
326 sc->hal.mtkswitch_vlan_get_pvid(sc, p->es_port, &p->es_pvid);
327
328 /*
329 * Port flags are not supported at the moment.
330 * Port's tag/untag/stack behaviour is defined per-VLAN.
331 */
332 p->es_flags = 0;
333
334 MTKSWITCH_UNLOCK(sc);
335
336 return (0);
337 }
338
339 static void
mtkswitch_invalidate_vlan(struct mtkswitch_softc * sc,uint32_t vid)340 mtkswitch_invalidate_vlan(struct mtkswitch_softc *sc, uint32_t vid)
341 {
342
343 while (sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR) & VTCR_BUSY);
344 sc->hal.mtkswitch_write(sc, MTKSWITCH_VTCR, VTCR_BUSY |
345 VTCR_FUNC_VID_INVALID | (vid & VTCR_VID_MASK));
346 while (sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR) & VTCR_BUSY);
347 }
348
349 static void
mtkswitch_vlan_init_hw(struct mtkswitch_softc * sc)350 mtkswitch_vlan_init_hw(struct mtkswitch_softc *sc)
351 {
352 uint32_t val, vid, i;
353
354 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
355 MTKSWITCH_LOCK(sc);
356 /* Reset all VLANs to defaults first */
357 for (i = 0; i < sc->info.es_nvlangroups; i++) {
358 mtkswitch_invalidate_vlan(sc, i);
359 if (sc->sc_switchtype == MTK_SWITCH_MT7620) {
360 val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VTIM(i));
361 val &= ~(VTIM_MASK << VTIM_OFF(i));
362 val |= ((i + 1) << VTIM_OFF(i));
363 sc->hal.mtkswitch_write(sc, MTKSWITCH_VTIM(i), val);
364 }
365 }
366
367 /* Now, add all ports as untagged members of VLAN 1 */
368 if (sc->sc_switchtype == MTK_SWITCH_MT7620) {
369 /* MT7620 uses vid index instead of actual vid */
370 vid = 0;
371 } else {
372 /* MT7621 uses the vid itself */
373 vid = 1;
374 }
375 val = VAWD1_IVL_MAC | VAWD1_VTAG_EN | VAWD1_VALID;
376 for (i = 0; i < sc->info.es_nports; i++)
377 val |= VAWD1_PORT_MEMBER(i);
378 sc->hal.mtkswitch_write(sc, MTKSWITCH_VAWD1, val);
379 sc->hal.mtkswitch_write(sc, MTKSWITCH_VAWD2, 0);
380 val = VTCR_BUSY | VTCR_FUNC_VID_WRITE | vid;
381 sc->hal.mtkswitch_write(sc, MTKSWITCH_VTCR, val);
382
383 /* Set all port PVIDs to 1 */
384 for (i = 0; i < sc->info.es_nports; i++) {
385 sc->hal.mtkswitch_vlan_set_pvid(sc, i, 1);
386 }
387
388 MTKSWITCH_UNLOCK(sc);
389 }
390
391 static int
mtkswitch_vlan_getvgroup(struct mtkswitch_softc * sc,etherswitch_vlangroup_t * v)392 mtkswitch_vlan_getvgroup(struct mtkswitch_softc *sc, etherswitch_vlangroup_t *v)
393 {
394 uint32_t val, i;
395
396 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
397
398 if ((sc->vlan_mode != ETHERSWITCH_VLAN_DOT1Q) ||
399 (v->es_vlangroup > sc->info.es_nvlangroups))
400 return (EINVAL);
401
402 /* Reset the member ports. */
403 v->es_untagged_ports = 0;
404 v->es_member_ports = 0;
405
406 /* Not supported for now */
407 v->es_fid = 0;
408
409 MTKSWITCH_LOCK(sc);
410 if (sc->sc_switchtype == MTK_SWITCH_MT7620) {
411 v->es_vid = (sc->hal.mtkswitch_read(sc,
412 MTKSWITCH_VTIM(v->es_vlangroup)) >>
413 VTIM_OFF(v->es_vlangroup)) & VTIM_MASK;
414 } else {
415 v->es_vid = v->es_vlangroup;
416 }
417
418 while (sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR) & VTCR_BUSY);
419 sc->hal.mtkswitch_write(sc, MTKSWITCH_VTCR, VTCR_BUSY |
420 VTCR_FUNC_VID_READ | (v->es_vlangroup & VTCR_VID_MASK));
421 while ((val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR)) & VTCR_BUSY);
422 if (val & VTCR_IDX_INVALID) {
423 MTKSWITCH_UNLOCK(sc);
424 return (0);
425 }
426
427 val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VAWD1);
428 if (val & VAWD1_VALID)
429 v->es_vid |= ETHERSWITCH_VID_VALID;
430 else {
431 MTKSWITCH_UNLOCK(sc);
432 return (0);
433 }
434 v->es_member_ports = (val >> VAWD1_MEMBER_OFF) & VAWD1_MEMBER_MASK;
435
436 val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VAWD2);
437 for (i = 0; i < sc->info.es_nports; i++) {
438 if ((val & VAWD2_PORT_MASK(i)) == VAWD2_PORT_UNTAGGED(i))
439 v->es_untagged_ports |= (1<<i);
440 }
441
442 MTKSWITCH_UNLOCK(sc);
443 return (0);
444 }
445
446 static int
mtkswitch_vlan_setvgroup(struct mtkswitch_softc * sc,etherswitch_vlangroup_t * v)447 mtkswitch_vlan_setvgroup(struct mtkswitch_softc *sc, etherswitch_vlangroup_t *v)
448 {
449 uint32_t val, i, vid;
450
451 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
452
453 if ((sc->vlan_mode != ETHERSWITCH_VLAN_DOT1Q) ||
454 (v->es_vlangroup > sc->info.es_nvlangroups))
455 return (EINVAL);
456
457 /* We currently don't support FID */
458 if (v->es_fid != 0)
459 return (EINVAL);
460
461 MTKSWITCH_LOCK(sc);
462 while (sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR) & VTCR_BUSY);
463 if (sc->sc_switchtype == MTK_SWITCH_MT7620) {
464 val = sc->hal.mtkswitch_read(sc,
465 MTKSWITCH_VTIM(v->es_vlangroup));
466 val &= ~(VTIM_MASK << VTIM_OFF(v->es_vlangroup));
467 val |= ((v->es_vid & VTIM_MASK) << VTIM_OFF(v->es_vlangroup));
468 sc->hal.mtkswitch_write(sc, MTKSWITCH_VTIM(v->es_vlangroup),
469 val);
470 vid = v->es_vlangroup;
471 } else
472 vid = v->es_vid;
473
474 /* We use FID 0 */
475 val = VAWD1_IVL_MAC | VAWD1_VTAG_EN | VAWD1_VALID;
476 val |= ((v->es_member_ports & VAWD1_MEMBER_MASK) << VAWD1_MEMBER_OFF);
477 sc->hal.mtkswitch_write(sc, MTKSWITCH_VAWD1, val);
478
479 /* Set tagged ports */
480 val = 0;
481 for (i = 0; i < sc->info.es_nports; i++)
482 if (((1<<i) & v->es_untagged_ports) == 0)
483 val |= VAWD2_PORT_TAGGED(i);
484 sc->hal.mtkswitch_write(sc, MTKSWITCH_VAWD2, val);
485
486 /* Write the VLAN entry */
487 sc->hal.mtkswitch_write(sc, MTKSWITCH_VTCR, VTCR_BUSY |
488 VTCR_FUNC_VID_WRITE | (vid & VTCR_VID_MASK));
489 while ((val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR)) & VTCR_BUSY);
490
491 MTKSWITCH_UNLOCK(sc);
492
493 if (val & VTCR_IDX_INVALID)
494 return (EINVAL);
495
496 return (0);
497 }
498
499 static int
mtkswitch_vlan_get_pvid(struct mtkswitch_softc * sc,int port,int * pvid)500 mtkswitch_vlan_get_pvid(struct mtkswitch_softc *sc, int port, int *pvid)
501 {
502
503 MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
504
505 *pvid = sc->hal.mtkswitch_read(sc, MTKSWITCH_PPBV1(port));
506 *pvid = PPBV_VID_FROM_REG(*pvid);
507
508 return (0);
509 }
510
511 static int
mtkswitch_vlan_set_pvid(struct mtkswitch_softc * sc,int port,int pvid)512 mtkswitch_vlan_set_pvid(struct mtkswitch_softc *sc, int port, int pvid)
513 {
514 uint32_t val;
515
516 MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
517 val = PPBV_VID(pvid & PPBV_VID_MASK);
518 sc->hal.mtkswitch_write(sc, MTKSWITCH_PPBV1(port), val);
519 sc->hal.mtkswitch_write(sc, MTKSWITCH_PPBV2(port), val);
520
521 return (0);
522 }
523
524 extern void
mtk_attach_switch_mt7620(struct mtkswitch_softc * sc)525 mtk_attach_switch_mt7620(struct mtkswitch_softc *sc)
526 {
527
528 sc->portmap = 0x7f;
529 sc->phymap = 0x1f;
530
531 sc->info.es_nports = 7;
532 sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q;
533 sc->info.es_nvlangroups = 16;
534 sprintf(sc->info.es_name, "Mediatek GSW");
535
536 if (sc->sc_switchtype == MTK_SWITCH_MT7621) {
537 sc->hal.mtkswitch_read = mtkswitch_reg_read32_mt7621;
538 sc->hal.mtkswitch_write = mtkswitch_reg_write32_mt7621;
539 sc->info.es_nvlangroups = 4096;
540 } else {
541 sc->hal.mtkswitch_read = mtkswitch_reg_read32;
542 sc->hal.mtkswitch_write = mtkswitch_reg_write32;
543 }
544
545 sc->hal.mtkswitch_reset = mtkswitch_reset;
546 sc->hal.mtkswitch_hw_setup = mtkswitch_hw_setup;
547 sc->hal.mtkswitch_hw_global_setup = mtkswitch_hw_global_setup;
548 sc->hal.mtkswitch_port_init = mtkswitch_port_init;
549 sc->hal.mtkswitch_get_port_status = mtkswitch_get_port_status;
550 sc->hal.mtkswitch_atu_flush = mtkswitch_atu_flush;
551 sc->hal.mtkswitch_port_vlan_setup = mtkswitch_port_vlan_setup;
552 sc->hal.mtkswitch_port_vlan_get = mtkswitch_port_vlan_get;
553 sc->hal.mtkswitch_vlan_init_hw = mtkswitch_vlan_init_hw;
554 sc->hal.mtkswitch_vlan_getvgroup = mtkswitch_vlan_getvgroup;
555 sc->hal.mtkswitch_vlan_setvgroup = mtkswitch_vlan_setvgroup;
556 sc->hal.mtkswitch_vlan_get_pvid = mtkswitch_vlan_get_pvid;
557 sc->hal.mtkswitch_vlan_set_pvid = mtkswitch_vlan_set_pvid;
558 sc->hal.mtkswitch_phy_read = mtkswitch_phy_read;
559 sc->hal.mtkswitch_phy_write = mtkswitch_phy_write;
560 sc->hal.mtkswitch_reg_read = mtkswitch_reg_read;
561 sc->hal.mtkswitch_reg_write = mtkswitch_reg_write;
562 }
563