]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - sys/dev/bce/if_bce.c
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / sys / dev / bce / if_bce.c
1 /*-
2  * Copyright (c) 2006-2010 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
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 /*
35  * The following controllers are supported by this driver:
36  *   BCM5706C A2, A3
37  *   BCM5706S A2, A3
38  *   BCM5708C B1, B2
39  *   BCM5708S B1, B2
40  *   BCM5709C A1, C0
41  *   BCM5709S A1, C0
42  *   BCM5716C C0
43  *   BCM5716S C0
44  *
45  * The following controllers are not supported by this driver:
46  *   BCM5706C A0, A1 (pre-production)
47  *   BCM5706S A0, A1 (pre-production)
48  *   BCM5708C A0, B0 (pre-production)
49  *   BCM5708S A0, B0 (pre-production)
50  *   BCM5709C A0  B0, B1, B2 (pre-production)
51  *   BCM5709S A0, B0, B1, B2 (pre-production)
52  */
53
54 #include "opt_bce.h"
55
56 #include <dev/bce/if_bcereg.h>
57 #include <dev/bce/if_bcefw.h>
58
59 /****************************************************************************/
60 /* BCE Debug Options                                                        */
61 /****************************************************************************/
62 #ifdef BCE_DEBUG
63         u32 bce_debug = BCE_WARN;
64
65         /*          0 = Never              */
66         /*          1 = 1 in 2,147,483,648 */
67         /*        256 = 1 in     8,388,608 */
68         /*       2048 = 1 in     1,048,576 */
69         /*      65536 = 1 in        32,768 */
70         /*    1048576 = 1 in         2,048 */
71         /*  268435456 = 1 in             8 */
72         /*  536870912 = 1 in             4 */
73         /* 1073741824 = 1 in             2 */
74
75         /* Controls how often the l2_fhdr frame error check will fail. */
76         int l2fhdr_error_sim_control = 0;
77
78         /* Controls how often the unexpected attention check will fail. */
79         int unexpected_attention_sim_control = 0;
80
81         /* Controls how often to simulate an mbuf allocation failure. */
82         int mbuf_alloc_failed_sim_control = 0;
83
84         /* Controls how often to simulate a DMA mapping failure. */
85         int dma_map_addr_failed_sim_control = 0;
86
87         /* Controls how often to simulate a bootcode failure. */
88         int bootcode_running_failure_sim_control = 0;
89 #endif
90
91 /****************************************************************************/
92 /* BCE Build Time Options                                                   */
93 /****************************************************************************/
94 /* #define BCE_NVRAM_WRITE_SUPPORT 1 */
95
96
97 /****************************************************************************/
98 /* PCI Device ID Table                                                      */
99 /*                                                                          */
100 /* Used by bce_probe() to identify the devices supported by this driver.    */
101 /****************************************************************************/
102 #define BCE_DEVDESC_MAX         64
103
104 static struct bce_type bce_devs[] = {
105         /* BCM5706C Controllers and OEM boards. */
106         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3101,
107                 "HP NC370T Multifunction Gigabit Server Adapter" },
108         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3106,
109                 "HP NC370i Multifunction Gigabit Server Adapter" },
110         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3070,
111                 "HP NC380T PCIe DP Multifunc Gig Server Adapter" },
112         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x1709,
113                 "HP NC371i Multifunction Gigabit Server Adapter" },
114         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  PCI_ANY_ID,  PCI_ANY_ID,
115                 "Broadcom NetXtreme II BCM5706 1000Base-T" },
116
117         /* BCM5706S controllers and OEM boards. */
118         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, HP_VENDORID, 0x3102,
119                 "HP NC370F Multifunction Gigabit Server Adapter" },
120         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, PCI_ANY_ID,  PCI_ANY_ID,
121                 "Broadcom NetXtreme II BCM5706 1000Base-SX" },
122
123         /* BCM5708C controllers and OEM boards. */
124         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7037,
125                 "HP NC373T PCIe Multifunction Gig Server Adapter" },
126         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7038,
127                 "HP NC373i Multifunction Gigabit Server Adapter" },
128         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7045,
129                 "HP NC374m PCIe Multifunction Adapter" },
130         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  PCI_ANY_ID,  PCI_ANY_ID,
131                 "Broadcom NetXtreme II BCM5708 1000Base-T" },
132
133         /* BCM5708S controllers and OEM boards. */
134         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x1706,
135                 "HP NC373m Multifunction Gigabit Server Adapter" },
136         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703b,
137                 "HP NC373i Multifunction Gigabit Server Adapter" },
138         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703d,
139                 "HP NC373F PCIe Multifunc Giga Server Adapter" },
140         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  PCI_ANY_ID,  PCI_ANY_ID,
141                 "Broadcom NetXtreme II BCM5708 1000Base-SX" },
142
143         /* BCM5709C controllers and OEM boards. */
144         { BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7055,
145                 "HP NC382i DP Multifunction Gigabit Server Adapter" },
146         { BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7059,
147                 "HP NC382T PCIe DP Multifunction Gigabit Server Adapter" },
148         { BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  PCI_ANY_ID,  PCI_ANY_ID,
149                 "Broadcom NetXtreme II BCM5709 1000Base-T" },
150
151         /* BCM5709S controllers and OEM boards. */
152         { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x171d,
153                 "HP NC382m DP 1GbE Multifunction BL-c Adapter" },
154         { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x7056,
155                 "HP NC382i DP Multifunction Gigabit Server Adapter" },
156         { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  PCI_ANY_ID,  PCI_ANY_ID,
157                 "Broadcom NetXtreme II BCM5709 1000Base-SX" },
158
159         /* BCM5716 controllers and OEM boards. */
160         { BRCM_VENDORID, BRCM_DEVICEID_BCM5716,  PCI_ANY_ID,  PCI_ANY_ID,
161                 "Broadcom NetXtreme II BCM5716 1000Base-T" },
162
163         { 0, 0, 0, 0, NULL }
164 };
165
166
167 /****************************************************************************/
168 /* Supported Flash NVRAM device data.                                       */
169 /****************************************************************************/
170 static struct flash_spec flash_table[] =
171 {
172 #define BUFFERED_FLAGS          (BCE_NV_BUFFERED | BCE_NV_TRANSLATE)
173 #define NONBUFFERED_FLAGS       (BCE_NV_WREN)
174
175         /* Slow EEPROM */
176         {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
177          BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
178          SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
179          "EEPROM - slow"},
180         /* Expansion entry 0001 */
181         {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
182          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
183          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
184          "Entry 0001"},
185         /* Saifun SA25F010 (non-buffered flash) */
186         /* strap, cfg1, & write1 need updates */
187         {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
188          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
189          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
190          "Non-buffered flash (128kB)"},
191         /* Saifun SA25F020 (non-buffered flash) */
192         /* strap, cfg1, & write1 need updates */
193         {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
194          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
195          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
196          "Non-buffered flash (256kB)"},
197         /* Expansion entry 0100 */
198         {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
199          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
200          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
201          "Entry 0100"},
202         /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
203         {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
204          NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
205          ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
206          "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
207         /* Entry 0110: ST M45PE20 (non-buffered flash)*/
208         {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
209          NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
210          ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
211          "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
212         /* Saifun SA25F005 (non-buffered flash) */
213         /* strap, cfg1, & write1 need updates */
214         {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
215          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
216          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
217          "Non-buffered flash (64kB)"},
218         /* Fast EEPROM */
219         {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
220          BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
221          SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
222          "EEPROM - fast"},
223         /* Expansion entry 1001 */
224         {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
225          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
226          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
227          "Entry 1001"},
228         /* Expansion entry 1010 */
229         {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
230          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
231          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
232          "Entry 1010"},
233         /* ATMEL AT45DB011B (buffered flash) */
234         {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
235          BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
236          BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
237          "Buffered flash (128kB)"},
238         /* Expansion entry 1100 */
239         {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
240          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
241          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
242          "Entry 1100"},
243         /* Expansion entry 1101 */
244         {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
245          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
246          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
247          "Entry 1101"},
248         /* Ateml Expansion entry 1110 */
249         {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
250          BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
251          BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
252          "Entry 1110 (Atmel)"},
253         /* ATMEL AT45DB021B (buffered flash) */
254         {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
255          BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
256          BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
257          "Buffered flash (256kB)"},
258 };
259
260 /*
261  * The BCM5709 controllers transparently handle the
262  * differences between Atmel 264 byte pages and all
263  * flash devices which use 256 byte pages, so no
264  * logical-to-physical mapping is required in the
265  * driver.
266  */
267 static struct flash_spec flash_5709 = {
268         .flags          = BCE_NV_BUFFERED,
269         .page_bits      = BCM5709_FLASH_PAGE_BITS,
270         .page_size      = BCM5709_FLASH_PAGE_SIZE,
271         .addr_mask      = BCM5709_FLASH_BYTE_ADDR_MASK,
272         .total_size     = BUFFERED_FLASH_TOTAL_SIZE * 2,
273         .name           = "5709/5716 buffered flash (256kB)",
274 };
275
276
277 /****************************************************************************/
278 /* FreeBSD device entry points.                                             */
279 /****************************************************************************/
280 static int  bce_probe                   (device_t);
281 static int  bce_attach                  (device_t);
282 static int  bce_detach                  (device_t);
283 static int  bce_shutdown                (device_t);
284
285
286 /****************************************************************************/
287 /* BCE Debug Data Structure Dump Routines                                   */
288 /****************************************************************************/
289 #ifdef BCE_DEBUG
290 static u32  bce_reg_rd                  (struct bce_softc *, u32);
291 static void bce_reg_wr                  (struct bce_softc *, u32, u32);
292 static void bce_reg_wr16                (struct bce_softc *, u32, u16);
293 static u32  bce_ctx_rd                  (struct bce_softc *, u32, u32);
294 static void bce_dump_enet               (struct bce_softc *, struct mbuf *);
295 static void bce_dump_mbuf               (struct bce_softc *, struct mbuf *);
296 static void bce_dump_tx_mbuf_chain      (struct bce_softc *, u16, int);
297 static void bce_dump_rx_mbuf_chain      (struct bce_softc *, u16, int);
298 #ifdef BCE_JUMBO_HDRSPLIT
299 static void bce_dump_pg_mbuf_chain      (struct bce_softc *, u16, int);
300 #endif
301 static void bce_dump_txbd               (struct bce_softc *,
302     int, struct tx_bd *);
303 static void bce_dump_rxbd               (struct bce_softc *,
304     int, struct rx_bd *);
305 #ifdef BCE_JUMBO_HDRSPLIT
306 static void bce_dump_pgbd               (struct bce_softc *, 
307     int, struct rx_bd *);
308 #endif
309 static void bce_dump_l2fhdr             (struct bce_softc *,
310     int, struct l2_fhdr *);
311 static void bce_dump_ctx                (struct bce_softc *, u16);
312 static void bce_dump_ftqs               (struct bce_softc *);
313 static void bce_dump_tx_chain           (struct bce_softc *, u16, int);
314 static void bce_dump_rx_bd_chain        (struct bce_softc *, u16, int);
315 #ifdef BCE_JUMBO_HDRSPLIT
316 static void bce_dump_pg_chain           (struct bce_softc *, u16, int);
317 #endif
318 static void bce_dump_status_block       (struct bce_softc *);
319 static void bce_dump_stats_block        (struct bce_softc *);
320 static void bce_dump_driver_state       (struct bce_softc *);
321 static void bce_dump_hw_state           (struct bce_softc *);
322 static void bce_dump_mq_regs            (struct bce_softc *);
323 static void bce_dump_bc_state           (struct bce_softc *);
324 static void bce_dump_txp_state          (struct bce_softc *, int);
325 static void bce_dump_rxp_state          (struct bce_softc *, int);
326 static void bce_dump_tpat_state         (struct bce_softc *, int);
327 static void bce_dump_cp_state           (struct bce_softc *, int);
328 static void bce_dump_com_state          (struct bce_softc *, int);
329 static void bce_dump_rv2p_state         (struct bce_softc *);
330 static void bce_breakpoint              (struct bce_softc *);
331 #endif
332
333
334 /****************************************************************************/
335 /* BCE Register/Memory Access Routines                                      */
336 /****************************************************************************/
337 static u32  bce_reg_rd_ind              (struct bce_softc *, u32);
338 static void bce_reg_wr_ind              (struct bce_softc *, u32, u32);
339 static void bce_shmem_wr                (struct bce_softc *, u32, u32);
340 static u32  bce_shmem_rd                (struct bce_softc *, u32);
341 static void bce_ctx_wr                  (struct bce_softc *, u32, u32, u32);
342 static int  bce_miibus_read_reg         (device_t, int, int);
343 static int  bce_miibus_write_reg        (device_t, int, int, int);
344 static void bce_miibus_statchg          (device_t);
345
346
347 /****************************************************************************/
348 /* BCE NVRAM Access Routines                                                */
349 /****************************************************************************/
350 static int  bce_acquire_nvram_lock      (struct bce_softc *);
351 static int  bce_release_nvram_lock      (struct bce_softc *);
352 static void bce_enable_nvram_access     (struct bce_softc *);
353 static void bce_disable_nvram_access    (struct bce_softc *);
354 static int  bce_nvram_read_dword        (struct bce_softc *, u32, u8 *, u32);
355 static int  bce_init_nvram              (struct bce_softc *);
356 static int  bce_nvram_read              (struct bce_softc *, u32, u8 *, int);
357 static int  bce_nvram_test              (struct bce_softc *);
358 #ifdef BCE_NVRAM_WRITE_SUPPORT
359 static int  bce_enable_nvram_write      (struct bce_softc *);
360 static void bce_disable_nvram_write     (struct bce_softc *);
361 static int  bce_nvram_erase_page        (struct bce_softc *, u32);
362 static int  bce_nvram_write_dword       (struct bce_softc *, u32, u8 *, u32);
363 static int  bce_nvram_write             (struct bce_softc *, u32, u8 *, int);
364 #endif
365
366 /****************************************************************************/
367 /*                                                                          */
368 /****************************************************************************/
369 static void bce_get_media               (struct bce_softc *);
370 static void bce_init_media              (struct bce_softc *);
371 static void bce_dma_map_addr            (void *, 
372     bus_dma_segment_t *, int, int);
373 static int  bce_dma_alloc               (device_t);
374 static void bce_dma_free                (struct bce_softc *);
375 static void bce_release_resources       (struct bce_softc *);
376
377 /****************************************************************************/
378 /* BCE Firmware Synchronization and Load                                    */
379 /****************************************************************************/
380 static int  bce_fw_sync                 (struct bce_softc *, u32);
381 static void bce_load_rv2p_fw            (struct bce_softc *, u32 *, u32, u32);
382 static void bce_load_cpu_fw             (struct bce_softc *, 
383     struct cpu_reg *, struct fw_info *);
384 static void bce_start_cpu               (struct bce_softc *, struct cpu_reg *);
385 static void bce_halt_cpu                (struct bce_softc *, struct cpu_reg *);
386 static void bce_start_rxp_cpu           (struct bce_softc *);
387 static void bce_init_rxp_cpu            (struct bce_softc *);
388 static void bce_init_txp_cpu            (struct bce_softc *);
389 static void bce_init_tpat_cpu           (struct bce_softc *);
390 static void bce_init_cp_cpu             (struct bce_softc *);
391 static void bce_init_com_cpu            (struct bce_softc *);
392 static void bce_init_cpus               (struct bce_softc *);
393
394 static void     bce_print_adapter_info  (struct bce_softc *);
395 static void bce_probe_pci_caps          (device_t, struct bce_softc *);
396 static void bce_stop                    (struct bce_softc *);
397 static int  bce_reset                   (struct bce_softc *, u32);
398 static int  bce_chipinit                (struct bce_softc *);
399 static int  bce_blockinit               (struct bce_softc *);
400
401 static int  bce_init_tx_chain           (struct bce_softc *);
402 static void bce_free_tx_chain           (struct bce_softc *);
403
404 static int  bce_get_rx_buf              (struct bce_softc *, 
405     struct mbuf *, u16 *, u16 *, u32 *);
406 static int  bce_init_rx_chain           (struct bce_softc *);
407 static void bce_fill_rx_chain           (struct bce_softc *);
408 static void bce_free_rx_chain           (struct bce_softc *);
409
410 #ifdef BCE_JUMBO_HDRSPLIT
411 static int  bce_get_pg_buf              (struct bce_softc *, 
412     struct mbuf *, u16 *, u16 *);
413 static int  bce_init_pg_chain           (struct bce_softc *);
414 static void bce_fill_pg_chain           (struct bce_softc *);
415 static void bce_free_pg_chain           (struct bce_softc *);
416 #endif
417
418 static struct mbuf *bce_tso_setup       (struct bce_softc *, 
419     struct mbuf **, u16 *);
420 static int  bce_tx_encap                (struct bce_softc *, struct mbuf **);
421 static void bce_start_locked            (struct ifnet *);
422 static void bce_start                   (struct ifnet *);
423 static int  bce_ioctl                   (struct ifnet *, u_long, caddr_t);
424 static void bce_watchdog                (struct bce_softc *);
425 static int  bce_ifmedia_upd             (struct ifnet *);
426 static void bce_ifmedia_upd_locked      (struct ifnet *);
427 static void bce_ifmedia_sts             (struct ifnet *, struct ifmediareq *);
428 static void bce_init_locked             (struct bce_softc *);
429 static void bce_init                    (void *);
430 static void bce_mgmt_init_locked        (struct bce_softc *sc);
431
432 static void bce_init_ctx                (struct bce_softc *);
433 static void bce_get_mac_addr            (struct bce_softc *);
434 static void bce_set_mac_addr            (struct bce_softc *);
435 static void bce_phy_intr                (struct bce_softc *);
436 static inline u16 bce_get_hw_rx_cons    (struct bce_softc *);
437 static void bce_rx_intr                 (struct bce_softc *);
438 static void bce_tx_intr                 (struct bce_softc *);
439 static void bce_disable_intr            (struct bce_softc *);
440 static void bce_enable_intr             (struct bce_softc *, int);
441
442 static void bce_intr                    (void *);
443 static void bce_set_rx_mode             (struct bce_softc *);
444 static void bce_stats_update            (struct bce_softc *);
445 static void bce_tick                    (void *);
446 static void bce_pulse                   (void *);
447 static void bce_add_sysctls             (struct bce_softc *);
448
449
450 /****************************************************************************/
451 /* FreeBSD device dispatch table.                                           */
452 /****************************************************************************/
453 static device_method_t bce_methods[] = {
454         /* Device interface (device_if.h) */
455         DEVMETHOD(device_probe,         bce_probe),
456         DEVMETHOD(device_attach,        bce_attach),
457         DEVMETHOD(device_detach,        bce_detach),
458         DEVMETHOD(device_shutdown,      bce_shutdown),
459 /* Supported by device interface but not used here. */
460 /*      DEVMETHOD(device_identify,      bce_identify),      */
461 /*      DEVMETHOD(device_suspend,       bce_suspend),       */
462 /*      DEVMETHOD(device_resume,        bce_resume),        */
463 /*      DEVMETHOD(device_quiesce,       bce_quiesce),       */
464
465         /* Bus interface (bus_if.h) */
466         DEVMETHOD(bus_print_child,      bus_generic_print_child),
467         DEVMETHOD(bus_driver_added,     bus_generic_driver_added),
468
469         /* MII interface (miibus_if.h) */
470         DEVMETHOD(miibus_readreg,       bce_miibus_read_reg),
471         DEVMETHOD(miibus_writereg,      bce_miibus_write_reg),
472         DEVMETHOD(miibus_statchg,       bce_miibus_statchg),
473 /* Supported by MII interface but not used here.       */
474 /*      DEVMETHOD(miibus_linkchg,       bce_miibus_linkchg),   */
475 /*      DEVMETHOD(miibus_mediainit,     bce_miibus_mediainit), */
476
477         { 0, 0 }
478 };
479
480 static driver_t bce_driver = {
481         "bce",
482         bce_methods,
483         sizeof(struct bce_softc)
484 };
485
486 static devclass_t bce_devclass;
487
488 MODULE_DEPEND(bce, pci, 1, 1, 1);
489 MODULE_DEPEND(bce, ether, 1, 1, 1);
490 MODULE_DEPEND(bce, miibus, 1, 1, 1);
491
492 DRIVER_MODULE(bce, pci, bce_driver, bce_devclass, 0, 0);
493 DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, 0, 0);
494
495
496 /****************************************************************************/
497 /* Tunable device values                                                    */
498 /****************************************************************************/
499 SYSCTL_NODE(_hw, OID_AUTO, bce, CTLFLAG_RD, 0, "bce driver parameters");
500
501 /* Allowable values are TRUE or FALSE */
502 static int bce_tso_enable = TRUE;
503 TUNABLE_INT("hw.bce.tso_enable", &bce_tso_enable);
504 SYSCTL_UINT(_hw_bce, OID_AUTO, tso_enable, CTLFLAG_RDTUN, &bce_tso_enable, 0,
505 "TSO Enable/Disable");
506
507 /* Allowable values are 0 (IRQ), 1 (MSI/IRQ), and 2 (MSI-X/MSI/IRQ) */
508 /* ToDo: Add MSI-X support. */
509 static int bce_msi_enable = 1;
510 TUNABLE_INT("hw.bce.msi_enable", &bce_msi_enable);
511 SYSCTL_UINT(_hw_bce, OID_AUTO, msi_enable, CTLFLAG_RDTUN, &bce_msi_enable, 0,
512 "MSI-X|MSI|INTx selector");
513
514 /* ToDo: Add tunable to enable/disable strict MTU handling. */
515 /* Currently allows "loose" RX MTU checking (i.e. sets the  */
516 /* H/W RX MTU to the size of the largest receive buffer, or */
517 /* 2048 bytes). This will cause a UNH failure but is more   */
518 /* desireable from a functional perspective.                */
519
520
521 /****************************************************************************/
522 /* Device probe function.                                                   */
523 /*                                                                          */
524 /* Compares the device to the driver's list of supported devices and        */
525 /* reports back to the OS whether this is the right driver for the device.  */
526 /*                                                                          */
527 /* Returns:                                                                 */
528 /*   BUS_PROBE_DEFAULT on success, positive value on failure.               */
529 /****************************************************************************/
530 static int
531 bce_probe(device_t dev)
532 {
533         struct bce_type *t;
534         struct bce_softc *sc;
535         char *descbuf;
536         u16 vid = 0, did = 0, svid = 0, sdid = 0;
537
538         t = bce_devs;
539
540         sc = device_get_softc(dev);
541         bzero(sc, sizeof(struct bce_softc));
542         sc->bce_unit = device_get_unit(dev);
543         sc->bce_dev = dev;
544
545         /* Get the data for the device to be probed. */
546         vid  = pci_get_vendor(dev);
547         did  = pci_get_device(dev);
548         svid = pci_get_subvendor(dev);
549         sdid = pci_get_subdevice(dev);
550
551         DBPRINT(sc, BCE_EXTREME_LOAD,
552             "%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
553             "SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
554
555         /* Look through the list of known devices for a match. */
556         while(t->bce_name != NULL) {
557
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
562                         descbuf = malloc(BCE_DEVDESC_MAX, M_TEMP, M_NOWAIT);
563
564                         if (descbuf == NULL)
565                                 return(ENOMEM);
566
567                         /* Print out the device identity. */
568                         snprintf(descbuf, BCE_DEVDESC_MAX, "%s (%c%d)",
569                             t->bce_name, (((pci_read_config(dev, 
570                             PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
571                             (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
572
573                         device_set_desc_copy(dev, descbuf);
574                         free(descbuf, M_TEMP);
575                         return(BUS_PROBE_DEFAULT);
576                 }
577                 t++;
578         }
579
580         return(ENXIO);
581 }
582
583
584 /****************************************************************************/
585 /* PCI Capabilities Probe Function.                                         */
586 /*                                                                          */
587 /* Walks the PCI capabiites list for the device to find what features are   */
588 /* supported.                                                               */
589 /*                                                                          */
590 /* Returns:                                                                 */
591 /*   None.                                                                  */
592 /****************************************************************************/
593 static void
594 bce_print_adapter_info(struct bce_softc *sc)
595 {
596     int i = 0;
597
598         DBENTER(BCE_VERBOSE_LOAD);
599
600         BCE_PRINTF("ASIC (0x%08X); ", sc->bce_chipid);
601         printf("Rev (%c%d); ", ((BCE_CHIP_ID(sc) & 0xf000) >> 12) + 'A',
602             ((BCE_CHIP_ID(sc) & 0x0ff0) >> 4));
603
604         /* Bus info. */
605         if (sc->bce_flags & BCE_PCIE_FLAG) {
606                 printf("Bus (PCIe x%d, ", sc->link_width);
607                 switch (sc->link_speed) {
608                 case 1: printf("2.5Gbps); "); break;
609                 case 2: printf("5Gbps); "); break;
610                 default: printf("Unknown link speed); ");
611                 }
612         } else {
613                 printf("Bus (PCI%s, %s, %dMHz); ",
614                     ((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""),
615                     ((sc->bce_flags & BCE_PCI_32BIT_FLAG) ? 
616                     "32-bit" : "64-bit"), sc->bus_speed_mhz);
617         }
618
619         /* Firmware version and device features. */
620         printf("B/C (%s); Flags (", sc->bce_bc_ver);
621
622 #ifdef BCE_JUMBO_HDRSPLIT
623         printf("SPLT");
624         i++;
625 #endif
626
627         if (sc->bce_flags & BCE_USING_MSI_FLAG) {
628                 if (i > 0) printf("|");
629                 printf("MSI"); i++;
630         }
631
632         if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
633                 if (i > 0) printf("|");
634                 printf("MSI-X"); i++;
635         }
636
637         if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
638                 if (i > 0) printf("|");
639                 printf("2.5G"); i++;
640         }
641
642         if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
643                 if (i > 0) printf("|");
644                 printf("MFW); MFW (%s)\n", sc->bce_mfw_ver);
645         } else {
646                 printf(")\n");
647         }
648
649         DBEXIT(BCE_VERBOSE_LOAD);
650 }
651
652
653 /****************************************************************************/
654 /* PCI Capabilities Probe Function.                                         */
655 /*                                                                          */
656 /* Walks the PCI capabiites list for the device to find what features are   */
657 /* supported.                                                               */
658 /*                                                                          */
659 /* Returns:                                                                 */
660 /*   None.                                                                  */
661 /****************************************************************************/
662 static void
663 bce_probe_pci_caps(device_t dev, struct bce_softc *sc)
664 {
665         u32 reg;
666
667         DBENTER(BCE_VERBOSE_LOAD);
668
669         /* Check if PCI-X capability is enabled. */
670         if (pci_find_extcap(dev, PCIY_PCIX, &reg) == 0) {
671                 if (reg != 0)
672                         sc->bce_cap_flags |= BCE_PCIX_CAPABLE_FLAG;
673         }
674
675         /* Check if PCIe capability is enabled. */
676         if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
677                 if (reg != 0) {
678                         u16 link_status = pci_read_config(dev, reg + 0x12, 2);
679                         DBPRINT(sc, BCE_INFO_LOAD, "PCIe link_status = "
680                             "0x%08X\n", link_status);
681                         sc->link_speed = link_status & 0xf;
682                         sc->link_width = (link_status >> 4) & 0x3f;
683                         sc->bce_cap_flags |= BCE_PCIE_CAPABLE_FLAG;
684                         sc->bce_flags |= BCE_PCIE_FLAG;
685                 }
686         }
687
688         /* Check if MSI capability is enabled. */
689         if (pci_find_extcap(dev, PCIY_MSI, &reg) == 0) {
690                 if (reg != 0)
691                         sc->bce_cap_flags |= BCE_MSI_CAPABLE_FLAG;
692         }
693
694         /* Check if MSI-X capability is enabled. */
695         if (pci_find_extcap(dev, PCIY_MSIX, &reg) == 0) {
696                 if (reg != 0)
697                         sc->bce_cap_flags |= BCE_MSIX_CAPABLE_FLAG;
698         }
699
700         DBEXIT(BCE_VERBOSE_LOAD);
701 }
702
703
704 /****************************************************************************/
705 /* Device attach function.                                                  */
706 /*                                                                          */
707 /* Allocates device resources, performs secondary chip identification,      */
708 /* resets and initializes the hardware, and initializes driver instance     */
709 /* variables.                                                               */
710 /*                                                                          */
711 /* Returns:                                                                 */
712 /*   0 on success, positive value on failure.                               */
713 /****************************************************************************/
714 static int
715 bce_attach(device_t dev)
716 {
717         struct bce_softc *sc;
718         struct ifnet *ifp;
719         u32 val;
720         int error, rid, rc = 0;
721
722         sc = device_get_softc(dev);
723         sc->bce_dev = dev;
724
725         DBENTER(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
726
727         sc->bce_unit = device_get_unit(dev);
728
729         /* Set initial device and PHY flags */
730         sc->bce_flags = 0;
731         sc->bce_phy_flags = 0;
732
733         pci_enable_busmaster(dev);
734
735         /* Allocate PCI memory resources. */
736         rid = PCIR_BAR(0);
737         sc->bce_res_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
738                 &rid, RF_ACTIVE);
739
740         if (sc->bce_res_mem == NULL) {
741                 BCE_PRINTF("%s(%d): PCI memory allocation failed\n",
742                     __FILE__, __LINE__);
743                 rc = ENXIO;
744                 goto bce_attach_fail;
745         }
746
747         /* Get various resource handles. */
748         sc->bce_btag    = rman_get_bustag(sc->bce_res_mem);
749         sc->bce_bhandle = rman_get_bushandle(sc->bce_res_mem);
750         sc->bce_vhandle = (vm_offset_t) rman_get_virtual(sc->bce_res_mem);
751
752         bce_probe_pci_caps(dev, sc);
753
754         rid = 1;
755 #if 0
756         /* Try allocating MSI-X interrupts. */
757         if ((sc->bce_cap_flags & BCE_MSIX_CAPABLE_FLAG) &&
758                 (bce_msi_enable >= 2) &&
759                 ((sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
760                 &rid, RF_ACTIVE)) != NULL)) {
761
762                 msi_needed = sc->bce_msi_count = 1;
763
764                 if (((error = pci_alloc_msix(dev, &sc->bce_msi_count)) != 0) ||
765                         (sc->bce_msi_count != msi_needed)) {
766                         BCE_PRINTF("%s(%d): MSI-X allocation failed! Requested = %d,"
767                                 "Received = %d, error = %d\n", __FILE__, __LINE__,
768                                 msi_needed, sc->bce_msi_count, error);
769                         sc->bce_msi_count = 0;
770                         pci_release_msi(dev);
771                         bus_release_resource(dev, SYS_RES_MEMORY, rid,
772                                 sc->bce_res_irq);
773                         sc->bce_res_irq = NULL;
774                 } else {
775                         DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI-X interrupt.\n",
776                                 __FUNCTION__);
777                         sc->bce_flags |= BCE_USING_MSIX_FLAG;
778                         sc->bce_intr = bce_intr;
779                 }
780         }
781 #endif
782
783         /* Try allocating a MSI interrupt. */
784         if ((sc->bce_cap_flags & BCE_MSI_CAPABLE_FLAG) &&
785                 (bce_msi_enable >= 1) && (sc->bce_msi_count == 0)) {
786                 sc->bce_msi_count = 1;
787                 if ((error = pci_alloc_msi(dev, &sc->bce_msi_count)) != 0) {
788                         BCE_PRINTF("%s(%d): MSI allocation failed! error = %d\n",
789                                 __FILE__, __LINE__, error);
790                         sc->bce_msi_count = 0;
791                         pci_release_msi(dev);
792                 } else {
793                         DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI interrupt.\n",
794                                 __FUNCTION__);
795                         sc->bce_flags |= BCE_USING_MSI_FLAG;
796                         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
797                                 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
798                                 sc->bce_flags |= BCE_ONE_SHOT_MSI_FLAG;
799                         sc->bce_irq_rid = 1;
800                         sc->bce_intr = bce_intr;
801                 }
802         }
803
804         /* Try allocating a legacy interrupt. */
805         if (sc->bce_msi_count == 0) {
806                 DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using INTx interrupt.\n",
807                         __FUNCTION__);
808                 rid = 0;
809                 sc->bce_intr = bce_intr;
810         }
811
812         sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
813             &rid, RF_SHAREABLE | RF_ACTIVE);
814
815         sc->bce_irq_rid = rid;
816
817         /* Report any IRQ allocation errors. */
818         if (sc->bce_res_irq == NULL) {
819                 BCE_PRINTF("%s(%d): PCI map interrupt failed!\n",
820                     __FILE__, __LINE__);
821                 rc = ENXIO;
822                 goto bce_attach_fail;
823         }
824
825         /* Initialize mutex for the current device instance. */
826         BCE_LOCK_INIT(sc, device_get_nameunit(dev));
827
828         /*
829          * Configure byte swap and enable indirect register access.
830          * Rely on CPU to do target byte swapping on big endian systems.
831          * Access to registers outside of PCI configurtion space are not
832          * valid until this is done.
833          */
834         pci_write_config(dev, BCE_PCICFG_MISC_CONFIG,
835             BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
836             BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4);
837
838         /* Save ASIC revsion info. */
839         sc->bce_chipid =  REG_RD(sc, BCE_MISC_ID);
840
841         /* Weed out any non-production controller revisions. */
842         switch(BCE_CHIP_ID(sc)) {
843         case BCE_CHIP_ID_5706_A0:
844         case BCE_CHIP_ID_5706_A1:
845         case BCE_CHIP_ID_5708_A0:
846         case BCE_CHIP_ID_5708_B0:
847         case BCE_CHIP_ID_5709_A0:
848         case BCE_CHIP_ID_5709_B0:
849         case BCE_CHIP_ID_5709_B1:
850         case BCE_CHIP_ID_5709_B2:
851                 BCE_PRINTF("%s(%d): Unsupported controller revision (%c%d)!\n",
852                     __FILE__, __LINE__,
853                     (((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
854                     (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
855                 rc = ENODEV;
856                 goto bce_attach_fail;
857         }
858
859         /*
860          * The embedded PCIe to PCI-X bridge (EPB)
861          * in the 5708 cannot address memory above
862          * 40 bits (E7_5708CB1_23043 & E6_5708SB1_23043).
863          */
864         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708)
865                 sc->max_bus_addr = BCE_BUS_SPACE_MAXADDR;
866         else
867                 sc->max_bus_addr = BUS_SPACE_MAXADDR;
868
869         /*
870          * Find the base address for shared memory access.
871          * Newer versions of bootcode use a signature and offset
872          * while older versions use a fixed address.
873          */
874         val = REG_RD_IND(sc, BCE_SHM_HDR_SIGNATURE);
875         if ((val & BCE_SHM_HDR_SIGNATURE_SIG_MASK) == BCE_SHM_HDR_SIGNATURE_SIG)
876                 /* Multi-port devices use different offsets in shared memory. */
877                 sc->bce_shmem_base = REG_RD_IND(sc, BCE_SHM_HDR_ADDR_0 +
878                     (pci_get_function(sc->bce_dev) << 2));
879         else
880                 sc->bce_shmem_base = HOST_VIEW_SHMEM_BASE;
881
882         DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): bce_shmem_base = 0x%08X\n",
883             __FUNCTION__, sc->bce_shmem_base);
884
885         /* Fetch the bootcode revision. */
886         val = bce_shmem_rd(sc, BCE_DEV_INFO_BC_REV);
887         for (int i = 0, j = 0; i < 3; i++) {
888                 u8 num;
889
890                 num = (u8) (val >> (24 - (i * 8)));
891                 for (int k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
892                         if (num >= k || !skip0 || k == 1) {
893                                 sc->bce_bc_ver[j++] = (num / k) + '0';
894                                 skip0 = 0;
895                         }
896                 }
897
898                 if (i != 2)
899                         sc->bce_bc_ver[j++] = '.';
900         }
901
902         /* Check if any management firwmare is enabled. */
903         val = bce_shmem_rd(sc, BCE_PORT_FEATURE);
904         if (val & BCE_PORT_FEATURE_ASF_ENABLED) {
905                 sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
906
907                 /* Allow time for firmware to enter the running state. */
908                 for (int i = 0; i < 30; i++) {
909                         val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
910                         if (val & BCE_CONDITION_MFW_RUN_MASK)
911                                 break;
912                         DELAY(10000);
913                 }
914
915                 /* Check if management firmware is running. */
916                 val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
917                 val &= BCE_CONDITION_MFW_RUN_MASK;
918                 if ((val != BCE_CONDITION_MFW_RUN_UNKNOWN) &&
919                     (val != BCE_CONDITION_MFW_RUN_NONE)) {
920                         u32 addr = bce_shmem_rd(sc, BCE_MFW_VER_PTR);
921                         int i = 0;
922
923                         /* Read the management firmware version string. */
924                         for (int j = 0; j < 3; j++) {
925                                 val = bce_reg_rd_ind(sc, addr + j * 4);
926                                 val = bswap32(val);
927                                 memcpy(&sc->bce_mfw_ver[i], &val, 4);
928                                 i += 4;
929                         }
930                 } else {
931                         /* May cause firmware synchronization timeouts. */
932                         BCE_PRINTF("%s(%d): Management firmware enabled "
933                             "but not running!\n", __FILE__, __LINE__);
934                         strcpy(sc->bce_mfw_ver, "NOT RUNNING!");
935
936                         /* ToDo: Any action the driver should take? */
937                 }
938         }
939
940         /* Get PCI bus information (speed and type). */
941         val = REG_RD(sc, BCE_PCICFG_MISC_STATUS);
942         if (val & BCE_PCICFG_MISC_STATUS_PCIX_DET) {
943                 u32 clkreg;
944
945                 sc->bce_flags |= BCE_PCIX_FLAG;
946
947                 clkreg = REG_RD(sc, BCE_PCICFG_PCI_CLOCK_CONTROL_BITS);
948
949                 clkreg &= BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
950                 switch (clkreg) {
951                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
952                         sc->bus_speed_mhz = 133;
953                         break;
954
955                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
956                         sc->bus_speed_mhz = 100;
957                         break;
958
959                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
960                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
961                         sc->bus_speed_mhz = 66;
962                         break;
963
964                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
965                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
966                         sc->bus_speed_mhz = 50;
967                         break;
968
969                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
970                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
971                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
972                         sc->bus_speed_mhz = 33;
973                         break;
974                 }
975         } else {
976                 if (val & BCE_PCICFG_MISC_STATUS_M66EN)
977                         sc->bus_speed_mhz = 66;
978                 else
979                         sc->bus_speed_mhz = 33;
980         }
981
982         if (val & BCE_PCICFG_MISC_STATUS_32BIT_DET)
983                 sc->bce_flags |= BCE_PCI_32BIT_FLAG;
984
985         /* Reset controller and announce to bootcode that driver is present. */
986         if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
987                 BCE_PRINTF("%s(%d): Controller reset failed!\n",
988                     __FILE__, __LINE__);
989                 rc = ENXIO;
990                 goto bce_attach_fail;
991         }
992
993         /* Initialize the controller. */
994         if (bce_chipinit(sc)) {
995                 BCE_PRINTF("%s(%d): Controller initialization failed!\n",
996                     __FILE__, __LINE__);
997                 rc = ENXIO;
998                 goto bce_attach_fail;
999         }
1000
1001         /* Perform NVRAM test. */
1002         if (bce_nvram_test(sc)) {
1003                 BCE_PRINTF("%s(%d): NVRAM test failed!\n",
1004                     __FILE__, __LINE__);
1005                 rc = ENXIO;
1006                 goto bce_attach_fail;
1007         }
1008
1009         /* Fetch the permanent Ethernet MAC address. */
1010         bce_get_mac_addr(sc);
1011
1012         /*
1013          * Trip points control how many BDs
1014          * should be ready before generating an
1015          * interrupt while ticks control how long
1016          * a BD can sit in the chain before
1017          * generating an interrupt.  Set the default
1018          * values for the RX and TX chains.
1019          */
1020
1021 #ifdef BCE_DEBUG
1022         /* Force more frequent interrupts. */
1023         sc->bce_tx_quick_cons_trip_int = 1;
1024         sc->bce_tx_quick_cons_trip     = 1;
1025         sc->bce_tx_ticks_int           = 0;
1026         sc->bce_tx_ticks               = 0;
1027
1028         sc->bce_rx_quick_cons_trip_int = 1;
1029         sc->bce_rx_quick_cons_trip     = 1;
1030         sc->bce_rx_ticks_int           = 0;
1031         sc->bce_rx_ticks               = 0;
1032 #else
1033         /* Improve throughput at the expense of increased latency. */
1034         sc->bce_tx_quick_cons_trip_int = 20;
1035         sc->bce_tx_quick_cons_trip     = 20;
1036         sc->bce_tx_ticks_int           = 80;
1037         sc->bce_tx_ticks               = 80;
1038
1039         sc->bce_rx_quick_cons_trip_int = 6;
1040         sc->bce_rx_quick_cons_trip     = 6;
1041         sc->bce_rx_ticks_int           = 18;
1042         sc->bce_rx_ticks               = 18;
1043 #endif
1044
1045         /* Not used for L2. */
1046         sc->bce_comp_prod_trip_int = 0;
1047         sc->bce_comp_prod_trip = 0;
1048         sc->bce_com_ticks_int = 0;
1049         sc->bce_com_ticks = 0;
1050         sc->bce_cmd_ticks_int = 0;
1051         sc->bce_cmd_ticks = 0;
1052
1053         /* Update statistics once every second. */
1054         sc->bce_stats_ticks = 1000000 & 0xffff00;
1055
1056         /* Find the media type for the adapter. */
1057         bce_get_media(sc);
1058
1059         /* Store data needed by PHY driver for backplane applications */
1060         sc->bce_shared_hw_cfg = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
1061         sc->bce_port_hw_cfg   = bce_shmem_rd(sc, BCE_PORT_HW_CFG_CONFIG);
1062
1063         /* Allocate DMA memory resources. */
1064         if (bce_dma_alloc(dev)) {
1065                 BCE_PRINTF("%s(%d): DMA resource allocation failed!\n",
1066                     __FILE__, __LINE__);
1067                 rc = ENXIO;
1068                 goto bce_attach_fail;
1069         }
1070
1071         /* Allocate an ifnet structure. */
1072         ifp = sc->bce_ifp = if_alloc(IFT_ETHER);
1073         if (ifp == NULL) {
1074                 BCE_PRINTF("%s(%d): Interface allocation failed!\n",
1075                         __FILE__, __LINE__);
1076                 rc = ENXIO;
1077                 goto bce_attach_fail;
1078         }
1079
1080         /* Initialize the ifnet interface. */
1081         ifp->if_softc        = sc;
1082         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
1083         ifp->if_flags        = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1084         ifp->if_ioctl        = bce_ioctl;
1085         ifp->if_start        = bce_start;
1086         ifp->if_init         = bce_init;
1087         ifp->if_mtu          = ETHERMTU;
1088
1089         if (bce_tso_enable) {
1090                 ifp->if_hwassist = BCE_IF_HWASSIST | CSUM_TSO;
1091                 ifp->if_capabilities = BCE_IF_CAPABILITIES | IFCAP_TSO4 |
1092                     IFCAP_VLAN_HWTSO;
1093         } else {
1094                 ifp->if_hwassist = BCE_IF_HWASSIST;
1095                 ifp->if_capabilities = BCE_IF_CAPABILITIES;
1096         }
1097
1098         ifp->if_capenable    = ifp->if_capabilities;
1099
1100         /*
1101          * Assume standard mbuf sizes for buffer allocation.
1102          * This may change later if the MTU size is set to
1103          * something other than 1500.
1104          */
1105 #ifdef BCE_JUMBO_HDRSPLIT
1106         sc->rx_bd_mbuf_alloc_size = MHLEN;
1107         /* Make sure offset is 16 byte aligned for hardware. */
1108         sc->rx_bd_mbuf_align_pad  = roundup2((MSIZE - MHLEN), 16) -
1109                 (MSIZE - MHLEN);
1110         sc->rx_bd_mbuf_data_len   = sc->rx_bd_mbuf_alloc_size -
1111                 sc->rx_bd_mbuf_align_pad;
1112         sc->pg_bd_mbuf_alloc_size = MCLBYTES;
1113 #else
1114         sc->rx_bd_mbuf_alloc_size = MCLBYTES;
1115         sc->rx_bd_mbuf_align_pad  = roundup2(MCLBYTES, 16) - MCLBYTES;
1116         sc->rx_bd_mbuf_data_len   = sc->rx_bd_mbuf_alloc_size -
1117                 sc->rx_bd_mbuf_align_pad;
1118 #endif
1119
1120         ifp->if_snd.ifq_drv_maxlen = USABLE_TX_BD;
1121         IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
1122         IFQ_SET_READY(&ifp->if_snd);
1123
1124         if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
1125                 ifp->if_baudrate = IF_Mbps(2500ULL);
1126         else
1127                 ifp->if_baudrate = IF_Mbps(1000);
1128
1129     /* Handle any special PHY initialization for SerDes PHYs. */
1130     bce_init_media(sc);
1131
1132         /* MII child bus by probing the PHY. */
1133         if (mii_phy_probe(dev, &sc->bce_miibus, bce_ifmedia_upd,
1134                 bce_ifmedia_sts)) {
1135                 BCE_PRINTF("%s(%d): No PHY found on child MII bus!\n",
1136                         __FILE__, __LINE__);
1137                 rc = ENXIO;
1138                 goto bce_attach_fail;
1139         }
1140
1141         /* Attach to the Ethernet interface list. */
1142         ether_ifattach(ifp, sc->eaddr);
1143
1144 #if __FreeBSD_version < 500000
1145         callout_init(&sc->bce_tick_callout);
1146         callout_init(&sc->bce_pulse_callout);
1147 #else
1148         callout_init_mtx(&sc->bce_tick_callout, &sc->bce_mtx, 0);
1149         callout_init_mtx(&sc->bce_pulse_callout, &sc->bce_mtx, 0);
1150 #endif
1151
1152         /* Hookup IRQ last. */
1153         rc = bus_setup_intr(dev, sc->bce_res_irq, INTR_TYPE_NET | INTR_MPSAFE,
1154                 NULL, bce_intr, sc, &sc->bce_intrhand);
1155
1156         if (rc) {
1157                 BCE_PRINTF("%s(%d): Failed to setup IRQ!\n",
1158                         __FILE__, __LINE__);
1159                 bce_detach(dev);
1160                 goto bce_attach_exit;
1161         }
1162
1163         /*
1164          * At this point we've acquired all the resources
1165          * we need to run so there's no turning back, we're
1166          * cleared for launch.
1167          */
1168
1169         /* Print some important debugging info. */
1170         DBRUNMSG(BCE_INFO, bce_dump_driver_state(sc));
1171
1172         /* Add the supported sysctls to the kernel. */
1173         bce_add_sysctls(sc);
1174
1175         BCE_LOCK(sc);
1176
1177         /*
1178          * The chip reset earlier notified the bootcode that
1179          * a driver is present.  We now need to start our pulse
1180          * routine so that the bootcode is reminded that we're
1181          * still running.
1182          */
1183         bce_pulse(sc);
1184
1185         bce_mgmt_init_locked(sc);
1186         BCE_UNLOCK(sc);
1187
1188         /* Finally, print some useful adapter info */
1189         bce_print_adapter_info(sc);
1190         DBPRINT(sc, BCE_FATAL, "%s(): sc = %p\n",
1191                 __FUNCTION__, sc);
1192
1193         goto bce_attach_exit;
1194
1195 bce_attach_fail:
1196         bce_release_resources(sc);
1197
1198 bce_attach_exit:
1199
1200         DBEXIT(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
1201
1202         return(rc);
1203 }
1204
1205
1206 /****************************************************************************/
1207 /* Device detach function.                                                  */
1208 /*                                                                          */
1209 /* Stops the controller, resets the controller, and releases resources.     */
1210 /*                                                                          */
1211 /* Returns:                                                                 */
1212 /*   0 on success, positive value on failure.                               */
1213 /****************************************************************************/
1214 static int
1215 bce_detach(device_t dev)
1216 {
1217         struct bce_softc *sc = device_get_softc(dev);
1218         struct ifnet *ifp;
1219         u32 msg;
1220
1221         DBENTER(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
1222
1223         ifp = sc->bce_ifp;
1224
1225         /* Stop and reset the controller. */
1226         BCE_LOCK(sc);
1227
1228         /* Stop the pulse so the bootcode can go to driver absent state. */
1229         callout_stop(&sc->bce_pulse_callout);
1230
1231         bce_stop(sc);
1232         if (sc->bce_flags & BCE_NO_WOL_FLAG)
1233                 msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
1234         else
1235                 msg = BCE_DRV_MSG_CODE_UNLOAD;
1236         bce_reset(sc, msg);
1237
1238         BCE_UNLOCK(sc);
1239
1240         ether_ifdetach(ifp);
1241
1242         /* If we have a child device on the MII bus remove it too. */
1243         bus_generic_detach(dev);
1244         device_delete_child(dev, sc->bce_miibus);
1245
1246         /* Release all remaining resources. */
1247         bce_release_resources(sc);
1248
1249         DBEXIT(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
1250
1251         return(0);
1252 }
1253
1254
1255 /****************************************************************************/
1256 /* Device shutdown function.                                                */
1257 /*                                                                          */
1258 /* Stops and resets the controller.                                         */
1259 /*                                                                          */
1260 /* Returns:                                                                 */
1261 /*   0 on success, positive value on failure.                               */
1262 /****************************************************************************/
1263 static int
1264 bce_shutdown(device_t dev)
1265 {
1266         struct bce_softc *sc = device_get_softc(dev);
1267         u32 msg;
1268
1269         DBENTER(BCE_VERBOSE);
1270
1271         BCE_LOCK(sc);
1272         bce_stop(sc);
1273         if (sc->bce_flags & BCE_NO_WOL_FLAG)
1274                 msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
1275         else
1276                 msg = BCE_DRV_MSG_CODE_UNLOAD;
1277         bce_reset(sc, msg);
1278         BCE_UNLOCK(sc);
1279
1280         DBEXIT(BCE_VERBOSE);
1281
1282         return (0);
1283 }
1284
1285
1286 #ifdef BCE_DEBUG
1287 /****************************************************************************/
1288 /* Register read.                                                           */
1289 /*                                                                          */
1290 /* Returns:                                                                 */
1291 /*   The value of the register.                                             */
1292 /****************************************************************************/
1293 static u32
1294 bce_reg_rd(struct bce_softc *sc, u32 offset)
1295 {
1296         u32 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, offset);
1297         DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1298                 __FUNCTION__, offset, val);
1299         return val;
1300 }
1301
1302
1303 /****************************************************************************/
1304 /* Register write (16 bit).                                                 */
1305 /*                                                                          */
1306 /* Returns:                                                                 */
1307 /*   Nothing.                                                               */
1308 /****************************************************************************/
1309 static void
1310 bce_reg_wr16(struct bce_softc *sc, u32 offset, u16 val)
1311 {
1312         DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%04X\n",
1313                 __FUNCTION__, offset, val);
1314         bus_space_write_2(sc->bce_btag, sc->bce_bhandle, offset, val);
1315 }
1316
1317
1318 /****************************************************************************/
1319 /* Register write.                                                          */
1320 /*                                                                          */
1321 /* Returns:                                                                 */
1322 /*   Nothing.                                                               */
1323 /****************************************************************************/
1324 static void
1325 bce_reg_wr(struct bce_softc *sc, u32 offset, u32 val)
1326 {
1327         DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1328                 __FUNCTION__, offset, val);
1329         bus_space_write_4(sc->bce_btag, sc->bce_bhandle, offset, val);
1330 }
1331 #endif
1332
1333 /****************************************************************************/
1334 /* Indirect register read.                                                  */
1335 /*                                                                          */
1336 /* Reads NetXtreme II registers using an index/data register pair in PCI    */
1337 /* configuration space.  Using this mechanism avoids issues with posted     */
1338 /* reads but is much slower than memory-mapped I/O.                         */
1339 /*                                                                          */
1340 /* Returns:                                                                 */
1341 /*   The value of the register.                                             */
1342 /****************************************************************************/
1343 static u32
1344 bce_reg_rd_ind(struct bce_softc *sc, u32 offset)
1345 {
1346         device_t dev;
1347         dev = sc->bce_dev;
1348
1349         pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
1350 #ifdef BCE_DEBUG
1351         {
1352                 u32 val;
1353                 val = pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
1354                 DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1355                         __FUNCTION__, offset, val);
1356                 return val;
1357         }
1358 #else
1359         return pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
1360 #endif
1361 }
1362
1363
1364 /****************************************************************************/
1365 /* Indirect register write.                                                 */
1366 /*                                                                          */
1367 /* Writes NetXtreme II registers using an index/data register pair in PCI   */
1368 /* configuration space.  Using this mechanism avoids issues with posted     */
1369 /* writes but is muchh slower than memory-mapped I/O.                       */
1370 /*                                                                          */
1371 /* Returns:                                                                 */
1372 /*   Nothing.                                                               */
1373 /****************************************************************************/
1374 static void
1375 bce_reg_wr_ind(struct bce_softc *sc, u32 offset, u32 val)
1376 {
1377         device_t dev;
1378         dev = sc->bce_dev;
1379
1380         DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1381                 __FUNCTION__, offset, val);
1382
1383         pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
1384         pci_write_config(dev, BCE_PCICFG_REG_WINDOW, val, 4);
1385 }
1386
1387
1388 /****************************************************************************/
1389 /* Shared memory write.                                                     */
1390 /*                                                                          */
1391 /* Writes NetXtreme II shared memory region.                                */
1392 /*                                                                          */
1393 /* Returns:                                                                 */
1394 /*   Nothing.                                                               */
1395 /****************************************************************************/
1396 static void
1397 bce_shmem_wr(struct bce_softc *sc, u32 offset, u32 val)
1398 {
1399         bce_reg_wr_ind(sc, sc->bce_shmem_base + offset, val);
1400 }
1401
1402
1403 /****************************************************************************/
1404 /* Shared memory read.                                                      */
1405 /*                                                                          */
1406 /* Reads NetXtreme II shared memory region.                                 */
1407 /*                                                                          */
1408 /* Returns:                                                                 */
1409 /*   The 32 bit value read.                                                 */
1410 /****************************************************************************/
1411 static u32
1412 bce_shmem_rd(struct bce_softc *sc, u32 offset)
1413 {
1414         return (bce_reg_rd_ind(sc, sc->bce_shmem_base + offset));
1415 }
1416
1417
1418 #ifdef BCE_DEBUG
1419 /****************************************************************************/
1420 /* Context memory read.                                                     */
1421 /*                                                                          */
1422 /* The NetXtreme II controller uses context memory to track connection      */
1423 /* information for L2 and higher network protocols.                         */
1424 /*                                                                          */
1425 /* Returns:                                                                 */
1426 /*   The requested 32 bit value of context memory.                          */
1427 /****************************************************************************/
1428 static u32
1429 bce_ctx_rd(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset)
1430 {
1431         u32 idx, offset, retry_cnt = 5, val;
1432
1433         DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 || cid_addr & CTX_MASK),
1434                 BCE_PRINTF("%s(): Invalid CID address: 0x%08X.\n",
1435                         __FUNCTION__, cid_addr));
1436
1437         offset = ctx_offset + cid_addr;
1438
1439         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
1440                 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
1441
1442                 REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_READ_REQ));
1443
1444                 for (idx = 0; idx < retry_cnt; idx++) {
1445                         val = REG_RD(sc, BCE_CTX_CTX_CTRL);
1446                         if ((val & BCE_CTX_CTX_CTRL_READ_REQ) == 0)
1447                                 break;
1448                         DELAY(5);
1449                 }
1450
1451                 if (val & BCE_CTX_CTX_CTRL_READ_REQ)
1452                         BCE_PRINTF("%s(%d); Unable to read CTX memory: "
1453                                 "cid_addr = 0x%08X, offset = 0x%08X!\n",
1454                                 __FILE__, __LINE__, cid_addr, ctx_offset);
1455
1456                 val = REG_RD(sc, BCE_CTX_CTX_DATA);
1457         } else {
1458                 REG_WR(sc, BCE_CTX_DATA_ADR, offset);
1459                 val = REG_RD(sc, BCE_CTX_DATA);
1460         }
1461
1462         DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
1463                 "val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, val);
1464
1465         return(val);
1466 }
1467 #endif
1468
1469
1470 /****************************************************************************/
1471 /* Context memory write.                                                    */
1472 /*                                                                          */
1473 /* The NetXtreme II controller uses context memory to track connection      */
1474 /* information for L2 and higher network protocols.                         */
1475 /*                                                                          */
1476 /* Returns:                                                                 */
1477 /*   Nothing.                                                               */
1478 /****************************************************************************/
1479 static void
1480 bce_ctx_wr(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset, u32 ctx_val)
1481 {
1482         u32 idx, offset = ctx_offset + cid_addr;
1483         u32 val, retry_cnt = 5;
1484
1485         DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
1486                 "val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, ctx_val);
1487
1488         DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 || cid_addr & CTX_MASK),
1489                 BCE_PRINTF("%s(): Invalid CID address: 0x%08X.\n",
1490                         __FUNCTION__, cid_addr));
1491
1492         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
1493                 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
1494
1495                 REG_WR(sc, BCE_CTX_CTX_DATA, ctx_val);
1496                 REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_WRITE_REQ));
1497
1498                 for (idx = 0; idx < retry_cnt; idx++) {
1499                         val = REG_RD(sc, BCE_CTX_CTX_CTRL);
1500                         if ((val & BCE_CTX_CTX_CTRL_WRITE_REQ) == 0)
1501                                 break;
1502                         DELAY(5);
1503                 }
1504
1505                 if (val & BCE_CTX_CTX_CTRL_WRITE_REQ)
1506                         BCE_PRINTF("%s(%d); Unable to write CTX memory: "
1507                                 "cid_addr = 0x%08X, offset = 0x%08X!\n",
1508                                 __FILE__, __LINE__, cid_addr, ctx_offset);
1509
1510         } else {
1511                 REG_WR(sc, BCE_CTX_DATA_ADR, offset);
1512                 REG_WR(sc, BCE_CTX_DATA, ctx_val);
1513         }
1514 }
1515
1516
1517 /****************************************************************************/
1518 /* PHY register read.                                                       */
1519 /*                                                                          */
1520 /* Implements register reads on the MII bus.                                */
1521 /*                                                                          */
1522 /* Returns:                                                                 */
1523 /*   The value of the register.                                             */
1524 /****************************************************************************/
1525 static int
1526 bce_miibus_read_reg(device_t dev, int phy, int reg)
1527 {
1528         struct bce_softc *sc;
1529         u32 val;
1530         int i;
1531
1532         sc = device_get_softc(dev);
1533
1534         /* Make sure we are accessing the correct PHY address. */
1535         if (phy != sc->bce_phy_addr) {
1536                 DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d "
1537                     "for PHY read!\n", phy);
1538                 return(0);
1539         }
1540
1541     /*
1542      * The 5709S PHY is an IEEE Clause 45 PHY
1543      * with special mappings to work with IEEE
1544      * Clause 22 register accesses.
1545      */
1546         if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
1547                 if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
1548                         reg += 0x10;
1549         }
1550
1551     if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1552                 val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1553                 val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1554
1555                 REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1556                 REG_RD(sc, BCE_EMAC_MDIO_MODE);
1557
1558                 DELAY(40);
1559         }
1560
1561
1562         val = BCE_MIPHY(phy) | BCE_MIREG(reg) |
1563             BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT |
1564             BCE_EMAC_MDIO_COMM_START_BUSY;
1565         REG_WR(sc, BCE_EMAC_MDIO_COMM, val);
1566
1567         for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1568                 DELAY(10);
1569
1570                 val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1571                 if (!(val & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1572                         DELAY(5);
1573
1574                         val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1575                         val &= BCE_EMAC_MDIO_COMM_DATA;
1576
1577                         break;
1578                 }
1579         }
1580
1581         if (val & BCE_EMAC_MDIO_COMM_START_BUSY) {
1582                 BCE_PRINTF("%s(%d): Error: PHY read timeout! phy = %d, "
1583                     "reg = 0x%04X\n", __FILE__, __LINE__, phy, reg);
1584                 val = 0x0;
1585         } else {
1586                 val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1587         }
1588
1589
1590         if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1591                 val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1592                 val |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1593
1594                 REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1595                 REG_RD(sc, BCE_EMAC_MDIO_MODE);
1596
1597                 DELAY(40);
1598         }
1599
1600         DB_PRINT_PHY_REG(reg, val);
1601         return (val & 0xffff);
1602
1603 }
1604
1605
1606 /****************************************************************************/
1607 /* PHY register write.                                                      */
1608 /*                                                                          */
1609 /* Implements register writes on the MII bus.                               */
1610 /*                                                                          */
1611 /* Returns:                                                                 */
1612 /*   The value of the register.                                             */
1613 /****************************************************************************/
1614 static int
1615 bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
1616 {
1617         struct bce_softc *sc;
1618         u32 val1;
1619         int i;
1620
1621         sc = device_get_softc(dev);
1622
1623         /* Make sure we are accessing the correct PHY address. */
1624         if (phy != sc->bce_phy_addr) {
1625                 DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d "
1626                     "for PHY write!\n", phy);
1627                 return(0);
1628         }
1629
1630         DB_PRINT_PHY_REG(reg, val);
1631
1632         /*
1633          * The 5709S PHY is an IEEE Clause 45 PHY
1634          * with special mappings to work with IEEE
1635          * Clause 22 register accesses.
1636          */
1637         if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
1638                 if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
1639                         reg += 0x10;
1640         }
1641
1642         if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1643                 val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1644                 val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1645
1646                 REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1647                 REG_RD(sc, BCE_EMAC_MDIO_MODE);
1648
1649                 DELAY(40);
1650         }
1651
1652         val1 = BCE_MIPHY(phy) | BCE_MIREG(reg) | val |
1653             BCE_EMAC_MDIO_COMM_COMMAND_WRITE |
1654             BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT;
1655         REG_WR(sc, BCE_EMAC_MDIO_COMM, val1);
1656
1657         for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1658                 DELAY(10);
1659
1660                 val1 = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1661                 if (!(val1 & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1662                         DELAY(5);
1663                         break;
1664                 }
1665         }
1666
1667         if (val1 & BCE_EMAC_MDIO_COMM_START_BUSY)
1668                 BCE_PRINTF("%s(%d): PHY write timeout!\n",
1669                     __FILE__, __LINE__);
1670
1671         if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1672                 val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1673                 val1 |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1674
1675                 REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1676                 REG_RD(sc, BCE_EMAC_MDIO_MODE);
1677
1678                 DELAY(40);
1679         }
1680
1681         return 0;
1682 }
1683
1684
1685 /****************************************************************************/
1686 /* MII bus status change.                                                   */
1687 /*                                                                          */
1688 /* Called by the MII bus driver when the PHY establishes link to set the    */
1689 /* MAC interface registers.                                                 */
1690 /*                                                                          */
1691 /* Returns:                                                                 */
1692 /*   Nothing.                                                               */
1693 /****************************************************************************/
1694 static void
1695 bce_miibus_statchg(device_t dev)
1696 {
1697         struct bce_softc *sc;
1698         struct mii_data *mii;
1699         int val;
1700
1701         sc = device_get_softc(dev);
1702
1703         DBENTER(BCE_VERBOSE_PHY);
1704
1705         mii = device_get_softc(sc->bce_miibus);
1706
1707         val = REG_RD(sc, BCE_EMAC_MODE);
1708         val &= ~(BCE_EMAC_MODE_PORT | BCE_EMAC_MODE_HALF_DUPLEX |
1709                 BCE_EMAC_MODE_MAC_LOOP | BCE_EMAC_MODE_FORCE_LINK |
1710                 BCE_EMAC_MODE_25G);
1711
1712         /* Set MII or GMII interface based on the speed negotiated by the PHY. */
1713         switch (IFM_SUBTYPE(mii->mii_media_active)) {
1714         case IFM_10_T:
1715                 if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
1716                         DBPRINT(sc, BCE_INFO, "Enabling 10Mb interface.\n");
1717                         val |= BCE_EMAC_MODE_PORT_MII_10;
1718                         break;
1719                 }
1720                 /* fall-through */
1721         case IFM_100_TX:
1722                 DBPRINT(sc, BCE_INFO, "Enabling MII interface.\n");
1723                 val |= BCE_EMAC_MODE_PORT_MII;
1724                 break;
1725         case IFM_2500_SX:
1726                 DBPRINT(sc, BCE_INFO, "Enabling 2.5G MAC mode.\n");
1727                 val |= BCE_EMAC_MODE_25G;
1728                 /* fall-through */
1729         case IFM_1000_T:
1730         case IFM_1000_SX:
1731                 DBPRINT(sc, BCE_INFO, "Enabling GMII interface.\n");
1732                 val |= BCE_EMAC_MODE_PORT_GMII;
1733                 break;
1734         default:
1735                 DBPRINT(sc, BCE_INFO, "Unknown speed, enabling default GMII "
1736                         "interface.\n");
1737                 val |= BCE_EMAC_MODE_PORT_GMII;
1738         }
1739
1740         /* Set half or full duplex based on the duplicity negotiated by the PHY. */
1741         if ((mii->mii_media_active & IFM_GMASK) == IFM_HDX) {
1742                 DBPRINT(sc, BCE_INFO, "Setting Half-Duplex interface.\n");
1743                 val |= BCE_EMAC_MODE_HALF_DUPLEX;
1744         } else
1745                 DBPRINT(sc, BCE_INFO, "Setting Full-Duplex interface.\n");
1746
1747         REG_WR(sc, BCE_EMAC_MODE, val);
1748
1749 #if 0
1750         /* ToDo: Enable flow control support in brgphy and bge. */
1751         /* FLAG0 is set if RX is enabled and FLAG1 if TX is enabled */
1752         if (mii->mii_media_active & IFM_FLAG0)
1753                 BCE_SETBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
1754         if (mii->mii_media_active & IFM_FLAG1)
1755                 BCE_SETBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_TX_MODE_FLOW_EN);
1756 #endif
1757
1758         DBEXIT(BCE_VERBOSE_PHY);
1759 }
1760
1761
1762 /****************************************************************************/
1763 /* Acquire NVRAM lock.                                                      */
1764 /*                                                                          */
1765 /* Before the NVRAM can be accessed the caller must acquire an NVRAM lock.  */
1766 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1767 /* for use by the driver.                                                   */
1768 /*                                                                          */
1769 /* Returns:                                                                 */
1770 /*   0 on success, positive value on failure.                               */
1771 /****************************************************************************/
1772 static int
1773 bce_acquire_nvram_lock(struct bce_softc *sc)
1774 {
1775         u32 val;
1776         int j, rc = 0;
1777
1778         DBENTER(BCE_VERBOSE_NVRAM);
1779
1780         /* Request access to the flash interface. */
1781         REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_SET2);
1782         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1783                 val = REG_RD(sc, BCE_NVM_SW_ARB);
1784                 if (val & BCE_NVM_SW_ARB_ARB_ARB2)
1785                         break;
1786
1787                 DELAY(5);
1788         }
1789
1790         if (j >= NVRAM_TIMEOUT_COUNT) {
1791                 DBPRINT(sc, BCE_WARN, "Timeout acquiring NVRAM lock!\n");
1792                 rc = EBUSY;
1793         }
1794
1795         DBEXIT(BCE_VERBOSE_NVRAM);
1796         return (rc);
1797 }
1798
1799
1800 /****************************************************************************/
1801 /* Release NVRAM lock.                                                      */
1802 /*                                                                          */
1803 /* When the caller is finished accessing NVRAM the lock must be released.   */
1804 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1805 /* for use by the driver.                                                   */
1806 /*                                                                          */
1807 /* Returns:                                                                 */
1808 /*   0 on success, positive value on failure.                               */
1809 /****************************************************************************/
1810 static int
1811 bce_release_nvram_lock(struct bce_softc *sc)
1812 {
1813         u32 val;
1814         int j, rc = 0;
1815
1816         DBENTER(BCE_VERBOSE_NVRAM);
1817
1818         /*
1819          * Relinquish nvram interface.
1820          */
1821         REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_CLR2);
1822
1823         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1824                 val = REG_RD(sc, BCE_NVM_SW_ARB);
1825                 if (!(val & BCE_NVM_SW_ARB_ARB_ARB2))
1826                         break;
1827
1828                 DELAY(5);
1829         }
1830
1831         if (j >= NVRAM_TIMEOUT_COUNT) {
1832                 DBPRINT(sc, BCE_WARN, "Timeout releasing NVRAM lock!\n");
1833                 rc = EBUSY;
1834         }
1835
1836         DBEXIT(BCE_VERBOSE_NVRAM);
1837         return (rc);
1838 }
1839
1840
1841 #ifdef BCE_NVRAM_WRITE_SUPPORT
1842 /****************************************************************************/
1843 /* Enable NVRAM write access.                                               */
1844 /*                                                                          */
1845 /* Before writing to NVRAM the caller must enable NVRAM writes.             */
1846 /*                                                                          */
1847 /* Returns:                                                                 */
1848 /*   0 on success, positive value on failure.                               */
1849 /****************************************************************************/
1850 static int
1851 bce_enable_nvram_write(struct bce_softc *sc)
1852 {
1853         u32 val;
1854         int rc = 0;
1855
1856         DBENTER(BCE_VERBOSE_NVRAM);
1857
1858         val = REG_RD(sc, BCE_MISC_CFG);
1859         REG_WR(sc, BCE_MISC_CFG, val | BCE_MISC_CFG_NVM_WR_EN_PCI);
1860
1861         if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
1862                 int j;
1863
1864                 REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1865                 REG_WR(sc, BCE_NVM_COMMAND,     BCE_NVM_COMMAND_WREN | BCE_NVM_COMMAND_DOIT);
1866
1867                 for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1868                         DELAY(5);
1869
1870                         val = REG_RD(sc, BCE_NVM_COMMAND);
1871                         if (val & BCE_NVM_COMMAND_DONE)
1872                                 break;
1873                 }
1874
1875                 if (j >= NVRAM_TIMEOUT_COUNT) {
1876                         DBPRINT(sc, BCE_WARN, "Timeout writing NVRAM!\n");
1877                         rc = EBUSY;
1878                 }
1879         }
1880
1881         DBENTER(BCE_VERBOSE_NVRAM);
1882         return (rc);
1883 }
1884
1885
1886 /****************************************************************************/
1887 /* Disable NVRAM write access.                                              */
1888 /*                                                                          */
1889 /* When the caller is finished writing to NVRAM write access must be        */
1890 /* disabled.                                                                */
1891 /*                                                                          */
1892 /* Returns:                                                                 */
1893 /*   Nothing.                                                               */
1894 /****************************************************************************/
1895 static void
1896 bce_disable_nvram_write(struct bce_softc *sc)
1897 {
1898         u32 val;
1899
1900         DBENTER(BCE_VERBOSE_NVRAM);
1901
1902         val = REG_RD(sc, BCE_MISC_CFG);
1903         REG_WR(sc, BCE_MISC_CFG, val & ~BCE_MISC_CFG_NVM_WR_EN);
1904
1905         DBEXIT(BCE_VERBOSE_NVRAM);
1906
1907 }
1908 #endif
1909
1910
1911 /****************************************************************************/
1912 /* Enable NVRAM access.                                                     */
1913 /*                                                                          */
1914 /* Before accessing NVRAM for read or write operations the caller must      */
1915 /* enabled NVRAM access.                                                    */
1916 /*                                                                          */
1917 /* Returns:                                                                 */
1918 /*   Nothing.                                                               */
1919 /****************************************************************************/
1920 static void
1921 bce_enable_nvram_access(struct bce_softc *sc)
1922 {
1923         u32 val;
1924
1925         DBENTER(BCE_VERBOSE_NVRAM);
1926
1927         val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
1928         /* Enable both bits, even on read. */
1929         REG_WR(sc, BCE_NVM_ACCESS_ENABLE,
1930                val | BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN);
1931
1932         DBEXIT(BCE_VERBOSE_NVRAM);
1933 }
1934
1935
1936 /****************************************************************************/
1937 /* Disable NVRAM access.                                                    */
1938 /*                                                                          */
1939 /* When the caller is finished accessing NVRAM access must be disabled.     */
1940 /*                                                                          */
1941 /* Returns:                                                                 */
1942 /*   Nothing.                                                               */
1943 /****************************************************************************/
1944 static void
1945 bce_disable_nvram_access(struct bce_softc *sc)
1946 {
1947         u32 val;
1948
1949         DBENTER(BCE_VERBOSE_NVRAM);
1950
1951         val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
1952
1953         /* Disable both bits, even after read. */
1954         REG_WR(sc, BCE_NVM_ACCESS_ENABLE,
1955                 val & ~(BCE_NVM_ACCESS_ENABLE_EN |
1956                         BCE_NVM_ACCESS_ENABLE_WR_EN));
1957
1958         DBEXIT(BCE_VERBOSE_NVRAM);
1959 }
1960
1961
1962 #ifdef BCE_NVRAM_WRITE_SUPPORT
1963 /****************************************************************************/
1964 /* Erase NVRAM page before writing.                                         */
1965 /*                                                                          */
1966 /* Non-buffered flash parts require that a page be erased before it is      */
1967 /* written.                                                                 */
1968 /*                                                                          */
1969 /* Returns:                                                                 */
1970 /*   0 on success, positive value on failure.                               */
1971 /****************************************************************************/
1972 static int
1973 bce_nvram_erase_page(struct bce_softc *sc, u32 offset)
1974 {
1975         u32 cmd;
1976         int j, rc = 0;
1977
1978         DBENTER(BCE_VERBOSE_NVRAM);
1979
1980         /* Buffered flash doesn't require an erase. */
1981         if (sc->bce_flash_info->flags & BCE_NV_BUFFERED)
1982                 goto bce_nvram_erase_page_exit;
1983
1984         /* Build an erase command. */
1985         cmd = BCE_NVM_COMMAND_ERASE | BCE_NVM_COMMAND_WR |
1986               BCE_NVM_COMMAND_DOIT;
1987
1988         /*
1989          * Clear the DONE bit separately, set the NVRAM adress to erase,
1990          * and issue the erase command.
1991          */
1992         REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1993         REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1994         REG_WR(sc, BCE_NVM_COMMAND, cmd);
1995
1996         /* Wait for completion. */
1997         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1998                 u32 val;
1999
2000                 DELAY(5);
2001
2002                 val = REG_RD(sc, BCE_NVM_COMMAND);
2003                 if (val & BCE_NVM_COMMAND_DONE)
2004                         break;
2005         }
2006
2007         if (j >= NVRAM_TIMEOUT_COUNT) {
2008                 DBPRINT(sc, BCE_WARN, "Timeout erasing NVRAM.\n");
2009                 rc = EBUSY;
2010         }
2011
2012 bce_nvram_erase_page_exit:
2013         DBEXIT(BCE_VERBOSE_NVRAM);
2014         return (rc);
2015 }
2016 #endif /* BCE_NVRAM_WRITE_SUPPORT */
2017
2018
2019 /****************************************************************************/
2020 /* Read a dword (32 bits) from NVRAM.                                       */
2021 /*                                                                          */
2022 /* Read a 32 bit word from NVRAM.  The caller is assumed to have already    */
2023 /* obtained the NVRAM lock and enabled the controller for NVRAM access.     */
2024 /*                                                                          */
2025 /* Returns:                                                                 */
2026 /*   0 on success and the 32 bit value read, positive value on failure.     */
2027 /****************************************************************************/
2028 static int
2029 bce_nvram_read_dword(struct bce_softc *sc, u32 offset, u8 *ret_val,
2030                                                         u32 cmd_flags)
2031 {
2032         u32 cmd;
2033         int i, rc = 0;
2034
2035         DBENTER(BCE_EXTREME_NVRAM);
2036
2037         /* Build the command word. */
2038         cmd = BCE_NVM_COMMAND_DOIT | cmd_flags;
2039
2040         /* Calculate the offset for buffered flash if translation is used. */
2041         if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
2042                 offset = ((offset / sc->bce_flash_info->page_size) <<
2043                            sc->bce_flash_info->page_bits) +
2044                           (offset % sc->bce_flash_info->page_size);
2045         }
2046
2047         /*
2048          * Clear the DONE bit separately, set the address to read,
2049          * and issue the read.
2050          */
2051         REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2052         REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
2053         REG_WR(sc, BCE_NVM_COMMAND, cmd);
2054
2055         /* Wait for completion. */
2056         for (i = 0; i < NVRAM_TIMEOUT_COUNT; i++) {
2057                 u32 val;
2058
2059                 DELAY(5);
2060
2061                 val = REG_RD(sc, BCE_NVM_COMMAND);
2062                 if (val & BCE_NVM_COMMAND_DONE) {
2063                         val = REG_RD(sc, BCE_NVM_READ);
2064
2065                         val = bce_be32toh(val);
2066                         memcpy(ret_val, &val, 4);
2067                         break;
2068                 }
2069         }
2070
2071         /* Check for errors. */
2072         if (i >= NVRAM_TIMEOUT_COUNT) {
2073                 BCE_PRINTF("%s(%d): Timeout error reading NVRAM at offset 0x%08X!\n",
2074                         __FILE__, __LINE__, offset);
2075                 rc = EBUSY;
2076         }
2077
2078         DBEXIT(BCE_EXTREME_NVRAM);
2079         return(rc);
2080 }
2081
2082
2083 #ifdef BCE_NVRAM_WRITE_SUPPORT
2084 /****************************************************************************/
2085 /* Write a dword (32 bits) to NVRAM.                                        */
2086 /*                                                                          */
2087 /* Write a 32 bit word to NVRAM.  The caller is assumed to have already     */
2088 /* obtained the NVRAM lock, enabled the controller for NVRAM access, and    */
2089 /* enabled NVRAM write access.                                              */
2090 /*                                                                          */
2091 /* Returns:                                                                 */
2092 /*   0 on success, positive value on failure.                               */
2093 /****************************************************************************/
2094 static int
2095 bce_nvram_write_dword(struct bce_softc *sc, u32 offset, u8 *val,
2096         u32 cmd_flags)
2097 {
2098         u32 cmd, val32;
2099         int j, rc = 0;
2100
2101         DBENTER(BCE_VERBOSE_NVRAM);
2102
2103         /* Build the command word. */
2104         cmd = BCE_NVM_COMMAND_DOIT | BCE_NVM_COMMAND_WR | cmd_flags;
2105
2106         /* Calculate the offset for buffered flash if translation is used. */
2107         if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
2108                 offset = ((offset / sc->bce_flash_info->page_size) <<
2109                           sc->bce_flash_info->page_bits) +
2110                          (offset % sc->bce_flash_info->page_size);
2111         }
2112
2113         /*
2114          * Clear the DONE bit separately, convert NVRAM data to big-endian,
2115          * set the NVRAM address to write, and issue the write command
2116          */
2117         REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2118         memcpy(&val32, val, 4);
2119         val32 = htobe32(val32);
2120         REG_WR(sc, BCE_NVM_WRITE, val32);
2121         REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
2122         REG_WR(sc, BCE_NVM_COMMAND, cmd);
2123
2124         /* Wait for completion. */
2125         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2126                 DELAY(5);
2127
2128                 if (REG_RD(sc, BCE_NVM_COMMAND) & BCE_NVM_COMMAND_DONE)
2129                         break;
2130         }
2131         if (j >= NVRAM_TIMEOUT_COUNT) {
2132                 BCE_PRINTF("%s(%d): Timeout error writing NVRAM at offset 0x%08X\n",
2133                         __FILE__, __LINE__, offset);
2134                 rc = EBUSY;
2135         }
2136
2137         DBEXIT(BCE_VERBOSE_NVRAM);
2138         return (rc);
2139 }
2140 #endif /* BCE_NVRAM_WRITE_SUPPORT */
2141
2142
2143 /****************************************************************************/
2144 /* Initialize NVRAM access.                                                 */
2145 /*                                                                          */
2146 /* Identify the NVRAM device in use and prepare the NVRAM interface to      */
2147 /* access that device.                                                      */
2148 /*                                                                          */
2149 /* Returns:                                                                 */
2150 /*   0 on success, positive value on failure.                               */
2151 /****************************************************************************/
2152 static int
2153 bce_init_nvram(struct bce_softc *sc)
2154 {
2155         u32 val;
2156         int j, entry_count, rc = 0;
2157         struct flash_spec *flash;
2158
2159         DBENTER(BCE_VERBOSE_NVRAM);
2160
2161         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
2162                 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
2163                 sc->bce_flash_info = &flash_5709;
2164                 goto bce_init_nvram_get_flash_size;
2165         }
2166
2167         /* Determine the selected interface. */
2168         val = REG_RD(sc, BCE_NVM_CFG1);
2169
2170         entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
2171
2172         /*
2173          * Flash reconfiguration is required to support additional
2174          * NVRAM devices not directly supported in hardware.
2175          * Check if the flash interface was reconfigured
2176          * by the bootcode.
2177          */
2178
2179         if (val & 0x40000000) {
2180                 /* Flash interface reconfigured by bootcode. */
2181
2182                 DBPRINT(sc,BCE_INFO_LOAD,
2183                         "bce_init_nvram(): Flash WAS reconfigured.\n");
2184
2185                 for (j = 0, flash = &flash_table[0]; j < entry_count;
2186                      j++, flash++) {
2187                         if ((val & FLASH_BACKUP_STRAP_MASK) ==
2188                             (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
2189                                 sc->bce_flash_info = flash;
2190                                 break;
2191                         }
2192                 }
2193         } else {
2194                 /* Flash interface not yet reconfigured. */
2195                 u32 mask;
2196
2197                 DBPRINT(sc, BCE_INFO_LOAD, "%s(): Flash was NOT reconfigured.\n",
2198                         __FUNCTION__);
2199
2200                 if (val & (1 << 23))
2201                         mask = FLASH_BACKUP_STRAP_MASK;
2202                 else
2203                         mask = FLASH_STRAP_MASK;
2204
2205                 /* Look for the matching NVRAM device configuration data. */
2206                 for (j = 0, flash = &flash_table[0]; j < entry_count; j++, flash++) {
2207
2208                         /* Check if the device matches any of the known devices. */
2209                         if ((val & mask) == (flash->strapping & mask)) {
2210                                 /* Found a device match. */
2211                                 sc->bce_flash_info = flash;
2212
2213                                 /* Request access to the flash interface. */
2214                                 if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2215                                         return rc;
2216
2217                                 /* Reconfigure the flash interface. */
2218                                 bce_enable_nvram_access(sc);
2219                                 REG_WR(sc, BCE_NVM_CFG1, flash->config1);
2220                                 REG_WR(sc, BCE_NVM_CFG2, flash->config2);
2221                                 REG_WR(sc, BCE_NVM_CFG3, flash->config3);
2222                                 REG_WR(sc, BCE_NVM_WRITE1, flash->write1);
2223                                 bce_disable_nvram_access(sc);
2224                                 bce_release_nvram_lock(sc);
2225
2226                                 break;
2227                         }
2228                 }
2229         }
2230
2231         /* Check if a matching device was found. */
2232         if (j == entry_count) {
2233                 sc->bce_flash_info = NULL;
2234                 BCE_PRINTF("%s(%d): Unknown Flash NVRAM found!\n",
2235                         __FILE__, __LINE__);
2236                 rc = ENODEV;
2237         }
2238
2239 bce_init_nvram_get_flash_size:
2240         /* Write the flash config data to the shared memory interface. */
2241         val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG2);
2242         val &= BCE_SHARED_HW_CFG2_NVM_SIZE_MASK;
2243         if (val)
2244                 sc->bce_flash_size = val;
2245         else
2246                 sc->bce_flash_size = sc->bce_flash_info->total_size;
2247
2248         DBPRINT(sc, BCE_INFO_LOAD, "%s(): Found %s, size = 0x%08X\n",
2249                 __FUNCTION__, sc->bce_flash_info->name,
2250                 sc->bce_flash_info->total_size);
2251
2252         DBEXIT(BCE_VERBOSE_NVRAM);
2253         return rc;
2254 }
2255
2256
2257 /****************************************************************************/
2258 /* Read an arbitrary range of data from NVRAM.                              */
2259 /*                                                                          */
2260 /* Prepares the NVRAM interface for access and reads the requested data     */
2261 /* into the supplied buffer.                                                */
2262 /*                                                                          */
2263 /* Returns:                                                                 */
2264 /*   0 on success and the data read, positive value on failure.             */
2265 /****************************************************************************/
2266 static int
2267 bce_nvram_read(struct bce_softc *sc, u32 offset, u8 *ret_buf,
2268         int buf_size)
2269 {
2270         int rc = 0;
2271         u32 cmd_flags, offset32, len32, extra;
2272
2273         DBENTER(BCE_VERBOSE_NVRAM);
2274
2275         if (buf_size == 0)
2276                 goto bce_nvram_read_exit;
2277
2278         /* Request access to the flash interface. */
2279         if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2280                 goto bce_nvram_read_exit;
2281
2282         /* Enable access to flash interface */
2283         bce_enable_nvram_access(sc);
2284
2285         len32 = buf_size;
2286         offset32 = offset;
2287         extra = 0;
2288
2289         cmd_flags = 0;
2290
2291         if (offset32 & 3) {
2292                 u8 buf[4];
2293                 u32 pre_len;
2294
2295                 offset32 &= ~3;
2296                 pre_len = 4 - (offset & 3);
2297
2298                 if (pre_len >= len32) {
2299                         pre_len = len32;
2300                         cmd_flags = BCE_NVM_COMMAND_FIRST | BCE_NVM_COMMAND_LAST;
2301                 }
2302                 else {
2303                         cmd_flags = BCE_NVM_COMMAND_FIRST;
2304                 }
2305
2306                 rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2307
2308                 if (rc)
2309                         return rc;
2310
2311                 memcpy(ret_buf, buf + (offset & 3), pre_len);
2312
2313                 offset32 += 4;
2314                 ret_buf += pre_len;
2315                 len32 -= pre_len;
2316         }
2317
2318         if (len32 & 3) {
2319                 extra = 4 - (len32 & 3);
2320                 len32 = (len32 + 4) & ~3;
2321         }
2322
2323         if (len32 == 4) {
2324                 u8 buf[4];
2325
2326                 if (cmd_flags)
2327                         cmd_flags = BCE_NVM_COMMAND_LAST;
2328                 else
2329                         cmd_flags = BCE_NVM_COMMAND_FIRST |
2330                                     BCE_NVM_COMMAND_LAST;
2331
2332                 rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2333
2334                 memcpy(ret_buf, buf, 4 - extra);
2335         }
2336         else if (len32 > 0) {
2337                 u8 buf[4];
2338
2339                 /* Read the first word. */
2340                 if (cmd_flags)
2341                         cmd_flags = 0;
2342                 else
2343                         cmd_flags = BCE_NVM_COMMAND_FIRST;
2344
2345                 rc = bce_nvram_read_dword(sc, offset32, ret_buf, cmd_flags);
2346
2347                 /* Advance to the next dword. */
2348                 offset32 += 4;
2349                 ret_buf += 4;
2350                 len32 -= 4;
2351
2352                 while (len32 > 4 && rc == 0) {
2353                         rc = bce_nvram_read_dword(sc, offset32, ret_buf, 0);
2354
2355                         /* Advance to the next dword. */
2356                         offset32 += 4;
2357                         ret_buf += 4;
2358                         len32 -= 4;
2359                 }
2360
2361                 if (rc)
2362                         goto bce_nvram_read_locked_exit;
2363
2364                 cmd_flags = BCE_NVM_COMMAND_LAST;
2365                 rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2366
2367                 memcpy(ret_buf, buf, 4 - extra);
2368         }
2369
2370 bce_nvram_read_locked_exit:
2371         /* Disable access to flash interface and release the lock. */
2372         bce_disable_nvram_access(sc);
2373         bce_release_nvram_lock(sc);
2374
2375 bce_nvram_read_exit:
2376         DBEXIT(BCE_VERBOSE_NVRAM);
2377         return rc;
2378 }
2379
2380
2381 #ifdef BCE_NVRAM_WRITE_SUPPORT
2382 /****************************************************************************/
2383 /* Write an arbitrary range of data from NVRAM.                             */
2384 /*                                                                          */
2385 /* Prepares the NVRAM interface for write access and writes the requested   */
2386 /* data from the supplied buffer.  The caller is responsible for            */
2387 /* calculating any appropriate CRCs.                                        */
2388 /*                                                                          */
2389 /* Returns:                                                                 */
2390 /*   0 on success, positive value on failure.                               */
2391 /****************************************************************************/
2392 static int
2393 bce_nvram_write(struct bce_softc *sc, u32 offset, u8 *data_buf,
2394         int buf_size)
2395 {
2396         u32 written, offset32, len32;
2397         u8 *buf, start[4], end[4];
2398         int rc = 0;
2399         int align_start, align_end;
2400
2401         DBENTER(BCE_VERBOSE_NVRAM);
2402
2403         buf = data_buf;
2404         offset32 = offset;
2405         len32 = buf_size;
2406         align_start = align_end = 0;
2407
2408         if ((align_start = (offset32 & 3))) {
2409                 offset32 &= ~3;
2410                 len32 += align_start;
2411                 if ((rc = bce_nvram_read(sc, offset32, start, 4)))
2412                         goto bce_nvram_write_exit;
2413         }
2414
2415         if (len32 & 3) {
2416                 if ((len32 > 4) || !align_start) {
2417                         align_end = 4 - (len32 & 3);
2418                         len32 += align_end;
2419                         if ((rc = bce_nvram_read(sc, offset32 + len32 - 4,
2420                                 end, 4))) {
2421                                 goto bce_nvram_write_exit;
2422                         }
2423                 }
2424         }
2425
2426         if (align_start || align_end) {
2427                 buf = malloc(len32, M_DEVBUF, M_NOWAIT);
2428                 if (buf == 0) {
2429                         rc = ENOMEM;
2430                         goto bce_nvram_write_exit;
2431                 }
2432
2433                 if (align_start) {
2434                         memcpy(buf, start, 4);
2435                 }
2436
2437                 if (align_end) {
2438                         memcpy(buf + len32 - 4, end, 4);
2439                 }
2440                 memcpy(buf + align_start, data_buf, buf_size);
2441         }
2442
2443         written = 0;
2444         while ((written < len32) && (rc == 0)) {
2445                 u32 page_start, page_end, data_start, data_end;
2446                 u32 addr, cmd_flags;
2447                 int i;
2448                 u8 flash_buffer[264];
2449
2450             /* Find the page_start addr */
2451                 page_start = offset32 + written;
2452                 page_start -= (page_start % sc->bce_flash_info->page_size);
2453                 /* Find the page_end addr */
2454                 page_end = page_start + sc->bce_flash_info->page_size;
2455                 /* Find the data_start addr */
2456                 data_start = (written == 0) ? offset32 : page_start;
2457                 /* Find the data_end addr */
2458                 data_end = (page_end > offset32 + len32) ?
2459                         (offset32 + len32) : page_end;
2460
2461                 /* Request access to the flash interface. */
2462                 if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2463                         goto bce_nvram_write_exit;
2464
2465                 /* Enable access to flash interface */
2466                 bce_enable_nvram_access(sc);
2467
2468                 cmd_flags = BCE_NVM_COMMAND_FIRST;
2469                 if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2470                         int j;
2471
2472                         /* Read the whole page into the buffer
2473                          * (non-buffer flash only) */
2474                         for (j = 0; j < sc->bce_flash_info->page_size; j += 4) {
2475                                 if (j == (sc->bce_flash_info->page_size - 4)) {
2476                                         cmd_flags |= BCE_NVM_COMMAND_LAST;
2477                                 }
2478                                 rc = bce_nvram_read_dword(sc,
2479                                         page_start + j,
2480                                         &flash_buffer[j],
2481                                         cmd_flags);
2482
2483                                 if (rc)
2484                                         goto bce_nvram_write_locked_exit;
2485
2486                                 cmd_flags = 0;
2487                         }
2488                 }
2489
2490                 /* Enable writes to flash interface (unlock write-protect) */
2491                 if ((rc = bce_enable_nvram_write(sc)) != 0)
2492                         goto bce_nvram_write_locked_exit;
2493
2494                 /* Erase the page */
2495                 if ((rc = bce_nvram_erase_page(sc, page_start)) != 0)
2496                         goto bce_nvram_write_locked_exit;
2497
2498                 /* Re-enable the write again for the actual write */
2499                 bce_enable_nvram_write(sc);
2500
2501                 /* Loop to write back the buffer data from page_start to
2502                  * data_start */
2503                 i = 0;
2504                 if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2505                         for (addr = page_start; addr < data_start;
2506                                 addr += 4, i += 4) {
2507
2508                                 rc = bce_nvram_write_dword(sc, addr,
2509                                         &flash_buffer[i], cmd_flags);
2510
2511                                 if (rc != 0)
2512                                         goto bce_nvram_write_locked_exit;
2513
2514                                 cmd_flags = 0;
2515                         }
2516                 }
2517
2518                 /* Loop to write the new data from data_start to data_end */
2519                 for (addr = data_start; addr < data_end; addr += 4, i++) {
2520                         if ((addr == page_end - 4) ||
2521                                 ((sc->bce_flash_info->flags & BCE_NV_BUFFERED) &&
2522                                 (addr == data_end - 4))) {
2523
2524                                 cmd_flags |= BCE_NVM_COMMAND_LAST;
2525                         }
2526                         rc = bce_nvram_write_dword(sc, addr, buf,
2527                                 cmd_flags);
2528
2529                         if (rc != 0)
2530                                 goto bce_nvram_write_locked_exit;
2531
2532                         cmd_flags = 0;
2533                         buf += 4;
2534                 }
2535
2536                 /* Loop to write back the buffer data from data_end
2537                  * to page_end */
2538                 if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2539                         for (addr = data_end; addr < page_end;
2540                                 addr += 4, i += 4) {
2541
2542                                 if (addr == page_end-4) {
2543                                         cmd_flags = BCE_NVM_COMMAND_LAST;
2544                                 }
2545                                 rc = bce_nvram_write_dword(sc, addr,
2546                                         &flash_buffer[i], cmd_flags);
2547
2548                                 if (rc != 0)
2549                                         goto bce_nvram_write_locked_exit;
2550
2551                                 cmd_flags = 0;
2552                         }
2553                 }
2554
2555                 /* Disable writes to flash interface (lock write-protect) */
2556                 bce_disable_nvram_write(sc);
2557
2558                 /* Disable access to flash interface */
2559                 bce_disable_nvram_access(sc);
2560                 bce_release_nvram_lock(sc);
2561
2562                 /* Increment written */
2563                 written += data_end - data_start;
2564         }
2565
2566         goto bce_nvram_write_exit;
2567
2568 bce_nvram_write_locked_exit:
2569                 bce_disable_nvram_write(sc);
2570                 bce_disable_nvram_access(sc);
2571                 bce_release_nvram_lock(sc);
2572
2573 bce_nvram_write_exit:
2574         if (align_start || align_end)
2575                 free(buf, M_DEVBUF);
2576
2577         DBEXIT(BCE_VERBOSE_NVRAM);
2578         return (rc);
2579 }
2580 #endif /* BCE_NVRAM_WRITE_SUPPORT */
2581
2582
2583 /****************************************************************************/
2584 /* Verifies that NVRAM is accessible and contains valid data.               */
2585 /*                                                                          */
2586 /* Reads the configuration data from NVRAM and verifies that the CRC is     */
2587 /* correct.                                                                 */
2588 /*                                                                          */
2589 /* Returns:                                                                 */
2590 /*   0 on success, positive value on failure.                               */
2591 /****************************************************************************/
2592 static int
2593 bce_nvram_test(struct bce_softc *sc)
2594 {
2595         u32 buf[BCE_NVRAM_SIZE / 4];
2596         u8 *data = (u8 *) buf;
2597         int rc = 0;
2598         u32 magic, csum;
2599
2600         DBENTER(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
2601
2602         /*
2603          * Check that the device NVRAM is valid by reading
2604          * the magic value at offset 0.
2605          */
2606         if ((rc = bce_nvram_read(sc, 0, data, 4)) != 0) {
2607                 BCE_PRINTF("%s(%d): Unable to read NVRAM!\n", __FILE__, __LINE__);
2608                 goto bce_nvram_test_exit;
2609         }
2610
2611         /*
2612          * Verify that offset 0 of the NVRAM contains
2613          * a valid magic number.
2614          */
2615     magic = bce_be32toh(buf[0]);
2616         if (magic != BCE_NVRAM_MAGIC) {
2617                 rc = ENODEV;
2618                 BCE_PRINTF("%s(%d): Invalid NVRAM magic value! Expected: 0x%08X, "
2619                         "Found: 0x%08X\n",
2620                         __FILE__, __LINE__, BCE_NVRAM_MAGIC, magic);
2621                 goto bce_nvram_test_exit;
2622         }
2623
2624         /*
2625          * Verify that the device NVRAM includes valid
2626          * configuration data.
2627          */
2628         if ((rc = bce_nvram_read(sc, 0x100, data, BCE_NVRAM_SIZE)) != 0) {
2629                 BCE_PRINTF("%s(%d): Unable to read Manufacturing Information from "
2630                         "NVRAM!\n", __FILE__, __LINE__);
2631                 goto bce_nvram_test_exit;
2632         }
2633
2634         csum = ether_crc32_le(data, 0x100);
2635         if (csum != BCE_CRC32_RESIDUAL) {
2636                 rc = ENODEV;
2637                 BCE_PRINTF("%s(%d): Invalid Manufacturing Information NVRAM CRC! "
2638                         "Expected: 0x%08X, Found: 0x%08X\n",
2639                         __FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
2640                 goto bce_nvram_test_exit;
2641         }
2642
2643         csum = ether_crc32_le(data + 0x100, 0x100);
2644         if (csum != BCE_CRC32_RESIDUAL) {
2645                 rc = ENODEV;
2646                 BCE_PRINTF("%s(%d): Invalid Feature Configuration Information "
2647                         "NVRAM CRC! Expected: 0x%08X, Found: 08%08X\n",
2648                         __FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
2649         }
2650
2651 bce_nvram_test_exit:
2652         DBEXIT(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
2653         return rc;
2654 }
2655
2656
2657 /****************************************************************************/
2658 /* Identifies the current media type of the controller and sets the PHY     */
2659 /* address.                                                                 */
2660 /*                                                                          */
2661 /* Returns:                                                                 */
2662 /*   Nothing.                                                               */
2663 /****************************************************************************/
2664 static void
2665 bce_get_media(struct bce_softc *sc)
2666 {
2667         u32 val;
2668
2669         DBENTER(BCE_VERBOSE);
2670
2671         /* Assume PHY address for copper controllers. */
2672         sc->bce_phy_addr = 1;
2673
2674         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
2675                 u32 val = REG_RD(sc, BCE_MISC_DUAL_MEDIA_CTRL);
2676                 u32 bond_id = val & BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID;
2677                 u32 strap;
2678
2679                 /*
2680                  * The BCM5709S is software configurable
2681                  * for Copper or SerDes operation.
2682                  */
2683                 if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_C) {
2684                         DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded "
2685                             "for copper.\n");
2686                         goto bce_get_media_exit;
2687                 } else if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_S) {
2688                         DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded "
2689                             "for dual media.\n");
2690                         sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2691                         goto bce_get_media_exit;
2692                 }
2693
2694                 if (val & BCE_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE)
2695                         strap = (val & 
2696                             BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21;
2697                 else
2698                         strap = (val & 
2699                             BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8;
2700
2701                 if (pci_get_function(sc->bce_dev) == 0) {
2702                         switch (strap) {
2703                         case 0x4:
2704                         case 0x5:
2705                         case 0x6:
2706                                 DBPRINT(sc, BCE_INFO_LOAD,
2707                                     "BCM5709 s/w configured for SerDes.\n");
2708                                 sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2709                                 break;
2710                         default:
2711                                 DBPRINT(sc, BCE_INFO_LOAD,
2712                                     "BCM5709 s/w configured for Copper.\n");
2713                                 break;
2714                         }
2715                 } else {
2716                         switch (strap) {
2717                         case 0x1:
2718                         case 0x2:
2719                         case 0x4:
2720                                 DBPRINT(sc, BCE_INFO_LOAD,
2721                                     "BCM5709 s/w configured for SerDes.\n");
2722                                 sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2723                                 break;
2724                         default:
2725                                 DBPRINT(sc, BCE_INFO_LOAD,
2726                                     "BCM5709 s/w configured for Copper.\n");
2727                                 break;
2728                         }
2729                 }
2730
2731         } else if (BCE_CHIP_BOND_ID(sc) & BCE_CHIP_BOND_ID_SERDES_BIT)
2732                 sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2733
2734         if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) {
2735
2736                 sc->bce_flags |= BCE_NO_WOL_FLAG;
2737
2738                 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
2739                         sc->bce_phy_flags |= BCE_PHY_IEEE_CLAUSE_45_FLAG;
2740
2741                 if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
2742                         /* 5708S/09S/16S use a separate PHY for SerDes. */
2743                         sc->bce_phy_addr = 2;
2744
2745                         val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
2746                         if (val & BCE_SHARED_HW_CFG_PHY_2_5G) {
2747                                 sc->bce_phy_flags |= 
2748                                     BCE_PHY_2_5G_CAPABLE_FLAG;
2749                                 DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb "
2750                                     "capable adapter\n");
2751                         }
2752                 }
2753         } else if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) ||
2754             (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708))
2755                 sc->bce_phy_flags |= BCE_PHY_CRC_FIX_FLAG;
2756
2757 bce_get_media_exit:
2758         DBPRINT(sc, (BCE_INFO_LOAD | BCE_INFO_PHY),
2759                 "Using PHY address %d.\n", sc->bce_phy_addr);
2760
2761         DBEXIT(BCE_VERBOSE);
2762 }
2763
2764
2765 /****************************************************************************/
2766 /* Performs PHY initialization required before MII drivers access the       */
2767 /* device.                                                                  */
2768 /*                                                                          */
2769 /* Returns:                                                                 */
2770 /*   Nothing.                                                               */
2771 /****************************************************************************/
2772 static void
2773 bce_init_media(struct bce_softc *sc)
2774 {
2775         if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
2776                 /*
2777                  * Configure 5709S/5716S PHYs to use traditional IEEE
2778                  * Clause 22 method. Otherwise we have no way to attach
2779                  * the PHY in mii(4) layer. PHY specific configuration
2780                  * is done in mii layer.
2781                  */
2782
2783                 /* Select auto-negotiation MMD of the PHY. */
2784                 bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
2785                     BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_ADDR_EXT);
2786                 bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
2787                     BRGPHY_ADDR_EXT, BRGPHY_ADDR_EXT_AN_MMD);
2788
2789                 /* Set IEEE0 block of AN MMD (assumed in brgphy(4) code). */
2790                 bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
2791                     BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
2792         }
2793 }
2794
2795
2796 /****************************************************************************/
2797 /* Free any DMA memory owned by the driver.                                 */
2798 /*                                                                          */
2799 /* Scans through each data structre that requires DMA memory and frees      */
2800 /* the memory if allocated.                                                 */
2801 /*                                                                          */
2802 /* Returns:                                                                 */
2803 /*   Nothing.                                                               */
2804 /****************************************************************************/
2805 static void
2806 bce_dma_free(struct bce_softc *sc)
2807 {
2808         int i;
2809
2810         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
2811
2812         /* Free, unmap, and destroy the status block. */
2813         if (sc->status_block != NULL) {
2814                 bus_dmamem_free(
2815                    sc->status_tag,
2816                     sc->status_block,
2817                     sc->status_map);
2818                 sc->status_block = NULL;
2819         }
2820
2821         if (sc->status_map != NULL) {
2822                 bus_dmamap_unload(
2823                     sc->status_tag,
2824                     sc->status_map);
2825                 bus_dmamap_destroy(sc->status_tag,
2826                     sc->status_map);
2827                 sc->status_map = NULL;
2828         }
2829
2830         if (sc->status_tag != NULL) {
2831                 bus_dma_tag_destroy(sc->status_tag);
2832                 sc->status_tag = NULL;
2833         }
2834
2835
2836         /* Free, unmap, and destroy the statistics block. */
2837         if (sc->stats_block != NULL) {
2838                 bus_dmamem_free(
2839                     sc->stats_tag,
2840                     sc->stats_block,
2841                     sc->stats_map);
2842                 sc->stats_block = NULL;
2843         }
2844
2845         if (sc->stats_map != NULL) {
2846                 bus_dmamap_unload(
2847                     sc->stats_tag,
2848                     sc->stats_map);
2849                 bus_dmamap_destroy(sc->stats_tag,
2850                     sc->stats_map);
2851                 sc->stats_map = NULL;
2852         }
2853
2854         if (sc->stats_tag != NULL) {
2855                 bus_dma_tag_destroy(sc->stats_tag);
2856                 sc->stats_tag = NULL;
2857         }
2858
2859
2860         /* Free, unmap and destroy all context memory pages. */
2861         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
2862                 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
2863                 for (i = 0; i < sc->ctx_pages; i++ ) {
2864                         if (sc->ctx_block[i] != NULL) {
2865                                 bus_dmamem_free(
2866                                     sc->ctx_tag,
2867                                     sc->ctx_block[i],
2868                                     sc->ctx_map[i]);
2869                                 sc->ctx_block[i] = NULL;
2870                         }
2871
2872                         if (sc->ctx_map[i] != NULL) {
2873                                 bus_dmamap_unload(
2874                                     sc->ctx_tag,
2875                                     sc->ctx_map[i]);
2876                                 bus_dmamap_destroy(
2877                                     sc->ctx_tag,
2878                                     sc->ctx_map[i]);
2879                                 sc->ctx_map[i] = NULL;
2880                         }
2881                 }
2882
2883                 /* Destroy the context memory tag. */
2884                 if (sc->ctx_tag != NULL) {
2885                         bus_dma_tag_destroy(sc->ctx_tag);
2886                         sc->ctx_tag = NULL;
2887                 }
2888         }
2889
2890
2891         /* Free, unmap and destroy all TX buffer descriptor chain pages. */
2892         for (i = 0; i < TX_PAGES; i++ ) {
2893                 if (sc->tx_bd_chain[i] != NULL) {
2894                         bus_dmamem_free(
2895                             sc->tx_bd_chain_tag,
2896                             sc->tx_bd_chain[i],
2897                             sc->tx_bd_chain_map[i]);
2898                         sc->tx_bd_chain[i] = NULL;
2899                 }
2900
2901                 if (sc->tx_bd_chain_map[i] != NULL) {
2902                         bus_dmamap_unload(
2903                             sc->tx_bd_chain_tag,
2904                             sc->tx_bd_chain_map[i]);
2905                         bus_dmamap_destroy(
2906                             sc->tx_bd_chain_tag,
2907                             sc->tx_bd_chain_map[i]);
2908                         sc->tx_bd_chain_map[i] = NULL;
2909                 }
2910         }
2911
2912         /* Destroy the TX buffer descriptor tag. */
2913         if (sc->tx_bd_chain_tag != NULL) {
2914                 bus_dma_tag_destroy(sc->tx_bd_chain_tag);
2915                 sc->tx_bd_chain_tag = NULL;
2916         }
2917
2918
2919         /* Free, unmap and destroy all RX buffer descriptor chain pages. */
2920         for (i = 0; i < RX_PAGES; i++ ) {
2921                 if (sc->rx_bd_chain[i] != NULL) {
2922                         bus_dmamem_free(
2923                             sc->rx_bd_chain_tag,
2924                             sc->rx_bd_chain[i],
2925                             sc->rx_bd_chain_map[i]);
2926                         sc->rx_bd_chain[i] = NULL;
2927                 }
2928
2929                 if (sc->rx_bd_chain_map[i] != NULL) {
2930                         bus_dmamap_unload(
2931                             sc->rx_bd_chain_tag,
2932                             sc->rx_bd_chain_map[i]);
2933                         bus_dmamap_destroy(
2934                             sc->rx_bd_chain_tag,
2935                             sc->rx_bd_chain_map[i]);
2936                         sc->rx_bd_chain_map[i] = NULL;
2937                 }
2938         }
2939
2940         /* Destroy the RX buffer descriptor tag. */
2941         if (sc->rx_bd_chain_tag != NULL) {
2942                 bus_dma_tag_destroy(sc->rx_bd_chain_tag);
2943                 sc->rx_bd_chain_tag = NULL;
2944         }
2945
2946
2947 #ifdef BCE_JUMBO_HDRSPLIT
2948         /* Free, unmap and destroy all page buffer descriptor chain pages. */
2949         for (i = 0; i < PG_PAGES; i++ ) {
2950                 if (sc->pg_bd_chain[i] != NULL) {
2951                         bus_dmamem_free(
2952                             sc->pg_bd_chain_tag,
2953                             sc->pg_bd_chain[i],
2954                             sc->pg_bd_chain_map[i]);
2955                         sc->pg_bd_chain[i] = NULL;
2956                 }
2957
2958                 if (sc->pg_bd_chain_map[i] != NULL) {
2959                         bus_dmamap_unload(
2960                             sc->pg_bd_chain_tag,
2961                             sc->pg_bd_chain_map[i]);
2962                         bus_dmamap_destroy(
2963                             sc->pg_bd_chain_tag,
2964                             sc->pg_bd_chain_map[i]);
2965                         sc->pg_bd_chain_map[i] = NULL;
2966                 }
2967         }
2968
2969         /* Destroy the page buffer descriptor tag. */
2970         if (sc->pg_bd_chain_tag != NULL) {
2971                 bus_dma_tag_destroy(sc->pg_bd_chain_tag);
2972                 sc->pg_bd_chain_tag = NULL;
2973         }
2974 #endif
2975
2976
2977         /* Unload and destroy the TX mbuf maps. */
2978         for (i = 0; i < TOTAL_TX_BD; i++) {
2979                 if (sc->tx_mbuf_map[i] != NULL) {
2980                         bus_dmamap_unload(sc->tx_mbuf_tag,
2981                             sc->tx_mbuf_map[i]);
2982                         bus_dmamap_destroy(sc->tx_mbuf_tag,
2983                             sc->tx_mbuf_map[i]);
2984                         sc->tx_mbuf_map[i] = NULL;
2985                 }
2986         }
2987
2988         /* Destroy the TX mbuf tag. */
2989         if (sc->tx_mbuf_tag != NULL) {
2990                 bus_dma_tag_destroy(sc->tx_mbuf_tag);
2991                 sc->tx_mbuf_tag = NULL;
2992         }
2993
2994         /* Unload and destroy the RX mbuf maps. */
2995         for (i = 0; i < TOTAL_RX_BD; i++) {
2996                 if (sc->rx_mbuf_map[i] != NULL) {
2997                         bus_dmamap_unload(sc->rx_mbuf_tag,
2998                             sc->rx_mbuf_map[i]);
2999                         bus_dmamap_destroy(sc->rx_mbuf_tag,
3000                             sc->rx_mbuf_map[i]);
3001                         sc->rx_mbuf_map[i] = NULL;
3002                 }
3003         }
3004
3005         /* Destroy the RX mbuf tag. */
3006         if (sc->rx_mbuf_tag != NULL) {
3007                 bus_dma_tag_destroy(sc->rx_mbuf_tag);
3008                 sc->rx_mbuf_tag = NULL;
3009         }
3010
3011 #ifdef BCE_JUMBO_HDRSPLIT
3012         /* Unload and destroy the page mbuf maps. */
3013         for (i = 0; i < TOTAL_PG_BD; i++) {
3014                 if (sc->pg_mbuf_map[i] != NULL) {
3015                         bus_dmamap_unload(sc->pg_mbuf_tag,
3016                             sc->pg_mbuf_map[i]);
3017                         bus_dmamap_destroy(sc->pg_mbuf_tag,
3018                             sc->pg_mbuf_map[i]);
3019                         sc->pg_mbuf_map[i] = NULL;
3020                 }
3021         }
3022
3023         /* Destroy the page mbuf tag. */
3024         if (sc->pg_mbuf_tag != NULL) {
3025                 bus_dma_tag_destroy(sc->pg_mbuf_tag);
3026                 sc->pg_mbuf_tag = NULL;
3027         }
3028 #endif
3029
3030         /* Destroy the parent tag */
3031         if (sc->parent_tag != NULL) {
3032                 bus_dma_tag_destroy(sc->parent_tag);
3033                 sc->parent_tag = NULL;
3034         }
3035
3036         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
3037 }
3038
3039
3040 /****************************************************************************/
3041 /* Get DMA memory from the OS.                                              */
3042 /*                                                                          */
3043 /* Validates that the OS has provided DMA buffers in response to a          */
3044 /* bus_dmamap_load() call and saves the physical address of those buffers.  */
3045 /* When the callback is used the OS will return 0 for the mapping function  */
3046 /* (bus_dmamap_load()) so we use the value of map_arg->maxsegs to pass any  */
3047 /* failures back to the caller.                                             */
3048 /*                                                                          */
3049 /* Returns:                                                                 */
3050 /*   Nothing.                                                               */
3051 /****************************************************************************/
3052 static void
3053 bce_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
3054 {
3055         bus_addr_t *busaddr = arg;
3056
3057         /* Simulate a mapping failure. */
3058         DBRUNIF(DB_RANDOMTRUE(dma_map_addr_failed_sim_control),
3059                 error = ENOMEM);
3060
3061         /* Check for an error and signal the caller that an error occurred. */
3062         if (error) {
3063                 *busaddr = 0;
3064         } else {
3065                 *busaddr = segs->ds_addr;
3066         }
3067
3068         return;
3069 }
3070
3071
3072 /****************************************************************************/
3073 /* Allocate any DMA memory needed by the driver.                            */
3074 /*                                                                          */
3075 /* Allocates DMA memory needed for the various global structures needed by  */
3076 /* hardware.                                                                */
3077 /*                                                                          */
3078 /* Memory alignment requirements:                                           */
3079 /* +-----------------+----------+----------+----------+----------+          */
3080 /* |                 |   5706   |   5708   |   5709   |   5716   |          */
3081 /* +-----------------+----------+----------+----------+----------+          */
3082 /* |Status Block     | 8 bytes  | 8 bytes  | 16 bytes | 16 bytes |          */
3083 /* |Statistics Block | 8 bytes  | 8 bytes  | 16 bytes | 16 bytes |          */
3084 /* |RX Buffers       | 16 bytes | 16 bytes | 16 bytes | 16 bytes |          */
3085 /* |PG Buffers       |   none   |   none   |   none   |   none   |          */
3086 /* |TX Buffers       |   none   |   none   |   none   |   none   |          */
3087 /* |Chain Pages(1)   |   4KiB   |   4KiB   |   4KiB   |   4KiB   |          */
3088 /* |Context Memory   |          |          |          |          |          */
3089 /* +-----------------+----------+----------+----------+----------+          */
3090 /*                                                                          */
3091 /* (1) Must align with CPU page size (BCM_PAGE_SZIE).                       */
3092 /*                                                                          */
3093 /* Returns:                                                                 */
3094 /*   0 for success, positive value for failure.                             */
3095 /****************************************************************************/
3096 static int
3097 bce_dma_alloc(device_t dev)
3098 {
3099         struct bce_softc *sc;
3100         int i, error, rc = 0;
3101         bus_size_t max_size, max_seg_size;
3102         int max_segments;
3103
3104         sc = device_get_softc(dev);
3105
3106         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
3107
3108         /*
3109          * Allocate the parent bus DMA tag appropriate for PCI.
3110          */
3111         if (bus_dma_tag_create(NULL, 1, BCE_DMA_BOUNDARY,
3112             sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
3113             MAXBSIZE, BUS_SPACE_UNRESTRICTED, BUS_SPACE_MAXSIZE_32BIT,
3114             0, NULL, NULL, &sc->parent_tag)) {
3115                 BCE_PRINTF("%s(%d): Could not allocate parent DMA tag!\n",
3116                     __FILE__, __LINE__);
3117                 rc = ENOMEM;
3118                 goto bce_dma_alloc_exit;
3119         }
3120
3121         /*
3122          * Create a DMA tag for the status block, allocate and clear the
3123          * memory, map the memory into DMA space, and fetch the physical
3124          * address of the block.
3125          */
3126         if (bus_dma_tag_create(sc->parent_tag, BCE_DMA_ALIGN,
3127             BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR,
3128             NULL, NULL, BCE_STATUS_BLK_SZ, 1, BCE_STATUS_BLK_SZ,
3129             0, NULL, NULL, &sc->status_tag)) {
3130                 BCE_PRINTF("%s(%d): Could not allocate status block "
3131                     "DMA tag!\n", __FILE__, __LINE__);
3132                 rc = ENOMEM;
3133                 goto bce_dma_alloc_exit;
3134         }
3135
3136         if(bus_dmamem_alloc(sc->status_tag, (void **)&sc->status_block,
3137             BUS_DMA_NOWAIT, &sc->status_map)) {
3138                 BCE_PRINTF("%s(%d): Could not allocate status block "
3139                     "DMA memory!\n", __FILE__, __LINE__);
3140                 rc = ENOMEM;
3141                 goto bce_dma_alloc_exit;
3142         }
3143
3144         bzero((char *)sc->status_block, BCE_STATUS_BLK_SZ);
3145
3146         error = bus_dmamap_load(sc->status_tag, sc->status_map,
3147             sc->status_block, BCE_STATUS_BLK_SZ, bce_dma_map_addr,
3148             &sc->status_block_paddr, BUS_DMA_NOWAIT);
3149
3150         if (error) {
3151                 BCE_PRINTF("%s(%d): Could not map status block "
3152                     "DMA memory!\n", __FILE__, __LINE__);
3153                 rc = ENOMEM;
3154                 goto bce_dma_alloc_exit;
3155         }
3156
3157         DBPRINT(sc, BCE_INFO, "%s(): status_block_paddr = 0x%jX\n",
3158             __FUNCTION__, (uintmax_t) sc->status_block_paddr);
3159
3160         /*
3161          * Create a DMA tag for the statistics block, allocate and clear the
3162          * memory, map the memory into DMA space, and fetch the physical
3163          * address of the block.
3164          */
3165         if (bus_dma_tag_create(sc->parent_tag, BCE_DMA_ALIGN,
3166             BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR,
3167             NULL, NULL, BCE_STATS_BLK_SZ, 1, BCE_STATS_BLK_SZ,
3168             0, NULL, NULL, &sc->stats_tag)) {
3169                 BCE_PRINTF("%s(%d): Could not allocate statistics block "
3170                     "DMA tag!\n", __FILE__, __LINE__);
3171                 rc = ENOMEM;
3172                 goto bce_dma_alloc_exit;
3173         }
3174
3175         if (bus_dmamem_alloc(sc->stats_tag, (void **)&sc->stats_block,
3176             BUS_DMA_NOWAIT,     &sc->stats_map)) {
3177                 BCE_PRINTF("%s(%d): Could not allocate statistics block "
3178                     "DMA memory!\n", __FILE__, __LINE__);
3179                 rc = ENOMEM;
3180                 goto bce_dma_alloc_exit;
3181         }
3182
3183         bzero((char *)sc->stats_block, BCE_STATS_BLK_SZ);
3184
3185         error = bus_dmamap_load(sc->stats_tag, sc->stats_map,
3186             sc->stats_block, BCE_STATS_BLK_SZ, bce_dma_map_addr,
3187             &sc->stats_block_paddr, BUS_DMA_NOWAIT);
3188
3189         if(error) {
3190                 BCE_PRINTF("%s(%d): Could not map statistics block "
3191                     "DMA memory!\n", __FILE__, __LINE__);
3192                 rc = ENOMEM;
3193                 goto bce_dma_alloc_exit;
3194         }
3195
3196         DBPRINT(sc, BCE_INFO, "%s(): stats_block_paddr = 0x%jX\n",
3197             __FUNCTION__, (uintmax_t) sc->stats_block_paddr);
3198
3199         /* BCM5709 uses host memory as cache for context memory. */
3200         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3201             (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3202                 sc->ctx_pages = 0x2000 / BCM_PAGE_SIZE;
3203                 if (sc->ctx_pages == 0)
3204                         sc->ctx_pages = 1;
3205
3206                 DBRUNIF((sc->ctx_pages > 512),
3207                     BCE_PRINTF("%s(%d): Too many CTX pages! %d > 512\n",
3208                     __FILE__, __LINE__, sc->ctx_pages));
3209
3210                 /*
3211                  * Create a DMA tag for the context pages,
3212                  * allocate and clear the memory, map the
3213                  * memory into DMA space, and fetch the
3214                  * physical address of the block.
3215                  */
3216                 if(bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
3217                     BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR,
3218                     NULL, NULL, BCM_PAGE_SIZE, 1, BCM_PAGE_SIZE,
3219                     0, NULL, NULL, &sc->ctx_tag)) {
3220                         BCE_PRINTF("%s(%d): Could not allocate CTX DMA tag!\n",
3221                             __FILE__, __LINE__);
3222                         rc = ENOMEM;
3223                         goto bce_dma_alloc_exit;
3224                 }
3225
3226                 for (i = 0; i < sc->ctx_pages; i++) {
3227
3228                         if(bus_dmamem_alloc(sc->ctx_tag,
3229                             (void **)&sc->ctx_block[i],
3230                             BUS_DMA_NOWAIT,
3231                             &sc->ctx_map[i])) {
3232                                 BCE_PRINTF("%s(%d): Could not allocate CTX "
3233                                     "DMA memory!\n", __FILE__, __LINE__);
3234                                 rc = ENOMEM;
3235                                 goto bce_dma_alloc_exit;
3236                         }
3237
3238                         bzero((char *)sc->ctx_block[i], BCM_PAGE_SIZE);
3239
3240                         error = bus_dmamap_load(sc->ctx_tag, sc->ctx_map[i],
3241                             sc->ctx_block[i], BCM_PAGE_SIZE, bce_dma_map_addr,
3242                             &sc->ctx_paddr[i], BUS_DMA_NOWAIT);
3243
3244                         if (error) {
3245                                 BCE_PRINTF("%s(%d): Could not map CTX "
3246                                     "DMA memory!\n", __FILE__, __LINE__);
3247                                 rc = ENOMEM;
3248                                 goto bce_dma_alloc_exit;
3249                         }
3250
3251                         DBPRINT(sc, BCE_INFO, "%s(): ctx_paddr[%d] = 0x%jX\n",
3252                             __FUNCTION__, i, (uintmax_t) sc->ctx_paddr[i]);
3253                 }
3254         }
3255
3256         /*
3257          * Create a DMA tag for the TX buffer descriptor chain,
3258          * allocate and clear the  memory, and fetch the
3259          * physical address of the block.
3260          */
3261         if(bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE, BCE_DMA_BOUNDARY,
3262             sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
3263             BCE_TX_CHAIN_PAGE_SZ, 1, BCE_TX_CHAIN_PAGE_SZ, 0,
3264             NULL, NULL, &sc->tx_bd_chain_tag)) {
3265                 BCE_PRINTF("%s(%d): Could not allocate TX descriptor chain "
3266                     "DMA tag!\n", __FILE__, __LINE__);
3267                 rc = ENOMEM;
3268                 goto bce_dma_alloc_exit;
3269         }
3270
3271         for (i = 0; i < TX_PAGES; i++) {
3272
3273                 if(bus_dmamem_alloc(sc->tx_bd_chain_tag, 
3274                     (void **)&sc->tx_bd_chain[i], BUS_DMA_NOWAIT,
3275                     &sc->tx_bd_chain_map[i])) {
3276                         BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
3277                             "chain DMA memory!\n", __FILE__, __LINE__);
3278                         rc = ENOMEM;
3279                         goto bce_dma_alloc_exit;
3280                 }
3281
3282                 error = bus_dmamap_load(sc->tx_bd_chain_tag,
3283                     sc->tx_bd_chain_map[i], sc->tx_bd_chain[i],
3284                     BCE_TX_CHAIN_PAGE_SZ, bce_dma_map_addr,
3285                     &sc->tx_bd_chain_paddr[i], BUS_DMA_NOWAIT);
3286
3287                 if (error) {
3288                         BCE_PRINTF("%s(%d): Could not map TX descriptor "
3289                             "chain DMA memory!\n", __FILE__, __LINE__);
3290                         rc = ENOMEM;
3291                         goto bce_dma_alloc_exit;
3292                 }
3293
3294                 DBPRINT(sc, BCE_INFO, "%s(): tx_bd_chain_paddr[%d] = 0x%jX\n",
3295                     __FUNCTION__, i, (uintmax_t) sc->tx_bd_chain_paddr[i]);
3296         }
3297
3298         /* Check the required size before mapping to conserve resources. */
3299         if (bce_tso_enable) {
3300                 max_size     = BCE_TSO_MAX_SIZE;
3301                 max_segments = BCE_MAX_SEGMENTS;
3302                 max_seg_size = BCE_TSO_MAX_SEG_SIZE;
3303         } else {
3304                 max_size     = MCLBYTES * BCE_MAX_SEGMENTS;
3305                 max_segments = BCE_MAX_SEGMENTS;
3306                 max_seg_size = MCLBYTES;
3307         }
3308
3309         /* Create a DMA tag for TX mbufs. */
3310         if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
3311             sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, max_size,
3312             max_segments, max_seg_size, 0, NULL, NULL, &sc->tx_mbuf_tag)) {
3313                 BCE_PRINTF("%s(%d): Could not allocate TX mbuf DMA tag!\n",
3314                     __FILE__, __LINE__);
3315                 rc = ENOMEM;
3316                 goto bce_dma_alloc_exit;
3317         }
3318
3319         /* Create DMA maps for the TX mbufs clusters. */
3320         for (i = 0; i < TOTAL_TX_BD; i++) {
3321                 if (bus_dmamap_create(sc->tx_mbuf_tag, BUS_DMA_NOWAIT,
3322                         &sc->tx_mbuf_map[i])) {
3323                         BCE_PRINTF("%s(%d): Unable to create TX mbuf DMA "
3324                             "map!\n", __FILE__, __LINE__);
3325                         rc = ENOMEM;
3326                         goto bce_dma_alloc_exit;
3327                 }
3328         }
3329
3330         /*
3331          * Create a DMA tag for the RX buffer descriptor chain,
3332          * allocate and clear the memory, and fetch the physical
3333          * address of the blocks.
3334          */
3335         if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
3336                         BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR,
3337                         sc->max_bus_addr, NULL, NULL,
3338                         BCE_RX_CHAIN_PAGE_SZ, 1, BCE_RX_CHAIN_PAGE_SZ,
3339                         0, NULL, NULL, &sc->rx_bd_chain_tag)) {
3340                 BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain "
3341                     "DMA tag!\n", __FILE__, __LINE__);
3342                 rc = ENOMEM;
3343                 goto bce_dma_alloc_exit;
3344         }
3345
3346         for (i = 0; i < RX_PAGES; i++) {
3347
3348                 if (bus_dmamem_alloc(sc->rx_bd_chain_tag,
3349                     (void **)&sc->rx_bd_chain[i], BUS_DMA_NOWAIT,
3350                     &sc->rx_bd_chain_map[i])) {
3351                         BCE_PRINTF("%s(%d): Could not allocate RX descriptor "
3352                             "chain DMA memory!\n", __FILE__, __LINE__);
3353                         rc = ENOMEM;
3354                         goto bce_dma_alloc_exit;
3355                 }
3356
3357                 bzero((char *)sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ);
3358
3359                 error = bus_dmamap_load(sc->rx_bd_chain_tag,
3360                     sc->rx_bd_chain_map[i], sc->rx_bd_chain[i],
3361                     BCE_RX_CHAIN_PAGE_SZ, bce_dma_map_addr,
3362                     &sc->rx_bd_chain_paddr[i], BUS_DMA_NOWAIT);
3363
3364                 if (error) {
3365                         BCE_PRINTF("%s(%d): Could not map RX descriptor "
3366                             "chain DMA memory!\n", __FILE__, __LINE__);
3367                         rc = ENOMEM;
3368                         goto bce_dma_alloc_exit;
3369                 }
3370
3371                 DBPRINT(sc, BCE_INFO, "%s(): rx_bd_chain_paddr[%d] = 0x%jX\n",
3372                     __FUNCTION__, i, (uintmax_t) sc->rx_bd_chain_paddr[i]);
3373         }
3374
3375         /*
3376          * Create a DMA tag for RX mbufs.
3377          */
3378 #ifdef BCE_JUMBO_HDRSPLIT
3379         max_size = max_seg_size = ((sc->rx_bd_mbuf_alloc_size < MCLBYTES) ?
3380                 MCLBYTES : sc->rx_bd_mbuf_alloc_size);
3381 #else
3382         max_size = max_seg_size = MJUM9BYTES;
3383 #endif
3384         max_segments = 1;
3385
3386         DBPRINT(sc, BCE_INFO, "%s(): Creating rx_mbuf_tag (max size = 0x%jX "
3387             "max segments = %d, max segment size = 0x%jX)\n", __FUNCTION__,
3388             (uintmax_t) max_size, max_segments, (uintmax_t) max_seg_size);
3389
3390         if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
3391             sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, max_size,
3392            max_segments, max_seg_size, 0, NULL, NULL, &sc->rx_mbuf_tag)) {
3393                 BCE_PRINTF("%s(%d): Could not allocate RX mbuf DMA tag!\n",
3394                     __FILE__, __LINE__);
3395                 rc = ENOMEM;
3396                 goto bce_dma_alloc_exit;
3397         }
3398
3399         /* Create DMA maps for the RX mbuf clusters. */
3400         for (i = 0; i < TOTAL_RX_BD; i++) {
3401                 if (bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_NOWAIT,
3402                     &sc->rx_mbuf_map[i])) {
3403                         BCE_PRINTF("%s(%d): Unable to create RX mbuf "
3404                             "DMA map!\n", __FILE__, __LINE__);
3405                         rc = ENOMEM;
3406                         goto bce_dma_alloc_exit;
3407                 }
3408         }
3409
3410 #ifdef BCE_JUMBO_HDRSPLIT
3411         /*
3412          * Create a DMA tag for the page buffer descriptor chain,
3413          * allocate and clear the memory, and fetch the physical
3414          * address of the blocks.
3415          */
3416         if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
3417             BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR, sc->max_bus_addr,
3418             NULL, NULL, BCE_PG_CHAIN_PAGE_SZ, 1, BCE_PG_CHAIN_PAGE_SZ,
3419             0, NULL, NULL, &sc->pg_bd_chain_tag)) {
3420                 BCE_PRINTF("%s(%d): Could not allocate page descriptor "
3421                     "chain DMA tag!\n", __FILE__, __LINE__);
3422                 rc = ENOMEM;
3423                 goto bce_dma_alloc_exit;
3424         }
3425
3426         for (i = 0; i < PG_PAGES; i++) {
3427
3428                 if (bus_dmamem_alloc(sc->pg_bd_chain_tag,
3429                     (void **)&sc->pg_bd_chain[i], BUS_DMA_NOWAIT,
3430                     &sc->pg_bd_chain_map[i])) {
3431                         BCE_PRINTF("%s(%d): Could not allocate page "
3432                             "descriptor chain DMA memory!\n", 
3433                             __FILE__, __LINE__);
3434                         rc = ENOMEM;
3435                         goto bce_dma_alloc_exit;
3436                 }
3437
3438                 bzero((char *)sc->pg_bd_chain[i], BCE_PG_CHAIN_PAGE_SZ);
3439
3440                 error = bus_dmamap_load(sc->pg_bd_chain_tag, 
3441                     sc->pg_bd_chain_map[i], sc->pg_bd_chain[i],
3442                     BCE_PG_CHAIN_PAGE_SZ, bce_dma_map_addr,
3443                     &sc->pg_bd_chain_paddr[i], BUS_DMA_NOWAIT);
3444
3445                 if (error) {
3446                         BCE_PRINTF("%s(%d): Could not map page descriptor "
3447                             "chain DMA memory!\n", __FILE__, __LINE__);
3448                         rc = ENOMEM;
3449                         goto bce_dma_alloc_exit;
3450                 }
3451
3452                 DBPRINT(sc, BCE_INFO, "%s(): pg_bd_chain_paddr[%d] = 0x%jX\n",
3453                     __FUNCTION__, i, (uintmax_t) sc->pg_bd_chain_paddr[i]);
3454         }
3455
3456         /*
3457          * Create a DMA tag for page mbufs.
3458          */
3459         max_size = max_seg_size = ((sc->pg_bd_mbuf_alloc_size < MCLBYTES) ?
3460             MCLBYTES : sc->pg_bd_mbuf_alloc_size);
3461
3462         if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
3463             sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
3464             max_size, 1, max_seg_size, 0, NULL, NULL, &sc->pg_mbuf_tag)) {
3465                 BCE_PRINTF("%s(%d): Could not allocate page mbuf "
3466                     "DMA tag!\n", __FILE__, __LINE__);
3467                 rc = ENOMEM;
3468                 goto bce_dma_alloc_exit;
3469         }
3470
3471         /* Create DMA maps for the page mbuf clusters. */
3472         for (i = 0; i < TOTAL_PG_BD; i++) {
3473                 if (bus_dmamap_create(sc->pg_mbuf_tag, BUS_DMA_NOWAIT,
3474                     &sc->pg_mbuf_map[i])) {
3475                         BCE_PRINTF("%s(%d): Unable to create page mbuf "
3476                             "DMA map!\n", __FILE__, __LINE__);
3477                         rc = ENOMEM;
3478                         goto bce_dma_alloc_exit;
3479                 }
3480         }
3481 #endif
3482
3483 bce_dma_alloc_exit:
3484         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
3485         return(rc);
3486 }
3487
3488
3489 /****************************************************************************/
3490 /* Release all resources used by the driver.                                */
3491 /*                                                                          */
3492 /* Releases all resources acquired by the driver including interrupts,      */
3493 /* interrupt handler, interfaces, mutexes, and DMA memory.                  */
3494 /*                                                                          */
3495 /* Returns:                                                                 */
3496 /*   Nothing.                                                               */
3497 /****************************************************************************/
3498 static void
3499 bce_release_resources(struct bce_softc *sc)
3500 {
3501         device_t dev;
3502
3503         DBENTER(BCE_VERBOSE_RESET);
3504
3505         dev = sc->bce_dev;
3506
3507         bce_dma_free(sc);
3508
3509         if (sc->bce_intrhand != NULL) {
3510                 DBPRINT(sc, BCE_INFO_RESET, "Removing interrupt handler.\n");
3511                 bus_teardown_intr(dev, sc->bce_res_irq, sc->bce_intrhand);
3512         }
3513
3514         if (sc->bce_res_irq != NULL) {
3515                 DBPRINT(sc, BCE_INFO_RESET, "Releasing IRQ.\n");
3516                 bus_release_resource(dev, SYS_RES_IRQ, sc->bce_irq_rid,
3517                     sc->bce_res_irq);
3518         }
3519
3520         if (sc->bce_flags & (BCE_USING_MSI_FLAG | BCE_USING_MSIX_FLAG)) {
3521                 DBPRINT(sc, BCE_INFO_RESET, "Releasing MSI/MSI-X vector.\n");
3522                 pci_release_msi(dev);
3523         }
3524
3525         if (sc->bce_res_mem != NULL) {
3526                 DBPRINT(sc, BCE_INFO_RESET, "Releasing PCI memory.\n");
3527                     bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), 
3528                     sc->bce_res_mem);
3529         }
3530
3531         if (sc->bce_ifp != NULL) {
3532                 DBPRINT(sc, BCE_INFO_RESET, "Releasing IF.\n");
3533                 if_free(sc->bce_ifp);
3534         }
3535
3536         if (mtx_initialized(&sc->bce_mtx))
3537                 BCE_LOCK_DESTROY(sc);
3538
3539         DBEXIT(BCE_VERBOSE_RESET);
3540 }
3541
3542
3543 /****************************************************************************/
3544 /* Firmware synchronization.                                                */
3545 /*                                                                          */
3546 /* Before performing certain events such as a chip reset, synchronize with  */
3547 /* the firmware first.                                                      */
3548 /*                                                                          */
3549 /* Returns:                                                                 */
3550 /*   0 for success, positive value for failure.                             */
3551 /****************************************************************************/
3552 static int
3553 bce_fw_sync(struct bce_softc *sc, u32 msg_data)
3554 {
3555         int i, rc = 0;
3556         u32 val;
3557
3558         DBENTER(BCE_VERBOSE_RESET);
3559
3560         /* Don't waste any time if we've timed out before. */
3561         if (sc->bce_fw_timed_out == TRUE) {
3562                 rc = EBUSY;
3563                 goto bce_fw_sync_exit;
3564         }
3565
3566         /* Increment the message sequence number. */
3567         sc->bce_fw_wr_seq++;
3568         msg_data |= sc->bce_fw_wr_seq;
3569
3570         DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "bce_fw_sync(): msg_data = "
3571             "0x%08X\n", msg_data);
3572
3573         /* Send the message to the bootcode driver mailbox. */
3574         bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
3575
3576         /* Wait for the bootcode to acknowledge the message. */
3577         for (i = 0; i < FW_ACK_TIME_OUT_MS; i++) {
3578                 /* Check for a response in the bootcode firmware mailbox. */
3579                 val = bce_shmem_rd(sc, BCE_FW_MB);
3580                 if ((val & BCE_FW_MSG_ACK) == (msg_data & BCE_DRV_MSG_SEQ))
3581                         break;
3582                 DELAY(1000);
3583         }
3584
3585         /* If we've timed out, tell the bootcode that we've stopped waiting. */
3586         if (((val & BCE_FW_MSG_ACK) != (msg_data & BCE_DRV_MSG_SEQ)) &&
3587             ((msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0)) {
3588
3589                 BCE_PRINTF("%s(%d): Firmware synchronization timeout! "
3590                     "msg_data = 0x%08X\n", __FILE__, __LINE__, msg_data);
3591
3592                 msg_data &= ~BCE_DRV_MSG_CODE;
3593                 msg_data |= BCE_DRV_MSG_CODE_FW_TIMEOUT;
3594
3595                 bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
3596
3597                 sc->bce_fw_timed_out = TRUE;
3598                 rc = EBUSY;
3599         }
3600
3601 bce_fw_sync_exit:
3602         DBEXIT(BCE_VERBOSE_RESET);
3603         return (rc);
3604 }
3605
3606
3607 /****************************************************************************/
3608 /* Load Receive Virtual 2 Physical (RV2P) processor firmware.               */
3609 /*                                                                          */
3610 /* Returns:                                                                 */
3611 /*   Nothing.                                                               */
3612 /****************************************************************************/
3613 static void
3614 bce_load_rv2p_fw(struct bce_softc *sc, u32 *rv2p_code,
3615         u32 rv2p_code_len, u32 rv2p_proc)
3616 {
3617         int i;
3618         u32 val;
3619
3620         DBENTER(BCE_VERBOSE_RESET);
3621
3622         /* Set the page size used by RV2P. */
3623         if (rv2p_proc == RV2P_PROC2) {
3624                 BCE_RV2P_PROC2_CHG_MAX_BD_PAGE(USABLE_RX_BD_PER_PAGE);
3625         }
3626
3627         for (i = 0; i < rv2p_code_len; i += 8) {
3628                 REG_WR(sc, BCE_RV2P_INSTR_HIGH, *rv2p_code);
3629                 rv2p_code++;
3630                 REG_WR(sc, BCE_RV2P_INSTR_LOW, *rv2p_code);
3631                 rv2p_code++;
3632
3633                 if (rv2p_proc == RV2P_PROC1) {
3634                         val = (i / 8) | BCE_RV2P_PROC1_ADDR_CMD_RDWR;
3635                         REG_WR(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
3636                 }
3637                 else {
3638                         val = (i / 8) | BCE_RV2P_PROC2_ADDR_CMD_RDWR;
3639                         REG_WR(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
3640                 }
3641         }
3642
3643         /* Reset the processor, un-stall is done later. */
3644         if (rv2p_proc == RV2P_PROC1) {
3645                 REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC1_RESET);
3646         }
3647         else {
3648                 REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC2_RESET);
3649         }
3650
3651         DBEXIT(BCE_VERBOSE_RESET);
3652 }
3653
3654
3655 /****************************************************************************/
3656 /* Load RISC processor firmware.                                            */
3657 /*                                                                          */
3658 /* Loads firmware from the file if_bcefw.h into the scratchpad memory       */
3659 /* associated with a particular processor.                                  */
3660 /*                                                                          */
3661 /* Returns:                                                                 */
3662 /*   Nothing.                                                               */
3663 /****************************************************************************/
3664 static void
3665 bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
3666         struct fw_info *fw)
3667 {
3668         u32 offset;
3669
3670         DBENTER(BCE_VERBOSE_RESET);
3671
3672     bce_halt_cpu(sc, cpu_reg);
3673
3674         /* Load the Text area. */
3675         offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
3676         if (fw->text) {
3677                 int j;
3678
3679                 for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
3680                         REG_WR_IND(sc, offset, fw->text[j]);
3681                 }
3682         }
3683
3684         /* Load the Data area. */
3685         offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
3686         if (fw->data) {
3687                 int j;
3688
3689                 for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
3690                         REG_WR_IND(sc, offset, fw->data[j]);
3691                 }
3692         }
3693
3694         /* Load the SBSS area. */
3695         offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
3696         if (fw->sbss) {
3697                 int j;
3698
3699                 for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
3700                         REG_WR_IND(sc, offset, fw->sbss[j]);
3701                 }
3702         }
3703
3704         /* Load the BSS area. */
3705         offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
3706         if (fw->bss) {
3707                 int j;
3708
3709                 for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
3710                         REG_WR_IND(sc, offset, fw->bss[j]);
3711                 }
3712         }
3713
3714         /* Load the Read-Only area. */
3715         offset = cpu_reg->spad_base +
3716                 (fw->rodata_addr - cpu_reg->mips_view_base);
3717         if (fw->rodata) {
3718                 int j;
3719
3720                 for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
3721                         REG_WR_IND(sc, offset, fw->rodata[j]);
3722                 }
3723         }
3724
3725         /* Clear the pre-fetch instruction and set the FW start address. */
3726         REG_WR_IND(sc, cpu_reg->inst, 0);
3727         REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
3728
3729         DBEXIT(BCE_VERBOSE_RESET);
3730 }
3731
3732
3733 /****************************************************************************/
3734 /* Starts the RISC processor.                                               */
3735 /*                                                                          */
3736 /* Assumes the CPU starting address has already been set.                   */
3737 /*                                                                          */
3738 /* Returns:                                                                 */
3739 /*   Nothing.                                                               */
3740 /****************************************************************************/
3741 static void
3742 bce_start_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
3743 {
3744         u32 val;
3745
3746         DBENTER(BCE_VERBOSE_RESET);
3747
3748         /* Start the CPU. */
3749         val = REG_RD_IND(sc, cpu_reg->mode);
3750         val &= ~cpu_reg->mode_value_halt;
3751         REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
3752         REG_WR_IND(sc, cpu_reg->mode, val);
3753
3754         DBEXIT(BCE_VERBOSE_RESET);
3755 }
3756
3757
3758 /****************************************************************************/
3759 /* Halts the RISC processor.                                                */
3760 /*                                                                          */
3761 /* Returns:                                                                 */
3762 /*   Nothing.                                                               */
3763 /****************************************************************************/
3764 static void
3765 bce_halt_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
3766 {
3767         u32 val;
3768
3769         DBENTER(BCE_VERBOSE_RESET);
3770
3771         /* Halt the CPU. */
3772         val = REG_RD_IND(sc, cpu_reg->mode);
3773         val |= cpu_reg->mode_value_halt;
3774         REG_WR_IND(sc, cpu_reg->mode, val);
3775         REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
3776
3777         DBEXIT(BCE_VERBOSE_RESET);
3778 }
3779
3780
3781 /****************************************************************************/
3782 /* Initialize the RX CPU.                                                   */
3783 /*                                                                          */
3784 /* Returns:                                                                 */
3785 /*   Nothing.                                                               */
3786 /****************************************************************************/
3787 static void
3788 bce_start_rxp_cpu(struct bce_softc *sc)
3789 {
3790         struct cpu_reg cpu_reg;
3791
3792         DBENTER(BCE_VERBOSE_RESET);
3793
3794         cpu_reg.mode = BCE_RXP_CPU_MODE;
3795         cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
3796         cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
3797         cpu_reg.state = BCE_RXP_CPU_STATE;
3798         cpu_reg.state_value_clear = 0xffffff;
3799         cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
3800         cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
3801         cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
3802         cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
3803         cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
3804         cpu_reg.spad_base = BCE_RXP_SCRATCH;
3805         cpu_reg.mips_view_base = 0x8000000;
3806
3807         DBPRINT(sc, BCE_INFO_RESET, "Starting RX firmware.\n");
3808         bce_start_cpu(sc, &cpu_reg);
3809
3810         DBEXIT(BCE_VERBOSE_RESET);
3811 }
3812
3813
3814 /****************************************************************************/
3815 /* Initialize the RX CPU.                                                   */
3816 /*                                                                          */
3817 /* Returns:                                                                 */
3818 /*   Nothing.                                                               */
3819 /****************************************************************************/
3820 static void
3821 bce_init_rxp_cpu(struct bce_softc *sc)
3822 {
3823         struct cpu_reg cpu_reg;
3824         struct fw_info fw;
3825
3826         DBENTER(BCE_VERBOSE_RESET);
3827
3828         cpu_reg.mode = BCE_RXP_CPU_MODE;
3829         cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
3830         cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
3831         cpu_reg.state = BCE_RXP_CPU_STATE;
3832         cpu_reg.state_value_clear = 0xffffff;
3833         cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
3834         cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
3835         cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
3836         cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
3837         cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
3838         cpu_reg.spad_base = BCE_RXP_SCRATCH;
3839         cpu_reg.mips_view_base = 0x8000000;
3840
3841         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3842                 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3843                 fw.ver_major = bce_RXP_b09FwReleaseMajor;
3844                 fw.ver_minor = bce_RXP_b09FwReleaseMinor;
3845                 fw.ver_fix = bce_RXP_b09FwReleaseFix;
3846                 fw.start_addr = bce_RXP_b09FwStartAddr;
3847
3848                 fw.text_addr = bce_RXP_b09FwTextAddr;
3849                 fw.text_len = bce_RXP_b09FwTextLen;
3850                 fw.text_index = 0;
3851                 fw.text = bce_RXP_b09FwText;
3852
3853                 fw.data_addr = bce_RXP_b09FwDataAddr;
3854                 fw.data_len = bce_RXP_b09FwDataLen;
3855                 fw.data_index = 0;
3856                 fw.data = bce_RXP_b09FwData;
3857
3858                 fw.sbss_addr = bce_RXP_b09FwSbssAddr;
3859                 fw.sbss_len = bce_RXP_b09FwSbssLen;
3860                 fw.sbss_index = 0;
3861                 fw.sbss = bce_RXP_b09FwSbss;
3862
3863                 fw.bss_addr = bce_RXP_b09FwBssAddr;
3864                 fw.bss_len = bce_RXP_b09FwBssLen;
3865                 fw.bss_index = 0;
3866                 fw.bss = bce_RXP_b09FwBss;
3867
3868                 fw.rodata_addr = bce_RXP_b09FwRodataAddr;
3869                 fw.rodata_len = bce_RXP_b09FwRodataLen;
3870                 fw.rodata_index = 0;
3871                 fw.rodata = bce_RXP_b09FwRodata;
3872         } else {
3873                 fw.ver_major = bce_RXP_b06FwReleaseMajor;
3874                 fw.ver_minor = bce_RXP_b06FwReleaseMinor;
3875                 fw.ver_fix = bce_RXP_b06FwReleaseFix;
3876                 fw.start_addr = bce_RXP_b06FwStartAddr;
3877
3878                 fw.text_addr = bce_RXP_b06FwTextAddr;
3879                 fw.text_len = bce_RXP_b06FwTextLen;
3880                 fw.text_index = 0;
3881                 fw.text = bce_RXP_b06FwText;
3882
3883                 fw.data_addr = bce_RXP_b06FwDataAddr;
3884                 fw.data_len = bce_RXP_b06FwDataLen;
3885                 fw.data_index = 0;
3886                 fw.data = bce_RXP_b06FwData;
3887
3888                 fw.sbss_addr = bce_RXP_b06FwSbssAddr;
3889                 fw.sbss_len = bce_RXP_b06FwSbssLen;
3890                 fw.sbss_index = 0;
3891                 fw.sbss = bce_RXP_b06FwSbss;
3892
3893                 fw.bss_addr = bce_RXP_b06FwBssAddr;
3894                 fw.bss_len = bce_RXP_b06FwBssLen;
3895                 fw.bss_index = 0;
3896                 fw.bss = bce_RXP_b06FwBss;
3897
3898                 fw.rodata_addr = bce_RXP_b06FwRodataAddr;
3899                 fw.rodata_len = bce_RXP_b06FwRodataLen;
3900                 fw.rodata_index = 0;
3901                 fw.rodata = bce_RXP_b06FwRodata;
3902         }
3903
3904         DBPRINT(sc, BCE_INFO_RESET, "Loading RX firmware.\n");
3905         bce_load_cpu_fw(sc, &cpu_reg, &fw);
3906
3907     /* Delay RXP start until initialization is complete. */
3908
3909         DBEXIT(BCE_VERBOSE_RESET);
3910 }
3911
3912
3913 /****************************************************************************/
3914 /* Initialize the TX CPU.                                                   */
3915 /*                                                                          */
3916 /* Returns:                                                                 */
3917 /*   Nothing.                                                               */
3918 /****************************************************************************/
3919 static void
3920 bce_init_txp_cpu(struct bce_softc *sc)
3921 {
3922         struct cpu_reg cpu_reg;
3923         struct fw_info fw;
3924
3925         DBENTER(BCE_VERBOSE_RESET);
3926
3927         cpu_reg.mode = BCE_TXP_CPU_MODE;
3928         cpu_reg.mode_value_halt = BCE_TXP_CPU_MODE_SOFT_HALT;
3929         cpu_reg.mode_value_sstep = BCE_TXP_CPU_MODE_STEP_ENA;
3930         cpu_reg.state = BCE_TXP_CPU_STATE;
3931         cpu_reg.state_value_clear = 0xffffff;
3932         cpu_reg.gpr0 = BCE_TXP_CPU_REG_FILE;
3933         cpu_reg.evmask = BCE_TXP_CPU_EVENT_MASK;
3934         cpu_reg.pc = BCE_TXP_CPU_PROGRAM_COUNTER;
3935         cpu_reg.inst = BCE_TXP_CPU_INSTRUCTION;
3936         cpu_reg.bp = BCE_TXP_CPU_HW_BREAKPOINT;
3937         cpu_reg.spad_base = BCE_TXP_SCRATCH;
3938         cpu_reg.mips_view_base = 0x8000000;
3939
3940         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3941                 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3942                 fw.ver_major = bce_TXP_b09FwReleaseMajor;
3943                 fw.ver_minor = bce_TXP_b09FwReleaseMinor;
3944                 fw.ver_fix = bce_TXP_b09FwReleaseFix;
3945                 fw.start_addr = bce_TXP_b09FwStartAddr;
3946
3947                 fw.text_addr = bce_TXP_b09FwTextAddr;
3948                 fw.text_len = bce_TXP_b09FwTextLen;
3949                 fw.text_index = 0;
3950                 fw.text = bce_TXP_b09FwText;
3951
3952                 fw.data_addr = bce_TXP_b09FwDataAddr;
3953                 fw.data_len = bce_TXP_b09FwDataLen;
3954                 fw.data_index = 0;
3955                 fw.data = bce_TXP_b09FwData;
3956
3957                 fw.sbss_addr = bce_TXP_b09FwSbssAddr;
3958                 fw.sbss_len = bce_TXP_b09FwSbssLen;
3959                 fw.sbss_index = 0;
3960                 fw.sbss = bce_TXP_b09FwSbss;
3961
3962                 fw.bss_addr = bce_TXP_b09FwBssAddr;
3963                 fw.bss_len = bce_TXP_b09FwBssLen;
3964                 fw.bss_index = 0;
3965                 fw.bss = bce_TXP_b09FwBss;
3966
3967                 fw.rodata_addr = bce_TXP_b09FwRodataAddr;
3968                 fw.rodata_len = bce_TXP_b09FwRodataLen;
3969                 fw.rodata_index = 0;
3970                 fw.rodata = bce_TXP_b09FwRodata;
3971         } else {
3972                 fw.ver_major = bce_TXP_b06FwReleaseMajor;
3973                 fw.ver_minor = bce_TXP_b06FwReleaseMinor;
3974                 fw.ver_fix = bce_TXP_b06FwReleaseFix;
3975                 fw.start_addr = bce_TXP_b06FwStartAddr;
3976
3977                 fw.text_addr = bce_TXP_b06FwTextAddr;
3978                 fw.text_len = bce_TXP_b06FwTextLen;
3979                 fw.text_index = 0;
3980                 fw.text = bce_TXP_b06FwText;
3981
3982                 fw.data_addr = bce_TXP_b06FwDataAddr;
3983                 fw.data_len = bce_TXP_b06FwDataLen;
3984                 fw.data_index = 0;
3985                 fw.data = bce_TXP_b06FwData;
3986
3987                 fw.sbss_addr = bce_TXP_b06FwSbssAddr;
3988                 fw.sbss_len = bce_TXP_b06FwSbssLen;
3989                 fw.sbss_index = 0;
3990                 fw.sbss = bce_TXP_b06FwSbss;
3991
3992                 fw.bss_addr = bce_TXP_b06FwBssAddr;
3993                 fw.bss_len = bce_TXP_b06FwBssLen;
3994                 fw.bss_index = 0;
3995                 fw.bss = bce_TXP_b06FwBss;
3996
3997                 fw.rodata_addr = bce_TXP_b06FwRodataAddr;
3998                 fw.rodata_len = bce_TXP_b06FwRodataLen;
3999                 fw.rodata_index = 0;
4000                 fw.rodata = bce_TXP_b06FwRodata;
4001         }
4002
4003         DBPRINT(sc, BCE_INFO_RESET, "Loading TX firmware.\n");
4004         bce_load_cpu_fw(sc, &cpu_reg, &fw);
4005     bce_start_cpu(sc, &cpu_reg);
4006
4007         DBEXIT(BCE_VERBOSE_RESET);
4008 }
4009
4010
4011 /****************************************************************************/
4012 /* Initialize the TPAT CPU.                                                 */
4013 /*                                                                          */
4014 /* Returns:                                                                 */
4015 /*   Nothing.                                                               */
4016 /****************************************************************************/
4017 static void
4018 bce_init_tpat_cpu(struct bce_softc *sc)
4019 {
4020         struct cpu_reg cpu_reg;
4021         struct fw_info fw;
4022
4023         DBENTER(BCE_VERBOSE_RESET);
4024
4025         cpu_reg.mode = BCE_TPAT_CPU_MODE;
4026         cpu_reg.mode_value_halt = BCE_TPAT_CPU_MODE_SOFT_HALT;
4027         cpu_reg.mode_value_sstep = BCE_TPAT_CPU_MODE_STEP_ENA;
4028         cpu_reg.state = BCE_TPAT_CPU_STATE;
4029         cpu_reg.state_value_clear = 0xffffff;
4030         cpu_reg.gpr0 = BCE_TPAT_CPU_REG_FILE;
4031         cpu_reg.evmask = BCE_TPAT_CPU_EVENT_MASK;
4032         cpu_reg.pc = BCE_TPAT_CPU_PROGRAM_COUNTER;
4033         cpu_reg.inst = BCE_TPAT_CPU_INSTRUCTION;
4034         cpu_reg.bp = BCE_TPAT_CPU_HW_BREAKPOINT;
4035         cpu_reg.spad_base = BCE_TPAT_SCRATCH;
4036         cpu_reg.mips_view_base = 0x8000000;
4037
4038         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4039                 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4040                 fw.ver_major = bce_TPAT_b09FwReleaseMajor;
4041                 fw.ver_minor = bce_TPAT_b09FwReleaseMinor;
4042                 fw.ver_fix = bce_TPAT_b09FwReleaseFix;
4043                 fw.start_addr = bce_TPAT_b09FwStartAddr;
4044
4045                 fw.text_addr = bce_TPAT_b09FwTextAddr;
4046                 fw.text_len = bce_TPAT_b09FwTextLen;
4047                 fw.text_index = 0;
4048                 fw.text = bce_TPAT_b09FwText;
4049
4050                 fw.data_addr = bce_TPAT_b09FwDataAddr;
4051                 fw.data_len = bce_TPAT_b09FwDataLen;
4052                 fw.data_index = 0;
4053                 fw.data = bce_TPAT_b09FwData;
4054
4055                 fw.sbss_addr = bce_TPAT_b09FwSbssAddr;
4056                 fw.sbss_len = bce_TPAT_b09FwSbssLen;
4057                 fw.sbss_index = 0;
4058                 fw.sbss = bce_TPAT_b09FwSbss;
4059
4060                 fw.bss_addr = bce_TPAT_b09FwBssAddr;
4061                 fw.bss_len = bce_TPAT_b09FwBssLen;
4062                 fw.bss_index = 0;
4063                 fw.bss = bce_TPAT_b09FwBss;
4064
4065                 fw.rodata_addr = bce_TPAT_b09FwRodataAddr;
4066                 fw.rodata_len = bce_TPAT_b09FwRodataLen;
4067                 fw.rodata_index = 0;
4068                 fw.rodata = bce_TPAT_b09FwRodata;
4069         } else {
4070                 fw.ver_major = bce_TPAT_b06FwReleaseMajor;
4071                 fw.ver_minor = bce_TPAT_b06FwReleaseMinor;
4072                 fw.ver_fix = bce_TPAT_b06FwReleaseFix;
4073                 fw.start_addr = bce_TPAT_b06FwStartAddr;
4074
4075                 fw.text_addr = bce_TPAT_b06FwTextAddr;
4076                 fw.text_len = bce_TPAT_b06FwTextLen;
4077                 fw.text_index = 0;
4078                 fw.text = bce_TPAT_b06FwText;
4079
4080                 fw.data_addr = bce_TPAT_b06FwDataAddr;
4081                 fw.data_len = bce_TPAT_b06FwDataLen;
4082                 fw.data_index = 0;
4083                 fw.data = bce_TPAT_b06FwData;
4084
4085                 fw.sbss_addr = bce_TPAT_b06FwSbssAddr;
4086                 fw.sbss_len = bce_TPAT_b06FwSbssLen;
4087                 fw.sbss_index = 0;
4088                 fw.sbss = bce_TPAT_b06FwSbss;
4089
4090                 fw.bss_addr = bce_TPAT_b06FwBssAddr;
4091                 fw.bss_len = bce_TPAT_b06FwBssLen;
4092                 fw.bss_index = 0;
4093                 fw.bss = bce_TPAT_b06FwBss;
4094
4095                 fw.rodata_addr = bce_TPAT_b06FwRodataAddr;
4096                 fw.rodata_len = bce_TPAT_b06FwRodataLen;
4097                 fw.rodata_index = 0;
4098                 fw.rodata = bce_TPAT_b06FwRodata;
4099         }
4100
4101         DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n");
4102         bce_load_cpu_fw(sc, &cpu_reg, &fw);
4103         bce_start_cpu(sc, &cpu_reg);
4104
4105         DBEXIT(BCE_VERBOSE_RESET);
4106 }
4107
4108
4109 /****************************************************************************/
4110 /* Initialize the CP CPU.                                                   */
4111 /*                                                                          */
4112 /* Returns:                                                                 */
4113 /*   Nothing.                                                               */
4114 /****************************************************************************/
4115 static void
4116 bce_init_cp_cpu(struct bce_softc *sc)
4117 {
4118         struct cpu_reg cpu_reg;
4119         struct fw_info fw;
4120
4121         DBENTER(BCE_VERBOSE_RESET);
4122
4123         cpu_reg.mode = BCE_CP_CPU_MODE;
4124         cpu_reg.mode_value_halt = BCE_CP_CPU_MODE_SOFT_HALT;
4125         cpu_reg.mode_value_sstep = BCE_CP_CPU_MODE_STEP_ENA;
4126         cpu_reg.state = BCE_CP_CPU_STATE;
4127         cpu_reg.state_value_clear = 0xffffff;
4128         cpu_reg.gpr0 = BCE_CP_CPU_REG_FILE;
4129         cpu_reg.evmask = BCE_CP_CPU_EVENT_MASK;
4130         cpu_reg.pc = BCE_CP_CPU_PROGRAM_COUNTER;
4131         cpu_reg.inst = BCE_CP_CPU_INSTRUCTION;
4132         cpu_reg.bp = BCE_CP_CPU_HW_BREAKPOINT;
4133         cpu_reg.spad_base = BCE_CP_SCRATCH;
4134         cpu_reg.mips_view_base = 0x8000000;
4135
4136         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4137                 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4138                 fw.ver_major = bce_CP_b09FwReleaseMajor;
4139                 fw.ver_minor = bce_CP_b09FwReleaseMinor;
4140                 fw.ver_fix = bce_CP_b09FwReleaseFix;
4141                 fw.start_addr = bce_CP_b09FwStartAddr;
4142
4143                 fw.text_addr = bce_CP_b09FwTextAddr;
4144                 fw.text_len = bce_CP_b09FwTextLen;
4145                 fw.text_index = 0;
4146                 fw.text = bce_CP_b09FwText;
4147
4148                 fw.data_addr = bce_CP_b09FwDataAddr;
4149                 fw.data_len = bce_CP_b09FwDataLen;
4150                 fw.data_index = 0;
4151                 fw.data = bce_CP_b09FwData;
4152
4153                 fw.sbss_addr = bce_CP_b09FwSbssAddr;
4154                 fw.sbss_len = bce_CP_b09FwSbssLen;
4155                 fw.sbss_index = 0;
4156                 fw.sbss = bce_CP_b09FwSbss;
4157
4158                 fw.bss_addr = bce_CP_b09FwBssAddr;
4159                 fw.bss_len = bce_CP_b09FwBssLen;
4160                 fw.bss_index = 0;
4161                 fw.bss = bce_CP_b09FwBss;
4162
4163                 fw.rodata_addr = bce_CP_b09FwRodataAddr;
4164                 fw.rodata_len = bce_CP_b09FwRodataLen;
4165                 fw.rodata_index = 0;
4166                 fw.rodata = bce_CP_b09FwRodata;
4167         } else {
4168                 fw.ver_major = bce_CP_b06FwReleaseMajor;
4169                 fw.ver_minor = bce_CP_b06FwReleaseMinor;
4170                 fw.ver_fix = bce_CP_b06FwReleaseFix;
4171                 fw.start_addr = bce_CP_b06FwStartAddr;
4172
4173                 fw.text_addr = bce_CP_b06FwTextAddr;
4174                 fw.text_len = bce_CP_b06FwTextLen;
4175                 fw.text_index = 0;
4176                 fw.text = bce_CP_b06FwText;
4177
4178                 fw.data_addr = bce_CP_b06FwDataAddr;
4179                 fw.data_len = bce_CP_b06FwDataLen;
4180                 fw.data_index = 0;
4181                 fw.data = bce_CP_b06FwData;
4182
4183                 fw.sbss_addr = bce_CP_b06FwSbssAddr;
4184                 fw.sbss_len = bce_CP_b06FwSbssLen;
4185                 fw.sbss_index = 0;
4186                 fw.sbss = bce_CP_b06FwSbss;
4187
4188                 fw.bss_addr = bce_CP_b06FwBssAddr;
4189                 fw.bss_len = bce_CP_b06FwBssLen;
4190                 fw.bss_index = 0;
4191                 fw.bss = bce_CP_b06FwBss;
4192
4193                 fw.rodata_addr = bce_CP_b06FwRodataAddr;
4194                 fw.rodata_len = bce_CP_b06FwRodataLen;
4195                 fw.rodata_index = 0;
4196                 fw.rodata = bce_CP_b06FwRodata;
4197         }
4198
4199         DBPRINT(sc, BCE_INFO_RESET, "Loading CP firmware.\n");
4200         bce_load_cpu_fw(sc, &cpu_reg, &fw);
4201         bce_start_cpu(sc, &cpu_reg);
4202
4203         DBEXIT(BCE_VERBOSE_RESET);
4204 }
4205
4206
4207 /****************************************************************************/
4208 /* Initialize the COM CPU.                                                 */
4209 /*                                                                          */
4210 /* Returns:                                                                 */
4211 /*   Nothing.                                                               */
4212 /****************************************************************************/
4213 static void
4214 bce_init_com_cpu(struct bce_softc *sc)
4215 {
4216         struct cpu_reg cpu_reg;
4217         struct fw_info fw;
4218
4219         DBENTER(BCE_VERBOSE_RESET);
4220
4221         cpu_reg.mode = BCE_COM_CPU_MODE;
4222         cpu_reg.mode_value_halt = BCE_COM_CPU_MODE_SOFT_HALT;
4223         cpu_reg.mode_value_sstep = BCE_COM_CPU_MODE_STEP_ENA;
4224         cpu_reg.state = BCE_COM_CPU_STATE;
4225         cpu_reg.state_value_clear = 0xffffff;
4226         cpu_reg.gpr0 = BCE_COM_CPU_REG_FILE;
4227         cpu_reg.evmask = BCE_COM_CPU_EVENT_MASK;
4228         cpu_reg.pc = BCE_COM_CPU_PROGRAM_COUNTER;
4229         cpu_reg.inst = BCE_COM_CPU_INSTRUCTION;
4230         cpu_reg.bp = BCE_COM_CPU_HW_BREAKPOINT;
4231         cpu_reg.spad_base = BCE_COM_SCRATCH;
4232         cpu_reg.mips_view_base = 0x8000000;
4233
4234         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4235                 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4236                 fw.ver_major = bce_COM_b09FwReleaseMajor;
4237                 fw.ver_minor = bce_COM_b09FwReleaseMinor;
4238                 fw.ver_fix = bce_COM_b09FwReleaseFix;
4239                 fw.start_addr = bce_COM_b09FwStartAddr;
4240
4241                 fw.text_addr = bce_COM_b09FwTextAddr;
4242                 fw.text_len = bce_COM_b09FwTextLen;
4243                 fw.text_index = 0;
4244                 fw.text = bce_COM_b09FwText;
4245
4246                 fw.data_addr = bce_COM_b09FwDataAddr;
4247                 fw.data_len = bce_COM_b09FwDataLen;
4248                 fw.data_index = 0;
4249                 fw.data = bce_COM_b09FwData;
4250
4251                 fw.sbss_addr = bce_COM_b09FwSbssAddr;
4252                 fw.sbss_len = bce_COM_b09FwSbssLen;
4253                 fw.sbss_index = 0;
4254                 fw.sbss = bce_COM_b09FwSbss;
4255
4256                 fw.bss_addr = bce_COM_b09FwBssAddr;
4257                 fw.bss_len = bce_COM_b09FwBssLen;
4258                 fw.bss_index = 0;
4259                 fw.bss = bce_COM_b09FwBss;
4260
4261                 fw.rodata_addr = bce_COM_b09FwRodataAddr;
4262                 fw.rodata_len = bce_COM_b09FwRodataLen;
4263                 fw.rodata_index = 0;
4264                 fw.rodata = bce_COM_b09FwRodata;
4265         } else {
4266                 fw.ver_major = bce_COM_b06FwReleaseMajor;
4267                 fw.ver_minor = bce_COM_b06FwReleaseMinor;
4268                 fw.ver_fix = bce_COM_b06FwReleaseFix;
4269                 fw.start_addr = bce_COM_b06FwStartAddr;
4270
4271                 fw.text_addr = bce_COM_b06FwTextAddr;
4272                 fw.text_len = bce_COM_b06FwTextLen;
4273                 fw.text_index = 0;
4274                 fw.text = bce_COM_b06FwText;
4275
4276                 fw.data_addr = bce_COM_b06FwDataAddr;
4277                 fw.data_len = bce_COM_b06FwDataLen;
4278                 fw.data_index = 0;
4279                 fw.data = bce_COM_b06FwData;
4280
4281                 fw.sbss_addr = bce_COM_b06FwSbssAddr;
4282                 fw.sbss_len = bce_COM_b06FwSbssLen;
4283                 fw.sbss_index = 0;
4284                 fw.sbss = bce_COM_b06FwSbss;
4285
4286                 fw.bss_addr = bce_COM_b06FwBssAddr;
4287                 fw.bss_len = bce_COM_b06FwBssLen;
4288                 fw.bss_index = 0;
4289                 fw.bss = bce_COM_b06FwBss;
4290
4291                 fw.rodata_addr = bce_COM_b06FwRodataAddr;
4292                 fw.rodata_len = bce_COM_b06FwRodataLen;
4293                 fw.rodata_index = 0;
4294                 fw.rodata = bce_COM_b06FwRodata;
4295         }
4296
4297         DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n");
4298         bce_load_cpu_fw(sc, &cpu_reg, &fw);
4299         bce_start_cpu(sc, &cpu_reg);
4300
4301         DBEXIT(BCE_VERBOSE_RESET);
4302 }
4303
4304
4305 /****************************************************************************/
4306 /* Initialize the RV2P, RX, TX, TPAT, COM, and CP CPUs.                     */
4307 /*                                                                          */
4308 /* Loads the firmware for each CPU and starts the CPU.                      */
4309 /*                                                                          */
4310 /* Returns:                                                                 */
4311 /*   Nothing.                                                               */
4312 /****************************************************************************/
4313 static void
4314 bce_init_cpus(struct bce_softc *sc)
4315 {
4316         DBENTER(BCE_VERBOSE_RESET);
4317
4318         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4319                 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4320
4321                 if ((BCE_CHIP_REV(sc) == BCE_CHIP_REV_Ax)) {
4322                         bce_load_rv2p_fw(sc, bce_xi90_rv2p_proc1, 
4323                                 sizeof(bce_xi90_rv2p_proc1), RV2P_PROC1);
4324                         bce_load_rv2p_fw(sc, bce_xi90_rv2p_proc2, 
4325                                 sizeof(bce_xi90_rv2p_proc2), RV2P_PROC2);
4326                 } else {
4327                         bce_load_rv2p_fw(sc, bce_xi_rv2p_proc1, 
4328                                 sizeof(bce_xi_rv2p_proc1), RV2P_PROC1);
4329                         bce_load_rv2p_fw(sc, bce_xi_rv2p_proc2, 
4330                                 sizeof(bce_xi_rv2p_proc2), RV2P_PROC2);
4331                 }
4332
4333         } else {
4334                 bce_load_rv2p_fw(sc, bce_rv2p_proc1, 
4335                         sizeof(bce_rv2p_proc1), RV2P_PROC1);
4336                 bce_load_rv2p_fw(sc, bce_rv2p_proc2,
4337                         sizeof(bce_rv2p_proc2), RV2P_PROC2);
4338         }
4339
4340         bce_init_rxp_cpu(sc);
4341         bce_init_txp_cpu(sc);
4342         bce_init_tpat_cpu(sc);
4343         bce_init_com_cpu(sc);
4344         bce_init_cp_cpu(sc);
4345
4346         DBEXIT(BCE_VERBOSE_RESET);
4347 }
4348
4349
4350 /****************************************************************************/
4351 /* Initialize context memory.                                               */
4352 /*                                                                          */
4353 /* Clears the memory associated with each Context ID (CID).                 */
4354 /*                                                                          */
4355 /* Returns:                                                                 */
4356 /*   Nothing.                                                               */
4357 /****************************************************************************/
4358 static void
4359 bce_init_ctx(struct bce_softc *sc)
4360 {
4361
4362         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
4363
4364         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4365             (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4366                 int i, retry_cnt = CTX_INIT_RETRY_COUNT;
4367                 u32 val;
4368
4369                 DBPRINT(sc, BCE_INFO_CTX, "Initializing 5709 context.\n");
4370
4371                 /*
4372                  * BCM5709 context memory may be cached
4373                  * in host memory so prepare the host memory
4374                  * for access.
4375                  */
4376                 val = BCE_CTX_COMMAND_ENABLED | 
4377                     BCE_CTX_COMMAND_MEM_INIT | (1 << 12);
4378                 val |= (BCM_PAGE_BITS - 8) << 16;
4379                 REG_WR(sc, BCE_CTX_COMMAND, val);
4380
4381                 /* Wait for mem init command to complete. */
4382                 for (i = 0; i < retry_cnt; i++) {
4383                         val = REG_RD(sc, BCE_CTX_COMMAND);
4384                         if (!(val & BCE_CTX_COMMAND_MEM_INIT))
4385                                 break;
4386                         DELAY(2);
4387                 }
4388
4389                 /* ToDo: Consider returning an error here. */
4390                 DBRUNIF((val & BCE_CTX_COMMAND_MEM_INIT),
4391                     BCE_PRINTF("%s(): Context memory initialization "
4392                     "failed!\n", __FUNCTION__));
4393
4394                 for (i = 0; i < sc->ctx_pages; i++) {
4395                         int j;
4396
4397                         /* Set the physical address of the context memory. */
4398                         REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA0,
4399                             BCE_ADDR_LO(sc->ctx_paddr[i] & 0xfffffff0) |
4400                             BCE_CTX_HOST_PAGE_TBL_DATA0_VALID);
4401                         REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA1,
4402                             BCE_ADDR_HI(sc->ctx_paddr[i]));
4403                         REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_CTRL, i |
4404                             BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
4405
4406                         /* Verify the context memory write was successful. */
4407                         for (j = 0; j < retry_cnt; j++) {
4408                                 val = REG_RD(sc, BCE_CTX_HOST_PAGE_TBL_CTRL);
4409                                 if ((val & 
4410                                     BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) == 0)
4411                                         break;
4412                                 DELAY(5);
4413                         }
4414
4415                         /* ToDo: Consider returning an error here. */
4416                         DBRUNIF((val & BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ),
4417                             BCE_PRINTF("%s(): Failed to initialize "
4418                             "context page %d!\n", __FUNCTION__, i));
4419                 }
4420         } else {
4421                 u32 vcid_addr, offset;
4422
4423                 DBPRINT(sc, BCE_INFO, "Initializing 5706/5708 context.\n");
4424
4425                 /*
4426                  * For the 5706/5708, context memory is local to
4427                  * the controller, so initialize the controller
4428                  * context memory.
4429                  */
4430
4431                 vcid_addr = GET_CID_ADDR(96);
4432                 while (vcid_addr) {
4433
4434                         vcid_addr -= PHY_CTX_SIZE;
4435
4436                         REG_WR(sc, BCE_CTX_VIRT_ADDR, 0);
4437                         REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
4438
4439                         for(offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
4440                                 CTX_WR(sc, 0x00, offset, 0);
4441                         }
4442
4443                         REG_WR(sc, BCE_CTX_VIRT_ADDR, vcid_addr);
4444                         REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
4445                 }
4446
4447         }
4448         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
4449 }
4450
4451
4452 /****************************************************************************/
4453 /* Fetch the permanent MAC address of the controller.                       */
4454 /*                                                                          */
4455 /* Returns:                                                                 */
4456 /*   Nothing.                                                               */
4457 /****************************************************************************/
4458 static void
4459 bce_get_mac_addr(struct bce_softc *sc)
4460 {
4461         u32 mac_lo = 0, mac_hi = 0;
4462
4463         DBENTER(BCE_VERBOSE_RESET);
4464         /*
4465          * The NetXtreme II bootcode populates various NIC
4466          * power-on and runtime configuration items in a
4467          * shared memory area.  The factory configured MAC
4468          * address is available from both NVRAM and the
4469          * shared memory area so we'll read the value from
4470          * shared memory for speed.
4471          */
4472
4473         mac_hi = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_UPPER);
4474         mac_lo = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_LOWER);
4475
4476         if ((mac_lo == 0) && (mac_hi == 0)) {
4477                 BCE_PRINTF("%s(%d): Invalid Ethernet address!\n",
4478                         __FILE__, __LINE__);
4479         } else {
4480                 sc->eaddr[0] = (u_char)(mac_hi >> 8);
4481                 sc->eaddr[1] = (u_char)(mac_hi >> 0);
4482                 sc->eaddr[2] = (u_char)(mac_lo >> 24);
4483                 sc->eaddr[3] = (u_char)(mac_lo >> 16);
4484                 sc->eaddr[4] = (u_char)(mac_lo >> 8);
4485                 sc->eaddr[5] = (u_char)(mac_lo >> 0);
4486         }
4487
4488         DBPRINT(sc, BCE_INFO_MISC, "Permanent Ethernet address = %6D\n", sc->eaddr, ":");
4489         DBEXIT(BCE_VERBOSE_RESET);
4490 }
4491
4492
4493 /****************************************************************************/
4494 /* Program the MAC address.                                                 */
4495 /*                                                                          */
4496 /* Returns:                                                                 */
4497 /*   Nothing.                                                               */
4498 /****************************************************************************/
4499 static void
4500 bce_set_mac_addr(struct bce_softc *sc)
4501 {
4502         u32 val;
4503         u8 *mac_addr = sc->eaddr;
4504
4505         /* ToDo: Add support for setting multiple MAC addresses. */
4506
4507         DBENTER(BCE_VERBOSE_RESET);
4508         DBPRINT(sc, BCE_INFO_MISC, "Setting Ethernet address = %6D\n", sc->eaddr, ":");
4509
4510         val = (mac_addr[0] << 8) | mac_addr[1];
4511
4512         REG_WR(sc, BCE_EMAC_MAC_MATCH0, val);
4513
4514         val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
4515                 (mac_addr[4] << 8) | mac_addr[5];
4516
4517         REG_WR(sc, BCE_EMAC_MAC_MATCH1, val);
4518
4519         DBEXIT(BCE_VERBOSE_RESET);
4520 }
4521
4522
4523 /****************************************************************************/
4524 /* Stop the controller.                                                     */
4525 /*                                                                          */
4526 /* Returns:                                                                 */
4527 /*   Nothing.                                                               */
4528 /****************************************************************************/
4529 static void
4530 bce_stop(struct bce_softc *sc)
4531 {
4532         struct ifnet *ifp;
4533         struct ifmedia_entry *ifm;
4534         struct mii_data *mii = NULL;
4535         int mtmp, itmp;
4536
4537         DBENTER(BCE_VERBOSE_RESET);
4538
4539         BCE_LOCK_ASSERT(sc);
4540
4541         ifp = sc->bce_ifp;
4542
4543         mii = device_get_softc(sc->bce_miibus);
4544
4545         callout_stop(&sc->bce_tick_callout);
4546
4547         /* Disable the transmit/receive blocks. */
4548         REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS, BCE_MISC_ENABLE_CLR_DEFAULT);
4549         REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
4550         DELAY(20);
4551
4552         bce_disable_intr(sc);
4553
4554         /* Free RX buffers. */
4555 #ifdef BCE_JUMBO_HDRSPLIT
4556         bce_free_pg_chain(sc);
4557 #endif
4558         bce_free_rx_chain(sc);
4559
4560         /* Free TX buffers. */
4561         bce_free_tx_chain(sc);
4562
4563         /*
4564          * Isolate/power down the PHY, but leave the media selection
4565          * unchanged so that things will be put back to normal when
4566          * we bring the interface back up.
4567          */
4568
4569         itmp = ifp->if_flags;
4570         ifp->if_flags |= IFF_UP;
4571
4572         /* If we are called from bce_detach(), mii is already NULL. */
4573         if (mii != NULL) {
4574                 ifm = mii->mii_media.ifm_cur;
4575                 mtmp = ifm->ifm_media;
4576                 ifm->ifm_media = IFM_ETHER | IFM_NONE;
4577                 mii_mediachg(mii);
4578                 ifm->ifm_media = mtmp;
4579         }
4580
4581         ifp->if_flags = itmp;
4582         sc->watchdog_timer = 0;
4583
4584         sc->bce_link_up = FALSE;
4585
4586         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
4587
4588         DBEXIT(BCE_VERBOSE_RESET);
4589 }
4590
4591
4592 static int
4593 bce_reset(struct bce_softc *sc, u32 reset_code)
4594 {
4595         u32 val;
4596         int i, rc = 0;
4597
4598         DBENTER(BCE_VERBOSE_RESET);
4599
4600         DBPRINT(sc, BCE_VERBOSE_RESET, "%s(): reset_code = 0x%08X\n",
4601                 __FUNCTION__, reset_code);
4602
4603         /* Wait for pending PCI transactions to complete. */
4604         REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS,
4605                BCE_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
4606                BCE_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
4607                BCE_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
4608                BCE_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
4609         val = REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
4610         DELAY(5);
4611
4612         /* Disable DMA */
4613         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4614                 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4615                 val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
4616                 val &= ~BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
4617                 REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
4618         }
4619
4620         /* Assume bootcode is running. */
4621         sc->bce_fw_timed_out = FALSE;
4622         sc->bce_drv_cardiac_arrest = FALSE;
4623
4624         /* Give the firmware a chance to prepare for the reset. */
4625         rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT0 | reset_code);
4626         if (rc)
4627                 goto bce_reset_exit;
4628
4629         /* Set a firmware reminder that this is a soft reset. */
4630         bce_shmem_wr(sc, BCE_DRV_RESET_SIGNATURE, BCE_DRV_RESET_SIGNATURE_MAGIC);
4631
4632         /* Dummy read to force the chip to complete all current transactions. */
4633         val = REG_RD(sc, BCE_MISC_ID);
4634
4635         /* Chip reset. */
4636         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4637                 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4638                 REG_WR(sc, BCE_MISC_COMMAND, BCE_MISC_COMMAND_SW_RESET);
4639                 REG_RD(sc, BCE_MISC_COMMAND);
4640                 DELAY(5);
4641
4642                 val = BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
4643                       BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
4644
4645                 pci_write_config(sc->bce_dev, BCE_PCICFG_MISC_CONFIG, val, 4);
4646         } else {
4647                 val = BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4648                         BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
4649                         BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
4650                 REG_WR(sc, BCE_PCICFG_MISC_CONFIG, val);
4651
4652                 /* Allow up to 30us for reset to complete. */
4653                 for (i = 0; i < 10; i++) {
4654                         val = REG_RD(sc, BCE_PCICFG_MISC_CONFIG);
4655                         if ((val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4656                                 BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
4657                                 break;
4658                         }
4659                         DELAY(10);
4660                 }
4661
4662                 /* Check that reset completed successfully. */
4663                 if (val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4664                         BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
4665                         BCE_PRINTF("%s(%d): Reset failed!\n",
4666                                 __FILE__, __LINE__);
4667                         rc = EBUSY;
4668                         goto bce_reset_exit;
4669                 }
4670         }
4671
4672         /* Make sure byte swapping is properly configured. */
4673         val = REG_RD(sc, BCE_PCI_SWAP_DIAG0);
4674         if (val != 0x01020304) {
4675                 BCE_PRINTF("%s(%d): Byte swap is incorrect!\n",
4676                         __FILE__, __LINE__);
4677                 rc = ENODEV;
4678                 goto bce_reset_exit;
4679         }
4680
4681         /* Just completed a reset, assume that firmware is running again. */
4682         sc->bce_fw_timed_out = FALSE;
4683         sc->bce_drv_cardiac_arrest = FALSE;
4684
4685         /* Wait for the firmware to finish its initialization. */
4686         rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT1 | reset_code);
4687         if (rc)
4688                 BCE_PRINTF("%s(%d): Firmware did not complete initialization!\n",
4689                         __FILE__, __LINE__);
4690
4691 bce_reset_exit:
4692         DBEXIT(BCE_VERBOSE_RESET);
4693         return (rc);
4694 }
4695
4696
4697 static int
4698 bce_chipinit(struct bce_softc *sc)
4699 {
4700         u32 val;
4701         int rc = 0;
4702
4703         DBENTER(BCE_VERBOSE_RESET);
4704
4705         bce_disable_intr(sc);
4706
4707         /*
4708          * Initialize DMA byte/word swapping, configure the number of DMA
4709          * channels and PCI clock compensation delay.
4710          */
4711         val = BCE_DMA_CONFIG_DATA_BYTE_SWAP |
4712               BCE_DMA_CONFIG_DATA_WORD_SWAP |
4713 #if BYTE_ORDER == BIG_ENDIAN
4714               BCE_DMA_CONFIG_CNTL_BYTE_SWAP |
4715 #endif
4716               BCE_DMA_CONFIG_CNTL_WORD_SWAP |
4717               DMA_READ_CHANS << 12 |
4718               DMA_WRITE_CHANS << 16;
4719
4720         val |= (0x2 << 20) | BCE_DMA_CONFIG_CNTL_PCI_COMP_DLY;
4721
4722         if ((sc->bce_flags & BCE_PCIX_FLAG) && (sc->bus_speed_mhz == 133))
4723                 val |= BCE_DMA_CONFIG_PCI_FAST_CLK_CMP;
4724
4725         /*
4726          * This setting resolves a problem observed on certain Intel PCI
4727          * chipsets that cannot handle multiple outstanding DMA operations.
4728          * See errata E9_5706A1_65.
4729          */
4730         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
4731             (BCE_CHIP_ID(sc) != BCE_CHIP_ID_5706_A0) &&
4732             !(sc->bce_flags & BCE_PCIX_FLAG))
4733                 val |= BCE_DMA_CONFIG_CNTL_PING_PONG_DMA;
4734
4735         REG_WR(sc, BCE_DMA_CONFIG, val);
4736
4737         /* Enable the RX_V2P and Context state machines before access. */
4738         REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
4739             BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
4740             BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
4741             BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
4742
4743         /* Initialize context mapping and zero out the quick contexts. */
4744         bce_init_ctx(sc);
4745
4746         /* Initialize the on-boards CPUs */
4747         bce_init_cpus(sc);
4748
4749         /* Enable management frames (NC-SI) to flow to the MCP. */
4750         if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
4751                 val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) | BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
4752                 REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
4753         }
4754
4755         /* Prepare NVRAM for access. */
4756         if (bce_init_nvram(sc)) {
4757                 rc = ENODEV;
4758                 goto bce_chipinit_exit;
4759         }
4760
4761         /* Set the kernel bypass block size */
4762         val = REG_RD(sc, BCE_MQ_CONFIG);
4763         val &= ~BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE;
4764         val |= BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
4765
4766         /* Enable bins used on the 5709. */
4767         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4768                 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4769                 val |= BCE_MQ_CONFIG_BIN_MQ_MODE;
4770                 if (BCE_CHIP_ID(sc) == BCE_CHIP_ID_5709_A1)
4771                         val |= BCE_MQ_CONFIG_HALT_DIS;
4772         }
4773
4774         REG_WR(sc, BCE_MQ_CONFIG, val);
4775
4776         val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
4777         REG_WR(sc, BCE_MQ_KNL_BYP_WIND_START, val);
4778         REG_WR(sc, BCE_MQ_KNL_WIND_END, val);
4779
4780         /* Set the page size and clear the RV2P processor stall bits. */
4781         val = (BCM_PAGE_BITS - 8) << 24;
4782         REG_WR(sc, BCE_RV2P_CONFIG, val);
4783
4784         /* Configure page size. */
4785         val = REG_RD(sc, BCE_TBDR_CONFIG);
4786         val &= ~BCE_TBDR_CONFIG_PAGE_SIZE;
4787         val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
4788         REG_WR(sc, BCE_TBDR_CONFIG, val);
4789
4790         /* Set the perfect match control register to default. */
4791         REG_WR_IND(sc, BCE_RXP_PM_CTRL, 0);
4792
4793 bce_chipinit_exit:
4794         DBEXIT(BCE_VERBOSE_RESET);
4795
4796         return(rc);
4797 }
4798
4799
4800 /****************************************************************************/
4801 /* Initialize the controller in preparation to send/receive traffic.        */
4802 /*                                                                          */
4803 /* Returns:                                                                 */
4804 /*   0 for success, positive value for failure.                             */
4805 /****************************************************************************/
4806 static int
4807 bce_blockinit(struct bce_softc *sc)
4808 {
4809         u32 reg, val;
4810         int rc = 0;
4811
4812         DBENTER(BCE_VERBOSE_RESET);
4813
4814         /* Load the hardware default MAC address. */
4815         bce_set_mac_addr(sc);
4816
4817         /* Set the Ethernet backoff seed value */
4818         val = sc->eaddr[0]         + (sc->eaddr[1] << 8) +
4819               (sc->eaddr[2] << 16) + (sc->eaddr[3]     ) +
4820               (sc->eaddr[4] << 8)  + (sc->eaddr[5] << 16);
4821         REG_WR(sc, BCE_EMAC_BACKOFF_SEED, val);
4822
4823         sc->last_status_idx = 0;
4824         sc->rx_mode = BCE_EMAC_RX_MODE_SORT_MODE;
4825
4826         /* Set up link change interrupt generation. */
4827         REG_WR(sc, BCE_EMAC_ATTENTION_ENA, BCE_EMAC_ATTENTION_ENA_LINK);
4828
4829         /* Program the physical address of the status block. */
4830         REG_WR(sc, BCE_HC_STATUS_ADDR_L,
4831             BCE_ADDR_LO(sc->status_block_paddr));
4832         REG_WR(sc, BCE_HC_STATUS_ADDR_H,
4833             BCE_ADDR_HI(sc->status_block_paddr));
4834
4835         /* Program the physical address of the statistics block. */
4836         REG_WR(sc, BCE_HC_STATISTICS_ADDR_L,
4837             BCE_ADDR_LO(sc->stats_block_paddr));
4838         REG_WR(sc, BCE_HC_STATISTICS_ADDR_H,
4839             BCE_ADDR_HI(sc->stats_block_paddr));
4840
4841         /* Program various host coalescing parameters. */
4842         REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
4843             (sc->bce_tx_quick_cons_trip_int << 16) | sc->bce_tx_quick_cons_trip);
4844         REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
4845             (sc->bce_rx_quick_cons_trip_int << 16) | sc->bce_rx_quick_cons_trip);
4846         REG_WR(sc, BCE_HC_COMP_PROD_TRIP,
4847             (sc->bce_comp_prod_trip_int << 16) | sc->bce_comp_prod_trip);
4848         REG_WR(sc, BCE_HC_TX_TICKS,
4849             (sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
4850         REG_WR(sc, BCE_HC_RX_TICKS,
4851             (sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
4852         REG_WR(sc, BCE_HC_COM_TICKS,
4853             (sc->bce_com_ticks_int << 16) | sc->bce_com_ticks);
4854         REG_WR(sc, BCE_HC_CMD_TICKS,
4855             (sc->bce_cmd_ticks_int << 16) | sc->bce_cmd_ticks);
4856         REG_WR(sc, BCE_HC_STATS_TICKS,
4857             (sc->bce_stats_ticks & 0xffff00));
4858         REG_WR(sc, BCE_HC_STAT_COLLECT_TICKS, 0xbb8);  /* 3ms */
4859
4860         /* Configure the Host Coalescing block. */
4861         val = BCE_HC_CONFIG_RX_TMR_MODE | BCE_HC_CONFIG_TX_TMR_MODE |
4862             BCE_HC_CONFIG_COLLECT_STATS;
4863
4864 #if 0
4865         /* ToDo: Add MSI-X support. */
4866         if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
4867                 u32 base = ((BCE_TX_VEC - 1) * BCE_HC_SB_CONFIG_SIZE) +
4868                     BCE_HC_SB_CONFIG_1;
4869
4870                 REG_WR(sc, BCE_HC_MSIX_BIT_VECTOR, BCE_HC_MSIX_BIT_VECTOR_VAL);
4871
4872                 REG_WR(sc, base, BCE_HC_SB_CONFIG_1_TX_TMR_MODE |
4873                     BCE_HC_SB_CONFIG_1_ONE_SHOT);
4874
4875                 REG_WR(sc, base + BCE_HC_TX_QUICK_CONS_TRIP_OFF,
4876                     (sc->tx_quick_cons_trip_int << 16) |
4877                      sc->tx_quick_cons_trip);
4878
4879                 REG_WR(sc, base + BCE_HC_TX_TICKS_OFF,
4880                     (sc->tx_ticks_int << 16) | sc->tx_ticks);
4881
4882                 val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
4883         }
4884
4885         /*
4886          * Tell the HC block to automatically set the
4887          * INT_MASK bit after an MSI/MSI-X interrupt
4888          * is generated so the driver doesn't have to.
4889          */
4890         if (sc->bce_flags & BCE_ONE_SHOT_MSI_FLAG)
4891                 val |= BCE_HC_CONFIG_ONE_SHOT;
4892
4893         /* Set the MSI-X status blocks to 128 byte boundaries. */
4894         if (sc->bce_flags & BCE_USING_MSIX_FLAG)
4895                 val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
4896 #endif
4897
4898         REG_WR(sc, BCE_HC_CONFIG, val);
4899
4900         /* Clear the internal statistics counters. */
4901         REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
4902
4903         /* Verify that bootcode is running. */
4904         reg = bce_shmem_rd(sc, BCE_DEV_INFO_SIGNATURE);
4905
4906         DBRUNIF(DB_RANDOMTRUE(bootcode_running_failure_sim_control),
4907             BCE_PRINTF("%s(%d): Simulating bootcode failure.\n",
4908             __FILE__, __LINE__);
4909             reg = 0);
4910
4911         if ((reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
4912             BCE_DEV_INFO_SIGNATURE_MAGIC) {
4913                 BCE_PRINTF("%s(%d): Bootcode not running! Found: 0x%08X, "
4914                     "Expected: 08%08X\n", __FILE__, __LINE__,
4915                     (reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK),
4916                     BCE_DEV_INFO_SIGNATURE_MAGIC);
4917                 rc = ENODEV;
4918                 goto bce_blockinit_exit;
4919         }
4920
4921         /* Enable DMA */
4922         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4923             (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4924                 val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
4925                 val |= BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
4926                 REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
4927         }
4928
4929         /* Allow bootcode to apply additional fixes before enabling MAC. */
4930         rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 | 
4931             BCE_DRV_MSG_CODE_RESET);
4932
4933         /* Enable link state change interrupt generation. */
4934         REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
4935
4936         /* Enable the RXP. */
4937         bce_start_rxp_cpu(sc);
4938
4939         /* Disable management frames (NC-SI) from flowing to the MCP. */
4940         if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
4941                 val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) & 
4942                     ~BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
4943                 REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
4944         }
4945
4946         /* Enable all remaining blocks in the MAC. */
4947         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4948             (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
4949                 REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, 
4950                     BCE_MISC_ENABLE_DEFAULT_XI);
4951         else
4952                 REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, 
4953                     BCE_MISC_ENABLE_DEFAULT);
4954
4955         REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
4956         DELAY(20);
4957
4958         /* Save the current host coalescing block settings. */
4959         sc->hc_command = REG_RD(sc, BCE_HC_COMMAND);
4960
4961 bce_blockinit_exit:
4962         DBEXIT(BCE_VERBOSE_RESET);
4963
4964         return (rc);
4965 }
4966
4967
4968 /****************************************************************************/
4969 /* Encapsulate an mbuf into the rx_bd chain.                                */
4970 /*                                                                          */
4971 /* Returns:                                                                 */
4972 /*   0 for success, positive value for failure.                             */
4973 /****************************************************************************/
4974 static int
4975 bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
4976     u16 *chain_prod, u32 *prod_bseq)
4977 {
4978         bus_dmamap_t map;
4979         bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
4980         struct mbuf *m_new = NULL;
4981         struct rx_bd *rxbd;
4982         int nsegs, error, rc = 0;
4983 #ifdef BCE_DEBUG
4984         u16 debug_chain_prod = *chain_prod;
4985 #endif
4986
4987         DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
4988
4989         /* Make sure the inputs are valid. */
4990         DBRUNIF((*chain_prod > MAX_RX_BD),
4991                 BCE_PRINTF("%s(%d): RX producer out of range: 0x%04X > 0x%04X\n",
4992                 __FILE__, __LINE__, *chain_prod, (u16) MAX_RX_BD));
4993
4994         DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
4995             "chain_prod = 0x%04X, prod_bseq = 0x%08X\n", __FUNCTION__,
4996             *prod, *chain_prod, *prod_bseq);
4997
4998         /* Update some debug statistic counters */
4999         DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
5000                 sc->rx_low_watermark = sc->free_rx_bd);
5001         DBRUNIF((sc->free_rx_bd == sc->max_rx_bd), sc->rx_empty_count++);
5002
5003         /* Check whether this is a new mbuf allocation. */
5004         if (m == NULL) {
5005
5006                 /* Simulate an mbuf allocation failure. */
5007                 DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
5008                     sc->mbuf_alloc_failed_count++;
5009                     sc->mbuf_alloc_failed_sim_count++;
5010                     rc = ENOBUFS;
5011                     goto bce_get_rx_buf_exit);
5012
5013                 /* This is a new mbuf allocation. */
5014 #ifdef BCE_JUMBO_HDRSPLIT
5015                 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
5016 #else
5017                 if (sc->rx_bd_mbuf_alloc_size <= MCLBYTES)
5018                         m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
5019                 else
5020                         m_new = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, 
5021                             sc->rx_bd_mbuf_alloc_size);
5022 #endif
5023
5024                 if (m_new == NULL) {
5025                         sc->mbuf_alloc_failed_count++;
5026                         rc = ENOBUFS;
5027                         goto bce_get_rx_buf_exit;
5028                 }
5029
5030                 DBRUN(sc->debug_rx_mbuf_alloc++);
5031         } else {
5032                 /* Reuse an existing mbuf. */
5033                 m_new = m;
5034         }
5035
5036         /* Make sure we have a valid packet header. */
5037         M_ASSERTPKTHDR(m_new);
5038
5039         /* Initialize the mbuf size and pad if necessary for alignment. */
5040         m_new->m_pkthdr.len = m_new->m_len = sc->rx_bd_mbuf_alloc_size;
5041         m_adj(m_new, sc->rx_bd_mbuf_align_pad);
5042
5043         /* ToDo: Consider calling m_fragment() to test error handling. */
5044
5045         /* Map the mbuf cluster into device memory. */
5046         map = sc->rx_mbuf_map[*chain_prod];
5047         error = bus_dmamap_load_mbuf_sg(sc->rx_mbuf_tag, map, m_new,
5048             segs, &nsegs, BUS_DMA_NOWAIT);
5049
5050         /* Handle any mapping errors. */
5051         if (error) {
5052                 BCE_PRINTF("%s(%d): Error mapping mbuf into RX chain (%d)!\n",
5053                     __FILE__, __LINE__, error);
5054
5055                 sc->dma_map_addr_rx_failed_count++;
5056                 m_freem(m_new);
5057
5058                 DBRUN(sc->debug_rx_mbuf_alloc--);
5059
5060                 rc = ENOBUFS;
5061                 goto bce_get_rx_buf_exit;
5062         }
5063
5064         /* All mbufs must map to a single segment. */
5065         KASSERT(nsegs == 1, ("%s(): Too many segments returned (%d)!",
5066             __FUNCTION__, nsegs));
5067
5068         /* Setup the rx_bd for the segment. */
5069         rxbd = &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
5070
5071         rxbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(segs[0].ds_addr));
5072         rxbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(segs[0].ds_addr));
5073         rxbd->rx_bd_len       = htole32(segs[0].ds_len);
5074         rxbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
5075         *prod_bseq += segs[0].ds_len;
5076
5077         /* Save the mbuf and update our counter. */
5078         sc->rx_mbuf_ptr[*chain_prod] = m_new;
5079         sc->free_rx_bd -= nsegs;
5080
5081         DBRUNMSG(BCE_INSANE_RECV, 
5082             bce_dump_rx_mbuf_chain(sc, debug_chain_prod, nsegs));
5083
5084         DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
5085             "chain_prod = 0x%04X, prod_bseq = 0x%08X\n", 
5086             __FUNCTION__, *prod, *chain_prod, *prod_bseq);
5087
5088 bce_get_rx_buf_exit:
5089         DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5090
5091         return(rc);
5092 }
5093
5094
5095 #ifdef BCE_JUMBO_HDRSPLIT
5096 /****************************************************************************/
5097 /* Encapsulate an mbuf cluster into the page chain.                         */
5098 /*                                                                          */
5099 /* Returns:                                                                 */
5100 /*   0 for success, positive value for failure.                             */
5101 /****************************************************************************/
5102 static int
5103 bce_get_pg_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
5104         u16 *prod_idx)
5105 {
5106         bus_dmamap_t map;
5107         bus_addr_t busaddr;
5108         struct mbuf *m_new = NULL;
5109         struct rx_bd *pgbd;
5110         int error, rc = 0;
5111 #ifdef BCE_DEBUG
5112         u16 debug_prod_idx = *prod_idx;
5113 #endif
5114
5115         DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5116
5117         /* Make sure the inputs are valid. */
5118         DBRUNIF((*prod_idx > MAX_PG_BD),
5119             BCE_PRINTF("%s(%d): page producer out of range: 0x%04X > 0x%04X\n",
5120             __FILE__, __LINE__, *prod_idx, (u16) MAX_PG_BD));
5121
5122         DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
5123             "chain_prod = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
5124
5125         /* Update counters if we've hit a new low or run out of pages. */
5126         DBRUNIF((sc->free_pg_bd < sc->pg_low_watermark),
5127             sc->pg_low_watermark = sc->free_pg_bd);
5128         DBRUNIF((sc->free_pg_bd == sc->max_pg_bd), sc->pg_empty_count++);
5129
5130         /* Check whether this is a new mbuf allocation. */
5131         if (m == NULL) {
5132
5133                 /* Simulate an mbuf allocation failure. */
5134                 DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
5135                     sc->mbuf_alloc_failed_count++;
5136                     sc->mbuf_alloc_failed_sim_count++;
5137                     rc = ENOBUFS;
5138                     goto bce_get_pg_buf_exit);
5139
5140                 /* This is a new mbuf allocation. */
5141                 m_new = m_getcl(M_DONTWAIT, MT_DATA, 0);
5142                 if (m_new == NULL) {
5143                         sc->mbuf_alloc_failed_count++;
5144                         rc = ENOBUFS;
5145                         goto bce_get_pg_buf_exit;
5146                 }
5147
5148                 DBRUN(sc->debug_pg_mbuf_alloc++);
5149         } else {
5150                 /* Reuse an existing mbuf. */
5151                 m_new = m;
5152                 m_new->m_data = m_new->m_ext.ext_buf;
5153         }
5154
5155         m_new->m_len = sc->pg_bd_mbuf_alloc_size;
5156
5157         /* ToDo: Consider calling m_fragment() to test error handling. */
5158
5159         /* Map the mbuf cluster into device memory. */
5160         map = sc->pg_mbuf_map[*prod_idx];
5161         error = bus_dmamap_load(sc->pg_mbuf_tag, map, mtod(m_new, void *),
5162             sc->pg_bd_mbuf_alloc_size, bce_dma_map_addr, 
5163             &busaddr, BUS_DMA_NOWAIT);
5164
5165         /* Handle any mapping errors. */
5166         if (error) {
5167                 BCE_PRINTF("%s(%d): Error mapping mbuf into page chain!\n",
5168                     __FILE__, __LINE__);
5169
5170                 m_freem(m_new);
5171                 DBRUN(sc->debug_pg_mbuf_alloc--);
5172
5173                 rc = ENOBUFS;
5174                 goto bce_get_pg_buf_exit;
5175         }
5176
5177         /* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREREAD) here? */
5178
5179         /*
5180          * The page chain uses the same rx_bd data structure
5181          * as the receive chain but doesn't require a byte sequence (bseq).
5182          */
5183         pgbd = &sc->pg_bd_chain[PG_PAGE(*prod_idx)][PG_IDX(*prod_idx)];
5184
5185         pgbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(busaddr));
5186         pgbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(busaddr));
5187         pgbd->rx_bd_len       = htole32(sc->pg_bd_mbuf_alloc_size);
5188         pgbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
5189
5190         /* Save the mbuf and update our counter. */
5191         sc->pg_mbuf_ptr[*prod_idx] = m_new;
5192         sc->free_pg_bd--;
5193
5194         DBRUNMSG(BCE_INSANE_RECV, 
5195             bce_dump_pg_mbuf_chain(sc, debug_prod_idx, 1));
5196
5197         DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
5198             "prod_idx = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
5199
5200 bce_get_pg_buf_exit:
5201         DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5202
5203         return(rc);
5204 }
5205 #endif /* BCE_JUMBO_HDRSPLIT */
5206
5207
5208 /****************************************************************************/
5209 /* Initialize the TX context memory.                                        */
5210 /*                                                                          */
5211 /* Returns:                                                                 */
5212 /*   Nothing                                                                */
5213 /****************************************************************************/
5214 static void
5215 bce_init_tx_context(struct bce_softc *sc)
5216 {
5217         u32 val;
5218
5219         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
5220
5221         /* Initialize the context ID for an L2 TX chain. */
5222         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
5223                 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
5224                 /* Set the CID type to support an L2 connection. */
5225                 val = BCE_L2CTX_TX_TYPE_TYPE_L2_XI | 
5226                     BCE_L2CTX_TX_TYPE_SIZE_L2_XI;
5227                 CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE_XI, val);
5228                 val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2_XI | (8 << 16);
5229                 CTX_WR(sc, GET_CID_ADDR(TX_CID), 
5230                     BCE_L2CTX_TX_CMD_TYPE_XI, val);
5231
5232                 /* Point the hardware to the first page in the chain. */
5233                 val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
5234                 CTX_WR(sc, GET_CID_ADDR(TX_CID), 
5235                     BCE_L2CTX_TX_TBDR_BHADDR_HI_XI, val);
5236                 val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
5237                 CTX_WR(sc, GET_CID_ADDR(TX_CID), 
5238                     BCE_L2CTX_TX_TBDR_BHADDR_LO_XI, val);
5239         } else {
5240                 /* Set the CID type to support an L2 connection. */
5241                 val = BCE_L2CTX_TX_TYPE_TYPE_L2 | BCE_L2CTX_TX_TYPE_SIZE_L2;
5242                 CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE, val);
5243                 val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2 | (8 << 16);
5244                 CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_CMD_TYPE, val);
5245
5246                 /* Point the hardware to the first page in the chain. */
5247                 val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
5248                 CTX_WR(sc, GET_CID_ADDR(TX_CID), 
5249                     BCE_L2CTX_TX_TBDR_BHADDR_HI, val);
5250                 val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
5251                 CTX_WR(sc, GET_CID_ADDR(TX_CID), 
5252                     BCE_L2CTX_TX_TBDR_BHADDR_LO, val);
5253         }
5254
5255         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
5256 }
5257
5258
5259 /****************************************************************************/
5260 /* Allocate memory and initialize the TX data structures.                   */
5261 /*                                                                          */
5262 /* Returns:                                                                 */
5263 /*   0 for success, positive value for failure.                             */
5264 /****************************************************************************/
5265 static int
5266 bce_init_tx_chain(struct bce_softc *sc)
5267 {
5268         struct tx_bd *txbd;
5269         int i, rc = 0;
5270
5271         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
5272
5273         /* Set the initial TX producer/consumer indices. */
5274         sc->tx_prod        = 0;
5275         sc->tx_cons        = 0;
5276         sc->tx_prod_bseq   = 0;
5277         sc->used_tx_bd     = 0;
5278         sc->max_tx_bd      = USABLE_TX_BD;
5279         DBRUN(sc->tx_hi_watermark = 0);
5280         DBRUN(sc->tx_full_count = 0);
5281
5282         /*
5283          * The NetXtreme II supports a linked-list structre called
5284          * a Buffer Descriptor Chain (or BD chain).  A BD chain
5285          * consists of a series of 1 or more chain pages, each of which
5286          * consists of a fixed number of BD entries.
5287          * The last BD entry on each page is a pointer to the next page
5288          * in the chain, and the last pointer in the BD chain
5289          * points back to the beginning of the chain.
5290          */
5291
5292         /* Set the TX next pointer chain entries. */
5293         for (i = 0; i < TX_PAGES; i++) {
5294                 int j;
5295
5296                 txbd = &sc->tx_bd_chain[i][USABLE_TX_BD_PER_PAGE];
5297
5298                 /* Check if we've reached the last page. */
5299                 if (i == (TX_PAGES - 1))
5300                         j = 0;
5301                 else
5302                         j = i + 1;
5303
5304                 txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->tx_bd_chain_paddr[j]));
5305                 txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->tx_bd_chain_paddr[j]));
5306         }
5307
5308         bce_init_tx_context(sc);
5309
5310         DBRUNMSG(BCE_INSANE_SEND, bce_dump_tx_chain(sc, 0, TOTAL_TX_BD));
5311         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
5312
5313         return(rc);
5314 }
5315
5316
5317 /****************************************************************************/
5318 /* Free memory and clear the TX data structures.                            */
5319 /*                                                                          */
5320 /* Returns:                                                                 */
5321 /*   Nothing.                                                               */
5322 /****************************************************************************/
5323 static void
5324 bce_free_tx_chain(struct bce_softc *sc)
5325 {
5326         int i;
5327
5328         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
5329
5330         /* Unmap, unload, and free any mbufs still in the TX mbuf chain. */
5331         for (i = 0; i < TOTAL_TX_BD; i++) {
5332                 if (sc->tx_mbuf_ptr[i] != NULL) {
5333                         if (sc->tx_mbuf_map[i] != NULL)
5334                                 bus_dmamap_sync(sc->tx_mbuf_tag, 
5335                                     sc->tx_mbuf_map[i],
5336                                     BUS_DMASYNC_POSTWRITE);
5337                         m_freem(sc->tx_mbuf_ptr[i]);
5338                         sc->tx_mbuf_ptr[i] = NULL;
5339                         DBRUN(sc->debug_tx_mbuf_alloc--);
5340                 }
5341         }
5342
5343         /* Clear each TX chain page. */
5344         for (i = 0; i < TX_PAGES; i++)
5345                 bzero((char *)sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ);
5346
5347         sc->used_tx_bd = 0;
5348
5349         /* Check if we lost any mbufs in the process. */
5350         DBRUNIF((sc->debug_tx_mbuf_alloc),
5351             BCE_PRINTF("%s(%d): Memory leak! Lost %d mbufs "
5352             "from tx chain!\n", __FILE__, __LINE__, 
5353             sc->debug_tx_mbuf_alloc));
5354
5355         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
5356 }
5357
5358
5359 /****************************************************************************/
5360 /* Initialize the RX context memory.                                        */
5361 /*                                                                          */
5362 /* Returns:                                                                 */
5363 /*   Nothing                                                                */
5364 /****************************************************************************/
5365 static void
5366 bce_init_rx_context(struct bce_softc *sc)
5367 {
5368         u32 val;
5369
5370         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
5371
5372         /* Init the type, size, and BD cache levels for the RX context. */
5373         val = BCE_L2CTX_RX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE |
5374             BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 |
5375             (0x02 << BCE_L2CTX_RX_BD_PRE_READ_SHIFT);
5376
5377         /*
5378          * Set the level for generating pause frames
5379          * when the number of available rx_bd's gets
5380          * too low (the low watermark) and the level
5381          * when pause frames can be stopped (the high
5382          * watermark).
5383          */
5384         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
5385             (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
5386                 u32 lo_water, hi_water;
5387
5388                 lo_water = BCE_L2CTX_RX_LO_WATER_MARK_DEFAULT;
5389                 hi_water = USABLE_RX_BD / 4;
5390
5391                 lo_water /= BCE_L2CTX_RX_LO_WATER_MARK_SCALE;
5392                 hi_water /= BCE_L2CTX_RX_HI_WATER_MARK_SCALE;
5393
5394                 if (hi_water > 0xf)
5395                         hi_water = 0xf;
5396                 else if (hi_water == 0)
5397                         lo_water = 0;
5398                 val |= (lo_water << BCE_L2CTX_RX_LO_WATER_MARK_SHIFT) |
5399                         (hi_water << BCE_L2CTX_RX_HI_WATER_MARK_SHIFT);
5400         }
5401
5402         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_CTX_TYPE, val);
5403
5404         /* Setup the MQ BIN mapping for l2_ctx_host_bseq. */
5405         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
5406             (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
5407                 val = REG_RD(sc, BCE_MQ_MAP_L2_5);
5408                 REG_WR(sc, BCE_MQ_MAP_L2_5, val | BCE_MQ_MAP_L2_5_ARM);
5409         }
5410
5411         /* Point the hardware to the first page in the chain. */
5412         val = BCE_ADDR_HI(sc->rx_bd_chain_paddr[0]);
5413         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_HI, val);
5414         val = BCE_ADDR_LO(sc->rx_bd_chain_paddr[0]);
5415         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_LO, val);
5416
5417         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
5418 }
5419
5420
5421 /****************************************************************************/
5422 /* Allocate memory and initialize the RX data structures.                   */
5423 /*                                                                          */
5424 /* Returns:                                                                 */
5425 /*   0 for success, positive value for failure.                             */
5426 /****************************************************************************/
5427 static int
5428 bce_init_rx_chain(struct bce_softc *sc)
5429 {
5430         struct rx_bd *rxbd;
5431         int i, rc = 0;
5432
5433         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5434             BCE_VERBOSE_CTX);
5435
5436         /* Initialize the RX producer and consumer indices. */
5437         sc->rx_prod        = 0;
5438         sc->rx_cons        = 0;
5439         sc->rx_prod_bseq   = 0;
5440         sc->free_rx_bd     = USABLE_RX_BD;
5441         sc->max_rx_bd      = USABLE_RX_BD;
5442
5443         /* Initialize the RX next pointer chain entries. */
5444         for (i = 0; i < RX_PAGES; i++) {
5445                 int j;
5446
5447                 rxbd = &sc->rx_bd_chain[i][USABLE_RX_BD_PER_PAGE];
5448
5449                 /* Check if we've reached the last page. */
5450                 if (i == (RX_PAGES - 1))
5451                         j = 0;
5452                 else
5453                         j = i + 1;
5454
5455                 /* Setup the chain page pointers. */
5456                 rxbd->rx_bd_haddr_hi = 
5457                     htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j]));
5458                 rxbd->rx_bd_haddr_lo = 
5459                     htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j]));
5460         }
5461
5462         /* Fill up the RX chain. */
5463         bce_fill_rx_chain(sc);
5464
5465         DBRUN(sc->rx_low_watermark = USABLE_RX_BD);
5466         DBRUN(sc->rx_empty_count = 0);
5467         for (i = 0; i < RX_PAGES; i++) {
5468                 bus_dmamap_sync(sc->rx_bd_chain_tag, sc->rx_bd_chain_map[i],
5469                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
5470         }
5471
5472         bce_init_rx_context(sc);
5473
5474         DBRUNMSG(BCE_EXTREME_RECV, bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD));
5475         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5476             BCE_VERBOSE_CTX);
5477
5478         /* ToDo: Are there possible failure modes here? */
5479
5480         return(rc);
5481 }
5482
5483
5484 /****************************************************************************/
5485 /* Add mbufs to the RX chain until its full or an mbuf allocation error     */
5486 /* occurs.                                                                  */
5487 /*                                                                          */
5488 /* Returns:                                                                 */
5489 /*   Nothing                                                                */
5490 /****************************************************************************/
5491 static void
5492 bce_fill_rx_chain(struct bce_softc *sc)
5493 {
5494         u16 prod, prod_idx;
5495         u32 prod_bseq;
5496
5497         DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5498             BCE_VERBOSE_CTX);
5499
5500         /* Get the RX chain producer indices. */
5501         prod      = sc->rx_prod;
5502         prod_bseq = sc->rx_prod_bseq;
5503
5504         /* Keep filling the RX chain until it's full. */
5505         while (sc->free_rx_bd > 0) {
5506                 prod_idx = RX_CHAIN_IDX(prod);
5507                 if (bce_get_rx_buf(sc, NULL, &prod, &prod_idx, &prod_bseq)) {
5508                         /* Bail out if we can't add an mbuf to the chain. */
5509                         break;
5510                 }
5511                 prod = NEXT_RX_BD(prod);
5512         }
5513
5514         /* Save the RX chain producer indices. */
5515         sc->rx_prod      = prod;
5516         sc->rx_prod_bseq = prod_bseq;
5517
5518         /* We should never end up pointing to a next page pointer. */
5519         DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
5520                 BCE_PRINTF("%s(): Invalid rx_prod value: 0x%04X\n",
5521                 __FUNCTION__, sc->rx_prod));
5522
5523         /* Write the mailbox and tell the chip about the waiting rx_bd's. */
5524         REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BDIDX,
5525                 sc->rx_prod);
5526         REG_WR(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BSEQ,
5527                 sc->rx_prod_bseq);
5528
5529         DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5530             BCE_VERBOSE_CTX);
5531 }
5532
5533
5534 /****************************************************************************/
5535 /* Free memory and clear the RX data structures.                            */
5536 /*                                                                          */
5537 /* Returns:                                                                 */
5538 /*   Nothing.                                                               */
5539 /****************************************************************************/
5540 static void
5541 bce_free_rx_chain(struct bce_softc *sc)
5542 {
5543         int i;
5544
5545         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5546
5547         /* Free any mbufs still in the RX mbuf chain. */
5548         for (i = 0; i < TOTAL_RX_BD; i++) {
5549                 if (sc->rx_mbuf_ptr[i] != NULL) {
5550                         if (sc->rx_mbuf_map[i] != NULL)
5551                                 bus_dmamap_sync(sc->rx_mbuf_tag, 
5552                                     sc->rx_mbuf_map[i],
5553                                     BUS_DMASYNC_POSTREAD);
5554                         m_freem(sc->rx_mbuf_ptr[i]);
5555                         sc->rx_mbuf_ptr[i] = NULL;
5556                         DBRUN(sc->debug_rx_mbuf_alloc--);
5557                 }
5558         }
5559
5560         /* Clear each RX chain page. */
5561         for (i = 0; i < RX_PAGES; i++)
5562                 if (sc->rx_bd_chain[i] != NULL) {
5563                         bzero((char *)sc->rx_bd_chain[i], 
5564                             BCE_RX_CHAIN_PAGE_SZ);
5565                 }
5566
5567         sc->free_rx_bd = sc->max_rx_bd;
5568
5569         /* Check if we lost any mbufs in the process. */
5570         DBRUNIF((sc->debug_rx_mbuf_alloc),
5571             BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from rx chain!\n",
5572             __FUNCTION__, sc->debug_rx_mbuf_alloc));
5573
5574         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5575 }
5576
5577
5578 #ifdef BCE_JUMBO_HDRSPLIT
5579 /****************************************************************************/
5580 /* Allocate memory and initialize the page data structures.                 */
5581 /* Assumes that bce_init_rx_chain() has not already been called.            */
5582 /*                                                                          */
5583 /* Returns:                                                                 */
5584 /*   0 for success, positive value for failure.                             */
5585 /****************************************************************************/
5586 static int
5587 bce_init_pg_chain(struct bce_softc *sc)
5588 {
5589         struct rx_bd *pgbd;
5590         int i, rc = 0;
5591         u32 val;
5592
5593         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5594                 BCE_VERBOSE_CTX);
5595
5596         /* Initialize the page producer and consumer indices. */
5597         sc->pg_prod        = 0;
5598         sc->pg_cons        = 0;
5599         sc->free_pg_bd     = USABLE_PG_BD;
5600         sc->max_pg_bd      = USABLE_PG_BD;
5601         DBRUN(sc->pg_low_watermark = sc->max_pg_bd);
5602         DBRUN(sc->pg_empty_count = 0);
5603
5604         /* Initialize the page next pointer chain entries. */
5605         for (i = 0; i < PG_PAGES; i++) {
5606                 int j;
5607
5608                 pgbd = &sc->pg_bd_chain[i][USABLE_PG_BD_PER_PAGE];
5609
5610                 /* Check if we've reached the last page. */
5611                 if (i == (PG_PAGES - 1))
5612                         j = 0;
5613                 else
5614                         j = i + 1;
5615
5616                 /* Setup the chain page pointers. */
5617                 pgbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->pg_bd_chain_paddr[j]));
5618                 pgbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->pg_bd_chain_paddr[j]));
5619         }
5620
5621         /* Setup the MQ BIN mapping for host_pg_bidx. */
5622         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)     ||
5623                 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
5624                 REG_WR(sc, BCE_MQ_MAP_L2_3, BCE_MQ_MAP_L2_3_DEFAULT);
5625
5626         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, 0);
5627
5628         /* Configure the rx_bd and page chain mbuf cluster size. */
5629         val = (sc->rx_bd_mbuf_data_len << 16) | sc->pg_bd_mbuf_alloc_size;
5630         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, val);
5631
5632         /* Configure the context reserved for jumbo support. */
5633         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_RBDC_KEY,
5634                 BCE_L2CTX_RX_RBDC_JUMBO_KEY);
5635
5636         /* Point the hardware to the first page in the page chain. */
5637         val = BCE_ADDR_HI(sc->pg_bd_chain_paddr[0]);
5638         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_HI, val);
5639         val = BCE_ADDR_LO(sc->pg_bd_chain_paddr[0]);
5640         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_LO, val);
5641
5642         /* Fill up the page chain. */
5643         bce_fill_pg_chain(sc);
5644
5645         for (i = 0; i < PG_PAGES; i++) {
5646                 bus_dmamap_sync(sc->pg_bd_chain_tag, sc->pg_bd_chain_map[i],
5647                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
5648         }
5649
5650         DBRUNMSG(BCE_EXTREME_RECV, bce_dump_pg_chain(sc, 0, TOTAL_PG_BD));
5651         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5652                 BCE_VERBOSE_CTX);
5653         return(rc);
5654 }
5655
5656
5657 /****************************************************************************/
5658 /* Add mbufs to the page chain until its full or an mbuf allocation error   */
5659 /* occurs.                                                                  */
5660 /*                                                                          */
5661 /* Returns:                                                                 */
5662 /*   Nothing                                                                */
5663 /****************************************************************************/
5664 static void
5665 bce_fill_pg_chain(struct bce_softc *sc)
5666 {
5667         u16 prod, prod_idx;
5668
5669         DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5670                 BCE_VERBOSE_CTX);
5671
5672         /* Get the page chain prodcuer index. */
5673         prod = sc->pg_prod;
5674
5675         /* Keep filling the page chain until it's full. */
5676         while (sc->free_pg_bd > 0) {
5677                 prod_idx = PG_CHAIN_IDX(prod);
5678                 if (bce_get_pg_buf(sc, NULL, &prod, &prod_idx)) {
5679                         /* Bail out if we can't add an mbuf to the chain. */
5680                         break;
5681                 }
5682                 prod = NEXT_PG_BD(prod);
5683         }
5684
5685         /* Save the page chain producer index. */
5686         sc->pg_prod = prod;
5687
5688         DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
5689                 BCE_PRINTF("%s(): Invalid pg_prod value: 0x%04X\n",
5690                 __FUNCTION__, sc->pg_prod));
5691
5692         /*
5693          * Write the mailbox and tell the chip about
5694          * the new rx_bd's in the page chain.
5695          */
5696         REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_PG_BDIDX,
5697                 sc->pg_prod);
5698
5699         DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5700                 BCE_VERBOSE_CTX);
5701 }
5702
5703
5704 /****************************************************************************/
5705 /* Free memory and clear the RX data structures.                            */
5706 /*                                                                          */
5707 /* Returns:                                                                 */
5708 /*   Nothing.                                                               */
5709 /****************************************************************************/
5710 static void
5711 bce_free_pg_chain(struct bce_softc *sc)
5712 {
5713         int i;
5714
5715         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5716
5717         /* Free any mbufs still in the mbuf page chain. */
5718         for (i = 0; i < TOTAL_PG_BD; i++) {
5719                 if (sc->pg_mbuf_ptr[i] != NULL) {
5720                         if (sc->pg_mbuf_map[i] != NULL)
5721                                 bus_dmamap_sync(sc->pg_mbuf_tag, sc->pg_mbuf_map[i],
5722                                         BUS_DMASYNC_POSTREAD);
5723                         m_freem(sc->pg_mbuf_ptr[i]);
5724                         sc->pg_mbuf_ptr[i] = NULL;
5725                         DBRUN(sc->debug_pg_mbuf_alloc--);
5726                 }
5727         }
5728
5729         /* Clear each page chain pages. */
5730         for (i = 0; i < PG_PAGES; i++)
5731                 bzero((char *)sc->pg_bd_chain[i], BCE_PG_CHAIN_PAGE_SZ);
5732
5733         sc->free_pg_bd = sc->max_pg_bd;
5734
5735         /* Check if we lost any mbufs in the process. */
5736         DBRUNIF((sc->debug_pg_mbuf_alloc),
5737                 BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from page chain!\n",
5738                         __FUNCTION__, sc->debug_pg_mbuf_alloc));
5739
5740         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5741 }
5742 #endif /* BCE_JUMBO_HDRSPLIT */
5743
5744
5745 /****************************************************************************/
5746 /* Set media options.                                                       */
5747 /*                                                                          */
5748 /* Returns:                                                                 */
5749 /*   0 for success, positive value for failure.                             */
5750 /****************************************************************************/
5751 static int
5752 bce_ifmedia_upd(struct ifnet *ifp)
5753 {
5754         struct bce_softc *sc = ifp->if_softc;
5755
5756         DBENTER(BCE_VERBOSE);
5757
5758         BCE_LOCK(sc);
5759         bce_ifmedia_upd_locked(ifp);
5760         BCE_UNLOCK(sc);
5761
5762         DBEXIT(BCE_VERBOSE);
5763         return (0);
5764 }
5765
5766
5767 /****************************************************************************/
5768 /* Set media options.                                                       */
5769 /*                                                                          */
5770 /* Returns:                                                                 */
5771 /*   Nothing.                                                               */
5772 /****************************************************************************/
5773 static void
5774 bce_ifmedia_upd_locked(struct ifnet *ifp)
5775 {
5776         struct bce_softc *sc = ifp->if_softc;
5777         struct mii_data *mii;
5778
5779         DBENTER(BCE_VERBOSE);
5780
5781         BCE_LOCK_ASSERT(sc);
5782
5783         mii = device_get_softc(sc->bce_miibus);
5784
5785         /* Make sure the MII bus has been enumerated. */
5786         if (mii) {
5787                 sc->bce_link_up = FALSE;
5788                 if (mii->mii_instance) {
5789                         struct mii_softc *miisc;
5790
5791                         LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
5792                             mii_phy_reset(miisc);
5793                 }
5794                 mii_mediachg(mii);
5795         }
5796
5797         DBEXIT(BCE_VERBOSE);
5798 }
5799
5800
5801 /****************************************************************************/
5802 /* Reports current media status.                                            */
5803 /*                                                                          */
5804 /* Returns:                                                                 */
5805 /*   Nothing.                                                               */
5806 /****************************************************************************/
5807 static void
5808 bce_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
5809 {
5810         struct bce_softc *sc = ifp->if_softc;
5811         struct mii_data *mii;
5812
5813         DBENTER(BCE_VERBOSE);
5814
5815         BCE_LOCK(sc);
5816
5817         mii = device_get_softc(sc->bce_miibus);
5818
5819         mii_pollstat(mii);
5820         ifmr->ifm_active = mii->mii_media_active;
5821         ifmr->ifm_status = mii->mii_media_status;
5822
5823         BCE_UNLOCK(sc);
5824
5825         DBEXIT(BCE_VERBOSE);
5826 }
5827
5828
5829 /****************************************************************************/
5830 /* Handles PHY generated interrupt events.                                  */
5831 /*                                                                          */
5832 /* Returns:                                                                 */
5833 /*   Nothing.                                                               */
5834 /****************************************************************************/
5835 static void
5836 bce_phy_intr(struct bce_softc *sc)
5837 {
5838         u32 new_link_state, old_link_state;
5839
5840         DBENTER(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
5841
5842         DBRUN(sc->phy_interrupts++);
5843
5844         new_link_state = sc->status_block->status_attn_bits &
5845             STATUS_ATTN_BITS_LINK_STATE;
5846         old_link_state = sc->status_block->status_attn_bits_ack &
5847             STATUS_ATTN_BITS_LINK_STATE;
5848
5849         /* Handle any changes if the link state has changed. */
5850         if (new_link_state != old_link_state) {
5851
5852                 /* Update the status_attn_bits_ack field. */
5853                 if (new_link_state) {
5854                         REG_WR(sc, BCE_PCICFG_STATUS_BIT_SET_CMD,
5855                             STATUS_ATTN_BITS_LINK_STATE);
5856                         DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now UP.\n",
5857                             __FUNCTION__);
5858                 }
5859                 else {
5860                         REG_WR(sc, BCE_PCICFG_STATUS_BIT_CLEAR_CMD,
5861                             STATUS_ATTN_BITS_LINK_STATE);
5862                         DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now DOWN.\n",
5863                             __FUNCTION__);
5864                 }
5865
5866                 /*
5867                  * Assume link is down and allow
5868                  * tick routine to update the state
5869                  * based on the actual media state.
5870                  */
5871                 sc->bce_link_up = FALSE;
5872                 callout_stop(&sc->bce_tick_callout);
5873                 bce_tick(sc);
5874         }
5875
5876         /* Acknowledge the link change interrupt. */
5877         REG_WR(sc, BCE_EMAC_STATUS, BCE_EMAC_STATUS_LINK_CHANGE);
5878
5879         DBEXIT(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
5880 }
5881
5882
5883 /****************************************************************************/
5884 /* Reads the receive consumer value from the status block (skipping over    */
5885 /* chain page pointer if necessary).                                        */
5886 /*                                                                          */
5887 /* Returns:                                                                 */
5888 /*   hw_cons                                                                */
5889 /****************************************************************************/
5890 static inline u16
5891 bce_get_hw_rx_cons(struct bce_softc *sc)
5892 {
5893         u16 hw_cons;
5894
5895         rmb();
5896         hw_cons = sc->status_block->status_rx_quick_consumer_index0;
5897         if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
5898                 hw_cons++;
5899
5900         return hw_cons;
5901 }
5902
5903 /****************************************************************************/
5904 /* Handles received frame interrupt events.                                 */
5905 /*                                                                          */
5906 /* Returns:                                                                 */
5907 /*   Nothing.                                                               */
5908 /****************************************************************************/
5909 static void
5910 bce_rx_intr(struct bce_softc *sc)
5911 {
5912         struct ifnet *ifp = sc->bce_ifp;
5913         struct l2_fhdr *l2fhdr;
5914         struct ether_vlan_header *vh;
5915         unsigned int pkt_len;
5916         u16 sw_rx_cons, sw_rx_cons_idx, hw_rx_cons;
5917         u32 status;
5918 #ifdef BCE_JUMBO_HDRSPLIT
5919         unsigned int rem_len;
5920         u16 sw_pg_cons, sw_pg_cons_idx;
5921 #endif
5922
5923         DBENTER(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
5924         DBRUN(sc->rx_interrupts++);
5925         DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): rx_prod = 0x%04X, "
5926             "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
5927             __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
5928
5929         /* Prepare the RX chain pages to be accessed by the host CPU. */
5930         for (int i = 0; i < RX_PAGES; i++)
5931                 bus_dmamap_sync(sc->rx_bd_chain_tag,
5932                     sc->rx_bd_chain_map[i], BUS_DMASYNC_POSTREAD);
5933
5934 #ifdef BCE_JUMBO_HDRSPLIT
5935         /* Prepare the page chain pages to be accessed by the host CPU. */
5936         for (int i = 0; i < PG_PAGES; i++)
5937                 bus_dmamap_sync(sc->pg_bd_chain_tag,
5938                     sc->pg_bd_chain_map[i], BUS_DMASYNC_POSTREAD);
5939 #endif
5940
5941         /* Get the hardware's view of the RX consumer index. */
5942         hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
5943
5944         /* Get working copies of the driver's view of the consumer indices. */
5945         sw_rx_cons = sc->rx_cons;
5946 #ifdef BCE_JUMBO_HDRSPLIT
5947         sw_pg_cons = sc->pg_cons;
5948 #endif
5949
5950         /* Update some debug statistics counters */
5951         DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
5952                 sc->rx_low_watermark = sc->free_rx_bd);
5953         DBRUNIF((sc->free_rx_bd == sc->max_rx_bd), sc->rx_empty_count++);
5954
5955         /* Scan through the receive chain as long as there is work to do */
5956         /* ToDo: Consider setting a limit on the number of packets processed. */
5957         rmb();
5958         while (sw_rx_cons != hw_rx_cons) {
5959                 struct mbuf *m0;
5960
5961                 /* Convert the producer/consumer indices to an actual rx_bd index. */
5962                 sw_rx_cons_idx = RX_CHAIN_IDX(sw_rx_cons);
5963
5964                 /* Unmap the mbuf from DMA space. */
5965                 bus_dmamap_sync(sc->rx_mbuf_tag, 
5966                     sc->rx_mbuf_map[sw_rx_cons_idx],
5967                     BUS_DMASYNC_POSTREAD);
5968                 bus_dmamap_unload(sc->rx_mbuf_tag,
5969                     sc->rx_mbuf_map[sw_rx_cons_idx]);
5970
5971                 /* Remove the mbuf from the RX chain. */
5972                 m0 = sc->rx_mbuf_ptr[sw_rx_cons_idx];
5973                 sc->rx_mbuf_ptr[sw_rx_cons_idx] = NULL;
5974                 DBRUN(sc->debug_rx_mbuf_alloc--);
5975                 sc->free_rx_bd++;
5976
5977                 if(m0 == NULL) {
5978                         DBPRINT(sc, BCE_EXTREME_RECV, 
5979                             "%s(): Oops! Empty mbuf pointer "
5980                             "found in sc->rx_mbuf_ptr[0x%04X]!\n",
5981                             __FUNCTION__, sw_rx_cons_idx);
5982                         goto bce_rx_int_next_rx;
5983                 }
5984
5985                 /*
5986                  * Frames received on the NetXteme II are prepended     with an
5987                  * l2_fhdr structure which provides status information about
5988                  * the received frame (including VLAN tags and checksum info).
5989                  * The frames are also automatically adjusted to align the IP
5990                  * header (i.e. two null bytes are inserted before the Ethernet
5991                  * header).  As a result the data DMA'd by the controller into
5992                  * the mbuf is as follows:
5993                  * 
5994                  * +---------+-----+---------------------+-----+
5995                  * | l2_fhdr | pad | packet data         | FCS |
5996                  * +---------+-----+---------------------+-----+
5997                  * 
5998                  * The l2_fhdr needs to be checked and skipped and the FCS needs
5999                  * to be stripped before sending the packet up the stack.
6000                  */
6001                 l2fhdr  = mtod(m0, struct l2_fhdr *);
6002
6003                 /* Get the packet data + FCS length and the status. */
6004                 pkt_len = l2fhdr->l2_fhdr_pkt_len;
6005                 status  = l2fhdr->l2_fhdr_status;
6006
6007                 /*
6008                  * Skip over the l2_fhdr and pad, resulting in the
6009                  * following data in the mbuf:
6010                  * +---------------------+-----+
6011                  * | packet data         | FCS |
6012                  * +---------------------+-----+
6013                  */
6014                 m_adj(m0, sizeof(struct l2_fhdr) + ETHER_ALIGN);
6015
6016 #ifdef BCE_JUMBO_HDRSPLIT
6017                 /*
6018                  * Check whether the received frame fits in a single
6019                  * mbuf or not (i.e. packet data + FCS <=
6020                  * sc->rx_bd_mbuf_data_len bytes).
6021                  */
6022                 if (pkt_len > m0->m_len) {
6023                         /*
6024                          * The received frame is larger than a single mbuf.
6025                          * If the frame was a TCP frame then only the TCP
6026                          * header is placed in the mbuf, the remaining
6027                          * payload (including FCS) is placed in the page
6028                          * chain, the SPLIT flag is set, and the header
6029                          * length is placed in the IP checksum field.
6030                          * If the frame is not a TCP frame then the mbuf
6031                          * is filled and the remaining bytes are placed
6032                          * in the page chain.
6033                          */
6034
6035                         DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a large "
6036                             "packet.\n", __FUNCTION__);
6037
6038                         /*
6039                          * When the page chain is enabled and the TCP
6040                          * header has been split from the TCP payload,
6041                          * the ip_xsum structure will reflect the length
6042                          * of the TCP header, not the IP checksum.  Set
6043                          * the packet length of the mbuf accordingly.
6044                          */
6045                         if (status & L2_FHDR_STATUS_SPLIT)
6046                                 m0->m_len = l2fhdr->l2_fhdr_ip_xsum;
6047
6048                         rem_len = pkt_len - m0->m_len;
6049
6050                         /* Pull mbufs off the page chain for the remaining data. */
6051                         while (rem_len > 0) {
6052                                 struct mbuf *m_pg;
6053
6054                                 sw_pg_cons_idx = PG_CHAIN_IDX(sw_pg_cons);
6055
6056                                 /* Remove the mbuf from the page chain. */
6057                                 m_pg = sc->pg_mbuf_ptr[sw_pg_cons_idx];
6058                                 sc->pg_mbuf_ptr[sw_pg_cons_idx] = NULL;
6059                                 DBRUN(sc->debug_pg_mbuf_alloc--);
6060                                 sc->free_pg_bd++;
6061
6062                                 /* Unmap the page chain mbuf from DMA space. */
6063                                 bus_dmamap_sync(sc->pg_mbuf_tag,
6064                                     sc->pg_mbuf_map[sw_pg_cons_idx],
6065                                     BUS_DMASYNC_POSTREAD);
6066                                 bus_dmamap_unload(sc->pg_mbuf_tag,
6067                                     sc->pg_mbuf_map[sw_pg_cons_idx]);
6068
6069                                 /* Adjust the mbuf length. */
6070                                 if (rem_len < m_pg->m_len) {
6071                                         /* The mbuf chain is complete. */
6072                                         m_pg->m_len = rem_len;
6073                                         rem_len = 0;
6074                                 } else {
6075                                         /* More packet data is waiting. */
6076                                         rem_len -= m_pg->m_len;
6077                                 }
6078
6079                                 /* Concatenate the mbuf cluster to the mbuf. */
6080                                 m_cat(m0, m_pg);
6081
6082                                 sw_pg_cons = NEXT_PG_BD(sw_pg_cons);
6083                         }
6084
6085                         /* Set the total packet length. */
6086                         m0->m_pkthdr.len = pkt_len;
6087
6088                 } else {
6089                         /*
6090                          * The received packet is small and fits in a
6091                          * single mbuf (i.e. the l2_fhdr + pad + packet +
6092                          * FCS <= MHLEN).  In other words, the packet is
6093                          * 154 bytes or less in size.
6094                          */
6095
6096                         DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a small "
6097                             "packet.\n", __FUNCTION__);
6098
6099                         /* Set the total packet length. */
6100                         m0->m_pkthdr.len = m0->m_len = pkt_len;
6101                 }
6102 #else
6103         /* Set the total packet length. */
6104                 m0->m_pkthdr.len = m0->m_len = pkt_len;
6105 #endif
6106
6107                 /* Remove the trailing Ethernet FCS. */
6108                 m_adj(m0, -ETHER_CRC_LEN);
6109
6110                 /* Check that the resulting mbuf chain is valid. */
6111                 DBRUN(m_sanity(m0, FALSE));
6112                 DBRUNIF(((m0->m_len < ETHER_HDR_LEN) |
6113                     (m0->m_pkthdr.len > BCE_MAX_JUMBO_ETHER_MTU_VLAN)),
6114                      BCE_PRINTF("Invalid Ethernet frame size!\n");
6115                      m_print(m0, 128));
6116
6117                 DBRUNIF(DB_RANDOMTRUE(l2fhdr_error_sim_control),
6118                     BCE_PRINTF("Simulating l2_fhdr status error.\n");
6119                     sc->l2fhdr_error_sim_count++;
6120                     status = status | L2_FHDR_ERRORS_PHY_DECODE);
6121
6122                 /* Check the received frame for errors. */
6123                 if (status & (L2_FHDR_ERRORS_BAD_CRC | 
6124                     L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT |
6125                     L2_FHDR_ERRORS_TOO_SHORT  | L2_FHDR_ERRORS_GIANT_FRAME)) {
6126
6127                         /* Log the error and release the mbuf. */
6128                         ifp->if_ierrors++;
6129                         sc->l2fhdr_error_count++;
6130
6131                         m_freem(m0);
6132                         m0 = NULL;
6133                         goto bce_rx_int_next_rx;
6134                 }
6135
6136                 /* Send the packet to the appropriate interface. */
6137                 m0->m_pkthdr.rcvif = ifp;
6138
6139                 /* Assume no hardware checksum. */
6140                 m0->m_pkthdr.csum_flags = 0;
6141
6142                 /* Validate the checksum if offload enabled. */
6143                 if (ifp->if_capenable & IFCAP_RXCSUM) {
6144
6145                         /* Check for an IP datagram. */
6146                         if (!(status & L2_FHDR_STATUS_SPLIT) &&
6147                                 (status & L2_FHDR_STATUS_IP_DATAGRAM)) {
6148                                 m0->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
6149
6150                                 /* Check if the IP checksum is valid. */
6151                                 if ((l2fhdr->l2_fhdr_ip_xsum ^ 0xffff) == 0)
6152                                         m0->m_pkthdr.csum_flags |= 
6153                                             CSUM_IP_VALID;
6154                         }
6155
6156                         /* Check for a valid TCP/UDP frame. */
6157                         if (status & (L2_FHDR_STATUS_TCP_SEGMENT |
6158                             L2_FHDR_STATUS_UDP_DATAGRAM)) {
6159
6160                                 /* Check for a good TCP/UDP checksum. */
6161                                 if ((status & (L2_FHDR_ERRORS_TCP_XSUM |
6162                                     L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
6163                                         m0->m_pkthdr.csum_data =
6164                                             l2fhdr->l2_fhdr_tcp_udp_xsum;
6165                                         m0->m_pkthdr.csum_flags |= 
6166                                             (CSUM_DATA_VALID
6167                                             | CSUM_PSEUDO_HDR);
6168                                 }
6169                         }
6170                 }
6171
6172                 /* Attach the VLAN tag. */
6173                 if (status & L2_FHDR_STATUS_L2_VLAN_TAG) {
6174                         if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
6175 #if __FreeBSD_version < 700000
6176                                 VLAN_INPUT_TAG(ifp, m0,
6177                                     l2fhdr->l2_fhdr_vlan_tag, continue);
6178 #else
6179                                 m0->m_pkthdr.ether_vtag =
6180                                     l2fhdr->l2_fhdr_vlan_tag;
6181                                 m0->m_flags |= M_VLANTAG;
6182 #endif
6183                         } else {
6184                                 /*
6185                                  * bce(4) controllers can't disable VLAN
6186                                  * tag stripping if management firmware
6187                                  * (ASF/IPMI/UMP) is running. So we always
6188                                  * strip VLAN tag and manually reconstruct
6189                                  * the VLAN frame by appending stripped
6190                                  * VLAN tag in driver if VLAN tag stripping
6191                                  * was disabled.
6192                                  *
6193                                  * TODO: LLC SNAP handling.
6194                                  */
6195                                 bcopy(mtod(m0, uint8_t *),
6196                                     mtod(m0, uint8_t *) - ETHER_VLAN_ENCAP_LEN,
6197                                     ETHER_ADDR_LEN * 2);
6198                                 m0->m_data -= ETHER_VLAN_ENCAP_LEN;
6199                                 vh = mtod(m0, struct ether_vlan_header *);
6200                                 vh->evl_encap_proto = htons(ETHERTYPE_VLAN);
6201                                 vh->evl_tag = htons(l2fhdr->l2_fhdr_vlan_tag);
6202                                 m0->m_pkthdr.len += ETHER_VLAN_ENCAP_LEN;
6203                                 m0->m_len += ETHER_VLAN_ENCAP_LEN;
6204                         }
6205                 }
6206
6207                 /* Increment received packet statistics. */
6208                 ifp->if_ipackets++;
6209
6210 bce_rx_int_next_rx:
6211                 sw_rx_cons = NEXT_RX_BD(sw_rx_cons);
6212
6213                 /* If we have a packet, pass it up the stack */
6214                 if (m0) {
6215                         /* Make sure we don't lose our place when we release the lock. */
6216                         sc->rx_cons = sw_rx_cons;
6217 #ifdef BCE_JUMBO_HDRSPLIT
6218                         sc->pg_cons = sw_pg_cons;
6219 #endif
6220
6221                         BCE_UNLOCK(sc);
6222                         (*ifp->if_input)(ifp, m0);
6223                         BCE_LOCK(sc);
6224
6225                         /* Recover our place. */
6226                         sw_rx_cons = sc->rx_cons;
6227 #ifdef BCE_JUMBO_HDRSPLIT
6228                         sw_pg_cons = sc->pg_cons;
6229 #endif
6230                 }
6231
6232                 /* Refresh hw_cons to see if there's new work */
6233                 if (sw_rx_cons == hw_rx_cons)
6234                         hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
6235         }
6236
6237         /* No new packets to process.  Refill the RX and page chains and exit. */
6238 #ifdef BCE_JUMBO_HDRSPLIT
6239         sc->pg_cons = sw_pg_cons;
6240         bce_fill_pg_chain(sc);
6241 #endif
6242
6243         sc->rx_cons = sw_rx_cons;
6244         bce_fill_rx_chain(sc);
6245
6246         /* Prepare the page chain pages to be accessed by the NIC. */
6247         for (int i = 0; i < RX_PAGES; i++)
6248                 bus_dmamap_sync(sc->rx_bd_chain_tag,
6249                     sc->rx_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
6250
6251 #ifdef BCE_JUMBO_HDRSPLIT
6252         for (int i = 0; i < PG_PAGES; i++)
6253                 bus_dmamap_sync(sc->pg_bd_chain_tag,
6254                     sc->pg_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
6255 #endif
6256
6257         DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): rx_prod = 0x%04X, "
6258             "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
6259             __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
6260         DBEXIT(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
6261 }
6262
6263
6264 /****************************************************************************/
6265 /* Reads the transmit consumer value from the status block (skipping over   */
6266 /* chain page pointer if necessary).                                        */
6267 /*                                                                          */
6268 /* Returns:                                                                 */
6269 /*   hw_cons                                                                */
6270 /****************************************************************************/
6271 static inline u16
6272 bce_get_hw_tx_cons(struct bce_softc *sc)
6273 {
6274         u16 hw_cons;
6275
6276         mb();
6277         hw_cons = sc->status_block->status_tx_quick_consumer_index0;
6278         if ((hw_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
6279                 hw_cons++;
6280
6281         return hw_cons;
6282 }
6283
6284
6285 /****************************************************************************/
6286 /* Handles transmit completion interrupt events.                            */
6287 /*                                                                          */
6288 /* Returns:                                                                 */
6289 /*   Nothing.                                                               */
6290 /****************************************************************************/
6291 static void
6292 bce_tx_intr(struct bce_softc *sc)
6293 {
6294         struct ifnet *ifp = sc->bce_ifp;
6295         u16 hw_tx_cons, sw_tx_cons, sw_tx_chain_cons;
6296
6297         DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
6298         DBRUN(sc->tx_interrupts++);
6299         DBPRINT(sc, BCE_EXTREME_SEND, "%s(enter): tx_prod = 0x%04X, "
6300             "tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
6301             __FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
6302
6303         BCE_LOCK_ASSERT(sc);
6304
6305         /* Get the hardware's view of the TX consumer index. */
6306         hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
6307         sw_tx_cons = sc->tx_cons;
6308
6309         /* Prevent speculative reads from getting ahead of the status block. */
6310         bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
6311             BUS_SPACE_BARRIER_READ);
6312
6313         /* Cycle through any completed TX chain page entries. */
6314         while (sw_tx_cons != hw_tx_cons) {
6315 #ifdef BCE_DEBUG
6316                 struct tx_bd *txbd = NULL;
6317 #endif
6318                 sw_tx_chain_cons = TX_CHAIN_IDX(sw_tx_cons);
6319
6320                 DBPRINT(sc, BCE_INFO_SEND,
6321                     "%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, "
6322                     "sw_tx_chain_cons = 0x%04X\n",
6323                     __FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
6324
6325                 DBRUNIF((sw_tx_chain_cons > MAX_TX_BD),
6326                     BCE_PRINTF("%s(%d): TX chain consumer out of range! "
6327                     " 0x%04X > 0x%04X\n", __FILE__, __LINE__, sw_tx_chain_cons,
6328                     (int) MAX_TX_BD);
6329                     bce_breakpoint(sc));
6330
6331                 DBRUN(txbd = &sc->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)]
6332                     [TX_IDX(sw_tx_chain_cons)]);
6333
6334                 DBRUNIF((txbd == NULL),
6335                     BCE_PRINTF("%s(%d): Unexpected NULL tx_bd[0x%04X]!\n",
6336                     __FILE__, __LINE__, sw_tx_chain_cons);
6337                     bce_breakpoint(sc));
6338
6339                 DBRUNMSG(BCE_INFO_SEND, BCE_PRINTF("%s(): ", __FUNCTION__);
6340                     bce_dump_txbd(sc, sw_tx_chain_cons, txbd));
6341
6342                 /*
6343                  * Free the associated mbuf. Remember
6344                  * that only the last tx_bd of a packet
6345                  * has an mbuf pointer and DMA map.
6346                  */
6347                 if (sc->tx_mbuf_ptr[sw_tx_chain_cons] != NULL) {
6348
6349                         /* Validate that this is the last tx_bd. */
6350                         DBRUNIF((!(txbd->tx_bd_flags & TX_BD_FLAGS_END)),
6351                             BCE_PRINTF("%s(%d): tx_bd END flag not set but "
6352                             "txmbuf == NULL!\n", __FILE__, __LINE__);
6353                             bce_breakpoint(sc));
6354
6355                         DBRUNMSG(BCE_INFO_SEND,
6356                             BCE_PRINTF("%s(): Unloading map/freeing mbuf "
6357                             "from tx_bd[0x%04X]\n", __FUNCTION__, 
6358                             sw_tx_chain_cons));
6359
6360                         /* Unmap the mbuf. */
6361                         bus_dmamap_unload(sc->tx_mbuf_tag,
6362                             sc->tx_mbuf_map[sw_tx_chain_cons]);
6363
6364                         /* Free the mbuf. */
6365                         m_freem(sc->tx_mbuf_ptr[sw_tx_chain_cons]);
6366                         sc->tx_mbuf_ptr[sw_tx_chain_cons] = NULL;
6367                         DBRUN(sc->debug_tx_mbuf_alloc--);
6368
6369                         ifp->if_opackets++;
6370                 }
6371
6372                 sc->used_tx_bd--;
6373                 sw_tx_cons = NEXT_TX_BD(sw_tx_cons);
6374
6375                 /* Refresh hw_cons to see if there's new work. */
6376                 hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
6377
6378                 /* Prevent speculative reads of the status block. */
6379                 bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
6380                     BUS_SPACE_BARRIER_READ);
6381         }
6382
6383         /* Clear the TX timeout timer. */
6384         sc->watchdog_timer = 0;
6385
6386         /* Clear the tx hardware queue full flag. */
6387         if (sc->used_tx_bd < sc->max_tx_bd) {
6388                 DBRUNIF((ifp->if_drv_flags & IFF_DRV_OACTIVE),
6389                     DBPRINT(sc, BCE_INFO_SEND,
6390                     "%s(): Open TX chain! %d/%d (used/total)\n",
6391                     __FUNCTION__, sc->used_tx_bd, sc->max_tx_bd));
6392                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
6393         }
6394
6395         sc->tx_cons = sw_tx_cons;
6396
6397         DBPRINT(sc, BCE_EXTREME_SEND, "%s(exit): tx_prod = 0x%04X, "
6398             "tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
6399             __FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
6400         DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
6401 }
6402
6403
6404 /****************************************************************************/
6405 /* Disables interrupt generation.                                           */
6406 /*                                                                          */
6407 /* Returns:                                                                 */
6408 /*   Nothing.                                                               */
6409 /****************************************************************************/
6410 static void
6411 bce_disable_intr(struct bce_softc *sc)
6412 {
6413         DBENTER(BCE_VERBOSE_INTR);
6414
6415         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_MASK_INT);
6416         REG_RD(sc, BCE_PCICFG_INT_ACK_CMD);
6417
6418         DBEXIT(BCE_VERBOSE_INTR);
6419 }
6420
6421
6422 /****************************************************************************/
6423 /* Enables interrupt generation.                                            */
6424 /*                                                                          */
6425 /* Returns:                                                                 */
6426 /*   Nothing.                                                               */
6427 /****************************************************************************/
6428 static void
6429 bce_enable_intr(struct bce_softc *sc, int coal_now)
6430 {
6431         DBENTER(BCE_VERBOSE_INTR);
6432
6433         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
6434             BCE_PCICFG_INT_ACK_CMD_INDEX_VALID |
6435             BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
6436
6437         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
6438             BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
6439
6440         /* Force an immediate interrupt (whether there is new data or not). */
6441         if (coal_now)
6442                 REG_WR(sc, BCE_HC_COMMAND, sc->hc_command | BCE_HC_COMMAND_COAL_NOW);
6443
6444         DBEXIT(BCE_VERBOSE_INTR);
6445 }
6446
6447
6448 /****************************************************************************/
6449 /* Handles controller initialization.                                       */
6450 /*                                                                          */
6451 /* Returns:                                                                 */
6452 /*   Nothing.                                                               */
6453 /****************************************************************************/
6454 static void
6455 bce_init_locked(struct bce_softc *sc)
6456 {
6457         struct ifnet *ifp;
6458         u32 ether_mtu = 0;
6459
6460         DBENTER(BCE_VERBOSE_RESET);
6461
6462         BCE_LOCK_ASSERT(sc);
6463
6464         ifp = sc->bce_ifp;
6465
6466         /* Check if the driver is still running and bail out if it is. */
6467         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
6468                 goto bce_init_locked_exit;
6469
6470         bce_stop(sc);
6471
6472         if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
6473                 BCE_PRINTF("%s(%d): Controller reset failed!\n",
6474                     __FILE__, __LINE__);
6475                 goto bce_init_locked_exit;
6476         }
6477
6478         if (bce_chipinit(sc)) {
6479                 BCE_PRINTF("%s(%d): Controller initialization failed!\n",
6480                     __FILE__, __LINE__);
6481                 goto bce_init_locked_exit;
6482         }
6483
6484         if (bce_blockinit(sc)) {
6485                 BCE_PRINTF("%s(%d): Block initialization failed!\n",
6486                     __FILE__, __LINE__);
6487                 goto bce_init_locked_exit;
6488         }
6489
6490         /* Load our MAC address. */
6491         bcopy(IF_LLADDR(sc->bce_ifp), sc->eaddr, ETHER_ADDR_LEN);
6492         bce_set_mac_addr(sc);
6493
6494         /*
6495          * Calculate and program the hardware Ethernet MTU
6496          * size. Be generous on the receive if we have room.
6497          */
6498 #ifdef BCE_JUMBO_HDRSPLIT
6499         if (ifp->if_mtu <= (sc->rx_bd_mbuf_data_len + 
6500             sc->pg_bd_mbuf_alloc_size))
6501                 ether_mtu = sc->rx_bd_mbuf_data_len + 
6502                     sc->pg_bd_mbuf_alloc_size;
6503 #else
6504         if (ifp->if_mtu <= sc->rx_bd_mbuf_data_len)
6505                 ether_mtu = sc->rx_bd_mbuf_data_len;
6506 #endif
6507         else
6508                 ether_mtu = ifp->if_mtu;
6509
6510         ether_mtu += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN;
6511
6512         DBPRINT(sc, BCE_INFO_MISC, "%s(): setting h/w mtu = %d\n", 
6513             __FUNCTION__, ether_mtu);
6514
6515         /* Program the mtu, enabling jumbo frame support if necessary. */
6516         if (ether_mtu > (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN))
6517                 REG_WR(sc, BCE_EMAC_RX_MTU_SIZE,
6518                     min(ether_mtu, BCE_MAX_JUMBO_ETHER_MTU) |
6519                     BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA);
6520         else
6521                 REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu);
6522
6523         DBPRINT(sc, BCE_INFO_LOAD,
6524             "%s(): rx_bd_mbuf_alloc_size = %d, rx_bce_mbuf_data_len = %d, "
6525             "rx_bd_mbuf_align_pad = %d\n", __FUNCTION__, 
6526             sc->rx_bd_mbuf_alloc_size, sc->rx_bd_mbuf_data_len,
6527             sc->rx_bd_mbuf_align_pad);
6528
6529         /* Program appropriate promiscuous/multicast filtering. */
6530         bce_set_rx_mode(sc);
6531
6532 #ifdef BCE_JUMBO_HDRSPLIT
6533         DBPRINT(sc, BCE_INFO_LOAD, "%s(): pg_bd_mbuf_alloc_size = %d\n",
6534             __FUNCTION__, sc->pg_bd_mbuf_alloc_size);
6535
6536         /* Init page buffer descriptor chain. */
6537         bce_init_pg_chain(sc);
6538 #endif
6539
6540         /* Init RX buffer descriptor chain. */
6541         bce_init_rx_chain(sc);
6542
6543         /* Init TX buffer descriptor chain. */
6544         bce_init_tx_chain(sc);
6545
6546         /* Enable host interrupts. */
6547         bce_enable_intr(sc, 1);
6548
6549         bce_ifmedia_upd_locked(ifp);
6550
6551         /* Let the OS know the driver is up and running. */
6552         ifp->if_drv_flags |= IFF_DRV_RUNNING;
6553         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
6554
6555         callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
6556
6557 bce_init_locked_exit:
6558         DBEXIT(BCE_VERBOSE_RESET);
6559 }
6560
6561
6562 /****************************************************************************/
6563 /* Initialize the controller just enough so that any management firmware    */
6564 /* running on the device will continue to operate correctly.                */
6565 /*                                                                          */
6566 /* Returns:                                                                 */
6567 /*   Nothing.                                                               */
6568 /****************************************************************************/
6569 static void
6570 bce_mgmt_init_locked(struct bce_softc *sc)
6571 {
6572         struct ifnet *ifp;
6573
6574         DBENTER(BCE_VERBOSE_RESET);
6575
6576         BCE_LOCK_ASSERT(sc);
6577
6578         /* Bail out if management firmware is not running. */
6579         if (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)) {
6580                 DBPRINT(sc, BCE_VERBOSE_SPECIAL,
6581                     "No management firmware running...\n");
6582                 goto bce_mgmt_init_locked_exit;
6583         }
6584
6585         ifp = sc->bce_ifp;
6586
6587         /* Enable all critical blocks in the MAC. */
6588         REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT);
6589         REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
6590         DELAY(20);
6591
6592         bce_ifmedia_upd_locked(ifp);
6593
6594 bce_mgmt_init_locked_exit:
6595         DBEXIT(BCE_VERBOSE_RESET);
6596 }
6597
6598
6599 /****************************************************************************/
6600 /* Handles controller initialization when called from an unlocked routine.  */
6601 /*                                                                          */
6602 /* Returns:                                                                 */
6603 /*   Nothing.                                                               */
6604 /****************************************************************************/
6605 static void
6606 bce_init(void *xsc)
6607 {
6608         struct bce_softc *sc = xsc;
6609
6610         DBENTER(BCE_VERBOSE_RESET);
6611
6612         BCE_LOCK(sc);
6613         bce_init_locked(sc);
6614         BCE_UNLOCK(sc);
6615
6616         DBEXIT(BCE_VERBOSE_RESET);
6617 }
6618
6619
6620 static struct mbuf *
6621 bce_tso_setup(struct bce_softc *sc, struct mbuf **m_head, u16 *flags)
6622 {
6623         struct mbuf *m;
6624         struct ether_header *eh;
6625         struct ip *ip;
6626         struct tcphdr *th;
6627         u16 etype;
6628         int hdr_len, ip_hlen = 0, tcp_hlen = 0, ip_len = 0;
6629
6630         DBRUN(sc->requested_tso_frames++);
6631         /* Controller requires to monify mbuf chains. */
6632         if (M_WRITABLE(*m_head) == 0) {
6633                 m = m_dup(*m_head, M_DONTWAIT);
6634                 m_freem(*m_head);
6635                 if (m == NULL) {
6636                         sc->mbuf_alloc_failed_count++;
6637                         *m_head = NULL;
6638                         return (NULL);
6639                 }
6640                 *m_head = m;
6641         }
6642         /*
6643          * For TSO the controller needs two pieces of info,
6644          * the MSS and the IP+TCP options length.
6645          */
6646         m = m_pullup(*m_head, sizeof(struct ether_header) + sizeof(struct ip));
6647         if (m == NULL) {
6648                 *m_head = NULL;
6649                 return (NULL);
6650         }
6651         eh = mtod(m, struct ether_header *);
6652         etype = ntohs(eh->ether_type);
6653
6654         /* Check for supported TSO Ethernet types (only IPv4 for now) */
6655         switch (etype) {
6656         case ETHERTYPE_IP:
6657                 ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
6658                 /* TSO only supported for TCP protocol. */
6659                 if (ip->ip_p != IPPROTO_TCP) {
6660                         BCE_PRINTF("%s(%d): TSO enabled for non-TCP frame!.\n",
6661                             __FILE__, __LINE__);
6662                         m_freem(*m_head);
6663                         *m_head = NULL;
6664                         return (NULL);
6665                 }
6666
6667                 /* Get IP header length in bytes (min 20) */
6668                 ip_hlen = ip->ip_hl << 2;
6669                 m = m_pullup(*m_head, sizeof(struct ether_header) + ip_hlen +
6670                     sizeof(struct tcphdr));
6671                 if (m == NULL) {
6672                         *m_head = NULL;
6673                         return (NULL);
6674                 }
6675
6676                 /* Get the TCP header length in bytes (min 20) */
6677                 th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
6678                 tcp_hlen = (th->th_off << 2);
6679
6680                 /* Make sure all IP/TCP options live in the same buffer. */
6681                 m = m_pullup(*m_head,  sizeof(struct ether_header)+ ip_hlen +
6682                     tcp_hlen);
6683                 if (m == NULL) {
6684                         *m_head = NULL;
6685                         return (NULL);
6686                 }
6687
6688                 /* IP header length and checksum will be calc'd by hardware */
6689                 ip_len = ip->ip_len;
6690                 ip->ip_len = 0;
6691                 ip->ip_sum = 0;
6692                 break;
6693         case ETHERTYPE_IPV6:
6694                 BCE_PRINTF("%s(%d): TSO over IPv6 not supported!.\n",
6695                     __FILE__, __LINE__);
6696                 m_freem(*m_head);
6697                 *m_head = NULL;
6698                 return (NULL);
6699                 /* NOT REACHED */
6700         default:
6701                 BCE_PRINTF("%s(%d): TSO enabled for unsupported protocol!.\n",
6702                     __FILE__, __LINE__);
6703                 m_freem(*m_head);
6704                 *m_head = NULL;
6705                 return (NULL);
6706         }
6707
6708         hdr_len = sizeof(struct ether_header) + ip_hlen + tcp_hlen;
6709
6710         DBPRINT(sc, BCE_EXTREME_SEND, "%s(): hdr_len = %d, e_hlen = %d, "
6711             "ip_hlen = %d, tcp_hlen = %d, ip_len = %d\n",
6712             __FUNCTION__, hdr_len, (int) sizeof(struct ether_header), ip_hlen,
6713             tcp_hlen, ip_len);
6714
6715         /* Set the LSO flag in the TX BD */
6716         *flags |= TX_BD_FLAGS_SW_LSO;
6717         /* Set the length of IP + TCP options (in 32 bit words) */
6718         *flags |= (((ip_hlen + tcp_hlen - sizeof(struct ip) -
6719             sizeof(struct tcphdr)) >> 2) << 8);
6720         return (*m_head);
6721 }
6722
6723
6724 /****************************************************************************/
6725 /* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
6726 /* memory visible to the controller.                                        */
6727 /*                                                                          */
6728 /* Returns:                                                                 */
6729 /*   0 for success, positive value for failure.                             */
6730 /* Modified:                                                                */
6731 /*   m_head: May be set to NULL if MBUF is excessively fragmented.          */
6732 /****************************************************************************/
6733 static int
6734 bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
6735 {
6736         bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
6737         bus_dmamap_t map;
6738         struct tx_bd *txbd = NULL;
6739         struct mbuf *m0;
6740         u16 prod, chain_prod, mss = 0, vlan_tag = 0, flags = 0;
6741         u32 prod_bseq;
6742
6743 #ifdef BCE_DEBUG
6744         u16 debug_prod;
6745 #endif
6746         int i, error, nsegs, rc = 0;
6747
6748         DBENTER(BCE_VERBOSE_SEND);
6749         DBPRINT(sc, BCE_INFO_SEND,
6750             "%s(enter): tx_prod = 0x%04X, tx_chain_prod = %04X, "
6751             "tx_prod_bseq = 0x%08X\n",
6752             __FUNCTION__, sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod),
6753             sc->tx_prod_bseq);
6754
6755         /* Transfer any checksum offload flags to the bd. */
6756         m0 = *m_head;
6757         if (m0->m_pkthdr.csum_flags) {
6758                 if (m0->m_pkthdr.csum_flags & CSUM_TSO) {
6759                         m0 = bce_tso_setup(sc, m_head, &flags);
6760                         if (m0 == NULL)
6761                                 goto bce_tx_encap_exit;
6762                         mss = htole16(m0->m_pkthdr.tso_segsz);
6763                 } else {
6764                         if (m0->m_pkthdr.csum_flags & CSUM_IP)
6765                                 flags |= TX_BD_FLAGS_IP_CKSUM;
6766                         if (m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
6767                                 flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
6768                 }
6769         }
6770
6771         /* Transfer any VLAN tags to the bd. */
6772         if (m0->m_flags & M_VLANTAG) {
6773                 flags |= TX_BD_FLAGS_VLAN_TAG;
6774                 vlan_tag = m0->m_pkthdr.ether_vtag;
6775         }
6776
6777         /* Map the mbuf into DMAable memory. */
6778         prod = sc->tx_prod;
6779         chain_prod = TX_CHAIN_IDX(prod);
6780         map = sc->tx_mbuf_map[chain_prod];
6781
6782         /* Map the mbuf into our DMA address space. */
6783         error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag, map, m0,
6784             segs, &nsegs, BUS_DMA_NOWAIT);
6785
6786         /* Check if the DMA mapping was successful */
6787         if (error == EFBIG) {
6788
6789                 sc->fragmented_mbuf_count++;
6790
6791                 /* Try to defrag the mbuf. */
6792                 m0 = m_collapse(*m_head, M_DONTWAIT, BCE_MAX_SEGMENTS);
6793                 if (m0 == NULL) {
6794                         /* Defrag was unsuccessful */
6795                         m_freem(*m_head);
6796                         *m_head = NULL;
6797                         sc->mbuf_alloc_failed_count++;
6798                         rc = ENOBUFS;
6799                         goto bce_tx_encap_exit;
6800                 }
6801
6802                 /* Defrag was successful, try mapping again */
6803                 *m_head = m0;
6804                 error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag, map, m0,
6805                     segs, &nsegs, BUS_DMA_NOWAIT);
6806
6807                 /* Still getting an error after a defrag. */
6808                 if (error == ENOMEM) {
6809                         /* Insufficient DMA buffers available. */
6810                         sc->dma_map_addr_tx_failed_count++;
6811                         rc = error;
6812                         goto bce_tx_encap_exit;
6813                 } else if (error != 0) {
6814                         /* Release it and return an error. */
6815                         BCE_PRINTF("%s(%d): Unknown error mapping mbuf into "
6816                             "TX chain!\n", __FILE__, __LINE__);
6817                         m_freem(m0);
6818                         *m_head = NULL;
6819                         sc->dma_map_addr_tx_failed_count++;
6820                         rc = ENOBUFS;
6821                         goto bce_tx_encap_exit;
6822                 }
6823         } else if (error == ENOMEM) {
6824                 /* Insufficient DMA buffers available. */
6825                 sc->dma_map_addr_tx_failed_count++;
6826                 rc = error;
6827                 goto bce_tx_encap_exit;
6828         } else if (error != 0) {
6829                 m_freem(m0);
6830                 *m_head = NULL;
6831                 sc->dma_map_addr_tx_failed_count++;
6832                 rc = error;
6833                 goto bce_tx_encap_exit;
6834         }
6835
6836         /* Make sure there's room in the chain */
6837         if (nsegs > (sc->max_tx_bd - sc->used_tx_bd)) {
6838                 bus_dmamap_unload(sc->tx_mbuf_tag, map);
6839                 rc = ENOBUFS;
6840                 goto bce_tx_encap_exit;
6841         }
6842
6843         /* prod points to an empty tx_bd at this point. */
6844         prod_bseq  = sc->tx_prod_bseq;
6845
6846 #ifdef BCE_DEBUG
6847         debug_prod = chain_prod;
6848 #endif
6849
6850         DBPRINT(sc, BCE_INFO_SEND,
6851             "%s(start): prod = 0x%04X, chain_prod = 0x%04X, "
6852             "prod_bseq = 0x%08X\n",
6853             __FUNCTION__, prod, chain_prod, prod_bseq);
6854
6855         /*
6856          * Cycle through each mbuf segment that makes up
6857          * the outgoing frame, gathering the mapping info
6858          * for that segment and creating a tx_bd for
6859          * the mbuf.
6860          */
6861         for (i = 0; i < nsegs ; i++) {
6862
6863                 chain_prod = TX_CHAIN_IDX(prod);
6864                 txbd= &sc->tx_bd_chain[TX_PAGE(chain_prod)]
6865                     [TX_IDX(chain_prod)];
6866
6867                 txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(segs[i].ds_addr));
6868                 txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(segs[i].ds_addr));
6869                 txbd->tx_bd_mss_nbytes = htole32(mss << 16) | 
6870                     htole16(segs[i].ds_len);
6871                 txbd->tx_bd_vlan_tag = htole16(vlan_tag);
6872                 txbd->tx_bd_flags = htole16(flags);
6873                 prod_bseq += segs[i].ds_len;
6874                 if (i == 0)
6875                         txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_START);
6876                 prod = NEXT_TX_BD(prod);
6877         }
6878
6879         /* Set the END flag on the last TX buffer descriptor. */
6880         txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_END);
6881
6882         DBRUNMSG(BCE_EXTREME_SEND, bce_dump_tx_chain(sc, debug_prod, nsegs));
6883
6884         DBPRINT(sc, BCE_INFO_SEND,
6885             "%s( end ): prod = 0x%04X, chain_prod = 0x%04X, "
6886             "prod_bseq = 0x%08X\n",
6887             __FUNCTION__, prod, chain_prod, prod_bseq);
6888
6889         /*
6890          * Ensure that the mbuf pointer for this transmission
6891          * is placed at the array index of the last
6892          * descriptor in this chain.  This is done
6893          * because a single map is used for all
6894          * segments of the mbuf and we don't want to
6895          * unload the map before all of the segments
6896          * have been freed.
6897          */
6898         sc->tx_mbuf_ptr[chain_prod] = m0;
6899         sc->used_tx_bd += nsegs;
6900
6901         /* Update some debug statistic counters */
6902         DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
6903             sc->tx_hi_watermark = sc->used_tx_bd);
6904         DBRUNIF((sc->used_tx_bd == sc->max_tx_bd), sc->tx_full_count++);
6905         DBRUNIF(sc->debug_tx_mbuf_alloc++);
6906
6907         DBRUNMSG(BCE_EXTREME_SEND, bce_dump_tx_mbuf_chain(sc, chain_prod, 1));
6908
6909         /* prod points to the next free tx_bd at this point. */
6910         sc->tx_prod = prod;
6911         sc->tx_prod_bseq = prod_bseq;
6912
6913         DBPRINT(sc, BCE_INFO_SEND,
6914             "%s(exit): prod = 0x%04X, chain_prod = %04X, "
6915             "prod_bseq = 0x%08X\n", __FUNCTION__, 
6916             sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod),
6917             sc->tx_prod_bseq);
6918
6919 bce_tx_encap_exit:
6920         DBEXIT(BCE_VERBOSE_SEND);
6921         return(rc);
6922 }
6923
6924
6925 /****************************************************************************/
6926 /* Main transmit routine when called from another routine with a lock.      */
6927 /*                                                                          */
6928 /* Returns:                                                                 */
6929 /*   Nothing.                                                               */
6930 /****************************************************************************/
6931 static void
6932 bce_start_locked(struct ifnet *ifp)
6933 {
6934         struct bce_softc *sc = ifp->if_softc;
6935         struct mbuf *m_head = NULL;
6936         int count = 0;
6937         u16 tx_prod, tx_chain_prod;
6938
6939         DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
6940
6941         BCE_LOCK_ASSERT(sc);
6942
6943         /* prod points to the next free tx_bd. */
6944         tx_prod = sc->tx_prod;
6945         tx_chain_prod = TX_CHAIN_IDX(tx_prod);
6946
6947         DBPRINT(sc, BCE_INFO_SEND,
6948             "%s(enter): tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
6949             "tx_prod_bseq = 0x%08X\n",
6950             __FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
6951
6952         /* If there's no link or the transmit queue is empty then just exit. */
6953         if (sc->bce_link_up == FALSE) {
6954                 DBPRINT(sc, BCE_INFO_SEND, "%s(): No link.\n",
6955                     __FUNCTION__);
6956                 goto bce_start_locked_exit;
6957         }
6958
6959         if (IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
6960                 DBPRINT(sc, BCE_INFO_SEND, "%s(): Transmit queue empty.\n",
6961                     __FUNCTION__);
6962                 goto bce_start_locked_exit;
6963         }
6964
6965         /*
6966          * Keep adding entries while there is space in the ring.
6967          */
6968         while (sc->used_tx_bd < sc->max_tx_bd) {
6969
6970                 /* Check for any frames to send. */
6971                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
6972
6973                 /* Stop when the transmit queue is empty. */
6974                 if (m_head == NULL)
6975                         break;
6976
6977                 /*
6978                  * Pack the data into the transmit ring. If we
6979                  * don't have room, place the mbuf back at the
6980                  * head of the queue and set the OACTIVE flag
6981                  * to wait for the NIC to drain the chain.
6982                  */
6983                 if (bce_tx_encap(sc, &m_head)) {
6984                         if (m_head != NULL)
6985                                 IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
6986                         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
6987                         DBPRINT(sc, BCE_INFO_SEND,
6988                             "TX chain is closed for business! Total "
6989                             "tx_bd used = %d\n", sc->used_tx_bd);
6990                         break;
6991                 }
6992
6993                 count++;
6994
6995                 /* Send a copy of the frame to any BPF listeners. */
6996                 ETHER_BPF_MTAP(ifp, m_head);
6997         }
6998
6999         /* Exit if no packets were dequeued. */
7000         if (count == 0) {
7001                 DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were "
7002                     "dequeued\n", __FUNCTION__);
7003                 goto bce_start_locked_exit;
7004         }
7005
7006         DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): Inserted %d frames into "
7007             "send queue.\n", __FUNCTION__, count);
7008
7009         REG_WR(sc, BCE_MQ_COMMAND, REG_RD(sc, BCE_MQ_COMMAND) | 
7010             BCE_MQ_COMMAND_NO_MAP_ERROR);
7011
7012         /* Write the mailbox and tell the chip about the waiting tx_bd's. */
7013         DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): MB_GET_CID_ADDR(TX_CID) = "
7014             "0x%08X; BCE_L2MQ_TX_HOST_BIDX = 0x%08X, sc->tx_prod = 0x%04X\n",
7015             __FUNCTION__, MB_GET_CID_ADDR(TX_CID), 
7016             BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
7017         REG_WR16(sc, MB_GET_CID_ADDR(TX_CID) + 
7018             BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
7019
7020         DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): MB_GET_CID_ADDR(TX_CID) = "
7021             "0x%08X; BCE_L2MQ_TX_HOST_BSEQ = 0x%08X, sc->tx_prod_bseq = "
7022             "0x%04X\n", __FUNCTION__, MB_GET_CID_ADDR(TX_CID), 
7023             BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
7024         REG_WR(sc, MB_GET_CID_ADDR(TX_CID) + BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
7025
7026         /* Set the tx timeout. */
7027         sc->watchdog_timer = BCE_TX_TIMEOUT;
7028
7029         DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_ctx(sc, TX_CID));
7030         DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_mq_regs(sc));
7031
7032 bce_start_locked_exit:
7033         DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
7034         return;
7035 }
7036
7037
7038 /****************************************************************************/
7039 /* Main transmit routine when called from another routine without a lock.   */
7040 /*                                                                          */
7041 /* Returns:                                                                 */
7042 /*   Nothing.                                                               */
7043 /****************************************************************************/
7044 static void
7045 bce_start(struct ifnet *ifp)
7046 {
7047         struct bce_softc *sc = ifp->if_softc;
7048
7049         DBENTER(BCE_VERBOSE_SEND);
7050
7051         BCE_LOCK(sc);
7052         bce_start_locked(ifp);
7053         BCE_UNLOCK(sc);
7054
7055         DBEXIT(BCE_VERBOSE_SEND);
7056 }
7057
7058
7059 /****************************************************************************/
7060 /* Handles any IOCTL calls from the operating system.                       */
7061 /*                                                                          */
7062 /* Returns:                                                                 */
7063 /*   0 for success, positive value for failure.                             */
7064 /****************************************************************************/
7065 static int
7066 bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
7067 {
7068         struct bce_softc *sc = ifp->if_softc;
7069         struct ifreq *ifr = (struct ifreq *) data;
7070         struct mii_data *mii;
7071         int mask, error = 0, reinit;
7072
7073         DBENTER(BCE_VERBOSE_MISC);
7074
7075         switch(command) {
7076
7077         /* Set the interface MTU. */
7078         case SIOCSIFMTU:
7079                 /* Check that the MTU setting is supported. */
7080                 if ((ifr->ifr_mtu < BCE_MIN_MTU) ||
7081                         (ifr->ifr_mtu > BCE_MAX_JUMBO_MTU)) {
7082                         error = EINVAL;
7083                         break;
7084                 }
7085
7086                 DBPRINT(sc, BCE_INFO_MISC,
7087                     "SIOCSIFMTU: Changing MTU from %d to %d\n",
7088                     (int) ifp->if_mtu, (int) ifr->ifr_mtu);
7089
7090                 BCE_LOCK(sc);
7091                 ifp->if_mtu = ifr->ifr_mtu;
7092                 reinit = 0;
7093                 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
7094                         /*
7095                          * Because allocation size is used in RX
7096                          * buffer allocation, stop controller if
7097                          * it is already running.
7098                          */
7099                         bce_stop(sc);
7100                         reinit = 1;
7101                 }
7102 #ifdef BCE_JUMBO_HDRSPLIT
7103                 /* No buffer allocation size changes are necessary. */
7104 #else
7105                 /* Recalculate our buffer allocation sizes. */
7106                 if ((ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + 
7107                      ETHER_CRC_LEN) > MCLBYTES) {
7108                         sc->rx_bd_mbuf_alloc_size = MJUM9BYTES;
7109                         sc->rx_bd_mbuf_align_pad  = 
7110                             roundup2(MJUM9BYTES, 16) - MJUM9BYTES;
7111                         sc->rx_bd_mbuf_data_len = 
7112                             sc->rx_bd_mbuf_alloc_size -
7113                             sc->rx_bd_mbuf_align_pad;
7114                 } else {
7115                         sc->rx_bd_mbuf_alloc_size = MCLBYTES;
7116                         sc->rx_bd_mbuf_align_pad  = 
7117                             roundup2(MCLBYTES, 16) - MCLBYTES;
7118                         sc->rx_bd_mbuf_data_len = 
7119                             sc->rx_bd_mbuf_alloc_size -
7120                             sc->rx_bd_mbuf_align_pad;
7121                 }
7122 #endif
7123
7124                 if (reinit != 0)
7125                         bce_init_locked(sc);
7126                 BCE_UNLOCK(sc);
7127                 break;
7128
7129         /* Set interface flags. */
7130         case SIOCSIFFLAGS:
7131                 DBPRINT(sc, BCE_VERBOSE_SPECIAL, "Received SIOCSIFFLAGS\n");
7132
7133                 BCE_LOCK(sc);
7134
7135                 /* Check if the interface is up. */
7136                 if (ifp->if_flags & IFF_UP) {
7137                         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
7138                                 /* Change promiscuous/multicast flags as necessary. */
7139                                 bce_set_rx_mode(sc);
7140                         } else {
7141                                 /* Start the HW */
7142                                 bce_init_locked(sc);
7143                         }
7144                 } else {
7145                         /* The interface is down, check if driver is running. */
7146                         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
7147                                 bce_stop(sc);
7148
7149                                 /* If MFW is running, restart the controller a bit. */
7150                                 if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
7151                                         bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
7152                                         bce_chipinit(sc);
7153                                         bce_mgmt_init_locked(sc);
7154                                 }
7155                         }
7156                 }
7157
7158                 BCE_UNLOCK(sc);
7159                 break;
7160
7161         /* Add/Delete multicast address */
7162         case SIOCADDMULTI:
7163         case SIOCDELMULTI:
7164                 DBPRINT(sc, BCE_VERBOSE_MISC, 
7165                     "Received SIOCADDMULTI/SIOCDELMULTI\n");
7166
7167                 BCE_LOCK(sc);
7168                 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
7169                         bce_set_rx_mode(sc);
7170                 BCE_UNLOCK(sc);
7171
7172                 break;
7173
7174         /* Set/Get Interface media */
7175         case SIOCSIFMEDIA:
7176         case SIOCGIFMEDIA:
7177                 DBPRINT(sc, BCE_VERBOSE_MISC, 
7178                     "Received SIOCSIFMEDIA/SIOCGIFMEDIA\n");
7179
7180                 mii = device_get_softc(sc->bce_miibus);
7181                 error = ifmedia_ioctl(ifp, ifr,
7182                     &mii->mii_media, command);
7183                 break;
7184
7185         /* Set interface capability */
7186         case SIOCSIFCAP:
7187                 mask = ifr->ifr_reqcap ^ ifp->if_capenable;
7188                 DBPRINT(sc, BCE_INFO_MISC, 
7189                     "Received SIOCSIFCAP = 0x%08X\n", (u32) mask);
7190
7191                 /* Toggle the TX checksum capabilities enable flag. */
7192                 if (mask & IFCAP_TXCSUM &&
7193                     ifp->if_capabilities & IFCAP_TXCSUM) {
7194                         ifp->if_capenable ^= IFCAP_TXCSUM;
7195                         if (IFCAP_TXCSUM & ifp->if_capenable)
7196                                 ifp->if_hwassist |= BCE_IF_HWASSIST;
7197                         else
7198                                 ifp->if_hwassist &= ~BCE_IF_HWASSIST;
7199                 }
7200
7201                 /* Toggle the RX checksum capabilities enable flag. */
7202                 if (mask & IFCAP_RXCSUM &&
7203                     ifp->if_capabilities & IFCAP_RXCSUM)
7204                         ifp->if_capenable ^= IFCAP_RXCSUM;
7205
7206                 /* Toggle the TSO capabilities enable flag. */
7207                 if (bce_tso_enable && (mask & IFCAP_TSO4) &&
7208                     ifp->if_capabilities & IFCAP_TSO4) {
7209                         ifp->if_capenable ^= IFCAP_TSO4;
7210                         if (IFCAP_TSO4 & ifp->if_capenable)
7211                                 ifp->if_hwassist |= CSUM_TSO;
7212                         else
7213                                 ifp->if_hwassist &= ~CSUM_TSO;
7214                 }
7215
7216                 if (mask & IFCAP_VLAN_HWCSUM &&
7217                     ifp->if_capabilities & IFCAP_VLAN_HWCSUM)
7218                         ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
7219
7220                 if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
7221                     (ifp->if_capabilities & IFCAP_VLAN_HWTSO) != 0)
7222                         ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
7223                 /*
7224                  * Don't actually disable VLAN tag stripping as
7225                  * management firmware (ASF/IPMI/UMP) requires the
7226                  * feature. If VLAN tag stripping is disabled driver
7227                  * will manually reconstruct the VLAN frame by
7228                  * appending stripped VLAN tag.
7229                  */
7230                 if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
7231                     (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)) {
7232                         ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
7233                         if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING)
7234                             == 0)
7235                                 ifp->if_capenable &= ~IFCAP_VLAN_HWTSO;
7236                 }
7237                 VLAN_CAPABILITIES(ifp);
7238                 break;
7239         default:
7240                 /* We don't know how to handle the IOCTL, pass it on. */
7241                 error = ether_ioctl(ifp, command, data);
7242                 break;
7243         }
7244
7245         DBEXIT(BCE_VERBOSE_MISC);
7246         return(error);
7247 }
7248
7249
7250 /****************************************************************************/
7251 /* Transmit timeout handler.                                                */
7252 /*                                                                          */
7253 /* Returns:                                                                 */
7254 /*   Nothing.                                                               */
7255 /****************************************************************************/
7256 static void
7257 bce_watchdog(struct bce_softc *sc)
7258 {
7259         DBENTER(BCE_EXTREME_SEND);
7260
7261         BCE_LOCK_ASSERT(sc);
7262
7263         /* If the watchdog timer hasn't expired then just exit. */
7264         if (sc->watchdog_timer == 0 || --sc->watchdog_timer)
7265                 goto bce_watchdog_exit;
7266
7267         /* If pause frames are active then don't reset the hardware. */
7268         /* ToDo: Should we reset the timer here? */
7269         if (REG_RD(sc, BCE_EMAC_TX_STATUS) & BCE_EMAC_TX_STATUS_XOFFED)
7270                 goto bce_watchdog_exit;
7271
7272         BCE_PRINTF("%s(%d): Watchdog timeout occurred, resetting!\n",
7273                 __FILE__, __LINE__);
7274
7275         DBRUNMSG(BCE_INFO,
7276             bce_dump_driver_state(sc);
7277             bce_dump_status_block(sc);
7278             bce_dump_stats_block(sc);
7279             bce_dump_ftqs(sc);
7280             bce_dump_txp_state(sc, 0);
7281             bce_dump_rxp_state(sc, 0);
7282             bce_dump_tpat_state(sc, 0);
7283             bce_dump_cp_state(sc, 0);
7284             bce_dump_com_state(sc, 0));
7285
7286         DBRUN(bce_breakpoint(sc));
7287
7288         sc->bce_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
7289
7290         bce_init_locked(sc);
7291         sc->bce_ifp->if_oerrors++;
7292
7293 bce_watchdog_exit:
7294         DBEXIT(BCE_EXTREME_SEND);
7295 }
7296
7297
7298 /*
7299  * Interrupt handler.
7300  */
7301 /****************************************************************************/
7302 /* Main interrupt entry point.  Verifies that the controller generated the  */
7303 /* interrupt and then calls a separate routine for handle the various       */
7304 /* interrupt causes (PHY, TX, RX).                                          */
7305 /*                                                                          */
7306 /* Returns:                                                                 */
7307 /*   0 for success, positive value for failure.                             */
7308 /****************************************************************************/
7309 static void
7310 bce_intr(void *xsc)
7311 {
7312         struct bce_softc *sc;
7313         struct ifnet *ifp;
7314         u32 status_attn_bits;
7315         u16 hw_rx_cons, hw_tx_cons;
7316
7317         sc = xsc;
7318         ifp = sc->bce_ifp;
7319
7320         DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
7321         DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_status_block(sc));
7322         DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_stats_block(sc));
7323
7324         BCE_LOCK(sc);
7325
7326         DBRUN(sc->interrupts_generated++);
7327
7328         /* Synchnorize before we read from interface's status block */
7329         bus_dmamap_sync(sc->status_tag, sc->status_map,
7330             BUS_DMASYNC_POSTREAD);
7331
7332         /*
7333          * If the hardware status block index
7334          * matches the last value read by the
7335          * driver and we haven't asserted our
7336          * interrupt then there's nothing to do.
7337          */
7338         if ((sc->status_block->status_idx == sc->last_status_idx) &&
7339             (REG_RD(sc, BCE_PCICFG_MISC_STATUS) & 
7340              BCE_PCICFG_MISC_STATUS_INTA_VALUE)) {
7341                 DBPRINT(sc, BCE_VERBOSE_INTR, "%s(): Spurious interrupt.\n",
7342                     __FUNCTION__);
7343                 goto bce_intr_exit;
7344         }
7345
7346         /* Ack the interrupt and stop others from occuring. */
7347         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
7348             BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
7349             BCE_PCICFG_INT_ACK_CMD_MASK_INT);
7350
7351         /* Check if the hardware has finished any work. */
7352         hw_rx_cons = bce_get_hw_rx_cons(sc);
7353         hw_tx_cons = bce_get_hw_tx_cons(sc);
7354
7355         /* Keep processing data as long as there is work to do. */
7356         for (;;) {
7357
7358                 status_attn_bits = sc->status_block->status_attn_bits;
7359
7360                 DBRUNIF(DB_RANDOMTRUE(unexpected_attention_sim_control),
7361                     BCE_PRINTF("Simulating unexpected status attention "
7362                     "bit set.");
7363                     sc->unexpected_attention_sim_count++;
7364                     status_attn_bits = status_attn_bits | 
7365                     STATUS_ATTN_BITS_PARITY_ERROR);
7366
7367                 /* Was it a link change interrupt? */
7368                 if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
7369                     (sc->status_block->status_attn_bits_ack & 
7370                      STATUS_ATTN_BITS_LINK_STATE)) {
7371                         bce_phy_intr(sc);
7372
7373                         /* Clear transient updates during link state change. */
7374                         REG_WR(sc, BCE_HC_COMMAND, sc->hc_command | 
7375                             BCE_HC_COMMAND_COAL_NOW_WO_INT);
7376                         REG_RD(sc, BCE_HC_COMMAND);
7377                 }
7378
7379                 /* If any other attention is asserted, the chip is toast. */
7380                 if (((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
7381                     (sc->status_block->status_attn_bits_ack &
7382                     ~STATUS_ATTN_BITS_LINK_STATE))) {
7383
7384                         sc->unexpected_attention_count++;
7385
7386                         BCE_PRINTF("%s(%d): Fatal attention detected: "
7387                             "0x%08X\n", __FILE__, __LINE__, 
7388                             sc->status_block->status_attn_bits);
7389
7390                         DBRUNMSG(BCE_FATAL,
7391                             if (unexpected_attention_sim_control == 0)
7392                                 bce_breakpoint(sc));
7393
7394                         bce_init_locked(sc);
7395                         goto bce_intr_exit;
7396                 }
7397
7398                 /* Check for any completed RX frames. */
7399                 if (hw_rx_cons != sc->hw_rx_cons)
7400                         bce_rx_intr(sc);
7401
7402                 /* Check for any completed TX frames. */
7403                 if (hw_tx_cons != sc->hw_tx_cons)
7404                         bce_tx_intr(sc);
7405
7406                 /* Save status block index value for the next interrupt. */
7407                 sc->last_status_idx = sc->status_block->status_idx;
7408
7409                 /*
7410                  * Prevent speculative reads from getting
7411                  * ahead of the status block.
7412                  */
7413                 bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
7414                     BUS_SPACE_BARRIER_READ);
7415
7416                 /*
7417                  * If there's no work left then exit the
7418                  * interrupt service routine.
7419                  */
7420                 hw_rx_cons = bce_get_hw_rx_cons(sc);
7421                 hw_tx_cons = bce_get_hw_tx_cons(sc);
7422
7423                 if ((hw_rx_cons == sc->hw_rx_cons) && 
7424                     (hw_tx_cons == sc->hw_tx_cons))
7425                         break;
7426
7427         }
7428
7429         bus_dmamap_sync(sc->status_tag, sc->status_map,
7430             BUS_DMASYNC_PREREAD);
7431
7432         /* Re-enable interrupts. */
7433         bce_enable_intr(sc, 0);
7434
7435         /* Handle any frames that arrived while handling the interrupt. */
7436         if (ifp->if_drv_flags & IFF_DRV_RUNNING && 
7437             !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
7438                 bce_start_locked(ifp);
7439
7440 bce_intr_exit:
7441         BCE_UNLOCK(sc);
7442
7443         DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
7444 }
7445
7446
7447 /****************************************************************************/
7448 /* Programs the various packet receive modes (broadcast and multicast).     */
7449 /*                                                                          */
7450 /* Returns:                                                                 */
7451 /*   Nothing.                                                               */
7452 /****************************************************************************/
7453 static void
7454 bce_set_rx_mode(struct bce_softc *sc)
7455 {
7456         struct ifnet *ifp;
7457         struct ifmultiaddr *ifma;
7458         u32 hashes[NUM_MC_HASH_REGISTERS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
7459         u32 rx_mode, sort_mode;
7460         int h, i;
7461
7462         DBENTER(BCE_VERBOSE_MISC);
7463
7464         BCE_LOCK_ASSERT(sc);
7465
7466         ifp = sc->bce_ifp;
7467
7468         /* Initialize receive mode default settings. */
7469         rx_mode   = sc->rx_mode & ~(BCE_EMAC_RX_MODE_PROMISCUOUS |
7470             BCE_EMAC_RX_MODE_KEEP_VLAN_TAG);
7471         sort_mode = 1 | BCE_RPM_SORT_USER0_BC_EN;
7472
7473         /*
7474          * ASF/IPMI/UMP firmware requires that VLAN tag stripping
7475          * be enbled.
7476          */
7477         if (!(BCE_IF_CAPABILITIES & IFCAP_VLAN_HWTAGGING) &&
7478             (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)))
7479                 rx_mode |= BCE_EMAC_RX_MODE_KEEP_VLAN_TAG;
7480
7481         /*
7482          * Check for promiscuous, all multicast, or selected
7483          * multicast address filtering.
7484          */
7485         if (ifp->if_flags & IFF_PROMISC) {
7486                 DBPRINT(sc, BCE_INFO_MISC, "Enabling promiscuous mode.\n");
7487
7488                 /* Enable promiscuous mode. */
7489                 rx_mode |= BCE_EMAC_RX_MODE_PROMISCUOUS;
7490                 sort_mode |= BCE_RPM_SORT_USER0_PROM_EN;
7491         } else if (ifp->if_flags & IFF_ALLMULTI) {
7492                 DBPRINT(sc, BCE_INFO_MISC, "Enabling all multicast mode.\n");
7493
7494                 /* Enable all multicast addresses. */
7495                 for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
7496                         REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), 0xffffffff);
7497         }
7498                 sort_mode |= BCE_RPM_SORT_USER0_MC_EN;
7499         } else {
7500                 /* Accept one or more multicast(s). */
7501                 DBPRINT(sc, BCE_INFO_MISC, "Enabling selective multicast mode.\n");
7502
7503                 if_maddr_rlock(ifp);
7504                 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
7505                         if (ifma->ifma_addr->sa_family != AF_LINK)
7506                                 continue;
7507                         h = ether_crc32_le(LLADDR((struct sockaddr_dl *)
7508                             ifma->ifma_addr), ETHER_ADDR_LEN) & 0xFF;
7509                             hashes[(h & 0xE0) >> 5] |= 1 << (h & 0x1F);
7510                 }
7511                 if_maddr_runlock(ifp);
7512
7513                 for (i = 0; i < NUM_MC_HASH_REGISTERS; i++)
7514                         REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), hashes[i]);
7515
7516                 sort_mode |= BCE_RPM_SORT_USER0_MC_HSH_EN;
7517         }
7518
7519         /* Only make changes if the recive mode has actually changed. */
7520         if (rx_mode != sc->rx_mode) {
7521                 DBPRINT(sc, BCE_VERBOSE_MISC, "Enabling new receive mode: "
7522                     "0x%08X\n", rx_mode);
7523
7524                 sc->rx_mode = rx_mode;
7525                 REG_WR(sc, BCE_EMAC_RX_MODE, rx_mode);
7526         }
7527
7528         /* Disable and clear the exisitng sort before enabling a new sort. */
7529         REG_WR(sc, BCE_RPM_SORT_USER0, 0x0);
7530         REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode);
7531         REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode | BCE_RPM_SORT_USER0_ENA);
7532
7533         DBEXIT(BCE_VERBOSE_MISC);
7534 }
7535
7536
7537 /****************************************************************************/
7538 /* Called periodically to updates statistics from the controllers           */
7539 /* statistics block.                                                        */
7540 /*                                                                          */
7541 /* Returns:                                                                 */
7542 /*   Nothing.                                                               */
7543 /****************************************************************************/
7544 static void
7545 bce_stats_update(struct bce_softc *sc)
7546 {
7547         struct ifnet *ifp;
7548         struct statistics_block *stats;
7549
7550         DBENTER(BCE_EXTREME_MISC);
7551
7552         ifp = sc->bce_ifp;
7553
7554         stats = (struct statistics_block *) sc->stats_block;
7555
7556         /*
7557          * Certain controllers don't report
7558          * carrier sense errors correctly.
7559          * See errata E11_5708CA0_1165.
7560          */
7561         if (!(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
7562             !(BCE_CHIP_ID(sc) == BCE_CHIP_ID_5708_A0))
7563                 ifp->if_oerrors += 
7564                     (u_long) stats->stat_Dot3StatsCarrierSenseErrors;
7565
7566         /*
7567          * Update the sysctl statistics from the
7568          * hardware statistics.
7569          */
7570         sc->stat_IfHCInOctets =
7571             ((u64) stats->stat_IfHCInOctets_hi << 32) +
7572              (u64) stats->stat_IfHCInOctets_lo;
7573
7574         sc->stat_IfHCInBadOctets =
7575             ((u64) stats->stat_IfHCInBadOctets_hi << 32) +
7576              (u64) stats->stat_IfHCInBadOctets_lo;
7577
7578         sc->stat_IfHCOutOctets =
7579             ((u64) stats->stat_IfHCOutOctets_hi << 32) +
7580              (u64) stats->stat_IfHCOutOctets_lo;
7581
7582         sc->stat_IfHCOutBadOctets =
7583             ((u64) stats->stat_IfHCOutBadOctets_hi << 32) +
7584              (u64) stats->stat_IfHCOutBadOctets_lo;
7585
7586         sc->stat_IfHCInUcastPkts =
7587             ((u64) stats->stat_IfHCInUcastPkts_hi << 32) +
7588              (u64) stats->stat_IfHCInUcastPkts_lo;
7589
7590         sc->stat_IfHCInMulticastPkts =
7591             ((u64) stats->stat_IfHCInMulticastPkts_hi << 32) +
7592              (u64) stats->stat_IfHCInMulticastPkts_lo;
7593
7594         sc->stat_IfHCInBroadcastPkts =
7595             ((u64) stats->stat_IfHCInBroadcastPkts_hi << 32) +
7596              (u64) stats->stat_IfHCInBroadcastPkts_lo;
7597
7598         sc->stat_IfHCOutUcastPkts =
7599             ((u64) stats->stat_IfHCOutUcastPkts_hi << 32) +
7600              (u64) stats->stat_IfHCOutUcastPkts_lo;
7601
7602         sc->stat_IfHCOutMulticastPkts =
7603             ((u64) stats->stat_IfHCOutMulticastPkts_hi << 32) +
7604              (u64) stats->stat_IfHCOutMulticastPkts_lo;
7605
7606         sc->stat_IfHCOutBroadcastPkts =
7607             ((u64) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
7608              (u64) stats->stat_IfHCOutBroadcastPkts_lo;
7609
7610         /* ToDo: Preserve counters beyond 32 bits? */
7611         /* ToDo: Read the statistics from auto-clear regs? */
7612
7613         sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors =
7614             stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
7615
7616         sc->stat_Dot3StatsCarrierSenseErrors =
7617             stats->stat_Dot3StatsCarrierSenseErrors;
7618
7619         sc->stat_Dot3StatsFCSErrors =
7620             stats->stat_Dot3StatsFCSErrors;
7621
7622         sc->stat_Dot3StatsAlignmentErrors =
7623             stats->stat_Dot3StatsAlignmentErrors;
7624
7625         sc->stat_Dot3StatsSingleCollisionFrames =
7626             stats->stat_Dot3StatsSingleCollisionFrames;
7627
7628         sc->stat_Dot3StatsMultipleCollisionFrames =
7629             stats->stat_Dot3StatsMultipleCollisionFrames;
7630
7631         sc->stat_Dot3StatsDeferredTransmissions =
7632             stats->stat_Dot3StatsDeferredTransmissions;
7633
7634         sc->stat_Dot3StatsExcessiveCollisions =
7635             stats->stat_Dot3StatsExcessiveCollisions;
7636
7637         sc->stat_Dot3StatsLateCollisions =
7638             stats->stat_Dot3StatsLateCollisions;
7639
7640         sc->stat_EtherStatsCollisions =
7641             stats->stat_EtherStatsCollisions;
7642
7643         sc->stat_EtherStatsFragments =
7644             stats->stat_EtherStatsFragments;
7645
7646         sc->stat_EtherStatsJabbers =
7647             stats->stat_EtherStatsJabbers;
7648
7649         sc->stat_EtherStatsUndersizePkts =
7650             stats->stat_EtherStatsUndersizePkts;
7651
7652         sc->stat_EtherStatsOversizePkts =
7653              stats->stat_EtherStatsOversizePkts;
7654
7655         sc->stat_EtherStatsPktsRx64Octets =
7656             stats->stat_EtherStatsPktsRx64Octets;
7657
7658         sc->stat_EtherStatsPktsRx65Octetsto127Octets =
7659             stats->stat_EtherStatsPktsRx65Octetsto127Octets;
7660
7661         sc->stat_EtherStatsPktsRx128Octetsto255Octets =
7662             stats->stat_EtherStatsPktsRx128Octetsto255Octets;
7663
7664         sc->stat_EtherStatsPktsRx256Octetsto511Octets =
7665             stats->stat_EtherStatsPktsRx256Octetsto511Octets;
7666
7667         sc->stat_EtherStatsPktsRx512Octetsto1023Octets =
7668             stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
7669
7670         sc->stat_EtherStatsPktsRx1024Octetsto1522Octets =
7671             stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
7672
7673         sc->stat_EtherStatsPktsRx1523Octetsto9022Octets =
7674             stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
7675
7676         sc->stat_EtherStatsPktsTx64Octets =
7677             stats->stat_EtherStatsPktsTx64Octets;
7678
7679         sc->stat_EtherStatsPktsTx65Octetsto127Octets =
7680             stats->stat_EtherStatsPktsTx65Octetsto127Octets;
7681
7682         sc->stat_EtherStatsPktsTx128Octetsto255Octets =
7683             stats->stat_EtherStatsPktsTx128Octetsto255Octets;
7684
7685         sc->stat_EtherStatsPktsTx256Octetsto511Octets =
7686             stats->stat_EtherStatsPktsTx256Octetsto511Octets;
7687
7688         sc->stat_EtherStatsPktsTx512Octetsto1023Octets =
7689             stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
7690
7691         sc->stat_EtherStatsPktsTx1024Octetsto1522Octets =
7692             stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
7693
7694         sc->stat_EtherStatsPktsTx1523Octetsto9022Octets =
7695             stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
7696
7697         sc->stat_XonPauseFramesReceived =
7698             stats->stat_XonPauseFramesReceived;
7699
7700         sc->stat_XoffPauseFramesReceived =
7701             stats->stat_XoffPauseFramesReceived;
7702
7703         sc->stat_OutXonSent =
7704             stats->stat_OutXonSent;
7705
7706         sc->stat_OutXoffSent =
7707             stats->stat_OutXoffSent;
7708
7709         sc->stat_FlowControlDone =
7710             stats->stat_FlowControlDone;
7711
7712         sc->stat_MacControlFramesReceived =
7713             stats->stat_MacControlFramesReceived;
7714
7715         sc->stat_XoffStateEntered =
7716             stats->stat_XoffStateEntered;
7717
7718         sc->stat_IfInFramesL2FilterDiscards =
7719             stats->stat_IfInFramesL2FilterDiscards;
7720
7721         sc->stat_IfInRuleCheckerDiscards =
7722             stats->stat_IfInRuleCheckerDiscards;
7723
7724         sc->stat_IfInFTQDiscards =
7725             stats->stat_IfInFTQDiscards;
7726
7727         sc->stat_IfInMBUFDiscards =
7728             stats->stat_IfInMBUFDiscards;
7729
7730         sc->stat_IfInRuleCheckerP4Hit =
7731             stats->stat_IfInRuleCheckerP4Hit;
7732
7733         sc->stat_CatchupInRuleCheckerDiscards =
7734             stats->stat_CatchupInRuleCheckerDiscards;
7735
7736         sc->stat_CatchupInFTQDiscards =
7737             stats->stat_CatchupInFTQDiscards;
7738
7739         sc->stat_CatchupInMBUFDiscards =
7740             stats->stat_CatchupInMBUFDiscards;
7741
7742         sc->stat_CatchupInRuleCheckerP4Hit =
7743             stats->stat_CatchupInRuleCheckerP4Hit;
7744
7745         sc->com_no_buffers = REG_RD_IND(sc, 0x120084);
7746
7747         /*
7748          * Update the interface statistics from the
7749          * hardware statistics.
7750          */
7751         ifp->if_collisions =
7752             (u_long) sc->stat_EtherStatsCollisions;
7753
7754         /* ToDo: This method loses soft errors. */
7755         ifp->if_ierrors =
7756             (u_long) sc->stat_EtherStatsUndersizePkts +
7757             (u_long) sc->stat_EtherStatsOversizePkts +
7758             (u_long) sc->stat_IfInMBUFDiscards +
7759             (u_long) sc->stat_Dot3StatsAlignmentErrors +
7760             (u_long) sc->stat_Dot3StatsFCSErrors +
7761             (u_long) sc->stat_IfInRuleCheckerDiscards +
7762             (u_long) sc->stat_IfInFTQDiscards +
7763             (u_long) sc->com_no_buffers;
7764
7765         /* ToDo: This method loses soft errors. */
7766         ifp->if_oerrors =
7767             (u_long) sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
7768             (u_long) sc->stat_Dot3StatsExcessiveCollisions +
7769             (u_long) sc->stat_Dot3StatsLateCollisions;
7770
7771         /* ToDo: Add additional statistics? */
7772
7773         DBEXIT(BCE_EXTREME_MISC);
7774 }
7775
7776
7777 /****************************************************************************/
7778 /* Periodic function to notify the bootcode that the driver is still        */
7779 /* present.                                                                 */
7780 /*                                                                          */
7781 /* Returns:                                                                 */
7782 /*   Nothing.                                                               */
7783 /****************************************************************************/
7784 static void
7785 bce_pulse(void *xsc)
7786 {
7787         struct bce_softc *sc = xsc;
7788         u32 msg;
7789
7790         DBENTER(BCE_EXTREME_MISC);
7791
7792         BCE_LOCK_ASSERT(sc);
7793
7794         /* Tell the firmware that the driver is still running. */
7795         msg = (u32) ++sc->bce_fw_drv_pulse_wr_seq;
7796         bce_shmem_wr(sc, BCE_DRV_PULSE_MB, msg);
7797
7798         /* Update the bootcode condition. */
7799         sc->bc_state = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
7800
7801         /* Report whether the bootcode still knows the driver is running. */
7802         if (sc->bce_drv_cardiac_arrest == FALSE) {
7803                 if (!(sc->bc_state & BCE_CONDITION_DRV_PRESENT)) {
7804                         sc->bce_drv_cardiac_arrest = TRUE;
7805                         BCE_PRINTF("%s(): Bootcode lost the driver pulse! "
7806                             "(bc_state = 0x%08X)\n", __FUNCTION__, 
7807                             sc->bc_state);
7808                 }
7809         } else {
7810                 /*
7811                  * Not supported by all bootcode versions.
7812                  * (v5.0.11+ and v5.2.1+)  Older bootcode
7813                  * will require the driver to reset the
7814                  * controller to clear this condition.
7815                  */
7816                 if (sc->bc_state & BCE_CONDITION_DRV_PRESENT) {
7817                         sc->bce_drv_cardiac_arrest = FALSE;
7818                         BCE_PRINTF("%s(): Bootcode found the driver pulse! "
7819                             "(bc_state = 0x%08X)\n", __FUNCTION__, 
7820                             sc->bc_state);
7821                 }
7822         }
7823
7824
7825         /* Schedule the next pulse. */
7826         callout_reset(&sc->bce_pulse_callout, hz, bce_pulse, sc);
7827
7828         DBEXIT(BCE_EXTREME_MISC);
7829 }
7830
7831
7832 /****************************************************************************/
7833 /* Periodic function to perform maintenance tasks.                          */
7834 /*                                                                          */
7835 /* Returns:                                                                 */
7836 /*   Nothing.                                                               */
7837 /****************************************************************************/
7838 static void
7839 bce_tick(void *xsc)
7840 {
7841         struct bce_softc *sc = xsc;
7842         struct mii_data *mii;
7843         struct ifnet *ifp;
7844
7845         ifp = sc->bce_ifp;
7846
7847         DBENTER(BCE_EXTREME_MISC);
7848
7849         BCE_LOCK_ASSERT(sc);
7850
7851         /* Schedule the next tick. */
7852         callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
7853
7854         /* Update the statistics from the hardware statistics block. */
7855         bce_stats_update(sc);
7856
7857         /* Top off the receive and page chains. */
7858 #ifdef BCE_JUMBO_HDRSPLIT
7859         bce_fill_pg_chain(sc);
7860 #endif
7861         bce_fill_rx_chain(sc);
7862
7863         /* Check that chip hasn't hung. */
7864         bce_watchdog(sc);
7865
7866         /* If link is up already up then we're done. */
7867         if (sc->bce_link_up == TRUE)
7868                 goto bce_tick_exit;
7869
7870         /* Link is down.  Check what the PHY's doing. */
7871         mii = device_get_softc(sc->bce_miibus);
7872         mii_tick(mii);
7873
7874         /* Check if the link has come up. */
7875         if ((mii->mii_media_status & IFM_ACTIVE) &&
7876             (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)) {
7877                 DBPRINT(sc, BCE_VERBOSE_MISC, 
7878                     "%s(): Link up!\n", __FUNCTION__);
7879                 sc->bce_link_up = TRUE;
7880                 if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
7881                     IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX ||
7882                     IFM_SUBTYPE(mii->mii_media_active) == IFM_2500_SX) &&
7883                     bootverbose)
7884                         BCE_PRINTF("Gigabit link up!\n");
7885
7886                 /* Now that link is up, handle any outstanding TX traffic. */
7887                 if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
7888                         DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Found "
7889                             "pending TX traffic.\n", __FUNCTION__);
7890                         bce_start_locked(ifp);
7891                 }
7892         }
7893
7894 bce_tick_exit:
7895         DBEXIT(BCE_EXTREME_MISC);
7896         return;
7897 }
7898
7899
7900 #ifdef BCE_DEBUG
7901 /****************************************************************************/
7902 /* Allows the driver state to be dumped through the sysctl interface.       */
7903 /*                                                                          */
7904 /* Returns:                                                                 */
7905 /*   0 for success, positive value for failure.                             */
7906 /****************************************************************************/
7907 static int
7908 bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS)
7909 {
7910         int error;
7911         int result;
7912         struct bce_softc *sc;
7913
7914         result = -1;
7915         error = sysctl_handle_int(oidp, &result, 0, req);
7916
7917         if (error || !req->newptr)
7918                 return (error);
7919
7920         if (result == 1) {
7921                 sc = (struct bce_softc *)arg1;
7922                 bce_dump_driver_state(sc);
7923         }
7924
7925         return error;
7926 }
7927
7928
7929 /****************************************************************************/
7930 /* Allows the hardware state to be dumped through the sysctl interface.     */
7931 /*                                                                          */
7932 /* Returns:                                                                 */
7933 /*   0 for success, positive value for failure.                             */
7934 /****************************************************************************/
7935 static int
7936 bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS)
7937 {
7938         int error;
7939         int result;
7940         struct bce_softc *sc;
7941
7942         result = -1;
7943         error = sysctl_handle_int(oidp, &result, 0, req);
7944
7945         if (error || !req->newptr)
7946                 return (error);
7947
7948         if (result == 1) {
7949                 sc = (struct bce_softc *)arg1;
7950                 bce_dump_hw_state(sc);
7951         }
7952
7953         return error;
7954 }
7955
7956
7957 /****************************************************************************/
7958 /* Allows the status block to be dumped through the sysctl interface.       */
7959 /*                                                                          */
7960 /* Returns:                                                                 */
7961 /*   0 for success, positive value for failure.                             */
7962 /****************************************************************************/
7963 static int
7964 bce_sysctl_status_block(SYSCTL_HANDLER_ARGS)
7965 {
7966         int error;
7967         int result;
7968         struct bce_softc *sc;
7969
7970         result = -1;
7971         error = sysctl_handle_int(oidp, &result, 0, req);
7972
7973         if (error || !req->newptr)
7974                 return (error);
7975
7976         if (result == 1) {
7977                 sc = (struct bce_softc *)arg1;
7978                 bce_dump_status_block(sc);
7979         }
7980
7981         return error;
7982 }
7983
7984
7985 /****************************************************************************/
7986 /* Allows the stats block to be dumped through the sysctl interface.        */
7987 /*                                                                          */
7988 /* Returns:                                                                 */
7989 /*   0 for success, positive value for failure.                             */
7990 /****************************************************************************/
7991 static int
7992 bce_sysctl_stats_block(SYSCTL_HANDLER_ARGS)
7993 {
7994         int error;
7995         int result;
7996         struct bce_softc *sc;
7997
7998         result = -1;
7999         error = sysctl_handle_int(oidp, &result, 0, req);
8000
8001         if (error || !req->newptr)
8002                 return (error);
8003
8004         if (result == 1) {
8005                 sc = (struct bce_softc *)arg1;
8006                 bce_dump_stats_block(sc);
8007         }
8008
8009         return error;
8010 }
8011
8012
8013 /****************************************************************************/
8014 /* Allows the bootcode state to be dumped through the sysctl interface.     */
8015 /*                                                                          */
8016 /* Returns:                                                                 */
8017 /*   0 for success, positive value for failure.                             */
8018 /****************************************************************************/
8019 static int
8020 bce_sysctl_bc_state(SYSCTL_HANDLER_ARGS)
8021 {
8022         int error;
8023         int result;
8024         struct bce_softc *sc;
8025
8026         result = -1;
8027         error = sysctl_handle_int(oidp, &result, 0, req);
8028
8029         if (error || !req->newptr)
8030                 return (error);
8031
8032         if (result == 1) {
8033                 sc = (struct bce_softc *)arg1;
8034                 bce_dump_bc_state(sc);
8035         }
8036
8037         return error;
8038 }
8039
8040
8041 /****************************************************************************/
8042 /* Provides a sysctl interface to allow dumping the RX BD chain.            */
8043 /*                                                                          */
8044 /* Returns:                                                                 */
8045 /*   0 for success, positive value for failure.                             */
8046 /****************************************************************************/
8047 static int
8048 bce_sysctl_dump_rx_bd_chain(SYSCTL_HANDLER_ARGS)
8049 {
8050         int error;
8051         int result;
8052         struct bce_softc *sc;
8053
8054         result = -1;
8055         error = sysctl_handle_int(oidp, &result, 0, req);
8056
8057         if (error || !req->newptr)
8058                 return (error);
8059
8060         if (result == 1) {
8061                 sc = (struct bce_softc *)arg1;
8062                 bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD);
8063         }
8064
8065         return error;
8066 }
8067
8068
8069 /****************************************************************************/
8070 /* Provides a sysctl interface to allow dumping the RX MBUF chain.          */
8071 /*                                                                          */
8072 /* Returns:                                                                 */
8073 /*   0 for success, positive value for failure.                             */
8074 /****************************************************************************/
8075 static int
8076 bce_sysctl_dump_rx_mbuf_chain(SYSCTL_HANDLER_ARGS)
8077 {
8078         int error;
8079         int result;
8080         struct bce_softc *sc;
8081
8082         result = -1;
8083         error = sysctl_handle_int(oidp, &result, 0, req);
8084
8085         if (error || !req->newptr)
8086                 return (error);
8087
8088         if (result == 1) {
8089                 sc = (struct bce_softc *)arg1;
8090                 bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD);
8091         }
8092
8093         return error;
8094 }
8095
8096
8097 /****************************************************************************/
8098 /* Provides a sysctl interface to allow dumping the TX chain.               */
8099 /*                                                                          */
8100 /* Returns:                                                                 */
8101 /*   0 for success, positive value for failure.                             */
8102 /****************************************************************************/
8103 static int
8104 bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
8105 {
8106         int error;
8107         int result;
8108         struct bce_softc *sc;
8109
8110         result = -1;
8111         error = sysctl_handle_int(oidp, &result, 0, req);
8112
8113         if (error || !req->newptr)
8114                 return (error);
8115
8116         if (result == 1) {
8117                 sc = (struct bce_softc *)arg1;
8118                 bce_dump_tx_chain(sc, 0, TOTAL_TX_BD);
8119         }
8120
8121         return error;
8122 }
8123
8124
8125 #ifdef BCE_JUMBO_HDRSPLIT
8126 /****************************************************************************/
8127 /* Provides a sysctl interface to allow dumping the page chain.             */
8128 /*                                                                          */
8129 /* Returns:                                                                 */
8130 /*   0 for success, positive value for failure.                             */
8131 /****************************************************************************/
8132 static int
8133 bce_sysctl_dump_pg_chain(SYSCTL_HANDLER_ARGS)
8134 {
8135         int error;
8136         int result;
8137         struct bce_softc *sc;
8138
8139         result = -1;
8140         error = sysctl_handle_int(oidp, &result, 0, req);
8141
8142         if (error || !req->newptr)
8143                 return (error);
8144
8145         if (result == 1) {
8146                 sc = (struct bce_softc *)arg1;
8147                 bce_dump_pg_chain(sc, 0, TOTAL_PG_BD);
8148         }
8149
8150         return error;
8151 }
8152 #endif
8153
8154 /****************************************************************************/
8155 /* Provides a sysctl interface to allow reading arbitrary NVRAM offsets in  */
8156 /* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
8157 /*                                                                          */
8158 /* Returns:                                                                 */
8159 /*   0 for success, positive value for failure.                             */
8160 /****************************************************************************/
8161 static int
8162 bce_sysctl_nvram_read(SYSCTL_HANDLER_ARGS)
8163 {
8164         struct bce_softc *sc = (struct bce_softc *)arg1;
8165         int error;
8166         u32 result;
8167         u32 val[1];
8168         u8 *data = (u8 *) val;
8169
8170         result = -1;
8171         error = sysctl_handle_int(oidp, &result, 0, req);
8172         if (error || (req->newptr == NULL))
8173                 return (error);
8174
8175         bce_nvram_read(sc, result, data, 4);
8176         BCE_PRINTF("offset 0x%08X = 0x%08X\n", result, bce_be32toh(val[0]));
8177
8178         return (error);
8179 }
8180
8181
8182 /****************************************************************************/
8183 /* Provides a sysctl interface to allow reading arbitrary registers in the  */
8184 /* device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                            */
8185 /*                                                                          */
8186 /* Returns:                                                                 */
8187 /*   0 for success, positive value for failure.                             */
8188 /****************************************************************************/
8189 static int
8190 bce_sysctl_reg_read(SYSCTL_HANDLER_ARGS)
8191 {
8192         struct bce_softc *sc = (struct bce_softc *)arg1;
8193         int error;
8194         u32 val, result;
8195
8196         result = -1;
8197         error = sysctl_handle_int(oidp, &result, 0, req);
8198         if (error || (req->newptr == NULL))
8199                 return (error);
8200
8201         /* Make sure the register is accessible. */
8202         if (result < 0x8000) {
8203                 val = REG_RD(sc, result);
8204                 BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
8205         } else if (result < 0x0280000) {
8206                 val = REG_RD_IND(sc, result);
8207                 BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
8208         }
8209
8210         return (error);
8211 }
8212
8213
8214 /****************************************************************************/
8215 /* Provides a sysctl interface to allow reading arbitrary PHY registers in  */
8216 /* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
8217 /*                                                                          */
8218 /* Returns:                                                                 */
8219 /*   0 for success, positive value for failure.                             */
8220 /****************************************************************************/
8221 static int
8222 bce_sysctl_phy_read(SYSCTL_HANDLER_ARGS)
8223 {
8224         struct bce_softc *sc;
8225         device_t dev;
8226         int error, result;
8227         u16 val;
8228
8229         result = -1;
8230         error = sysctl_handle_int(oidp, &result, 0, req);
8231         if (error || (req->newptr == NULL))
8232                 return (error);
8233
8234         /* Make sure the register is accessible. */
8235         if (result < 0x20) {
8236                 sc = (struct bce_softc *)arg1;
8237                 dev = sc->bce_dev;
8238                 val = bce_miibus_read_reg(dev, sc->bce_phy_addr, result);
8239                 BCE_PRINTF("phy 0x%02X = 0x%04X\n", result, val);
8240         }
8241         return (error);
8242 }
8243
8244
8245 /****************************************************************************/
8246 /* Provides a sysctl interface to allow reading a CID.                      */
8247 /*                                                                          */
8248 /* Returns:                                                                 */
8249 /*   0 for success, positive value for failure.                             */
8250 /****************************************************************************/
8251 static int
8252 bce_sysctl_dump_ctx(SYSCTL_HANDLER_ARGS)
8253 {
8254         struct bce_softc *sc;
8255         int error;
8256         u16 result;
8257
8258         result = -1;
8259         error = sysctl_handle_int(oidp, &result, 0, req);
8260         if (error || (req->newptr == NULL))
8261                 return (error);
8262
8263         /* Make sure the register is accessible. */
8264         if (result <= TX_CID) {
8265                 sc = (struct bce_softc *)arg1;
8266                 bce_dump_ctx(sc, result);
8267         }
8268
8269         return (error);
8270 }
8271
8272
8273  /****************************************************************************/
8274 /* Provides a sysctl interface to forcing the driver to dump state and      */
8275 /* enter the debugger.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                */
8276 /*                                                                          */
8277 /* Returns:                                                                 */
8278 /*   0 for success, positive value for failure.                             */
8279 /****************************************************************************/
8280 static int
8281 bce_sysctl_breakpoint(SYSCTL_HANDLER_ARGS)
8282 {
8283         int error;
8284         int result;
8285         struct bce_softc *sc;
8286
8287         result = -1;
8288         error = sysctl_handle_int(oidp, &result, 0, req);
8289
8290         if (error || !req->newptr)
8291                 return (error);
8292
8293         if (result == 1) {
8294                 sc = (struct bce_softc *)arg1;
8295                 bce_breakpoint(sc);
8296         }
8297
8298         return error;
8299 }
8300 #endif
8301
8302
8303 /****************************************************************************/
8304 /* Adds any sysctl parameters for tuning or debugging purposes.             */
8305 /*                                                                          */
8306 /* Returns:                                                                 */
8307 /*   0 for success, positive value for failure.                             */
8308 /****************************************************************************/
8309 static void
8310 bce_add_sysctls(struct bce_softc *sc)
8311 {
8312         struct sysctl_ctx_list *ctx;
8313         struct sysctl_oid_list *children;
8314
8315         DBENTER(BCE_VERBOSE_MISC);
8316
8317         ctx = device_get_sysctl_ctx(sc->bce_dev);
8318         children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->bce_dev));
8319
8320 #ifdef BCE_DEBUG
8321         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8322             "l2fhdr_error_sim_control",
8323             CTLFLAG_RW, &l2fhdr_error_sim_control,
8324             0, "Debug control to force l2fhdr errors");
8325
8326         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8327             "l2fhdr_error_sim_count",
8328             CTLFLAG_RD, &sc->l2fhdr_error_sim_count,
8329             0, "Number of simulated l2_fhdr errors");
8330 #endif
8331
8332         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8333             "l2fhdr_error_count",
8334             CTLFLAG_RD, &sc->l2fhdr_error_count,
8335             0, "Number of l2_fhdr errors");
8336
8337 #ifdef BCE_DEBUG
8338         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8339             "mbuf_alloc_failed_sim_control",
8340             CTLFLAG_RW, &mbuf_alloc_failed_sim_control,
8341             0, "Debug control to force mbuf allocation failures");
8342
8343         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8344             "mbuf_alloc_failed_sim_count",
8345             CTLFLAG_RD, &sc->mbuf_alloc_failed_sim_count,
8346             0, "Number of simulated mbuf cluster allocation failures");
8347 #endif
8348
8349         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8350             "mbuf_alloc_failed_count",
8351             CTLFLAG_RD, &sc->mbuf_alloc_failed_count,
8352             0, "Number of mbuf allocation failures");
8353
8354         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8355             "fragmented_mbuf_count",
8356             CTLFLAG_RD, &sc->fragmented_mbuf_count,
8357             0, "Number of fragmented mbufs");
8358
8359 #ifdef BCE_DEBUG
8360         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8361             "dma_map_addr_failed_sim_control",
8362             CTLFLAG_RW, &dma_map_addr_failed_sim_control,
8363             0, "Debug control to force DMA mapping failures");
8364
8365         /* ToDo: Figure out how to update this value in bce_dma_map_addr(). */
8366         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8367             "dma_map_addr_failed_sim_count",
8368             CTLFLAG_RD, &sc->dma_map_addr_failed_sim_count,
8369             0, "Number of simulated DMA mapping failures");
8370         
8371 #endif
8372
8373         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8374             "dma_map_addr_rx_failed_count",
8375             CTLFLAG_RD, &sc->dma_map_addr_rx_failed_count,
8376             0, "Number of RX DMA mapping failures");
8377
8378         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8379             "dma_map_addr_tx_failed_count",
8380             CTLFLAG_RD, &sc->dma_map_addr_tx_failed_count,
8381             0, "Number of TX DMA mapping failures");
8382
8383 #ifdef BCE_DEBUG
8384         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8385             "unexpected_attention_sim_control",
8386             CTLFLAG_RW, &unexpected_attention_sim_control,
8387             0, "Debug control to simulate unexpected attentions");
8388
8389         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8390             "unexpected_attention_sim_count",
8391             CTLFLAG_RW, &sc->unexpected_attention_sim_count,
8392             0, "Number of simulated unexpected attentions");
8393 #endif
8394
8395         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8396             "unexpected_attention_count",
8397             CTLFLAG_RW, &sc->unexpected_attention_count,
8398             0, "Number of unexpected attentions");
8399
8400 #ifdef BCE_DEBUG
8401         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8402             "debug_bootcode_running_failure",
8403             CTLFLAG_RW, &bootcode_running_failure_sim_control,
8404             0, "Debug control to force bootcode running failures");
8405
8406         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8407             "rx_low_watermark",
8408             CTLFLAG_RD, &sc->rx_low_watermark,
8409             0, "Lowest level of free rx_bd's");
8410
8411         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8412             "rx_empty_count",
8413             CTLFLAG_RD, &sc->rx_empty_count,
8414             0, "Number of times the RX chain was empty");
8415
8416         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8417             "tx_hi_watermark",
8418             CTLFLAG_RD, &sc->tx_hi_watermark,
8419             0, "Highest level of used tx_bd's");
8420
8421         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8422             "tx_full_count",
8423             CTLFLAG_RD, &sc->tx_full_count,
8424             0, "Number of times the TX chain was full");
8425
8426         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8427             "requested_tso_frames",
8428             CTLFLAG_RD, &sc->requested_tso_frames,
8429             0, "Number of TSO frames received");
8430
8431         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8432             "rx_interrupts",
8433             CTLFLAG_RD, &sc->rx_interrupts,
8434             0, "Number of RX interrupts");
8435
8436         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8437             "tx_interrupts",
8438             CTLFLAG_RD, &sc->tx_interrupts,
8439             0, "Number of TX interrupts");
8440 #endif
8441
8442         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8443             "stat_IfHcInOctets",
8444             CTLFLAG_RD, &sc->stat_IfHCInOctets,
8445             "Bytes received");
8446
8447         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8448             "stat_IfHCInBadOctets",
8449             CTLFLAG_RD, &sc->stat_IfHCInBadOctets,
8450             "Bad bytes received");
8451
8452         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8453             "stat_IfHCOutOctets",
8454             CTLFLAG_RD, &sc->stat_IfHCOutOctets,
8455             "Bytes sent");
8456
8457         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8458             "stat_IfHCOutBadOctets",
8459             CTLFLAG_RD, &sc->stat_IfHCOutBadOctets,
8460             "Bad bytes sent");
8461
8462         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8463             "stat_IfHCInUcastPkts",
8464             CTLFLAG_RD, &sc->stat_IfHCInUcastPkts,
8465             "Unicast packets received");
8466
8467         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8468             "stat_IfHCInMulticastPkts",
8469             CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts,
8470             "Multicast packets received");
8471
8472         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8473             "stat_IfHCInBroadcastPkts",
8474             CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts,
8475             "Broadcast packets received");
8476
8477         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8478             "stat_IfHCOutUcastPkts",
8479             CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts,
8480             "Unicast packets sent");
8481
8482         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8483             "stat_IfHCOutMulticastPkts",
8484             CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts,
8485             "Multicast packets sent");
8486
8487         SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8488             "stat_IfHCOutBroadcastPkts",
8489             CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts,
8490             "Broadcast packets sent");
8491
8492         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8493             "stat_emac_tx_stat_dot3statsinternalmactransmiterrors",
8494             CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors,
8495             0, "Internal MAC transmit errors");
8496
8497         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8498             "stat_Dot3StatsCarrierSenseErrors",
8499             CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors,
8500             0, "Carrier sense errors");
8501
8502         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8503             "stat_Dot3StatsFCSErrors",
8504             CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors,
8505             0, "Frame check sequence errors");
8506
8507         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8508             "stat_Dot3StatsAlignmentErrors",
8509             CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors,
8510             0, "Alignment errors");
8511
8512         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8513             "stat_Dot3StatsSingleCollisionFrames",
8514             CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames,
8515             0, "Single Collision Frames");
8516
8517         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8518             "stat_Dot3StatsMultipleCollisionFrames",
8519             CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames,
8520             0, "Multiple Collision Frames");
8521
8522         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8523             "stat_Dot3StatsDeferredTransmissions",
8524             CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions,
8525             0, "Deferred Transmissions");
8526
8527         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8528             "stat_Dot3StatsExcessiveCollisions",
8529             CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions,
8530             0, "Excessive Collisions");
8531
8532         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8533             "stat_Dot3StatsLateCollisions",
8534             CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions,
8535             0, "Late Collisions");
8536
8537         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8538             "stat_EtherStatsCollisions",
8539             CTLFLAG_RD, &sc->stat_EtherStatsCollisions,
8540             0, "Collisions");
8541
8542         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8543             "stat_EtherStatsFragments",
8544             CTLFLAG_RD, &sc->stat_EtherStatsFragments,
8545             0, "Fragments");
8546
8547         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8548             "stat_EtherStatsJabbers",
8549             CTLFLAG_RD, &sc->stat_EtherStatsJabbers,
8550             0, "Jabbers");
8551
8552         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8553             "stat_EtherStatsUndersizePkts",
8554             CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts,
8555             0, "Undersize packets");
8556
8557         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8558             "stat_EtherStatsOversizePkts",
8559             CTLFLAG_RD, &sc->stat_EtherStatsOversizePkts,
8560             0, "stat_EtherStatsOversizePkts");
8561
8562         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8563             "stat_EtherStatsPktsRx64Octets",
8564             CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets,
8565             0, "Bytes received in 64 byte packets");
8566
8567         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8568             "stat_EtherStatsPktsRx65Octetsto127Octets",
8569             CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets,
8570             0, "Bytes received in 65 to 127 byte packets");
8571
8572         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8573             "stat_EtherStatsPktsRx128Octetsto255Octets",
8574             CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets,
8575             0, "Bytes received in 128 to 255 byte packets");
8576
8577         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8578             "stat_EtherStatsPktsRx256Octetsto511Octets",
8579             CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets,
8580             0, "Bytes received in 256 to 511 byte packets");
8581
8582         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8583             "stat_EtherStatsPktsRx512Octetsto1023Octets",
8584             CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets,
8585             0, "Bytes received in 512 to 1023 byte packets");
8586
8587         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8588             "stat_EtherStatsPktsRx1024Octetsto1522Octets",
8589             CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets,
8590             0, "Bytes received in 1024 t0 1522 byte packets");
8591
8592         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8593             "stat_EtherStatsPktsRx1523Octetsto9022Octets",
8594             CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets,
8595             0, "Bytes received in 1523 to 9022 byte packets");
8596
8597         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8598             "stat_EtherStatsPktsTx64Octets",
8599             CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets,
8600             0, "Bytes sent in 64 byte packets");
8601
8602         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8603             "stat_EtherStatsPktsTx65Octetsto127Octets",
8604             CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets,
8605             0, "Bytes sent in 65 to 127 byte packets");
8606
8607         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8608             "stat_EtherStatsPktsTx128Octetsto255Octets",
8609             CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets,
8610             0, "Bytes sent in 128 to 255 byte packets");
8611
8612         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8613             "stat_EtherStatsPktsTx256Octetsto511Octets",
8614             CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets,
8615             0, "Bytes sent in 256 to 511 byte packets");
8616
8617         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8618             "stat_EtherStatsPktsTx512Octetsto1023Octets",
8619             CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets,
8620             0, "Bytes sent in 512 to 1023 byte packets");
8621
8622         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8623             "stat_EtherStatsPktsTx1024Octetsto1522Octets",
8624             CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets,
8625             0, "Bytes sent in 1024 to 1522 byte packets");
8626
8627         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8628             "stat_EtherStatsPktsTx1523Octetsto9022Octets",
8629             CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets,
8630             0, "Bytes sent in 1523 to 9022 byte packets");
8631
8632         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8633             "stat_XonPauseFramesReceived",
8634             CTLFLAG_RD, &sc->stat_XonPauseFramesReceived,
8635             0, "XON pause frames receved");
8636
8637         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8638             "stat_XoffPauseFramesReceived",
8639             CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived,
8640             0, "XOFF pause frames received");
8641
8642         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8643             "stat_OutXonSent",
8644             CTLFLAG_RD, &sc->stat_OutXonSent,
8645             0, "XON pause frames sent");
8646
8647         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8648             "stat_OutXoffSent",
8649             CTLFLAG_RD, &sc->stat_OutXoffSent,
8650             0, "XOFF pause frames sent");
8651
8652         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8653             "stat_FlowControlDone",
8654             CTLFLAG_RD, &sc->stat_FlowControlDone,
8655             0, "Flow control done");
8656
8657         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8658             "stat_MacControlFramesReceived",
8659             CTLFLAG_RD, &sc->stat_MacControlFramesReceived,
8660             0, "MAC control frames received");
8661
8662         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8663             "stat_XoffStateEntered",
8664             CTLFLAG_RD, &sc->stat_XoffStateEntered,
8665             0, "XOFF state entered");
8666
8667         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8668             "stat_IfInFramesL2FilterDiscards",
8669             CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards,
8670             0, "Received L2 packets discarded");
8671
8672         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8673             "stat_IfInRuleCheckerDiscards",
8674             CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards,
8675             0, "Received packets discarded by rule");
8676
8677         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8678             "stat_IfInFTQDiscards",
8679             CTLFLAG_RD, &sc->stat_IfInFTQDiscards,
8680             0, "Received packet FTQ discards");
8681
8682         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8683             "stat_IfInMBUFDiscards",
8684             CTLFLAG_RD, &sc->stat_IfInMBUFDiscards,
8685             0, "Received packets discarded due to lack "
8686             "of controller buffer memory");
8687
8688         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8689             "stat_IfInRuleCheckerP4Hit",
8690             CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit,
8691             0, "Received packets rule checker hits");
8692
8693         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8694             "stat_CatchupInRuleCheckerDiscards",
8695             CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards,
8696             0, "Received packets discarded in Catchup path");
8697
8698         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8699             "stat_CatchupInFTQDiscards",
8700             CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards,
8701             0, "Received packets discarded in FTQ in Catchup path");
8702
8703         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8704             "stat_CatchupInMBUFDiscards",
8705             CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards,
8706             0, "Received packets discarded in controller "
8707             "buffer memory in Catchup path");
8708
8709         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8710             "stat_CatchupInRuleCheckerP4Hit",
8711             CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit,
8712             0, "Received packets rule checker hits in Catchup path");
8713
8714         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8715             "com_no_buffers",
8716             CTLFLAG_RD, &sc->com_no_buffers,
8717             0, "Valid packets received but no RX buffers available");
8718
8719 #ifdef BCE_DEBUG
8720         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8721             "driver_state", CTLTYPE_INT | CTLFLAG_RW,
8722             (void *)sc, 0,
8723             bce_sysctl_driver_state, "I", "Drive state information");
8724
8725         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8726             "hw_state", CTLTYPE_INT | CTLFLAG_RW,
8727             (void *)sc, 0,
8728             bce_sysctl_hw_state, "I", "Hardware state information");
8729
8730         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8731             "status_block", CTLTYPE_INT | CTLFLAG_RW,
8732             (void *)sc, 0,
8733             bce_sysctl_status_block, "I", "Status block");
8734
8735         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8736             "stats_block", CTLTYPE_INT | CTLFLAG_RW,
8737             (void *)sc, 0,
8738             bce_sysctl_stats_block, "I", "Stats block");
8739
8740         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8741             "bc_state", CTLTYPE_INT | CTLFLAG_RW,
8742             (void *)sc, 0,
8743             bce_sysctl_bc_state, "I", "Bootcode state information");
8744
8745         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8746             "dump_rx_bd_chain", CTLTYPE_INT | CTLFLAG_RW,
8747             (void *)sc, 0,
8748             bce_sysctl_dump_rx_bd_chain, "I", "Dump RX BD chain");
8749
8750         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8751             "dump_rx_mbuf_chain", CTLTYPE_INT | CTLFLAG_RW,
8752             (void *)sc, 0,
8753             bce_sysctl_dump_rx_mbuf_chain, "I", "Dump RX MBUF chain");
8754
8755         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8756             "dump_tx_chain", CTLTYPE_INT | CTLFLAG_RW,
8757             (void *)sc, 0,
8758             bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
8759
8760 #ifdef BCE_JUMBO_HDRSPLIT
8761         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8762             "dump_pg_chain", CTLTYPE_INT | CTLFLAG_RW,
8763             (void *)sc, 0,
8764             bce_sysctl_dump_pg_chain, "I", "Dump page chain");
8765 #endif
8766         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8767             "dump_ctx", CTLTYPE_INT | CTLFLAG_RW,
8768             (void *)sc, 0,
8769             bce_sysctl_dump_ctx, "I", "Dump context memory");
8770
8771         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8772             "breakpoint", CTLTYPE_INT | CTLFLAG_RW,
8773             (void *)sc, 0,
8774             bce_sysctl_breakpoint, "I", "Driver breakpoint");
8775
8776         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8777             "reg_read", CTLTYPE_INT | CTLFLAG_RW,
8778             (void *)sc, 0,
8779             bce_sysctl_reg_read, "I", "Register read");
8780
8781         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8782             "nvram_read", CTLTYPE_INT | CTLFLAG_RW,
8783             (void *)sc, 0,
8784             bce_sysctl_nvram_read, "I", "NVRAM read");
8785
8786         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8787             "phy_read", CTLTYPE_INT | CTLFLAG_RW,
8788             (void *)sc, 0,
8789             bce_sysctl_phy_read, "I", "PHY register read");
8790
8791 #endif
8792
8793         DBEXIT(BCE_VERBOSE_MISC);
8794 }
8795
8796
8797 /****************************************************************************/
8798 /* BCE Debug Routines                                                       */
8799 /****************************************************************************/
8800 #ifdef BCE_DEBUG
8801
8802 /****************************************************************************/
8803 /* Freezes the controller to allow for a cohesive state dump.               */
8804 /*                                                                          */
8805 /* Returns:                                                                 */
8806 /*   Nothing.                                                               */
8807 /****************************************************************************/
8808 static __attribute__ ((noinline)) void
8809 bce_freeze_controller(struct bce_softc *sc)
8810 {
8811         u32 val;
8812         val = REG_RD(sc, BCE_MISC_COMMAND);
8813         val |= BCE_MISC_COMMAND_DISABLE_ALL;
8814         REG_WR(sc, BCE_MISC_COMMAND, val);
8815 }
8816
8817
8818 /****************************************************************************/
8819 /* Unfreezes the controller after a freeze operation.  This may not always  */
8820 /* work and the controller will require a reset!                            */
8821 /*                                                                          */
8822 /* Returns:                                                                 */
8823 /*   Nothing.                                                               */
8824 /****************************************************************************/
8825 static __attribute__ ((noinline)) void
8826 bce_unfreeze_controller(struct bce_softc *sc)
8827 {
8828         u32 val;
8829         val = REG_RD(sc, BCE_MISC_COMMAND);
8830         val |= BCE_MISC_COMMAND_ENABLE_ALL;
8831         REG_WR(sc, BCE_MISC_COMMAND, val);
8832 }
8833
8834
8835 /****************************************************************************/
8836 /* Prints out Ethernet frame information from an mbuf.                      */
8837 /*                                                                          */
8838 /* Partially decode an Ethernet frame to look at some important headers.    */
8839 /*                                                                          */
8840 /* Returns:                                                                 */
8841 /*   Nothing.                                                               */
8842 /****************************************************************************/
8843 static __attribute__ ((noinline)) void
8844 bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
8845 {
8846         struct ether_vlan_header *eh;
8847         u16 etype;
8848         int ehlen;
8849         struct ip *ip;
8850         struct tcphdr *th;
8851         struct udphdr *uh;
8852         struct arphdr *ah;
8853
8854         BCE_PRINTF(
8855             "-----------------------------"
8856             " Frame Decode "
8857             "-----------------------------\n");
8858
8859         eh = mtod(m, struct ether_vlan_header *);
8860
8861         /* Handle VLAN encapsulation if present. */
8862         if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
8863                 etype = ntohs(eh->evl_proto);
8864                 ehlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
8865         } else {
8866                 etype = ntohs(eh->evl_encap_proto);
8867                 ehlen = ETHER_HDR_LEN;
8868         }
8869
8870         /* ToDo: Add VLAN output. */
8871         BCE_PRINTF("enet: dest = %6D, src = %6D, type = 0x%04X, hlen = %d\n",
8872             eh->evl_dhost, ":", eh->evl_shost, ":", etype, ehlen);
8873
8874         switch (etype) {
8875         case ETHERTYPE_IP:
8876                 ip = (struct ip *)(m->m_data + ehlen);
8877                 BCE_PRINTF("--ip: dest = 0x%08X , src = 0x%08X, "
8878                     "len = %d bytes, protocol = 0x%02X, xsum = 0x%04X\n",
8879                     ntohl(ip->ip_dst.s_addr), ntohl(ip->ip_src.s_addr),
8880                     ntohs(ip->ip_len), ip->ip_p, ntohs(ip->ip_sum));
8881
8882                 switch (ip->ip_p) {
8883                 case IPPROTO_TCP:
8884                         th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
8885                         BCE_PRINTF("-tcp: dest = %d, src = %d, hlen = %d bytes, "
8886                             "flags = 0x%b, csum = 0x%04X\n",
8887                             ntohs(th->th_dport), ntohs(th->th_sport), 
8888                             (th->th_off << 2), th->th_flags, 
8889                             "\20\10CWR\07ECE\06URG\05ACK\04PSH\03RST"
8890                             "\02SYN\01FIN", ntohs(th->th_sum));
8891                         break;
8892                 case IPPROTO_UDP:
8893                         uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
8894                         BCE_PRINTF("-udp: dest = %d, src = %d, len = %d "
8895                             "bytes, csum = 0x%04X\n", ntohs(uh->uh_dport), 
8896                             ntohs(uh->uh_sport), ntohs(uh->uh_ulen), 
8897                             ntohs(uh->uh_sum));
8898                         break;
8899                 case IPPROTO_ICMP:
8900                         BCE_PRINTF("icmp:\n");
8901                         break;
8902                 default:
8903                         BCE_PRINTF("----: Other IP protocol.\n");
8904                         }
8905                 break;
8906         case ETHERTYPE_IPV6:
8907                 BCE_PRINTF("ipv6: No decode supported.\n");
8908                 break;
8909         case ETHERTYPE_ARP:
8910                 BCE_PRINTF("-arp: ");
8911                 ah = (struct arphdr *) (m->m_data + ehlen);
8912                 switch (ntohs(ah->ar_op)) {
8913                 case ARPOP_REVREQUEST:
8914                         printf("reverse ARP request\n");
8915                         break;
8916                 case ARPOP_REVREPLY:
8917                         printf("reverse ARP reply\n");
8918                         break;
8919                 case ARPOP_REQUEST:
8920                         printf("ARP request\n");
8921                         break;
8922                 case ARPOP_REPLY:
8923                         printf("ARP reply\n");
8924                         break;
8925                 default:
8926                         printf("other ARP operation\n");
8927                 }
8928                 break;
8929         default:
8930                 BCE_PRINTF("----: Other protocol.\n");
8931         }
8932
8933         BCE_PRINTF(
8934                 "-----------------------------"
8935                 "--------------"
8936                 "-----------------------------\n");
8937 }
8938
8939
8940 /****************************************************************************/
8941 /* Prints out information about an mbuf.                                    */
8942 /*                                                                          */
8943 /* Returns:                                                                 */
8944 /*   Nothing.                                                               */
8945 /****************************************************************************/
8946 static __attribute__ ((noinline)) void
8947 bce_dump_mbuf(struct bce_softc *sc, struct mbuf *m)
8948 {
8949         struct mbuf *mp = m;
8950
8951         if (m == NULL) {
8952                 BCE_PRINTF("mbuf: null pointer\n");
8953                 return;
8954         }
8955
8956         while (mp) {
8957                 BCE_PRINTF("mbuf: %p, m_len = %d, m_flags = 0x%b, "
8958                     "m_data = %p\n", mp, mp->m_len, mp->m_flags,
8959                     "\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY", mp->m_data);
8960
8961                 if (mp->m_flags & M_PKTHDR) {
8962                         BCE_PRINTF("- m_pkthdr: len = %d, flags = 0x%b, "
8963                             "csum_flags = %b\n", mp->m_pkthdr.len, 
8964                             mp->m_flags, "\20\12M_BCAST\13M_MCAST\14M_FRAG"
8965                             "\15M_FIRSTFRAG\16M_LASTFRAG\21M_VLANTAG"
8966                             "\22M_PROMISC\23M_NOFREE", 
8967                             mp->m_pkthdr.csum_flags,
8968                             "\20\1CSUM_IP\2CSUM_TCP\3CSUM_UDP\4CSUM_IP_FRAGS"
8969                             "\5CSUM_FRAGMENT\6CSUM_TSO\11CSUM_IP_CHECKED"
8970                             "\12CSUM_IP_VALID\13CSUM_DATA_VALID"
8971                             "\14CSUM_PSEUDO_HDR");
8972                 }
8973
8974                 if (mp->m_flags & M_EXT) {
8975                         BCE_PRINTF("- m_ext: %p, ext_size = %d, type = ",
8976                             mp->m_ext.ext_buf, mp->m_ext.ext_size);
8977                         switch (mp->m_ext.ext_type) {
8978                         case EXT_CLUSTER:
8979                                 printf("EXT_CLUSTER\n"); break;
8980                         case EXT_SFBUF:
8981                                 printf("EXT_SFBUF\n"); break;
8982                         case EXT_JUMBO9:
8983                                 printf("EXT_JUMBO9\n"); break;
8984                         case EXT_JUMBO16:
8985                                 printf("EXT_JUMBO16\n"); break;
8986                         case EXT_PACKET:
8987                                 printf("EXT_PACKET\n"); break;
8988                         case EXT_MBUF:
8989                                 printf("EXT_MBUF\n"); break;
8990                         case EXT_NET_DRV:
8991                                 printf("EXT_NET_DRV\n"); break;
8992                         case EXT_MOD_TYPE:
8993                                 printf("EXT_MDD_TYPE\n"); break;
8994                         case EXT_DISPOSABLE:
8995                                 printf("EXT_DISPOSABLE\n"); break;
8996                         case EXT_EXTREF:
8997                                 printf("EXT_EXTREF\n"); break;
8998                         default:             
8999                                 printf("UNKNOWN\n");
9000                         }
9001                 }
9002
9003                 mp = mp->m_next;
9004         }
9005 }
9006
9007
9008 /****************************************************************************/
9009 /* Prints out the mbufs in the TX mbuf chain.                               */
9010 /*                                                                          */
9011 /* Returns:                                                                 */
9012 /*   Nothing.                                                               */
9013 /****************************************************************************/
9014 static __attribute__ ((noinline)) void
9015 bce_dump_tx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
9016 {
9017         struct mbuf *m;
9018
9019         BCE_PRINTF(
9020                 "----------------------------"
9021                 "  tx mbuf data  "
9022                 "----------------------------\n");
9023
9024         for (int i = 0; i < count; i++) {
9025                 m = sc->tx_mbuf_ptr[chain_prod];
9026                 BCE_PRINTF("txmbuf[0x%04X]\n", chain_prod);
9027                 bce_dump_mbuf(sc, m);
9028                 chain_prod = TX_CHAIN_IDX(NEXT_TX_BD(chain_prod));
9029         }
9030
9031         BCE_PRINTF(
9032                 "----------------------------"
9033                 "----------------"
9034                 "----------------------------\n");
9035 }
9036
9037
9038 /****************************************************************************/
9039 /* Prints out the mbufs in the RX mbuf chain.                               */
9040 /*                                                                          */
9041 /* Returns:                                                                 */
9042 /*   Nothing.                                                               */
9043 /****************************************************************************/
9044 static __attribute__ ((noinline)) void
9045 bce_dump_rx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
9046 {
9047         struct mbuf *m;
9048
9049         BCE_PRINTF(
9050                 "----------------------------"
9051                 "  rx mbuf data  "
9052                 "----------------------------\n");
9053
9054         for (int i = 0; i < count; i++) {
9055                 m = sc->rx_mbuf_ptr[chain_prod];
9056                 BCE_PRINTF("rxmbuf[0x%04X]\n", chain_prod);
9057                 bce_dump_mbuf(sc, m);
9058                 chain_prod = RX_CHAIN_IDX(NEXT_RX_BD(chain_prod));
9059         }
9060
9061
9062         BCE_PRINTF(
9063                 "----------------------------"
9064                 "----------------"
9065                 "----------------------------\n");
9066 }
9067
9068
9069 #ifdef BCE_JUMBO_HDRSPLIT
9070 /****************************************************************************/
9071 /* Prints out the mbufs in the mbuf page chain.                             */
9072 /*                                                                          */
9073 /* Returns:                                                                 */
9074 /*   Nothing.                                                               */
9075 /****************************************************************************/
9076 static __attribute__ ((noinline)) void
9077 bce_dump_pg_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
9078 {
9079         struct mbuf *m;
9080
9081         BCE_PRINTF(
9082                 "----------------------------"
9083                 "  pg mbuf data  "
9084                 "----------------------------\n");
9085
9086         for (int i = 0; i < count; i++) {
9087                 m = sc->pg_mbuf_ptr[chain_prod];
9088                 BCE_PRINTF("pgmbuf[0x%04X]\n", chain_prod);
9089                 bce_dump_mbuf(sc, m);
9090                 chain_prod = PG_CHAIN_IDX(NEXT_PG_BD(chain_prod));
9091         }
9092
9093
9094         BCE_PRINTF(
9095                 "----------------------------"
9096                 "----------------"
9097                 "----------------------------\n");
9098 }
9099 #endif
9100
9101
9102 /****************************************************************************/
9103 /* Prints out a tx_bd structure.                                            */
9104 /*                                                                          */
9105 /* Returns:                                                                 */
9106 /*   Nothing.                                                               */
9107 /****************************************************************************/
9108 static __attribute__ ((noinline)) void
9109 bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
9110 {
9111         int i = 0;
9112
9113         if (idx > MAX_TX_BD)
9114                 /* Index out of range. */
9115                 BCE_PRINTF("tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
9116         else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
9117                 /* TX Chain page pointer. */
9118                 BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
9119                     "pointer\n", idx, txbd->tx_bd_haddr_hi, 
9120                     txbd->tx_bd_haddr_lo);
9121         else {
9122                 /* Normal tx_bd entry. */
9123                 BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, "
9124                     "mss_nbytes = 0x%08X, vlan tag = 0x%04X, flags = "
9125                     "0x%04X (", idx, txbd->tx_bd_haddr_hi, 
9126                     txbd->tx_bd_haddr_lo, txbd->tx_bd_mss_nbytes, 
9127                     txbd->tx_bd_vlan_tag, txbd->tx_bd_flags);
9128
9129                 if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT) {
9130                         if (i>0) 
9131                                 printf("|"); 
9132                         printf("CONN_FAULT"); 
9133                         i++;
9134                 }
9135
9136                 if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM) {
9137                         if (i>0) 
9138                                 printf("|"); 
9139                         printf("TCP_UDP_CKSUM"); 
9140                         i++;
9141                 }
9142
9143                 if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM) {
9144                         if (i>0) 
9145                                 printf("|"); 
9146                         printf("IP_CKSUM"); 
9147                         i++;
9148                 }
9149
9150                 if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG) {
9151                         if (i>0) 
9152                                 printf("|"); 
9153                         printf("VLAN"); 
9154                         i++;
9155                 }
9156
9157                 if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW) {
9158                         if (i>0) 
9159                                 printf("|"); 
9160                         printf("COAL_NOW"); 
9161                         i++;
9162                 }
9163
9164                 if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC) {
9165                         if (i>0) 
9166                                 printf("|"); 
9167                         printf("DONT_GEN_CRC"); 
9168                         i++;
9169                 }
9170
9171                 if (txbd->tx_bd_flags & TX_BD_FLAGS_START) {
9172                         if (i>0) 
9173                                 printf("|"); 
9174                         printf("START"); 
9175                         i++;
9176                 }
9177
9178                 if (txbd->tx_bd_flags & TX_BD_FLAGS_END) {
9179                         if (i>0) 
9180                                 printf("|"); 
9181                         printf("END"); 
9182                         i++;
9183                 }
9184
9185                 if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO) {
9186                         if (i>0) 
9187                                 printf("|"); 
9188                         printf("LSO"); 
9189                         i++;
9190                 }
9191
9192                 if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD) {
9193                         if (i>0) 
9194                                 printf("|"); 
9195                         printf("SW_OPTION=%d", ((txbd->tx_bd_flags & 
9196                             TX_BD_FLAGS_SW_OPTION_WORD) >> 8)); i++;
9197                 }
9198
9199                 if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS) {
9200                         if (i>0) 
9201                                 printf("|"); 
9202                         printf("SW_FLAGS"); 
9203                         i++;
9204                 }
9205
9206                 if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP) {
9207                         if (i>0) 
9208                                 printf("|"); 
9209                         printf("SNAP)");
9210                 } else {
9211                         printf(")\n");
9212                 }
9213         }
9214 }
9215
9216
9217 /****************************************************************************/
9218 /* Prints out a rx_bd structure.                                            */
9219 /*                                                                          */
9220 /* Returns:                                                                 */
9221 /*   Nothing.                                                               */
9222 /****************************************************************************/
9223 static __attribute__ ((noinline)) void
9224 bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd)
9225 {
9226         if (idx > MAX_RX_BD)
9227                 /* Index out of range. */
9228                 BCE_PRINTF("rx_bd[0x%04X]: Invalid rx_bd index!\n", idx);
9229         else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
9230                 /* RX Chain page pointer. */
9231                 BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
9232                     "pointer\n", idx, rxbd->rx_bd_haddr_hi, 
9233                     rxbd->rx_bd_haddr_lo);
9234         else
9235                 /* Normal rx_bd entry. */
9236                 BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = "
9237                     "0x%08X, flags = 0x%08X\n", idx, rxbd->rx_bd_haddr_hi, 
9238                     rxbd->rx_bd_haddr_lo, rxbd->rx_bd_len, 
9239                     rxbd->rx_bd_flags);
9240 }
9241
9242
9243 #ifdef BCE_JUMBO_HDRSPLIT
9244 /****************************************************************************/
9245 /* Prints out a rx_bd structure in the page chain.                          */
9246 /*                                                                          */
9247 /* Returns:                                                                 */
9248 /*   Nothing.                                                               */
9249 /****************************************************************************/
9250 static __attribute__ ((noinline)) void
9251 bce_dump_pgbd(struct bce_softc *sc, int idx, struct rx_bd *pgbd)
9252 {
9253         if (idx > MAX_PG_BD)
9254                 /* Index out of range. */
9255                 BCE_PRINTF("pg_bd[0x%04X]: Invalid pg_bd index!\n", idx);
9256         else if ((idx & USABLE_PG_BD_PER_PAGE) == USABLE_PG_BD_PER_PAGE)
9257                 /* Page Chain page pointer. */
9258                 BCE_PRINTF("px_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
9259                         idx, pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo);
9260         else
9261                 /* Normal rx_bd entry. */
9262                 BCE_PRINTF("pg_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
9263                         "flags = 0x%08X\n", idx,
9264                         pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo,
9265                         pgbd->rx_bd_len, pgbd->rx_bd_flags);
9266 }
9267 #endif
9268
9269
9270 /****************************************************************************/
9271 /* Prints out a l2_fhdr structure.                                          */
9272 /*                                                                          */
9273 /* Returns:                                                                 */
9274 /*   Nothing.                                                               */
9275 /****************************************************************************/
9276 static __attribute__ ((noinline)) void
9277 bce_dump_l2fhdr(struct bce_softc *sc, int idx, struct l2_fhdr *l2fhdr)
9278 {
9279         BCE_PRINTF("l2_fhdr[0x%04X]: status = 0x%b, "
9280                 "pkt_len = %d, vlan = 0x%04x, ip_xsum/hdr_len = 0x%04X, "
9281                 "tcp_udp_xsum = 0x%04X\n", idx,
9282                 l2fhdr->l2_fhdr_status, BCE_L2FHDR_PRINTFB,
9283                 l2fhdr->l2_fhdr_pkt_len, l2fhdr->l2_fhdr_vlan_tag,
9284                 l2fhdr->l2_fhdr_ip_xsum, l2fhdr->l2_fhdr_tcp_udp_xsum);
9285 }
9286
9287
9288 /****************************************************************************/
9289 /* Prints out context memory info.  (Only useful for CID 0 to 16.)          */
9290 /*                                                                          */
9291 /* Returns:                                                                 */
9292 /*   Nothing.                                                               */
9293 /****************************************************************************/
9294 static __attribute__ ((noinline)) void
9295 bce_dump_ctx(struct bce_softc *sc, u16 cid)
9296 {
9297         if (cid > TX_CID) {
9298                 BCE_PRINTF(" Unknown CID\n");
9299                 return;
9300         }
9301
9302         BCE_PRINTF(
9303             "----------------------------"
9304             "    CTX Data    "
9305             "----------------------------\n");
9306
9307         BCE_PRINTF("     0x%04X - (CID) Context ID\n", cid);
9308
9309         if (cid == RX_CID) {
9310                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BDIDX) host rx "
9311                    "producer index\n",
9312                     CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BDIDX));
9313                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BSEQ) host "
9314                     "byte sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
9315                     BCE_L2CTX_RX_HOST_BSEQ));
9316                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BSEQ) h/w byte sequence\n",
9317                     CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BSEQ));
9318                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_HI) h/w buffer "
9319                     "descriptor address\n",
9320                     CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_HI));
9321                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_LO) h/w buffer "
9322                     "descriptor address\n",
9323                     CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_LO));
9324                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDIDX) h/w rx consumer "
9325                     "index\n", CTX_RD(sc, GET_CID_ADDR(cid),
9326                     BCE_L2CTX_RX_NX_BDIDX));
9327                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_PG_BDIDX) host page "
9328                     "producer index\n", CTX_RD(sc, GET_CID_ADDR(cid), 
9329                     BCE_L2CTX_RX_HOST_PG_BDIDX));
9330                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_PG_BUF_SIZE) host rx_bd/page "
9331                     "buffer size\n", CTX_RD(sc, GET_CID_ADDR(cid), 
9332                     BCE_L2CTX_RX_PG_BUF_SIZE));
9333                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_HI) h/w page "
9334                     "chain address\n", CTX_RD(sc, GET_CID_ADDR(cid), 
9335                     BCE_L2CTX_RX_NX_PG_BDHADDR_HI));
9336                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_LO) h/w page "
9337                     "chain address\n", CTX_RD(sc, GET_CID_ADDR(cid), 
9338                     BCE_L2CTX_RX_NX_PG_BDHADDR_LO));
9339                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDIDX) h/w page "
9340                     "consumer index\n", CTX_RD(sc, GET_CID_ADDR(cid), 
9341                     BCE_L2CTX_RX_NX_PG_BDIDX));
9342         } else if (cid == TX_CID) {
9343                 if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
9344                     (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
9345                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE_XI) ctx type\n",
9346                             CTX_RD(sc, GET_CID_ADDR(cid), 
9347                             BCE_L2CTX_TX_TYPE_XI));
9348                         BCE_PRINTF(" 0x%08X - (L2CTX_CMD_TX_TYPE_XI) ctx "
9349                             "cmd\n", CTX_RD(sc, GET_CID_ADDR(cid), 
9350                             BCE_L2CTX_TX_CMD_TYPE_XI));
9351                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI_XI) "
9352                             "h/w buffer descriptor address\n",  
9353                             CTX_RD(sc, GET_CID_ADDR(cid), 
9354                             BCE_L2CTX_TX_TBDR_BHADDR_HI_XI));
9355                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO_XI) "
9356                             "h/w buffer descriptor address\n", 
9357                             CTX_RD(sc, GET_CID_ADDR(cid),
9358                             BCE_L2CTX_TX_TBDR_BHADDR_LO_XI));
9359                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX_XI) "
9360                             "host producer index\n", 
9361                             CTX_RD(sc, GET_CID_ADDR(cid),
9362                             BCE_L2CTX_TX_HOST_BIDX_XI));
9363                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ_XI) "
9364                             "host byte sequence\n", 
9365                             CTX_RD(sc, GET_CID_ADDR(cid),
9366                             BCE_L2CTX_TX_HOST_BSEQ_XI));
9367                 } else {
9368                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE) ctx type\n",
9369                             CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE));
9370                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_CMD_TYPE) ctx cmd\n",
9371                             CTX_RD(sc, GET_CID_ADDR(cid), 
9372                             BCE_L2CTX_TX_CMD_TYPE));
9373                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI) "
9374                             "h/w buffer descriptor address\n", 
9375                             CTX_RD(sc, GET_CID_ADDR(cid),
9376                             BCE_L2CTX_TX_TBDR_BHADDR_HI));
9377                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO) "
9378                             "h/w buffer descriptor address\n", 
9379                             CTX_RD(sc, GET_CID_ADDR(cid),
9380                             BCE_L2CTX_TX_TBDR_BHADDR_LO));
9381                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX) host "
9382                             "producer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
9383                             BCE_L2CTX_TX_HOST_BIDX));
9384                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ) host byte "
9385                             "sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
9386                             BCE_L2CTX_TX_HOST_BSEQ));
9387                 }
9388         }
9389
9390         BCE_PRINTF(
9391            "----------------------------"
9392            "    Raw CTX     "
9393            "----------------------------\n");
9394
9395         for (int i = 0x0; i < 0x300; i += 0x10) {
9396                 BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n", i,
9397                    CTX_RD(sc, GET_CID_ADDR(cid), i),
9398                    CTX_RD(sc, GET_CID_ADDR(cid), i + 0x4),
9399                    CTX_RD(sc, GET_CID_ADDR(cid), i + 0x8),
9400                    CTX_RD(sc, GET_CID_ADDR(cid), i + 0xc));
9401         }
9402
9403
9404         BCE_PRINTF(
9405            "----------------------------"
9406            "----------------"
9407            "----------------------------\n");
9408 }
9409
9410
9411 /****************************************************************************/
9412 /* Prints out the FTQ data.                                                 */
9413 /*                                                                          */
9414 /* Returns:                                                                */
9415 /*   Nothing.                                                               */
9416 /****************************************************************************/
9417 static __attribute__ ((noinline)) void
9418 bce_dump_ftqs(struct bce_softc *sc)
9419 {
9420         u32 cmd, ctl, cur_depth, max_depth, valid_cnt, val;
9421
9422         BCE_PRINTF(
9423             "----------------------------"
9424             "    FTQ Data    "
9425             "----------------------------\n");
9426
9427         BCE_PRINTF("   FTQ    Command    Control   Depth_Now  "
9428             "Max_Depth  Valid_Cnt \n");
9429         BCE_PRINTF(" ------- ---------- ---------- ---------- "
9430             "---------- ----------\n");
9431
9432         /* Setup the generic statistic counters for the FTQ valid count. */
9433         val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PPQ_VALID_CNT << 24) |
9434             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT  << 16) |
9435             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT   <<  8) |
9436             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT);
9437         REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
9438
9439         val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCHQ_VALID_CNT  << 24) |
9440             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT  << 16) |
9441             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT <<  8) |
9442             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT);
9443         REG_WR(sc, BCE_HC_STAT_GEN_SEL_1, val);
9444
9445         val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPATQ_VALID_CNT  << 24) |
9446             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT  << 16) |
9447             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT   <<  8) |
9448             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT);
9449         REG_WR(sc, BCE_HC_STAT_GEN_SEL_2, val);
9450
9451         val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMQ_VALID_CNT   << 24) |
9452             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT  << 16) |
9453             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT  <<  8) |
9454             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT);
9455         REG_WR(sc, BCE_HC_STAT_GEN_SEL_3, val);
9456
9457         /* Input queue to the Receive Lookup state machine */
9458         cmd = REG_RD(sc, BCE_RLUP_FTQ_CMD);
9459         ctl = REG_RD(sc, BCE_RLUP_FTQ_CTL);
9460         cur_depth = (ctl & BCE_RLUP_FTQ_CTL_CUR_DEPTH) >> 22;
9461         max_depth = (ctl & BCE_RLUP_FTQ_CTL_MAX_DEPTH) >> 12;
9462         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
9463         BCE_PRINTF(" RLUP    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9464             cmd, ctl, cur_depth, max_depth, valid_cnt);
9465
9466         /* Input queue to the Receive Processor */
9467         cmd = REG_RD_IND(sc, BCE_RXP_FTQ_CMD);
9468         ctl = REG_RD_IND(sc, BCE_RXP_FTQ_CTL);
9469         cur_depth = (ctl & BCE_RXP_FTQ_CTL_CUR_DEPTH) >> 22;
9470         max_depth = (ctl & BCE_RXP_FTQ_CTL_MAX_DEPTH) >> 12;
9471         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
9472         BCE_PRINTF(" RXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9473             cmd, ctl, cur_depth, max_depth, valid_cnt);
9474
9475         /* Input queue to the Recevie Processor */
9476         cmd = REG_RD_IND(sc, BCE_RXP_CFTQ_CMD);
9477         ctl = REG_RD_IND(sc, BCE_RXP_CFTQ_CTL);
9478         cur_depth = (ctl & BCE_RXP_CFTQ_CTL_CUR_DEPTH) >> 22;
9479         max_depth = (ctl & BCE_RXP_CFTQ_CTL_MAX_DEPTH) >> 12;
9480         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
9481         BCE_PRINTF(" RXPC    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9482             cmd, ctl, cur_depth, max_depth, valid_cnt);
9483
9484         /* Input queue to the Receive Virtual to Physical state machine */
9485         cmd = REG_RD(sc, BCE_RV2P_PFTQ_CMD);
9486         ctl = REG_RD(sc, BCE_RV2P_PFTQ_CTL);
9487         cur_depth = (ctl & BCE_RV2P_PFTQ_CTL_CUR_DEPTH) >> 22;
9488         max_depth = (ctl & BCE_RV2P_PFTQ_CTL_MAX_DEPTH) >> 12;
9489         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
9490         BCE_PRINTF(" RV2PP   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9491             cmd, ctl, cur_depth, max_depth, valid_cnt);
9492
9493         /* Input queue to the Recevie Virtual to Physical state machine */
9494         cmd = REG_RD(sc, BCE_RV2P_MFTQ_CMD);
9495         ctl = REG_RD(sc, BCE_RV2P_MFTQ_CTL);
9496         cur_depth = (ctl & BCE_RV2P_MFTQ_CTL_CUR_DEPTH) >> 22;
9497         max_depth = (ctl & BCE_RV2P_MFTQ_CTL_MAX_DEPTH) >> 12;
9498         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT4);
9499         BCE_PRINTF(" RV2PM   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9500             cmd, ctl, cur_depth, max_depth, valid_cnt);
9501
9502         /* Input queue to the Receive Virtual to Physical state machine */
9503         cmd = REG_RD(sc, BCE_RV2P_TFTQ_CMD);
9504         ctl = REG_RD(sc, BCE_RV2P_TFTQ_CTL);
9505         cur_depth = (ctl & BCE_RV2P_TFTQ_CTL_CUR_DEPTH) >> 22;
9506         max_depth = (ctl & BCE_RV2P_TFTQ_CTL_MAX_DEPTH) >> 12;
9507         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT5);
9508         BCE_PRINTF(" RV2PT   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9509             cmd, ctl, cur_depth, max_depth, valid_cnt);
9510
9511         /* Input queue to the Receive DMA state machine */
9512         cmd = REG_RD(sc, BCE_RDMA_FTQ_CMD);
9513         ctl = REG_RD(sc, BCE_RDMA_FTQ_CTL);
9514         cur_depth = (ctl & BCE_RDMA_FTQ_CTL_CUR_DEPTH) >> 22;
9515         max_depth = (ctl & BCE_RDMA_FTQ_CTL_MAX_DEPTH) >> 12;
9516         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT6);
9517         BCE_PRINTF(" RDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9518             cmd, ctl, cur_depth, max_depth, valid_cnt);
9519
9520         /* Input queue to the Transmit Scheduler state machine */
9521         cmd = REG_RD(sc, BCE_TSCH_FTQ_CMD);
9522         ctl = REG_RD(sc, BCE_TSCH_FTQ_CTL);
9523         cur_depth = (ctl & BCE_TSCH_FTQ_CTL_CUR_DEPTH) >> 22;
9524         max_depth = (ctl & BCE_TSCH_FTQ_CTL_MAX_DEPTH) >> 12;
9525         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT7);
9526         BCE_PRINTF(" TSCH    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9527             cmd, ctl, cur_depth, max_depth, valid_cnt);
9528
9529         /* Input queue to the Transmit Buffer Descriptor state machine */
9530         cmd = REG_RD(sc, BCE_TBDR_FTQ_CMD);
9531         ctl = REG_RD(sc, BCE_TBDR_FTQ_CTL);
9532         cur_depth = (ctl & BCE_TBDR_FTQ_CTL_CUR_DEPTH) >> 22;
9533         max_depth = (ctl & BCE_TBDR_FTQ_CTL_MAX_DEPTH) >> 12;
9534         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT8);
9535         BCE_PRINTF(" TBDR    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9536             cmd, ctl, cur_depth, max_depth, valid_cnt);
9537
9538         /* Input queue to the Transmit Processor */
9539         cmd = REG_RD_IND(sc, BCE_TXP_FTQ_CMD);
9540         ctl = REG_RD_IND(sc, BCE_TXP_FTQ_CTL);
9541         cur_depth = (ctl & BCE_TXP_FTQ_CTL_CUR_DEPTH) >> 22;
9542         max_depth = (ctl & BCE_TXP_FTQ_CTL_MAX_DEPTH) >> 12;
9543         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT9);
9544         BCE_PRINTF(" TXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9545             cmd, ctl, cur_depth, max_depth, valid_cnt);
9546
9547         /* Input queue to the Transmit DMA state machine */
9548         cmd = REG_RD(sc, BCE_TDMA_FTQ_CMD);
9549         ctl = REG_RD(sc, BCE_TDMA_FTQ_CTL);
9550         cur_depth = (ctl & BCE_TDMA_FTQ_CTL_CUR_DEPTH) >> 22;
9551         max_depth = (ctl & BCE_TDMA_FTQ_CTL_MAX_DEPTH) >> 12;
9552         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT10);
9553         BCE_PRINTF(" TDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9554             cmd, ctl, cur_depth, max_depth, valid_cnt);
9555
9556         /* Input queue to the Transmit Patch-Up Processor */
9557         cmd = REG_RD_IND(sc, BCE_TPAT_FTQ_CMD);
9558         ctl = REG_RD_IND(sc, BCE_TPAT_FTQ_CTL);
9559         cur_depth = (ctl & BCE_TPAT_FTQ_CTL_CUR_DEPTH) >> 22;
9560         max_depth = (ctl & BCE_TPAT_FTQ_CTL_MAX_DEPTH) >> 12;
9561         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT11);
9562         BCE_PRINTF(" TPAT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9563             cmd, ctl, cur_depth, max_depth, valid_cnt);
9564
9565         /* Input queue to the Transmit Assembler state machine */
9566         cmd = REG_RD_IND(sc, BCE_TAS_FTQ_CMD);
9567         ctl = REG_RD_IND(sc, BCE_TAS_FTQ_CTL);
9568         cur_depth = (ctl & BCE_TAS_FTQ_CTL_CUR_DEPTH) >> 22;
9569         max_depth = (ctl & BCE_TAS_FTQ_CTL_MAX_DEPTH) >> 12;
9570         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT12);
9571         BCE_PRINTF(" TAS     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9572             cmd, ctl, cur_depth, max_depth, valid_cnt);
9573
9574         /* Input queue to the Completion Processor */
9575         cmd = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CMD);
9576         ctl = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CTL);
9577         cur_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_CUR_DEPTH) >> 22;
9578         max_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_MAX_DEPTH) >> 12;
9579         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT13);
9580         BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9581             cmd, ctl, cur_depth, max_depth, valid_cnt);
9582
9583         /* Input queue to the Completion Processor */
9584         cmd = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CMD);
9585         ctl = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CTL);
9586         cur_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_CUR_DEPTH) >> 22;
9587         max_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_MAX_DEPTH) >> 12;
9588         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT14);
9589         BCE_PRINTF(" COMT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9590             cmd, ctl, cur_depth, max_depth, valid_cnt);
9591
9592         /* Input queue to the Completion Processor */
9593         cmd = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CMD);
9594         ctl = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CTL);
9595         cur_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_CUR_DEPTH) >> 22;
9596         max_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_MAX_DEPTH) >> 12;
9597         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT15);
9598         BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9599             cmd, ctl, cur_depth, max_depth, valid_cnt);
9600
9601         /* Setup the generic statistic counters for the FTQ valid count. */
9602         val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSQ_VALID_CNT  << 16) |
9603             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT  <<  8) |
9604             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT);
9605
9606         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
9607             (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
9608                 val = val | 
9609                     (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCSQ_VALID_CNT_XI << 
9610                      24);
9611         REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
9612
9613         /* Input queue to the Management Control Processor */
9614         cmd = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CMD);
9615         ctl = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CTL);
9616         cur_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_CUR_DEPTH) >> 22;
9617         max_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_MAX_DEPTH) >> 12;
9618         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
9619         BCE_PRINTF(" MCP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9620             cmd, ctl, cur_depth, max_depth, valid_cnt);
9621
9622         /* Input queue to the Command Processor */
9623         cmd = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CMD);
9624         ctl = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CTL);
9625         cur_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_CUR_DEPTH) >> 22;
9626         max_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_MAX_DEPTH) >> 12;
9627         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
9628         BCE_PRINTF(" CP      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9629             cmd, ctl, cur_depth, max_depth, valid_cnt);
9630
9631         /* Input queue to the Completion Scheduler state machine */
9632         cmd = REG_RD(sc, BCE_CSCH_CH_FTQ_CMD);
9633         ctl = REG_RD(sc, BCE_CSCH_CH_FTQ_CTL);
9634         cur_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_CUR_DEPTH) >> 22;
9635         max_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_MAX_DEPTH) >> 12;
9636         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
9637         BCE_PRINTF(" CS      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9638             cmd, ctl, cur_depth, max_depth, valid_cnt);
9639
9640         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
9641             (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
9642                 /* Input queue to the RV2P Command Scheduler */
9643                 cmd = REG_RD(sc, BCE_RV2PCSR_FTQ_CMD);
9644                 ctl = REG_RD(sc, BCE_RV2PCSR_FTQ_CTL);
9645                 cur_depth = (ctl & 0xFFC00000) >> 22;
9646                 max_depth = (ctl & 0x003FF000) >> 12;
9647                 valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
9648                 BCE_PRINTF(" RV2PCSR 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9649                     cmd, ctl, cur_depth, max_depth, valid_cnt);
9650         }
9651
9652         BCE_PRINTF(
9653             "----------------------------"
9654             "----------------"
9655             "----------------------------\n");
9656 }
9657
9658
9659 /****************************************************************************/
9660 /* Prints out the TX chain.                                                 */
9661 /*                                                                          */
9662 /* Returns:                                                                 */
9663 /*   Nothing.                                                               */
9664 /****************************************************************************/
9665 static __attribute__ ((noinline)) void
9666 bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count)
9667 {
9668         struct tx_bd *txbd;
9669
9670         /* First some info about the tx_bd chain structure. */
9671         BCE_PRINTF(
9672             "----------------------------"
9673             "  tx_bd  chain  "
9674             "----------------------------\n");
9675
9676         BCE_PRINTF("page size      = 0x%08X, tx chain pages        = 0x%08X\n",
9677             (u32) BCM_PAGE_SIZE, (u32) TX_PAGES);
9678         BCE_PRINTF("tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
9679             (u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
9680         BCE_PRINTF("total tx_bd    = 0x%08X\n", (u32) TOTAL_TX_BD);
9681
9682         BCE_PRINTF(
9683             "----------------------------"
9684             "   tx_bd data   "
9685             "----------------------------\n");
9686
9687         /* Now print out a decoded list of TX buffer descriptors. */
9688         for (int i = 0; i < count; i++) {
9689                 txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
9690                 bce_dump_txbd(sc, tx_prod, txbd);
9691                 tx_prod++;
9692         }
9693
9694         BCE_PRINTF(
9695             "----------------------------"
9696             "----------------"
9697             "----------------------------\n");
9698 }
9699
9700
9701 /****************************************************************************/
9702 /* Prints out the RX chain.                                                 */
9703 /*                                                                          */
9704 /* Returns:                                                                 */
9705 /*   Nothing.                                                               */
9706 /****************************************************************************/
9707 static __attribute__ ((noinline)) void
9708 bce_dump_rx_bd_chain(struct bce_softc *sc, u16 rx_prod, int count)
9709 {
9710         struct rx_bd *rxbd;
9711
9712         /* First some info about the rx_bd chain structure. */
9713         BCE_PRINTF(
9714             "----------------------------"
9715             "  rx_bd  chain  "
9716             "----------------------------\n");
9717
9718         BCE_PRINTF("page size      = 0x%08X, rx chain pages        = 0x%08X\n",
9719             (u32) BCM_PAGE_SIZE, (u32) RX_PAGES);
9720
9721         BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
9722             (u32) TOTAL_RX_BD_PER_PAGE, (u32) USABLE_RX_BD_PER_PAGE);
9723
9724         BCE_PRINTF("total rx_bd    = 0x%08X\n", (u32) TOTAL_RX_BD);
9725
9726         BCE_PRINTF(
9727             "----------------------------"
9728             "   rx_bd data   "
9729             "----------------------------\n");
9730
9731         /* Now print out the rx_bd's themselves. */
9732         for (int i = 0; i < count; i++) {
9733                 rxbd = &sc->rx_bd_chain[RX_PAGE(rx_prod)][RX_IDX(rx_prod)];
9734                 bce_dump_rxbd(sc, rx_prod, rxbd);
9735                 rx_prod = RX_CHAIN_IDX(rx_prod + 1);
9736         }
9737
9738         BCE_PRINTF(
9739             "----------------------------"
9740             "----------------"
9741             "----------------------------\n");
9742 }
9743
9744
9745 #ifdef BCE_JUMBO_HDRSPLIT
9746 /****************************************************************************/
9747 /* Prints out the page chain.                                               */
9748 /*                                                                          */
9749 /* Returns:                                                                 */
9750 /*   Nothing.                                                               */
9751 /****************************************************************************/
9752 static __attribute__ ((noinline)) void
9753 bce_dump_pg_chain(struct bce_softc *sc, u16 pg_prod, int count)
9754 {
9755         struct rx_bd *pgbd;
9756
9757         /* First some info about the page chain structure. */
9758         BCE_PRINTF(
9759             "----------------------------"
9760             "   page chain   "
9761             "----------------------------\n");
9762
9763         BCE_PRINTF("page size      = 0x%08X, pg chain pages        = 0x%08X\n",
9764             (u32) BCM_PAGE_SIZE, (u32) PG_PAGES);
9765
9766         BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
9767             (u32) TOTAL_PG_BD_PER_PAGE, (u32) USABLE_PG_BD_PER_PAGE);
9768
9769         BCE_PRINTF("total rx_bd    = 0x%08X, max_pg_bd             = 0x%08X\n",
9770             (u32) TOTAL_PG_BD, (u32) MAX_PG_BD);
9771
9772         BCE_PRINTF(
9773             "----------------------------"
9774             "   page data    "
9775             "----------------------------\n");
9776
9777         /* Now print out the rx_bd's themselves. */
9778         for (int i = 0; i < count; i++) {
9779                 pgbd = &sc->pg_bd_chain[PG_PAGE(pg_prod)][PG_IDX(pg_prod)];
9780                 bce_dump_pgbd(sc, pg_prod, pgbd);
9781                 pg_prod = PG_CHAIN_IDX(pg_prod + 1);
9782         }
9783
9784         BCE_PRINTF(
9785             "----------------------------"
9786             "----------------"
9787             "----------------------------\n");
9788 }
9789 #endif
9790
9791
9792 #define BCE_PRINT_RX_CONS(arg)                                          \
9793 if (sblk->status_rx_quick_consumer_index##arg)                          \
9794         BCE_PRINTF("0x%04X(0x%04X) - rx_quick_consumer_index%d\n",      \
9795             sblk->status_rx_quick_consumer_index##arg, (u16)            \
9796             RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index##arg),    \
9797             arg);
9798
9799
9800 #define BCE_PRINT_TX_CONS(arg)                                          \
9801 if (sblk->status_tx_quick_consumer_index##arg)                          \
9802         BCE_PRINTF("0x%04X(0x%04X) - tx_quick_consumer_index%d\n",      \
9803             sblk->status_tx_quick_consumer_index##arg, (u16)            \
9804             TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index##arg),    \
9805             arg);
9806
9807 /****************************************************************************/
9808 /* Prints out the status block from host memory.                            */
9809 /*                                                                          */
9810 /* Returns:                                                                 */
9811 /*   Nothing.                                                               */
9812 /****************************************************************************/
9813 static __attribute__ ((noinline)) void
9814 bce_dump_status_block(struct bce_softc *sc)
9815 {
9816         struct status_block *sblk;
9817
9818         sblk = sc->status_block;
9819
9820         BCE_PRINTF(
9821             "----------------------------"
9822             "  Status Block  "
9823             "----------------------------\n");
9824
9825         /* Theses indices are used for normal L2 drivers. */
9826         BCE_PRINTF("    0x%08X - attn_bits\n",
9827             sblk->status_attn_bits);
9828
9829         BCE_PRINTF("    0x%08X - attn_bits_ack\n",
9830             sblk->status_attn_bits_ack);
9831
9832         BCE_PRINT_RX_CONS(0);
9833         BCE_PRINT_TX_CONS(0)
9834
9835         BCE_PRINTF("        0x%04X - status_idx\n", sblk->status_idx);
9836
9837         /* Theses indices are not used for normal L2 drivers. */
9838         BCE_PRINT_RX_CONS(1);   BCE_PRINT_RX_CONS(2);   BCE_PRINT_RX_CONS(3);
9839         BCE_PRINT_RX_CONS(4);   BCE_PRINT_RX_CONS(5);   BCE_PRINT_RX_CONS(6);
9840         BCE_PRINT_RX_CONS(7);   BCE_PRINT_RX_CONS(8);   BCE_PRINT_RX_CONS(9);
9841         BCE_PRINT_RX_CONS(10);  BCE_PRINT_RX_CONS(11);  BCE_PRINT_RX_CONS(12);
9842         BCE_PRINT_RX_CONS(13);  BCE_PRINT_RX_CONS(14);  BCE_PRINT_RX_CONS(15);
9843
9844         BCE_PRINT_TX_CONS(1);   BCE_PRINT_TX_CONS(2);   BCE_PRINT_TX_CONS(3);
9845
9846         if (sblk->status_completion_producer_index ||
9847             sblk->status_cmd_consumer_index)
9848                 BCE_PRINTF("com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
9849                     sblk->status_completion_producer_index,
9850                     sblk->status_cmd_consumer_index);
9851
9852         BCE_PRINTF(
9853             "----------------------------"
9854             "----------------"
9855             "----------------------------\n");
9856 }
9857
9858
9859 #define BCE_PRINT_64BIT_STAT(arg)                               \
9860 if (sblk->arg##_lo || sblk->arg##_hi)                           \
9861         BCE_PRINTF("0x%08X:%08X : %s\n", sblk->arg##_hi,        \
9862             sblk->arg##_lo, #arg);
9863
9864 #define BCE_PRINT_32BIT_STAT(arg)                               \
9865 if (sblk->arg)                                                  \
9866         BCE_PRINTF("         0x%08X : %s\n",                    \
9867             sblk->arg, #arg);
9868
9869 /****************************************************************************/
9870 /* Prints out the statistics block from host memory.                        */
9871 /*                                                                          */
9872 /* Returns:                                                                 */
9873 /*   Nothing.                                                               */
9874 /****************************************************************************/
9875 static __attribute__ ((noinline)) void
9876 bce_dump_stats_block(struct bce_softc *sc)
9877 {
9878         struct statistics_block *sblk;
9879
9880         sblk = sc->stats_block;
9881
9882         BCE_PRINTF(
9883             "---------------"
9884             " Stats Block  (All Stats Not Shown Are 0) "
9885             "---------------\n");
9886
9887         BCE_PRINT_64BIT_STAT(stat_IfHCInOctets);
9888         BCE_PRINT_64BIT_STAT(stat_IfHCInBadOctets);
9889         BCE_PRINT_64BIT_STAT(stat_IfHCOutOctets);
9890         BCE_PRINT_64BIT_STAT(stat_IfHCOutBadOctets);
9891         BCE_PRINT_64BIT_STAT(stat_IfHCInUcastPkts);
9892         BCE_PRINT_64BIT_STAT(stat_IfHCInBroadcastPkts);
9893         BCE_PRINT_64BIT_STAT(stat_IfHCInMulticastPkts);
9894         BCE_PRINT_64BIT_STAT(stat_IfHCOutUcastPkts);
9895         BCE_PRINT_64BIT_STAT(stat_IfHCOutBroadcastPkts);
9896         BCE_PRINT_64BIT_STAT(stat_IfHCOutMulticastPkts);
9897         BCE_PRINT_32BIT_STAT(
9898             stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
9899         BCE_PRINT_32BIT_STAT(stat_Dot3StatsCarrierSenseErrors);
9900         BCE_PRINT_32BIT_STAT(stat_Dot3StatsFCSErrors);
9901         BCE_PRINT_32BIT_STAT(stat_Dot3StatsAlignmentErrors);
9902         BCE_PRINT_32BIT_STAT(stat_Dot3StatsSingleCollisionFrames);
9903         BCE_PRINT_32BIT_STAT(stat_Dot3StatsMultipleCollisionFrames);
9904         BCE_PRINT_32BIT_STAT(stat_Dot3StatsDeferredTransmissions);
9905         BCE_PRINT_32BIT_STAT(stat_Dot3StatsExcessiveCollisions);
9906         BCE_PRINT_32BIT_STAT(stat_Dot3StatsLateCollisions);
9907         BCE_PRINT_32BIT_STAT(stat_EtherStatsCollisions);
9908         BCE_PRINT_32BIT_STAT(stat_EtherStatsFragments);
9909         BCE_PRINT_32BIT_STAT(stat_EtherStatsJabbers);
9910         BCE_PRINT_32BIT_STAT(stat_EtherStatsUndersizePkts);
9911         BCE_PRINT_32BIT_STAT(stat_EtherStatsOversizePkts);
9912         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx64Octets);
9913         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx65Octetsto127Octets);
9914         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx128Octetsto255Octets);
9915         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx256Octetsto511Octets);
9916         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx512Octetsto1023Octets);
9917         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1024Octetsto1522Octets);
9918         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1523Octetsto9022Octets);
9919         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx64Octets);
9920         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx65Octetsto127Octets);
9921         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx128Octetsto255Octets);
9922         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx256Octetsto511Octets);
9923         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx512Octetsto1023Octets);
9924         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1024Octetsto1522Octets);
9925         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1523Octetsto9022Octets);
9926         BCE_PRINT_32BIT_STAT(stat_XonPauseFramesReceived);
9927         BCE_PRINT_32BIT_STAT(stat_XoffPauseFramesReceived);
9928         BCE_PRINT_32BIT_STAT(stat_OutXonSent);
9929         BCE_PRINT_32BIT_STAT(stat_OutXoffSent);
9930         BCE_PRINT_32BIT_STAT(stat_FlowControlDone);
9931         BCE_PRINT_32BIT_STAT(stat_MacControlFramesReceived);
9932         BCE_PRINT_32BIT_STAT(stat_XoffStateEntered);
9933         BCE_PRINT_32BIT_STAT(stat_IfInFramesL2FilterDiscards);
9934         BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerDiscards);
9935         BCE_PRINT_32BIT_STAT(stat_IfInFTQDiscards);
9936         BCE_PRINT_32BIT_STAT(stat_IfInMBUFDiscards);
9937         BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerP4Hit);
9938         BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerDiscards);
9939         BCE_PRINT_32BIT_STAT(stat_CatchupInFTQDiscards);
9940         BCE_PRINT_32BIT_STAT(stat_CatchupInMBUFDiscards);
9941         BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerP4Hit);
9942
9943         BCE_PRINTF(
9944             "----------------------------"
9945             "----------------"
9946             "----------------------------\n");
9947 }
9948
9949
9950 /****************************************************************************/
9951 /* Prints out a summary of the driver state.                                */
9952 /*                                                                          */
9953 /* Returns:                                                                 */
9954 /*   Nothing.                                                               */
9955 /****************************************************************************/
9956 static __attribute__ ((noinline)) void
9957 bce_dump_driver_state(struct bce_softc *sc)
9958 {
9959         u32 val_hi, val_lo;
9960
9961         BCE_PRINTF(
9962             "-----------------------------"
9963             " Driver State "
9964             "-----------------------------\n");
9965
9966         val_hi = BCE_ADDR_HI(sc);
9967         val_lo = BCE_ADDR_LO(sc);
9968         BCE_PRINTF("0x%08X:%08X - (sc) driver softc structure virtual "
9969             "address\n", val_hi, val_lo);
9970
9971         val_hi = BCE_ADDR_HI(sc->bce_vhandle);
9972         val_lo = BCE_ADDR_LO(sc->bce_vhandle);
9973         BCE_PRINTF("0x%08X:%08X - (sc->bce_vhandle) PCI BAR virtual "
9974             "address\n", val_hi, val_lo);
9975
9976         val_hi = BCE_ADDR_HI(sc->status_block);
9977         val_lo = BCE_ADDR_LO(sc->status_block);
9978         BCE_PRINTF("0x%08X:%08X - (sc->status_block) status block "
9979             "virtual address\n",        val_hi, val_lo);
9980
9981         val_hi = BCE_ADDR_HI(sc->stats_block);
9982         val_lo = BCE_ADDR_LO(sc->stats_block);
9983         BCE_PRINTF("0x%08X:%08X - (sc->stats_block) statistics block "
9984             "virtual address\n", val_hi, val_lo);
9985
9986         val_hi = BCE_ADDR_HI(sc->tx_bd_chain);
9987         val_lo = BCE_ADDR_LO(sc->tx_bd_chain);
9988         BCE_PRINTF("0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain "
9989             "virtual adddress\n", val_hi, val_lo);
9990
9991         val_hi = BCE_ADDR_HI(sc->rx_bd_chain);
9992         val_lo = BCE_ADDR_LO(sc->rx_bd_chain);
9993         BCE_PRINTF("0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain "
9994             "virtual address\n", val_hi, val_lo);
9995
9996 #ifdef BCE_JUMBO_HDRSPLIT
9997         val_hi = BCE_ADDR_HI(sc->pg_bd_chain);
9998         val_lo = BCE_ADDR_LO(sc->pg_bd_chain);
9999         BCE_PRINTF("0x%08X:%08X - (sc->pg_bd_chain) page chain "
10000             "virtual address\n", val_hi, val_lo);
10001 #endif
10002
10003         val_hi = BCE_ADDR_HI(sc->tx_mbuf_ptr);
10004         val_lo = BCE_ADDR_LO(sc->tx_mbuf_ptr);
10005         BCE_PRINTF("0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain "
10006             "virtual address\n",        val_hi, val_lo);
10007
10008         val_hi = BCE_ADDR_HI(sc->rx_mbuf_ptr);
10009         val_lo = BCE_ADDR_LO(sc->rx_mbuf_ptr);
10010         BCE_PRINTF("0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain "
10011             "virtual address\n", val_hi, val_lo);
10012
10013 #ifdef BCE_JUMBO_HDRSPLIT
10014         val_hi = BCE_ADDR_HI(sc->pg_mbuf_ptr);
10015         val_lo = BCE_ADDR_LO(sc->pg_mbuf_ptr);
10016         BCE_PRINTF("0x%08X:%08X - (sc->pg_mbuf_ptr) page mbuf chain "
10017             "virtual address\n", val_hi, val_lo);
10018 #endif
10019
10020         BCE_PRINTF("         0x%08X - (sc->interrupts_generated) "
10021             "h/w intrs\n", sc->interrupts_generated);
10022
10023         BCE_PRINTF("         0x%08X - (sc->rx_interrupts) "
10024             "rx interrupts handled\n", sc->rx_interrupts);
10025
10026         BCE_PRINTF("         0x%08X - (sc->tx_interrupts) "
10027             "tx interrupts handled\n", sc->tx_interrupts);
10028
10029         BCE_PRINTF("         0x%08X - (sc->phy_interrupts) "
10030             "phy interrupts handled\n", sc->phy_interrupts);
10031
10032         BCE_PRINTF("         0x%08X - (sc->last_status_idx) "
10033             "status block index\n", sc->last_status_idx);
10034
10035         BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_prod) tx producer "
10036             "index\n", sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod));
10037
10038         BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_cons) tx consumer "
10039             "index\n", sc->tx_cons, (u16) TX_CHAIN_IDX(sc->tx_cons));
10040
10041         BCE_PRINTF("         0x%08X - (sc->tx_prod_bseq) tx producer "
10042             "byte seq index\n", sc->tx_prod_bseq);
10043
10044         BCE_PRINTF("         0x%08X - (sc->debug_tx_mbuf_alloc) tx "
10045             "mbufs allocated\n", sc->debug_tx_mbuf_alloc);
10046
10047         BCE_PRINTF("         0x%08X - (sc->used_tx_bd) used "
10048             "tx_bd's\n", sc->used_tx_bd);
10049
10050         BCE_PRINTF("0x%08X/%08X - (sc->tx_hi_watermark) tx hi "
10051             "watermark\n", sc->tx_hi_watermark, sc->max_tx_bd);
10052
10053         BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_prod) rx producer "
10054             "index\n", sc->rx_prod, (u16) RX_CHAIN_IDX(sc->rx_prod));
10055
10056         BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_cons) rx consumer "
10057             "index\n", sc->rx_cons, (u16) RX_CHAIN_IDX(sc->rx_cons));
10058
10059         BCE_PRINTF("         0x%08X - (sc->rx_prod_bseq) rx producer "
10060             "byte seq index\n", sc->rx_prod_bseq);
10061
10062         BCE_PRINTF("         0x%08X - (sc->debug_rx_mbuf_alloc) rx "
10063             "mbufs allocated\n", sc->debug_rx_mbuf_alloc);
10064
10065         BCE_PRINTF("         0x%08X - (sc->free_rx_bd) free "
10066             "rx_bd's\n", sc->free_rx_bd);
10067
10068 #ifdef BCE_JUMBO_HDRSPLIT
10069         BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_prod) page producer "
10070             "index\n", sc->pg_prod, (u16) PG_CHAIN_IDX(sc->pg_prod));
10071
10072         BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_cons) page consumer "
10073             "index\n", sc->pg_cons, (u16) PG_CHAIN_IDX(sc->pg_cons));
10074
10075         BCE_PRINTF("         0x%08X - (sc->debug_pg_mbuf_alloc) page "
10076             "mbufs allocated\n", sc->debug_pg_mbuf_alloc);
10077
10078         BCE_PRINTF("         0x%08X - (sc->free_pg_bd) free page "
10079             "rx_bd's\n", sc->free_pg_bd);
10080
10081         BCE_PRINTF("0x%08X/%08X - (sc->pg_low_watermark) page low "
10082             "watermark\n", sc->pg_low_watermark, sc->max_pg_bd);
10083 #endif
10084
10085         BCE_PRINTF("         0x%08X - (sc->mbuf_alloc_failed_count) "
10086             "mbuf alloc failures\n", sc->mbuf_alloc_failed_count);
10087
10088         BCE_PRINTF("         0x%08X - (sc->bce_flags) "
10089             "bce mac flags\n", sc->bce_flags);
10090
10091         BCE_PRINTF("         0x%08X - (sc->bce_phy_flags) "
10092             "bce phy flags\n", sc->bce_phy_flags);
10093
10094         BCE_PRINTF(
10095             "----------------------------"
10096             "----------------"
10097             "----------------------------\n");
10098 }
10099
10100
10101 /****************************************************************************/
10102 /* Prints out the hardware state through a summary of important register,   */
10103 /* followed by a complete register dump.                                    */
10104 /*                                                                          */
10105 /* Returns:                                                                 */
10106 /*   Nothing.                                                               */
10107 /****************************************************************************/
10108 static __attribute__ ((noinline)) void
10109 bce_dump_hw_state(struct bce_softc *sc)
10110 {
10111         u32 val;
10112
10113         BCE_PRINTF(
10114             "----------------------------"
10115             " Hardware State "
10116             "----------------------------\n");
10117
10118         BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
10119
10120         val = REG_RD(sc, BCE_MISC_ENABLE_STATUS_BITS);
10121         BCE_PRINTF("0x%08X - (0x%06X) misc_enable_status_bits\n",
10122             val, BCE_MISC_ENABLE_STATUS_BITS);
10123
10124         val = REG_RD(sc, BCE_DMA_STATUS);
10125         BCE_PRINTF("0x%08X - (0x%06X) dma_status\n", 
10126             val, BCE_DMA_STATUS);
10127
10128         val = REG_RD(sc, BCE_CTX_STATUS);
10129         BCE_PRINTF("0x%08X - (0x%06X) ctx_status\n", 
10130             val, BCE_CTX_STATUS);
10131
10132         val = REG_RD(sc, BCE_EMAC_STATUS);
10133         BCE_PRINTF("0x%08X - (0x%06X) emac_status\n", 
10134             val, BCE_EMAC_STATUS);
10135
10136         val = REG_RD(sc, BCE_RPM_STATUS);
10137         BCE_PRINTF("0x%08X - (0x%06X) rpm_status\n",
10138             val, BCE_RPM_STATUS);
10139
10140         /* ToDo: Create a #define for this constant. */
10141         val = REG_RD(sc, 0x2004);
10142         BCE_PRINTF("0x%08X - (0x%06X) rlup_status\n", 
10143             val, 0x2004);
10144
10145         val = REG_RD(sc, BCE_RV2P_STATUS);
10146         BCE_PRINTF("0x%08X - (0x%06X) rv2p_status\n", 
10147             val, BCE_RV2P_STATUS);
10148
10149         /* ToDo: Create a #define for this constant. */
10150         val = REG_RD(sc, 0x2c04);
10151         BCE_PRINTF("0x%08X - (0x%06X) rdma_status\n", 
10152             val, 0x2c04);
10153
10154         val = REG_RD(sc, BCE_TBDR_STATUS);
10155         BCE_PRINTF("0x%08X - (0x%06X) tbdr_status\n",
10156             val, BCE_TBDR_STATUS);
10157
10158         val = REG_RD(sc, BCE_TDMA_STATUS);
10159         BCE_PRINTF("0x%08X - (0x%06X) tdma_status\n", 
10160             val, BCE_TDMA_STATUS);
10161
10162         val = REG_RD(sc, BCE_HC_STATUS);
10163         BCE_PRINTF("0x%08X - (0x%06X) hc_status\n",
10164             val, BCE_HC_STATUS);
10165
10166         val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
10167         BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n", 
10168             val, BCE_TXP_CPU_STATE);
10169
10170         val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
10171         BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n", 
10172             val, BCE_TPAT_CPU_STATE);
10173
10174         val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
10175         BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n", 
10176             val, BCE_RXP_CPU_STATE);
10177
10178         val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
10179         BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n", 
10180             val, BCE_COM_CPU_STATE);
10181
10182         val = REG_RD_IND(sc, BCE_MCP_CPU_STATE);
10183         BCE_PRINTF("0x%08X - (0x%06X) mcp_cpu_state\n", 
10184             val, BCE_MCP_CPU_STATE);
10185
10186         val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
10187         BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n", 
10188             val, BCE_CP_CPU_STATE);
10189
10190         BCE_PRINTF(
10191             "----------------------------"
10192             "----------------"
10193             "----------------------------\n");
10194
10195         BCE_PRINTF(
10196             "----------------------------"
10197             " Register  Dump "
10198             "----------------------------\n");
10199
10200         for (int i = 0x400; i < 0x8000; i += 0x10) {
10201                 BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10202                     i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
10203                     REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
10204         }
10205
10206         BCE_PRINTF(
10207             "----------------------------"
10208             "----------------"
10209             "----------------------------\n");
10210 }
10211
10212
10213 /****************************************************************************/
10214 /* Prints out the mailbox queue registers.                                  */
10215 /*                                                                          */
10216 /* Returns:                                                                 */
10217 /*   Nothing.                                                               */
10218 /****************************************************************************/
10219 static __attribute__ ((noinline)) void
10220 bce_dump_mq_regs(struct bce_softc *sc)
10221 {
10222         BCE_PRINTF(
10223             "----------------------------"
10224             "    MQ Regs     "
10225             "----------------------------\n");
10226
10227         BCE_PRINTF(
10228             "----------------------------"
10229             "----------------"
10230             "----------------------------\n");
10231
10232         for (int i = 0x3c00; i < 0x4000; i += 0x10) {
10233                 BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10234                     i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
10235                     REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
10236         }
10237
10238         BCE_PRINTF(
10239             "----------------------------"
10240             "----------------"
10241             "----------------------------\n");
10242 }
10243
10244
10245 /****************************************************************************/
10246 /* Prints out the bootcode state.                                           */
10247 /*                                                                          */
10248 /* Returns:                                                                 */
10249 /*   Nothing.                                                               */
10250 /****************************************************************************/
10251 static __attribute__ ((noinline)) void
10252 bce_dump_bc_state(struct bce_softc *sc)
10253 {
10254         u32 val;
10255
10256         BCE_PRINTF(
10257             "----------------------------"
10258             " Bootcode State "
10259             "----------------------------\n");
10260
10261         BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
10262
10263         val = bce_shmem_rd(sc, BCE_BC_RESET_TYPE);
10264         BCE_PRINTF("0x%08X - (0x%06X) reset_type\n",
10265             val, BCE_BC_RESET_TYPE);
10266
10267         val = bce_shmem_rd(sc, BCE_BC_STATE);
10268         BCE_PRINTF("0x%08X - (0x%06X) state\n",
10269             val, BCE_BC_STATE);
10270
10271         val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
10272         BCE_PRINTF("0x%08X - (0x%06X) condition\n",
10273             val, BCE_BC_STATE_CONDITION);
10274
10275         val = bce_shmem_rd(sc, BCE_BC_STATE_DEBUG_CMD);
10276         BCE_PRINTF("0x%08X - (0x%06X) debug_cmd\n",
10277             val, BCE_BC_STATE_DEBUG_CMD);
10278
10279         BCE_PRINTF(
10280             "----------------------------"
10281             "----------------"
10282             "----------------------------\n");
10283 }
10284
10285
10286 /****************************************************************************/
10287 /* Prints out the TXP processor state.                                      */
10288 /*                                                                          */
10289 /* Returns:                                                                 */
10290 /*   Nothing.                                                               */
10291 /****************************************************************************/
10292 static __attribute__ ((noinline)) void
10293 bce_dump_txp_state(struct bce_softc *sc, int regs)
10294 {
10295         u32 val;
10296         u32 fw_version[3];
10297
10298         BCE_PRINTF(
10299             "----------------------------"
10300             "   TXP  State   "
10301             "----------------------------\n");
10302
10303         for (int i = 0; i < 3; i++)
10304                 fw_version[i] = htonl(REG_RD_IND(sc,
10305                     (BCE_TXP_SCRATCH + 0x10 + i * 4)));
10306         BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10307
10308         val = REG_RD_IND(sc, BCE_TXP_CPU_MODE);
10309         BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_mode\n", 
10310             val, BCE_TXP_CPU_MODE);
10311
10312         val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
10313         BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n", 
10314             val, BCE_TXP_CPU_STATE);
10315
10316         val = REG_RD_IND(sc, BCE_TXP_CPU_EVENT_MASK);
10317         BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_event_mask\n", 
10318             val, BCE_TXP_CPU_EVENT_MASK);
10319
10320         if (regs) {
10321                 BCE_PRINTF(
10322                     "----------------------------"
10323                     " Register  Dump "
10324                     "----------------------------\n");
10325
10326                 for (int i = BCE_TXP_CPU_MODE; i < 0x68000; i += 0x10) {
10327                         /* Skip the big blank spaces */
10328                         if (i < 0x454000 && i > 0x5ffff)
10329                                 BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
10330                                     "0x%08X 0x%08X\n", i, 
10331                                     REG_RD_IND(sc, i), 
10332                                     REG_RD_IND(sc, i + 0x4),
10333                                     REG_RD_IND(sc, i + 0x8),
10334                                     REG_RD_IND(sc, i + 0xC));
10335                 }
10336         }
10337
10338         BCE_PRINTF(
10339             "----------------------------"
10340             "----------------"
10341             "----------------------------\n");
10342 }
10343
10344
10345 /****************************************************************************/
10346 /* Prints out the RXP processor state.                                      */
10347 /*                                                                          */
10348 /* Returns:                                                                 */
10349 /*   Nothing.                                                               */
10350 /****************************************************************************/
10351 static __attribute__ ((noinline)) void
10352 bce_dump_rxp_state(struct bce_softc *sc, int regs)
10353 {
10354         u32 val;
10355         u32 fw_version[3];
10356
10357         BCE_PRINTF(
10358             "----------------------------"
10359             "   RXP  State   "
10360             "----------------------------\n");
10361
10362         for (int i = 0; i < 3; i++)
10363                 fw_version[i] = htonl(REG_RD_IND(sc,
10364                     (BCE_RXP_SCRATCH + 0x10 + i * 4)));
10365
10366         BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10367
10368         val = REG_RD_IND(sc, BCE_RXP_CPU_MODE);
10369         BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_mode\n", 
10370             val, BCE_RXP_CPU_MODE);
10371
10372         val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
10373         BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n", 
10374             val, BCE_RXP_CPU_STATE);
10375
10376         val = REG_RD_IND(sc, BCE_RXP_CPU_EVENT_MASK);
10377         BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_event_mask\n", 
10378             val, BCE_RXP_CPU_EVENT_MASK);
10379
10380         if (regs) {
10381                 BCE_PRINTF(
10382                     "----------------------------"
10383                     " Register  Dump "
10384                     "----------------------------\n");
10385
10386                 for (int i = BCE_RXP_CPU_MODE; i < 0xe8fff; i += 0x10) {
10387                         /* Skip the big blank sapces */
10388                         if (i < 0xc5400 && i > 0xdffff)
10389                                 BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
10390                                     "0x%08X 0x%08X\n", i, 
10391                                     REG_RD_IND(sc, i), 
10392                                     REG_RD_IND(sc, i + 0x4),
10393                                     REG_RD_IND(sc, i + 0x8), 
10394                                     REG_RD_IND(sc, i + 0xC));
10395                 }
10396         }
10397
10398         BCE_PRINTF(
10399             "----------------------------"
10400             "----------------"
10401             "----------------------------\n");
10402 }
10403
10404
10405 /****************************************************************************/
10406 /* Prints out the TPAT processor state.                                     */
10407 /*                                                                          */
10408 /* Returns:                                                                 */
10409 /*   Nothing.                                                               */
10410 /****************************************************************************/
10411 static __attribute__ ((noinline)) void
10412 bce_dump_tpat_state(struct bce_softc *sc, int regs)
10413 {
10414         u32 val;
10415         u32 fw_version[3];
10416
10417         BCE_PRINTF(
10418             "----------------------------"
10419             "   TPAT State   "
10420             "----------------------------\n");
10421
10422         for (int i = 0; i < 3; i++)
10423                 fw_version[i] = htonl(REG_RD_IND(sc,
10424                     (BCE_TPAT_SCRATCH + 0x410 + i * 4)));
10425
10426         BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10427
10428         val = REG_RD_IND(sc, BCE_TPAT_CPU_MODE);
10429         BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_mode\n", 
10430             val, BCE_TPAT_CPU_MODE);
10431
10432         val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
10433         BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n", 
10434             val, BCE_TPAT_CPU_STATE);
10435
10436         val = REG_RD_IND(sc, BCE_TPAT_CPU_EVENT_MASK);
10437         BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_event_mask\n", 
10438             val, BCE_TPAT_CPU_EVENT_MASK);
10439
10440         if (regs) {
10441                 BCE_PRINTF(
10442                     "----------------------------"
10443                     " Register  Dump "
10444                     "----------------------------\n");
10445
10446                 for (int i = BCE_TPAT_CPU_MODE; i < 0xa3fff; i += 0x10) {
10447                         /* Skip the big blank spaces */
10448                         if (i < 0x854000 && i > 0x9ffff)
10449                                 BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
10450                                     "0x%08X 0x%08X\n", i,
10451                                     REG_RD_IND(sc, i), 
10452                                     REG_RD_IND(sc, i + 0x4),
10453                                     REG_RD_IND(sc, i + 0x8), 
10454                                     REG_RD_IND(sc, i + 0xC));
10455                 }
10456         }
10457
10458         BCE_PRINTF(
10459                 "----------------------------"
10460                 "----------------"
10461                 "----------------------------\n");
10462 }
10463
10464
10465 /****************************************************************************/
10466 /* Prints out the Command Procesor (CP) state.                              */
10467 /*                                                                          */
10468 /* Returns:                                                                 */
10469 /*   Nothing.                                                               */
10470 /****************************************************************************/
10471 static __attribute__ ((noinline)) void
10472 bce_dump_cp_state(struct bce_softc *sc, int regs)
10473 {
10474         u32 val;
10475         u32 fw_version[3];
10476
10477         BCE_PRINTF(
10478             "----------------------------"
10479             "    CP State    "
10480             "----------------------------\n");
10481
10482         for (int i = 0; i < 3; i++)
10483                 fw_version[i] = htonl(REG_RD_IND(sc,
10484                     (BCE_CP_SCRATCH + 0x10 + i * 4)));
10485
10486         BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10487
10488         val = REG_RD_IND(sc, BCE_CP_CPU_MODE);
10489         BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_mode\n", 
10490             val, BCE_CP_CPU_MODE);
10491
10492         val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
10493         BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n", 
10494             val, BCE_CP_CPU_STATE);
10495
10496         val = REG_RD_IND(sc, BCE_CP_CPU_EVENT_MASK);
10497         BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_event_mask\n", val,
10498             BCE_CP_CPU_EVENT_MASK);
10499
10500         if (regs) {
10501                 BCE_PRINTF(
10502                     "----------------------------"
10503                     " Register  Dump "
10504                     "----------------------------\n");
10505
10506                 for (int i = BCE_CP_CPU_MODE; i < 0x1aa000; i += 0x10) {
10507                         /* Skip the big blank spaces */
10508                         if (i < 0x185400 && i > 0x19ffff)
10509                                 BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
10510                                     "0x%08X 0x%08X\n", i, 
10511                                     REG_RD_IND(sc, i), 
10512                                     REG_RD_IND(sc, i + 0x4),
10513                                     REG_RD_IND(sc, i + 0x8), 
10514                                     REG_RD_IND(sc, i + 0xC));
10515                 }
10516         }
10517
10518         BCE_PRINTF(
10519             "----------------------------"
10520             "----------------"
10521             "----------------------------\n");
10522 }
10523
10524
10525 /****************************************************************************/
10526 /* Prints out the Completion Procesor (COM) state.                          */
10527 /*                                                                          */
10528 /* Returns:                                                                 */
10529 /*   Nothing.                                                               */
10530 /****************************************************************************/
10531 static __attribute__ ((noinline)) void
10532 bce_dump_com_state(struct bce_softc *sc, int regs)
10533 {
10534         u32 val;
10535         u32 fw_version[4];
10536
10537         BCE_PRINTF(
10538             "----------------------------"
10539             "   COM State    "
10540             "----------------------------\n");
10541
10542         for (int i = 0; i < 3; i++)
10543                 fw_version[i] = htonl(REG_RD_IND(sc,
10544                     (BCE_COM_SCRATCH + 0x10 + i * 4)));
10545
10546         BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10547
10548         val = REG_RD_IND(sc, BCE_COM_CPU_MODE);
10549         BCE_PRINTF("0x%08X - (0x%06X) com_cpu_mode\n", 
10550             val, BCE_COM_CPU_MODE);
10551
10552         val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
10553         BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n", 
10554             val, BCE_COM_CPU_STATE);
10555
10556         val = REG_RD_IND(sc, BCE_COM_CPU_EVENT_MASK);
10557         BCE_PRINTF("0x%08X - (0x%06X) com_cpu_event_mask\n", val,
10558             BCE_COM_CPU_EVENT_MASK);
10559
10560         if (regs) {
10561                 BCE_PRINTF(
10562                     "----------------------------"
10563                     " Register  Dump "
10564                     "----------------------------\n");
10565
10566                 for (int i = BCE_COM_CPU_MODE; i < 0x1053e8; i += 0x10) {
10567                         BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
10568                             "0x%08X 0x%08X\n", i, 
10569                             REG_RD_IND(sc, i), 
10570                             REG_RD_IND(sc, i + 0x4),
10571                             REG_RD_IND(sc, i + 0x8),
10572                             REG_RD_IND(sc, i + 0xC));
10573                 }
10574         }
10575
10576         BCE_PRINTF(
10577                 "----------------------------"
10578                 "----------------"
10579                 "----------------------------\n");
10580 }
10581
10582
10583 /****************************************************************************/
10584 /* Prints out the Receive Virtual 2 Physical (RV2P) state.                  */
10585 /*                                                                          */
10586 /* Returns:                                                                 */
10587 /*   Nothing.                                                               */
10588 /****************************************************************************/
10589 static __attribute__ ((noinline)) void
10590 bce_dump_rv2p_state(struct bce_softc *sc)
10591 {
10592         u32 val, pc1, pc2, fw_ver_high, fw_ver_low;
10593
10594         BCE_PRINTF(
10595             "----------------------------"
10596             "   RV2P State   "
10597             "----------------------------\n");
10598
10599         /* Stall the RV2P processors. */
10600         val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
10601         val |= BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2;
10602         REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
10603
10604         /* Read the firmware version. */
10605         val = 0x00000001;
10606         REG_WR_IND(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
10607         fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
10608         fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) & 
10609             BCE_RV2P_INSTR_HIGH_HIGH;
10610         BCE_PRINTF("RV2P1 Firmware version - 0x%08X:0x%08X\n", 
10611             fw_ver_high, fw_ver_low);
10612
10613         val = 0x00000001;
10614         REG_WR_IND(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
10615         fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
10616         fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) & 
10617             BCE_RV2P_INSTR_HIGH_HIGH;
10618         BCE_PRINTF("RV2P2 Firmware version - 0x%08X:0x%08X\n", 
10619             fw_ver_high, fw_ver_low);
10620
10621         /* Resume the RV2P processors. */
10622         val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
10623         val &= ~(BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2);
10624         REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
10625
10626         /* Fetch the program counter value. */
10627         val = 0x68007800;
10628         REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
10629         val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
10630         pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
10631         pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
10632         BCE_PRINTF("0x%08X - RV2P1 program counter (1st read)\n", pc1);
10633         BCE_PRINTF("0x%08X - RV2P2 program counter (1st read)\n", pc2);
10634
10635         /* Fetch the program counter value again to see if it is advancing. */
10636         val = 0x68007800;
10637         REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
10638         val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
10639         pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
10640         pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
10641         BCE_PRINTF("0x%08X - RV2P1 program counter (2nd read)\n", pc1);
10642         BCE_PRINTF("0x%08X - RV2P2 program counter (2nd read)\n", pc2);
10643
10644         BCE_PRINTF(
10645             "----------------------------"
10646             "----------------"
10647             "----------------------------\n");
10648 }
10649
10650
10651 /****************************************************************************/
10652 /* Prints out the driver state and then enters the debugger.                */
10653 /*                                                                          */
10654 /* Returns:                                                                 */
10655 /*   Nothing.                                                               */
10656 /****************************************************************************/
10657 static __attribute__ ((noinline)) void
10658 bce_breakpoint(struct bce_softc *sc)
10659 {
10660
10661         /*
10662          * Unreachable code to silence compiler warnings
10663          * about unused functions.
10664          */
10665         if (0) {
10666                 bce_freeze_controller(sc);
10667                 bce_unfreeze_controller(sc);
10668                 bce_dump_enet(sc, NULL);
10669                 bce_dump_txbd(sc, 0, NULL);
10670                 bce_dump_rxbd(sc, 0, NULL);
10671                 bce_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD);
10672                 bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD);
10673                 bce_dump_l2fhdr(sc, 0, NULL);
10674                 bce_dump_ctx(sc, RX_CID);
10675                 bce_dump_ftqs(sc);
10676                 bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
10677                 bce_dump_rx_bd_chain(sc, 0, USABLE_RX_BD);
10678                 bce_dump_status_block(sc);
10679                 bce_dump_stats_block(sc);
10680                 bce_dump_driver_state(sc);
10681                 bce_dump_hw_state(sc);
10682                 bce_dump_bc_state(sc);
10683                 bce_dump_txp_state(sc, 0);
10684                 bce_dump_rxp_state(sc, 0);
10685                 bce_dump_tpat_state(sc, 0);
10686                 bce_dump_cp_state(sc, 0);
10687                 bce_dump_com_state(sc, 0);
10688                 bce_dump_rv2p_state(sc);
10689
10690 #ifdef BCE_JUMBO_HDRSPLIT
10691                 bce_dump_pgbd(sc, 0, NULL);
10692                 bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD);
10693                 bce_dump_pg_chain(sc, 0, USABLE_PG_BD);
10694 #endif
10695         }
10696
10697         bce_dump_status_block(sc);
10698         bce_dump_driver_state(sc);
10699
10700         /* Call the debugger. */
10701         breakpoint();
10702
10703         return;
10704 }
10705 #endif
10706