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