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