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