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