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