Merge branch 'vendor/GDB'
[dragonfly.git] / sys / dev / netif / bce / if_bce.c
1 /*-
2  * Copyright (c) 2006-2007 Broadcom Corporation
3  *      David Christensen <davidch@broadcom.com>.  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  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of Broadcom Corporation nor the name of its contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written consent.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * $FreeBSD: src/sys/dev/bce/if_bce.c,v 1.31 2007/05/16 23:34:11 davidch Exp $
31  */
32
33 /*
34  * The following controllers are supported by this driver:
35  *   BCM5706C A2, A3
36  *   BCM5708C B1, B2
37  *
38  * The following controllers are not supported by this driver:
39  *   BCM5706C A0, A1
40  *   BCM5706S A0, A1, A2, A3
41  *   BCM5708C A0, B0
42  *   BCM5708S A0, B0, B1, B2
43  */
44
45 #include "opt_bce.h"
46 #include "opt_polling.h"
47
48 #include <sys/param.h>
49 #include <sys/bus.h>
50 #include <sys/endian.h>
51 #include <sys/kernel.h>
52 #include <sys/interrupt.h>
53 #include <sys/mbuf.h>
54 #include <sys/malloc.h>
55 #include <sys/queue.h>
56 #ifdef BCE_DEBUG
57 #include <sys/random.h>
58 #endif
59 #include <sys/rman.h>
60 #include <sys/serialize.h>
61 #include <sys/socket.h>
62 #include <sys/sockio.h>
63 #include <sys/sysctl.h>
64
65 #include <net/bpf.h>
66 #include <net/ethernet.h>
67 #include <net/if.h>
68 #include <net/if_arp.h>
69 #include <net/if_dl.h>
70 #include <net/if_media.h>
71 #include <net/if_types.h>
72 #include <net/ifq_var.h>
73 #include <net/vlan/if_vlan_var.h>
74 #include <net/vlan/if_vlan_ether.h>
75
76 #include <dev/netif/mii_layer/mii.h>
77 #include <dev/netif/mii_layer/miivar.h>
78
79 #include <bus/pci/pcireg.h>
80 #include <bus/pci/pcivar.h>
81
82 #include "miibus_if.h"
83
84 #include <dev/netif/bce/if_bcereg.h>
85 #include <dev/netif/bce/if_bcefw.h>
86
87 /****************************************************************************/
88 /* BCE Debug Options                                                        */
89 /****************************************************************************/
90 #ifdef BCE_DEBUG
91
92 static uint32_t bce_debug = BCE_WARN;
93
94 /*
95  *          0 = Never             
96  *          1 = 1 in 2,147,483,648
97  *        256 = 1 in     8,388,608
98  *       2048 = 1 in     1,048,576
99  *      65536 = 1 in        32,768
100  *    1048576 = 1 in         2,048
101  *  268435456 = 1 in             8
102  *  536870912 = 1 in             4
103  * 1073741824 = 1 in             2
104  *
105  * bce_debug_l2fhdr_status_check:
106  *     How often the l2_fhdr frame error check will fail.
107  *
108  * bce_debug_unexpected_attention:
109  *     How often the unexpected attention check will fail.
110  *
111  * bce_debug_mbuf_allocation_failure:
112  *     How often to simulate an mbuf allocation failure.
113  *
114  * bce_debug_dma_map_addr_failure:
115  *     How often to simulate a DMA mapping failure.
116  *
117  * bce_debug_bootcode_running_failure:
118  *     How often to simulate a bootcode failure.
119  */
120 static int      bce_debug_l2fhdr_status_check = 0;
121 static int      bce_debug_unexpected_attention = 0;
122 static int      bce_debug_mbuf_allocation_failure = 0;
123 static int      bce_debug_dma_map_addr_failure = 0;
124 static int      bce_debug_bootcode_running_failure = 0;
125
126 #endif  /* BCE_DEBUG */
127
128
129 /****************************************************************************/
130 /* PCI Device ID Table                                                      */
131 /*                                                                          */
132 /* Used by bce_probe() to identify the devices supported by this driver.    */
133 /****************************************************************************/
134 #define BCE_DEVDESC_MAX         64
135
136 static struct bce_type bce_devs[] = {
137         /* BCM5706C Controllers and OEM boards. */
138         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3101,
139                 "HP NC370T Multifunction Gigabit Server Adapter" },
140         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3106,
141                 "HP NC370i Multifunction Gigabit Server Adapter" },
142         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  PCI_ANY_ID,  PCI_ANY_ID,
143                 "Broadcom NetXtreme II BCM5706 1000Base-T" },
144
145         /* BCM5706S controllers and OEM boards. */
146         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, HP_VENDORID, 0x3102,
147                 "HP NC370F Multifunction Gigabit Server Adapter" },
148         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, PCI_ANY_ID,  PCI_ANY_ID,
149                 "Broadcom NetXtreme II BCM5706 1000Base-SX" },
150
151         /* BCM5708C controllers and OEM boards. */
152         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  PCI_ANY_ID,  PCI_ANY_ID,
153                 "Broadcom NetXtreme II BCM5708 1000Base-T" },
154
155         /* BCM5708S controllers and OEM boards. */
156         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  PCI_ANY_ID,  PCI_ANY_ID,
157                 "Broadcom NetXtreme II BCM5708S 1000Base-T" },
158         { 0, 0, 0, 0, NULL }
159 };
160
161
162 /****************************************************************************/
163 /* Supported Flash NVRAM device data.                                       */
164 /****************************************************************************/
165 static const struct flash_spec flash_table[] =
166 {
167         /* Slow EEPROM */
168         {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
169          1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
170          SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
171          "EEPROM - slow"},
172         /* Expansion entry 0001 */
173         {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
174          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
175          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
176          "Entry 0001"},
177         /* Saifun SA25F010 (non-buffered flash) */
178         /* strap, cfg1, & write1 need updates */
179         {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
180          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
181          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
182          "Non-buffered flash (128kB)"},
183         /* Saifun SA25F020 (non-buffered flash) */
184         /* strap, cfg1, & write1 need updates */
185         {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
186          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
187          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
188          "Non-buffered flash (256kB)"},
189         /* Expansion entry 0100 */
190         {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
191          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
192          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
193          "Entry 0100"},
194         /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
195         {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
196          0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
197          ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
198          "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
199         /* Entry 0110: ST M45PE20 (non-buffered flash)*/
200         {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
201          0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
202          ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
203          "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
204         /* Saifun SA25F005 (non-buffered flash) */
205         /* strap, cfg1, & write1 need updates */
206         {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
207          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
208          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
209          "Non-buffered flash (64kB)"},
210         /* Fast EEPROM */
211         {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
212          1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
213          SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
214          "EEPROM - fast"},
215         /* Expansion entry 1001 */
216         {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
217          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
218          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
219          "Entry 1001"},
220         /* Expansion entry 1010 */
221         {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
222          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
223          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
224          "Entry 1010"},
225         /* ATMEL AT45DB011B (buffered flash) */
226         {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
227          1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
228          BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
229          "Buffered flash (128kB)"},
230         /* Expansion entry 1100 */
231         {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
232          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
233          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
234          "Entry 1100"},
235         /* Expansion entry 1101 */
236         {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
237          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
238          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
239          "Entry 1101"},
240         /* Ateml Expansion entry 1110 */
241         {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
242          1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
243          BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
244          "Entry 1110 (Atmel)"},
245         /* ATMEL AT45DB021B (buffered flash) */
246         {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
247          1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
248          BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
249          "Buffered flash (256kB)"},
250 };
251
252
253 /****************************************************************************/
254 /* DragonFly device entry points.                                           */
255 /****************************************************************************/
256 static int      bce_probe(device_t);
257 static int      bce_attach(device_t);
258 static int      bce_detach(device_t);
259 static void     bce_shutdown(device_t);
260
261 /****************************************************************************/
262 /* BCE Debug Data Structure Dump Routines                                   */
263 /****************************************************************************/
264 #ifdef BCE_DEBUG
265 static void     bce_dump_mbuf(struct bce_softc *, struct mbuf *);
266 static void     bce_dump_tx_mbuf_chain(struct bce_softc *, int, int);
267 static void     bce_dump_rx_mbuf_chain(struct bce_softc *, int, int);
268 static void     bce_dump_txbd(struct bce_softc *, int, struct tx_bd *);
269 static void     bce_dump_rxbd(struct bce_softc *, int, struct rx_bd *);
270 static void     bce_dump_l2fhdr(struct bce_softc *, int,
271                                 struct l2_fhdr *) __unused;
272 static void     bce_dump_tx_chain(struct bce_softc *, int, int);
273 static void     bce_dump_rx_chain(struct bce_softc *, int, int);
274 static void     bce_dump_status_block(struct bce_softc *);
275 static void     bce_dump_driver_state(struct bce_softc *);
276 static void     bce_dump_stats_block(struct bce_softc *) __unused;
277 static void     bce_dump_hw_state(struct bce_softc *);
278 static void     bce_dump_txp_state(struct bce_softc *);
279 static void     bce_dump_rxp_state(struct bce_softc *) __unused;
280 static void     bce_dump_tpat_state(struct bce_softc *) __unused;
281 static void     bce_freeze_controller(struct bce_softc *) __unused;
282 static void     bce_unfreeze_controller(struct bce_softc *) __unused;
283 static void     bce_breakpoint(struct bce_softc *);
284 #endif  /* BCE_DEBUG */
285
286
287 /****************************************************************************/
288 /* BCE Register/Memory Access Routines                                      */
289 /****************************************************************************/
290 static uint32_t bce_reg_rd_ind(struct bce_softc *, uint32_t);
291 static void     bce_reg_wr_ind(struct bce_softc *, uint32_t, uint32_t);
292 static void     bce_ctx_wr(struct bce_softc *, uint32_t, uint32_t, uint32_t);
293 static int      bce_miibus_read_reg(device_t, int, int);
294 static int      bce_miibus_write_reg(device_t, int, int, int);
295 static void     bce_miibus_statchg(device_t);
296
297
298 /****************************************************************************/
299 /* BCE NVRAM Access Routines                                                */
300 /****************************************************************************/
301 static int      bce_acquire_nvram_lock(struct bce_softc *);
302 static int      bce_release_nvram_lock(struct bce_softc *);
303 static void     bce_enable_nvram_access(struct bce_softc *);
304 static void     bce_disable_nvram_access(struct bce_softc *);
305 static int      bce_nvram_read_dword(struct bce_softc *, uint32_t, uint8_t *,
306                                      uint32_t);
307 static int      bce_init_nvram(struct bce_softc *);
308 static int      bce_nvram_read(struct bce_softc *, uint32_t, uint8_t *, int);
309 static int      bce_nvram_test(struct bce_softc *);
310 #ifdef BCE_NVRAM_WRITE_SUPPORT
311 static int      bce_enable_nvram_write(struct bce_softc *);
312 static void     bce_disable_nvram_write(struct bce_softc *);
313 static int      bce_nvram_erase_page(struct bce_softc *, uint32_t);
314 static int      bce_nvram_write_dword(struct bce_softc *, uint32_t, uint8_t *,
315                                       uint32_t);
316 static int      bce_nvram_write(struct bce_softc *, uint32_t, uint8_t *,
317                                 int) __unused;
318 #endif
319
320 /****************************************************************************/
321 /* BCE DMA Allocate/Free Routines                                           */
322 /****************************************************************************/
323 static int      bce_dma_alloc(struct bce_softc *);
324 static void     bce_dma_free(struct bce_softc *);
325 static void     bce_dma_map_addr(void *, bus_dma_segment_t *, int, int);
326
327 /****************************************************************************/
328 /* BCE Firmware Synchronization and Load                                    */
329 /****************************************************************************/
330 static int      bce_fw_sync(struct bce_softc *, uint32_t);
331 static void     bce_load_rv2p_fw(struct bce_softc *, uint32_t *,
332                                  uint32_t, uint32_t);
333 static void     bce_load_cpu_fw(struct bce_softc *, struct cpu_reg *,
334                                 struct fw_info *);
335 static void     bce_init_cpus(struct bce_softc *);
336
337 static void     bce_stop(struct bce_softc *);
338 static int      bce_reset(struct bce_softc *, uint32_t);
339 static int      bce_chipinit(struct bce_softc *);
340 static int      bce_blockinit(struct bce_softc *);
341 static int      bce_newbuf_std(struct bce_softc *, uint16_t *, uint16_t *,
342                                uint32_t *, int);
343 static void     bce_setup_rxdesc_std(struct bce_softc *, uint16_t, uint32_t *);
344
345 static int      bce_init_tx_chain(struct bce_softc *);
346 static int      bce_init_rx_chain(struct bce_softc *);
347 static void     bce_free_rx_chain(struct bce_softc *);
348 static void     bce_free_tx_chain(struct bce_softc *);
349
350 static int      bce_encap(struct bce_softc *, struct mbuf **);
351 static void     bce_start(struct ifnet *);
352 static int      bce_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *);
353 static void     bce_watchdog(struct ifnet *);
354 static int      bce_ifmedia_upd(struct ifnet *);
355 static void     bce_ifmedia_sts(struct ifnet *, struct ifmediareq *);
356 static void     bce_init(void *);
357 static void     bce_mgmt_init(struct bce_softc *);
358
359 static void     bce_init_ctx(struct bce_softc *);
360 static void     bce_get_mac_addr(struct bce_softc *);
361 static void     bce_set_mac_addr(struct bce_softc *);
362 static void     bce_phy_intr(struct bce_softc *);
363 static void     bce_rx_intr(struct bce_softc *, int);
364 static void     bce_tx_intr(struct bce_softc *);
365 static void     bce_disable_intr(struct bce_softc *);
366 static void     bce_enable_intr(struct bce_softc *);
367
368 #ifdef DEVICE_POLLING
369 static void     bce_poll(struct ifnet *, enum poll_cmd, int);
370 #endif
371 static void     bce_intr(void *);
372 static void     bce_set_rx_mode(struct bce_softc *);
373 static void     bce_stats_update(struct bce_softc *);
374 static void     bce_tick(void *);
375 static void     bce_tick_serialized(struct bce_softc *);
376 static void     bce_add_sysctls(struct bce_softc *);
377
378 static void     bce_coal_change(struct bce_softc *);
379 static int      bce_sysctl_tx_bds_int(SYSCTL_HANDLER_ARGS);
380 static int      bce_sysctl_tx_bds(SYSCTL_HANDLER_ARGS);
381 static int      bce_sysctl_tx_ticks_int(SYSCTL_HANDLER_ARGS);
382 static int      bce_sysctl_tx_ticks(SYSCTL_HANDLER_ARGS);
383 static int      bce_sysctl_rx_bds_int(SYSCTL_HANDLER_ARGS);
384 static int      bce_sysctl_rx_bds(SYSCTL_HANDLER_ARGS);
385 static int      bce_sysctl_rx_ticks_int(SYSCTL_HANDLER_ARGS);
386 static int      bce_sysctl_rx_ticks(SYSCTL_HANDLER_ARGS);
387 static int      bce_sysctl_coal_change(SYSCTL_HANDLER_ARGS,
388                                        uint32_t *, uint32_t);
389
390 /*
391  * NOTE:
392  * Don't set bce_tx_ticks_int/bce_tx_ticks to 1023.  Linux's bnx2
393  * takes 1023 as the TX ticks limit.  However, using 1023 will
394  * cause 5708(B2) to generate extra interrupts (~2000/s) even when
395  * there is _no_ network activity on the NIC.
396  */
397 static uint32_t bce_tx_bds_int = 255;           /* bcm: 20 */
398 static uint32_t bce_tx_bds = 255;               /* bcm: 20 */
399 static uint32_t bce_tx_ticks_int = 1022;        /* bcm: 80 */
400 static uint32_t bce_tx_ticks = 1022;            /* bcm: 80 */
401 static uint32_t bce_rx_bds_int = 128;           /* bcm: 6 */
402 static uint32_t bce_rx_bds = 128;               /* bcm: 6 */
403 static uint32_t bce_rx_ticks_int = 125;         /* bcm: 18 */
404 static uint32_t bce_rx_ticks = 125;             /* bcm: 18 */
405
406 TUNABLE_INT("hw.bce.tx_bds_int", &bce_tx_bds_int);
407 TUNABLE_INT("hw.bce.tx_bds", &bce_tx_bds);
408 TUNABLE_INT("hw.bce.tx_ticks_int", &bce_tx_ticks_int);
409 TUNABLE_INT("hw.bce.tx_ticks", &bce_tx_ticks);
410 TUNABLE_INT("hw.bce.rx_bds_int", &bce_rx_bds_int);
411 TUNABLE_INT("hw.bce.rx_bds", &bce_rx_bds);
412 TUNABLE_INT("hw.bce.rx_ticks_int", &bce_rx_ticks_int);
413 TUNABLE_INT("hw.bce.rx_ticks", &bce_rx_ticks);
414
415 /****************************************************************************/
416 /* DragonFly device dispatch table.                                         */
417 /****************************************************************************/
418 static device_method_t bce_methods[] = {
419         /* Device interface */
420         DEVMETHOD(device_probe,         bce_probe),
421         DEVMETHOD(device_attach,        bce_attach),
422         DEVMETHOD(device_detach,        bce_detach),
423         DEVMETHOD(device_shutdown,      bce_shutdown),
424
425         /* bus interface */
426         DEVMETHOD(bus_print_child,      bus_generic_print_child),
427         DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
428
429         /* MII interface */
430         DEVMETHOD(miibus_readreg,       bce_miibus_read_reg),
431         DEVMETHOD(miibus_writereg,      bce_miibus_write_reg),
432         DEVMETHOD(miibus_statchg,       bce_miibus_statchg),
433
434         { 0, 0 }
435 };
436
437 static driver_t bce_driver = {
438         "bce",
439         bce_methods,
440         sizeof(struct bce_softc)
441 };
442
443 static devclass_t bce_devclass;
444
445
446 DECLARE_DUMMY_MODULE(if_xl);
447 MODULE_DEPEND(bce, miibus, 1, 1, 1);
448 DRIVER_MODULE(if_bce, pci, bce_driver, bce_devclass, 0, 0);
449 DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, 0, 0);
450
451
452 /****************************************************************************/
453 /* Device probe function.                                                   */
454 /*                                                                          */
455 /* Compares the device to the driver's list of supported devices and        */
456 /* reports back to the OS whether this is the right driver for the device.  */
457 /*                                                                          */
458 /* Returns:                                                                 */
459 /*   BUS_PROBE_DEFAULT on success, positive value on failure.               */
460 /****************************************************************************/
461 static int
462 bce_probe(device_t dev)
463 {
464         struct bce_type *t;
465         uint16_t vid, did, svid, sdid;
466
467         /* Get the data for the device to be probed. */
468         vid  = pci_get_vendor(dev);
469         did  = pci_get_device(dev);
470         svid = pci_get_subvendor(dev);
471         sdid = pci_get_subdevice(dev);
472
473         /* Look through the list of known devices for a match. */
474         for (t = bce_devs; t->bce_name != NULL; ++t) {
475                 if (vid == t->bce_vid && did == t->bce_did && 
476                     (svid == t->bce_svid || t->bce_svid == PCI_ANY_ID) &&
477                     (sdid == t->bce_sdid || t->bce_sdid == PCI_ANY_ID)) {
478                         uint32_t revid = pci_read_config(dev, PCIR_REVID, 4);
479                         char *descbuf;
480
481                         descbuf = kmalloc(BCE_DEVDESC_MAX, M_TEMP, M_WAITOK);
482
483                         /* Print out the device identity. */
484                         ksnprintf(descbuf, BCE_DEVDESC_MAX, "%s (%c%d)",
485                                   t->bce_name,
486                                   ((revid & 0xf0) >> 4) + 'A', revid & 0xf);
487
488                         device_set_desc_copy(dev, descbuf);
489                         kfree(descbuf, M_TEMP);
490                         return 0;
491                 }
492         }
493         return ENXIO;
494 }
495
496
497 /****************************************************************************/
498 /* Device attach function.                                                  */
499 /*                                                                          */
500 /* Allocates device resources, performs secondary chip identification,      */
501 /* resets and initializes the hardware, and initializes driver instance     */
502 /* variables.                                                               */
503 /*                                                                          */
504 /* Returns:                                                                 */
505 /*   0 on success, positive value on failure.                               */
506 /****************************************************************************/
507 static int
508 bce_attach(device_t dev)
509 {
510         struct bce_softc *sc = device_get_softc(dev);
511         struct ifnet *ifp = &sc->arpcom.ac_if;
512         uint32_t val;
513         int rid, rc = 0;
514 #ifdef notyet
515         int count;
516 #endif
517
518         sc->bce_dev = dev;
519         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
520
521         pci_enable_busmaster(dev);
522
523         /* Allocate PCI memory resources. */
524         rid = PCIR_BAR(0);
525         sc->bce_res_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
526                                                  RF_ACTIVE | PCI_RF_DENSE);
527         if (sc->bce_res_mem == NULL) {
528                 device_printf(dev, "PCI memory allocation failed\n");
529                 return ENXIO;
530         }
531         sc->bce_btag = rman_get_bustag(sc->bce_res_mem);
532         sc->bce_bhandle = rman_get_bushandle(sc->bce_res_mem);
533
534         /* Allocate PCI IRQ resources. */
535 #ifdef notyet
536         count = pci_msi_count(dev);
537         if (count == 1 && pci_alloc_msi(dev, &count) == 0) {
538                 rid = 1;
539                 sc->bce_flags |= BCE_USING_MSI_FLAG;
540         } else
541 #endif
542         rid = 0;
543         sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
544                                                  RF_SHAREABLE | RF_ACTIVE);
545         if (sc->bce_res_irq == NULL) {
546                 device_printf(dev, "PCI map interrupt failed\n");
547                 rc = ENXIO;
548                 goto fail;
549         }
550
551         /*
552          * Configure byte swap and enable indirect register access.
553          * Rely on CPU to do target byte swapping on big endian systems.
554          * Access to registers outside of PCI configurtion space are not
555          * valid until this is done.
556          */
557         pci_write_config(dev, BCE_PCICFG_MISC_CONFIG,
558                          BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
559                          BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4);
560
561         /* Save ASIC revsion info. */
562         sc->bce_chipid =  REG_RD(sc, BCE_MISC_ID);
563
564         /* Weed out any non-production controller revisions. */
565         switch(BCE_CHIP_ID(sc)) {
566         case BCE_CHIP_ID_5706_A0:
567         case BCE_CHIP_ID_5706_A1:
568         case BCE_CHIP_ID_5708_A0:
569         case BCE_CHIP_ID_5708_B0:
570                 device_printf(dev, "Unsupported chip id 0x%08x!\n",
571                               BCE_CHIP_ID(sc));
572                 rc = ENODEV;
573                 goto fail;
574         }
575
576         /* 
577          * The embedded PCIe to PCI-X bridge (EPB) 
578          * in the 5708 cannot address memory above 
579          * 40 bits (E7_5708CB1_23043 & E6_5708SB1_23043). 
580          */
581         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708)
582                 sc->max_bus_addr = BCE_BUS_SPACE_MAXADDR;
583         else
584                 sc->max_bus_addr = BUS_SPACE_MAXADDR;
585
586         /*
587          * Find the base address for shared memory access.
588          * Newer versions of bootcode use a signature and offset
589          * while older versions use a fixed address.
590          */
591         val = REG_RD_IND(sc, BCE_SHM_HDR_SIGNATURE);
592         if ((val & BCE_SHM_HDR_SIGNATURE_SIG_MASK) == BCE_SHM_HDR_SIGNATURE_SIG)
593                 sc->bce_shmem_base = REG_RD_IND(sc, BCE_SHM_HDR_ADDR_0);
594         else
595                 sc->bce_shmem_base = HOST_VIEW_SHMEM_BASE;
596
597         DBPRINT(sc, BCE_INFO, "bce_shmem_base = 0x%08X\n", sc->bce_shmem_base);
598
599         /* Get PCI bus information (speed and type). */
600         val = REG_RD(sc, BCE_PCICFG_MISC_STATUS);
601         if (val & BCE_PCICFG_MISC_STATUS_PCIX_DET) {
602                 uint32_t clkreg;
603
604                 sc->bce_flags |= BCE_PCIX_FLAG;
605
606                 clkreg = REG_RD(sc, BCE_PCICFG_PCI_CLOCK_CONTROL_BITS) &
607                          BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
608                 switch (clkreg) {
609                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
610                         sc->bus_speed_mhz = 133;
611                         break;
612
613                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
614                         sc->bus_speed_mhz = 100;
615                         break;
616
617                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
618                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
619                         sc->bus_speed_mhz = 66;
620                         break;
621
622                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
623                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
624                         sc->bus_speed_mhz = 50;
625                         break;
626
627                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
628                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
629                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
630                         sc->bus_speed_mhz = 33;
631                         break;
632                 }
633         } else {
634                 if (val & BCE_PCICFG_MISC_STATUS_M66EN)
635                         sc->bus_speed_mhz = 66;
636                 else
637                         sc->bus_speed_mhz = 33;
638         }
639
640         if (val & BCE_PCICFG_MISC_STATUS_32BIT_DET)
641                 sc->bce_flags |= BCE_PCI_32BIT_FLAG;
642
643         device_printf(dev, "ASIC ID 0x%08X; Revision (%c%d); PCI%s %s %dMHz\n",
644                       sc->bce_chipid,
645                       ((BCE_CHIP_ID(sc) & 0xf000) >> 12) + 'A',
646                       (BCE_CHIP_ID(sc) & 0x0ff0) >> 4,
647                       (sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : "",
648                       (sc->bce_flags & BCE_PCI_32BIT_FLAG) ?
649                       "32-bit" : "64-bit", sc->bus_speed_mhz);
650
651         /* Reset the controller. */
652         rc = bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
653         if (rc != 0)
654                 goto fail;
655
656         /* Initialize the controller. */
657         rc = bce_chipinit(sc);
658         if (rc != 0) {
659                 device_printf(dev, "Controller initialization failed!\n");
660                 goto fail;
661         }
662
663         /* Perform NVRAM test. */
664         rc = bce_nvram_test(sc);
665         if (rc != 0) {
666                 device_printf(dev, "NVRAM test failed!\n");
667                 goto fail;
668         }
669
670         /* Fetch the permanent Ethernet MAC address. */
671         bce_get_mac_addr(sc);
672
673         /*
674          * Trip points control how many BDs
675          * should be ready before generating an
676          * interrupt while ticks control how long
677          * a BD can sit in the chain before
678          * generating an interrupt.  Set the default 
679          * values for the RX and TX rings.
680          */
681
682 #ifdef BCE_DRBUG
683         /* Force more frequent interrupts. */
684         sc->bce_tx_quick_cons_trip_int = 1;
685         sc->bce_tx_quick_cons_trip     = 1;
686         sc->bce_tx_ticks_int           = 0;
687         sc->bce_tx_ticks               = 0;
688
689         sc->bce_rx_quick_cons_trip_int = 1;
690         sc->bce_rx_quick_cons_trip     = 1;
691         sc->bce_rx_ticks_int           = 0;
692         sc->bce_rx_ticks               = 0;
693 #else
694         sc->bce_tx_quick_cons_trip_int = bce_tx_bds_int;
695         sc->bce_tx_quick_cons_trip     = bce_tx_bds;
696         sc->bce_tx_ticks_int           = bce_tx_ticks_int;
697         sc->bce_tx_ticks               = bce_tx_ticks;
698
699         sc->bce_rx_quick_cons_trip_int = bce_rx_bds_int;
700         sc->bce_rx_quick_cons_trip     = bce_rx_bds;
701         sc->bce_rx_ticks_int           = bce_rx_ticks_int;
702         sc->bce_rx_ticks               = bce_rx_ticks;
703 #endif
704
705         /* Update statistics once every second. */
706         sc->bce_stats_ticks = 1000000 & 0xffff00;
707
708         /*
709          * The copper based NetXtreme II controllers
710          * use an integrated PHY at address 1 while
711          * the SerDes controllers use a PHY at
712          * address 2.
713          */
714         sc->bce_phy_addr = 1;
715
716         if (BCE_CHIP_BOND_ID(sc) & BCE_CHIP_BOND_ID_SERDES_BIT) {
717                 sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
718                 sc->bce_flags |= BCE_NO_WOL_FLAG;
719                 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708) {
720                         sc->bce_phy_addr = 2;
721                         val = REG_RD_IND(sc, sc->bce_shmem_base +
722                                          BCE_SHARED_HW_CFG_CONFIG);
723                         if (val & BCE_SHARED_HW_CFG_PHY_2_5G)
724                                 sc->bce_phy_flags |= BCE_PHY_2_5G_CAPABLE_FLAG;
725                 }
726         }
727
728         /* Allocate DMA memory resources. */
729         rc = bce_dma_alloc(sc);
730         if (rc != 0) {
731                 device_printf(dev, "DMA resource allocation failed!\n");
732                 goto fail;
733         }
734
735         /* Initialize the ifnet interface. */
736         ifp->if_softc = sc;
737         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
738         ifp->if_ioctl = bce_ioctl;
739         ifp->if_start = bce_start;
740         ifp->if_init = bce_init;
741         ifp->if_watchdog = bce_watchdog;
742 #ifdef DEVICE_POLLING
743         ifp->if_poll = bce_poll;
744 #endif
745         ifp->if_mtu = ETHERMTU;
746         ifp->if_hwassist = BCE_IF_HWASSIST;
747         ifp->if_capabilities = BCE_IF_CAPABILITIES;
748         ifp->if_capenable = ifp->if_capabilities;
749         ifq_set_maxlen(&ifp->if_snd, USABLE_TX_BD);
750         ifq_set_ready(&ifp->if_snd);
751
752         if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
753                 ifp->if_baudrate = IF_Gbps(2.5);
754         else
755                 ifp->if_baudrate = IF_Gbps(1);
756
757         /* Assume a standard 1500 byte MTU size for mbuf allocations. */
758         sc->mbuf_alloc_size  = MCLBYTES;
759
760         /* Look for our PHY. */
761         rc = mii_phy_probe(dev, &sc->bce_miibus,
762                            bce_ifmedia_upd, bce_ifmedia_sts);
763         if (rc != 0) {
764                 device_printf(dev, "PHY probe failed!\n");
765                 goto fail;
766         }
767
768         /* Attach to the Ethernet interface list. */
769         ether_ifattach(ifp, sc->eaddr, NULL);
770
771         callout_init(&sc->bce_stat_ch);
772
773         /* Hookup IRQ last. */
774         rc = bus_setup_intr(dev, sc->bce_res_irq, INTR_MPSAFE, bce_intr, sc,
775                             &sc->bce_intrhand, ifp->if_serializer);
776         if (rc != 0) {
777                 device_printf(dev, "Failed to setup IRQ!\n");
778                 ether_ifdetach(ifp);
779                 goto fail;
780         }
781
782         ifp->if_cpuid = ithread_cpuid(rman_get_start(sc->bce_res_irq));
783         KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus);
784
785         /* Print some important debugging info. */
786         DBRUN(BCE_INFO, bce_dump_driver_state(sc));
787
788         /* Add the supported sysctls to the kernel. */
789         bce_add_sysctls(sc);
790
791         /* Get the firmware running so IPMI still works */
792         bce_mgmt_init(sc);
793
794         return 0;
795 fail:
796         bce_detach(dev);
797         return(rc);
798 }
799
800
801 /****************************************************************************/
802 /* Device detach function.                                                  */
803 /*                                                                          */
804 /* Stops the controller, resets the controller, and releases resources.     */
805 /*                                                                          */
806 /* Returns:                                                                 */
807 /*   0 on success, positive value on failure.                               */
808 /****************************************************************************/
809 static int
810 bce_detach(device_t dev)
811 {
812         struct bce_softc *sc = device_get_softc(dev);
813
814         if (device_is_attached(dev)) {
815                 struct ifnet *ifp = &sc->arpcom.ac_if;
816
817                 /* Stop and reset the controller. */
818                 lwkt_serialize_enter(ifp->if_serializer);
819                 bce_stop(sc);
820                 bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
821                 bus_teardown_intr(dev, sc->bce_res_irq, sc->bce_intrhand);
822                 lwkt_serialize_exit(ifp->if_serializer);
823
824                 ether_ifdetach(ifp);
825         }
826
827         /* If we have a child device on the MII bus remove it too. */
828         if (sc->bce_miibus)
829                 device_delete_child(dev, sc->bce_miibus);
830         bus_generic_detach(dev);
831
832         if (sc->bce_res_irq != NULL) {
833                 bus_release_resource(dev, SYS_RES_IRQ,
834                         sc->bce_flags & BCE_USING_MSI_FLAG ? 1 : 0,
835                         sc->bce_res_irq);
836         }
837
838 #ifdef notyet
839         if (sc->bce_flags & BCE_USING_MSI_FLAG)
840                 pci_release_msi(dev);
841 #endif
842
843         if (sc->bce_res_mem != NULL) {
844                 bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0),
845                                      sc->bce_res_mem);
846         }
847
848         bce_dma_free(sc);
849
850         if (sc->bce_sysctl_tree != NULL)
851                 sysctl_ctx_free(&sc->bce_sysctl_ctx);
852
853         return 0;
854 }
855
856
857 /****************************************************************************/
858 /* Device shutdown function.                                                */
859 /*                                                                          */
860 /* Stops and resets the controller.                                         */
861 /*                                                                          */
862 /* Returns:                                                                 */
863 /*   Nothing                                                                */
864 /****************************************************************************/
865 static void
866 bce_shutdown(device_t dev)
867 {
868         struct bce_softc *sc = device_get_softc(dev);
869         struct ifnet *ifp = &sc->arpcom.ac_if;
870
871         lwkt_serialize_enter(ifp->if_serializer);
872         bce_stop(sc);
873         bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
874         lwkt_serialize_exit(ifp->if_serializer);
875 }
876
877
878 /****************************************************************************/
879 /* Indirect register read.                                                  */
880 /*                                                                          */
881 /* Reads NetXtreme II registers using an index/data register pair in PCI    */
882 /* configuration space.  Using this mechanism avoids issues with posted     */
883 /* reads but is much slower than memory-mapped I/O.                         */
884 /*                                                                          */
885 /* Returns:                                                                 */
886 /*   The value of the register.                                             */
887 /****************************************************************************/
888 static uint32_t
889 bce_reg_rd_ind(struct bce_softc *sc, uint32_t offset)
890 {
891         device_t dev = sc->bce_dev;
892
893         pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
894 #ifdef BCE_DEBUG
895         {
896                 uint32_t val;
897                 val = pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
898                 DBPRINT(sc, BCE_EXCESSIVE,
899                         "%s(); offset = 0x%08X, val = 0x%08X\n",
900                         __func__, offset, val);
901                 return val;
902         }
903 #else
904         return pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
905 #endif
906 }
907
908
909 /****************************************************************************/
910 /* Indirect register write.                                                 */
911 /*                                                                          */
912 /* Writes NetXtreme II registers using an index/data register pair in PCI   */
913 /* configuration space.  Using this mechanism avoids issues with posted     */
914 /* writes but is muchh slower than memory-mapped I/O.                       */
915 /*                                                                          */
916 /* Returns:                                                                 */
917 /*   Nothing.                                                               */
918 /****************************************************************************/
919 static void
920 bce_reg_wr_ind(struct bce_softc *sc, uint32_t offset, uint32_t val)
921 {
922         device_t dev = sc->bce_dev;
923
924         DBPRINT(sc, BCE_EXCESSIVE, "%s(); offset = 0x%08X, val = 0x%08X\n",
925                 __func__, offset, val);
926
927         pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
928         pci_write_config(dev, BCE_PCICFG_REG_WINDOW, val, 4);
929 }
930
931
932 /****************************************************************************/
933 /* Context memory write.                                                    */
934 /*                                                                          */
935 /* The NetXtreme II controller uses context memory to track connection      */
936 /* information for L2 and higher network protocols.                         */
937 /*                                                                          */
938 /* Returns:                                                                 */
939 /*   Nothing.                                                               */
940 /****************************************************************************/
941 static void
942 bce_ctx_wr(struct bce_softc *sc, uint32_t cid_addr, uint32_t offset,
943            uint32_t val)
944 {
945         DBPRINT(sc, BCE_EXCESSIVE, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
946                 "val = 0x%08X\n", __func__, cid_addr, offset, val);
947
948         offset += cid_addr;
949         REG_WR(sc, BCE_CTX_DATA_ADR, offset);
950         REG_WR(sc, BCE_CTX_DATA, val);
951 }
952
953
954 /****************************************************************************/
955 /* PHY register read.                                                       */
956 /*                                                                          */
957 /* Implements register reads on the MII bus.                                */
958 /*                                                                          */
959 /* Returns:                                                                 */
960 /*   The value of the register.                                             */
961 /****************************************************************************/
962 static int
963 bce_miibus_read_reg(device_t dev, int phy, int reg)
964 {
965         struct bce_softc *sc = device_get_softc(dev);
966         uint32_t val;
967         int i;
968
969         /* Make sure we are accessing the correct PHY address. */
970         if (phy != sc->bce_phy_addr) {
971                 DBPRINT(sc, BCE_VERBOSE,
972                         "Invalid PHY address %d for PHY read!\n", phy);
973                 return 0;
974         }
975
976         if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
977                 val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
978                 val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
979
980                 REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
981                 REG_RD(sc, BCE_EMAC_MDIO_MODE);
982
983                 DELAY(40);
984         }
985
986         val = BCE_MIPHY(phy) | BCE_MIREG(reg) |
987               BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT |
988               BCE_EMAC_MDIO_COMM_START_BUSY;
989         REG_WR(sc, BCE_EMAC_MDIO_COMM, val);
990
991         for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
992                 DELAY(10);
993
994                 val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
995                 if (!(val & BCE_EMAC_MDIO_COMM_START_BUSY)) {
996                         DELAY(5);
997
998                         val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
999                         val &= BCE_EMAC_MDIO_COMM_DATA;
1000                         break;
1001                 }
1002         }
1003
1004         if (val & BCE_EMAC_MDIO_COMM_START_BUSY) {
1005                 if_printf(&sc->arpcom.ac_if,
1006                           "Error: PHY read timeout! phy = %d, reg = 0x%04X\n",
1007                           phy, reg);
1008                 val = 0x0;
1009         } else {
1010                 val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1011         }
1012
1013         DBPRINT(sc, BCE_EXCESSIVE,
1014                 "%s(): phy = %d, reg = 0x%04X, val = 0x%04X\n",
1015                 __func__, phy, (uint16_t)reg & 0xffff, (uint16_t) val & 0xffff);
1016
1017         if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1018                 val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1019                 val |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1020
1021                 REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1022                 REG_RD(sc, BCE_EMAC_MDIO_MODE);
1023
1024                 DELAY(40);
1025         }
1026         return (val & 0xffff);
1027 }
1028
1029
1030 /****************************************************************************/
1031 /* PHY register write.                                                      */
1032 /*                                                                          */
1033 /* Implements register writes on the MII bus.                               */
1034 /*                                                                          */
1035 /* Returns:                                                                 */
1036 /*   The value of the register.                                             */
1037 /****************************************************************************/
1038 static int
1039 bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
1040 {
1041         struct bce_softc *sc = device_get_softc(dev);
1042         uint32_t val1;
1043         int i;
1044
1045         /* Make sure we are accessing the correct PHY address. */
1046         if (phy != sc->bce_phy_addr) {
1047                 DBPRINT(sc, BCE_WARN,
1048                         "Invalid PHY address %d for PHY write!\n", phy);
1049                 return(0);
1050         }
1051
1052         DBPRINT(sc, BCE_EXCESSIVE,
1053                 "%s(): phy = %d, reg = 0x%04X, val = 0x%04X\n",
1054                 __func__, phy, (uint16_t)(reg & 0xffff),
1055                 (uint16_t)(val & 0xffff));
1056
1057         if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1058                 val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1059                 val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1060
1061                 REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1062                 REG_RD(sc, BCE_EMAC_MDIO_MODE);
1063
1064                 DELAY(40);
1065         }
1066
1067         val1 = BCE_MIPHY(phy) | BCE_MIREG(reg) | val |
1068                 BCE_EMAC_MDIO_COMM_COMMAND_WRITE |
1069                 BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT;
1070         REG_WR(sc, BCE_EMAC_MDIO_COMM, val1);
1071
1072         for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1073                 DELAY(10);
1074
1075                 val1 = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1076                 if (!(val1 & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1077                         DELAY(5);
1078                         break;
1079                 }
1080         }
1081
1082         if (val1 & BCE_EMAC_MDIO_COMM_START_BUSY)
1083                 if_printf(&sc->arpcom.ac_if, "PHY write timeout!\n");
1084
1085         if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1086                 val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1087                 val1 |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1088
1089                 REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1090                 REG_RD(sc, BCE_EMAC_MDIO_MODE);
1091
1092                 DELAY(40);
1093         }
1094         return 0;
1095 }
1096
1097
1098 /****************************************************************************/
1099 /* MII bus status change.                                                   */
1100 /*                                                                          */
1101 /* Called by the MII bus driver when the PHY establishes link to set the    */
1102 /* MAC interface registers.                                                 */
1103 /*                                                                          */
1104 /* Returns:                                                                 */
1105 /*   Nothing.                                                               */
1106 /****************************************************************************/
1107 static void
1108 bce_miibus_statchg(device_t dev)
1109 {
1110         struct bce_softc *sc = device_get_softc(dev);
1111         struct mii_data *mii = device_get_softc(sc->bce_miibus);
1112
1113         DBPRINT(sc, BCE_INFO, "mii_media_active = 0x%08X\n",
1114                 mii->mii_media_active);
1115
1116 #ifdef BCE_DEBUG
1117         /* Decode the interface media flags. */
1118         if_printf(&sc->arpcom.ac_if, "Media: ( ");
1119         switch(IFM_TYPE(mii->mii_media_active)) {
1120         case IFM_ETHER:
1121                 kprintf("Ethernet )");
1122                 break;
1123         default:
1124                 kprintf("Unknown )");
1125                 break;
1126         }
1127
1128         kprintf(" Media Options: ( ");
1129         switch(IFM_SUBTYPE(mii->mii_media_active)) {
1130         case IFM_AUTO:
1131                 kprintf("Autoselect )");
1132                 break;
1133         case IFM_MANUAL:
1134                 kprintf("Manual )");
1135                 break;
1136         case IFM_NONE:
1137                 kprintf("None )");
1138                 break;
1139         case IFM_10_T:
1140                 kprintf("10Base-T )");
1141                 break;
1142         case IFM_100_TX:
1143                 kprintf("100Base-TX )");
1144                 break;
1145         case IFM_1000_SX:
1146                 kprintf("1000Base-SX )");
1147                 break;
1148         case IFM_1000_T:
1149                 kprintf("1000Base-T )");
1150                 break;
1151         default:
1152                 kprintf("Other )");
1153                 break;
1154         }
1155
1156         kprintf(" Global Options: (");
1157         if (mii->mii_media_active & IFM_FDX)
1158                 kprintf(" FullDuplex");
1159         if (mii->mii_media_active & IFM_HDX)
1160                 kprintf(" HalfDuplex");
1161         if (mii->mii_media_active & IFM_LOOP)
1162                 kprintf(" Loopback");
1163         if (mii->mii_media_active & IFM_FLAG0)
1164                 kprintf(" Flag0");
1165         if (mii->mii_media_active & IFM_FLAG1)
1166                 kprintf(" Flag1");
1167         if (mii->mii_media_active & IFM_FLAG2)
1168                 kprintf(" Flag2");
1169         kprintf(" )\n");
1170 #endif
1171
1172         BCE_CLRBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_PORT);
1173
1174         /*
1175          * Set MII or GMII interface based on the speed negotiated
1176          * by the PHY.
1177          */
1178         if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T || 
1179             IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX) {
1180                 DBPRINT(sc, BCE_INFO, "Setting GMII interface.\n");
1181                 BCE_SETBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_PORT_GMII);
1182         } else {
1183                 DBPRINT(sc, BCE_INFO, "Setting MII interface.\n");
1184                 BCE_SETBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_PORT_MII);
1185         }
1186
1187         /*
1188          * Set half or full duplex based on the duplicity negotiated
1189          * by the PHY.
1190          */
1191         if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
1192                 DBPRINT(sc, BCE_INFO, "Setting Full-Duplex interface.\n");
1193                 BCE_CLRBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_HALF_DUPLEX);
1194         } else {
1195                 DBPRINT(sc, BCE_INFO, "Setting Half-Duplex interface.\n");
1196                 BCE_SETBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_HALF_DUPLEX);
1197         }
1198 }
1199
1200
1201 /****************************************************************************/
1202 /* Acquire NVRAM lock.                                                      */
1203 /*                                                                          */
1204 /* Before the NVRAM can be accessed the caller must acquire an NVRAM lock.  */
1205 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1206 /* for use by the driver.                                                   */
1207 /*                                                                          */
1208 /* Returns:                                                                 */
1209 /*   0 on success, positive value on failure.                               */
1210 /****************************************************************************/
1211 static int
1212 bce_acquire_nvram_lock(struct bce_softc *sc)
1213 {
1214         uint32_t val;
1215         int j;
1216
1217         DBPRINT(sc, BCE_VERBOSE, "Acquiring NVRAM lock.\n");
1218
1219         /* Request access to the flash interface. */
1220         REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_SET2);
1221         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1222                 val = REG_RD(sc, BCE_NVM_SW_ARB);
1223                 if (val & BCE_NVM_SW_ARB_ARB_ARB2)
1224                         break;
1225
1226                 DELAY(5);
1227         }
1228
1229         if (j >= NVRAM_TIMEOUT_COUNT) {
1230                 DBPRINT(sc, BCE_WARN, "Timeout acquiring NVRAM lock!\n");
1231                 return EBUSY;
1232         }
1233         return 0;
1234 }
1235
1236
1237 /****************************************************************************/
1238 /* Release NVRAM lock.                                                      */
1239 /*                                                                          */
1240 /* When the caller is finished accessing NVRAM the lock must be released.   */
1241 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1242 /* for use by the driver.                                                   */
1243 /*                                                                          */
1244 /* Returns:                                                                 */
1245 /*   0 on success, positive value on failure.                               */
1246 /****************************************************************************/
1247 static int
1248 bce_release_nvram_lock(struct bce_softc *sc)
1249 {
1250         int j;
1251         uint32_t val;
1252
1253         DBPRINT(sc, BCE_VERBOSE, "Releasing NVRAM lock.\n");
1254
1255         /*
1256          * Relinquish nvram interface.
1257          */
1258         REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_CLR2);
1259
1260         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1261                 val = REG_RD(sc, BCE_NVM_SW_ARB);
1262                 if (!(val & BCE_NVM_SW_ARB_ARB_ARB2))
1263                         break;
1264
1265                 DELAY(5);
1266         }
1267
1268         if (j >= NVRAM_TIMEOUT_COUNT) {
1269                 DBPRINT(sc, BCE_WARN, "Timeout reeasing NVRAM lock!\n");
1270                 return EBUSY;
1271         }
1272         return 0;
1273 }
1274
1275
1276 #ifdef BCE_NVRAM_WRITE_SUPPORT
1277 /****************************************************************************/
1278 /* Enable NVRAM write access.                                               */
1279 /*                                                                          */
1280 /* Before writing to NVRAM the caller must enable NVRAM writes.             */
1281 /*                                                                          */
1282 /* Returns:                                                                 */
1283 /*   0 on success, positive value on failure.                               */
1284 /****************************************************************************/
1285 static int
1286 bce_enable_nvram_write(struct bce_softc *sc)
1287 {
1288         uint32_t val;
1289
1290         DBPRINT(sc, BCE_VERBOSE, "Enabling NVRAM write.\n");
1291
1292         val = REG_RD(sc, BCE_MISC_CFG);
1293         REG_WR(sc, BCE_MISC_CFG, val | BCE_MISC_CFG_NVM_WR_EN_PCI);
1294
1295         if (!sc->bce_flash_info->buffered) {
1296                 int j;
1297
1298                 REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1299                 REG_WR(sc, BCE_NVM_COMMAND,
1300                        BCE_NVM_COMMAND_WREN | BCE_NVM_COMMAND_DOIT);
1301
1302                 for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1303                         DELAY(5);
1304
1305                         val = REG_RD(sc, BCE_NVM_COMMAND);
1306                         if (val & BCE_NVM_COMMAND_DONE)
1307                                 break;
1308                 }
1309
1310                 if (j >= NVRAM_TIMEOUT_COUNT) {
1311                         DBPRINT(sc, BCE_WARN, "Timeout writing NVRAM!\n");
1312                         return EBUSY;
1313                 }
1314         }
1315         return 0;
1316 }
1317
1318
1319 /****************************************************************************/
1320 /* Disable NVRAM write access.                                              */
1321 /*                                                                          */
1322 /* When the caller is finished writing to NVRAM write access must be        */
1323 /* disabled.                                                                */
1324 /*                                                                          */
1325 /* Returns:                                                                 */
1326 /*   Nothing.                                                               */
1327 /****************************************************************************/
1328 static void
1329 bce_disable_nvram_write(struct bce_softc *sc)
1330 {
1331         uint32_t val;
1332
1333         DBPRINT(sc, BCE_VERBOSE, "Disabling NVRAM write.\n");
1334
1335         val = REG_RD(sc, BCE_MISC_CFG);
1336         REG_WR(sc, BCE_MISC_CFG, val & ~BCE_MISC_CFG_NVM_WR_EN);
1337 }
1338 #endif  /* BCE_NVRAM_WRITE_SUPPORT */
1339
1340
1341 /****************************************************************************/
1342 /* Enable NVRAM access.                                                     */
1343 /*                                                                          */
1344 /* Before accessing NVRAM for read or write operations the caller must      */
1345 /* enabled NVRAM access.                                                    */
1346 /*                                                                          */
1347 /* Returns:                                                                 */
1348 /*   Nothing.                                                               */
1349 /****************************************************************************/
1350 static void
1351 bce_enable_nvram_access(struct bce_softc *sc)
1352 {
1353         uint32_t val;
1354
1355         DBPRINT(sc, BCE_VERBOSE, "Enabling NVRAM access.\n");
1356
1357         val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
1358         /* Enable both bits, even on read. */
1359         REG_WR(sc, BCE_NVM_ACCESS_ENABLE,
1360                val | BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN);
1361 }
1362
1363
1364 /****************************************************************************/
1365 /* Disable NVRAM access.                                                    */
1366 /*                                                                          */
1367 /* When the caller is finished accessing NVRAM access must be disabled.     */
1368 /*                                                                          */
1369 /* Returns:                                                                 */
1370 /*   Nothing.                                                               */
1371 /****************************************************************************/
1372 static void
1373 bce_disable_nvram_access(struct bce_softc *sc)
1374 {
1375         uint32_t val;
1376
1377         DBPRINT(sc, BCE_VERBOSE, "Disabling NVRAM access.\n");
1378
1379         val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
1380
1381         /* Disable both bits, even after read. */
1382         REG_WR(sc, BCE_NVM_ACCESS_ENABLE,
1383                val & ~(BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN));
1384 }
1385
1386
1387 #ifdef BCE_NVRAM_WRITE_SUPPORT
1388 /****************************************************************************/
1389 /* Erase NVRAM page before writing.                                         */
1390 /*                                                                          */
1391 /* Non-buffered flash parts require that a page be erased before it is      */
1392 /* written.                                                                 */
1393 /*                                                                          */
1394 /* Returns:                                                                 */
1395 /*   0 on success, positive value on failure.                               */
1396 /****************************************************************************/
1397 static int
1398 bce_nvram_erase_page(struct bce_softc *sc, uint32_t offset)
1399 {
1400         uint32_t cmd;
1401         int j;
1402
1403         /* Buffered flash doesn't require an erase. */
1404         if (sc->bce_flash_info->buffered)
1405                 return 0;
1406
1407         DBPRINT(sc, BCE_VERBOSE, "Erasing NVRAM page.\n");
1408
1409         /* Build an erase command. */
1410         cmd = BCE_NVM_COMMAND_ERASE | BCE_NVM_COMMAND_WR |
1411               BCE_NVM_COMMAND_DOIT;
1412
1413         /*
1414          * Clear the DONE bit separately, set the NVRAM adress to erase,
1415          * and issue the erase command.
1416          */
1417         REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1418         REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1419         REG_WR(sc, BCE_NVM_COMMAND, cmd);
1420
1421         /* Wait for completion. */
1422         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1423                 uint32_t val;
1424
1425                 DELAY(5);
1426
1427                 val = REG_RD(sc, BCE_NVM_COMMAND);
1428                 if (val & BCE_NVM_COMMAND_DONE)
1429                         break;
1430         }
1431
1432         if (j >= NVRAM_TIMEOUT_COUNT) {
1433                 DBPRINT(sc, BCE_WARN, "Timeout erasing NVRAM.\n");
1434                 return EBUSY;
1435         }
1436         return 0;
1437 }
1438 #endif /* BCE_NVRAM_WRITE_SUPPORT */
1439
1440
1441 /****************************************************************************/
1442 /* Read a dword (32 bits) from NVRAM.                                       */
1443 /*                                                                          */
1444 /* Read a 32 bit word from NVRAM.  The caller is assumed to have already    */
1445 /* obtained the NVRAM lock and enabled the controller for NVRAM access.     */
1446 /*                                                                          */
1447 /* Returns:                                                                 */
1448 /*   0 on success and the 32 bit value read, positive value on failure.     */
1449 /****************************************************************************/
1450 static int
1451 bce_nvram_read_dword(struct bce_softc *sc, uint32_t offset, uint8_t *ret_val,
1452                      uint32_t cmd_flags)
1453 {
1454         uint32_t cmd;
1455         int i, rc = 0;
1456
1457         /* Build the command word. */
1458         cmd = BCE_NVM_COMMAND_DOIT | cmd_flags;
1459
1460         /* Calculate the offset for buffered flash. */
1461         if (sc->bce_flash_info->buffered) {
1462                 offset = ((offset / sc->bce_flash_info->page_size) <<
1463                           sc->bce_flash_info->page_bits) +
1464                          (offset % sc->bce_flash_info->page_size);
1465         }
1466
1467         /*
1468          * Clear the DONE bit separately, set the address to read,
1469          * and issue the read.
1470          */
1471         REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1472         REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1473         REG_WR(sc, BCE_NVM_COMMAND, cmd);
1474
1475         /* Wait for completion. */
1476         for (i = 0; i < NVRAM_TIMEOUT_COUNT; i++) {
1477                 uint32_t val;
1478
1479                 DELAY(5);
1480
1481                 val = REG_RD(sc, BCE_NVM_COMMAND);
1482                 if (val & BCE_NVM_COMMAND_DONE) {
1483                         val = REG_RD(sc, BCE_NVM_READ);
1484
1485                         val = be32toh(val);
1486                         memcpy(ret_val, &val, 4);
1487                         break;
1488                 }
1489         }
1490
1491         /* Check for errors. */
1492         if (i >= NVRAM_TIMEOUT_COUNT) {
1493                 if_printf(&sc->arpcom.ac_if,
1494                           "Timeout error reading NVRAM at offset 0x%08X!\n",
1495                           offset);
1496                 rc = EBUSY;
1497         }
1498         return rc;
1499 }
1500
1501
1502 #ifdef BCE_NVRAM_WRITE_SUPPORT
1503 /****************************************************************************/
1504 /* Write a dword (32 bits) to NVRAM.                                        */
1505 /*                                                                          */
1506 /* Write a 32 bit word to NVRAM.  The caller is assumed to have already     */
1507 /* obtained the NVRAM lock, enabled the controller for NVRAM access, and    */
1508 /* enabled NVRAM write access.                                              */
1509 /*                                                                          */
1510 /* Returns:                                                                 */
1511 /*   0 on success, positive value on failure.                               */
1512 /****************************************************************************/
1513 static int
1514 bce_nvram_write_dword(struct bce_softc *sc, uint32_t offset, uint8_t *val,
1515                       uint32_t cmd_flags)
1516 {
1517         uint32_t cmd, val32;
1518         int j;
1519
1520         /* Build the command word. */
1521         cmd = BCE_NVM_COMMAND_DOIT | BCE_NVM_COMMAND_WR | cmd_flags;
1522
1523         /* Calculate the offset for buffered flash. */
1524         if (sc->bce_flash_info->buffered) {
1525                 offset = ((offset / sc->bce_flash_info->page_size) <<
1526                           sc->bce_flash_info->page_bits) +
1527                          (offset % sc->bce_flash_info->page_size);
1528         }
1529
1530         /*
1531          * Clear the DONE bit separately, convert NVRAM data to big-endian,
1532          * set the NVRAM address to write, and issue the write command
1533          */
1534         REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1535         memcpy(&val32, val, 4);
1536         val32 = htobe32(val32);
1537         REG_WR(sc, BCE_NVM_WRITE, val32);
1538         REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1539         REG_WR(sc, BCE_NVM_COMMAND, cmd);
1540
1541         /* Wait for completion. */
1542         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1543                 DELAY(5);
1544
1545                 if (REG_RD(sc, BCE_NVM_COMMAND) & BCE_NVM_COMMAND_DONE)
1546                         break;
1547         }
1548         if (j >= NVRAM_TIMEOUT_COUNT) {
1549                 if_printf(&sc->arpcom.ac_if,
1550                           "Timeout error writing NVRAM at offset 0x%08X\n",
1551                           offset);
1552                 return EBUSY;
1553         }
1554         return 0;
1555 }
1556 #endif /* BCE_NVRAM_WRITE_SUPPORT */
1557
1558
1559 /****************************************************************************/
1560 /* Initialize NVRAM access.                                                 */
1561 /*                                                                          */
1562 /* Identify the NVRAM device in use and prepare the NVRAM interface to      */
1563 /* access that device.                                                      */
1564 /*                                                                          */
1565 /* Returns:                                                                 */
1566 /*   0 on success, positive value on failure.                               */
1567 /****************************************************************************/
1568 static int
1569 bce_init_nvram(struct bce_softc *sc)
1570 {
1571         uint32_t val;
1572         int j, entry_count, rc = 0;
1573         const struct flash_spec *flash;
1574
1575         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __func__);
1576
1577         /* Determine the selected interface. */
1578         val = REG_RD(sc, BCE_NVM_CFG1);
1579
1580         entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
1581
1582         /*
1583          * Flash reconfiguration is required to support additional
1584          * NVRAM devices not directly supported in hardware.
1585          * Check if the flash interface was reconfigured
1586          * by the bootcode.
1587          */
1588
1589         if (val & 0x40000000) {
1590                 /* Flash interface reconfigured by bootcode. */
1591
1592                 DBPRINT(sc, BCE_INFO_LOAD, 
1593                         "%s(): Flash WAS reconfigured.\n", __func__);
1594
1595                 for (j = 0, flash = flash_table; j < entry_count;
1596                      j++, flash++) {
1597                         if ((val & FLASH_BACKUP_STRAP_MASK) ==
1598                             (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
1599                                 sc->bce_flash_info = flash;
1600                                 break;
1601                         }
1602                 }
1603         } else {
1604                 /* Flash interface not yet reconfigured. */
1605                 uint32_t mask;
1606
1607                 DBPRINT(sc, BCE_INFO_LOAD, 
1608                         "%s(): Flash was NOT reconfigured.\n", __func__);
1609
1610                 if (val & (1 << 23))
1611                         mask = FLASH_BACKUP_STRAP_MASK;
1612                 else
1613                         mask = FLASH_STRAP_MASK;
1614
1615                 /* Look for the matching NVRAM device configuration data. */
1616                 for (j = 0, flash = flash_table; j < entry_count;
1617                      j++, flash++) {
1618                         /* Check if the device matches any of the known devices. */
1619                         if ((val & mask) == (flash->strapping & mask)) {
1620                                 /* Found a device match. */
1621                                 sc->bce_flash_info = flash;
1622
1623                                 /* Request access to the flash interface. */
1624                                 rc = bce_acquire_nvram_lock(sc);
1625                                 if (rc != 0)
1626                                         return rc;
1627
1628                                 /* Reconfigure the flash interface. */
1629                                 bce_enable_nvram_access(sc);
1630                                 REG_WR(sc, BCE_NVM_CFG1, flash->config1);
1631                                 REG_WR(sc, BCE_NVM_CFG2, flash->config2);
1632                                 REG_WR(sc, BCE_NVM_CFG3, flash->config3);
1633                                 REG_WR(sc, BCE_NVM_WRITE1, flash->write1);
1634                                 bce_disable_nvram_access(sc);
1635                                 bce_release_nvram_lock(sc);
1636                                 break;
1637                         }
1638                 }
1639         }
1640
1641         /* Check if a matching device was found. */
1642         if (j == entry_count) {
1643                 sc->bce_flash_info = NULL;
1644                 if_printf(&sc->arpcom.ac_if, "Unknown Flash NVRAM found!\n");
1645                 rc = ENODEV;
1646         }
1647
1648         /* Write the flash config data to the shared memory interface. */
1649         val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_SHARED_HW_CFG_CONFIG2) &
1650               BCE_SHARED_HW_CFG2_NVM_SIZE_MASK;
1651         if (val)
1652                 sc->bce_flash_size = val;
1653         else
1654                 sc->bce_flash_size = sc->bce_flash_info->total_size;
1655
1656         DBPRINT(sc, BCE_INFO_LOAD, "%s() flash->total_size = 0x%08X\n",
1657                 __func__, sc->bce_flash_info->total_size);
1658
1659         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __func__);
1660
1661         return rc;
1662 }
1663
1664
1665 /****************************************************************************/
1666 /* Read an arbitrary range of data from NVRAM.                              */
1667 /*                                                                          */
1668 /* Prepares the NVRAM interface for access and reads the requested data     */
1669 /* into the supplied buffer.                                                */
1670 /*                                                                          */
1671 /* Returns:                                                                 */
1672 /*   0 on success and the data read, positive value on failure.             */
1673 /****************************************************************************/
1674 static int
1675 bce_nvram_read(struct bce_softc *sc, uint32_t offset, uint8_t *ret_buf,
1676                int buf_size)
1677 {
1678         uint32_t cmd_flags, offset32, len32, extra;
1679         int rc = 0;
1680
1681         if (buf_size == 0)
1682                 return 0;
1683
1684         /* Request access to the flash interface. */
1685         rc = bce_acquire_nvram_lock(sc);
1686         if (rc != 0)
1687                 return rc;
1688
1689         /* Enable access to flash interface */
1690         bce_enable_nvram_access(sc);
1691
1692         len32 = buf_size;
1693         offset32 = offset;
1694         extra = 0;
1695
1696         cmd_flags = 0;
1697
1698         /* XXX should we release nvram lock if read_dword() fails? */
1699         if (offset32 & 3) {
1700                 uint8_t buf[4];
1701                 uint32_t pre_len;
1702
1703                 offset32 &= ~3;
1704                 pre_len = 4 - (offset & 3);
1705
1706                 if (pre_len >= len32) {
1707                         pre_len = len32;
1708                         cmd_flags = BCE_NVM_COMMAND_FIRST | BCE_NVM_COMMAND_LAST;
1709                 } else {
1710                         cmd_flags = BCE_NVM_COMMAND_FIRST;
1711                 }
1712
1713                 rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
1714                 if (rc)
1715                         return rc;
1716
1717                 memcpy(ret_buf, buf + (offset & 3), pre_len);
1718
1719                 offset32 += 4;
1720                 ret_buf += pre_len;
1721                 len32 -= pre_len;
1722         }
1723
1724         if (len32 & 3) {
1725                 extra = 4 - (len32 & 3);
1726                 len32 = (len32 + 4) & ~3;
1727         }
1728
1729         if (len32 == 4) {
1730                 uint8_t buf[4];
1731
1732                 if (cmd_flags)
1733                         cmd_flags = BCE_NVM_COMMAND_LAST;
1734                 else
1735                         cmd_flags = BCE_NVM_COMMAND_FIRST |
1736                                     BCE_NVM_COMMAND_LAST;
1737
1738                 rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
1739
1740                 memcpy(ret_buf, buf, 4 - extra);
1741         } else if (len32 > 0) {
1742                 uint8_t buf[4];
1743
1744                 /* Read the first word. */
1745                 if (cmd_flags)
1746                         cmd_flags = 0;
1747                 else
1748                         cmd_flags = BCE_NVM_COMMAND_FIRST;
1749
1750                 rc = bce_nvram_read_dword(sc, offset32, ret_buf, cmd_flags);
1751
1752                 /* Advance to the next dword. */
1753                 offset32 += 4;
1754                 ret_buf += 4;
1755                 len32 -= 4;
1756
1757                 while (len32 > 4 && rc == 0) {
1758                         rc = bce_nvram_read_dword(sc, offset32, ret_buf, 0);
1759
1760                         /* Advance to the next dword. */
1761                         offset32 += 4;
1762                         ret_buf += 4;
1763                         len32 -= 4;
1764                 }
1765
1766                 if (rc)
1767                         return rc;
1768
1769                 cmd_flags = BCE_NVM_COMMAND_LAST;
1770                 rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
1771
1772                 memcpy(ret_buf, buf, 4 - extra);
1773         }
1774
1775         /* Disable access to flash interface and release the lock. */
1776         bce_disable_nvram_access(sc);
1777         bce_release_nvram_lock(sc);
1778
1779         return rc;
1780 }
1781
1782
1783 #ifdef BCE_NVRAM_WRITE_SUPPORT
1784 /****************************************************************************/
1785 /* Write an arbitrary range of data from NVRAM.                             */
1786 /*                                                                          */
1787 /* Prepares the NVRAM interface for write access and writes the requested   */
1788 /* data from the supplied buffer.  The caller is responsible for            */
1789 /* calculating any appropriate CRCs.                                        */
1790 /*                                                                          */
1791 /* Returns:                                                                 */
1792 /*   0 on success, positive value on failure.                               */
1793 /****************************************************************************/
1794 static int
1795 bce_nvram_write(struct bce_softc *sc, uint32_t offset, uint8_t *data_buf,
1796                 int buf_size)
1797 {
1798         uint32_t written, offset32, len32;
1799         uint8_t *buf, start[4], end[4];
1800         int rc = 0;
1801         int align_start, align_end;
1802
1803         buf = data_buf;
1804         offset32 = offset;
1805         len32 = buf_size;
1806         align_end = 0;
1807         align_start = (offset32 & 3);
1808
1809         if (align_start) {
1810                 offset32 &= ~3;
1811                 len32 += align_start;
1812                 rc = bce_nvram_read(sc, offset32, start, 4);
1813                 if (rc)
1814                         return rc;
1815         }
1816
1817         if (len32 & 3) {
1818                 if (len32 > 4 || !align_start) {
1819                         align_end = 4 - (len32 & 3);
1820                         len32 += align_end;
1821                         rc = bce_nvram_read(sc, offset32 + len32 - 4, end, 4);
1822                         if (rc)
1823                                 return rc;
1824                 }
1825         }
1826
1827         if (align_start || align_end) {
1828                 buf = kmalloc(len32, M_DEVBUF, M_NOWAIT);
1829                 if (buf == NULL)
1830                         return ENOMEM;
1831                 if (align_start)
1832                         memcpy(buf, start, 4);
1833                 if (align_end)
1834                         memcpy(buf + len32 - 4, end, 4);
1835                 memcpy(buf + align_start, data_buf, buf_size);
1836         }
1837
1838         written = 0;
1839         while (written < len32 && rc == 0) {
1840                 uint32_t page_start, page_end, data_start, data_end;
1841                 uint32_t addr, cmd_flags;
1842                 int i;
1843                 uint8_t flash_buffer[264];
1844
1845                 /* Find the page_start addr */
1846                 page_start = offset32 + written;
1847                 page_start -= (page_start % sc->bce_flash_info->page_size);
1848                 /* Find the page_end addr */
1849                 page_end = page_start + sc->bce_flash_info->page_size;
1850                 /* Find the data_start addr */
1851                 data_start = (written == 0) ? offset32 : page_start;
1852                 /* Find the data_end addr */
1853                 data_end = (page_end > offset32 + len32) ? (offset32 + len32)
1854                                                          : page_end;
1855
1856                 /* Request access to the flash interface. */
1857                 rc = bce_acquire_nvram_lock(sc);
1858                 if (rc != 0)
1859                         goto nvram_write_end;
1860
1861                 /* Enable access to flash interface */
1862                 bce_enable_nvram_access(sc);
1863
1864                 cmd_flags = BCE_NVM_COMMAND_FIRST;
1865                 if (sc->bce_flash_info->buffered == 0) {
1866                         int j;
1867
1868                         /*
1869                          * Read the whole page into the buffer
1870                          * (non-buffer flash only)
1871                          */
1872                         for (j = 0; j < sc->bce_flash_info->page_size; j += 4) {
1873                                 if (j == (sc->bce_flash_info->page_size - 4))
1874                                         cmd_flags |= BCE_NVM_COMMAND_LAST;
1875
1876                                 rc = bce_nvram_read_dword(sc, page_start + j,
1877                                                           &flash_buffer[j],
1878                                                           cmd_flags);
1879                                 if (rc)
1880                                         goto nvram_write_end;
1881
1882                                 cmd_flags = 0;
1883                         }
1884                 }
1885
1886                 /* Enable writes to flash interface (unlock write-protect) */
1887                 rc = bce_enable_nvram_write(sc);
1888                 if (rc != 0)
1889                         goto nvram_write_end;
1890
1891                 /* Erase the page */
1892                 rc = bce_nvram_erase_page(sc, page_start);
1893                 if (rc != 0)
1894                         goto nvram_write_end;
1895
1896                 /* Re-enable the write again for the actual write */
1897                 bce_enable_nvram_write(sc);
1898
1899                 /* Loop to write back the buffer data from page_start to
1900                  * data_start */
1901                 i = 0;
1902                 if (sc->bce_flash_info->buffered == 0) {
1903                         for (addr = page_start; addr < data_start;
1904                              addr += 4, i += 4) {
1905                                 rc = bce_nvram_write_dword(sc, addr,
1906                                                            &flash_buffer[i],
1907                                                            cmd_flags);
1908                                 if (rc != 0)
1909                                         goto nvram_write_end;
1910
1911                                 cmd_flags = 0;
1912                         }
1913                 }
1914
1915                 /* Loop to write the new data from data_start to data_end */
1916                 for (addr = data_start; addr < data_end; addr += 4, i++) {
1917                         if (addr == page_end - 4 ||
1918                             (sc->bce_flash_info->buffered &&
1919                              addr == data_end - 4))
1920                                 cmd_flags |= BCE_NVM_COMMAND_LAST;
1921
1922                         rc = bce_nvram_write_dword(sc, addr, buf, cmd_flags);
1923                         if (rc != 0)
1924                                 goto nvram_write_end;
1925
1926                         cmd_flags = 0;
1927                         buf += 4;
1928                 }
1929
1930                 /* Loop to write back the buffer data from data_end
1931                  * to page_end */
1932                 if (sc->bce_flash_info->buffered == 0) {
1933                         for (addr = data_end; addr < page_end;
1934                              addr += 4, i += 4) {
1935                                 if (addr == page_end-4)
1936                                         cmd_flags = BCE_NVM_COMMAND_LAST;
1937
1938                                 rc = bce_nvram_write_dword(sc, addr,
1939                                         &flash_buffer[i], cmd_flags);
1940                                 if (rc != 0)
1941                                         goto nvram_write_end;
1942
1943                                 cmd_flags = 0;
1944                         }
1945                 }
1946
1947                 /* Disable writes to flash interface (lock write-protect) */
1948                 bce_disable_nvram_write(sc);
1949
1950                 /* Disable access to flash interface */
1951                 bce_disable_nvram_access(sc);
1952                 bce_release_nvram_lock(sc);
1953
1954                 /* Increment written */
1955                 written += data_end - data_start;
1956         }
1957
1958 nvram_write_end:
1959         if (align_start || align_end)
1960                 kfree(buf, M_DEVBUF);
1961         return rc;
1962 }
1963 #endif /* BCE_NVRAM_WRITE_SUPPORT */
1964
1965
1966 /****************************************************************************/
1967 /* Verifies that NVRAM is accessible and contains valid data.               */
1968 /*                                                                          */
1969 /* Reads the configuration data from NVRAM and verifies that the CRC is     */
1970 /* correct.                                                                 */
1971 /*                                                                          */
1972 /* Returns:                                                                 */
1973 /*   0 on success, positive value on failure.                               */
1974 /****************************************************************************/
1975 static int
1976 bce_nvram_test(struct bce_softc *sc)
1977 {
1978         uint32_t buf[BCE_NVRAM_SIZE / 4];
1979         uint32_t magic, csum;
1980         uint8_t *data = (uint8_t *)buf;
1981         int rc = 0;
1982
1983         /*
1984          * Check that the device NVRAM is valid by reading
1985          * the magic value at offset 0.
1986          */
1987         rc = bce_nvram_read(sc, 0, data, 4);
1988         if (rc != 0)
1989                 return rc;
1990
1991         magic = be32toh(buf[0]);
1992         if (magic != BCE_NVRAM_MAGIC) {
1993                 if_printf(&sc->arpcom.ac_if,
1994                           "Invalid NVRAM magic value! Expected: 0x%08X, "
1995                           "Found: 0x%08X\n", BCE_NVRAM_MAGIC, magic);
1996                 return ENODEV;
1997         }
1998
1999         /*
2000          * Verify that the device NVRAM includes valid
2001          * configuration data.
2002          */
2003         rc = bce_nvram_read(sc, 0x100, data, BCE_NVRAM_SIZE);
2004         if (rc != 0)
2005                 return rc;
2006
2007         csum = ether_crc32_le(data, 0x100);
2008         if (csum != BCE_CRC32_RESIDUAL) {
2009                 if_printf(&sc->arpcom.ac_if,
2010                           "Invalid Manufacturing Information NVRAM CRC! "
2011                           "Expected: 0x%08X, Found: 0x%08X\n",
2012                           BCE_CRC32_RESIDUAL, csum);
2013                 return ENODEV;
2014         }
2015
2016         csum = ether_crc32_le(data + 0x100, 0x100);
2017         if (csum != BCE_CRC32_RESIDUAL) {
2018                 if_printf(&sc->arpcom.ac_if,
2019                           "Invalid Feature Configuration Information "
2020                           "NVRAM CRC! Expected: 0x%08X, Found: 08%08X\n",
2021                           BCE_CRC32_RESIDUAL, csum);
2022                 rc = ENODEV;
2023         }
2024         return rc;
2025 }
2026
2027
2028 /****************************************************************************/
2029 /* Free any DMA memory owned by the driver.                                 */
2030 /*                                                                          */
2031 /* Scans through each data structre that requires DMA memory and frees      */
2032 /* the memory if allocated.                                                 */
2033 /*                                                                          */
2034 /* Returns:                                                                 */
2035 /*   Nothing.                                                               */
2036 /****************************************************************************/
2037 static void
2038 bce_dma_free(struct bce_softc *sc)
2039 {
2040         int i;
2041
2042         /* Destroy the status block. */
2043         if (sc->status_tag != NULL) {
2044                 if (sc->status_block != NULL) {
2045                         bus_dmamap_unload(sc->status_tag, sc->status_map);
2046                         bus_dmamem_free(sc->status_tag, sc->status_block,
2047                                         sc->status_map);
2048                 }
2049                 bus_dma_tag_destroy(sc->status_tag);
2050         }
2051
2052
2053         /* Destroy the statistics block. */
2054         if (sc->stats_tag != NULL) {
2055                 if (sc->stats_block != NULL) {
2056                         bus_dmamap_unload(sc->stats_tag, sc->stats_map);
2057                         bus_dmamem_free(sc->stats_tag, sc->stats_block,
2058                                         sc->stats_map);
2059                 }
2060                 bus_dma_tag_destroy(sc->stats_tag);
2061         }
2062
2063         /* Destroy the TX buffer descriptor DMA stuffs. */
2064         if (sc->tx_bd_chain_tag != NULL) {
2065                 for (i = 0; i < TX_PAGES; i++) {
2066                         if (sc->tx_bd_chain[i] != NULL) {
2067                                 bus_dmamap_unload(sc->tx_bd_chain_tag,
2068                                                   sc->tx_bd_chain_map[i]);
2069                                 bus_dmamem_free(sc->tx_bd_chain_tag,
2070                                                 sc->tx_bd_chain[i],
2071                                                 sc->tx_bd_chain_map[i]);
2072                         }
2073                 }
2074                 bus_dma_tag_destroy(sc->tx_bd_chain_tag);
2075         }
2076
2077         /* Destroy the RX buffer descriptor DMA stuffs. */
2078         if (sc->rx_bd_chain_tag != NULL) {
2079                 for (i = 0; i < RX_PAGES; i++) {
2080                         if (sc->rx_bd_chain[i] != NULL) {
2081                                 bus_dmamap_unload(sc->rx_bd_chain_tag,
2082                                                   sc->rx_bd_chain_map[i]);
2083                                 bus_dmamem_free(sc->rx_bd_chain_tag,
2084                                                 sc->rx_bd_chain[i],
2085                                                 sc->rx_bd_chain_map[i]);
2086                         }
2087                 }
2088                 bus_dma_tag_destroy(sc->rx_bd_chain_tag);
2089         }
2090
2091         /* Destroy the TX mbuf DMA stuffs. */
2092         if (sc->tx_mbuf_tag != NULL) {
2093                 for (i = 0; i < TOTAL_TX_BD; i++) {
2094                         /* Must have been unloaded in bce_stop() */
2095                         KKASSERT(sc->tx_mbuf_ptr[i] == NULL);
2096                         bus_dmamap_destroy(sc->tx_mbuf_tag,
2097                                            sc->tx_mbuf_map[i]);
2098                 }
2099                 bus_dma_tag_destroy(sc->tx_mbuf_tag);
2100         }
2101
2102         /* Destroy the RX mbuf DMA stuffs. */
2103         if (sc->rx_mbuf_tag != NULL) {
2104                 for (i = 0; i < TOTAL_RX_BD; i++) {
2105                         /* Must have been unloaded in bce_stop() */
2106                         KKASSERT(sc->rx_mbuf_ptr[i] == NULL);
2107                         bus_dmamap_destroy(sc->rx_mbuf_tag,
2108                                            sc->rx_mbuf_map[i]);
2109                 }
2110                 bus_dmamap_destroy(sc->rx_mbuf_tag, sc->rx_mbuf_tmpmap);
2111                 bus_dma_tag_destroy(sc->rx_mbuf_tag);
2112         }
2113
2114         /* Destroy the parent tag */
2115         if (sc->parent_tag != NULL)
2116                 bus_dma_tag_destroy(sc->parent_tag);
2117 }
2118
2119
2120 /****************************************************************************/
2121 /* Get DMA memory from the OS.                                              */
2122 /*                                                                          */
2123 /* Validates that the OS has provided DMA buffers in response to a          */
2124 /* bus_dmamap_load() call and saves the physical address of those buffers.  */
2125 /* When the callback is used the OS will return 0 for the mapping function  */
2126 /* (bus_dmamap_load()) so we use the value of map_arg->maxsegs to pass any  */
2127 /* failures back to the caller.                                             */
2128 /*                                                                          */
2129 /* Returns:                                                                 */
2130 /*   Nothing.                                                               */
2131 /****************************************************************************/
2132 static void
2133 bce_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
2134 {
2135         bus_addr_t *busaddr = arg;
2136
2137         /*
2138          * Simulate a mapping failure.
2139          * XXX not correct.
2140          */
2141         DBRUNIF(DB_RANDOMTRUE(bce_debug_dma_map_addr_failure),
2142                 kprintf("bce: %s(%d): Simulating DMA mapping error.\n",
2143                         __FILE__, __LINE__);
2144                 error = ENOMEM);
2145                 
2146         /* Check for an error and signal the caller that an error occurred. */
2147         if (error)
2148                 return;
2149
2150         KASSERT(nseg == 1, ("only one segment is allowed\n"));
2151         *busaddr = segs->ds_addr;
2152 }
2153
2154
2155 /****************************************************************************/
2156 /* Allocate any DMA memory needed by the driver.                            */
2157 /*                                                                          */
2158 /* Allocates DMA memory needed for the various global structures needed by  */
2159 /* hardware.                                                                */
2160 /*                                                                          */
2161 /* Returns:                                                                 */
2162 /*   0 for success, positive value for failure.                             */
2163 /****************************************************************************/
2164 static int
2165 bce_dma_alloc(struct bce_softc *sc)
2166 {
2167         struct ifnet *ifp = &sc->arpcom.ac_if;
2168         int i, j, rc = 0;
2169         bus_addr_t busaddr;
2170
2171         /*
2172          * Allocate the parent bus DMA tag appropriate for PCI.
2173          */
2174         rc = bus_dma_tag_create(NULL, 1, BCE_DMA_BOUNDARY,
2175                                 sc->max_bus_addr, BUS_SPACE_MAXADDR,
2176                                 NULL, NULL,
2177                                 BUS_SPACE_MAXSIZE_32BIT, 0,
2178                                 BUS_SPACE_MAXSIZE_32BIT,
2179                                 0, &sc->parent_tag);
2180         if (rc != 0) {
2181                 if_printf(ifp, "Could not allocate parent DMA tag!\n");
2182                 return rc;
2183         }
2184
2185         /*
2186          * Allocate status block.
2187          */
2188         sc->status_block = bus_dmamem_coherent_any(sc->parent_tag,
2189                                 BCE_DMA_ALIGN, BCE_STATUS_BLK_SZ,
2190                                 BUS_DMA_WAITOK | BUS_DMA_ZERO,
2191                                 &sc->status_tag, &sc->status_map,
2192                                 &sc->status_block_paddr);
2193         if (sc->status_block == NULL) {
2194                 if_printf(ifp, "Could not allocate status block!\n");
2195                 return ENOMEM;
2196         }
2197
2198         /*
2199          * Allocate statistics block.
2200          */
2201         sc->stats_block = bus_dmamem_coherent_any(sc->parent_tag,
2202                                 BCE_DMA_ALIGN, BCE_STATS_BLK_SZ,
2203                                 BUS_DMA_WAITOK | BUS_DMA_ZERO,
2204                                 &sc->stats_tag, &sc->stats_map,
2205                                 &sc->stats_block_paddr);
2206         if (sc->stats_block == NULL) {
2207                 if_printf(ifp, "Could not allocate statistics block!\n");
2208                 return ENOMEM;
2209         }
2210
2211         /*
2212          * Create a DMA tag for the TX buffer descriptor chain,
2213          * allocate and clear the  memory, and fetch the
2214          * physical address of the block.
2215          */
2216         rc = bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE, 0,
2217                                 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
2218                                 NULL, NULL,
2219                                 BCE_TX_CHAIN_PAGE_SZ, 1, BCE_TX_CHAIN_PAGE_SZ,
2220                                 0, &sc->tx_bd_chain_tag);
2221         if (rc != 0) {
2222                 if_printf(ifp, "Could not allocate "
2223                           "TX descriptor chain DMA tag!\n");
2224                 return rc;
2225         }
2226
2227         for (i = 0; i < TX_PAGES; i++) {
2228                 rc = bus_dmamem_alloc(sc->tx_bd_chain_tag,
2229                                       (void **)&sc->tx_bd_chain[i],
2230                                       BUS_DMA_WAITOK | BUS_DMA_ZERO |
2231                                       BUS_DMA_COHERENT,
2232                                       &sc->tx_bd_chain_map[i]);
2233                 if (rc != 0) {
2234                         if_printf(ifp, "Could not allocate %dth TX descriptor "
2235                                   "chain DMA memory!\n", i);
2236                         return rc;
2237                 }
2238
2239                 rc = bus_dmamap_load(sc->tx_bd_chain_tag,
2240                                      sc->tx_bd_chain_map[i],
2241                                      sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ,
2242                                      bce_dma_map_addr, &busaddr,
2243                                      BUS_DMA_WAITOK);
2244                 if (rc != 0) {
2245                         if (rc == EINPROGRESS) {
2246                                 panic("%s coherent memory loading "
2247                                       "is still in progress!", ifp->if_xname);
2248                         }
2249                         if_printf(ifp, "Could not map %dth TX descriptor "
2250                                   "chain DMA memory!\n", i);
2251                         bus_dmamem_free(sc->tx_bd_chain_tag,
2252                                         sc->tx_bd_chain[i],
2253                                         sc->tx_bd_chain_map[i]);
2254                         sc->tx_bd_chain[i] = NULL;
2255                         return rc;
2256                 }
2257
2258                 sc->tx_bd_chain_paddr[i] = busaddr;
2259                 /* DRC - Fix for 64 bit systems. */
2260                 DBPRINT(sc, BCE_INFO, "tx_bd_chain_paddr[%d] = 0x%08X\n", 
2261                         i, (uint32_t)sc->tx_bd_chain_paddr[i]);
2262         }
2263
2264         /* Create a DMA tag for TX mbufs. */
2265         rc = bus_dma_tag_create(sc->parent_tag, 1, 0,
2266                                 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
2267                                 NULL, NULL,
2268                                 /* BCE_MAX_JUMBO_ETHER_MTU_VLAN */MCLBYTES,
2269                                 BCE_MAX_SEGMENTS, MCLBYTES,
2270                                 BUS_DMA_ALLOCNOW | BUS_DMA_WAITOK |
2271                                 BUS_DMA_ONEBPAGE,
2272                                 &sc->tx_mbuf_tag);
2273         if (rc != 0) {
2274                 if_printf(ifp, "Could not allocate TX mbuf DMA tag!\n");
2275                 return rc;
2276         }
2277
2278         /* Create DMA maps for the TX mbufs clusters. */
2279         for (i = 0; i < TOTAL_TX_BD; i++) {
2280                 rc = bus_dmamap_create(sc->tx_mbuf_tag,
2281                                        BUS_DMA_WAITOK | BUS_DMA_ONEBPAGE,
2282                                        &sc->tx_mbuf_map[i]);
2283                 if (rc != 0) {
2284                         for (j = 0; j < i; ++j) {
2285                                 bus_dmamap_destroy(sc->tx_mbuf_tag,
2286                                                    sc->tx_mbuf_map[i]);
2287                         }
2288                         bus_dma_tag_destroy(sc->tx_mbuf_tag);
2289                         sc->tx_mbuf_tag = NULL;
2290
2291                         if_printf(ifp, "Unable to create "
2292                                   "%dth TX mbuf DMA map!\n", i);
2293                         return rc;
2294                 }
2295         }
2296
2297         /*
2298          * Create a DMA tag for the RX buffer descriptor chain,
2299          * allocate and clear the  memory, and fetch the physical
2300          * address of the blocks.
2301          */
2302         rc = bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE, 0,
2303                                 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
2304                                 NULL, NULL,
2305                                 BCE_RX_CHAIN_PAGE_SZ, 1, BCE_RX_CHAIN_PAGE_SZ,
2306                                 0, &sc->rx_bd_chain_tag);
2307         if (rc != 0) {
2308                 if_printf(ifp, "Could not allocate "
2309                           "RX descriptor chain DMA tag!\n");
2310                 return rc;
2311         }
2312
2313         for (i = 0; i < RX_PAGES; i++) {
2314                 rc = bus_dmamem_alloc(sc->rx_bd_chain_tag,
2315                                       (void **)&sc->rx_bd_chain[i],
2316                                       BUS_DMA_WAITOK | BUS_DMA_ZERO |
2317                                       BUS_DMA_COHERENT,
2318                                       &sc->rx_bd_chain_map[i]);
2319                 if (rc != 0) {
2320                         if_printf(ifp, "Could not allocate %dth RX descriptor "
2321                                   "chain DMA memory!\n", i);
2322                         return rc;
2323                 }
2324
2325                 rc = bus_dmamap_load(sc->rx_bd_chain_tag,
2326                                      sc->rx_bd_chain_map[i],
2327                                      sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ,
2328                                      bce_dma_map_addr, &busaddr,
2329                                      BUS_DMA_WAITOK);
2330                 if (rc != 0) {
2331                         if (rc == EINPROGRESS) {
2332                                 panic("%s coherent memory loading "
2333                                       "is still in progress!", ifp->if_xname);
2334                         }
2335                         if_printf(ifp, "Could not map %dth RX descriptor "
2336                                   "chain DMA memory!\n", i);
2337                         bus_dmamem_free(sc->rx_bd_chain_tag,
2338                                         sc->rx_bd_chain[i],
2339                                         sc->rx_bd_chain_map[i]);
2340                         sc->rx_bd_chain[i] = NULL;
2341                         return rc;
2342                 }
2343
2344                 sc->rx_bd_chain_paddr[i] = busaddr;
2345                 /* DRC - Fix for 64 bit systems. */
2346                 DBPRINT(sc, BCE_INFO, "rx_bd_chain_paddr[%d] = 0x%08X\n",
2347                         i, (uint32_t)sc->rx_bd_chain_paddr[i]);
2348         }
2349
2350         /* Create a DMA tag for RX mbufs. */
2351         rc = bus_dma_tag_create(sc->parent_tag, 1, 0,
2352                                 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR,
2353                                 NULL, NULL,
2354                                 MCLBYTES, 1, MCLBYTES,
2355                                 BUS_DMA_ALLOCNOW | BUS_DMA_WAITOK,
2356                                 &sc->rx_mbuf_tag);
2357         if (rc != 0) {
2358                 if_printf(ifp, "Could not allocate RX mbuf DMA tag!\n");
2359                 return rc;
2360         }
2361
2362         /* Create tmp DMA map for RX mbuf clusters. */
2363         rc = bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_WAITOK,
2364                                &sc->rx_mbuf_tmpmap);
2365         if (rc != 0) {
2366                 bus_dma_tag_destroy(sc->rx_mbuf_tag);
2367                 sc->rx_mbuf_tag = NULL;
2368
2369                 if_printf(ifp, "Could not create RX mbuf tmp DMA map!\n");
2370                 return rc;
2371         }
2372
2373         /* Create DMA maps for the RX mbuf clusters. */
2374         for (i = 0; i < TOTAL_RX_BD; i++) {
2375                 rc = bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_WAITOK,
2376                                        &sc->rx_mbuf_map[i]);
2377                 if (rc != 0) {
2378                         for (j = 0; j < i; ++j) {
2379                                 bus_dmamap_destroy(sc->rx_mbuf_tag,
2380                                                    sc->rx_mbuf_map[j]);
2381                         }
2382                         bus_dma_tag_destroy(sc->rx_mbuf_tag);
2383                         sc->rx_mbuf_tag = NULL;
2384
2385                         if_printf(ifp, "Unable to create "
2386                                   "%dth RX mbuf DMA map!\n", i);
2387                         return rc;
2388                 }
2389         }
2390         return 0;
2391 }
2392
2393
2394 /****************************************************************************/
2395 /* Firmware synchronization.                                                */
2396 /*                                                                          */
2397 /* Before performing certain events such as a chip reset, synchronize with  */
2398 /* the firmware first.                                                      */
2399 /*                                                                          */
2400 /* Returns:                                                                 */
2401 /*   0 for success, positive value for failure.                             */
2402 /****************************************************************************/
2403 static int
2404 bce_fw_sync(struct bce_softc *sc, uint32_t msg_data)
2405 {
2406         int i, rc = 0;
2407         uint32_t val;
2408
2409         /* Don't waste any time if we've timed out before. */
2410         if (sc->bce_fw_timed_out)
2411                 return EBUSY;
2412
2413         /* Increment the message sequence number. */
2414         sc->bce_fw_wr_seq++;
2415         msg_data |= sc->bce_fw_wr_seq;
2416
2417         DBPRINT(sc, BCE_VERBOSE, "bce_fw_sync(): msg_data = 0x%08X\n", msg_data);
2418
2419         /* Send the message to the bootcode driver mailbox. */
2420         REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_MB, msg_data);
2421
2422         /* Wait for the bootcode to acknowledge the message. */
2423         for (i = 0; i < FW_ACK_TIME_OUT_MS; i++) {
2424                 /* Check for a response in the bootcode firmware mailbox. */
2425                 val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_FW_MB);
2426                 if ((val & BCE_FW_MSG_ACK) == (msg_data & BCE_DRV_MSG_SEQ))
2427                         break;
2428                 DELAY(1000);
2429         }
2430
2431         /* If we've timed out, tell the bootcode that we've stopped waiting. */
2432         if ((val & BCE_FW_MSG_ACK) != (msg_data & BCE_DRV_MSG_SEQ) &&
2433             (msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0) {
2434                 if_printf(&sc->arpcom.ac_if,
2435                           "Firmware synchronization timeout! "
2436                           "msg_data = 0x%08X\n", msg_data);
2437
2438                 msg_data &= ~BCE_DRV_MSG_CODE;
2439                 msg_data |= BCE_DRV_MSG_CODE_FW_TIMEOUT;
2440
2441                 REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_MB, msg_data);
2442
2443                 sc->bce_fw_timed_out = 1;
2444                 rc = EBUSY;
2445         }
2446         return rc;
2447 }
2448
2449
2450 /****************************************************************************/
2451 /* Load Receive Virtual 2 Physical (RV2P) processor firmware.               */
2452 /*                                                                          */
2453 /* Returns:                                                                 */
2454 /*   Nothing.                                                               */
2455 /****************************************************************************/
2456 static void
2457 bce_load_rv2p_fw(struct bce_softc *sc, uint32_t *rv2p_code,
2458                  uint32_t rv2p_code_len, uint32_t rv2p_proc)
2459 {
2460         int i;
2461         uint32_t val;
2462
2463         for (i = 0; i < rv2p_code_len; i += 8) {
2464                 REG_WR(sc, BCE_RV2P_INSTR_HIGH, *rv2p_code);
2465                 rv2p_code++;
2466                 REG_WR(sc, BCE_RV2P_INSTR_LOW, *rv2p_code);
2467                 rv2p_code++;
2468
2469                 if (rv2p_proc == RV2P_PROC1) {
2470                         val = (i / 8) | BCE_RV2P_PROC1_ADDR_CMD_RDWR;
2471                         REG_WR(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
2472                 } else {
2473                         val = (i / 8) | BCE_RV2P_PROC2_ADDR_CMD_RDWR;
2474                         REG_WR(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
2475                 }
2476         }
2477
2478         /* Reset the processor, un-stall is done later. */
2479         if (rv2p_proc == RV2P_PROC1)
2480                 REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC1_RESET);
2481         else
2482                 REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC2_RESET);
2483 }
2484
2485
2486 /****************************************************************************/
2487 /* Load RISC processor firmware.                                            */
2488 /*                                                                          */
2489 /* Loads firmware from the file if_bcefw.h into the scratchpad memory       */
2490 /* associated with a particular processor.                                  */
2491 /*                                                                          */
2492 /* Returns:                                                                 */
2493 /*   Nothing.                                                               */
2494 /****************************************************************************/
2495 static void
2496 bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
2497                 struct fw_info *fw)
2498 {
2499         uint32_t offset, val;
2500         int j;
2501
2502         /* Halt the CPU. */
2503         val = REG_RD_IND(sc, cpu_reg->mode);
2504         val |= cpu_reg->mode_value_halt;
2505         REG_WR_IND(sc, cpu_reg->mode, val);
2506         REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
2507
2508         /* Load the Text area. */
2509         offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
2510         if (fw->text) {
2511                 for (j = 0; j < (fw->text_len / 4); j++, offset += 4)
2512                         REG_WR_IND(sc, offset, fw->text[j]);
2513         }
2514
2515         /* Load the Data area. */
2516         offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
2517         if (fw->data) {
2518                 for (j = 0; j < (fw->data_len / 4); j++, offset += 4)
2519                         REG_WR_IND(sc, offset, fw->data[j]);
2520         }
2521
2522         /* Load the SBSS area. */
2523         offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
2524         if (fw->sbss) {
2525                 for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4)
2526                         REG_WR_IND(sc, offset, fw->sbss[j]);
2527         }
2528
2529         /* Load the BSS area. */
2530         offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
2531         if (fw->bss) {
2532                 for (j = 0; j < (fw->bss_len/4); j++, offset += 4)
2533                         REG_WR_IND(sc, offset, fw->bss[j]);
2534         }
2535
2536         /* Load the Read-Only area. */
2537         offset = cpu_reg->spad_base +
2538                 (fw->rodata_addr - cpu_reg->mips_view_base);
2539         if (fw->rodata) {
2540                 for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4)
2541                         REG_WR_IND(sc, offset, fw->rodata[j]);
2542         }
2543
2544         /* Clear the pre-fetch instruction. */
2545         REG_WR_IND(sc, cpu_reg->inst, 0);
2546         REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
2547
2548         /* Start the CPU. */
2549         val = REG_RD_IND(sc, cpu_reg->mode);
2550         val &= ~cpu_reg->mode_value_halt;
2551         REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
2552         REG_WR_IND(sc, cpu_reg->mode, val);
2553 }
2554
2555
2556 /****************************************************************************/
2557 /* Initialize the RV2P, RX, TX, TPAT, and COM CPUs.                         */
2558 /*                                                                          */
2559 /* Loads the firmware for each CPU and starts the CPU.                      */
2560 /*                                                                          */
2561 /* Returns:                                                                 */
2562 /*   Nothing.                                                               */
2563 /****************************************************************************/
2564 static void
2565 bce_init_cpus(struct bce_softc *sc)
2566 {
2567         struct cpu_reg cpu_reg;
2568         struct fw_info fw;
2569
2570         /* Initialize the RV2P processor. */
2571         bce_load_rv2p_fw(sc, bce_rv2p_proc1, sizeof(bce_rv2p_proc1), RV2P_PROC1);
2572         bce_load_rv2p_fw(sc, bce_rv2p_proc2, sizeof(bce_rv2p_proc2), RV2P_PROC2);
2573
2574         /* Initialize the RX Processor. */
2575         cpu_reg.mode = BCE_RXP_CPU_MODE;
2576         cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
2577         cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
2578         cpu_reg.state = BCE_RXP_CPU_STATE;
2579         cpu_reg.state_value_clear = 0xffffff;
2580         cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
2581         cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
2582         cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
2583         cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
2584         cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
2585         cpu_reg.spad_base = BCE_RXP_SCRATCH;
2586         cpu_reg.mips_view_base = 0x8000000;
2587
2588         fw.ver_major = bce_RXP_b06FwReleaseMajor;
2589         fw.ver_minor = bce_RXP_b06FwReleaseMinor;
2590         fw.ver_fix = bce_RXP_b06FwReleaseFix;
2591         fw.start_addr = bce_RXP_b06FwStartAddr;
2592
2593         fw.text_addr = bce_RXP_b06FwTextAddr;
2594         fw.text_len = bce_RXP_b06FwTextLen;
2595         fw.text_index = 0;
2596         fw.text = bce_RXP_b06FwText;
2597
2598         fw.data_addr = bce_RXP_b06FwDataAddr;
2599         fw.data_len = bce_RXP_b06FwDataLen;
2600         fw.data_index = 0;
2601         fw.data = bce_RXP_b06FwData;
2602
2603         fw.sbss_addr = bce_RXP_b06FwSbssAddr;
2604         fw.sbss_len = bce_RXP_b06FwSbssLen;
2605         fw.sbss_index = 0;
2606         fw.sbss = bce_RXP_b06FwSbss;
2607
2608         fw.bss_addr = bce_RXP_b06FwBssAddr;
2609         fw.bss_len = bce_RXP_b06FwBssLen;
2610         fw.bss_index = 0;
2611         fw.bss = bce_RXP_b06FwBss;
2612
2613         fw.rodata_addr = bce_RXP_b06FwRodataAddr;
2614         fw.rodata_len = bce_RXP_b06FwRodataLen;
2615         fw.rodata_index = 0;
2616         fw.rodata = bce_RXP_b06FwRodata;
2617
2618         DBPRINT(sc, BCE_INFO_RESET, "Loading RX firmware.\n");
2619         bce_load_cpu_fw(sc, &cpu_reg, &fw);
2620
2621         /* Initialize the TX Processor. */
2622         cpu_reg.mode = BCE_TXP_CPU_MODE;
2623         cpu_reg.mode_value_halt = BCE_TXP_CPU_MODE_SOFT_HALT;
2624         cpu_reg.mode_value_sstep = BCE_TXP_CPU_MODE_STEP_ENA;
2625         cpu_reg.state = BCE_TXP_CPU_STATE;
2626         cpu_reg.state_value_clear = 0xffffff;
2627         cpu_reg.gpr0 = BCE_TXP_CPU_REG_FILE;
2628         cpu_reg.evmask = BCE_TXP_CPU_EVENT_MASK;
2629         cpu_reg.pc = BCE_TXP_CPU_PROGRAM_COUNTER;
2630         cpu_reg.inst = BCE_TXP_CPU_INSTRUCTION;
2631         cpu_reg.bp = BCE_TXP_CPU_HW_BREAKPOINT;
2632         cpu_reg.spad_base = BCE_TXP_SCRATCH;
2633         cpu_reg.mips_view_base = 0x8000000;
2634
2635         fw.ver_major = bce_TXP_b06FwReleaseMajor;
2636         fw.ver_minor = bce_TXP_b06FwReleaseMinor;
2637         fw.ver_fix = bce_TXP_b06FwReleaseFix;
2638         fw.start_addr = bce_TXP_b06FwStartAddr;
2639
2640         fw.text_addr = bce_TXP_b06FwTextAddr;
2641         fw.text_len = bce_TXP_b06FwTextLen;
2642         fw.text_index = 0;
2643         fw.text = bce_TXP_b06FwText;
2644
2645         fw.data_addr = bce_TXP_b06FwDataAddr;
2646         fw.data_len = bce_TXP_b06FwDataLen;
2647         fw.data_index = 0;
2648         fw.data = bce_TXP_b06FwData;
2649
2650         fw.sbss_addr = bce_TXP_b06FwSbssAddr;
2651         fw.sbss_len = bce_TXP_b06FwSbssLen;
2652         fw.sbss_index = 0;
2653         fw.sbss = bce_TXP_b06FwSbss;
2654
2655         fw.bss_addr = bce_TXP_b06FwBssAddr;
2656         fw.bss_len = bce_TXP_b06FwBssLen;
2657         fw.bss_index = 0;
2658         fw.bss = bce_TXP_b06FwBss;
2659
2660         fw.rodata_addr = bce_TXP_b06FwRodataAddr;
2661         fw.rodata_len = bce_TXP_b06FwRodataLen;
2662         fw.rodata_index = 0;
2663         fw.rodata = bce_TXP_b06FwRodata;
2664
2665         DBPRINT(sc, BCE_INFO_RESET, "Loading TX firmware.\n");
2666         bce_load_cpu_fw(sc, &cpu_reg, &fw);
2667
2668         /* Initialize the TX Patch-up Processor. */
2669         cpu_reg.mode = BCE_TPAT_CPU_MODE;
2670         cpu_reg.mode_value_halt = BCE_TPAT_CPU_MODE_SOFT_HALT;
2671         cpu_reg.mode_value_sstep = BCE_TPAT_CPU_MODE_STEP_ENA;
2672         cpu_reg.state = BCE_TPAT_CPU_STATE;
2673         cpu_reg.state_value_clear = 0xffffff;
2674         cpu_reg.gpr0 = BCE_TPAT_CPU_REG_FILE;
2675         cpu_reg.evmask = BCE_TPAT_CPU_EVENT_MASK;
2676         cpu_reg.pc = BCE_TPAT_CPU_PROGRAM_COUNTER;
2677         cpu_reg.inst = BCE_TPAT_CPU_INSTRUCTION;
2678         cpu_reg.bp = BCE_TPAT_CPU_HW_BREAKPOINT;
2679         cpu_reg.spad_base = BCE_TPAT_SCRATCH;
2680         cpu_reg.mips_view_base = 0x8000000;
2681
2682         fw.ver_major = bce_TPAT_b06FwReleaseMajor;
2683         fw.ver_minor = bce_TPAT_b06FwReleaseMinor;
2684         fw.ver_fix = bce_TPAT_b06FwReleaseFix;
2685         fw.start_addr = bce_TPAT_b06FwStartAddr;
2686
2687         fw.text_addr = bce_TPAT_b06FwTextAddr;
2688         fw.text_len = bce_TPAT_b06FwTextLen;
2689         fw.text_index = 0;
2690         fw.text = bce_TPAT_b06FwText;
2691
2692         fw.data_addr = bce_TPAT_b06FwDataAddr;
2693         fw.data_len = bce_TPAT_b06FwDataLen;
2694         fw.data_index = 0;
2695         fw.data = bce_TPAT_b06FwData;
2696
2697         fw.sbss_addr = bce_TPAT_b06FwSbssAddr;
2698         fw.sbss_len = bce_TPAT_b06FwSbssLen;
2699         fw.sbss_index = 0;
2700         fw.sbss = bce_TPAT_b06FwSbss;
2701
2702         fw.bss_addr = bce_TPAT_b06FwBssAddr;
2703         fw.bss_len = bce_TPAT_b06FwBssLen;
2704         fw.bss_index = 0;
2705         fw.bss = bce_TPAT_b06FwBss;
2706
2707         fw.rodata_addr = bce_TPAT_b06FwRodataAddr;
2708         fw.rodata_len = bce_TPAT_b06FwRodataLen;
2709         fw.rodata_index = 0;
2710         fw.rodata = bce_TPAT_b06FwRodata;
2711
2712         DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n");
2713         bce_load_cpu_fw(sc, &cpu_reg, &fw);
2714
2715         /* Initialize the Completion Processor. */
2716         cpu_reg.mode = BCE_COM_CPU_MODE;
2717         cpu_reg.mode_value_halt = BCE_COM_CPU_MODE_SOFT_HALT;
2718         cpu_reg.mode_value_sstep = BCE_COM_CPU_MODE_STEP_ENA;
2719         cpu_reg.state = BCE_COM_CPU_STATE;
2720         cpu_reg.state_value_clear = 0xffffff;
2721         cpu_reg.gpr0 = BCE_COM_CPU_REG_FILE;
2722         cpu_reg.evmask = BCE_COM_CPU_EVENT_MASK;
2723         cpu_reg.pc = BCE_COM_CPU_PROGRAM_COUNTER;
2724         cpu_reg.inst = BCE_COM_CPU_INSTRUCTION;
2725         cpu_reg.bp = BCE_COM_CPU_HW_BREAKPOINT;
2726         cpu_reg.spad_base = BCE_COM_SCRATCH;
2727         cpu_reg.mips_view_base = 0x8000000;
2728
2729         fw.ver_major = bce_COM_b06FwReleaseMajor;
2730         fw.ver_minor = bce_COM_b06FwReleaseMinor;
2731         fw.ver_fix = bce_COM_b06FwReleaseFix;
2732         fw.start_addr = bce_COM_b06FwStartAddr;
2733
2734         fw.text_addr = bce_COM_b06FwTextAddr;
2735         fw.text_len = bce_COM_b06FwTextLen;
2736         fw.text_index = 0;
2737         fw.text = bce_COM_b06FwText;
2738
2739         fw.data_addr = bce_COM_b06FwDataAddr;
2740         fw.data_len = bce_COM_b06FwDataLen;
2741         fw.data_index = 0;
2742         fw.data = bce_COM_b06FwData;
2743
2744         fw.sbss_addr = bce_COM_b06FwSbssAddr;
2745         fw.sbss_len = bce_COM_b06FwSbssLen;
2746         fw.sbss_index = 0;
2747         fw.sbss = bce_COM_b06FwSbss;
2748
2749         fw.bss_addr = bce_COM_b06FwBssAddr;
2750         fw.bss_len = bce_COM_b06FwBssLen;
2751         fw.bss_index = 0;
2752         fw.bss = bce_COM_b06FwBss;
2753
2754         fw.rodata_addr = bce_COM_b06FwRodataAddr;
2755         fw.rodata_len = bce_COM_b06FwRodataLen;
2756         fw.rodata_index = 0;
2757         fw.rodata = bce_COM_b06FwRodata;
2758
2759         DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n");
2760         bce_load_cpu_fw(sc, &cpu_reg, &fw);
2761 }
2762
2763
2764 /****************************************************************************/
2765 /* Initialize context memory.                                               */
2766 /*                                                                          */
2767 /* Clears the memory associated with each Context ID (CID).                 */
2768 /*                                                                          */
2769 /* Returns:                                                                 */
2770 /*   Nothing.                                                               */
2771 /****************************************************************************/
2772 static void
2773 bce_init_ctx(struct bce_softc *sc)
2774 {
2775         uint32_t vcid = 96;
2776
2777         while (vcid) {
2778                 uint32_t vcid_addr, pcid_addr, offset;
2779                 int i;
2780
2781                 vcid--;
2782
2783                 vcid_addr = GET_CID_ADDR(vcid);
2784                 pcid_addr = vcid_addr;
2785
2786                 for (i = 0; i < (CTX_SIZE / PHY_CTX_SIZE); i++) {
2787                         vcid_addr += (i << PHY_CTX_SHIFT);
2788                         pcid_addr += (i << PHY_CTX_SHIFT);
2789
2790                         REG_WR(sc, BCE_CTX_VIRT_ADDR, vcid_addr);
2791                         REG_WR(sc, BCE_CTX_PAGE_TBL, pcid_addr);
2792
2793                         /* Zero out the context. */
2794                         for (offset = 0; offset < PHY_CTX_SIZE; offset += 4)
2795                                 CTX_WR(sc, vcid_addr, offset, 0);
2796                 }
2797         }
2798 }
2799
2800
2801 /****************************************************************************/
2802 /* Fetch the permanent MAC address of the controller.                       */
2803 /*                                                                          */
2804 /* Returns:                                                                 */
2805 /*   Nothing.                                                               */
2806 /****************************************************************************/
2807 static void
2808 bce_get_mac_addr(struct bce_softc *sc)
2809 {
2810         uint32_t mac_lo = 0, mac_hi = 0;
2811
2812         /*
2813          * The NetXtreme II bootcode populates various NIC
2814          * power-on and runtime configuration items in a
2815          * shared memory area.  The factory configured MAC
2816          * address is available from both NVRAM and the
2817          * shared memory area so we'll read the value from
2818          * shared memory for speed.
2819          */
2820
2821         mac_hi = REG_RD_IND(sc, sc->bce_shmem_base + BCE_PORT_HW_CFG_MAC_UPPER);
2822         mac_lo = REG_RD_IND(sc, sc->bce_shmem_base + BCE_PORT_HW_CFG_MAC_LOWER);
2823
2824         if (mac_lo == 0 && mac_hi == 0) {
2825                 if_printf(&sc->arpcom.ac_if, "Invalid Ethernet address!\n");
2826         } else {
2827                 sc->eaddr[0] = (u_char)(mac_hi >> 8);
2828                 sc->eaddr[1] = (u_char)(mac_hi >> 0);
2829                 sc->eaddr[2] = (u_char)(mac_lo >> 24);
2830                 sc->eaddr[3] = (u_char)(mac_lo >> 16);
2831                 sc->eaddr[4] = (u_char)(mac_lo >> 8);
2832                 sc->eaddr[5] = (u_char)(mac_lo >> 0);
2833         }
2834
2835         DBPRINT(sc, BCE_INFO, "Permanent Ethernet address = %6D\n", sc->eaddr, ":");
2836 }
2837
2838
2839 /****************************************************************************/
2840 /* Program the MAC address.                                                 */
2841 /*                                                                          */
2842 /* Returns:                                                                 */
2843 /*   Nothing.                                                               */
2844 /****************************************************************************/
2845 static void
2846 bce_set_mac_addr(struct bce_softc *sc)
2847 {
2848         const uint8_t *mac_addr = sc->eaddr;
2849         uint32_t val;
2850
2851         DBPRINT(sc, BCE_INFO, "Setting Ethernet address = %6D\n",
2852                 sc->eaddr, ":");
2853
2854         val = (mac_addr[0] << 8) | mac_addr[1];
2855         REG_WR(sc, BCE_EMAC_MAC_MATCH0, val);
2856
2857         val = (mac_addr[2] << 24) |
2858               (mac_addr[3] << 16) |
2859               (mac_addr[4] << 8) |
2860               mac_addr[5];
2861         REG_WR(sc, BCE_EMAC_MAC_MATCH1, val);
2862 }
2863
2864
2865 /****************************************************************************/
2866 /* Stop the controller.                                                     */
2867 /*                                                                          */
2868 /* Returns:                                                                 */
2869 /*   Nothing.                                                               */
2870 /****************************************************************************/
2871 static void
2872 bce_stop(struct bce_softc *sc)
2873 {
2874         struct ifnet *ifp = &sc->arpcom.ac_if;
2875         struct mii_data *mii = device_get_softc(sc->bce_miibus);
2876         struct ifmedia_entry *ifm;
2877         int mtmp, itmp;
2878
2879         ASSERT_SERIALIZED(ifp->if_serializer);
2880
2881         callout_stop(&sc->bce_stat_ch);
2882
2883         /* Disable the transmit/receive blocks. */
2884         REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS, 0x5ffffff);
2885         REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
2886         DELAY(20);
2887
2888         bce_disable_intr(sc);
2889
2890         /* Tell firmware that the driver is going away. */
2891         bce_reset(sc, BCE_DRV_MSG_CODE_SUSPEND_NO_WOL);
2892
2893         /* Free the RX lists. */
2894         bce_free_rx_chain(sc);
2895
2896         /* Free TX buffers. */
2897         bce_free_tx_chain(sc);
2898
2899         /*
2900          * Isolate/power down the PHY, but leave the media selection
2901          * unchanged so that things will be put back to normal when
2902          * we bring the interface back up.
2903          *
2904          * 'mii' may be NULL if bce_stop() is called by bce_detach().
2905          */
2906         if (mii != NULL) {
2907                 itmp = ifp->if_flags;
2908                 ifp->if_flags |= IFF_UP;
2909                 ifm = mii->mii_media.ifm_cur;
2910                 mtmp = ifm->ifm_media;
2911                 ifm->ifm_media = IFM_ETHER | IFM_NONE;
2912                 mii_mediachg(mii);
2913                 ifm->ifm_media = mtmp;
2914                 ifp->if_flags = itmp;
2915         }
2916
2917         sc->bce_link = 0;
2918         sc->bce_coalchg_mask = 0;
2919
2920         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
2921         ifp->if_timer = 0;
2922
2923         bce_mgmt_init(sc);
2924 }
2925
2926
2927 static int
2928 bce_reset(struct bce_softc *sc, uint32_t reset_code)
2929 {
2930         uint32_t val;
2931         int i, rc = 0;
2932
2933         /* Wait for pending PCI transactions to complete. */
2934         REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS,
2935                BCE_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
2936                BCE_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
2937                BCE_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
2938                BCE_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
2939         val = REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
2940         DELAY(5);
2941
2942         /* Assume bootcode is running. */
2943         sc->bce_fw_timed_out = 0;
2944
2945         /* Give the firmware a chance to prepare for the reset. */
2946         rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT0 | reset_code);
2947         if (rc) {
2948                 if_printf(&sc->arpcom.ac_if,
2949                           "Firmware is not ready for reset\n");
2950                 return rc;
2951         }
2952
2953         /* Set a firmware reminder that this is a soft reset. */
2954         REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_RESET_SIGNATURE,
2955                    BCE_DRV_RESET_SIGNATURE_MAGIC);
2956
2957         /* Dummy read to force the chip to complete all current transactions. */
2958         val = REG_RD(sc, BCE_MISC_ID);
2959
2960         /* Chip reset. */
2961         val = BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
2962               BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
2963               BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
2964         REG_WR(sc, BCE_PCICFG_MISC_CONFIG, val);
2965
2966         /* Allow up to 30us for reset to complete. */
2967         for (i = 0; i < 10; i++) {
2968                 val = REG_RD(sc, BCE_PCICFG_MISC_CONFIG);
2969                 if ((val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
2970                             BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
2971                         break;
2972                 }
2973                 DELAY(10);
2974         }
2975
2976         /* Check that reset completed successfully. */
2977         if (val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
2978                    BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
2979                 if_printf(&sc->arpcom.ac_if, "Reset failed!\n");
2980                 return EBUSY;
2981         }
2982
2983         /* Make sure byte swapping is properly configured. */
2984         val = REG_RD(sc, BCE_PCI_SWAP_DIAG0);
2985         if (val != 0x01020304) {
2986                 if_printf(&sc->arpcom.ac_if, "Byte swap is incorrect!\n");
2987                 return ENODEV;
2988         }
2989
2990         /* Just completed a reset, assume that firmware is running again. */
2991         sc->bce_fw_timed_out = 0;
2992
2993         /* Wait for the firmware to finish its initialization. */
2994         rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT1 | reset_code);
2995         if (rc) {
2996                 if_printf(&sc->arpcom.ac_if,
2997                           "Firmware did not complete initialization!\n");
2998         }
2999         return rc;
3000 }
3001
3002
3003 static int
3004 bce_chipinit(struct bce_softc *sc)
3005 {
3006         uint32_t val;
3007         int rc = 0;
3008
3009         /* Make sure the interrupt is not active. */
3010         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_MASK_INT);
3011
3012         /*
3013          * Initialize DMA byte/word swapping, configure the number of DMA
3014          * channels and PCI clock compensation delay.
3015          */
3016         val = BCE_DMA_CONFIG_DATA_BYTE_SWAP |
3017               BCE_DMA_CONFIG_DATA_WORD_SWAP |
3018 #if BYTE_ORDER == BIG_ENDIAN
3019               BCE_DMA_CONFIG_CNTL_BYTE_SWAP |
3020 #endif
3021               BCE_DMA_CONFIG_CNTL_WORD_SWAP |
3022               DMA_READ_CHANS << 12 |
3023               DMA_WRITE_CHANS << 16;
3024
3025         val |= (0x2 << 20) | BCE_DMA_CONFIG_CNTL_PCI_COMP_DLY;
3026
3027         if ((sc->bce_flags & BCE_PCIX_FLAG) && sc->bus_speed_mhz == 133)
3028                 val |= BCE_DMA_CONFIG_PCI_FAST_CLK_CMP;
3029
3030         /*
3031          * This setting resolves a problem observed on certain Intel PCI
3032          * chipsets that cannot handle multiple outstanding DMA operations.
3033          * See errata E9_5706A1_65.
3034          */
3035         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706 &&
3036             BCE_CHIP_ID(sc) != BCE_CHIP_ID_5706_A0 &&
3037             !(sc->bce_flags & BCE_PCIX_FLAG))
3038                 val |= BCE_DMA_CONFIG_CNTL_PING_PONG_DMA;
3039
3040         REG_WR(sc, BCE_DMA_CONFIG, val);
3041
3042         /* Clear the PCI-X relaxed ordering bit. See errata E3_5708CA0_570. */
3043         if (sc->bce_flags & BCE_PCIX_FLAG) {
3044                 uint16_t cmd;
3045
3046                 cmd = pci_read_config(sc->bce_dev, BCE_PCI_PCIX_CMD, 2);
3047                 pci_write_config(sc->bce_dev, BCE_PCI_PCIX_CMD, cmd & ~0x2, 2);
3048         }
3049
3050         /* Enable the RX_V2P and Context state machines before access. */
3051         REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
3052                BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
3053                BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
3054                BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
3055
3056         /* Initialize context mapping and zero out the quick contexts. */
3057         bce_init_ctx(sc);
3058
3059         /* Initialize the on-boards CPUs */
3060         bce_init_cpus(sc);
3061
3062         /* Prepare NVRAM for access. */
3063         rc = bce_init_nvram(sc);
3064         if (rc != 0)
3065                 return rc;
3066
3067         /* Set the kernel bypass block size */
3068         val = REG_RD(sc, BCE_MQ_CONFIG);
3069         val &= ~BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE;
3070         val |= BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
3071         REG_WR(sc, BCE_MQ_CONFIG, val);
3072
3073         val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
3074         REG_WR(sc, BCE_MQ_KNL_BYP_WIND_START, val);
3075         REG_WR(sc, BCE_MQ_KNL_WIND_END, val);
3076
3077         /* Set the page size and clear the RV2P processor stall bits. */
3078         val = (BCM_PAGE_BITS - 8) << 24;
3079         REG_WR(sc, BCE_RV2P_CONFIG, val);
3080
3081         /* Configure page size. */
3082         val = REG_RD(sc, BCE_TBDR_CONFIG);
3083         val &= ~BCE_TBDR_CONFIG_PAGE_SIZE;
3084         val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
3085         REG_WR(sc, BCE_TBDR_CONFIG, val);
3086
3087         return 0;
3088 }
3089
3090
3091 /****************************************************************************/
3092 /* Initialize the controller in preparation to send/receive traffic.        */
3093 /*                                                                          */
3094 /* Returns:                                                                 */
3095 /*   0 for success, positive value for failure.                             */
3096 /****************************************************************************/
3097 static int
3098 bce_blockinit(struct bce_softc *sc)
3099 {
3100         uint32_t reg, val;
3101         int rc = 0;
3102
3103         /* Load the hardware default MAC address. */
3104         bce_set_mac_addr(sc);
3105
3106         /* Set the Ethernet backoff seed value */
3107         val = sc->eaddr[0] + (sc->eaddr[1] << 8) + (sc->eaddr[2] << 16) +
3108               sc->eaddr[3] + (sc->eaddr[4] << 8) + (sc->eaddr[5] << 16);
3109         REG_WR(sc, BCE_EMAC_BACKOFF_SEED, val);
3110
3111         sc->last_status_idx = 0;
3112         sc->rx_mode = BCE_EMAC_RX_MODE_SORT_MODE;
3113
3114         /* Set up link change interrupt generation. */
3115         REG_WR(sc, BCE_EMAC_ATTENTION_ENA, BCE_EMAC_ATTENTION_ENA_LINK);
3116
3117         /* Program the physical address of the status block. */
3118         REG_WR(sc, BCE_HC_STATUS_ADDR_L, BCE_ADDR_LO(sc->status_block_paddr));
3119         REG_WR(sc, BCE_HC_STATUS_ADDR_H, BCE_ADDR_HI(sc->status_block_paddr));
3120
3121         /* Program the physical address of the statistics block. */
3122         REG_WR(sc, BCE_HC_STATISTICS_ADDR_L,
3123                BCE_ADDR_LO(sc->stats_block_paddr));
3124         REG_WR(sc, BCE_HC_STATISTICS_ADDR_H,
3125                BCE_ADDR_HI(sc->stats_block_paddr));
3126
3127         /* Program various host coalescing parameters. */
3128         REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
3129                (sc->bce_tx_quick_cons_trip_int << 16) |
3130                sc->bce_tx_quick_cons_trip);
3131         REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
3132                (sc->bce_rx_quick_cons_trip_int << 16) |
3133                sc->bce_rx_quick_cons_trip);
3134         REG_WR(sc, BCE_HC_COMP_PROD_TRIP,
3135                (sc->bce_comp_prod_trip_int << 16) | sc->bce_comp_prod_trip);
3136         REG_WR(sc, BCE_HC_TX_TICKS,
3137                (sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
3138         REG_WR(sc, BCE_HC_RX_TICKS,
3139                (sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
3140         REG_WR(sc, BCE_HC_COM_TICKS,
3141                (sc->bce_com_ticks_int << 16) | sc->bce_com_ticks);
3142         REG_WR(sc, BCE_HC_CMD_TICKS,
3143                (sc->bce_cmd_ticks_int << 16) | sc->bce_cmd_ticks);
3144         REG_WR(sc, BCE_HC_STATS_TICKS, (sc->bce_stats_ticks & 0xffff00));
3145         REG_WR(sc, BCE_HC_STAT_COLLECT_TICKS, 0xbb8);   /* 3ms */
3146         REG_WR(sc, BCE_HC_CONFIG,
3147                BCE_HC_CONFIG_TX_TMR_MODE |
3148                BCE_HC_CONFIG_COLLECT_STATS);
3149
3150         /* Clear the internal statistics counters. */
3151         REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
3152
3153         /* Verify that bootcode is running. */
3154         reg = REG_RD_IND(sc, sc->bce_shmem_base + BCE_DEV_INFO_SIGNATURE);
3155
3156         DBRUNIF(DB_RANDOMTRUE(bce_debug_bootcode_running_failure),
3157                 if_printf(&sc->arpcom.ac_if,
3158                           "%s(%d): Simulating bootcode failure.\n",
3159                           __FILE__, __LINE__);
3160                 reg = 0);
3161
3162         if ((reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
3163             BCE_DEV_INFO_SIGNATURE_MAGIC) {
3164                 if_printf(&sc->arpcom.ac_if,
3165                           "Bootcode not running! Found: 0x%08X, "
3166                           "Expected: 08%08X\n",
3167                           reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK,
3168                           BCE_DEV_INFO_SIGNATURE_MAGIC);
3169                 return ENODEV;
3170         }
3171
3172         /* Check if any management firmware is running. */
3173         reg = REG_RD_IND(sc, sc->bce_shmem_base + BCE_PORT_FEATURE);
3174         if (reg & (BCE_PORT_FEATURE_ASF_ENABLED |
3175                    BCE_PORT_FEATURE_IMD_ENABLED)) {
3176                 DBPRINT(sc, BCE_INFO, "Management F/W Enabled.\n");
3177                 sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
3178         }
3179
3180         sc->bce_fw_ver =
3181                 REG_RD_IND(sc, sc->bce_shmem_base + BCE_DEV_INFO_BC_REV);
3182         DBPRINT(sc, BCE_INFO, "bootcode rev = 0x%08X\n", sc->bce_fw_ver);
3183
3184         /* Allow bootcode to apply any additional fixes before enabling MAC. */
3185         rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 | BCE_DRV_MSG_CODE_RESET);
3186
3187         /* Enable link state change interrupt generation. */
3188         REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
3189
3190         /* Enable all remaining blocks in the MAC. */
3191         REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, 0x5ffffff);
3192         REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
3193         DELAY(20);
3194
3195         return 0;
3196 }
3197
3198
3199 /****************************************************************************/
3200 /* Encapsulate an mbuf cluster into the rx_bd chain.                        */
3201 /*                                                                          */
3202 /* The NetXtreme II can support Jumbo frames by using multiple rx_bd's.     */
3203 /* This routine will map an mbuf cluster into 1 or more rx_bd's as          */
3204 /* necessary.                                                               */
3205 /*                                                                          */
3206 /* Returns:                                                                 */
3207 /*   0 for success, positive value for failure.                             */
3208 /****************************************************************************/
3209 static int
3210 bce_newbuf_std(struct bce_softc *sc, uint16_t *prod, uint16_t *chain_prod,
3211                uint32_t *prod_bseq, int init)
3212 {
3213         bus_dmamap_t map;
3214         bus_dma_segment_t seg;
3215         struct mbuf *m_new;
3216         int error, nseg;
3217 #ifdef BCE_DEBUG
3218         uint16_t debug_chain_prod = *chain_prod;
3219 #endif
3220
3221         /* Make sure the inputs are valid. */
3222         DBRUNIF((*chain_prod > MAX_RX_BD),
3223                 if_printf(&sc->arpcom.ac_if, "%s(%d): "
3224                           "RX producer out of range: 0x%04X > 0x%04X\n",
3225                           __FILE__, __LINE__,
3226                           *chain_prod, (uint16_t)MAX_RX_BD));
3227
3228         DBPRINT(sc, BCE_VERBOSE_RECV, "%s(enter): prod = 0x%04X, chain_prod = 0x%04X, "
3229                 "prod_bseq = 0x%08X\n", __func__, *prod, *chain_prod, *prod_bseq);
3230
3231         DBRUNIF(DB_RANDOMTRUE(bce_debug_mbuf_allocation_failure),
3232                 if_printf(&sc->arpcom.ac_if, "%s(%d): "
3233                           "Simulating mbuf allocation failure.\n",
3234                           __FILE__, __LINE__);
3235                 sc->mbuf_alloc_failed++;
3236                 return ENOBUFS);
3237
3238         /* This is a new mbuf allocation. */
3239         m_new = m_getcl(init ? MB_WAIT : MB_DONTWAIT, MT_DATA, M_PKTHDR);
3240         if (m_new == NULL)
3241                 return ENOBUFS;
3242         DBRUNIF(1, sc->rx_mbuf_alloc++);
3243
3244         m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
3245
3246         /* Map the mbuf cluster into device memory. */
3247         error = bus_dmamap_load_mbuf_segment(sc->rx_mbuf_tag,
3248                         sc->rx_mbuf_tmpmap, m_new, &seg, 1, &nseg,
3249                         BUS_DMA_NOWAIT);
3250         if (error) {
3251                 m_freem(m_new);
3252                 if (init) {
3253                         if_printf(&sc->arpcom.ac_if,
3254                                   "Error mapping mbuf into RX chain!\n");
3255                 }
3256                 DBRUNIF(1, sc->rx_mbuf_alloc--);
3257                 return error;
3258         }
3259
3260         if (sc->rx_mbuf_ptr[*chain_prod] != NULL) {
3261                 bus_dmamap_unload(sc->rx_mbuf_tag,
3262                                   sc->rx_mbuf_map[*chain_prod]);
3263         }
3264
3265         map = sc->rx_mbuf_map[*chain_prod];
3266         sc->rx_mbuf_map[*chain_prod] = sc->rx_mbuf_tmpmap;
3267         sc->rx_mbuf_tmpmap = map;
3268
3269         /* Watch for overflow. */
3270         DBRUNIF((sc->free_rx_bd > USABLE_RX_BD),
3271                 if_printf(&sc->arpcom.ac_if, "%s(%d): "
3272                           "Too many free rx_bd (0x%04X > 0x%04X)!\n",
3273                           __FILE__, __LINE__, sc->free_rx_bd,
3274                           (uint16_t)USABLE_RX_BD));
3275
3276         /* Update some debug statistic counters */
3277         DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
3278                 sc->rx_low_watermark = sc->free_rx_bd);
3279         DBRUNIF((sc->free_rx_bd == 0), sc->rx_empty_count++);
3280
3281         /* Save the mbuf and update our counter. */
3282         sc->rx_mbuf_ptr[*chain_prod] = m_new;
3283         sc->rx_mbuf_paddr[*chain_prod] = seg.ds_addr;
3284         sc->free_rx_bd--;
3285
3286         bce_setup_rxdesc_std(sc, *chain_prod, prod_bseq);
3287
3288         DBRUN(BCE_VERBOSE_RECV,
3289               bce_dump_rx_mbuf_chain(sc, debug_chain_prod, 1));
3290
3291         DBPRINT(sc, BCE_VERBOSE_RECV, "%s(exit): prod = 0x%04X, chain_prod = 0x%04X, "
3292                 "prod_bseq = 0x%08X\n", __func__, *prod, *chain_prod, *prod_bseq);
3293
3294         return 0;
3295 }
3296
3297
3298 static void
3299 bce_setup_rxdesc_std(struct bce_softc *sc, uint16_t chain_prod, uint32_t *prod_bseq)
3300 {
3301         struct rx_bd *rxbd;
3302         bus_addr_t paddr;
3303         int len;
3304
3305         paddr = sc->rx_mbuf_paddr[chain_prod];
3306         len = sc->rx_mbuf_ptr[chain_prod]->m_len;
3307
3308         /* Setup the rx_bd for the first segment. */
3309         rxbd = &sc->rx_bd_chain[RX_PAGE(chain_prod)][RX_IDX(chain_prod)];
3310
3311         rxbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(paddr));
3312         rxbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(paddr));
3313         rxbd->rx_bd_len = htole32(len);
3314         rxbd->rx_bd_flags = htole32(RX_BD_FLAGS_START);
3315         *prod_bseq += len;
3316
3317         rxbd->rx_bd_flags |= htole32(RX_BD_FLAGS_END);
3318 }
3319
3320
3321 /****************************************************************************/
3322 /* Allocate memory and initialize the TX data structures.                   */
3323 /*                                                                          */
3324 /* Returns:                                                                 */
3325 /*   0 for success, positive value for failure.                             */
3326 /****************************************************************************/
3327 static int
3328 bce_init_tx_chain(struct bce_softc *sc)
3329 {
3330         struct tx_bd *txbd;
3331         uint32_t val;
3332         int i, rc = 0;
3333
3334         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __func__);
3335
3336         /* Set the initial TX producer/consumer indices. */
3337         sc->tx_prod = 0;
3338         sc->tx_cons = 0;
3339         sc->tx_prod_bseq   = 0;
3340         sc->used_tx_bd = 0;
3341         sc->max_tx_bd = USABLE_TX_BD;
3342         DBRUNIF(1, sc->tx_hi_watermark = USABLE_TX_BD);
3343         DBRUNIF(1, sc->tx_full_count = 0);
3344
3345         /*
3346          * The NetXtreme II supports a linked-list structre called
3347          * a Buffer Descriptor Chain (or BD chain).  A BD chain
3348          * consists of a series of 1 or more chain pages, each of which
3349          * consists of a fixed number of BD entries.
3350          * The last BD entry on each page is a pointer to the next page
3351          * in the chain, and the last pointer in the BD chain
3352          * points back to the beginning of the chain.
3353          */
3354
3355         /* Set the TX next pointer chain entries. */
3356         for (i = 0; i < TX_PAGES; i++) {
3357                 int j;
3358
3359                 txbd = &sc->tx_bd_chain[i][USABLE_TX_BD_PER_PAGE];
3360
3361                 /* Check if we've reached the last page. */
3362                 if (i == (TX_PAGES - 1))
3363                         j = 0;
3364                 else
3365                         j = i + 1;
3366
3367                 txbd->tx_bd_haddr_hi =
3368                         htole32(BCE_ADDR_HI(sc->tx_bd_chain_paddr[j]));
3369                 txbd->tx_bd_haddr_lo =
3370                         htole32(BCE_ADDR_LO(sc->tx_bd_chain_paddr[j]));
3371         }
3372
3373         /* Initialize the context ID for an L2 TX chain. */
3374         val = BCE_L2CTX_TYPE_TYPE_L2;
3375         val |= BCE_L2CTX_TYPE_SIZE_L2;
3376         CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TYPE, val);
3377
3378         val = BCE_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16);
3379         CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_CMD_TYPE, val);
3380
3381         /* Point the hardware to the first page in the chain. */
3382         val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
3383         CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TBDR_BHADDR_HI, val);
3384         val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
3385         CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TBDR_BHADDR_LO, val);
3386
3387         DBRUN(BCE_VERBOSE_SEND, bce_dump_tx_chain(sc, 0, TOTAL_TX_BD));
3388
3389         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __func__);
3390
3391         return(rc);
3392 }
3393
3394
3395 /****************************************************************************/
3396 /* Free memory and clear the TX data structures.                            */
3397 /*                                                                          */
3398 /* Returns:                                                                 */
3399 /*   Nothing.                                                               */
3400 /****************************************************************************/
3401 static void
3402 bce_free_tx_chain(struct bce_softc *sc)
3403 {
3404         int i;
3405
3406         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __func__);
3407
3408         /* Unmap, unload, and free any mbufs still in the TX mbuf chain. */
3409         for (i = 0; i < TOTAL_TX_BD; i++) {
3410                 if (sc->tx_mbuf_ptr[i] != NULL) {
3411                         bus_dmamap_unload(sc->tx_mbuf_tag, sc->tx_mbuf_map[i]);
3412                         m_freem(sc->tx_mbuf_ptr[i]);
3413                         sc->tx_mbuf_ptr[i] = NULL;
3414                         DBRUNIF(1, sc->tx_mbuf_alloc--);
3415                 }
3416         }
3417
3418         /* Clear each TX chain page. */
3419         for (i = 0; i < TX_PAGES; i++)
3420                 bzero(sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ);
3421         sc->used_tx_bd = 0;
3422
3423         /* Check if we lost any mbufs in the process. */
3424         DBRUNIF((sc->tx_mbuf_alloc),
3425                 if_printf(&sc->arpcom.ac_if,
3426                           "%s(%d): Memory leak! "
3427                           "Lost %d mbufs from tx chain!\n",
3428                           __FILE__, __LINE__, sc->tx_mbuf_alloc));
3429
3430         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __func__);
3431 }
3432
3433
3434 /****************************************************************************/
3435 /* Allocate memory and initialize the RX data structures.                   */
3436 /*                                                                          */
3437 /* Returns:                                                                 */
3438 /*   0 for success, positive value for failure.                             */
3439 /****************************************************************************/
3440 static int
3441 bce_init_rx_chain(struct bce_softc *sc)
3442 {
3443         struct rx_bd *rxbd;
3444         int i, rc = 0;
3445         uint16_t prod, chain_prod;
3446         uint32_t prod_bseq, val;
3447
3448         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __func__);
3449
3450         /* Initialize the RX producer and consumer indices. */
3451         sc->rx_prod = 0;
3452         sc->rx_cons = 0;
3453         sc->rx_prod_bseq = 0;
3454         sc->free_rx_bd = USABLE_RX_BD;
3455         sc->max_rx_bd = USABLE_RX_BD;
3456         DBRUNIF(1, sc->rx_low_watermark = USABLE_RX_BD);
3457         DBRUNIF(1, sc->rx_empty_count = 0);
3458
3459         /* Initialize the RX next pointer chain entries. */
3460         for (i = 0; i < RX_PAGES; i++) {
3461                 int j;
3462
3463                 rxbd = &sc->rx_bd_chain[i][USABLE_RX_BD_PER_PAGE];
3464
3465                 /* Check if we've reached the last page. */
3466                 if (i == (RX_PAGES - 1))
3467                         j = 0;
3468                 else
3469                         j = i + 1;
3470
3471                 /* Setup the chain page pointers. */
3472                 rxbd->rx_bd_haddr_hi =
3473                         htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j]));
3474                 rxbd->rx_bd_haddr_lo =
3475                         htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j]));
3476         }
3477
3478         /* Initialize the context ID for an L2 RX chain. */
3479         val = BCE_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
3480         val |= BCE_L2CTX_CTX_TYPE_SIZE_L2;
3481         val |= 0x02 << 8;
3482         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_CTX_TYPE, val);
3483
3484         /* Point the hardware to the first page in the chain. */
3485         /* XXX shouldn't this after RX descriptor initialization? */
3486         val = BCE_ADDR_HI(sc->rx_bd_chain_paddr[0]);
3487         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_NX_BDHADDR_HI, val);
3488         val = BCE_ADDR_LO(sc->rx_bd_chain_paddr[0]);
3489         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_NX_BDHADDR_LO, val);
3490
3491         /* Allocate mbuf clusters for the rx_bd chain. */
3492         prod = prod_bseq = 0;
3493         while (prod < TOTAL_RX_BD) {
3494                 chain_prod = RX_CHAIN_IDX(prod);
3495                 if (bce_newbuf_std(sc, &prod, &chain_prod, &prod_bseq, 1)) {
3496                         if_printf(&sc->arpcom.ac_if,
3497                                   "Error filling RX chain: rx_bd[0x%04X]!\n",
3498                                   chain_prod);
3499                         rc = ENOBUFS;
3500                         break;
3501                 }
3502                 prod = NEXT_RX_BD(prod);
3503         }
3504
3505         /* Save the RX chain producer index. */
3506         sc->rx_prod = prod;
3507         sc->rx_prod_bseq = prod_bseq;
3508
3509         /* Tell the chip about the waiting rx_bd's. */
3510         REG_WR16(sc, MB_RX_CID_ADDR + BCE_L2CTX_HOST_BDIDX, sc->rx_prod);
3511         REG_WR(sc, MB_RX_CID_ADDR + BCE_L2CTX_HOST_BSEQ, sc->rx_prod_bseq);
3512
3513         DBRUN(BCE_VERBOSE_RECV, bce_dump_rx_chain(sc, 0, TOTAL_RX_BD));
3514
3515         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __func__);
3516
3517         return(rc);
3518 }
3519
3520
3521 /****************************************************************************/
3522 /* Free memory and clear the RX data structures.                            */
3523 /*                                                                          */
3524 /* Returns:                                                                 */
3525 /*   Nothing.                                                               */
3526 /****************************************************************************/
3527 static void
3528 bce_free_rx_chain(struct bce_softc *sc)
3529 {
3530         int i;
3531
3532         DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __func__);
3533
3534         /* Free any mbufs still in the RX mbuf chain. */
3535         for (i = 0; i < TOTAL_RX_BD; i++) {
3536                 if (sc->rx_mbuf_ptr[i] != NULL) {
3537                         bus_dmamap_unload(sc->rx_mbuf_tag, sc->rx_mbuf_map[i]);
3538                         m_freem(sc->rx_mbuf_ptr[i]);
3539                         sc->rx_mbuf_ptr[i] = NULL;
3540                         DBRUNIF(1, sc->rx_mbuf_alloc--);
3541                 }
3542         }
3543
3544         /* Clear each RX chain page. */
3545         for (i = 0; i < RX_PAGES; i++)
3546                 bzero(sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ);
3547
3548         /* Check if we lost any mbufs in the process. */
3549         DBRUNIF((sc->rx_mbuf_alloc),
3550                 if_printf(&sc->arpcom.ac_if,
3551                           "%s(%d): Memory leak! "
3552                           "Lost %d mbufs from rx chain!\n",
3553                           __FILE__, __LINE__, sc->rx_mbuf_alloc));
3554
3555         DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __func__);
3556 }
3557
3558
3559 /****************************************************************************/
3560 /* Set media options.                                                       */
3561 /*                                                                          */
3562 /* Returns:                                                                 */
3563 /*   0 for success, positive value for failure.                             */
3564 /****************************************************************************/
3565 static int
3566 bce_ifmedia_upd(struct ifnet *ifp)
3567 {
3568         struct bce_softc *sc = ifp->if_softc;
3569         struct mii_data *mii = device_get_softc(sc->bce_miibus);
3570
3571         /*
3572          * 'mii' will be NULL, when this function is called on following
3573          * code path: bce_attach() -> bce_mgmt_init()
3574          */
3575         if (mii != NULL) {
3576                 /* Make sure the MII bus has been enumerated. */
3577                 sc->bce_link = 0;
3578                 if (mii->mii_instance) {
3579                         struct mii_softc *miisc;
3580
3581                         LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
3582                                 mii_phy_reset(miisc);
3583                 }
3584                 mii_mediachg(mii);
3585         }
3586         return 0;
3587 }
3588
3589
3590 /****************************************************************************/
3591 /* Reports current media status.                                            */
3592 /*                                                                          */
3593 /* Returns:                                                                 */
3594 /*   Nothing.                                                               */
3595 /****************************************************************************/
3596 static void
3597 bce_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
3598 {
3599         struct bce_softc *sc = ifp->if_softc;
3600         struct mii_data *mii = device_get_softc(sc->bce_miibus);
3601
3602         mii_pollstat(mii);
3603         ifmr->ifm_active = mii->mii_media_active;
3604         ifmr->ifm_status = mii->mii_media_status;
3605 }
3606
3607
3608 /****************************************************************************/
3609 /* Handles PHY generated interrupt events.                                  */
3610 /*                                                                          */
3611 /* Returns:                                                                 */
3612 /*   Nothing.                                                               */
3613 /****************************************************************************/
3614 static void
3615 bce_phy_intr(struct bce_softc *sc)
3616 {
3617         uint32_t new_link_state, old_link_state;
3618         struct ifnet *ifp = &sc->arpcom.ac_if;
3619
3620         ASSERT_SERIALIZED(ifp->if_serializer);
3621
3622         new_link_state = sc->status_block->status_attn_bits &
3623                          STATUS_ATTN_BITS_LINK_STATE;
3624         old_link_state = sc->status_block->status_attn_bits_ack &
3625                          STATUS_ATTN_BITS_LINK_STATE;
3626
3627         /* Handle any changes if the link state has changed. */
3628         if (new_link_state != old_link_state) { /* XXX redundant? */
3629                 DBRUN(BCE_VERBOSE_INTR, bce_dump_status_block(sc));
3630
3631                 sc->bce_link = 0;
3632                 callout_stop(&sc->bce_stat_ch);
3633                 bce_tick_serialized(sc);
3634
3635                 /* Update the status_attn_bits_ack field in the status block. */
3636                 if (new_link_state) {
3637                         REG_WR(sc, BCE_PCICFG_STATUS_BIT_SET_CMD,
3638                                STATUS_ATTN_BITS_LINK_STATE);
3639                         if (bootverbose)
3640                                 if_printf(ifp, "Link is now UP.\n");
3641                 } else {
3642                         REG_WR(sc, BCE_PCICFG_STATUS_BIT_CLEAR_CMD,
3643                                STATUS_ATTN_BITS_LINK_STATE);
3644                         if (bootverbose)
3645                                 if_printf(ifp, "Link is now DOWN.\n");
3646                 }
3647         }
3648
3649         /* Acknowledge the link change interrupt. */
3650         REG_WR(sc, BCE_EMAC_STATUS, BCE_EMAC_STATUS_LINK_CHANGE);
3651 }
3652
3653
3654 /****************************************************************************/
3655 /* Reads the receive consumer value from the status block (skipping over    */
3656 /* chain page pointer if necessary).                                        */
3657 /*                                                                          */
3658 /* Returns:                                                                 */
3659 /*   hw_cons                                                                */
3660 /****************************************************************************/
3661 static __inline uint16_t
3662 bce_get_hw_rx_cons(struct bce_softc *sc)
3663 {
3664         uint16_t hw_cons = sc->status_block->status_rx_quick_consumer_index0;
3665
3666         if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
3667                 hw_cons++;
3668         return hw_cons;
3669 }
3670
3671
3672 /****************************************************************************/
3673 /* Handles received frame interrupt events.                                 */
3674 /*                                                                          */
3675 /* Returns:                                                                 */
3676 /*   Nothing.                                                               */
3677 /****************************************************************************/
3678 static void
3679 bce_rx_intr(struct bce_softc *sc, int count)
3680 {
3681         struct ifnet *ifp = &sc->arpcom.ac_if;
3682         uint16_t hw_cons, sw_cons, sw_chain_cons, sw_prod, sw_chain_prod;
3683         uint32_t sw_prod_bseq;
3684         struct mbuf_chain chain[MAXCPU];
3685
3686         ASSERT_SERIALIZED(ifp->if_serializer);
3687
3688         ether_input_chain_init(chain);
3689
3690         DBRUNIF(1, sc->rx_interrupts++);
3691
3692         /* Get the hardware's view of the RX consumer index. */
3693         hw_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
3694
3695         /* Get working copies of the driver's view of the RX indices. */
3696         sw_cons = sc->rx_cons;
3697         sw_prod = sc->rx_prod;
3698         sw_prod_bseq = sc->rx_prod_bseq;
3699
3700         DBPRINT(sc, BCE_INFO_RECV, "%s(enter): sw_prod = 0x%04X, "
3701                 "sw_cons = 0x%04X, sw_prod_bseq = 0x%08X\n",
3702                 __func__, sw_prod, sw_cons, sw_prod_bseq);
3703
3704         /* Prevent speculative reads from getting ahead of the status block. */
3705         bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
3706                           BUS_SPACE_BARRIER_READ);
3707
3708         /* Update some debug statistics counters */
3709         DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
3710                 sc->rx_low_watermark = sc->free_rx_bd);
3711         DBRUNIF((sc->free_rx_bd == 0), sc->rx_empty_count++);
3712
3713         /* Scan through the receive chain as long as there is work to do. */
3714         while (sw_cons != hw_cons) {
3715                 struct mbuf *m = NULL;
3716                 struct l2_fhdr *l2fhdr = NULL;
3717                 struct rx_bd *rxbd;
3718                 unsigned int len;
3719                 uint32_t status = 0;
3720
3721 #ifdef DEVICE_POLLING
3722                 if (count >= 0 && count-- == 0) {
3723                         sc->hw_rx_cons = sw_cons;
3724                         break;
3725                 }
3726 #endif
3727
3728                 /*
3729                  * Convert the producer/consumer indices
3730                  * to an actual rx_bd index.
3731                  */
3732                 sw_chain_cons = RX_CHAIN_IDX(sw_cons);
3733                 sw_chain_prod = RX_CHAIN_IDX(sw_prod);
3734
3735                 /* Get the used rx_bd. */
3736                 rxbd = &sc->rx_bd_chain[RX_PAGE(sw_chain_cons)]
3737                                        [RX_IDX(sw_chain_cons)];
3738                 sc->free_rx_bd++;
3739
3740                 DBRUN(BCE_VERBOSE_RECV,
3741                       if_printf(ifp, "%s(): ", __func__);
3742                       bce_dump_rxbd(sc, sw_chain_cons, rxbd));
3743
3744                 /* The mbuf is stored with the last rx_bd entry of a packet. */
3745                 if (sc->rx_mbuf_ptr[sw_chain_cons] != NULL) {
3746                         /* Validate that this is the last rx_bd. */
3747                         DBRUNIF((!(rxbd->rx_bd_flags & RX_BD_FLAGS_END)),
3748                                 if_printf(ifp, "%s(%d): "
3749                                 "Unexpected mbuf found in rx_bd[0x%04X]!\n",
3750                                 __FILE__, __LINE__, sw_chain_cons);
3751                                 bce_breakpoint(sc));
3752
3753                         if (sw_chain_cons != sw_chain_prod) {
3754                                 if_printf(ifp, "RX cons(%d) != prod(%d), "
3755                                           "drop!\n", sw_chain_cons,
3756                                           sw_chain_prod);
3757                                 ifp->if_ierrors++;
3758
3759                                 bce_setup_rxdesc_std(sc, sw_chain_cons,
3760                                                      &sw_prod_bseq);
3761                                 m = NULL;
3762                                 goto bce_rx_int_next_rx;
3763                         }
3764
3765                         /* Unmap the mbuf from DMA space. */
3766                         bus_dmamap_sync(sc->rx_mbuf_tag,
3767                                         sc->rx_mbuf_map[sw_chain_cons],
3768                                         BUS_DMASYNC_POSTREAD);
3769
3770                         /* Save the mbuf from the driver's chain. */
3771                         m = sc->rx_mbuf_ptr[sw_chain_cons];
3772
3773                         /*
3774                          * Frames received on the NetXteme II are prepended 
3775                          * with an l2_fhdr structure which provides status
3776                          * information about the received frame (including
3777                          * VLAN tags and checksum info).  The frames are also
3778                          * automatically adjusted to align the IP header
3779                          * (i.e. two null bytes are inserted before the 
3780                          * Ethernet header).
3781                          */
3782                         l2fhdr = mtod(m, struct l2_fhdr *);
3783
3784                         len = l2fhdr->l2_fhdr_pkt_len;
3785                         status = l2fhdr->l2_fhdr_status;
3786
3787                         DBRUNIF(DB_RANDOMTRUE(bce_debug_l2fhdr_status_check),
3788                                 if_printf(ifp,
3789                                 "Simulating l2_fhdr status error.\n");
3790                                 status = status | L2_FHDR_ERRORS_PHY_DECODE);
3791
3792                         /* Watch for unusual sized frames. */
3793                         DBRUNIF((len < BCE_MIN_MTU ||
3794                                  len > BCE_MAX_JUMBO_ETHER_MTU_VLAN),
3795                                 if_printf(ifp,
3796                                 "%s(%d): Unusual frame size found. "
3797                                 "Min(%d), Actual(%d), Max(%d)\n",
3798                                 __FILE__, __LINE__,
3799                                 (int)BCE_MIN_MTU, len,
3800                                 (int)BCE_MAX_JUMBO_ETHER_MTU_VLAN);
3801                                 bce_dump_mbuf(sc, m);
3802                                 bce_breakpoint(sc));
3803
3804                         len -= ETHER_CRC_LEN;
3805
3806                         /* Check the received frame for errors. */
3807                         if (status & (L2_FHDR_ERRORS_BAD_CRC |
3808                                       L2_FHDR_ERRORS_PHY_DECODE |
3809                                       L2_FHDR_ERRORS_ALIGNMENT |
3810                                       L2_FHDR_ERRORS_TOO_SHORT |
3811                                       L2_FHDR_ERRORS_GIANT_FRAME)) {
3812                                 ifp->if_ierrors++;
3813                                 DBRUNIF(1, sc->l2fhdr_status_errors++);
3814
3815                                 /* Reuse the mbuf for a new frame. */
3816                                 bce_setup_rxdesc_std(sc, sw_chain_prod,
3817                                                      &sw_prod_bseq);
3818                                 m = NULL;
3819                                 goto bce_rx_int_next_rx;
3820                         }
3821
3822                         /* 
3823                          * Get a new mbuf for the rx_bd.   If no new
3824                          * mbufs are available then reuse the current mbuf,
3825                          * log an ierror on the interface, and generate
3826                          * an error in the system log.
3827                          */
3828                         if (bce_newbuf_std(sc, &sw_prod, &sw_chain_prod,
3829                                            &sw_prod_bseq, 0)) {
3830                                 DBRUN(BCE_WARN,
3831                                       if_printf(ifp,
3832                                       "%s(%d): Failed to allocate new mbuf, "
3833                                       "incoming frame dropped!\n",
3834                                       __FILE__, __LINE__));
3835
3836                                 ifp->if_ierrors++;
3837
3838                                 /* Try and reuse the exisitng mbuf. */
3839                                 bce_setup_rxdesc_std(sc, sw_chain_prod,
3840                                                      &sw_prod_bseq);
3841                                 m = NULL;
3842                                 goto bce_rx_int_next_rx;
3843                         }
3844
3845                         /*
3846                          * Skip over the l2_fhdr when passing
3847                          * the data up the stack.
3848                          */
3849                         m_adj(m, sizeof(struct l2_fhdr) + ETHER_ALIGN);
3850
3851                         m->m_pkthdr.len = m->m_len = len;
3852                         m->m_pkthdr.rcvif = ifp;
3853
3854                         DBRUN(BCE_VERBOSE_RECV,
3855                               struct ether_header *eh;
3856                               eh = mtod(m, struct ether_header *);
3857                               if_printf(ifp, "%s(): to: %6D, from: %6D, "
3858                                         "type: 0x%04X\n", __func__,
3859                                         eh->ether_dhost, ":", 
3860                                         eh->ether_shost, ":",
3861                                         htons(eh->ether_type)));
3862
3863                         /* Validate the checksum if offload enabled. */
3864                         if (ifp->if_capenable & IFCAP_RXCSUM) {
3865                                 /* Check for an IP datagram. */
3866                                 if (status & L2_FHDR_STATUS_IP_DATAGRAM) {
3867                                         m->m_pkthdr.csum_flags |=
3868                                                 CSUM_IP_CHECKED;
3869
3870                                         /* Check if the IP checksum is valid. */
3871                                         if ((l2fhdr->l2_fhdr_ip_xsum ^
3872                                              0xffff) == 0) {
3873                                                 m->m_pkthdr.csum_flags |=
3874                                                         CSUM_IP_VALID;
3875                                         } else {
3876                                                 DBPRINT(sc, BCE_WARN_RECV, 
3877                                                         "%s(): Invalid IP checksum = 0x%04X!\n",
3878                                                         __func__, l2fhdr->l2_fhdr_ip_xsum);
3879                                         }
3880                                 }
3881
3882                                 /* Check for a valid TCP/UDP frame. */
3883                                 if (status & (L2_FHDR_STATUS_TCP_SEGMENT |
3884                                               L2_FHDR_STATUS_UDP_DATAGRAM)) {
3885
3886                                         /* Check for a good TCP/UDP checksum. */
3887                                         if ((status &
3888                                              (L2_FHDR_ERRORS_TCP_XSUM |
3889                                               L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
3890                                                 m->m_pkthdr.csum_data =
3891                                                 l2fhdr->l2_fhdr_tcp_udp_xsum;
3892                                                 m->m_pkthdr.csum_flags |=
3893                                                         CSUM_DATA_VALID |
3894                                                         CSUM_PSEUDO_HDR;
3895                                         } else {
3896                                                 DBPRINT(sc, BCE_WARN_RECV,
3897                                                         "%s(): Invalid TCP/UDP checksum = 0x%04X!\n",
3898                                                         __func__, l2fhdr->l2_fhdr_tcp_udp_xsum);
3899                                         }
3900                                 }
3901                         }
3902
3903                         ifp->if_ipackets++;
3904 bce_rx_int_next_rx:
3905                         sw_prod = NEXT_RX_BD(sw_prod);
3906                 }
3907
3908                 sw_cons = NEXT_RX_BD(sw_cons);
3909
3910                 /* If we have a packet, pass it up the stack */
3911                 if (m) {
3912                         DBPRINT(sc, BCE_VERBOSE_RECV,
3913                                 "%s(): Passing received frame up.\n", __func__);
3914
3915                         if (status & L2_FHDR_STATUS_L2_VLAN_TAG) {
3916                                 m->m_flags |= M_VLANTAG;
3917                                 m->m_pkthdr.ether_vlantag =
3918                                         l2fhdr->l2_fhdr_vlan_tag;
3919                         }
3920                         ether_input_chain(ifp, m, NULL, chain);
3921
3922                         DBRUNIF(1, sc->rx_mbuf_alloc--);
3923                 }
3924
3925                 /*
3926                  * If polling(4) is not enabled, refresh hw_cons to see
3927                  * whether there's new work.
3928                  *
3929                  * If polling(4) is enabled, i.e count >= 0, refreshing
3930                  * should not be performed, so that we would not spend
3931                  * too much time in RX processing.
3932                  */
3933                 if (count < 0 && sw_cons == hw_cons)
3934                         hw_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
3935
3936                 /*
3937                  * Prevent speculative reads from getting ahead
3938                  * of the status block.
3939                  */
3940                 bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
3941                                   BUS_SPACE_BARRIER_READ);
3942         }
3943
3944         ether_input_dispatch(chain);
3945
3946         sc->rx_cons = sw_cons;
3947         sc->rx_prod = sw_prod;
3948         sc->rx_prod_bseq = sw_prod_bseq;
3949
3950         REG_WR16(sc, MB_RX_CID_ADDR + BCE_L2CTX_HOST_BDIDX, sc->rx_prod);
3951         REG_WR(sc, MB_RX_CID_ADDR + BCE_L2CTX_HOST_BSEQ, sc->rx_prod_bseq);
3952
3953         DBPRINT(sc, BCE_INFO_RECV, "%s(exit): rx_prod = 0x%04X, "
3954                 "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
3955                 __func__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
3956 }
3957
3958
3959 /****************************************************************************/
3960 /* Reads the transmit consumer value from the status block (skipping over   */
3961 /* chain page pointer if necessary).                                        */
3962 /*                                                                          */
3963 /* Returns:                                                                 */
3964 /*   hw_cons                                                                */
3965 /****************************************************************************/
3966 static __inline uint16_t
3967 bce_get_hw_tx_cons(struct bce_softc *sc)
3968 {
3969         uint16_t hw_cons = sc->status_block->status_tx_quick_consumer_index0;
3970
3971         if ((hw_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
3972                 hw_cons++;
3973         return hw_cons;
3974 }
3975
3976
3977 /****************************************************************************/
3978 /* Handles transmit completion interrupt events.                            */
3979 /*                                                                          */
3980 /* Returns:                                                                 */
3981 /*   Nothing.                                                               */
3982 /****************************************************************************/
3983 static void
3984 bce_tx_intr(struct bce_softc *sc)
3985 {
3986         struct ifnet *ifp = &sc->arpcom.ac_if;
3987         uint16_t hw_tx_cons, sw_tx_cons, sw_tx_chain_cons;
3988
3989         ASSERT_SERIALIZED(ifp->if_serializer);
3990
3991         DBRUNIF(1, sc->tx_interrupts++);
3992
3993         /* Get the hardware's view of the TX consumer index. */
3994         hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
3995         sw_tx_cons = sc->tx_cons;
3996
3997         /* Prevent speculative reads from getting ahead of the status block. */
3998         bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
3999                           BUS_SPACE_BARRIER_READ);
4000
4001         /* Cycle through any completed TX chain page entries. */
4002         while (sw_tx_cons != hw_tx_cons) {
4003 #ifdef BCE_DEBUG
4004                 struct tx_bd *txbd = NULL;
4005 #endif
4006                 sw_tx_chain_cons = TX_CHAIN_IDX(sw_tx_cons);
4007
4008                 DBPRINT(sc, BCE_INFO_SEND,
4009                         "%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, "
4010                         "sw_tx_chain_cons = 0x%04X\n",
4011                         __func__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
4012
4013                 DBRUNIF((sw_tx_chain_cons > MAX_TX_BD),
4014                         if_printf(ifp, "%s(%d): "
4015                                   "TX chain consumer out of range! "
4016                                   " 0x%04X > 0x%04X\n",
4017                                   __FILE__, __LINE__, sw_tx_chain_cons,
4018                                   (int)MAX_TX_BD);
4019                         bce_breakpoint(sc));
4020
4021                 DBRUNIF(1, txbd = &sc->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)]
4022                                 [TX_IDX(sw_tx_chain_cons)]);
4023
4024                 DBRUNIF((txbd == NULL),
4025                         if_printf(ifp, "%s(%d): "
4026                                   "Unexpected NULL tx_bd[0x%04X]!\n",
4027                                   __FILE__, __LINE__, sw_tx_chain_cons);
4028                         bce_breakpoint(sc));
4029
4030                 DBRUN(BCE_INFO_SEND,
4031                       if_printf(ifp, "%s(): ", __func__);
4032                       bce_dump_txbd(sc, sw_tx_chain_cons, txbd));
4033
4034                 /*
4035                  * Free the associated mbuf. Remember
4036                  * that only the last tx_bd of a packet
4037                  * has an mbuf pointer and DMA map.
4038                  */
4039                 if (sc->tx_mbuf_ptr[sw_tx_chain_cons] != NULL) {
4040                         /* Validate that this is the last tx_bd. */
4041                         DBRUNIF((!(txbd->tx_bd_flags & TX_BD_FLAGS_END)),
4042                                 if_printf(ifp, "%s(%d): "
4043                                 "tx_bd END flag not set but "
4044                                 "txmbuf == NULL!\n", __FILE__, __LINE__);
4045                                 bce_breakpoint(sc));
4046
4047                         DBRUN(BCE_INFO_SEND,
4048                               if_printf(ifp, "%s(): Unloading map/freeing mbuf "
4049                                         "from tx_bd[0x%04X]\n", __func__,
4050                                         sw_tx_chain_cons));
4051
4052                         /* Unmap the mbuf. */
4053                         bus_dmamap_unload(sc->tx_mbuf_tag,
4054                                           sc->tx_mbuf_map[sw_tx_chain_cons]);
4055
4056                         /* Free the mbuf. */
4057                         m_freem(sc->tx_mbuf_ptr[sw_tx_chain_cons]);
4058                         sc->tx_mbuf_ptr[sw_tx_chain_cons] = NULL;
4059                         DBRUNIF(1, sc->tx_mbuf_alloc--);
4060
4061                         ifp->if_opackets++;
4062                 }
4063
4064                 sc->used_tx_bd--;
4065                 sw_tx_cons = NEXT_TX_BD(sw_tx_cons);
4066
4067                 if (sw_tx_cons == hw_tx_cons) {
4068                         /* Refresh hw_cons to see if there's new work. */
4069                         hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
4070                 }
4071
4072                 /*
4073                  * Prevent speculative reads from getting
4074                  * ahead of the status block.
4075                  */
4076                 bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
4077                                   BUS_SPACE_BARRIER_READ);
4078         }
4079
4080         if (sc->used_tx_bd == 0) {
4081                 /* Clear the TX timeout timer. */
4082                 ifp->if_timer = 0;
4083         }
4084
4085         /* Clear the tx hardware queue full flag. */
4086         if (sc->max_tx_bd - sc->used_tx_bd >= BCE_TX_SPARE_SPACE) {
4087                 DBRUNIF((ifp->if_flags & IFF_OACTIVE),
4088                         DBPRINT(sc, BCE_WARN_SEND,
4089                                 "%s(): Open TX chain! %d/%d (used/total)\n", 
4090                                 __func__, sc->used_tx_bd, sc->max_tx_bd));
4091                 ifp->if_flags &= ~IFF_OACTIVE;
4092         }
4093         sc->tx_cons = sw_tx_cons;
4094 }
4095
4096
4097 /****************************************************************************/
4098 /* Disables interrupt generation.                                           */
4099 /*                                                                          */
4100 /* Returns:                                                                 */
4101 /*   Nothing.                                                               */
4102 /****************************************************************************/
4103 static void
4104 bce_disable_intr(struct bce_softc *sc)
4105 {
4106         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_MASK_INT);
4107         REG_RD(sc, BCE_PCICFG_INT_ACK_CMD);
4108         lwkt_serialize_handler_disable(sc->arpcom.ac_if.if_serializer);
4109 }
4110
4111
4112 /****************************************************************************/
4113 /* Enables interrupt generation.                                            */
4114 /*                                                                          */
4115 /* Returns:                                                                 */
4116 /*   Nothing.                                                               */
4117 /****************************************************************************/
4118 static void
4119 bce_enable_intr(struct bce_softc *sc)
4120 {
4121         uint32_t val;
4122
4123         lwkt_serialize_handler_enable(sc->arpcom.ac_if.if_serializer);
4124
4125         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
4126                BCE_PCICFG_INT_ACK_CMD_INDEX_VALID |
4127                BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
4128
4129         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
4130                BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
4131
4132         val = REG_RD(sc, BCE_HC_COMMAND);
4133         REG_WR(sc, BCE_HC_COMMAND, val | BCE_HC_COMMAND_COAL_NOW);
4134 }
4135
4136
4137 /****************************************************************************/
4138 /* Handles controller initialization.                                       */
4139 /*                                                                          */
4140 /* Returns:                                                                 */
4141 /*   Nothing.                                                               */
4142 /****************************************************************************/
4143 static void
4144 bce_init(void *xsc)
4145 {
4146         struct bce_softc *sc = xsc;
4147         struct ifnet *ifp = &sc->arpcom.ac_if;
4148         uint32_t ether_mtu;
4149         int error;
4150
4151         ASSERT_SERIALIZED(ifp->if_serializer);
4152
4153         /* Check if the driver is still running and bail out if it is. */
4154         if (ifp->if_flags & IFF_RUNNING)
4155                 return;
4156
4157         bce_stop(sc);
4158
4159         error = bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
4160         if (error) {
4161                 if_printf(ifp, "Controller reset failed!\n");
4162                 goto back;
4163         }
4164
4165         error = bce_chipinit(sc);
4166         if (error) {
4167                 if_printf(ifp, "Controller initialization failed!\n");
4168                 goto back;
4169         }
4170
4171         error = bce_blockinit(sc);
4172         if (error) {
4173                 if_printf(ifp, "Block initialization failed!\n");
4174                 goto back;
4175         }
4176
4177         /* Load our MAC address. */
4178         bcopy(IF_LLADDR(ifp), sc->eaddr, ETHER_ADDR_LEN);
4179         bce_set_mac_addr(sc);
4180
4181         /* Calculate and program the Ethernet MTU size. */
4182         ether_mtu = ETHER_HDR_LEN + EVL_ENCAPLEN + ifp->if_mtu + ETHER_CRC_LEN;
4183
4184         DBPRINT(sc, BCE_INFO, "%s(): setting mtu = %d\n", __func__, ether_mtu);
4185
4186         /* 
4187          * Program the mtu, enabling jumbo frame 
4188          * support if necessary.  Also set the mbuf
4189          * allocation count for RX frames.
4190          */
4191         if (ether_mtu > ETHER_MAX_LEN + EVL_ENCAPLEN) {
4192 #ifdef notyet
4193                 REG_WR(sc, BCE_EMAC_RX_MTU_SIZE,
4194                        min(ether_mtu, BCE_MAX_JUMBO_ETHER_MTU) |
4195                        BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA);
4196                 sc->mbuf_alloc_size = MJUM9BYTES;
4197 #else
4198                 panic("jumbo buffer is not supported yet\n");
4199 #endif
4200         } else {
4201                 REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu);
4202                 sc->mbuf_alloc_size = MCLBYTES;
4203         }
4204
4205         /* Calculate the RX Ethernet frame size for rx_bd's. */
4206         sc->max_frame_size = sizeof(struct l2_fhdr) + 2 + ether_mtu + 8;
4207
4208         DBPRINT(sc, BCE_INFO,
4209                 "%s(): mclbytes = %d, mbuf_alloc_size = %d, "
4210                 "max_frame_size = %d\n",
4211                 __func__, (int)MCLBYTES, sc->mbuf_alloc_size,
4212                 sc->max_frame_size);
4213
4214         /* Program appropriate promiscuous/multicast filtering. */
4215         bce_set_rx_mode(sc);
4216
4217         /* Init RX buffer descriptor chain. */
4218         bce_init_rx_chain(sc);  /* XXX return value */
4219
4220         /* Init TX buffer descriptor chain. */
4221         bce_init_tx_chain(sc);  /* XXX return value */
4222
4223 #ifdef DEVICE_POLLING
4224         /* Disable interrupts if we are polling. */
4225         if (ifp->if_flags & IFF_POLLING) {
4226                 bce_disable_intr(sc);
4227
4228                 REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
4229                        (1 << 16) | sc->bce_rx_quick_cons_trip);
4230                 REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
4231                        (1 << 16) | sc->bce_tx_quick_cons_trip);
4232         } else
4233 #endif
4234         /* Enable host interrupts. */
4235         bce_enable_intr(sc);
4236
4237         bce_ifmedia_upd(ifp);
4238
4239         ifp->if_flags |= IFF_RUNNING;
4240         ifp->if_flags &= ~IFF_OACTIVE;
4241
4242         callout_reset(&sc->bce_stat_ch, hz, bce_tick, sc);
4243 back:
4244         if (error)
4245                 bce_stop(sc);
4246 }
4247
4248
4249 /****************************************************************************/
4250 /* Initialize the controller just enough so that any management firmware    */
4251 /* running on the device will continue to operate corectly.                 */
4252 /*                                                                          */
4253 /* Returns:                                                                 */
4254 /*   Nothing.                                                               */
4255 /****************************************************************************/
4256 static void
4257 bce_mgmt_init(struct bce_softc *sc)
4258 {
4259         struct ifnet *ifp = &sc->arpcom.ac_if;
4260         uint32_t val;
4261
4262         /* Check if the driver is still running and bail out if it is. */
4263         if (ifp->if_flags & IFF_RUNNING)
4264                 return;
4265
4266         /* Initialize the on-boards CPUs */
4267         bce_init_cpus(sc);
4268
4269         /* Set the page size and clear the RV2P processor stall bits. */
4270         val = (BCM_PAGE_BITS - 8) << 24;
4271         REG_WR(sc, BCE_RV2P_CONFIG, val);
4272
4273         /* Enable all critical blocks in the MAC. */
4274         REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
4275                BCE_MISC_ENABLE_SET_BITS_RX_V2P_ENABLE |
4276                BCE_MISC_ENABLE_SET_BITS_RX_DMA_ENABLE |
4277                BCE_MISC_ENABLE_SET_BITS_COMPLETION_ENABLE);
4278         REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
4279         DELAY(20);
4280
4281         bce_ifmedia_upd(ifp);
4282 }
4283
4284
4285 /****************************************************************************/
4286 /* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
4287 /* memory visible to the controller.                                        */
4288 /*                                                                          */
4289 /* Returns:                                                                 */
4290 /*   0 for success, positive value for failure.                             */
4291 /****************************************************************************/
4292 static int
4293 bce_encap(struct bce_softc *sc, struct mbuf **m_head)
4294 {
4295         bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
4296         bus_dmamap_t map, tmp_map;
4297         struct mbuf *m0 = *m_head;
4298         struct tx_bd *txbd = NULL;
4299         uint16_t vlan_tag = 0, flags = 0;
4300         uint16_t chain_prod, chain_prod_start, prod;
4301         uint32_t prod_bseq;
4302         int i, error, maxsegs, nsegs;
4303 #ifdef BCE_DEBUG
4304         uint16_t debug_prod;
4305 #endif
4306
4307         /* Transfer any checksum offload flags to the bd. */
4308         if (m0->m_pkthdr.csum_flags) {
4309                 if (m0->m_pkthdr.csum_flags & CSUM_IP)
4310                         flags |= TX_BD_FLAGS_IP_CKSUM;
4311                 if (m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
4312                         flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
4313         }
4314
4315         /* Transfer any VLAN tags to the bd. */
4316         if (m0->m_flags & M_VLANTAG) {
4317                 flags |= TX_BD_FLAGS_VLAN_TAG;
4318                 vlan_tag = m0->m_pkthdr.ether_vlantag;
4319         }
4320
4321         prod = sc->tx_prod;
4322         chain_prod_start = chain_prod = TX_CHAIN_IDX(prod);
4323
4324         /* Map the mbuf into DMAable memory. */
4325         map = sc->tx_mbuf_map[chain_prod_start];
4326
4327         maxsegs = sc->max_tx_bd - sc->used_tx_bd;
4328         KASSERT(maxsegs >= BCE_TX_SPARE_SPACE,
4329                 ("not enough segements %d\n", maxsegs));
4330         if (maxsegs > BCE_MAX_SEGMENTS)
4331                 maxsegs = BCE_MAX_SEGMENTS;
4332
4333         /* Map the mbuf into our DMA address space. */
4334         error = bus_dmamap_load_mbuf_defrag(sc->tx_mbuf_tag, map, m_head,
4335                         segs, maxsegs, &nsegs, BUS_DMA_NOWAIT);
4336         if (error)
4337                 goto back;
4338         bus_dmamap_sync(sc->tx_mbuf_tag, map, BUS_DMASYNC_PREWRITE);
4339
4340         /* Reset m0 */
4341         m0 = *m_head;
4342
4343         /* prod points to an empty tx_bd at this point. */
4344         prod_bseq  = sc->tx_prod_bseq;
4345
4346 #ifdef BCE_DEBUG
4347         debug_prod = chain_prod;
4348 #endif
4349
4350         DBPRINT(sc, BCE_INFO_SEND,
4351                 "%s(): Start: prod = 0x%04X, chain_prod = %04X, "
4352                 "prod_bseq = 0x%08X\n",
4353                 __func__, prod, chain_prod, prod_bseq);
4354
4355         /*
4356          * Cycle through each mbuf segment that makes up
4357          * the outgoing frame, gathering the mapping info
4358          * for that segment and creating a tx_bd to for
4359          * the mbuf.
4360          */
4361         for (i = 0; i < nsegs; i++) {
4362                 chain_prod = TX_CHAIN_IDX(prod);
4363                 txbd= &sc->tx_bd_chain[TX_PAGE(chain_prod)][TX_IDX(chain_prod)];
4364
4365                 txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(segs[i].ds_addr));
4366                 txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(segs[i].ds_addr));
4367                 txbd->tx_bd_mss_nbytes = htole16(segs[i].ds_len);
4368                 txbd->tx_bd_vlan_tag = htole16(vlan_tag);
4369                 txbd->tx_bd_flags = htole16(flags);
4370                 prod_bseq += segs[i].ds_len;
4371                 if (i == 0)
4372                         txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_START);
4373                 prod = NEXT_TX_BD(prod);
4374         }
4375
4376         /* Set the END flag on the last TX buffer descriptor. */
4377         txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_END);
4378
4379         DBRUN(BCE_EXCESSIVE_SEND,
4380               bce_dump_tx_chain(sc, debug_prod, nsegs));
4381
4382         DBPRINT(sc, BCE_INFO_SEND,
4383                 "%s(): End: prod = 0x%04X, chain_prod = %04X, "
4384                 "prod_bseq = 0x%08X\n",
4385                 __func__, prod, chain_prod, prod_bseq);
4386
4387         /*
4388          * Ensure that the mbuf pointer for this transmission
4389          * is placed at the array index of the last
4390          * descriptor in this chain.  This is done
4391          * because a single map is used for all 
4392          * segments of the mbuf and we don't want to
4393          * unload the map before all of the segments
4394          * have been freed.
4395          */
4396         sc->tx_mbuf_ptr[chain_prod] = m0;
4397
4398         tmp_map = sc->tx_mbuf_map[chain_prod];
4399         sc->tx_mbuf_map[chain_prod] = map;
4400         sc->tx_mbuf_map[chain_prod_start] = tmp_map;
4401
4402         sc->used_tx_bd += nsegs;
4403
4404         /* Update some debug statistic counters */
4405         DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
4406                 sc->tx_hi_watermark = sc->used_tx_bd);
4407         DBRUNIF((sc->used_tx_bd == sc->max_tx_bd), sc->tx_full_count++);
4408         DBRUNIF(1, sc->tx_mbuf_alloc++);
4409
4410         DBRUN(BCE_VERBOSE_SEND,
4411               bce_dump_tx_mbuf_chain(sc, chain_prod, nsegs));
4412
4413         /* prod points to the next free tx_bd at this point. */
4414         sc->tx_prod = prod;
4415         sc->tx_prod_bseq = prod_bseq;
4416 back:
4417         if (error) {
4418                 m_freem(*m_head);
4419                 *m_head = NULL;
4420         }
4421         return error;
4422 }
4423
4424
4425 /****************************************************************************/
4426 /* Main transmit routine when called from another routine with a lock.      */
4427 /*                                                                          */
4428 /* Returns:                                                                 */
4429 /*   Nothing.                                                               */
4430 /****************************************************************************/
4431 static void
4432 bce_start(struct ifnet *ifp)
4433 {
4434         struct bce_softc *sc = ifp->if_softc;
4435         int count = 0;
4436
4437         ASSERT_SERIALIZED(ifp->if_serializer);
4438
4439         /* If there's no link or the transmit queue is empty then just exit. */
4440         if (!sc->bce_link) {
4441                 ifq_purge(&ifp->if_snd);
4442                 return;
4443         }
4444
4445         if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
4446                 return;
4447
4448         DBPRINT(sc, BCE_INFO_SEND,
4449                 "%s(): Start: tx_prod = 0x%04X, tx_chain_prod = %04zX, "
4450                 "tx_prod_bseq = 0x%08X\n",
4451                 __func__,
4452                 sc->tx_prod, TX_CHAIN_IDX(sc->tx_prod), sc->tx_prod_bseq);
4453
4454         for (;;) {
4455                 struct mbuf *m_head;
4456
4457                 /*
4458                  * We keep BCE_TX_SPARE_SPACE entries, so bce_encap() is
4459                  * unlikely to fail.
4460                  */
4461                 if (sc->max_tx_bd - sc->used_tx_bd < BCE_TX_SPARE_SPACE) {
4462                         ifp->if_flags |= IFF_OACTIVE;
4463                         break;
4464                 }
4465
4466                 /* Check for any frames to send. */
4467                 m_head = ifq_dequeue(&ifp->if_snd, NULL);
4468                 if (m_head == NULL)
4469                         break;
4470
4471                 /*
4472                  * Pack the data into the transmit ring. If we
4473                  * don't have room, place the mbuf back at the
4474                  * head of the queue and set the OACTIVE flag
4475                  * to wait for the NIC to drain the chain.
4476                  */
4477                 if (bce_encap(sc, &m_head)) {
4478                         ifp->if_oerrors++;
4479                         if (sc->used_tx_bd == 0) {
4480                                 continue;
4481                         } else {
4482                                 ifp->if_flags |= IFF_OACTIVE;
4483                                 break;
4484                         }
4485                 }
4486
4487                 count++;
4488
4489                 /* Send a copy of the frame to any BPF listeners. */
4490                 ETHER_BPF_MTAP(ifp, m_head);
4491         }
4492
4493         if (count == 0) {
4494                 /* no packets were dequeued */
4495                 DBPRINT(sc, BCE_VERBOSE_SEND,
4496                         "%s(): No packets were dequeued\n", __func__);
4497                 return;
4498         }
4499
4500         DBPRINT(sc, BCE_INFO_SEND,
4501                 "%s(): End: tx_prod = 0x%04X, tx_chain_prod = 0x%04zX, "
4502                 "tx_prod_bseq = 0x%08X\n",
4503                 __func__,
4504                 sc->tx_prod, TX_CHAIN_IDX(sc->tx_prod), sc->tx_prod_bseq);
4505
4506         /* Start the transmit. */
4507         REG_WR16(sc, MB_TX_CID_ADDR + BCE_L2CTX_TX_HOST_BIDX, sc->tx_prod);
4508         REG_WR(sc, MB_TX_CID_ADDR + BCE_L2CTX_TX_HOST_BSEQ, sc->tx_prod_bseq);
4509
4510         /* Set the tx timeout. */
4511         ifp->if_timer = BCE_TX_TIMEOUT;
4512 }
4513
4514
4515 /****************************************************************************/
4516 /* Handles any IOCTL calls from the operating system.                       */
4517 /*                                                                          */
4518 /* Returns:                                                                 */
4519 /*   0 for success, positive value for failure.                             */
4520 /****************************************************************************/
4521 static int
4522 bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr)
4523 {
4524         struct bce_softc *sc = ifp->if_softc;
4525         struct ifreq *ifr = (struct ifreq *)data;
4526         struct mii_data *mii;
4527         int mask, error = 0;
4528
4529         ASSERT_SERIALIZED(ifp->if_serializer);
4530
4531         switch(command) {
4532         case SIOCSIFMTU:
4533                 /* Check that the MTU setting is supported. */
4534                 if (ifr->ifr_mtu < BCE_MIN_MTU ||
4535 #ifdef notyet
4536                     ifr->ifr_mtu > BCE_MAX_JUMBO_MTU
4537 #else
4538                     ifr->ifr_mtu > ETHERMTU
4539 #endif
4540                    ) {
4541                         error = EINVAL;
4542                         break;
4543                 }
4544
4545                 DBPRINT(sc, BCE_INFO, "Setting new MTU of %d\n", ifr->ifr_mtu);
4546
4547                 ifp->if_mtu = ifr->ifr_mtu;
4548                 ifp->if_flags &= ~IFF_RUNNING;  /* Force reinitialize */
4549                 bce_init(sc);
4550                 break;
4551
4552         case SIOCSIFFLAGS:
4553                 if (ifp->if_flags & IFF_UP) {
4554                         if (ifp->if_flags & IFF_RUNNING) {
4555                                 mask = ifp->if_flags ^ sc->bce_if_flags;
4556
4557                                 if (mask & (IFF_PROMISC | IFF_ALLMULTI))
4558                                         bce_set_rx_mode(sc);
4559                         } else {
4560                                 bce_init(sc);
4561                         }
4562                 } else if (ifp->if_flags & IFF_RUNNING) {
4563                         bce_stop(sc);
4564                 }
4565                 sc->bce_if_flags = ifp->if_flags;
4566                 break;
4567
4568         case SIOCADDMULTI:
4569         case SIOCDELMULTI:
4570                 if (ifp->if_flags & IFF_RUNNING)
4571                         bce_set_rx_mode(sc);
4572                 break;
4573
4574         case SIOCSIFMEDIA:
4575         case SIOCGIFMEDIA:
4576                 DBPRINT(sc, BCE_VERBOSE, "bce_phy_flags = 0x%08X\n",
4577                         sc->bce_phy_flags);
4578                 DBPRINT(sc, BCE_VERBOSE, "Copper media set/get\n");
4579
4580                 mii = device_get_softc(sc->bce_miibus);
4581                 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command);
4582                 break;
4583
4584         case SIOCSIFCAP:
4585                 mask = ifr->ifr_reqcap ^ ifp->if_capenable;
4586                 DBPRINT(sc, BCE_INFO, "Received SIOCSIFCAP = 0x%08X\n",
4587                         (uint32_t) mask);
4588
4589                 if (mask & IFCAP_HWCSUM) {
4590                         ifp->if_capenable ^= (mask & IFCAP_HWCSUM);
4591                         if (IFCAP_HWCSUM & ifp->if_capenable)
4592                                 ifp->if_hwassist = BCE_IF_HWASSIST;
4593                         else
4594                                 ifp->if_hwassist = 0;
4595                 }
4596                 break;
4597
4598         default:
4599                 error = ether_ioctl(ifp, command, data);
4600                 break;
4601         }
4602         return error;
4603 }
4604
4605
4606 /****************************************************************************/
4607 /* Transmit timeout handler.                                                */
4608 /*                                                                          */
4609 /* Returns:                                                                 */
4610 /*   Nothing.                                                               */
4611 /****************************************************************************/
4612 static void
4613 bce_watchdog(struct ifnet *ifp)
4614 {
4615         struct bce_softc *sc = ifp->if_softc;
4616
4617         ASSERT_SERIALIZED(ifp->if_serializer);
4618
4619         DBRUN(BCE_VERBOSE_SEND,
4620               bce_dump_driver_state(sc);
4621               bce_dump_status_block(sc));
4622
4623         /*
4624          * If we are in this routine because of pause frames, then
4625          * don't reset the hardware.
4626          */
4627         if (REG_RD(sc, BCE_EMAC_TX_STATUS) & BCE_EMAC_TX_STATUS_XOFFED) 
4628                 return;
4629
4630         if_printf(ifp, "Watchdog timeout occurred, resetting!\n");
4631
4632         /* DBRUN(BCE_FATAL, bce_breakpoint(sc)); */
4633
4634         ifp->if_flags &= ~IFF_RUNNING;  /* Force reinitialize */
4635         bce_init(sc);
4636
4637         ifp->if_oerrors++;
4638
4639         if (!ifq_is_empty(&ifp->if_snd))
4640                 if_devstart(ifp);
4641 }
4642
4643
4644 #ifdef DEVICE_POLLING
4645
4646 static void
4647 bce_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
4648 {
4649         struct bce_softc *sc = ifp->if_softc;
4650         struct status_block *sblk = sc->status_block;
4651         uint16_t hw_tx_cons, hw_rx_cons;
4652
4653         ASSERT_SERIALIZED(ifp->if_serializer);
4654
4655         switch (cmd) {
4656         case POLL_REGISTER:
4657                 bce_disable_intr(sc);
4658
4659                 REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
4660                        (1 << 16) | sc->bce_rx_quick_cons_trip);
4661                 REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
4662                        (1 << 16) | sc->bce_tx_quick_cons_trip);
4663                 return;
4664         case POLL_DEREGISTER:
4665                 bce_enable_intr(sc);
4666
4667                 REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
4668                        (sc->bce_tx_quick_cons_trip_int << 16) |
4669                        sc->bce_tx_quick_cons_trip);
4670                 REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
4671                        (sc->bce_rx_quick_cons_trip_int << 16) |
4672                        sc->bce_rx_quick_cons_trip);
4673                 return;
4674         default:
4675                 break;
4676         }
4677
4678         if (cmd == POLL_AND_CHECK_STATUS) {
4679                 uint32_t status_attn_bits;
4680
4681                 status_attn_bits = sblk->status_attn_bits;
4682
4683                 DBRUNIF(DB_RANDOMTRUE(bce_debug_unexpected_attention),
4684                         if_printf(ifp,
4685                         "Simulating unexpected status attention bit set.");
4686                         status_attn_bits |= STATUS_ATTN_BITS_PARITY_ERROR);
4687
4688                 /* Was it a link change interrupt? */
4689                 if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
4690                     (sblk->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE))
4691                         bce_phy_intr(sc);
4692
4693                 /*
4694                  * If any other attention is asserted then
4695                  * the chip is toast.
4696                  */
4697                 if ((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
4698                      (sblk->status_attn_bits_ack &
4699                       ~STATUS_ATTN_BITS_LINK_STATE)) {
4700                         DBRUN(1, sc->unexpected_attentions++);
4701
4702                         if_printf(ifp, "Fatal attention detected: 0x%08X\n",
4703                                   sblk->status_attn_bits);
4704
4705                         DBRUN(BCE_FATAL,
4706                         if (bce_debug_unexpected_attention == 0)
4707                                 bce_breakpoint(sc));
4708
4709                         bce_init(sc);
4710                         return;
4711                 }
4712         }
4713
4714         hw_rx_cons = bce_get_hw_rx_cons(sc);
4715         hw_tx_cons = bce_get_hw_tx_cons(sc);
4716
4717         /* Check for any completed RX frames. */
4718         if (hw_rx_cons != sc->hw_rx_cons)
4719                 bce_rx_intr(sc, count);
4720
4721         /* Check for any completed TX frames. */
4722         if (hw_tx_cons != sc->hw_tx_cons)
4723                 bce_tx_intr(sc);
4724
4725         /* Check for new frames to transmit. */
4726         if (!ifq_is_empty(&ifp->if_snd))
4727                 if_devstart(ifp);
4728 }
4729
4730 #endif  /* DEVICE_POLLING */
4731
4732
4733 /*
4734  * Interrupt handler.
4735  */
4736 /****************************************************************************/
4737 /* Main interrupt entry point.  Verifies that the controller generated the  */
4738 /* interrupt and then calls a separate routine for handle the various       */
4739 /* interrupt causes (PHY, TX, RX).                                          */
4740 /*                                                                          */
4741 /* Returns:                                                                 */
4742 /*   0 for success, positive value for failure.                             */
4743 /****************************************************************************/
4744 static void
4745 bce_intr(void *xsc)
4746 {
4747         struct bce_softc *sc = xsc;
4748         struct ifnet *ifp = &sc->arpcom.ac_if;
4749         struct status_block *sblk;
4750         uint16_t hw_rx_cons, hw_tx_cons;
4751
4752         ASSERT_SERIALIZED(ifp->if_serializer);
4753
4754         DBPRINT(sc, BCE_EXCESSIVE, "Entering %s()\n", __func__);
4755         DBRUNIF(1, sc->interrupts_generated++);
4756
4757         sblk = sc->status_block;
4758
4759         /*
4760          * If the hardware status block index matches the last value
4761          * read by the driver and we haven't asserted our interrupt
4762          * then there's nothing to do.
4763          */
4764         if (sblk->status_idx == sc->last_status_idx &&
4765             (REG_RD(sc, BCE_PCICFG_MISC_STATUS) &
4766              BCE_PCICFG_MISC_STATUS_INTA_VALUE))
4767                 return;
4768
4769         /* Ack the interrupt and stop others from occuring. */
4770         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
4771                BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
4772                BCE_PCICFG_INT_ACK_CMD_MASK_INT);
4773
4774         /* Check if the hardware has finished any work. */
4775         hw_rx_cons = bce_get_hw_rx_cons(sc);
4776         hw_tx_cons = bce_get_hw_tx_cons(sc);
4777
4778         /* Keep processing data as long as there is work to do. */
4779         for (;;) {
4780                 uint32_t status_attn_bits;
4781
4782                 status_attn_bits = sblk->status_attn_bits;
4783
4784                 DBRUNIF(DB_RANDOMTRUE(bce_debug_unexpected_attention),
4785                         if_printf(ifp,
4786                         "Simulating unexpected status attention bit set.");
4787                         status_attn_bits |= STATUS_ATTN_BITS_PARITY_ERROR);
4788
4789                 /* Was it a link change interrupt? */
4790                 if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
4791                     (sblk->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE))
4792                         bce_phy_intr(sc);
4793
4794                 /*
4795                  * If any other attention is asserted then
4796                  * the chip is toast.
4797                  */
4798                 if ((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
4799                      (sblk->status_attn_bits_ack &
4800                       ~STATUS_ATTN_BITS_LINK_STATE)) {
4801                         DBRUN(1, sc->unexpected_attentions++);
4802
4803                         if_printf(ifp, "Fatal attention detected: 0x%08X\n",
4804                                   sblk->status_attn_bits);
4805
4806                         DBRUN(BCE_FATAL,
4807                         if (bce_debug_unexpected_attention == 0)
4808                                 bce_breakpoint(sc));
4809
4810                         bce_init(sc);
4811                         return;
4812                 }
4813
4814                 /* Check for any completed RX frames. */
4815                 if (hw_rx_cons != sc->hw_rx_cons)
4816                         bce_rx_intr(sc, -1);
4817
4818                 /* Check for any completed TX frames. */
4819                 if (hw_tx_cons != sc->hw_tx_cons)
4820                         bce_tx_intr(sc);
4821
4822                 /*
4823                  * Save the status block index value
4824                  * for use during the next interrupt.
4825                  */
4826                 sc->last_status_idx = sblk->status_idx;
4827
4828                 /*
4829                  * Prevent speculative reads from getting
4830                  * ahead of the status block.
4831                  */
4832                 bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
4833                                   BUS_SPACE_BARRIER_READ);
4834
4835                 /*
4836                  * If there's no work left then exit the
4837                  * interrupt service routine.
4838                  */
4839                 hw_rx_cons = bce_get_hw_rx_cons(sc);
4840                 hw_tx_cons = bce_get_hw_tx_cons(sc);
4841                 if ((hw_rx_cons == sc->hw_rx_cons) && (hw_tx_cons == sc->hw_tx_cons))
4842                         break;
4843         }
4844
4845         /* Re-enable interrupts. */
4846         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
4847                BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx |
4848                BCE_PCICFG_INT_ACK_CMD_MASK_INT);
4849         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
4850                BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
4851
4852         if (sc->bce_coalchg_mask)
4853                 bce_coal_change(sc);
4854
4855         /* Handle any frames that arrived while handling the interrupt. */
4856         if (!ifq_is_empty(&ifp->if_snd))
4857                 if_devstart(ifp);
4858 }
4859
4860
4861 /****************************************************************************/
4862 /* Programs the various packet receive modes (broadcast and multicast).     */
4863 /*                                                                          */
4864 /* Returns:                                                                 */
4865 /*   Nothing.                                                               */
4866 /****************************************************************************/
4867 static void
4868 bce_set_rx_mode(struct bce_softc *sc)
4869 {
4870         struct ifnet *ifp = &sc->arpcom.ac_if;
4871         struct ifmultiaddr *ifma;
4872         uint32_t hashes[NUM_MC_HASH_REGISTERS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
4873         uint32_t rx_mode, sort_mode;
4874         int h, i;
4875
4876         ASSERT_SERIALIZED(ifp->if_serializer);
4877
4878         /* Initialize receive mode default settings. */
4879         rx_mode = sc->rx_mode &
4880                   ~(BCE_EMAC_RX_MODE_PROMISCUOUS |
4881                     BCE_EMAC_RX_MODE_KEEP_VLAN_TAG);
4882         sort_mode = 1 | BCE_RPM_SORT_USER0_BC_EN;
4883
4884         /*
4885          * ASF/IPMI/UMP firmware requires that VLAN tag stripping
4886          * be enbled.
4887          */
4888         if (!(BCE_IF_CAPABILITIES & IFCAP_VLAN_HWTAGGING) &&
4889             !(sc->bce_flags & BCE_MFW_ENABLE_FLAG))
4890                 rx_mode |= BCE_EMAC_RX_MODE_KEEP_VLAN_TAG;
4891
4892         /*
4893          * Check for promiscuous, all multicast, or selected
4894          * multicast address filtering.
4895          */
4896         if (ifp->if_flags & IFF_PROMISC) {
4897                 DBPRINT(sc, BCE_INFO, "Enabling promiscuous mode.\n");
4898
4899                 /* Enable promiscuous mode. */
4900                 rx_mode |= BCE_EMAC_RX_MODE_PROMISCUOUS;
4901                 sort_mode |= BCE_RPM_SORT_USER0_PROM_EN;
4902         } else if (ifp->if_flags & IFF_ALLMULTI) {
4903                 DBPRINT(sc, BCE_INFO, "Enabling all multicast mode.\n");
4904
4905                 /* Enable all multicast addresses. */
4906                 for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
4907                         REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4),
4908                                0xffffffff);
4909                 }
4910                 sort_mode |= BCE_RPM_SORT_USER0_MC_EN;
4911         } else {
4912                 /* Accept one or more multicast(s). */
4913                 DBPRINT(sc, BCE_INFO, "Enabling selective multicast mode.\n");
4914
4915                 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
4916                         if (ifma->ifma_addr->sa_family != AF_LINK)
4917                                 continue;
4918                         h = ether_crc32_le(
4919                             LLADDR((struct sockaddr_dl *)ifma->ifma_addr),
4920                             ETHER_ADDR_LEN) & 0xFF;
4921                         hashes[(h & 0xE0) >> 5] |= 1 << (h & 0x1F);
4922                 }
4923
4924                 for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
4925                         REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4),
4926                                hashes[i]);
4927                 }
4928                 sort_mode |= BCE_RPM_SORT_USER0_MC_HSH_EN;
4929         }
4930
4931         /* Only make changes if the recive mode has actually changed. */
4932         if (rx_mode != sc->rx_mode) {
4933                 DBPRINT(sc, BCE_VERBOSE, "Enabling new receive mode: 0x%08X\n",
4934                         rx_mode);
4935
4936                 sc->rx_mode = rx_mode;
4937                 REG_WR(sc, BCE_EMAC_RX_MODE, rx_mode);
4938         }
4939
4940         /* Disable and clear the exisitng sort before enabling a new sort. */
4941         REG_WR(sc, BCE_RPM_SORT_USER0, 0x0);
4942         REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode);
4943         REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode | BCE_RPM_SORT_USER0_ENA);
4944 }
4945
4946
4947 /****************************************************************************/
4948 /* Called periodically to updates statistics from the controllers           */
4949 /* statistics block.                                                        */
4950 /*                                                                          */
4951 /* Returns:                                                                 */
4952 /*   Nothing.                                                               */
4953 /****************************************************************************/
4954 static void
4955 bce_stats_update(struct bce_softc *sc)
4956 {
4957         struct ifnet *ifp = &sc->arpcom.ac_if;
4958         struct statistics_block *stats = sc->stats_block;
4959
4960         DBPRINT(sc, BCE_EXCESSIVE, "Entering %s()\n", __func__);
4961
4962         ASSERT_SERIALIZED(ifp->if_serializer);
4963
4964         /* 
4965          * Update the interface statistics from the hardware statistics.
4966          */
4967         ifp->if_collisions = (u_long)stats->stat_EtherStatsCollisions;
4968
4969         ifp->if_ierrors = (u_long)stats->stat_EtherStatsUndersizePkts +
4970                           (u_long)stats->stat_EtherStatsOverrsizePkts +
4971                           (u_long)stats->stat_IfInMBUFDiscards +
4972                           (u_long)stats->stat_Dot3StatsAlignmentErrors +
4973                           (u_long)stats->stat_Dot3StatsFCSErrors;
4974
4975         ifp->if_oerrors =
4976         (u_long)stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
4977         (u_long)stats->stat_Dot3StatsExcessiveCollisions +
4978         (u_long)stats->stat_Dot3StatsLateCollisions;
4979
4980         /* 
4981          * Certain controllers don't report carrier sense errors correctly.
4982          * See errata E11_5708CA0_1165.
4983          */
4984         if (!(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
4985             !(BCE_CHIP_ID(sc) == BCE_CHIP_ID_5708_A0)) {
4986                 ifp->if_oerrors +=
4987                         (u_long)stats->stat_Dot3StatsCarrierSenseErrors;
4988         }
4989
4990         /*
4991          * Update the sysctl statistics from the hardware statistics.
4992          */
4993         sc->stat_IfHCInOctets =
4994                 ((uint64_t)stats->stat_IfHCInOctets_hi << 32) +
4995                  (uint64_t)stats->stat_IfHCInOctets_lo;
4996
4997         sc->stat_IfHCInBadOctets =
4998                 ((uint64_t)stats->stat_IfHCInBadOctets_hi << 32) +
4999                  (uint64_t)stats->stat_IfHCInBadOctets_lo;
5000
5001         sc->stat_IfHCOutOctets =
5002                 ((uint64_t)stats->stat_IfHCOutOctets_hi << 32) +
5003                  (uint64_t)stats->stat_IfHCOutOctets_lo;
5004
5005         sc->stat_IfHCOutBadOctets =
5006                 ((uint64_t)stats->stat_IfHCOutBadOctets_hi << 32) +
5007                  (uint64_t)stats->stat_IfHCOutBadOctets_lo;
5008
5009         sc->stat_IfHCInUcastPkts =
5010                 ((uint64_t)stats->stat_IfHCInUcastPkts_hi << 32) +
5011                  (uint64_t)stats->stat_IfHCInUcastPkts_lo;
5012
5013         sc->stat_IfHCInMulticastPkts =
5014                 ((uint64_t)stats->stat_IfHCInMulticastPkts_hi << 32) +
5015                  (uint64_t)stats->stat_IfHCInMulticastPkts_lo;
5016
5017         sc->stat_IfHCInBroadcastPkts =
5018                 ((uint64_t)stats->stat_IfHCInBroadcastPkts_hi << 32) +
5019                  (uint64_t)stats->stat_IfHCInBroadcastPkts_lo;
5020
5021         sc->stat_IfHCOutUcastPkts =
5022                 ((uint64_t)stats->stat_IfHCOutUcastPkts_hi << 32) +
5023                  (uint64_t)stats->stat_IfHCOutUcastPkts_lo;
5024
5025         sc->stat_IfHCOutMulticastPkts =
5026                 ((uint64_t)stats->stat_IfHCOutMulticastPkts_hi << 32) +
5027                  (uint64_t)stats->stat_IfHCOutMulticastPkts_lo;
5028
5029         sc->stat_IfHCOutBroadcastPkts =
5030                 ((uint64_t)stats->stat_IfHCOutBroadcastPkts_hi << 32) +
5031                  (uint64_t)stats->stat_IfHCOutBroadcastPkts_lo;
5032
5033         sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors =
5034                 stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
5035
5036         sc->stat_Dot3StatsCarrierSenseErrors =
5037                 stats->stat_Dot3StatsCarrierSenseErrors;
5038
5039         sc->stat_Dot3StatsFCSErrors =
5040                 stats->stat_Dot3StatsFCSErrors;
5041
5042         sc->stat_Dot3StatsAlignmentErrors =
5043                 stats->stat_Dot3StatsAlignmentErrors;
5044
5045         sc->stat_Dot3StatsSingleCollisionFrames =
5046                 stats->stat_Dot3StatsSingleCollisionFrames;
5047
5048         sc->stat_Dot3StatsMultipleCollisionFrames =
5049                 stats->stat_Dot3StatsMultipleCollisionFrames;
5050
5051         sc->stat_Dot3StatsDeferredTransmissions =
5052                 stats->stat_Dot3StatsDeferredTransmissions;
5053
5054         sc->stat_Dot3StatsExcessiveCollisions =
5055                 stats->stat_Dot3StatsExcessiveCollisions;
5056
5057         sc->stat_Dot3StatsLateCollisions =
5058                 stats->stat_Dot3StatsLateCollisions;
5059
5060         sc->stat_EtherStatsCollisions =
5061                 stats->stat_EtherStatsCollisions;
5062
5063         sc->stat_EtherStatsFragments =
5064                 stats->stat_EtherStatsFragments;
5065
5066         sc->stat_EtherStatsJabbers =
5067                 stats->stat_EtherStatsJabbers;
5068
5069         sc->stat_EtherStatsUndersizePkts =
5070                 stats->stat_EtherStatsUndersizePkts;
5071
5072         sc->stat_EtherStatsOverrsizePkts =
5073                 stats->stat_EtherStatsOverrsizePkts;
5074
5075         sc->stat_EtherStatsPktsRx64Octets =
5076                 stats->stat_EtherStatsPktsRx64Octets;
5077
5078         sc->stat_EtherStatsPktsRx65Octetsto127Octets =
5079                 stats->stat_EtherStatsPktsRx65Octetsto127Octets;
5080
5081         sc->stat_EtherStatsPktsRx128Octetsto255Octets =
5082                 stats->stat_EtherStatsPktsRx128Octetsto255Octets;
5083
5084         sc->stat_EtherStatsPktsRx256Octetsto511Octets =
5085                 stats->stat_EtherStatsPktsRx256Octetsto511Octets;
5086
5087         sc->stat_EtherStatsPktsRx512Octetsto1023Octets =
5088                 stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
5089
5090         sc->stat_EtherStatsPktsRx1024Octetsto1522Octets =
5091                 stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
5092
5093         sc->stat_EtherStatsPktsRx1523Octetsto9022Octets =
5094                 stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
5095
5096         sc->stat_EtherStatsPktsTx64Octets =
5097                 stats->stat_EtherStatsPktsTx64Octets;
5098
5099         sc->stat_EtherStatsPktsTx65Octetsto127Octets =
5100                 stats->stat_EtherStatsPktsTx65Octetsto127Octets;
5101
5102         sc->stat_EtherStatsPktsTx128Octetsto255Octets =
5103                 stats->stat_EtherStatsPktsTx128Octetsto255Octets;
5104
5105         sc->stat_EtherStatsPktsTx256Octetsto511Octets =
5106                 stats->stat_EtherStatsPktsTx256Octetsto511Octets;
5107
5108         sc->stat_EtherStatsPktsTx512Octetsto1023Octets =
5109                 stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
5110
5111         sc->stat_EtherStatsPktsTx1024Octetsto1522Octets =
5112                 stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
5113
5114         sc->stat_EtherStatsPktsTx1523Octetsto9022Octets =
5115                 stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
5116
5117         sc->stat_XonPauseFramesReceived =
5118                 stats->stat_XonPauseFramesReceived;
5119
5120         sc->stat_XoffPauseFramesReceived =
5121                 stats->stat_XoffPauseFramesReceived;
5122
5123         sc->stat_OutXonSent =
5124                 stats->stat_OutXonSent;
5125
5126         sc->stat_OutXoffSent =
5127                 stats->stat_OutXoffSent;
5128
5129         sc->stat_FlowControlDone =
5130                 stats->stat_FlowControlDone;
5131
5132         sc->stat_MacControlFramesReceived =
5133                 stats->stat_MacControlFramesReceived;
5134
5135         sc->stat_XoffStateEntered =
5136                 stats->stat_XoffStateEntered;
5137
5138         sc->stat_IfInFramesL2FilterDiscards =
5139                 stats->stat_IfInFramesL2FilterDiscards;
5140
5141         sc->stat_IfInRuleCheckerDiscards =
5142                 stats->stat_IfInRuleCheckerDiscards;
5143
5144         sc->stat_IfInFTQDiscards =
5145                 stats->stat_IfInFTQDiscards;
5146
5147         sc->stat_IfInMBUFDiscards =
5148                 stats->stat_IfInMBUFDiscards;
5149
5150         sc->stat_IfInRuleCheckerP4Hit =
5151                 stats->stat_IfInRuleCheckerP4Hit;
5152
5153         sc->stat_CatchupInRuleCheckerDiscards =
5154                 stats->stat_CatchupInRuleCheckerDiscards;
5155
5156         sc->stat_CatchupInFTQDiscards =
5157                 stats->stat_CatchupInFTQDiscards;
5158
5159         sc->stat_CatchupInMBUFDiscards =
5160                 stats->stat_CatchupInMBUFDiscards;
5161
5162         sc->stat_CatchupInRuleCheckerP4Hit =
5163                 stats->stat_CatchupInRuleCheckerP4Hit;
5164
5165         sc->com_no_buffers = REG_RD_IND(sc, 0x120084);
5166
5167         DBPRINT(sc, BCE_EXCESSIVE, "Exiting %s()\n", __func__);
5168 }
5169
5170
5171 /****************************************************************************/
5172 /* Periodic function to perform maintenance tasks.                          */
5173 /*                                                                          */
5174 /* Returns:                                                                 */
5175 /*   Nothing.                                                               */
5176 /****************************************************************************/
5177 static void
5178 bce_tick_serialized(struct bce_softc *sc)
5179 {
5180         struct ifnet *ifp = &sc->arpcom.ac_if;
5181         struct mii_data *mii;
5182         uint32_t msg;
5183
5184         ASSERT_SERIALIZED(ifp->if_serializer);
5185
5186         /* Tell the firmware that the driver is still running. */
5187 #ifdef BCE_DEBUG
5188         msg = (uint32_t)BCE_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE;
5189 #else
5190         msg = (uint32_t)++sc->bce_fw_drv_pulse_wr_seq;
5191 #endif
5192         REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_PULSE_MB, msg);
5193
5194         /* Update the statistics from the hardware statistics block. */
5195         bce_stats_update(sc);
5196
5197         /* Schedule the next tick. */
5198         callout_reset(&sc->bce_stat_ch, hz, bce_tick, sc);
5199
5200         /* If link is up already up then we're done. */
5201         if (sc->bce_link)
5202                 return;
5203
5204         mii = device_get_softc(sc->bce_miibus);
5205         mii_tick(mii);
5206
5207         /* Check if the link has come up. */
5208         if (!sc->bce_link && (mii->mii_media_status & IFM_ACTIVE) &&
5209             IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
5210                 sc->bce_link++;
5211                 /* Now that link is up, handle any outstanding TX traffic. */
5212                 if (!ifq_is_empty(&ifp->if_snd))
5213                         if_devstart(ifp);
5214         }
5215 }
5216
5217
5218 static void
5219 bce_tick(void *xsc)
5220 {
5221         struct bce_softc *sc = xsc;
5222         struct ifnet *ifp = &sc->arpcom.ac_if;
5223
5224         lwkt_serialize_enter(ifp->if_serializer);
5225         bce_tick_serialized(sc);
5226         lwkt_serialize_exit(ifp->if_serializer);
5227 }
5228
5229
5230 #ifdef BCE_DEBUG
5231 /****************************************************************************/
5232 /* Allows the driver state to be dumped through the sysctl interface.       */
5233 /*                                                                          */
5234 /* Returns:                                                                 */
5235 /*   0 for success, positive value for failure.                             */
5236 /****************************************************************************/
5237 static int
5238 bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS)
5239 {
5240         int error;
5241         int result;
5242         struct bce_softc *sc;
5243
5244         result = -1;
5245         error = sysctl_handle_int(oidp, &result, 0, req);
5246
5247         if (error || !req->newptr)
5248                 return (error);
5249
5250         if (result == 1) {
5251                 sc = (struct bce_softc *)arg1;
5252                 bce_dump_driver_state(sc);
5253         }
5254
5255         return error;
5256 }
5257
5258
5259 /****************************************************************************/
5260 /* Allows the hardware state to be dumped through the sysctl interface.     */
5261 /*                                                                          */
5262 /* Returns:                                                                 */
5263 /*   0 for success, positive value for failure.                             */
5264 /****************************************************************************/
5265 static int
5266 bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS)
5267 {
5268         int error;
5269         int result;
5270         struct bce_softc *sc;
5271
5272         result = -1;
5273         error = sysctl_handle_int(oidp, &result, 0, req);
5274
5275         if (error || !req->newptr)
5276                 return (error);
5277
5278         if (result == 1) {
5279                 sc = (struct bce_softc *)arg1;
5280                 bce_dump_hw_state(sc);
5281         }
5282
5283         return error;
5284 }
5285
5286
5287 /****************************************************************************/
5288 /* Provides a sysctl interface to allows dumping the RX chain.              */
5289 /*                                                                          */
5290 /* Returns:                                                                 */
5291 /*   0 for success, positive value for failure.                             */
5292 /****************************************************************************/
5293 static int
5294 bce_sysctl_dump_rx_chain(SYSCTL_HANDLER_ARGS)
5295 {
5296         int error;
5297         int result;
5298         struct bce_softc *sc;
5299
5300         result = -1;
5301         error = sysctl_handle_int(oidp, &result, 0, req);
5302
5303         if (error || !req->newptr)
5304                 return (error);
5305
5306         if (result == 1) {
5307                 sc = (struct bce_softc *)arg1;
5308                 bce_dump_rx_chain(sc, 0, USABLE_RX_BD);
5309         }
5310
5311         return error;
5312 }
5313
5314
5315 /****************************************************************************/
5316 /* Provides a sysctl interface to allows dumping the TX chain.              */
5317 /*                                                                          */
5318 /* Returns:                                                                 */
5319 /*   0 for success, positive value for failure.                             */
5320 /****************************************************************************/
5321 static int
5322 bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
5323 {
5324         int error;
5325         int result;
5326         struct bce_softc *sc;
5327
5328         result = -1;
5329         error = sysctl_handle_int(oidp, &result, 0, req);
5330
5331         if (error || !req->newptr)
5332                 return (error);
5333
5334         if (result == 1) {
5335                 sc = (struct bce_softc *)arg1;
5336                 bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
5337         }
5338
5339         return error;
5340 }
5341
5342
5343 /****************************************************************************/
5344 /* Provides a sysctl interface to allow reading arbitrary registers in the  */
5345 /* device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                            */
5346 /*                                                                          */
5347 /* Returns:                                                                 */
5348 /*   0 for success, positive value for failure.                             */
5349 /****************************************************************************/
5350 static int
5351 bce_sysctl_reg_read(SYSCTL_HANDLER_ARGS)
5352 {
5353         struct bce_softc *sc;
5354         int error;
5355         uint32_t val, result;
5356
5357         result = -1;
5358         error = sysctl_handle_int(oidp, &result, 0, req);
5359         if (error || (req->newptr == NULL))
5360                 return (error);
5361
5362         /* Make sure the register is accessible. */
5363         if (result < 0x8000) {
5364                 sc = (struct bce_softc *)arg1;
5365                 val = REG_RD(sc, result);
5366                 if_printf(&sc->arpcom.ac_if, "reg 0x%08X = 0x%08X\n",
5367                           result, val);
5368         } else if (result < 0x0280000) {
5369                 sc = (struct bce_softc *)arg1;
5370                 val = REG_RD_IND(sc, result);
5371                 if_printf(&sc->arpcom.ac_if, "reg 0x%08X = 0x%08X\n",
5372                           result, val);
5373         }
5374         return (error);
5375 }
5376
5377
5378 /****************************************************************************/
5379 /* Provides a sysctl interface to allow reading arbitrary PHY registers in  */
5380 /* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
5381 /*                                                                          */
5382 /* Returns:                                                                 */
5383 /*   0 for success, positive value for failure.                             */
5384 /****************************************************************************/
5385 static int
5386 bce_sysctl_phy_read(SYSCTL_HANDLER_ARGS)
5387 {
5388         struct bce_softc *sc;
5389         device_t dev;
5390         int error, result;
5391         uint16_t val;
5392
5393         result = -1;
5394         error = sysctl_handle_int(oidp, &result, 0, req);
5395         if (error || (req->newptr == NULL))
5396                 return (error);
5397
5398         /* Make sure the register is accessible. */
5399         if (result < 0x20) {
5400                 sc = (struct bce_softc *)arg1;
5401                 dev = sc->bce_dev;
5402                 val = bce_miibus_read_reg(dev, sc->bce_phy_addr, result);
5403                 if_printf(&sc->arpcom.ac_if,
5404                           "phy 0x%02X = 0x%04X\n", result, val);
5405         }
5406         return (error);
5407 }
5408
5409
5410 /****************************************************************************/
5411 /* Provides a sysctl interface to forcing the driver to dump state and      */
5412 /* enter the debugger.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                */
5413 /*                                                                          */
5414 /* Returns:                                                                 */
5415 /*   0 for success, positive value for failure.                             */
5416 /****************************************************************************/
5417 static int
5418 bce_sysctl_breakpoint(SYSCTL_HANDLER_ARGS)
5419 {
5420         int error;
5421         int result;
5422         struct bce_softc *sc;
5423
5424         result = -1;
5425         error = sysctl_handle_int(oidp, &result, 0, req);
5426
5427         if (error || !req->newptr)
5428                 return (error);
5429
5430         if (result == 1) {
5431                 sc = (struct bce_softc *)arg1;
5432                 bce_breakpoint(sc);
5433         }
5434
5435         return error;
5436 }
5437 #endif
5438
5439
5440 /****************************************************************************/
5441 /* Adds any sysctl parameters for tuning or debugging purposes.             */
5442 /*                                                                          */
5443 /* Returns:                                                                 */
5444 /*   0 for success, positive value for failure.                             */
5445 /****************************************************************************/
5446 static void
5447 bce_add_sysctls(struct bce_softc *sc)
5448 {
5449         struct sysctl_ctx_list *ctx;
5450         struct sysctl_oid_list *children;
5451
5452         sysctl_ctx_init(&sc->bce_sysctl_ctx);
5453         sc->bce_sysctl_tree = SYSCTL_ADD_NODE(&sc->bce_sysctl_ctx,
5454                                               SYSCTL_STATIC_CHILDREN(_hw),
5455                                               OID_AUTO,
5456                                               device_get_nameunit(sc->bce_dev),
5457                                               CTLFLAG_RD, 0, "");
5458         if (sc->bce_sysctl_tree == NULL) {
5459                 device_printf(sc->bce_dev, "can't add sysctl node\n");
5460                 return;
5461         }
5462
5463         ctx = &sc->bce_sysctl_ctx;
5464         children = SYSCTL_CHILDREN(sc->bce_sysctl_tree);
5465
5466         SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tx_bds_int",
5467                         CTLTYPE_INT | CTLFLAG_RW,
5468                         sc, 0, bce_sysctl_tx_bds_int, "I",
5469                         "Send max coalesced BD count during interrupt");
5470         SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tx_bds",
5471                         CTLTYPE_INT | CTLFLAG_RW,
5472                         sc, 0, bce_sysctl_tx_bds, "I",
5473                         "Send max coalesced BD count");
5474         SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tx_ticks_int",
5475                         CTLTYPE_INT | CTLFLAG_RW,
5476                         sc, 0, bce_sysctl_tx_ticks_int, "I",
5477                         "Send coalescing ticks during interrupt");
5478         SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tx_ticks",
5479                         CTLTYPE_INT | CTLFLAG_RW,
5480                         sc, 0, bce_sysctl_tx_ticks, "I",
5481                         "Send coalescing ticks");
5482
5483         SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rx_bds_int",
5484                         CTLTYPE_INT | CTLFLAG_RW,
5485                         sc, 0, bce_sysctl_rx_bds_int, "I",
5486                         "Receive max coalesced BD count during interrupt");
5487         SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rx_bds",
5488                         CTLTYPE_INT | CTLFLAG_RW,
5489                         sc, 0, bce_sysctl_rx_bds, "I",
5490                         "Receive max coalesced BD count");
5491         SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rx_ticks_int",
5492                         CTLTYPE_INT | CTLFLAG_RW,
5493                         sc, 0, bce_sysctl_rx_ticks_int, "I",
5494                         "Receive coalescing ticks during interrupt");
5495         SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rx_ticks",
5496                         CTLTYPE_INT | CTLFLAG_RW,
5497                         sc, 0, bce_sysctl_rx_ticks, "I",
5498                         "Receive coalescing ticks");
5499
5500 #ifdef BCE_DEBUG
5501         SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
5502                 "rx_low_watermark",
5503                 CTLFLAG_RD, &sc->rx_low_watermark,
5504                 0, "Lowest level of free rx_bd's");
5505
5506         SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
5507                 "rx_empty_count",
5508                 CTLFLAG_RD, &sc->rx_empty_count,
5509                 0, "Number of times the RX chain was empty");
5510
5511         SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
5512                 "tx_hi_watermark",
5513                 CTLFLAG_RD, &sc->tx_hi_watermark,
5514                 0, "Highest level of used tx_bd's");
5515
5516         SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
5517                 "tx_full_count",
5518                 CTLFLAG_RD, &sc->tx_full_count,
5519                 0, "Number of times the TX chain was full");
5520
5521         SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
5522                 "l2fhdr_status_errors",
5523                 CTLFLAG_RD, &sc->l2fhdr_status_errors,
5524                 0, "l2_fhdr status errors");
5525
5526         SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
5527                 "unexpected_attentions",
5528                 CTLFLAG_RD, &sc->unexpected_attentions,
5529                 0, "unexpected attentions");
5530
5531         SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
5532                 "lost_status_block_updates",
5533                 CTLFLAG_RD, &sc->lost_status_block_updates,
5534                 0, "lost status block updates");
5535
5536         SYSCTL_ADD_INT(ctx, children, OID_AUTO, 
5537                 "mbuf_alloc_failed",
5538                 CTLFLAG_RD, &sc->mbuf_alloc_failed,
5539                 0, "mbuf cluster allocation failures");
5540 #endif
5541
5542         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5543                 "stat_IfHCInOctets",
5544                 CTLFLAG_RD, &sc->stat_IfHCInOctets,
5545                 "Bytes received");
5546
5547         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5548                 "stat_IfHCInBadOctets",
5549                 CTLFLAG_RD, &sc->stat_IfHCInBadOctets,
5550                 "Bad bytes received");
5551
5552         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5553                 "stat_IfHCOutOctets",
5554                 CTLFLAG_RD, &sc->stat_IfHCOutOctets,
5555                 "Bytes sent");
5556
5557         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5558                 "stat_IfHCOutBadOctets",
5559                 CTLFLAG_RD, &sc->stat_IfHCOutBadOctets,
5560                 "Bad bytes sent");
5561
5562         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5563                 "stat_IfHCInUcastPkts",
5564                 CTLFLAG_RD, &sc->stat_IfHCInUcastPkts,
5565                 "Unicast packets received");
5566
5567         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5568                 "stat_IfHCInMulticastPkts",
5569                 CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts,
5570                 "Multicast packets received");
5571
5572         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5573                 "stat_IfHCInBroadcastPkts",
5574                 CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts,
5575                 "Broadcast packets received");
5576
5577         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5578                 "stat_IfHCOutUcastPkts",
5579                 CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts,
5580                 "Unicast packets sent");
5581
5582         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5583                 "stat_IfHCOutMulticastPkts",
5584                 CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts,
5585                 "Multicast packets sent");
5586
5587         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 
5588                 "stat_IfHCOutBroadcastPkts",
5589                 CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts,
5590                 "Broadcast packets sent");
5591
5592         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5593                 "stat_emac_tx_stat_dot3statsinternalmactransmiterrors",
5594                 CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors,
5595                 0, "Internal MAC transmit errors");
5596
5597         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5598                 "stat_Dot3StatsCarrierSenseErrors",
5599                 CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors,
5600                 0, "Carrier sense errors");
5601
5602         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5603                 "stat_Dot3StatsFCSErrors",
5604                 CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors,
5605                 0, "Frame check sequence errors");
5606
5607         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5608                 "stat_Dot3StatsAlignmentErrors",
5609                 CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors,
5610                 0, "Alignment errors");
5611
5612         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5613                 "stat_Dot3StatsSingleCollisionFrames",
5614                 CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames,
5615                 0, "Single Collision Frames");
5616
5617         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5618                 "stat_Dot3StatsMultipleCollisionFrames",
5619                 CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames,
5620                 0, "Multiple Collision Frames");
5621
5622         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5623                 "stat_Dot3StatsDeferredTransmissions",
5624                 CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions,
5625                 0, "Deferred Transmissions");
5626
5627         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5628                 "stat_Dot3StatsExcessiveCollisions",
5629                 CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions,
5630                 0, "Excessive Collisions");
5631
5632         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5633                 "stat_Dot3StatsLateCollisions",
5634                 CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions,
5635                 0, "Late Collisions");
5636
5637         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5638                 "stat_EtherStatsCollisions",
5639                 CTLFLAG_RD, &sc->stat_EtherStatsCollisions,
5640                 0, "Collisions");
5641
5642         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5643                 "stat_EtherStatsFragments",
5644                 CTLFLAG_RD, &sc->stat_EtherStatsFragments,
5645                 0, "Fragments");
5646
5647         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5648                 "stat_EtherStatsJabbers",
5649                 CTLFLAG_RD, &sc->stat_EtherStatsJabbers,
5650                 0, "Jabbers");
5651
5652         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5653                 "stat_EtherStatsUndersizePkts",
5654                 CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts,
5655                 0, "Undersize packets");
5656
5657         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5658                 "stat_EtherStatsOverrsizePkts",
5659                 CTLFLAG_RD, &sc->stat_EtherStatsOverrsizePkts,
5660                 0, "stat_EtherStatsOverrsizePkts");
5661
5662         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5663                 "stat_EtherStatsPktsRx64Octets",
5664                 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets,
5665                 0, "Bytes received in 64 byte packets");
5666
5667         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5668                 "stat_EtherStatsPktsRx65Octetsto127Octets",
5669                 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets,
5670                 0, "Bytes received in 65 to 127 byte packets");
5671
5672         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5673                 "stat_EtherStatsPktsRx128Octetsto255Octets",
5674                 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets,
5675                 0, "Bytes received in 128 to 255 byte packets");
5676
5677         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5678                 "stat_EtherStatsPktsRx256Octetsto511Octets",
5679                 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets,
5680                 0, "Bytes received in 256 to 511 byte packets");
5681
5682         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5683                 "stat_EtherStatsPktsRx512Octetsto1023Octets",
5684                 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets,
5685                 0, "Bytes received in 512 to 1023 byte packets");
5686
5687         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5688                 "stat_EtherStatsPktsRx1024Octetsto1522Octets",
5689                 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets,
5690                 0, "Bytes received in 1024 t0 1522 byte packets");
5691
5692         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5693                 "stat_EtherStatsPktsRx1523Octetsto9022Octets",
5694                 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets,
5695                 0, "Bytes received in 1523 to 9022 byte packets");
5696
5697         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5698                 "stat_EtherStatsPktsTx64Octets",
5699                 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets,
5700                 0, "Bytes sent in 64 byte packets");
5701
5702         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5703                 "stat_EtherStatsPktsTx65Octetsto127Octets",
5704                 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets,
5705                 0, "Bytes sent in 65 to 127 byte packets");
5706
5707         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5708                 "stat_EtherStatsPktsTx128Octetsto255Octets",
5709                 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets,
5710                 0, "Bytes sent in 128 to 255 byte packets");
5711
5712         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5713                 "stat_EtherStatsPktsTx256Octetsto511Octets",
5714                 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets,
5715                 0, "Bytes sent in 256 to 511 byte packets");
5716
5717         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5718                 "stat_EtherStatsPktsTx512Octetsto1023Octets",
5719                 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets,
5720                 0, "Bytes sent in 512 to 1023 byte packets");
5721
5722         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5723                 "stat_EtherStatsPktsTx1024Octetsto1522Octets",
5724                 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets,
5725                 0, "Bytes sent in 1024 to 1522 byte packets");
5726
5727         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5728                 "stat_EtherStatsPktsTx1523Octetsto9022Octets",
5729                 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets,
5730                 0, "Bytes sent in 1523 to 9022 byte packets");
5731
5732         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5733                 "stat_XonPauseFramesReceived",
5734                 CTLFLAG_RD, &sc->stat_XonPauseFramesReceived,
5735                 0, "XON pause frames receved");
5736
5737         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5738                 "stat_XoffPauseFramesReceived",
5739                 CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived,
5740                 0, "XOFF pause frames received");
5741
5742         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5743                 "stat_OutXonSent",
5744                 CTLFLAG_RD, &sc->stat_OutXonSent,
5745                 0, "XON pause frames sent");
5746
5747         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5748                 "stat_OutXoffSent",
5749                 CTLFLAG_RD, &sc->stat_OutXoffSent,
5750                 0, "XOFF pause frames sent");
5751
5752         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5753                 "stat_FlowControlDone",
5754                 CTLFLAG_RD, &sc->stat_FlowControlDone,
5755                 0, "Flow control done");
5756
5757         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5758                 "stat_MacControlFramesReceived",
5759                 CTLFLAG_RD, &sc->stat_MacControlFramesReceived,
5760                 0, "MAC control frames received");
5761
5762         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5763                 "stat_XoffStateEntered",
5764                 CTLFLAG_RD, &sc->stat_XoffStateEntered,
5765                 0, "XOFF state entered");
5766
5767         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5768                 "stat_IfInFramesL2FilterDiscards",
5769                 CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards,
5770                 0, "Received L2 packets discarded");
5771
5772         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5773                 "stat_IfInRuleCheckerDiscards",
5774                 CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards,
5775                 0, "Received packets discarded by rule");
5776
5777         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5778                 "stat_IfInFTQDiscards",
5779                 CTLFLAG_RD, &sc->stat_IfInFTQDiscards,
5780                 0, "Received packet FTQ discards");
5781
5782         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5783                 "stat_IfInMBUFDiscards",
5784                 CTLFLAG_RD, &sc->stat_IfInMBUFDiscards,
5785                 0, "Received packets discarded due to lack of controller buffer memory");
5786
5787         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5788                 "stat_IfInRuleCheckerP4Hit",
5789                 CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit,
5790                 0, "Received packets rule checker hits");
5791
5792         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5793                 "stat_CatchupInRuleCheckerDiscards",
5794                 CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards,
5795                 0, "Received packets discarded in Catchup path");
5796
5797         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5798                 "stat_CatchupInFTQDiscards",
5799                 CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards,
5800                 0, "Received packets discarded in FTQ in Catchup path");
5801
5802         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5803                 "stat_CatchupInMBUFDiscards",
5804                 CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards,
5805                 0, "Received packets discarded in controller buffer memory in Catchup path");
5806
5807         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5808                 "stat_CatchupInRuleCheckerP4Hit",
5809                 CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit,
5810                 0, "Received packets rule checker hits in Catchup path");
5811
5812         SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 
5813                 "com_no_buffers",
5814                 CTLFLAG_RD, &sc->com_no_buffers,
5815                 0, "Valid packets received but no RX buffers available");
5816
5817 #ifdef BCE_DEBUG
5818         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
5819                 "driver_state", CTLTYPE_INT | CTLFLAG_RW,
5820                 (void *)sc, 0,
5821                 bce_sysctl_driver_state, "I", "Drive state information");
5822
5823         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
5824                 "hw_state", CTLTYPE_INT | CTLFLAG_RW,
5825                 (void *)sc, 0,
5826                 bce_sysctl_hw_state, "I", "Hardware state information");
5827
5828         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
5829                 "dump_rx_chain", CTLTYPE_INT | CTLFLAG_RW,
5830                 (void *)sc, 0,
5831                 bce_sysctl_dump_rx_chain, "I", "Dump rx_bd chain");
5832
5833         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
5834                 "dump_tx_chain", CTLTYPE_INT | CTLFLAG_RW,
5835                 (void *)sc, 0,
5836                 bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
5837
5838         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
5839                 "breakpoint", CTLTYPE_INT | CTLFLAG_RW,
5840                 (void *)sc, 0,
5841                 bce_sysctl_breakpoint, "I", "Driver breakpoint");
5842
5843         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
5844                 "reg_read", CTLTYPE_INT | CTLFLAG_RW,
5845                 (void *)sc, 0,
5846                 bce_sysctl_reg_read, "I", "Register read");
5847
5848         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
5849                 "phy_read", CTLTYPE_INT | CTLFLAG_RW,
5850                 (void *)sc, 0,
5851                 bce_sysctl_phy_read, "I", "PHY register read");
5852
5853 #endif
5854
5855 }
5856
5857
5858 /****************************************************************************/
5859 /* BCE Debug Routines                                                       */
5860 /****************************************************************************/
5861 #ifdef BCE_DEBUG
5862
5863 /****************************************************************************/
5864 /* Freezes the controller to allow for a cohesive state dump.               */
5865 /*                                                                          */
5866 /* Returns:                                                                 */
5867 /*   Nothing.                                                               */
5868 /****************************************************************************/
5869 static void
5870 bce_freeze_controller(struct bce_softc *sc)
5871 {
5872         uint32_t val;
5873
5874         val = REG_RD(sc, BCE_MISC_COMMAND);
5875         val |= BCE_MISC_COMMAND_DISABLE_ALL;
5876         REG_WR(sc, BCE_MISC_COMMAND, val);
5877 }
5878
5879
5880 /****************************************************************************/
5881 /* Unfreezes the controller after a freeze operation.  This may not always  */
5882 /* work and the controller will require a reset!                            */
5883 /*                                                                          */
5884 /* Returns:                                                                 */
5885 /*   Nothing.                                                               */
5886 /****************************************************************************/
5887 static void
5888 bce_unfreeze_controller(struct bce_softc *sc)
5889 {
5890         uint32_t val;
5891
5892         val = REG_RD(sc, BCE_MISC_COMMAND);
5893         val |= BCE_MISC_COMMAND_ENABLE_ALL;
5894         REG_WR(sc, BCE_MISC_COMMAND, val);
5895 }
5896
5897
5898 /****************************************************************************/
5899 /* Prints out information about an mbuf.                                    */
5900 /*                                                                          */
5901 /* Returns:                                                                 */
5902 /*   Nothing.                                                               */
5903 /****************************************************************************/
5904 static void
5905 bce_dump_mbuf(struct bce_softc *sc, struct mbuf *m)
5906 {
5907         struct ifnet *ifp = &sc->arpcom.ac_if;
5908         uint32_t val_hi, val_lo;
5909         struct mbuf *mp = m;
5910
5911         if (m == NULL) {
5912                 /* Index out of range. */
5913                 if_printf(ifp, "mbuf: null pointer\n");
5914                 return;
5915         }
5916
5917         while (mp) {
5918                 val_hi = BCE_ADDR_HI(mp);
5919                 val_lo = BCE_ADDR_LO(mp);
5920                 if_printf(ifp, "mbuf: vaddr = 0x%08X:%08X, m_len = %d, "
5921                           "m_flags = ( ", val_hi, val_lo, mp->m_len);
5922
5923                 if (mp->m_flags & M_EXT)
5924                         kprintf("M_EXT ");
5925                 if (mp->m_flags & M_PKTHDR)
5926                         kprintf("M_PKTHDR ");
5927                 if (mp->m_flags & M_EOR)
5928                         kprintf("M_EOR ");
5929 #ifdef M_RDONLY
5930                 if (mp->m_flags & M_RDONLY)
5931                         kprintf("M_RDONLY ");
5932 #endif
5933
5934                 val_hi = BCE_ADDR_HI(mp->m_data);
5935                 val_lo = BCE_ADDR_LO(mp->m_data);
5936                 kprintf(") m_data = 0x%08X:%08X\n", val_hi, val_lo);
5937
5938                 if (mp->m_flags & M_PKTHDR) {
5939                         if_printf(ifp, "- m_pkthdr: flags = ( ");
5940                         if (mp->m_flags & M_BCAST) 
5941                                 kprintf("M_BCAST ");
5942                         if (mp->m_flags & M_MCAST)
5943                                 kprintf("M_MCAST ");
5944                         if (mp->m_flags & M_FRAG)
5945                                 kprintf("M_FRAG ");
5946                         if (mp->m_flags & M_FIRSTFRAG)
5947                                 kprintf("M_FIRSTFRAG ");
5948                         if (mp->m_flags & M_LASTFRAG)
5949                                 kprintf("M_LASTFRAG ");
5950 #ifdef M_VLANTAG
5951                         if (mp->m_flags & M_VLANTAG)
5952                                 kprintf("M_VLANTAG ");
5953 #endif
5954 #ifdef M_PROMISC
5955                         if (mp->m_flags & M_PROMISC)
5956                                 kprintf("M_PROMISC ");
5957 #endif
5958                         kprintf(") csum_flags = ( ");
5959                         if (mp->m_pkthdr.csum_flags & CSUM_IP)
5960                                 kprintf("CSUM_IP ");
5961                         if (mp->m_pkthdr.csum_flags & CSUM_TCP)
5962                                 kprintf("CSUM_TCP ");
5963                         if (mp->m_pkthdr.csum_flags & CSUM_UDP)
5964                                 kprintf("CSUM_UDP ");
5965                         if (mp->m_pkthdr.csum_flags & CSUM_IP_FRAGS)
5966                                 kprintf("CSUM_IP_FRAGS ");
5967                         if (mp->m_pkthdr.csum_flags & CSUM_FRAGMENT)
5968                                 kprintf("CSUM_FRAGMENT ");
5969 #ifdef CSUM_TSO
5970                         if (mp->m_pkthdr.csum_flags & CSUM_TSO)
5971                                 kprintf("CSUM_TSO ");
5972 #endif
5973                         if (mp->m_pkthdr.csum_flags & CSUM_IP_CHECKED)
5974                                 kprintf("CSUM_IP_CHECKED ");
5975                         if (mp->m_pkthdr.csum_flags & CSUM_IP_VALID)
5976                                 kprintf("CSUM_IP_VALID ");
5977                         if (mp->m_pkthdr.csum_flags & CSUM_DATA_VALID)
5978                                 kprintf("CSUM_DATA_VALID ");
5979                         kprintf(")\n");
5980                 }
5981
5982                 if (mp->m_flags & M_EXT) {
5983                         val_hi = BCE_ADDR_HI(mp->m_ext.ext_buf);
5984                         val_lo = BCE_ADDR_LO(mp->m_ext.ext_buf);
5985                         if_printf(ifp, "- m_ext: vaddr = 0x%08X:%08X, "
5986                                   "ext_size = %d\n",
5987                                   val_hi, val_lo, mp->m_ext.ext_size);
5988                 }
5989                 mp = mp->m_next;
5990         }
5991 }
5992
5993
5994 /****************************************************************************/
5995 /* Prints out the mbufs in the TX mbuf chain.                               */
5996 /*                                                                          */
5997 /* Returns:                                                                 */
5998 /*   Nothing.                                                               */
5999 /****************************************************************************/
6000 static void
6001 bce_dump_tx_mbuf_chain(struct bce_softc *sc, int chain_prod, int count)
6002 {
6003         struct ifnet *ifp = &sc->arpcom.ac_if;
6004         int i;
6005
6006         if_printf(ifp,
6007         "----------------------------"
6008         "  tx mbuf data  "
6009         "----------------------------\n");
6010
6011         for (i = 0; i < count; i++) {
6012                 if_printf(ifp, "txmbuf[%d]\n", chain_prod);
6013                 bce_dump_mbuf(sc, sc->tx_mbuf_ptr[chain_prod]);
6014                 chain_prod = TX_CHAIN_IDX(NEXT_TX_BD(chain_prod));
6015         }
6016
6017         if_printf(ifp,
6018         "----------------------------"
6019         "----------------"
6020         "----------------------------\n");
6021 }
6022
6023
6024 /****************************************************************************/
6025 /* Prints out the mbufs in the RX mbuf chain.                               */
6026 /*                                                                          */
6027 /* Returns:                                                                 */
6028 /*   Nothing.                                                               */
6029 /****************************************************************************/
6030 static void
6031 bce_dump_rx_mbuf_chain(struct bce_softc *sc, int chain_prod, int count)
6032 {
6033         struct ifnet *ifp = &sc->arpcom.ac_if;
6034         int i;
6035
6036         if_printf(ifp,
6037         "----------------------------"
6038         "  rx mbuf data  "
6039         "----------------------------\n");
6040
6041         for (i = 0; i < count; i++) {
6042                 if_printf(ifp, "rxmbuf[0x%04X]\n", chain_prod);
6043                 bce_dump_mbuf(sc, sc->rx_mbuf_ptr[chain_prod]);
6044                 chain_prod = RX_CHAIN_IDX(NEXT_RX_BD(chain_prod));
6045         }
6046
6047         if_printf(ifp,
6048         "----------------------------"
6049         "----------------"
6050         "----------------------------\n");
6051 }
6052
6053
6054 /****************************************************************************/
6055 /* Prints out a tx_bd structure.                                            */
6056 /*                                                                          */
6057 /* Returns:                                                                 */
6058 /*   Nothing.                                                               */
6059 /****************************************************************************/
6060 static void
6061 bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
6062 {
6063         struct ifnet *ifp = &sc->arpcom.ac_if;
6064
6065         if (idx > MAX_TX_BD) {
6066                 /* Index out of range. */
6067                 if_printf(ifp, "tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
6068         } else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE) {
6069                 /* TX Chain page pointer. */
6070                 if_printf(ifp, "tx_bd[0x%04X]: haddr = 0x%08X:%08X, "
6071                           "chain page pointer\n",
6072                           idx, txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo);
6073         } else {
6074                 /* Normal tx_bd entry. */
6075                 if_printf(ifp, "tx_bd[0x%04X]: haddr = 0x%08X:%08X, "
6076                           "nbytes = 0x%08X, "
6077                           "vlan tag= 0x%04X, flags = 0x%04X (",
6078                           idx, txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
6079                           txbd->tx_bd_mss_nbytes,
6080                           txbd->tx_bd_vlan_tag, txbd->tx_bd_flags);
6081
6082                 if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT)
6083                         kprintf(" CONN_FAULT");
6084
6085                 if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM)
6086                         kprintf(" TCP_UDP_CKSUM");
6087
6088                 if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM)
6089                         kprintf(" IP_CKSUM");
6090
6091                 if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG)
6092                         kprintf("  VLAN");
6093
6094                 if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW)
6095                         kprintf(" COAL_NOW");
6096
6097                 if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC)
6098                         kprintf(" DONT_GEN_CRC");
6099
6100                 if (txbd->tx_bd_flags & TX_BD_FLAGS_START)
6101                         kprintf(" START");
6102
6103                 if (txbd->tx_bd_flags & TX_BD_FLAGS_END)
6104                         kprintf(" END");
6105
6106                 if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO)
6107                         kprintf(" LSO");
6108
6109                 if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD)
6110                         kprintf(" OPTION_WORD");
6111
6112                 if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS)
6113                         kprintf(" FLAGS");
6114
6115                 if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP)
6116                         kprintf(" SNAP");
6117
6118                 kprintf(" )\n");
6119         }
6120 }
6121
6122
6123 /****************************************************************************/
6124 /* Prints out a rx_bd structure.                                            */
6125 /*                                                                          */
6126 /* Returns:                                                                 */
6127 /*   Nothing.                                                               */
6128 /****************************************************************************/
6129 static void
6130 bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd)
6131 {
6132         struct ifnet *ifp = &sc->arpcom.ac_if;
6133
6134         if (idx > MAX_RX_BD) {
6135                 /* Index out of range. */
6136                 if_printf(ifp, "rx_bd[0x%04X]: Invalid rx_bd index!\n", idx);
6137         } else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE) {
6138                 /* TX Chain page pointer. */
6139                 if_printf(ifp, "rx_bd[0x%04X]: haddr = 0x%08X:%08X, "
6140                           "chain page pointer\n",
6141                           idx, rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo);
6142         } else {
6143                 /* Normal tx_bd entry. */
6144                 if_printf(ifp, "rx_bd[0x%04X]: haddr = 0x%08X:%08X, "
6145                           "nbytes = 0x%08X, flags = 0x%08X\n",
6146                           idx, rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo,
6147                           rxbd->rx_bd_len, rxbd->rx_bd_flags);
6148         }
6149 }
6150
6151
6152 /****************************************************************************/
6153 /* Prints out a l2_fhdr structure.                                          */
6154 /*                                                                          */
6155 /* Returns:                                                                 */
6156 /*   Nothing.                                                               */
6157 /****************************************************************************/
6158 static void
6159 bce_dump_l2fhdr(struct bce_softc *sc, int idx, struct l2_fhdr *l2fhdr)
6160 {
6161         if_printf(&sc->arpcom.ac_if, "l2_fhdr[0x%04X]: status = 0x%08X, "
6162                   "pkt_len = 0x%04X, vlan = 0x%04x, "
6163                   "ip_xsum = 0x%04X, tcp_udp_xsum = 0x%04X\n",
6164                   idx, l2fhdr->l2_fhdr_status,
6165                   l2fhdr->l2_fhdr_pkt_len, l2fhdr->l2_fhdr_vlan_tag,
6166                   l2fhdr->l2_fhdr_ip_xsum, l2fhdr->l2_fhdr_tcp_udp_xsum);
6167 }
6168
6169
6170 /****************************************************************************/
6171 /* Prints out the tx chain.                                                 */
6172 /*                                                                          */
6173 /* Returns:                                                                 */
6174 /*   Nothing.                                                               */
6175 /****************************************************************************/
6176 static void
6177 bce_dump_tx_chain(struct bce_softc *sc, int tx_prod, int count)
6178 {
6179         struct ifnet *ifp = &sc->arpcom.ac_if;
6180         int i;
6181
6182         /* First some info about the tx_bd chain structure. */
6183         if_printf(ifp,
6184         "----------------------------"
6185         "  tx_bd  chain  "
6186         "----------------------------\n");
6187
6188         if_printf(ifp, "page size      = 0x%08X, "
6189                   "tx chain pages        = 0x%08X\n",
6190                   (uint32_t)BCM_PAGE_SIZE, (uint32_t)TX_PAGES);
6191
6192         if_printf(ifp, "tx_bd per page = 0x%08X, "
6193                   "usable tx_bd per page = 0x%08X\n",
6194                   (uint32_t)TOTAL_TX_BD_PER_PAGE,
6195                   (uint32_t)USABLE_TX_BD_PER_PAGE);
6196
6197         if_printf(ifp, "total tx_bd    = 0x%08X\n", (uint32_t)TOTAL_TX_BD);
6198
6199         if_printf(ifp,
6200         "----------------------------"
6201         "  tx_bd data    "
6202         "----------------------------\n");
6203
6204         /* Now print out the tx_bd's themselves. */
6205         for (i = 0; i < count; i++) {
6206                 struct tx_bd *txbd;
6207
6208                 txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
6209                 bce_dump_txbd(sc, tx_prod, txbd);
6210                 tx_prod = TX_CHAIN_IDX(NEXT_TX_BD(tx_prod));
6211         }
6212
6213         if_printf(ifp,
6214         "----------------------------"
6215         "----------------"
6216         "----------------------------\n");
6217 }
6218
6219
6220 /****************************************************************************/
6221 /* Prints out the rx chain.                                                 */
6222 /*                                                                          */
6223 /* Returns:                                                                 */
6224 /*   Nothing.                                                               */
6225 /****************************************************************************/
6226 static void
6227 bce_dump_rx_chain(struct bce_softc *sc, int rx_prod, int count)
6228 {
6229         struct ifnet *ifp = &sc->arpcom.ac_if;
6230         int i;
6231
6232         /* First some info about the tx_bd chain structure. */
6233         if_printf(ifp,
6234         "----------------------------"
6235         "  rx_bd  chain  "
6236         "----------------------------\n");
6237
6238         if_printf(ifp, "page size      = 0x%08X, "
6239                   "rx chain pages        = 0x%08X\n",
6240                   (uint32_t)BCM_PAGE_SIZE, (uint32_t)RX_PAGES);
6241
6242         if_printf(ifp, "rx_bd per page = 0x%08X, "
6243                   "usable rx_bd per page = 0x%08X\n",
6244                   (uint32_t)TOTAL_RX_BD_PER_PAGE,
6245                   (uint32_t)USABLE_RX_BD_PER_PAGE);
6246
6247         if_printf(ifp, "total rx_bd    = 0x%08X\n", (uint32_t)TOTAL_RX_BD);
6248
6249         if_printf(ifp,
6250         "----------------------------"
6251         "   rx_bd data   "
6252         "----------------------------\n");
6253
6254         /* Now print out the rx_bd's themselves. */
6255         for (i = 0; i < count; i++) {
6256                 struct rx_bd *rxbd;
6257
6258                 rxbd = &sc->rx_bd_chain[RX_PAGE(rx_prod)][RX_IDX(rx_prod)];
6259                 bce_dump_rxbd(sc, rx_prod, rxbd);
6260                 rx_prod = RX_CHAIN_IDX(NEXT_RX_BD(rx_prod));
6261         }
6262
6263         if_printf(ifp,
6264         "----------------------------"
6265         "----------------"
6266         "----------------------------\n");
6267 }
6268
6269
6270 /****************************************************************************/
6271 /* Prints out the status block from host memory.                            */
6272 /*                                                                          */
6273 /* Returns:                                                                 */
6274 /*   Nothing.                                                               */
6275 /****************************************************************************/
6276 static void
6277 bce_dump_status_block(struct bce_softc *sc)
6278 {
6279         struct status_block *sblk = sc->status_block;
6280         struct ifnet *ifp = &sc->arpcom.ac_if;
6281
6282         if_printf(ifp,
6283         "----------------------------"
6284         "  Status Block  "
6285         "----------------------------\n");
6286
6287         if_printf(ifp, "    0x%08X - attn_bits\n", sblk->status_attn_bits);
6288
6289         if_printf(ifp, "    0x%08X - attn_bits_ack\n",
6290                   sblk->status_attn_bits_ack);
6291
6292         if_printf(ifp, "0x%04X(0x%04X) - rx_cons0\n",
6293             sblk->status_rx_quick_consumer_index0,
6294             (uint16_t)RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index0));
6295
6296         if_printf(ifp, "0x%04X(0x%04X) - tx_cons0\n",
6297             sblk->status_tx_quick_consumer_index0,
6298             (uint16_t)TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index0));
6299
6300         if_printf(ifp, "        0x%04X - status_idx\n", sblk->status_idx);
6301
6302         /* Theses indices are not used for normal L2 drivers. */
6303         if (sblk->status_rx_quick_consumer_index1) {
6304                 if_printf(ifp, "0x%04X(0x%04X) - rx_cons1\n",
6305                 sblk->status_rx_quick_consumer_index1,
6306                 (uint16_t)RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index1));
6307         }
6308
6309         if (sblk->status_tx_quick_consumer_index1) {
6310                 if_printf(ifp, "0x%04X(0x%04X) - tx_cons1\n",
6311                 sblk->status_tx_quick_consumer_index1,
6312                 (uint16_t)TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index1));
6313         }
6314
6315         if (sblk->status_rx_quick_consumer_index2) {
6316                 if_printf(ifp, "0x%04X(0x%04X)- rx_cons2\n",
6317                 sblk->status_rx_quick_consumer_index2,
6318                 (uint16_t)RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index2));
6319         }
6320
6321         if (sblk->status_tx_quick_consumer_index2) {
6322                 if_printf(ifp, "0x%04X(0x%04X) - tx_cons2\n",
6323                 sblk->status_tx_quick_consumer_index2,
6324                 (uint16_t)TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index2));
6325         }
6326
6327         if (sblk->status_rx_quick_consumer_index3) {
6328                 if_printf(ifp, "0x%04X(0x%04X) - rx_cons3\n",
6329                 sblk->status_rx_quick_consumer_index3,
6330                 (uint16_t)RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index3));
6331         }
6332
6333         if (sblk->status_tx_quick_consumer_index3) {
6334                 if_printf(ifp, "0x%04X(0x%04X) - tx_cons3\n",
6335                 sblk->status_tx_quick_consumer_index3,
6336                 (uint16_t)TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index3));
6337         }
6338
6339         if (sblk->status_rx_quick_consumer_index4 ||
6340             sblk->status_rx_quick_consumer_index5) {
6341                 if_printf(ifp, "rx_cons4  = 0x%08X, rx_cons5      = 0x%08X\n",
6342                           sblk->status_rx_quick_consumer_index4,
6343                           sblk->status_rx_quick_consumer_index5);
6344         }
6345
6346         if (sblk->status_rx_quick_consumer_index6 ||
6347             sblk->status_rx_quick_consumer_index7) {
6348                 if_printf(ifp, "rx_cons6  = 0x%08X, rx_cons7      = 0x%08X\n",
6349                           sblk->status_rx_quick_consumer_index6,
6350                           sblk->status_rx_quick_consumer_index7);
6351         }
6352
6353         if (sblk->status_rx_quick_consumer_index8 ||
6354             sblk->status_rx_quick_consumer_index9) {
6355                 if_printf(ifp, "rx_cons8  = 0x%08X, rx_cons9      = 0x%08X\n",
6356                           sblk->status_rx_quick_consumer_index8,
6357                           sblk->status_rx_quick_consumer_index9);
6358         }
6359
6360         if (sblk->status_rx_quick_consumer_index10 ||
6361             sblk->status_rx_quick_consumer_index11) {
6362                 if_printf(ifp, "rx_cons10 = 0x%08X, rx_cons11     = 0x%08X\n",
6363                           sblk->status_rx_quick_consumer_index10,
6364                           sblk->status_rx_quick_consumer_index11);
6365         }
6366
6367         if (sblk->status_rx_quick_consumer_index12 ||
6368             sblk->status_rx_quick_consumer_index13) {
6369                 if_printf(ifp, "rx_cons12 = 0x%08X, rx_cons13     = 0x%08X\n",
6370                           sblk->status_rx_quick_consumer_index12,
6371                           sblk->status_rx_quick_consumer_index13);
6372         }
6373
6374         if (sblk->status_rx_quick_consumer_index14 ||
6375             sblk->status_rx_quick_consumer_index15) {
6376                 if_printf(ifp, "rx_cons14 = 0x%08X, rx_cons15     = 0x%08X\n",
6377                           sblk->status_rx_quick_consumer_index14,
6378                           sblk->status_rx_quick_consumer_index15);
6379         }
6380
6381         if (sblk->status_completion_producer_index ||
6382             sblk->status_cmd_consumer_index) {
6383                 if_printf(ifp, "com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
6384                           sblk->status_completion_producer_index,
6385                           sblk->status_cmd_consumer_index);
6386         }
6387
6388         if_printf(ifp,
6389         "----------------------------"
6390         "----------------"
6391         "----------------------------\n");
6392 }
6393
6394
6395 /****************************************************************************/
6396 /* Prints out the statistics block.                                         */
6397 /*                                                                          */
6398 /* Returns:                                                                 */
6399 /*   Nothing.                                                               */
6400 /****************************************************************************/
6401 static void
6402 bce_dump_stats_block(struct bce_softc *sc)
6403 {
6404         struct statistics_block *sblk = sc->stats_block;
6405         struct ifnet *ifp = &sc->arpcom.ac_if;
6406
6407         if_printf(ifp,
6408         "---------------"
6409         " Stats Block  (All Stats Not Shown Are 0) "
6410         "---------------\n");
6411
6412         if (sblk->stat_IfHCInOctets_hi || sblk->stat_IfHCInOctets_lo) {
6413                 if_printf(ifp, "0x%08X:%08X : IfHcInOctets\n",
6414                           sblk->stat_IfHCInOctets_hi,
6415                           sblk->stat_IfHCInOctets_lo);
6416         }
6417
6418         if (sblk->stat_IfHCInBadOctets_hi || sblk->stat_IfHCInBadOctets_lo) {
6419                 if_printf(ifp, "0x%08X:%08X : IfHcInBadOctets\n",
6420                           sblk->stat_IfHCInBadOctets_hi,
6421                           sblk->stat_IfHCInBadOctets_lo);
6422         }
6423
6424         if (sblk->stat_IfHCOutOctets_hi || sblk->stat_IfHCOutOctets_lo) {
6425                 if_printf(ifp, "0x%08X:%08X : IfHcOutOctets\n",
6426                           sblk->stat_IfHCOutOctets_hi,
6427                           sblk->stat_IfHCOutOctets_lo);
6428         }
6429
6430         if (sblk->stat_IfHCOutBadOctets_hi || sblk->stat_IfHCOutBadOctets_lo) {
6431                 if_printf(ifp, "0x%08X:%08X : IfHcOutBadOctets\n",
6432                           sblk->stat_IfHCOutBadOctets_hi,
6433                           sblk->stat_IfHCOutBadOctets_lo);
6434         }
6435
6436         if (sblk->stat_IfHCInUcastPkts_hi || sblk->stat_IfHCInUcastPkts_lo) {
6437                 if_printf(ifp, "0x%08X:%08X : IfHcInUcastPkts\n",
6438                           sblk->stat_IfHCInUcastPkts_hi,
6439                           sblk->stat_IfHCInUcastPkts_lo);
6440         }
6441
6442         if (sblk->stat_IfHCInBroadcastPkts_hi ||
6443             sblk->stat_IfHCInBroadcastPkts_lo) {
6444                 if_printf(ifp, "0x%08X:%08X : IfHcInBroadcastPkts\n",
6445                           sblk->stat_IfHCInBroadcastPkts_hi,
6446                           sblk->stat_IfHCInBroadcastPkts_lo);
6447         }
6448
6449         if (sblk->stat_IfHCInMulticastPkts_hi ||
6450             sblk->stat_IfHCInMulticastPkts_lo) {
6451                 if_printf(ifp, "0x%08X:%08X : IfHcInMulticastPkts\n",
6452                           sblk->stat_IfHCInMulticastPkts_hi,
6453                           sblk->stat_IfHCInMulticastPkts_lo);
6454         }
6455
6456         if (sblk->stat_IfHCOutUcastPkts_hi || sblk->stat_IfHCOutUcastPkts_lo) {
6457                 if_printf(ifp, "0x%08X:%08X : IfHcOutUcastPkts\n",
6458                           sblk->stat_IfHCOutUcastPkts_hi,
6459                           sblk->stat_IfHCOutUcastPkts_lo);
6460         }
6461
6462         if (sblk->stat_IfHCOutBroadcastPkts_hi ||
6463             sblk->stat_IfHCOutBroadcastPkts_lo) {
6464                 if_printf(ifp, "0x%08X:%08X : IfHcOutBroadcastPkts\n",
6465                           sblk->stat_IfHCOutBroadcastPkts_hi,
6466                           sblk->stat_IfHCOutBroadcastPkts_lo);
6467         }
6468
6469         if (sblk->stat_IfHCOutMulticastPkts_hi ||
6470             sblk->stat_IfHCOutMulticastPkts_lo) {
6471                 if_printf(ifp, "0x%08X:%08X : IfHcOutMulticastPkts\n",
6472                           sblk->stat_IfHCOutMulticastPkts_hi,
6473                           sblk->stat_IfHCOutMulticastPkts_lo);
6474         }
6475
6476         if (sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors) {
6477                 if_printf(ifp, "         0x%08X : "
6478                 "emac_tx_stat_dot3statsinternalmactransmiterrors\n", 
6479                 sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
6480         }
6481
6482         if (sblk->stat_Dot3StatsCarrierSenseErrors) {
6483                 if_printf(ifp, "         0x%08X : "
6484                           "Dot3StatsCarrierSenseErrors\n",
6485                           sblk->stat_Dot3StatsCarrierSenseErrors);
6486         }
6487
6488         if (sblk->stat_Dot3StatsFCSErrors) {
6489                 if_printf(ifp, "         0x%08X : Dot3StatsFCSErrors\n",
6490                           sblk->stat_Dot3StatsFCSErrors);
6491         }
6492
6493         if (sblk->stat_Dot3StatsAlignmentErrors) {
6494                 if_printf(ifp, "         0x%08X : Dot3StatsAlignmentErrors\n",
6495                           sblk->stat_Dot3StatsAlignmentErrors);
6496         }
6497
6498         if (sblk->stat_Dot3StatsSingleCollisionFrames) {
6499                 if_printf(ifp, "         0x%08X : "
6500                           "Dot3StatsSingleCollisionFrames\n",
6501                           sblk->stat_Dot3StatsSingleCollisionFrames);
6502         }
6503
6504         if (sblk->stat_Dot3StatsMultipleCollisionFrames) {
6505                 if_printf(ifp, "         0x%08X : "
6506                           "Dot3StatsMultipleCollisionFrames\n",
6507                           sblk->stat_Dot3StatsMultipleCollisionFrames);
6508         }
6509
6510         if (sblk->stat_Dot3StatsDeferredTransmissions) {
6511                 if_printf(ifp, "         0x%08X : "
6512                           "Dot3StatsDeferredTransmissions\n",
6513                           sblk->stat_Dot3StatsDeferredTransmissions);
6514         }
6515
6516         if (sblk->stat_Dot3StatsExcessiveCollisions) {
6517                 if_printf(ifp, "         0x%08X : "
6518                           "Dot3StatsExcessiveCollisions\n",
6519                           sblk->stat_Dot3StatsExcessiveCollisions);
6520         }
6521
6522         if (sblk->stat_Dot3StatsLateCollisions) {
6523                 if_printf(ifp, "         0x%08X : Dot3StatsLateCollisions\n",
6524                           sblk->stat_Dot3StatsLateCollisions);
6525         }
6526
6527         if (sblk->stat_EtherStatsCollisions) {
6528                 if_printf(ifp, "         0x%08X : EtherStatsCollisions\n",
6529                           sblk->stat_EtherStatsCollisions);
6530         }
6531
6532         if (sblk->stat_EtherStatsFragments)  {
6533                 if_printf(ifp, "         0x%08X : EtherStatsFragments\n",
6534                           sblk->stat_EtherStatsFragments);
6535         }
6536
6537         if (sblk->stat_EtherStatsJabbers) {
6538                 if_printf(ifp, "         0x%08X : EtherStatsJabbers\n",
6539                           sblk->stat_EtherStatsJabbers);
6540         }
6541
6542         if (sblk->stat_EtherStatsUndersizePkts) {
6543                 if_printf(ifp, "         0x%08X : EtherStatsUndersizePkts\n",
6544                           sblk->stat_EtherStatsUndersizePkts);
6545         }
6546
6547         if (sblk->stat_EtherStatsOverrsizePkts) {
6548                 if_printf(ifp, "         0x%08X : EtherStatsOverrsizePkts\n",
6549                           sblk->stat_EtherStatsOverrsizePkts);
6550         }
6551
6552         if (sblk->stat_EtherStatsPktsRx64Octets) {
6553                 if_printf(ifp, "         0x%08X : EtherStatsPktsRx64Octets\n",
6554                           sblk->stat_EtherStatsPktsRx64Octets);
6555         }
6556
6557         if (sblk->stat_EtherStatsPktsRx65Octetsto127Octets) {
6558                 if_printf(ifp, "         0x%08X : "
6559                           "EtherStatsPktsRx65Octetsto127Octets\n",
6560                           sblk->stat_EtherStatsPktsRx65Octetsto127Octets);
6561         }
6562
6563         if (sblk->stat_EtherStatsPktsRx128Octetsto255Octets) {
6564                 if_printf(ifp, "         0x%08X : "
6565                           "EtherStatsPktsRx128Octetsto255Octets\n",
6566                           sblk->stat_EtherStatsPktsRx128Octetsto255Octets);
6567         }
6568
6569         if (sblk->stat_EtherStatsPktsRx256Octetsto511Octets) {
6570                 if_printf(ifp, "         0x%08X : "
6571                           "EtherStatsPktsRx256Octetsto511Octets\n",
6572                           sblk->stat_EtherStatsPktsRx256Octetsto511Octets);
6573         }
6574
6575         if (sblk->stat_EtherStatsPktsRx512Octetsto1023Octets) {
6576                 if_printf(ifp, "         0x%08X : "
6577                           "EtherStatsPktsRx512Octetsto1023Octets\n",
6578                           sblk->stat_EtherStatsPktsRx512Octetsto1023Octets);
6579         }
6580
6581         if (sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets) {
6582                 if_printf(ifp, "         0x%08X : "
6583                           "EtherStatsPktsRx1024Octetsto1522Octets\n",
6584                           sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets);
6585         }
6586
6587         if (sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets) {
6588                 if_printf(ifp, "         0x%08X : "
6589                           "EtherStatsPktsRx1523Octetsto9022Octets\n",
6590                           sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets);
6591         }
6592
6593         if (sblk->stat_EtherStatsPktsTx64Octets) {
6594                 if_printf(ifp, "         0x%08X : EtherStatsPktsTx64Octets\n",
6595                           sblk->stat_EtherStatsPktsTx64Octets);
6596         }
6597
6598         if (sblk->stat_EtherStatsPktsTx65Octetsto127Octets) {
6599                 if_printf(ifp, "         0x%08X : "
6600                           "EtherStatsPktsTx65Octetsto127Octets\n",
6601                           sblk->stat_EtherStatsPktsTx65Octetsto127Octets);
6602         }
6603
6604         if (sblk->stat_EtherStatsPktsTx128Octetsto255Octets) {
6605                 if_printf(ifp, "         0x%08X : "
6606                           "EtherStatsPktsTx128Octetsto255Octets\n",
6607                           sblk->stat_EtherStatsPktsTx128Octetsto255Octets);
6608         }
6609
6610         if (sblk->stat_EtherStatsPktsTx256Octetsto511Octets) {
6611                 if_printf(ifp, "         0x%08X : "
6612                           "EtherStatsPktsTx256Octetsto511Octets\n",
6613                           sblk->stat_EtherStatsPktsTx256Octetsto511Octets);
6614         }
6615
6616         if (sblk->stat_EtherStatsPktsTx512Octetsto1023Octets) {
6617                 if_printf(ifp, "         0x%08X : "
6618                           "EtherStatsPktsTx512Octetsto1023Octets\n",
6619                           sblk->stat_EtherStatsPktsTx512Octetsto1023Octets);
6620         }
6621
6622         if (sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets) {
6623                 if_printf(ifp, "         0x%08X : "
6624                           "EtherStatsPktsTx1024Octetsto1522Octets\n",
6625                           sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets);
6626         }
6627
6628         if (sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets) {
6629                 if_printf(ifp, "         0x%08X : "
6630                           "EtherStatsPktsTx1523Octetsto9022Octets\n",
6631                           sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets);
6632         }
6633
6634         if (sblk->stat_XonPauseFramesReceived) {
6635                 if_printf(ifp, "         0x%08X : XonPauseFramesReceived\n",
6636                           sblk->stat_XonPauseFramesReceived);
6637         }
6638
6639         if (sblk->stat_XoffPauseFramesReceived) {
6640                 if_printf(ifp, "          0x%08X : XoffPauseFramesReceived\n",
6641                           sblk->stat_XoffPauseFramesReceived);
6642         }
6643
6644         if (sblk->stat_OutXonSent) {
6645                 if_printf(ifp, "         0x%08X : OutXoffSent\n",
6646                           sblk->stat_OutXonSent);
6647         }
6648
6649         if (sblk->stat_OutXoffSent) {
6650                 if_printf(ifp, "         0x%08X : OutXoffSent\n",
6651                           sblk->stat_OutXoffSent);
6652         }
6653
6654         if (sblk->stat_FlowControlDone) {
6655                 if_printf(ifp, "         0x%08X : FlowControlDone\n",
6656                           sblk->stat_FlowControlDone);
6657         }
6658
6659         if (sblk->stat_MacControlFramesReceived) {
6660                 if_printf(ifp, "         0x%08X : MacControlFramesReceived\n",
6661                           sblk->stat_MacControlFramesReceived);
6662         }
6663
6664         if (sblk->stat_XoffStateEntered) {
6665                 if_printf(ifp, "         0x%08X : XoffStateEntered\n",
6666                           sblk->stat_XoffStateEntered);
6667         }
6668
6669         if (sblk->stat_IfInFramesL2FilterDiscards) {
6670                 if_printf(ifp, "         0x%08X : IfInFramesL2FilterDiscards\n",                          sblk->stat_IfInFramesL2FilterDiscards);
6671         }
6672
6673         if (sblk->stat_IfInRuleCheckerDiscards) {
6674                 if_printf(ifp, "         0x%08X : IfInRuleCheckerDiscards\n",
6675                           sblk->stat_IfInRuleCheckerDiscards);
6676         }
6677
6678         if (sblk->stat_IfInFTQDiscards) {
6679                 if_printf(ifp, "         0x%08X : IfInFTQDiscards\n",
6680                           sblk->stat_IfInFTQDiscards);
6681         }
6682
6683         if (sblk->stat_IfInMBUFDiscards) {
6684                 if_printf(ifp, "         0x%08X : IfInMBUFDiscards\n",
6685                           sblk->stat_IfInMBUFDiscards);
6686         }
6687
6688         if (sblk->stat_IfInRuleCheckerP4Hit) {
6689                 if_printf(ifp, "         0x%08X : IfInRuleCheckerP4Hit\n",
6690                           sblk->stat_IfInRuleCheckerP4Hit);
6691         }
6692
6693         if (sblk->stat_CatchupInRuleCheckerDiscards) {
6694                 if_printf(ifp, "         0x%08X : "
6695                           "CatchupInRuleCheckerDiscards\n",
6696                           sblk->stat_CatchupInRuleCheckerDiscards);
6697         }
6698
6699         if (sblk->stat_CatchupInFTQDiscards) {
6700                 if_printf(ifp, "         0x%08X : CatchupInFTQDiscards\n",
6701                           sblk->stat_CatchupInFTQDiscards);
6702         }
6703
6704         if (sblk->stat_CatchupInMBUFDiscards) {
6705                 if_printf(ifp, "         0x%08X : CatchupInMBUFDiscards\n",
6706                           sblk->stat_CatchupInMBUFDiscards);
6707         }
6708
6709         if (sblk->stat_CatchupInRuleCheckerP4Hit) {
6710                 if_printf(ifp, "         0x%08X : CatchupInRuleCheckerP4Hit\n",
6711                           sblk->stat_CatchupInRuleCheckerP4Hit);
6712         }
6713
6714         if_printf(ifp,
6715         "----------------------------"
6716         "----------------"
6717         "----------------------------\n");
6718 }
6719
6720
6721 /****************************************************************************/
6722 /* Prints out a summary of the driver state.                                */
6723 /*                                                                          */
6724 /* Returns:                                                                 */
6725 /*   Nothing.                                                               */
6726 /****************************************************************************/
6727 static void
6728 bce_dump_driver_state(struct bce_softc *sc)
6729 {
6730         struct ifnet *ifp = &sc->arpcom.ac_if;
6731         uint32_t val_hi, val_lo;
6732
6733         if_printf(ifp,
6734         "-----------------------------"
6735         " Driver State "
6736         "-----------------------------\n");
6737
6738         val_hi = BCE_ADDR_HI(sc);
6739         val_lo = BCE_ADDR_LO(sc);
6740         if_printf(ifp, "0x%08X:%08X - (sc) driver softc structure "
6741                   "virtual address\n", val_hi, val_lo);
6742
6743         val_hi = BCE_ADDR_HI(sc->status_block);
6744         val_lo = BCE_ADDR_LO(sc->status_block);
6745         if_printf(ifp, "0x%08X:%08X - (sc->status_block) status block "
6746                   "virtual address\n", val_hi, val_lo);
6747
6748         val_hi = BCE_ADDR_HI(sc->stats_block);
6749         val_lo = BCE_ADDR_LO(sc->stats_block);
6750         if_printf(ifp, "0x%08X:%08X - (sc->stats_block) statistics block "
6751                   "virtual address\n", val_hi, val_lo);
6752
6753         val_hi = BCE_ADDR_HI(sc->tx_bd_chain);
6754         val_lo = BCE_ADDR_LO(sc->tx_bd_chain);
6755         if_printf(ifp, "0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain "
6756                   "virtual adddress\n", val_hi, val_lo);
6757
6758         val_hi = BCE_ADDR_HI(sc->rx_bd_chain);
6759         val_lo = BCE_ADDR_LO(sc->rx_bd_chain);
6760         if_printf(ifp, "0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain "
6761                   "virtual address\n", val_hi, val_lo);
6762
6763         val_hi = BCE_ADDR_HI(sc->tx_mbuf_ptr);
6764         val_lo = BCE_ADDR_LO(sc->tx_mbuf_ptr);
6765         if_printf(ifp, "0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain "
6766                   "virtual address\n", val_hi, val_lo);
6767
6768         val_hi = BCE_ADDR_HI(sc->rx_mbuf_ptr);
6769         val_lo = BCE_ADDR_LO(sc->rx_mbuf_ptr);
6770         if_printf(ifp, "0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain "
6771                   "virtual address\n", val_hi, val_lo);
6772
6773         if_printf(ifp, "         0x%08X - (sc->interrupts_generated) "
6774                   "h/w intrs\n", sc->interrupts_generated);
6775
6776         if_printf(ifp, "         0x%08X - (sc->rx_interrupts) "
6777                   "rx interrupts handled\n", sc->rx_interrupts);
6778
6779         if_printf(ifp, "         0x%08X - (sc->tx_interrupts) "
6780                   "tx interrupts handled\n", sc->tx_interrupts);
6781
6782         if_printf(ifp, "         0x%08X - (sc->last_status_idx) "
6783                   "status block index\n", sc->last_status_idx);
6784
6785         if_printf(ifp, "     0x%04X(0x%04X) - (sc->tx_prod) "
6786                   "tx producer index\n",
6787                   sc->tx_prod, (uint16_t)TX_CHAIN_IDX(sc->tx_prod));
6788
6789         if_printf(ifp, "     0x%04X(0x%04X) - (sc->tx_cons) "
6790                   "tx consumer index\n",
6791                   sc->tx_cons, (uint16_t)TX_CHAIN_IDX(sc->tx_cons));
6792
6793         if_printf(ifp, "         0x%08X - (sc->tx_prod_bseq) "
6794                   "tx producer bseq index\n", sc->tx_prod_bseq);
6795
6796         if_printf(ifp, "     0x%04X(0x%04X) - (sc->rx_prod) "
6797                   "rx producer index\n",
6798                   sc->rx_prod, (uint16_t)RX_CHAIN_IDX(sc->rx_prod));
6799
6800         if_printf(ifp, "     0x%04X(0x%04X) - (sc->rx_cons) "
6801                   "rx consumer index\n",
6802                   sc->rx_cons, (uint16_t)RX_CHAIN_IDX(sc->rx_cons));
6803
6804         if_printf(ifp, "         0x%08X - (sc->rx_prod_bseq) "
6805                   "rx producer bseq index\n", sc->rx_prod_bseq);
6806
6807         if_printf(ifp, "         0x%08X - (sc->rx_mbuf_alloc) "
6808                   "rx mbufs allocated\n", sc->rx_mbuf_alloc);
6809
6810         if_printf(ifp, "         0x%08X - (sc->free_rx_bd) "
6811                   "free rx_bd's\n", sc->free_rx_bd);
6812
6813         if_printf(ifp, "0x%08X/%08X - (sc->rx_low_watermark) rx "
6814                   "low watermark\n", sc->rx_low_watermark, sc->max_rx_bd);
6815
6816         if_printf(ifp, "         0x%08X - (sc->txmbuf_alloc) "
6817                   "tx mbufs allocated\n", sc->tx_mbuf_alloc);
6818
6819         if_printf(ifp, "         0x%08X - (sc->rx_mbuf_alloc) "
6820                   "rx mbufs allocated\n", sc->rx_mbuf_alloc);
6821
6822         if_printf(ifp, "         0x%08X - (sc->used_tx_bd) used tx_bd's\n",
6823                   sc->used_tx_bd);
6824
6825         if_printf(ifp, "0x%08X/%08X - (sc->tx_hi_watermark) tx hi watermark\n",
6826                   sc->tx_hi_watermark, sc->max_tx_bd);
6827
6828         if_printf(ifp, "         0x%08X - (sc->mbuf_alloc_failed) "
6829                   "failed mbuf alloc\n", sc->mbuf_alloc_failed);
6830
6831         if_printf(ifp,
6832         "----------------------------"
6833         "----------------"
6834         "----------------------------\n");
6835 }
6836
6837
6838 /****************************************************************************/
6839 /* Prints out the hardware state through a summary of important registers,  */
6840 /* followed by a complete register dump.                                    */
6841 /*                                                                          */
6842 /* Returns:                                                                 */
6843 /*   Nothing.                                                               */
6844 /****************************************************************************/
6845 static void
6846 bce_dump_hw_state(struct bce_softc *sc)
6847 {
6848         struct ifnet *ifp = &sc->arpcom.ac_if;
6849         uint32_t val1;
6850         int i;
6851
6852         if_printf(ifp,
6853         "----------------------------"
6854         " Hardware State "
6855         "----------------------------\n");
6856
6857         if_printf(ifp, "0x%08X - bootcode version\n", sc->bce_fw_ver);
6858
6859         val1 = REG_RD(sc, BCE_MISC_ENABLE_STATUS_BITS);
6860         if_printf(ifp, "0x%08X - (0x%06X) misc_enable_status_bits\n",
6861                   val1, BCE_MISC_ENABLE_STATUS_BITS);
6862
6863         val1 = REG_RD(sc, BCE_DMA_STATUS);
6864         if_printf(ifp, "0x%08X - (0x%04X) dma_status\n", val1, BCE_DMA_STATUS);
6865
6866         val1 = REG_RD(sc, BCE_CTX_STATUS);
6867         if_printf(ifp, "0x%08X - (0x%04X) ctx_status\n", val1, BCE_CTX_STATUS);
6868
6869         val1 = REG_RD(sc, BCE_EMAC_STATUS);
6870         if_printf(ifp, "0x%08X - (0x%04X) emac_status\n",
6871                   val1, BCE_EMAC_STATUS);
6872
6873         val1 = REG_RD(sc, BCE_RPM_STATUS);
6874         if_printf(ifp, "0x%08X - (0x%04X) rpm_status\n", val1, BCE_RPM_STATUS);
6875
6876         val1 = REG_RD(sc, BCE_TBDR_STATUS);
6877         if_printf(ifp, "0x%08X - (0x%04X) tbdr_status\n",
6878                   val1, BCE_TBDR_STATUS);
6879
6880         val1 = REG_RD(sc, BCE_TDMA_STATUS);
6881         if_printf(ifp, "0x%08X - (0x%04X) tdma_status\n",
6882                   val1, BCE_TDMA_STATUS);
6883
6884         val1 = REG_RD(sc, BCE_HC_STATUS);
6885         if_printf(ifp, "0x%08X - (0x%06X) hc_status\n", val1, BCE_HC_STATUS);
6886
6887         val1 = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
6888         if_printf(ifp, "0x%08X - (0x%06X) txp_cpu_state\n",
6889                   val1, BCE_TXP_CPU_STATE);
6890
6891         val1 = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
6892         if_printf(ifp, "0x%08X - (0x%06X) tpat_cpu_state\n",
6893                   val1, BCE_TPAT_CPU_STATE);
6894
6895         val1 = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
6896         if_printf(ifp, "0x%08X - (0x%06X) rxp_cpu_state\n",
6897                   val1, BCE_RXP_CPU_STATE);
6898
6899         val1 = REG_RD_IND(sc, BCE_COM_CPU_STATE);
6900         if_printf(ifp, "0x%08X - (0x%06X) com_cpu_state\n",
6901                   val1, BCE_COM_CPU_STATE);
6902
6903         val1 = REG_RD_IND(sc, BCE_MCP_CPU_STATE);
6904         if_printf(ifp, "0x%08X - (0x%06X) mcp_cpu_state\n",
6905                   val1, BCE_MCP_CPU_STATE);
6906
6907         val1 = REG_RD_IND(sc, BCE_CP_CPU_STATE);
6908         if_printf(ifp, "0x%08X - (0x%06X) cp_cpu_state\n",
6909                   val1, BCE_CP_CPU_STATE);
6910
6911         if_printf(ifp,
6912         "----------------------------"
6913         "----------------"
6914         "----------------------------\n");
6915
6916         if_printf(ifp,
6917         "----------------------------"
6918         " Register  Dump "
6919         "----------------------------\n");
6920
6921         for (i = 0x400; i < 0x8000; i += 0x10) {
6922                 if_printf(ifp, "0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n", i,
6923                           REG_RD(sc, i),
6924                           REG_RD(sc, i + 0x4),
6925                           REG_RD(sc, i + 0x8),
6926                           REG_RD(sc, i + 0xc));
6927         }
6928
6929         if_printf(ifp,
6930         "----------------------------"
6931         "----------------"
6932         "----------------------------\n");
6933 }
6934
6935
6936 /****************************************************************************/
6937 /* Prints out the TXP state.                                                */
6938 /*                                                                          */
6939 /* Returns:                                                                 */
6940 /*   Nothing.                                                               */
6941 /****************************************************************************/
6942 static void
6943 bce_dump_txp_state(struct bce_softc *sc)
6944 {
6945         struct ifnet *ifp = &sc->arpcom.ac_if;
6946         uint32_t val1;
6947         int i;
6948
6949         if_printf(ifp,
6950         "----------------------------"
6951         "   TXP  State   "
6952         "----------------------------\n");
6953
6954         val1 = REG_RD_IND(sc, BCE_TXP_CPU_MODE);
6955         if_printf(ifp, "0x%08X - (0x%06X) txp_cpu_mode\n",
6956                   val1, BCE_TXP_CPU_MODE);
6957
6958         val1 = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
6959         if_printf(ifp, "0x%08X - (0x%06X) txp_cpu_state\n",
6960                   val1, BCE_TXP_CPU_STATE);
6961
6962         val1 = REG_RD_IND(sc, BCE_TXP_CPU_EVENT_MASK);
6963         if_printf(ifp, "0x%08X - (0x%06X) txp_cpu_event_mask\n",
6964                   val1, BCE_TXP_CPU_EVENT_MASK);
6965
6966         if_printf(ifp,
6967         "----------------------------"
6968         " Register  Dump "
6969         "----------------------------\n");
6970
6971         for (i = BCE_TXP_CPU_MODE; i < 0x68000; i += 0x10) {
6972                 /* Skip the big blank spaces */
6973                 if (i < 0x454000 && i > 0x5ffff) {
6974                         if_printf(ifp, "0x%04X: "
6975                                   "0x%08X 0x%08X 0x%08X 0x%08X\n", i,
6976                                   REG_RD_IND(sc, i),
6977                                   REG_RD_IND(sc, i + 0x4),
6978                                   REG_RD_IND(sc, i + 0x8),
6979                                   REG_RD_IND(sc, i + 0xc));
6980                 }
6981         }
6982
6983         if_printf(ifp,
6984         "----------------------------"
6985         "----------------"
6986         "----------------------------\n");
6987 }
6988
6989
6990 /****************************************************************************/
6991 /* Prints out the RXP state.                                                */
6992 /*                                                                          */
6993 /* Returns:                                                                 */
6994 /*   Nothing.                                                               */
6995 /****************************************************************************/
6996 static void
6997 bce_dump_rxp_state(struct bce_softc *sc)
6998 {
6999         struct ifnet *ifp = &sc->arpcom.ac_if;
7000         uint32_t val1;
7001         int i;
7002
7003         if_printf(ifp,
7004         "----------------------------"
7005         "   RXP  State   "
7006         "----------------------------\n");
7007
7008         val1 = REG_RD_IND(sc, BCE_RXP_CPU_MODE);
7009         if_printf(ifp, "0x%08X - (0x%06X) rxp_cpu_mode\n",
7010                   val1, BCE_RXP_CPU_MODE);
7011
7012         val1 = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
7013         if_printf(ifp, "0x%08X - (0x%06X) rxp_cpu_state\n",
7014                   val1, BCE_RXP_CPU_STATE);
7015
7016         val1 = REG_RD_IND(sc, BCE_RXP_CPU_EVENT_MASK);
7017         if_printf(ifp, "0x%08X - (0x%06X) rxp_cpu_event_mask\n",
7018                   val1, BCE_RXP_CPU_EVENT_MASK);
7019
7020         if_printf(ifp,
7021         "----------------------------"
7022         " Register  Dump "
7023         "----------------------------\n");
7024
7025         for (i = BCE_RXP_CPU_MODE; i < 0xe8fff; i += 0x10) {
7026                 /* Skip the big blank sapces */
7027                 if (i < 0xc5400 && i > 0xdffff) {
7028                         if_printf(ifp, "0x%04X: "
7029                                   "0x%08X 0x%08X 0x%08X 0x%08X\n", i,
7030                                   REG_RD_IND(sc, i),
7031                                   REG_RD_IND(sc, i + 0x4),
7032                                   REG_RD_IND(sc, i + 0x8),
7033                                   REG_RD_IND(sc, i + 0xc));
7034                 }
7035         }
7036
7037         if_printf(ifp,
7038         "----------------------------"
7039         "----------------"
7040         "----------------------------\n");
7041 }
7042
7043
7044 /****************************************************************************/
7045 /* Prints out the TPAT state.                                               */
7046 /*                                                                          */
7047 /* Returns:                                                                 */
7048 /*   Nothing.                                                               */
7049 /****************************************************************************/
7050 static void
7051 bce_dump_tpat_state(struct bce_softc *sc)
7052 {
7053         struct ifnet *ifp = &sc->arpcom.ac_if;
7054         uint32_t val1;
7055         int i;
7056
7057         if_printf(ifp,
7058         "----------------------------"
7059         "   TPAT State   "
7060         "----------------------------\n");
7061
7062         val1 = REG_RD_IND(sc, BCE_TPAT_CPU_MODE);
7063         if_printf(ifp, "0x%08X - (0x%06X) tpat_cpu_mode\n",
7064                   val1, BCE_TPAT_CPU_MODE);
7065
7066         val1 = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
7067         if_printf(ifp, "0x%08X - (0x%06X) tpat_cpu_state\n",
7068                   val1, BCE_TPAT_CPU_STATE);
7069
7070         val1 = REG_RD_IND(sc, BCE_TPAT_CPU_EVENT_MASK);
7071         if_printf(ifp, "0x%08X - (0x%06X) tpat_cpu_event_mask\n",
7072                   val1, BCE_TPAT_CPU_EVENT_MASK);
7073
7074         if_printf(ifp,
7075         "----------------------------"
7076         " Register  Dump "
7077         "----------------------------\n");
7078
7079         for (i = BCE_TPAT_CPU_MODE; i < 0xa3fff; i += 0x10) {
7080                 /* Skip the big blank spaces */
7081                 if (i < 0x854000 && i > 0x9ffff) {
7082                         if_printf(ifp, "0x%04X: "
7083                                   "0x%08X 0x%08X 0x%08X 0x%08X\n", i,
7084                                   REG_RD_IND(sc, i),
7085                                   REG_RD_IND(sc, i + 0x4),
7086                                   REG_RD_IND(sc, i + 0x8),
7087                                   REG_RD_IND(sc, i + 0xc));
7088                 }
7089         }
7090
7091         if_printf(ifp,
7092         "----------------------------"
7093         "----------------"
7094         "----------------------------\n");
7095 }
7096
7097
7098 /****************************************************************************/
7099 /* Prints out the driver state and then enters the debugger.                */
7100 /*                                                                          */
7101 /* Returns:                                                                 */
7102 /*   Nothing.                                                               */
7103 /****************************************************************************/
7104 static void
7105 bce_breakpoint(struct bce_softc *sc)
7106 {
7107 #if 0
7108         bce_freeze_controller(sc);
7109 #endif
7110
7111         bce_dump_driver_state(sc);
7112         bce_dump_status_block(sc);
7113         bce_dump_tx_chain(sc, 0, TOTAL_TX_BD);
7114         bce_dump_hw_state(sc);
7115         bce_dump_txp_state(sc);
7116
7117 #if 0
7118         bce_unfreeze_controller(sc);
7119 #endif
7120
7121         /* Call the debugger. */
7122         breakpoint();
7123 }
7124
7125 #endif  /* BCE_DEBUG */
7126
7127 static int
7128 bce_sysctl_tx_bds_int(SYSCTL_HANDLER_ARGS)
7129 {
7130         struct bce_softc *sc = arg1;
7131
7132         return bce_sysctl_coal_change(oidp, arg1, arg2, req,
7133                         &sc->bce_tx_quick_cons_trip_int,
7134                         BCE_COALMASK_TX_BDS_INT);
7135 }
7136
7137 static int
7138 bce_sysctl_tx_bds(SYSCTL_HANDLER_ARGS)
7139 {
7140         struct bce_softc *sc = arg1;
7141
7142         return bce_sysctl_coal_change(oidp, arg1, arg2, req,
7143                         &sc->bce_tx_quick_cons_trip,
7144                         BCE_COALMASK_TX_BDS);
7145 }
7146
7147 static int
7148 bce_sysctl_tx_ticks_int(SYSCTL_HANDLER_ARGS)
7149 {
7150         struct bce_softc *sc = arg1;
7151
7152         return bce_sysctl_coal_change(oidp, arg1, arg2, req,
7153                         &sc->bce_tx_ticks_int,
7154                         BCE_COALMASK_TX_TICKS_INT);
7155 }
7156
7157 static int
7158 bce_sysctl_tx_ticks(SYSCTL_HANDLER_ARGS)
7159 {
7160         struct bce_softc *sc = arg1;
7161
7162         return bce_sysctl_coal_change(oidp, arg1, arg2, req,
7163                         &sc->bce_tx_ticks,
7164                         BCE_COALMASK_TX_TICKS);
7165 }
7166
7167 static int
7168 bce_sysctl_rx_bds_int(SYSCTL_HANDLER_ARGS)
7169 {
7170         struct bce_softc *sc = arg1;
7171
7172         return bce_sysctl_coal_change(oidp, arg1, arg2, req,
7173                         &sc->bce_rx_quick_cons_trip_int,
7174                         BCE_COALMASK_RX_BDS_INT);
7175 }
7176
7177 static int
7178 bce_sysctl_rx_bds(SYSCTL_HANDLER_ARGS)
7179 {
7180         struct bce_softc *sc = arg1;
7181
7182         return bce_sysctl_coal_change(oidp, arg1, arg2, req,
7183                         &sc->bce_rx_quick_cons_trip,
7184                         BCE_COALMASK_RX_BDS);
7185 }
7186
7187 static int
7188 bce_sysctl_rx_ticks_int(SYSCTL_HANDLER_ARGS)
7189 {
7190         struct bce_softc *sc = arg1;
7191
7192         return bce_sysctl_coal_change(oidp, arg1, arg2, req,
7193                         &sc->bce_rx_ticks_int,
7194                         BCE_COALMASK_RX_TICKS_INT);
7195 }
7196
7197 static int
7198 bce_sysctl_rx_ticks(SYSCTL_HANDLER_ARGS)
7199 {
7200         struct bce_softc *sc = arg1;
7201
7202         return bce_sysctl_coal_change(oidp, arg1, arg2, req,
7203                         &sc->bce_rx_ticks,
7204                         BCE_COALMASK_RX_TICKS);
7205 }
7206
7207 static int
7208 bce_sysctl_coal_change(SYSCTL_HANDLER_ARGS, uint32_t *coal,
7209                        uint32_t coalchg_mask)
7210 {
7211         struct bce_softc *sc = arg1;
7212         struct ifnet *ifp = &sc->arpcom.ac_if;
7213         int error = 0, v;
7214
7215         lwkt_serialize_enter(ifp->if_serializer);
7216
7217         v = *coal;
7218         error = sysctl_handle_int(oidp, &v, 0, req);
7219         if (!error && req->newptr != NULL) {
7220                 if (v < 0) {
7221                         error = EINVAL;
7222                 } else {
7223                         *coal = v;
7224                         sc->bce_coalchg_mask |= coalchg_mask;
7225                 }
7226         }
7227
7228         lwkt_serialize_exit(ifp->if_serializer);
7229         return error;
7230 }
7231
7232 static void
7233 bce_coal_change(struct bce_softc *sc)
7234 {
7235         struct ifnet *ifp = &sc->arpcom.ac_if;
7236
7237         ASSERT_SERIALIZED(ifp->if_serializer);
7238
7239         if ((ifp->if_flags & IFF_RUNNING) == 0) {
7240                 sc->bce_coalchg_mask = 0;
7241                 return;
7242         }
7243
7244         if (sc->bce_coalchg_mask &
7245             (BCE_COALMASK_TX_BDS | BCE_COALMASK_TX_BDS_INT)) {
7246                 REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
7247                        (sc->bce_tx_quick_cons_trip_int << 16) |
7248                        sc->bce_tx_quick_cons_trip);
7249                 if (bootverbose) {
7250                         if_printf(ifp, "tx_bds %u, tx_bds_int %u\n",
7251                                   sc->bce_tx_quick_cons_trip,
7252                                   sc->bce_tx_quick_cons_trip_int);
7253                 }
7254         }
7255
7256         if (sc->bce_coalchg_mask &
7257             (BCE_COALMASK_TX_TICKS | BCE_COALMASK_TX_TICKS_INT)) {
7258                 REG_WR(sc, BCE_HC_TX_TICKS,
7259                        (sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
7260                 if (bootverbose) {
7261                         if_printf(ifp, "tx_ticks %u, tx_ticks_int %u\n",
7262                                   sc->bce_tx_ticks, sc->bce_tx_ticks_int);
7263                 }
7264         }
7265
7266         if (sc->bce_coalchg_mask &
7267             (BCE_COALMASK_RX_BDS | BCE_COALMASK_RX_BDS_INT)) {
7268                 REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
7269                        (sc->bce_rx_quick_cons_trip_int << 16) |
7270                        sc->bce_rx_quick_cons_trip);
7271                 if (bootverbose) {
7272                         if_printf(ifp, "rx_bds %u, rx_bds_int %u\n",
7273                                   sc->bce_rx_quick_cons_trip,
7274                                   sc->bce_rx_quick_cons_trip_int);
7275                 }
7276         }
7277
7278         if (sc->bce_coalchg_mask &
7279             (BCE_COALMASK_RX_TICKS | BCE_COALMASK_RX_TICKS_INT)) {
7280                 REG_WR(sc, BCE_HC_RX_TICKS,
7281                        (sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
7282                 if (bootverbose) {
7283                         if_printf(ifp, "rx_ticks %u, rx_ticks_int %u\n",
7284                                   sc->bce_rx_ticks, sc->bce_rx_ticks_int);
7285                 }
7286         }
7287
7288         sc->bce_coalchg_mask = 0;
7289 }