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