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