xref: /freebsd/sys/dev/etherswitch/e6000sw/e6000sw.c (revision 716fd348)
1 /*-
2  * Copyright (c) 2015 Semihalf
3  * Copyright (c) 2015 Stormshield
4  * Copyright (c) 2018-2019, Rubicon Communications, LLC (Netgate)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31 
32 #include <sys/param.h>
33 #include <sys/bus.h>
34 #include <sys/errno.h>
35 #include <sys/kernel.h>
36 #include <sys/kthread.h>
37 #include <sys/module.h>
38 #include <sys/taskqueue.h>
39 #include <sys/socket.h>
40 #include <sys/sockio.h>
41 
42 #include <net/if.h>
43 #include <net/if_media.h>
44 #include <net/if_types.h>
45 
46 #include <dev/etherswitch/etherswitch.h>
47 #include <dev/mii/mii.h>
48 #include <dev/mii/miivar.h>
49 
50 #include <dev/ofw/ofw_bus.h>
51 #include <dev/ofw/ofw_bus_subr.h>
52 
53 #include "e6000swreg.h"
54 #include "etherswitch_if.h"
55 #include "miibus_if.h"
56 #include "mdio_if.h"
57 
58 MALLOC_DECLARE(M_E6000SW);
59 MALLOC_DEFINE(M_E6000SW, "e6000sw", "e6000sw switch");
60 
61 #define	E6000SW_LOCK(_sc)		sx_xlock(&(_sc)->sx)
62 #define	E6000SW_UNLOCK(_sc)		sx_unlock(&(_sc)->sx)
63 #define	E6000SW_LOCK_ASSERT(_sc, _what)	sx_assert(&(_sc)->sx, (_what))
64 #define	E6000SW_TRYLOCK(_sc)		sx_tryxlock(&(_sc)->sx)
65 #define	E6000SW_WAITREADY(_sc, _reg, _bit)				\
66     e6000sw_waitready((_sc), REG_GLOBAL, (_reg), (_bit))
67 #define	E6000SW_WAITREADY2(_sc, _reg, _bit)				\
68     e6000sw_waitready((_sc), REG_GLOBAL2, (_reg), (_bit))
69 #define	MDIO_READ(dev, addr, reg)					\
70     MDIO_READREG(device_get_parent(dev), (addr), (reg))
71 #define	MDIO_WRITE(dev, addr, reg, val)					\
72     MDIO_WRITEREG(device_get_parent(dev), (addr), (reg), (val))
73 
74 
75 typedef struct e6000sw_softc {
76 	device_t		dev;
77 	phandle_t		node;
78 
79 	struct sx		sx;
80 	struct ifnet		*ifp[E6000SW_MAX_PORTS];
81 	char			*ifname[E6000SW_MAX_PORTS];
82 	device_t		miibus[E6000SW_MAX_PORTS];
83 	struct taskqueue	*sc_tq;
84 	struct timeout_task	sc_tt;
85 
86 	int			vlans[E6000SW_NUM_VLANS];
87 	uint32_t		swid;
88 	uint32_t		vlan_mode;
89 	uint32_t		cpuports_mask;
90 	uint32_t		fixed_mask;
91 	uint32_t		fixed25_mask;
92 	uint32_t		ports_mask;
93 	int			phy_base;
94 	int			sw_addr;
95 	int			num_ports;
96 } e6000sw_softc_t;
97 
98 static etherswitch_info_t etherswitch_info = {
99 	.es_nports =		0,
100 	.es_nvlangroups =	0,
101 	.es_vlan_caps =		ETHERSWITCH_VLAN_PORT | ETHERSWITCH_VLAN_DOT1Q,
102 	.es_name =		"Marvell 6000 series switch"
103 };
104 
105 static void e6000sw_identify(driver_t *, device_t);
106 static int e6000sw_probe(device_t);
107 static int e6000sw_parse_fixed_link(e6000sw_softc_t *, phandle_t, uint32_t);
108 static int e6000sw_parse_ethernet(e6000sw_softc_t *, phandle_t, uint32_t);
109 static int e6000sw_attach(device_t);
110 static int e6000sw_detach(device_t);
111 static int e6000sw_read_xmdio(device_t, int, int, int);
112 static int e6000sw_write_xmdio(device_t, int, int, int, int);
113 static int e6000sw_readphy(device_t, int, int);
114 static int e6000sw_writephy(device_t, int, int, int);
115 static etherswitch_info_t* e6000sw_getinfo(device_t);
116 static int e6000sw_getconf(device_t, etherswitch_conf_t *);
117 static int e6000sw_setconf(device_t, etherswitch_conf_t *);
118 static void e6000sw_lock(device_t);
119 static void e6000sw_unlock(device_t);
120 static int e6000sw_getport(device_t, etherswitch_port_t *);
121 static int e6000sw_setport(device_t, etherswitch_port_t *);
122 static int e6000sw_set_vlan_mode(e6000sw_softc_t *, uint32_t);
123 static int e6000sw_readreg_wrapper(device_t, int);
124 static int e6000sw_writereg_wrapper(device_t, int, int);
125 static int e6000sw_getvgroup_wrapper(device_t, etherswitch_vlangroup_t *);
126 static int e6000sw_setvgroup_wrapper(device_t, etherswitch_vlangroup_t *);
127 static int e6000sw_setvgroup(device_t, etherswitch_vlangroup_t *);
128 static int e6000sw_getvgroup(device_t, etherswitch_vlangroup_t *);
129 static void e6000sw_setup(device_t, e6000sw_softc_t *);
130 static void e6000sw_tick(void *, int);
131 static void e6000sw_set_atustat(device_t, e6000sw_softc_t *, int, int);
132 static int e6000sw_atu_flush(device_t, e6000sw_softc_t *, int);
133 static int e6000sw_vtu_flush(e6000sw_softc_t *);
134 static int e6000sw_vtu_update(e6000sw_softc_t *, int, int, int, int, int);
135 static __inline void e6000sw_writereg(e6000sw_softc_t *, int, int, int);
136 static __inline uint32_t e6000sw_readreg(e6000sw_softc_t *, int, int);
137 static int e6000sw_ifmedia_upd(struct ifnet *);
138 static void e6000sw_ifmedia_sts(struct ifnet *, struct ifmediareq *);
139 static int e6000sw_atu_mac_table(device_t, e6000sw_softc_t *, struct atu_opt *,
140     int);
141 static int e6000sw_get_pvid(e6000sw_softc_t *, int, int *);
142 static void e6000sw_set_pvid(e6000sw_softc_t *, int, int);
143 static __inline bool e6000sw_is_cpuport(e6000sw_softc_t *, int);
144 static __inline bool e6000sw_is_fixedport(e6000sw_softc_t *, int);
145 static __inline bool e6000sw_is_fixed25port(e6000sw_softc_t *, int);
146 static __inline bool e6000sw_is_phyport(e6000sw_softc_t *, int);
147 static __inline bool e6000sw_is_portenabled(e6000sw_softc_t *, int);
148 static __inline struct mii_data *e6000sw_miiforphy(e6000sw_softc_t *,
149     unsigned int);
150 
151 static device_method_t e6000sw_methods[] = {
152 	/* device interface */
153 	DEVMETHOD(device_identify,		e6000sw_identify),
154 	DEVMETHOD(device_probe,			e6000sw_probe),
155 	DEVMETHOD(device_attach,		e6000sw_attach),
156 	DEVMETHOD(device_detach,		e6000sw_detach),
157 
158 	/* bus interface */
159 	DEVMETHOD(bus_add_child,		device_add_child_ordered),
160 
161 	/* mii interface */
162 	DEVMETHOD(miibus_readreg,		e6000sw_readphy),
163 	DEVMETHOD(miibus_writereg,		e6000sw_writephy),
164 
165 	/* etherswitch interface */
166 	DEVMETHOD(etherswitch_getinfo,		e6000sw_getinfo),
167 	DEVMETHOD(etherswitch_getconf,		e6000sw_getconf),
168 	DEVMETHOD(etherswitch_setconf,		e6000sw_setconf),
169 	DEVMETHOD(etherswitch_lock,		e6000sw_lock),
170 	DEVMETHOD(etherswitch_unlock,		e6000sw_unlock),
171 	DEVMETHOD(etherswitch_getport,		e6000sw_getport),
172 	DEVMETHOD(etherswitch_setport,		e6000sw_setport),
173 	DEVMETHOD(etherswitch_readreg,		e6000sw_readreg_wrapper),
174 	DEVMETHOD(etherswitch_writereg,		e6000sw_writereg_wrapper),
175 	DEVMETHOD(etherswitch_readphyreg,	e6000sw_readphy),
176 	DEVMETHOD(etherswitch_writephyreg,	e6000sw_writephy),
177 	DEVMETHOD(etherswitch_setvgroup,	e6000sw_setvgroup_wrapper),
178 	DEVMETHOD(etherswitch_getvgroup,	e6000sw_getvgroup_wrapper),
179 
180 	DEVMETHOD_END
181 };
182 
183 DEFINE_CLASS_0(e6000sw, e6000sw_driver, e6000sw_methods,
184     sizeof(e6000sw_softc_t));
185 
186 DRIVER_MODULE(e6000sw, mdio, e6000sw_driver, 0, 0);
187 DRIVER_MODULE(etherswitch, e6000sw, etherswitch_driver, 0, 0);
188 DRIVER_MODULE(miibus, e6000sw, miibus_driver, 0, 0);
189 MODULE_DEPEND(e6000sw, mdio, 1, 1, 1);
190 
191 
192 static void
193 e6000sw_identify(driver_t *driver, device_t parent)
194 {
195 
196 	if (device_find_child(parent, "e6000sw", -1) == NULL)
197 		BUS_ADD_CHILD(parent, 0, "e6000sw", -1);
198 }
199 
200 static int
201 e6000sw_probe(device_t dev)
202 {
203 	e6000sw_softc_t *sc;
204 	const char *description;
205 	phandle_t switch_node;
206 
207 	sc = device_get_softc(dev);
208 	switch_node = ofw_bus_find_compatible(OF_finddevice("/"),
209 	    "marvell,mv88e6085");
210 	if (switch_node == 0) {
211 		switch_node = ofw_bus_find_compatible(OF_finddevice("/"),
212 		    "marvell,mv88e6190");
213 
214 		if (switch_node == 0)
215 			return (ENXIO);
216 
217 		/*
218 		 * Trust DTS and fix the port register offset for the MV88E6190
219 		 * detection bellow.
220 		 */
221 		sc->swid = MV88E6190;
222 	}
223 
224 	if (bootverbose)
225 		device_printf(dev, "Found switch_node: 0x%x\n", switch_node);
226 
227 	sc->dev = dev;
228 	sc->node = switch_node;
229 
230 	if (OF_getencprop(sc->node, "reg", &sc->sw_addr,
231 	    sizeof(sc->sw_addr)) < 0)
232 		return (ENXIO);
233 	if (sc->sw_addr < 0 || sc->sw_addr > 32)
234 		return (ENXIO);
235 
236 	/*
237 	 * Create temporary lock, just to satisfy assertions,
238 	 * when obtaining the switch ID. Destroy immediately afterwards.
239 	 */
240 	sx_init(&sc->sx, "e6000sw_tmp");
241 	E6000SW_LOCK(sc);
242 	sc->swid = e6000sw_readreg(sc, REG_PORT(sc, 0), SWITCH_ID) & 0xfff0;
243 	E6000SW_UNLOCK(sc);
244 	sx_destroy(&sc->sx);
245 
246 	switch (sc->swid) {
247 	case MV88E6141:
248 		description = "Marvell 88E6141";
249 		sc->phy_base = 0x10;
250 		sc->num_ports = 6;
251 		break;
252 	case MV88E6341:
253 		description = "Marvell 88E6341";
254 		sc->phy_base = 0x10;
255 		sc->num_ports = 6;
256 		break;
257 	case MV88E6352:
258 		description = "Marvell 88E6352";
259 		sc->num_ports = 7;
260 		break;
261 	case MV88E6172:
262 		description = "Marvell 88E6172";
263 		sc->num_ports = 7;
264 		break;
265 	case MV88E6176:
266 		description = "Marvell 88E6176";
267 		sc->num_ports = 7;
268 		break;
269 	case MV88E6190:
270 		description = "Marvell 88E6190";
271 		sc->num_ports = 11;
272 		break;
273 	default:
274 		device_printf(dev, "Unrecognized device, id 0x%x.\n", sc->swid);
275 		return (ENXIO);
276 	}
277 
278 	device_set_desc(dev, description);
279 
280 	return (BUS_PROBE_DEFAULT);
281 }
282 
283 static int
284 e6000sw_parse_fixed_link(e6000sw_softc_t *sc, phandle_t node, uint32_t port)
285 {
286 	int speed;
287 	phandle_t fixed_link;
288 
289 	fixed_link = ofw_bus_find_child(node, "fixed-link");
290 
291 	if (fixed_link != 0) {
292 		sc->fixed_mask |= (1 << port);
293 
294 		if (OF_getencprop(fixed_link,
295 		    "speed", &speed, sizeof(speed)) < 0) {
296 			device_printf(sc->dev,
297 			    "Port %d has a fixed-link node without a speed "
298 			    "property\n", port);
299 			return (ENXIO);
300 		}
301 		if (speed == 2500 && (MVSWITCH(sc, MV88E6141) ||
302 		     MVSWITCH(sc, MV88E6341) || MVSWITCH(sc, MV88E6190)))
303 			sc->fixed25_mask |= (1 << port);
304 	}
305 
306 	return (0);
307 }
308 
309 static int
310 e6000sw_parse_ethernet(e6000sw_softc_t *sc, phandle_t port_handle, uint32_t port) {
311 	phandle_t switch_eth, switch_eth_handle;
312 
313 	if (OF_getencprop(port_handle, "ethernet", (void*)&switch_eth_handle,
314 	    sizeof(switch_eth_handle)) > 0) {
315 		if (switch_eth_handle > 0) {
316 			switch_eth = OF_node_from_xref(switch_eth_handle);
317 
318 			device_printf(sc->dev, "CPU port at %d\n", port);
319 			sc->cpuports_mask |= (1 << port);
320 
321 			return (e6000sw_parse_fixed_link(sc, switch_eth, port));
322 		} else
323 			device_printf(sc->dev,
324 				"Port %d has ethernet property but it points "
325 				"to an invalid location\n", port);
326 	}
327 
328 	return (0);
329 }
330 
331 static int
332 e6000sw_parse_child_fdt(e6000sw_softc_t *sc, phandle_t child, int *pport)
333 {
334 	uint32_t port;
335 
336 	if (pport == NULL)
337 		return (ENXIO);
338 
339 	if (OF_getencprop(child, "reg", (void *)&port, sizeof(port)) < 0)
340 		return (ENXIO);
341 	if (port >= sc->num_ports)
342 		return (ENXIO);
343 	*pport = port;
344 
345 	if (e6000sw_parse_fixed_link(sc, child, port) != 0)
346 		return (ENXIO);
347 
348 	if (e6000sw_parse_ethernet(sc, child, port) != 0)
349 		return (ENXIO);
350 
351 	if ((sc->fixed_mask & (1 << port)) != 0)
352 		device_printf(sc->dev, "fixed port at %d\n", port);
353 	else
354 		device_printf(sc->dev, "PHY at port %d\n", port);
355 
356 	return (0);
357 }
358 
359 static int
360 e6000sw_init_interface(e6000sw_softc_t *sc, int port)
361 {
362 	char name[IFNAMSIZ];
363 
364 	snprintf(name, IFNAMSIZ, "%sport", device_get_nameunit(sc->dev));
365 
366 	sc->ifp[port] = if_alloc(IFT_ETHER);
367 	if (sc->ifp[port] == NULL)
368 		return (ENOMEM);
369 	sc->ifp[port]->if_softc = sc;
370 	sc->ifp[port]->if_flags |= IFF_UP | IFF_BROADCAST |
371 	    IFF_DRV_RUNNING | IFF_SIMPLEX;
372 	sc->ifname[port] = malloc(strlen(name) + 1, M_E6000SW, M_NOWAIT);
373 	if (sc->ifname[port] == NULL) {
374 		if_free(sc->ifp[port]);
375 		return (ENOMEM);
376 	}
377 	memcpy(sc->ifname[port], name, strlen(name) + 1);
378 	if_initname(sc->ifp[port], sc->ifname[port], port);
379 
380 	return (0);
381 }
382 
383 static int
384 e6000sw_attach_miibus(e6000sw_softc_t *sc, int port)
385 {
386 	int err;
387 
388 	err = mii_attach(sc->dev, &sc->miibus[port], sc->ifp[port],
389 	    e6000sw_ifmedia_upd, e6000sw_ifmedia_sts, BMSR_DEFCAPMASK,
390 	    port + sc->phy_base, MII_OFFSET_ANY, 0);
391 	if (err != 0)
392 		return (err);
393 
394 	return (0);
395 }
396 
397 static void
398 e6000sw_serdes_power(device_t dev, int port, bool sgmii)
399 {
400 	uint32_t reg;
401 
402 	/* SGMII */
403 	reg = e6000sw_read_xmdio(dev, port, E6000SW_SERDES_DEV,
404 	    E6000SW_SERDES_SGMII_CTL);
405 	if (sgmii)
406 		reg &= ~E6000SW_SERDES_PDOWN;
407 	else
408 		reg |= E6000SW_SERDES_PDOWN;
409 	e6000sw_write_xmdio(dev, port, E6000SW_SERDES_DEV,
410 	    E6000SW_SERDES_SGMII_CTL, reg);
411 
412 	/* 10GBASE-R/10GBASE-X4/X2 */
413 	reg = e6000sw_read_xmdio(dev, port, E6000SW_SERDES_DEV,
414 	    E6000SW_SERDES_PCS_CTL1);
415 	if (sgmii)
416 		reg |= E6000SW_SERDES_PDOWN;
417 	else
418 		reg &= ~E6000SW_SERDES_PDOWN;
419 	e6000sw_write_xmdio(dev, port, E6000SW_SERDES_DEV,
420 	    E6000SW_SERDES_PCS_CTL1, reg);
421 }
422 
423 static int
424 e6000sw_attach(device_t dev)
425 {
426 	bool sgmii;
427 	e6000sw_softc_t *sc;
428 	phandle_t child, ports;
429 	int err, port;
430 	uint32_t reg;
431 
432 	err = 0;
433 	sc = device_get_softc(dev);
434 
435 	/*
436 	 * According to the Linux source code, all of the Switch IDs we support
437 	 * are multi_chip capable, and should go into multi-chip mode if the
438 	 * sw_addr != 0.
439 	 */
440 	if (MVSWITCH_MULTICHIP(sc))
441 		device_printf(dev, "multi-chip addressing mode (%#x)\n",
442 		    sc->sw_addr);
443 	else
444 		device_printf(dev, "single-chip addressing mode\n");
445 
446 	sx_init(&sc->sx, "e6000sw");
447 
448 	E6000SW_LOCK(sc);
449 	e6000sw_setup(dev, sc);
450 	ports = ofw_bus_find_child(sc->node, "ports");
451 	sc->sc_tq = taskqueue_create("e6000sw_taskq", M_NOWAIT,
452 	    taskqueue_thread_enqueue, &sc->sc_tq);
453 
454 	TIMEOUT_TASK_INIT(sc->sc_tq, &sc->sc_tt, 0, e6000sw_tick, sc);
455 	taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq",
456 	    device_get_nameunit(dev));
457 
458 	if (ports == 0) {
459 		device_printf(dev, "failed to parse DTS: no ports found for "
460 		    "switch\n");
461 		E6000SW_UNLOCK(sc);
462 		return (ENXIO);
463 	}
464 
465 	for (child = OF_child(ports); child != 0; child = OF_peer(child)) {
466 		err = e6000sw_parse_child_fdt(sc, child, &port);
467 		if (err != 0) {
468 			device_printf(sc->dev, "failed to parse DTS\n");
469 			goto out_fail;
470 		}
471 
472 		/* Port is in use. */
473 		sc->ports_mask |= (1 << port);
474 
475 		err = e6000sw_init_interface(sc, port);
476 		if (err != 0) {
477 			device_printf(sc->dev, "failed to init interface\n");
478 			goto out_fail;
479 		}
480 
481 		if (e6000sw_is_fixedport(sc, port)) {
482 			/* Link must be down to change speed force value. */
483 			reg = e6000sw_readreg(sc, REG_PORT(sc, port),
484 			    PSC_CONTROL);
485 			reg &= ~PSC_CONTROL_LINK_UP;
486 			reg |= PSC_CONTROL_FORCED_LINK;
487 			e6000sw_writereg(sc, REG_PORT(sc, port), PSC_CONTROL,
488 			    reg);
489 
490 			/*
491 			 * Force speed, full-duplex, EEE off and flow-control
492 			 * on.
493 			 */
494 			reg &= ~(PSC_CONTROL_SPD2500 | PSC_CONTROL_ALT_SPD |
495 			    PSC_CONTROL_FORCED_FC | PSC_CONTROL_FC_ON |
496 			    PSC_CONTROL_FORCED_EEE);
497 			if (e6000sw_is_fixed25port(sc, port))
498 				reg |= PSC_CONTROL_SPD2500;
499 			else
500 				reg |= PSC_CONTROL_SPD1000;
501 			if (MVSWITCH(sc, MV88E6190) &&
502 			    e6000sw_is_fixed25port(sc, port))
503 				reg |= PSC_CONTROL_ALT_SPD;
504 			reg |= PSC_CONTROL_FORCED_DPX | PSC_CONTROL_FULLDPX |
505 			    PSC_CONTROL_FORCED_LINK | PSC_CONTROL_LINK_UP |
506 			    PSC_CONTROL_FORCED_SPD;
507 			if (!MVSWITCH(sc, MV88E6190))
508 				reg |= PSC_CONTROL_FORCED_FC | PSC_CONTROL_FC_ON;
509 			if (MVSWITCH(sc, MV88E6141) ||
510 			    MVSWITCH(sc, MV88E6341) ||
511 			    MVSWITCH(sc, MV88E6190))
512 				reg |= PSC_CONTROL_FORCED_EEE;
513 			e6000sw_writereg(sc, REG_PORT(sc, port), PSC_CONTROL,
514 			    reg);
515 			/* Power on the SERDES interfaces. */
516 			if (MVSWITCH(sc, MV88E6190) &&
517 			    (port == 9 || port == 10)) {
518 				if (e6000sw_is_fixed25port(sc, port))
519 					sgmii = false;
520 				else
521 					sgmii = true;
522 				e6000sw_serdes_power(sc->dev, port, sgmii);
523 			}
524 		}
525 
526 		/* Don't attach miibus at CPU/fixed ports */
527 		if (!e6000sw_is_phyport(sc, port))
528 			continue;
529 
530 		/*
531 		 * It's necessary to unlock mutex, because e6000sw_attach_miibus
532 		 * calls functions, which try to lock mutex.That leads
533 		 * to recursive lock on non recursive mutex.
534 		 */
535 		E6000SW_UNLOCK(sc);
536 
537 		err = e6000sw_attach_miibus(sc, port);
538 		if (err != 0) {
539 			device_printf(sc->dev, "failed to attach miibus\n");
540 			goto out_fail;
541 		}
542 
543 		E6000SW_LOCK(sc);
544 	}
545 
546 	etherswitch_info.es_nports = sc->num_ports;
547 
548 	/* Default to port vlan. */
549 	e6000sw_set_vlan_mode(sc, ETHERSWITCH_VLAN_PORT);
550 
551 	reg = e6000sw_readreg(sc, REG_GLOBAL, SWITCH_GLOBAL_STATUS);
552 	if (reg & SWITCH_GLOBAL_STATUS_IR)
553 		device_printf(dev, "switch is ready.\n");
554 	E6000SW_UNLOCK(sc);
555 
556 	bus_generic_probe(dev);
557 	bus_generic_attach(dev);
558 
559 	taskqueue_enqueue_timeout(sc->sc_tq, &sc->sc_tt, hz);
560 
561 	return (0);
562 
563 out_fail:
564 	e6000sw_detach(dev);
565 
566 	return (err);
567 }
568 
569 static int
570 e6000sw_waitready(e6000sw_softc_t *sc, uint32_t phy, uint32_t reg,
571     uint32_t busybit)
572 {
573 	int i;
574 
575 	for (i = 0; i < E6000SW_RETRIES; i++) {
576 		if ((e6000sw_readreg(sc, phy, reg) & busybit) == 0)
577 			return (0);
578 		DELAY(1);
579 	}
580 
581 	return (1);
582 }
583 
584 /* XMDIO/Clause 45 access. */
585 static int
586 e6000sw_read_xmdio(device_t dev, int phy, int devaddr, int devreg)
587 {
588 	e6000sw_softc_t *sc;
589 	uint32_t reg;
590 
591 	sc = device_get_softc(dev);
592 	E6000SW_LOCK_ASSERT(sc, SA_XLOCKED);
593 	if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) {
594 		device_printf(dev, "Timeout while waiting for switch\n");
595 		return (ETIMEDOUT);
596 	}
597 
598 	reg = devaddr & SMI_CMD_REG_ADDR_MASK;
599 	reg |= (phy << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK;
600 
601 	/* Load C45 register address. */
602 	e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG, devreg);
603 	e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG,
604 	    reg | SMI_CMD_OP_C45_ADDR);
605 	if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) {
606 		device_printf(dev, "Timeout while waiting for switch\n");
607 		return (ETIMEDOUT);
608 	}
609 
610 	/* Start C45 read operation. */
611 	e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG,
612 	    reg | SMI_CMD_OP_C45_READ);
613 	if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) {
614 		device_printf(dev, "Timeout while waiting for switch\n");
615 		return (ETIMEDOUT);
616 	}
617 
618 	/* Read C45 data. */
619 	reg = e6000sw_readreg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG);
620 
621 	return (reg & PHY_DATA_MASK);
622 }
623 
624 static int
625 e6000sw_write_xmdio(device_t dev, int phy, int devaddr, int devreg, int val)
626 {
627 	e6000sw_softc_t *sc;
628 	uint32_t reg;
629 
630 	sc = device_get_softc(dev);
631 	E6000SW_LOCK_ASSERT(sc, SA_XLOCKED);
632 	if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) {
633 		device_printf(dev, "Timeout while waiting for switch\n");
634 		return (ETIMEDOUT);
635 	}
636 
637 	reg = devaddr & SMI_CMD_REG_ADDR_MASK;
638 	reg |= (phy << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK;
639 
640 	/* Load C45 register address. */
641 	e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG, devreg);
642 	e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG,
643 	    reg | SMI_CMD_OP_C45_ADDR);
644 	if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) {
645 		device_printf(dev, "Timeout while waiting for switch\n");
646 		return (ETIMEDOUT);
647 	}
648 
649 	/* Load data and start the C45 write operation. */
650 	e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG, devreg);
651 	e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG,
652 	    reg | SMI_CMD_OP_C45_WRITE);
653 
654 	return (0);
655 }
656 
657 /*
658  * PHY registers are paged. Put page index in reg 22 (accessible from every
659  * page), then access specific register.
660  */
661 static int
662 e6000sw_readphy(device_t dev, int phy, int reg)
663 {
664 	e6000sw_softc_t *sc;
665 	uint32_t val;
666 
667 	sc = device_get_softc(dev);
668 	E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED);
669 
670 	if (!e6000sw_is_phyport(sc, phy) || reg >= E6000SW_NUM_PHY_REGS) {
671 		device_printf(dev, "Wrong register address.\n");
672 		return (EINVAL);
673 	}
674 
675 	E6000SW_LOCK(sc);
676 
677 	if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) {
678 		device_printf(dev, "Timeout while waiting for switch\n");
679 		E6000SW_UNLOCK(sc);
680 		return (ETIMEDOUT);
681 	}
682 
683 	e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG,
684 	    SMI_CMD_OP_C22_READ | (reg & SMI_CMD_REG_ADDR_MASK) |
685 	    ((phy << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK));
686 	if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) {
687 		device_printf(dev, "Timeout while waiting for switch\n");
688 		E6000SW_UNLOCK(sc);
689 		return (ETIMEDOUT);
690 	}
691 
692 	val = e6000sw_readreg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG);
693 
694 	E6000SW_UNLOCK(sc);
695 
696 	return (val & PHY_DATA_MASK);
697 }
698 
699 static int
700 e6000sw_writephy(device_t dev, int phy, int reg, int data)
701 {
702 	e6000sw_softc_t *sc;
703 
704 	sc = device_get_softc(dev);
705 	E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED);
706 
707 	if (!e6000sw_is_phyport(sc, phy) || reg >= E6000SW_NUM_PHY_REGS) {
708 		device_printf(dev, "Wrong register address.\n");
709 		return (EINVAL);
710 	}
711 
712 	E6000SW_LOCK(sc);
713 
714 	if (E6000SW_WAITREADY2(sc, SMI_PHY_CMD_REG, SMI_CMD_BUSY)) {
715 		device_printf(dev, "Timeout while waiting for switch\n");
716 		E6000SW_UNLOCK(sc);
717 		return (ETIMEDOUT);
718 	}
719 
720 	e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_DATA_REG,
721 	    data & PHY_DATA_MASK);
722 	e6000sw_writereg(sc, REG_GLOBAL2, SMI_PHY_CMD_REG,
723 	    SMI_CMD_OP_C22_WRITE | (reg & SMI_CMD_REG_ADDR_MASK) |
724 	    ((phy << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK));
725 
726 	E6000SW_UNLOCK(sc);
727 
728 	return (0);
729 }
730 
731 static int
732 e6000sw_detach(device_t dev)
733 {
734 	int phy;
735 	e6000sw_softc_t *sc;
736 
737 	sc = device_get_softc(dev);
738 
739 	if (device_is_attached(dev))
740 		taskqueue_drain_timeout(sc->sc_tq, &sc->sc_tt);
741 
742 	if (sc->sc_tq != NULL)
743 		taskqueue_free(sc->sc_tq);
744 
745 	device_delete_children(dev);
746 
747 	sx_destroy(&sc->sx);
748 	for (phy = 0; phy < sc->num_ports; phy++) {
749 		if (sc->ifp[phy] != NULL)
750 			if_free(sc->ifp[phy]);
751 		if (sc->ifname[phy] != NULL)
752 			free(sc->ifname[phy], M_E6000SW);
753 	}
754 
755 	return (0);
756 }
757 
758 static etherswitch_info_t*
759 e6000sw_getinfo(device_t dev)
760 {
761 
762 	return (&etherswitch_info);
763 }
764 
765 static int
766 e6000sw_getconf(device_t dev, etherswitch_conf_t *conf)
767 {
768 	struct e6000sw_softc *sc;
769 
770 	/* Return the VLAN mode. */
771 	sc = device_get_softc(dev);
772 	conf->cmd = ETHERSWITCH_CONF_VLAN_MODE;
773 	conf->vlan_mode = sc->vlan_mode;
774 
775 	return (0);
776 }
777 
778 static int
779 e6000sw_setconf(device_t dev, etherswitch_conf_t *conf)
780 {
781 	struct e6000sw_softc *sc;
782 
783 	/* Set the VLAN mode. */
784 	sc = device_get_softc(dev);
785 	if (conf->cmd & ETHERSWITCH_CONF_VLAN_MODE) {
786 		E6000SW_LOCK(sc);
787 		e6000sw_set_vlan_mode(sc, conf->vlan_mode);
788 		E6000SW_UNLOCK(sc);
789 	}
790 
791 	return (0);
792 }
793 
794 static void
795 e6000sw_lock(device_t dev)
796 {
797 	struct e6000sw_softc *sc;
798 
799 	sc = device_get_softc(dev);
800 
801 	E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED);
802 	E6000SW_LOCK(sc);
803 }
804 
805 static void
806 e6000sw_unlock(device_t dev)
807 {
808 	struct e6000sw_softc *sc;
809 
810 	sc = device_get_softc(dev);
811 
812 	E6000SW_LOCK_ASSERT(sc, SA_XLOCKED);
813 	E6000SW_UNLOCK(sc);
814 }
815 
816 static int
817 e6000sw_getport(device_t dev, etherswitch_port_t *p)
818 {
819 	struct mii_data *mii;
820 	int err;
821 	struct ifmediareq *ifmr;
822 	uint32_t reg;
823 
824 	e6000sw_softc_t *sc = device_get_softc(dev);
825 	E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED);
826 
827 	if (p->es_port >= sc->num_ports || p->es_port < 0)
828 		return (EINVAL);
829 	if (!e6000sw_is_portenabled(sc, p->es_port))
830 		return (0);
831 
832 	E6000SW_LOCK(sc);
833 	e6000sw_get_pvid(sc, p->es_port, &p->es_pvid);
834 
835 	/* Port flags. */
836 	reg = e6000sw_readreg(sc, REG_PORT(sc, p->es_port), PORT_CONTROL2);
837 	if (reg & PORT_CONTROL2_DISC_TAGGED)
838 		p->es_flags |= ETHERSWITCH_PORT_DROPTAGGED;
839 	if (reg & PORT_CONTROL2_DISC_UNTAGGED)
840 		p->es_flags |= ETHERSWITCH_PORT_DROPUNTAGGED;
841 
842 	err = 0;
843 	if (e6000sw_is_fixedport(sc, p->es_port)) {
844 		if (e6000sw_is_cpuport(sc, p->es_port))
845 			p->es_flags |= ETHERSWITCH_PORT_CPU;
846 		ifmr = &p->es_ifmr;
847 		ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID;
848 		ifmr->ifm_count = 0;
849 		if (e6000sw_is_fixed25port(sc, p->es_port))
850 			ifmr->ifm_active = IFM_2500_T;
851 		else
852 			ifmr->ifm_active = IFM_1000_T;
853 		ifmr->ifm_active |= IFM_ETHER | IFM_FDX;
854 		ifmr->ifm_current = ifmr->ifm_active;
855 		ifmr->ifm_mask = 0;
856 	} else {
857 		mii = e6000sw_miiforphy(sc, p->es_port);
858 		err = ifmedia_ioctl(mii->mii_ifp, &p->es_ifr,
859 		    &mii->mii_media, SIOCGIFMEDIA);
860 	}
861 	E6000SW_UNLOCK(sc);
862 
863 	return (err);
864 }
865 
866 static int
867 e6000sw_setport(device_t dev, etherswitch_port_t *p)
868 {
869 	e6000sw_softc_t *sc;
870 	int err;
871 	struct mii_data *mii;
872 	uint32_t reg;
873 
874 	sc = device_get_softc(dev);
875 	E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED);
876 
877 	if (p->es_port >= sc->num_ports || p->es_port < 0)
878 		return (EINVAL);
879 	if (!e6000sw_is_portenabled(sc, p->es_port))
880 		return (0);
881 
882 	E6000SW_LOCK(sc);
883 
884 	/* Port flags. */
885 	reg = e6000sw_readreg(sc, REG_PORT(sc, p->es_port), PORT_CONTROL2);
886 	if (p->es_flags & ETHERSWITCH_PORT_DROPTAGGED)
887 		reg |= PORT_CONTROL2_DISC_TAGGED;
888 	else
889 		reg &= ~PORT_CONTROL2_DISC_TAGGED;
890 	if (p->es_flags & ETHERSWITCH_PORT_DROPUNTAGGED)
891 		reg |= PORT_CONTROL2_DISC_UNTAGGED;
892 	else
893 		reg &= ~PORT_CONTROL2_DISC_UNTAGGED;
894 	e6000sw_writereg(sc, REG_PORT(sc, p->es_port), PORT_CONTROL2, reg);
895 
896 	err = 0;
897 	if (p->es_pvid != 0)
898 		e6000sw_set_pvid(sc, p->es_port, p->es_pvid);
899 	if (e6000sw_is_phyport(sc, p->es_port)) {
900 		mii = e6000sw_miiforphy(sc, p->es_port);
901 		err = ifmedia_ioctl(mii->mii_ifp, &p->es_ifr, &mii->mii_media,
902 		    SIOCSIFMEDIA);
903 	}
904 	E6000SW_UNLOCK(sc);
905 
906 	return (err);
907 }
908 
909 static __inline void
910 e6000sw_port_vlan_assign(e6000sw_softc_t *sc, int port, uint32_t fid,
911     uint32_t members)
912 {
913 	uint32_t reg;
914 
915 	reg = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_VLAN_MAP);
916 	reg &= ~(PORT_MASK(sc) | PORT_VLAN_MAP_FID_MASK);
917 	reg |= members & PORT_MASK(sc) & ~(1 << port);
918 	reg |= (fid << PORT_VLAN_MAP_FID) & PORT_VLAN_MAP_FID_MASK;
919 	e6000sw_writereg(sc, REG_PORT(sc, port), PORT_VLAN_MAP, reg);
920 	reg = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_CONTROL1);
921 	reg &= ~PORT_CONTROL1_FID_MASK;
922 	reg |= (fid >> 4) & PORT_CONTROL1_FID_MASK;
923 	e6000sw_writereg(sc, REG_PORT(sc, port), PORT_CONTROL1, reg);
924 }
925 
926 static int
927 e6000sw_init_vlan(struct e6000sw_softc *sc)
928 {
929 	int i, port, ret;
930 	uint32_t members;
931 
932 	/* Disable all ports */
933 	for (port = 0; port < sc->num_ports; port++) {
934 		ret = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_CONTROL);
935 		e6000sw_writereg(sc, REG_PORT(sc, port), PORT_CONTROL,
936 		    (ret & ~PORT_CONTROL_ENABLE));
937 	}
938 
939 	/* Flush VTU. */
940 	e6000sw_vtu_flush(sc);
941 
942 	for (port = 0; port < sc->num_ports; port++) {
943 		/* Reset the egress and frame mode. */
944 		ret = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_CONTROL);
945 		ret &= ~(PORT_CONTROL_EGRESS | PORT_CONTROL_FRAME);
946 		e6000sw_writereg(sc, REG_PORT(sc, port), PORT_CONTROL, ret);
947 
948 		/* Set the the 802.1q mode. */
949 		ret = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_CONTROL2);
950 		ret &= ~PORT_CONTROL2_DOT1Q;
951 		if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q)
952 			ret |= PORT_CONTROL2_DOT1Q;
953 		e6000sw_writereg(sc, REG_PORT(sc, port), PORT_CONTROL2, ret);
954 	}
955 
956 	for (port = 0; port < sc->num_ports; port++) {
957 		if (!e6000sw_is_portenabled(sc, port))
958 			continue;
959 
960 		ret = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_VID);
961 
962 		/* Set port priority */
963 		ret &= ~PORT_VID_PRIORITY_MASK;
964 
965 		/* Set VID map */
966 		ret &= ~PORT_VID_DEF_VID_MASK;
967 		if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q)
968 			ret |= 1;
969 		else
970 			ret |= (port + 1);
971 		e6000sw_writereg(sc, REG_PORT(sc, port), PORT_VID, ret);
972 	}
973 
974 	/* Assign the member ports to each origin port. */
975 	for (port = 0; port < sc->num_ports; port++) {
976 		members = 0;
977 		if (e6000sw_is_portenabled(sc, port)) {
978 			for (i = 0; i < sc->num_ports; i++) {
979 				if (i == port || !e6000sw_is_portenabled(sc, i))
980 					continue;
981 				members |= (1 << i);
982 			}
983 		}
984 		/* Default to FID 0. */
985 		e6000sw_port_vlan_assign(sc, port, 0, members);
986 	}
987 
988 	/* Reset internal VLAN table. */
989 	for (i = 0; i < nitems(sc->vlans); i++)
990 		sc->vlans[i] = 0;
991 
992 	/* Create default VLAN (1). */
993 	if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) {
994 		sc->vlans[0] = 1;
995 		e6000sw_vtu_update(sc, 0, sc->vlans[0], 1, 0, sc->ports_mask);
996 	}
997 
998 	/* Enable all ports */
999 	for (port = 0; port < sc->num_ports; port++) {
1000 		if (!e6000sw_is_portenabled(sc, port))
1001 			continue;
1002 		ret = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_CONTROL);
1003 		e6000sw_writereg(sc, REG_PORT(sc, port), PORT_CONTROL,
1004 		    (ret | PORT_CONTROL_ENABLE));
1005 	}
1006 
1007 	return (0);
1008 }
1009 
1010 static int
1011 e6000sw_set_vlan_mode(struct e6000sw_softc *sc, uint32_t mode)
1012 {
1013 
1014 	E6000SW_LOCK_ASSERT(sc, SA_XLOCKED);
1015 	switch (mode) {
1016 	case ETHERSWITCH_VLAN_PORT:
1017 		sc->vlan_mode = ETHERSWITCH_VLAN_PORT;
1018 		etherswitch_info.es_nvlangroups = sc->num_ports;
1019 		return (e6000sw_init_vlan(sc));
1020 		break;
1021 	case ETHERSWITCH_VLAN_DOT1Q:
1022 		sc->vlan_mode = ETHERSWITCH_VLAN_DOT1Q;
1023 		etherswitch_info.es_nvlangroups = E6000SW_NUM_VLANS;
1024 		return (e6000sw_init_vlan(sc));
1025 		break;
1026 	default:
1027 		return (EINVAL);
1028 	}
1029 }
1030 
1031 /*
1032  * Registers in this switch are divided into sections, specified in
1033  * documentation. So as to access any of them, section index and reg index
1034  * is necessary. etherswitchcfg uses only one variable, so indexes were
1035  * compressed into addr_reg: 32 * section_index + reg_index.
1036  */
1037 static int
1038 e6000sw_readreg_wrapper(device_t dev, int addr_reg)
1039 {
1040 	e6000sw_softc_t *sc;
1041 
1042 	sc = device_get_softc(dev);
1043 	if ((addr_reg > (REG_GLOBAL2 * 32 + REG_NUM_MAX)) ||
1044 	    (addr_reg < (REG_PORT(sc, 0) * 32))) {
1045 		device_printf(dev, "Wrong register address.\n");
1046 		return (EINVAL);
1047 	}
1048 
1049 	return (e6000sw_readreg(device_get_softc(dev), addr_reg / 32,
1050 	    addr_reg % 32));
1051 }
1052 
1053 static int
1054 e6000sw_writereg_wrapper(device_t dev, int addr_reg, int val)
1055 {
1056 	e6000sw_softc_t *sc;
1057 
1058 	sc = device_get_softc(dev);
1059 	if ((addr_reg > (REG_GLOBAL2 * 32 + REG_NUM_MAX)) ||
1060 	    (addr_reg < (REG_PORT(sc, 0) * 32))) {
1061 		device_printf(dev, "Wrong register address.\n");
1062 		return (EINVAL);
1063 	}
1064 	e6000sw_writereg(device_get_softc(dev), addr_reg / 5,
1065 	    addr_reg % 32, val);
1066 
1067 	return (0);
1068 }
1069 
1070 /*
1071  * setvgroup/getvgroup called from etherswitchfcg need to be locked,
1072  * while internal calls do not.
1073  */
1074 static int
1075 e6000sw_setvgroup_wrapper(device_t dev, etherswitch_vlangroup_t *vg)
1076 {
1077 	e6000sw_softc_t *sc;
1078 	int ret;
1079 
1080 	sc = device_get_softc(dev);
1081 	E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED);
1082 
1083 	E6000SW_LOCK(sc);
1084 	ret = e6000sw_setvgroup(dev, vg);
1085 	E6000SW_UNLOCK(sc);
1086 
1087 	return (ret);
1088 }
1089 
1090 static int
1091 e6000sw_getvgroup_wrapper(device_t dev, etherswitch_vlangroup_t *vg)
1092 {
1093 	e6000sw_softc_t *sc;
1094 	int ret;
1095 
1096 	sc = device_get_softc(dev);
1097 	E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED);
1098 
1099 	E6000SW_LOCK(sc);
1100 	ret = e6000sw_getvgroup(dev, vg);
1101 	E6000SW_UNLOCK(sc);
1102 
1103 	return (ret);
1104 }
1105 
1106 static int
1107 e6000sw_set_port_vlan(e6000sw_softc_t *sc, etherswitch_vlangroup_t *vg)
1108 {
1109 	uint32_t port;
1110 
1111 	port = vg->es_vlangroup;
1112 	if (port > sc->num_ports)
1113 		return (EINVAL);
1114 
1115 	if (vg->es_member_ports != vg->es_untagged_ports) {
1116 		device_printf(sc->dev, "Tagged ports not supported.\n");
1117 		return (EINVAL);
1118 	}
1119 
1120 	e6000sw_port_vlan_assign(sc, port, 0, vg->es_untagged_ports);
1121 	vg->es_vid = port | ETHERSWITCH_VID_VALID;
1122 
1123 	return (0);
1124 }
1125 
1126 static int
1127 e6000sw_set_dot1q_vlan(e6000sw_softc_t *sc, etherswitch_vlangroup_t *vg)
1128 {
1129 	int i, vlan;
1130 
1131 	vlan = vg->es_vid & ETHERSWITCH_VID_MASK;
1132 
1133 	/* Set VLAN to '0' removes it from table. */
1134 	if (vlan == 0) {
1135 		e6000sw_vtu_update(sc, VTU_PURGE,
1136 		    sc->vlans[vg->es_vlangroup], 0, 0, 0);
1137 		sc->vlans[vg->es_vlangroup] = 0;
1138 		return (0);
1139 	}
1140 
1141 	/* Is this VLAN already in table ? */
1142 	for (i = 0; i < etherswitch_info.es_nvlangroups; i++)
1143 		if (i != vg->es_vlangroup && vlan == sc->vlans[i])
1144 			return (EINVAL);
1145 
1146 	sc->vlans[vg->es_vlangroup] = vlan;
1147 	e6000sw_vtu_update(sc, 0, vlan, vg->es_vlangroup + 1,
1148 	    vg->es_member_ports & sc->ports_mask,
1149 	    vg->es_untagged_ports & sc->ports_mask);
1150 
1151 	return (0);
1152 }
1153 
1154 static int
1155 e6000sw_setvgroup(device_t dev, etherswitch_vlangroup_t *vg)
1156 {
1157 	e6000sw_softc_t *sc;
1158 
1159 	sc = device_get_softc(dev);
1160 	E6000SW_LOCK_ASSERT(sc, SA_XLOCKED);
1161 
1162 	if (sc->vlan_mode == ETHERSWITCH_VLAN_PORT)
1163 		return (e6000sw_set_port_vlan(sc, vg));
1164 	else if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q)
1165 		return (e6000sw_set_dot1q_vlan(sc, vg));
1166 
1167 	return (EINVAL);
1168 }
1169 
1170 static int
1171 e6000sw_get_port_vlan(e6000sw_softc_t *sc, etherswitch_vlangroup_t *vg)
1172 {
1173 	uint32_t port, reg;
1174 
1175 	port = vg->es_vlangroup;
1176 	if (port > sc->num_ports)
1177 		return (EINVAL);
1178 
1179 	if (!e6000sw_is_portenabled(sc, port)) {
1180 		vg->es_vid = port;
1181 		return (0);
1182 	}
1183 
1184 	reg = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_VLAN_MAP);
1185 	vg->es_untagged_ports = vg->es_member_ports = reg & PORT_MASK(sc);
1186 	vg->es_vid = port | ETHERSWITCH_VID_VALID;
1187 	vg->es_fid = (reg & PORT_VLAN_MAP_FID_MASK) >> PORT_VLAN_MAP_FID;
1188 	reg = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_CONTROL1);
1189 	vg->es_fid |= (reg & PORT_CONTROL1_FID_MASK) << 4;
1190 
1191 	return (0);
1192 }
1193 
1194 static int
1195 e6000sw_get_dot1q_vlan(e6000sw_softc_t *sc, etherswitch_vlangroup_t *vg)
1196 {
1197 	int i, port;
1198 	uint32_t reg;
1199 
1200 	vg->es_fid = 0;
1201 	vg->es_vid = sc->vlans[vg->es_vlangroup];
1202 	vg->es_untagged_ports = vg->es_member_ports = 0;
1203 	if (vg->es_vid == 0)
1204 		return (0);
1205 
1206 	if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) {
1207 		device_printf(sc->dev, "VTU unit is busy, cannot access\n");
1208 		return (EBUSY);
1209 	}
1210 
1211 	e6000sw_writereg(sc, REG_GLOBAL, VTU_VID, vg->es_vid - 1);
1212 
1213 	reg = e6000sw_readreg(sc, REG_GLOBAL, VTU_OPERATION);
1214 	reg &= ~VTU_OP_MASK;
1215 	reg |= VTU_GET_NEXT | VTU_BUSY;
1216 	e6000sw_writereg(sc, REG_GLOBAL, VTU_OPERATION, reg);
1217 	if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) {
1218 		device_printf(sc->dev, "Timeout while reading\n");
1219 		return (EBUSY);
1220 	}
1221 
1222 	reg = e6000sw_readreg(sc, REG_GLOBAL, VTU_VID);
1223 	if (reg == VTU_VID_MASK || (reg & VTU_VID_VALID) == 0)
1224 		return (EINVAL);
1225 	if ((reg & VTU_VID_MASK) != vg->es_vid)
1226 		return (EINVAL);
1227 
1228 	vg->es_vid |= ETHERSWITCH_VID_VALID;
1229 	reg = e6000sw_readreg(sc, REG_GLOBAL, VTU_DATA);
1230 	for (i = 0; i < sc->num_ports; i++) {
1231 		if (i == VTU_PPREG(sc))
1232 			reg = e6000sw_readreg(sc, REG_GLOBAL, VTU_DATA2);
1233 		port = (reg >> VTU_PORT(sc, i)) & VTU_PORT_MASK;
1234 		if (port == VTU_PORT_UNTAGGED) {
1235 			vg->es_untagged_ports |= (1 << i);
1236 			vg->es_member_ports |= (1 << i);
1237 		} else if (port == VTU_PORT_TAGGED)
1238 			vg->es_member_ports |= (1 << i);
1239 	}
1240 
1241 	return (0);
1242 }
1243 
1244 static int
1245 e6000sw_getvgroup(device_t dev, etherswitch_vlangroup_t *vg)
1246 {
1247 	e6000sw_softc_t *sc;
1248 
1249 	sc = device_get_softc(dev);
1250 	E6000SW_LOCK_ASSERT(sc, SA_XLOCKED);
1251 
1252 	if (sc->vlan_mode == ETHERSWITCH_VLAN_PORT)
1253 		return (e6000sw_get_port_vlan(sc, vg));
1254 	else if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q)
1255 		return (e6000sw_get_dot1q_vlan(sc, vg));
1256 
1257 	return (EINVAL);
1258 }
1259 
1260 static __inline struct mii_data*
1261 e6000sw_miiforphy(e6000sw_softc_t *sc, unsigned int phy)
1262 {
1263 
1264 	if (!e6000sw_is_phyport(sc, phy))
1265 		return (NULL);
1266 
1267 	return (device_get_softc(sc->miibus[phy]));
1268 }
1269 
1270 static int
1271 e6000sw_ifmedia_upd(struct ifnet *ifp)
1272 {
1273 	e6000sw_softc_t *sc;
1274 	struct mii_data *mii;
1275 
1276 	sc = ifp->if_softc;
1277 	mii = e6000sw_miiforphy(sc, ifp->if_dunit);
1278 	if (mii == NULL)
1279 		return (ENXIO);
1280 	mii_mediachg(mii);
1281 
1282 	return (0);
1283 }
1284 
1285 static void
1286 e6000sw_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
1287 {
1288 	e6000sw_softc_t *sc;
1289 	struct mii_data *mii;
1290 
1291 	sc = ifp->if_softc;
1292 	mii = e6000sw_miiforphy(sc, ifp->if_dunit);
1293 
1294 	if (mii == NULL)
1295 		return;
1296 
1297 	mii_pollstat(mii);
1298 	ifmr->ifm_active = mii->mii_media_active;
1299 	ifmr->ifm_status = mii->mii_media_status;
1300 }
1301 
1302 static int
1303 e6000sw_smi_waitready(e6000sw_softc_t *sc, int phy)
1304 {
1305 	int i;
1306 
1307 	for (i = 0; i < E6000SW_SMI_TIMEOUT; i++) {
1308 		if ((MDIO_READ(sc->dev, phy, SMI_CMD) & SMI_CMD_BUSY) == 0)
1309 			return (0);
1310 		DELAY(1);
1311 	}
1312 
1313 	return (1);
1314 }
1315 
1316 static __inline uint32_t
1317 e6000sw_readreg(e6000sw_softc_t *sc, int addr, int reg)
1318 {
1319 
1320 	E6000SW_LOCK_ASSERT(sc, SA_XLOCKED);
1321 
1322 	if (!MVSWITCH_MULTICHIP(sc))
1323 		return (MDIO_READ(sc->dev, addr, reg) & 0xffff);
1324 
1325 	if (e6000sw_smi_waitready(sc, sc->sw_addr)) {
1326 		printf("e6000sw: readreg timeout\n");
1327 		return (0xffff);
1328 	}
1329 	MDIO_WRITE(sc->dev, sc->sw_addr, SMI_CMD,
1330 	    SMI_CMD_OP_C22_READ | (reg & SMI_CMD_REG_ADDR_MASK) |
1331 	    ((addr << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK));
1332 	if (e6000sw_smi_waitready(sc, sc->sw_addr)) {
1333 		printf("e6000sw: readreg timeout\n");
1334 		return (0xffff);
1335 	}
1336 
1337 	return (MDIO_READ(sc->dev, sc->sw_addr, SMI_DATA) & 0xffff);
1338 }
1339 
1340 static __inline void
1341 e6000sw_writereg(e6000sw_softc_t *sc, int addr, int reg, int val)
1342 {
1343 
1344 	E6000SW_LOCK_ASSERT(sc, SA_XLOCKED);
1345 
1346 	if (!MVSWITCH_MULTICHIP(sc)) {
1347 		MDIO_WRITE(sc->dev, addr, reg, val);
1348 		return;
1349 	}
1350 
1351 	if (e6000sw_smi_waitready(sc, sc->sw_addr)) {
1352 		printf("e6000sw: readreg timeout\n");
1353 		return;
1354 	}
1355 	MDIO_WRITE(sc->dev, sc->sw_addr, SMI_DATA, val);
1356 	MDIO_WRITE(sc->dev, sc->sw_addr, SMI_CMD,
1357 	    SMI_CMD_OP_C22_WRITE | (reg & SMI_CMD_REG_ADDR_MASK) |
1358 	    ((addr << SMI_CMD_DEV_ADDR) & SMI_CMD_DEV_ADDR_MASK));
1359 }
1360 
1361 static __inline bool
1362 e6000sw_is_cpuport(e6000sw_softc_t *sc, int port)
1363 {
1364 
1365 	return ((sc->cpuports_mask & (1 << port)) ? true : false);
1366 }
1367 
1368 static __inline bool
1369 e6000sw_is_fixedport(e6000sw_softc_t *sc, int port)
1370 {
1371 
1372 	return ((sc->fixed_mask & (1 << port)) ? true : false);
1373 }
1374 
1375 static __inline bool
1376 e6000sw_is_fixed25port(e6000sw_softc_t *sc, int port)
1377 {
1378 
1379 	return ((sc->fixed25_mask & (1 << port)) ? true : false);
1380 }
1381 
1382 static __inline bool
1383 e6000sw_is_phyport(e6000sw_softc_t *sc, int port)
1384 {
1385 	uint32_t phy_mask;
1386 	phy_mask = ~(sc->fixed_mask | sc->cpuports_mask);
1387 
1388 	return ((phy_mask & (1 << port)) ? true : false);
1389 }
1390 
1391 static __inline bool
1392 e6000sw_is_portenabled(e6000sw_softc_t *sc, int port)
1393 {
1394 
1395 	return ((sc->ports_mask & (1 << port)) ? true : false);
1396 }
1397 
1398 static __inline void
1399 e6000sw_set_pvid(e6000sw_softc_t *sc, int port, int pvid)
1400 {
1401 	uint32_t reg;
1402 
1403 	reg = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_VID);
1404 	reg &= ~PORT_VID_DEF_VID_MASK;
1405 	reg |= (pvid & PORT_VID_DEF_VID_MASK);
1406 	e6000sw_writereg(sc, REG_PORT(sc, port), PORT_VID, reg);
1407 }
1408 
1409 static __inline int
1410 e6000sw_get_pvid(e6000sw_softc_t *sc, int port, int *pvid)
1411 {
1412 
1413 	if (pvid == NULL)
1414 		return (ENXIO);
1415 
1416 	*pvid = e6000sw_readreg(sc, REG_PORT(sc, port), PORT_VID) &
1417 	    PORT_VID_DEF_VID_MASK;
1418 
1419 	return (0);
1420 }
1421 
1422 /*
1423  * Convert port status to ifmedia.
1424  */
1425 static void
1426 e6000sw_update_ifmedia(uint16_t portstatus, u_int *media_status, u_int *media_active)
1427 {
1428 	*media_active = IFM_ETHER;
1429 	*media_status = IFM_AVALID;
1430 
1431 	if ((portstatus & PORT_STATUS_LINK_MASK) != 0)
1432 		*media_status |= IFM_ACTIVE;
1433 	else {
1434 		*media_active |= IFM_NONE;
1435 		return;
1436 	}
1437 
1438 	switch (portstatus & PORT_STATUS_SPEED_MASK) {
1439 	case PORT_STATUS_SPEED_10:
1440 		*media_active |= IFM_10_T;
1441 		break;
1442 	case PORT_STATUS_SPEED_100:
1443 		*media_active |= IFM_100_TX;
1444 		break;
1445 	case PORT_STATUS_SPEED_1000:
1446 		*media_active |= IFM_1000_T;
1447 		break;
1448 	}
1449 
1450 	if ((portstatus & PORT_STATUS_DUPLEX_MASK) == 0)
1451 		*media_active |= IFM_FDX;
1452 	else
1453 		*media_active |= IFM_HDX;
1454 }
1455 
1456 static void
1457 e6000sw_tick(void *arg, int p __unused)
1458 {
1459 	e6000sw_softc_t *sc;
1460 	struct mii_data *mii;
1461 	struct mii_softc *miisc;
1462 	uint16_t portstatus;
1463 	int port;
1464 
1465 	sc = arg;
1466 
1467 	E6000SW_LOCK_ASSERT(sc, SA_UNLOCKED);
1468 
1469 	E6000SW_LOCK(sc);
1470 	for (port = 0; port < sc->num_ports; port++) {
1471 		/* Tick only on PHY ports */
1472 		if (!e6000sw_is_portenabled(sc, port) ||
1473 		    !e6000sw_is_phyport(sc, port))
1474 			continue;
1475 
1476 		mii = e6000sw_miiforphy(sc, port);
1477 		if (mii == NULL)
1478 			continue;
1479 
1480 		portstatus = e6000sw_readreg(sc, REG_PORT(sc, port),
1481 		    PORT_STATUS);
1482 
1483 		e6000sw_update_ifmedia(portstatus,
1484 		    &mii->mii_media_status, &mii->mii_media_active);
1485 
1486 		LIST_FOREACH(miisc, &mii->mii_phys, mii_list) {
1487 			if (IFM_INST(mii->mii_media.ifm_cur->ifm_media)
1488 			    != miisc->mii_inst)
1489 				continue;
1490 			mii_phy_update(miisc, MII_POLLSTAT);
1491 		}
1492 	}
1493 	E6000SW_UNLOCK(sc);
1494 }
1495 
1496 static void
1497 e6000sw_setup(device_t dev, e6000sw_softc_t *sc)
1498 {
1499 	uint32_t atu_ctrl;
1500 
1501 	/* Set aging time. */
1502 	atu_ctrl = e6000sw_readreg(sc, REG_GLOBAL, ATU_CONTROL);
1503 	atu_ctrl &= ~ATU_CONTROL_AGETIME_MASK;
1504 	atu_ctrl |= E6000SW_DEFAULT_AGETIME << ATU_CONTROL_AGETIME;
1505 	e6000sw_writereg(sc, REG_GLOBAL, ATU_CONTROL, atu_ctrl);
1506 
1507 	/* Send all with specific mac address to cpu port */
1508 	e6000sw_writereg(sc, REG_GLOBAL2, MGMT_EN_2x, MGMT_EN_ALL);
1509 	e6000sw_writereg(sc, REG_GLOBAL2, MGMT_EN_0x, MGMT_EN_ALL);
1510 
1511 	/* Disable Remote Management */
1512 	e6000sw_writereg(sc, REG_GLOBAL, SWITCH_GLOBAL_CONTROL2, 0);
1513 
1514 	/* Disable loopback filter and flow control messages */
1515 	e6000sw_writereg(sc, REG_GLOBAL2, SWITCH_MGMT,
1516 	    SWITCH_MGMT_PRI_MASK |
1517 	    (1 << SWITCH_MGMT_RSVD2CPU) |
1518 	    SWITCH_MGMT_FC_PRI_MASK |
1519 	    (1 << SWITCH_MGMT_FORCEFLOW));
1520 
1521 	e6000sw_atu_flush(dev, sc, NO_OPERATION);
1522 	e6000sw_atu_mac_table(dev, sc, NULL, NO_OPERATION);
1523 	e6000sw_set_atustat(dev, sc, 0, COUNT_ALL);
1524 }
1525 
1526 static void
1527 e6000sw_set_atustat(device_t dev, e6000sw_softc_t *sc, int bin, int flag)
1528 {
1529 
1530 	e6000sw_readreg(sc, REG_GLOBAL2, ATU_STATS);
1531 	e6000sw_writereg(sc, REG_GLOBAL2, ATU_STATS, (bin << ATU_STATS_BIN ) |
1532 	    (flag << ATU_STATS_FLAG));
1533 }
1534 
1535 static int
1536 e6000sw_atu_mac_table(device_t dev, e6000sw_softc_t *sc, struct atu_opt *atu,
1537     int flag)
1538 {
1539 	uint16_t ret_opt;
1540 	uint16_t ret_data;
1541 
1542 	if (flag == NO_OPERATION)
1543 		return (0);
1544 	else if ((flag & (LOAD_FROM_FIB | PURGE_FROM_FIB | GET_NEXT_IN_FIB |
1545 	    GET_VIOLATION_DATA | CLEAR_VIOLATION_DATA)) == 0) {
1546 		device_printf(dev, "Wrong Opcode for ATU operation\n");
1547 		return (EINVAL);
1548 	}
1549 
1550 	if (E6000SW_WAITREADY(sc, ATU_OPERATION, ATU_UNIT_BUSY)) {
1551 		device_printf(dev, "ATU unit is busy, cannot access\n");
1552 		return (EBUSY);
1553 	}
1554 
1555 	ret_opt = e6000sw_readreg(sc, REG_GLOBAL, ATU_OPERATION);
1556 	if (flag & LOAD_FROM_FIB) {
1557 		ret_data = e6000sw_readreg(sc, REG_GLOBAL, ATU_DATA);
1558 		e6000sw_writereg(sc, REG_GLOBAL2, ATU_DATA, (ret_data &
1559 		    ~ENTRY_STATE));
1560 	}
1561 	e6000sw_writereg(sc, REG_GLOBAL, ATU_MAC_ADDR01, atu->mac_01);
1562 	e6000sw_writereg(sc, REG_GLOBAL, ATU_MAC_ADDR23, atu->mac_23);
1563 	e6000sw_writereg(sc, REG_GLOBAL, ATU_MAC_ADDR45, atu->mac_45);
1564 	e6000sw_writereg(sc, REG_GLOBAL, ATU_FID, atu->fid);
1565 
1566 	e6000sw_writereg(sc, REG_GLOBAL, ATU_OPERATION,
1567 	    (ret_opt | ATU_UNIT_BUSY | flag));
1568 
1569 	if (E6000SW_WAITREADY(sc, ATU_OPERATION, ATU_UNIT_BUSY))
1570 		device_printf(dev, "Timeout while waiting ATU\n");
1571 	else if (flag & GET_NEXT_IN_FIB) {
1572 		atu->mac_01 = e6000sw_readreg(sc, REG_GLOBAL,
1573 		    ATU_MAC_ADDR01);
1574 		atu->mac_23 = e6000sw_readreg(sc, REG_GLOBAL,
1575 		    ATU_MAC_ADDR23);
1576 		atu->mac_45 = e6000sw_readreg(sc, REG_GLOBAL,
1577 		    ATU_MAC_ADDR45);
1578 	}
1579 
1580 	return (0);
1581 }
1582 
1583 static int
1584 e6000sw_atu_flush(device_t dev, e6000sw_softc_t *sc, int flag)
1585 {
1586 	uint32_t reg;
1587 
1588 	if (flag == NO_OPERATION)
1589 		return (0);
1590 
1591 	if (E6000SW_WAITREADY(sc, ATU_OPERATION, ATU_UNIT_BUSY)) {
1592 		device_printf(dev, "ATU unit is busy, cannot access\n");
1593 		return (EBUSY);
1594 	}
1595 	reg = e6000sw_readreg(sc, REG_GLOBAL, ATU_OPERATION);
1596 	e6000sw_writereg(sc, REG_GLOBAL, ATU_OPERATION,
1597 	    (reg | ATU_UNIT_BUSY | flag));
1598 	if (E6000SW_WAITREADY(sc, ATU_OPERATION, ATU_UNIT_BUSY))
1599 		device_printf(dev, "Timeout while flushing ATU\n");
1600 
1601 	return (0);
1602 }
1603 
1604 static int
1605 e6000sw_vtu_flush(e6000sw_softc_t *sc)
1606 {
1607 
1608 	if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) {
1609 		device_printf(sc->dev, "VTU unit is busy, cannot access\n");
1610 		return (EBUSY);
1611 	}
1612 
1613 	e6000sw_writereg(sc, REG_GLOBAL, VTU_OPERATION, VTU_FLUSH | VTU_BUSY);
1614 	if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) {
1615 		device_printf(sc->dev, "Timeout while flushing VTU\n");
1616 		return (ETIMEDOUT);
1617 	}
1618 
1619 	return (0);
1620 }
1621 
1622 static int
1623 e6000sw_vtu_update(e6000sw_softc_t *sc, int purge, int vid, int fid,
1624     int members, int untagged)
1625 {
1626 	int i, op;
1627 	uint32_t data[2];
1628 
1629 	if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) {
1630 		device_printf(sc->dev, "VTU unit is busy, cannot access\n");
1631 		return (EBUSY);
1632 	}
1633 
1634 	*data = (vid & VTU_VID_MASK);
1635 	if (purge == 0)
1636 		*data |= VTU_VID_VALID;
1637 	e6000sw_writereg(sc, REG_GLOBAL, VTU_VID, *data);
1638 
1639 	if (purge == 0) {
1640 		data[0] = 0;
1641 		data[1] = 0;
1642 		for (i = 0; i < sc->num_ports; i++) {
1643 			if ((untagged & (1 << i)) != 0)
1644 				data[i / VTU_PPREG(sc)] |=
1645 				    VTU_PORT_UNTAGGED << VTU_PORT(sc, i);
1646 			else if ((members & (1 << i)) != 0)
1647 				data[i / VTU_PPREG(sc)] |=
1648 				    VTU_PORT_TAGGED << VTU_PORT(sc, i);
1649 			else
1650 				data[i / VTU_PPREG(sc)] |=
1651 				    VTU_PORT_DISCARD << VTU_PORT(sc, i);
1652 		}
1653 		e6000sw_writereg(sc, REG_GLOBAL, VTU_DATA, data[0]);
1654 		e6000sw_writereg(sc, REG_GLOBAL, VTU_DATA2, data[1]);
1655 		e6000sw_writereg(sc, REG_GLOBAL, VTU_FID,
1656 		    fid & VTU_FID_MASK(sc));
1657 		op = VTU_LOAD;
1658 	} else
1659 		op = VTU_PURGE;
1660 
1661 	e6000sw_writereg(sc, REG_GLOBAL, VTU_OPERATION, op | VTU_BUSY);
1662 	if (E6000SW_WAITREADY(sc, VTU_OPERATION, VTU_BUSY)) {
1663 		device_printf(sc->dev, "Timeout while flushing VTU\n");
1664 		return (ETIMEDOUT);
1665 	}
1666 
1667 	return (0);
1668 }
1669