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