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