2 * Copyright (c) 2011-2012 Stefan Bethke.
3 * Copyright (c) 2014 Adrian Chadd.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/param.h>
32 #include <sys/errno.h>
33 #include <sys/kernel.h>
34 #include <sys/module.h>
35 #include <sys/socket.h>
36 #include <sys/sockio.h>
37 #include <sys/sysctl.h>
38 #include <sys/systm.h>
41 #include <net/if_arp.h>
42 #include <net/ethernet.h>
43 #include <net/if_dl.h>
44 #include <net/if_media.h>
45 #include <net/if_types.h>
47 #include <machine/bus.h>
48 #include <dev/iicbus/iic.h>
49 #include <dev/iicbus/iiconf.h>
50 #include <dev/iicbus/iicbus.h>
51 #include <dev/mii/mii.h>
52 #include <dev/mii/miivar.h>
53 #include <dev/etherswitch/mdio.h>
55 #include <dev/etherswitch/etherswitch.h>
57 #include <dev/etherswitch/arswitch/arswitchreg.h>
58 #include <dev/etherswitch/arswitch/arswitchvar.h>
59 #include <dev/etherswitch/arswitch/arswitch_reg.h>
60 #include <dev/etherswitch/arswitch/arswitch_8327.h>
63 #include "miibus_if.h"
64 #include "etherswitch_if.h"
67 ar8327_phy_fixup(struct arswitch_softc *sc, int phy)
70 switch (sc->chip_rev) {
72 /* For 100M waveform */
73 arswitch_writedbg(sc->sc_dev, phy, 0, 0x02ea);
74 /* Turn on Gigabit clock */
75 arswitch_writedbg(sc->sc_dev, phy, 0x3d, 0x68a0);
79 arswitch_writemmd(sc->sc_dev, phy, 0x7, 0x3c);
80 arswitch_writemmd(sc->sc_dev, phy, 0x4007, 0x0);
83 arswitch_writemmd(sc->sc_dev, phy, 0x3, 0x800d);
84 arswitch_writemmd(sc->sc_dev, phy, 0x4003, 0x803f);
86 arswitch_writedbg(sc->sc_dev, phy, 0x3d, 0x6860);
87 arswitch_writedbg(sc->sc_dev, phy, 0x5, 0x2c46);
88 arswitch_writedbg(sc->sc_dev, phy, 0x3c, 0x6000);
94 ar8327_get_pad_cfg(struct ar8327_pad_cfg *cfg)
106 case AR8327_PAD_MAC2MAC_MII:
107 t = AR8327_PAD_MAC_MII_EN;
109 t |= AR8327_PAD_MAC_MII_RXCLK_SEL;
111 t |= AR8327_PAD_MAC_MII_TXCLK_SEL;
114 case AR8327_PAD_MAC2MAC_GMII:
115 t = AR8327_PAD_MAC_GMII_EN;
117 t |= AR8327_PAD_MAC_GMII_RXCLK_SEL;
119 t |= AR8327_PAD_MAC_GMII_TXCLK_SEL;
122 case AR8327_PAD_MAC_SGMII:
123 t = AR8327_PAD_SGMII_EN;
126 * WAR for the Qualcomm Atheros AP136 board.
127 * It seems that RGMII TX/RX delay settings needs to be
128 * applied for SGMII mode as well, The ethernet is not
129 * reliable without this.
131 t |= cfg->txclk_delay_sel << AR8327_PAD_RGMII_TXCLK_DELAY_SEL_S;
132 t |= cfg->rxclk_delay_sel << AR8327_PAD_RGMII_RXCLK_DELAY_SEL_S;
133 if (cfg->rxclk_delay_en)
134 t |= AR8327_PAD_RGMII_RXCLK_DELAY_EN;
135 if (cfg->txclk_delay_en)
136 t |= AR8327_PAD_RGMII_TXCLK_DELAY_EN;
138 if (cfg->sgmii_delay_en)
139 t |= AR8327_PAD_SGMII_DELAY_EN;
143 case AR8327_PAD_MAC2PHY_MII:
144 t = AR8327_PAD_PHY_MII_EN;
146 t |= AR8327_PAD_PHY_MII_RXCLK_SEL;
148 t |= AR8327_PAD_PHY_MII_TXCLK_SEL;
151 case AR8327_PAD_MAC2PHY_GMII:
152 t = AR8327_PAD_PHY_GMII_EN;
153 if (cfg->pipe_rxclk_sel)
154 t |= AR8327_PAD_PHY_GMII_PIPE_RXCLK_SEL;
156 t |= AR8327_PAD_PHY_GMII_RXCLK_SEL;
158 t |= AR8327_PAD_PHY_GMII_TXCLK_SEL;
161 case AR8327_PAD_MAC_RGMII:
162 t = AR8327_PAD_RGMII_EN;
163 t |= cfg->txclk_delay_sel << AR8327_PAD_RGMII_TXCLK_DELAY_SEL_S;
164 t |= cfg->rxclk_delay_sel << AR8327_PAD_RGMII_RXCLK_DELAY_SEL_S;
165 if (cfg->rxclk_delay_en)
166 t |= AR8327_PAD_RGMII_RXCLK_DELAY_EN;
167 if (cfg->txclk_delay_en)
168 t |= AR8327_PAD_RGMII_TXCLK_DELAY_EN;
171 case AR8327_PAD_PHY_GMII:
172 t = AR8327_PAD_PHYX_GMII_EN;
175 case AR8327_PAD_PHY_RGMII:
176 t = AR8327_PAD_PHYX_RGMII_EN;
179 case AR8327_PAD_PHY_MII:
180 t = AR8327_PAD_PHYX_MII_EN;
188 * Map the hard-coded port config from the switch setup to
189 * the chipset port config (status, duplex, flow, etc.)
192 ar8327_get_port_init_status(struct ar8327_port_cfg *cfg)
196 if (!cfg->force_link)
197 return (AR8X16_PORT_STS_LINK_AUTO);
199 t = AR8X16_PORT_STS_TXMAC | AR8X16_PORT_STS_RXMAC;
200 t |= cfg->duplex ? AR8X16_PORT_STS_DUPLEX : 0;
201 t |= cfg->rxpause ? AR8X16_PORT_STS_RXFLOW : 0;
202 t |= cfg->txpause ? AR8X16_PORT_STS_TXFLOW : 0;
204 switch (cfg->speed) {
205 case AR8327_PORT_SPEED_10:
206 t |= AR8X16_PORT_STS_SPEED_10;
208 case AR8327_PORT_SPEED_100:
209 t |= AR8X16_PORT_STS_SPEED_100;
211 case AR8327_PORT_SPEED_1000:
212 t |= AR8X16_PORT_STS_SPEED_1000;
220 * Fetch the port data for the given port.
222 * This goes and does dirty things with the hints space
223 * to determine what the configuration parameters should be.
225 * Returns 1 if the structure was successfully parsed and
226 * the contents are valid; 0 otherwise.
229 ar8327_fetch_pdata_port(struct arswitch_softc *sc,
230 struct ar8327_port_cfg *pcfg,
236 /* Check if force_link exists */
238 snprintf(sbuf, 128, "port.%d.force_link", port);
239 (void) resource_int_value(device_get_name(sc->sc_dev),
240 device_get_unit(sc->sc_dev),
244 pcfg->force_link = 1;
246 /* force_link is set; let's parse the rest of the fields */
247 snprintf(sbuf, 128, "port.%d.speed", port);
248 if (resource_int_value(device_get_name(sc->sc_dev),
249 device_get_unit(sc->sc_dev),
253 pcfg->speed = AR8327_PORT_SPEED_10;
256 pcfg->speed = AR8327_PORT_SPEED_100;
259 pcfg->speed = AR8327_PORT_SPEED_1000;
262 device_printf(sc->sc_dev,
263 "%s: invalid port %d duplex value (%d)\n",
271 snprintf(sbuf, 128, "port.%d.duplex", port);
272 if (resource_int_value(device_get_name(sc->sc_dev),
273 device_get_unit(sc->sc_dev),
277 snprintf(sbuf, 128, "port.%d.txpause", port);
278 if (resource_int_value(device_get_name(sc->sc_dev),
279 device_get_unit(sc->sc_dev),
283 snprintf(sbuf, 128, "port.%d.rxpause", port);
284 if (resource_int_value(device_get_name(sc->sc_dev),
285 device_get_unit(sc->sc_dev),
290 device_printf(sc->sc_dev,
291 "%s: port %d: speed=%d, duplex=%d, txpause=%d, rxpause=%d\n",
304 * Parse the pad configuration from the boot hints.
306 * The (mostly optional) fields are:
309 * uint32_t rxclk_sel;
310 * uint32_t txclk_sel;
311 * uint32_t txclk_delay_sel;
312 * uint32_t rxclk_delay_sel;
313 * uint32_t txclk_delay_en;
314 * uint32_t rxclk_delay_en;
315 * uint32_t sgmii_delay_en;
316 * uint32_t pipe_rxclk_sel;
318 * If mode isn't in the hints, 0 is returned.
319 * Else the structure is fleshed out and 1 is returned.
322 ar8327_fetch_pdata_pad(struct arswitch_softc *sc,
323 struct ar8327_pad_cfg *pc,
329 /* Check if mode exists */
331 snprintf(sbuf, 128, "pad.%d.mode", pad);
332 if (resource_int_value(device_get_name(sc->sc_dev),
333 device_get_unit(sc->sc_dev),
337 /* assume that 'mode' exists and was found */
340 snprintf(sbuf, 128, "pad.%d.rxclk_sel", pad);
341 if (resource_int_value(device_get_name(sc->sc_dev),
342 device_get_unit(sc->sc_dev),
346 snprintf(sbuf, 128, "pad.%d.txclk_sel", pad);
347 if (resource_int_value(device_get_name(sc->sc_dev),
348 device_get_unit(sc->sc_dev),
352 snprintf(sbuf, 128, "pad.%d.txclk_delay_sel", pad);
353 if (resource_int_value(device_get_name(sc->sc_dev),
354 device_get_unit(sc->sc_dev),
356 pc->txclk_delay_sel = val;
358 snprintf(sbuf, 128, "pad.%d.rxclk_delay_sel", pad);
359 if (resource_int_value(device_get_name(sc->sc_dev),
360 device_get_unit(sc->sc_dev),
362 pc->rxclk_delay_sel = val;
364 snprintf(sbuf, 128, "pad.%d.txclk_delay_en", pad);
365 if (resource_int_value(device_get_name(sc->sc_dev),
366 device_get_unit(sc->sc_dev),
368 pc->txclk_delay_en = val;
370 snprintf(sbuf, 128, "pad.%d.rxclk_delay_en", pad);
371 if (resource_int_value(device_get_name(sc->sc_dev),
372 device_get_unit(sc->sc_dev),
374 pc->rxclk_delay_en = val;
376 snprintf(sbuf, 128, "pad.%d.sgmii_delay_en", pad);
377 if (resource_int_value(device_get_name(sc->sc_dev),
378 device_get_unit(sc->sc_dev),
380 pc->sgmii_delay_en = val;
382 snprintf(sbuf, 128, "pad.%d.pipe_rxclk_sel", pad);
383 if (resource_int_value(device_get_name(sc->sc_dev),
384 device_get_unit(sc->sc_dev),
386 pc->pipe_rxclk_sel = val;
389 device_printf(sc->sc_dev,
390 "%s: pad %d: mode=%d, rxclk_sel=%d, txclk_sel=%d, "
391 "txclk_delay_sel=%d, rxclk_delay_sel=%d, txclk_delay_en=%d, "
392 "rxclk_enable_en=%d, sgmii_delay_en=%d, pipe_rxclk_sel=%d\n",
410 * Fetch the SGMII configuration block from the boot hints.
413 ar8327_fetch_pdata_sgmii(struct arswitch_softc *sc,
414 struct ar8327_sgmii_cfg *scfg)
420 if (resource_int_value(device_get_name(sc->sc_dev),
421 device_get_unit(sc->sc_dev),
422 "sgmii.ctrl", &val) != 0)
424 scfg->sgmii_ctrl = val;
428 if (resource_int_value(device_get_name(sc->sc_dev),
429 device_get_unit(sc->sc_dev),
430 "sgmii.serdes_aen", &val) != 0)
432 scfg->serdes_aen = val;
438 * Fetch the LED configuration from the boot hints.
441 ar8327_fetch_pdata_led(struct arswitch_softc *sc,
442 struct ar8327_led_cfg *lcfg)
447 if (resource_int_value(device_get_name(sc->sc_dev),
448 device_get_unit(sc->sc_dev),
449 "led.ctrl0", &val) != 0)
451 lcfg->led_ctrl0 = val;
454 if (resource_int_value(device_get_name(sc->sc_dev),
455 device_get_unit(sc->sc_dev),
456 "led.ctrl1", &val) != 0)
458 lcfg->led_ctrl1 = val;
461 if (resource_int_value(device_get_name(sc->sc_dev),
462 device_get_unit(sc->sc_dev),
463 "led.ctrl2", &val) != 0)
465 lcfg->led_ctrl2 = val;
468 if (resource_int_value(device_get_name(sc->sc_dev),
469 device_get_unit(sc->sc_dev),
470 "led.ctrl3", &val) != 0)
472 lcfg->led_ctrl3 = val;
475 if (resource_int_value(device_get_name(sc->sc_dev),
476 device_get_unit(sc->sc_dev),
477 "led.open_drain", &val) != 0)
479 lcfg->open_drain = val;
485 * Initialise the ar8327 specific hardware features from
486 * the hints provided in the boot environment.
489 ar8327_init_pdata(struct arswitch_softc *sc)
491 struct ar8327_pad_cfg pc;
492 struct ar8327_port_cfg port_cfg;
493 struct ar8327_sgmii_cfg scfg;
494 struct ar8327_led_cfg lcfg;
495 uint32_t t, new_pos, pos;
498 bzero(&port_cfg, sizeof(port_cfg));
499 sc->ar8327.port0_status = 0;
500 if (ar8327_fetch_pdata_port(sc, &port_cfg, 0))
501 sc->ar8327.port0_status = ar8327_get_port_init_status(&port_cfg);
504 bzero(&port_cfg, sizeof(port_cfg));
505 sc->ar8327.port6_status = 0;
506 if (ar8327_fetch_pdata_port(sc, &port_cfg, 6))
507 sc->ar8327.port6_status = ar8327_get_port_init_status(&port_cfg);
510 bzero(&pc, sizeof(pc));
512 if (ar8327_fetch_pdata_pad(sc, &pc, 0))
513 t = ar8327_get_pad_cfg(&pc);
515 if (AR8X16_IS_SWITCH(sc, AR8337))
516 t |= AR8337_PAD_MAC06_EXCHANGE_EN;
518 arswitch_writereg(sc->sc_dev, AR8327_REG_PAD0_MODE, t);
521 bzero(&pc, sizeof(pc));
523 if (ar8327_fetch_pdata_pad(sc, &pc, 5))
524 t = ar8327_get_pad_cfg(&pc);
525 arswitch_writereg(sc->sc_dev, AR8327_REG_PAD5_MODE, t);
528 bzero(&pc, sizeof(pc));
530 if (ar8327_fetch_pdata_pad(sc, &pc, 6))
531 t = ar8327_get_pad_cfg(&pc);
532 arswitch_writereg(sc->sc_dev, AR8327_REG_PAD6_MODE, t);
534 pos = arswitch_readreg(sc->sc_dev, AR8327_REG_POWER_ON_STRIP);
538 bzero(&lcfg, sizeof(lcfg));
539 if (ar8327_fetch_pdata_led(sc, &lcfg)) {
541 new_pos |= AR8327_POWER_ON_STRIP_LED_OPEN_EN;
543 new_pos &= ~AR8327_POWER_ON_STRIP_LED_OPEN_EN;
545 arswitch_writereg(sc->sc_dev, AR8327_REG_LED_CTRL0,
547 arswitch_writereg(sc->sc_dev, AR8327_REG_LED_CTRL1,
549 arswitch_writereg(sc->sc_dev, AR8327_REG_LED_CTRL2,
551 arswitch_writereg(sc->sc_dev, AR8327_REG_LED_CTRL3,
555 new_pos |= AR8327_POWER_ON_STRIP_POWER_ON_SEL;
559 bzero(&scfg, sizeof(scfg));
560 if (ar8327_fetch_pdata_sgmii(sc, &scfg)) {
562 if (sc->chip_rev == 1)
563 t |= AR8327_SGMII_CTRL_EN_PLL |
564 AR8327_SGMII_CTRL_EN_RX |
565 AR8327_SGMII_CTRL_EN_TX;
567 t &= ~(AR8327_SGMII_CTRL_EN_PLL |
568 AR8327_SGMII_CTRL_EN_RX |
569 AR8327_SGMII_CTRL_EN_TX);
571 arswitch_writereg(sc->sc_dev, AR8327_REG_SGMII_CTRL, t);
574 new_pos &= ~AR8327_POWER_ON_STRIP_SERDES_AEN;
576 new_pos |= AR8327_POWER_ON_STRIP_SERDES_AEN;
579 arswitch_writereg(sc->sc_dev, AR8327_REG_POWER_ON_STRIP, new_pos);
585 ar8327_hw_setup(struct arswitch_softc *sc)
590 /* pdata fetch and setup */
591 err = ar8327_init_pdata(sc);
597 for (i = 0; i < AR8327_NUM_PHYS; i++) {
599 ar8327_phy_fixup(sc, i);
601 /* start PHY autonegotiation? */
602 /* XXX is this done as part of the normal PHY setup? */
606 /* Let things settle */
613 * Initialise other global values, for the AR8327.
616 ar8327_hw_global_setup(struct arswitch_softc *sc)
620 /* enable CPU port and disable mirror port */
621 t = AR8327_FWD_CTRL0_CPU_PORT_EN |
622 AR8327_FWD_CTRL0_MIRROR_PORT;
623 arswitch_writereg(sc->sc_dev, AR8327_REG_FWD_CTRL0, t);
625 /* forward multicast and broadcast frames to CPU */
626 t = (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_UC_FLOOD_S) |
627 (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_MC_FLOOD_S) |
628 (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_BC_FLOOD_S);
629 arswitch_writereg(sc->sc_dev, AR8327_REG_FWD_CTRL1, t);
631 /* enable jumbo frames */
632 /* XXX need to macro-shift the value! */
633 arswitch_modifyreg(sc->sc_dev, AR8327_REG_MAX_FRAME_SIZE,
634 AR8327_MAX_FRAME_SIZE_MTU, 9018 + 8 + 2);
636 /* Enable MIB counters */
637 arswitch_modifyreg(sc->sc_dev, AR8327_REG_MODULE_EN,
638 AR8327_MODULE_EN_MIB, AR8327_MODULE_EN_MIB);
640 /* Set the right number of ports */
641 sc->info.es_nports = 6;
650 ar8327_port_init(struct arswitch_softc *sc, int port)
654 if (port == AR8X16_PORT_CPU)
655 t = sc->ar8327.port0_status;
657 t = sc->ar8327.port6_status;
659 t = AR8X16_PORT_STS_LINK_AUTO;
661 arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_STATUS(port), t);
662 arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_HEADER(port), 0);
665 * Default to 1 port group.
667 t = 1 << AR8327_PORT_VLAN0_DEF_SVID_S;
668 t |= 1 << AR8327_PORT_VLAN0_DEF_CVID_S;
669 arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN0(port), t);
671 t = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH << AR8327_PORT_VLAN1_OUT_MODE_S;
672 arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN1(port), t);
675 * This doesn't configure any ports which this port can "see".
676 * bits 0-6 control which ports a frame coming into this port
677 * can be sent out to.
679 * So by doing this, we're making it impossible to send frames out
682 t = AR8327_PORT_LOOKUP_LEARN;
683 t |= AR8X16_PORT_CTRL_STATE_FORWARD << AR8327_PORT_LOOKUP_STATE_S;
685 /* So this allows traffic to any port except ourselves */
686 t |= (0x3f & ~(1 << port));
687 arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(port), t);
691 ar8327_port_vlan_setup(struct arswitch_softc *sc, etherswitch_port_t *p)
694 /* XXX stub for now */
695 device_printf(sc->sc_dev, "%s: called\n", __func__);
700 ar8327_port_vlan_get(struct arswitch_softc *sc, etherswitch_port_t *p)
703 /* XXX stub for now */
704 device_printf(sc->sc_dev, "%s: called\n", __func__);
709 ar8327_reset_vlans(struct arswitch_softc *sc)
717 arswitch_modifyreg(sc->sc_dev, AR8327_REG_FWD_CTRL0,
718 AR8327_FWD_CTRL0_MIRROR_PORT,
719 (0xF << AR8327_FWD_CTRL0_MIRROR_PORT_S));
722 * For now, let's default to one portgroup, just so traffic
723 * flows. All ports can see other ports.
725 for (i = 0; i < AR8327_NUM_PORTS; i++) {
726 /* set pvid = 1; there's only one vlangroup */
727 t = 1 << AR8327_PORT_VLAN0_DEF_SVID_S;
728 t |= 1 << AR8327_PORT_VLAN0_DEF_CVID_S;
729 arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN0(i), t);
731 /* set egress == out_keep */
732 mode = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH;
734 t = AR8327_PORT_VLAN1_PORT_VLAN_PROP;
735 t |= mode << AR8327_PORT_VLAN1_OUT_MODE_S;
736 arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN1(i), t);
738 /* Ports can see other ports */
739 t = (0x3f & ~(1 << i)); /* all ports besides us */
740 t |= AR8327_PORT_LOOKUP_LEARN;
742 /* in_port_only, forward */
743 t |= AR8X16_PORT_VLAN_MODE_PORT_ONLY << AR8327_PORT_LOOKUP_IN_MODE_S;
744 t |= AR8X16_PORT_CTRL_STATE_FORWARD << AR8327_PORT_LOOKUP_STATE_S;
745 arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(i), t);
748 * Disable port mirroring entirely.
750 arswitch_modifyreg(sc->sc_dev,
751 AR8327_REG_PORT_LOOKUP(i),
752 AR8327_PORT_LOOKUP_ING_MIRROR_EN,
754 arswitch_modifyreg(sc->sc_dev,
755 AR8327_REG_PORT_HOL_CTRL1(i),
756 AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN,
762 ar8327_vlan_getvgroup(struct arswitch_softc *sc, etherswitch_vlangroup_t *vg)
764 device_printf(sc->sc_dev, "%s: called\n", __func__);
769 ar8327_vlan_setvgroup(struct arswitch_softc *sc, etherswitch_vlangroup_t *vg)
772 device_printf(sc->sc_dev, "%s: called\n", __func__);
777 ar8327_get_pvid(struct arswitch_softc *sc, int port, int *pvid)
780 device_printf(sc->sc_dev, "%s: called\n", __func__);
785 ar8327_set_pvid(struct arswitch_softc *sc, int port, int pvid)
788 device_printf(sc->sc_dev, "%s: called\n", __func__);
793 ar8327_atu_flush(struct arswitch_softc *sc)
798 ret = arswitch_waitreg(sc->sc_dev,
800 AR8327_ATU_FUNC_BUSY,
805 device_printf(sc->sc_dev, "%s: waitreg failed\n", __func__);
808 arswitch_writereg(sc->sc_dev,
810 AR8327_ATU_FUNC_OP_FLUSH);
815 ar8327_attach(struct arswitch_softc *sc)
818 sc->hal.arswitch_hw_setup = ar8327_hw_setup;
819 sc->hal.arswitch_hw_global_setup = ar8327_hw_global_setup;
821 sc->hal.arswitch_port_init = ar8327_port_init;
822 sc->hal.arswitch_port_vlan_setup = ar8327_port_vlan_setup;
823 sc->hal.arswitch_port_vlan_get = ar8327_port_vlan_get;
825 sc->hal.arswitch_vlan_init_hw = ar8327_reset_vlans;
826 sc->hal.arswitch_vlan_getvgroup = ar8327_vlan_getvgroup;
827 sc->hal.arswitch_vlan_setvgroup = ar8327_vlan_setvgroup;
828 sc->hal.arswitch_vlan_get_pvid = ar8327_get_pvid;
829 sc->hal.arswitch_vlan_set_pvid = ar8327_set_pvid;
831 sc->hal.arswitch_atu_flush = ar8327_atu_flush;
833 /* Set the switch vlan capabilities. */
834 sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q |
835 ETHERSWITCH_VLAN_PORT | ETHERSWITCH_VLAN_DOUBLE_TAG;
836 sc->info.es_nvlangroups = AR8X16_MAX_VLANS;