xref: /freebsd/sys/dev/etherswitch/arswitch/arswitch_8327.c (revision 2e3507c25e42292b45a5482e116d278f5515d04d)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
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 
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 static int
704 ar8327_atu_learn_default(struct arswitch_softc *sc)
705 {
706 
707 	device_printf(sc->sc_dev, "%s: TODO!\n", __func__);
708 	return (0);
709 }
710 
711 /*
712  * Initialise other global values, for the AR8327.
713  */
714 static int
715 ar8327_hw_global_setup(struct arswitch_softc *sc)
716 {
717 	uint32_t t;
718 
719 	ARSWITCH_LOCK(sc);
720 
721 	/* enable CPU port and disable mirror port */
722 	t = AR8327_FWD_CTRL0_CPU_PORT_EN |
723 	    AR8327_FWD_CTRL0_MIRROR_PORT;
724 	arswitch_writereg(sc->sc_dev, AR8327_REG_FWD_CTRL0, t);
725 
726 	/* forward multicast and broadcast frames to CPU */
727 	t = (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_UC_FLOOD_S) |
728 	    (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_MC_FLOOD_S) |
729 	    (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_BC_FLOOD_S);
730 	arswitch_writereg(sc->sc_dev, AR8327_REG_FWD_CTRL1, t);
731 
732 	/* enable jumbo frames */
733 	/* XXX need to macro-shift the value! */
734 	arswitch_modifyreg(sc->sc_dev, AR8327_REG_MAX_FRAME_SIZE,
735 	    AR8327_MAX_FRAME_SIZE_MTU, 9018 + 8 + 2);
736 
737 	/* Enable MIB counters */
738 	arswitch_modifyreg(sc->sc_dev, AR8327_REG_MODULE_EN,
739 	    AR8327_MODULE_EN_MIB, AR8327_MODULE_EN_MIB);
740 
741 	/* Disable EEE on all ports due to stability issues */
742 	t = arswitch_readreg(sc->sc_dev, AR8327_REG_EEE_CTRL);
743 	t |= AR8327_EEE_CTRL_DISABLE_PHY(0) |
744 	    AR8327_EEE_CTRL_DISABLE_PHY(1) |
745 	    AR8327_EEE_CTRL_DISABLE_PHY(2) |
746 	    AR8327_EEE_CTRL_DISABLE_PHY(3) |
747 	    AR8327_EEE_CTRL_DISABLE_PHY(4);
748 	arswitch_writereg(sc->sc_dev, AR8327_REG_EEE_CTRL, t);
749 
750 	/* Set the right number of ports */
751 	/* GMAC0 (CPU), GMAC1..5 (PHYs), GMAC6 (CPU) */
752 	sc->info.es_nports = 7;
753 
754 	ARSWITCH_UNLOCK(sc);
755 	return (0);
756 }
757 
758 /*
759  * Port setup.  Called at attach time.
760  */
761 static void
762 ar8327_port_init(struct arswitch_softc *sc, int port)
763 {
764 	uint32_t t;
765 	int ports;
766 
767 	/* For now, port can see all other ports */
768 	ports = 0x7f;
769 
770 	if (port == AR8X16_PORT_CPU)
771 		t = sc->ar8327.port0_status;
772 	else if (port == 6)
773 		t = sc->ar8327.port6_status;
774         else
775 		t = AR8X16_PORT_STS_LINK_AUTO;
776 
777 	arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_STATUS(port), t);
778 	arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_HEADER(port), 0);
779 
780 	/*
781 	 * Default to 1 port group.
782 	 */
783 	t = 1 << AR8327_PORT_VLAN0_DEF_SVID_S;
784 	t |= 1 << AR8327_PORT_VLAN0_DEF_CVID_S;
785 	arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN0(port), t);
786 
787 	t = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH << AR8327_PORT_VLAN1_OUT_MODE_S;
788 	arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN1(port), t);
789 
790 	/*
791 	 * This doesn't configure any ports which this port can "see".
792 	 * bits 0-6 control which ports a frame coming into this port
793 	 * can be sent out to.
794 	 *
795 	 * So by doing this, we're making it impossible to send frames out
796 	 * to that port.
797 	 */
798 	t = AR8327_PORT_LOOKUP_LEARN;
799 	t |= AR8X16_PORT_CTRL_STATE_FORWARD << AR8327_PORT_LOOKUP_STATE_S;
800 
801 	/* So this allows traffic to any port except ourselves */
802 	t |= (ports & ~(1 << port));
803 	arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(port), t);
804 }
805 
806 static int
807 ar8327_port_vlan_setup(struct arswitch_softc *sc, etherswitch_port_t *p)
808 {
809 
810 	/* Check: ADDTAG/STRIPTAG - exclusive */
811 
812 	ARSWITCH_LOCK(sc);
813 
814 	/* Set the PVID. */
815 	if (p->es_pvid != 0)
816 		sc->hal.arswitch_vlan_set_pvid(sc, p->es_port, p->es_pvid);
817 
818 	/*
819 	 * DOUBLE_TAG
820 	 * VLAN_MODE_ADD
821 	 * VLAN_MODE_STRIP
822 	 */
823 	ARSWITCH_UNLOCK(sc);
824 	return (0);
825 }
826 
827 /*
828  * Get the port VLAN configuration.
829  */
830 static int
831 ar8327_port_vlan_get(struct arswitch_softc *sc, etherswitch_port_t *p)
832 {
833 
834 	ARSWITCH_LOCK(sc);
835 
836 	/* Retrieve the PVID */
837 	sc->hal.arswitch_vlan_get_pvid(sc, p->es_port, &p->es_pvid);
838 
839 	/* Retrieve the current port configuration from the VTU */
840 	/*
841 	 * DOUBLE_TAG
842 	 * VLAN_MODE_ADD
843 	 * VLAN_MODE_STRIP
844 	 */
845 
846 	ARSWITCH_UNLOCK(sc);
847 	return (0);
848 }
849 
850 static void
851 ar8327_port_disable_mirror(struct arswitch_softc *sc, int port)
852 {
853 
854 	arswitch_modifyreg(sc->sc_dev,
855 	    AR8327_REG_PORT_LOOKUP(port),
856 	    AR8327_PORT_LOOKUP_ING_MIRROR_EN,
857 	    0);
858 	arswitch_modifyreg(sc->sc_dev,
859 	    AR8327_REG_PORT_HOL_CTRL1(port),
860 	    AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN,
861 	    0);
862 }
863 
864 static void
865 ar8327_reset_vlans(struct arswitch_softc *sc)
866 {
867 	int i;
868 	uint32_t t;
869 	int ports;
870 
871 	ARSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
872 	ARSWITCH_LOCK(sc);
873 
874 	/* Clear the existing VLAN configuration */
875 	memset(sc->vid, 0, sizeof(sc->vid));
876 
877 	/*
878 	 * Disable mirroring.
879 	 */
880 	arswitch_modifyreg(sc->sc_dev, AR8327_REG_FWD_CTRL0,
881 	    AR8327_FWD_CTRL0_MIRROR_PORT,
882 	    (0xF << AR8327_FWD_CTRL0_MIRROR_PORT_S));
883 
884 	/*
885 	 * XXX TODO: disable any Q-in-Q port configuration,
886 	 * tagging, egress filters, etc.
887 	 */
888 
889 	/*
890 	 * For now, let's default to one portgroup, just so traffic
891 	 * flows.  All ports can see other ports. There are two CPU GMACs
892 	 * (GMAC0, GMAC6), GMAC1..GMAC5 are external PHYs.
893 	 *
894 	 * (ETHERSWITCH_VLAN_PORT)
895 	 */
896 	ports = 0x7f;
897 
898 	/*
899 	 * XXX TODO: set things up correctly for vlans!
900 	 */
901 	for (i = 0; i < AR8327_NUM_PORTS; i++) {
902 		int egress, ingress;
903 
904 		if (sc->vlan_mode == ETHERSWITCH_VLAN_PORT) {
905 			sc->vid[i] = i | ETHERSWITCH_VID_VALID;
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 		} else if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) {
911 			ingress = AR8X16_PORT_VLAN_MODE_SECURE;
912 			egress = AR8327_PORT_VLAN1_OUT_MODE_UNMOD;
913 		} else {
914 			/* set egress == out_keep */
915 			ingress = AR8X16_PORT_VLAN_MODE_PORT_ONLY;
916 			/* in_port_only, forward */
917 			egress = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH;
918 		}
919 
920 		/* set pvid = 1; there's only one vlangroup to start with */
921 		t = 1 << AR8327_PORT_VLAN0_DEF_SVID_S;
922 		t |= 1 << AR8327_PORT_VLAN0_DEF_CVID_S;
923 		arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN0(i), t);
924 
925 		t = AR8327_PORT_VLAN1_PORT_VLAN_PROP;
926 		t |= egress << AR8327_PORT_VLAN1_OUT_MODE_S;
927 		arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN1(i), t);
928 
929 		/* Ports can see other ports */
930 		/* XXX not entirely true for dot1q? */
931 		t = (ports & ~(1 << i));	/* all ports besides us */
932 		t |= AR8327_PORT_LOOKUP_LEARN;
933 
934 		t |= ingress << AR8327_PORT_LOOKUP_IN_MODE_S;
935 		t |= AR8X16_PORT_CTRL_STATE_FORWARD << AR8327_PORT_LOOKUP_STATE_S;
936 		arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(i), t);
937 	}
938 
939 	/*
940 	 * Disable port mirroring entirely.
941 	 */
942 	for (i = 0; i < AR8327_NUM_PORTS; i++) {
943 		ar8327_port_disable_mirror(sc, i);
944 	}
945 
946 	/*
947 	 * If dot1q - set pvid; dot1q, etc.
948 	 */
949 	if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) {
950 		sc->vid[0] = 1;
951 		for (i = 0; i < AR8327_NUM_PORTS; i++) {
952 			/* Each port - pvid 1 */
953 			sc->hal.arswitch_vlan_set_pvid(sc, i, sc->vid[0]);
954 		}
955 		/* Initialise vlan1 - all ports, untagged */
956 		sc->hal.arswitch_set_dot1q_vlan(sc, ports, ports, sc->vid[0]);
957 		sc->vid[0] |= ETHERSWITCH_VID_VALID;
958 	}
959 
960 	ARSWITCH_UNLOCK(sc);
961 }
962 
963 static int
964 ar8327_vlan_get_port(struct arswitch_softc *sc, uint32_t *ports, int vid)
965 {
966 	int port;
967 	uint32_t reg;
968 
969 	ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);
970 
971 	/* For port based vlans the vlanid is the same as the port index. */
972 	port = vid & ETHERSWITCH_VID_MASK;
973 	reg = arswitch_readreg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(port));
974 	*ports = reg & 0x7f;
975 	return (0);
976 }
977 
978 static int
979 ar8327_vlan_set_port(struct arswitch_softc *sc, uint32_t ports, int vid)
980 {
981 	int err, port;
982 
983 	ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);
984 
985 	/* For port based vlans the vlanid is the same as the port index. */
986 	port = vid & ETHERSWITCH_VID_MASK;
987 
988 	err = arswitch_modifyreg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(port),
989 	    0x7f, /* vlan membership mask */
990 	    (ports & 0x7f));
991 
992 	if (err)
993 		return (err);
994 	return (0);
995 }
996 
997 static int
998 ar8327_vlan_getvgroup(struct arswitch_softc *sc, etherswitch_vlangroup_t *vg)
999 {
1000 
1001 	return (ar8xxx_getvgroup(sc, vg));
1002 }
1003 
1004 static int
1005 ar8327_vlan_setvgroup(struct arswitch_softc *sc, etherswitch_vlangroup_t *vg)
1006 {
1007 
1008 	return (ar8xxx_setvgroup(sc, vg));
1009 }
1010 
1011 static int
1012 ar8327_get_pvid(struct arswitch_softc *sc, int port, int *pvid)
1013 {
1014 	uint32_t reg;
1015 
1016 	ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);
1017 
1018 	/*
1019 	 * XXX for now, assuming it's CVID; likely very wrong!
1020 	 */
1021 	port = port & ETHERSWITCH_VID_MASK;
1022 	reg = arswitch_readreg(sc->sc_dev, AR8327_REG_PORT_VLAN0(port));
1023 	reg = reg >> AR8327_PORT_VLAN0_DEF_CVID_S;
1024 	reg = reg & 0xfff;
1025 
1026 	*pvid = reg;
1027 	return (0);
1028 }
1029 
1030 static int
1031 ar8327_set_pvid(struct arswitch_softc *sc, int port, int pvid)
1032 {
1033 	uint32_t t;
1034 
1035 	/* Limit pvid to valid values */
1036 	pvid &= 0x7f;
1037 
1038 	t = pvid << AR8327_PORT_VLAN0_DEF_SVID_S;
1039 	t |= pvid << AR8327_PORT_VLAN0_DEF_CVID_S;
1040 	arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN0(port), t);
1041 
1042 	return (0);
1043 }
1044 
1045 static int
1046 ar8327_atu_wait_ready(struct arswitch_softc *sc)
1047 {
1048 	int ret;
1049 
1050 	ret = arswitch_waitreg(sc->sc_dev,
1051 	    AR8327_REG_ATU_FUNC,
1052 	    AR8327_ATU_FUNC_BUSY,
1053 	    0,
1054 	    1000);
1055 
1056 	return (ret);
1057 }
1058 
1059 static int
1060 ar8327_atu_flush(struct arswitch_softc *sc)
1061 {
1062 
1063 	int ret;
1064 
1065 	ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);
1066 
1067 	ret = ar8327_atu_wait_ready(sc);
1068 	if (ret)
1069 		device_printf(sc->sc_dev, "%s: waitreg failed\n", __func__);
1070 
1071 	if (!ret)
1072 		arswitch_writereg(sc->sc_dev,
1073 		    AR8327_REG_ATU_FUNC,
1074 		    AR8327_ATU_FUNC_OP_FLUSH | AR8327_ATU_FUNC_BUSY);
1075 	return (ret);
1076 }
1077 
1078 static int
1079 ar8327_atu_flush_port(struct arswitch_softc *sc, int port)
1080 {
1081 	int ret;
1082 	uint32_t val;
1083 
1084 	ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);
1085 
1086 	ret = ar8327_atu_wait_ready(sc);
1087 	if (ret)
1088 		device_printf(sc->sc_dev, "%s: waitreg failed\n", __func__);
1089 
1090 	val = AR8327_ATU_FUNC_OP_FLUSH_UNICAST;
1091 	val |= SM(port, AR8327_ATU_FUNC_PORT_NUM);
1092 
1093 	if (!ret)
1094 		arswitch_writereg(sc->sc_dev,
1095 		    AR8327_REG_ATU_FUNC,
1096 		    val | AR8327_ATU_FUNC_BUSY);
1097 
1098 	return (ret);
1099 }
1100 
1101 /*
1102  * Fetch a single entry from the ATU.
1103  */
1104 static int
1105 ar8327_atu_fetch_table(struct arswitch_softc *sc, etherswitch_atu_entry_t *e,
1106     int atu_fetch_op)
1107 {
1108 	uint32_t ret0, ret1, ret2, val;
1109 
1110 	ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);
1111 
1112 	switch (atu_fetch_op) {
1113 	case 0:
1114 		/* Initialise things for the first fetch */
1115 
1116 		DPRINTF(sc, ARSWITCH_DBG_ATU, "%s: initializing\n", __func__);
1117 		(void) ar8327_atu_wait_ready(sc);
1118 
1119 		arswitch_writereg(sc->sc_dev,
1120 		    AR8327_REG_ATU_FUNC, AR8327_ATU_FUNC_OP_GET_NEXT);
1121 		arswitch_writereg(sc->sc_dev, AR8327_REG_ATU_DATA0, 0);
1122 		arswitch_writereg(sc->sc_dev, AR8327_REG_ATU_DATA1, 0);
1123 		arswitch_writereg(sc->sc_dev, AR8327_REG_ATU_DATA2, 0);
1124 
1125 		return (0);
1126 	case 1:
1127 		DPRINTF(sc, ARSWITCH_DBG_ATU, "%s: reading next\n", __func__);
1128 		/*
1129 		 * Attempt to read the next address entry; don't modify what
1130 		 * is there in these registers as its used for the next fetch
1131 		 */
1132 		(void) ar8327_atu_wait_ready(sc);
1133 
1134 		/* Begin the next read event; not modifying anything */
1135 		val = arswitch_readreg(sc->sc_dev, AR8327_REG_ATU_FUNC);
1136 		val |= AR8327_ATU_FUNC_BUSY;
1137 		arswitch_writereg(sc->sc_dev, AR8327_REG_ATU_FUNC, val);
1138 
1139 		/* Wait for it to complete */
1140 		(void) ar8327_atu_wait_ready(sc);
1141 
1142 		/* Fetch the ethernet address and ATU status */
1143 		ret0 = arswitch_readreg(sc->sc_dev, AR8327_REG_ATU_DATA0);
1144 		ret1 = arswitch_readreg(sc->sc_dev, AR8327_REG_ATU_DATA1);
1145 		ret2 = arswitch_readreg(sc->sc_dev, AR8327_REG_ATU_DATA2);
1146 
1147 		/* If the status is zero, then we're done */
1148 		if (MS(ret2, AR8327_ATU_FUNC_DATA2_STATUS) == 0)
1149 			return (-1);
1150 
1151 		/* MAC address */
1152 		e->es_macaddr[5] = MS(ret0, AR8327_ATU_DATA0_MAC_ADDR3);
1153 		e->es_macaddr[4] = MS(ret0, AR8327_ATU_DATA0_MAC_ADDR2);
1154 		e->es_macaddr[3] = MS(ret0, AR8327_ATU_DATA0_MAC_ADDR1);
1155 		e->es_macaddr[2] = MS(ret0, AR8327_ATU_DATA0_MAC_ADDR0);
1156 		e->es_macaddr[0] = MS(ret1, AR8327_ATU_DATA1_MAC_ADDR5);
1157 		e->es_macaddr[1] = MS(ret1, AR8327_ATU_DATA1_MAC_ADDR4);
1158 
1159 		/* Bitmask of ports this entry is for */
1160 		e->es_portmask = MS(ret1, AR8327_ATU_DATA1_DEST_PORT);
1161 
1162 		/* TODO: other flags that are interesting */
1163 
1164 		DPRINTF(sc, ARSWITCH_DBG_ATU, "%s: MAC %6D portmask 0x%08x\n",
1165 		    __func__,
1166 		    e->es_macaddr, ":", e->es_portmask);
1167 		return (0);
1168 	default:
1169 		return (-1);
1170 	}
1171 	return (-1);
1172 }
1173 static int
1174 ar8327_flush_dot1q_vlan(struct arswitch_softc *sc)
1175 {
1176 
1177 	return (ar8327_vlan_op(sc, AR8327_VTU_FUNC1_OP_FLUSH, 0, 0));
1178 }
1179 
1180 static int
1181 ar8327_purge_dot1q_vlan(struct arswitch_softc *sc, int vid)
1182 {
1183 
1184 	return (ar8327_vlan_op(sc, AR8327_VTU_FUNC1_OP_PURGE, vid, 0));
1185 }
1186 
1187 static int
1188 ar8327_get_dot1q_vlan(struct arswitch_softc *sc, uint32_t *ports,
1189     uint32_t *untagged_ports, int vid)
1190 {
1191 	int i, r;
1192 	uint32_t op, reg, val;
1193 
1194 	op = AR8327_VTU_FUNC1_OP_GET_ONE;
1195 
1196 	/* Filter out the vid flags; only grab the VLAN ID */
1197 	vid &= 0xfff;
1198 
1199 	/* XXX TODO: the VTU here stores egress mode - keep, tag, untagged, none */
1200 	r = ar8327_vlan_op(sc, op, vid, 0);
1201 	if (r != 0) {
1202 		device_printf(sc->sc_dev, "%s: %d: op failed\n", __func__, vid);
1203 	}
1204 
1205 	reg = arswitch_readreg(sc->sc_dev, AR8327_REG_VTU_FUNC0);
1206 	DPRINTF(sc, ARSWITCH_DBG_REGIO, "%s: %d: reg=0x%08x\n", __func__, vid, reg);
1207 
1208 	/*
1209 	 * If any of the bits are set, update the port mask.
1210 	 * Worry about the port config itself when getport() is called.
1211 	 */
1212 	*ports = 0;
1213 	for (i = 0; i < AR8327_NUM_PORTS; i++) {
1214 		val = reg >> AR8327_VTU_FUNC0_EG_MODE_S(i);
1215 		val = val & 0x3;
1216 		/* XXX KEEP (unmodified?) */
1217 		if (val == AR8327_VTU_FUNC0_EG_MODE_TAG) {
1218 			*ports |= (1 << i);
1219 		} else if (val == AR8327_VTU_FUNC0_EG_MODE_UNTAG) {
1220 			*ports |= (1 << i);
1221 			*untagged_ports |= (1 << i);
1222 		}
1223 	}
1224 
1225 	return (0);
1226 }
1227 
1228 static int
1229 ar8327_set_dot1q_vlan(struct arswitch_softc *sc, uint32_t ports,
1230     uint32_t untagged_ports, int vid)
1231 {
1232 	int i;
1233 	uint32_t op, val, mode;
1234 
1235 	op = AR8327_VTU_FUNC1_OP_LOAD;
1236 	vid &= 0xfff;
1237 
1238 	DPRINTF(sc, ARSWITCH_DBG_VLAN,
1239 	    "%s: vid: %d, ports=0x%08x, untagged_ports=0x%08x\n",
1240 	    __func__,
1241 	    vid,
1242 	    ports,
1243 	    untagged_ports);
1244 
1245 	/*
1246 	 * Mark it as valid; and that it should use per-VLAN MAC table,
1247 	 * not VID=0 when doing MAC lookups
1248 	 */
1249 	val = AR8327_VTU_FUNC0_VALID | AR8327_VTU_FUNC0_IVL;
1250 
1251 	for (i = 0; i < AR8327_NUM_PORTS; i++) {
1252 		if ((ports & BIT(i)) == 0)
1253 			mode = AR8327_VTU_FUNC0_EG_MODE_NOT;
1254 		else if (untagged_ports & BIT(i))
1255 			mode = AR8327_VTU_FUNC0_EG_MODE_UNTAG;
1256 		else
1257 			mode = AR8327_VTU_FUNC0_EG_MODE_TAG;
1258 
1259 		val |= mode << AR8327_VTU_FUNC0_EG_MODE_S(i);
1260 	}
1261 
1262 	return (ar8327_vlan_op(sc, op, vid, val));
1263 }
1264 
1265 void
1266 ar8327_attach(struct arswitch_softc *sc)
1267 {
1268 
1269 	sc->hal.arswitch_hw_setup = ar8327_hw_setup;
1270 	sc->hal.arswitch_hw_global_setup = ar8327_hw_global_setup;
1271 
1272 	sc->hal.arswitch_port_init = ar8327_port_init;
1273 
1274 	sc->hal.arswitch_vlan_getvgroup = ar8327_vlan_getvgroup;
1275 	sc->hal.arswitch_vlan_setvgroup = ar8327_vlan_setvgroup;
1276 	sc->hal.arswitch_port_vlan_setup = ar8327_port_vlan_setup;
1277 	sc->hal.arswitch_port_vlan_get = ar8327_port_vlan_get;
1278 	sc->hal.arswitch_flush_dot1q_vlan = ar8327_flush_dot1q_vlan;
1279 	sc->hal.arswitch_purge_dot1q_vlan = ar8327_purge_dot1q_vlan;
1280 	sc->hal.arswitch_set_dot1q_vlan = ar8327_set_dot1q_vlan;
1281 	sc->hal.arswitch_get_dot1q_vlan = ar8327_get_dot1q_vlan;
1282 
1283 	sc->hal.arswitch_vlan_init_hw = ar8327_reset_vlans;
1284 	sc->hal.arswitch_vlan_get_pvid = ar8327_get_pvid;
1285 	sc->hal.arswitch_vlan_set_pvid = ar8327_set_pvid;
1286 
1287 	sc->hal.arswitch_get_port_vlan = ar8327_vlan_get_port;
1288 	sc->hal.arswitch_set_port_vlan = ar8327_vlan_set_port;
1289 
1290 	sc->hal.arswitch_atu_learn_default = ar8327_atu_learn_default;
1291 	sc->hal.arswitch_atu_flush = ar8327_atu_flush;
1292 	sc->hal.arswitch_atu_flush_port = ar8327_atu_flush_port;
1293 	sc->hal.arswitch_atu_fetch_table = ar8327_atu_fetch_table;
1294 
1295 	/*
1296 	 * Reading the PHY via the MDIO interface currently doesn't
1297 	 * work correctly.
1298 	 *
1299 	 * So for now, just go direct to the PHY registers themselves.
1300 	 * This has always worked  on external devices, but not internal
1301 	 * devices (AR934x, AR724x, AR933x.)
1302 	 */
1303 	sc->hal.arswitch_phy_read = arswitch_readphy_external;
1304 	sc->hal.arswitch_phy_write = arswitch_writephy_external;
1305 
1306 	/* Set the switch vlan capabilities. */
1307 	sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q |
1308 	    ETHERSWITCH_VLAN_PORT | ETHERSWITCH_VLAN_DOUBLE_TAG;
1309 	sc->info.es_nvlangroups = AR8X16_MAX_VLANS;
1310 }
1311