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