if_nlge.c revision 213443
1/*-
2 * Copyright (c) 2003-2009 RMI Corporation
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of RMI Corporation, nor the names of its contributors,
14 *    may be used to endorse or promote products derived from this software
15 *    without specific prior written permission.
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 * RMI_BSD */
30
31/*
32 * The XLR device supports upto four 10/100/1000 Ethernet MACs and upto
33 * two 10G Ethernet MACs (of XGMII). Alternatively, each 10G port can used
34 * as a SPI-4 interface, with 8 ports per such interface. The MACs are
35 * encapsulated in another hardware block referred to as network accelerator,
36 * such that there are three instances of these in a XLR. One of them controls
37 * the four 1G RGMII ports while one each of the others controls an XGMII port.
38 * Enabling MACs requires configuring the corresponding network accelerator
39 * and the individual port.
40 * The XLS device supports upto 8 10/100/1000 Ethernet MACs or max 2 10G
41 * Ethernet MACs. The 1G MACs are of SGMII and 10G MACs are of XAUI
42 * interface. These ports are part of two network accelerators.
43 * The nlge driver configures and initializes non-SPI4 Ethernet ports in the
44 * XLR/XLS devices and enables data transfer on them.
45 */
46
47#include <sys/cdefs.h>
48__FBSDID("$FreeBSD: head/sys/mips/rmi/dev/nlge/if_nlge.c 213443 2010-10-05 06:44:47Z jchandra $");
49
50#ifdef HAVE_KERNEL_OPTION_HEADERS
51#include "opt_device_polling.h"
52#endif
53
54#include <sys/endian.h>
55#include <sys/systm.h>
56#include <sys/sockio.h>
57#include <sys/param.h>
58#include <sys/lock.h>
59#include <sys/mutex.h>
60#include <sys/proc.h>
61#include <sys/limits.h>
62#include <sys/bus.h>
63#include <sys/mbuf.h>
64#include <sys/malloc.h>
65#include <sys/kernel.h>
66#include <sys/module.h>
67#include <sys/socket.h>
68#define __RMAN_RESOURCE_VISIBLE
69#include <sys/rman.h>
70#include <sys/taskqueue.h>
71#include <sys/smp.h>
72#include <sys/sysctl.h>
73
74#include <net/if.h>
75#include <net/if_arp.h>
76#include <net/ethernet.h>
77#include <net/if_dl.h>
78#include <net/if_media.h>
79#include <net/bpf.h>
80#include <net/if_types.h>
81#include <net/if_vlan_var.h>
82
83#include <netinet/in_systm.h>
84#include <netinet/in.h>
85#include <netinet/ip.h>
86
87#include <vm/vm.h>
88#include <vm/pmap.h>
89#include <vm/uma.h>
90
91#include <machine/reg.h>
92#include <machine/cpu.h>
93#include <machine/mips_opcode.h>
94#include <machine/asm.h>
95#include <machine/cpuregs.h>
96#include <machine/param.h>
97#include <machine/intr_machdep.h>
98#include <machine/clock.h>	/* for DELAY */
99#include <machine/bus.h>
100#include <machine/resource.h>
101
102#include <mips/rmi/interrupt.h>
103#include <mips/rmi/msgring.h>
104#include <mips/rmi/iomap.h>
105#include <mips/rmi/pic.h>
106#include <mips/rmi/board.h>
107#include <mips/rmi/rmi_mips_exts.h>
108#include <mips/rmi/rmi_boot_info.h>
109#include <mips/rmi/dev/xlr/atx_cpld.h>
110#include <mips/rmi/dev/xlr/xgmac_mdio.h>
111
112#include <dev/mii/mii.h>
113#include <dev/mii/miivar.h>
114#include "miidevs.h"
115#include <dev/mii/brgphyreg.h>
116#include "miibus_if.h"
117
118#include <mips/rmi/dev/nlge/if_nlge.h>
119
120MODULE_DEPEND(nlna, nlge, 1, 1, 1);
121MODULE_DEPEND(nlge, ether, 1, 1, 1);
122MODULE_DEPEND(nlge, miibus, 1, 1, 1);
123
124/* Network accelarator entry points */
125static int      nlna_probe(device_t);
126static int      nlna_attach(device_t);
127static int      nlna_detach(device_t);
128static int      nlna_suspend(device_t);
129static int      nlna_resume(device_t);
130static int 	nlna_shutdown(device_t);
131
132/* GMAC port entry points */
133static int	nlge_probe(device_t);
134static int	nlge_attach(device_t);
135static int	nlge_detach(device_t);
136static int	nlge_suspend(device_t);
137static int	nlge_resume(device_t);
138static void	nlge_init(void *);
139static int	nlge_ioctl(struct ifnet *, u_long, caddr_t);
140static void	nlge_start(struct ifnet *);
141static void 	nlge_rx(struct nlge_softc *sc, vm_paddr_t paddr, int len);
142
143static int	nlge_mii_write(struct device *, int, int, int);
144static int	nlge_mii_read(struct device *, int, int);
145static void	nlge_mac_mii_statchg(device_t);
146static int	nlge_mediachange(struct ifnet *ifp);
147static void	nlge_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr);
148
149/* Other internal/helper functions */
150static void 	*get_buf(void);
151
152static void	nlna_add_to_port_set(struct nlge_port_set *pset,
153    struct nlge_softc *sc);
154static void	nlna_config_pde(struct nlna_softc *);
155static void	nlna_config_parser(struct nlna_softc *);
156static void	nlna_config_classifier(struct nlna_softc *);
157static void	nlna_config_fifo_spill_area(struct nlna_softc *sc);
158static void	nlna_config_common(struct nlna_softc *);
159static void	nlna_disable_ports(struct nlna_softc *sc);
160static void	nlna_enable_intr(struct nlna_softc *sc);
161static void	nlna_disable_intr(struct nlna_softc *sc);
162static void	nlna_enable_ports(struct nlna_softc *sc);
163static void	nlna_get_all_softc(device_t iodi_dev,
164    struct nlna_softc **sc_vec, uint32_t vec_sz);
165static void 	nlna_hw_init(struct nlna_softc *sc);
166static int 	nlna_is_last_active_na(struct nlna_softc *sc);
167static void	nlna_media_specific_config(struct nlna_softc *sc);
168static void 	nlna_reset_ports(struct nlna_softc *sc,
169    struct xlr_gmac_block_t *blk);
170static struct nlna_softc *nlna_sc_init(device_t dev,
171    struct xlr_gmac_block_t *blk);
172static void	nlna_setup_intr(struct nlna_softc *sc);
173static void	nlna_smp_update_pde(void *dummy __unused);
174static void	nlna_submit_rx_free_desc(struct nlna_softc *sc,
175    uint32_t n_desc);
176
177static int	nlge_gmac_config_speed(struct nlge_softc *, int quick);
178static void	nlge_hw_init(struct nlge_softc *sc);
179static int	nlge_if_init(struct nlge_softc *sc);
180static void	nlge_intr(void *arg);
181static int	nlge_irq_init(struct nlge_softc *sc);
182static void	nlge_irq_fini(struct nlge_softc *sc);
183static void	nlge_media_specific_init(struct nlge_softc *sc);
184static void	nlge_mii_init(device_t dev, struct nlge_softc *sc);
185static int	nlge_mii_read_internal(xlr_reg_t *mii_base, int phyaddr,
186    int regidx);
187static void 	nlge_mii_write_internal(xlr_reg_t *mii_base, int phyaddr,
188    int regidx, int regval);
189void 		nlge_msgring_handler(int bucket, int size, int code,
190    int stid, struct msgrng_msg *msg, void *data);
191static void 	nlge_port_disable(int id, xlr_reg_t *base, int port_type);
192static void 	nlge_port_enable(struct nlge_softc *sc);
193static void 	nlge_read_mac_addr(struct nlge_softc *sc);
194static void	nlge_sc_init(struct nlge_softc *sc, device_t dev,
195    struct xlr_gmac_port *port_info);
196static void 	nlge_set_mac_addr(struct nlge_softc *sc);
197static void	nlge_set_port_attribs(struct nlge_softc *,
198    struct xlr_gmac_port *);
199static void 	nlge_sgmii_init(struct nlge_softc *sc);
200static void	nlge_start_locked(struct ifnet *ifp, struct nlge_softc *sc);
201
202static int	prepare_fmn_message(struct nlge_softc *sc,
203    struct msgrng_msg *msg, uint32_t *n_entries, struct mbuf *m_head,
204    uint64_t fr_stid, struct nlge_tx_desc **tx_desc);
205
206static void 	release_tx_desc(vm_paddr_t phy_addr);
207static int	send_fmn_msg_tx(struct nlge_softc *, struct msgrng_msg *,
208    uint32_t n_entries);
209
210static void
211nl_tx_q_wakeup(void *addr);
212
213//#define DEBUG
214#ifdef DEBUG
215static int	mac_debug = 1;
216static int 	reg_dump = 0;
217#undef PDEBUG
218#define PDEBUG(fmt, args...) \
219        do {\
220            if (mac_debug) {\
221                printf("[%s@%d|%s]: cpu_%d: " fmt, \
222                __FILE__, __LINE__, __FUNCTION__,  PCPU_GET(cpuid), ##args);\
223            }\
224        } while(0);
225
226/* Debug/dump functions */
227static void 	dump_reg(xlr_reg_t *addr, uint32_t offset, char *name);
228static void	dump_gmac_registers(struct nlge_softc *);
229static void	dump_na_registers(xlr_reg_t *base, int port_id);
230static void	dump_mac_stats(struct nlge_softc *sc);
231static void 	dump_mii_regs(struct nlge_softc *sc) __attribute__((used));
232static void 	dump_mii_data(struct mii_data *mii) __attribute__((used));
233static void	dump_board_info(struct xlr_board_info *);
234static void	dump_pcs_regs(struct nlge_softc *sc, int phy);
235
236#else
237#undef PDEBUG
238#define PDEBUG(fmt, args...)
239#define dump_reg(a, o, n)		/* nop */
240#define dump_gmac_registers(a)		/* nop */
241#define dump_na_registers(a, p)	/* nop */
242#define dump_board_info(b)		/* nop */
243#define dump_mac_stats(sc)		/* nop */
244#define dump_mii_regs(sc)		/* nop */
245#define dump_mii_data(mii)		/* nop */
246#define dump_pcs_regs(sc, phy)		/* nop */
247#endif
248
249/* Wrappers etc. to export the driver entry points. */
250static device_method_t nlna_methods[] = {
251	/* Device interface */
252	DEVMETHOD(device_probe,         nlna_probe),
253	DEVMETHOD(device_attach,        nlna_attach),
254	DEVMETHOD(device_detach,        nlna_detach),
255	DEVMETHOD(device_shutdown,      nlna_shutdown),
256	DEVMETHOD(device_suspend,       nlna_suspend),
257	DEVMETHOD(device_resume,        nlna_resume),
258
259	/* bus interface : TBD : what are these for ? */
260	DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
261	DEVMETHOD(bus_print_child,	bus_generic_print_child),
262	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
263
264	{ 0, 0 }
265};
266
267static driver_t	nlna_driver = {
268	"nlna",
269	nlna_methods,
270	sizeof(struct nlna_softc)
271};
272
273static devclass_t nlna_devclass;
274
275static device_method_t nlge_methods[] = {
276	/* Device interface */
277	DEVMETHOD(device_probe,         nlge_probe),
278	DEVMETHOD(device_attach,        nlge_attach),
279	DEVMETHOD(device_detach,        nlge_detach),
280	DEVMETHOD(device_shutdown,      bus_generic_shutdown),
281	DEVMETHOD(device_suspend,       nlge_suspend),
282	DEVMETHOD(device_resume,        nlge_resume),
283
284	/* MII interface */
285	DEVMETHOD(miibus_readreg, nlge_mii_read),
286	DEVMETHOD(miibus_writereg, nlge_mii_write),
287	DEVMETHOD(miibus_statchg, nlge_mac_mii_statchg),
288
289	{0, 0}
290};
291
292static driver_t	nlge_driver = {
293	"nlge",
294	nlge_methods,
295	sizeof(struct nlge_softc)
296};
297
298static devclass_t nlge_devclass;
299
300DRIVER_MODULE(nlna, iodi, nlna_driver, nlna_devclass, 0, 0);
301DRIVER_MODULE(nlge, nlna,  nlge_driver, nlge_devclass, 0, 0);
302DRIVER_MODULE(miibus, nlge, miibus_driver, miibus_devclass, 0, 0);
303
304static uma_zone_t nl_tx_desc_zone;
305
306static __inline void
307atomic_incr_long(unsigned long *addr)
308{
309	/* XXX: fix for 64 bit */
310	unsigned int *iaddr = (unsigned int *)addr;
311
312	xlr_ldaddwu(1, iaddr);
313}
314
315static int
316nlna_probe(device_t dev)
317{
318	return (BUS_PROBE_DEFAULT);
319}
320
321/*
322 * Add all attached GMAC/XGMAC ports to the device tree. Port
323 * configuration is spread in two regions - common configuration
324 * for all ports in the NA and per-port configuration in MAC-specific
325 * region. This function does the following:
326 *  - adds the ports to the device tree
327 *  - reset the ports
328 *  - do all the common initialization
329 *  - invoke bus_generic_attach for per-port configuration
330 *  - supply initial free rx descriptors to ports
331 *  - initialize s/w data structures
332 *  - finally, enable interrupts (only in the last NA).
333 *
334 * For reference, sample address space for common and per-port
335 * registers is given below.
336 *
337 * The address map for RNA0 is:                           (typical value)
338 *
339 * XLR_IO_BASE +--------------------------------------+   0xbef0_0000
340 *             |                                      |
341 *             |                                      |
342 *             |                                      |
343 *             |                                      |
344 *             |                                      |
345 *             |                                      |
346 * GMAC0  ---> +--------------------------------------+   0xbef0_c000
347 *             |                                      |
348 *             |                                      |
349 * (common) -> |......................................|   0xbef0_c400
350 *             |                                      |
351 *             |   (RGMII/SGMII: common registers)    |
352 *             |                                      |
353 * GMAC1  ---> |--------------------------------------|   0xbef0_d000
354 *             |                                      |
355 *             |                                      |
356 * (common) -> |......................................|   0xbef0_d400
357 *             |                                      |
358 *             |   (RGMII/SGMII: common registers)    |
359 *             |                                      |
360 *             |......................................|
361 *       and so on ....
362 *
363 * Ref: Figure 14-3 and Table 14-1 of XLR PRM
364 */
365static int
366nlna_attach(device_t dev)
367{
368	struct xlr_gmac_block_t *block_info;
369	device_t		 gmac_dev;
370	struct nlna_softc	*sc;
371	int			 error;
372	int			 i;
373	int			 id;
374
375	id = device_get_unit(dev);
376	block_info = device_get_ivars(dev);
377	if (!block_info->enabled) {
378		return 0;
379	}
380
381#ifdef DEBUG
382	dump_board_info(&xlr_board_info);
383#endif
384	/* Initialize nlna state in softc structure */
385	sc = nlna_sc_init(dev, block_info);
386
387	/* Add device's for the ports controlled by this NA. */
388	if (block_info->type == XLR_GMAC) {
389		KASSERT(id < 2, ("No GMACs supported with this network"
390		    "accelerator: %d", id));
391		for (i = 0; i < sc->num_ports; i++) {
392			gmac_dev = device_add_child(dev, "nlge", -1);
393			device_set_ivars(gmac_dev, &block_info->gmac_port[i]);
394		}
395	} else if (block_info->type == XLR_XGMAC) {
396		KASSERT(id > 0 && id <= 2, ("No XGMACs supported with this"
397		    "network accelerator: %d", id));
398		gmac_dev = device_add_child(dev, "nlge", -1);
399		device_set_ivars(gmac_dev, &block_info->gmac_port[0]);
400	} else if (block_info->type == XLR_SPI4) {
401		/* SPI4 is not supported here */
402		device_printf(dev, "Unsupported: NA with SPI4 type");
403		return (ENOTSUP);
404	}
405
406	nlna_reset_ports(sc, block_info);
407
408	/* Initialize Network Accelarator registers. */
409	nlna_hw_init(sc);
410
411	error = bus_generic_attach(dev);
412	if (error) {
413		device_printf(dev, "failed to attach port(s)\n");
414		goto fail;
415	}
416
417	/* Send out the initial pool of free-descriptors for the rx path */
418	nlna_submit_rx_free_desc(sc, MAX_FRIN_SPILL);
419
420	/* S/w data structure initializations shared by all NA's. */
421	if (nl_tx_desc_zone == NULL) {
422		/* Create a zone for allocating tx descriptors */
423		nl_tx_desc_zone = uma_zcreate("NL Tx Desc",
424		    sizeof(struct nlge_tx_desc), NULL, NULL, NULL, NULL,
425		    XLR_CACHELINE_SIZE, 0);
426	}
427
428	/* Other per NA s/w initialization */
429	callout_init(&sc->tx_thr, CALLOUT_MPSAFE);
430	callout_reset(&sc->tx_thr, hz, nl_tx_q_wakeup, sc);
431
432	/* Enable NA interrupts */
433	nlna_setup_intr(sc);
434
435	return (0);
436
437fail:
438	return (error);
439}
440
441static int
442nlna_detach(device_t dev)
443{
444	struct nlna_softc *sc;
445
446	sc = device_get_softc(dev);
447	if (device_is_alive(dev)) {
448		nlna_disable_intr(sc);
449		/* This will make sure that per-port detach is complete
450		 * and all traffic on the ports has been stopped. */
451		bus_generic_detach(dev);
452		uma_zdestroy(nl_tx_desc_zone);
453	}
454
455	return (0);
456}
457
458static int
459nlna_suspend(device_t dev)
460{
461
462	return (0);
463}
464
465static int
466nlna_resume(device_t dev)
467{
468
469	return (0);
470}
471
472static int
473nlna_shutdown(device_t dev)
474{
475	return (0);
476}
477
478
479/* GMAC port entry points */
480static int
481nlge_probe(device_t dev)
482{
483	struct nlge_softc	*sc;
484	struct xlr_gmac_port	*port_info;
485	int index;
486	char *desc[] = { "RGMII", "SGMII", "RGMII/SGMII", "XGMAC", "XAUI",
487	    "Unknown"};
488
489	port_info = device_get_ivars(dev);
490	index = (port_info->type < XLR_RGMII || port_info->type > XLR_XAUI) ?
491	    5 : port_info->type;
492	device_set_desc_copy(dev, desc[index]);
493
494	sc = device_get_softc(dev);
495	nlge_sc_init(sc, dev, port_info);
496
497	nlge_port_disable(sc->id, sc->base, sc->port_type);
498
499	return (0);
500}
501
502static int
503nlge_attach(device_t dev)
504{
505	struct nlge_softc *sc;
506	struct nlna_softc *nsc;
507	int error;
508
509	sc = device_get_softc(dev);
510
511	nlge_if_init(sc);
512	nlge_mii_init(dev, sc);
513	error = nlge_irq_init(sc);
514	if (error)
515		return error;
516	nlge_hw_init(sc);
517
518	nsc = (struct nlna_softc *)device_get_softc(device_get_parent(dev));
519	nsc->child_sc[sc->instance] = sc;
520
521	return (0);
522}
523
524static int
525nlge_detach(device_t dev)
526{
527	struct nlge_softc *sc;
528	struct ifnet   *ifp;
529
530	sc = device_get_softc(dev);
531	ifp = sc->nlge_if;
532
533	if (device_is_attached(dev)) {
534		ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING);
535		nlge_port_disable(sc->id, sc->base, sc->port_type);
536		nlge_irq_fini(sc);
537		ether_ifdetach(ifp);
538		bus_generic_detach(dev);
539	}
540	if (ifp)
541		if_free(ifp);
542
543	return (0);
544}
545
546static int
547nlge_suspend(device_t dev)
548{
549	return (0);
550}
551
552static int
553nlge_resume(device_t dev)
554{
555	return (0);
556}
557
558static void
559nlge_init(void *addr)
560{
561	struct nlge_softc *sc;
562	struct ifnet   *ifp;
563
564	sc = (struct nlge_softc *)addr;
565	ifp = sc->nlge_if;
566
567	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
568		return;
569
570	nlge_gmac_config_speed(sc, 0);
571	ifp->if_drv_flags |= IFF_DRV_RUNNING;
572	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
573	nlge_port_enable(sc);
574
575	if (sc->port_type == XLR_SGMII) {
576		dump_pcs_regs(sc, 27);
577	}
578	dump_gmac_registers(sc);
579	dump_mac_stats(sc);
580}
581
582static int
583nlge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
584{
585	struct mii_data 	*mii;
586	struct nlge_softc 	*sc;
587	struct ifreq 		*ifr;
588	int 			error;
589
590	sc = ifp->if_softc;
591	error = 0;
592	ifr = (struct ifreq *)data;
593	switch(command) {
594	case SIOCSIFFLAGS:
595		break;
596	case SIOCSIFMEDIA:
597	case SIOCGIFMEDIA:
598		if (sc->mii_bus != NULL) {
599			mii = (struct mii_data *)device_get_softc(sc->mii_bus);
600			error = ifmedia_ioctl(ifp, ifr, &mii->mii_media,
601			    command);
602		}
603		break;
604	case SIOCSIFADDR:
605			// intentional fall thru
606	case SIOCSIFMTU:
607	default:
608		error = ether_ioctl(ifp, command, data);
609		break;
610	}
611
612	return (error);
613}
614
615/* This function is called from an interrupt handler */
616void
617nlge_msgring_handler(int bucket, int size, int code, int stid,
618		    struct msgrng_msg *msg, void *data)
619{
620	struct nlna_softc *na_sc;
621	struct nlge_softc *sc;
622	struct ifnet	*ifp;
623	struct mbuf	*m;
624	vm_paddr_t	phys_addr;
625	uint32_t	length;
626	int		ctrl;
627	int		tx_error;
628	int		port;
629	int		is_p2p;
630
631	is_p2p = 0;
632	tx_error = 0;
633	length = (msg->msg0 >> 40) & 0x3fff;
634	na_sc = (struct nlna_softc *)data;
635	if (length == 0) {
636		ctrl = CTRL_REG_FREE;
637		phys_addr = msg->msg0 & 0xffffffffffULL;
638		port = (msg->msg0 >> 54) & 0x0f;
639		is_p2p = (msg->msg0 >> 62) & 0x1;
640		tx_error = (msg->msg0 >> 58) & 0xf;
641	} else {
642		ctrl = CTRL_SNGL;
643		phys_addr = msg->msg0 & 0xffffffffe0ULL;
644		length = length - BYTE_OFFSET - MAC_CRC_LEN;
645		port = msg->msg0 & 0x0f;
646	}
647
648	sc = na_sc->child_sc[port];
649	if (sc == NULL) {
650		printf("Message (of %d len) with softc=NULL on %d port (type=%s)\n",
651		    length, port, (ctrl == CTRL_SNGL ? "Pkt rx" :
652		    "Freeback for tx packet"));
653		return;
654	}
655
656	if (ctrl == CTRL_REG_FREE || ctrl == CTRL_JUMBO_FREE) {
657		ifp = sc->nlge_if;
658		if (!tx_error) {
659			if (is_p2p) {
660				release_tx_desc(phys_addr);
661			} else {
662#ifdef __mips_n64
663				m = (struct mbuf *)(uintptr_t)xlr_paddr_ld(phys_addr);
664				m->m_nextpkt = NULL;
665#else
666				m = (struct mbuf *)(uintptr_t)phys_addr;
667#endif
668				m_freem(m);
669			}
670			NLGE_LOCK(sc);
671			if (ifp->if_drv_flags & IFF_DRV_OACTIVE){
672				ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
673				callout_reset(&na_sc->tx_thr, hz,
674				    nl_tx_q_wakeup, na_sc);
675			}
676			NLGE_UNLOCK(sc);
677		} else {
678			printf("ERROR: Tx fb error (%d) on port %d\n", tx_error,
679			    port);
680		}
681		atomic_incr_long((tx_error) ? &ifp->if_oerrors: &ifp->if_opackets);
682	} else if (ctrl == CTRL_SNGL || ctrl == CTRL_START) {
683		/* Rx Packet */
684
685		nlge_rx(sc, phys_addr, length);
686		nlna_submit_rx_free_desc(na_sc, 1);	/* return free descr to NA */
687	} else {
688		printf("[%s]: unrecognized ctrl=%d!\n", __func__, ctrl);
689	}
690
691}
692
693static void
694nlge_start(struct ifnet *ifp)
695{
696	struct nlge_softc	*sc;
697
698	sc = ifp->if_softc;
699	//NLGE_LOCK(sc);
700	nlge_start_locked(ifp, sc);
701	//NLGE_UNLOCK(sc);
702}
703
704static void
705nl_tx_q_wakeup(void *addr)
706{
707	struct nlna_softc *na_sc;
708	struct nlge_softc *sc;
709	int i;
710
711	na_sc = (struct nlna_softc *) addr;
712	for (i = 0; i < XLR_MAX_MACS; i++) {
713		sc = na_sc->child_sc[i];
714		if (sc == NULL)
715			continue;
716		nlge_start_locked(sc->nlge_if, sc);
717	}
718	callout_reset(&na_sc->tx_thr, 5 * hz, nl_tx_q_wakeup, na_sc);
719}
720
721static void
722nlge_start_locked(struct ifnet *ifp, struct nlge_softc *sc)
723{
724	struct msgrng_msg 	msg;
725	struct mbuf  		*m;
726	struct nlge_tx_desc 	*tx_desc;
727	uint64_t		fr_stid;
728	uint32_t		cpu;
729	uint32_t		n_entries;
730	uint32_t		tid;
731	int 			ret;
732
733	cpu = xlr_core_id();
734	tid = xlr_thr_id();
735	/* H/w threads [0, 2] --> bucket 6 and [1, 3] --> bucket 7 */
736	fr_stid = cpu * 8 + 6 + (tid % 2);
737
738	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
739		return;
740	}
741
742	do {
743		/*
744		 * First, remove some freeback messages before transmitting
745		 * any new packets. However, cap the number of messages
746		 * drained to permit this thread to continue with its
747		 * transmission.
748		 *
749		 * Mask for buckets {6, 7} is 0xc0
750		 */
751		xlr_msgring_handler(0xc0, 4);
752
753		/* Grab a packet off the queue. */
754		IF_DEQUEUE(&ifp->if_snd, m);
755		if (m == NULL) {
756			return;
757		}
758
759		tx_desc = NULL;
760		ret = prepare_fmn_message(sc, &msg, &n_entries, m, fr_stid, &tx_desc);
761		if (ret) {
762			goto fail;
763		}
764		ret = send_fmn_msg_tx(sc, &msg, n_entries);
765		if (ret != 0) {
766			goto fail;
767		}
768	} while(1);
769
770	return;
771
772fail:
773	if (tx_desc != NULL) {
774		uma_zfree(nl_tx_desc_zone, tx_desc);
775	}
776	if (m != NULL) {
777		NLGE_LOCK(sc);
778		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
779		NLGE_UNLOCK(sc);
780		IF_PREPEND(&ifp->if_snd, m);
781		atomic_incr_long(&ifp->if_iqdrops);
782	}
783	return;
784}
785
786static void
787nlge_rx(struct nlge_softc *sc, vm_paddr_t paddr, int len)
788{
789	struct ifnet	*ifp;
790	struct mbuf	*m;
791	uint64_t	tm, mag;
792	uint32_t	sr;
793
794	sr = xlr_enable_kx();
795	tm = xlr_paddr_ld(paddr - XLR_CACHELINE_SIZE);
796	mag = xlr_paddr_ld(paddr - XLR_CACHELINE_SIZE + sizeof(uint64_t));
797	xlr_restore_kx(sr);
798
799	m = (struct mbuf *)(intptr_t)tm;
800	if (mag != 0xf00bad) {
801		/* somebody else's packet. Error - FIXME in intialization */
802		printf("cpu %d: *ERROR* Not my packet paddr %jx\n",
803		    xlr_core_id(), (uintmax_t)paddr);
804		return;
805	}
806
807	ifp = sc->nlge_if;
808	/* align the data */
809	m->m_data += BYTE_OFFSET;
810	m->m_pkthdr.len = m->m_len = len;
811	m->m_pkthdr.rcvif = ifp;
812
813	atomic_incr_long(&ifp->if_ipackets);
814	(*ifp->if_input)(ifp, m);
815}
816
817static int
818nlge_mii_write(struct device *dev, int phyaddr, int regidx, int regval)
819{
820	struct nlge_softc *sc;
821
822	sc = device_get_softc(dev);
823	if (sc->phy_addr == phyaddr && sc->port_type != XLR_XGMII)
824		nlge_mii_write_internal(sc->mii_base, phyaddr, regidx, regval);
825
826	return (0);
827}
828
829static int
830nlge_mii_read(struct device *dev, int phyaddr, int regidx)
831{
832	struct nlge_softc *sc;
833	int val;
834
835	sc = device_get_softc(dev);
836	val = (sc->phy_addr != phyaddr && sc->port_type != XLR_XGMII) ? (0xffff) :
837	    nlge_mii_read_internal(sc->mii_base, phyaddr, regidx);
838
839	return (val);
840}
841
842static void
843nlge_mac_mii_statchg(device_t dev)
844{
845}
846
847static int
848nlge_mediachange(struct ifnet *ifp)
849{
850	return 0;
851}
852
853static void
854nlge_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
855{
856	struct nlge_softc *sc;
857	struct mii_data *md;
858
859	md = NULL;
860	sc = ifp->if_softc;
861	if (sc->mii_bus)
862		md = device_get_softc(sc->mii_bus);
863
864	ifmr->ifm_status = IFM_AVALID;
865	ifmr->ifm_active = IFM_ETHER;
866
867	if (sc->link == xlr_mac_link_down)
868		return;
869
870	if (md != NULL)
871		ifmr->ifm_active = md->mii_media.ifm_cur->ifm_media;
872	ifmr->ifm_status |= IFM_ACTIVE;
873}
874
875static struct nlna_softc *
876nlna_sc_init(device_t dev, struct xlr_gmac_block_t *blk)
877{
878	struct nlna_softc	*sc;
879
880	sc = device_get_softc(dev);
881	memset(sc, 0, sizeof(*sc));
882	sc->nlna_dev = dev;
883	sc->base = xlr_io_mmio(blk->baseaddr);
884	sc->rfrbucket = blk->station_rfr;
885	sc->station_id = blk->station_id;
886	sc->na_type = blk->type;
887	sc->mac_type = blk->mode;
888	sc->num_ports = blk->num_ports;
889
890	sc->mdio_set.port_vec 	= sc->mdio_sc;
891	sc->mdio_set.vec_sz   	= XLR_MAX_MACS;
892
893	return (sc);
894}
895
896/*
897 * Do:
898 *     - Initialize common GMAC registers (index range 0x100-0x3ff).
899 */
900static void
901nlna_hw_init(struct nlna_softc *sc)
902{
903
904	/*
905	 * Register message ring handler for the NA block, messages from
906	 * the GMAC will have source station id to the first bucket of the
907	 * NA FMN station, so register just that station id.
908	 */
909	if (register_msgring_handler(sc->station_id, sc->station_id + 1,
910	    nlge_msgring_handler, sc)) {
911		panic("Couldn't register msgring handler\n");
912	}
913	nlna_config_fifo_spill_area(sc);
914	nlna_config_pde(sc);
915	nlna_config_common(sc);
916	nlna_config_parser(sc);
917	nlna_config_classifier(sc);
918}
919
920/*
921 * Enable interrupts on all the ports controlled by this NA. For now, we
922 * only care about the MII interrupt and this has to be enabled only
923 * on the port id0.
924 *
925 * This function is not in-sync with the regular way of doing things - it
926 * executes only in the context of the last active network accelerator (and
927 * thereby has some ugly accesses in the device tree). Though inelegant, it
928 * is necessary to do it this way as the per-port interrupts can be
929 * setup/enabled only after all the network accelerators have been
930 * initialized.
931 */
932static void
933nlna_setup_intr(struct nlna_softc *sc)
934{
935	struct nlna_softc *na_sc[XLR_MAX_NLNA];
936	struct nlge_port_set *pset;
937	struct xlr_gmac_port *port_info;
938	device_t	iodi_dev;
939	int 		i, j;
940
941	if (!nlna_is_last_active_na(sc))
942		return ;
943
944	/* Collect all nlna softc pointers */
945	memset(na_sc, 0, sizeof(*na_sc) * XLR_MAX_NLNA);
946	iodi_dev = device_get_parent(sc->nlna_dev);
947	nlna_get_all_softc(iodi_dev, na_sc, XLR_MAX_NLNA);
948
949	/* Setup the MDIO interrupt lists. */
950	/*
951	 * MDIO interrupts are coarse - a single interrupt line provides
952	 * information about one of many possible ports. To figure out the
953	 * exact port on which action is to be taken, all of the ports
954	 * linked to an MDIO interrupt should be read. To enable this,
955	 * ports need to add themselves to port sets.
956	 */
957	for (i = 0; i < XLR_MAX_NLNA; i++) {
958		if (na_sc[i] == NULL)
959			continue;
960		for (j = 0; j < na_sc[i]->num_ports; j++) {
961			/* processing j-th port on i-th NA */
962			port_info = device_get_ivars(
963			    na_sc[i]->child_sc[j]->nlge_dev);
964			pset = &na_sc[port_info->mdint_id]->mdio_set;
965			nlna_add_to_port_set(pset, na_sc[i]->child_sc[j]);
966		}
967	}
968
969	/* Enable interrupts */
970	for (i = 0; i < XLR_MAX_NLNA; i++) {
971		if (na_sc[i] != NULL && na_sc[i]->na_type != XLR_XGMAC) {
972			nlna_enable_intr(na_sc[i]);
973		}
974	}
975}
976
977static void
978nlna_add_to_port_set(struct nlge_port_set *pset, struct nlge_softc *sc)
979{
980	int i;
981
982	/* step past the non-NULL elements */
983	for (i = 0; i < pset->vec_sz && pset->port_vec[i] != NULL; i++) ;
984	if (i < pset->vec_sz)
985		pset->port_vec[i] = sc;
986	else
987		printf("warning: internal error: out-of-bounds for MDIO array");
988}
989
990static void
991nlna_enable_intr(struct nlna_softc *sc)
992{
993	int i;
994
995	for (i = 0; i < sc->num_ports; i++) {
996		if (sc->child_sc[i]->instance == 0)
997			NLGE_WRITE(sc->child_sc[i]->base, R_INTMASK,
998			    (1 << O_INTMASK__MDInt));
999	}
1000}
1001
1002static void
1003nlna_disable_intr(struct nlna_softc *sc)
1004{
1005	int i;
1006
1007	for (i = 0; i < sc->num_ports; i++) {
1008		if (sc->child_sc[i]->instance == 0)
1009			NLGE_WRITE(sc->child_sc[i]->base, R_INTMASK, 0);
1010	}
1011}
1012
1013static int
1014nlna_is_last_active_na(struct nlna_softc *sc)
1015{
1016	int id;
1017
1018	id = device_get_unit(sc->nlna_dev);
1019	return (id == 2 || xlr_board_info.gmac_block[id + 1].enabled == 0);
1020}
1021
1022static void
1023nlna_submit_rx_free_desc(struct nlna_softc *sc, uint32_t n_desc)
1024{
1025	struct msgrng_msg msg;
1026	void           *ptr;
1027	uint32_t	msgrng_flags;
1028	int		i, n, stid, ret, code;
1029
1030	if (n_desc > 1) {
1031		PDEBUG("Sending %d free-in descriptors to station=%d\n", n_desc,
1032		    sc->rfrbucket);
1033	}
1034
1035	stid = sc->rfrbucket;
1036	code = (sc->na_type == XLR_XGMAC) ? MSGRNG_CODE_XGMAC : MSGRNG_CODE_MAC;
1037	memset(&msg, 0, sizeof(msg));
1038
1039	for (i = 0; i < n_desc; i++) {
1040		ptr = get_buf();
1041		if (!ptr) {
1042			ret = -ENOMEM;
1043			device_printf(sc->nlna_dev, "Cannot allocate mbuf\n");
1044			break;
1045		}
1046
1047		/* Send the free Rx desc to the MAC */
1048		msg.msg0 = vtophys(ptr) & 0xffffffffe0ULL;
1049		n = 0;
1050		do {
1051			msgrng_flags = msgrng_access_enable();
1052			ret = message_send(1, code, stid, &msg);
1053			msgrng_restore(msgrng_flags);
1054			KASSERT(n++ < 100000, ("Too many credit fails in rx path\n"));
1055		} while (ret != 0);
1056	}
1057}
1058
1059static __inline__ void *
1060nlna_config_spill(xlr_reg_t *base, int reg_start_0, int reg_start_1,
1061    int reg_size, int size)
1062{
1063	void	*spill;
1064	uint64_t phys_addr;
1065	uint32_t spill_size;
1066
1067	spill_size = size;
1068	spill = contigmalloc((spill_size + XLR_CACHELINE_SIZE), M_DEVBUF,
1069	    M_NOWAIT | M_ZERO, 0, 0xffffffff, XLR_CACHELINE_SIZE, 0);
1070	if (spill == NULL || ((vm_offset_t) spill & (XLR_CACHELINE_SIZE - 1))) {
1071		panic("Unable to allocate memory for spill area!\n");
1072	}
1073	phys_addr = vtophys(spill);
1074	PDEBUG("Allocated spill %d bytes at %llx\n", size, phys_addr);
1075	NLGE_WRITE(base, reg_start_0, (phys_addr >> 5) & 0xffffffff);
1076	NLGE_WRITE(base, reg_start_1, (phys_addr >> 37) & 0x07);
1077	NLGE_WRITE(base, reg_size, spill_size);
1078
1079	return (spill);
1080}
1081
1082/*
1083 * Configure the 6 FIFO's that are used by the network accelarator to
1084 * communicate with the rest of the XLx device. 4 of the FIFO's are for
1085 * packets from NA --> cpu (called Class FIFO's) and 2 are for feeding
1086 * the NA with free descriptors.
1087 */
1088static void
1089nlna_config_fifo_spill_area(struct nlna_softc *sc)
1090{
1091	sc->frin_spill = nlna_config_spill(sc->base,
1092				     	R_REG_FRIN_SPILL_MEM_START_0,
1093				     	R_REG_FRIN_SPILL_MEM_START_1,
1094				     	R_REG_FRIN_SPILL_MEM_SIZE,
1095				     	MAX_FRIN_SPILL *
1096				     	sizeof(struct fr_desc));
1097	sc->frout_spill = nlna_config_spill(sc->base,
1098				     	R_FROUT_SPILL_MEM_START_0,
1099				     	R_FROUT_SPILL_MEM_START_1,
1100				     	R_FROUT_SPILL_MEM_SIZE,
1101				     	MAX_FROUT_SPILL *
1102				     	sizeof(struct fr_desc));
1103	sc->class_0_spill = nlna_config_spill(sc->base,
1104				     	R_CLASS0_SPILL_MEM_START_0,
1105				     	R_CLASS0_SPILL_MEM_START_1,
1106				     	R_CLASS0_SPILL_MEM_SIZE,
1107				     	MAX_CLASS_0_SPILL *
1108				     	sizeof(union rx_tx_desc));
1109	sc->class_1_spill = nlna_config_spill(sc->base,
1110				     	R_CLASS1_SPILL_MEM_START_0,
1111				     	R_CLASS1_SPILL_MEM_START_1,
1112				     	R_CLASS1_SPILL_MEM_SIZE,
1113				     	MAX_CLASS_1_SPILL *
1114				     	sizeof(union rx_tx_desc));
1115	sc->class_2_spill = nlna_config_spill(sc->base,
1116				     	R_CLASS2_SPILL_MEM_START_0,
1117				     	R_CLASS2_SPILL_MEM_START_1,
1118				     	R_CLASS2_SPILL_MEM_SIZE,
1119				     	MAX_CLASS_2_SPILL *
1120				     	sizeof(union rx_tx_desc));
1121	sc->class_3_spill = nlna_config_spill(sc->base,
1122				     	R_CLASS3_SPILL_MEM_START_0,
1123				     	R_CLASS3_SPILL_MEM_START_1,
1124				     	R_CLASS3_SPILL_MEM_SIZE,
1125				     	MAX_CLASS_3_SPILL *
1126				     	sizeof(union rx_tx_desc));
1127}
1128
1129/* Set the CPU buckets that receive packets from the NA class FIFOs. */
1130static void
1131nlna_config_pde(struct nlna_softc *sc)
1132{
1133	uint64_t	bucket_map;
1134	uint32_t	cpumask;
1135	int		i, cpu, bucket;
1136
1137	cpumask = 0x1;
1138#ifdef SMP
1139	/*
1140         * rge may be called before SMP start in a BOOTP/NFSROOT
1141         * setup. we will distribute packets to other cpus only when
1142         * the SMP is started.
1143	 */
1144	if (smp_started)
1145		cpumask = xlr_hw_thread_mask;
1146#endif
1147	bucket_map = 0;
1148	for (i = 0; i < 32; i++) {
1149		if (cpumask & (1 << i)) {
1150			cpu = i;
1151			/* use bucket 0 and 1 on every core for NA msgs */
1152			bucket = cpu/4 * 8;
1153			bucket_map |= (3ULL << bucket);
1154		}
1155	}
1156	NLGE_WRITE(sc->base, R_PDE_CLASS_0, (bucket_map & 0xffffffff));
1157	NLGE_WRITE(sc->base, R_PDE_CLASS_0 + 1, ((bucket_map >> 32) & 0xffffffff));
1158
1159	NLGE_WRITE(sc->base, R_PDE_CLASS_1, (bucket_map & 0xffffffff));
1160	NLGE_WRITE(sc->base, R_PDE_CLASS_1 + 1, ((bucket_map >> 32) & 0xffffffff));
1161
1162	NLGE_WRITE(sc->base, R_PDE_CLASS_2, (bucket_map & 0xffffffff));
1163	NLGE_WRITE(sc->base, R_PDE_CLASS_2 + 1, ((bucket_map >> 32) & 0xffffffff));
1164
1165	NLGE_WRITE(sc->base, R_PDE_CLASS_3, (bucket_map & 0xffffffff));
1166	NLGE_WRITE(sc->base, R_PDE_CLASS_3 + 1, ((bucket_map >> 32) & 0xffffffff));
1167}
1168
1169/*
1170 * Update the network accelerator packet distribution engine for SMP.
1171 * On bootup, we have just the boot hw thread handling all packets, on SMP
1172 * start, we can start distributing packets across all the cores which are up.
1173 */
1174static void
1175nlna_smp_update_pde(void *dummy __unused)
1176{
1177	device_t	   iodi_dev;
1178	struct nlna_softc *na_sc[XLR_MAX_NLNA];
1179	int i;
1180
1181	printf("Updating packet distribution for SMP\n");
1182
1183	iodi_dev = devclass_get_device(devclass_find("iodi"), 0);
1184	nlna_get_all_softc(iodi_dev, na_sc, XLR_MAX_NLNA);
1185
1186	for (i = 0; i < XLR_MAX_NLNA; i++) {
1187		if (na_sc[i] == NULL)
1188			continue;
1189		nlna_disable_ports(na_sc[i]);
1190		nlna_config_pde(na_sc[i]);
1191		nlna_enable_ports(na_sc[i]);
1192	}
1193}
1194
1195SYSINIT(nlna_smp_update_pde, SI_SUB_SMP, SI_ORDER_ANY, nlna_smp_update_pde,
1196    NULL);
1197
1198static void
1199nlna_config_parser(struct nlna_softc *sc)
1200{
1201	/*
1202	 * Mark it as no classification. The parser extract is gauranteed to
1203	 * be zero with no classfication
1204	 */
1205	NLGE_WRITE(sc->base, R_L2TYPE_0, 0x00);
1206	NLGE_WRITE(sc->base, R_L2TYPE_0, 0x01);
1207
1208	/* configure the parser : L2 Type is configured in the bootloader */
1209	/* extract IP: src, dest protocol */
1210	NLGE_WRITE(sc->base, R_L3CTABLE,
1211	    (9 << 20) | (1 << 19) | (1 << 18) | (0x01 << 16) |
1212	    (0x0800 << 0));
1213	NLGE_WRITE(sc->base, R_L3CTABLE + 1,
1214	    (12 << 25) | (4 << 21) | (16 << 14) | (4 << 10));
1215}
1216
1217static void
1218nlna_config_classifier(struct nlna_softc *sc)
1219{
1220	int i;
1221
1222	if (sc->mac_type == XLR_XGMII) {	/* TBD: XGMII init sequence */
1223		/* xgmac translation table doesn't have sane values on reset */
1224		for (i = 0; i < 64; i++)
1225			NLGE_WRITE(sc->base, R_TRANSLATETABLE + i, 0x0);
1226
1227		/*
1228		 * use upper 7 bits of the parser extract to index the
1229		 * translate table
1230		 */
1231		NLGE_WRITE(sc->base, R_PARSERCONFIGREG, 0x0);
1232	}
1233}
1234
1235/*
1236 * Complete a bunch of h/w register initializations that are common for all the
1237 * ports controlled by a NA.
1238 */
1239static void
1240nlna_config_common(struct nlna_softc *sc)
1241{
1242	struct xlr_gmac_block_t *block_info;
1243	struct stn_cc 		*gmac_cc_config;
1244	int			i;
1245
1246	block_info = device_get_ivars(sc->nlna_dev);
1247	gmac_cc_config = block_info->credit_config;
1248	for (i = 0; i < MAX_NUM_MSGRNG_STN_CC; i++) {
1249		NLGE_WRITE(sc->base, R_CC_CPU0_0 + i,
1250		    gmac_cc_config->counters[i >> 3][i & 0x07]);
1251	}
1252
1253	NLGE_WRITE(sc->base, R_MSG_TX_THRESHOLD, 3);
1254
1255	NLGE_WRITE(sc->base, R_DMACR0, 0xffffffff);
1256	NLGE_WRITE(sc->base, R_DMACR1, 0xffffffff);
1257	NLGE_WRITE(sc->base, R_DMACR2, 0xffffffff);
1258	NLGE_WRITE(sc->base, R_DMACR3, 0xffffffff);
1259	NLGE_WRITE(sc->base, R_FREEQCARVE, 0);
1260
1261	nlna_media_specific_config(sc);
1262}
1263
1264static void
1265nlna_media_specific_config(struct nlna_softc *sc)
1266{
1267	struct bucket_size *bucket_sizes;
1268
1269	bucket_sizes = xlr_board_info.bucket_sizes;
1270	switch (sc->mac_type) {
1271	case XLR_RGMII:
1272	case XLR_SGMII:
1273	case XLR_XAUI:
1274		NLGE_WRITE(sc->base, R_GMAC_JFR0_BUCKET_SIZE,
1275		    bucket_sizes->bucket[MSGRNG_STNID_GMACJFR_0]);
1276		NLGE_WRITE(sc->base, R_GMAC_RFR0_BUCKET_SIZE,
1277		    bucket_sizes->bucket[MSGRNG_STNID_GMACRFR_0]);
1278		NLGE_WRITE(sc->base, R_GMAC_JFR1_BUCKET_SIZE,
1279		    bucket_sizes->bucket[MSGRNG_STNID_GMACJFR_1]);
1280		NLGE_WRITE(sc->base, R_GMAC_RFR1_BUCKET_SIZE,
1281		    bucket_sizes->bucket[MSGRNG_STNID_GMACRFR_1]);
1282
1283		if (sc->mac_type == XLR_XAUI) {
1284			NLGE_WRITE(sc->base, R_TXDATAFIFO0, (224 << 16));
1285		}
1286		break;
1287
1288	case XLR_XGMII:
1289		NLGE_WRITE(sc->base, R_XGS_RFR_BUCKET_SIZE,
1290		    bucket_sizes->bucket[sc->rfrbucket]);
1291
1292	default:
1293		break;
1294	}
1295}
1296
1297static void
1298nlna_reset_ports(struct nlna_softc *sc, struct xlr_gmac_block_t *blk)
1299{
1300	xlr_reg_t *addr;
1301	int i;
1302	uint32_t   rx_ctrl;
1303
1304	/* Refer Section 13.9.3 in the PRM for the reset sequence */
1305
1306	for (i = 0; i < sc->num_ports; i++) {
1307		addr = xlr_io_mmio(blk->gmac_port[i].base_addr);
1308
1309		/* 1. Reset RxEnable in MAC_CONFIG */
1310		switch (sc->mac_type) {
1311		case XLR_RGMII:
1312		case XLR_SGMII:
1313			NLGE_UPDATE(addr, R_MAC_CONFIG_1, 0,
1314			    (1 << O_MAC_CONFIG_1__rxen));
1315			break;
1316		case XLR_XAUI:
1317		case XLR_XGMII:
1318			NLGE_UPDATE(addr, R_RX_CONTROL, 0,
1319			   (1 << O_RX_CONTROL__RxEnable));
1320			break;
1321		default:
1322			printf("Error: Unsupported port_type=%d\n",
1323			    sc->mac_type);
1324		}
1325
1326		/* 1.1 Wait for RxControl.RxHalt to be set */
1327		do {
1328			rx_ctrl = NLGE_READ(addr, R_RX_CONTROL);
1329		} while (!(rx_ctrl & 0x2));
1330
1331		/* 2. Set the soft reset bit in RxControl */
1332		NLGE_UPDATE(addr, R_RX_CONTROL, (1 << O_RX_CONTROL__SoftReset),
1333		    (1 << O_RX_CONTROL__SoftReset));
1334
1335		/* 2.1 Wait for RxControl.SoftResetDone to be set */
1336		do {
1337			rx_ctrl = NLGE_READ(addr, R_RX_CONTROL);
1338		} while (!(rx_ctrl & 0x8));
1339
1340		/* 3. Clear the soft reset bit in RxControl */
1341		NLGE_UPDATE(addr, R_RX_CONTROL, 0,
1342		    (1 << O_RX_CONTROL__SoftReset));
1343
1344		/* Turn off tx/rx on the port. */
1345		NLGE_UPDATE(addr, R_RX_CONTROL, 0,
1346		    (1 << O_RX_CONTROL__RxEnable));
1347		NLGE_UPDATE(addr, R_TX_CONTROL, 0,
1348		    (1 << O_TX_CONTROL__TxEnable));
1349	}
1350}
1351
1352static void
1353nlna_disable_ports(struct nlna_softc *sc)
1354{
1355	struct xlr_gmac_block_t *blk;
1356	xlr_reg_t *addr;
1357	int i;
1358
1359	blk = device_get_ivars(sc->nlna_dev);
1360	for (i = 0; i < sc->num_ports; i++) {
1361		addr = xlr_io_mmio(blk->gmac_port[i].base_addr);
1362		nlge_port_disable(i, addr, blk->gmac_port[i].type);
1363	}
1364}
1365
1366static void
1367nlna_enable_ports(struct nlna_softc *sc)
1368{
1369	device_t		nlge_dev, *devlist;
1370	struct nlge_softc 	*port_sc;
1371	int 			i, numdevs;
1372
1373	device_get_children(sc->nlna_dev, &devlist, &numdevs);
1374	for (i = 0; i < numdevs; i++) {
1375		nlge_dev = devlist[i];
1376		if (nlge_dev == NULL)
1377			continue;
1378		port_sc = device_get_softc(nlge_dev);
1379		if (port_sc->nlge_if->if_drv_flags & IFF_DRV_RUNNING)
1380			nlge_port_enable(port_sc);
1381	}
1382	free(devlist, M_TEMP);
1383}
1384
1385static void
1386nlna_get_all_softc(device_t iodi_dev, struct nlna_softc **sc_vec,
1387		   uint32_t vec_sz)
1388{
1389	device_t  na_dev;
1390	int       i;
1391
1392	for (i = 0; i < vec_sz; i++) {
1393		sc_vec[i] = NULL;
1394		na_dev = device_find_child(iodi_dev, "nlna", i);
1395		if (na_dev != NULL)
1396			sc_vec[i] = device_get_softc(na_dev);
1397	}
1398}
1399
1400static void
1401nlge_port_disable(int id, xlr_reg_t *base, int port_type)
1402{
1403	uint32_t rd;
1404
1405	NLGE_UPDATE(base, R_RX_CONTROL, 0x0, 1 << O_RX_CONTROL__RxEnable);
1406	do {
1407		rd = NLGE_READ(base, R_RX_CONTROL);
1408	} while (!(rd & (1 << O_RX_CONTROL__RxHalt)));
1409
1410	NLGE_UPDATE(base, R_TX_CONTROL, 0, 1 << O_TX_CONTROL__TxEnable);
1411	do {
1412		rd = NLGE_READ(base, R_TX_CONTROL);
1413	} while (!(rd & (1 << O_TX_CONTROL__TxIdle)));
1414
1415	switch (port_type) {
1416	case XLR_RGMII:
1417	case XLR_SGMII:
1418		NLGE_UPDATE(base, R_MAC_CONFIG_1, 0,
1419		   ((1 << O_MAC_CONFIG_1__rxen) |
1420		   (1 << O_MAC_CONFIG_1__txen)));
1421		break;
1422	case XLR_XGMII:
1423	case XLR_XAUI:
1424		NLGE_UPDATE(base, R_XGMAC_CONFIG_1, 0,
1425		   ((1 << O_XGMAC_CONFIG_1__hsttfen) |
1426		   (1 << O_XGMAC_CONFIG_1__hstrfen)));
1427		break;
1428	default:
1429		panic("Unknown MAC type on port %d\n", id);
1430	}
1431}
1432
1433static void
1434nlge_port_enable(struct nlge_softc *sc)
1435{
1436	struct xlr_gmac_port  *self;
1437	xlr_reg_t *base;
1438
1439	base = sc->base;
1440	self = device_get_ivars(sc->nlge_dev);
1441	if (xlr_board_info.is_xls && sc->port_type == XLR_RGMII)
1442		NLGE_UPDATE(base, R_RX_CONTROL, (1 << O_RX_CONTROL__RGMII),
1443	    	    (1 << O_RX_CONTROL__RGMII));
1444
1445	NLGE_UPDATE(base, R_RX_CONTROL, (1 << O_RX_CONTROL__RxEnable),
1446	    (1 << O_RX_CONTROL__RxEnable));
1447	NLGE_UPDATE(base, R_TX_CONTROL,
1448	    (1 << O_TX_CONTROL__TxEnable | RGE_TX_THRESHOLD_BYTES),
1449	    (1 << O_TX_CONTROL__TxEnable | 0x3fff));
1450	switch (sc->port_type) {
1451	case XLR_RGMII:
1452	case XLR_SGMII:
1453		NLGE_UPDATE(base, R_MAC_CONFIG_1,
1454		    ((1 << O_MAC_CONFIG_1__rxen) | (1 << O_MAC_CONFIG_1__txen)),
1455		    ((1 << O_MAC_CONFIG_1__rxen) | (1 << O_MAC_CONFIG_1__txen)));
1456		break;
1457	case XLR_XGMII:
1458	case XLR_XAUI:
1459		NLGE_UPDATE(base, R_XGMAC_CONFIG_1,
1460		    ((1 << O_XGMAC_CONFIG_1__hsttfen) | (1 << O_XGMAC_CONFIG_1__hstrfen)),
1461		    ((1 << O_XGMAC_CONFIG_1__hsttfen) | (1 << O_XGMAC_CONFIG_1__hstrfen)));
1462		break;
1463	default:
1464		panic("Unknown MAC type on port %d\n", sc->id);
1465	}
1466}
1467
1468static void
1469nlge_sgmii_init(struct nlge_softc *sc)
1470{
1471	xlr_reg_t *mmio_gpio;
1472	int phy;
1473
1474	if (sc->port_type != XLR_SGMII)
1475		return;
1476
1477	nlge_mii_write_internal(sc->serdes_addr, 26, 0, 0x6DB0);
1478	nlge_mii_write_internal(sc->serdes_addr, 26, 1, 0xFFFF);
1479	nlge_mii_write_internal(sc->serdes_addr, 26, 2, 0xB6D0);
1480	nlge_mii_write_internal(sc->serdes_addr, 26, 3, 0x00FF);
1481	nlge_mii_write_internal(sc->serdes_addr, 26, 4, 0x0000);
1482	nlge_mii_write_internal(sc->serdes_addr, 26, 5, 0x0000);
1483	nlge_mii_write_internal(sc->serdes_addr, 26, 6, 0x0005);
1484	nlge_mii_write_internal(sc->serdes_addr, 26, 7, 0x0001);
1485	nlge_mii_write_internal(sc->serdes_addr, 26, 8, 0x0000);
1486	nlge_mii_write_internal(sc->serdes_addr, 26, 9, 0x0000);
1487	nlge_mii_write_internal(sc->serdes_addr, 26,10, 0x0000);
1488
1489	/* program  GPIO values for serdes init parameters */
1490	DELAY(100);
1491	mmio_gpio = xlr_io_mmio(XLR_IO_GPIO_OFFSET);
1492	xlr_write_reg(mmio_gpio, 0x20, 0x7e6802);
1493	xlr_write_reg(mmio_gpio, 0x10, 0x7104);
1494	DELAY(100);
1495
1496	/*
1497	 * This kludge is needed to setup serdes (?) clock correctly on some
1498	 * XLS boards
1499	 */
1500	if ((xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_XI ||
1501	    xlr_boot1_info.board_major_version == RMI_XLR_BOARD_ARIZONA_XII) &&
1502	    xlr_boot1_info.board_minor_version == 4) {
1503		/* use 125 Mhz instead of 156.25Mhz ref clock */
1504		DELAY(100);
1505		xlr_write_reg(mmio_gpio, 0x10, 0x7103);
1506		xlr_write_reg(mmio_gpio, 0x21, 0x7103);
1507		DELAY(100);
1508	}
1509
1510	/* enable autoneg - more magic */
1511	phy = sc->phy_addr % 4 + 27;
1512	nlge_mii_write_internal(sc->pcs_addr, phy, 0, 0x1000);
1513	DELAY(100000);
1514	nlge_mii_write_internal(sc->pcs_addr, phy, 0, 0x0200);
1515	DELAY(100000);
1516}
1517
1518static void
1519nlge_intr(void *arg)
1520{
1521	struct nlge_port_set    *pset;
1522	struct nlge_softc 	*sc;
1523	struct nlge_softc 	*port_sc;
1524	xlr_reg_t 		*base;
1525	uint32_t		intreg;
1526	uint32_t		intr_status;
1527	int 			i;
1528
1529	sc = arg;
1530	if (sc == NULL) {
1531		printf("warning: No port registered for interrupt\n");
1532		return;
1533	}
1534	base = sc->base;
1535
1536	intreg = NLGE_READ(base, R_INTREG);
1537	if (intreg & (1 << O_INTREG__MDInt)) {
1538		pset = sc->mdio_pset;
1539		if (pset == NULL) {
1540			printf("warning: No ports for MDIO interrupt\n");
1541			return;
1542		}
1543		for (i = 0; i < pset->vec_sz; i++) {
1544			port_sc = pset->port_vec[i];
1545
1546			if (port_sc == NULL)
1547				continue;
1548
1549			/* Ack phy interrupt - clear on read*/
1550			intr_status = nlge_mii_read_internal(port_sc->mii_base,
1551			    port_sc->phy_addr, 26);
1552			PDEBUG("Phy_%d: int_status=0x%08x\n", port_sc->phy_addr,
1553			    intr_status);
1554
1555			if (!(intr_status & 0x8000)) {
1556				/* no interrupt for this port */
1557				continue;
1558			}
1559
1560			if (intr_status & 0x2410) {
1561				/* update link status for port */
1562				nlge_gmac_config_speed(port_sc, 0);
1563			} else {
1564				printf("%s: Unsupported phy interrupt"
1565				    " (0x%08x)\n",
1566				    device_get_nameunit(port_sc->nlge_dev),
1567				    intr_status);
1568			}
1569		}
1570	}
1571
1572	/* Clear the NA interrupt */
1573	xlr_write_reg(base, R_INTREG, 0xffffffff);
1574
1575	return;
1576}
1577
1578static int
1579nlge_irq_init(struct nlge_softc *sc)
1580{
1581	struct resource		irq_res;
1582	struct nlna_softc  	*na_sc;
1583	struct xlr_gmac_block_t *block_info;
1584	device_t		na_dev;
1585	int			ret;
1586	int			irq_num;
1587
1588	na_dev = device_get_parent(sc->nlge_dev);
1589	block_info = device_get_ivars(na_dev);
1590
1591	irq_num = block_info->baseirq + sc->instance;
1592	irq_res.__r_i = (struct resource_i *)(intptr_t) (irq_num);
1593	ret = bus_setup_intr(sc->nlge_dev, &irq_res, (INTR_FAST |
1594	    INTR_TYPE_NET | INTR_MPSAFE), NULL, nlge_intr, sc, NULL);
1595	if (ret) {
1596		nlge_detach(sc->nlge_dev);
1597		device_printf(sc->nlge_dev, "couldn't set up irq: error=%d\n",
1598		    ret);
1599		return (ENXIO);
1600	}
1601	PDEBUG("Setup intr for dev=%s, irq=%d\n",
1602	    device_get_nameunit(sc->nlge_dev), irq_num);
1603
1604	if (sc->instance == 0) {
1605		na_sc = device_get_softc(na_dev);
1606		sc->mdio_pset = &na_sc->mdio_set;
1607	}
1608	return (0);
1609}
1610
1611static void
1612nlge_irq_fini(struct nlge_softc *sc)
1613{
1614}
1615
1616static void
1617nlge_hw_init(struct nlge_softc *sc)
1618{
1619	struct xlr_gmac_port  *port_info;
1620	xlr_reg_t *base;
1621
1622	base = sc->base;
1623	port_info = device_get_ivars(sc->nlge_dev);
1624	sc->tx_bucket_id = port_info->tx_bucket_id;
1625
1626	/* each packet buffer is 1536 bytes */
1627	NLGE_WRITE(base, R_DESC_PACK_CTRL,
1628		  (1 << O_DESC_PACK_CTRL__MaxEntry) |
1629		  (MAX_FRAME_SIZE << O_DESC_PACK_CTRL__RegularSize));
1630	NLGE_WRITE(base, R_STATCTRL, ((1 << O_STATCTRL__Sten) |
1631	    (1 << O_STATCTRL__ClrCnt)));
1632	NLGE_WRITE(base, R_L2ALLOCCTRL, 0xffffffff);
1633	NLGE_WRITE(base, R_INTMASK, 0);
1634	nlge_set_mac_addr(sc);
1635	nlge_media_specific_init(sc);
1636}
1637
1638static void
1639nlge_sc_init(struct nlge_softc *sc, device_t dev,
1640    struct xlr_gmac_port *port_info)
1641{
1642	memset(sc, 0, sizeof(*sc));
1643	sc->nlge_dev = dev;
1644	sc->id = device_get_unit(dev);
1645	nlge_set_port_attribs(sc, port_info);
1646}
1647
1648static void
1649nlge_media_specific_init(struct nlge_softc *sc)
1650{
1651	struct mii_data *media;
1652	struct bucket_size *bucket_sizes;
1653
1654	bucket_sizes = xlr_board_info.bucket_sizes;
1655	switch (sc->port_type) {
1656	case XLR_RGMII:
1657	case XLR_SGMII:
1658	case XLR_XAUI:
1659		NLGE_UPDATE(sc->base, R_DESC_PACK_CTRL,
1660		    (BYTE_OFFSET << O_DESC_PACK_CTRL__ByteOffset),
1661		    (W_DESC_PACK_CTRL__ByteOffset <<
1662		        O_DESC_PACK_CTRL__ByteOffset));
1663		NLGE_WRITE(sc->base, R_GMAC_TX0_BUCKET_SIZE + sc->instance,
1664		    bucket_sizes->bucket[sc->tx_bucket_id]);
1665		if (sc->port_type != XLR_XAUI) {
1666			nlge_gmac_config_speed(sc, 1);
1667			if (sc->mii_bus) {
1668				media = (struct mii_data *)device_get_softc(
1669				    sc->mii_bus);
1670			}
1671		}
1672		break;
1673
1674	case XLR_XGMII:
1675		NLGE_WRITE(sc->base, R_BYTEOFFSET0, 0x2);
1676		NLGE_WRITE(sc->base, R_XGMACPADCALIBRATION, 0x30);
1677		NLGE_WRITE(sc->base, R_XGS_TX0_BUCKET_SIZE,
1678		    bucket_sizes->bucket[sc->tx_bucket_id]);
1679		break;
1680	default:
1681		break;
1682	}
1683}
1684
1685/*
1686 * Read the MAC address from the XLR boot registers. All port addresses
1687 * are identical except for the lowest octet.
1688 */
1689static void
1690nlge_read_mac_addr(struct nlge_softc *sc)
1691{
1692	int i, j;
1693
1694	for (i = 0, j = 40; i < ETHER_ADDR_LEN && j >= 0; i++, j-= 8)
1695		sc->dev_addr[i] = (xlr_boot1_info.mac_addr >> j) & 0xff;
1696
1697	sc->dev_addr[i - 1] +=  sc->id;	/* last octet is port-specific */
1698}
1699
1700/*
1701 * Write the MAC address to the XLR MAC port. Also, set the address
1702 * masks and MAC filter configuration.
1703 */
1704static void
1705nlge_set_mac_addr(struct nlge_softc *sc)
1706{
1707	NLGE_WRITE(sc->base, R_MAC_ADDR0,
1708		  ((sc->dev_addr[5] << 24) | (sc->dev_addr[4] << 16) |
1709		   (sc->dev_addr[3] << 8) | (sc->dev_addr[2])));
1710	NLGE_WRITE(sc->base, R_MAC_ADDR0 + 1,
1711		  ((sc->dev_addr[1] << 24) | (sc-> dev_addr[0] << 16)));
1712
1713	NLGE_WRITE(sc->base, R_MAC_ADDR_MASK2, 0xffffffff);
1714	NLGE_WRITE(sc->base, R_MAC_ADDR_MASK2 + 1, 0xffffffff);
1715	NLGE_WRITE(sc->base, R_MAC_ADDR_MASK3, 0xffffffff);
1716	NLGE_WRITE(sc->base, R_MAC_ADDR_MASK3 + 1, 0xffffffff);
1717
1718	NLGE_WRITE(sc->base, R_MAC_FILTER_CONFIG,
1719		  (1 << O_MAC_FILTER_CONFIG__BROADCAST_EN) |
1720		  (1 << O_MAC_FILTER_CONFIG__ALL_MCAST_EN) |
1721		  (1 << O_MAC_FILTER_CONFIG__MAC_ADDR0_VALID));
1722
1723	if (sc->port_type == XLR_RGMII || sc->port_type == XLR_SGMII) {
1724		NLGE_UPDATE(sc->base, R_IPG_IFG, MAC_B2B_IPG, 0x7f);
1725	}
1726}
1727
1728static int
1729nlge_if_init(struct nlge_softc *sc)
1730{
1731	struct ifnet 	*ifp;
1732	device_t	dev;
1733	int error;
1734
1735	error = 0;
1736	dev = sc->nlge_dev;
1737	NLGE_LOCK_INIT(sc, device_get_nameunit(dev));
1738
1739	ifp = sc->nlge_if = if_alloc(IFT_ETHER);
1740	if (ifp == NULL) {
1741		device_printf(dev, "can not if_alloc()\n");
1742		error = ENOSPC;
1743		goto fail;
1744	}
1745	ifp->if_softc = sc;
1746	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
1747	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1748	ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_VLAN_HWTAGGING;
1749	ifp->if_capenable = ifp->if_capabilities;
1750	ifp->if_ioctl = nlge_ioctl;
1751	ifp->if_start = nlge_start;
1752	ifp->if_init = nlge_init;
1753	ifp->if_hwassist = 0;
1754	ifp->if_snd.ifq_drv_maxlen = RGE_TX_Q_SIZE;
1755	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
1756	IFQ_SET_READY(&ifp->if_snd);
1757
1758	ifmedia_init(&sc->nlge_mii.mii_media, 0, nlge_mediachange,
1759	    nlge_mediastatus);
1760	ifmedia_add(&sc->nlge_mii.mii_media, IFM_ETHER | IFM_AUTO, 0, NULL);
1761	ifmedia_set(&sc->nlge_mii.mii_media, IFM_ETHER | IFM_AUTO);
1762	sc->nlge_mii.mii_media.ifm_media = sc->nlge_mii.mii_media.ifm_cur->ifm_media;
1763	nlge_read_mac_addr(sc);
1764
1765	ether_ifattach(ifp, sc->dev_addr);
1766
1767fail:
1768	return (error);
1769}
1770
1771static void
1772nlge_mii_init(device_t dev, struct nlge_softc *sc)
1773{
1774	int error;
1775
1776	if (sc->port_type != XLR_XAUI && sc->port_type != XLR_XGMII) {
1777		NLGE_WRITE(sc->mii_base, R_MII_MGMT_CONFIG, 0x07);
1778	}
1779	error = mii_phy_probe(dev, &sc->mii_bus, nlge_mediachange, nlge_mediastatus);
1780	if (error) {
1781		device_printf(dev, "no PHY device found\n");
1782		sc->mii_bus = NULL;
1783	}
1784	if (sc->mii_bus != NULL) {
1785		/*
1786		 * Enable all MDIO interrupts in the phy. RX_ER bit seems to get
1787		 * set about every 1 sec in GigE mode, ignore it for now...
1788		 */
1789		nlge_mii_write_internal(sc->mii_base, sc->phy_addr, 25,
1790		    0xfffffffe);
1791	}
1792}
1793
1794/*
1795 *  Read a PHY register.
1796 *
1797 *  Input parameters:
1798 *  	   mii_base - Base address of MII
1799 *  	   phyaddr - PHY's address
1800 *  	   regidx = index of register to read
1801 *
1802 *  Return value:
1803 *  	   value read, or 0 if an error occurred.
1804 */
1805
1806static int
1807nlge_mii_read_internal(xlr_reg_t *mii_base, int phyaddr, int regidx)
1808{
1809	int i, val;
1810
1811	/* setup the phy reg to be used */
1812	NLGE_WRITE(mii_base, R_MII_MGMT_ADDRESS,
1813	    (phyaddr << 8) | (regidx << 0));
1814	/* Issue the read command */
1815	NLGE_WRITE(mii_base, R_MII_MGMT_COMMAND,
1816	    (1 << O_MII_MGMT_COMMAND__rstat));
1817
1818	/* poll for the read cycle to complete */
1819	for (i = 0; i < PHY_STATUS_RETRIES; i++) {
1820		if (NLGE_READ(mii_base, R_MII_MGMT_INDICATORS) == 0)
1821			break;
1822	}
1823
1824	/* clear the read cycle */
1825	NLGE_WRITE(mii_base, R_MII_MGMT_COMMAND, 0);
1826
1827	if (i == PHY_STATUS_RETRIES) {
1828		return (0xffffffff);
1829	}
1830
1831	val = NLGE_READ(mii_base, R_MII_MGMT_STATUS);
1832
1833	return (val);
1834}
1835
1836/*
1837 *  Write a value to a PHY register.
1838 *
1839 *  Input parameters:
1840 *  	   mii_base - Base address of MII
1841 *  	   phyaddr - PHY to use
1842 *  	   regidx - register within the PHY
1843 *  	   regval - data to write to register
1844 *
1845 *  Return value:
1846 *  	   nothing
1847 */
1848static void
1849nlge_mii_write_internal(xlr_reg_t *mii_base, int phyaddr, int regidx,
1850    int regval)
1851{
1852	int i;
1853
1854	NLGE_WRITE(mii_base, R_MII_MGMT_ADDRESS,
1855	   (phyaddr << 8) | (regidx << 0));
1856
1857	/* Write the data which starts the write cycle */
1858	NLGE_WRITE(mii_base, R_MII_MGMT_WRITE_DATA, regval);
1859
1860	/* poll for the write cycle to complete */
1861	for (i = 0; i < PHY_STATUS_RETRIES; i++) {
1862		if (NLGE_READ(mii_base, R_MII_MGMT_INDICATORS) == 0)
1863			break;
1864	}
1865}
1866
1867/*
1868 * Function to optimize the use of p2d descriptors for the given PDU.
1869 * As it is on the fast-path (called during packet transmission), it
1870 * described in more detail than the initialization functions.
1871 *
1872 * Input: mbuf chain (MC), pointer to fmn message
1873 * Input constraints: None
1874 * Output: FMN message to transmit the data in MC
1875 * Return values: 0 - success
1876 *                1 - MC cannot be handled (see Limitations below)
1877 *                2 - MC cannot be handled presently (maybe worth re-trying)
1878 * Other output: Number of entries filled in the FMN message
1879 *
1880 * Output structure/constraints:
1881 *     1. Max 3 p2d's + 1 zero-len (ZL) p2d with virtual address of MC.
1882 *     2. 3 p2d's + 1 p2p with max 14 p2d's (ZL p2d not required in this case).
1883 *     3. Each p2d points to physically contiguous chunk of data (subject to
1884 *        entire MC requiring max 17 p2d's).
1885 * Limitations:
1886 *     1. MC's that require more than 17 p2d's are not handled.
1887 * Benefits: MC's that require <= 3 p2d's avoid the overhead of allocating
1888 *           the p2p structure. Small packets (which typically give low
1889 *           performance) are expected to have a small MC that takes
1890 *           advantage of this.
1891 */
1892static int
1893prepare_fmn_message(struct nlge_softc *sc, struct msgrng_msg *fmn_msg,
1894    uint32_t *n_entries, struct mbuf *mbuf_chain, uint64_t fb_stn_id,
1895    struct nlge_tx_desc **tx_desc)
1896{
1897	struct mbuf     *m;
1898	struct nlge_tx_desc *p2p;
1899	uint64_t        *cur_p2d;
1900	uint64_t        fbpaddr;
1901	vm_offset_t	buf;
1902	vm_paddr_t      paddr;
1903	int             msg_sz, p2p_sz, len, frag_sz;
1904	/* Num entries per FMN msg is 4 for XLR/XLS */
1905	const int       FMN_SZ = sizeof(*fmn_msg) / sizeof(uint64_t);
1906
1907	msg_sz = p2p_sz = 0;
1908	p2p = NULL;
1909	cur_p2d = &fmn_msg->msg0;
1910
1911	for (m = mbuf_chain; m != NULL; m = m->m_next) {
1912		buf = (vm_offset_t) m->m_data;
1913		len = m->m_len;
1914
1915		while (len) {
1916			if (msg_sz == (FMN_SZ - 1)) {
1917				p2p = uma_zalloc(nl_tx_desc_zone, M_NOWAIT);
1918				if (p2p == NULL) {
1919					return (2);
1920				}
1921				/*
1922				 * Save the virtual address in the descriptor,
1923				 * it makes freeing easy.
1924				 */
1925				p2p->frag[XLR_MAX_TX_FRAGS] =
1926				    (uint64_t)(vm_offset_t)p2p;
1927				cur_p2d = &p2p->frag[0];
1928			} else if (msg_sz == (FMN_SZ - 2 + XLR_MAX_TX_FRAGS)) {
1929				uma_zfree(nl_tx_desc_zone, p2p);
1930				return (1);
1931			}
1932			paddr = vtophys(buf);
1933			frag_sz = PAGE_SIZE - (buf & PAGE_MASK);
1934			if (len < frag_sz)
1935				frag_sz = len;
1936			*cur_p2d++ = (127ULL << 54) | ((uint64_t)frag_sz << 40)
1937			    | paddr;
1938			msg_sz++;
1939			if (p2p != NULL)
1940				p2p_sz++;
1941			len -= frag_sz;
1942			buf += frag_sz;
1943		}
1944	}
1945
1946	if (msg_sz ==  0) {
1947		printf("Zero-length mbuf chain ??\n");
1948		*n_entries = msg_sz ;
1949		return (0);
1950	}
1951
1952	/* set eop in most-recent p2d */
1953	cur_p2d[-1] |= (1ULL << 63);
1954
1955#ifdef __mips_n64
1956	/*
1957	 * On n64, we cannot store our mbuf pointer(64 bit) in the freeback
1958	 * message (40bit available), so we put the mbuf in m_nextpkt and
1959	 * use the physical addr of that in freeback message.
1960	 */
1961	mbuf_chain->m_nextpkt = mbuf_chain;
1962	fbpaddr = vtophys(&mbuf_chain->m_nextpkt);
1963#else
1964	/* Careful, don't sign extend when going to 64bit */
1965	fbpaddr = (uint64_t)(uintptr_t)mbuf_chain;
1966#endif
1967	*cur_p2d = (1ULL << 63) | ((uint64_t)fb_stn_id << 54) | fbpaddr;
1968	*tx_desc = p2p;
1969
1970	if (p2p != NULL) {
1971		paddr = vtophys(p2p);
1972		p2p_sz++;
1973		fmn_msg->msg3 = (1ULL << 62) | ((uint64_t)fb_stn_id << 54) |
1974		    ((uint64_t)(p2p_sz * 8) << 40) | paddr;
1975		*n_entries = FMN_SZ;
1976	} else {
1977		*n_entries = msg_sz + 1;
1978	}
1979
1980	return (0);
1981}
1982
1983static int
1984send_fmn_msg_tx(struct nlge_softc *sc, struct msgrng_msg *msg,
1985    uint32_t n_entries)
1986{
1987	uint32_t msgrng_flags;
1988	int ret;
1989	int i = 0;
1990
1991	do {
1992		msgrng_flags = msgrng_access_enable();
1993		ret = message_send(n_entries, MSGRNG_CODE_MAC,
1994		    sc->tx_bucket_id, msg);
1995		msgrng_restore(msgrng_flags);
1996		if (ret == 0)
1997			return (0);
1998		i++;
1999	} while (i < 100000);
2000
2001	device_printf(sc->nlge_dev, "Too many credit fails in tx path\n");
2002
2003	return (1);
2004}
2005
2006static void
2007release_tx_desc(vm_paddr_t paddr)
2008{
2009	struct nlge_tx_desc *tx_desc;
2010	uint32_t 	sr;
2011	uint64_t	vaddr;
2012
2013	paddr += (XLR_MAX_TX_FRAGS * sizeof(uint64_t));
2014	sr = xlr_enable_kx();
2015	vaddr = xlr_paddr_ld(paddr);
2016	xlr_restore_kx(sr);
2017
2018	tx_desc = (struct nlge_tx_desc*)(intptr_t)vaddr;
2019	uma_zfree(nl_tx_desc_zone, tx_desc);
2020}
2021
2022static void *
2023get_buf(void)
2024{
2025	struct mbuf	*m_new;
2026	uint64_t 	*md;
2027#ifdef INVARIANTS
2028	vm_paddr_t	temp1, temp2;
2029#endif
2030
2031	if ((m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR)) == NULL)
2032		return (NULL);
2033	m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
2034	m_adj(m_new, XLR_CACHELINE_SIZE - ((uintptr_t)m_new->m_data & 0x1f));
2035	md = (uint64_t *)m_new->m_data;
2036	md[0] = (intptr_t)m_new;	/* Back Ptr */
2037	md[1] = 0xf00bad;
2038	m_adj(m_new, XLR_CACHELINE_SIZE);
2039
2040#ifdef INVARIANTS
2041	temp1 = vtophys((vm_offset_t) m_new->m_data);
2042	temp2 = vtophys((vm_offset_t) m_new->m_data + 1536);
2043	if ((temp1 + 1536) != temp2)
2044		panic("ALLOCED BUFFER IS NOT CONTIGUOUS\n");
2045#endif
2046
2047	return ((void *)m_new->m_data);
2048}
2049
2050static int
2051nlge_gmac_config_speed(struct nlge_softc *sc, int quick)
2052{
2053	struct mii_data *md;
2054	xlr_reg_t  *mmio;
2055	int bmsr, n_tries, max_tries;
2056	int core_ctl[]    = { 0x2, 0x1, 0x0, 0x1 };
2057	int sgmii_speed[] = { SGMII_SPEED_10,
2058			      SGMII_SPEED_100,
2059			      SGMII_SPEED_1000,
2060			      SGMII_SPEED_100 };    /* default to 100Mbps */
2061	char *speed_str[] = { "10",
2062			      "100",
2063			      "1000",
2064			      "unknown, defaulting to 100" };
2065	int link_state = LINK_STATE_DOWN;
2066
2067	if (sc->port_type == XLR_XAUI || sc->port_type == XLR_XGMII)
2068		return 0;
2069
2070	md = NULL;
2071	mmio = sc->base;
2072	if (sc->mii_base != NULL) {
2073		max_tries = (quick == 1) ? 100 : 4000;
2074		bmsr = 0;
2075		for (n_tries = 0; n_tries < max_tries; n_tries++) {
2076			bmsr = nlge_mii_read_internal(sc->mii_base,
2077			    sc->phy_addr, MII_BMSR);
2078			if ((bmsr & BMSR_ACOMP) && (bmsr & BMSR_LINK))
2079				break; /* Auto-negotiation is complete
2080					  and link is up */
2081			DELAY(1000);
2082		}
2083		bmsr &= BMSR_LINK;
2084		sc->link = (bmsr == 0) ? xlr_mac_link_down : xlr_mac_link_up;
2085		sc->speed = nlge_mii_read_internal(sc->mii_base, sc->phy_addr, 28);
2086		sc->speed = (sc->speed >> 3) & 0x03;
2087		if (sc->link == xlr_mac_link_up) {
2088			link_state = LINK_STATE_UP;
2089			nlge_sgmii_init(sc);
2090		}
2091		if (sc->mii_bus)
2092			md = (struct mii_data *)device_get_softc(sc->mii_bus);
2093	}
2094
2095	if (sc->port_type != XLR_RGMII)
2096		NLGE_WRITE(mmio, R_INTERFACE_CONTROL, sgmii_speed[sc->speed]);
2097	if (sc->speed == xlr_mac_speed_10 || sc->speed == xlr_mac_speed_100 ||
2098	    sc->speed == xlr_mac_speed_rsvd) {
2099		NLGE_WRITE(mmio, R_MAC_CONFIG_2, 0x7117);
2100	} else if (sc->speed == xlr_mac_speed_1000) {
2101		NLGE_WRITE(mmio, R_MAC_CONFIG_2, 0x7217);
2102		if (md != NULL) {
2103			ifmedia_set(&md->mii_media, IFM_MAKEWORD(IFM_ETHER,
2104			    IFM_1000_T, IFM_FDX, md->mii_instance));
2105		}
2106	}
2107	NLGE_WRITE(mmio, R_CORECONTROL, core_ctl[sc->speed]);
2108	if_link_state_change(sc->nlge_if, link_state);
2109	printf("%s: [%sMbps]\n", device_get_nameunit(sc->nlge_dev),
2110	    speed_str[sc->speed]);
2111
2112	return (0);
2113}
2114
2115/*
2116 * This function is called for each port that was added to the device tree
2117 * and it initializes the following port attributes:
2118 * 	- type
2119 *      - base (base address to access port-specific registers)
2120 *      - mii_base
2121 * 	- phy_addr
2122 */
2123static void
2124nlge_set_port_attribs(struct nlge_softc *sc,
2125    struct xlr_gmac_port *port_info)
2126{
2127	sc->instance = port_info->instance % 4;	/* TBD: will not work for SPI-4 */
2128	sc->port_type = port_info->type;
2129	sc->base = xlr_io_mmio(port_info->base_addr);
2130	sc->mii_base = xlr_io_mmio(port_info->mii_addr);
2131	if (port_info->pcs_addr != 0)
2132		sc->pcs_addr = xlr_io_mmio(port_info->pcs_addr);
2133	if (port_info->serdes_addr != 0)
2134		sc->serdes_addr = xlr_io_mmio(port_info->serdes_addr);
2135	sc->phy_addr = port_info->phy_addr;
2136
2137	PDEBUG("Port%d: base=%p, mii_base=%p, phy_addr=%d\n", sc->id, sc->base,
2138	    sc->mii_base, sc->phy_addr);
2139}
2140
2141/* ------------------------------------------------------------------------ */
2142
2143/* Debug dump functions */
2144
2145#ifdef DEBUG
2146
2147static void
2148dump_reg(xlr_reg_t *base, uint32_t offset, char *name)
2149{
2150	int val;
2151
2152	val = NLGE_READ(base, offset);
2153	printf("%-30s: 0x%8x 0x%8x\n", name, offset, val);
2154}
2155
2156#define STRINGIFY(x) 		#x
2157
2158static void
2159dump_na_registers(xlr_reg_t *base_addr, int port_id)
2160{
2161	PDEBUG("Register dump for NA (of port=%d)\n", port_id);
2162	dump_reg(base_addr, R_PARSERCONFIGREG, STRINGIFY(R_PARSERCONFIGREG));
2163	PDEBUG("Tx bucket sizes\n");
2164	dump_reg(base_addr, R_GMAC_JFR0_BUCKET_SIZE,
2165	    STRINGIFY(R_GMAC_JFR0_BUCKET_SIZE));
2166	dump_reg(base_addr, R_GMAC_RFR0_BUCKET_SIZE,
2167	    STRINGIFY(R_GMAC_RFR0_BUCKET_SIZE));
2168	dump_reg(base_addr, R_GMAC_TX0_BUCKET_SIZE,
2169	    STRINGIFY(R_GMAC_TX0_BUCKET_SIZE));
2170	dump_reg(base_addr, R_GMAC_TX1_BUCKET_SIZE,
2171	    STRINGIFY(R_GMAC_TX1_BUCKET_SIZE));
2172	dump_reg(base_addr, R_GMAC_TX2_BUCKET_SIZE,
2173	    STRINGIFY(R_GMAC_TX2_BUCKET_SIZE));
2174	dump_reg(base_addr, R_GMAC_TX3_BUCKET_SIZE,
2175	    STRINGIFY(R_GMAC_TX3_BUCKET_SIZE));
2176	dump_reg(base_addr, R_GMAC_JFR1_BUCKET_SIZE,
2177	    STRINGIFY(R_GMAC_JFR1_BUCKET_SIZE));
2178	dump_reg(base_addr, R_GMAC_RFR1_BUCKET_SIZE,
2179	    STRINGIFY(R_GMAC_RFR1_BUCKET_SIZE));
2180	dump_reg(base_addr, R_TXDATAFIFO0, STRINGIFY(R_TXDATAFIFO0));
2181	dump_reg(base_addr, R_TXDATAFIFO1, STRINGIFY(R_TXDATAFIFO1));
2182}
2183
2184static void
2185dump_gmac_registers(struct nlge_softc *sc)
2186{
2187	xlr_reg_t *base_addr = sc->base;
2188	int port_id = sc->instance;
2189
2190	PDEBUG("Register dump for port=%d\n", port_id);
2191	if (sc->port_type == XLR_RGMII || sc->port_type == XLR_SGMII) {
2192		dump_reg(base_addr, R_MAC_CONFIG_1, STRINGIFY(R_MAC_CONFIG_1));
2193		dump_reg(base_addr, R_MAC_CONFIG_2, STRINGIFY(R_MAC_CONFIG_2));
2194		dump_reg(base_addr, R_IPG_IFG, STRINGIFY(R_IPG_IFG));
2195		dump_reg(base_addr, R_HALF_DUPLEX, STRINGIFY(R_HALF_DUPLEX));
2196		dump_reg(base_addr, R_MAXIMUM_FRAME_LENGTH,
2197		    STRINGIFY(R_MAXIMUM_FRAME_LENGTH));
2198		dump_reg(base_addr, R_TEST, STRINGIFY(R_TEST));
2199		dump_reg(base_addr, R_MII_MGMT_CONFIG,
2200		    STRINGIFY(R_MII_MGMT_CONFIG));
2201		dump_reg(base_addr, R_MII_MGMT_COMMAND,
2202		    STRINGIFY(R_MII_MGMT_COMMAND));
2203		dump_reg(base_addr, R_MII_MGMT_ADDRESS,
2204		    STRINGIFY(R_MII_MGMT_ADDRESS));
2205		dump_reg(base_addr, R_MII_MGMT_WRITE_DATA,
2206		    STRINGIFY(R_MII_MGMT_WRITE_DATA));
2207		dump_reg(base_addr, R_MII_MGMT_STATUS,
2208		    STRINGIFY(R_MII_MGMT_STATUS));
2209		dump_reg(base_addr, R_MII_MGMT_INDICATORS,
2210		    STRINGIFY(R_MII_MGMT_INDICATORS));
2211		dump_reg(base_addr, R_INTERFACE_CONTROL,
2212		    STRINGIFY(R_INTERFACE_CONTROL));
2213		dump_reg(base_addr, R_INTERFACE_STATUS,
2214		    STRINGIFY(R_INTERFACE_STATUS));
2215	} else if (sc->port_type == XLR_XAUI || sc->port_type == XLR_XGMII) {
2216		dump_reg(base_addr, R_XGMAC_CONFIG_0,
2217		    STRINGIFY(R_XGMAC_CONFIG_0));
2218		dump_reg(base_addr, R_XGMAC_CONFIG_1,
2219		    STRINGIFY(R_XGMAC_CONFIG_1));
2220		dump_reg(base_addr, R_XGMAC_CONFIG_2,
2221		    STRINGIFY(R_XGMAC_CONFIG_2));
2222		dump_reg(base_addr, R_XGMAC_CONFIG_3,
2223		    STRINGIFY(R_XGMAC_CONFIG_3));
2224		dump_reg(base_addr, R_XGMAC_STATION_ADDRESS_LS,
2225		    STRINGIFY(R_XGMAC_STATION_ADDRESS_LS));
2226		dump_reg(base_addr, R_XGMAC_STATION_ADDRESS_MS,
2227		    STRINGIFY(R_XGMAC_STATION_ADDRESS_MS));
2228		dump_reg(base_addr, R_XGMAC_MAX_FRAME_LEN,
2229		    STRINGIFY(R_XGMAC_MAX_FRAME_LEN));
2230		dump_reg(base_addr, R_XGMAC_REV_LEVEL,
2231		    STRINGIFY(R_XGMAC_REV_LEVEL));
2232		dump_reg(base_addr, R_XGMAC_MIIM_COMMAND,
2233		    STRINGIFY(R_XGMAC_MIIM_COMMAND));
2234		dump_reg(base_addr, R_XGMAC_MIIM_FILED,
2235		    STRINGIFY(R_XGMAC_MIIM_FILED));
2236		dump_reg(base_addr, R_XGMAC_MIIM_CONFIG,
2237		    STRINGIFY(R_XGMAC_MIIM_CONFIG));
2238		dump_reg(base_addr, R_XGMAC_MIIM_LINK_FAIL_VECTOR,
2239		    STRINGIFY(R_XGMAC_MIIM_LINK_FAIL_VECTOR));
2240		dump_reg(base_addr, R_XGMAC_MIIM_INDICATOR,
2241		    STRINGIFY(R_XGMAC_MIIM_INDICATOR));
2242	}
2243
2244	dump_reg(base_addr, R_MAC_ADDR0, STRINGIFY(R_MAC_ADDR0));
2245	dump_reg(base_addr, R_MAC_ADDR0 + 1, STRINGIFY(R_MAC_ADDR0+1));
2246	dump_reg(base_addr, R_MAC_ADDR1, STRINGIFY(R_MAC_ADDR1));
2247	dump_reg(base_addr, R_MAC_ADDR2, STRINGIFY(R_MAC_ADDR2));
2248	dump_reg(base_addr, R_MAC_ADDR3, STRINGIFY(R_MAC_ADDR3));
2249	dump_reg(base_addr, R_MAC_ADDR_MASK2, STRINGIFY(R_MAC_ADDR_MASK2));
2250	dump_reg(base_addr, R_MAC_ADDR_MASK3, STRINGIFY(R_MAC_ADDR_MASK3));
2251	dump_reg(base_addr, R_MAC_FILTER_CONFIG, STRINGIFY(R_MAC_FILTER_CONFIG));
2252	dump_reg(base_addr, R_TX_CONTROL, STRINGIFY(R_TX_CONTROL));
2253	dump_reg(base_addr, R_RX_CONTROL, STRINGIFY(R_RX_CONTROL));
2254	dump_reg(base_addr, R_DESC_PACK_CTRL, STRINGIFY(R_DESC_PACK_CTRL));
2255	dump_reg(base_addr, R_STATCTRL, STRINGIFY(R_STATCTRL));
2256	dump_reg(base_addr, R_L2ALLOCCTRL, STRINGIFY(R_L2ALLOCCTRL));
2257	dump_reg(base_addr, R_INTMASK, STRINGIFY(R_INTMASK));
2258	dump_reg(base_addr, R_INTREG, STRINGIFY(R_INTREG));
2259	dump_reg(base_addr, R_TXRETRY, STRINGIFY(R_TXRETRY));
2260	dump_reg(base_addr, R_CORECONTROL, STRINGIFY(R_CORECONTROL));
2261	dump_reg(base_addr, R_BYTEOFFSET0, STRINGIFY(R_BYTEOFFSET0));
2262	dump_reg(base_addr, R_BYTEOFFSET1, STRINGIFY(R_BYTEOFFSET1));
2263	dump_reg(base_addr, R_L2TYPE_0, STRINGIFY(R_L2TYPE_0));
2264	dump_na_registers(base_addr, port_id);
2265}
2266
2267static void
2268dump_fmn_cpu_credits_for_gmac(struct xlr_board_info *board, int gmac_id)
2269{
2270	struct stn_cc *cc;
2271	int gmac_bucket_ids[] = { 97, 98, 99, 100, 101, 103 };
2272	int j, k, r, c;
2273	int n_gmac_buckets;
2274
2275	n_gmac_buckets = sizeof (gmac_bucket_ids) / sizeof (gmac_bucket_ids[0]);
2276	for (j = 0; j < 8; j++) { 		// for each cpu
2277		cc = board->credit_configs[j];
2278		printf("Credits for Station CPU_%d ---> GMAC buckets (tx path)\n", j);
2279		for (k = 0; k < n_gmac_buckets; k++) {
2280			r = gmac_bucket_ids[k] / 8;
2281			c = gmac_bucket_ids[k] % 8;
2282			printf ("    --> gmac%d_bucket_%-3d: credits=%d\n", gmac_id,
2283				gmac_bucket_ids[k], cc->counters[r][c]);
2284		}
2285	}
2286}
2287
2288static void
2289dump_fmn_gmac_credits(struct xlr_board_info *board, int gmac_id)
2290{
2291	struct stn_cc *cc;
2292	int j, k;
2293
2294	cc = board->gmac_block[gmac_id].credit_config;
2295	printf("Credits for Station: GMAC_%d ---> CPU buckets (rx path)\n", gmac_id);
2296	for (j = 0; j < 8; j++) { 		// for each cpu
2297		printf("    ---> cpu_%d\n", j);
2298		for (k = 0; k < 8; k++) {	// for each bucket in cpu
2299			printf("        ---> bucket_%d: credits=%d\n", j * 8 + k,
2300			       cc->counters[j][k]);
2301		}
2302	}
2303}
2304
2305static void
2306dump_board_info(struct xlr_board_info *board)
2307{
2308	struct xlr_gmac_block_t *gm;
2309	int i, k;
2310
2311	printf("cpu=%x ", xlr_revision());
2312	printf("board_version: major=%llx, minor=%llx\n",
2313	    xlr_boot1_info.board_major_version,
2314	    xlr_boot1_info.board_minor_version);
2315	printf("is_xls=%d, nr_cpus=%d, usb=%s, cfi=%s, ata=%s\npci_irq=%d,"
2316	    "gmac_ports=%d\n", board->is_xls, board->nr_cpus,
2317	    board->usb ? "Yes" : "No", board->cfi ? "Yes": "No",
2318	    board->ata ? "Yes" : "No", board->pci_irq, board->gmacports);
2319	printf("FMN: Core-station bucket sizes\n");
2320	for (i = 0; i < 128; i++) {
2321		if (i && ((i % 16) == 0))
2322			printf("\n");
2323		printf ("b[%d] = %d ", i, board->bucket_sizes->bucket[i]);
2324	}
2325	printf("\n");
2326	for (i = 0; i < 3; i++) {
2327		gm = &board->gmac_block[i];
2328		printf("RNA_%d: type=%d, enabled=%s, mode=%d, station_id=%d,"
2329		    "station_txbase=%d, station_rfr=%d ", i, gm->type,
2330		    gm->enabled ? "Yes" : "No", gm->mode, gm->station_id,
2331		    gm->station_txbase, gm->station_rfr);
2332		printf("n_ports=%d, baseaddr=%p, baseirq=%d, baseinst=%d\n",
2333		     gm->num_ports, (xlr_reg_t *)gm->baseaddr, gm->baseirq,
2334		     gm->baseinst);
2335	}
2336	for (k = 0; k < 3; k++) { 	// for each NA
2337		dump_fmn_cpu_credits_for_gmac(board, k);
2338		dump_fmn_gmac_credits(board, k);
2339	}
2340}
2341
2342static void
2343dump_mac_stats(struct nlge_softc *sc)
2344{
2345	xlr_reg_t *addr;
2346	uint32_t pkts_tx, pkts_rx;
2347
2348	addr = sc->base;
2349	pkts_rx = NLGE_READ(sc->base, R_RPKT);
2350	pkts_tx = NLGE_READ(sc->base, R_TPKT);
2351
2352	printf("[nlge_%d mac stats]: pkts_tx=%u, pkts_rx=%u\n", sc->id, pkts_tx,
2353	    pkts_rx);
2354	if (pkts_rx > 0) {
2355		uint32_t r;
2356
2357		/* dump all rx counters. we need this because pkts_rx includes
2358		   bad packets. */
2359		for (r = R_RFCS; r <= R_ROVR; r++)
2360			printf("[nlge_%d mac stats]: [0x%x]=%u\n", sc->id, r,
2361			    NLGE_READ(sc->base, r));
2362	}
2363	if (pkts_tx > 0) {
2364		uint32_t r;
2365
2366		/* dump all tx counters. might be useful for debugging. */
2367		for (r = R_TMCA; r <= R_TFRG; r++) {
2368			if ((r == (R_TNCL + 1)) || (r == (R_TNCL + 2)))
2369				continue;
2370			printf("[nlge_%d mac stats]: [0x%x]=%u\n", sc->id, r,
2371			    NLGE_READ(sc->base, r));
2372		}
2373	}
2374
2375}
2376
2377static void
2378dump_mii_regs(struct nlge_softc *sc)
2379{
2380	uint32_t mii_regs[] = {  0x0,  0x1,  0x2,  0x3,  0x4,  0x5,  0x6,  0x7,
2381	                         0x8,  0x9,  0xa,  0xf, 0x10, 0x11, 0x12, 0x13,
2382				0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
2383				0x1c, 0x1d, 0x1e};
2384	int i, n_regs;
2385
2386	if (sc->mii_base == NULL || sc->mii_bus == NULL)
2387		return;
2388
2389	n_regs = sizeof (mii_regs) / sizeof (mii_regs[0]);
2390	for (i = 0; i < n_regs; i++) {
2391		printf("[mii_0x%x] = %x\n", mii_regs[i],
2392		    nlge_mii_read_internal(sc->mii_base, sc->phy_addr,
2393		        mii_regs[i]));
2394	}
2395}
2396
2397static void
2398dump_ifmedia(struct ifmedia *ifm)
2399{
2400	printf("ifm_mask=%08x, ifm_media=%08x, cur=%p\n", ifm->ifm_mask,
2401	    ifm->ifm_media, ifm->ifm_cur);
2402	if (ifm->ifm_cur != NULL) {
2403		printf("Cur attribs: ifmedia_entry.ifm_media=%08x,"
2404		    " ifmedia_entry.ifm_data=%08x\n", ifm->ifm_cur->ifm_media,
2405		    ifm->ifm_cur->ifm_data);
2406	}
2407}
2408
2409static void
2410dump_mii_data(struct mii_data *mii)
2411{
2412	dump_ifmedia(&mii->mii_media);
2413	printf("ifp=%p, mii_instance=%d, mii_media_status=%08x,"
2414	    " mii_media_active=%08x\n", mii->mii_ifp, mii->mii_instance,
2415	    mii->mii_media_status, mii->mii_media_active);
2416}
2417
2418static void
2419dump_pcs_regs(struct nlge_softc *sc, int phy)
2420{
2421	int i, val;
2422
2423	printf("PCS regs from %p for phy=%d\n", sc->pcs_addr, phy);
2424	for (i = 0; i < 18; i++) {
2425		if (i == 2 || i == 3 || (i >= 9 && i <= 14))
2426			continue;
2427		val = nlge_mii_read_internal(sc->pcs_addr, phy, i);
2428		printf("PHY:%d pcs[0x%x] is 0x%x\n", phy, i, val);
2429	}
2430}
2431#endif
2432