2 * Copyright (c) 2016 Stanislav Galabov.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
29 #include <sys/param.h>
31 #include <sys/errno.h>
32 #include <sys/kernel.h>
34 #include <sys/malloc.h>
35 #include <sys/module.h>
36 #include <sys/mutex.h>
38 #include <sys/socket.h>
39 #include <sys/sockio.h>
40 #include <sys/sysctl.h>
41 #include <sys/systm.h>
44 #include <net/if_var.h>
45 #include <net/ethernet.h>
46 #include <net/if_media.h>
47 #include <net/if_types.h>
49 #include <machine/bus.h>
50 #include <dev/mii/mii.h>
51 #include <dev/mii/miivar.h>
52 #include <dev/mdio/mdio.h>
54 #include <dev/etherswitch/etherswitch.h>
55 #include <dev/etherswitch/mtkswitch/mtkswitchvar.h>
56 #include <dev/etherswitch/mtkswitch/mtkswitch_mt7620.h>
59 mtkswitch_phy_read_locked(struct mtkswitch_softc *sc, int phy, int reg)
63 MTKSWITCH_WRITE(sc, MTKSWITCH_PIAC, PIAC_PHY_ACS_ST | PIAC_MDIO_ST |
64 (reg << PIAC_MDIO_REG_ADDR_OFF) | (phy << PIAC_MDIO_PHY_ADDR_OFF) |
66 while ((data = MTKSWITCH_READ(sc, MTKSWITCH_PIAC)) & PIAC_PHY_ACS_ST);
68 return ((int)(data & PIAC_MDIO_RW_DATA_MASK));
72 mtkswitch_phy_read(device_t dev, int phy, int reg)
74 struct mtkswitch_softc *sc = device_get_softc(dev);
77 if ((phy < 0 || phy >= 32) || (reg < 0 || reg >= 32))
80 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
82 data = mtkswitch_phy_read_locked(sc, phy, reg);
89 mtkswitch_phy_write_locked(struct mtkswitch_softc *sc, int phy, int reg,
93 MTKSWITCH_WRITE(sc, MTKSWITCH_PIAC, PIAC_PHY_ACS_ST | PIAC_MDIO_ST |
94 (reg << PIAC_MDIO_REG_ADDR_OFF) | (phy << PIAC_MDIO_PHY_ADDR_OFF) |
95 (val & PIAC_MDIO_RW_DATA_MASK) | PIAC_MDIO_CMD_WRITE);
96 while (MTKSWITCH_READ(sc, MTKSWITCH_PIAC) & PIAC_PHY_ACS_ST);
102 mtkswitch_phy_write(device_t dev, int phy, int reg, int val)
104 struct mtkswitch_softc *sc = device_get_softc(dev);
107 if ((phy < 0 || phy >= 32) || (reg < 0 || reg >= 32))
110 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
112 res = mtkswitch_phy_write_locked(sc, phy, reg, val);
113 MTKSWITCH_UNLOCK(sc);
119 mtkswitch_reg_read32(struct mtkswitch_softc *sc, int reg)
122 return (MTKSWITCH_READ(sc, reg));
126 mtkswitch_reg_write32(struct mtkswitch_softc *sc, int reg, uint32_t val)
129 MTKSWITCH_WRITE(sc, reg, val);
134 mtkswitch_reg_read32_mt7621(struct mtkswitch_softc *sc, int reg)
138 mtkswitch_phy_write_locked(sc, MTKSWITCH_GLOBAL_PHY,
139 MTKSWITCH_GLOBAL_REG, MTKSWITCH_REG_ADDR(reg));
140 low = mtkswitch_phy_read_locked(sc, MTKSWITCH_GLOBAL_PHY,
141 MTKSWITCH_REG_LO(reg));
142 hi = mtkswitch_phy_read_locked(sc, MTKSWITCH_GLOBAL_PHY,
143 MTKSWITCH_REG_HI(reg));;
144 return (low | (hi << 16));
148 mtkswitch_reg_write32_mt7621(struct mtkswitch_softc *sc, int reg, uint32_t val)
151 mtkswitch_phy_write_locked(sc, MTKSWITCH_GLOBAL_PHY,
152 MTKSWITCH_GLOBAL_REG, MTKSWITCH_REG_ADDR(reg));
153 mtkswitch_phy_write_locked(sc, MTKSWITCH_GLOBAL_PHY,
154 MTKSWITCH_REG_LO(reg), MTKSWITCH_VAL_LO(val));
155 mtkswitch_phy_write_locked(sc, MTKSWITCH_GLOBAL_PHY,
156 MTKSWITCH_REG_HI(reg), MTKSWITCH_VAL_HI(val));
161 mtkswitch_reg_read(device_t dev, int reg)
163 struct mtkswitch_softc *sc = device_get_softc(dev);
166 val = sc->hal.mtkswitch_read(sc, MTKSWITCH_REG32(reg));
167 if (MTKSWITCH_IS_HI16(reg))
168 return (MTKSWITCH_HI16(val));
169 return (MTKSWITCH_LO16(val));
173 mtkswitch_reg_write(device_t dev, int reg, int val)
175 struct mtkswitch_softc *sc = device_get_softc(dev);
178 tmp = sc->hal.mtkswitch_read(sc, MTKSWITCH_REG32(reg));
179 if (MTKSWITCH_IS_HI16(reg)) {
180 tmp &= MTKSWITCH_LO16_MSK;
181 tmp |= MTKSWITCH_TO_HI16(val);
183 tmp &= MTKSWITCH_HI16_MSK;
184 tmp |= MTKSWITCH_TO_LO16(val);
186 sc->hal.mtkswitch_write(sc, MTKSWITCH_REG32(reg), tmp);
192 mtkswitch_reset(struct mtkswitch_softc *sc)
195 /* We don't reset the switch for now */
200 mtkswitch_hw_setup(struct mtkswitch_softc *sc)
204 * TODO: parse the device tree and see if we need to configure
205 * ports, etc. differently. For now we fallback to defaults.
208 /* Called early and hence unlocked */
213 mtkswitch_hw_global_setup(struct mtkswitch_softc *sc)
215 /* Currently does nothing */
217 /* Called early and hence unlocked */
222 mtkswitch_port_init(struct mtkswitch_softc *sc, int port)
226 /* Called early and hence unlocked */
228 /* Set the port to secure mode */
229 val = sc->hal.mtkswitch_read(sc, MTKSWITCH_PCR(port));
230 val |= PCR_PORT_VLAN_SECURE;
231 sc->hal.mtkswitch_write(sc, MTKSWITCH_PCR(port), val);
233 /* Set port's vlan_attr to user port */
234 val = sc->hal.mtkswitch_read(sc, MTKSWITCH_PVC(port));
235 val &= ~PVC_VLAN_ATTR_MASK;
236 sc->hal.mtkswitch_write(sc, MTKSWITCH_PVC(port), val);
238 val = PMCR_CFG_DEFAULT;
239 if (port == sc->cpuport)
240 val |= PMCR_FORCE_LINK | PMCR_FORCE_DPX | PMCR_FORCE_SPD_1000 |
242 /* Set port's MAC to default settings */
243 sc->hal.mtkswitch_write(sc, MTKSWITCH_PMCR(port), val);
247 mtkswitch_get_port_status(struct mtkswitch_softc *sc, int port)
249 uint32_t val, res, tmp;
251 MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
253 val = sc->hal.mtkswitch_read(sc, MTKSWITCH_PMSR(port));
255 if (val & PMSR_MAC_LINK_STS)
256 res |= MTKSWITCH_LINK_UP;
257 if (val & PMSR_MAC_DPX_STS)
258 res |= MTKSWITCH_DUPLEX;
259 tmp = PMSR_MAC_SPD(val);
261 res |= MTKSWITCH_SPEED_10;
263 res |= MTKSWITCH_SPEED_100;
265 res |= MTKSWITCH_SPEED_1000;
266 if (val & PMSR_TX_FC_STS)
267 res |= MTKSWITCH_TXFLOW;
268 if (val & PMSR_RX_FC_STS)
269 res |= MTKSWITCH_RXFLOW;
275 mtkswitch_atu_flush(struct mtkswitch_softc *sc)
278 MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
280 /* Flush all non-static MAC addresses */
281 while (sc->hal.mtkswitch_read(sc, MTKSWITCH_ATC) & ATC_BUSY);
282 sc->hal.mtkswitch_write(sc, MTKSWITCH_ATC, ATC_BUSY |
283 ATC_AC_MAT_NON_STATIC_MACS | ATC_AC_CMD_CLEAN);
284 while (sc->hal.mtkswitch_read(sc, MTKSWITCH_ATC) & ATC_BUSY);
290 mtkswitch_port_vlan_setup(struct mtkswitch_softc *sc, etherswitch_port_t *p)
295 * Port behaviour wrt tag/untag/stack is currently defined per-VLAN.
296 * So we say we don't support it here.
298 if ((p->es_flags & (ETHERSWITCH_PORT_DOUBLE_TAG |
299 ETHERSWITCH_PORT_ADDTAG | ETHERSWITCH_PORT_STRIPTAG)) != 0)
302 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
306 if (p->es_pvid != 0) {
307 err = sc->hal.mtkswitch_vlan_set_pvid(sc, p->es_port,
310 MTKSWITCH_UNLOCK(sc);
315 MTKSWITCH_UNLOCK(sc);
321 mtkswitch_port_vlan_get(struct mtkswitch_softc *sc, etherswitch_port_t *p)
324 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
327 /* Retrieve the PVID */
328 sc->hal.mtkswitch_vlan_get_pvid(sc, p->es_port, &p->es_pvid);
331 * Port flags are not supported at the moment.
332 * Port's tag/untag/stack behaviour is defined per-VLAN.
336 MTKSWITCH_UNLOCK(sc);
342 mtkswitch_invalidate_vlan(struct mtkswitch_softc *sc, uint32_t vid)
345 while (sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR) & VTCR_BUSY);
346 sc->hal.mtkswitch_write(sc, MTKSWITCH_VTCR, VTCR_BUSY |
347 VTCR_FUNC_VID_INVALID | (vid & VTCR_VID_MASK));
348 while (sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR) & VTCR_BUSY);
352 mtkswitch_vlan_init_hw(struct mtkswitch_softc *sc)
354 uint32_t val, vid, i;
356 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
358 /* Reset all VLANs to defaults first */
359 for (i = 0; i < sc->info.es_nvlangroups; i++) {
360 mtkswitch_invalidate_vlan(sc, i);
361 if (sc->sc_switchtype == MTK_SWITCH_MT7620) {
362 val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VTIM(i));
363 val &= ~(VTIM_MASK << VTIM_OFF(i));
364 val |= ((i + 1) << VTIM_OFF(i));
365 sc->hal.mtkswitch_write(sc, MTKSWITCH_VTIM(i), val);
369 /* Now, add all ports as untagged members of VLAN 1 */
370 if (sc->sc_switchtype == MTK_SWITCH_MT7620) {
371 /* MT7620 uses vid index instead of actual vid */
374 /* MT7621 uses the vid itself */
377 val = VAWD1_IVL_MAC | VAWD1_VTAG_EN | VAWD1_VALID;
378 for (i = 0; i < sc->info.es_nports; i++)
379 val |= VAWD1_PORT_MEMBER(i);
380 sc->hal.mtkswitch_write(sc, MTKSWITCH_VAWD1, val);
381 sc->hal.mtkswitch_write(sc, MTKSWITCH_VAWD2, 0);
382 val = VTCR_BUSY | VTCR_FUNC_VID_WRITE | vid;
383 sc->hal.mtkswitch_write(sc, MTKSWITCH_VTCR, val);
385 /* Set all port PVIDs to 1 */
386 for (i = 0; i < sc->info.es_nports; i++) {
387 sc->hal.mtkswitch_vlan_set_pvid(sc, i, 1);
390 MTKSWITCH_UNLOCK(sc);
394 mtkswitch_vlan_getvgroup(struct mtkswitch_softc *sc, etherswitch_vlangroup_t *v)
398 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
400 if ((sc->vlan_mode != ETHERSWITCH_VLAN_DOT1Q) ||
401 (v->es_vlangroup > sc->info.es_nvlangroups))
404 /* Reset the member ports. */
405 v->es_untagged_ports = 0;
406 v->es_member_ports = 0;
408 /* Not supported for now */
412 if (sc->sc_switchtype == MTK_SWITCH_MT7620) {
413 v->es_vid = (sc->hal.mtkswitch_read(sc,
414 MTKSWITCH_VTIM(v->es_vlangroup)) >>
415 VTIM_OFF(v->es_vlangroup)) & VTIM_MASK;
417 v->es_vid = v->es_vlangroup;
420 while (sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR) & VTCR_BUSY);
421 sc->hal.mtkswitch_write(sc, MTKSWITCH_VTCR, VTCR_BUSY |
422 VTCR_FUNC_VID_READ | (v->es_vlangroup & VTCR_VID_MASK));
423 while ((val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR)) & VTCR_BUSY);
424 if (val & VTCR_IDX_INVALID) {
425 MTKSWITCH_UNLOCK(sc);
429 val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VAWD1);
430 if (val & VAWD1_VALID)
431 v->es_vid |= ETHERSWITCH_VID_VALID;
433 MTKSWITCH_UNLOCK(sc);
436 v->es_member_ports = (val >> VAWD1_MEMBER_OFF) & VAWD1_MEMBER_MASK;
438 val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VAWD2);
439 for (i = 0; i < sc->info.es_nports; i++) {
440 if ((val & VAWD2_PORT_MASK(i)) == VAWD2_PORT_UNTAGGED(i))
441 v->es_untagged_ports |= (1<<i);
444 MTKSWITCH_UNLOCK(sc);
449 mtkswitch_vlan_setvgroup(struct mtkswitch_softc *sc, etherswitch_vlangroup_t *v)
451 uint32_t val, i, vid;
453 MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
455 if ((sc->vlan_mode != ETHERSWITCH_VLAN_DOT1Q) ||
456 (v->es_vlangroup > sc->info.es_nvlangroups))
459 /* We currently don't support FID */
464 while (sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR) & VTCR_BUSY);
465 if (sc->sc_switchtype == MTK_SWITCH_MT7620) {
466 val = sc->hal.mtkswitch_read(sc,
467 MTKSWITCH_VTIM(v->es_vlangroup));
468 val &= ~(VTIM_MASK << VTIM_OFF(v->es_vlangroup));
469 val |= ((v->es_vid & VTIM_MASK) << VTIM_OFF(v->es_vlangroup));
470 sc->hal.mtkswitch_write(sc, MTKSWITCH_VTIM(v->es_vlangroup),
472 vid = v->es_vlangroup;
477 val = VAWD1_IVL_MAC | VAWD1_VTAG_EN | VAWD1_VALID;
478 val |= ((v->es_member_ports & VAWD1_MEMBER_MASK) << VAWD1_MEMBER_OFF);
479 sc->hal.mtkswitch_write(sc, MTKSWITCH_VAWD1, val);
481 /* Set tagged ports */
483 for (i = 0; i < sc->info.es_nports; i++)
484 if (((1<<i) & v->es_untagged_ports) == 0)
485 val |= VAWD2_PORT_TAGGED(i);
486 sc->hal.mtkswitch_write(sc, MTKSWITCH_VAWD2, val);
488 /* Write the VLAN entry */
489 sc->hal.mtkswitch_write(sc, MTKSWITCH_VTCR, VTCR_BUSY |
490 VTCR_FUNC_VID_WRITE | (vid & VTCR_VID_MASK));
491 while ((val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR)) & VTCR_BUSY);
493 MTKSWITCH_UNLOCK(sc);
495 if (val & VTCR_IDX_INVALID)
502 mtkswitch_vlan_get_pvid(struct mtkswitch_softc *sc, int port, int *pvid)
505 MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
507 *pvid = sc->hal.mtkswitch_read(sc, MTKSWITCH_PPBV1(port));
508 *pvid = PPBV_VID_FROM_REG(*pvid);
514 mtkswitch_vlan_set_pvid(struct mtkswitch_softc *sc, int port, int pvid)
518 MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
519 val = PPBV_VID(pvid & PPBV_VID_MASK);
520 sc->hal.mtkswitch_write(sc, MTKSWITCH_PPBV1(port), val);
521 sc->hal.mtkswitch_write(sc, MTKSWITCH_PPBV2(port), val);
527 mtk_attach_switch_mt7620(struct mtkswitch_softc *sc)
533 sc->info.es_nports = 7;
534 sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q;
535 sc->info.es_nvlangroups = 16;
536 sprintf(sc->info.es_name, "Mediatek GSW");
538 if (sc->sc_switchtype == MTK_SWITCH_MT7621) {
539 sc->hal.mtkswitch_read = mtkswitch_reg_read32_mt7621;
540 sc->hal.mtkswitch_write = mtkswitch_reg_write32_mt7621;
541 sc->info.es_nvlangroups = 4096;
543 sc->hal.mtkswitch_read = mtkswitch_reg_read32;
544 sc->hal.mtkswitch_write = mtkswitch_reg_write32;
547 sc->hal.mtkswitch_reset = mtkswitch_reset;
548 sc->hal.mtkswitch_hw_setup = mtkswitch_hw_setup;
549 sc->hal.mtkswitch_hw_global_setup = mtkswitch_hw_global_setup;
550 sc->hal.mtkswitch_port_init = mtkswitch_port_init;
551 sc->hal.mtkswitch_get_port_status = mtkswitch_get_port_status;
552 sc->hal.mtkswitch_atu_flush = mtkswitch_atu_flush;
553 sc->hal.mtkswitch_port_vlan_setup = mtkswitch_port_vlan_setup;
554 sc->hal.mtkswitch_port_vlan_get = mtkswitch_port_vlan_get;
555 sc->hal.mtkswitch_vlan_init_hw = mtkswitch_vlan_init_hw;
556 sc->hal.mtkswitch_vlan_getvgroup = mtkswitch_vlan_getvgroup;
557 sc->hal.mtkswitch_vlan_setvgroup = mtkswitch_vlan_setvgroup;
558 sc->hal.mtkswitch_vlan_get_pvid = mtkswitch_vlan_get_pvid;
559 sc->hal.mtkswitch_vlan_set_pvid = mtkswitch_vlan_set_pvid;
560 sc->hal.mtkswitch_phy_read = mtkswitch_phy_read;
561 sc->hal.mtkswitch_phy_write = mtkswitch_phy_write;
562 sc->hal.mtkswitch_reg_read = mtkswitch_reg_read;
563 sc->hal.mtkswitch_reg_write = mtkswitch_reg_write;