xref: /freebsd/sys/dev/etherswitch/arswitch/arswitch_8327.c (revision af6a5351a1fdb1130f18be6c782c4d48916eb971)
1 /*-
2  * Copyright (c) 2011-2012 Stefan Bethke.
3  * Copyright (c) 2014 Adrian Chadd.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
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.
14  *
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
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  */
29 
30 #include <sys/param.h>
31 #include <sys/bus.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>
39 
40 #include <net/if.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>
46 
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/mdio/mdio.h>
54 
55 #include <dev/etherswitch/etherswitch.h>
56 
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_phy.h>
61 #include <dev/etherswitch/arswitch/arswitch_vlans.h>
62 
63 #include <dev/etherswitch/arswitch/arswitch_8327.h>
64 
65 #include "mdio_if.h"
66 #include "miibus_if.h"
67 #include "etherswitch_if.h"
68 
69 /*
70  * AR8327 TODO:
71  *
72  * There should be a default hardware setup hint set for the default
73  * switch config.  Otherwise the default is "all ports in one vlangroup",
74  * which means both CPU ports can see each other and that will quickly
75  * lead to traffic storms/loops.
76  */
77 
78 /* Map port+led to register+shift */
79 struct ar8327_led_mapping ar8327_led_mapping[AR8327_NUM_PHYS][ETHERSWITCH_PORT_MAX_LEDS] =
80 {
81 	{	/* PHY0 */
82 		{AR8327_REG_LED_CTRL0, 14 },
83 		{AR8327_REG_LED_CTRL1, 14 },
84 		{AR8327_REG_LED_CTRL2, 14 }
85 	},
86 	{	/* PHY1 */
87 		{AR8327_REG_LED_CTRL3, 8  },
88 		{AR8327_REG_LED_CTRL3, 10 },
89 		{AR8327_REG_LED_CTRL3, 12 }
90 	},
91 	{	/* PHY2 */
92 		{AR8327_REG_LED_CTRL3, 14 },
93 		{AR8327_REG_LED_CTRL3, 16 },
94 		{AR8327_REG_LED_CTRL3, 18 }
95 	},
96 	{	/* PHY3 */
97 		{AR8327_REG_LED_CTRL3, 20 },
98 		{AR8327_REG_LED_CTRL3, 22 },
99 		{AR8327_REG_LED_CTRL3, 24 }
100 	},
101 	{	/* PHY4 */
102 		{AR8327_REG_LED_CTRL0, 30 },
103 		{AR8327_REG_LED_CTRL1, 30 },
104 		{AR8327_REG_LED_CTRL2, 30 }
105 	}
106 };
107 
108 static int
109 ar8327_vlan_op(struct arswitch_softc *sc, uint32_t op, uint32_t vid,
110     uint32_t data)
111 {
112 	int err;
113 
114 	/*
115 	 * Wait for the "done" bit to finish.
116 	 */
117 	if (arswitch_waitreg(sc->sc_dev, AR8327_REG_VTU_FUNC1,
118 	    AR8327_VTU_FUNC1_BUSY, 0, 5))
119 		return (EBUSY);
120 
121 	/*
122 	 * If it's a "load" operation, then ensure 'data' is loaded
123 	 * in first.
124 	 */
125 	if ((op & AR8327_VTU_FUNC1_OP) == AR8327_VTU_FUNC1_OP_LOAD) {
126 		err = arswitch_writereg(sc->sc_dev, AR8327_REG_VTU_FUNC0, data);
127 		if (err)
128 			return (err);
129 	}
130 
131 	/*
132 	 * Set the VID.
133 	 */
134 	op |= ((vid & 0xfff) << AR8327_VTU_FUNC1_VID_S);
135 
136 	/*
137 	 * Set busy bit to start loading in the command.
138 	 */
139 	op |= AR8327_VTU_FUNC1_BUSY;
140 	arswitch_writereg(sc->sc_dev, AR8327_REG_VTU_FUNC1, op);
141 
142 	/*
143 	 * Finally - wait for it to load.
144 	 */
145 	if (arswitch_waitreg(sc->sc_dev, AR8327_REG_VTU_FUNC1,
146 	    AR8327_VTU_FUNC1_BUSY, 0, 5))
147 		return (EBUSY);
148 
149 	return (0);
150 }
151 
152 static void
153 ar8327_phy_fixup(struct arswitch_softc *sc, int phy)
154 {
155 	if (bootverbose)
156 		device_printf(sc->sc_dev,
157 		    "%s: called; phy=%d; chiprev=%d\n", __func__,
158 		    phy,
159 		    sc->chip_rev);
160 	switch (sc->chip_rev) {
161 	case 1:
162 		/* For 100M waveform */
163 		arswitch_writedbg(sc->sc_dev, phy, 0, 0x02ea);
164 		/* Turn on Gigabit clock */
165 		arswitch_writedbg(sc->sc_dev, phy, 0x3d, 0x68a0);
166 		break;
167 
168 	case 2:
169 		arswitch_writemmd(sc->sc_dev, phy, 0x7, 0x3c);
170 		arswitch_writemmd(sc->sc_dev, phy, 0x4007, 0x0);
171 		/* fallthrough */
172 	case 4:
173 		arswitch_writemmd(sc->sc_dev, phy, 0x3, 0x800d);
174 		arswitch_writemmd(sc->sc_dev, phy, 0x4003, 0x803f);
175 
176 		arswitch_writedbg(sc->sc_dev, phy, 0x3d, 0x6860);
177 		arswitch_writedbg(sc->sc_dev, phy, 0x5, 0x2c46);
178 		arswitch_writedbg(sc->sc_dev, phy, 0x3c, 0x6000);
179 		break;
180 	}
181 }
182 
183 static uint32_t
184 ar8327_get_pad_cfg(struct ar8327_pad_cfg *cfg)
185 {
186 	uint32_t t;
187 
188 	if (!cfg)
189 		return (0);
190 
191 	t = 0;
192 	switch (cfg->mode) {
193 	case AR8327_PAD_NC:
194 		break;
195 
196 	case AR8327_PAD_MAC2MAC_MII:
197 		t = AR8327_PAD_MAC_MII_EN;
198 		if (cfg->rxclk_sel)
199 			t |= AR8327_PAD_MAC_MII_RXCLK_SEL;
200 		if (cfg->txclk_sel)
201 			t |= AR8327_PAD_MAC_MII_TXCLK_SEL;
202 		break;
203 
204 	case AR8327_PAD_MAC2MAC_GMII:
205 		t = AR8327_PAD_MAC_GMII_EN;
206 		if (cfg->rxclk_sel)
207 			t |= AR8327_PAD_MAC_GMII_RXCLK_SEL;
208 		if (cfg->txclk_sel)
209 			t |= AR8327_PAD_MAC_GMII_TXCLK_SEL;
210 		break;
211 
212 	case AR8327_PAD_MAC_SGMII:
213 		t = AR8327_PAD_SGMII_EN;
214 
215 		/*
216 		 * WAR for the Qualcomm Atheros AP136 board.
217 		 * It seems that RGMII TX/RX delay settings needs to be
218 		 * applied for SGMII mode as well, The ethernet is not
219 		 * reliable without this.
220 		 */
221 		t |= cfg->txclk_delay_sel << AR8327_PAD_RGMII_TXCLK_DELAY_SEL_S;
222 		t |= cfg->rxclk_delay_sel << AR8327_PAD_RGMII_RXCLK_DELAY_SEL_S;
223 		if (cfg->rxclk_delay_en)
224 			t |= AR8327_PAD_RGMII_RXCLK_DELAY_EN;
225 		if (cfg->txclk_delay_en)
226 			t |= AR8327_PAD_RGMII_TXCLK_DELAY_EN;
227 
228 		if (cfg->sgmii_delay_en)
229 			t |= AR8327_PAD_SGMII_DELAY_EN;
230 
231 		break;
232 
233 	case AR8327_PAD_MAC2PHY_MII:
234 		t = AR8327_PAD_PHY_MII_EN;
235 		if (cfg->rxclk_sel)
236 			t |= AR8327_PAD_PHY_MII_RXCLK_SEL;
237 		if (cfg->txclk_sel)
238 			t |= AR8327_PAD_PHY_MII_TXCLK_SEL;
239 		break;
240 
241 	case AR8327_PAD_MAC2PHY_GMII:
242 		t = AR8327_PAD_PHY_GMII_EN;
243 		if (cfg->pipe_rxclk_sel)
244 			t |= AR8327_PAD_PHY_GMII_PIPE_RXCLK_SEL;
245 		if (cfg->rxclk_sel)
246 			t |= AR8327_PAD_PHY_GMII_RXCLK_SEL;
247 		if (cfg->txclk_sel)
248 			t |= AR8327_PAD_PHY_GMII_TXCLK_SEL;
249 		break;
250 
251 	case AR8327_PAD_MAC_RGMII:
252 		t = AR8327_PAD_RGMII_EN;
253 		t |= cfg->txclk_delay_sel << AR8327_PAD_RGMII_TXCLK_DELAY_SEL_S;
254 		t |= cfg->rxclk_delay_sel << AR8327_PAD_RGMII_RXCLK_DELAY_SEL_S;
255 		if (cfg->rxclk_delay_en)
256 			t |= AR8327_PAD_RGMII_RXCLK_DELAY_EN;
257 		if (cfg->txclk_delay_en)
258 			t |= AR8327_PAD_RGMII_TXCLK_DELAY_EN;
259 		break;
260 
261 	case AR8327_PAD_PHY_GMII:
262 		t = AR8327_PAD_PHYX_GMII_EN;
263 		break;
264 
265 	case AR8327_PAD_PHY_RGMII:
266 		t = AR8327_PAD_PHYX_RGMII_EN;
267 		break;
268 
269 	case AR8327_PAD_PHY_MII:
270 		t = AR8327_PAD_PHYX_MII_EN;
271 		break;
272 	}
273 
274 	return (t);
275 }
276 
277 /*
278  * Map the hard-coded port config from the switch setup to
279  * the chipset port config (status, duplex, flow, etc.)
280  */
281 static uint32_t
282 ar8327_get_port_init_status(struct ar8327_port_cfg *cfg)
283 {
284 	uint32_t t;
285 
286 	if (!cfg->force_link)
287 		return (AR8X16_PORT_STS_LINK_AUTO);
288 
289 	t = AR8X16_PORT_STS_TXMAC | AR8X16_PORT_STS_RXMAC;
290 	t |= cfg->duplex ? AR8X16_PORT_STS_DUPLEX : 0;
291 	t |= cfg->rxpause ? AR8X16_PORT_STS_RXFLOW : 0;
292 	t |= cfg->txpause ? AR8X16_PORT_STS_TXFLOW : 0;
293 
294 	switch (cfg->speed) {
295 	case AR8327_PORT_SPEED_10:
296 		t |= AR8X16_PORT_STS_SPEED_10;
297 		break;
298 	case AR8327_PORT_SPEED_100:
299 		t |= AR8X16_PORT_STS_SPEED_100;
300 		break;
301 	case AR8327_PORT_SPEED_1000:
302 		t |= AR8X16_PORT_STS_SPEED_1000;
303 		break;
304 	}
305 
306 	return (t);
307 }
308 
309 /*
310  * Fetch the port data for the given port.
311  *
312  * This goes and does dirty things with the hints space
313  * to determine what the configuration parameters should be.
314  *
315  * Returns 1 if the structure was successfully parsed and
316  * the contents are valid; 0 otherwise.
317  */
318 static int
319 ar8327_fetch_pdata_port(struct arswitch_softc *sc,
320     struct ar8327_port_cfg *pcfg,
321     int port)
322 {
323 	int val;
324 	char sbuf[128];
325 
326 	/* Check if force_link exists */
327 	val = 0;
328 	snprintf(sbuf, 128, "port.%d.force_link", port);
329 	(void) resource_int_value(device_get_name(sc->sc_dev),
330 	    device_get_unit(sc->sc_dev),
331 	    sbuf, &val);
332 	if (val != 1)
333 		return (0);
334 	pcfg->force_link = 1;
335 
336 	/* force_link is set; let's parse the rest of the fields */
337 	snprintf(sbuf, 128, "port.%d.speed", port);
338 	if (resource_int_value(device_get_name(sc->sc_dev),
339 	    device_get_unit(sc->sc_dev),
340 	    sbuf, &val) == 0) {
341 		switch (val) {
342 		case 10:
343 			pcfg->speed = AR8327_PORT_SPEED_10;
344 			break;
345 		case 100:
346 			pcfg->speed = AR8327_PORT_SPEED_100;
347 			break;
348 		case 1000:
349 			pcfg->speed = AR8327_PORT_SPEED_1000;
350 			break;
351 		default:
352 			device_printf(sc->sc_dev,
353 			    "%s: invalid port %d duplex value (%d)\n",
354 			    __func__,
355 			    port,
356 			    val);
357 			return (0);
358 		}
359 	}
360 
361 	snprintf(sbuf, 128, "port.%d.duplex", port);
362 	if (resource_int_value(device_get_name(sc->sc_dev),
363 	    device_get_unit(sc->sc_dev),
364 	    sbuf, &val) == 0)
365 		pcfg->duplex = val;
366 
367 	snprintf(sbuf, 128, "port.%d.txpause", port);
368 	if (resource_int_value(device_get_name(sc->sc_dev),
369 	    device_get_unit(sc->sc_dev),
370 	    sbuf, &val) == 0)
371 		pcfg->txpause = val;
372 
373 	snprintf(sbuf, 128, "port.%d.rxpause", port);
374 	if (resource_int_value(device_get_name(sc->sc_dev),
375 	    device_get_unit(sc->sc_dev),
376 	    sbuf, &val) == 0)
377 		pcfg->rxpause = val;
378 
379 #if 1
380 	device_printf(sc->sc_dev,
381 	    "%s: port %d: speed=%d, duplex=%d, txpause=%d, rxpause=%d\n",
382 	    __func__,
383 	    port,
384 	    pcfg->speed,
385 	    pcfg->duplex,
386 	    pcfg->txpause,
387 	    pcfg->rxpause);
388 #endif
389 
390 	return (1);
391 }
392 
393 /*
394  * Parse the pad configuration from the boot hints.
395  *
396  * The (mostly optional) fields are:
397  *
398  * uint32_t mode;
399  * uint32_t rxclk_sel;
400  * uint32_t txclk_sel;
401  * uint32_t txclk_delay_sel;
402  * uint32_t rxclk_delay_sel;
403  * uint32_t txclk_delay_en;
404  * uint32_t rxclk_delay_en;
405  * uint32_t sgmii_delay_en;
406  * uint32_t pipe_rxclk_sel;
407  *
408  * If mode isn't in the hints, 0 is returned.
409  * Else the structure is fleshed out and 1 is returned.
410  */
411 static int
412 ar8327_fetch_pdata_pad(struct arswitch_softc *sc,
413     struct ar8327_pad_cfg *pc,
414     int pad)
415 {
416 	int val;
417 	char sbuf[128];
418 
419 	/* Check if mode exists */
420 	val = 0;
421 	snprintf(sbuf, 128, "pad.%d.mode", pad);
422 	if (resource_int_value(device_get_name(sc->sc_dev),
423 	    device_get_unit(sc->sc_dev),
424 	    sbuf, &val) != 0)
425 		return (0);
426 
427 	/* assume that 'mode' exists and was found */
428 	pc->mode = val;
429 
430 	snprintf(sbuf, 128, "pad.%d.rxclk_sel", pad);
431 	if (resource_int_value(device_get_name(sc->sc_dev),
432 	    device_get_unit(sc->sc_dev),
433 	    sbuf, &val) == 0)
434 		pc->rxclk_sel = val;
435 
436 	snprintf(sbuf, 128, "pad.%d.txclk_sel", pad);
437 	if (resource_int_value(device_get_name(sc->sc_dev),
438 	    device_get_unit(sc->sc_dev),
439 	    sbuf, &val) == 0)
440 		pc->txclk_sel = val;
441 
442 	snprintf(sbuf, 128, "pad.%d.txclk_delay_sel", pad);
443 	if (resource_int_value(device_get_name(sc->sc_dev),
444 	    device_get_unit(sc->sc_dev),
445 	    sbuf, &val) == 0)
446 		pc->txclk_delay_sel = val;
447 
448 	snprintf(sbuf, 128, "pad.%d.rxclk_delay_sel", pad);
449 	if (resource_int_value(device_get_name(sc->sc_dev),
450 	    device_get_unit(sc->sc_dev),
451 	    sbuf, &val) == 0)
452 		pc->rxclk_delay_sel = val;
453 
454 	snprintf(sbuf, 128, "pad.%d.txclk_delay_en", pad);
455 	if (resource_int_value(device_get_name(sc->sc_dev),
456 	    device_get_unit(sc->sc_dev),
457 	    sbuf, &val) == 0)
458 		pc->txclk_delay_en = val;
459 
460 	snprintf(sbuf, 128, "pad.%d.rxclk_delay_en", pad);
461 	if (resource_int_value(device_get_name(sc->sc_dev),
462 	    device_get_unit(sc->sc_dev),
463 	    sbuf, &val) == 0)
464 		pc->rxclk_delay_en = val;
465 
466 	snprintf(sbuf, 128, "pad.%d.sgmii_delay_en", pad);
467 	if (resource_int_value(device_get_name(sc->sc_dev),
468 	    device_get_unit(sc->sc_dev),
469 	    sbuf, &val) == 0)
470 		pc->sgmii_delay_en = val;
471 
472 	snprintf(sbuf, 128, "pad.%d.pipe_rxclk_sel", pad);
473 	if (resource_int_value(device_get_name(sc->sc_dev),
474 	    device_get_unit(sc->sc_dev),
475 	    sbuf, &val) == 0)
476 		pc->pipe_rxclk_sel = val;
477 
478 	if (bootverbose) {
479 		device_printf(sc->sc_dev,
480 		    "%s: pad %d: mode=%d, rxclk_sel=%d, txclk_sel=%d, "
481 		    "txclk_delay_sel=%d, rxclk_delay_sel=%d, txclk_delay_en=%d, "
482 		    "rxclk_enable_en=%d, sgmii_delay_en=%d, pipe_rxclk_sel=%d\n",
483 		    __func__,
484 		    pad,
485 		    pc->mode,
486 		    pc->rxclk_sel,
487 		    pc->txclk_sel,
488 		    pc->txclk_delay_sel,
489 		    pc->rxclk_delay_sel,
490 		    pc->txclk_delay_en,
491 		    pc->rxclk_delay_en,
492 		    pc->sgmii_delay_en,
493 		    pc->pipe_rxclk_sel);
494 	}
495 
496 	return (1);
497 }
498 
499 /*
500  * Fetch the SGMII configuration block from the boot hints.
501  */
502 static int
503 ar8327_fetch_pdata_sgmii(struct arswitch_softc *sc,
504     struct ar8327_sgmii_cfg *scfg)
505 {
506 	int val;
507 
508 	/* sgmii_ctrl */
509 	val = 0;
510 	if (resource_int_value(device_get_name(sc->sc_dev),
511 	    device_get_unit(sc->sc_dev),
512 	    "sgmii.ctrl", &val) != 0)
513 		return (0);
514 	scfg->sgmii_ctrl = val;
515 
516 	/* serdes_aen */
517 	val = 0;
518 	if (resource_int_value(device_get_name(sc->sc_dev),
519 	    device_get_unit(sc->sc_dev),
520 	    "sgmii.serdes_aen", &val) != 0)
521 		return (0);
522 	scfg->serdes_aen = val;
523 
524 	return (1);
525 }
526 
527 /*
528  * Fetch the LED configuration from the boot hints.
529  */
530 static int
531 ar8327_fetch_pdata_led(struct arswitch_softc *sc,
532     struct ar8327_led_cfg *lcfg)
533 {
534 	int val;
535 
536 	val = 0;
537 	if (resource_int_value(device_get_name(sc->sc_dev),
538 	    device_get_unit(sc->sc_dev),
539 	    "led.ctrl0", &val) != 0)
540 		return (0);
541 	lcfg->led_ctrl0 = val;
542 
543 	val = 0;
544 	if (resource_int_value(device_get_name(sc->sc_dev),
545 	    device_get_unit(sc->sc_dev),
546 	    "led.ctrl1", &val) != 0)
547 		return (0);
548 	lcfg->led_ctrl1 = val;
549 
550 	val = 0;
551 	if (resource_int_value(device_get_name(sc->sc_dev),
552 	    device_get_unit(sc->sc_dev),
553 	    "led.ctrl2", &val) != 0)
554 		return (0);
555 	lcfg->led_ctrl2 = val;
556 
557 	val = 0;
558 	if (resource_int_value(device_get_name(sc->sc_dev),
559 	    device_get_unit(sc->sc_dev),
560 	    "led.ctrl3", &val) != 0)
561 		return (0);
562 	lcfg->led_ctrl3 = val;
563 
564 	val = 0;
565 	if (resource_int_value(device_get_name(sc->sc_dev),
566 	    device_get_unit(sc->sc_dev),
567 	    "led.open_drain", &val) != 0)
568 		return (0);
569 	lcfg->open_drain = val;
570 
571 	return (1);
572 }
573 
574 /*
575  * Initialise the ar8327 specific hardware features from
576  * the hints provided in the boot environment.
577  */
578 static int
579 ar8327_init_pdata(struct arswitch_softc *sc)
580 {
581 	struct ar8327_pad_cfg pc;
582 	struct ar8327_port_cfg port_cfg;
583 	struct ar8327_sgmii_cfg scfg;
584 	struct ar8327_led_cfg lcfg;
585 	uint32_t t, new_pos, pos;
586 
587 	/* Port 0 */
588 	bzero(&port_cfg, sizeof(port_cfg));
589 	sc->ar8327.port0_status = 0;
590 	if (ar8327_fetch_pdata_port(sc, &port_cfg, 0))
591 		sc->ar8327.port0_status = ar8327_get_port_init_status(&port_cfg);
592 
593 	/* Port 6 */
594 	bzero(&port_cfg, sizeof(port_cfg));
595 	sc->ar8327.port6_status = 0;
596 	if (ar8327_fetch_pdata_port(sc, &port_cfg, 6))
597 		sc->ar8327.port6_status = ar8327_get_port_init_status(&port_cfg);
598 
599 	/* Pad 0 */
600 	bzero(&pc, sizeof(pc));
601 	t = 0;
602 	if (ar8327_fetch_pdata_pad(sc, &pc, 0))
603 		t = ar8327_get_pad_cfg(&pc);
604 #if 0
605 		if (AR8X16_IS_SWITCH(sc, AR8337))
606 			t |= AR8337_PAD_MAC06_EXCHANGE_EN;
607 #endif
608 	arswitch_writereg(sc->sc_dev, AR8327_REG_PAD0_MODE, t);
609 
610 	/* Pad 5 */
611 	bzero(&pc, sizeof(pc));
612 	t = 0;
613 	if (ar8327_fetch_pdata_pad(sc, &pc, 5))
614 		t = ar8327_get_pad_cfg(&pc);
615 	arswitch_writereg(sc->sc_dev, AR8327_REG_PAD5_MODE, t);
616 
617 	/* Pad 6 */
618 	bzero(&pc, sizeof(pc));
619 	t = 0;
620 	if (ar8327_fetch_pdata_pad(sc, &pc, 6))
621 		t = ar8327_get_pad_cfg(&pc);
622 	arswitch_writereg(sc->sc_dev, AR8327_REG_PAD6_MODE, t);
623 
624 	pos = arswitch_readreg(sc->sc_dev, AR8327_REG_POWER_ON_STRIP);
625 	new_pos = pos;
626 
627 	/* XXX LED config */
628 	bzero(&lcfg, sizeof(lcfg));
629 	if (ar8327_fetch_pdata_led(sc, &lcfg)) {
630 		if (lcfg.open_drain)
631 			new_pos |= AR8327_POWER_ON_STRIP_LED_OPEN_EN;
632 		else
633 			new_pos &= ~AR8327_POWER_ON_STRIP_LED_OPEN_EN;
634 
635 		arswitch_writereg(sc->sc_dev, AR8327_REG_LED_CTRL0,
636 		    lcfg.led_ctrl0);
637 		arswitch_writereg(sc->sc_dev, AR8327_REG_LED_CTRL1,
638 		    lcfg.led_ctrl1);
639 		arswitch_writereg(sc->sc_dev, AR8327_REG_LED_CTRL2,
640 		    lcfg.led_ctrl2);
641 		arswitch_writereg(sc->sc_dev, AR8327_REG_LED_CTRL3,
642 		    lcfg.led_ctrl3);
643 
644 		if (new_pos != pos)
645 			new_pos |= AR8327_POWER_ON_STRIP_POWER_ON_SEL;
646 	}
647 
648 	/* SGMII config */
649 	bzero(&scfg, sizeof(scfg));
650 	if (ar8327_fetch_pdata_sgmii(sc, &scfg)) {
651 		device_printf(sc->sc_dev, "%s: SGMII cfg?\n", __func__);
652 		t = scfg.sgmii_ctrl;
653 		if (sc->chip_rev == 1)
654 			t |= AR8327_SGMII_CTRL_EN_PLL |
655 			    AR8327_SGMII_CTRL_EN_RX |
656 			    AR8327_SGMII_CTRL_EN_TX;
657 		else
658 			t &= ~(AR8327_SGMII_CTRL_EN_PLL |
659 			    AR8327_SGMII_CTRL_EN_RX |
660 			    AR8327_SGMII_CTRL_EN_TX);
661 
662 		arswitch_writereg(sc->sc_dev, AR8327_REG_SGMII_CTRL, t);
663 
664 		if (scfg.serdes_aen)
665 			new_pos &= ~AR8327_POWER_ON_STRIP_SERDES_AEN;
666 		else
667 			new_pos |= AR8327_POWER_ON_STRIP_SERDES_AEN;
668 	}
669 
670 	arswitch_writereg(sc->sc_dev, AR8327_REG_POWER_ON_STRIP, new_pos);
671 
672 	return (0);
673 }
674 
675 static int
676 ar8327_hw_setup(struct arswitch_softc *sc)
677 {
678 	int i;
679 	int err;
680 
681 	/* pdata fetch and setup */
682 	err = ar8327_init_pdata(sc);
683 	if (err != 0)
684 		return (err);
685 
686 	/* XXX init leds */
687 
688 	for (i = 0; i < AR8327_NUM_PHYS; i++) {
689 		/* phy fixup */
690 		ar8327_phy_fixup(sc, i);
691 
692 		/* start PHY autonegotiation? */
693 		/* XXX is this done as part of the normal PHY setup? */
694 
695 	}
696 
697 	/* Let things settle */
698 	DELAY(1000);
699 
700 	return (0);
701 }
702 
703 /*
704  * Initialise other global values, for the AR8327.
705  */
706 static int
707 ar8327_hw_global_setup(struct arswitch_softc *sc)
708 {
709 	uint32_t t;
710 
711 	ARSWITCH_LOCK(sc);
712 
713 	/* enable CPU port and disable mirror port */
714 	t = AR8327_FWD_CTRL0_CPU_PORT_EN |
715 	    AR8327_FWD_CTRL0_MIRROR_PORT;
716 	arswitch_writereg(sc->sc_dev, AR8327_REG_FWD_CTRL0, t);
717 
718 	/* forward multicast and broadcast frames to CPU */
719 	t = (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_UC_FLOOD_S) |
720 	    (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_MC_FLOOD_S) |
721 	    (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_BC_FLOOD_S);
722 	arswitch_writereg(sc->sc_dev, AR8327_REG_FWD_CTRL1, t);
723 
724 	/* enable jumbo frames */
725 	/* XXX need to macro-shift the value! */
726 	arswitch_modifyreg(sc->sc_dev, AR8327_REG_MAX_FRAME_SIZE,
727 	    AR8327_MAX_FRAME_SIZE_MTU, 9018 + 8 + 2);
728 
729 	/* Enable MIB counters */
730 	arswitch_modifyreg(sc->sc_dev, AR8327_REG_MODULE_EN,
731 	    AR8327_MODULE_EN_MIB, AR8327_MODULE_EN_MIB);
732 
733 	/* Disable EEE on all ports due to stability issues */
734 	t = arswitch_readreg(sc->sc_dev, AR8327_REG_EEE_CTRL);
735 	t |= AR8327_EEE_CTRL_DISABLE_PHY(0) |
736 	    AR8327_EEE_CTRL_DISABLE_PHY(1) |
737 	    AR8327_EEE_CTRL_DISABLE_PHY(2) |
738 	    AR8327_EEE_CTRL_DISABLE_PHY(3) |
739 	    AR8327_EEE_CTRL_DISABLE_PHY(4);
740 	arswitch_writereg(sc->sc_dev, AR8327_REG_EEE_CTRL, t);
741 
742 	/* Set the right number of ports */
743 	/* GMAC0 (CPU), GMAC1..5 (PHYs), GMAC6 (CPU) */
744 	sc->info.es_nports = 7;
745 
746 	ARSWITCH_UNLOCK(sc);
747 	return (0);
748 }
749 
750 /*
751  * Port setup.  Called at attach time.
752  */
753 static void
754 ar8327_port_init(struct arswitch_softc *sc, int port)
755 {
756 	uint32_t t;
757 	int ports;
758 
759 	/* For now, port can see all other ports */
760 	ports = 0x7f;
761 
762 	if (port == AR8X16_PORT_CPU)
763 		t = sc->ar8327.port0_status;
764 	else if (port == 6)
765 		t = sc->ar8327.port6_status;
766         else
767 		t = AR8X16_PORT_STS_LINK_AUTO;
768 
769 	arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_STATUS(port), t);
770 	arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_HEADER(port), 0);
771 
772 	/*
773 	 * Default to 1 port group.
774 	 */
775 	t = 1 << AR8327_PORT_VLAN0_DEF_SVID_S;
776 	t |= 1 << AR8327_PORT_VLAN0_DEF_CVID_S;
777 	arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN0(port), t);
778 
779 	t = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH << AR8327_PORT_VLAN1_OUT_MODE_S;
780 	arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN1(port), t);
781 
782 	/*
783 	 * This doesn't configure any ports which this port can "see".
784 	 * bits 0-6 control which ports a frame coming into this port
785 	 * can be sent out to.
786 	 *
787 	 * So by doing this, we're making it impossible to send frames out
788 	 * to that port.
789 	 */
790 	t = AR8327_PORT_LOOKUP_LEARN;
791 	t |= AR8X16_PORT_CTRL_STATE_FORWARD << AR8327_PORT_LOOKUP_STATE_S;
792 
793 	/* So this allows traffic to any port except ourselves */
794 	t |= (ports & ~(1 << port));
795 	arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(port), t);
796 }
797 
798 static int
799 ar8327_port_vlan_setup(struct arswitch_softc *sc, etherswitch_port_t *p)
800 {
801 
802 	/* Check: ADDTAG/STRIPTAG - exclusive */
803 
804 	ARSWITCH_LOCK(sc);
805 
806 	/* Set the PVID. */
807 	if (p->es_pvid != 0)
808 		sc->hal.arswitch_vlan_set_pvid(sc, p->es_port, p->es_pvid);
809 
810 	/*
811 	 * DOUBLE_TAG
812 	 * VLAN_MODE_ADD
813 	 * VLAN_MODE_STRIP
814 	 */
815 	ARSWITCH_UNLOCK(sc);
816 	return (0);
817 }
818 
819 /*
820  * Get the port VLAN configuration.
821  */
822 static int
823 ar8327_port_vlan_get(struct arswitch_softc *sc, etherswitch_port_t *p)
824 {
825 
826 	ARSWITCH_LOCK(sc);
827 
828 	/* Retrieve the PVID */
829 	sc->hal.arswitch_vlan_get_pvid(sc, p->es_port, &p->es_pvid);
830 
831 	/* Retrieve the current port configuration from the VTU */
832 	/*
833 	 * DOUBLE_TAG
834 	 * VLAN_MODE_ADD
835 	 * VLAN_MODE_STRIP
836 	 */
837 
838 	ARSWITCH_UNLOCK(sc);
839 	return (0);
840 }
841 
842 static void
843 ar8327_port_disable_mirror(struct arswitch_softc *sc, int port)
844 {
845 
846 	arswitch_modifyreg(sc->sc_dev,
847 	    AR8327_REG_PORT_LOOKUP(port),
848 	    AR8327_PORT_LOOKUP_ING_MIRROR_EN,
849 	    0);
850 	arswitch_modifyreg(sc->sc_dev,
851 	    AR8327_REG_PORT_HOL_CTRL1(port),
852 	    AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN,
853 	    0);
854 }
855 
856 static void
857 ar8327_reset_vlans(struct arswitch_softc *sc)
858 {
859 	int i;
860 	uint32_t t;
861 	int ports;
862 
863 	ARSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
864 	ARSWITCH_LOCK(sc);
865 
866 	/* Clear the existing VLAN configuration */
867 	memset(sc->vid, 0, sizeof(sc->vid));
868 
869 	/*
870 	 * Disable mirroring.
871 	 */
872 	arswitch_modifyreg(sc->sc_dev, AR8327_REG_FWD_CTRL0,
873 	    AR8327_FWD_CTRL0_MIRROR_PORT,
874 	    (0xF << AR8327_FWD_CTRL0_MIRROR_PORT_S));
875 
876 	/*
877 	 * XXX TODO: disable any Q-in-Q port configuration,
878 	 * tagging, egress filters, etc.
879 	 */
880 
881 	/*
882 	 * For now, let's default to one portgroup, just so traffic
883 	 * flows.  All ports can see other ports. There are two CPU GMACs
884 	 * (GMAC0, GMAC6), GMAC1..GMAC5 are external PHYs.
885 	 *
886 	 * (ETHERSWITCH_VLAN_PORT)
887 	 */
888 	ports = 0x7f;
889 
890 	/*
891 	 * XXX TODO: set things up correctly for vlans!
892 	 */
893 	for (i = 0; i < AR8327_NUM_PORTS; i++) {
894 		int egress, ingress;
895 
896 		if (sc->vlan_mode == ETHERSWITCH_VLAN_PORT) {
897 			sc->vid[i] = i | ETHERSWITCH_VID_VALID;
898 			/* set egress == out_keep */
899 			ingress = AR8X16_PORT_VLAN_MODE_PORT_ONLY;
900 			/* in_port_only, forward */
901 			egress = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH;
902 		} else if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) {
903 			ingress = AR8X16_PORT_VLAN_MODE_SECURE;
904 			egress = AR8327_PORT_VLAN1_OUT_MODE_UNMOD;
905 		} else {
906 			/* set egress == out_keep */
907 			ingress = AR8X16_PORT_VLAN_MODE_PORT_ONLY;
908 			/* in_port_only, forward */
909 			egress = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH;
910 		}
911 
912 		/* set pvid = 1; there's only one vlangroup to start with */
913 		t = 1 << AR8327_PORT_VLAN0_DEF_SVID_S;
914 		t |= 1 << AR8327_PORT_VLAN0_DEF_CVID_S;
915 		arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN0(i), t);
916 
917 		t = AR8327_PORT_VLAN1_PORT_VLAN_PROP;
918 		t |= egress << AR8327_PORT_VLAN1_OUT_MODE_S;
919 		arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN1(i), t);
920 
921 		/* Ports can see other ports */
922 		/* XXX not entirely true for dot1q? */
923 		t = (ports & ~(1 << i));	/* all ports besides us */
924 		t |= AR8327_PORT_LOOKUP_LEARN;
925 
926 		t |= ingress << AR8327_PORT_LOOKUP_IN_MODE_S;
927 		t |= AR8X16_PORT_CTRL_STATE_FORWARD << AR8327_PORT_LOOKUP_STATE_S;
928 		arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(i), t);
929 	}
930 
931 	/*
932 	 * Disable port mirroring entirely.
933 	 */
934 	for (i = 0; i < AR8327_NUM_PORTS; i++) {
935 		ar8327_port_disable_mirror(sc, i);
936 	}
937 
938 	/*
939 	 * If dot1q - set pvid; dot1q, etc.
940 	 */
941 	if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) {
942 		sc->vid[0] = 1;
943 		for (i = 0; i < AR8327_NUM_PORTS; i++) {
944 			/* Each port - pvid 1 */
945 			sc->hal.arswitch_vlan_set_pvid(sc, i, sc->vid[0]);
946 		}
947 		/* Initialise vlan1 - all ports, untagged */
948 		sc->hal.arswitch_set_dot1q_vlan(sc, ports, ports, sc->vid[0]);
949 		sc->vid[0] |= ETHERSWITCH_VID_VALID;
950 	}
951 
952 	ARSWITCH_UNLOCK(sc);
953 }
954 
955 static int
956 ar8327_vlan_get_port(struct arswitch_softc *sc, uint32_t *ports, int vid)
957 {
958 	int port;
959 	uint32_t reg;
960 
961 	ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);
962 
963 	/* For port based vlans the vlanid is the same as the port index. */
964 	port = vid & ETHERSWITCH_VID_MASK;
965 	reg = arswitch_readreg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(port));
966 	*ports = reg & 0x7f;
967 	return (0);
968 }
969 
970 static int
971 ar8327_vlan_set_port(struct arswitch_softc *sc, uint32_t ports, int vid)
972 {
973 	int err, port;
974 
975 	ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);
976 
977 	/* For port based vlans the vlanid is the same as the port index. */
978 	port = vid & ETHERSWITCH_VID_MASK;
979 
980 	err = arswitch_modifyreg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(port),
981 	    0x7f, /* vlan membership mask */
982 	    (ports & 0x7f));
983 
984 	if (err)
985 		return (err);
986 	return (0);
987 }
988 
989 static int
990 ar8327_vlan_getvgroup(struct arswitch_softc *sc, etherswitch_vlangroup_t *vg)
991 {
992 
993 	return (ar8xxx_getvgroup(sc, vg));
994 }
995 
996 static int
997 ar8327_vlan_setvgroup(struct arswitch_softc *sc, etherswitch_vlangroup_t *vg)
998 {
999 
1000 	return (ar8xxx_setvgroup(sc, vg));
1001 }
1002 
1003 static int
1004 ar8327_get_pvid(struct arswitch_softc *sc, int port, int *pvid)
1005 {
1006 	uint32_t reg;
1007 
1008 	ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);
1009 
1010 	/*
1011 	 * XXX for now, assuming it's CVID; likely very wrong!
1012 	 */
1013 	port = port & ETHERSWITCH_VID_MASK;
1014 	reg = arswitch_readreg(sc->sc_dev, AR8327_REG_PORT_VLAN0(port));
1015 	reg = reg >> AR8327_PORT_VLAN0_DEF_CVID_S;
1016 	reg = reg & 0xfff;
1017 
1018 	*pvid = reg;
1019 	return (0);
1020 }
1021 
1022 static int
1023 ar8327_set_pvid(struct arswitch_softc *sc, int port, int pvid)
1024 {
1025 	uint32_t t;
1026 
1027 	/* Limit pvid to valid values */
1028 	pvid &= 0x7f;
1029 
1030 	t = pvid << AR8327_PORT_VLAN0_DEF_SVID_S;
1031 	t |= pvid << AR8327_PORT_VLAN0_DEF_CVID_S;
1032 	arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN0(port), t);
1033 
1034 	return (0);
1035 }
1036 
1037 static int
1038 ar8327_atu_flush(struct arswitch_softc *sc)
1039 {
1040 
1041 	int ret;
1042 
1043 	ret = arswitch_waitreg(sc->sc_dev,
1044 	    AR8327_REG_ATU_FUNC,
1045 	    AR8327_ATU_FUNC_BUSY,
1046 	    0,
1047 	    1000);
1048 
1049 	if (ret)
1050 		device_printf(sc->sc_dev, "%s: waitreg failed\n", __func__);
1051 
1052 	if (!ret)
1053 		arswitch_writereg(sc->sc_dev,
1054 		    AR8327_REG_ATU_FUNC,
1055 		    AR8327_ATU_FUNC_OP_FLUSH);
1056 	return (ret);
1057 }
1058 
1059 static int
1060 ar8327_flush_dot1q_vlan(struct arswitch_softc *sc)
1061 {
1062 
1063 	return (ar8327_vlan_op(sc, AR8327_VTU_FUNC1_OP_FLUSH, 0, 0));
1064 }
1065 
1066 static int
1067 ar8327_purge_dot1q_vlan(struct arswitch_softc *sc, int vid)
1068 {
1069 
1070 	return (ar8327_vlan_op(sc, AR8327_VTU_FUNC1_OP_PURGE, vid, 0));
1071 }
1072 
1073 static int
1074 ar8327_get_dot1q_vlan(struct arswitch_softc *sc, uint32_t *ports,
1075     uint32_t *untagged_ports, int vid)
1076 {
1077 	int i, r;
1078 	uint32_t op, reg, val;
1079 
1080 	op = AR8327_VTU_FUNC1_OP_GET_ONE;
1081 
1082 	/* Filter out the vid flags; only grab the VLAN ID */
1083 	vid &= 0xfff;
1084 
1085 	/* XXX TODO: the VTU here stores egress mode - keep, tag, untagged, none */
1086 	r = ar8327_vlan_op(sc, op, vid, 0);
1087 	if (r != 0) {
1088 		device_printf(sc->sc_dev, "%s: %d: op failed\n", __func__, vid);
1089 	}
1090 
1091 	reg = arswitch_readreg(sc->sc_dev, AR8327_REG_VTU_FUNC0);
1092 	DPRINTF(sc, ARSWITCH_DBG_REGIO, "%s: %d: reg=0x%08x\n", __func__, vid, reg);
1093 
1094 	/*
1095 	 * If any of the bits are set, update the port mask.
1096 	 * Worry about the port config itself when getport() is called.
1097 	 */
1098 	*ports = 0;
1099 	for (i = 0; i < AR8327_NUM_PORTS; i++) {
1100 		val = reg >> AR8327_VTU_FUNC0_EG_MODE_S(i);
1101 		val = val & 0x3;
1102 		/* XXX KEEP (unmodified?) */
1103 		if (val == AR8327_VTU_FUNC0_EG_MODE_TAG) {
1104 			*ports |= (1 << i);
1105 		} else if (val == AR8327_VTU_FUNC0_EG_MODE_UNTAG) {
1106 			*ports |= (1 << i);
1107 			*untagged_ports |= (1 << i);
1108 		}
1109 	}
1110 
1111 	return (0);
1112 }
1113 
1114 static int
1115 ar8327_set_dot1q_vlan(struct arswitch_softc *sc, uint32_t ports,
1116     uint32_t untagged_ports, int vid)
1117 {
1118 	int i;
1119 	uint32_t op, val, mode;
1120 
1121 	op = AR8327_VTU_FUNC1_OP_LOAD;
1122 	vid &= 0xfff;
1123 
1124 	DPRINTF(sc, ARSWITCH_DBG_VLAN,
1125 	    "%s: vid: %d, ports=0x%08x, untagged_ports=0x%08x\n",
1126 	    __func__,
1127 	    vid,
1128 	    ports,
1129 	    untagged_ports);
1130 
1131 	/*
1132 	 * Mark it as valid; and that it should use per-VLAN MAC table,
1133 	 * not VID=0 when doing MAC lookups
1134 	 */
1135 	val = AR8327_VTU_FUNC0_VALID | AR8327_VTU_FUNC0_IVL;
1136 
1137 	for (i = 0; i < AR8327_NUM_PORTS; i++) {
1138 		if ((ports & BIT(i)) == 0)
1139 			mode = AR8327_VTU_FUNC0_EG_MODE_NOT;
1140 		else if (untagged_ports & BIT(i))
1141 			mode = AR8327_VTU_FUNC0_EG_MODE_UNTAG;
1142 		else
1143 			mode = AR8327_VTU_FUNC0_EG_MODE_TAG;
1144 
1145 		val |= mode << AR8327_VTU_FUNC0_EG_MODE_S(i);
1146 	}
1147 
1148 	return (ar8327_vlan_op(sc, op, vid, val));
1149 }
1150 
1151 void
1152 ar8327_attach(struct arswitch_softc *sc)
1153 {
1154 
1155 	sc->hal.arswitch_hw_setup = ar8327_hw_setup;
1156 	sc->hal.arswitch_hw_global_setup = ar8327_hw_global_setup;
1157 
1158 	sc->hal.arswitch_port_init = ar8327_port_init;
1159 
1160 	sc->hal.arswitch_vlan_getvgroup = ar8327_vlan_getvgroup;
1161 	sc->hal.arswitch_vlan_setvgroup = ar8327_vlan_setvgroup;
1162 	sc->hal.arswitch_port_vlan_setup = ar8327_port_vlan_setup;
1163 	sc->hal.arswitch_port_vlan_get = ar8327_port_vlan_get;
1164 	sc->hal.arswitch_flush_dot1q_vlan = ar8327_flush_dot1q_vlan;
1165 	sc->hal.arswitch_purge_dot1q_vlan = ar8327_purge_dot1q_vlan;
1166 	sc->hal.arswitch_set_dot1q_vlan = ar8327_set_dot1q_vlan;
1167 	sc->hal.arswitch_get_dot1q_vlan = ar8327_get_dot1q_vlan;
1168 
1169 	sc->hal.arswitch_vlan_init_hw = ar8327_reset_vlans;
1170 	sc->hal.arswitch_vlan_get_pvid = ar8327_get_pvid;
1171 	sc->hal.arswitch_vlan_set_pvid = ar8327_set_pvid;
1172 
1173 	sc->hal.arswitch_get_port_vlan = ar8327_vlan_get_port;
1174 	sc->hal.arswitch_set_port_vlan = ar8327_vlan_set_port;
1175 
1176 	sc->hal.arswitch_atu_flush = ar8327_atu_flush;
1177 
1178 	/*
1179 	 * Reading the PHY via the MDIO interface currently doesn't
1180 	 * work correctly.
1181 	 *
1182 	 * So for now, just go direct to the PHY registers themselves.
1183 	 * This has always worked  on external devices, but not internal
1184 	 * devices (AR934x, AR724x, AR933x.)
1185 	 */
1186 	sc->hal.arswitch_phy_read = arswitch_readphy_external;
1187 	sc->hal.arswitch_phy_write = arswitch_writephy_external;
1188 
1189 	/* Set the switch vlan capabilities. */
1190 	sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q |
1191 	    ETHERSWITCH_VLAN_PORT | ETHERSWITCH_VLAN_DOUBLE_TAG;
1192 	sc->info.es_nvlangroups = AR8X16_MAX_VLANS;
1193 }
1194