xref: /freebsd/sys/dev/bce/if_bce.c (revision c74c7b73a005e689b922dfcfe5b94804669b595b)
1 /*-
2  * Copyright (c) 2006-2008 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  *   BCM5716  C0
42  *
43  * The following controllers are not supported by this driver:
44  *   BCM5706C A0, A1 (pre-production)
45  *   BCM5706S A0, A1 (pre-production)
46  *   BCM5708C A0, B0 (pre-production)
47  *   BCM5708S A0, B0 (pre-production)
48  *   BCM5709C A0  B0, B1, B2 (pre-production)
49  *   BCM5709S A0, A1, B0, B1, B2, C0 (pre-production)
50  */
51 
52 #include "opt_bce.h"
53 
54 #include <dev/bce/if_bcereg.h>
55 #include <dev/bce/if_bcefw.h>
56 
57 /****************************************************************************/
58 /* BCE Debug Options                                                        */
59 /****************************************************************************/
60 #ifdef BCE_DEBUG
61 	u32 bce_debug = BCE_WARN;
62 
63 	/*          0 = Never              */
64 	/*          1 = 1 in 2,147,483,648 */
65 	/*        256 = 1 in     8,388,608 */
66 	/*       2048 = 1 in     1,048,576 */
67 	/*      65536 = 1 in        32,768 */
68 	/*    1048576 = 1 in         2,048 */
69 	/*  268435456 =	1 in             8 */
70 	/*  536870912 = 1 in             4 */
71 	/* 1073741824 = 1 in             2 */
72 
73 	/* Controls how often the l2_fhdr frame error check will fail. */
74 	int bce_debug_l2fhdr_status_check = 0;
75 
76 	/* Controls how often the unexpected attention check will fail. */
77 	int bce_debug_unexpected_attention = 0;
78 
79 	/* Controls how often to simulate an mbuf allocation failure. */
80 	int bce_debug_mbuf_allocation_failure = 0;
81 
82 	/* Controls how often to simulate a DMA mapping failure. */
83 	int bce_debug_dma_map_addr_failure = 0;
84 
85 	/* Controls how often to simulate a bootcode failure. */
86 	int bce_debug_bootcode_running_failure = 0;
87 #endif
88 
89 /****************************************************************************/
90 /* BCE Build Time Options                                                   */
91 /****************************************************************************/
92 #define BCE_USE_SPLIT_HEADER 1
93 /* #define BCE_NVRAM_WRITE_SUPPORT 1 */
94 
95 
96 /****************************************************************************/
97 /* PCI Device ID Table                                                      */
98 /*                                                                          */
99 /* Used by bce_probe() to identify the devices supported by this driver.    */
100 /****************************************************************************/
101 #define BCE_DEVDESC_MAX		64
102 
103 static struct bce_type bce_devs[] = {
104 	/* BCM5706C Controllers and OEM boards. */
105 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3101,
106 		"HP NC370T Multifunction Gigabit Server Adapter" },
107 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3106,
108 		"HP NC370i Multifunction Gigabit Server Adapter" },
109 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3070,
110 		"HP NC380T PCI Express Dual Port Multifunction Gigabit Server Adapter" },
111 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  PCI_ANY_ID,  PCI_ANY_ID,
112 		"Broadcom NetXtreme II BCM5706 1000Base-T" },
113 
114 	/* BCM5706S controllers and OEM boards. */
115 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, HP_VENDORID, 0x3102,
116 		"HP NC370F Multifunction Gigabit Server Adapter" },
117 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, PCI_ANY_ID,  PCI_ANY_ID,
118 		"Broadcom NetXtreme II BCM5706 1000Base-SX" },
119 
120 	/* BCM5708C controllers and OEM boards. */
121 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7037,
122 		"HP NC373T PCI Express Multifunction Gigabit Server Adapter" },
123 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7038,
124 		"HP NC373i Integrated Multifunction Gigabit Server Adapter" },
125 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  PCI_ANY_ID,  PCI_ANY_ID,
126 		"Broadcom NetXtreme II BCM5708 1000Base-T" },
127 
128 	/* BCM5708S controllers and OEM boards. */
129 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x1706,
130                 "HP NC373m Multifunction Gigabit Server Adapter" },
131 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x7038,
132                 "HP NC373i PCI Express Multifunction Gigabit Server Adapter" },
133 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703b,
134                 "HP NC373i Integrated Multifunction Gigabit Server Adapter" },
135 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703d,
136                 "HP NC373F PCI Express Multifunction Gigabit Server Adapter" },
137 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  PCI_ANY_ID,  PCI_ANY_ID,
138 		"Broadcom NetXtreme II BCM5708 1000Base-SX" },
139 
140 	/* BCM5709C controllers and OEM boards. */
141 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7055,
142 		"HP NC382i Integrated Quad Port PCI Express Gigabit Server Adapter" },
143 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7059,
144 		"HP NC382T PCI Express Dual Port Multifunction Gigabit Server Adapter" },
145 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  PCI_ANY_ID,  PCI_ANY_ID,
146 		"Broadcom NetXtreme II BCM5709 1000Base-T" },
147 
148 	/* BCM5709S controllers and OEM boards. */
149 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x171d,
150 		"HP NC382m Dual Port 1GbE Multifunction BL-c Adapter" },
151 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x7056,
152 		"HP NC382i Integrated Quad Port PCI Express Gigabit Server Adapter" },
153 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  PCI_ANY_ID,  PCI_ANY_ID,
154 		"Broadcom NetXtreme II BCM5709 1000Base-SX" },
155 
156 	/* BCM5716 controllers and OEM boards. */
157 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5716,  PCI_ANY_ID,  PCI_ANY_ID,
158 		"Broadcom NetXtreme II BCM5716 1000Base-T" },
159 
160 	{ 0, 0, 0, 0, NULL }
161 };
162 
163 
164 /****************************************************************************/
165 /* Supported Flash NVRAM device data.                                       */
166 /****************************************************************************/
167 static struct flash_spec flash_table[] =
168 {
169 #define BUFFERED_FLAGS		(BCE_NV_BUFFERED | BCE_NV_TRANSLATE)
170 #define NONBUFFERED_FLAGS	(BCE_NV_WREN)
171 
172 	/* Slow EEPROM */
173 	{0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
174 	 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
175 	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
176 	 "EEPROM - slow"},
177 	/* Expansion entry 0001 */
178 	{0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
179 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
180 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
181 	 "Entry 0001"},
182 	/* Saifun SA25F010 (non-buffered flash) */
183 	/* strap, cfg1, & write1 need updates */
184 	{0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
185 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
186 	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
187 	 "Non-buffered flash (128kB)"},
188 	/* Saifun SA25F020 (non-buffered flash) */
189 	/* strap, cfg1, & write1 need updates */
190 	{0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
191 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
192 	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
193 	 "Non-buffered flash (256kB)"},
194 	/* Expansion entry 0100 */
195 	{0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
196 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
197 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
198 	 "Entry 0100"},
199 	/* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
200 	{0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
201 	 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
202 	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
203 	 "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
204 	/* Entry 0110: ST M45PE20 (non-buffered flash)*/
205 	{0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
206 	 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
207 	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
208 	 "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
209 	/* Saifun SA25F005 (non-buffered flash) */
210 	/* strap, cfg1, & write1 need updates */
211 	{0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
212 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
213 	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
214 	 "Non-buffered flash (64kB)"},
215 	/* Fast EEPROM */
216 	{0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
217 	 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
218 	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
219 	 "EEPROM - fast"},
220 	/* Expansion entry 1001 */
221 	{0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
222 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
223 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
224 	 "Entry 1001"},
225 	/* Expansion entry 1010 */
226 	{0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
227 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
228 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
229 	 "Entry 1010"},
230 	/* ATMEL AT45DB011B (buffered flash) */
231 	{0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
232 	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
233 	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
234 	 "Buffered flash (128kB)"},
235 	/* Expansion entry 1100 */
236 	{0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
237 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
238 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
239 	 "Entry 1100"},
240 	/* Expansion entry 1101 */
241 	{0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
242 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
243 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
244 	 "Entry 1101"},
245 	/* Ateml Expansion entry 1110 */
246 	{0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
247 	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
248 	 BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
249 	 "Entry 1110 (Atmel)"},
250 	/* ATMEL AT45DB021B (buffered flash) */
251 	{0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
252 	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
253 	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
254 	 "Buffered flash (256kB)"},
255 };
256 
257 /*
258  * The BCM5709 controllers transparently handle the
259  * differences between Atmel 264 byte pages and all
260  * flash devices which use 256 byte pages, so no
261  * logical-to-physical mapping is required in the
262  * driver.
263  */
264 static struct flash_spec flash_5709 = {
265 	.flags		= BCE_NV_BUFFERED,
266 	.page_bits	= BCM5709_FLASH_PAGE_BITS,
267 	.page_size	= BCM5709_FLASH_PAGE_SIZE,
268 	.addr_mask	= BCM5709_FLASH_BYTE_ADDR_MASK,
269 	.total_size	= BUFFERED_FLASH_TOTAL_SIZE * 2,
270 	.name		= "5709/5716 buffered flash (256kB)",
271 };
272 
273 
274 /****************************************************************************/
275 /* FreeBSD device entry points.                                             */
276 /****************************************************************************/
277 static int  bce_probe				(device_t);
278 static int  bce_attach				(device_t);
279 static int  bce_detach				(device_t);
280 static int  bce_shutdown			(device_t);
281 
282 
283 /****************************************************************************/
284 /* BCE Debug Data Structure Dump Routines                                   */
285 /****************************************************************************/
286 #ifdef BCE_DEBUG
287 static u32	bce_reg_rd				(struct bce_softc *, u32);
288 static void	bce_reg_wr				(struct bce_softc *, u32, u32);
289 static void	bce_reg_wr16			(struct bce_softc *, u32, u16);
290 static u32  bce_ctx_rd				(struct bce_softc *, u32, u32);
291 static void bce_dump_enet           (struct bce_softc *, struct mbuf *);
292 static void bce_dump_mbuf 			(struct bce_softc *, struct mbuf *);
293 static void bce_dump_tx_mbuf_chain	(struct bce_softc *, u16, int);
294 static void bce_dump_rx_mbuf_chain	(struct bce_softc *, u16, int);
295 #ifdef BCE_USE_SPLIT_HEADER
296 static void bce_dump_pg_mbuf_chain	(struct bce_softc *, u16, int);
297 #endif
298 static void bce_dump_txbd			(struct bce_softc *, int, struct tx_bd *);
299 static void bce_dump_rxbd			(struct bce_softc *, int, struct rx_bd *);
300 #ifdef BCE_USE_SPLIT_HEADER
301 static void bce_dump_pgbd			(struct bce_softc *, int, struct rx_bd *);
302 #endif
303 static void bce_dump_l2fhdr			(struct bce_softc *, int, struct l2_fhdr *);
304 static void bce_dump_ctx			(struct bce_softc *, u16);
305 static void bce_dump_ftqs			(struct bce_softc *);
306 static void bce_dump_tx_chain		(struct bce_softc *, u16, int);
307 static void bce_dump_rx_chain		(struct bce_softc *, u16, int);
308 #ifdef BCE_USE_SPLIT_HEADER
309 static void bce_dump_pg_chain		(struct bce_softc *, u16, int);
310 #endif
311 static void bce_dump_status_block	(struct bce_softc *);
312 static void bce_dump_stats_block	(struct bce_softc *);
313 static void bce_dump_driver_state	(struct bce_softc *);
314 static void bce_dump_hw_state		(struct bce_softc *);
315 static void bce_dump_mq_regs        (struct bce_softc *);
316 static void bce_dump_bc_state		(struct bce_softc *);
317 static void bce_dump_txp_state		(struct bce_softc *, int);
318 static void bce_dump_rxp_state		(struct bce_softc *, int);
319 static void bce_dump_tpat_state		(struct bce_softc *, int);
320 static void bce_dump_cp_state		(struct bce_softc *, int);
321 static void bce_dump_com_state		(struct bce_softc *, int);
322 static void bce_breakpoint			(struct bce_softc *);
323 #endif
324 
325 
326 /****************************************************************************/
327 /* BCE Register/Memory Access Routines                                      */
328 /****************************************************************************/
329 static u32  bce_reg_rd_ind			(struct bce_softc *, u32);
330 static void bce_reg_wr_ind			(struct bce_softc *, u32, u32);
331 static void bce_ctx_wr				(struct bce_softc *, u32, u32, u32);
332 static int  bce_miibus_read_reg		(device_t, int, int);
333 static int  bce_miibus_write_reg	(device_t, int, int, int);
334 static void bce_miibus_statchg		(device_t);
335 
336 
337 /****************************************************************************/
338 /* BCE NVRAM Access Routines                                                */
339 /****************************************************************************/
340 static int  bce_acquire_nvram_lock	(struct bce_softc *);
341 static int  bce_release_nvram_lock	(struct bce_softc *);
342 static void bce_enable_nvram_access	(struct bce_softc *);
343 static void	bce_disable_nvram_access(struct bce_softc *);
344 static int  bce_nvram_read_dword	(struct bce_softc *, u32, u8 *, u32);
345 static int  bce_init_nvram			(struct bce_softc *);
346 static int  bce_nvram_read			(struct bce_softc *, u32, u8 *, int);
347 static int  bce_nvram_test			(struct bce_softc *);
348 #ifdef BCE_NVRAM_WRITE_SUPPORT
349 static int  bce_enable_nvram_write	(struct bce_softc *);
350 static void bce_disable_nvram_write	(struct bce_softc *);
351 static int  bce_nvram_erase_page	(struct bce_softc *, u32);
352 static int  bce_nvram_write_dword	(struct bce_softc *, u32, u8 *, u32);
353 static int  bce_nvram_write			(struct bce_softc *, u32, u8 *, int);
354 #endif
355 
356 /****************************************************************************/
357 /*                                                                          */
358 /****************************************************************************/
359 static void bce_get_media			(struct bce_softc *);
360 static void bce_dma_map_addr		(void *, bus_dma_segment_t *, int, int);
361 static int  bce_dma_alloc			(device_t);
362 static void bce_dma_free			(struct bce_softc *);
363 static void bce_release_resources	(struct bce_softc *);
364 
365 /****************************************************************************/
366 /* BCE Firmware Synchronization and Load                                    */
367 /****************************************************************************/
368 static int  bce_fw_sync				(struct bce_softc *, u32);
369 static void bce_load_rv2p_fw		(struct bce_softc *, u32 *, u32, u32);
370 static void bce_load_cpu_fw			(struct bce_softc *, struct cpu_reg *, struct fw_info *);
371 static void bce_init_rxp_cpu		(struct bce_softc *);
372 static void bce_init_txp_cpu 		(struct bce_softc *);
373 static void bce_init_tpat_cpu		(struct bce_softc *);
374 static void bce_init_cp_cpu		  	(struct bce_softc *);
375 static void bce_init_com_cpu	  	(struct bce_softc *);
376 static void bce_init_cpus			(struct bce_softc *);
377 
378 static void	bce_print_adapter_info	(struct bce_softc *);
379 static void bce_probe_pci_caps		(device_t, struct bce_softc *);
380 static void bce_stop				(struct bce_softc *);
381 static int  bce_reset				(struct bce_softc *, u32);
382 static int  bce_chipinit 			(struct bce_softc *);
383 static int  bce_blockinit 			(struct bce_softc *);
384 
385 static int  bce_init_tx_chain		(struct bce_softc *);
386 static void bce_free_tx_chain		(struct bce_softc *);
387 
388 static int  bce_get_rx_buf			(struct bce_softc *, struct mbuf *, u16 *, u16 *, u32 *);
389 static int  bce_init_rx_chain		(struct bce_softc *);
390 static void bce_fill_rx_chain		(struct bce_softc *);
391 static void bce_free_rx_chain		(struct bce_softc *);
392 
393 #ifdef BCE_USE_SPLIT_HEADER
394 static int  bce_get_pg_buf			(struct bce_softc *, struct mbuf *, u16 *, u16 *);
395 static int  bce_init_pg_chain		(struct bce_softc *);
396 static void bce_fill_pg_chain		(struct bce_softc *);
397 static void bce_free_pg_chain		(struct bce_softc *);
398 #endif
399 
400 static int  bce_tx_encap			(struct bce_softc *, struct mbuf **);
401 static void bce_start_locked		(struct ifnet *);
402 static void bce_start				(struct ifnet *);
403 static int  bce_ioctl				(struct ifnet *, u_long, caddr_t);
404 static void bce_watchdog			(struct bce_softc *);
405 static int  bce_ifmedia_upd			(struct ifnet *);
406 static void bce_ifmedia_upd_locked	(struct ifnet *);
407 static void bce_ifmedia_sts			(struct ifnet *, struct ifmediareq *);
408 static void bce_init_locked			(struct bce_softc *);
409 static void bce_init				(void *);
410 static void bce_mgmt_init_locked	(struct bce_softc *sc);
411 
412 static void bce_init_ctx			(struct bce_softc *);
413 static void bce_get_mac_addr		(struct bce_softc *);
414 static void bce_set_mac_addr		(struct bce_softc *);
415 static void bce_phy_intr			(struct bce_softc *);
416 static inline u16 bce_get_hw_rx_cons(struct bce_softc *);
417 static void bce_rx_intr				(struct bce_softc *);
418 static void bce_tx_intr				(struct bce_softc *);
419 static void bce_disable_intr		(struct bce_softc *);
420 static void bce_enable_intr			(struct bce_softc *, int);
421 
422 static void bce_intr				(void *);
423 static void bce_set_rx_mode			(struct bce_softc *);
424 static void bce_stats_update		(struct bce_softc *);
425 static void bce_tick				(void *);
426 static void bce_pulse				(void *);
427 static void bce_add_sysctls			(struct bce_softc *);
428 
429 
430 /****************************************************************************/
431 /* FreeBSD device dispatch table.                                           */
432 /****************************************************************************/
433 static device_method_t bce_methods[] = {
434 	/* Device interface (device_if.h) */
435 	DEVMETHOD(device_probe,		bce_probe),
436 	DEVMETHOD(device_attach,	bce_attach),
437 	DEVMETHOD(device_detach,	bce_detach),
438 	DEVMETHOD(device_shutdown,	bce_shutdown),
439 /* Supported by device interface but not used here. */
440 /*	DEVMETHOD(device_identify,	bce_identify),      */
441 /*	DEVMETHOD(device_suspend,	bce_suspend),       */
442 /*	DEVMETHOD(device_resume,	bce_resume),        */
443 /*	DEVMETHOD(device_quiesce,	bce_quiesce),       */
444 
445 	/* Bus interface (bus_if.h) */
446 	DEVMETHOD(bus_print_child,	bus_generic_print_child),
447 	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
448 
449 	/* MII interface (miibus_if.h) */
450 	DEVMETHOD(miibus_readreg,	bce_miibus_read_reg),
451 	DEVMETHOD(miibus_writereg,	bce_miibus_write_reg),
452 	DEVMETHOD(miibus_statchg,	bce_miibus_statchg),
453 /* Supported by MII interface but not used here.       */
454 /*	DEVMETHOD(miibus_linkchg,	bce_miibus_linkchg),   */
455 /*	DEVMETHOD(miibus_mediainit,	bce_miibus_mediainit), */
456 
457 	{ 0, 0 }
458 };
459 
460 static driver_t bce_driver = {
461 	"bce",
462 	bce_methods,
463 	sizeof(struct bce_softc)
464 };
465 
466 static devclass_t bce_devclass;
467 
468 MODULE_DEPEND(bce, pci, 1, 1, 1);
469 MODULE_DEPEND(bce, ether, 1, 1, 1);
470 MODULE_DEPEND(bce, miibus, 1, 1, 1);
471 
472 DRIVER_MODULE(bce, pci, bce_driver, bce_devclass, 0, 0);
473 DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, 0, 0);
474 
475 
476 /****************************************************************************/
477 /* Tunable device values                                                    */
478 /****************************************************************************/
479 SYSCTL_NODE(_hw, OID_AUTO, bce, CTLFLAG_RD, 0, "bce driver parameters");
480 
481 /* Allowable values are TRUE or FALSE */
482 static int bce_tso_enable = TRUE;
483 TUNABLE_INT("hw.bce.tso_enable", &bce_tso_enable);
484 SYSCTL_UINT(_hw_bce, OID_AUTO, tso_enable, CTLFLAG_RDTUN, &bce_tso_enable, 0,
485 "TSO Enable/Disable");
486 
487 /* Allowable values are 0 (IRQ), 1 (MSI/IRQ), and 2 (MSI-X/MSI/IRQ) */
488 /* ToDo: Add MSI-X support. */
489 static int bce_msi_enable = 1;
490 TUNABLE_INT("hw.bce.msi_enable", &bce_msi_enable);
491 SYSCTL_UINT(_hw_bce, OID_AUTO, msi_enable, CTLFLAG_RDTUN, &bce_msi_enable, 0,
492 "MSI-X|MSI|INTx selector");
493 
494 /* ToDo: Add tunable to enable/disable strict MTU handling. */
495 /* Currently allows "loose" RX MTU checking (i.e. sets the  */
496 /* H/W RX MTU to the size of the largest receive buffer, or */
497 /* 2048 bytes).                                             */
498 
499 
500 /****************************************************************************/
501 /* Device probe function.                                                   */
502 /*                                                                          */
503 /* Compares the device to the driver's list of supported devices and        */
504 /* reports back to the OS whether this is the right driver for the device.  */
505 /*                                                                          */
506 /* Returns:                                                                 */
507 /*   BUS_PROBE_DEFAULT on success, positive value on failure.               */
508 /****************************************************************************/
509 static int
510 bce_probe(device_t dev)
511 {
512 	struct bce_type *t;
513 	struct bce_softc *sc;
514 	char *descbuf;
515 	u16 vid = 0, did = 0, svid = 0, sdid = 0;
516 
517 	t = bce_devs;
518 
519 	sc = device_get_softc(dev);
520 	bzero(sc, sizeof(struct bce_softc));
521 	sc->bce_unit = device_get_unit(dev);
522 	sc->bce_dev = dev;
523 
524 	/* Get the data for the device to be probed. */
525 	vid  = pci_get_vendor(dev);
526 	did  = pci_get_device(dev);
527 	svid = pci_get_subvendor(dev);
528 	sdid = pci_get_subdevice(dev);
529 
530 	DBPRINT(sc, BCE_EXTREME_LOAD,
531 		"%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
532 		"SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
533 
534 	/* Look through the list of known devices for a match. */
535 	while(t->bce_name != NULL) {
536 
537 		if ((vid == t->bce_vid) && (did == t->bce_did) &&
538 			((svid == t->bce_svid) || (t->bce_svid == PCI_ANY_ID)) &&
539 			((sdid == t->bce_sdid) || (t->bce_sdid == PCI_ANY_ID))) {
540 
541 			descbuf = malloc(BCE_DEVDESC_MAX, M_TEMP, M_NOWAIT);
542 
543 			if (descbuf == NULL)
544 				return(ENOMEM);
545 
546 			/* Print out the device identity. */
547 			snprintf(descbuf, BCE_DEVDESC_MAX, "%s (%c%d)",
548 				t->bce_name,
549 			    (((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
550 			    (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
551 
552 			device_set_desc_copy(dev, descbuf);
553 			free(descbuf, M_TEMP);
554 			return(BUS_PROBE_DEFAULT);
555 		}
556 		t++;
557 	}
558 
559 	return(ENXIO);
560 }
561 
562 
563 /****************************************************************************/
564 /* PCI Capabilities Probe Function.                                         */
565 /*                                                                          */
566 /* Walks the PCI capabiites list for the device to find what features are   */
567 /* supported.                                                               */
568 /*                                                                          */
569 /* Returns:                                                                 */
570 /*   None.                                                                  */
571 /****************************************************************************/
572 static void
573 bce_print_adapter_info(struct bce_softc *sc)
574 {
575 	DBENTER(BCE_VERBOSE_LOAD);
576 
577 	BCE_PRINTF("ASIC (0x%08X); ", sc->bce_chipid);
578 	printf("Rev (%c%d); ", ((BCE_CHIP_ID(sc) & 0xf000) >> 12) + 'A',
579 		((BCE_CHIP_ID(sc) & 0x0ff0) >> 4));
580 
581 	/* Bus info. */
582 	if (sc->bce_flags & BCE_PCIE_FLAG) {
583 		printf("Bus (PCIe x%d, ", sc->link_width);
584 		switch (sc->link_speed) {
585 			case 1: printf("2.5Gbps); "); break;
586 			case 2:	printf("5Gbps); "); break;
587 			default: printf("Unknown link speed); ");
588 		}
589 	} else {
590 		printf("Bus (PCI%s, %s, %dMHz); ",
591 			((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""),
592 			((sc->bce_flags & BCE_PCI_32BIT_FLAG) ? "32-bit" : "64-bit"),
593 			sc->bus_speed_mhz);
594 	}
595 
596 	/* Firmware version and device features. */
597 	printf("F/W (0x%08X); Flags( ", sc->bce_fw_ver);
598 #ifdef BCE_USE_SPLIT_HEADER
599 	printf("SPLT ");
600 #endif
601 	if (sc->bce_flags & BCE_MFW_ENABLE_FLAG)
602 		printf("MFW ");
603 	if (sc->bce_flags & BCE_USING_MSI_FLAG)
604 		printf("MSI ");
605 	if (sc->bce_flags & BCE_USING_MSIX_FLAG)
606 		printf("MSI-X ");
607 	if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
608 		printf("2.5G ");
609 	printf(")\n");
610 
611 	DBEXIT(BCE_VERBOSE_LOAD);
612 }
613 
614 
615 /****************************************************************************/
616 /* PCI Capabilities Probe Function.                                         */
617 /*                                                                          */
618 /* Walks the PCI capabiites list for the device to find what features are   */
619 /* supported.                                                               */
620 /*                                                                          */
621 /* Returns:                                                                 */
622 /*   None.                                                                  */
623 /****************************************************************************/
624 static void
625 bce_probe_pci_caps(device_t dev, struct bce_softc *sc)
626 {
627 	u32 reg;
628 
629 	DBENTER(BCE_VERBOSE_LOAD);
630 
631 	/* Check if PCI-X capability is enabled. */
632 	if (pci_find_extcap(dev, PCIY_PCIX, &reg) == 0) {
633 		if (reg != 0)
634 			sc->bce_cap_flags |= BCE_PCIX_CAPABLE_FLAG;
635 	}
636 
637 	/* Check if PCIe capability is enabled. */
638 	if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
639 		if (reg != 0) {
640 			u16 link_status = pci_read_config(dev, reg + 0x12, 2);
641 			DBPRINT(sc, BCE_INFO_LOAD, "PCIe link_status = 0x%08X\n",
642 				link_status);
643 			sc->link_speed = link_status & 0xf;
644 			sc->link_width = (link_status >> 4) & 0x3f;
645 			sc->bce_cap_flags |= BCE_PCIE_CAPABLE_FLAG;
646 			sc->bce_flags |= BCE_PCIE_FLAG;
647 		}
648 	}
649 
650 	/* Check if MSI capability is enabled. */
651 	if (pci_find_extcap(dev, PCIY_MSI, &reg) == 0) {
652 		if (reg != 0)
653 			sc->bce_cap_flags |= BCE_MSI_CAPABLE_FLAG;
654 	}
655 
656 	/* Check if MSI-X capability is enabled. */
657 	if (pci_find_extcap(dev, PCIY_MSIX, &reg) == 0) {
658 		if (reg != 0)
659 			sc->bce_cap_flags |= BCE_MSIX_CAPABLE_FLAG;
660 	}
661 
662 	DBEXIT(BCE_VERBOSE_LOAD);
663 }
664 
665 
666 /****************************************************************************/
667 /* Device attach function.                                                  */
668 /*                                                                          */
669 /* Allocates device resources, performs secondary chip identification,      */
670 /* resets and initializes the hardware, and initializes driver instance     */
671 /* variables.                                                               */
672 /*                                                                          */
673 /* Returns:                                                                 */
674 /*   0 on success, positive value on failure.                               */
675 /****************************************************************************/
676 static int
677 bce_attach(device_t dev)
678 {
679 	struct bce_softc *sc;
680 	struct ifnet *ifp;
681 	u32 val;
682 	int error, rid, rc = 0;
683 
684 	sc = device_get_softc(dev);
685 	sc->bce_dev = dev;
686 
687 	DBENTER(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
688 
689 	sc->bce_unit = device_get_unit(dev);
690 
691 	/* Set initial device and PHY flags */
692 	sc->bce_flags = 0;
693 	sc->bce_phy_flags = 0;
694 
695 	pci_enable_busmaster(dev);
696 
697 	/* Allocate PCI memory resources. */
698 	rid = PCIR_BAR(0);
699 	sc->bce_res_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
700 		&rid, RF_ACTIVE);
701 
702 	if (sc->bce_res_mem == NULL) {
703 		BCE_PRINTF("%s(%d): PCI memory allocation failed\n",
704 			__FILE__, __LINE__);
705 		rc = ENXIO;
706 		goto bce_attach_fail;
707 	}
708 
709 	/* Get various resource handles. */
710 	sc->bce_btag    = rman_get_bustag(sc->bce_res_mem);
711 	sc->bce_bhandle = rman_get_bushandle(sc->bce_res_mem);
712 	sc->bce_vhandle = (vm_offset_t) rman_get_virtual(sc->bce_res_mem);
713 
714 	bce_probe_pci_caps(dev, sc);
715 
716 	rid = 1;
717 #if 0
718 	/* Try allocating MSI-X interrupts. */
719 	if ((sc->bce_cap_flags & BCE_MSIX_CAPABLE_FLAG) &&
720 		(bce_msi_enable >= 2) &&
721 		((sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
722 		&rid, RF_ACTIVE)) != NULL)) {
723 
724 		msi_needed = sc->bce_msi_count = 1;
725 
726 		if (((error = pci_alloc_msix(dev, &sc->bce_msi_count)) != 0) ||
727 			(sc->bce_msi_count != msi_needed)) {
728 			BCE_PRINTF("%s(%d): MSI-X allocation failed! Requested = %d,"
729 				"Received = %d, error = %d\n", __FILE__, __LINE__,
730 				msi_needed, sc->bce_msi_count, error);
731 			sc->bce_msi_count = 0;
732 			pci_release_msi(dev);
733 			bus_release_resource(dev, SYS_RES_MEMORY, rid,
734 				sc->bce_res_irq);
735 			sc->bce_res_irq = NULL;
736 		} else {
737 			DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI-X interrupt.\n",
738 				__FUNCTION__);
739 			sc->bce_flags |= BCE_USING_MSIX_FLAG;
740 			sc->bce_intr = bce_intr;
741 		}
742 	}
743 #endif
744 
745 	/* Try allocating a MSI interrupt. */
746 	if ((sc->bce_cap_flags & BCE_MSI_CAPABLE_FLAG) &&
747 		(bce_msi_enable >= 1) && (sc->bce_msi_count == 0)) {
748 		sc->bce_msi_count = 1;
749 		if ((error = pci_alloc_msi(dev, &sc->bce_msi_count)) != 0) {
750 			BCE_PRINTF("%s(%d): MSI allocation failed! error = %d\n",
751 				__FILE__, __LINE__, error);
752 			sc->bce_msi_count = 0;
753 			pci_release_msi(dev);
754 		} else {
755 			DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI interrupt.\n",
756 				__FUNCTION__);
757 			sc->bce_flags |= BCE_USING_MSI_FLAG;
758 			if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
759 				(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
760 				sc->bce_flags |= BCE_ONE_SHOT_MSI_FLAG;
761 			sc->bce_irq_rid = 1;
762 			sc->bce_intr = bce_intr;
763 		}
764 	}
765 
766 	/* Try allocating a legacy interrupt. */
767 	if (sc->bce_msi_count == 0) {
768 		DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using INTx interrupt.\n",
769 			__FUNCTION__);
770 		rid = 0;
771 		sc->bce_intr = bce_intr;
772 	}
773 
774 	sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
775 		&rid, RF_SHAREABLE | RF_ACTIVE);
776 
777 	sc->bce_irq_rid = rid;
778 
779 	/* Report any IRQ allocation errors. */
780 	if (sc->bce_res_irq == NULL) {
781 		BCE_PRINTF("%s(%d): PCI map interrupt failed!\n",
782 			__FILE__, __LINE__);
783 		rc = ENXIO;
784 		goto bce_attach_fail;
785 	}
786 
787 	/* Initialize mutex for the current device instance. */
788 	BCE_LOCK_INIT(sc, device_get_nameunit(dev));
789 
790 	/*
791 	 * Configure byte swap and enable indirect register access.
792 	 * Rely on CPU to do target byte swapping on big endian systems.
793 	 * Access to registers outside of PCI configurtion space are not
794 	 * valid until this is done.
795 	 */
796 	pci_write_config(dev, BCE_PCICFG_MISC_CONFIG,
797 			       BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
798 			       BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4);
799 
800 	/* Save ASIC revsion info. */
801 	sc->bce_chipid =  REG_RD(sc, BCE_MISC_ID);
802 
803 	/* Weed out any non-production controller revisions. */
804 	switch(BCE_CHIP_ID(sc)) {
805 		case BCE_CHIP_ID_5706_A0:
806 		case BCE_CHIP_ID_5706_A1:
807 		case BCE_CHIP_ID_5708_A0:
808 		case BCE_CHIP_ID_5708_B0:
809 		case BCE_CHIP_ID_5709_A0:
810 		case BCE_CHIP_ID_5709_B0:
811 		case BCE_CHIP_ID_5709_B1:
812 		case BCE_CHIP_ID_5709_B2:
813 			BCE_PRINTF("%s(%d): Unsupported controller revision (%c%d)!\n",
814 				__FILE__, __LINE__,
815 				(((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
816 			    (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
817 			rc = ENODEV;
818 			goto bce_attach_fail;
819 	}
820 
821 	/*
822 	 * The embedded PCIe to PCI-X bridge (EPB)
823 	 * in the 5708 cannot address memory above
824 	 * 40 bits (E7_5708CB1_23043 & E6_5708SB1_23043).
825 	 */
826 	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708)
827 		sc->max_bus_addr = BCE_BUS_SPACE_MAXADDR;
828 	else
829 		sc->max_bus_addr = BUS_SPACE_MAXADDR;
830 
831 	/*
832 	 * Find the base address for shared memory access.
833 	 * Newer versions of bootcode use a signature and offset
834 	 * while older versions use a fixed address.
835 	 */
836 	val = REG_RD_IND(sc, BCE_SHM_HDR_SIGNATURE);
837 	if ((val & BCE_SHM_HDR_SIGNATURE_SIG_MASK) == BCE_SHM_HDR_SIGNATURE_SIG)
838 		/* Multi-port devices use different offsets in shared memory. */
839 		sc->bce_shmem_base = REG_RD_IND(sc, BCE_SHM_HDR_ADDR_0 +
840 			(pci_get_function(sc->bce_dev) << 2));
841 	else
842 		sc->bce_shmem_base = HOST_VIEW_SHMEM_BASE;
843 
844 	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): bce_shmem_base = 0x%08X\n",
845 		__FUNCTION__, sc->bce_shmem_base);
846 
847 	/* Fetch the bootcode revision. */
848 	sc->bce_fw_ver = REG_RD_IND(sc, sc->bce_shmem_base +
849 		BCE_DEV_INFO_BC_REV);
850 
851 	/* Check if any management firmware is running. */
852 	val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_PORT_FEATURE);
853 	if (val & (BCE_PORT_FEATURE_ASF_ENABLED | BCE_PORT_FEATURE_IMD_ENABLED))
854 		sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
855 
856 	/* Get PCI bus information (speed and type). */
857 	val = REG_RD(sc, BCE_PCICFG_MISC_STATUS);
858 	if (val & BCE_PCICFG_MISC_STATUS_PCIX_DET) {
859 		u32 clkreg;
860 
861 		sc->bce_flags |= BCE_PCIX_FLAG;
862 
863 		clkreg = REG_RD(sc, BCE_PCICFG_PCI_CLOCK_CONTROL_BITS);
864 
865 		clkreg &= BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
866 		switch (clkreg) {
867 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
868 			sc->bus_speed_mhz = 133;
869 			break;
870 
871 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
872 			sc->bus_speed_mhz = 100;
873 			break;
874 
875 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
876 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
877 			sc->bus_speed_mhz = 66;
878 			break;
879 
880 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
881 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
882 			sc->bus_speed_mhz = 50;
883 			break;
884 
885 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
886 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
887 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
888 			sc->bus_speed_mhz = 33;
889 			break;
890 		}
891 	} else {
892 		if (val & BCE_PCICFG_MISC_STATUS_M66EN)
893 			sc->bus_speed_mhz = 66;
894 		else
895 			sc->bus_speed_mhz = 33;
896 	}
897 
898 	if (val & BCE_PCICFG_MISC_STATUS_32BIT_DET)
899 		sc->bce_flags |= BCE_PCI_32BIT_FLAG;
900 
901 	/* Reset the controller and announce to bootcode that driver is present. */
902 	if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
903 		BCE_PRINTF("%s(%d): Controller reset failed!\n",
904 			__FILE__, __LINE__);
905 		rc = ENXIO;
906 		goto bce_attach_fail;
907 	}
908 
909 	/* Initialize the controller. */
910 	if (bce_chipinit(sc)) {
911 		BCE_PRINTF("%s(%d): Controller initialization failed!\n",
912 			__FILE__, __LINE__);
913 		rc = ENXIO;
914 		goto bce_attach_fail;
915 	}
916 
917 	/* Perform NVRAM test. */
918 	if (bce_nvram_test(sc)) {
919 		BCE_PRINTF("%s(%d): NVRAM test failed!\n",
920 			__FILE__, __LINE__);
921 		rc = ENXIO;
922 		goto bce_attach_fail;
923 	}
924 
925 	/* Fetch the permanent Ethernet MAC address. */
926 	bce_get_mac_addr(sc);
927 
928 	/*
929 	 * Trip points control how many BDs
930 	 * should be ready before generating an
931 	 * interrupt while ticks control how long
932 	 * a BD can sit in the chain before
933 	 * generating an interrupt.  Set the default
934 	 * values for the RX and TX chains.
935 	 */
936 
937 #ifdef BCE_DEBUG
938 	/* Force more frequent interrupts. */
939 	sc->bce_tx_quick_cons_trip_int = 1;
940 	sc->bce_tx_quick_cons_trip     = 1;
941 	sc->bce_tx_ticks_int           = 0;
942 	sc->bce_tx_ticks               = 0;
943 
944 	sc->bce_rx_quick_cons_trip_int = 1;
945 	sc->bce_rx_quick_cons_trip     = 1;
946 	sc->bce_rx_ticks_int           = 0;
947 	sc->bce_rx_ticks               = 0;
948 #else
949 	/* Improve throughput at the expense of increased latency. */
950 	sc->bce_tx_quick_cons_trip_int = 20;
951 	sc->bce_tx_quick_cons_trip     = 20;
952 	sc->bce_tx_ticks_int           = 80;
953 	sc->bce_tx_ticks               = 80;
954 
955 	sc->bce_rx_quick_cons_trip_int = 6;
956 	sc->bce_rx_quick_cons_trip     = 6;
957 	sc->bce_rx_ticks_int           = 18;
958 	sc->bce_rx_ticks               = 18;
959 #endif
960 
961 	/* Update statistics once every second. */
962 	sc->bce_stats_ticks = 1000000 & 0xffff00;
963 
964 	/* Find the media type for the adapter. */
965 	bce_get_media(sc);
966 
967 	/* Store data needed by PHY driver for backplane applications */
968 	sc->bce_shared_hw_cfg = REG_RD_IND(sc, sc->bce_shmem_base +
969 		BCE_SHARED_HW_CFG_CONFIG);
970 	sc->bce_port_hw_cfg   = REG_RD_IND(sc, sc->bce_shmem_base +
971 		BCE_PORT_HW_CFG_CONFIG);
972 
973 	/* Allocate DMA memory resources. */
974 	if (bce_dma_alloc(dev)) {
975 		BCE_PRINTF("%s(%d): DMA resource allocation failed!\n",
976 		    __FILE__, __LINE__);
977 		rc = ENXIO;
978 		goto bce_attach_fail;
979 	}
980 
981 	/* Allocate an ifnet structure. */
982 	ifp = sc->bce_ifp = if_alloc(IFT_ETHER);
983 	if (ifp == NULL) {
984 		BCE_PRINTF("%s(%d): Interface allocation failed!\n",
985 			__FILE__, __LINE__);
986 		rc = ENXIO;
987 		goto bce_attach_fail;
988 	}
989 
990 	/* Initialize the ifnet interface. */
991 	ifp->if_softc        = sc;
992 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
993 	ifp->if_flags        = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
994 	ifp->if_ioctl        = bce_ioctl;
995 	ifp->if_start        = bce_start;
996 	ifp->if_init         = bce_init;
997 	ifp->if_mtu          = ETHERMTU;
998 
999 	if (bce_tso_enable) {
1000 		ifp->if_hwassist = BCE_IF_HWASSIST | CSUM_TSO;
1001 		ifp->if_capabilities = BCE_IF_CAPABILITIES | IFCAP_TSO4;
1002 	} else {
1003 		ifp->if_hwassist = BCE_IF_HWASSIST;
1004 		ifp->if_capabilities = BCE_IF_CAPABILITIES;
1005 	}
1006 
1007 	ifp->if_capenable    = ifp->if_capabilities;
1008 
1009 	/*
1010 	 * Assume standard mbuf sizes for buffer allocation.
1011 	 * This may change later if the MTU size is set to
1012 	 * something other than 1500.
1013 	 */
1014 #ifdef BCE_USE_SPLIT_HEADER
1015 	sc->rx_bd_mbuf_alloc_size = MHLEN;
1016 	/* Make sure offset is 16 byte aligned for hardware. */
1017 	sc->rx_bd_mbuf_align_pad  = roundup2((MSIZE - MHLEN), 16) -
1018 		(MSIZE - MHLEN);
1019 	sc->rx_bd_mbuf_data_len   = sc->rx_bd_mbuf_alloc_size -
1020 		sc->rx_bd_mbuf_align_pad;
1021 	sc->pg_bd_mbuf_alloc_size = MCLBYTES;
1022 #else
1023 	sc->rx_bd_mbuf_alloc_size = MCLBYTES;
1024 	sc->rx_bd_mbuf_align_pad  = roundup2(MCLBYTES, 16) - MCLBYTES;
1025 	sc->rx_bd_mbuf_data_len   = sc->rx_bd_mbuf_alloc_size -
1026 		sc->rx_bd_mbuf_align_pad;
1027 #endif
1028 
1029 	ifp->if_snd.ifq_drv_maxlen = USABLE_TX_BD;
1030 	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
1031 	IFQ_SET_READY(&ifp->if_snd);
1032 
1033 	if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
1034 		ifp->if_baudrate = IF_Mbps(2500ULL);
1035 	else
1036 		ifp->if_baudrate = IF_Mbps(1000);
1037 
1038 	/* Check for an MII child bus by probing the PHY. */
1039 	if (mii_phy_probe(dev, &sc->bce_miibus, bce_ifmedia_upd,
1040 		bce_ifmedia_sts)) {
1041 		BCE_PRINTF("%s(%d): No PHY found on child MII bus!\n",
1042 			__FILE__, __LINE__);
1043 		rc = ENXIO;
1044 		goto bce_attach_fail;
1045 	}
1046 
1047 	/* Attach to the Ethernet interface list. */
1048 	ether_ifattach(ifp, sc->eaddr);
1049 
1050 #if __FreeBSD_version < 500000
1051 	callout_init(&sc->bce_tick_callout);
1052 	callout_init(&sc->bce_pulse_callout);
1053 #else
1054 	callout_init_mtx(&sc->bce_tick_callout, &sc->bce_mtx, 0);
1055 	callout_init_mtx(&sc->bce_pulse_callout, &sc->bce_mtx, 0);
1056 #endif
1057 
1058 	/* Hookup IRQ last. */
1059 	rc = bus_setup_intr(dev, sc->bce_res_irq, INTR_TYPE_NET | INTR_MPSAFE,
1060 		NULL, bce_intr, sc, &sc->bce_intrhand);
1061 
1062 	if (rc) {
1063 		BCE_PRINTF("%s(%d): Failed to setup IRQ!\n",
1064 			__FILE__, __LINE__);
1065 		bce_detach(dev);
1066 		goto bce_attach_exit;
1067 	}
1068 
1069 	/*
1070 	 * At this point we've acquired all the resources
1071 	 * we need to run so there's no turning back, we're
1072 	 * cleared for launch.
1073 	 */
1074 
1075 	/* Print some important debugging info. */
1076 	DBRUNMSG(BCE_INFO, bce_dump_driver_state(sc));
1077 
1078 	/* Add the supported sysctls to the kernel. */
1079 	bce_add_sysctls(sc);
1080 
1081 	BCE_LOCK(sc);
1082 
1083 	/*
1084 	 * The chip reset earlier notified the bootcode that
1085 	 * a driver is present.  We now need to start our pulse
1086 	 * routine so that the bootcode is reminded that we're
1087 	 * still running.
1088 	 */
1089 	bce_pulse(sc);
1090 
1091 	bce_mgmt_init_locked(sc);
1092 	BCE_UNLOCK(sc);
1093 
1094 	/* Finally, print some useful adapter info */
1095 	bce_print_adapter_info(sc);
1096 	DBPRINT(sc, BCE_FATAL, "%s(): sc = %p\n",
1097 		__FUNCTION__, sc);
1098 
1099 	goto bce_attach_exit;
1100 
1101 bce_attach_fail:
1102 	bce_release_resources(sc);
1103 
1104 bce_attach_exit:
1105 
1106 	DBEXIT(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
1107 
1108 	return(rc);
1109 }
1110 
1111 
1112 /****************************************************************************/
1113 /* Device detach function.                                                  */
1114 /*                                                                          */
1115 /* Stops the controller, resets the controller, and releases resources.     */
1116 /*                                                                          */
1117 /* Returns:                                                                 */
1118 /*   0 on success, positive value on failure.                               */
1119 /****************************************************************************/
1120 static int
1121 bce_detach(device_t dev)
1122 {
1123 	struct bce_softc *sc = device_get_softc(dev);
1124 	struct ifnet *ifp;
1125 	u32 msg;
1126 
1127 	DBENTER(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
1128 
1129 	ifp = sc->bce_ifp;
1130 
1131 	/* Stop and reset the controller. */
1132 	BCE_LOCK(sc);
1133 
1134 	/* Stop the pulse so the bootcode can go to driver absent state. */
1135 	callout_stop(&sc->bce_pulse_callout);
1136 
1137 	bce_stop(sc);
1138 	if (sc->bce_flags & BCE_NO_WOL_FLAG)
1139 		msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
1140 	else
1141 		msg = BCE_DRV_MSG_CODE_UNLOAD;
1142 	bce_reset(sc, msg);
1143 
1144 	BCE_UNLOCK(sc);
1145 
1146 	ether_ifdetach(ifp);
1147 
1148 	/* If we have a child device on the MII bus remove it too. */
1149 	bus_generic_detach(dev);
1150 	device_delete_child(dev, sc->bce_miibus);
1151 
1152 	/* Release all remaining resources. */
1153 	bce_release_resources(sc);
1154 
1155 	DBEXIT(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
1156 
1157 	return(0);
1158 }
1159 
1160 
1161 /****************************************************************************/
1162 /* Device shutdown function.                                                */
1163 /*                                                                          */
1164 /* Stops and resets the controller.                                         */
1165 /*                                                                          */
1166 /* Returns:                                                                 */
1167 /*   0 on success, positive value on failure.                               */
1168 /****************************************************************************/
1169 static int
1170 bce_shutdown(device_t dev)
1171 {
1172 	struct bce_softc *sc = device_get_softc(dev);
1173 	u32 msg;
1174 
1175 	DBENTER(BCE_VERBOSE);
1176 
1177 	BCE_LOCK(sc);
1178 	bce_stop(sc);
1179 	if (sc->bce_flags & BCE_NO_WOL_FLAG)
1180 		msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
1181 	else
1182 		msg = BCE_DRV_MSG_CODE_UNLOAD;
1183 	bce_reset(sc, msg);
1184 	BCE_UNLOCK(sc);
1185 
1186 	DBEXIT(BCE_VERBOSE);
1187 
1188 	return (0);
1189 }
1190 
1191 
1192 #ifdef BCE_DEBUG
1193 /****************************************************************************/
1194 /* Register read.                                                           */
1195 /*                                                                          */
1196 /* Returns:                                                                 */
1197 /*   The value of the register.                                             */
1198 /****************************************************************************/
1199 static u32
1200 bce_reg_rd(struct bce_softc *sc, u32 offset)
1201 {
1202 	u32 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, offset);
1203 	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1204 		__FUNCTION__, offset, val);
1205 	return val;
1206 }
1207 
1208 
1209 /****************************************************************************/
1210 /* Register write (16 bit).                                                 */
1211 /*                                                                          */
1212 /* Returns:                                                                 */
1213 /*   Nothing.                                                               */
1214 /****************************************************************************/
1215 static void
1216 bce_reg_wr16(struct bce_softc *sc, u32 offset, u16 val)
1217 {
1218 	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%04X\n",
1219 		__FUNCTION__, offset, val);
1220 	bus_space_write_2(sc->bce_btag, sc->bce_bhandle, offset, val);
1221 }
1222 
1223 
1224 /****************************************************************************/
1225 /* Register write.                                                          */
1226 /*                                                                          */
1227 /* Returns:                                                                 */
1228 /*   Nothing.                                                               */
1229 /****************************************************************************/
1230 static void
1231 bce_reg_wr(struct bce_softc *sc, u32 offset, u32 val)
1232 {
1233 	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1234 		__FUNCTION__, offset, val);
1235 	bus_space_write_4(sc->bce_btag, sc->bce_bhandle, offset, val);
1236 }
1237 #endif
1238 
1239 /****************************************************************************/
1240 /* Indirect register read.                                                  */
1241 /*                                                                          */
1242 /* Reads NetXtreme II registers using an index/data register pair in PCI    */
1243 /* configuration space.  Using this mechanism avoids issues with posted     */
1244 /* reads but is much slower than memory-mapped I/O.                         */
1245 /*                                                                          */
1246 /* Returns:                                                                 */
1247 /*   The value of the register.                                             */
1248 /****************************************************************************/
1249 static u32
1250 bce_reg_rd_ind(struct bce_softc *sc, u32 offset)
1251 {
1252 	device_t dev;
1253 	dev = sc->bce_dev;
1254 
1255 	pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
1256 #ifdef BCE_DEBUG
1257 	{
1258 		u32 val;
1259 		val = pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
1260 		DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1261 			__FUNCTION__, offset, val);
1262 		return val;
1263 	}
1264 #else
1265 	return pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
1266 #endif
1267 }
1268 
1269 
1270 /****************************************************************************/
1271 /* Indirect register write.                                                 */
1272 /*                                                                          */
1273 /* Writes NetXtreme II registers using an index/data register pair in PCI   */
1274 /* configuration space.  Using this mechanism avoids issues with posted     */
1275 /* writes but is muchh slower than memory-mapped I/O.                       */
1276 /*                                                                          */
1277 /* Returns:                                                                 */
1278 /*   Nothing.                                                               */
1279 /****************************************************************************/
1280 static void
1281 bce_reg_wr_ind(struct bce_softc *sc, u32 offset, u32 val)
1282 {
1283 	device_t dev;
1284 	dev = sc->bce_dev;
1285 
1286 	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1287 		__FUNCTION__, offset, val);
1288 
1289 	pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
1290 	pci_write_config(dev, BCE_PCICFG_REG_WINDOW, val, 4);
1291 }
1292 
1293 
1294 #ifdef BCE_DEBUG
1295 /****************************************************************************/
1296 /* Context memory read.                                                     */
1297 /*                                                                          */
1298 /* The NetXtreme II controller uses context memory to track connection      */
1299 /* information for L2 and higher network protocols.                         */
1300 /*                                                                          */
1301 /* Returns:                                                                 */
1302 /*   The requested 32 bit value of context memory.                          */
1303 /****************************************************************************/
1304 static u32
1305 bce_ctx_rd(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset)
1306 {
1307 	u32 idx, offset, retry_cnt = 5, val;
1308 
1309 	DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 || cid_addr & CTX_MASK),
1310 		BCE_PRINTF("%s(): Invalid CID address: 0x%08X.\n",
1311 			__FUNCTION__, cid_addr));
1312 
1313 	offset = ctx_offset + cid_addr;
1314 
1315 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
1316 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
1317 
1318 		REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_READ_REQ));
1319 
1320 		for (idx = 0; idx < retry_cnt; idx++) {
1321 			val = REG_RD(sc, BCE_CTX_CTX_CTRL);
1322 			if ((val & BCE_CTX_CTX_CTRL_READ_REQ) == 0)
1323 				break;
1324 			DELAY(5);
1325 		}
1326 
1327 		if (val & BCE_CTX_CTX_CTRL_READ_REQ)
1328 			BCE_PRINTF("%s(%d); Unable to read CTX memory: "
1329 				"cid_addr = 0x%08X, offset = 0x%08X!\n",
1330 				__FILE__, __LINE__, cid_addr, ctx_offset);
1331 
1332 		val = REG_RD(sc, BCE_CTX_CTX_DATA);
1333 	} else {
1334 		REG_WR(sc, BCE_CTX_DATA_ADR, offset);
1335 		val = REG_RD(sc, BCE_CTX_DATA);
1336 	}
1337 
1338 	DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
1339 		"val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, val);
1340 
1341 	return(val);
1342 }
1343 #endif
1344 
1345 
1346 /****************************************************************************/
1347 /* Context memory write.                                                    */
1348 /*                                                                          */
1349 /* The NetXtreme II controller uses context memory to track connection      */
1350 /* information for L2 and higher network protocols.                         */
1351 /*                                                                          */
1352 /* Returns:                                                                 */
1353 /*   Nothing.                                                               */
1354 /****************************************************************************/
1355 static void
1356 bce_ctx_wr(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset, u32 ctx_val)
1357 {
1358 	u32 idx, offset = ctx_offset + cid_addr;
1359 	u32 val, retry_cnt = 5;
1360 
1361 	DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
1362 		"val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, ctx_val);
1363 
1364 	DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 || cid_addr & CTX_MASK),
1365 		BCE_PRINTF("%s(): Invalid CID address: 0x%08X.\n",
1366 			__FUNCTION__, cid_addr));
1367 
1368 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
1369 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
1370 
1371 		REG_WR(sc, BCE_CTX_CTX_DATA, ctx_val);
1372 		REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_WRITE_REQ));
1373 
1374 		for (idx = 0; idx < retry_cnt; idx++) {
1375 			val = REG_RD(sc, BCE_CTX_CTX_CTRL);
1376 			if ((val & BCE_CTX_CTX_CTRL_WRITE_REQ) == 0)
1377 				break;
1378 			DELAY(5);
1379 		}
1380 
1381 		if (val & BCE_CTX_CTX_CTRL_WRITE_REQ)
1382 			BCE_PRINTF("%s(%d); Unable to write CTX memory: "
1383 				"cid_addr = 0x%08X, offset = 0x%08X!\n",
1384 				__FILE__, __LINE__, cid_addr, ctx_offset);
1385 
1386 	} else {
1387 		REG_WR(sc, BCE_CTX_DATA_ADR, offset);
1388 		REG_WR(sc, BCE_CTX_DATA, ctx_val);
1389 	}
1390 }
1391 
1392 
1393 /****************************************************************************/
1394 /* PHY register read.                                                       */
1395 /*                                                                          */
1396 /* Implements register reads on the MII bus.                                */
1397 /*                                                                          */
1398 /* Returns:                                                                 */
1399 /*   The value of the register.                                             */
1400 /****************************************************************************/
1401 static int
1402 bce_miibus_read_reg(device_t dev, int phy, int reg)
1403 {
1404 	struct bce_softc *sc;
1405 	u32 val;
1406 	int i;
1407 
1408 	sc = device_get_softc(dev);
1409 
1410 	/* Make sure we are accessing the correct PHY address. */
1411 	if (phy != sc->bce_phy_addr) {
1412 		DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d for PHY read!\n", phy);
1413 		return(0);
1414 	}
1415 
1416 	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1417 		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1418 		val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1419 
1420 		REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1421 		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1422 
1423 		DELAY(40);
1424 	}
1425 
1426 
1427 	val = BCE_MIPHY(phy) | BCE_MIREG(reg) |
1428 		BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT |
1429 		BCE_EMAC_MDIO_COMM_START_BUSY;
1430 	REG_WR(sc, BCE_EMAC_MDIO_COMM, val);
1431 
1432 	for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1433 		DELAY(10);
1434 
1435 		val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1436 		if (!(val & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1437 			DELAY(5);
1438 
1439 			val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1440 			val &= BCE_EMAC_MDIO_COMM_DATA;
1441 
1442 			break;
1443 		}
1444 	}
1445 
1446 	if (val & BCE_EMAC_MDIO_COMM_START_BUSY) {
1447 		BCE_PRINTF("%s(%d): Error: PHY read timeout! phy = %d, reg = 0x%04X\n",
1448 			__FILE__, __LINE__, phy, reg);
1449 		val = 0x0;
1450 	} else {
1451 		val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1452 	}
1453 
1454 
1455 	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1456 		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1457 		val |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1458 
1459 		REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1460 		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1461 
1462 		DELAY(40);
1463 	}
1464 
1465 	DB_PRINT_PHY_REG(reg, val);
1466 	return (val & 0xffff);
1467 
1468 }
1469 
1470 
1471 /****************************************************************************/
1472 /* PHY register write.                                                      */
1473 /*                                                                          */
1474 /* Implements register writes on the MII bus.                               */
1475 /*                                                                          */
1476 /* Returns:                                                                 */
1477 /*   The value of the register.                                             */
1478 /****************************************************************************/
1479 static int
1480 bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
1481 {
1482 	struct bce_softc *sc;
1483 	u32 val1;
1484 	int i;
1485 
1486 	sc = device_get_softc(dev);
1487 
1488 	/* Make sure we are accessing the correct PHY address. */
1489 	if (phy != sc->bce_phy_addr) {
1490 		DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d for PHY write!\n", phy);
1491 		return(0);
1492 	}
1493 
1494 	DB_PRINT_PHY_REG(reg, val);
1495 
1496 	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1497 		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1498 		val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1499 
1500 		REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1501 		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1502 
1503 		DELAY(40);
1504 	}
1505 
1506 	val1 = BCE_MIPHY(phy) | BCE_MIREG(reg) | val |
1507 		BCE_EMAC_MDIO_COMM_COMMAND_WRITE |
1508 		BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT;
1509 	REG_WR(sc, BCE_EMAC_MDIO_COMM, val1);
1510 
1511 	for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1512 		DELAY(10);
1513 
1514 		val1 = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1515 		if (!(val1 & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1516 			DELAY(5);
1517 			break;
1518 		}
1519 	}
1520 
1521 	if (val1 & BCE_EMAC_MDIO_COMM_START_BUSY)
1522 		BCE_PRINTF("%s(%d): PHY write timeout!\n",
1523 			__FILE__, __LINE__);
1524 
1525 	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1526 		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1527 		val1 |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1528 
1529 		REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1530 		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1531 
1532 		DELAY(40);
1533 	}
1534 
1535 	return 0;
1536 }
1537 
1538 
1539 /****************************************************************************/
1540 /* MII bus status change.                                                   */
1541 /*                                                                          */
1542 /* Called by the MII bus driver when the PHY establishes link to set the    */
1543 /* MAC interface registers.                                                 */
1544 /*                                                                          */
1545 /* Returns:                                                                 */
1546 /*   Nothing.                                                               */
1547 /****************************************************************************/
1548 static void
1549 bce_miibus_statchg(device_t dev)
1550 {
1551 	struct bce_softc *sc;
1552 	struct mii_data *mii;
1553 	int val;
1554 
1555 	sc = device_get_softc(dev);
1556 
1557 	DBENTER(BCE_VERBOSE_PHY);
1558 
1559 	mii = device_get_softc(sc->bce_miibus);
1560 
1561 	val = REG_RD(sc, BCE_EMAC_MODE);
1562 	val &= ~(BCE_EMAC_MODE_PORT | BCE_EMAC_MODE_HALF_DUPLEX |
1563 		BCE_EMAC_MODE_MAC_LOOP | BCE_EMAC_MODE_FORCE_LINK |
1564 		BCE_EMAC_MODE_25G);
1565 
1566 	/* Set MII or GMII interface based on the speed negotiated by the PHY. */
1567 	switch (IFM_SUBTYPE(mii->mii_media_active)) {
1568 	case IFM_10_T:
1569 		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
1570 			DBPRINT(sc, BCE_INFO, "Enabling 10Mb interface.\n");
1571 			val |= BCE_EMAC_MODE_PORT_MII_10;
1572 			break;
1573 		}
1574 		/* fall-through */
1575 	case IFM_100_TX:
1576 		DBPRINT(sc, BCE_INFO, "Enabling MII interface.\n");
1577 		val |= BCE_EMAC_MODE_PORT_MII;
1578 		break;
1579 	case IFM_2500_SX:
1580 		DBPRINT(sc, BCE_INFO, "Enabling 2.5G MAC mode.\n");
1581 		val |= BCE_EMAC_MODE_25G;
1582 		/* fall-through */
1583 	case IFM_1000_T:
1584 	case IFM_1000_SX:
1585 		DBPRINT(sc, BCE_INFO, "Enabling GMII interface.\n");
1586 		val |= BCE_EMAC_MODE_PORT_GMII;
1587 		break;
1588 	default:
1589 		DBPRINT(sc, BCE_INFO, "Unknown speed, enabling default GMII "
1590 			"interface.\n");
1591 		val |= BCE_EMAC_MODE_PORT_GMII;
1592 	}
1593 
1594 	/* Set half or full duplex based on the duplicity negotiated by the PHY. */
1595 	if ((mii->mii_media_active & IFM_GMASK) == IFM_HDX) {
1596 		DBPRINT(sc, BCE_INFO, "Setting Half-Duplex interface.\n");
1597 		val |= BCE_EMAC_MODE_HALF_DUPLEX;
1598 	} else
1599 		DBPRINT(sc, BCE_INFO, "Setting Full-Duplex interface.\n");
1600 
1601 	REG_WR(sc, BCE_EMAC_MODE, val);
1602 
1603 #if 0
1604 	/* ToDo: Enable flow control support in brgphy and bge. */
1605 	/* FLAG0 is set if RX is enabled and FLAG1 if TX is enabled */
1606 	if (mii->mii_media_active & IFM_FLAG0)
1607 		BCE_SETBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
1608 	if (mii->mii_media_active & IFM_FLAG1)
1609 		BCE_SETBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_TX_MODE_FLOW_EN);
1610 #endif
1611 
1612 	DBEXIT(BCE_VERBOSE_PHY);
1613 }
1614 
1615 
1616 /****************************************************************************/
1617 /* Acquire NVRAM lock.                                                      */
1618 /*                                                                          */
1619 /* Before the NVRAM can be accessed the caller must acquire an NVRAM lock.  */
1620 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1621 /* for use by the driver.                                                   */
1622 /*                                                                          */
1623 /* Returns:                                                                 */
1624 /*   0 on success, positive value on failure.                               */
1625 /****************************************************************************/
1626 static int
1627 bce_acquire_nvram_lock(struct bce_softc *sc)
1628 {
1629 	u32 val;
1630 	int j, rc = 0;
1631 
1632 	DBENTER(BCE_VERBOSE_NVRAM);
1633 
1634 	/* Request access to the flash interface. */
1635 	REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_SET2);
1636 	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1637 		val = REG_RD(sc, BCE_NVM_SW_ARB);
1638 		if (val & BCE_NVM_SW_ARB_ARB_ARB2)
1639 			break;
1640 
1641 		DELAY(5);
1642 	}
1643 
1644 	if (j >= NVRAM_TIMEOUT_COUNT) {
1645 		DBPRINT(sc, BCE_WARN, "Timeout acquiring NVRAM lock!\n");
1646 		rc = EBUSY;
1647 	}
1648 
1649 	DBEXIT(BCE_VERBOSE_NVRAM);
1650 	return (rc);
1651 }
1652 
1653 
1654 /****************************************************************************/
1655 /* Release NVRAM lock.                                                      */
1656 /*                                                                          */
1657 /* When the caller is finished accessing NVRAM the lock must be released.   */
1658 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1659 /* for use by the driver.                                                   */
1660 /*                                                                          */
1661 /* Returns:                                                                 */
1662 /*   0 on success, positive value on failure.                               */
1663 /****************************************************************************/
1664 static int
1665 bce_release_nvram_lock(struct bce_softc *sc)
1666 {
1667 	u32 val;
1668 	int j, rc = 0;
1669 
1670 	DBENTER(BCE_VERBOSE_NVRAM);
1671 
1672 	/*
1673 	 * Relinquish nvram interface.
1674 	 */
1675 	REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_CLR2);
1676 
1677 	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1678 		val = REG_RD(sc, BCE_NVM_SW_ARB);
1679 		if (!(val & BCE_NVM_SW_ARB_ARB_ARB2))
1680 			break;
1681 
1682 		DELAY(5);
1683 	}
1684 
1685 	if (j >= NVRAM_TIMEOUT_COUNT) {
1686 		DBPRINT(sc, BCE_WARN, "Timeout releasing NVRAM lock!\n");
1687 		rc = EBUSY;
1688 	}
1689 
1690 	DBEXIT(BCE_VERBOSE_NVRAM);
1691 	return (rc);
1692 }
1693 
1694 
1695 #ifdef BCE_NVRAM_WRITE_SUPPORT
1696 /****************************************************************************/
1697 /* Enable NVRAM write access.                                               */
1698 /*                                                                          */
1699 /* Before writing to NVRAM the caller must enable NVRAM writes.             */
1700 /*                                                                          */
1701 /* Returns:                                                                 */
1702 /*   0 on success, positive value on failure.                               */
1703 /****************************************************************************/
1704 static int
1705 bce_enable_nvram_write(struct bce_softc *sc)
1706 {
1707 	u32 val;
1708 	int rc = 0;
1709 
1710 	DBENTER(BCE_VERBOSE_NVRAM);
1711 
1712 	val = REG_RD(sc, BCE_MISC_CFG);
1713 	REG_WR(sc, BCE_MISC_CFG, val | BCE_MISC_CFG_NVM_WR_EN_PCI);
1714 
1715 	if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
1716 		int j;
1717 
1718 		REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1719 		REG_WR(sc, BCE_NVM_COMMAND,	BCE_NVM_COMMAND_WREN | BCE_NVM_COMMAND_DOIT);
1720 
1721 		for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1722 			DELAY(5);
1723 
1724 			val = REG_RD(sc, BCE_NVM_COMMAND);
1725 			if (val & BCE_NVM_COMMAND_DONE)
1726 				break;
1727 		}
1728 
1729 		if (j >= NVRAM_TIMEOUT_COUNT) {
1730 			DBPRINT(sc, BCE_WARN, "Timeout writing NVRAM!\n");
1731 			rc = EBUSY;
1732 		}
1733 	}
1734 
1735 	DBENTER(BCE_VERBOSE_NVRAM);
1736 	return (rc);
1737 }
1738 
1739 
1740 /****************************************************************************/
1741 /* Disable NVRAM write access.                                              */
1742 /*                                                                          */
1743 /* When the caller is finished writing to NVRAM write access must be        */
1744 /* disabled.                                                                */
1745 /*                                                                          */
1746 /* Returns:                                                                 */
1747 /*   Nothing.                                                               */
1748 /****************************************************************************/
1749 static void
1750 bce_disable_nvram_write(struct bce_softc *sc)
1751 {
1752 	u32 val;
1753 
1754 	DBENTER(BCE_VERBOSE_NVRAM);
1755 
1756 	val = REG_RD(sc, BCE_MISC_CFG);
1757 	REG_WR(sc, BCE_MISC_CFG, val & ~BCE_MISC_CFG_NVM_WR_EN);
1758 
1759 	DBEXIT(BCE_VERBOSE_NVRAM);
1760 
1761 }
1762 #endif
1763 
1764 
1765 /****************************************************************************/
1766 /* Enable NVRAM access.                                                     */
1767 /*                                                                          */
1768 /* Before accessing NVRAM for read or write operations the caller must      */
1769 /* enabled NVRAM access.                                                    */
1770 /*                                                                          */
1771 /* Returns:                                                                 */
1772 /*   Nothing.                                                               */
1773 /****************************************************************************/
1774 static void
1775 bce_enable_nvram_access(struct bce_softc *sc)
1776 {
1777 	u32 val;
1778 
1779 	DBENTER(BCE_VERBOSE_NVRAM);
1780 
1781 	val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
1782 	/* Enable both bits, even on read. */
1783 	REG_WR(sc, BCE_NVM_ACCESS_ENABLE,
1784 	       val | BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN);
1785 
1786 	DBEXIT(BCE_VERBOSE_NVRAM);
1787 }
1788 
1789 
1790 /****************************************************************************/
1791 /* Disable NVRAM access.                                                    */
1792 /*                                                                          */
1793 /* When the caller is finished accessing NVRAM access must be disabled.     */
1794 /*                                                                          */
1795 /* Returns:                                                                 */
1796 /*   Nothing.                                                               */
1797 /****************************************************************************/
1798 static void
1799 bce_disable_nvram_access(struct bce_softc *sc)
1800 {
1801 	u32 val;
1802 
1803 	DBENTER(BCE_VERBOSE_NVRAM);
1804 
1805 	val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
1806 
1807 	/* Disable both bits, even after read. */
1808 	REG_WR(sc, BCE_NVM_ACCESS_ENABLE,
1809 		val & ~(BCE_NVM_ACCESS_ENABLE_EN |
1810 			BCE_NVM_ACCESS_ENABLE_WR_EN));
1811 
1812 	DBEXIT(BCE_VERBOSE_NVRAM);
1813 }
1814 
1815 
1816 #ifdef BCE_NVRAM_WRITE_SUPPORT
1817 /****************************************************************************/
1818 /* Erase NVRAM page before writing.                                         */
1819 /*                                                                          */
1820 /* Non-buffered flash parts require that a page be erased before it is      */
1821 /* written.                                                                 */
1822 /*                                                                          */
1823 /* Returns:                                                                 */
1824 /*   0 on success, positive value on failure.                               */
1825 /****************************************************************************/
1826 static int
1827 bce_nvram_erase_page(struct bce_softc *sc, u32 offset)
1828 {
1829 	u32 cmd;
1830 	int j, rc = 0;
1831 
1832 	DBENTER(BCE_VERBOSE_NVRAM);
1833 
1834 	/* Buffered flash doesn't require an erase. */
1835 	if (sc->bce_flash_info->flags & BCE_NV_BUFFERED)
1836 		goto bce_nvram_erase_page_exit;
1837 
1838 	/* Build an erase command. */
1839 	cmd = BCE_NVM_COMMAND_ERASE | BCE_NVM_COMMAND_WR |
1840 	      BCE_NVM_COMMAND_DOIT;
1841 
1842 	/*
1843 	 * Clear the DONE bit separately, set the NVRAM adress to erase,
1844 	 * and issue the erase command.
1845 	 */
1846 	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1847 	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1848 	REG_WR(sc, BCE_NVM_COMMAND, cmd);
1849 
1850 	/* Wait for completion. */
1851 	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1852 		u32 val;
1853 
1854 		DELAY(5);
1855 
1856 		val = REG_RD(sc, BCE_NVM_COMMAND);
1857 		if (val & BCE_NVM_COMMAND_DONE)
1858 			break;
1859 	}
1860 
1861 	if (j >= NVRAM_TIMEOUT_COUNT) {
1862 		DBPRINT(sc, BCE_WARN, "Timeout erasing NVRAM.\n");
1863 		rc = EBUSY;
1864 	}
1865 
1866 bce_nvram_erase_page_exit:
1867 	DBEXIT(BCE_VERBOSE_NVRAM);
1868 	return (rc);
1869 }
1870 #endif /* BCE_NVRAM_WRITE_SUPPORT */
1871 
1872 
1873 /****************************************************************************/
1874 /* Read a dword (32 bits) from NVRAM.                                       */
1875 /*                                                                          */
1876 /* Read a 32 bit word from NVRAM.  The caller is assumed to have already    */
1877 /* obtained the NVRAM lock and enabled the controller for NVRAM access.     */
1878 /*                                                                          */
1879 /* Returns:                                                                 */
1880 /*   0 on success and the 32 bit value read, positive value on failure.     */
1881 /****************************************************************************/
1882 static int
1883 bce_nvram_read_dword(struct bce_softc *sc, u32 offset, u8 *ret_val,
1884 							u32 cmd_flags)
1885 {
1886 	u32 cmd;
1887 	int i, rc = 0;
1888 
1889 	DBENTER(BCE_EXTREME_NVRAM);
1890 
1891 	/* Build the command word. */
1892 	cmd = BCE_NVM_COMMAND_DOIT | cmd_flags;
1893 
1894 	/* Calculate the offset for buffered flash if translation is used. */
1895 	if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
1896 		offset = ((offset / sc->bce_flash_info->page_size) <<
1897 			   sc->bce_flash_info->page_bits) +
1898 			  (offset % sc->bce_flash_info->page_size);
1899 	}
1900 
1901 	/*
1902 	 * Clear the DONE bit separately, set the address to read,
1903 	 * and issue the read.
1904 	 */
1905 	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1906 	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1907 	REG_WR(sc, BCE_NVM_COMMAND, cmd);
1908 
1909 	/* Wait for completion. */
1910 	for (i = 0; i < NVRAM_TIMEOUT_COUNT; i++) {
1911 		u32 val;
1912 
1913 		DELAY(5);
1914 
1915 		val = REG_RD(sc, BCE_NVM_COMMAND);
1916 		if (val & BCE_NVM_COMMAND_DONE) {
1917 			val = REG_RD(sc, BCE_NVM_READ);
1918 
1919 			val = bce_be32toh(val);
1920 			memcpy(ret_val, &val, 4);
1921 			break;
1922 		}
1923 	}
1924 
1925 	/* Check for errors. */
1926 	if (i >= NVRAM_TIMEOUT_COUNT) {
1927 		BCE_PRINTF("%s(%d): Timeout error reading NVRAM at offset 0x%08X!\n",
1928 			__FILE__, __LINE__, offset);
1929 		rc = EBUSY;
1930 	}
1931 
1932 	DBEXIT(BCE_EXTREME_NVRAM);
1933 	return(rc);
1934 }
1935 
1936 
1937 #ifdef BCE_NVRAM_WRITE_SUPPORT
1938 /****************************************************************************/
1939 /* Write a dword (32 bits) to NVRAM.                                        */
1940 /*                                                                          */
1941 /* Write a 32 bit word to NVRAM.  The caller is assumed to have already     */
1942 /* obtained the NVRAM lock, enabled the controller for NVRAM access, and    */
1943 /* enabled NVRAM write access.                                              */
1944 /*                                                                          */
1945 /* Returns:                                                                 */
1946 /*   0 on success, positive value on failure.                               */
1947 /****************************************************************************/
1948 static int
1949 bce_nvram_write_dword(struct bce_softc *sc, u32 offset, u8 *val,
1950 	u32 cmd_flags)
1951 {
1952 	u32 cmd, val32;
1953 	int j, rc = 0;
1954 
1955 	DBENTER(BCE_VERBOSE_NVRAM);
1956 
1957 	/* Build the command word. */
1958 	cmd = BCE_NVM_COMMAND_DOIT | BCE_NVM_COMMAND_WR | cmd_flags;
1959 
1960 	/* Calculate the offset for buffered flash if translation is used. */
1961 	if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
1962 		offset = ((offset / sc->bce_flash_info->page_size) <<
1963 			  sc->bce_flash_info->page_bits) +
1964 			 (offset % sc->bce_flash_info->page_size);
1965 	}
1966 
1967 	/*
1968 	 * Clear the DONE bit separately, convert NVRAM data to big-endian,
1969 	 * set the NVRAM address to write, and issue the write command
1970 	 */
1971 	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1972 	memcpy(&val32, val, 4);
1973 	val32 = htobe32(val32);
1974 	REG_WR(sc, BCE_NVM_WRITE, val32);
1975 	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1976 	REG_WR(sc, BCE_NVM_COMMAND, cmd);
1977 
1978 	/* Wait for completion. */
1979 	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1980 		DELAY(5);
1981 
1982 		if (REG_RD(sc, BCE_NVM_COMMAND) & BCE_NVM_COMMAND_DONE)
1983 			break;
1984 	}
1985 	if (j >= NVRAM_TIMEOUT_COUNT) {
1986 		BCE_PRINTF("%s(%d): Timeout error writing NVRAM at offset 0x%08X\n",
1987 			__FILE__, __LINE__, offset);
1988 		rc = EBUSY;
1989 	}
1990 
1991 	DBEXIT(BCE_VERBOSE_NVRAM);
1992 	return (rc);
1993 }
1994 #endif /* BCE_NVRAM_WRITE_SUPPORT */
1995 
1996 
1997 /****************************************************************************/
1998 /* Initialize NVRAM access.                                                 */
1999 /*                                                                          */
2000 /* Identify the NVRAM device in use and prepare the NVRAM interface to      */
2001 /* access that device.                                                      */
2002 /*                                                                          */
2003 /* Returns:                                                                 */
2004 /*   0 on success, positive value on failure.                               */
2005 /****************************************************************************/
2006 static int
2007 bce_init_nvram(struct bce_softc *sc)
2008 {
2009 	u32 val;
2010 	int j, entry_count, rc = 0;
2011 	struct flash_spec *flash;
2012 
2013 	DBENTER(BCE_VERBOSE_NVRAM);
2014 
2015 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
2016 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
2017 		sc->bce_flash_info = &flash_5709;
2018 		goto bce_init_nvram_get_flash_size;
2019 	}
2020 
2021 	/* Determine the selected interface. */
2022 	val = REG_RD(sc, BCE_NVM_CFG1);
2023 
2024 	entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
2025 
2026 	/*
2027 	 * Flash reconfiguration is required to support additional
2028 	 * NVRAM devices not directly supported in hardware.
2029 	 * Check if the flash interface was reconfigured
2030 	 * by the bootcode.
2031 	 */
2032 
2033 	if (val & 0x40000000) {
2034 		/* Flash interface reconfigured by bootcode. */
2035 
2036 		DBPRINT(sc,BCE_INFO_LOAD,
2037 			"bce_init_nvram(): Flash WAS reconfigured.\n");
2038 
2039 		for (j = 0, flash = &flash_table[0]; j < entry_count;
2040 		     j++, flash++) {
2041 			if ((val & FLASH_BACKUP_STRAP_MASK) ==
2042 			    (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
2043 				sc->bce_flash_info = flash;
2044 				break;
2045 			}
2046 		}
2047 	} else {
2048 		/* Flash interface not yet reconfigured. */
2049 		u32 mask;
2050 
2051 		DBPRINT(sc, BCE_INFO_LOAD, "%s(): Flash was NOT reconfigured.\n",
2052 			__FUNCTION__);
2053 
2054 		if (val & (1 << 23))
2055 			mask = FLASH_BACKUP_STRAP_MASK;
2056 		else
2057 			mask = FLASH_STRAP_MASK;
2058 
2059 		/* Look for the matching NVRAM device configuration data. */
2060 		for (j = 0, flash = &flash_table[0]; j < entry_count; j++, flash++) {
2061 
2062 			/* Check if the device matches any of the known devices. */
2063 			if ((val & mask) == (flash->strapping & mask)) {
2064 				/* Found a device match. */
2065 				sc->bce_flash_info = flash;
2066 
2067 				/* Request access to the flash interface. */
2068 				if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2069 					return rc;
2070 
2071 				/* Reconfigure the flash interface. */
2072 				bce_enable_nvram_access(sc);
2073 				REG_WR(sc, BCE_NVM_CFG1, flash->config1);
2074 				REG_WR(sc, BCE_NVM_CFG2, flash->config2);
2075 				REG_WR(sc, BCE_NVM_CFG3, flash->config3);
2076 				REG_WR(sc, BCE_NVM_WRITE1, flash->write1);
2077 				bce_disable_nvram_access(sc);
2078 				bce_release_nvram_lock(sc);
2079 
2080 				break;
2081 			}
2082 		}
2083 	}
2084 
2085 	/* Check if a matching device was found. */
2086 	if (j == entry_count) {
2087 		sc->bce_flash_info = NULL;
2088 		BCE_PRINTF("%s(%d): Unknown Flash NVRAM found!\n",
2089 			__FILE__, __LINE__);
2090 		rc = ENODEV;
2091 	}
2092 
2093 bce_init_nvram_get_flash_size:
2094 	/* Write the flash config data to the shared memory interface. */
2095 	val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_SHARED_HW_CFG_CONFIG2);
2096 	val &= BCE_SHARED_HW_CFG2_NVM_SIZE_MASK;
2097 	if (val)
2098 		sc->bce_flash_size = val;
2099 	else
2100 		sc->bce_flash_size = sc->bce_flash_info->total_size;
2101 
2102 	DBPRINT(sc, BCE_INFO_LOAD, "%s(): Found %s, size = 0x%08X\n",
2103 		__FUNCTION__, sc->bce_flash_info->name,
2104 		sc->bce_flash_info->total_size);
2105 
2106 	DBEXIT(BCE_VERBOSE_NVRAM);
2107 	return rc;
2108 }
2109 
2110 
2111 /****************************************************************************/
2112 /* Read an arbitrary range of data from NVRAM.                              */
2113 /*                                                                          */
2114 /* Prepares the NVRAM interface for access and reads the requested data     */
2115 /* into the supplied buffer.                                                */
2116 /*                                                                          */
2117 /* Returns:                                                                 */
2118 /*   0 on success and the data read, positive value on failure.             */
2119 /****************************************************************************/
2120 static int
2121 bce_nvram_read(struct bce_softc *sc, u32 offset, u8 *ret_buf,
2122 	int buf_size)
2123 {
2124 	int rc = 0;
2125 	u32 cmd_flags, offset32, len32, extra;
2126 
2127 	DBENTER(BCE_VERBOSE_NVRAM);
2128 
2129 	if (buf_size == 0)
2130 		goto bce_nvram_read_exit;
2131 
2132 	/* Request access to the flash interface. */
2133 	if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2134 		goto bce_nvram_read_exit;
2135 
2136 	/* Enable access to flash interface */
2137 	bce_enable_nvram_access(sc);
2138 
2139 	len32 = buf_size;
2140 	offset32 = offset;
2141 	extra = 0;
2142 
2143 	cmd_flags = 0;
2144 
2145 	if (offset32 & 3) {
2146 		u8 buf[4];
2147 		u32 pre_len;
2148 
2149 		offset32 &= ~3;
2150 		pre_len = 4 - (offset & 3);
2151 
2152 		if (pre_len >= len32) {
2153 			pre_len = len32;
2154 			cmd_flags = BCE_NVM_COMMAND_FIRST | BCE_NVM_COMMAND_LAST;
2155 		}
2156 		else {
2157 			cmd_flags = BCE_NVM_COMMAND_FIRST;
2158 		}
2159 
2160 		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2161 
2162 		if (rc)
2163 			return rc;
2164 
2165 		memcpy(ret_buf, buf + (offset & 3), pre_len);
2166 
2167 		offset32 += 4;
2168 		ret_buf += pre_len;
2169 		len32 -= pre_len;
2170 	}
2171 
2172 	if (len32 & 3) {
2173 		extra = 4 - (len32 & 3);
2174 		len32 = (len32 + 4) & ~3;
2175 	}
2176 
2177 	if (len32 == 4) {
2178 		u8 buf[4];
2179 
2180 		if (cmd_flags)
2181 			cmd_flags = BCE_NVM_COMMAND_LAST;
2182 		else
2183 			cmd_flags = BCE_NVM_COMMAND_FIRST |
2184 				    BCE_NVM_COMMAND_LAST;
2185 
2186 		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2187 
2188 		memcpy(ret_buf, buf, 4 - extra);
2189 	}
2190 	else if (len32 > 0) {
2191 		u8 buf[4];
2192 
2193 		/* Read the first word. */
2194 		if (cmd_flags)
2195 			cmd_flags = 0;
2196 		else
2197 			cmd_flags = BCE_NVM_COMMAND_FIRST;
2198 
2199 		rc = bce_nvram_read_dword(sc, offset32, ret_buf, cmd_flags);
2200 
2201 		/* Advance to the next dword. */
2202 		offset32 += 4;
2203 		ret_buf += 4;
2204 		len32 -= 4;
2205 
2206 		while (len32 > 4 && rc == 0) {
2207 			rc = bce_nvram_read_dword(sc, offset32, ret_buf, 0);
2208 
2209 			/* Advance to the next dword. */
2210 			offset32 += 4;
2211 			ret_buf += 4;
2212 			len32 -= 4;
2213 		}
2214 
2215 		if (rc)
2216 			goto bce_nvram_read_locked_exit;
2217 
2218 		cmd_flags = BCE_NVM_COMMAND_LAST;
2219 		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2220 
2221 		memcpy(ret_buf, buf, 4 - extra);
2222 	}
2223 
2224 bce_nvram_read_locked_exit:
2225 	/* Disable access to flash interface and release the lock. */
2226 	bce_disable_nvram_access(sc);
2227 	bce_release_nvram_lock(sc);
2228 
2229 bce_nvram_read_exit:
2230 	DBEXIT(BCE_VERBOSE_NVRAM);
2231 	return rc;
2232 }
2233 
2234 
2235 #ifdef BCE_NVRAM_WRITE_SUPPORT
2236 /****************************************************************************/
2237 /* Write an arbitrary range of data from NVRAM.                             */
2238 /*                                                                          */
2239 /* Prepares the NVRAM interface for write access and writes the requested   */
2240 /* data from the supplied buffer.  The caller is responsible for            */
2241 /* calculating any appropriate CRCs.                                        */
2242 /*                                                                          */
2243 /* Returns:                                                                 */
2244 /*   0 on success, positive value on failure.                               */
2245 /****************************************************************************/
2246 static int
2247 bce_nvram_write(struct bce_softc *sc, u32 offset, u8 *data_buf,
2248 	int buf_size)
2249 {
2250 	u32 written, offset32, len32;
2251 	u8 *buf, start[4], end[4];
2252 	int rc = 0;
2253 	int align_start, align_end;
2254 
2255 	DBENTER(BCE_VERBOSE_NVRAM);
2256 
2257 	buf = data_buf;
2258 	offset32 = offset;
2259 	len32 = buf_size;
2260 	align_start = align_end = 0;
2261 
2262 	if ((align_start = (offset32 & 3))) {
2263 		offset32 &= ~3;
2264 		len32 += align_start;
2265 		if ((rc = bce_nvram_read(sc, offset32, start, 4)))
2266 			goto bce_nvram_write_exit;
2267 	}
2268 
2269 	if (len32 & 3) {
2270 	       	if ((len32 > 4) || !align_start) {
2271 			align_end = 4 - (len32 & 3);
2272 			len32 += align_end;
2273 			if ((rc = bce_nvram_read(sc, offset32 + len32 - 4,
2274 				end, 4))) {
2275 				goto bce_nvram_write_exit;
2276 			}
2277 		}
2278 	}
2279 
2280 	if (align_start || align_end) {
2281 		buf = malloc(len32, M_DEVBUF, M_NOWAIT);
2282 		if (buf == 0) {
2283 			rc = ENOMEM;
2284 			goto bce_nvram_write_exit;
2285 		}
2286 
2287 		if (align_start) {
2288 			memcpy(buf, start, 4);
2289 		}
2290 
2291 		if (align_end) {
2292 			memcpy(buf + len32 - 4, end, 4);
2293 		}
2294 		memcpy(buf + align_start, data_buf, buf_size);
2295 	}
2296 
2297 	written = 0;
2298 	while ((written < len32) && (rc == 0)) {
2299 		u32 page_start, page_end, data_start, data_end;
2300 		u32 addr, cmd_flags;
2301 		int i;
2302 		u8 flash_buffer[264];
2303 
2304 	    /* Find the page_start addr */
2305 		page_start = offset32 + written;
2306 		page_start -= (page_start % sc->bce_flash_info->page_size);
2307 		/* Find the page_end addr */
2308 		page_end = page_start + sc->bce_flash_info->page_size;
2309 		/* Find the data_start addr */
2310 		data_start = (written == 0) ? offset32 : page_start;
2311 		/* Find the data_end addr */
2312 		data_end = (page_end > offset32 + len32) ?
2313 			(offset32 + len32) : page_end;
2314 
2315 		/* Request access to the flash interface. */
2316 		if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2317 			goto bce_nvram_write_exit;
2318 
2319 		/* Enable access to flash interface */
2320 		bce_enable_nvram_access(sc);
2321 
2322 		cmd_flags = BCE_NVM_COMMAND_FIRST;
2323 		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2324 			int j;
2325 
2326 			/* Read the whole page into the buffer
2327 			 * (non-buffer flash only) */
2328 			for (j = 0; j < sc->bce_flash_info->page_size; j += 4) {
2329 				if (j == (sc->bce_flash_info->page_size - 4)) {
2330 					cmd_flags |= BCE_NVM_COMMAND_LAST;
2331 				}
2332 				rc = bce_nvram_read_dword(sc,
2333 					page_start + j,
2334 					&flash_buffer[j],
2335 					cmd_flags);
2336 
2337 				if (rc)
2338 					goto bce_nvram_write_locked_exit;
2339 
2340 				cmd_flags = 0;
2341 			}
2342 		}
2343 
2344 		/* Enable writes to flash interface (unlock write-protect) */
2345 		if ((rc = bce_enable_nvram_write(sc)) != 0)
2346 			goto bce_nvram_write_locked_exit;
2347 
2348 		/* Erase the page */
2349 		if ((rc = bce_nvram_erase_page(sc, page_start)) != 0)
2350 			goto bce_nvram_write_locked_exit;
2351 
2352 		/* Re-enable the write again for the actual write */
2353 		bce_enable_nvram_write(sc);
2354 
2355 		/* Loop to write back the buffer data from page_start to
2356 		 * data_start */
2357 		i = 0;
2358 		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2359 			for (addr = page_start; addr < data_start;
2360 				addr += 4, i += 4) {
2361 
2362 				rc = bce_nvram_write_dword(sc, addr,
2363 					&flash_buffer[i], cmd_flags);
2364 
2365 				if (rc != 0)
2366 					goto bce_nvram_write_locked_exit;
2367 
2368 				cmd_flags = 0;
2369 			}
2370 		}
2371 
2372 		/* Loop to write the new data from data_start to data_end */
2373 		for (addr = data_start; addr < data_end; addr += 4, i++) {
2374 			if ((addr == page_end - 4) ||
2375 				((sc->bce_flash_info->flags & BCE_NV_BUFFERED) &&
2376 				(addr == data_end - 4))) {
2377 
2378 				cmd_flags |= BCE_NVM_COMMAND_LAST;
2379 			}
2380 			rc = bce_nvram_write_dword(sc, addr, buf,
2381 				cmd_flags);
2382 
2383 			if (rc != 0)
2384 				goto bce_nvram_write_locked_exit;
2385 
2386 			cmd_flags = 0;
2387 			buf += 4;
2388 		}
2389 
2390 		/* Loop to write back the buffer data from data_end
2391 		 * to page_end */
2392 		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2393 			for (addr = data_end; addr < page_end;
2394 				addr += 4, i += 4) {
2395 
2396 				if (addr == page_end-4) {
2397 					cmd_flags = BCE_NVM_COMMAND_LAST;
2398                 		}
2399 				rc = bce_nvram_write_dword(sc, addr,
2400 					&flash_buffer[i], cmd_flags);
2401 
2402 				if (rc != 0)
2403 					goto bce_nvram_write_locked_exit;
2404 
2405 				cmd_flags = 0;
2406 			}
2407 		}
2408 
2409 		/* Disable writes to flash interface (lock write-protect) */
2410 		bce_disable_nvram_write(sc);
2411 
2412 		/* Disable access to flash interface */
2413 		bce_disable_nvram_access(sc);
2414 		bce_release_nvram_lock(sc);
2415 
2416 		/* Increment written */
2417 		written += data_end - data_start;
2418 	}
2419 
2420 	goto bce_nvram_write_exit;
2421 
2422 bce_nvram_write_locked_exit:
2423 		bce_disable_nvram_write(sc);
2424 		bce_disable_nvram_access(sc);
2425 		bce_release_nvram_lock(sc);
2426 
2427 bce_nvram_write_exit:
2428 	if (align_start || align_end)
2429 		free(buf, M_DEVBUF);
2430 
2431 	DBEXIT(BCE_VERBOSE_NVRAM);
2432 	return (rc);
2433 }
2434 #endif /* BCE_NVRAM_WRITE_SUPPORT */
2435 
2436 
2437 /****************************************************************************/
2438 /* Verifies that NVRAM is accessible and contains valid data.               */
2439 /*                                                                          */
2440 /* Reads the configuration data from NVRAM and verifies that the CRC is     */
2441 /* correct.                                                                 */
2442 /*                                                                          */
2443 /* Returns:                                                                 */
2444 /*   0 on success, positive value on failure.                               */
2445 /****************************************************************************/
2446 static int
2447 bce_nvram_test(struct bce_softc *sc)
2448 {
2449 	u32 buf[BCE_NVRAM_SIZE / 4];
2450 	u8 *data = (u8 *) buf;
2451 	int rc = 0;
2452 	u32 magic, csum;
2453 
2454 	DBENTER(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
2455 
2456 	/*
2457 	 * Check that the device NVRAM is valid by reading
2458 	 * the magic value at offset 0.
2459 	 */
2460 	if ((rc = bce_nvram_read(sc, 0, data, 4)) != 0) {
2461 		BCE_PRINTF("%s(%d): Unable to read NVRAM!\n", __FILE__, __LINE__);
2462 		goto bce_nvram_test_exit;
2463 	}
2464 
2465 	/*
2466 	 * Verify that offset 0 of the NVRAM contains
2467 	 * a valid magic number.
2468 	 */
2469     magic = bce_be32toh(buf[0]);
2470 	if (magic != BCE_NVRAM_MAGIC) {
2471 		rc = ENODEV;
2472 		BCE_PRINTF("%s(%d): Invalid NVRAM magic value! Expected: 0x%08X, "
2473 			"Found: 0x%08X\n",
2474 			__FILE__, __LINE__, BCE_NVRAM_MAGIC, magic);
2475 		goto bce_nvram_test_exit;
2476 	}
2477 
2478 	/*
2479 	 * Verify that the device NVRAM includes valid
2480 	 * configuration data.
2481 	 */
2482 	if ((rc = bce_nvram_read(sc, 0x100, data, BCE_NVRAM_SIZE)) != 0) {
2483 		BCE_PRINTF("%s(%d): Unable to read Manufacturing Information from "
2484 			"NVRAM!\n", __FILE__, __LINE__);
2485 		goto bce_nvram_test_exit;
2486 	}
2487 
2488 	csum = ether_crc32_le(data, 0x100);
2489 	if (csum != BCE_CRC32_RESIDUAL) {
2490 		rc = ENODEV;
2491 		BCE_PRINTF("%s(%d): Invalid Manufacturing Information NVRAM CRC! "
2492 			"Expected: 0x%08X, Found: 0x%08X\n",
2493 			__FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
2494 		goto bce_nvram_test_exit;
2495 	}
2496 
2497 	csum = ether_crc32_le(data + 0x100, 0x100);
2498 	if (csum != BCE_CRC32_RESIDUAL) {
2499 		rc = ENODEV;
2500 		BCE_PRINTF("%s(%d): Invalid Feature Configuration Information "
2501 			"NVRAM CRC! Expected: 0x%08X, Found: 08%08X\n",
2502 			__FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
2503 	}
2504 
2505 bce_nvram_test_exit:
2506 	DBEXIT(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
2507 	return rc;
2508 }
2509 
2510 
2511 /****************************************************************************/
2512 /* Identifies the current media type of the controller and sets the PHY     */
2513 /* address.                                                                 */
2514 /*                                                                          */
2515 /* Returns:                                                                 */
2516 /*   Nothing.                                                               */
2517 /****************************************************************************/
2518 static void
2519 bce_get_media(struct bce_softc *sc)
2520 {
2521 	u32 val;
2522 
2523 	DBENTER(BCE_VERBOSE);
2524 
2525 	/* Assume PHY address for copper controllers. */
2526 	sc->bce_phy_addr = 1;
2527 
2528 	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
2529  		u32 val = REG_RD(sc, BCE_MISC_DUAL_MEDIA_CTRL);
2530 		u32 bond_id = val & BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID;
2531 		u32 strap;
2532 
2533 		/*
2534 		 * The BCM5709S is software configurable
2535 		 * for Copper or SerDes operation.
2536 		 */
2537 		if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_C) {
2538 			DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded for copper.\n");
2539 			goto bce_get_media_exit;
2540 		} else if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_S) {
2541 			DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded for dual media.\n");
2542 			sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2543 			goto bce_get_media_exit;
2544 		}
2545 
2546 		if (val & BCE_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE)
2547 			strap = (val & BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21;
2548 		else
2549 			strap = (val & BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8;
2550 
2551 		if (pci_get_function(sc->bce_dev) == 0) {
2552 			switch (strap) {
2553 			case 0x4:
2554 			case 0x5:
2555 			case 0x6:
2556 				DBPRINT(sc, BCE_INFO_LOAD,
2557 					"BCM5709 s/w configured for SerDes.\n");
2558 				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2559 			default:
2560 				DBPRINT(sc, BCE_INFO_LOAD,
2561 					"BCM5709 s/w configured for Copper.\n");
2562 			}
2563 		} else {
2564 			switch (strap) {
2565 			case 0x1:
2566 			case 0x2:
2567 			case 0x4:
2568 				DBPRINT(sc, BCE_INFO_LOAD,
2569 					"BCM5709 s/w configured for SerDes.\n");
2570 				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2571 			default:
2572 				DBPRINT(sc, BCE_INFO_LOAD,
2573 					"BCM5709 s/w configured for Copper.\n");
2574 			}
2575 		}
2576 
2577 	} else if (BCE_CHIP_BOND_ID(sc) & BCE_CHIP_BOND_ID_SERDES_BIT)
2578 		sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2579 
2580 	if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) {
2581 		sc->bce_flags |= BCE_NO_WOL_FLAG;
2582 		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
2583 			sc->bce_phy_addr = 2;
2584 			val = REG_RD_IND(sc, sc->bce_shmem_base +
2585 				 BCE_SHARED_HW_CFG_CONFIG);
2586 			if (val & BCE_SHARED_HW_CFG_PHY_2_5G) {
2587 				sc->bce_phy_flags |= BCE_PHY_2_5G_CAPABLE_FLAG;
2588 				DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb capable adapter\n");
2589 			}
2590 		}
2591 	} else if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) ||
2592 		   (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708))
2593 		sc->bce_phy_flags |= BCE_PHY_CRC_FIX_FLAG;
2594 
2595 bce_get_media_exit:
2596 	DBPRINT(sc, (BCE_INFO_LOAD | BCE_INFO_PHY),
2597 		"Using PHY address %d.\n", sc->bce_phy_addr);
2598 
2599 	DBEXIT(BCE_VERBOSE);
2600 }
2601 
2602 
2603 /****************************************************************************/
2604 /* Free any DMA memory owned by the driver.                                 */
2605 /*                                                                          */
2606 /* Scans through each data structre that requires DMA memory and frees      */
2607 /* the memory if allocated.                                                 */
2608 /*                                                                          */
2609 /* Returns:                                                                 */
2610 /*   Nothing.                                                               */
2611 /****************************************************************************/
2612 static void
2613 bce_dma_free(struct bce_softc *sc)
2614 {
2615 	int i;
2616 
2617 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
2618 
2619 	/* Free, unmap, and destroy the status block. */
2620 	if (sc->status_block != NULL) {
2621 		bus_dmamem_free(
2622 			sc->status_tag,
2623 		    sc->status_block,
2624 		    sc->status_map);
2625 		sc->status_block = NULL;
2626 	}
2627 
2628 	if (sc->status_map != NULL) {
2629 		bus_dmamap_unload(
2630 			sc->status_tag,
2631 		    sc->status_map);
2632 		bus_dmamap_destroy(sc->status_tag,
2633 		    sc->status_map);
2634 		sc->status_map = NULL;
2635 	}
2636 
2637 	if (sc->status_tag != NULL) {
2638 		bus_dma_tag_destroy(sc->status_tag);
2639 		sc->status_tag = NULL;
2640 	}
2641 
2642 
2643 	/* Free, unmap, and destroy the statistics block. */
2644 	if (sc->stats_block != NULL) {
2645 		bus_dmamem_free(
2646 			sc->stats_tag,
2647 		    sc->stats_block,
2648 		    sc->stats_map);
2649 		sc->stats_block = NULL;
2650 	}
2651 
2652 	if (sc->stats_map != NULL) {
2653 		bus_dmamap_unload(
2654 			sc->stats_tag,
2655 		    sc->stats_map);
2656 		bus_dmamap_destroy(sc->stats_tag,
2657 		    sc->stats_map);
2658 		sc->stats_map = NULL;
2659 	}
2660 
2661 	if (sc->stats_tag != NULL) {
2662 		bus_dma_tag_destroy(sc->stats_tag);
2663 		sc->stats_tag = NULL;
2664 	}
2665 
2666 
2667 	/* Free, unmap and destroy all context memory pages. */
2668 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
2669 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
2670 		for (i = 0; i < sc->ctx_pages; i++ ) {
2671 			if (sc->ctx_block[i] != NULL) {
2672 				bus_dmamem_free(
2673 					sc->ctx_tag,
2674 				    sc->ctx_block[i],
2675 				    sc->ctx_map[i]);
2676 				sc->ctx_block[i] = NULL;
2677 			}
2678 
2679 			if (sc->ctx_map[i] != NULL) {
2680 				bus_dmamap_unload(
2681 					sc->ctx_tag,
2682 		    		sc->ctx_map[i]);
2683 				bus_dmamap_destroy(
2684 					sc->ctx_tag,
2685 				    sc->ctx_map[i]);
2686 				sc->ctx_map[i] = NULL;
2687 			}
2688 		}
2689 
2690 		/* Destroy the context memory tag. */
2691 		if (sc->ctx_tag != NULL) {
2692 			bus_dma_tag_destroy(sc->ctx_tag);
2693 			sc->ctx_tag = NULL;
2694 		}
2695 	}
2696 
2697 
2698 	/* Free, unmap and destroy all TX buffer descriptor chain pages. */
2699 	for (i = 0; i < TX_PAGES; i++ ) {
2700 		if (sc->tx_bd_chain[i] != NULL) {
2701 			bus_dmamem_free(
2702 				sc->tx_bd_chain_tag,
2703 			    sc->tx_bd_chain[i],
2704 			    sc->tx_bd_chain_map[i]);
2705 			sc->tx_bd_chain[i] = NULL;
2706 		}
2707 
2708 		if (sc->tx_bd_chain_map[i] != NULL) {
2709 			bus_dmamap_unload(
2710 				sc->tx_bd_chain_tag,
2711 		    	sc->tx_bd_chain_map[i]);
2712 			bus_dmamap_destroy(
2713 				sc->tx_bd_chain_tag,
2714 			    sc->tx_bd_chain_map[i]);
2715 			sc->tx_bd_chain_map[i] = NULL;
2716 		}
2717 	}
2718 
2719 	/* Destroy the TX buffer descriptor tag. */
2720 	if (sc->tx_bd_chain_tag != NULL) {
2721 		bus_dma_tag_destroy(sc->tx_bd_chain_tag);
2722 		sc->tx_bd_chain_tag = NULL;
2723 	}
2724 
2725 
2726 	/* Free, unmap and destroy all RX buffer descriptor chain pages. */
2727 	for (i = 0; i < RX_PAGES; i++ ) {
2728 		if (sc->rx_bd_chain[i] != NULL) {
2729 			bus_dmamem_free(
2730 				sc->rx_bd_chain_tag,
2731 			    sc->rx_bd_chain[i],
2732 			    sc->rx_bd_chain_map[i]);
2733 			sc->rx_bd_chain[i] = NULL;
2734 		}
2735 
2736 		if (sc->rx_bd_chain_map[i] != NULL) {
2737 			bus_dmamap_unload(
2738 				sc->rx_bd_chain_tag,
2739 		    	sc->rx_bd_chain_map[i]);
2740 			bus_dmamap_destroy(
2741 				sc->rx_bd_chain_tag,
2742 			    sc->rx_bd_chain_map[i]);
2743 			sc->rx_bd_chain_map[i] = NULL;
2744 		}
2745 	}
2746 
2747 	/* Destroy the RX buffer descriptor tag. */
2748 	if (sc->rx_bd_chain_tag != NULL) {
2749 		bus_dma_tag_destroy(sc->rx_bd_chain_tag);
2750 		sc->rx_bd_chain_tag = NULL;
2751 	}
2752 
2753 
2754 #ifdef BCE_USE_SPLIT_HEADER
2755 	/* Free, unmap and destroy all page buffer descriptor chain pages. */
2756 	for (i = 0; i < PG_PAGES; i++ ) {
2757 		if (sc->pg_bd_chain[i] != NULL) {
2758 			bus_dmamem_free(
2759 				sc->pg_bd_chain_tag,
2760 			    sc->pg_bd_chain[i],
2761 			    sc->pg_bd_chain_map[i]);
2762 			sc->pg_bd_chain[i] = NULL;
2763 		}
2764 
2765 		if (sc->pg_bd_chain_map[i] != NULL) {
2766 			bus_dmamap_unload(
2767 				sc->pg_bd_chain_tag,
2768 		    	sc->pg_bd_chain_map[i]);
2769 			bus_dmamap_destroy(
2770 				sc->pg_bd_chain_tag,
2771 			    sc->pg_bd_chain_map[i]);
2772 			sc->pg_bd_chain_map[i] = NULL;
2773 		}
2774 	}
2775 
2776 	/* Destroy the page buffer descriptor tag. */
2777 	if (sc->pg_bd_chain_tag != NULL) {
2778 		bus_dma_tag_destroy(sc->pg_bd_chain_tag);
2779 		sc->pg_bd_chain_tag = NULL;
2780 	}
2781 #endif
2782 
2783 
2784 	/* Unload and destroy the TX mbuf maps. */
2785 	for (i = 0; i < TOTAL_TX_BD; i++) {
2786 		if (sc->tx_mbuf_map[i] != NULL) {
2787 			bus_dmamap_unload(sc->tx_mbuf_tag,
2788 				sc->tx_mbuf_map[i]);
2789 			bus_dmamap_destroy(sc->tx_mbuf_tag,
2790 	 			sc->tx_mbuf_map[i]);
2791 			sc->tx_mbuf_map[i] = NULL;
2792 		}
2793 	}
2794 
2795 	/* Destroy the TX mbuf tag. */
2796 	if (sc->tx_mbuf_tag != NULL) {
2797 		bus_dma_tag_destroy(sc->tx_mbuf_tag);
2798 		sc->tx_mbuf_tag = NULL;
2799 	}
2800 
2801 	/* Unload and destroy the RX mbuf maps. */
2802 	for (i = 0; i < TOTAL_RX_BD; i++) {
2803 		if (sc->rx_mbuf_map[i] != NULL) {
2804 			bus_dmamap_unload(sc->rx_mbuf_tag,
2805 				sc->rx_mbuf_map[i]);
2806 			bus_dmamap_destroy(sc->rx_mbuf_tag,
2807 	 			sc->rx_mbuf_map[i]);
2808 			sc->rx_mbuf_map[i] = NULL;
2809 		}
2810 	}
2811 
2812 	/* Destroy the RX mbuf tag. */
2813 	if (sc->rx_mbuf_tag != NULL) {
2814 		bus_dma_tag_destroy(sc->rx_mbuf_tag);
2815 		sc->rx_mbuf_tag = NULL;
2816 	}
2817 
2818 #ifdef BCE_USE_SPLIT_HEADER
2819 	/* Unload and destroy the page mbuf maps. */
2820 	for (i = 0; i < TOTAL_PG_BD; i++) {
2821 		if (sc->pg_mbuf_map[i] != NULL) {
2822 			bus_dmamap_unload(sc->pg_mbuf_tag,
2823 				sc->pg_mbuf_map[i]);
2824 			bus_dmamap_destroy(sc->pg_mbuf_tag,
2825 	 			sc->pg_mbuf_map[i]);
2826 			sc->pg_mbuf_map[i] = NULL;
2827 		}
2828 	}
2829 
2830 	/* Destroy the page mbuf tag. */
2831 	if (sc->pg_mbuf_tag != NULL) {
2832 		bus_dma_tag_destroy(sc->pg_mbuf_tag);
2833 		sc->pg_mbuf_tag = NULL;
2834 	}
2835 #endif
2836 
2837 	/* Destroy the parent tag */
2838 	if (sc->parent_tag != NULL) {
2839 		bus_dma_tag_destroy(sc->parent_tag);
2840 		sc->parent_tag = NULL;
2841 	}
2842 
2843 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
2844 }
2845 
2846 
2847 /****************************************************************************/
2848 /* Get DMA memory from the OS.                                              */
2849 /*                                                                          */
2850 /* Validates that the OS has provided DMA buffers in response to a          */
2851 /* bus_dmamap_load() call and saves the physical address of those buffers.  */
2852 /* When the callback is used the OS will return 0 for the mapping function  */
2853 /* (bus_dmamap_load()) so we use the value of map_arg->maxsegs to pass any  */
2854 /* failures back to the caller.                                             */
2855 /*                                                                          */
2856 /* Returns:                                                                 */
2857 /*   Nothing.                                                               */
2858 /****************************************************************************/
2859 static void
2860 bce_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
2861 {
2862 	bus_addr_t *busaddr = arg;
2863 
2864 	/* Simulate a mapping failure. */
2865 	DBRUNIF(DB_RANDOMTRUE(bce_debug_dma_map_addr_failure),
2866 		printf("bce: %s(%d): Simulating DMA mapping error.\n",
2867 			__FILE__, __LINE__);
2868 		error = ENOMEM);
2869 
2870 	/* Check for an error and signal the caller that an error occurred. */
2871 	if (error) {
2872 		printf("bce %s(%d): DMA mapping error! error = %d, "
2873 		    "nseg = %d\n", __FILE__, __LINE__, error, nseg);
2874 		*busaddr = 0;
2875 		return;
2876 	}
2877 
2878 	*busaddr = segs->ds_addr;
2879 	return;
2880 }
2881 
2882 
2883 /****************************************************************************/
2884 /* Allocate any DMA memory needed by the driver.                            */
2885 /*                                                                          */
2886 /* Allocates DMA memory needed for the various global structures needed by  */
2887 /* hardware.                                                                */
2888 /*                                                                          */
2889 /* Memory alignment requirements:                                           */
2890 /* +-----------------+----------+----------+----------+----------+          */
2891 /* |                 |   5706   |   5708   |   5709   |   5716   |          */
2892 /* +-----------------+----------+----------+----------+----------+          */
2893 /* |Status Block     | 8 bytes  | 8 bytes  | 16 bytes | 16 bytes |          */
2894 /* |Statistics Block | 8 bytes  | 8 bytes  | 16 bytes | 16 bytes |          */
2895 /* |RX Buffers       | 16 bytes | 16 bytes | 16 bytes | 16 bytes |          */
2896 /* |PG Buffers       |   none   |   none   |   none   |   none   |          */
2897 /* |TX Buffers       |   none   |   none   |   none   |   none   |          */
2898 /* |Chain Pages(1)   |   4KiB   |   4KiB   |   4KiB   |   4KiB   |          */
2899 /* +-----------------+----------+----------+----------+----------+          */
2900 /*                                                                          */
2901 /* (1) Must align with CPU page size (BCM_PAGE_SZIE).                       */
2902 /*                                                                          */
2903 /* Returns:                                                                 */
2904 /*   0 for success, positive value for failure.                             */
2905 /****************************************************************************/
2906 static int
2907 bce_dma_alloc(device_t dev)
2908 {
2909 	struct bce_softc *sc;
2910 	int i, error, rc = 0;
2911 	bus_size_t max_size, max_seg_size;
2912 	int max_segments;
2913 
2914 	sc = device_get_softc(dev);
2915 
2916 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
2917 
2918 	/*
2919 	 * Allocate the parent bus DMA tag appropriate for PCI.
2920 	 */
2921 	if (bus_dma_tag_create(NULL,
2922 			1,
2923 			BCE_DMA_BOUNDARY,
2924 			sc->max_bus_addr,
2925 			BUS_SPACE_MAXADDR,
2926 			NULL, NULL,
2927 			MAXBSIZE,
2928 			BUS_SPACE_UNRESTRICTED,
2929 			BUS_SPACE_MAXSIZE_32BIT,
2930 			0,
2931 			NULL, NULL,
2932 			&sc->parent_tag)) {
2933 		BCE_PRINTF("%s(%d): Could not allocate parent DMA tag!\n",
2934 			__FILE__, __LINE__);
2935 		rc = ENOMEM;
2936 		goto bce_dma_alloc_exit;
2937 	}
2938 
2939 	/*
2940 	 * Create a DMA tag for the status block, allocate and clear the
2941 	 * memory, map the memory into DMA space, and fetch the physical
2942 	 * address of the block.
2943 	 */
2944 	if (bus_dma_tag_create(sc->parent_tag,
2945 	    	BCE_DMA_ALIGN,
2946 	    	BCE_DMA_BOUNDARY,
2947 	    	sc->max_bus_addr,
2948 	    	BUS_SPACE_MAXADDR,
2949 	    	NULL, NULL,
2950 	    	BCE_STATUS_BLK_SZ,
2951 	    	1,
2952 	    	BCE_STATUS_BLK_SZ,
2953 	    	0,
2954 	    	NULL, NULL,
2955 	    	&sc->status_tag)) {
2956 		BCE_PRINTF("%s(%d): Could not allocate status block DMA tag!\n",
2957 			__FILE__, __LINE__);
2958 		rc = ENOMEM;
2959 		goto bce_dma_alloc_exit;
2960 	}
2961 
2962 	if(bus_dmamem_alloc(sc->status_tag,
2963 	    	(void **)&sc->status_block,
2964 	    	BUS_DMA_NOWAIT,
2965 	    	&sc->status_map)) {
2966 		BCE_PRINTF("%s(%d): Could not allocate status block DMA memory!\n",
2967 			__FILE__, __LINE__);
2968 		rc = ENOMEM;
2969 		goto bce_dma_alloc_exit;
2970 	}
2971 
2972 	bzero((char *)sc->status_block, BCE_STATUS_BLK_SZ);
2973 
2974 	error = bus_dmamap_load(sc->status_tag,
2975 	    	sc->status_map,
2976 	    	sc->status_block,
2977 	    	BCE_STATUS_BLK_SZ,
2978 	    	bce_dma_map_addr,
2979 	    	&sc->status_block_paddr,
2980 	    	BUS_DMA_NOWAIT);
2981 
2982 	if (error) {
2983 		BCE_PRINTF("%s(%d): Could not map status block DMA memory!\n",
2984 			__FILE__, __LINE__);
2985 		rc = ENOMEM;
2986 		goto bce_dma_alloc_exit;
2987 	}
2988 
2989 	DBPRINT(sc, BCE_INFO, "%s(): status_block_paddr = 0x%jX\n",
2990 		__FUNCTION__, (uintmax_t) sc->status_block_paddr);
2991 
2992 	/*
2993 	 * Create a DMA tag for the statistics block, allocate and clear the
2994 	 * memory, map the memory into DMA space, and fetch the physical
2995 	 * address of the block.
2996 	 */
2997 	if (bus_dma_tag_create(sc->parent_tag,
2998 	    	BCE_DMA_ALIGN,
2999 	    	BCE_DMA_BOUNDARY,
3000 	    	sc->max_bus_addr,
3001 	    	BUS_SPACE_MAXADDR,
3002 	    	NULL, NULL,
3003 	    	BCE_STATS_BLK_SZ,
3004 	    	1,
3005 	    	BCE_STATS_BLK_SZ,
3006 	    	0,
3007 	    	NULL, NULL,
3008 	    	&sc->stats_tag)) {
3009 		BCE_PRINTF("%s(%d): Could not allocate statistics block DMA tag!\n",
3010 			__FILE__, __LINE__);
3011 		rc = ENOMEM;
3012 		goto bce_dma_alloc_exit;
3013 	}
3014 
3015 	if (bus_dmamem_alloc(sc->stats_tag,
3016 	    	(void **)&sc->stats_block,
3017 	    	BUS_DMA_NOWAIT,
3018 	    	&sc->stats_map)) {
3019 		BCE_PRINTF("%s(%d): Could not allocate statistics block DMA memory!\n",
3020 			__FILE__, __LINE__);
3021 		rc = ENOMEM;
3022 		goto bce_dma_alloc_exit;
3023 	}
3024 
3025 	bzero((char *)sc->stats_block, BCE_STATS_BLK_SZ);
3026 
3027 	error = bus_dmamap_load(sc->stats_tag,
3028 	    	sc->stats_map,
3029 	    	sc->stats_block,
3030 	    	BCE_STATS_BLK_SZ,
3031 	    	bce_dma_map_addr,
3032 	    	&sc->stats_block_paddr,
3033 	    	BUS_DMA_NOWAIT);
3034 
3035 	if(error) {
3036 		BCE_PRINTF("%s(%d): Could not map statistics block DMA memory!\n",
3037 			__FILE__, __LINE__);
3038 		rc = ENOMEM;
3039 		goto bce_dma_alloc_exit;
3040 	}
3041 
3042 	DBPRINT(sc, BCE_INFO, "%s(): stats_block_paddr = 0x%jX\n",
3043 		__FUNCTION__, (uintmax_t) sc->stats_block_paddr);
3044 
3045 	/* BCM5709 uses host memory as cache for context memory. */
3046 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3047 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3048 		sc->ctx_pages = 0x2000 / BCM_PAGE_SIZE;
3049 		if (sc->ctx_pages == 0)
3050 			sc->ctx_pages = 1;
3051 
3052 		DBRUNIF((sc->ctx_pages > 512),
3053 			BCE_PRINTF("%s(%d): Too many CTX pages! %d > 512\n",
3054 				__FILE__, __LINE__, sc->ctx_pages));
3055 
3056 		/*
3057 		 * Create a DMA tag for the context pages,
3058 		 * allocate and clear the memory, map the
3059 		 * memory into DMA space, and fetch the
3060 		 * physical address of the block.
3061 		 */
3062 		if(bus_dma_tag_create(sc->parent_tag,
3063 			BCM_PAGE_SIZE,
3064 		    BCE_DMA_BOUNDARY,
3065 			sc->max_bus_addr,
3066 			BUS_SPACE_MAXADDR,
3067 			NULL, NULL,
3068 			BCM_PAGE_SIZE,
3069 			1,
3070 			BCM_PAGE_SIZE,
3071 			0,
3072 			NULL, NULL,
3073 			&sc->ctx_tag)) {
3074 			BCE_PRINTF("%s(%d): Could not allocate CTX DMA tag!\n",
3075 				__FILE__, __LINE__);
3076 			rc = ENOMEM;
3077 			goto bce_dma_alloc_exit;
3078 		}
3079 
3080 		for (i = 0; i < sc->ctx_pages; i++) {
3081 
3082 			if(bus_dmamem_alloc(sc->ctx_tag,
3083 		    		(void **)&sc->ctx_block[i],
3084 	    		BUS_DMA_NOWAIT,
3085 		    	&sc->ctx_map[i])) {
3086 				BCE_PRINTF("%s(%d): Could not allocate CTX "
3087 					"DMA memory!\n", __FILE__, __LINE__);
3088 				rc = ENOMEM;
3089 				goto bce_dma_alloc_exit;
3090 			}
3091 
3092 			bzero((char *)sc->ctx_block[i], BCM_PAGE_SIZE);
3093 
3094 			error = bus_dmamap_load(sc->ctx_tag,
3095 	    		sc->ctx_map[i],
3096 	    		sc->ctx_block[i],
3097 		    	BCM_PAGE_SIZE,
3098 		    	bce_dma_map_addr,
3099 	    		&sc->ctx_paddr[i],
3100 	    		BUS_DMA_NOWAIT);
3101 
3102 			if (error) {
3103 				BCE_PRINTF("%s(%d): Could not map CTX DMA memory!\n",
3104 					__FILE__, __LINE__);
3105 				rc = ENOMEM;
3106 				goto bce_dma_alloc_exit;
3107 			}
3108 
3109 			DBPRINT(sc, BCE_INFO, "%s(): ctx_paddr[%d] = 0x%jX\n",
3110 				__FUNCTION__, i, (uintmax_t) sc->ctx_paddr[i]);
3111 		}
3112 	}
3113 
3114 	/*
3115 	 * Create a DMA tag for the TX buffer descriptor chain,
3116 	 * allocate and clear the  memory, and fetch the
3117 	 * physical address of the block.
3118 	 */
3119 	if(bus_dma_tag_create(sc->parent_tag,
3120 			BCM_PAGE_SIZE,
3121 		    BCE_DMA_BOUNDARY,
3122 			sc->max_bus_addr,
3123 			BUS_SPACE_MAXADDR,
3124 			NULL, NULL,
3125 			BCE_TX_CHAIN_PAGE_SZ,
3126 			1,
3127 			BCE_TX_CHAIN_PAGE_SZ,
3128 			0,
3129 			NULL, NULL,
3130 			&sc->tx_bd_chain_tag)) {
3131 		BCE_PRINTF("%s(%d): Could not allocate TX descriptor chain DMA tag!\n",
3132 			__FILE__, __LINE__);
3133 		rc = ENOMEM;
3134 		goto bce_dma_alloc_exit;
3135 	}
3136 
3137 	for (i = 0; i < TX_PAGES; i++) {
3138 
3139 		if(bus_dmamem_alloc(sc->tx_bd_chain_tag,
3140 	    		(void **)&sc->tx_bd_chain[i],
3141 	    		BUS_DMA_NOWAIT,
3142 		    	&sc->tx_bd_chain_map[i])) {
3143 			BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
3144 				"chain DMA memory!\n", __FILE__, __LINE__);
3145 			rc = ENOMEM;
3146 			goto bce_dma_alloc_exit;
3147 		}
3148 
3149 		error = bus_dmamap_load(sc->tx_bd_chain_tag,
3150 	    		sc->tx_bd_chain_map[i],
3151 	    		sc->tx_bd_chain[i],
3152 		    	BCE_TX_CHAIN_PAGE_SZ,
3153 		    	bce_dma_map_addr,
3154 	    		&sc->tx_bd_chain_paddr[i],
3155 	    		BUS_DMA_NOWAIT);
3156 
3157 		if (error) {
3158 			BCE_PRINTF("%s(%d): Could not map TX descriptor chain DMA memory!\n",
3159 				__FILE__, __LINE__);
3160 			rc = ENOMEM;
3161 			goto bce_dma_alloc_exit;
3162 		}
3163 
3164 		DBPRINT(sc, BCE_INFO, "%s(): tx_bd_chain_paddr[%d] = 0x%jX\n",
3165 			__FUNCTION__, i, (uintmax_t) sc->tx_bd_chain_paddr[i]);
3166 	}
3167 
3168 	/* Check the required size before mapping to conserve resources. */
3169 	if (bce_tso_enable) {
3170 		max_size     = BCE_TSO_MAX_SIZE;
3171 		max_segments = BCE_MAX_SEGMENTS;
3172 		max_seg_size = BCE_TSO_MAX_SEG_SIZE;
3173 	} else {
3174 		max_size     = MCLBYTES * BCE_MAX_SEGMENTS;
3175 		max_segments = BCE_MAX_SEGMENTS;
3176 		max_seg_size = MCLBYTES;
3177 	}
3178 
3179 	/* Create a DMA tag for TX mbufs. */
3180 	if (bus_dma_tag_create(sc->parent_tag,
3181 			1,
3182 			BCE_DMA_BOUNDARY,
3183 			sc->max_bus_addr,
3184 			BUS_SPACE_MAXADDR,
3185 			NULL, NULL,
3186 			max_size,
3187 			max_segments,
3188 			max_seg_size,
3189 			0,
3190 			NULL, NULL,
3191 			&sc->tx_mbuf_tag)) {
3192 		BCE_PRINTF("%s(%d): Could not allocate TX mbuf DMA tag!\n",
3193 			__FILE__, __LINE__);
3194 		rc = ENOMEM;
3195 		goto bce_dma_alloc_exit;
3196 	}
3197 
3198 	/* Create DMA maps for the TX mbufs clusters. */
3199 	for (i = 0; i < TOTAL_TX_BD; i++) {
3200 		if (bus_dmamap_create(sc->tx_mbuf_tag, BUS_DMA_NOWAIT,
3201 			&sc->tx_mbuf_map[i])) {
3202 			BCE_PRINTF("%s(%d): Unable to create TX mbuf DMA map!\n",
3203 				__FILE__, __LINE__);
3204 			rc = ENOMEM;
3205 			goto bce_dma_alloc_exit;
3206 		}
3207 	}
3208 
3209 	/*
3210 	 * Create a DMA tag for the RX buffer descriptor chain,
3211 	 * allocate and clear the memory, and fetch the physical
3212 	 * address of the blocks.
3213 	 */
3214 	if (bus_dma_tag_create(sc->parent_tag,
3215 			BCM_PAGE_SIZE,
3216 			BCE_DMA_BOUNDARY,
3217 			BUS_SPACE_MAXADDR,
3218 			sc->max_bus_addr,
3219 			NULL, NULL,
3220 			BCE_RX_CHAIN_PAGE_SZ,
3221 			1,
3222 			BCE_RX_CHAIN_PAGE_SZ,
3223 			0,
3224 			NULL, NULL,
3225 			&sc->rx_bd_chain_tag)) {
3226 		BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain DMA tag!\n",
3227 			__FILE__, __LINE__);
3228 		rc = ENOMEM;
3229 		goto bce_dma_alloc_exit;
3230 	}
3231 
3232 	for (i = 0; i < RX_PAGES; i++) {
3233 
3234 		if (bus_dmamem_alloc(sc->rx_bd_chain_tag,
3235 	    		(void **)&sc->rx_bd_chain[i],
3236 	    		BUS_DMA_NOWAIT,
3237 		    	&sc->rx_bd_chain_map[i])) {
3238 			BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain "
3239 				"DMA memory!\n", __FILE__, __LINE__);
3240 			rc = ENOMEM;
3241 			goto bce_dma_alloc_exit;
3242 		}
3243 
3244 		bzero((char *)sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ);
3245 
3246 		error = bus_dmamap_load(sc->rx_bd_chain_tag,
3247 	    		sc->rx_bd_chain_map[i],
3248 	    		sc->rx_bd_chain[i],
3249 		    	BCE_RX_CHAIN_PAGE_SZ,
3250 		    	bce_dma_map_addr,
3251 	    		&sc->rx_bd_chain_paddr[i],
3252 	    		BUS_DMA_NOWAIT);
3253 
3254 		if (error) {
3255 			BCE_PRINTF("%s(%d): Could not map RX descriptor chain DMA memory!\n",
3256 				__FILE__, __LINE__);
3257 			rc = ENOMEM;
3258 			goto bce_dma_alloc_exit;
3259 		}
3260 
3261 		DBPRINT(sc, BCE_INFO, "%s(): rx_bd_chain_paddr[%d] = 0x%jX\n",
3262 			__FUNCTION__, i, (uintmax_t) sc->rx_bd_chain_paddr[i]);
3263 	}
3264 
3265 	/*
3266 	 * Create a DMA tag for RX mbufs.
3267 	 */
3268 #ifdef BCE_USE_SPLIT_HEADER
3269 	max_size = max_seg_size = ((sc->rx_bd_mbuf_alloc_size < MCLBYTES) ?
3270 		MCLBYTES : sc->rx_bd_mbuf_alloc_size);
3271 #else
3272 	max_size = max_seg_size = MJUM9BYTES;
3273 #endif
3274 
3275 	if (bus_dma_tag_create(sc->parent_tag,
3276 			1,
3277 			BCE_DMA_BOUNDARY,
3278 			sc->max_bus_addr,
3279 			BUS_SPACE_MAXADDR,
3280 			NULL, NULL,
3281 			max_size,
3282 			1,
3283 			max_seg_size,
3284 			0,
3285 			NULL, NULL,
3286 	    	&sc->rx_mbuf_tag)) {
3287 		BCE_PRINTF("%s(%d): Could not allocate RX mbuf DMA tag!\n",
3288 			__FILE__, __LINE__);
3289 		rc = ENOMEM;
3290 		goto bce_dma_alloc_exit;
3291 	}
3292 
3293 	/* Create DMA maps for the RX mbuf clusters. */
3294 	for (i = 0; i < TOTAL_RX_BD; i++) {
3295 		if (bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_NOWAIT,
3296 				&sc->rx_mbuf_map[i])) {
3297 			BCE_PRINTF("%s(%d): Unable to create RX mbuf DMA map!\n",
3298 				__FILE__, __LINE__);
3299 			rc = ENOMEM;
3300 			goto bce_dma_alloc_exit;
3301 		}
3302 	}
3303 
3304 #ifdef BCE_USE_SPLIT_HEADER
3305 	/*
3306 	 * Create a DMA tag for the page buffer descriptor chain,
3307 	 * allocate and clear the memory, and fetch the physical
3308 	 * address of the blocks.
3309 	 */
3310 	if (bus_dma_tag_create(sc->parent_tag,
3311 			BCM_PAGE_SIZE,
3312 			BCE_DMA_BOUNDARY,
3313 			BUS_SPACE_MAXADDR,
3314 			sc->max_bus_addr,
3315 			NULL, NULL,
3316 			BCE_PG_CHAIN_PAGE_SZ,
3317 			1,
3318 			BCE_PG_CHAIN_PAGE_SZ,
3319 			0,
3320 			NULL, NULL,
3321 			&sc->pg_bd_chain_tag)) {
3322 		BCE_PRINTF("%s(%d): Could not allocate page descriptor chain DMA tag!\n",
3323 			__FILE__, __LINE__);
3324 		rc = ENOMEM;
3325 		goto bce_dma_alloc_exit;
3326 	}
3327 
3328 	for (i = 0; i < PG_PAGES; i++) {
3329 
3330 		if (bus_dmamem_alloc(sc->pg_bd_chain_tag,
3331 	    		(void **)&sc->pg_bd_chain[i],
3332 	    		BUS_DMA_NOWAIT,
3333 		    	&sc->pg_bd_chain_map[i])) {
3334 			BCE_PRINTF("%s(%d): Could not allocate page descriptor chain "
3335 				"DMA memory!\n", __FILE__, __LINE__);
3336 			rc = ENOMEM;
3337 			goto bce_dma_alloc_exit;
3338 		}
3339 
3340 		bzero((char *)sc->pg_bd_chain[i], BCE_PG_CHAIN_PAGE_SZ);
3341 
3342 		error = bus_dmamap_load(sc->pg_bd_chain_tag,
3343 	    		sc->pg_bd_chain_map[i],
3344 	    		sc->pg_bd_chain[i],
3345 		    	BCE_PG_CHAIN_PAGE_SZ,
3346 		    	bce_dma_map_addr,
3347 	    		&sc->pg_bd_chain_paddr[i],
3348 	    		BUS_DMA_NOWAIT);
3349 
3350 		if (error) {
3351 			BCE_PRINTF("%s(%d): Could not map page descriptor chain DMA memory!\n",
3352 				__FILE__, __LINE__);
3353 			rc = ENOMEM;
3354 			goto bce_dma_alloc_exit;
3355 		}
3356 
3357 		DBPRINT(sc, BCE_INFO, "%s(): pg_bd_chain_paddr[%d] = 0x%jX\n",
3358 			__FUNCTION__, i, (uintmax_t) sc->pg_bd_chain_paddr[i]);
3359 	}
3360 
3361 	/*
3362 	 * Create a DMA tag for page mbufs.
3363 	 */
3364 	max_size = max_seg_size = ((sc->pg_bd_mbuf_alloc_size < MCLBYTES) ?
3365 		MCLBYTES : sc->pg_bd_mbuf_alloc_size);
3366 
3367 	if (bus_dma_tag_create(sc->parent_tag,
3368 			1,
3369 			BCE_DMA_BOUNDARY,
3370 			sc->max_bus_addr,
3371 			BUS_SPACE_MAXADDR,
3372 			NULL, NULL,
3373 			max_size,
3374 			1,
3375 			max_seg_size,
3376 			0,
3377 			NULL, NULL,
3378 	    	&sc->pg_mbuf_tag)) {
3379 		BCE_PRINTF("%s(%d): Could not allocate page mbuf DMA tag!\n",
3380 			__FILE__, __LINE__);
3381 		rc = ENOMEM;
3382 		goto bce_dma_alloc_exit;
3383 	}
3384 
3385 	/* Create DMA maps for the page mbuf clusters. */
3386 	for (i = 0; i < TOTAL_PG_BD; i++) {
3387 		if (bus_dmamap_create(sc->pg_mbuf_tag, BUS_DMA_NOWAIT,
3388 				&sc->pg_mbuf_map[i])) {
3389 			BCE_PRINTF("%s(%d): Unable to create page mbuf DMA map!\n",
3390 				__FILE__, __LINE__);
3391 			rc = ENOMEM;
3392 			goto bce_dma_alloc_exit;
3393 		}
3394 	}
3395 #endif
3396 
3397 bce_dma_alloc_exit:
3398 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
3399 	return(rc);
3400 }
3401 
3402 
3403 /****************************************************************************/
3404 /* Release all resources used by the driver.                                */
3405 /*                                                                          */
3406 /* Releases all resources acquired by the driver including interrupts,      */
3407 /* interrupt handler, interfaces, mutexes, and DMA memory.                  */
3408 /*                                                                          */
3409 /* Returns:                                                                 */
3410 /*   Nothing.                                                               */
3411 /****************************************************************************/
3412 static void
3413 bce_release_resources(struct bce_softc *sc)
3414 {
3415 	device_t dev;
3416 
3417 	DBENTER(BCE_VERBOSE_RESET);
3418 
3419 	dev = sc->bce_dev;
3420 
3421 	bce_dma_free(sc);
3422 
3423 	if (sc->bce_intrhand != NULL) {
3424 		DBPRINT(sc, BCE_INFO_RESET, "Removing interrupt handler.\n");
3425 		bus_teardown_intr(dev, sc->bce_res_irq, sc->bce_intrhand);
3426 	}
3427 
3428 	if (sc->bce_res_irq != NULL) {
3429 		DBPRINT(sc, BCE_INFO_RESET, "Releasing IRQ.\n");
3430 		bus_release_resource(dev, SYS_RES_IRQ, sc->bce_irq_rid,
3431 			sc->bce_res_irq);
3432 	}
3433 
3434 	if (sc->bce_flags & (BCE_USING_MSI_FLAG | BCE_USING_MSIX_FLAG)) {
3435 		DBPRINT(sc, BCE_INFO_RESET, "Releasing MSI/MSI-X vector.\n");
3436 		pci_release_msi(dev);
3437 	}
3438 
3439 	if (sc->bce_res_mem != NULL) {
3440 		DBPRINT(sc, BCE_INFO_RESET, "Releasing PCI memory.\n");
3441 		bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), sc->bce_res_mem);
3442 	}
3443 
3444 	if (sc->bce_ifp != NULL) {
3445 		DBPRINT(sc, BCE_INFO_RESET, "Releasing IF.\n");
3446 		if_free(sc->bce_ifp);
3447 	}
3448 
3449 	if (mtx_initialized(&sc->bce_mtx))
3450 		BCE_LOCK_DESTROY(sc);
3451 
3452 	DBEXIT(BCE_VERBOSE_RESET);
3453 }
3454 
3455 
3456 /****************************************************************************/
3457 /* Firmware synchronization.                                                */
3458 /*                                                                          */
3459 /* Before performing certain events such as a chip reset, synchronize with  */
3460 /* the firmware first.                                                      */
3461 /*                                                                          */
3462 /* Returns:                                                                 */
3463 /*   0 for success, positive value for failure.                             */
3464 /****************************************************************************/
3465 static int
3466 bce_fw_sync(struct bce_softc *sc, u32 msg_data)
3467 {
3468 	int i, rc = 0;
3469 	u32 val;
3470 
3471 	DBENTER(BCE_VERBOSE_RESET);
3472 
3473 	/* Don't waste any time if we've timed out before. */
3474 	if (sc->bce_fw_timed_out) {
3475 		rc = EBUSY;
3476 		goto bce_fw_sync_exit;
3477 	}
3478 
3479 	/* Increment the message sequence number. */
3480 	sc->bce_fw_wr_seq++;
3481 	msg_data |= sc->bce_fw_wr_seq;
3482 
3483  	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "bce_fw_sync(): msg_data = 0x%08X\n",
3484  		msg_data);
3485 
3486 	/* Send the message to the bootcode driver mailbox. */
3487 	REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_MB, msg_data);
3488 
3489 	/* Wait for the bootcode to acknowledge the message. */
3490 	for (i = 0; i < FW_ACK_TIME_OUT_MS; i++) {
3491 		/* Check for a response in the bootcode firmware mailbox. */
3492 		val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_FW_MB);
3493 		if ((val & BCE_FW_MSG_ACK) == (msg_data & BCE_DRV_MSG_SEQ))
3494 			break;
3495 		DELAY(1000);
3496 	}
3497 
3498 	/* If we've timed out, tell the bootcode that we've stopped waiting. */
3499 	if (((val & BCE_FW_MSG_ACK) != (msg_data & BCE_DRV_MSG_SEQ)) &&
3500 		((msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0)) {
3501 
3502 		BCE_PRINTF("%s(%d): Firmware synchronization timeout! "
3503 			"msg_data = 0x%08X\n",
3504 			__FILE__, __LINE__, msg_data);
3505 
3506 		msg_data &= ~BCE_DRV_MSG_CODE;
3507 		msg_data |= BCE_DRV_MSG_CODE_FW_TIMEOUT;
3508 
3509 		REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_MB, msg_data);
3510 
3511 		sc->bce_fw_timed_out = 1;
3512 		rc = EBUSY;
3513 	}
3514 
3515 bce_fw_sync_exit:
3516 	DBEXIT(BCE_VERBOSE_RESET);
3517 	return (rc);
3518 }
3519 
3520 
3521 /****************************************************************************/
3522 /* Load Receive Virtual 2 Physical (RV2P) processor firmware.               */
3523 /*                                                                          */
3524 /* Returns:                                                                 */
3525 /*   Nothing.                                                               */
3526 /****************************************************************************/
3527 static void
3528 bce_load_rv2p_fw(struct bce_softc *sc, u32 *rv2p_code,
3529 	u32 rv2p_code_len, u32 rv2p_proc)
3530 {
3531 	int i;
3532 	u32 val;
3533 
3534 	DBENTER(BCE_VERBOSE_RESET);
3535 
3536 	/* Set the page size used by RV2P. */
3537 	if (rv2p_proc == RV2P_PROC2) {
3538 		BCE_RV2P_PROC2_CHG_MAX_BD_PAGE(USABLE_RX_BD_PER_PAGE);
3539 	}
3540 
3541 	for (i = 0; i < rv2p_code_len; i += 8) {
3542 		REG_WR(sc, BCE_RV2P_INSTR_HIGH, *rv2p_code);
3543 		rv2p_code++;
3544 		REG_WR(sc, BCE_RV2P_INSTR_LOW, *rv2p_code);
3545 		rv2p_code++;
3546 
3547 		if (rv2p_proc == RV2P_PROC1) {
3548 			val = (i / 8) | BCE_RV2P_PROC1_ADDR_CMD_RDWR;
3549 			REG_WR(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
3550 		}
3551 		else {
3552 			val = (i / 8) | BCE_RV2P_PROC2_ADDR_CMD_RDWR;
3553 			REG_WR(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
3554 		}
3555 	}
3556 
3557 	/* Reset the processor, un-stall is done later. */
3558 	if (rv2p_proc == RV2P_PROC1) {
3559 		REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC1_RESET);
3560 	}
3561 	else {
3562 		REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC2_RESET);
3563 	}
3564 
3565 	DBEXIT(BCE_VERBOSE_RESET);
3566 }
3567 
3568 
3569 /****************************************************************************/
3570 /* Load RISC processor firmware.                                            */
3571 /*                                                                          */
3572 /* Loads firmware from the file if_bcefw.h into the scratchpad memory       */
3573 /* associated with a particular processor.                                  */
3574 /*                                                                          */
3575 /* Returns:                                                                 */
3576 /*   Nothing.                                                               */
3577 /****************************************************************************/
3578 static void
3579 bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
3580 	struct fw_info *fw)
3581 {
3582 	u32 offset;
3583 	u32 val;
3584 
3585 	DBENTER(BCE_VERBOSE_RESET);
3586 
3587 	/* Halt the CPU. */
3588 	val = REG_RD_IND(sc, cpu_reg->mode);
3589 	val |= cpu_reg->mode_value_halt;
3590 	REG_WR_IND(sc, cpu_reg->mode, val);
3591 	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
3592 
3593 	/* Load the Text area. */
3594 	offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
3595 	if (fw->text) {
3596 		int j;
3597 
3598 		for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
3599 			REG_WR_IND(sc, offset, fw->text[j]);
3600 	        }
3601 	}
3602 
3603 	/* Load the Data area. */
3604 	offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
3605 	if (fw->data) {
3606 		int j;
3607 
3608 		for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
3609 			REG_WR_IND(sc, offset, fw->data[j]);
3610 		}
3611 	}
3612 
3613 	/* Load the SBSS area. */
3614 	offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
3615 	if (fw->sbss) {
3616 		int j;
3617 
3618 		for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
3619 			REG_WR_IND(sc, offset, fw->sbss[j]);
3620 		}
3621 	}
3622 
3623 	/* Load the BSS area. */
3624 	offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
3625 	if (fw->bss) {
3626 		int j;
3627 
3628 		for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
3629 			REG_WR_IND(sc, offset, fw->bss[j]);
3630 		}
3631 	}
3632 
3633 	/* Load the Read-Only area. */
3634 	offset = cpu_reg->spad_base +
3635 		(fw->rodata_addr - cpu_reg->mips_view_base);
3636 	if (fw->rodata) {
3637 		int j;
3638 
3639 		for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
3640 			REG_WR_IND(sc, offset, fw->rodata[j]);
3641 		}
3642 	}
3643 
3644 	/* Clear the pre-fetch instruction. */
3645 	REG_WR_IND(sc, cpu_reg->inst, 0);
3646 	REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
3647 
3648 	/* Start the CPU. */
3649 	val = REG_RD_IND(sc, cpu_reg->mode);
3650 	val &= ~cpu_reg->mode_value_halt;
3651 	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
3652 	REG_WR_IND(sc, cpu_reg->mode, val);
3653 
3654 	DBEXIT(BCE_VERBOSE_RESET);
3655 }
3656 
3657 
3658 /****************************************************************************/
3659 /* Initialize the RX CPU.                                                   */
3660 /*                                                                          */
3661 /* Returns:                                                                 */
3662 /*   Nothing.                                                               */
3663 /****************************************************************************/
3664 static void
3665 bce_init_rxp_cpu(struct bce_softc *sc)
3666 {
3667 	struct cpu_reg cpu_reg;
3668 	struct fw_info fw;
3669 
3670 	DBENTER(BCE_VERBOSE_RESET);
3671 
3672 	cpu_reg.mode = BCE_RXP_CPU_MODE;
3673 	cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
3674 	cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
3675 	cpu_reg.state = BCE_RXP_CPU_STATE;
3676 	cpu_reg.state_value_clear = 0xffffff;
3677 	cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
3678 	cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
3679 	cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
3680 	cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
3681 	cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
3682 	cpu_reg.spad_base = BCE_RXP_SCRATCH;
3683 	cpu_reg.mips_view_base = 0x8000000;
3684 
3685 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3686 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3687  		fw.ver_major = bce_RXP_b09FwReleaseMajor;
3688 		fw.ver_minor = bce_RXP_b09FwReleaseMinor;
3689 		fw.ver_fix = bce_RXP_b09FwReleaseFix;
3690 		fw.start_addr = bce_RXP_b09FwStartAddr;
3691 
3692 		fw.text_addr = bce_RXP_b09FwTextAddr;
3693 		fw.text_len = bce_RXP_b09FwTextLen;
3694 		fw.text_index = 0;
3695 		fw.text = bce_RXP_b09FwText;
3696 
3697 		fw.data_addr = bce_RXP_b09FwDataAddr;
3698 		fw.data_len = bce_RXP_b09FwDataLen;
3699 		fw.data_index = 0;
3700 		fw.data = bce_RXP_b09FwData;
3701 
3702 		fw.sbss_addr = bce_RXP_b09FwSbssAddr;
3703 		fw.sbss_len = bce_RXP_b09FwSbssLen;
3704 		fw.sbss_index = 0;
3705 		fw.sbss = bce_RXP_b09FwSbss;
3706 
3707 		fw.bss_addr = bce_RXP_b09FwBssAddr;
3708 		fw.bss_len = bce_RXP_b09FwBssLen;
3709 		fw.bss_index = 0;
3710 		fw.bss = bce_RXP_b09FwBss;
3711 
3712 		fw.rodata_addr = bce_RXP_b09FwRodataAddr;
3713 		fw.rodata_len = bce_RXP_b09FwRodataLen;
3714 		fw.rodata_index = 0;
3715 		fw.rodata = bce_RXP_b09FwRodata;
3716 	} else {
3717 		fw.ver_major = bce_RXP_b06FwReleaseMajor;
3718 		fw.ver_minor = bce_RXP_b06FwReleaseMinor;
3719 		fw.ver_fix = bce_RXP_b06FwReleaseFix;
3720 		fw.start_addr = bce_RXP_b06FwStartAddr;
3721 
3722 		fw.text_addr = bce_RXP_b06FwTextAddr;
3723 		fw.text_len = bce_RXP_b06FwTextLen;
3724 		fw.text_index = 0;
3725 		fw.text = bce_RXP_b06FwText;
3726 
3727 		fw.data_addr = bce_RXP_b06FwDataAddr;
3728 		fw.data_len = bce_RXP_b06FwDataLen;
3729 		fw.data_index = 0;
3730 		fw.data = bce_RXP_b06FwData;
3731 
3732 		fw.sbss_addr = bce_RXP_b06FwSbssAddr;
3733 		fw.sbss_len = bce_RXP_b06FwSbssLen;
3734 		fw.sbss_index = 0;
3735 		fw.sbss = bce_RXP_b06FwSbss;
3736 
3737 		fw.bss_addr = bce_RXP_b06FwBssAddr;
3738 		fw.bss_len = bce_RXP_b06FwBssLen;
3739 		fw.bss_index = 0;
3740 		fw.bss = bce_RXP_b06FwBss;
3741 
3742 		fw.rodata_addr = bce_RXP_b06FwRodataAddr;
3743 		fw.rodata_len = bce_RXP_b06FwRodataLen;
3744 		fw.rodata_index = 0;
3745 		fw.rodata = bce_RXP_b06FwRodata;
3746 	}
3747 
3748 	DBPRINT(sc, BCE_INFO_RESET, "Loading RX firmware.\n");
3749 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
3750 
3751 	DBEXIT(BCE_VERBOSE_RESET);
3752 }
3753 
3754 
3755 /****************************************************************************/
3756 /* Initialize the TX CPU.                                                   */
3757 /*                                                                          */
3758 /* Returns:                                                                 */
3759 /*   Nothing.                                                               */
3760 /****************************************************************************/
3761 static void
3762 bce_init_txp_cpu(struct bce_softc *sc)
3763 {
3764 	struct cpu_reg cpu_reg;
3765 	struct fw_info fw;
3766 
3767 	DBENTER(BCE_VERBOSE_RESET);
3768 
3769 	cpu_reg.mode = BCE_TXP_CPU_MODE;
3770 	cpu_reg.mode_value_halt = BCE_TXP_CPU_MODE_SOFT_HALT;
3771 	cpu_reg.mode_value_sstep = BCE_TXP_CPU_MODE_STEP_ENA;
3772 	cpu_reg.state = BCE_TXP_CPU_STATE;
3773 	cpu_reg.state_value_clear = 0xffffff;
3774 	cpu_reg.gpr0 = BCE_TXP_CPU_REG_FILE;
3775 	cpu_reg.evmask = BCE_TXP_CPU_EVENT_MASK;
3776 	cpu_reg.pc = BCE_TXP_CPU_PROGRAM_COUNTER;
3777 	cpu_reg.inst = BCE_TXP_CPU_INSTRUCTION;
3778 	cpu_reg.bp = BCE_TXP_CPU_HW_BREAKPOINT;
3779 	cpu_reg.spad_base = BCE_TXP_SCRATCH;
3780 	cpu_reg.mips_view_base = 0x8000000;
3781 
3782 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3783 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3784 		fw.ver_major = bce_TXP_b09FwReleaseMajor;
3785 		fw.ver_minor = bce_TXP_b09FwReleaseMinor;
3786 		fw.ver_fix = bce_TXP_b09FwReleaseFix;
3787 		fw.start_addr = bce_TXP_b09FwStartAddr;
3788 
3789 		fw.text_addr = bce_TXP_b09FwTextAddr;
3790 		fw.text_len = bce_TXP_b09FwTextLen;
3791 		fw.text_index = 0;
3792 		fw.text = bce_TXP_b09FwText;
3793 
3794 		fw.data_addr = bce_TXP_b09FwDataAddr;
3795 		fw.data_len = bce_TXP_b09FwDataLen;
3796 		fw.data_index = 0;
3797 		fw.data = bce_TXP_b09FwData;
3798 
3799 		fw.sbss_addr = bce_TXP_b09FwSbssAddr;
3800 		fw.sbss_len = bce_TXP_b09FwSbssLen;
3801 		fw.sbss_index = 0;
3802 		fw.sbss = bce_TXP_b09FwSbss;
3803 
3804 		fw.bss_addr = bce_TXP_b09FwBssAddr;
3805 		fw.bss_len = bce_TXP_b09FwBssLen;
3806 		fw.bss_index = 0;
3807 		fw.bss = bce_TXP_b09FwBss;
3808 
3809 		fw.rodata_addr = bce_TXP_b09FwRodataAddr;
3810 		fw.rodata_len = bce_TXP_b09FwRodataLen;
3811 		fw.rodata_index = 0;
3812 		fw.rodata = bce_TXP_b09FwRodata;
3813 	} else {
3814 		fw.ver_major = bce_TXP_b06FwReleaseMajor;
3815 		fw.ver_minor = bce_TXP_b06FwReleaseMinor;
3816 		fw.ver_fix = bce_TXP_b06FwReleaseFix;
3817 		fw.start_addr = bce_TXP_b06FwStartAddr;
3818 
3819 		fw.text_addr = bce_TXP_b06FwTextAddr;
3820 		fw.text_len = bce_TXP_b06FwTextLen;
3821 		fw.text_index = 0;
3822 		fw.text = bce_TXP_b06FwText;
3823 
3824 		fw.data_addr = bce_TXP_b06FwDataAddr;
3825 		fw.data_len = bce_TXP_b06FwDataLen;
3826 		fw.data_index = 0;
3827 		fw.data = bce_TXP_b06FwData;
3828 
3829 		fw.sbss_addr = bce_TXP_b06FwSbssAddr;
3830 		fw.sbss_len = bce_TXP_b06FwSbssLen;
3831 		fw.sbss_index = 0;
3832 		fw.sbss = bce_TXP_b06FwSbss;
3833 
3834 		fw.bss_addr = bce_TXP_b06FwBssAddr;
3835 		fw.bss_len = bce_TXP_b06FwBssLen;
3836 		fw.bss_index = 0;
3837 		fw.bss = bce_TXP_b06FwBss;
3838 
3839 		fw.rodata_addr = bce_TXP_b06FwRodataAddr;
3840 		fw.rodata_len = bce_TXP_b06FwRodataLen;
3841 		fw.rodata_index = 0;
3842 		fw.rodata = bce_TXP_b06FwRodata;
3843 	}
3844 
3845 	DBPRINT(sc, BCE_INFO_RESET, "Loading TX firmware.\n");
3846 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
3847 
3848 	DBEXIT(BCE_VERBOSE_RESET);
3849 }
3850 
3851 
3852 /****************************************************************************/
3853 /* Initialize the TPAT CPU.                                                 */
3854 /*                                                                          */
3855 /* Returns:                                                                 */
3856 /*   Nothing.                                                               */
3857 /****************************************************************************/
3858 static void
3859 bce_init_tpat_cpu(struct bce_softc *sc)
3860 {
3861 	struct cpu_reg cpu_reg;
3862 	struct fw_info fw;
3863 
3864 	DBENTER(BCE_VERBOSE_RESET);
3865 
3866 	cpu_reg.mode = BCE_TPAT_CPU_MODE;
3867 	cpu_reg.mode_value_halt = BCE_TPAT_CPU_MODE_SOFT_HALT;
3868 	cpu_reg.mode_value_sstep = BCE_TPAT_CPU_MODE_STEP_ENA;
3869 	cpu_reg.state = BCE_TPAT_CPU_STATE;
3870 	cpu_reg.state_value_clear = 0xffffff;
3871 	cpu_reg.gpr0 = BCE_TPAT_CPU_REG_FILE;
3872 	cpu_reg.evmask = BCE_TPAT_CPU_EVENT_MASK;
3873 	cpu_reg.pc = BCE_TPAT_CPU_PROGRAM_COUNTER;
3874 	cpu_reg.inst = BCE_TPAT_CPU_INSTRUCTION;
3875 	cpu_reg.bp = BCE_TPAT_CPU_HW_BREAKPOINT;
3876 	cpu_reg.spad_base = BCE_TPAT_SCRATCH;
3877 	cpu_reg.mips_view_base = 0x8000000;
3878 
3879 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3880 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3881 		fw.ver_major = bce_TPAT_b09FwReleaseMajor;
3882 		fw.ver_minor = bce_TPAT_b09FwReleaseMinor;
3883 		fw.ver_fix = bce_TPAT_b09FwReleaseFix;
3884 		fw.start_addr = bce_TPAT_b09FwStartAddr;
3885 
3886 		fw.text_addr = bce_TPAT_b09FwTextAddr;
3887 		fw.text_len = bce_TPAT_b09FwTextLen;
3888 		fw.text_index = 0;
3889 		fw.text = bce_TPAT_b09FwText;
3890 
3891 		fw.data_addr = bce_TPAT_b09FwDataAddr;
3892 		fw.data_len = bce_TPAT_b09FwDataLen;
3893 		fw.data_index = 0;
3894 		fw.data = bce_TPAT_b09FwData;
3895 
3896 		fw.sbss_addr = bce_TPAT_b09FwSbssAddr;
3897 		fw.sbss_len = bce_TPAT_b09FwSbssLen;
3898 		fw.sbss_index = 0;
3899 		fw.sbss = bce_TPAT_b09FwSbss;
3900 
3901 		fw.bss_addr = bce_TPAT_b09FwBssAddr;
3902 		fw.bss_len = bce_TPAT_b09FwBssLen;
3903 		fw.bss_index = 0;
3904 		fw.bss = bce_TPAT_b09FwBss;
3905 
3906 		fw.rodata_addr = bce_TPAT_b09FwRodataAddr;
3907 		fw.rodata_len = bce_TPAT_b09FwRodataLen;
3908 		fw.rodata_index = 0;
3909 		fw.rodata = bce_TPAT_b09FwRodata;
3910 	} else {
3911 		fw.ver_major = bce_TPAT_b06FwReleaseMajor;
3912 		fw.ver_minor = bce_TPAT_b06FwReleaseMinor;
3913 		fw.ver_fix = bce_TPAT_b06FwReleaseFix;
3914 		fw.start_addr = bce_TPAT_b06FwStartAddr;
3915 
3916 		fw.text_addr = bce_TPAT_b06FwTextAddr;
3917 		fw.text_len = bce_TPAT_b06FwTextLen;
3918 		fw.text_index = 0;
3919 		fw.text = bce_TPAT_b06FwText;
3920 
3921 		fw.data_addr = bce_TPAT_b06FwDataAddr;
3922 		fw.data_len = bce_TPAT_b06FwDataLen;
3923 		fw.data_index = 0;
3924 		fw.data = bce_TPAT_b06FwData;
3925 
3926 		fw.sbss_addr = bce_TPAT_b06FwSbssAddr;
3927 		fw.sbss_len = bce_TPAT_b06FwSbssLen;
3928 		fw.sbss_index = 0;
3929 		fw.sbss = bce_TPAT_b06FwSbss;
3930 
3931 		fw.bss_addr = bce_TPAT_b06FwBssAddr;
3932 		fw.bss_len = bce_TPAT_b06FwBssLen;
3933 		fw.bss_index = 0;
3934 		fw.bss = bce_TPAT_b06FwBss;
3935 
3936 		fw.rodata_addr = bce_TPAT_b06FwRodataAddr;
3937 		fw.rodata_len = bce_TPAT_b06FwRodataLen;
3938 		fw.rodata_index = 0;
3939 		fw.rodata = bce_TPAT_b06FwRodata;
3940 	}
3941 
3942 	DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n");
3943 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
3944 
3945 	DBEXIT(BCE_VERBOSE_RESET);
3946 }
3947 
3948 
3949 /****************************************************************************/
3950 /* Initialize the CP CPU.                                                   */
3951 /*                                                                          */
3952 /* Returns:                                                                 */
3953 /*   Nothing.                                                               */
3954 /****************************************************************************/
3955 static void
3956 bce_init_cp_cpu(struct bce_softc *sc)
3957 {
3958 	struct cpu_reg cpu_reg;
3959 	struct fw_info fw;
3960 
3961 	DBENTER(BCE_VERBOSE_RESET);
3962 
3963 	cpu_reg.mode = BCE_CP_CPU_MODE;
3964 	cpu_reg.mode_value_halt = BCE_CP_CPU_MODE_SOFT_HALT;
3965 	cpu_reg.mode_value_sstep = BCE_CP_CPU_MODE_STEP_ENA;
3966 	cpu_reg.state = BCE_CP_CPU_STATE;
3967 	cpu_reg.state_value_clear = 0xffffff;
3968 	cpu_reg.gpr0 = BCE_CP_CPU_REG_FILE;
3969 	cpu_reg.evmask = BCE_CP_CPU_EVENT_MASK;
3970 	cpu_reg.pc = BCE_CP_CPU_PROGRAM_COUNTER;
3971 	cpu_reg.inst = BCE_CP_CPU_INSTRUCTION;
3972 	cpu_reg.bp = BCE_CP_CPU_HW_BREAKPOINT;
3973 	cpu_reg.spad_base = BCE_CP_SCRATCH;
3974 	cpu_reg.mips_view_base = 0x8000000;
3975 
3976 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3977 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3978 		fw.ver_major = bce_CP_b09FwReleaseMajor;
3979 		fw.ver_minor = bce_CP_b09FwReleaseMinor;
3980 		fw.ver_fix = bce_CP_b09FwReleaseFix;
3981 		fw.start_addr = bce_CP_b09FwStartAddr;
3982 
3983 		fw.text_addr = bce_CP_b09FwTextAddr;
3984 		fw.text_len = bce_CP_b09FwTextLen;
3985 		fw.text_index = 0;
3986 		fw.text = bce_CP_b09FwText;
3987 
3988 		fw.data_addr = bce_CP_b09FwDataAddr;
3989 		fw.data_len = bce_CP_b09FwDataLen;
3990 		fw.data_index = 0;
3991 		fw.data = bce_CP_b09FwData;
3992 
3993 		fw.sbss_addr = bce_CP_b09FwSbssAddr;
3994 		fw.sbss_len = bce_CP_b09FwSbssLen;
3995 		fw.sbss_index = 0;
3996 		fw.sbss = bce_CP_b09FwSbss;
3997 
3998 		fw.bss_addr = bce_CP_b09FwBssAddr;
3999 		fw.bss_len = bce_CP_b09FwBssLen;
4000 		fw.bss_index = 0;
4001 		fw.bss = bce_CP_b09FwBss;
4002 
4003 		fw.rodata_addr = bce_CP_b09FwRodataAddr;
4004 		fw.rodata_len = bce_CP_b09FwRodataLen;
4005 		fw.rodata_index = 0;
4006 		fw.rodata = bce_CP_b09FwRodata;
4007 	} else {
4008 		fw.ver_major = bce_CP_b06FwReleaseMajor;
4009 		fw.ver_minor = bce_CP_b06FwReleaseMinor;
4010 		fw.ver_fix = bce_CP_b06FwReleaseFix;
4011 		fw.start_addr = bce_CP_b06FwStartAddr;
4012 
4013 		fw.text_addr = bce_CP_b06FwTextAddr;
4014 		fw.text_len = bce_CP_b06FwTextLen;
4015 		fw.text_index = 0;
4016 		fw.text = bce_CP_b06FwText;
4017 
4018 		fw.data_addr = bce_CP_b06FwDataAddr;
4019 		fw.data_len = bce_CP_b06FwDataLen;
4020 		fw.data_index = 0;
4021 		fw.data = bce_CP_b06FwData;
4022 
4023 		fw.sbss_addr = bce_CP_b06FwSbssAddr;
4024 		fw.sbss_len = bce_CP_b06FwSbssLen;
4025 		fw.sbss_index = 0;
4026 		fw.sbss = bce_CP_b06FwSbss;
4027 
4028 		fw.bss_addr = bce_CP_b06FwBssAddr;
4029 		fw.bss_len = bce_CP_b06FwBssLen;
4030 		fw.bss_index = 0;
4031 		fw.bss = bce_CP_b06FwBss;
4032 
4033 		fw.rodata_addr = bce_CP_b06FwRodataAddr;
4034 		fw.rodata_len = bce_CP_b06FwRodataLen;
4035 		fw.rodata_index = 0;
4036 		fw.rodata = bce_CP_b06FwRodata;
4037 	}
4038 
4039 	DBPRINT(sc, BCE_INFO_RESET, "Loading CP firmware.\n");
4040 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4041 
4042 	DBEXIT(BCE_VERBOSE_RESET);
4043 }
4044 
4045 
4046 /****************************************************************************/
4047 /* Initialize the COM CPU.                                                 */
4048 /*                                                                          */
4049 /* Returns:                                                                 */
4050 /*   Nothing.                                                               */
4051 /****************************************************************************/
4052 static void
4053 bce_init_com_cpu(struct bce_softc *sc)
4054 {
4055 	struct cpu_reg cpu_reg;
4056 	struct fw_info fw;
4057 
4058 	DBENTER(BCE_VERBOSE_RESET);
4059 
4060 	cpu_reg.mode = BCE_COM_CPU_MODE;
4061 	cpu_reg.mode_value_halt = BCE_COM_CPU_MODE_SOFT_HALT;
4062 	cpu_reg.mode_value_sstep = BCE_COM_CPU_MODE_STEP_ENA;
4063 	cpu_reg.state = BCE_COM_CPU_STATE;
4064 	cpu_reg.state_value_clear = 0xffffff;
4065 	cpu_reg.gpr0 = BCE_COM_CPU_REG_FILE;
4066 	cpu_reg.evmask = BCE_COM_CPU_EVENT_MASK;
4067 	cpu_reg.pc = BCE_COM_CPU_PROGRAM_COUNTER;
4068 	cpu_reg.inst = BCE_COM_CPU_INSTRUCTION;
4069 	cpu_reg.bp = BCE_COM_CPU_HW_BREAKPOINT;
4070 	cpu_reg.spad_base = BCE_COM_SCRATCH;
4071 	cpu_reg.mips_view_base = 0x8000000;
4072 
4073 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4074 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4075 		fw.ver_major = bce_COM_b09FwReleaseMajor;
4076 		fw.ver_minor = bce_COM_b09FwReleaseMinor;
4077 		fw.ver_fix = bce_COM_b09FwReleaseFix;
4078 		fw.start_addr = bce_COM_b09FwStartAddr;
4079 
4080 		fw.text_addr = bce_COM_b09FwTextAddr;
4081 		fw.text_len = bce_COM_b09FwTextLen;
4082 		fw.text_index = 0;
4083 		fw.text = bce_COM_b09FwText;
4084 
4085 		fw.data_addr = bce_COM_b09FwDataAddr;
4086 		fw.data_len = bce_COM_b09FwDataLen;
4087 		fw.data_index = 0;
4088 		fw.data = bce_COM_b09FwData;
4089 
4090 		fw.sbss_addr = bce_COM_b09FwSbssAddr;
4091 		fw.sbss_len = bce_COM_b09FwSbssLen;
4092 		fw.sbss_index = 0;
4093 		fw.sbss = bce_COM_b09FwSbss;
4094 
4095 		fw.bss_addr = bce_COM_b09FwBssAddr;
4096 		fw.bss_len = bce_COM_b09FwBssLen;
4097 		fw.bss_index = 0;
4098 		fw.bss = bce_COM_b09FwBss;
4099 
4100 		fw.rodata_addr = bce_COM_b09FwRodataAddr;
4101 		fw.rodata_len = bce_COM_b09FwRodataLen;
4102 		fw.rodata_index = 0;
4103 		fw.rodata = bce_COM_b09FwRodata;
4104 	} else {
4105 		fw.ver_major = bce_COM_b06FwReleaseMajor;
4106 		fw.ver_minor = bce_COM_b06FwReleaseMinor;
4107 		fw.ver_fix = bce_COM_b06FwReleaseFix;
4108 		fw.start_addr = bce_COM_b06FwStartAddr;
4109 
4110 		fw.text_addr = bce_COM_b06FwTextAddr;
4111 		fw.text_len = bce_COM_b06FwTextLen;
4112 		fw.text_index = 0;
4113 		fw.text = bce_COM_b06FwText;
4114 
4115 		fw.data_addr = bce_COM_b06FwDataAddr;
4116 		fw.data_len = bce_COM_b06FwDataLen;
4117 		fw.data_index = 0;
4118 		fw.data = bce_COM_b06FwData;
4119 
4120 		fw.sbss_addr = bce_COM_b06FwSbssAddr;
4121 		fw.sbss_len = bce_COM_b06FwSbssLen;
4122 		fw.sbss_index = 0;
4123 		fw.sbss = bce_COM_b06FwSbss;
4124 
4125 		fw.bss_addr = bce_COM_b06FwBssAddr;
4126 		fw.bss_len = bce_COM_b06FwBssLen;
4127 		fw.bss_index = 0;
4128 		fw.bss = bce_COM_b06FwBss;
4129 
4130 		fw.rodata_addr = bce_COM_b06FwRodataAddr;
4131 		fw.rodata_len = bce_COM_b06FwRodataLen;
4132 		fw.rodata_index = 0;
4133 		fw.rodata = bce_COM_b06FwRodata;
4134 	}
4135 
4136 	DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n");
4137 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4138 
4139 	DBEXIT(BCE_VERBOSE_RESET);
4140 }
4141 
4142 
4143 /****************************************************************************/
4144 /* Initialize the RV2P, RX, TX, TPAT, COM, and CP CPUs.                     */
4145 /*                                                                          */
4146 /* Loads the firmware for each CPU and starts the CPU.                      */
4147 /*                                                                          */
4148 /* Returns:                                                                 */
4149 /*   Nothing.                                                               */
4150 /****************************************************************************/
4151 static void
4152 bce_init_cpus(struct bce_softc *sc)
4153 {
4154 	DBENTER(BCE_VERBOSE_RESET);
4155 
4156 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4157 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4158 		bce_load_rv2p_fw(sc, bce_xi_rv2p_proc1, sizeof(bce_xi_rv2p_proc1),
4159 			RV2P_PROC1);
4160 		bce_load_rv2p_fw(sc, bce_xi_rv2p_proc2, sizeof(bce_xi_rv2p_proc2),
4161 			RV2P_PROC2);
4162 	} else {
4163 		bce_load_rv2p_fw(sc, bce_rv2p_proc1, sizeof(bce_rv2p_proc1),
4164 			RV2P_PROC1);
4165 		bce_load_rv2p_fw(sc, bce_rv2p_proc2, sizeof(bce_rv2p_proc2),
4166 			RV2P_PROC2);
4167 	}
4168 
4169 	bce_init_rxp_cpu(sc);
4170 	bce_init_txp_cpu(sc);
4171 	bce_init_tpat_cpu(sc);
4172 	bce_init_com_cpu(sc);
4173 	bce_init_cp_cpu(sc);
4174 
4175 	DBEXIT(BCE_VERBOSE_RESET);
4176 }
4177 
4178 
4179 /****************************************************************************/
4180 /* Initialize context memory.                                               */
4181 /*                                                                          */
4182 /* Clears the memory associated with each Context ID (CID).                 */
4183 /*                                                                          */
4184 /* Returns:                                                                 */
4185 /*   Nothing.                                                               */
4186 /****************************************************************************/
4187 static void
4188 bce_init_ctx(struct bce_softc *sc)
4189 {
4190 
4191 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
4192 
4193 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4194 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4195 		/* DRC: Replace this constant value with a #define. */
4196 		int i, retry_cnt = 10;
4197 		u32 val;
4198 
4199 		DBPRINT(sc, BCE_INFO_CTX, "Initializing 5709 context.\n");
4200 
4201 		/*
4202 		 * BCM5709 context memory may be cached
4203 		 * in host memory so prepare the host memory
4204 		 * for access.
4205 		 */
4206 		val = BCE_CTX_COMMAND_ENABLED | BCE_CTX_COMMAND_MEM_INIT | (1 << 12);
4207 		val |= (BCM_PAGE_BITS - 8) << 16;
4208 		REG_WR(sc, BCE_CTX_COMMAND, val);
4209 
4210 		/* Wait for mem init command to complete. */
4211 		for (i = 0; i < retry_cnt; i++) {
4212 			val = REG_RD(sc, BCE_CTX_COMMAND);
4213 			if (!(val & BCE_CTX_COMMAND_MEM_INIT))
4214 				break;
4215 			DELAY(2);
4216 		}
4217 
4218 		/* ToDo: Consider returning an error here. */
4219 		DBRUNIF((val & BCE_CTX_COMMAND_MEM_INIT),
4220 			BCE_PRINTF("%s(): Context memory initialization failed!\n",
4221 			__FUNCTION__));
4222 
4223 		for (i = 0; i < sc->ctx_pages; i++) {
4224 			int j;
4225 
4226 			/* Set the physical address of the context memory cache. */
4227 			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA0,
4228 				BCE_ADDR_LO(sc->ctx_paddr[i] & 0xfffffff0) |
4229 				BCE_CTX_HOST_PAGE_TBL_DATA0_VALID);
4230 			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA1,
4231 				BCE_ADDR_HI(sc->ctx_paddr[i]));
4232 			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_CTRL, i |
4233 				BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
4234 
4235 			/* Verify that the context memory write was successful. */
4236 			for (j = 0; j < retry_cnt; j++) {
4237 				val = REG_RD(sc, BCE_CTX_HOST_PAGE_TBL_CTRL);
4238 				if ((val & BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) == 0)
4239 					break;
4240 				DELAY(5);
4241 			}
4242 
4243 			/* ToDo: Consider returning an error here. */
4244 			DBRUNIF((val & BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ),
4245 				BCE_PRINTF("%s(): Failed to initialize context page %d!\n",
4246 				__FUNCTION__, i));
4247 		}
4248 	} else {
4249 		u32 vcid_addr, offset;
4250 
4251 		DBPRINT(sc, BCE_INFO, "Initializing 5706/5708 context.\n");
4252 
4253 		/*
4254 		 * For the 5706/5708, context memory is local to
4255 		 * the controller, so initialize the controller
4256 		 * context memory.
4257 		 */
4258 
4259 		vcid_addr = GET_CID_ADDR(96);
4260 		while (vcid_addr) {
4261 
4262 			vcid_addr -= PHY_CTX_SIZE;
4263 
4264 			REG_WR(sc, BCE_CTX_VIRT_ADDR, 0);
4265 			REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
4266 
4267             for(offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
4268                 CTX_WR(sc, 0x00, offset, 0);
4269             }
4270 
4271 			REG_WR(sc, BCE_CTX_VIRT_ADDR, vcid_addr);
4272 			REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
4273 		}
4274 
4275 	}
4276 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
4277 }
4278 
4279 
4280 /****************************************************************************/
4281 /* Fetch the permanent MAC address of the controller.                       */
4282 /*                                                                          */
4283 /* Returns:                                                                 */
4284 /*   Nothing.                                                               */
4285 /****************************************************************************/
4286 static void
4287 bce_get_mac_addr(struct bce_softc *sc)
4288 {
4289 	u32 mac_lo = 0, mac_hi = 0;
4290 
4291 	DBENTER(BCE_VERBOSE_RESET);
4292 	/*
4293 	 * The NetXtreme II bootcode populates various NIC
4294 	 * power-on and runtime configuration items in a
4295 	 * shared memory area.  The factory configured MAC
4296 	 * address is available from both NVRAM and the
4297 	 * shared memory area so we'll read the value from
4298 	 * shared memory for speed.
4299 	 */
4300 
4301 	mac_hi = REG_RD_IND(sc, sc->bce_shmem_base +
4302 		BCE_PORT_HW_CFG_MAC_UPPER);
4303 	mac_lo = REG_RD_IND(sc, sc->bce_shmem_base +
4304 		BCE_PORT_HW_CFG_MAC_LOWER);
4305 
4306 	if ((mac_lo == 0) && (mac_hi == 0)) {
4307 		BCE_PRINTF("%s(%d): Invalid Ethernet address!\n",
4308 			__FILE__, __LINE__);
4309 	} else {
4310 		sc->eaddr[0] = (u_char)(mac_hi >> 8);
4311 		sc->eaddr[1] = (u_char)(mac_hi >> 0);
4312 		sc->eaddr[2] = (u_char)(mac_lo >> 24);
4313 		sc->eaddr[3] = (u_char)(mac_lo >> 16);
4314 		sc->eaddr[4] = (u_char)(mac_lo >> 8);
4315 		sc->eaddr[5] = (u_char)(mac_lo >> 0);
4316 	}
4317 
4318 	DBPRINT(sc, BCE_INFO_MISC, "Permanent Ethernet address = %6D\n", sc->eaddr, ":");
4319 	DBEXIT(BCE_VERBOSE_RESET);
4320 }
4321 
4322 
4323 /****************************************************************************/
4324 /* Program the MAC address.                                                 */
4325 /*                                                                          */
4326 /* Returns:                                                                 */
4327 /*   Nothing.                                                               */
4328 /****************************************************************************/
4329 static void
4330 bce_set_mac_addr(struct bce_softc *sc)
4331 {
4332 	u32 val;
4333 	u8 *mac_addr = sc->eaddr;
4334 
4335 	/* ToDo: Add support for setting multiple MAC addresses. */
4336 
4337 	DBENTER(BCE_VERBOSE_RESET);
4338 	DBPRINT(sc, BCE_INFO_MISC, "Setting Ethernet address = %6D\n", sc->eaddr, ":");
4339 
4340 	val = (mac_addr[0] << 8) | mac_addr[1];
4341 
4342 	REG_WR(sc, BCE_EMAC_MAC_MATCH0, val);
4343 
4344 	val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
4345 		(mac_addr[4] << 8) | mac_addr[5];
4346 
4347 	REG_WR(sc, BCE_EMAC_MAC_MATCH1, val);
4348 
4349 	DBEXIT(BCE_VERBOSE_RESET);
4350 }
4351 
4352 
4353 /****************************************************************************/
4354 /* Stop the controller.                                                     */
4355 /*                                                                          */
4356 /* Returns:                                                                 */
4357 /*   Nothing.                                                               */
4358 /****************************************************************************/
4359 static void
4360 bce_stop(struct bce_softc *sc)
4361 {
4362 	struct ifnet *ifp;
4363 	struct ifmedia_entry *ifm;
4364 	struct mii_data *mii = NULL;
4365 	int mtmp, itmp;
4366 
4367 	DBENTER(BCE_VERBOSE_RESET);
4368 
4369 	BCE_LOCK_ASSERT(sc);
4370 
4371 	ifp = sc->bce_ifp;
4372 
4373 	mii = device_get_softc(sc->bce_miibus);
4374 
4375 	callout_stop(&sc->bce_tick_callout);
4376 
4377 	/* Disable the transmit/receive blocks. */
4378 	REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS, BCE_MISC_ENABLE_CLR_DEFAULT);
4379 	REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
4380 	DELAY(20);
4381 
4382 	bce_disable_intr(sc);
4383 
4384 	/* Free RX buffers. */
4385 #ifdef BCE_USE_SPLIT_HEADER
4386 	bce_free_pg_chain(sc);
4387 #endif
4388 	bce_free_rx_chain(sc);
4389 
4390 	/* Free TX buffers. */
4391 	bce_free_tx_chain(sc);
4392 
4393 	/*
4394 	 * Isolate/power down the PHY, but leave the media selection
4395 	 * unchanged so that things will be put back to normal when
4396 	 * we bring the interface back up.
4397 	 */
4398 
4399 	itmp = ifp->if_flags;
4400 	ifp->if_flags |= IFF_UP;
4401 
4402 	/* If we are called from bce_detach(), mii is already NULL. */
4403 	if (mii != NULL) {
4404 		ifm = mii->mii_media.ifm_cur;
4405 		mtmp = ifm->ifm_media;
4406 		ifm->ifm_media = IFM_ETHER | IFM_NONE;
4407 		mii_mediachg(mii);
4408 		ifm->ifm_media = mtmp;
4409 	}
4410 
4411 	ifp->if_flags = itmp;
4412 	sc->watchdog_timer = 0;
4413 
4414 	sc->bce_link = 0;
4415 
4416 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
4417 
4418 	DBEXIT(BCE_VERBOSE_RESET);
4419 }
4420 
4421 
4422 static int
4423 bce_reset(struct bce_softc *sc, u32 reset_code)
4424 {
4425 	u32 val;
4426 	int i, rc = 0;
4427 
4428 	DBENTER(BCE_VERBOSE_RESET);
4429 
4430 	DBPRINT(sc, BCE_VERBOSE_RESET, "%s(): reset_code = 0x%08X\n",
4431 		__FUNCTION__, reset_code);
4432 
4433 	/* Wait for pending PCI transactions to complete. */
4434 	REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS,
4435 	       BCE_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
4436 	       BCE_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
4437 	       BCE_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
4438 	       BCE_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
4439 	val = REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
4440 	DELAY(5);
4441 
4442 	/* Disable DMA */
4443 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4444 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4445 		val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
4446 		val &= ~BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
4447 		REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
4448 	}
4449 
4450 	/* Assume bootcode is running. */
4451 	sc->bce_fw_timed_out = 0;
4452 
4453 	/* Give the firmware a chance to prepare for the reset. */
4454 	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT0 | reset_code);
4455 	if (rc)
4456 		goto bce_reset_exit;
4457 
4458 	/* Set a firmware reminder that this is a soft reset. */
4459 	REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_RESET_SIGNATURE,
4460 		   BCE_DRV_RESET_SIGNATURE_MAGIC);
4461 
4462 	/* Dummy read to force the chip to complete all current transactions. */
4463 	val = REG_RD(sc, BCE_MISC_ID);
4464 
4465 	/* Chip reset. */
4466 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4467 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4468 		REG_WR(sc, BCE_MISC_COMMAND, BCE_MISC_COMMAND_SW_RESET);
4469 		REG_RD(sc, BCE_MISC_COMMAND);
4470 		DELAY(5);
4471 
4472 		val = BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
4473 		      BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
4474 
4475 		pci_write_config(sc->bce_dev, BCE_PCICFG_MISC_CONFIG, val, 4);
4476 	} else {
4477 		val = BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4478 			BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
4479 			BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
4480 		REG_WR(sc, BCE_PCICFG_MISC_CONFIG, val);
4481 
4482 		/* Allow up to 30us for reset to complete. */
4483 		for (i = 0; i < 10; i++) {
4484 			val = REG_RD(sc, BCE_PCICFG_MISC_CONFIG);
4485 			if ((val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4486 				BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
4487 				break;
4488 			}
4489 			DELAY(10);
4490 		}
4491 
4492 		/* Check that reset completed successfully. */
4493 		if (val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4494 			BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
4495 			BCE_PRINTF("%s(%d): Reset failed!\n",
4496 				__FILE__, __LINE__);
4497 			rc = EBUSY;
4498 			goto bce_reset_exit;
4499 		}
4500 	}
4501 
4502 	/* Make sure byte swapping is properly configured. */
4503 	val = REG_RD(sc, BCE_PCI_SWAP_DIAG0);
4504 	if (val != 0x01020304) {
4505 		BCE_PRINTF("%s(%d): Byte swap is incorrect!\n",
4506 			__FILE__, __LINE__);
4507 		rc = ENODEV;
4508 		goto bce_reset_exit;
4509 	}
4510 
4511 	/* Just completed a reset, assume that firmware is running again. */
4512 	sc->bce_fw_timed_out = 0;
4513 
4514 	/* Wait for the firmware to finish its initialization. */
4515 	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT1 | reset_code);
4516 	if (rc)
4517 		BCE_PRINTF("%s(%d): Firmware did not complete initialization!\n",
4518 			__FILE__, __LINE__);
4519 
4520 bce_reset_exit:
4521 	DBEXIT(BCE_VERBOSE_RESET);
4522 	return (rc);
4523 }
4524 
4525 
4526 static int
4527 bce_chipinit(struct bce_softc *sc)
4528 {
4529 	u32 val;
4530 	int rc = 0;
4531 
4532 	DBENTER(BCE_VERBOSE_RESET);
4533 
4534 	bce_disable_intr(sc);
4535 
4536 	/*
4537 	 * Initialize DMA byte/word swapping, configure the number of DMA
4538 	 * channels and PCI clock compensation delay.
4539 	 */
4540 	val = BCE_DMA_CONFIG_DATA_BYTE_SWAP |
4541 	      BCE_DMA_CONFIG_DATA_WORD_SWAP |
4542 #if BYTE_ORDER == BIG_ENDIAN
4543 	      BCE_DMA_CONFIG_CNTL_BYTE_SWAP |
4544 #endif
4545 	      BCE_DMA_CONFIG_CNTL_WORD_SWAP |
4546 	      DMA_READ_CHANS << 12 |
4547 	      DMA_WRITE_CHANS << 16;
4548 
4549 	val |= (0x2 << 20) | BCE_DMA_CONFIG_CNTL_PCI_COMP_DLY;
4550 
4551 	if ((sc->bce_flags & BCE_PCIX_FLAG) && (sc->bus_speed_mhz == 133))
4552 		val |= BCE_DMA_CONFIG_PCI_FAST_CLK_CMP;
4553 
4554 	/*
4555 	 * This setting resolves a problem observed on certain Intel PCI
4556 	 * chipsets that cannot handle multiple outstanding DMA operations.
4557 	 * See errata E9_5706A1_65.
4558 	 */
4559 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
4560 	    (BCE_CHIP_ID(sc) != BCE_CHIP_ID_5706_A0) &&
4561 	    !(sc->bce_flags & BCE_PCIX_FLAG))
4562 		val |= BCE_DMA_CONFIG_CNTL_PING_PONG_DMA;
4563 
4564 	REG_WR(sc, BCE_DMA_CONFIG, val);
4565 
4566 	/* Enable the RX_V2P and Context state machines before access. */
4567 	REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
4568 	       BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
4569 	       BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
4570 	       BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
4571 
4572 	/* Initialize context mapping and zero out the quick contexts. */
4573 	bce_init_ctx(sc);
4574 
4575 	/* Initialize the on-boards CPUs */
4576 	bce_init_cpus(sc);
4577 
4578 	/* Prepare NVRAM for access. */
4579 	if (bce_init_nvram(sc)) {
4580 		rc = ENODEV;
4581 		goto bce_chipinit_exit;
4582 	}
4583 
4584 	/* Set the kernel bypass block size */
4585 	val = REG_RD(sc, BCE_MQ_CONFIG);
4586 	val &= ~BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE;
4587 	val |= BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
4588 
4589 	/* Enable bins used on the 5709. */
4590 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4591 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4592 		val |= BCE_MQ_CONFIG_BIN_MQ_MODE;
4593 		if (BCE_CHIP_ID(sc) == BCE_CHIP_ID_5709_A1)
4594 			val |= BCE_MQ_CONFIG_HALT_DIS;
4595 	}
4596 
4597 	REG_WR(sc, BCE_MQ_CONFIG, val);
4598 
4599 	val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
4600 	REG_WR(sc, BCE_MQ_KNL_BYP_WIND_START, val);
4601 	REG_WR(sc, BCE_MQ_KNL_WIND_END, val);
4602 
4603 	/* Set the page size and clear the RV2P processor stall bits. */
4604 	val = (BCM_PAGE_BITS - 8) << 24;
4605 	REG_WR(sc, BCE_RV2P_CONFIG, val);
4606 
4607 	/* Configure page size. */
4608 	val = REG_RD(sc, BCE_TBDR_CONFIG);
4609 	val &= ~BCE_TBDR_CONFIG_PAGE_SIZE;
4610 	val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
4611 	REG_WR(sc, BCE_TBDR_CONFIG, val);
4612 
4613 	/* Set the perfect match control register to default. */
4614 	REG_WR_IND(sc, BCE_RXP_PM_CTRL, 0);
4615 
4616 bce_chipinit_exit:
4617 	DBEXIT(BCE_VERBOSE_RESET);
4618 
4619 	return(rc);
4620 }
4621 
4622 
4623 /****************************************************************************/
4624 /* Initialize the controller in preparation to send/receive traffic.        */
4625 /*                                                                          */
4626 /* Returns:                                                                 */
4627 /*   0 for success, positive value for failure.                             */
4628 /****************************************************************************/
4629 static int
4630 bce_blockinit(struct bce_softc *sc)
4631 {
4632 	u32 reg, val;
4633 	int rc = 0;
4634 
4635 	DBENTER(BCE_VERBOSE_RESET);
4636 
4637 	/* Load the hardware default MAC address. */
4638 	bce_set_mac_addr(sc);
4639 
4640 	/* Set the Ethernet backoff seed value */
4641 	val = sc->eaddr[0]         + (sc->eaddr[1] << 8) +
4642 	      (sc->eaddr[2] << 16) + (sc->eaddr[3]     ) +
4643 	      (sc->eaddr[4] << 8)  + (sc->eaddr[5] << 16);
4644 	REG_WR(sc, BCE_EMAC_BACKOFF_SEED, val);
4645 
4646 	sc->last_status_idx = 0;
4647 	sc->rx_mode = BCE_EMAC_RX_MODE_SORT_MODE;
4648 
4649 	/* Set up link change interrupt generation. */
4650 	REG_WR(sc, BCE_EMAC_ATTENTION_ENA, BCE_EMAC_ATTENTION_ENA_LINK);
4651 
4652 	/* Program the physical address of the status block. */
4653 	REG_WR(sc, BCE_HC_STATUS_ADDR_L,
4654 		BCE_ADDR_LO(sc->status_block_paddr));
4655 	REG_WR(sc, BCE_HC_STATUS_ADDR_H,
4656 		BCE_ADDR_HI(sc->status_block_paddr));
4657 
4658 	/* Program the physical address of the statistics block. */
4659 	REG_WR(sc, BCE_HC_STATISTICS_ADDR_L,
4660 		BCE_ADDR_LO(sc->stats_block_paddr));
4661 	REG_WR(sc, BCE_HC_STATISTICS_ADDR_H,
4662 		BCE_ADDR_HI(sc->stats_block_paddr));
4663 
4664 	/* Program various host coalescing parameters. */
4665 	REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
4666 		(sc->bce_tx_quick_cons_trip_int << 16) | sc->bce_tx_quick_cons_trip);
4667 	REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
4668 		(sc->bce_rx_quick_cons_trip_int << 16) | sc->bce_rx_quick_cons_trip);
4669 	REG_WR(sc, BCE_HC_COMP_PROD_TRIP,
4670 		(sc->bce_comp_prod_trip_int << 16) | sc->bce_comp_prod_trip);
4671 	REG_WR(sc, BCE_HC_TX_TICKS,
4672 		(sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
4673 	REG_WR(sc, BCE_HC_RX_TICKS,
4674 		(sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
4675 	REG_WR(sc, BCE_HC_COM_TICKS,
4676 		(sc->bce_com_ticks_int << 16) | sc->bce_com_ticks);
4677 	REG_WR(sc, BCE_HC_CMD_TICKS,
4678 		(sc->bce_cmd_ticks_int << 16) | sc->bce_cmd_ticks);
4679 	REG_WR(sc, BCE_HC_STATS_TICKS,
4680 		(sc->bce_stats_ticks & 0xffff00));
4681 	REG_WR(sc, BCE_HC_STAT_COLLECT_TICKS, 0xbb8);  /* 3ms */
4682 
4683 	/* Configure the Host Coalescing block. */
4684 	val = BCE_HC_CONFIG_RX_TMR_MODE | BCE_HC_CONFIG_TX_TMR_MODE |
4685 		      BCE_HC_CONFIG_COLLECT_STATS;
4686 
4687 #if 0
4688 	/* ToDo: Add MSI-X support. */
4689 	if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
4690 		u32 base = ((BCE_TX_VEC - 1) * BCE_HC_SB_CONFIG_SIZE) +
4691 			   BCE_HC_SB_CONFIG_1;
4692 
4693 		REG_WR(sc, BCE_HC_MSIX_BIT_VECTOR, BCE_HC_MSIX_BIT_VECTOR_VAL);
4694 
4695 		REG_WR(sc, base, BCE_HC_SB_CONFIG_1_TX_TMR_MODE |
4696 			BCE_HC_SB_CONFIG_1_ONE_SHOT);
4697 
4698 		REG_WR(sc, base + BCE_HC_TX_QUICK_CONS_TRIP_OFF,
4699 			(sc->tx_quick_cons_trip_int << 16) |
4700 			 sc->tx_quick_cons_trip);
4701 
4702 		REG_WR(sc, base + BCE_HC_TX_TICKS_OFF,
4703 			(sc->tx_ticks_int << 16) | sc->tx_ticks);
4704 
4705 		val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
4706 	}
4707 
4708 	/*
4709 	 * Tell the HC block to automatically set the
4710 	 * INT_MASK bit after an MSI/MSI-X interrupt
4711 	 * is generated so the driver doesn't have to.
4712 	 */
4713 	if (sc->bce_flags & BCE_ONE_SHOT_MSI_FLAG)
4714 		val |= BCE_HC_CONFIG_ONE_SHOT;
4715 
4716 	/* Set the MSI-X status blocks to 128 byte boundaries. */
4717 	if (sc->bce_flags & BCE_USING_MSIX_FLAG)
4718 		val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
4719 #endif
4720 
4721 	REG_WR(sc, BCE_HC_CONFIG, val);
4722 
4723 	/* Clear the internal statistics counters. */
4724 	REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
4725 
4726 	/* Verify that bootcode is running. */
4727 	reg = REG_RD_IND(sc, sc->bce_shmem_base + BCE_DEV_INFO_SIGNATURE);
4728 
4729 	DBRUNIF(DB_RANDOMTRUE(bce_debug_bootcode_running_failure),
4730 		BCE_PRINTF("%s(%d): Simulating bootcode failure.\n",
4731 			__FILE__, __LINE__);
4732 		reg = 0);
4733 
4734 	if ((reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
4735 	    BCE_DEV_INFO_SIGNATURE_MAGIC) {
4736 		BCE_PRINTF("%s(%d): Bootcode not running! Found: 0x%08X, "
4737 			"Expected: 08%08X\n", __FILE__, __LINE__,
4738 			(reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK),
4739 			BCE_DEV_INFO_SIGNATURE_MAGIC);
4740 		rc = ENODEV;
4741 		goto bce_blockinit_exit;
4742 	}
4743 
4744 	/* Enable DMA */
4745 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4746 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4747 		val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
4748 		val |= BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
4749 		REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
4750 	}
4751 
4752 	/* Allow bootcode to apply any additional fixes before enabling MAC. */
4753 	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 | BCE_DRV_MSG_CODE_RESET);
4754 
4755 	/* Enable link state change interrupt generation. */
4756 	REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
4757 
4758 	/* Enable all remaining blocks in the MAC. */
4759 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)	||
4760 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
4761 		REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT_XI);
4762 	else
4763 		REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT);
4764 
4765 	REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
4766 	DELAY(20);
4767 
4768 	/* Save the current host coalescing block settings. */
4769 	sc->hc_command = REG_RD(sc, BCE_HC_COMMAND);
4770 
4771 bce_blockinit_exit:
4772 	DBEXIT(BCE_VERBOSE_RESET);
4773 
4774 	return (rc);
4775 }
4776 
4777 
4778 /****************************************************************************/
4779 /* Encapsulate an mbuf into the rx_bd chain.                                */
4780 /*                                                                          */
4781 /* Returns:                                                                 */
4782 /*   0 for success, positive value for failure.                             */
4783 /****************************************************************************/
4784 static int
4785 bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
4786 	u16 *chain_prod, u32 *prod_bseq)
4787 {
4788 	bus_dmamap_t map;
4789 	bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
4790 	struct mbuf *m_new = NULL;
4791 	struct rx_bd *rxbd;
4792 	int nsegs, error, rc = 0;
4793 #ifdef BCE_DEBUG
4794 	u16 debug_chain_prod = *chain_prod;
4795 #endif
4796 
4797 	DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
4798 
4799 	/* Make sure the inputs are valid. */
4800 	DBRUNIF((*chain_prod > MAX_RX_BD),
4801 		BCE_PRINTF("%s(%d): RX producer out of range: 0x%04X > 0x%04X\n",
4802 		__FILE__, __LINE__, *chain_prod, (u16) MAX_RX_BD));
4803 
4804 	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, chain_prod = 0x%04X, "
4805 		"prod_bseq = 0x%08X\n", __FUNCTION__, *prod, *chain_prod, *prod_bseq);
4806 
4807 	/* Update some debug statistic counters */
4808 	DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
4809 		sc->rx_low_watermark = sc->free_rx_bd);
4810 	DBRUNIF((sc->free_rx_bd == sc->max_rx_bd), sc->rx_empty_count++);
4811 
4812 	/* Check whether this is a new mbuf allocation. */
4813 	if (m == NULL) {
4814 
4815 		/* Simulate an mbuf allocation failure. */
4816 		DBRUNIF(DB_RANDOMTRUE(bce_debug_mbuf_allocation_failure),
4817 			sc->mbuf_alloc_failed++;
4818 			sc->debug_mbuf_sim_alloc_failed++;
4819 			rc = ENOBUFS;
4820 			goto bce_get_rx_buf_exit);
4821 
4822 		/* This is a new mbuf allocation. */
4823 #ifdef BCE_USE_SPLIT_HEADER
4824 		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
4825 #else
4826 		if (sc->rx_bd_mbuf_alloc_size <= MCLBYTES)
4827 			m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
4828 		else
4829 			m_new = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, sc->rx_bd_mbuf_alloc_size);
4830 #endif
4831 
4832 		if (m_new == NULL) {
4833 			sc->mbuf_alloc_failed++;
4834 			rc = ENOBUFS;
4835 			goto bce_get_rx_buf_exit;
4836 		}
4837 
4838 		DBRUN(sc->debug_rx_mbuf_alloc++);
4839 	} else {
4840 		/* Reuse an existing mbuf. */
4841 		m_new = m;
4842 	}
4843 
4844 	/* Make sure we have a valid packet header. */
4845 	M_ASSERTPKTHDR(m_new);
4846 
4847 	/* Initialize the mbuf size and pad if necessary for alignment. */
4848 	m_new->m_pkthdr.len = m_new->m_len = sc->rx_bd_mbuf_alloc_size;
4849 	m_adj(m_new, sc->rx_bd_mbuf_align_pad);
4850 
4851 	/* ToDo: Consider calling m_fragment() to test error handling. */
4852 
4853 	/* Map the mbuf cluster into device memory. */
4854 	map = sc->rx_mbuf_map[*chain_prod];
4855 	error = bus_dmamap_load_mbuf_sg(sc->rx_mbuf_tag, map, m_new,
4856 	    segs, &nsegs, BUS_DMA_NOWAIT);
4857 
4858 	/* Handle any mapping errors. */
4859 	if (error) {
4860 		BCE_PRINTF("%s(%d): Error mapping mbuf into RX chain (%d)!\n",
4861 			__FILE__, __LINE__, error);
4862 
4863 		m_freem(m_new);
4864 		DBRUN(sc->debug_rx_mbuf_alloc--);
4865 
4866 		rc = ENOBUFS;
4867 		goto bce_get_rx_buf_exit;
4868 	}
4869 
4870 	/* All mbufs must map to a single segment. */
4871 	KASSERT(nsegs == 1, ("%s(): Too many segments returned (%d)!",
4872 		 __FUNCTION__, nsegs));
4873 
4874 	/* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREWRITE) here? */
4875 
4876 	/* Setup the rx_bd for the segment. */
4877 	rxbd = &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
4878 
4879 	rxbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(segs[0].ds_addr));
4880 	rxbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(segs[0].ds_addr));
4881 	rxbd->rx_bd_len       = htole32(segs[0].ds_len);
4882 	rxbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
4883 	*prod_bseq += segs[0].ds_len;
4884 
4885 	/* Save the mbuf and update our counter. */
4886 	sc->rx_mbuf_ptr[*chain_prod] = m_new;
4887 	sc->free_rx_bd -= nsegs;
4888 
4889 	DBRUNMSG(BCE_INSANE_RECV, bce_dump_rx_mbuf_chain(sc, debug_chain_prod,
4890 		nsegs));
4891 
4892 	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, chain_prod = 0x%04X, "
4893 		"prod_bseq = 0x%08X\n", __FUNCTION__, *prod, *chain_prod, *prod_bseq);
4894 
4895 bce_get_rx_buf_exit:
4896 	DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
4897 
4898 	return(rc);
4899 }
4900 
4901 
4902 #ifdef BCE_USE_SPLIT_HEADER
4903 /****************************************************************************/
4904 /* Encapsulate an mbuf cluster into the page chain.                        */
4905 /*                                                                          */
4906 /* Returns:                                                                 */
4907 /*   0 for success, positive value for failure.                             */
4908 /****************************************************************************/
4909 static int
4910 bce_get_pg_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
4911 	u16 *prod_idx)
4912 {
4913 	bus_dmamap_t map;
4914 	bus_addr_t busaddr;
4915 	struct mbuf *m_new = NULL;
4916 	struct rx_bd *pgbd;
4917 	int error, rc = 0;
4918 #ifdef BCE_DEBUG
4919 	u16 debug_prod_idx = *prod_idx;
4920 #endif
4921 
4922 	DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
4923 
4924 	/* Make sure the inputs are valid. */
4925 	DBRUNIF((*prod_idx > MAX_PG_BD),
4926 		BCE_PRINTF("%s(%d): page producer out of range: 0x%04X > 0x%04X\n",
4927 		__FILE__, __LINE__, *prod_idx, (u16) MAX_PG_BD));
4928 
4929 	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
4930 		"chain_prod = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
4931 
4932 	/* Update counters if we've hit a new low or run out of pages. */
4933 	DBRUNIF((sc->free_pg_bd < sc->pg_low_watermark),
4934 		sc->pg_low_watermark = sc->free_pg_bd);
4935 	DBRUNIF((sc->free_pg_bd == sc->max_pg_bd), sc->pg_empty_count++);
4936 
4937 	/* Check whether this is a new mbuf allocation. */
4938 	if (m == NULL) {
4939 
4940 		/* Simulate an mbuf allocation failure. */
4941 		DBRUNIF(DB_RANDOMTRUE(bce_debug_mbuf_allocation_failure),
4942 			sc->mbuf_alloc_failed++;
4943 			sc->debug_mbuf_sim_alloc_failed++;
4944 			rc = ENOBUFS;
4945 			goto bce_get_pg_buf_exit);
4946 
4947 		/* This is a new mbuf allocation. */
4948 		m_new = m_getcl(M_DONTWAIT, MT_DATA, 0);
4949 		if (m_new == NULL) {
4950 			sc->mbuf_alloc_failed++;
4951 			rc = ENOBUFS;
4952 			goto bce_get_pg_buf_exit;
4953 		}
4954 
4955 		DBRUN(sc->debug_pg_mbuf_alloc++);
4956 	} else {
4957 		/* Reuse an existing mbuf. */
4958 		m_new = m;
4959 		m_new->m_data = m_new->m_ext.ext_buf;
4960 	}
4961 
4962 	m_new->m_len = sc->pg_bd_mbuf_alloc_size;
4963 
4964 	/* ToDo: Consider calling m_fragment() to test error handling. */
4965 
4966 	/* Map the mbuf cluster into device memory. */
4967 	map = sc->pg_mbuf_map[*prod_idx];
4968 	error = bus_dmamap_load(sc->pg_mbuf_tag, map, mtod(m_new, void *),
4969 	    sc->pg_bd_mbuf_alloc_size, bce_dma_map_addr, &busaddr, BUS_DMA_NOWAIT);
4970 
4971 	/* Handle any mapping errors. */
4972 	if (error) {
4973 		BCE_PRINTF("%s(%d): Error mapping mbuf into page chain!\n",
4974 			__FILE__, __LINE__);
4975 
4976 		m_freem(m_new);
4977 		DBRUN(sc->debug_pg_mbuf_alloc--);
4978 
4979 		rc = ENOBUFS;
4980 		goto bce_get_pg_buf_exit;
4981 	}
4982 
4983 	/* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREWRITE) here? */
4984 
4985 	/*
4986 	 * The page chain uses the same rx_bd data structure
4987 	 * as the receive chain but doesn't require a byte sequence (bseq).
4988 	 */
4989 	pgbd = &sc->pg_bd_chain[PG_PAGE(*prod_idx)][PG_IDX(*prod_idx)];
4990 
4991 	pgbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(busaddr));
4992 	pgbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(busaddr));
4993 	pgbd->rx_bd_len       = htole32(sc->pg_bd_mbuf_alloc_size);
4994 	pgbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
4995 
4996 	/* Save the mbuf and update our counter. */
4997 	sc->pg_mbuf_ptr[*prod_idx] = m_new;
4998 	sc->free_pg_bd--;
4999 
5000 	DBRUNMSG(BCE_INSANE_RECV, bce_dump_pg_mbuf_chain(sc, debug_prod_idx,
5001 		1));
5002 
5003 	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
5004 		"prod_idx = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
5005 
5006 bce_get_pg_buf_exit:
5007 	DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5008 
5009 	return(rc);
5010 }
5011 #endif /* BCE_USE_SPLIT_HEADER */
5012 
5013 /****************************************************************************/
5014 /* Initialize the TX context memory.                                        */
5015 /*                                                                          */
5016 /* Returns:                                                                 */
5017 /*   Nothing                                                                */
5018 /****************************************************************************/
5019 static void
5020 bce_init_tx_context(struct bce_softc *sc)
5021 {
5022 	u32 val;
5023 
5024 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
5025 
5026 	/* Initialize the context ID for an L2 TX chain. */
5027 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
5028 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
5029 		/* Set the CID type to support an L2 connection. */
5030 		val = BCE_L2CTX_TX_TYPE_TYPE_L2_XI | BCE_L2CTX_TX_TYPE_SIZE_L2_XI;
5031 		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE_XI, val);
5032 		val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2_XI | (8 << 16);
5033 		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_CMD_TYPE_XI, val);
5034 
5035 		/* Point the hardware to the first page in the chain. */
5036 		val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
5037 		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_HI_XI, val);
5038 		val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
5039 		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_LO_XI, val);
5040 	} else {
5041 		/* Set the CID type to support an L2 connection. */
5042 		val = BCE_L2CTX_TX_TYPE_TYPE_L2 | BCE_L2CTX_TX_TYPE_SIZE_L2;
5043 		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE, val);
5044 		val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2 | (8 << 16);
5045 		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_CMD_TYPE, val);
5046 
5047 		/* Point the hardware to the first page in the chain. */
5048 		val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
5049 		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_HI, val);
5050 		val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
5051 		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_LO, val);
5052 	}
5053 
5054 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
5055 }
5056 
5057 
5058 /****************************************************************************/
5059 /* Allocate memory and initialize the TX data structures.                   */
5060 /*                                                                          */
5061 /* Returns:                                                                 */
5062 /*   0 for success, positive value for failure.                             */
5063 /****************************************************************************/
5064 static int
5065 bce_init_tx_chain(struct bce_softc *sc)
5066 {
5067 	struct tx_bd *txbd;
5068 	int i, rc = 0;
5069 
5070 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
5071 
5072 	/* Set the initial TX producer/consumer indices. */
5073 	sc->tx_prod        = 0;
5074 	sc->tx_cons        = 0;
5075 	sc->tx_prod_bseq   = 0;
5076 	sc->used_tx_bd     = 0;
5077 	sc->max_tx_bd      = USABLE_TX_BD;
5078 	DBRUN(sc->tx_hi_watermark = USABLE_TX_BD);
5079 	DBRUN(sc->tx_full_count = 0);
5080 
5081 	/*
5082 	 * The NetXtreme II supports a linked-list structre called
5083 	 * a Buffer Descriptor Chain (or BD chain).  A BD chain
5084 	 * consists of a series of 1 or more chain pages, each of which
5085 	 * consists of a fixed number of BD entries.
5086 	 * The last BD entry on each page is a pointer to the next page
5087 	 * in the chain, and the last pointer in the BD chain
5088 	 * points back to the beginning of the chain.
5089 	 */
5090 
5091 	/* Set the TX next pointer chain entries. */
5092 	for (i = 0; i < TX_PAGES; i++) {
5093 		int j;
5094 
5095 		txbd = &sc->tx_bd_chain[i][USABLE_TX_BD_PER_PAGE];
5096 
5097 		/* Check if we've reached the last page. */
5098 		if (i == (TX_PAGES - 1))
5099 			j = 0;
5100 		else
5101 			j = i + 1;
5102 
5103 		txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->tx_bd_chain_paddr[j]));
5104 		txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->tx_bd_chain_paddr[j]));
5105 	}
5106 
5107 	bce_init_tx_context(sc);
5108 
5109 	DBRUNMSG(BCE_INSANE_SEND, bce_dump_tx_chain(sc, 0, TOTAL_TX_BD));
5110 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
5111 
5112 	return(rc);
5113 }
5114 
5115 
5116 /****************************************************************************/
5117 /* Free memory and clear the TX data structures.                            */
5118 /*                                                                          */
5119 /* Returns:                                                                 */
5120 /*   Nothing.                                                               */
5121 /****************************************************************************/
5122 static void
5123 bce_free_tx_chain(struct bce_softc *sc)
5124 {
5125 	int i;
5126 
5127 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
5128 
5129 	/* Unmap, unload, and free any mbufs still in the TX mbuf chain. */
5130 	for (i = 0; i < TOTAL_TX_BD; i++) {
5131 		if (sc->tx_mbuf_ptr[i] != NULL) {
5132 			if (sc->tx_mbuf_map[i] != NULL)
5133 				bus_dmamap_sync(sc->tx_mbuf_tag, sc->tx_mbuf_map[i],
5134 					BUS_DMASYNC_POSTWRITE);
5135 			m_freem(sc->tx_mbuf_ptr[i]);
5136 			sc->tx_mbuf_ptr[i] = NULL;
5137 			DBRUN(sc->debug_tx_mbuf_alloc--);
5138 		}
5139 	}
5140 
5141 	/* Clear each TX chain page. */
5142 	for (i = 0; i < TX_PAGES; i++)
5143 		bzero((char *)sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ);
5144 
5145 	sc->used_tx_bd     = 0;
5146 
5147 	/* Check if we lost any mbufs in the process. */
5148 	DBRUNIF((sc->debug_tx_mbuf_alloc),
5149 		BCE_PRINTF("%s(%d): Memory leak! Lost %d mbufs "
5150 			"from tx chain!\n",
5151 			__FILE__, __LINE__, sc->debug_tx_mbuf_alloc));
5152 
5153 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
5154 }
5155 
5156 
5157 /****************************************************************************/
5158 /* Initialize the RX context memory.                                        */
5159 /*                                                                          */
5160 /* Returns:                                                                 */
5161 /*   Nothing                                                                */
5162 /****************************************************************************/
5163 static void
5164 bce_init_rx_context(struct bce_softc *sc)
5165 {
5166 	u32 val;
5167 
5168 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
5169 
5170 	/* Initialize the type, size, and BD cache levels for the RX context. */
5171 	val = BCE_L2CTX_RX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE |
5172 		BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 |
5173 		(0x02 << BCE_L2CTX_RX_BD_PRE_READ_SHIFT);
5174 
5175 	/*
5176 	 * Set the level for generating pause frames
5177 	 * when the number of available rx_bd's gets
5178 	 * too low (the low watermark) and the level
5179 	 * when pause frames can be stopped (the high
5180 	 * watermark).
5181 	 */
5182 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
5183 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
5184 		u32 lo_water, hi_water;
5185 
5186 		lo_water = BCE_L2CTX_RX_LO_WATER_MARK_DEFAULT;
5187 		hi_water = USABLE_RX_BD / 4;
5188 
5189 		lo_water /= BCE_L2CTX_RX_LO_WATER_MARK_SCALE;
5190 		hi_water /= BCE_L2CTX_RX_HI_WATER_MARK_SCALE;
5191 
5192 		if (hi_water > 0xf)
5193 			hi_water = 0xf;
5194 		else if (hi_water == 0)
5195 			lo_water = 0;
5196 		val |= (lo_water << BCE_L2CTX_RX_LO_WATER_MARK_SHIFT) |
5197 			(hi_water << BCE_L2CTX_RX_HI_WATER_MARK_SHIFT);
5198 	}
5199 
5200  	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_CTX_TYPE, val);
5201 
5202 	/* Setup the MQ BIN mapping for l2_ctx_host_bseq. */
5203 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
5204 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
5205 		val = REG_RD(sc, BCE_MQ_MAP_L2_5);
5206 		REG_WR(sc, BCE_MQ_MAP_L2_5, val | BCE_MQ_MAP_L2_5_ARM);
5207 	}
5208 
5209 	/* Point the hardware to the first page in the chain. */
5210 	val = BCE_ADDR_HI(sc->rx_bd_chain_paddr[0]);
5211 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_HI, val);
5212 	val = BCE_ADDR_LO(sc->rx_bd_chain_paddr[0]);
5213 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_LO, val);
5214 
5215 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
5216 }
5217 
5218 
5219 /****************************************************************************/
5220 /* Allocate memory and initialize the RX data structures.                   */
5221 /*                                                                          */
5222 /* Returns:                                                                 */
5223 /*   0 for success, positive value for failure.                             */
5224 /****************************************************************************/
5225 static int
5226 bce_init_rx_chain(struct bce_softc *sc)
5227 {
5228 	struct rx_bd *rxbd;
5229 	int i, rc = 0;
5230 
5231 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5232 		BCE_VERBOSE_CTX);
5233 
5234 	/* Initialize the RX producer and consumer indices. */
5235 	sc->rx_prod        = 0;
5236 	sc->rx_cons        = 0;
5237 	sc->rx_prod_bseq   = 0;
5238 	sc->free_rx_bd     = USABLE_RX_BD;
5239 	sc->max_rx_bd      = USABLE_RX_BD;
5240 	DBRUN(sc->rx_low_watermark = sc->max_rx_bd);
5241 	DBRUN(sc->rx_empty_count = 0);
5242 
5243 	/* Initialize the RX next pointer chain entries. */
5244 	for (i = 0; i < RX_PAGES; i++) {
5245 		int j;
5246 
5247 		rxbd = &sc->rx_bd_chain[i][USABLE_RX_BD_PER_PAGE];
5248 
5249 		/* Check if we've reached the last page. */
5250 		if (i == (RX_PAGES - 1))
5251 			j = 0;
5252 		else
5253 			j = i + 1;
5254 
5255 		/* Setup the chain page pointers. */
5256 		rxbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j]));
5257 		rxbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j]));
5258 	}
5259 
5260 /* Fill up the RX chain. */
5261 	bce_fill_rx_chain(sc);
5262 
5263 	for (i = 0; i < RX_PAGES; i++) {
5264 		bus_dmamap_sync(
5265 			sc->rx_bd_chain_tag,
5266 	    	sc->rx_bd_chain_map[i],
5267 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
5268 	}
5269 
5270 	bce_init_rx_context(sc);
5271 
5272 	DBRUNMSG(BCE_EXTREME_RECV, bce_dump_rx_chain(sc, 0, TOTAL_RX_BD));
5273 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5274 		BCE_VERBOSE_CTX);
5275 	/* ToDo: Are there possible failure modes here? */
5276 	return(rc);
5277 }
5278 
5279 
5280 /****************************************************************************/
5281 /* Add mbufs to the RX chain until its full or an mbuf allocation error     */
5282 /* occurs.                                                                  */
5283 /*                                                                          */
5284 /* Returns:                                                                 */
5285 /*   Nothing                                                                */
5286 /****************************************************************************/
5287 static void
5288 bce_fill_rx_chain(struct bce_softc *sc)
5289 {
5290 	u16 prod, prod_idx;
5291 	u32 prod_bseq;
5292 
5293 	DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5294 		BCE_VERBOSE_CTX);
5295 
5296 	/* Get the RX chain producer indices. */
5297 	prod      = sc->rx_prod;
5298 	prod_bseq = sc->rx_prod_bseq;
5299 
5300 	/* Keep filling the RX chain until it's full. */
5301 	while (sc->free_rx_bd > 0) {
5302 		prod_idx = RX_CHAIN_IDX(prod);
5303 		if (bce_get_rx_buf(sc, NULL, &prod, &prod_idx, &prod_bseq)) {
5304 			/* Bail out if we can't add an mbuf to the chain. */
5305 			break;
5306 		}
5307 		prod = NEXT_RX_BD(prod);
5308 	}
5309 
5310 	/* Save the RX chain producer indices. */
5311 	sc->rx_prod      = prod;
5312 	sc->rx_prod_bseq = prod_bseq;
5313 
5314 	DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
5315 		BCE_PRINTF("%s(): Invalid rx_prod value: 0x%04X\n",
5316 		__FUNCTION__, sc->rx_prod));
5317 
5318 	/* Write the mailbox and tell the chip about the waiting rx_bd's. */
5319 	REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BDIDX,
5320 		sc->rx_prod);
5321 	REG_WR(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BSEQ,
5322 		sc->rx_prod_bseq);
5323 
5324 	DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5325 		BCE_VERBOSE_CTX);
5326 }
5327 
5328 
5329 /****************************************************************************/
5330 /* Free memory and clear the RX data structures.                            */
5331 /*                                                                          */
5332 /* Returns:                                                                 */
5333 /*   Nothing.                                                               */
5334 /****************************************************************************/
5335 static void
5336 bce_free_rx_chain(struct bce_softc *sc)
5337 {
5338 	int i;
5339 
5340 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5341 
5342 	/* Free any mbufs still in the RX mbuf chain. */
5343 	for (i = 0; i < TOTAL_RX_BD; i++) {
5344 		if (sc->rx_mbuf_ptr[i] != NULL) {
5345 			if (sc->rx_mbuf_map[i] != NULL)
5346 				bus_dmamap_sync(sc->rx_mbuf_tag, sc->rx_mbuf_map[i],
5347 					BUS_DMASYNC_POSTREAD);
5348 			m_freem(sc->rx_mbuf_ptr[i]);
5349 			sc->rx_mbuf_ptr[i] = NULL;
5350 			DBRUN(sc->debug_rx_mbuf_alloc--);
5351 		}
5352 	}
5353 
5354 	/* Clear each RX chain page. */
5355 	for (i = 0; i < RX_PAGES; i++)
5356 		bzero((char *)sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ);
5357 
5358 	sc->free_rx_bd = sc->max_rx_bd;
5359 
5360 	/* Check if we lost any mbufs in the process. */
5361 	DBRUNIF((sc->debug_rx_mbuf_alloc),
5362 		BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from rx chain!\n",
5363 			__FUNCTION__, sc->debug_rx_mbuf_alloc));
5364 
5365 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5366 }
5367 
5368 
5369 #ifdef BCE_USE_SPLIT_HEADER
5370 /****************************************************************************/
5371 /* Allocate memory and initialize the page data structures.                 */
5372 /* Assumes that bce_init_rx_chain() has not already been called.            */
5373 /*                                                                          */
5374 /* Returns:                                                                 */
5375 /*   0 for success, positive value for failure.                             */
5376 /****************************************************************************/
5377 static int
5378 bce_init_pg_chain(struct bce_softc *sc)
5379 {
5380 	struct rx_bd *pgbd;
5381 	int i, rc = 0;
5382 	u32 val;
5383 
5384 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5385 		BCE_VERBOSE_CTX);
5386 
5387 	/* Initialize the page producer and consumer indices. */
5388 	sc->pg_prod        = 0;
5389 	sc->pg_cons        = 0;
5390 	sc->free_pg_bd     = USABLE_PG_BD;
5391 	sc->max_pg_bd      = USABLE_PG_BD;
5392 	DBRUN(sc->pg_low_watermark = sc->max_pg_bd);
5393 	DBRUN(sc->pg_empty_count = 0);
5394 
5395 	/* Initialize the page next pointer chain entries. */
5396 	for (i = 0; i < PG_PAGES; i++) {
5397 		int j;
5398 
5399 		pgbd = &sc->pg_bd_chain[i][USABLE_PG_BD_PER_PAGE];
5400 
5401 		/* Check if we've reached the last page. */
5402 		if (i == (PG_PAGES - 1))
5403 			j = 0;
5404 		else
5405 			j = i + 1;
5406 
5407 		/* Setup the chain page pointers. */
5408 		pgbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->pg_bd_chain_paddr[j]));
5409 		pgbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->pg_bd_chain_paddr[j]));
5410 	}
5411 
5412 	/* Setup the MQ BIN mapping for host_pg_bidx. */
5413 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)	||
5414 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
5415 		REG_WR(sc, BCE_MQ_MAP_L2_3, BCE_MQ_MAP_L2_3_DEFAULT);
5416 
5417 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, 0);
5418 
5419 	/* Configure the rx_bd and page chain mbuf cluster size. */
5420 	val = (sc->rx_bd_mbuf_data_len << 16) | sc->pg_bd_mbuf_alloc_size;
5421 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, val);
5422 
5423 	/* Configure the context reserved for jumbo support. */
5424 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_RBDC_KEY,
5425 		BCE_L2CTX_RX_RBDC_JUMBO_KEY);
5426 
5427 	/* Point the hardware to the first page in the page chain. */
5428 	val = BCE_ADDR_HI(sc->pg_bd_chain_paddr[0]);
5429 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_HI, val);
5430 	val = BCE_ADDR_LO(sc->pg_bd_chain_paddr[0]);
5431 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_LO, val);
5432 
5433 	/* Fill up the page chain. */
5434 	bce_fill_pg_chain(sc);
5435 
5436 	for (i = 0; i < PG_PAGES; i++) {
5437 		bus_dmamap_sync(
5438 			sc->pg_bd_chain_tag,
5439 	    	sc->pg_bd_chain_map[i],
5440 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
5441 	}
5442 
5443 	DBRUNMSG(BCE_EXTREME_RECV, bce_dump_pg_chain(sc, 0, TOTAL_PG_BD));
5444 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5445 		BCE_VERBOSE_CTX);
5446 	return(rc);
5447 }
5448 
5449 
5450 /****************************************************************************/
5451 /* Add mbufs to the page chain until its full or an mbuf allocation error   */
5452 /* occurs.                                                                  */
5453 /*                                                                          */
5454 /* Returns:                                                                 */
5455 /*   Nothing                                                                */
5456 /****************************************************************************/
5457 static void
5458 bce_fill_pg_chain(struct bce_softc *sc)
5459 {
5460 	u16 prod, prod_idx;
5461 
5462 	DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5463 		BCE_VERBOSE_CTX);
5464 
5465 	/* Get the page chain prodcuer index. */
5466 	prod = sc->pg_prod;
5467 
5468 	/* Keep filling the page chain until it's full. */
5469 	while (sc->free_pg_bd > 0) {
5470 		prod_idx = PG_CHAIN_IDX(prod);
5471 		if (bce_get_pg_buf(sc, NULL, &prod, &prod_idx)) {
5472 			/* Bail out if we can't add an mbuf to the chain. */
5473 			break;
5474 		}
5475 		prod = NEXT_PG_BD(prod);
5476 	}
5477 
5478 	/* Save the page chain producer index. */
5479 	sc->pg_prod = prod;
5480 
5481 	DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
5482 		BCE_PRINTF("%s(): Invalid pg_prod value: 0x%04X\n",
5483 		__FUNCTION__, sc->pg_prod));
5484 
5485 	/*
5486 	 * Write the mailbox and tell the chip about
5487 	 * the new rx_bd's in the page chain.
5488 	 */
5489 	REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_PG_BDIDX,
5490 		sc->pg_prod);
5491 
5492 	DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5493 		BCE_VERBOSE_CTX);
5494 }
5495 
5496 
5497 /****************************************************************************/
5498 /* Free memory and clear the RX data structures.                            */
5499 /*                                                                          */
5500 /* Returns:                                                                 */
5501 /*   Nothing.                                                               */
5502 /****************************************************************************/
5503 static void
5504 bce_free_pg_chain(struct bce_softc *sc)
5505 {
5506 	int i;
5507 
5508 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5509 
5510 	/* Free any mbufs still in the mbuf page chain. */
5511 	for (i = 0; i < TOTAL_PG_BD; i++) {
5512 		if (sc->pg_mbuf_ptr[i] != NULL) {
5513 			if (sc->pg_mbuf_map[i] != NULL)
5514 				bus_dmamap_sync(sc->pg_mbuf_tag, sc->pg_mbuf_map[i],
5515 					BUS_DMASYNC_POSTREAD);
5516 			m_freem(sc->pg_mbuf_ptr[i]);
5517 			sc->pg_mbuf_ptr[i] = NULL;
5518 			DBRUN(sc->debug_pg_mbuf_alloc--);
5519 		}
5520 	}
5521 
5522 	/* Clear each page chain pages. */
5523 	for (i = 0; i < PG_PAGES; i++)
5524 		bzero((char *)sc->pg_bd_chain[i], BCE_PG_CHAIN_PAGE_SZ);
5525 
5526 	sc->free_pg_bd = sc->max_pg_bd;
5527 
5528 	/* Check if we lost any mbufs in the process. */
5529 	DBRUNIF((sc->debug_pg_mbuf_alloc),
5530 		BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from page chain!\n",
5531 			__FUNCTION__, sc->debug_pg_mbuf_alloc));
5532 
5533 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5534 }
5535 #endif /* BCE_USE_SPLIT_HEADER */
5536 
5537 
5538 /****************************************************************************/
5539 /* Set media options.                                                       */
5540 /*                                                                          */
5541 /* Returns:                                                                 */
5542 /*   0 for success, positive value for failure.                             */
5543 /****************************************************************************/
5544 static int
5545 bce_ifmedia_upd(struct ifnet *ifp)
5546 {
5547 	struct bce_softc *sc = ifp->if_softc;
5548 
5549 	DBENTER(BCE_VERBOSE);
5550 
5551 	BCE_LOCK(sc);
5552 	bce_ifmedia_upd_locked(ifp);
5553 	BCE_UNLOCK(sc);
5554 
5555 	DBEXIT(BCE_VERBOSE);
5556 	return (0);
5557 }
5558 
5559 
5560 /****************************************************************************/
5561 /* Set media options.                                                       */
5562 /*                                                                          */
5563 /* Returns:                                                                 */
5564 /*   Nothing.                                                               */
5565 /****************************************************************************/
5566 static void
5567 bce_ifmedia_upd_locked(struct ifnet *ifp)
5568 {
5569 	struct bce_softc *sc = ifp->if_softc;
5570 	struct mii_data *mii;
5571 
5572 	DBENTER(BCE_VERBOSE);
5573 
5574 	BCE_LOCK_ASSERT(sc);
5575 
5576 	mii = device_get_softc(sc->bce_miibus);
5577 
5578 	/* Make sure the MII bus has been enumerated. */
5579 	if (mii) {
5580 		sc->bce_link = 0;
5581 		if (mii->mii_instance) {
5582 			struct mii_softc *miisc;
5583 
5584 			LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
5585 				mii_phy_reset(miisc);
5586 		}
5587 		mii_mediachg(mii);
5588 	}
5589 
5590 	DBEXIT(BCE_VERBOSE);
5591 }
5592 
5593 
5594 /****************************************************************************/
5595 /* Reports current media status.                                            */
5596 /*                                                                          */
5597 /* Returns:                                                                 */
5598 /*   Nothing.                                                               */
5599 /****************************************************************************/
5600 static void
5601 bce_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
5602 {
5603 	struct bce_softc *sc = ifp->if_softc;
5604 	struct mii_data *mii;
5605 
5606 	DBENTER(BCE_VERBOSE);
5607 
5608 	BCE_LOCK(sc);
5609 
5610 	mii = device_get_softc(sc->bce_miibus);
5611 
5612 	mii_pollstat(mii);
5613 	ifmr->ifm_active = mii->mii_media_active;
5614 	ifmr->ifm_status = mii->mii_media_status;
5615 
5616 	BCE_UNLOCK(sc);
5617 
5618 	DBEXIT(BCE_VERBOSE);
5619 }
5620 
5621 
5622 /****************************************************************************/
5623 /* Handles PHY generated interrupt events.                                  */
5624 /*                                                                          */
5625 /* Returns:                                                                 */
5626 /*   Nothing.                                                               */
5627 /****************************************************************************/
5628 static void
5629 bce_phy_intr(struct bce_softc *sc)
5630 {
5631 	u32 new_link_state, old_link_state;
5632 
5633 	DBENTER(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
5634 
5635 	new_link_state = sc->status_block->status_attn_bits &
5636 		STATUS_ATTN_BITS_LINK_STATE;
5637 	old_link_state = sc->status_block->status_attn_bits_ack &
5638 		STATUS_ATTN_BITS_LINK_STATE;
5639 
5640 	/* Handle any changes if the link state has changed. */
5641 	if (new_link_state != old_link_state) {
5642 
5643 		/* Update the status_attn_bits_ack field in the status block. */
5644 		if (new_link_state) {
5645 			REG_WR(sc, BCE_PCICFG_STATUS_BIT_SET_CMD,
5646 				STATUS_ATTN_BITS_LINK_STATE);
5647 			DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now UP.\n",
5648 				__FUNCTION__);
5649 		}
5650 		else {
5651 			REG_WR(sc, BCE_PCICFG_STATUS_BIT_CLEAR_CMD,
5652 				STATUS_ATTN_BITS_LINK_STATE);
5653 			DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now DOWN.\n",
5654 				__FUNCTION__);
5655 		}
5656 
5657 		/*
5658 		 * Assume link is down and allow
5659 		 * tick routine to update the state
5660 		 * based on the actual media state.
5661 		 */
5662 		sc->bce_link = 0;
5663 		callout_stop(&sc->bce_tick_callout);
5664 		bce_tick(sc);
5665 	}
5666 
5667 	/* Acknowledge the link change interrupt. */
5668 	REG_WR(sc, BCE_EMAC_STATUS, BCE_EMAC_STATUS_LINK_CHANGE);
5669 
5670 	DBEXIT(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
5671 }
5672 
5673 
5674 /****************************************************************************/
5675 /* Reads the receive consumer value from the status block (skipping over    */
5676 /* chain page pointer if necessary).                                        */
5677 /*                                                                          */
5678 /* Returns:                                                                 */
5679 /*   hw_cons                                                                */
5680 /****************************************************************************/
5681 static inline u16
5682 bce_get_hw_rx_cons(struct bce_softc *sc)
5683 {
5684 	u16 hw_cons;
5685 
5686 	rmb();
5687 	hw_cons = sc->status_block->status_rx_quick_consumer_index0;
5688 	if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
5689 		hw_cons++;
5690 
5691 	return hw_cons;
5692 }
5693 
5694 /****************************************************************************/
5695 /* Handles received frame interrupt events.                                 */
5696 /*                                                                          */
5697 /* Returns:                                                                 */
5698 /*   Nothing.                                                               */
5699 /****************************************************************************/
5700 static void
5701 bce_rx_intr(struct bce_softc *sc)
5702 {
5703 	struct ifnet *ifp = sc->bce_ifp;
5704 	struct l2_fhdr *l2fhdr;
5705 	unsigned int pkt_len;
5706 	u16 sw_rx_cons, sw_rx_cons_idx, hw_rx_cons;
5707 	u32 status;
5708 #ifdef BCE_USE_SPLIT_HEADER
5709 	unsigned int rem_len;
5710 	u16 sw_pg_cons, sw_pg_cons_idx;
5711 #endif
5712 
5713 	DBENTER(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
5714 	DBRUN(sc->rx_interrupts++);
5715 	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): rx_prod = 0x%04X, "
5716 		"rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
5717 		__FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
5718 
5719 	/* Prepare the RX chain pages to be accessed by the host CPU. */
5720 	for (int i = 0; i < RX_PAGES; i++)
5721 		bus_dmamap_sync(sc->rx_bd_chain_tag,
5722 		    sc->rx_bd_chain_map[i], BUS_DMASYNC_POSTWRITE);
5723 
5724 #ifdef BCE_USE_SPLIT_HEADER
5725 	/* Prepare the page chain pages to be accessed by the host CPU. */
5726 	for (int i = 0; i < PG_PAGES; i++)
5727 		bus_dmamap_sync(sc->pg_bd_chain_tag,
5728 		    sc->pg_bd_chain_map[i], BUS_DMASYNC_POSTWRITE);
5729 #endif
5730 
5731 	/* Get the hardware's view of the RX consumer index. */
5732 	hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
5733 
5734 	/* Get working copies of the driver's view of the consumer indices. */
5735 	sw_rx_cons = sc->rx_cons;
5736 #ifdef BCE_USE_SPLIT_HEADER
5737 	sw_pg_cons = sc->pg_cons;
5738 #endif
5739 
5740 	/* Update some debug statistics counters */
5741 	DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
5742 		sc->rx_low_watermark = sc->free_rx_bd);
5743 	DBRUNIF((sc->free_rx_bd == sc->max_rx_bd), sc->rx_empty_count++);
5744 
5745 	/* Scan through the receive chain as long as there is work to do */
5746 	/* ToDo: Consider setting a limit on the number of packets processed. */
5747 	rmb();
5748 	while (sw_rx_cons != hw_rx_cons) {
5749 		struct mbuf *m0;
5750 
5751 		/* Convert the producer/consumer indices to an actual rx_bd index. */
5752 		sw_rx_cons_idx = RX_CHAIN_IDX(sw_rx_cons);
5753 
5754 		/* Unmap the mbuf from DMA space. */
5755 		bus_dmamap_sync(sc->rx_mbuf_tag,
5756 		    sc->rx_mbuf_map[sw_rx_cons_idx],
5757 	    	BUS_DMASYNC_POSTREAD);
5758 		bus_dmamap_unload(sc->rx_mbuf_tag,
5759 		    sc->rx_mbuf_map[sw_rx_cons_idx]);
5760 
5761 		/* Remove the mbuf from the RX chain. */
5762 		m0 = sc->rx_mbuf_ptr[sw_rx_cons_idx];
5763 		sc->rx_mbuf_ptr[sw_rx_cons_idx] = NULL;
5764 		DBRUN(sc->debug_rx_mbuf_alloc--);
5765 		sc->free_rx_bd++;
5766 
5767 		/*
5768 		 * Frames received on the NetXteme II are prepended
5769 		 * with an l2_fhdr structure which provides status
5770 		 * information about the received frame (including
5771 		 * VLAN tags and checksum info).  The frames are also
5772 		 * automatically adjusted to align the IP header
5773 		 * (i.e. two null bytes are inserted before the
5774 		 * Ethernet header).  As a result the data DMA'd by
5775 		 * the controller into the mbuf is as follows:
5776 		 * +---------+-----+---------------------+-----+
5777 		 * | l2_fhdr | pad | packet data         | FCS |
5778 		 * +---------+-----+---------------------+-----+
5779 		 * The l2_fhdr needs to be checked and skipped and
5780 		 * the FCS needs to be stripped before sending the
5781 		 * packet up the stack.
5782 		 */
5783 		l2fhdr  = mtod(m0, struct l2_fhdr *);
5784 
5785 		/* Get the packet data + FCS length and the status. */
5786 		pkt_len = l2fhdr->l2_fhdr_pkt_len;
5787 		status  = l2fhdr->l2_fhdr_status;
5788 
5789 		/*
5790 		 * Skip over the l2_fhdr and pad, resulting in the
5791 		 * following data in the mbuf:
5792 		 * +---------------------+-----+
5793 		 * | packet data         | FCS |
5794 		 * +---------------------+-----+
5795 		 */
5796 		m_adj(m0, sizeof(struct l2_fhdr) + ETHER_ALIGN);
5797 
5798 #ifdef BCE_USE_SPLIT_HEADER
5799 		/*
5800 		 * Check whether the received frame fits in a single
5801 		 * mbuf or not (i.e. packet data + FCS <=
5802 		 * sc->rx_bd_mbuf_data_len bytes).
5803 		 */
5804 		if (pkt_len > m0->m_len) {
5805 			/*
5806 			 * The received frame is larger than a single mbuf.
5807 			 * If the frame was a TCP frame then only the TCP
5808 			 * header is placed in the mbuf, the remaining
5809 			 * payload (including FCS) is placed in the page
5810 			 * chain, the SPLIT flag is set, and the header
5811 			 * length is placed in the IP checksum field.
5812 			 * If the frame is not a TCP frame then the mbuf
5813 			 * is filled and the remaining bytes are placed
5814 			 * in the page chain.
5815 			 */
5816 
5817 			DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a large packet.\n",
5818 				__FUNCTION__);
5819 
5820 			/*
5821 			 * When the page chain is enabled and the TCP
5822 			 * header has been split from the TCP payload,
5823 			 * the ip_xsum structure will reflect the length
5824 			 * of the TCP header, not the IP checksum.  Set
5825 			 * the packet length of the mbuf accordingly.
5826 			 */
5827 		 	if (status & L2_FHDR_STATUS_SPLIT)
5828 				m0->m_len = l2fhdr->l2_fhdr_ip_xsum;
5829 
5830 			rem_len = pkt_len - m0->m_len;
5831 
5832 			/* Pull mbufs off the page chain for the remaining data. */
5833 			while (rem_len > 0) {
5834 				struct mbuf *m_pg;
5835 
5836 				sw_pg_cons_idx = PG_CHAIN_IDX(sw_pg_cons);
5837 
5838 				/* Remove the mbuf from the page chain. */
5839 				m_pg = sc->pg_mbuf_ptr[sw_pg_cons_idx];
5840 				sc->pg_mbuf_ptr[sw_pg_cons_idx] = NULL;
5841 				DBRUN(sc->debug_pg_mbuf_alloc--);
5842 				sc->free_pg_bd++;
5843 
5844 				/* Unmap the page chain mbuf from DMA space. */
5845 				bus_dmamap_sync(sc->pg_mbuf_tag,
5846 					sc->pg_mbuf_map[sw_pg_cons_idx],
5847 					BUS_DMASYNC_POSTREAD);
5848 				bus_dmamap_unload(sc->pg_mbuf_tag,
5849 					sc->pg_mbuf_map[sw_pg_cons_idx]);
5850 
5851 				/* Adjust the mbuf length. */
5852 				if (rem_len < m_pg->m_len) {
5853 					/* The mbuf chain is complete. */
5854 					m_pg->m_len = rem_len;
5855 					rem_len = 0;
5856 				} else {
5857 					/* More packet data is waiting. */
5858 					rem_len -= m_pg->m_len;
5859 				}
5860 
5861 				/* Concatenate the mbuf cluster to the mbuf. */
5862 				m_cat(m0, m_pg);
5863 
5864 				sw_pg_cons = NEXT_PG_BD(sw_pg_cons);
5865 			}
5866 
5867 			/* Set the total packet length. */
5868 			m0->m_pkthdr.len = pkt_len;
5869 
5870 		} else {
5871 			/*
5872 			 * The received packet is small and fits in a
5873 			 * single mbuf (i.e. the l2_fhdr + pad + packet +
5874 			 * FCS <= MHLEN).  In other words, the packet is
5875 			 * 154 bytes or less in size.
5876 			 */
5877 
5878 			DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a small packet.\n",
5879 				__FUNCTION__);
5880 
5881 			/* Set the total packet length. */
5882 			m0->m_pkthdr.len = m0->m_len = pkt_len;
5883 		}
5884 #endif
5885 
5886 		/* Remove the trailing Ethernet FCS. */
5887 		m_adj(m0, -ETHER_CRC_LEN);
5888 
5889 		/* Check that the resulting mbuf chain is valid. */
5890 		DBRUN(m_sanity(m0, FALSE));
5891 		DBRUNIF(((m0->m_len < ETHER_HDR_LEN) |
5892 			(m0->m_pkthdr.len > BCE_MAX_JUMBO_ETHER_MTU_VLAN)),
5893 			BCE_PRINTF("Invalid Ethernet frame size!\n");
5894 			m_print(m0, 128));
5895 
5896 		DBRUNIF(DB_RANDOMTRUE(bce_debug_l2fhdr_status_check),
5897 			BCE_PRINTF("Simulating l2_fhdr status error.\n");
5898 			status = status | L2_FHDR_ERRORS_PHY_DECODE);
5899 
5900 		/* Check the received frame for errors. */
5901 		if (status & (L2_FHDR_ERRORS_BAD_CRC |
5902 			L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT |
5903 			L2_FHDR_ERRORS_TOO_SHORT  | L2_FHDR_ERRORS_GIANT_FRAME)) {
5904 
5905 			/* Log the error and release the mbuf. */
5906 			ifp->if_ierrors++;
5907 			DBRUN(sc->l2fhdr_status_errors++);
5908 
5909 			m_freem(m0);
5910 			m0 = NULL;
5911 			goto bce_rx_int_next_rx;
5912 		}
5913 
5914 		/* Send the packet to the appropriate interface. */
5915 		m0->m_pkthdr.rcvif = ifp;
5916 
5917 		/* Assume no hardware checksum. */
5918 		m0->m_pkthdr.csum_flags = 0;
5919 
5920 		/* Validate the checksum if offload enabled. */
5921 		if (ifp->if_capenable & IFCAP_RXCSUM) {
5922 
5923 			/* Check for an IP datagram. */
5924 		 	if (!(status & L2_FHDR_STATUS_SPLIT) &&
5925 				(status & L2_FHDR_STATUS_IP_DATAGRAM)) {
5926 				m0->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
5927 
5928 				/* Check if the IP checksum is valid. */
5929 				if ((l2fhdr->l2_fhdr_ip_xsum ^ 0xffff) == 0)
5930 					m0->m_pkthdr.csum_flags |= CSUM_IP_VALID;
5931 			}
5932 
5933 			/* Check for a valid TCP/UDP frame. */
5934 			if (status & (L2_FHDR_STATUS_TCP_SEGMENT |
5935 				L2_FHDR_STATUS_UDP_DATAGRAM)) {
5936 
5937 				/* Check for a good TCP/UDP checksum. */
5938 				if ((status & (L2_FHDR_ERRORS_TCP_XSUM |
5939 					      L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
5940 					m0->m_pkthdr.csum_data =
5941 					    l2fhdr->l2_fhdr_tcp_udp_xsum;
5942 					m0->m_pkthdr.csum_flags |= (CSUM_DATA_VALID
5943 						| CSUM_PSEUDO_HDR);
5944 				}
5945 			}
5946 		}
5947 
5948 		/*
5949 		 * If we received a packet with a vlan tag,
5950 		 * attach that information to the packet.
5951 		 */
5952 		if (status & L2_FHDR_STATUS_L2_VLAN_TAG) {
5953 #if __FreeBSD_version < 700000
5954 			VLAN_INPUT_TAG(ifp, m0, l2fhdr->l2_fhdr_vlan_tag, continue);
5955 #else
5956 			m0->m_pkthdr.ether_vtag = l2fhdr->l2_fhdr_vlan_tag;
5957 			m0->m_flags |= M_VLANTAG;
5958 #endif
5959 		}
5960 
5961 		/* Pass the mbuf off to the upper layers. */
5962 		ifp->if_ipackets++;
5963 
5964 bce_rx_int_next_rx:
5965 		sw_rx_cons = NEXT_RX_BD(sw_rx_cons);
5966 
5967 		/* If we have a packet, pass it up the stack */
5968 		if (m0) {
5969 			/* Make sure we don't lose our place when we release the lock. */
5970 			sc->rx_cons = sw_rx_cons;
5971 #ifdef BCE_USE_SPLIT_HEADER
5972 			sc->pg_cons = sw_pg_cons;
5973 #endif
5974 
5975 			BCE_UNLOCK(sc);
5976 			(*ifp->if_input)(ifp, m0);
5977 			BCE_LOCK(sc);
5978 
5979 			/* Recover our place. */
5980 			sw_rx_cons = sc->rx_cons;
5981 #ifdef BCE_USE_SPLIT_HEADER
5982 			sw_pg_cons = sc->pg_cons;
5983 #endif
5984 		}
5985 
5986 		/* Refresh hw_cons to see if there's new work */
5987 		if (sw_rx_cons == hw_rx_cons)
5988 			hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
5989 	}
5990 
5991 	/* No new packets to process.  Refill the RX and page chains and exit. */
5992 #ifdef BCE_USE_SPLIT_HEADER
5993 	sc->pg_cons = sw_pg_cons;
5994 	bce_fill_pg_chain(sc);
5995 #endif
5996 
5997 	sc->rx_cons = sw_rx_cons;
5998 	bce_fill_rx_chain(sc);
5999 
6000 	for (int i = 0; i < RX_PAGES; i++)
6001 		bus_dmamap_sync(sc->rx_bd_chain_tag,
6002 		    sc->rx_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
6003 
6004 #ifdef BCE_USE_SPLIT_HEADER
6005 	for (int i = 0; i < PG_PAGES; i++)
6006 		bus_dmamap_sync(sc->pg_bd_chain_tag,
6007 		    sc->pg_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
6008 #endif
6009 
6010 	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): rx_prod = 0x%04X, "
6011 		"rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
6012 		__FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
6013 	DBEXIT(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
6014 }
6015 
6016 
6017 /****************************************************************************/
6018 /* Reads the transmit consumer value from the status block (skipping over   */
6019 /* chain page pointer if necessary).                                        */
6020 /*                                                                          */
6021 /* Returns:                                                                 */
6022 /*   hw_cons                                                                */
6023 /****************************************************************************/
6024 static inline u16
6025 bce_get_hw_tx_cons(struct bce_softc *sc)
6026 {
6027 	u16 hw_cons;
6028 
6029 	mb();
6030 	hw_cons = sc->status_block->status_tx_quick_consumer_index0;
6031 	if ((hw_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
6032 		hw_cons++;
6033 
6034 	return hw_cons;
6035 }
6036 
6037 
6038 /****************************************************************************/
6039 /* Handles transmit completion interrupt events.                            */
6040 /*                                                                          */
6041 /* Returns:                                                                 */
6042 /*   Nothing.                                                               */
6043 /****************************************************************************/
6044 static void
6045 bce_tx_intr(struct bce_softc *sc)
6046 {
6047 	struct ifnet *ifp = sc->bce_ifp;
6048 	u16 hw_tx_cons, sw_tx_cons, sw_tx_chain_cons;
6049 
6050 	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
6051 	DBRUN(sc->tx_interrupts++);
6052 	DBPRINT(sc, BCE_EXTREME_SEND, "%s(enter): tx_prod = 0x%04X, "
6053 		"tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
6054 		__FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
6055 
6056 	BCE_LOCK_ASSERT(sc);
6057 
6058 	/* Get the hardware's view of the TX consumer index. */
6059 	hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
6060 	sw_tx_cons = sc->tx_cons;
6061 
6062 	/* Prevent speculative reads from getting ahead of the status block. */
6063 	bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
6064 		BUS_SPACE_BARRIER_READ);
6065 
6066 	/* Cycle through any completed TX chain page entries. */
6067 	while (sw_tx_cons != hw_tx_cons) {
6068 #ifdef BCE_DEBUG
6069 		struct tx_bd *txbd = NULL;
6070 #endif
6071 		sw_tx_chain_cons = TX_CHAIN_IDX(sw_tx_cons);
6072 
6073 		DBPRINT(sc, BCE_INFO_SEND,
6074 			"%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, "
6075 			"sw_tx_chain_cons = 0x%04X\n",
6076 			__FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
6077 
6078 		DBRUNIF((sw_tx_chain_cons > MAX_TX_BD),
6079 			BCE_PRINTF("%s(%d): TX chain consumer out of range! "
6080 				" 0x%04X > 0x%04X\n", __FILE__, __LINE__, sw_tx_chain_cons,
6081 				(int) MAX_TX_BD);
6082 			bce_breakpoint(sc));
6083 
6084 		DBRUN(txbd = &sc->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)]
6085 				[TX_IDX(sw_tx_chain_cons)]);
6086 
6087 		DBRUNIF((txbd == NULL),
6088 			BCE_PRINTF("%s(%d): Unexpected NULL tx_bd[0x%04X]!\n",
6089 				__FILE__, __LINE__, sw_tx_chain_cons);
6090 			bce_breakpoint(sc));
6091 
6092 		DBRUNMSG(BCE_INFO_SEND, BCE_PRINTF("%s(): ", __FUNCTION__);
6093 			bce_dump_txbd(sc, sw_tx_chain_cons, txbd));
6094 
6095 		/*
6096 		 * Free the associated mbuf. Remember
6097 		 * that only the last tx_bd of a packet
6098 		 * has an mbuf pointer and DMA map.
6099 		 */
6100 		if (sc->tx_mbuf_ptr[sw_tx_chain_cons] != NULL) {
6101 
6102 			/* Validate that this is the last tx_bd. */
6103 			DBRUNIF((!(txbd->tx_bd_flags & TX_BD_FLAGS_END)),
6104 				BCE_PRINTF("%s(%d): tx_bd END flag not set but "
6105 				"txmbuf == NULL!\n", __FILE__, __LINE__);
6106 				bce_breakpoint(sc));
6107 
6108 			DBRUNMSG(BCE_INFO_SEND,
6109 				BCE_PRINTF("%s(): Unloading map/freeing mbuf "
6110 					"from tx_bd[0x%04X]\n", __FUNCTION__, sw_tx_chain_cons));
6111 
6112 			/* Unmap the mbuf. */
6113 			bus_dmamap_unload(sc->tx_mbuf_tag,
6114 			    sc->tx_mbuf_map[sw_tx_chain_cons]);
6115 
6116 			/* Free the mbuf. */
6117 			m_freem(sc->tx_mbuf_ptr[sw_tx_chain_cons]);
6118 			sc->tx_mbuf_ptr[sw_tx_chain_cons] = NULL;
6119 			DBRUN(sc->debug_tx_mbuf_alloc--);
6120 
6121 			ifp->if_opackets++;
6122 		}
6123 
6124 		sc->used_tx_bd--;
6125 		sw_tx_cons = NEXT_TX_BD(sw_tx_cons);
6126 
6127 		/* Refresh hw_cons to see if there's new work. */
6128 		hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
6129 
6130 		/* Prevent speculative reads from getting ahead of the status block. */
6131 		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
6132 			BUS_SPACE_BARRIER_READ);
6133 	}
6134 
6135 	/* Clear the TX timeout timer. */
6136 	sc->watchdog_timer = 0;
6137 
6138 	/* Clear the tx hardware queue full flag. */
6139 	if (sc->used_tx_bd < sc->max_tx_bd) {
6140 		DBRUNIF((ifp->if_drv_flags & IFF_DRV_OACTIVE),
6141 			DBPRINT(sc, BCE_INFO_SEND,
6142 				"%s(): Open TX chain! %d/%d (used/total)\n",
6143 				__FUNCTION__, sc->used_tx_bd, sc->max_tx_bd));
6144 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
6145 	}
6146 
6147 	sc->tx_cons = sw_tx_cons;
6148 
6149 	DBPRINT(sc, BCE_EXTREME_SEND, "%s(exit): tx_prod = 0x%04X, "
6150 		"tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
6151 		__FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
6152 	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
6153 }
6154 
6155 
6156 /****************************************************************************/
6157 /* Disables interrupt generation.                                           */
6158 /*                                                                          */
6159 /* Returns:                                                                 */
6160 /*   Nothing.                                                               */
6161 /****************************************************************************/
6162 static void
6163 bce_disable_intr(struct bce_softc *sc)
6164 {
6165 	DBENTER(BCE_VERBOSE_INTR);
6166 
6167 	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_MASK_INT);
6168 	REG_RD(sc, BCE_PCICFG_INT_ACK_CMD);
6169 
6170 	DBEXIT(BCE_VERBOSE_INTR);
6171 }
6172 
6173 
6174 /****************************************************************************/
6175 /* Enables interrupt generation.                                            */
6176 /*                                                                          */
6177 /* Returns:                                                                 */
6178 /*   Nothing.                                                               */
6179 /****************************************************************************/
6180 static void
6181 bce_enable_intr(struct bce_softc *sc, int coal_now)
6182 {
6183 	DBENTER(BCE_VERBOSE_INTR);
6184 
6185 	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
6186 	       BCE_PCICFG_INT_ACK_CMD_INDEX_VALID |
6187 	       BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
6188 
6189 	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
6190 	       BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
6191 
6192 	/* Force an immediate interrupt (whether there is new data or not). */
6193 	if (coal_now)
6194 		REG_WR(sc, BCE_HC_COMMAND, sc->hc_command | BCE_HC_COMMAND_COAL_NOW);
6195 
6196 	DBEXIT(BCE_VERBOSE_INTR);
6197 }
6198 
6199 
6200 /****************************************************************************/
6201 /* Handles controller initialization.                                       */
6202 /*                                                                          */
6203 /* Returns:                                                                 */
6204 /*   Nothing.                                                               */
6205 /****************************************************************************/
6206 static void
6207 bce_init_locked(struct bce_softc *sc)
6208 {
6209 	struct ifnet *ifp;
6210 	u32 ether_mtu = 0;
6211 
6212 	DBENTER(BCE_VERBOSE_RESET);
6213 
6214 	BCE_LOCK_ASSERT(sc);
6215 
6216 	ifp = sc->bce_ifp;
6217 
6218 	/* Check if the driver is still running and bail out if it is. */
6219 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
6220 		goto bce_init_locked_exit;
6221 
6222 	bce_stop(sc);
6223 
6224 	if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
6225 		BCE_PRINTF("%s(%d): Controller reset failed!\n",
6226 			__FILE__, __LINE__);
6227 		goto bce_init_locked_exit;
6228 	}
6229 
6230 	if (bce_chipinit(sc)) {
6231 		BCE_PRINTF("%s(%d): Controller initialization failed!\n",
6232 			__FILE__, __LINE__);
6233 		goto bce_init_locked_exit;
6234 	}
6235 
6236 	if (bce_blockinit(sc)) {
6237 		BCE_PRINTF("%s(%d): Block initialization failed!\n",
6238 			__FILE__, __LINE__);
6239 		goto bce_init_locked_exit;
6240 	}
6241 
6242 	/* Load our MAC address. */
6243 	bcopy(IF_LLADDR(sc->bce_ifp), sc->eaddr, ETHER_ADDR_LEN);
6244 	bce_set_mac_addr(sc);
6245 
6246 	/*
6247 	 * Calculate and program the hardware Ethernet MTU
6248 	 * size. Be generous on the receive if we have room.
6249 	 */
6250 #ifdef BCE_USE_SPLIT_HEADER
6251 	if (ifp->if_mtu <= (sc->rx_bd_mbuf_data_len + sc->pg_bd_mbuf_alloc_size))
6252 		ether_mtu = sc->rx_bd_mbuf_data_len + sc->pg_bd_mbuf_alloc_size;
6253 #else
6254 	if (ifp->if_mtu <= sc->rx_bd_mbuf_data_len)
6255 		ether_mtu = sc->rx_bd_mbuf_data_len;
6256 #endif
6257 	else
6258 		ether_mtu = ifp->if_mtu;
6259 
6260 	ether_mtu += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN;
6261 
6262 	DBPRINT(sc, BCE_INFO_MISC, "%s(): setting h/w mtu = %d\n", __FUNCTION__,
6263 		ether_mtu);
6264 
6265 	/* Program the mtu, enabling jumbo frame support if necessary. */
6266 	if (ether_mtu > (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN))
6267 		REG_WR(sc, BCE_EMAC_RX_MTU_SIZE,
6268 			min(ether_mtu, BCE_MAX_JUMBO_ETHER_MTU) |
6269 			BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA);
6270 	else
6271 		REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu);
6272 
6273 	DBPRINT(sc, BCE_INFO_LOAD,
6274 		"%s(): rx_bd_mbuf_alloc_size = %d, rx_bce_mbuf_data_len = %d, "
6275 		"rx_bd_mbuf_align_pad = %d, pg_bd_mbuf_alloc_size = %d\n",
6276 		__FUNCTION__, sc->rx_bd_mbuf_alloc_size, sc->rx_bd_mbuf_data_len,
6277 		sc->rx_bd_mbuf_align_pad, sc->pg_bd_mbuf_alloc_size);
6278 
6279 	/* Program appropriate promiscuous/multicast filtering. */
6280 	bce_set_rx_mode(sc);
6281 
6282 #ifdef BCE_USE_SPLIT_HEADER
6283 	/* Init page buffer descriptor chain. */
6284 	bce_init_pg_chain(sc);
6285 #endif
6286 
6287 	/* Init RX buffer descriptor chain. */
6288 	bce_init_rx_chain(sc);
6289 
6290 	/* Init TX buffer descriptor chain. */
6291 	bce_init_tx_chain(sc);
6292 
6293 	/* Enable host interrupts. */
6294 	bce_enable_intr(sc, 1);
6295 
6296 	bce_ifmedia_upd_locked(ifp);
6297 
6298 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
6299 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
6300 
6301 	callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
6302 
6303 bce_init_locked_exit:
6304 	DBEXIT(BCE_VERBOSE_RESET);
6305 }
6306 
6307 
6308 /****************************************************************************/
6309 /* Initialize the controller just enough so that any management firmware    */
6310 /* running on the device will continue to operate correctly.                */
6311 /*                                                                          */
6312 /* Returns:                                                                 */
6313 /*   Nothing.                                                               */
6314 /****************************************************************************/
6315 static void
6316 bce_mgmt_init_locked(struct bce_softc *sc)
6317 {
6318 	struct ifnet *ifp;
6319 
6320 	DBENTER(BCE_VERBOSE_RESET);
6321 
6322 	BCE_LOCK_ASSERT(sc);
6323 
6324 	/* Bail out if management firmware is not running. */
6325 	if (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)) {
6326 		DBPRINT(sc, BCE_VERBOSE_SPECIAL,
6327 			"No management firmware running...\n");
6328 		goto bce_mgmt_init_locked_exit;
6329 	}
6330 
6331 	ifp = sc->bce_ifp;
6332 
6333 	/* Enable all critical blocks in the MAC. */
6334 	REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT);
6335 	REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
6336 	DELAY(20);
6337 
6338 	bce_ifmedia_upd_locked(ifp);
6339 
6340 bce_mgmt_init_locked_exit:
6341 	DBEXIT(BCE_VERBOSE_RESET);
6342 }
6343 
6344 
6345 /****************************************************************************/
6346 /* Handles controller initialization when called from an unlocked routine.  */
6347 /*                                                                          */
6348 /* Returns:                                                                 */
6349 /*   Nothing.                                                               */
6350 /****************************************************************************/
6351 static void
6352 bce_init(void *xsc)
6353 {
6354 	struct bce_softc *sc = xsc;
6355 
6356 	DBENTER(BCE_VERBOSE_RESET);
6357 
6358 	BCE_LOCK(sc);
6359 	bce_init_locked(sc);
6360 	BCE_UNLOCK(sc);
6361 
6362 	DBEXIT(BCE_VERBOSE_RESET);
6363 }
6364 
6365 
6366 /****************************************************************************/
6367 /* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
6368 /* memory visible to the controller.                                        */
6369 /*                                                                          */
6370 /* Returns:                                                                 */
6371 /*   0 for success, positive value for failure.                             */
6372 /* Modified:                                                                */
6373 /*   m_head: May be set to NULL if MBUF is excessively fragmented.          */
6374 /****************************************************************************/
6375 static int
6376 bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
6377 {
6378 	bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
6379 	bus_dmamap_t map;
6380 	struct tx_bd *txbd = NULL;
6381 	struct mbuf *m0;
6382 	struct ether_vlan_header *eh;
6383 	struct ip *ip;
6384 	struct tcphdr *th;
6385 	u16 prod, chain_prod, etype, mss = 0, vlan_tag = 0, flags = 0;
6386 	u32 prod_bseq;
6387 	int hdr_len = 0, e_hlen = 0, ip_hlen = 0, tcp_hlen = 0, ip_len = 0;
6388 
6389 #ifdef BCE_DEBUG
6390 	u16 debug_prod;
6391 #endif
6392 	int i, error, nsegs, rc = 0;
6393 
6394 	DBENTER(BCE_VERBOSE_SEND);
6395 	DBPRINT(sc, BCE_INFO_SEND,
6396 		"%s(enter): tx_prod = 0x%04X, tx_chain_prod = %04X, "
6397 		"tx_prod_bseq = 0x%08X\n",
6398 		__FUNCTION__, sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod),
6399 		sc->tx_prod_bseq);
6400 
6401 	/* Transfer any checksum offload flags to the bd. */
6402 	m0 = *m_head;
6403 	if (m0->m_pkthdr.csum_flags) {
6404 		if (m0->m_pkthdr.csum_flags & CSUM_IP)
6405 			flags |= TX_BD_FLAGS_IP_CKSUM;
6406 		if (m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
6407 			flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
6408 		if (m0->m_pkthdr.csum_flags & CSUM_TSO) {
6409 			/* For TSO the controller needs two pieces of info, */
6410 			/* the MSS and the IP+TCP options length.           */
6411 			mss = htole16(m0->m_pkthdr.tso_segsz);
6412 
6413 			/* Map the header and find the Ethernet type & header length */
6414 			eh = mtod(m0, struct ether_vlan_header *);
6415 			if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
6416 				etype = ntohs(eh->evl_proto);
6417 				e_hlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
6418 			} else {
6419 				etype = ntohs(eh->evl_encap_proto);
6420 				e_hlen = ETHER_HDR_LEN;
6421 			}
6422 
6423 			/* Check for supported TSO Ethernet types (only IPv4 for now) */
6424 			switch (etype) {
6425 				case ETHERTYPE_IP:
6426 					ip = (struct ip *)(m0->m_data + e_hlen);
6427 
6428 					/* TSO only supported for TCP protocol */
6429 					if (ip->ip_p != IPPROTO_TCP) {
6430 						BCE_PRINTF("%s(%d): TSO enabled for non-TCP frame!.\n",
6431 							__FILE__, __LINE__);
6432 						goto bce_tx_encap_skip_tso;
6433 					}
6434 
6435 					/* Get IP header length in bytes (min 20) */
6436 					ip_hlen = ip->ip_hl << 2;
6437 
6438 					/* Get the TCP header length in bytes (min 20) */
6439 					th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
6440 					tcp_hlen = (th->th_off << 2);
6441 
6442 					/* IP header length and checksum will be calc'd by hardware */
6443 					ip_len = ip->ip_len;
6444 					ip->ip_len = 0;
6445 					ip->ip_sum = 0;
6446 					break;
6447 				case ETHERTYPE_IPV6:
6448 					BCE_PRINTF("%s(%d): TSO over IPv6 not supported!.\n",
6449 						__FILE__, __LINE__);
6450 					goto bce_tx_encap_skip_tso;
6451 				default:
6452 					BCE_PRINTF("%s(%d): TSO enabled for unsupported protocol!.\n",
6453 						__FILE__, __LINE__);
6454 					goto bce_tx_encap_skip_tso;
6455 			}
6456 
6457 			hdr_len = e_hlen + ip_hlen + tcp_hlen;
6458 
6459 			DBPRINT(sc, BCE_EXTREME_SEND,
6460 				"%s(): hdr_len = %d, e_hlen = %d, ip_hlen = %d, tcp_hlen = %d, ip_len = %d\n",
6461 				 __FUNCTION__, hdr_len, e_hlen, ip_hlen, tcp_hlen, ip_len);
6462 
6463 			/* Set the LSO flag in the TX BD */
6464 			flags |= TX_BD_FLAGS_SW_LSO;
6465 			/* Set the length of IP + TCP options (in 32 bit words) */
6466 			flags |= (((ip_hlen + tcp_hlen - 40) >> 2) << 8);
6467 
6468 bce_tx_encap_skip_tso:
6469 			DBRUN(sc->requested_tso_frames++);
6470 		}
6471 	}
6472 
6473 	/* Transfer any VLAN tags to the bd. */
6474 	if (m0->m_flags & M_VLANTAG) {
6475 		flags |= TX_BD_FLAGS_VLAN_TAG;
6476 		vlan_tag = m0->m_pkthdr.ether_vtag;
6477 	}
6478 
6479 	/* Map the mbuf into DMAable memory. */
6480 	prod = sc->tx_prod;
6481 	chain_prod = TX_CHAIN_IDX(prod);
6482 	map = sc->tx_mbuf_map[chain_prod];
6483 
6484 	/* Map the mbuf into our DMA address space. */
6485 	error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag, map, m0,
6486 	    segs, &nsegs, BUS_DMA_NOWAIT);
6487 
6488 	/* Check if the DMA mapping was successful */
6489 	if (error == EFBIG) {
6490 
6491 		/* The mbuf is too fragmented for our DMA mapping. */
6492    		DBPRINT(sc, BCE_WARN, "%s(): fragmented mbuf (%d pieces)\n",
6493 			__FUNCTION__, nsegs);
6494 		DBRUN(bce_dump_mbuf(sc, m0););
6495 
6496 		/* Try to defrag the mbuf. */
6497 		m0 = m_defrag(*m_head, M_DONTWAIT);
6498 		if (m0 == NULL) {
6499 			/* Defrag was unsuccessful */
6500 			m_freem(*m_head);
6501 			*m_head = NULL;
6502 			sc->mbuf_alloc_failed++;
6503 			rc = ENOBUFS;
6504 			goto bce_tx_encap_exit;
6505 		}
6506 
6507 		/* Defrag was successful, try mapping again */
6508 		*m_head = m0;
6509 		error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag, map, m0,
6510 		    segs, &nsegs, BUS_DMA_NOWAIT);
6511 
6512 		/* Still getting an error after a defrag. */
6513 		if (error == ENOMEM) {
6514 			/* Insufficient DMA buffers available. */
6515 			sc->tx_dma_map_failures++;
6516 			rc = error;
6517 			goto bce_tx_encap_exit;
6518 		} else if (error != 0) {
6519 			/* Still can't map the mbuf, release it and return an error. */
6520 			BCE_PRINTF(
6521 			    "%s(%d): Unknown error mapping mbuf into TX chain!\n",
6522 			    __FILE__, __LINE__);
6523 			m_freem(m0);
6524 			*m_head = NULL;
6525 			sc->tx_dma_map_failures++;
6526 			rc = ENOBUFS;
6527 			goto bce_tx_encap_exit;
6528 		}
6529 	} else if (error == ENOMEM) {
6530 		/* Insufficient DMA buffers available. */
6531 		sc->tx_dma_map_failures++;
6532 		rc = error;
6533 		goto bce_tx_encap_exit;
6534 	} else if (error != 0) {
6535 		m_freem(m0);
6536 		*m_head = NULL;
6537 		sc->tx_dma_map_failures++;
6538 		rc = error;
6539 		goto bce_tx_encap_exit;
6540 	}
6541 
6542 	/* Make sure there's room in the chain */
6543 	if (nsegs > (sc->max_tx_bd - sc->used_tx_bd)) {
6544 		bus_dmamap_unload(sc->tx_mbuf_tag, map);
6545 		rc = ENOBUFS;
6546 		goto bce_tx_encap_exit;
6547 	}
6548 
6549 	/* prod points to an empty tx_bd at this point. */
6550 	prod_bseq  = sc->tx_prod_bseq;
6551 
6552 #ifdef BCE_DEBUG
6553 	debug_prod = chain_prod;
6554 #endif
6555 
6556 	DBPRINT(sc, BCE_INFO_SEND,
6557 		"%s(start): prod = 0x%04X, chain_prod = 0x%04X, "
6558 		"prod_bseq = 0x%08X\n",
6559 		__FUNCTION__, prod, chain_prod, prod_bseq);
6560 
6561 	/*
6562 	 * Cycle through each mbuf segment that makes up
6563 	 * the outgoing frame, gathering the mapping info
6564 	 * for that segment and creating a tx_bd for
6565 	 * the mbuf.
6566 	 */
6567 	for (i = 0; i < nsegs ; i++) {
6568 
6569 		chain_prod = TX_CHAIN_IDX(prod);
6570 		txbd= &sc->tx_bd_chain[TX_PAGE(chain_prod)][TX_IDX(chain_prod)];
6571 
6572 		txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(segs[i].ds_addr));
6573 		txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(segs[i].ds_addr));
6574 		txbd->tx_bd_mss_nbytes = htole32(mss << 16) | htole16(segs[i].ds_len);
6575 		txbd->tx_bd_vlan_tag = htole16(vlan_tag);
6576 		txbd->tx_bd_flags = htole16(flags);
6577 		prod_bseq += segs[i].ds_len;
6578 		if (i == 0)
6579 			txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_START);
6580 		prod = NEXT_TX_BD(prod);
6581 	}
6582 
6583 	/* Set the END flag on the last TX buffer descriptor. */
6584 	txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_END);
6585 
6586 	DBRUNMSG(BCE_EXTREME_SEND, bce_dump_tx_chain(sc, debug_prod, nsegs));
6587 
6588 	DBPRINT(sc, BCE_INFO_SEND,
6589 		"%s( end ): prod = 0x%04X, chain_prod = 0x%04X, "
6590 		"prod_bseq = 0x%08X\n",
6591 		__FUNCTION__, prod, chain_prod, prod_bseq);
6592 
6593 	/*
6594 	 * Ensure that the mbuf pointer for this transmission
6595 	 * is placed at the array index of the last
6596 	 * descriptor in this chain.  This is done
6597 	 * because a single map is used for all
6598 	 * segments of the mbuf and we don't want to
6599 	 * unload the map before all of the segments
6600 	 * have been freed.
6601 	 */
6602 	sc->tx_mbuf_ptr[chain_prod] = m0;
6603 	sc->used_tx_bd += nsegs;
6604 
6605 	/* Update some debug statistic counters */
6606 	DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
6607 		sc->tx_hi_watermark = sc->used_tx_bd);
6608 	DBRUNIF((sc->used_tx_bd == sc->max_tx_bd), sc->tx_full_count++);
6609 	DBRUNIF(sc->debug_tx_mbuf_alloc++);
6610 
6611 	DBRUNMSG(BCE_EXTREME_SEND, bce_dump_tx_mbuf_chain(sc, chain_prod, 1));
6612 
6613 	/* prod points to the next free tx_bd at this point. */
6614 	sc->tx_prod = prod;
6615 	sc->tx_prod_bseq = prod_bseq;
6616 
6617 	DBPRINT(sc, BCE_INFO_SEND,
6618 		"%s(exit): prod = 0x%04X, chain_prod = %04X, "
6619 		"prod_bseq = 0x%08X\n",
6620 		__FUNCTION__, sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod),
6621 		sc->tx_prod_bseq);
6622 
6623 bce_tx_encap_exit:
6624 	DBEXIT(BCE_VERBOSE_SEND);
6625 	return(rc);
6626 }
6627 
6628 
6629 /****************************************************************************/
6630 /* Main transmit routine when called from another routine with a lock.      */
6631 /*                                                                          */
6632 /* Returns:                                                                 */
6633 /*   Nothing.                                                               */
6634 /****************************************************************************/
6635 static void
6636 bce_start_locked(struct ifnet *ifp)
6637 {
6638 	struct bce_softc *sc = ifp->if_softc;
6639 	struct mbuf *m_head = NULL;
6640 	int count = 0;
6641 	u16 tx_prod, tx_chain_prod;
6642 
6643 	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
6644 
6645 	BCE_LOCK_ASSERT(sc);
6646 
6647 	/* prod points to the next free tx_bd. */
6648 	tx_prod = sc->tx_prod;
6649 	tx_chain_prod = TX_CHAIN_IDX(tx_prod);
6650 
6651 	DBPRINT(sc, BCE_INFO_SEND,
6652 		"%s(enter): tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
6653 		"tx_prod_bseq = 0x%08X\n",
6654 		__FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
6655 
6656 	/* If there's no link or the transmit queue is empty then just exit. */
6657 	if (!sc->bce_link) {
6658 		DBPRINT(sc, BCE_INFO_SEND, "%s(): No link.\n",
6659 			__FUNCTION__);
6660 		goto bce_start_locked_exit;
6661 	}
6662 
6663 	if (IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
6664 		DBPRINT(sc, BCE_INFO_SEND, "%s(): Transmit queue empty.\n",
6665 			__FUNCTION__);
6666 		goto bce_start_locked_exit;
6667 	}
6668 
6669 	/*
6670 	 * Keep adding entries while there is space in the ring.
6671 	 */
6672 	while (sc->used_tx_bd < sc->max_tx_bd) {
6673 
6674 		/* Check for any frames to send. */
6675 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
6676 
6677 		/* Stop when the transmit queue is empty. */
6678 		if (m_head == NULL)
6679 			break;
6680 
6681 		/*
6682 		 * Pack the data into the transmit ring. If we
6683 		 * don't have room, place the mbuf back at the
6684 		 * head of the queue and set the OACTIVE flag
6685 		 * to wait for the NIC to drain the chain.
6686 		 */
6687 		if (bce_tx_encap(sc, &m_head)) {
6688 			/* No room, put the frame back on the transmit queue. */
6689 			if (m_head != NULL)
6690 				IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
6691 			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
6692 			DBPRINT(sc, BCE_INFO_SEND,
6693 				"TX chain is closed for business! Total tx_bd used = %d\n",
6694 				sc->used_tx_bd);
6695 			break;
6696 		}
6697 
6698 		count++;
6699 
6700 		/* Send a copy of the frame to any BPF listeners. */
6701 		ETHER_BPF_MTAP(ifp, m_head);
6702 	}
6703 
6704 	/* Exit if no packets were dequeued. */
6705 	if (count == 0) {
6706 		DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were dequeued\n",
6707 			__FUNCTION__);
6708 		goto bce_start_locked_exit;
6709 	}
6710 
6711 	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): Inserted %d frames into send queue.\n",
6712 		__FUNCTION__, count);
6713 
6714 	REG_WR(sc, BCE_MQ_COMMAND, REG_RD(sc, BCE_MQ_COMMAND) | BCE_MQ_COMMAND_NO_MAP_ERROR);
6715 
6716 	/* Write the mailbox and tell the chip about the waiting tx_bd's. */
6717 	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): MB_GET_CID_ADDR(TX_CID) = 0x%08X; "
6718 		"BCE_L2MQ_TX_HOST_BIDX = 0x%08X, sc->tx_prod = 0x%04X\n",
6719 		__FUNCTION__,
6720 		MB_GET_CID_ADDR(TX_CID), BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
6721 	REG_WR16(sc, MB_GET_CID_ADDR(TX_CID) + BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
6722 	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): MB_GET_CID_ADDR(TX_CID) = 0x%08X; "
6723 		"BCE_L2MQ_TX_HOST_BSEQ = 0x%08X, sc->tx_prod_bseq = 0x%04X\n",
6724 		__FUNCTION__,
6725 		MB_GET_CID_ADDR(TX_CID), BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
6726 	REG_WR(sc, MB_GET_CID_ADDR(TX_CID) + BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
6727 
6728 	/* Set the tx timeout. */
6729 	sc->watchdog_timer = BCE_TX_TIMEOUT;
6730 
6731 	DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_ctx(sc, TX_CID));
6732 	DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_mq_regs(sc));
6733 
6734 bce_start_locked_exit:
6735 	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
6736 	return;
6737 }
6738 
6739 
6740 /****************************************************************************/
6741 /* Main transmit routine when called from another routine without a lock.   */
6742 /*                                                                          */
6743 /* Returns:                                                                 */
6744 /*   Nothing.                                                               */
6745 /****************************************************************************/
6746 static void
6747 bce_start(struct ifnet *ifp)
6748 {
6749 	struct bce_softc *sc = ifp->if_softc;
6750 
6751 	DBENTER(BCE_VERBOSE_SEND);
6752 
6753 	BCE_LOCK(sc);
6754 	bce_start_locked(ifp);
6755 	BCE_UNLOCK(sc);
6756 
6757 	DBEXIT(BCE_VERBOSE_SEND);
6758 }
6759 
6760 
6761 /****************************************************************************/
6762 /* Handles any IOCTL calls from the operating system.                       */
6763 /*                                                                          */
6764 /* Returns:                                                                 */
6765 /*   0 for success, positive value for failure.                             */
6766 /****************************************************************************/
6767 static int
6768 bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
6769 {
6770 	struct bce_softc *sc = ifp->if_softc;
6771 	struct ifreq *ifr = (struct ifreq *) data;
6772 	struct mii_data *mii;
6773 	int mask, error = 0;
6774 
6775 	DBENTER(BCE_VERBOSE_MISC);
6776 
6777 	switch(command) {
6778 
6779 		/* Set the interface MTU. */
6780 		case SIOCSIFMTU:
6781 			/* Check that the MTU setting is supported. */
6782 			if ((ifr->ifr_mtu < BCE_MIN_MTU) ||
6783 				(ifr->ifr_mtu > BCE_MAX_JUMBO_MTU)) {
6784 				error = EINVAL;
6785 				break;
6786 			}
6787 
6788 			DBPRINT(sc, BCE_INFO_MISC,
6789 				"SIOCSIFMTU: Changing MTU from %d to %d\n",
6790 				(int) ifp->if_mtu, (int) ifr->ifr_mtu);
6791 
6792 			BCE_LOCK(sc);
6793 			ifp->if_mtu = ifr->ifr_mtu;
6794 			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
6795 #ifdef BCE_USE_SPLIT_HEADER
6796 			/* No buffer allocation size changes are necessary. */
6797 #else
6798 			/* Recalculate our buffer allocation sizes. */
6799 			if ((ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN) > MCLBYTES) {
6800 				sc->rx_bd_mbuf_alloc_size = MJUM9BYTES;
6801 				sc->rx_bd_mbuf_align_pad  = roundup2(MJUM9BYTES, 16) - MJUM9BYTES;
6802 				sc->rx_bd_mbuf_data_len   = sc->rx_bd_mbuf_alloc_size -
6803 					sc->rx_bd_mbuf_align_pad;
6804 			} else {
6805 				sc->rx_bd_mbuf_alloc_size = MCLBYTES;
6806 				sc->rx_bd_mbuf_align_pad  = roundup2(MCLBYTES, 16) - MCLBYTES;
6807 				sc->rx_bd_mbuf_data_len   = sc->rx_bd_mbuf_alloc_size -
6808 					sc->rx_bd_mbuf_align_pad;
6809 			}
6810 #endif
6811 
6812 			bce_init_locked(sc);
6813 			BCE_UNLOCK(sc);
6814 			break;
6815 
6816 		/* Set interface flags. */
6817 		case SIOCSIFFLAGS:
6818 			DBPRINT(sc, BCE_VERBOSE_SPECIAL, "Received SIOCSIFFLAGS\n");
6819 
6820 			BCE_LOCK(sc);
6821 
6822 			/* Check if the interface is up. */
6823 			if (ifp->if_flags & IFF_UP) {
6824 				if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
6825 					/* Change promiscuous/multicast flags as necessary. */
6826 					bce_set_rx_mode(sc);
6827 				} else {
6828 					/* Start the HW */
6829 					bce_init_locked(sc);
6830 				}
6831 			} else {
6832 				/* The interface is down, check if driver is running. */
6833 				if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
6834 					bce_stop(sc);
6835 
6836 					/* If MFW is running, restart the controller a bit. */
6837 					if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
6838 						bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
6839 						bce_chipinit(sc);
6840 						bce_mgmt_init_locked(sc);
6841 					}
6842 				}
6843 			}
6844 
6845 			BCE_UNLOCK(sc);
6846 			error = 0;
6847 
6848 			break;
6849 
6850 		/* Add/Delete multicast address */
6851 		case SIOCADDMULTI:
6852 		case SIOCDELMULTI:
6853 			DBPRINT(sc, BCE_VERBOSE_MISC, "Received SIOCADDMULTI/SIOCDELMULTI\n");
6854 
6855 			BCE_LOCK(sc);
6856 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
6857 				bce_set_rx_mode(sc);
6858 				error = 0;
6859 			}
6860 			BCE_UNLOCK(sc);
6861 
6862 			break;
6863 
6864 		/* Set/Get Interface media */
6865 		case SIOCSIFMEDIA:
6866 		case SIOCGIFMEDIA:
6867 			DBPRINT(sc, BCE_VERBOSE_MISC, "Received SIOCSIFMEDIA/SIOCGIFMEDIA\n");
6868 
6869 			mii = device_get_softc(sc->bce_miibus);
6870 			error = ifmedia_ioctl(ifp, ifr,
6871 			    &mii->mii_media, command);
6872 			break;
6873 
6874 		/* Set interface capability */
6875 		case SIOCSIFCAP:
6876 			mask = ifr->ifr_reqcap ^ ifp->if_capenable;
6877 			DBPRINT(sc, BCE_INFO_MISC, "Received SIOCSIFCAP = 0x%08X\n", (u32) mask);
6878 
6879 			/* Toggle the TX checksum capabilites enable flag. */
6880 			if (mask & IFCAP_TXCSUM) {
6881 				ifp->if_capenable ^= IFCAP_TXCSUM;
6882 				if (IFCAP_TXCSUM & ifp->if_capenable)
6883 					ifp->if_hwassist = BCE_IF_HWASSIST;
6884 				else
6885 					ifp->if_hwassist = 0;
6886 			}
6887 
6888 			/* Toggle the RX checksum capabilities enable flag. */
6889 			if (mask & IFCAP_RXCSUM) {
6890 				ifp->if_capenable ^= IFCAP_RXCSUM;
6891 				if (IFCAP_RXCSUM & ifp->if_capenable)
6892 					ifp->if_hwassist = BCE_IF_HWASSIST;
6893 				else
6894 					ifp->if_hwassist = 0;
6895 			}
6896 
6897 			/* Toggle the TSO capabilities enable flag. */
6898 			if (bce_tso_enable && (mask & IFCAP_TSO4)) {
6899 				ifp->if_capenable ^= IFCAP_TSO4;
6900 				if (IFCAP_RXCSUM & ifp->if_capenable)
6901 					ifp->if_hwassist = BCE_IF_HWASSIST;
6902 				else
6903 					ifp->if_hwassist = 0;
6904 			}
6905 
6906 			/* Toggle VLAN_MTU capabilities enable flag. */
6907 			if (mask & IFCAP_VLAN_MTU) {
6908 				BCE_PRINTF("%s(%d): Changing VLAN_MTU not supported.\n",
6909 					__FILE__, __LINE__);
6910 			}
6911 
6912 			/* Toggle VLANHWTAG capabilities enabled flag. */
6913 			if (mask & IFCAP_VLAN_HWTAGGING) {
6914 				if (sc->bce_flags & BCE_MFW_ENABLE_FLAG)
6915 					BCE_PRINTF("%s(%d): Cannot change VLAN_HWTAGGING while "
6916 						"management firmware (ASF/IPMI/UMP) is running!\n",
6917 						__FILE__, __LINE__);
6918 				else
6919 					BCE_PRINTF("%s(%d): Changing VLAN_HWTAGGING not supported!\n",
6920 						__FILE__, __LINE__);
6921 			}
6922 
6923 			break;
6924 		default:
6925 			/* We don't know how to handle the IOCTL, pass it on. */
6926 			error = ether_ioctl(ifp, command, data);
6927 			break;
6928 	}
6929 
6930 	DBEXIT(BCE_VERBOSE_MISC);
6931 	return(error);
6932 }
6933 
6934 
6935 /****************************************************************************/
6936 /* Transmit timeout handler.                                                */
6937 /*                                                                          */
6938 /* Returns:                                                                 */
6939 /*   Nothing.                                                               */
6940 /****************************************************************************/
6941 static void
6942 bce_watchdog(struct bce_softc *sc)
6943 {
6944 	DBENTER(BCE_EXTREME_SEND);
6945 
6946 	BCE_LOCK_ASSERT(sc);
6947 
6948 	/* If the watchdog timer hasn't expired then just exit. */
6949 	if (sc->watchdog_timer == 0 || --sc->watchdog_timer)
6950 		goto bce_watchdog_exit;
6951 
6952 	/* If pause frames are active then don't reset the hardware. */
6953 	/* ToDo: Should we reset the timer here? */
6954 	if (REG_RD(sc, BCE_EMAC_TX_STATUS) & BCE_EMAC_TX_STATUS_XOFFED)
6955 		goto bce_watchdog_exit;
6956 
6957 	BCE_PRINTF("%s(%d): Watchdog timeout occurred, resetting!\n",
6958 		__FILE__, __LINE__);
6959 
6960 	DBRUNMSG(BCE_INFO,
6961 		bce_dump_driver_state(sc);
6962 		bce_dump_status_block(sc);
6963 		bce_dump_stats_block(sc);
6964 		bce_dump_ftqs(sc);
6965 		bce_dump_txp_state(sc, 0);
6966 		bce_dump_rxp_state(sc, 0);
6967 		bce_dump_tpat_state(sc, 0);
6968 		bce_dump_cp_state(sc, 0);
6969 		bce_dump_com_state(sc, 0));
6970 
6971 	DBRUN(bce_breakpoint(sc));
6972 
6973 	sc->bce_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
6974 
6975 	bce_init_locked(sc);
6976 	sc->bce_ifp->if_oerrors++;
6977 
6978 bce_watchdog_exit:
6979 	DBEXIT(BCE_EXTREME_SEND);
6980 }
6981 
6982 
6983 /*
6984  * Interrupt handler.
6985  */
6986 /****************************************************************************/
6987 /* Main interrupt entry point.  Verifies that the controller generated the  */
6988 /* interrupt and then calls a separate routine for handle the various       */
6989 /* interrupt causes (PHY, TX, RX).                                          */
6990 /*                                                                          */
6991 /* Returns:                                                                 */
6992 /*   0 for success, positive value for failure.                             */
6993 /****************************************************************************/
6994 static void
6995 bce_intr(void *xsc)
6996 {
6997 	struct bce_softc *sc;
6998 	struct ifnet *ifp;
6999 	u32 status_attn_bits;
7000 	u16 hw_rx_cons, hw_tx_cons;
7001 
7002 	sc = xsc;
7003 	ifp = sc->bce_ifp;
7004 
7005 	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
7006 	DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_status_block(sc));
7007 
7008 	BCE_LOCK(sc);
7009 
7010 	DBRUN(sc->interrupts_generated++);
7011 
7012 	bus_dmamap_sync(sc->status_tag, sc->status_map,
7013 	    BUS_DMASYNC_POSTWRITE);
7014 
7015 	/*
7016 	 * If the hardware status block index
7017 	 * matches the last value read by the
7018 	 * driver and we haven't asserted our
7019 	 * interrupt then there's nothing to do.
7020 	 */
7021 	if ((sc->status_block->status_idx == sc->last_status_idx) &&
7022 		(REG_RD(sc, BCE_PCICFG_MISC_STATUS) & BCE_PCICFG_MISC_STATUS_INTA_VALUE)) {
7023 			DBPRINT(sc, BCE_VERBOSE_INTR, "%s(): Spurious interrupt.\n",
7024 				__FUNCTION__);
7025 			goto bce_intr_exit;
7026 	}
7027 
7028 	/* Ack the interrupt and stop others from occuring. */
7029 	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
7030 		BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
7031 		BCE_PCICFG_INT_ACK_CMD_MASK_INT);
7032 
7033 	/* Check if the hardware has finished any work. */
7034 	hw_rx_cons = bce_get_hw_rx_cons(sc);
7035 	hw_tx_cons = bce_get_hw_tx_cons(sc);
7036 
7037 	/* Keep processing data as long as there is work to do. */
7038 	for (;;) {
7039 
7040 		status_attn_bits = sc->status_block->status_attn_bits;
7041 
7042 		DBRUNIF(DB_RANDOMTRUE(bce_debug_unexpected_attention),
7043 			BCE_PRINTF("Simulating unexpected status attention bit set.");
7044 			status_attn_bits = status_attn_bits | STATUS_ATTN_BITS_PARITY_ERROR);
7045 
7046 		/* Was it a link change interrupt? */
7047 		if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
7048 			(sc->status_block->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE)) {
7049 			bce_phy_intr(sc);
7050 
7051 			/* Clear any transient status updates during link state change. */
7052 			REG_WR(sc, BCE_HC_COMMAND,
7053 				sc->hc_command | BCE_HC_COMMAND_COAL_NOW_WO_INT);
7054 			REG_RD(sc, BCE_HC_COMMAND);
7055 		}
7056 
7057 		/* If any other attention is asserted then the chip is toast. */
7058 		if (((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
7059 			(sc->status_block->status_attn_bits_ack &
7060 			~STATUS_ATTN_BITS_LINK_STATE))) {
7061 
7062 			DBRUN(sc->unexpected_attentions++);
7063 
7064 			BCE_PRINTF("%s(%d): Fatal attention detected: 0x%08X\n",
7065 				__FILE__, __LINE__, sc->status_block->status_attn_bits);
7066 
7067 			DBRUNMSG(BCE_FATAL,
7068 				if (bce_debug_unexpected_attention == 0)
7069 					bce_breakpoint(sc));
7070 
7071 			bce_init_locked(sc);
7072 			goto bce_intr_exit;
7073 		}
7074 
7075 		/* Check for any completed RX frames. */
7076 		if (hw_rx_cons != sc->hw_rx_cons)
7077 			bce_rx_intr(sc);
7078 
7079 		/* Check for any completed TX frames. */
7080 		if (hw_tx_cons != sc->hw_tx_cons)
7081 			bce_tx_intr(sc);
7082 
7083 		/* Save the status block index value for use during the next interrupt. */
7084 		sc->last_status_idx = sc->status_block->status_idx;
7085 
7086 		/* Prevent speculative reads from getting ahead of the status block. */
7087 		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
7088 			BUS_SPACE_BARRIER_READ);
7089 
7090 		/* If there's no work left then exit the interrupt service routine. */
7091 		hw_rx_cons = bce_get_hw_rx_cons(sc);
7092 		hw_tx_cons = bce_get_hw_tx_cons(sc);
7093 
7094 		if ((hw_rx_cons == sc->hw_rx_cons) && (hw_tx_cons == sc->hw_tx_cons))
7095 			break;
7096 
7097 	}
7098 
7099 	bus_dmamap_sync(sc->status_tag,	sc->status_map,
7100 	    BUS_DMASYNC_PREWRITE);
7101 
7102 	/* Re-enable interrupts. */
7103 	bce_enable_intr(sc, 0);
7104 
7105 	/* Handle any frames that arrived while handling the interrupt. */
7106 	if (ifp->if_drv_flags & IFF_DRV_RUNNING && !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
7107 		bce_start_locked(ifp);
7108 
7109 bce_intr_exit:
7110 	BCE_UNLOCK(sc);
7111 
7112 	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
7113 }
7114 
7115 
7116 /****************************************************************************/
7117 /* Programs the various packet receive modes (broadcast and multicast).     */
7118 /*                                                                          */
7119 /* Returns:                                                                 */
7120 /*   Nothing.                                                               */
7121 /****************************************************************************/
7122 static void
7123 bce_set_rx_mode(struct bce_softc *sc)
7124 {
7125 	struct ifnet *ifp;
7126 	struct ifmultiaddr *ifma;
7127 	u32 hashes[NUM_MC_HASH_REGISTERS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
7128 	u32 rx_mode, sort_mode;
7129 	int h, i;
7130 
7131 	DBENTER(BCE_VERBOSE_MISC);
7132 
7133 	BCE_LOCK_ASSERT(sc);
7134 
7135 	ifp = sc->bce_ifp;
7136 
7137 	/* Initialize receive mode default settings. */
7138 	rx_mode   = sc->rx_mode & ~(BCE_EMAC_RX_MODE_PROMISCUOUS |
7139 			    BCE_EMAC_RX_MODE_KEEP_VLAN_TAG);
7140 	sort_mode = 1 | BCE_RPM_SORT_USER0_BC_EN;
7141 
7142 	/*
7143 	 * ASF/IPMI/UMP firmware requires that VLAN tag stripping
7144 	 * be enbled.
7145 	 */
7146 	if (!(BCE_IF_CAPABILITIES & IFCAP_VLAN_HWTAGGING) &&
7147 		(!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)))
7148 		rx_mode |= BCE_EMAC_RX_MODE_KEEP_VLAN_TAG;
7149 
7150 	/*
7151 	 * Check for promiscuous, all multicast, or selected
7152 	 * multicast address filtering.
7153 	 */
7154 	if (ifp->if_flags & IFF_PROMISC) {
7155 		DBPRINT(sc, BCE_INFO_MISC, "Enabling promiscuous mode.\n");
7156 
7157 		/* Enable promiscuous mode. */
7158 		rx_mode |= BCE_EMAC_RX_MODE_PROMISCUOUS;
7159 		sort_mode |= BCE_RPM_SORT_USER0_PROM_EN;
7160 	} else if (ifp->if_flags & IFF_ALLMULTI) {
7161 		DBPRINT(sc, BCE_INFO_MISC, "Enabling all multicast mode.\n");
7162 
7163 		/* Enable all multicast addresses. */
7164 		for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
7165 			REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), 0xffffffff);
7166        	}
7167 		sort_mode |= BCE_RPM_SORT_USER0_MC_EN;
7168 	} else {
7169 		/* Accept one or more multicast(s). */
7170 		DBPRINT(sc, BCE_INFO_MISC, "Enabling selective multicast mode.\n");
7171 
7172 		IF_ADDR_LOCK(ifp);
7173 		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
7174 			if (ifma->ifma_addr->sa_family != AF_LINK)
7175 				continue;
7176 			h = ether_crc32_le(LLADDR((struct sockaddr_dl *)
7177 			    ifma->ifma_addr), ETHER_ADDR_LEN) & 0xFF;
7178 			    hashes[(h & 0xE0) >> 5] |= 1 << (h & 0x1F);
7179 		}
7180 		IF_ADDR_UNLOCK(ifp);
7181 
7182 		for (i = 0; i < NUM_MC_HASH_REGISTERS; i++)
7183 			REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), hashes[i]);
7184 
7185 		sort_mode |= BCE_RPM_SORT_USER0_MC_HSH_EN;
7186 	}
7187 
7188 	/* Only make changes if the recive mode has actually changed. */
7189 	if (rx_mode != sc->rx_mode) {
7190 		DBPRINT(sc, BCE_VERBOSE_MISC, "Enabling new receive mode: 0x%08X\n",
7191 			rx_mode);
7192 
7193 		sc->rx_mode = rx_mode;
7194 		REG_WR(sc, BCE_EMAC_RX_MODE, rx_mode);
7195 	}
7196 
7197 	/* Disable and clear the exisitng sort before enabling a new sort. */
7198 	REG_WR(sc, BCE_RPM_SORT_USER0, 0x0);
7199 	REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode);
7200 	REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode | BCE_RPM_SORT_USER0_ENA);
7201 
7202 	DBEXIT(BCE_VERBOSE_MISC);
7203 }
7204 
7205 
7206 /****************************************************************************/
7207 /* Called periodically to updates statistics from the controllers           */
7208 /* statistics block.                                                        */
7209 /*                                                                          */
7210 /* Returns:                                                                 */
7211 /*   Nothing.                                                               */
7212 /****************************************************************************/
7213 static void
7214 bce_stats_update(struct bce_softc *sc)
7215 {
7216 	struct ifnet *ifp;
7217 	struct statistics_block *stats;
7218 
7219 	DBENTER(BCE_EXTREME_MISC);
7220 
7221 	ifp = sc->bce_ifp;
7222 
7223 	stats = (struct statistics_block *) sc->stats_block;
7224 
7225 	/*
7226 	 * Certain controllers don't report
7227 	 * carrier sense errors correctly.
7228 	 * See errata E11_5708CA0_1165.
7229 	 */
7230 	if (!(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
7231 	    !(BCE_CHIP_ID(sc) == BCE_CHIP_ID_5708_A0))
7232 		ifp->if_oerrors += (u_long) stats->stat_Dot3StatsCarrierSenseErrors;
7233 
7234 	/*
7235 	 * Update the sysctl statistics from the
7236 	 * hardware statistics.
7237 	 */
7238 	sc->stat_IfHCInOctets =
7239 		((u64) stats->stat_IfHCInOctets_hi << 32) +
7240 		 (u64) stats->stat_IfHCInOctets_lo;
7241 
7242 	sc->stat_IfHCInBadOctets =
7243 		((u64) stats->stat_IfHCInBadOctets_hi << 32) +
7244 		 (u64) stats->stat_IfHCInBadOctets_lo;
7245 
7246 	sc->stat_IfHCOutOctets =
7247 		((u64) stats->stat_IfHCOutOctets_hi << 32) +
7248 		 (u64) stats->stat_IfHCOutOctets_lo;
7249 
7250 	sc->stat_IfHCOutBadOctets =
7251 		((u64) stats->stat_IfHCOutBadOctets_hi << 32) +
7252 		 (u64) stats->stat_IfHCOutBadOctets_lo;
7253 
7254 	sc->stat_IfHCInUcastPkts =
7255 		((u64) stats->stat_IfHCInUcastPkts_hi << 32) +
7256 		 (u64) stats->stat_IfHCInUcastPkts_lo;
7257 
7258 	sc->stat_IfHCInMulticastPkts =
7259 		((u64) stats->stat_IfHCInMulticastPkts_hi << 32) +
7260 		 (u64) stats->stat_IfHCInMulticastPkts_lo;
7261 
7262 	sc->stat_IfHCInBroadcastPkts =
7263 		((u64) stats->stat_IfHCInBroadcastPkts_hi << 32) +
7264 		 (u64) stats->stat_IfHCInBroadcastPkts_lo;
7265 
7266 	sc->stat_IfHCOutUcastPkts =
7267 		((u64) stats->stat_IfHCOutUcastPkts_hi << 32) +
7268 		 (u64) stats->stat_IfHCOutUcastPkts_lo;
7269 
7270 	sc->stat_IfHCOutMulticastPkts =
7271 		((u64) stats->stat_IfHCOutMulticastPkts_hi << 32) +
7272 		 (u64) stats->stat_IfHCOutMulticastPkts_lo;
7273 
7274 	sc->stat_IfHCOutBroadcastPkts =
7275 		((u64) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
7276 		 (u64) stats->stat_IfHCOutBroadcastPkts_lo;
7277 
7278 	sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors =
7279 		stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
7280 
7281 	sc->stat_Dot3StatsCarrierSenseErrors =
7282 		stats->stat_Dot3StatsCarrierSenseErrors;
7283 
7284 	sc->stat_Dot3StatsFCSErrors =
7285 		stats->stat_Dot3StatsFCSErrors;
7286 
7287 	sc->stat_Dot3StatsAlignmentErrors =
7288 		stats->stat_Dot3StatsAlignmentErrors;
7289 
7290 	sc->stat_Dot3StatsSingleCollisionFrames =
7291 		stats->stat_Dot3StatsSingleCollisionFrames;
7292 
7293 	sc->stat_Dot3StatsMultipleCollisionFrames =
7294 		stats->stat_Dot3StatsMultipleCollisionFrames;
7295 
7296 	sc->stat_Dot3StatsDeferredTransmissions =
7297 		stats->stat_Dot3StatsDeferredTransmissions;
7298 
7299 	sc->stat_Dot3StatsExcessiveCollisions =
7300 		stats->stat_Dot3StatsExcessiveCollisions;
7301 
7302 	sc->stat_Dot3StatsLateCollisions =
7303 		stats->stat_Dot3StatsLateCollisions;
7304 
7305 	sc->stat_EtherStatsCollisions =
7306 		stats->stat_EtherStatsCollisions;
7307 
7308 	sc->stat_EtherStatsFragments =
7309 		stats->stat_EtherStatsFragments;
7310 
7311 	sc->stat_EtherStatsJabbers =
7312 		stats->stat_EtherStatsJabbers;
7313 
7314 	sc->stat_EtherStatsUndersizePkts =
7315 		stats->stat_EtherStatsUndersizePkts;
7316 
7317 	sc->stat_EtherStatsOverrsizePkts =
7318 		stats->stat_EtherStatsOverrsizePkts;
7319 
7320 	sc->stat_EtherStatsPktsRx64Octets =
7321 		stats->stat_EtherStatsPktsRx64Octets;
7322 
7323 	sc->stat_EtherStatsPktsRx65Octetsto127Octets =
7324 		stats->stat_EtherStatsPktsRx65Octetsto127Octets;
7325 
7326 	sc->stat_EtherStatsPktsRx128Octetsto255Octets =
7327 		stats->stat_EtherStatsPktsRx128Octetsto255Octets;
7328 
7329 	sc->stat_EtherStatsPktsRx256Octetsto511Octets =
7330 		stats->stat_EtherStatsPktsRx256Octetsto511Octets;
7331 
7332 	sc->stat_EtherStatsPktsRx512Octetsto1023Octets =
7333 		stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
7334 
7335 	sc->stat_EtherStatsPktsRx1024Octetsto1522Octets =
7336 		stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
7337 
7338 	sc->stat_EtherStatsPktsRx1523Octetsto9022Octets =
7339 		stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
7340 
7341 	sc->stat_EtherStatsPktsTx64Octets =
7342 		stats->stat_EtherStatsPktsTx64Octets;
7343 
7344 	sc->stat_EtherStatsPktsTx65Octetsto127Octets =
7345 		stats->stat_EtherStatsPktsTx65Octetsto127Octets;
7346 
7347 	sc->stat_EtherStatsPktsTx128Octetsto255Octets =
7348 		stats->stat_EtherStatsPktsTx128Octetsto255Octets;
7349 
7350 	sc->stat_EtherStatsPktsTx256Octetsto511Octets =
7351 		stats->stat_EtherStatsPktsTx256Octetsto511Octets;
7352 
7353 	sc->stat_EtherStatsPktsTx512Octetsto1023Octets =
7354 		stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
7355 
7356 	sc->stat_EtherStatsPktsTx1024Octetsto1522Octets =
7357 		stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
7358 
7359 	sc->stat_EtherStatsPktsTx1523Octetsto9022Octets =
7360 		stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
7361 
7362 	sc->stat_XonPauseFramesReceived =
7363 		stats->stat_XonPauseFramesReceived;
7364 
7365 	sc->stat_XoffPauseFramesReceived =
7366 		stats->stat_XoffPauseFramesReceived;
7367 
7368 	sc->stat_OutXonSent =
7369 		stats->stat_OutXonSent;
7370 
7371 	sc->stat_OutXoffSent =
7372 		stats->stat_OutXoffSent;
7373 
7374 	sc->stat_FlowControlDone =
7375 		stats->stat_FlowControlDone;
7376 
7377 	sc->stat_MacControlFramesReceived =
7378 		stats->stat_MacControlFramesReceived;
7379 
7380 	sc->stat_XoffStateEntered =
7381 		stats->stat_XoffStateEntered;
7382 
7383 	sc->stat_IfInFramesL2FilterDiscards =
7384 		stats->stat_IfInFramesL2FilterDiscards;
7385 
7386 	sc->stat_IfInRuleCheckerDiscards =
7387 		stats->stat_IfInRuleCheckerDiscards;
7388 
7389 	sc->stat_IfInFTQDiscards =
7390 		stats->stat_IfInFTQDiscards;
7391 
7392 	sc->stat_IfInMBUFDiscards =
7393 		stats->stat_IfInMBUFDiscards;
7394 
7395 	sc->stat_IfInRuleCheckerP4Hit =
7396 		stats->stat_IfInRuleCheckerP4Hit;
7397 
7398 	sc->stat_CatchupInRuleCheckerDiscards =
7399 		stats->stat_CatchupInRuleCheckerDiscards;
7400 
7401 	sc->stat_CatchupInFTQDiscards =
7402 		stats->stat_CatchupInFTQDiscards;
7403 
7404 	sc->stat_CatchupInMBUFDiscards =
7405 		stats->stat_CatchupInMBUFDiscards;
7406 
7407 	sc->stat_CatchupInRuleCheckerP4Hit =
7408 		stats->stat_CatchupInRuleCheckerP4Hit;
7409 
7410 	sc->com_no_buffers = REG_RD_IND(sc, 0x120084);
7411 
7412 	/*
7413 	 * Update the interface statistics from the
7414 	 * hardware statistics.
7415 	 */
7416 	ifp->if_collisions =
7417 		(u_long) sc->stat_EtherStatsCollisions;
7418 
7419 	/* ToDo: This method loses soft errors. */
7420 	ifp->if_ierrors =
7421 		(u_long) sc->stat_EtherStatsUndersizePkts +
7422 		(u_long) sc->stat_EtherStatsOverrsizePkts +
7423 		(u_long) sc->stat_IfInMBUFDiscards +
7424 		(u_long) sc->stat_Dot3StatsAlignmentErrors +
7425 		(u_long) sc->stat_Dot3StatsFCSErrors +
7426 		(u_long) sc->stat_IfInRuleCheckerDiscards +
7427 		(u_long) sc->stat_IfInFTQDiscards +
7428 		(u_long) sc->com_no_buffers;
7429 
7430 	/* ToDo: This method loses soft errors. */
7431 	ifp->if_oerrors =
7432 		(u_long) sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
7433 		(u_long) sc->stat_Dot3StatsExcessiveCollisions +
7434 		(u_long) sc->stat_Dot3StatsLateCollisions;
7435 
7436 	/* ToDo: Add additional statistics. */
7437 
7438 	DBEXIT(BCE_EXTREME_MISC);
7439 }
7440 
7441 
7442 /****************************************************************************/
7443 /* Periodic function to notify the bootcode that the driver is still        */
7444 /* present.                                                                 */
7445 /*                                                                          */
7446 /* Returns:                                                                 */
7447 /*   Nothing.                                                               */
7448 /****************************************************************************/
7449 static void
7450 bce_pulse(void *xsc)
7451 {
7452 	struct bce_softc *sc = xsc;
7453 	u32 msg;
7454 
7455 	DBENTER(BCE_EXTREME_MISC);
7456 
7457 	BCE_LOCK_ASSERT(sc);
7458 
7459 	/* Tell the firmware that the driver is still running. */
7460 	msg = (u32) ++sc->bce_fw_drv_pulse_wr_seq;
7461 	REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_PULSE_MB, msg);
7462 
7463 	/* Schedule the next pulse. */
7464 	callout_reset(&sc->bce_pulse_callout, hz, bce_pulse, sc);
7465 
7466 	DBEXIT(BCE_EXTREME_MISC);
7467 }
7468 
7469 
7470 /****************************************************************************/
7471 /* Periodic function to perform maintenance tasks.                          */
7472 /*                                                                          */
7473 /* Returns:                                                                 */
7474 /*   Nothing.                                                               */
7475 /****************************************************************************/
7476 static void
7477 bce_tick(void *xsc)
7478 {
7479 	struct bce_softc *sc = xsc;
7480 	struct mii_data *mii;
7481 	struct ifnet *ifp;
7482 
7483 	ifp = sc->bce_ifp;
7484 
7485 	DBENTER(BCE_EXTREME_MISC);
7486 
7487 	BCE_LOCK_ASSERT(sc);
7488 
7489 	/* Schedule the next tick. */
7490 	callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
7491 
7492 	/* Update the statistics from the hardware statistics block. */
7493 	bce_stats_update(sc);
7494 
7495 	/* Top off the receive and page chains. */
7496 #ifdef BCE_USE_SPLIT_HEADER
7497 	bce_fill_pg_chain(sc);
7498 #endif
7499 	bce_fill_rx_chain(sc);
7500 
7501 	/* Check that chip hasn't hung. */
7502 	bce_watchdog(sc);
7503 
7504 	/* If link is up already up then we're done. */
7505 	if (sc->bce_link)
7506 		goto bce_tick_exit;
7507 
7508 	/* Link is down.  Check what the PHY's doing. */
7509 	mii = device_get_softc(sc->bce_miibus);
7510 	mii_tick(mii);
7511 
7512 	/* Check if the link has come up. */
7513 	if ((mii->mii_media_status & IFM_ACTIVE) &&
7514 	    (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)) {
7515 		DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Link up!\n", __FUNCTION__);
7516 		sc->bce_link++;
7517 		if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
7518 		    IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX) &&
7519 		    bootverbose)
7520 			BCE_PRINTF("Gigabit link up!\n");
7521 		/* Now that link is up, handle any outstanding TX traffic. */
7522 		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
7523 			DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Found pending TX traffic.\n",
7524 				 __FUNCTION__);
7525 			bce_start_locked(ifp);
7526 		}
7527 	}
7528 
7529 bce_tick_exit:
7530 	DBEXIT(BCE_EXTREME_MISC);
7531 	return;
7532 }
7533 
7534 
7535 #ifdef BCE_DEBUG
7536 /****************************************************************************/
7537 /* Allows the driver state to be dumped through the sysctl interface.       */
7538 /*                                                                          */
7539 /* Returns:                                                                 */
7540 /*   0 for success, positive value for failure.                             */
7541 /****************************************************************************/
7542 static int
7543 bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS)
7544 {
7545         int error;
7546         int result;
7547         struct bce_softc *sc;
7548 
7549         result = -1;
7550         error = sysctl_handle_int(oidp, &result, 0, req);
7551 
7552         if (error || !req->newptr)
7553                 return (error);
7554 
7555         if (result == 1) {
7556                 sc = (struct bce_softc *)arg1;
7557                 bce_dump_driver_state(sc);
7558         }
7559 
7560         return error;
7561 }
7562 
7563 
7564 /****************************************************************************/
7565 /* Allows the hardware state to be dumped through the sysctl interface.     */
7566 /*                                                                          */
7567 /* Returns:                                                                 */
7568 /*   0 for success, positive value for failure.                             */
7569 /****************************************************************************/
7570 static int
7571 bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS)
7572 {
7573         int error;
7574         int result;
7575         struct bce_softc *sc;
7576 
7577         result = -1;
7578         error = sysctl_handle_int(oidp, &result, 0, req);
7579 
7580         if (error || !req->newptr)
7581                 return (error);
7582 
7583         if (result == 1) {
7584                 sc = (struct bce_softc *)arg1;
7585                 bce_dump_hw_state(sc);
7586         }
7587 
7588         return error;
7589 }
7590 
7591 
7592 /****************************************************************************/
7593 /* Allows the bootcode state to be dumped through the sysctl interface.     */
7594 /*                                                                          */
7595 /* Returns:                                                                 */
7596 /*   0 for success, positive value for failure.                             */
7597 /****************************************************************************/
7598 static int
7599 bce_sysctl_bc_state(SYSCTL_HANDLER_ARGS)
7600 {
7601         int error;
7602         int result;
7603         struct bce_softc *sc;
7604 
7605         result = -1;
7606         error = sysctl_handle_int(oidp, &result, 0, req);
7607 
7608         if (error || !req->newptr)
7609                 return (error);
7610 
7611         if (result == 1) {
7612                 sc = (struct bce_softc *)arg1;
7613                 bce_dump_bc_state(sc);
7614         }
7615 
7616         return error;
7617 }
7618 
7619 
7620 /****************************************************************************/
7621 /* Provides a sysctl interface to allow dumping the RX chain.               */
7622 /*                                                                          */
7623 /* Returns:                                                                 */
7624 /*   0 for success, positive value for failure.                             */
7625 /****************************************************************************/
7626 static int
7627 bce_sysctl_dump_rx_chain(SYSCTL_HANDLER_ARGS)
7628 {
7629         int error;
7630         int result;
7631         struct bce_softc *sc;
7632 
7633         result = -1;
7634         error = sysctl_handle_int(oidp, &result, 0, req);
7635 
7636         if (error || !req->newptr)
7637                 return (error);
7638 
7639         if (result == 1) {
7640                 sc = (struct bce_softc *)arg1;
7641                 bce_dump_rx_chain(sc, 0, TOTAL_RX_BD);
7642         }
7643 
7644         return error;
7645 }
7646 
7647 
7648 /****************************************************************************/
7649 /* Provides a sysctl interface to allow dumping the TX chain.               */
7650 /*                                                                          */
7651 /* Returns:                                                                 */
7652 /*   0 for success, positive value for failure.                             */
7653 /****************************************************************************/
7654 static int
7655 bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
7656 {
7657         int error;
7658         int result;
7659         struct bce_softc *sc;
7660 
7661         result = -1;
7662         error = sysctl_handle_int(oidp, &result, 0, req);
7663 
7664         if (error || !req->newptr)
7665                 return (error);
7666 
7667         if (result == 1) {
7668                 sc = (struct bce_softc *)arg1;
7669                 bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
7670         }
7671 
7672         return error;
7673 }
7674 
7675 
7676 #ifdef BCE_USE_SPLIT_HEADER
7677 /****************************************************************************/
7678 /* Provides a sysctl interface to allow dumping the page chain.             */
7679 /*                                                                          */
7680 /* Returns:                                                                 */
7681 /*   0 for success, positive value for failure.                             */
7682 /****************************************************************************/
7683 static int
7684 bce_sysctl_dump_pg_chain(SYSCTL_HANDLER_ARGS)
7685 {
7686         int error;
7687         int result;
7688         struct bce_softc *sc;
7689 
7690         result = -1;
7691         error = sysctl_handle_int(oidp, &result, 0, req);
7692 
7693         if (error || !req->newptr)
7694                 return (error);
7695 
7696         if (result == 1) {
7697                 sc = (struct bce_softc *)arg1;
7698                 bce_dump_pg_chain(sc, 0, TOTAL_PG_BD);
7699         }
7700 
7701         return error;
7702 }
7703 #endif
7704 
7705 /****************************************************************************/
7706 /* Provides a sysctl interface to allow reading arbitrary NVRAM offsets in  */
7707 /* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
7708 /*                                                                          */
7709 /* Returns:                                                                 */
7710 /*   0 for success, positive value for failure.                             */
7711 /****************************************************************************/
7712 static int
7713 bce_sysctl_nvram_read(SYSCTL_HANDLER_ARGS)
7714 {
7715 	struct bce_softc *sc = (struct bce_softc *)arg1;
7716 	int error;
7717 	u32 result;
7718 	u32 val[1];
7719 	u8 *data = (u8 *) val;
7720 
7721 	result = -1;
7722 	error = sysctl_handle_int(oidp, &result, 0, req);
7723 	if (error || (req->newptr == NULL))
7724 		return (error);
7725 
7726 	bce_nvram_read(sc, result, data, 4);
7727 	BCE_PRINTF("offset 0x%08X = 0x%08X\n", result, bce_be32toh(val[0]));
7728 
7729 	return (error);
7730 }
7731 
7732 
7733 /****************************************************************************/
7734 /* Provides a sysctl interface to allow reading arbitrary registers in the  */
7735 /* device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                            */
7736 /*                                                                          */
7737 /* Returns:                                                                 */
7738 /*   0 for success, positive value for failure.                             */
7739 /****************************************************************************/
7740 static int
7741 bce_sysctl_reg_read(SYSCTL_HANDLER_ARGS)
7742 {
7743 	struct bce_softc *sc = (struct bce_softc *)arg1;
7744 	int error;
7745 	u32 val, result;
7746 
7747 	result = -1;
7748 	error = sysctl_handle_int(oidp, &result, 0, req);
7749 	if (error || (req->newptr == NULL))
7750 		return (error);
7751 
7752 	/* Make sure the register is accessible. */
7753 	if (result < 0x8000) {
7754 		val = REG_RD(sc, result);
7755 		BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
7756 	} else if (result < 0x0280000) {
7757 		val = REG_RD_IND(sc, result);
7758 		BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
7759 	}
7760 
7761 	return (error);
7762 }
7763 
7764 
7765 /****************************************************************************/
7766 /* Provides a sysctl interface to allow reading arbitrary PHY registers in  */
7767 /* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
7768 /*                                                                          */
7769 /* Returns:                                                                 */
7770 /*   0 for success, positive value for failure.                             */
7771 /****************************************************************************/
7772 static int
7773 bce_sysctl_phy_read(SYSCTL_HANDLER_ARGS)
7774 {
7775 	struct bce_softc *sc;
7776 	device_t dev;
7777 	int error, result;
7778 	u16 val;
7779 
7780 	result = -1;
7781 	error = sysctl_handle_int(oidp, &result, 0, req);
7782 	if (error || (req->newptr == NULL))
7783 		return (error);
7784 
7785 	/* Make sure the register is accessible. */
7786 	if (result < 0x20) {
7787 		sc = (struct bce_softc *)arg1;
7788 		dev = sc->bce_dev;
7789 		val = bce_miibus_read_reg(dev, sc->bce_phy_addr, result);
7790 		BCE_PRINTF("phy 0x%02X = 0x%04X\n", result, val);
7791 	}
7792 	return (error);
7793 }
7794 
7795 
7796 /****************************************************************************/
7797 /* Provides a sysctl interface to allow reading a CID.                      */
7798 /*                                                                          */
7799 /* Returns:                                                                 */
7800 /*   0 for success, positive value for failure.                             */
7801 /****************************************************************************/
7802 static int
7803 bce_sysctl_dump_ctx(SYSCTL_HANDLER_ARGS)
7804 {
7805 	struct bce_softc *sc;
7806 	int error;
7807 	u16 result;
7808 
7809 	result = -1;
7810 	error = sysctl_handle_int(oidp, &result, 0, req);
7811 	if (error || (req->newptr == NULL))
7812 		return (error);
7813 
7814 	/* Make sure the register is accessible. */
7815 	if (result <= TX_CID) {
7816 		sc = (struct bce_softc *)arg1;
7817 		bce_dump_ctx(sc, result);
7818 	}
7819 
7820 	return (error);
7821 }
7822 
7823 
7824  /****************************************************************************/
7825 /* Provides a sysctl interface to forcing the driver to dump state and      */
7826 /* enter the debugger.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                */
7827 /*                                                                          */
7828 /* Returns:                                                                 */
7829 /*   0 for success, positive value for failure.                             */
7830 /****************************************************************************/
7831 static int
7832 bce_sysctl_breakpoint(SYSCTL_HANDLER_ARGS)
7833 {
7834         int error;
7835         int result;
7836         struct bce_softc *sc;
7837 
7838         result = -1;
7839         error = sysctl_handle_int(oidp, &result, 0, req);
7840 
7841         if (error || !req->newptr)
7842                 return (error);
7843 
7844         if (result == 1) {
7845                 sc = (struct bce_softc *)arg1;
7846                 bce_breakpoint(sc);
7847         }
7848 
7849         return error;
7850 }
7851 #endif
7852 
7853 
7854 /****************************************************************************/
7855 /* Adds any sysctl parameters for tuning or debugging purposes.             */
7856 /*                                                                          */
7857 /* Returns:                                                                 */
7858 /*   0 for success, positive value for failure.                             */
7859 /****************************************************************************/
7860 static void
7861 bce_add_sysctls(struct bce_softc *sc)
7862 {
7863 	struct sysctl_ctx_list *ctx;
7864 	struct sysctl_oid_list *children;
7865 
7866 	DBENTER(BCE_VERBOSE_MISC);
7867 
7868 	ctx = device_get_sysctl_ctx(sc->bce_dev);
7869 	children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->bce_dev));
7870 
7871 #ifdef BCE_DEBUG
7872 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7873 		"rx_low_watermark",
7874 		CTLFLAG_RD, &sc->rx_low_watermark,
7875 		0, "Lowest level of free rx_bd's");
7876 
7877 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7878 		"rx_empty_count",
7879 		CTLFLAG_RD, &sc->rx_empty_count,
7880 		0, "Number of times the RX chain was empty");
7881 
7882 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7883 		"tx_hi_watermark",
7884 		CTLFLAG_RD, &sc->tx_hi_watermark,
7885 		0, "Highest level of used tx_bd's");
7886 
7887 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7888 		"tx_full_count",
7889 		CTLFLAG_RD, &sc->tx_full_count,
7890 		0, "Number of times the TX chain was full");
7891 
7892 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7893 		"l2fhdr_status_errors",
7894 		CTLFLAG_RD, &sc->l2fhdr_status_errors,
7895 		0, "l2_fhdr status errors");
7896 
7897 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7898 		"unexpected_attentions",
7899 		CTLFLAG_RD, &sc->unexpected_attentions,
7900 		0, "Unexpected attentions");
7901 
7902 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7903 		"lost_status_block_updates",
7904 		CTLFLAG_RD, &sc->lost_status_block_updates,
7905 		0, "Lost status block updates");
7906 
7907 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7908 		"debug_mbuf_sim_alloc_failed",
7909 		CTLFLAG_RD, &sc->debug_mbuf_sim_alloc_failed,
7910 		0, "Simulated mbuf cluster allocation failures");
7911 
7912 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7913 		"requested_tso_frames",
7914 		CTLFLAG_RD, &sc->requested_tso_frames,
7915 		0, "Number of TSO frames received");
7916 
7917 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
7918 		"rx_interrupts",
7919 		CTLFLAG_RD, &sc->rx_interrupts,
7920 		0, "Number of RX interrupts");
7921 
7922 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
7923 		"tx_interrupts",
7924 		CTLFLAG_RD, &sc->tx_interrupts,
7925 		0, "Number of TX interrupts");
7926 
7927 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7928 		"rx_intr_time",
7929 		CTLFLAG_RD, &sc->rx_intr_time,
7930 		"RX interrupt time");
7931 
7932 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7933 		"tx_intr_time",
7934 		CTLFLAG_RD, &sc->tx_intr_time,
7935 		"TX interrupt time");
7936 #endif
7937 
7938 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7939 		"mbuf_alloc_failed",
7940 		CTLFLAG_RD, &sc->mbuf_alloc_failed,
7941 		0, "mbuf cluster allocation failures");
7942 
7943 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7944 		"tx_dma_map_failures",
7945 		CTLFLAG_RD, &sc->tx_dma_map_failures,
7946 		0, "tx dma mapping failures");
7947 
7948 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7949 		"stat_IfHcInOctets",
7950 		CTLFLAG_RD, &sc->stat_IfHCInOctets,
7951 		"Bytes received");
7952 
7953 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7954 		"stat_IfHCInBadOctets",
7955 		CTLFLAG_RD, &sc->stat_IfHCInBadOctets,
7956 		"Bad bytes received");
7957 
7958 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7959 		"stat_IfHCOutOctets",
7960 		CTLFLAG_RD, &sc->stat_IfHCOutOctets,
7961 		"Bytes sent");
7962 
7963 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7964 		"stat_IfHCOutBadOctets",
7965 		CTLFLAG_RD, &sc->stat_IfHCOutBadOctets,
7966 		"Bad bytes sent");
7967 
7968 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7969 		"stat_IfHCInUcastPkts",
7970 		CTLFLAG_RD, &sc->stat_IfHCInUcastPkts,
7971 		"Unicast packets received");
7972 
7973 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7974 		"stat_IfHCInMulticastPkts",
7975 		CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts,
7976 		"Multicast packets received");
7977 
7978 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7979 		"stat_IfHCInBroadcastPkts",
7980 		CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts,
7981 		"Broadcast packets received");
7982 
7983 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7984 		"stat_IfHCOutUcastPkts",
7985 		CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts,
7986 		"Unicast packets sent");
7987 
7988 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7989 		"stat_IfHCOutMulticastPkts",
7990 		CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts,
7991 		"Multicast packets sent");
7992 
7993 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7994 		"stat_IfHCOutBroadcastPkts",
7995 		CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts,
7996 		"Broadcast packets sent");
7997 
7998 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
7999 		"stat_emac_tx_stat_dot3statsinternalmactransmiterrors",
8000 		CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors,
8001 		0, "Internal MAC transmit errors");
8002 
8003 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8004 		"stat_Dot3StatsCarrierSenseErrors",
8005 		CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors,
8006 		0, "Carrier sense errors");
8007 
8008 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8009 		"stat_Dot3StatsFCSErrors",
8010 		CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors,
8011 		0, "Frame check sequence errors");
8012 
8013 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8014 		"stat_Dot3StatsAlignmentErrors",
8015 		CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors,
8016 		0, "Alignment errors");
8017 
8018 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8019 		"stat_Dot3StatsSingleCollisionFrames",
8020 		CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames,
8021 		0, "Single Collision Frames");
8022 
8023 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8024 		"stat_Dot3StatsMultipleCollisionFrames",
8025 		CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames,
8026 		0, "Multiple Collision Frames");
8027 
8028 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8029 		"stat_Dot3StatsDeferredTransmissions",
8030 		CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions,
8031 		0, "Deferred Transmissions");
8032 
8033 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8034 		"stat_Dot3StatsExcessiveCollisions",
8035 		CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions,
8036 		0, "Excessive Collisions");
8037 
8038 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8039 		"stat_Dot3StatsLateCollisions",
8040 		CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions,
8041 		0, "Late Collisions");
8042 
8043 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8044 		"stat_EtherStatsCollisions",
8045 		CTLFLAG_RD, &sc->stat_EtherStatsCollisions,
8046 		0, "Collisions");
8047 
8048 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8049 		"stat_EtherStatsFragments",
8050 		CTLFLAG_RD, &sc->stat_EtherStatsFragments,
8051 		0, "Fragments");
8052 
8053 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8054 		"stat_EtherStatsJabbers",
8055 		CTLFLAG_RD, &sc->stat_EtherStatsJabbers,
8056 		0, "Jabbers");
8057 
8058 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8059 		"stat_EtherStatsUndersizePkts",
8060 		CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts,
8061 		0, "Undersize packets");
8062 
8063 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8064 		"stat_EtherStatsOverrsizePkts",
8065 		CTLFLAG_RD, &sc->stat_EtherStatsOverrsizePkts,
8066 		0, "stat_EtherStatsOverrsizePkts");
8067 
8068 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8069 		"stat_EtherStatsPktsRx64Octets",
8070 		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets,
8071 		0, "Bytes received in 64 byte packets");
8072 
8073 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8074 		"stat_EtherStatsPktsRx65Octetsto127Octets",
8075 		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets,
8076 		0, "Bytes received in 65 to 127 byte packets");
8077 
8078 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8079 		"stat_EtherStatsPktsRx128Octetsto255Octets",
8080 		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets,
8081 		0, "Bytes received in 128 to 255 byte packets");
8082 
8083 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8084 		"stat_EtherStatsPktsRx256Octetsto511Octets",
8085 		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets,
8086 		0, "Bytes received in 256 to 511 byte packets");
8087 
8088 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8089 		"stat_EtherStatsPktsRx512Octetsto1023Octets",
8090 		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets,
8091 		0, "Bytes received in 512 to 1023 byte packets");
8092 
8093 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8094 		"stat_EtherStatsPktsRx1024Octetsto1522Octets",
8095 		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets,
8096 		0, "Bytes received in 1024 t0 1522 byte packets");
8097 
8098 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8099 		"stat_EtherStatsPktsRx1523Octetsto9022Octets",
8100 		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets,
8101 		0, "Bytes received in 1523 to 9022 byte packets");
8102 
8103 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8104 		"stat_EtherStatsPktsTx64Octets",
8105 		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets,
8106 		0, "Bytes sent in 64 byte packets");
8107 
8108 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8109 		"stat_EtherStatsPktsTx65Octetsto127Octets",
8110 		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets,
8111 		0, "Bytes sent in 65 to 127 byte packets");
8112 
8113 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8114 		"stat_EtherStatsPktsTx128Octetsto255Octets",
8115 		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets,
8116 		0, "Bytes sent in 128 to 255 byte packets");
8117 
8118 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8119 		"stat_EtherStatsPktsTx256Octetsto511Octets",
8120 		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets,
8121 		0, "Bytes sent in 256 to 511 byte packets");
8122 
8123 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8124 		"stat_EtherStatsPktsTx512Octetsto1023Octets",
8125 		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets,
8126 		0, "Bytes sent in 512 to 1023 byte packets");
8127 
8128 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8129 		"stat_EtherStatsPktsTx1024Octetsto1522Octets",
8130 		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets,
8131 		0, "Bytes sent in 1024 to 1522 byte packets");
8132 
8133 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8134 		"stat_EtherStatsPktsTx1523Octetsto9022Octets",
8135 		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets,
8136 		0, "Bytes sent in 1523 to 9022 byte packets");
8137 
8138 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8139 		"stat_XonPauseFramesReceived",
8140 		CTLFLAG_RD, &sc->stat_XonPauseFramesReceived,
8141 		0, "XON pause frames receved");
8142 
8143 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8144 		"stat_XoffPauseFramesReceived",
8145 		CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived,
8146 		0, "XOFF pause frames received");
8147 
8148 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8149 		"stat_OutXonSent",
8150 		CTLFLAG_RD, &sc->stat_OutXonSent,
8151 		0, "XON pause frames sent");
8152 
8153 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8154 		"stat_OutXoffSent",
8155 		CTLFLAG_RD, &sc->stat_OutXoffSent,
8156 		0, "XOFF pause frames sent");
8157 
8158 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8159 		"stat_FlowControlDone",
8160 		CTLFLAG_RD, &sc->stat_FlowControlDone,
8161 		0, "Flow control done");
8162 
8163 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8164 		"stat_MacControlFramesReceived",
8165 		CTLFLAG_RD, &sc->stat_MacControlFramesReceived,
8166 		0, "MAC control frames received");
8167 
8168 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8169 		"stat_XoffStateEntered",
8170 		CTLFLAG_RD, &sc->stat_XoffStateEntered,
8171 		0, "XOFF state entered");
8172 
8173 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8174 		"stat_IfInFramesL2FilterDiscards",
8175 		CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards,
8176 		0, "Received L2 packets discarded");
8177 
8178 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8179 		"stat_IfInRuleCheckerDiscards",
8180 		CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards,
8181 		0, "Received packets discarded by rule");
8182 
8183 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8184 		"stat_IfInFTQDiscards",
8185 		CTLFLAG_RD, &sc->stat_IfInFTQDiscards,
8186 		0, "Received packet FTQ discards");
8187 
8188 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8189 		"stat_IfInMBUFDiscards",
8190 		CTLFLAG_RD, &sc->stat_IfInMBUFDiscards,
8191 		0, "Received packets discarded due to lack of controller buffer memory");
8192 
8193 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8194 		"stat_IfInRuleCheckerP4Hit",
8195 		CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit,
8196 		0, "Received packets rule checker hits");
8197 
8198 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8199 		"stat_CatchupInRuleCheckerDiscards",
8200 		CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards,
8201 		0, "Received packets discarded in Catchup path");
8202 
8203 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8204 		"stat_CatchupInFTQDiscards",
8205 		CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards,
8206 		0, "Received packets discarded in FTQ in Catchup path");
8207 
8208 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8209 		"stat_CatchupInMBUFDiscards",
8210 		CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards,
8211 		0, "Received packets discarded in controller buffer memory in Catchup path");
8212 
8213 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8214 		"stat_CatchupInRuleCheckerP4Hit",
8215 		CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit,
8216 		0, "Received packets rule checker hits in Catchup path");
8217 
8218 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8219 		"com_no_buffers",
8220 		CTLFLAG_RD, &sc->com_no_buffers,
8221 		0, "Valid packets received but no RX buffers available");
8222 
8223 #ifdef BCE_DEBUG
8224 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8225 		"driver_state", CTLTYPE_INT | CTLFLAG_RW,
8226 		(void *)sc, 0,
8227 		bce_sysctl_driver_state, "I", "Drive state information");
8228 
8229 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8230 		"hw_state", CTLTYPE_INT | CTLFLAG_RW,
8231 		(void *)sc, 0,
8232 		bce_sysctl_hw_state, "I", "Hardware state information");
8233 
8234 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8235 		"bc_state", CTLTYPE_INT | CTLFLAG_RW,
8236 		(void *)sc, 0,
8237 		bce_sysctl_bc_state, "I", "Bootcode state information");
8238 
8239 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8240 		"dump_rx_chain", CTLTYPE_INT | CTLFLAG_RW,
8241 		(void *)sc, 0,
8242 		bce_sysctl_dump_rx_chain, "I", "Dump rx_bd chain");
8243 
8244 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8245 		"dump_tx_chain", CTLTYPE_INT | CTLFLAG_RW,
8246 		(void *)sc, 0,
8247 		bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
8248 
8249 #ifdef BCE_USE_SPLIT_HEADER
8250 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8251 		"dump_pg_chain", CTLTYPE_INT | CTLFLAG_RW,
8252 		(void *)sc, 0,
8253 		bce_sysctl_dump_pg_chain, "I", "Dump page chain");
8254 #endif
8255 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8256 		"dump_ctx", CTLTYPE_INT | CTLFLAG_RW,
8257 		(void *)sc, 0,
8258 		bce_sysctl_dump_ctx, "I", "Dump context memory");
8259 
8260 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8261 		"breakpoint", CTLTYPE_INT | CTLFLAG_RW,
8262 		(void *)sc, 0,
8263 		bce_sysctl_breakpoint, "I", "Driver breakpoint");
8264 
8265 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8266 		"reg_read", CTLTYPE_INT | CTLFLAG_RW,
8267 		(void *)sc, 0,
8268 		bce_sysctl_reg_read, "I", "Register read");
8269 
8270 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8271 		"nvram_read", CTLTYPE_INT | CTLFLAG_RW,
8272 		(void *)sc, 0,
8273 		bce_sysctl_nvram_read, "I", "NVRAM read");
8274 
8275 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8276 		"phy_read", CTLTYPE_INT | CTLFLAG_RW,
8277 		(void *)sc, 0,
8278 		bce_sysctl_phy_read, "I", "PHY register read");
8279 
8280 #endif
8281 
8282 	DBEXIT(BCE_VERBOSE_MISC);
8283 }
8284 
8285 
8286 /****************************************************************************/
8287 /* BCE Debug Routines                                                       */
8288 /****************************************************************************/
8289 #ifdef BCE_DEBUG
8290 
8291 /****************************************************************************/
8292 /* Freezes the controller to allow for a cohesive state dump.               */
8293 /*                                                                          */
8294 /* Returns:                                                                 */
8295 /*   Nothing.                                                               */
8296 /****************************************************************************/
8297 static void
8298 bce_freeze_controller(struct bce_softc *sc)
8299 {
8300 	u32 val;
8301 	val = REG_RD(sc, BCE_MISC_COMMAND);
8302 	val |= BCE_MISC_COMMAND_DISABLE_ALL;
8303 	REG_WR(sc, BCE_MISC_COMMAND, val);
8304 }
8305 
8306 
8307 /****************************************************************************/
8308 /* Unfreezes the controller after a freeze operation.  This may not always  */
8309 /* work and the controller will require a reset!                            */
8310 /*                                                                          */
8311 /* Returns:                                                                 */
8312 /*   Nothing.                                                               */
8313 /****************************************************************************/
8314 static void
8315 bce_unfreeze_controller(struct bce_softc *sc)
8316 {
8317 	u32 val;
8318 	val = REG_RD(sc, BCE_MISC_COMMAND);
8319 	val |= BCE_MISC_COMMAND_ENABLE_ALL;
8320 	REG_WR(sc, BCE_MISC_COMMAND, val);
8321 }
8322 
8323 
8324 /****************************************************************************/
8325 /* Prints out Ethernet frame information from an mbuf.                      */
8326 /*                                                                          */
8327 /* Partially decode an Ethernet frame to look at some important headers.    */
8328 /*                                                                          */
8329 /* Returns:                                                                 */
8330 /*   Nothing.                                                               */
8331 /****************************************************************************/
8332 static void
8333 bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
8334 {
8335 	struct ether_vlan_header *eh;
8336 	u16 etype;
8337 	int ehlen;
8338 	struct ip *ip;
8339 	struct tcphdr *th;
8340 	struct udphdr *uh;
8341 	struct arphdr *ah;
8342 
8343 		BCE_PRINTF(
8344 			"-----------------------------"
8345 			" Frame Decode "
8346 			"-----------------------------\n");
8347 
8348 	eh = mtod(m, struct ether_vlan_header *);
8349 
8350 	/* Handle VLAN encapsulation if present. */
8351 	if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
8352 		etype = ntohs(eh->evl_proto);
8353 		ehlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
8354 	} else {
8355 		etype = ntohs(eh->evl_encap_proto);
8356 		ehlen = ETHER_HDR_LEN;
8357 	}
8358 
8359 	/* ToDo: Add VLAN output. */
8360 	BCE_PRINTF("enet: dest = %6D, src = %6D, type = 0x%04X, hlen = %d\n",
8361 		eh->evl_dhost, ":", eh->evl_shost, ":", etype, ehlen);
8362 
8363 	switch (etype) {
8364 		case ETHERTYPE_IP:
8365 			ip = (struct ip *)(m->m_data + ehlen);
8366 			BCE_PRINTF("--ip: dest = 0x%08X , src = 0x%08X, len = %d bytes, "
8367 				"protocol = 0x%02X, xsum = 0x%04X\n",
8368 				ntohl(ip->ip_dst.s_addr), ntohl(ip->ip_src.s_addr),
8369 				ntohs(ip->ip_len), ip->ip_p, ntohs(ip->ip_sum));
8370 
8371 			switch (ip->ip_p) {
8372 				case IPPROTO_TCP:
8373 					th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
8374 					BCE_PRINTF("-tcp: dest = %d, src = %d, hlen = %d bytes, "
8375 						"flags = 0x%b, csum = 0x%04X\n",
8376 						ntohs(th->th_dport), ntohs(th->th_sport), (th->th_off << 2),
8377 						th->th_flags, "\20\10CWR\07ECE\06URG\05ACK\04PSH\03RST\02SYN\01FIN",
8378 						ntohs(th->th_sum));
8379 					break;
8380 				case IPPROTO_UDP:
8381         		    uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
8382 					BCE_PRINTF("-udp: dest = %d, src = %d, len = %d bytes, "
8383 						"csum = 0x%04X\n", ntohs(uh->uh_dport), ntohs(uh->uh_sport),
8384 						ntohs(uh->uh_ulen), ntohs(uh->uh_sum));
8385 					break;
8386 				case IPPROTO_ICMP:
8387 					BCE_PRINTF("icmp:\n");
8388 					break;
8389 				default:
8390 					BCE_PRINTF("----: Other IP protocol.\n");
8391 			}
8392 			break;
8393 		case ETHERTYPE_IPV6:
8394 			BCE_PRINTF("ipv6: No decode supported.\n");
8395 			break;
8396 		case ETHERTYPE_ARP:
8397 			BCE_PRINTF("-arp: ");
8398 			ah = (struct arphdr *) (m->m_data + ehlen);
8399 			switch (ntohs(ah->ar_op)) {
8400 				case ARPOP_REVREQUEST:
8401 					printf("reverse ARP request\n");
8402 					break;
8403 				case ARPOP_REVREPLY:
8404 					printf("reverse ARP reply\n");
8405 					break;
8406 				case ARPOP_REQUEST:
8407 					printf("ARP request\n");
8408 					break;
8409 				case ARPOP_REPLY:
8410 					printf("ARP reply\n");
8411 					break;
8412 				default:
8413 					printf("other ARP operation\n");
8414 			}
8415 			break;
8416 		default:
8417 			BCE_PRINTF("----: Other protocol.\n");
8418 	}
8419 
8420 	BCE_PRINTF(
8421 		"-----------------------------"
8422 		"--------------"
8423 		"-----------------------------\n");
8424 }
8425 
8426 
8427 /****************************************************************************/
8428 /* Prints out information about an mbuf.                                    */
8429 /*                                                                          */
8430 /* Returns:                                                                 */
8431 /*   Nothing.                                                               */
8432 /****************************************************************************/
8433 static __attribute__ ((noinline)) void
8434 bce_dump_mbuf(struct bce_softc *sc, struct mbuf *m)
8435 {
8436 	struct mbuf *mp = m;
8437 
8438 	if (m == NULL) {
8439 		BCE_PRINTF("mbuf: null pointer\n");
8440 		return;
8441 	}
8442 
8443 	while (mp) {
8444 		BCE_PRINTF("mbuf: %p, m_len = %d, m_flags = 0x%b, m_data = %p\n",
8445 			mp, mp->m_len, mp->m_flags,
8446 			"\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY",
8447 			mp->m_data);
8448 
8449 		if (mp->m_flags & M_PKTHDR) {
8450 			BCE_PRINTF("- m_pkthdr: len = %d, flags = 0x%b, csum_flags = %b\n",
8451 				mp->m_pkthdr.len, mp->m_flags,
8452 				"\20\12M_BCAST\13M_MCAST\14M_FRAG\15M_FIRSTFRAG"
8453 				"\16M_LASTFRAG\21M_VLANTAG\22M_PROMISC\23M_NOFREE",
8454 				mp->m_pkthdr.csum_flags,
8455 				"\20\1CSUM_IP\2CSUM_TCP\3CSUM_UDP\4CSUM_IP_FRAGS"
8456 				"\5CSUM_FRAGMENT\6CSUM_TSO\11CSUM_IP_CHECKED"
8457 				"\12CSUM_IP_VALID\13CSUM_DATA_VALID\14CSUM_PSEUDO_HDR");
8458 		}
8459 
8460 		if (mp->m_flags & M_EXT) {
8461 			BCE_PRINTF("- m_ext: %p, ext_size = %d, type = ",
8462 				mp->m_ext.ext_buf, mp->m_ext.ext_size);
8463 			switch (mp->m_ext.ext_type) {
8464 				case EXT_CLUSTER:    printf("EXT_CLUSTER\n"); break;
8465 				case EXT_SFBUF:      printf("EXT_SFBUF\n"); break;
8466 				case EXT_JUMBO9:     printf("EXT_JUMBO9\n"); break;
8467 				case EXT_JUMBO16:    printf("EXT_JUMBO16\n"); break;
8468 				case EXT_PACKET:     printf("EXT_PACKET\n"); break;
8469 				case EXT_MBUF:       printf("EXT_MBUF\n"); break;
8470 				case EXT_NET_DRV:    printf("EXT_NET_DRV\n"); break;
8471 				case EXT_MOD_TYPE:   printf("EXT_MDD_TYPE\n"); break;
8472 				case EXT_DISPOSABLE: printf("EXT_DISPOSABLE\n"); break;
8473 				case EXT_EXTREF:     printf("EXT_EXTREF\n"); break;
8474 				default:             printf("UNKNOWN\n");
8475 			}
8476 		}
8477 
8478 		mp = mp->m_next;
8479 	}
8480 }
8481 
8482 
8483 /****************************************************************************/
8484 /* Prints out the mbufs in the TX mbuf chain.                               */
8485 /*                                                                          */
8486 /* Returns:                                                                 */
8487 /*   Nothing.                                                               */
8488 /****************************************************************************/
8489 static __attribute__ ((noinline)) void
8490 bce_dump_tx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
8491 {
8492 	struct mbuf *m;
8493 
8494 	BCE_PRINTF(
8495 		"----------------------------"
8496 		"  tx mbuf data  "
8497 		"----------------------------\n");
8498 
8499 	for (int i = 0; i < count; i++) {
8500 	 	m = sc->tx_mbuf_ptr[chain_prod];
8501 		BCE_PRINTF("txmbuf[0x%04X]\n", chain_prod);
8502 		bce_dump_mbuf(sc, m);
8503 		chain_prod = TX_CHAIN_IDX(NEXT_TX_BD(chain_prod));
8504 	}
8505 
8506 	BCE_PRINTF(
8507 		"----------------------------"
8508 		"----------------"
8509 		"----------------------------\n");
8510 }
8511 
8512 
8513 /****************************************************************************/
8514 /* Prints out the mbufs in the RX mbuf chain.                               */
8515 /*                                                                          */
8516 /* Returns:                                                                 */
8517 /*   Nothing.                                                               */
8518 /****************************************************************************/
8519 static __attribute__ ((noinline)) void
8520 bce_dump_rx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
8521 {
8522 	struct mbuf *m;
8523 
8524 	BCE_PRINTF(
8525 		"----------------------------"
8526 		"  rx mbuf data  "
8527 		"----------------------------\n");
8528 
8529 	for (int i = 0; i < count; i++) {
8530 	 	m = sc->rx_mbuf_ptr[chain_prod];
8531 		BCE_PRINTF("rxmbuf[0x%04X]\n", chain_prod);
8532 		bce_dump_mbuf(sc, m);
8533 		chain_prod = RX_CHAIN_IDX(NEXT_RX_BD(chain_prod));
8534 	}
8535 
8536 
8537 	BCE_PRINTF(
8538 		"----------------------------"
8539 		"----------------"
8540 		"----------------------------\n");
8541 }
8542 
8543 
8544 #ifdef BCE_USE_SPLIT_HEADER
8545 /****************************************************************************/
8546 /* Prints out the mbufs in the mbuf page chain.                             */
8547 /*                                                                          */
8548 /* Returns:                                                                 */
8549 /*   Nothing.                                                               */
8550 /****************************************************************************/
8551 static __attribute__ ((noinline)) void
8552 bce_dump_pg_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
8553 {
8554 	struct mbuf *m;
8555 
8556 	BCE_PRINTF(
8557 		"----------------------------"
8558 		"  pg mbuf data  "
8559 		"----------------------------\n");
8560 
8561 	for (int i = 0; i < count; i++) {
8562 	 	m = sc->pg_mbuf_ptr[chain_prod];
8563 		BCE_PRINTF("pgmbuf[0x%04X]\n", chain_prod);
8564 		bce_dump_mbuf(sc, m);
8565 		chain_prod = PG_CHAIN_IDX(NEXT_PG_BD(chain_prod));
8566 	}
8567 
8568 
8569 	BCE_PRINTF(
8570 		"----------------------------"
8571 		"----------------"
8572 		"----------------------------\n");
8573 }
8574 #endif
8575 
8576 
8577 /****************************************************************************/
8578 /* Prints out a tx_bd structure.                                            */
8579 /*                                                                          */
8580 /* Returns:                                                                 */
8581 /*   Nothing.                                                               */
8582 /****************************************************************************/
8583 static __attribute__ ((noinline)) void
8584 bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
8585 {
8586 	if (idx > MAX_TX_BD)
8587 		/* Index out of range. */
8588 		BCE_PRINTF("tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
8589 	else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
8590 		/* TX Chain page pointer. */
8591 		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
8592 			idx, txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo);
8593 	else {
8594 			/* Normal tx_bd entry. */
8595 			BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
8596 				"vlan tag= 0x%04X, flags = 0x%04X (", idx,
8597 				txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
8598 				txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag,
8599 				txbd->tx_bd_flags);
8600 
8601 			if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT)
8602 				printf(" CONN_FAULT");
8603 
8604 			if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM)
8605 				printf(" TCP_UDP_CKSUM");
8606 
8607 			if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM)
8608 				printf(" IP_CKSUM");
8609 
8610 			if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG)
8611 				printf("  VLAN");
8612 
8613 			if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW)
8614 				printf(" COAL_NOW");
8615 
8616 			if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC)
8617 				printf(" DONT_GEN_CRC");
8618 
8619 			if (txbd->tx_bd_flags & TX_BD_FLAGS_START)
8620 				printf(" START");
8621 
8622 			if (txbd->tx_bd_flags & TX_BD_FLAGS_END)
8623 				printf(" END");
8624 
8625 			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO)
8626 				printf(" LSO");
8627 
8628 			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD)
8629 				printf(" OPTION_WORD");
8630 
8631 			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS)
8632 				printf(" FLAGS");
8633 
8634 			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP)
8635 				printf(" SNAP");
8636 
8637 			printf(" )\n");
8638 		}
8639 
8640 }
8641 
8642 
8643 /****************************************************************************/
8644 /* Prints out a rx_bd structure.                                            */
8645 /*                                                                          */
8646 /* Returns:                                                                 */
8647 /*   Nothing.                                                               */
8648 /****************************************************************************/
8649 static __attribute__ ((noinline)) void
8650 bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd)
8651 {
8652 	if (idx > MAX_RX_BD)
8653 		/* Index out of range. */
8654 		BCE_PRINTF("rx_bd[0x%04X]: Invalid rx_bd index!\n", idx);
8655 	else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
8656 		/* RX Chain page pointer. */
8657 		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
8658 			idx, rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo);
8659 	else
8660 		/* Normal rx_bd entry. */
8661 		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
8662 			"flags = 0x%08X\n", idx,
8663 			rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo,
8664 			rxbd->rx_bd_len, rxbd->rx_bd_flags);
8665 }
8666 
8667 
8668 #ifdef BCE_USE_SPLIT_HEADER
8669 /****************************************************************************/
8670 /* Prints out a rx_bd structure in the page chain.                          */
8671 /*                                                                          */
8672 /* Returns:                                                                 */
8673 /*   Nothing.                                                               */
8674 /****************************************************************************/
8675 static __attribute__ ((noinline)) void
8676 bce_dump_pgbd(struct bce_softc *sc, int idx, struct rx_bd *pgbd)
8677 {
8678 	if (idx > MAX_PG_BD)
8679 		/* Index out of range. */
8680 		BCE_PRINTF("pg_bd[0x%04X]: Invalid pg_bd index!\n", idx);
8681 	else if ((idx & USABLE_PG_BD_PER_PAGE) == USABLE_PG_BD_PER_PAGE)
8682 		/* Page Chain page pointer. */
8683 		BCE_PRINTF("px_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
8684 			idx, pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo);
8685 	else
8686 		/* Normal rx_bd entry. */
8687 		BCE_PRINTF("pg_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
8688 			"flags = 0x%08X\n", idx,
8689 			pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo,
8690 			pgbd->rx_bd_len, pgbd->rx_bd_flags);
8691 }
8692 #endif
8693 
8694 
8695 /****************************************************************************/
8696 /* Prints out a l2_fhdr structure.                                          */
8697 /*                                                                          */
8698 /* Returns:                                                                 */
8699 /*   Nothing.                                                               */
8700 /****************************************************************************/
8701 static __attribute__ ((noinline)) void
8702 bce_dump_l2fhdr(struct bce_softc *sc, int idx, struct l2_fhdr *l2fhdr)
8703 {
8704 	BCE_PRINTF("l2_fhdr[0x%04X]: status = 0x%b, "
8705 		"pkt_len = %d, vlan = 0x%04x, ip_xsum/hdr_len = 0x%04X, "
8706 		"tcp_udp_xsum = 0x%04X\n", idx,
8707 		l2fhdr->l2_fhdr_status, BCE_L2FHDR_PRINTFB,
8708 		l2fhdr->l2_fhdr_pkt_len, l2fhdr->l2_fhdr_vlan_tag,
8709 		l2fhdr->l2_fhdr_ip_xsum, l2fhdr->l2_fhdr_tcp_udp_xsum);
8710 }
8711 
8712 
8713 /****************************************************************************/
8714 /* Prints out context memory info.  (Only useful for CID 0 to 16.)          */
8715 /*                                                                          */
8716 /* Returns:                                                                 */
8717 /*   Nothing.                                                               */
8718 /****************************************************************************/
8719 static __attribute__ ((noinline)) void
8720 bce_dump_ctx(struct bce_softc *sc, u16 cid)
8721 {
8722 	if (cid <= TX_CID) {
8723 		BCE_PRINTF(
8724 			"----------------------------"
8725 			"    CTX Data    "
8726 			"----------------------------\n");
8727 
8728 		BCE_PRINTF("     0x%04X - (CID) Context ID\n", cid);
8729 
8730 		if (cid == RX_CID) {
8731 			BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BDIDX) host rx "
8732 				"producer index\n",
8733 				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BDIDX));
8734 			BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BSEQ) host byte sequence\n",
8735 				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BSEQ));
8736 			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BSEQ) h/w byte sequence\n",
8737 				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BSEQ));
8738 			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_HI) h/w buffer "
8739 				"descriptor address\n",
8740  				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_HI));
8741 			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_LO) h/w buffer "
8742 				"descriptor address\n",
8743 				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_LO));
8744 			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDIDX) h/w rx consumer index\n",
8745 				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDIDX));
8746 			BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_PG_BDIDX) host page "
8747 				"producer index\n",
8748 				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_PG_BDIDX));
8749 			BCE_PRINTF(" 0x%08X - (L2CTX_RX_PG_BUF_SIZE) host rx_bd/page "
8750 				"buffer size\n",
8751 				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_PG_BUF_SIZE));
8752 			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_HI) h/w page "
8753 				"chain address\n",
8754 				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_PG_BDHADDR_HI));
8755 			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_LO) h/w page "
8756 				"chain address\n",
8757 				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_PG_BDHADDR_LO));
8758 			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDIDX) h/w page "
8759 				"consumer index\n",
8760 				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_PG_BDIDX));
8761 		} else if (cid == TX_CID) {
8762 			if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
8763 				(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
8764 				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE_XI) ctx type\n",
8765 					CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE_XI));
8766 				BCE_PRINTF(" 0x%08X - (L2CTX_CMD_TX_TYPE_XI) ctx cmd\n",
8767 					CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_CMD_TYPE_XI));
8768 				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI_XI) h/w buffer "
8769 					"descriptor address\n",	CTX_RD(sc,
8770 					GET_CID_ADDR(cid), BCE_L2CTX_TX_TBDR_BHADDR_HI_XI));
8771 				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO_XI) h/w buffer "
8772 					"descriptor address\n", CTX_RD(sc,
8773 					GET_CID_ADDR(cid), BCE_L2CTX_TX_TBDR_BHADDR_LO_XI));
8774 				BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX_XI) host producer "
8775 					"index\n", CTX_RD(sc, GET_CID_ADDR(cid),
8776 					BCE_L2CTX_TX_HOST_BIDX_XI));
8777 				BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ_XI) host byte "
8778 					"sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
8779 					BCE_L2CTX_TX_HOST_BSEQ_XI));
8780 			} else {
8781 				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE) ctx type\n",
8782 					CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE));
8783 				BCE_PRINTF(" 0x%08X - (L2CTX_TX_CMD_TYPE) ctx cmd\n",
8784 					CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_CMD_TYPE));
8785 				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI) h/w buffer "
8786 					"descriptor address\n", CTX_RD(sc, GET_CID_ADDR(cid),
8787 					BCE_L2CTX_TX_TBDR_BHADDR_HI));
8788 				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO) h/w buffer "
8789 					"descriptor address\n", CTX_RD(sc, GET_CID_ADDR(cid),
8790 					BCE_L2CTX_TX_TBDR_BHADDR_LO));
8791 				BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX) host producer "
8792 					"index\n", CTX_RD(sc, GET_CID_ADDR(cid),
8793 					BCE_L2CTX_TX_HOST_BIDX));
8794 				BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ) host byte "
8795 					"sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
8796 					BCE_L2CTX_TX_HOST_BSEQ));
8797 			}
8798 		} else
8799 			BCE_PRINTF(" Unknown CID\n");
8800 
8801 		BCE_PRINTF(
8802 			"----------------------------"
8803 			"    Raw CTX     "
8804 			"----------------------------\n");
8805 
8806 		for (int i = 0x0; i < 0x300; i += 0x10) {
8807 			BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n", i,
8808 				CTX_RD(sc, GET_CID_ADDR(cid), i),
8809 				CTX_RD(sc, GET_CID_ADDR(cid), i + 0x4),
8810 				CTX_RD(sc, GET_CID_ADDR(cid), i + 0x8),
8811 				CTX_RD(sc, GET_CID_ADDR(cid), i + 0xc));
8812 		}
8813 
8814 
8815 		BCE_PRINTF(
8816 			"----------------------------"
8817 			"----------------"
8818 			"----------------------------\n");
8819 	}
8820 }
8821 
8822 
8823 /****************************************************************************/
8824 /* Prints out the FTQ data.                                                 */
8825 /*                                                                          */
8826 /* Returns:                                                                */
8827 /*   Nothing.                                                               */
8828 /****************************************************************************/
8829 static __attribute__ ((noinline)) void
8830 bce_dump_ftqs(struct bce_softc *sc)
8831 {
8832 	u32 cmd, ctl, cur_depth, max_depth, valid_cnt, val;
8833 
8834 	BCE_PRINTF(
8835 		"----------------------------"
8836 		"    FTQ Data    "
8837 		"----------------------------\n");
8838 
8839 	BCE_PRINTF("   FTQ    Command    Control   Depth_Now  Max_Depth  Valid_Cnt \n");
8840 	BCE_PRINTF(" ------- ---------- ---------- ---------- ---------- ----------\n");
8841 
8842 	/* Setup the generic statistic counters for the FTQ valid count. */
8843 	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PPQ_VALID_CNT << 24) |
8844 		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT  << 16) |
8845 		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT   <<  8) |
8846 		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT);
8847 	REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
8848 
8849 	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCHQ_VALID_CNT  << 24) |
8850 		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT  << 16) |
8851 		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT <<  8) |
8852 		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT);
8853 	REG_WR(sc, BCE_HC_STAT_GEN_SEL_1, val);
8854 
8855 	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPATQ_VALID_CNT  << 24) |
8856 		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT  << 16) |
8857 		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT   <<  8) |
8858 		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT);
8859 	REG_WR(sc, BCE_HC_STAT_GEN_SEL_2, val);
8860 
8861 	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMQ_VALID_CNT   << 24) |
8862 		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT  << 16) |
8863 		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT  <<  8) |
8864 		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT);
8865 	REG_WR(sc, BCE_HC_STAT_GEN_SEL_3, val);
8866 
8867 	/* Input queue to the Receive Lookup state machine */
8868 	cmd = REG_RD(sc, BCE_RLUP_FTQ_CMD);
8869 	ctl = REG_RD(sc, BCE_RLUP_FTQ_CTL);
8870 	cur_depth = (ctl & BCE_RLUP_FTQ_CTL_CUR_DEPTH) >> 22;
8871 	max_depth = (ctl & BCE_RLUP_FTQ_CTL_MAX_DEPTH) >> 12;
8872 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
8873 	BCE_PRINTF(" RLUP    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8874 		cmd, ctl, cur_depth, max_depth, valid_cnt);
8875 
8876 	/* Input queue to the Receive Processor */
8877 	cmd = REG_RD_IND(sc, BCE_RXP_FTQ_CMD);
8878 	ctl = REG_RD_IND(sc, BCE_RXP_FTQ_CTL);
8879 	cur_depth = (ctl & BCE_RXP_FTQ_CTL_CUR_DEPTH) >> 22;
8880 	max_depth = (ctl & BCE_RXP_FTQ_CTL_MAX_DEPTH) >> 12;
8881 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
8882 	BCE_PRINTF(" RXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8883 		cmd, ctl, cur_depth, max_depth, valid_cnt);
8884 
8885 	/* Input queue to the Recevie Processor */
8886 	cmd = REG_RD_IND(sc, BCE_RXP_CFTQ_CMD);
8887 	ctl = REG_RD_IND(sc, BCE_RXP_CFTQ_CTL);
8888 	cur_depth = (ctl & BCE_RXP_CFTQ_CTL_CUR_DEPTH) >> 22;
8889 	max_depth = (ctl & BCE_RXP_CFTQ_CTL_MAX_DEPTH) >> 12;
8890 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
8891 	BCE_PRINTF(" RXPC    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8892 		cmd, ctl, cur_depth, max_depth, valid_cnt);
8893 
8894 	/* Input queue to the Receive Virtual to Physical state machine */
8895 	cmd = REG_RD(sc, BCE_RV2P_PFTQ_CMD);
8896 	ctl = REG_RD(sc, BCE_RV2P_PFTQ_CTL);
8897 	cur_depth = (ctl & BCE_RV2P_PFTQ_CTL_CUR_DEPTH) >> 22;
8898 	max_depth = (ctl & BCE_RV2P_PFTQ_CTL_MAX_DEPTH) >> 12;
8899 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
8900 	BCE_PRINTF(" RV2PP   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8901 		cmd, ctl, cur_depth, max_depth, valid_cnt);
8902 
8903 	/* Input queue to the Recevie Virtual to Physical state machine */
8904 	cmd = REG_RD(sc, BCE_RV2P_MFTQ_CMD);
8905 	ctl = REG_RD(sc, BCE_RV2P_MFTQ_CTL);
8906 	cur_depth = (ctl & BCE_RV2P_MFTQ_CTL_CUR_DEPTH) >> 22;
8907 	max_depth = (ctl & BCE_RV2P_MFTQ_CTL_MAX_DEPTH) >> 12;
8908 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT4);
8909 	BCE_PRINTF(" RV2PM   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8910 		cmd, ctl, cur_depth, max_depth, valid_cnt);
8911 
8912 	/* Input queue to the Receive Virtual to Physical state machine */
8913 	cmd = REG_RD(sc, BCE_RV2P_TFTQ_CMD);
8914 	ctl = REG_RD(sc, BCE_RV2P_TFTQ_CTL);
8915 	cur_depth = (ctl & BCE_RV2P_TFTQ_CTL_CUR_DEPTH) >> 22;
8916 	max_depth = (ctl & BCE_RV2P_TFTQ_CTL_MAX_DEPTH) >> 12;
8917 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT5);
8918 	BCE_PRINTF(" RV2PT   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8919 		cmd, ctl, cur_depth, max_depth, valid_cnt);
8920 
8921 	/* Input queue to the Receive DMA state machine */
8922 	cmd = REG_RD(sc, BCE_RDMA_FTQ_CMD);
8923 	ctl = REG_RD(sc, BCE_RDMA_FTQ_CTL);
8924 	cur_depth = (ctl & BCE_RDMA_FTQ_CTL_CUR_DEPTH) >> 22;
8925 	max_depth = (ctl & BCE_RDMA_FTQ_CTL_MAX_DEPTH) >> 12;
8926 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT6);
8927 	BCE_PRINTF(" RDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8928 		cmd, ctl, cur_depth, max_depth, valid_cnt);
8929 
8930 	/* Input queue to the Transmit Scheduler state machine */
8931 	cmd = REG_RD(sc, BCE_TSCH_FTQ_CMD);
8932 	ctl = REG_RD(sc, BCE_TSCH_FTQ_CTL);
8933 	cur_depth = (ctl & BCE_TSCH_FTQ_CTL_CUR_DEPTH) >> 22;
8934 	max_depth = (ctl & BCE_TSCH_FTQ_CTL_MAX_DEPTH) >> 12;
8935 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT7);
8936 	BCE_PRINTF(" TSCH    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8937 		cmd, ctl, cur_depth, max_depth, valid_cnt);
8938 
8939 	/* Input queue to the Transmit Buffer Descriptor state machine */
8940 	cmd = REG_RD(sc, BCE_TBDR_FTQ_CMD);
8941 	ctl = REG_RD(sc, BCE_TBDR_FTQ_CTL);
8942 	cur_depth = (ctl & BCE_TBDR_FTQ_CTL_CUR_DEPTH) >> 22;
8943 	max_depth = (ctl & BCE_TBDR_FTQ_CTL_MAX_DEPTH) >> 12;
8944 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT8);
8945 	BCE_PRINTF(" TBDR    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8946 		cmd, ctl, cur_depth, max_depth, valid_cnt);
8947 
8948 	/* Input queue to the Transmit Processor */
8949 	cmd = REG_RD_IND(sc, BCE_TXP_FTQ_CMD);
8950 	ctl = REG_RD_IND(sc, BCE_TXP_FTQ_CTL);
8951 	cur_depth = (ctl & BCE_TXP_FTQ_CTL_CUR_DEPTH) >> 22;
8952 	max_depth = (ctl & BCE_TXP_FTQ_CTL_MAX_DEPTH) >> 12;
8953 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT9);
8954 	BCE_PRINTF(" TXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8955 		cmd, ctl, cur_depth, max_depth, valid_cnt);
8956 
8957 	/* Input queue to the Transmit DMA state machine */
8958 	cmd = REG_RD(sc, BCE_TDMA_FTQ_CMD);
8959 	ctl = REG_RD(sc, BCE_TDMA_FTQ_CTL);
8960 	cur_depth = (ctl & BCE_TDMA_FTQ_CTL_CUR_DEPTH) >> 22;
8961 	max_depth = (ctl & BCE_TDMA_FTQ_CTL_MAX_DEPTH) >> 12;
8962 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT10);
8963 	BCE_PRINTF(" TDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8964 		cmd, ctl, cur_depth, max_depth, valid_cnt);
8965 
8966 	/* Input queue to the Transmit Patch-Up Processor */
8967 	cmd = REG_RD_IND(sc, BCE_TPAT_FTQ_CMD);
8968 	ctl = REG_RD_IND(sc, BCE_TPAT_FTQ_CTL);
8969 	cur_depth = (ctl & BCE_TPAT_FTQ_CTL_CUR_DEPTH) >> 22;
8970 	max_depth = (ctl & BCE_TPAT_FTQ_CTL_MAX_DEPTH) >> 12;
8971 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT11);
8972 	BCE_PRINTF(" TPAT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8973 		cmd, ctl, cur_depth, max_depth, valid_cnt);
8974 
8975 	/* Input queue to the Transmit Assembler state machine */
8976 	cmd = REG_RD_IND(sc, BCE_TAS_FTQ_CMD);
8977 	ctl = REG_RD_IND(sc, BCE_TAS_FTQ_CTL);
8978 	cur_depth = (ctl & BCE_TAS_FTQ_CTL_CUR_DEPTH) >> 22;
8979 	max_depth = (ctl & BCE_TAS_FTQ_CTL_MAX_DEPTH) >> 12;
8980 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT12);
8981 	BCE_PRINTF(" TAS     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8982 		cmd, ctl, cur_depth, max_depth, valid_cnt);
8983 
8984 	/* Input queue to the Completion Processor */
8985 	cmd = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CMD);
8986 	ctl = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CTL);
8987 	cur_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_CUR_DEPTH) >> 22;
8988 	max_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_MAX_DEPTH) >> 12;
8989 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT13);
8990 	BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8991 		cmd, ctl, cur_depth, max_depth, valid_cnt);
8992 
8993 	/* Input queue to the Completion Processor */
8994 	cmd = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CMD);
8995 	ctl = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CTL);
8996 	cur_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_CUR_DEPTH) >> 22;
8997 	max_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_MAX_DEPTH) >> 12;
8998 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT14);
8999 	BCE_PRINTF(" COMT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9000 		cmd, ctl, cur_depth, max_depth, valid_cnt);
9001 
9002 	/* Input queue to the Completion Processor */
9003 	cmd = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CMD);
9004 	ctl = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CTL);
9005 	cur_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_CUR_DEPTH) >> 22;
9006 	max_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_MAX_DEPTH) >> 12;
9007 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT15);
9008 	BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9009 		cmd, ctl, cur_depth, max_depth, valid_cnt);
9010 
9011 	/* Setup the generic statistic counters for the FTQ valid count. */
9012 	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSQ_VALID_CNT  << 16) |
9013 		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT  <<  8) |
9014 		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT);
9015 
9016 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)	||
9017 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
9018 		val = val | (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCSQ_VALID_CNT_XI << 24);
9019 		REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
9020 
9021 	/* Input queue to the Management Control Processor */
9022 	cmd = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CMD);
9023 	ctl = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CTL);
9024 	cur_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_CUR_DEPTH) >> 22;
9025 	max_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_MAX_DEPTH) >> 12;
9026 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
9027 	BCE_PRINTF(" MCP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9028 		cmd, ctl, cur_depth, max_depth, valid_cnt);
9029 
9030 	/* Input queue to the Command Processor */
9031 	cmd = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CMD);
9032 	ctl = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CTL);
9033 	cur_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_CUR_DEPTH) >> 22;
9034 	max_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_MAX_DEPTH) >> 12;
9035 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
9036 	BCE_PRINTF(" CP      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9037 		cmd, ctl, cur_depth, max_depth, valid_cnt);
9038 
9039 	/* Input queue to the Completion Scheduler state machine */
9040 	cmd = REG_RD(sc, BCE_CSCH_CH_FTQ_CMD);
9041 	ctl = REG_RD(sc, BCE_CSCH_CH_FTQ_CTL);
9042 	cur_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_CUR_DEPTH) >> 22;
9043 	max_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_MAX_DEPTH) >> 12;
9044 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
9045 	BCE_PRINTF(" CS      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9046 		cmd, ctl, cur_depth, max_depth, valid_cnt);
9047 
9048 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
9049 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
9050 		/* Input queue to the Receive Virtual to Physical Command Scheduler */
9051 		cmd = REG_RD(sc, BCE_RV2PCSR_FTQ_CMD);
9052 		ctl = REG_RD(sc, BCE_RV2PCSR_FTQ_CTL);
9053 		cur_depth = (ctl & 0xFFC00000) >> 22;
9054 		max_depth = (ctl & 0x003FF000) >> 12;
9055 		valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
9056 		BCE_PRINTF(" RV2PCSR 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9057 			cmd, ctl, cur_depth, max_depth, valid_cnt);
9058 	}
9059 
9060 	BCE_PRINTF(
9061 		"----------------------------"
9062 		"----------------"
9063 		"----------------------------\n");
9064 }
9065 
9066 
9067 /****************************************************************************/
9068 /* Prints out the TX chain.                                                 */
9069 /*                                                                          */
9070 /* Returns:                                                                 */
9071 /*   Nothing.                                                               */
9072 /****************************************************************************/
9073 static __attribute__ ((noinline)) void
9074 bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count)
9075 {
9076 	struct tx_bd *txbd;
9077 
9078 	/* First some info about the tx_bd chain structure. */
9079 	BCE_PRINTF(
9080 		"----------------------------"
9081 		"  tx_bd  chain  "
9082 		"----------------------------\n");
9083 
9084 	BCE_PRINTF("page size      = 0x%08X, tx chain pages        = 0x%08X\n",
9085 		(u32) BCM_PAGE_SIZE, (u32) TX_PAGES);
9086 
9087 	BCE_PRINTF("tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
9088 		(u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
9089 
9090 	BCE_PRINTF("total tx_bd    = 0x%08X\n", (u32) TOTAL_TX_BD);
9091 
9092 	BCE_PRINTF(
9093 		"----------------------------"
9094 		"   tx_bd data   "
9095 		"----------------------------\n");
9096 
9097 	/* Now print out the tx_bd's themselves. */
9098 	for (int i = 0; i < count; i++) {
9099 	 	txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
9100 		bce_dump_txbd(sc, tx_prod, txbd);
9101 		tx_prod = NEXT_TX_BD(tx_prod);
9102 	}
9103 
9104 	BCE_PRINTF(
9105 		"----------------------------"
9106 		"----------------"
9107 		"----------------------------\n");
9108 }
9109 
9110 
9111 /****************************************************************************/
9112 /* Prints out the RX chain.                                                 */
9113 /*                                                                          */
9114 /* Returns:                                                                 */
9115 /*   Nothing.                                                               */
9116 /****************************************************************************/
9117 static __attribute__ ((noinline)) void
9118 bce_dump_rx_chain(struct bce_softc *sc, u16 rx_prod, int count)
9119 {
9120 	struct rx_bd *rxbd;
9121 
9122 	/* First some info about the rx_bd chain structure. */
9123 	BCE_PRINTF(
9124 		"----------------------------"
9125 		"  rx_bd  chain  "
9126 		"----------------------------\n");
9127 
9128 	BCE_PRINTF("page size      = 0x%08X, rx chain pages        = 0x%08X\n",
9129 		(u32) BCM_PAGE_SIZE, (u32) RX_PAGES);
9130 
9131 	BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
9132 		(u32) TOTAL_RX_BD_PER_PAGE, (u32) USABLE_RX_BD_PER_PAGE);
9133 
9134 	BCE_PRINTF("total rx_bd    = 0x%08X\n", (u32) TOTAL_RX_BD);
9135 
9136 	BCE_PRINTF(
9137 		"----------------------------"
9138 		"   rx_bd data   "
9139 		"----------------------------\n");
9140 
9141 	/* Now print out the rx_bd's themselves. */
9142 	for (int i = 0; i < count; i++) {
9143 		rxbd = &sc->rx_bd_chain[RX_PAGE(rx_prod)][RX_IDX(rx_prod)];
9144 		bce_dump_rxbd(sc, rx_prod, rxbd);
9145 		rx_prod = RX_CHAIN_IDX(rx_prod + 1);
9146 	}
9147 
9148 	BCE_PRINTF(
9149 		"----------------------------"
9150 		"----------------"
9151 		"----------------------------\n");
9152 }
9153 
9154 
9155 #ifdef BCE_USE_SPLIT_HEADER
9156 /****************************************************************************/
9157 /* Prints out the page chain.                                               */
9158 /*                                                                          */
9159 /* Returns:                                                                 */
9160 /*   Nothing.                                                               */
9161 /****************************************************************************/
9162 static __attribute__ ((noinline)) void
9163 bce_dump_pg_chain(struct bce_softc *sc, u16 pg_prod, int count)
9164 {
9165 	struct rx_bd *pgbd;
9166 
9167 	/* First some info about the page chain structure. */
9168 	BCE_PRINTF(
9169 		"----------------------------"
9170 		"   page chain   "
9171 		"----------------------------\n");
9172 
9173 	BCE_PRINTF("page size      = 0x%08X, pg chain pages        = 0x%08X\n",
9174 		(u32) BCM_PAGE_SIZE, (u32) PG_PAGES);
9175 
9176 	BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
9177 		(u32) TOTAL_PG_BD_PER_PAGE, (u32) USABLE_PG_BD_PER_PAGE);
9178 
9179 	BCE_PRINTF("total rx_bd    = 0x%08X, max_pg_bd             = 0x%08X\n",
9180 		(u32) TOTAL_PG_BD, (u32) MAX_PG_BD);
9181 
9182 	BCE_PRINTF(
9183 		"----------------------------"
9184 		"   page data    "
9185 		"----------------------------\n");
9186 
9187 	/* Now print out the rx_bd's themselves. */
9188 	for (int i = 0; i < count; i++) {
9189 		pgbd = &sc->pg_bd_chain[PG_PAGE(pg_prod)][PG_IDX(pg_prod)];
9190 		bce_dump_pgbd(sc, pg_prod, pgbd);
9191 		pg_prod = PG_CHAIN_IDX(pg_prod + 1);
9192 	}
9193 
9194 	BCE_PRINTF(
9195 		"----------------------------"
9196 		"----------------"
9197 		"----------------------------\n");
9198 }
9199 #endif
9200 
9201 
9202 /****************************************************************************/
9203 /* Prints out the status block from host memory.                            */
9204 /*                                                                          */
9205 /* Returns:                                                                 */
9206 /*   Nothing.                                                               */
9207 /****************************************************************************/
9208 static __attribute__ ((noinline)) void
9209 bce_dump_status_block(struct bce_softc *sc)
9210 {
9211 	struct status_block *sblk;
9212 
9213 	sblk = sc->status_block;
9214 
9215    	BCE_PRINTF(
9216 		"----------------------------"
9217 		"  Status Block  "
9218 		"----------------------------\n");
9219 
9220 	BCE_PRINTF("    0x%08X - attn_bits\n",
9221 		sblk->status_attn_bits);
9222 
9223 	BCE_PRINTF("    0x%08X - attn_bits_ack\n",
9224 		sblk->status_attn_bits_ack);
9225 
9226 	BCE_PRINTF("0x%04X(0x%04X) - rx_cons0\n",
9227 		sblk->status_rx_quick_consumer_index0,
9228 		(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index0));
9229 
9230 	BCE_PRINTF("0x%04X(0x%04X) - tx_cons0\n",
9231 		sblk->status_tx_quick_consumer_index0,
9232 		(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index0));
9233 
9234 	BCE_PRINTF("        0x%04X - status_idx\n", sblk->status_idx);
9235 
9236 	/* Theses indices are not used for normal L2 drivers. */
9237 	if (sblk->status_rx_quick_consumer_index1)
9238 		BCE_PRINTF("0x%04X(0x%04X) - rx_cons1\n",
9239 			sblk->status_rx_quick_consumer_index1,
9240 			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index1));
9241 
9242 	if (sblk->status_tx_quick_consumer_index1)
9243 		BCE_PRINTF("0x%04X(0x%04X) - tx_cons1\n",
9244 			sblk->status_tx_quick_consumer_index1,
9245 			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index1));
9246 
9247 	if (sblk->status_rx_quick_consumer_index2)
9248 		BCE_PRINTF("0x%04X(0x%04X)- rx_cons2\n",
9249 			sblk->status_rx_quick_consumer_index2,
9250 			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index2));
9251 
9252 	if (sblk->status_tx_quick_consumer_index2)
9253 		BCE_PRINTF("0x%04X(0x%04X) - tx_cons2\n",
9254 			sblk->status_tx_quick_consumer_index2,
9255 			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index2));
9256 
9257 	if (sblk->status_rx_quick_consumer_index3)
9258 		BCE_PRINTF("0x%04X(0x%04X) - rx_cons3\n",
9259 			sblk->status_rx_quick_consumer_index3,
9260 			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index3));
9261 
9262 	if (sblk->status_tx_quick_consumer_index3)
9263 		BCE_PRINTF("0x%04X(0x%04X) - tx_cons3\n",
9264 			sblk->status_tx_quick_consumer_index3,
9265 			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index3));
9266 
9267 	if (sblk->status_rx_quick_consumer_index4 ||
9268 		sblk->status_rx_quick_consumer_index5)
9269 		BCE_PRINTF("rx_cons4  = 0x%08X, rx_cons5      = 0x%08X\n",
9270 			sblk->status_rx_quick_consumer_index4,
9271 			sblk->status_rx_quick_consumer_index5);
9272 
9273 	if (sblk->status_rx_quick_consumer_index6 ||
9274 		sblk->status_rx_quick_consumer_index7)
9275 		BCE_PRINTF("rx_cons6  = 0x%08X, rx_cons7      = 0x%08X\n",
9276 			sblk->status_rx_quick_consumer_index6,
9277 			sblk->status_rx_quick_consumer_index7);
9278 
9279 	if (sblk->status_rx_quick_consumer_index8 ||
9280 		sblk->status_rx_quick_consumer_index9)
9281 		BCE_PRINTF("rx_cons8  = 0x%08X, rx_cons9      = 0x%08X\n",
9282 			sblk->status_rx_quick_consumer_index8,
9283 			sblk->status_rx_quick_consumer_index9);
9284 
9285 	if (sblk->status_rx_quick_consumer_index10 ||
9286 		sblk->status_rx_quick_consumer_index11)
9287 		BCE_PRINTF("rx_cons10 = 0x%08X, rx_cons11     = 0x%08X\n",
9288 			sblk->status_rx_quick_consumer_index10,
9289 			sblk->status_rx_quick_consumer_index11);
9290 
9291 	if (sblk->status_rx_quick_consumer_index12 ||
9292 		sblk->status_rx_quick_consumer_index13)
9293 		BCE_PRINTF("rx_cons12 = 0x%08X, rx_cons13     = 0x%08X\n",
9294 			sblk->status_rx_quick_consumer_index12,
9295 			sblk->status_rx_quick_consumer_index13);
9296 
9297 	if (sblk->status_rx_quick_consumer_index14 ||
9298 		sblk->status_rx_quick_consumer_index15)
9299 		BCE_PRINTF("rx_cons14 = 0x%08X, rx_cons15     = 0x%08X\n",
9300 			sblk->status_rx_quick_consumer_index14,
9301 			sblk->status_rx_quick_consumer_index15);
9302 
9303 	if (sblk->status_completion_producer_index ||
9304 		sblk->status_cmd_consumer_index)
9305 		BCE_PRINTF("com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
9306 			sblk->status_completion_producer_index,
9307 			sblk->status_cmd_consumer_index);
9308 
9309 	BCE_PRINTF(
9310 		"----------------------------"
9311 		"----------------"
9312 		"----------------------------\n");
9313 }
9314 
9315 
9316 /****************************************************************************/
9317 /* Prints out the statistics block from host memory.                        */
9318 /*                                                                          */
9319 /* Returns:                                                                 */
9320 /*   Nothing.                                                               */
9321 /****************************************************************************/
9322 static __attribute__ ((noinline)) void
9323 bce_dump_stats_block(struct bce_softc *sc)
9324 {
9325 	struct statistics_block *sblk;
9326 
9327 	sblk = sc->stats_block;
9328 
9329 	BCE_PRINTF(
9330 		"---------------"
9331 		" Stats Block  (All Stats Not Shown Are 0) "
9332 		"---------------\n");
9333 
9334 	if (sblk->stat_IfHCInOctets_hi
9335 		|| sblk->stat_IfHCInOctets_lo)
9336 		BCE_PRINTF("0x%08X:%08X : "
9337 			"IfHcInOctets\n",
9338 			sblk->stat_IfHCInOctets_hi,
9339 			sblk->stat_IfHCInOctets_lo);
9340 
9341 	if (sblk->stat_IfHCInBadOctets_hi
9342 		|| sblk->stat_IfHCInBadOctets_lo)
9343 		BCE_PRINTF("0x%08X:%08X : "
9344 			"IfHcInBadOctets\n",
9345 			sblk->stat_IfHCInBadOctets_hi,
9346 			sblk->stat_IfHCInBadOctets_lo);
9347 
9348 	if (sblk->stat_IfHCOutOctets_hi
9349 		|| sblk->stat_IfHCOutOctets_lo)
9350 		BCE_PRINTF("0x%08X:%08X : "
9351 			"IfHcOutOctets\n",
9352 			sblk->stat_IfHCOutOctets_hi,
9353 			sblk->stat_IfHCOutOctets_lo);
9354 
9355 	if (sblk->stat_IfHCOutBadOctets_hi
9356 		|| sblk->stat_IfHCOutBadOctets_lo)
9357 		BCE_PRINTF("0x%08X:%08X : "
9358 			"IfHcOutBadOctets\n",
9359 			sblk->stat_IfHCOutBadOctets_hi,
9360 			sblk->stat_IfHCOutBadOctets_lo);
9361 
9362 	if (sblk->stat_IfHCInUcastPkts_hi
9363 		|| sblk->stat_IfHCInUcastPkts_lo)
9364 		BCE_PRINTF("0x%08X:%08X : "
9365 			"IfHcInUcastPkts\n",
9366 			sblk->stat_IfHCInUcastPkts_hi,
9367 			sblk->stat_IfHCInUcastPkts_lo);
9368 
9369 	if (sblk->stat_IfHCInBroadcastPkts_hi
9370 		|| sblk->stat_IfHCInBroadcastPkts_lo)
9371 		BCE_PRINTF("0x%08X:%08X : "
9372 			"IfHcInBroadcastPkts\n",
9373 			sblk->stat_IfHCInBroadcastPkts_hi,
9374 			sblk->stat_IfHCInBroadcastPkts_lo);
9375 
9376 	if (sblk->stat_IfHCInMulticastPkts_hi
9377 		|| sblk->stat_IfHCInMulticastPkts_lo)
9378 		BCE_PRINTF("0x%08X:%08X : "
9379 			"IfHcInMulticastPkts\n",
9380 			sblk->stat_IfHCInMulticastPkts_hi,
9381 			sblk->stat_IfHCInMulticastPkts_lo);
9382 
9383 	if (sblk->stat_IfHCOutUcastPkts_hi
9384 		|| sblk->stat_IfHCOutUcastPkts_lo)
9385 		BCE_PRINTF("0x%08X:%08X : "
9386 			"IfHcOutUcastPkts\n",
9387 			sblk->stat_IfHCOutUcastPkts_hi,
9388 			sblk->stat_IfHCOutUcastPkts_lo);
9389 
9390 	if (sblk->stat_IfHCOutBroadcastPkts_hi
9391 		|| sblk->stat_IfHCOutBroadcastPkts_lo)
9392 		BCE_PRINTF("0x%08X:%08X : "
9393 			"IfHcOutBroadcastPkts\n",
9394 			sblk->stat_IfHCOutBroadcastPkts_hi,
9395 			sblk->stat_IfHCOutBroadcastPkts_lo);
9396 
9397 	if (sblk->stat_IfHCOutMulticastPkts_hi
9398 		|| sblk->stat_IfHCOutMulticastPkts_lo)
9399 		BCE_PRINTF("0x%08X:%08X : "
9400 			"IfHcOutMulticastPkts\n",
9401 			sblk->stat_IfHCOutMulticastPkts_hi,
9402 			sblk->stat_IfHCOutMulticastPkts_lo);
9403 
9404 	if (sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors)
9405 		BCE_PRINTF("         0x%08X : "
9406 			"emac_tx_stat_dot3statsinternalmactransmiterrors\n",
9407 			sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
9408 
9409 	if (sblk->stat_Dot3StatsCarrierSenseErrors)
9410 		BCE_PRINTF("         0x%08X : Dot3StatsCarrierSenseErrors\n",
9411 			sblk->stat_Dot3StatsCarrierSenseErrors);
9412 
9413 	if (sblk->stat_Dot3StatsFCSErrors)
9414 		BCE_PRINTF("         0x%08X : Dot3StatsFCSErrors\n",
9415 			sblk->stat_Dot3StatsFCSErrors);
9416 
9417 	if (sblk->stat_Dot3StatsAlignmentErrors)
9418 		BCE_PRINTF("         0x%08X : Dot3StatsAlignmentErrors\n",
9419 			sblk->stat_Dot3StatsAlignmentErrors);
9420 
9421 	if (sblk->stat_Dot3StatsSingleCollisionFrames)
9422 		BCE_PRINTF("         0x%08X : Dot3StatsSingleCollisionFrames\n",
9423 			sblk->stat_Dot3StatsSingleCollisionFrames);
9424 
9425 	if (sblk->stat_Dot3StatsMultipleCollisionFrames)
9426 		BCE_PRINTF("         0x%08X : Dot3StatsMultipleCollisionFrames\n",
9427 			sblk->stat_Dot3StatsMultipleCollisionFrames);
9428 
9429 	if (sblk->stat_Dot3StatsDeferredTransmissions)
9430 		BCE_PRINTF("         0x%08X : Dot3StatsDeferredTransmissions\n",
9431 			sblk->stat_Dot3StatsDeferredTransmissions);
9432 
9433 	if (sblk->stat_Dot3StatsExcessiveCollisions)
9434 		BCE_PRINTF("         0x%08X : Dot3StatsExcessiveCollisions\n",
9435 			sblk->stat_Dot3StatsExcessiveCollisions);
9436 
9437 	if (sblk->stat_Dot3StatsLateCollisions)
9438 		BCE_PRINTF("         0x%08X : Dot3StatsLateCollisions\n",
9439 			sblk->stat_Dot3StatsLateCollisions);
9440 
9441 	if (sblk->stat_EtherStatsCollisions)
9442 		BCE_PRINTF("         0x%08X : EtherStatsCollisions\n",
9443 			sblk->stat_EtherStatsCollisions);
9444 
9445 	if (sblk->stat_EtherStatsFragments)
9446 		BCE_PRINTF("         0x%08X : EtherStatsFragments\n",
9447 			sblk->stat_EtherStatsFragments);
9448 
9449 	if (sblk->stat_EtherStatsJabbers)
9450 		BCE_PRINTF("         0x%08X : EtherStatsJabbers\n",
9451 			sblk->stat_EtherStatsJabbers);
9452 
9453 	if (sblk->stat_EtherStatsUndersizePkts)
9454 		BCE_PRINTF("         0x%08X : EtherStatsUndersizePkts\n",
9455 			sblk->stat_EtherStatsUndersizePkts);
9456 
9457 	if (sblk->stat_EtherStatsOverrsizePkts)
9458 		BCE_PRINTF("         0x%08X : EtherStatsOverrsizePkts\n",
9459 			sblk->stat_EtherStatsOverrsizePkts);
9460 
9461 	if (sblk->stat_EtherStatsPktsRx64Octets)
9462 		BCE_PRINTF("         0x%08X : EtherStatsPktsRx64Octets\n",
9463 			sblk->stat_EtherStatsPktsRx64Octets);
9464 
9465 	if (sblk->stat_EtherStatsPktsRx65Octetsto127Octets)
9466 		BCE_PRINTF("         0x%08X : EtherStatsPktsRx65Octetsto127Octets\n",
9467 			sblk->stat_EtherStatsPktsRx65Octetsto127Octets);
9468 
9469 	if (sblk->stat_EtherStatsPktsRx128Octetsto255Octets)
9470 		BCE_PRINTF("         0x%08X : EtherStatsPktsRx128Octetsto255Octets\n",
9471 			sblk->stat_EtherStatsPktsRx128Octetsto255Octets);
9472 
9473 	if (sblk->stat_EtherStatsPktsRx256Octetsto511Octets)
9474 		BCE_PRINTF("         0x%08X : EtherStatsPktsRx256Octetsto511Octets\n",
9475 			sblk->stat_EtherStatsPktsRx256Octetsto511Octets);
9476 
9477 	if (sblk->stat_EtherStatsPktsRx512Octetsto1023Octets)
9478 		BCE_PRINTF("         0x%08X : EtherStatsPktsRx512Octetsto1023Octets\n",
9479 			sblk->stat_EtherStatsPktsRx512Octetsto1023Octets);
9480 
9481 	if (sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets)
9482 		BCE_PRINTF("         0x%08X : EtherStatsPktsRx1024Octetsto1522Octets\n",
9483 			sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets);
9484 
9485 	if (sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets)
9486 		BCE_PRINTF("         0x%08X : EtherStatsPktsRx1523Octetsto9022Octets\n",
9487 			sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets);
9488 
9489 	if (sblk->stat_EtherStatsPktsTx64Octets)
9490 		BCE_PRINTF("         0x%08X : EtherStatsPktsTx64Octets\n",
9491 			sblk->stat_EtherStatsPktsTx64Octets);
9492 
9493 	if (sblk->stat_EtherStatsPktsTx65Octetsto127Octets)
9494 		BCE_PRINTF("         0x%08X : EtherStatsPktsTx65Octetsto127Octets\n",
9495 			sblk->stat_EtherStatsPktsTx65Octetsto127Octets);
9496 
9497 	if (sblk->stat_EtherStatsPktsTx128Octetsto255Octets)
9498 		BCE_PRINTF("         0x%08X : EtherStatsPktsTx128Octetsto255Octets\n",
9499 			sblk->stat_EtherStatsPktsTx128Octetsto255Octets);
9500 
9501 	if (sblk->stat_EtherStatsPktsTx256Octetsto511Octets)
9502 		BCE_PRINTF("         0x%08X : EtherStatsPktsTx256Octetsto511Octets\n",
9503 			sblk->stat_EtherStatsPktsTx256Octetsto511Octets);
9504 
9505 	if (sblk->stat_EtherStatsPktsTx512Octetsto1023Octets)
9506 		BCE_PRINTF("         0x%08X : EtherStatsPktsTx512Octetsto1023Octets\n",
9507 			sblk->stat_EtherStatsPktsTx512Octetsto1023Octets);
9508 
9509 	if (sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets)
9510 		BCE_PRINTF("         0x%08X : EtherStatsPktsTx1024Octetsto1522Octets\n",
9511 			sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets);
9512 
9513 	if (sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets)
9514 		BCE_PRINTF("         0x%08X : EtherStatsPktsTx1523Octetsto9022Octets\n",
9515 			sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets);
9516 
9517 	if (sblk->stat_XonPauseFramesReceived)
9518 		BCE_PRINTF("         0x%08X : XonPauseFramesReceived\n",
9519 			sblk->stat_XonPauseFramesReceived);
9520 
9521 	if (sblk->stat_XoffPauseFramesReceived)
9522 	   BCE_PRINTF("          0x%08X : XoffPauseFramesReceived\n",
9523 			sblk->stat_XoffPauseFramesReceived);
9524 
9525 	if (sblk->stat_OutXonSent)
9526 		BCE_PRINTF("         0x%08X : OutXonSent\n",
9527 			sblk->stat_OutXonSent);
9528 
9529 	if (sblk->stat_OutXoffSent)
9530 		BCE_PRINTF("         0x%08X : OutXoffSent\n",
9531 			sblk->stat_OutXoffSent);
9532 
9533 	if (sblk->stat_FlowControlDone)
9534 		BCE_PRINTF("         0x%08X : FlowControlDone\n",
9535 			sblk->stat_FlowControlDone);
9536 
9537 	if (sblk->stat_MacControlFramesReceived)
9538 		BCE_PRINTF("         0x%08X : MacControlFramesReceived\n",
9539 			sblk->stat_MacControlFramesReceived);
9540 
9541 	if (sblk->stat_XoffStateEntered)
9542 		BCE_PRINTF("         0x%08X : XoffStateEntered\n",
9543 			sblk->stat_XoffStateEntered);
9544 
9545 	if (sblk->stat_IfInFramesL2FilterDiscards)
9546 		BCE_PRINTF("         0x%08X : IfInFramesL2FilterDiscards\n",
9547 			sblk->stat_IfInFramesL2FilterDiscards);
9548 
9549 	if (sblk->stat_IfInRuleCheckerDiscards)
9550 		BCE_PRINTF("         0x%08X : IfInRuleCheckerDiscards\n",
9551 			sblk->stat_IfInRuleCheckerDiscards);
9552 
9553 	if (sblk->stat_IfInFTQDiscards)
9554 		BCE_PRINTF("         0x%08X : IfInFTQDiscards\n",
9555 			sblk->stat_IfInFTQDiscards);
9556 
9557 	if (sblk->stat_IfInMBUFDiscards)
9558 		BCE_PRINTF("         0x%08X : IfInMBUFDiscards\n",
9559 			sblk->stat_IfInMBUFDiscards);
9560 
9561 	if (sblk->stat_IfInRuleCheckerP4Hit)
9562 		BCE_PRINTF("         0x%08X : IfInRuleCheckerP4Hit\n",
9563 			sblk->stat_IfInRuleCheckerP4Hit);
9564 
9565 	if (sblk->stat_CatchupInRuleCheckerDiscards)
9566 		BCE_PRINTF("         0x%08X : CatchupInRuleCheckerDiscards\n",
9567 			sblk->stat_CatchupInRuleCheckerDiscards);
9568 
9569 	if (sblk->stat_CatchupInFTQDiscards)
9570 		BCE_PRINTF("         0x%08X : CatchupInFTQDiscards\n",
9571 			sblk->stat_CatchupInFTQDiscards);
9572 
9573 	if (sblk->stat_CatchupInMBUFDiscards)
9574 		BCE_PRINTF("         0x%08X : CatchupInMBUFDiscards\n",
9575 			sblk->stat_CatchupInMBUFDiscards);
9576 
9577 	if (sblk->stat_CatchupInRuleCheckerP4Hit)
9578 		BCE_PRINTF("         0x%08X : CatchupInRuleCheckerP4Hit\n",
9579 			sblk->stat_CatchupInRuleCheckerP4Hit);
9580 
9581 	BCE_PRINTF(
9582 		"----------------------------"
9583 		"----------------"
9584 		"----------------------------\n");
9585 }
9586 
9587 
9588 /****************************************************************************/
9589 /* Prints out a summary of the driver state.                                */
9590 /*                                                                          */
9591 /* Returns:                                                                 */
9592 /*   Nothing.                                                               */
9593 /****************************************************************************/
9594 static __attribute__ ((noinline)) void
9595 bce_dump_driver_state(struct bce_softc *sc)
9596 {
9597 	u32 val_hi, val_lo;
9598 
9599 	BCE_PRINTF(
9600 		"-----------------------------"
9601 		" Driver State "
9602 		"-----------------------------\n");
9603 
9604 	val_hi = BCE_ADDR_HI(sc);
9605 	val_lo = BCE_ADDR_LO(sc);
9606 	BCE_PRINTF("0x%08X:%08X - (sc) driver softc structure virtual address\n",
9607 		val_hi, val_lo);
9608 
9609 	val_hi = BCE_ADDR_HI(sc->bce_vhandle);
9610 	val_lo = BCE_ADDR_LO(sc->bce_vhandle);
9611 	BCE_PRINTF("0x%08X:%08X - (sc->bce_vhandle) PCI BAR virtual address\n",
9612 		val_hi, val_lo);
9613 
9614 	val_hi = BCE_ADDR_HI(sc->status_block);
9615 	val_lo = BCE_ADDR_LO(sc->status_block);
9616 	BCE_PRINTF("0x%08X:%08X - (sc->status_block) status block virtual address\n",
9617 		val_hi, val_lo);
9618 
9619 	val_hi = BCE_ADDR_HI(sc->stats_block);
9620 	val_lo = BCE_ADDR_LO(sc->stats_block);
9621 	BCE_PRINTF("0x%08X:%08X - (sc->stats_block) statistics block virtual address\n",
9622 		val_hi, val_lo);
9623 
9624 	val_hi = BCE_ADDR_HI(sc->tx_bd_chain);
9625 	val_lo = BCE_ADDR_LO(sc->tx_bd_chain);
9626 	BCE_PRINTF(
9627 		"0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain virtual adddress\n",
9628 		val_hi, val_lo);
9629 
9630 	val_hi = BCE_ADDR_HI(sc->rx_bd_chain);
9631 	val_lo = BCE_ADDR_LO(sc->rx_bd_chain);
9632 	BCE_PRINTF(
9633 		"0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain virtual address\n",
9634 		val_hi, val_lo);
9635 
9636 #ifdef BCE_USE_SPLIT_HEADER
9637 	val_hi = BCE_ADDR_HI(sc->pg_bd_chain);
9638 	val_lo = BCE_ADDR_LO(sc->pg_bd_chain);
9639 	BCE_PRINTF(
9640 		"0x%08X:%08X - (sc->pg_bd_chain) page chain virtual address\n",
9641 		val_hi, val_lo);
9642 #endif
9643 
9644 	val_hi = BCE_ADDR_HI(sc->tx_mbuf_ptr);
9645 	val_lo = BCE_ADDR_LO(sc->tx_mbuf_ptr);
9646 	BCE_PRINTF(
9647 		"0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain virtual address\n",
9648 		val_hi, val_lo);
9649 
9650 	val_hi = BCE_ADDR_HI(sc->rx_mbuf_ptr);
9651 	val_lo = BCE_ADDR_LO(sc->rx_mbuf_ptr);
9652 	BCE_PRINTF(
9653 		"0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain virtual address\n",
9654 		val_hi, val_lo);
9655 
9656 #ifdef BCE_USE_SPLIT_HEADER
9657 	val_hi = BCE_ADDR_HI(sc->pg_mbuf_ptr);
9658 	val_lo = BCE_ADDR_LO(sc->pg_mbuf_ptr);
9659 	BCE_PRINTF(
9660 		"0x%08X:%08X - (sc->pg_mbuf_ptr) page mbuf chain virtual address\n",
9661 		val_hi, val_lo);
9662 #endif
9663 
9664 	BCE_PRINTF("         0x%08X - (sc->interrupts_generated) h/w intrs\n",
9665 		sc->interrupts_generated);
9666 
9667 	BCE_PRINTF("         0x%08X - (sc->rx_interrupts) rx interrupts handled\n",
9668 		sc->rx_interrupts);
9669 
9670 	BCE_PRINTF("         0x%08X - (sc->tx_interrupts) tx interrupts handled\n",
9671 		sc->tx_interrupts);
9672 
9673 	BCE_PRINTF("         0x%08X - (sc->last_status_idx) status block index\n",
9674 		sc->last_status_idx);
9675 
9676 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_prod) tx producer index\n",
9677 		sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod));
9678 
9679 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_cons) tx consumer index\n",
9680 		sc->tx_cons, (u16) TX_CHAIN_IDX(sc->tx_cons));
9681 
9682 	BCE_PRINTF("         0x%08X - (sc->tx_prod_bseq) tx producer bseq index\n",
9683 		sc->tx_prod_bseq);
9684 
9685 	BCE_PRINTF("         0x%08X - (sc->debug_tx_mbuf_alloc) tx mbufs allocated\n",
9686 		sc->debug_tx_mbuf_alloc);
9687 
9688 	BCE_PRINTF("         0x%08X - (sc->used_tx_bd) used tx_bd's\n",
9689 		sc->used_tx_bd);
9690 
9691 	BCE_PRINTF("0x%08X/%08X - (sc->tx_hi_watermark) tx hi watermark\n",
9692 		sc->tx_hi_watermark, sc->max_tx_bd);
9693 
9694 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_prod) rx producer index\n",
9695 		sc->rx_prod, (u16) RX_CHAIN_IDX(sc->rx_prod));
9696 
9697 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_cons) rx consumer index\n",
9698 		sc->rx_cons, (u16) RX_CHAIN_IDX(sc->rx_cons));
9699 
9700 	BCE_PRINTF("         0x%08X - (sc->rx_prod_bseq) rx producer bseq index\n",
9701 		sc->rx_prod_bseq);
9702 
9703 	BCE_PRINTF("         0x%08X - (sc->debug_rx_mbuf_alloc) rx mbufs allocated\n",
9704 		sc->debug_rx_mbuf_alloc);
9705 
9706 	BCE_PRINTF("         0x%08X - (sc->free_rx_bd) free rx_bd's\n",
9707 		sc->free_rx_bd);
9708 
9709 #ifdef BCE_USE_SPLIT_HEADER
9710 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_prod) page producer index\n",
9711 		sc->pg_prod, (u16) PG_CHAIN_IDX(sc->pg_prod));
9712 
9713 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_cons) page consumer index\n",
9714 		sc->pg_cons, (u16) PG_CHAIN_IDX(sc->pg_cons));
9715 
9716 	BCE_PRINTF("         0x%08X - (sc->debug_pg_mbuf_alloc) page mbufs allocated\n",
9717 		sc->debug_pg_mbuf_alloc);
9718 
9719 	BCE_PRINTF("         0x%08X - (sc->free_pg_bd) free page rx_bd's\n",
9720 		sc->free_pg_bd);
9721 
9722 	BCE_PRINTF("0x%08X/%08X - (sc->pg_low_watermark) page low watermark\n",
9723 		sc->pg_low_watermark, sc->max_pg_bd);
9724 #endif
9725 
9726 	BCE_PRINTF("         0x%08X - (sc->mbuf_alloc_failed) "
9727 		"mbuf alloc failures\n",
9728 		sc->mbuf_alloc_failed);
9729 
9730 	BCE_PRINTF("         0x%08X - (sc->debug_mbuf_sim_alloc_failed) "
9731 		"simulated mbuf alloc failures\n",
9732 		sc->debug_mbuf_sim_alloc_failed);
9733 
9734 	BCE_PRINTF("         0x%08X - (sc->bce_flags) bce mac flags\n",
9735 		sc->bce_flags);
9736 
9737 	BCE_PRINTF("         0x%08X - (sc->bce_phy_flags) bce phy flags\n",
9738 		sc->bce_phy_flags);
9739 
9740 	BCE_PRINTF(
9741 		"----------------------------"
9742 		"----------------"
9743 		"----------------------------\n");
9744 }
9745 
9746 
9747 /****************************************************************************/
9748 /* Prints out the hardware state through a summary of important register,   */
9749 /* followed by a complete register dump.                                    */
9750 /*                                                                          */
9751 /* Returns:                                                                 */
9752 /*   Nothing.                                                               */
9753 /****************************************************************************/
9754 static __attribute__ ((noinline)) void
9755 bce_dump_hw_state(struct bce_softc *sc)
9756 {
9757 	u32 val;
9758 
9759 	BCE_PRINTF(
9760 		"----------------------------"
9761 		" Hardware State "
9762 		"----------------------------\n");
9763 
9764 	BCE_PRINTF("0x%08X - bootcode version\n", sc->bce_fw_ver);
9765 
9766 	val = REG_RD(sc, BCE_MISC_ENABLE_STATUS_BITS);
9767 	BCE_PRINTF("0x%08X - (0x%06X) misc_enable_status_bits\n",
9768 		val, BCE_MISC_ENABLE_STATUS_BITS);
9769 
9770 	val = REG_RD(sc, BCE_DMA_STATUS);
9771 	BCE_PRINTF("0x%08X - (0x%06X) dma_status\n", val, BCE_DMA_STATUS);
9772 
9773 	val = REG_RD(sc, BCE_CTX_STATUS);
9774 	BCE_PRINTF("0x%08X - (0x%06X) ctx_status\n", val, BCE_CTX_STATUS);
9775 
9776 	val = REG_RD(sc, BCE_EMAC_STATUS);
9777 	BCE_PRINTF("0x%08X - (0x%06X) emac_status\n", val, BCE_EMAC_STATUS);
9778 
9779 	val = REG_RD(sc, BCE_RPM_STATUS);
9780 	BCE_PRINTF("0x%08X - (0x%06X) rpm_status\n", val, BCE_RPM_STATUS);
9781 
9782 	val = REG_RD(sc, 0x2004);
9783 	BCE_PRINTF("0x%08X - (0x%06X) rlup_status\n", val, 0x2004);
9784 
9785 	val = REG_RD(sc, BCE_RV2P_STATUS);
9786 	BCE_PRINTF("0x%08X - (0x%06X) rv2p_status\n", val, BCE_RV2P_STATUS);
9787 
9788 	val = REG_RD(sc, 0x2c04);
9789 	BCE_PRINTF("0x%08X - (0x%06X) rdma_status\n", val, 0x2c04);
9790 
9791 	val = REG_RD(sc, BCE_TBDR_STATUS);
9792 	BCE_PRINTF("0x%08X - (0x%06X) tbdr_status\n", val, BCE_TBDR_STATUS);
9793 
9794 	val = REG_RD(sc, BCE_TDMA_STATUS);
9795 	BCE_PRINTF("0x%08X - (0x%06X) tdma_status\n", val, BCE_TDMA_STATUS);
9796 
9797 	val = REG_RD(sc, BCE_HC_STATUS);
9798 	BCE_PRINTF("0x%08X - (0x%06X) hc_status\n", val, BCE_HC_STATUS);
9799 
9800 	val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
9801 	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n", val, BCE_TXP_CPU_STATE);
9802 
9803 	val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
9804 	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n", val, BCE_TPAT_CPU_STATE);
9805 
9806 	val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
9807 	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n", val, BCE_RXP_CPU_STATE);
9808 
9809 	val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
9810 	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n", val, BCE_COM_CPU_STATE);
9811 
9812 	val = REG_RD_IND(sc, BCE_MCP_CPU_STATE);
9813 	BCE_PRINTF("0x%08X - (0x%06X) mcp_cpu_state\n", val, BCE_MCP_CPU_STATE);
9814 
9815 	val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
9816 	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n", val, BCE_CP_CPU_STATE);
9817 
9818 	BCE_PRINTF(
9819 		"----------------------------"
9820 		"----------------"
9821 		"----------------------------\n");
9822 
9823 	BCE_PRINTF(
9824 		"----------------------------"
9825 		" Register  Dump "
9826 		"----------------------------\n");
9827 
9828 	for (int i = 0x400; i < 0x8000; i += 0x10) {
9829 		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
9830 			i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
9831 			REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
9832 	}
9833 
9834 	BCE_PRINTF(
9835 		"----------------------------"
9836 		"----------------"
9837 		"----------------------------\n");
9838 }
9839 
9840 
9841 /****************************************************************************/
9842 /* Prints out the mailbox queue registers.                                  */
9843 /*                                                                          */
9844 /* Returns:                                                                 */
9845 /*   Nothing.                                                               */
9846 /****************************************************************************/
9847 static __attribute__ ((noinline)) void
9848 bce_dump_mq_regs(struct bce_softc *sc)
9849 {
9850 	BCE_PRINTF(
9851 		"----------------------------"
9852 		"    MQ Regs     "
9853 		"----------------------------\n");
9854 
9855 	BCE_PRINTF(
9856 		"----------------------------"
9857 		"----------------"
9858 		"----------------------------\n");
9859 
9860 	for (int i = 0x3c00; i < 0x4000; i += 0x10) {
9861 		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
9862 			i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
9863 			REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
9864 	}
9865 
9866 	BCE_PRINTF(
9867 		"----------------------------"
9868 		"----------------"
9869 		"----------------------------\n");
9870 }
9871 
9872 
9873 /****************************************************************************/
9874 /* Prints out the bootcode state.                                           */
9875 /*                                                                          */
9876 /* Returns:                                                                 */
9877 /*   Nothing.                                                               */
9878 /****************************************************************************/
9879 static __attribute__ ((noinline)) void
9880 bce_dump_bc_state(struct bce_softc *sc)
9881 {
9882 	u32 val;
9883 
9884 	BCE_PRINTF(
9885 		"----------------------------"
9886 		" Bootcode State "
9887 		"----------------------------\n");
9888 
9889 	BCE_PRINTF("0x%08X - bootcode version\n", sc->bce_fw_ver);
9890 
9891 	val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_BC_RESET_TYPE);
9892 	BCE_PRINTF("0x%08X - (0x%06X) reset_type\n",
9893 		val, BCE_BC_RESET_TYPE);
9894 
9895 	val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_BC_STATE);
9896 	BCE_PRINTF("0x%08X - (0x%06X) state\n",
9897 		val, BCE_BC_STATE);
9898 
9899 	val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_BC_CONDITION);
9900 	BCE_PRINTF("0x%08X - (0x%06X) condition\n",
9901 		val, BCE_BC_CONDITION);
9902 
9903 	val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_BC_STATE_DEBUG_CMD);
9904 	BCE_PRINTF("0x%08X - (0x%06X) debug_cmd\n",
9905 		val, BCE_BC_STATE_DEBUG_CMD);
9906 
9907 	BCE_PRINTF(
9908 		"----------------------------"
9909 		"----------------"
9910 		"----------------------------\n");
9911 }
9912 
9913 
9914 /****************************************************************************/
9915 /* Prints out the TXP processor state.                                      */
9916 /*                                                                          */
9917 /* Returns:                                                                 */
9918 /*   Nothing.                                                               */
9919 /****************************************************************************/
9920 static __attribute__ ((noinline)) void
9921 bce_dump_txp_state(struct bce_softc *sc, int regs)
9922 {
9923 	u32 val;
9924 	u32 fw_version[3];
9925 
9926 	BCE_PRINTF(
9927 		"----------------------------"
9928 		"   TXP  State   "
9929 		"----------------------------\n");
9930 
9931 	for (int i = 0; i < 3; i++)
9932 		fw_version[i] = htonl(REG_RD_IND(sc,
9933 			(BCE_TXP_SCRATCH + 0x10 + i * 4)));
9934 	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
9935 
9936 	val = REG_RD_IND(sc, BCE_TXP_CPU_MODE);
9937 	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_mode\n", val, BCE_TXP_CPU_MODE);
9938 
9939 	val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
9940 	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n", val, BCE_TXP_CPU_STATE);
9941 
9942 	val = REG_RD_IND(sc, BCE_TXP_CPU_EVENT_MASK);
9943 	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_event_mask\n", val,
9944 		BCE_TXP_CPU_EVENT_MASK);
9945 
9946 	if (regs) {
9947 		BCE_PRINTF(
9948 			"----------------------------"
9949 			" Register  Dump "
9950 			"----------------------------\n");
9951 
9952 		for (int i = BCE_TXP_CPU_MODE; i < 0x68000; i += 0x10) {
9953 			/* Skip the big blank spaces */
9954 			if (i < 0x454000 && i > 0x5ffff)
9955 				BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
9956 					i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
9957 					REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
9958 		}
9959 	}
9960 
9961 	BCE_PRINTF(
9962 		"----------------------------"
9963 		"----------------"
9964 		"----------------------------\n");
9965 }
9966 
9967 
9968 /****************************************************************************/
9969 /* Prints out the RXP processor state.                                      */
9970 /*                                                                          */
9971 /* Returns:                                                                 */
9972 /*   Nothing.                                                               */
9973 /****************************************************************************/
9974 static __attribute__ ((noinline)) void
9975 bce_dump_rxp_state(struct bce_softc *sc, int regs)
9976 {
9977 	u32 val;
9978 	u32 fw_version[3];
9979 
9980 	BCE_PRINTF(
9981 		"----------------------------"
9982 		"   RXP  State   "
9983 		"----------------------------\n");
9984 
9985 	for (int i = 0; i < 3; i++)
9986 		fw_version[i] = htonl(REG_RD_IND(sc,
9987 			(BCE_RXP_SCRATCH + 0x10 + i * 4)));
9988 	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
9989 
9990 	val = REG_RD_IND(sc, BCE_RXP_CPU_MODE);
9991 	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_mode\n", val, BCE_RXP_CPU_MODE);
9992 
9993 	val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
9994 	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n", val, BCE_RXP_CPU_STATE);
9995 
9996 	val = REG_RD_IND(sc, BCE_RXP_CPU_EVENT_MASK);
9997 	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_event_mask\n", val,
9998 		BCE_RXP_CPU_EVENT_MASK);
9999 
10000 	if (regs) {
10001 		BCE_PRINTF(
10002 			"----------------------------"
10003 			" Register  Dump "
10004 			"----------------------------\n");
10005 
10006 		for (int i = BCE_RXP_CPU_MODE; i < 0xe8fff; i += 0x10) {
10007 			/* Skip the big blank sapces */
10008 			if (i < 0xc5400 && i > 0xdffff)
10009 				BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10010 	 				i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
10011 					REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
10012 		}
10013 	}
10014 
10015 	BCE_PRINTF(
10016 		"----------------------------"
10017 		"----------------"
10018 		"----------------------------\n");
10019 }
10020 
10021 
10022 /****************************************************************************/
10023 /* Prints out the TPAT processor state.                                     */
10024 /*                                                                          */
10025 /* Returns:                                                                 */
10026 /*   Nothing.                                                               */
10027 /****************************************************************************/
10028 static __attribute__ ((noinline)) void
10029 bce_dump_tpat_state(struct bce_softc *sc, int regs)
10030 {
10031 	u32 val;
10032 	u32 fw_version[3];
10033 
10034 	BCE_PRINTF(
10035 		"----------------------------"
10036 		"   TPAT State   "
10037 		"----------------------------\n");
10038 
10039 	for (int i = 0; i < 3; i++)
10040 		fw_version[i] = htonl(REG_RD_IND(sc,
10041 			(BCE_TPAT_SCRATCH + 0x410 + i * 4)));
10042 	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10043 
10044 	val = REG_RD_IND(sc, BCE_TPAT_CPU_MODE);
10045 	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_mode\n", val, BCE_TPAT_CPU_MODE);
10046 
10047 	val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
10048 	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n", val, BCE_TPAT_CPU_STATE);
10049 
10050 	val = REG_RD_IND(sc, BCE_TPAT_CPU_EVENT_MASK);
10051 	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_event_mask\n", val,
10052 		BCE_TPAT_CPU_EVENT_MASK);
10053 
10054 	if (regs) {
10055 		BCE_PRINTF(
10056 			"----------------------------"
10057 			" Register  Dump "
10058 			"----------------------------\n");
10059 
10060 		for (int i = BCE_TPAT_CPU_MODE; i < 0xa3fff; i += 0x10) {
10061 			/* Skip the big blank spaces */
10062 			if (i < 0x854000 && i > 0x9ffff)
10063 				BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10064 					i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
10065 					REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
10066 		}
10067 	}
10068 
10069 	BCE_PRINTF(
10070 		"----------------------------"
10071 		"----------------"
10072 		"----------------------------\n");
10073 }
10074 
10075 
10076 /****************************************************************************/
10077 /* Prints out the Command Procesor (CP) state.                              */
10078 /*                                                                          */
10079 /* Returns:                                                                 */
10080 /*   Nothing.                                                               */
10081 /****************************************************************************/
10082 static __attribute__ ((noinline)) void
10083 bce_dump_cp_state(struct bce_softc *sc, int regs)
10084 {
10085 	u32 val;
10086 	u32 fw_version[3];
10087 
10088 	BCE_PRINTF(
10089 		"----------------------------"
10090 		"    CP State    "
10091 		"----------------------------\n");
10092 
10093 	for (int i = 0; i < 3; i++)
10094 		fw_version[i] = htonl(REG_RD_IND(sc,
10095 			(BCE_CP_SCRATCH + 0x10 + i * 4)));
10096 	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10097 
10098 	val = REG_RD_IND(sc, BCE_CP_CPU_MODE);
10099 	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_mode\n", val, BCE_CP_CPU_MODE);
10100 
10101 	val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
10102 	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n", val, BCE_CP_CPU_STATE);
10103 
10104 	val = REG_RD_IND(sc, BCE_CP_CPU_EVENT_MASK);
10105 	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_event_mask\n", val,
10106 		BCE_CP_CPU_EVENT_MASK);
10107 
10108 	if (regs) {
10109 		BCE_PRINTF(
10110 			"----------------------------"
10111 			" Register  Dump "
10112 			"----------------------------\n");
10113 
10114 		for (int i = BCE_CP_CPU_MODE; i < 0x1aa000; i += 0x10) {
10115 			/* Skip the big blank spaces */
10116 			if (i < 0x185400 && i > 0x19ffff)
10117 				BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10118 					i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
10119 					REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
10120 		}
10121 	}
10122 
10123 	BCE_PRINTF(
10124 		"----------------------------"
10125 		"----------------"
10126 		"----------------------------\n");
10127 }
10128 
10129 
10130 /****************************************************************************/
10131 /* Prints out the Completion Procesor (COM) state.                          */
10132 /*                                                                          */
10133 /* Returns:                                                                 */
10134 /*   Nothing.                                                               */
10135 /****************************************************************************/
10136 static __attribute__ ((noinline)) void
10137 bce_dump_com_state(struct bce_softc *sc, int regs)
10138 {
10139 	u32 val;
10140 	u32 fw_version[3];
10141 
10142 	BCE_PRINTF(
10143 		"----------------------------"
10144 		"   COM State    "
10145 		"----------------------------\n");
10146 
10147 	for (int i = 0; i < 3; i++)
10148 		fw_version[i] = htonl(REG_RD_IND(sc,
10149 			(BCE_COM_SCRATCH + 0x10 + i * 4)));
10150 	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10151 
10152 	val = REG_RD_IND(sc, BCE_COM_CPU_MODE);
10153 	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_mode\n", val, BCE_COM_CPU_MODE);
10154 
10155 	val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
10156 	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n", val, BCE_COM_CPU_STATE);
10157 
10158 	val = REG_RD_IND(sc, BCE_COM_CPU_EVENT_MASK);
10159 	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_event_mask\n", val,
10160 		BCE_COM_CPU_EVENT_MASK);
10161 
10162 	if (regs) {
10163 		BCE_PRINTF(
10164 			"----------------------------"
10165 			" Register  Dump "
10166 			"----------------------------\n");
10167 
10168 		for (int i = BCE_COM_CPU_MODE; i < 0x1053e8; i += 0x10) {
10169 			BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10170 				i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
10171 				REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
10172 		}
10173 	}
10174 
10175 	BCE_PRINTF(
10176 		"----------------------------"
10177 		"----------------"
10178 		"----------------------------\n");
10179 }
10180 
10181 
10182 /****************************************************************************/
10183 /* Prints out the driver state and then enters the debugger.                */
10184 /*                                                                          */
10185 /* Returns:                                                                 */
10186 /*   Nothing.                                                               */
10187 /****************************************************************************/
10188 static void
10189 bce_breakpoint(struct bce_softc *sc)
10190 {
10191 
10192 	/*
10193 	 * Unreachable code to silence compiler warnings
10194 	 * about unused functions.
10195 	 */
10196 	if (0) {
10197 		bce_freeze_controller(sc);
10198 		bce_unfreeze_controller(sc);
10199 		bce_dump_enet(sc, NULL);
10200    		bce_dump_txbd(sc, 0, NULL);
10201 		bce_dump_rxbd(sc, 0, NULL);
10202 		bce_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD);
10203 		bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD);
10204 		bce_dump_l2fhdr(sc, 0, NULL);
10205 		bce_dump_ctx(sc, RX_CID);
10206 		bce_dump_ftqs(sc);
10207 		bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
10208 		bce_dump_rx_chain(sc, 0, USABLE_RX_BD);
10209 		bce_dump_status_block(sc);
10210 		bce_dump_stats_block(sc);
10211 		bce_dump_driver_state(sc);
10212 		bce_dump_hw_state(sc);
10213 		bce_dump_bc_state(sc);
10214 		bce_dump_txp_state(sc, 0);
10215 		bce_dump_rxp_state(sc, 0);
10216 		bce_dump_tpat_state(sc, 0);
10217 		bce_dump_cp_state(sc, 0);
10218 		bce_dump_com_state(sc, 0);
10219 #ifdef BCE_USE_SPLIT_HEADER
10220 		bce_dump_pgbd(sc, 0, NULL);
10221 		bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD);
10222 		bce_dump_pg_chain(sc, 0, USABLE_PG_BD);
10223 #endif
10224 	}
10225 
10226 	bce_dump_status_block(sc);
10227 	bce_dump_driver_state(sc);
10228 
10229 	/* Call the debugger. */
10230 	breakpoint();
10231 
10232 	return;
10233 }
10234 #endif
10235 
10236