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 */
79struct 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
108static int
109ar8327_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
152static void
153ar8327_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
183static uint32_t
184ar8327_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 */
281static uint32_t
282ar8327_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 */
318static int
319ar8327_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 */
411static int
412ar8327_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 */
502static int
503ar8327_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 */
530static int
531ar8327_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 */
578static int
579ar8327_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
675static int
676ar8327_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
703static int
704ar8327_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 */
714static int
715ar8327_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 */
761static void
762ar8327_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
806static int
807ar8327_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 */
830static int
831ar8327_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
850static void
851ar8327_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
864static void
865ar8327_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
963static int
964ar8327_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
978static int
979ar8327_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
997static int
998ar8327_vlan_getvgroup(struct arswitch_softc *sc, etherswitch_vlangroup_t *vg)
999{
1000
1001	return (ar8xxx_getvgroup(sc, vg));
1002}
1003
1004static int
1005ar8327_vlan_setvgroup(struct arswitch_softc *sc, etherswitch_vlangroup_t *vg)
1006{
1007
1008	return (ar8xxx_setvgroup(sc, vg));
1009}
1010
1011static int
1012ar8327_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
1030static int
1031ar8327_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
1045static int
1046ar8327_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
1059static int
1060ar8327_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
1078static int
1079ar8327_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 */
1104static int
1105ar8327_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}
1173static int
1174ar8327_flush_dot1q_vlan(struct arswitch_softc *sc)
1175{
1176
1177	return (ar8327_vlan_op(sc, AR8327_VTU_FUNC1_OP_FLUSH, 0, 0));
1178}
1179
1180static int
1181ar8327_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
1187static int
1188ar8327_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
1228static int
1229ar8327_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
1265void
1266ar8327_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