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