xref: /freebsd/sys/dev/bce/if_bce.c (revision 4c8945a06b01a5c8122cdeb402af36bb46a06acc)
1 /*-
2  * Copyright (c) 2006-2010 Broadcom Corporation
3  *	David Christensen <davidch@broadcom.com>.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of Broadcom Corporation nor the name of its contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written consent.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 /*
35  * The following controllers are supported by this driver:
36  *   BCM5706C A2, A3
37  *   BCM5706S A2, A3
38  *   BCM5708C B1, B2
39  *   BCM5708S B1, B2
40  *   BCM5709C A1, C0
41  *   BCM5709S A1, C0
42  *   BCM5716C C0
43  *   BCM5716S C0
44  *
45  * The following controllers are not supported by this driver:
46  *   BCM5706C A0, A1 (pre-production)
47  *   BCM5706S A0, A1 (pre-production)
48  *   BCM5708C A0, B0 (pre-production)
49  *   BCM5708S A0, B0 (pre-production)
50  *   BCM5709C A0  B0, B1, B2 (pre-production)
51  *   BCM5709S A0, B0, B1, B2 (pre-production)
52  */
53 
54 #include "opt_bce.h"
55 
56 #include <dev/bce/if_bcereg.h>
57 #include <dev/bce/if_bcefw.h>
58 
59 /****************************************************************************/
60 /* BCE Debug Options                                                        */
61 /****************************************************************************/
62 #ifdef BCE_DEBUG
63 	u32 bce_debug = BCE_WARN;
64 
65 	/*          0 = Never              */
66 	/*          1 = 1 in 2,147,483,648 */
67 	/*        256 = 1 in     8,388,608 */
68 	/*       2048 = 1 in     1,048,576 */
69 	/*      65536 = 1 in        32,768 */
70 	/*    1048576 = 1 in         2,048 */
71 	/*  268435456 =	1 in             8 */
72 	/*  536870912 = 1 in             4 */
73 	/* 1073741824 = 1 in             2 */
74 
75 	/* Controls how often the l2_fhdr frame error check will fail. */
76 	int l2fhdr_error_sim_control = 0;
77 
78 	/* Controls how often the unexpected attention check will fail. */
79 	int unexpected_attention_sim_control = 0;
80 
81 	/* Controls how often to simulate an mbuf allocation failure. */
82 	int mbuf_alloc_failed_sim_control = 0;
83 
84 	/* Controls how often to simulate a DMA mapping failure. */
85 	int dma_map_addr_failed_sim_control = 0;
86 
87 	/* Controls how often to simulate a bootcode failure. */
88 	int bootcode_running_failure_sim_control = 0;
89 #endif
90 
91 /****************************************************************************/
92 /* BCE Build Time Options                                                   */
93 /****************************************************************************/
94 /* #define BCE_NVRAM_WRITE_SUPPORT 1 */
95 
96 
97 /****************************************************************************/
98 /* PCI Device ID Table                                                      */
99 /*                                                                          */
100 /* Used by bce_probe() to identify the devices supported by this driver.    */
101 /****************************************************************************/
102 #define BCE_DEVDESC_MAX		64
103 
104 static struct bce_type bce_devs[] = {
105 	/* BCM5706C Controllers and OEM boards. */
106 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3101,
107 		"HP NC370T Multifunction Gigabit Server Adapter" },
108 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3106,
109 		"HP NC370i Multifunction Gigabit Server Adapter" },
110 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3070,
111 		"HP NC380T PCIe DP Multifunc Gig Server Adapter" },
112 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x1709,
113 		"HP NC371i Multifunction Gigabit Server Adapter" },
114 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  PCI_ANY_ID,  PCI_ANY_ID,
115 		"Broadcom NetXtreme II BCM5706 1000Base-T" },
116 
117 	/* BCM5706S controllers and OEM boards. */
118 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, HP_VENDORID, 0x3102,
119 		"HP NC370F Multifunction Gigabit Server Adapter" },
120 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, PCI_ANY_ID,  PCI_ANY_ID,
121 		"Broadcom NetXtreme II BCM5706 1000Base-SX" },
122 
123 	/* BCM5708C controllers and OEM boards. */
124 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7037,
125 		"HP NC373T PCIe Multifunction Gig Server Adapter" },
126 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7038,
127 		"HP NC373i Multifunction Gigabit Server Adapter" },
128 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7045,
129 		"HP NC374m PCIe Multifunction Adapter" },
130 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  PCI_ANY_ID,  PCI_ANY_ID,
131 		"Broadcom NetXtreme II BCM5708 1000Base-T" },
132 
133 	/* BCM5708S controllers and OEM boards. */
134 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x1706,
135 		"HP NC373m Multifunction Gigabit Server Adapter" },
136 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703b,
137 		"HP NC373i Multifunction Gigabit Server Adapter" },
138 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703d,
139 		"HP NC373F PCIe Multifunc Giga Server Adapter" },
140 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  PCI_ANY_ID,  PCI_ANY_ID,
141 		"Broadcom NetXtreme II BCM5708 1000Base-SX" },
142 
143 	/* BCM5709C controllers and OEM boards. */
144 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7055,
145 		"HP NC382i DP Multifunction Gigabit Server Adapter" },
146 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7059,
147 		"HP NC382T PCIe DP Multifunction Gigabit Server Adapter" },
148 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  PCI_ANY_ID,  PCI_ANY_ID,
149 		"Broadcom NetXtreme II BCM5709 1000Base-T" },
150 
151 	/* BCM5709S controllers and OEM boards. */
152 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x171d,
153 		"HP NC382m DP 1GbE Multifunction BL-c Adapter" },
154 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x7056,
155 		"HP NC382i DP Multifunction Gigabit Server Adapter" },
156 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  PCI_ANY_ID,  PCI_ANY_ID,
157 		"Broadcom NetXtreme II BCM5709 1000Base-SX" },
158 
159 	/* BCM5716 controllers and OEM boards. */
160 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5716,  PCI_ANY_ID,  PCI_ANY_ID,
161 		"Broadcom NetXtreme II BCM5716 1000Base-T" },
162 
163 	{ 0, 0, 0, 0, NULL }
164 };
165 
166 
167 /****************************************************************************/
168 /* Supported Flash NVRAM device data.                                       */
169 /****************************************************************************/
170 static struct flash_spec flash_table[] =
171 {
172 #define BUFFERED_FLAGS		(BCE_NV_BUFFERED | BCE_NV_TRANSLATE)
173 #define NONBUFFERED_FLAGS	(BCE_NV_WREN)
174 
175 	/* Slow EEPROM */
176 	{0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
177 	 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
178 	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
179 	 "EEPROM - slow"},
180 	/* Expansion entry 0001 */
181 	{0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
182 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
183 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
184 	 "Entry 0001"},
185 	/* Saifun SA25F010 (non-buffered flash) */
186 	/* strap, cfg1, & write1 need updates */
187 	{0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
188 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
189 	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
190 	 "Non-buffered flash (128kB)"},
191 	/* Saifun SA25F020 (non-buffered flash) */
192 	/* strap, cfg1, & write1 need updates */
193 	{0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
194 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
195 	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
196 	 "Non-buffered flash (256kB)"},
197 	/* Expansion entry 0100 */
198 	{0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
199 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
200 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
201 	 "Entry 0100"},
202 	/* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
203 	{0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
204 	 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
205 	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
206 	 "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
207 	/* Entry 0110: ST M45PE20 (non-buffered flash)*/
208 	{0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
209 	 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
210 	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
211 	 "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
212 	/* Saifun SA25F005 (non-buffered flash) */
213 	/* strap, cfg1, & write1 need updates */
214 	{0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
215 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
216 	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
217 	 "Non-buffered flash (64kB)"},
218 	/* Fast EEPROM */
219 	{0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
220 	 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
221 	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
222 	 "EEPROM - fast"},
223 	/* Expansion entry 1001 */
224 	{0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
225 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
226 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
227 	 "Entry 1001"},
228 	/* Expansion entry 1010 */
229 	{0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
230 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
231 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
232 	 "Entry 1010"},
233 	/* ATMEL AT45DB011B (buffered flash) */
234 	{0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
235 	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
236 	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
237 	 "Buffered flash (128kB)"},
238 	/* Expansion entry 1100 */
239 	{0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
240 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
241 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
242 	 "Entry 1100"},
243 	/* Expansion entry 1101 */
244 	{0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
245 	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
246 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
247 	 "Entry 1101"},
248 	/* Ateml Expansion entry 1110 */
249 	{0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
250 	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
251 	 BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
252 	 "Entry 1110 (Atmel)"},
253 	/* ATMEL AT45DB021B (buffered flash) */
254 	{0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
255 	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
256 	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
257 	 "Buffered flash (256kB)"},
258 };
259 
260 /*
261  * The BCM5709 controllers transparently handle the
262  * differences between Atmel 264 byte pages and all
263  * flash devices which use 256 byte pages, so no
264  * logical-to-physical mapping is required in the
265  * driver.
266  */
267 static struct flash_spec flash_5709 = {
268 	.flags		= BCE_NV_BUFFERED,
269 	.page_bits	= BCM5709_FLASH_PAGE_BITS,
270 	.page_size	= BCM5709_FLASH_PAGE_SIZE,
271 	.addr_mask	= BCM5709_FLASH_BYTE_ADDR_MASK,
272 	.total_size	= BUFFERED_FLASH_TOTAL_SIZE * 2,
273 	.name		= "5709/5716 buffered flash (256kB)",
274 };
275 
276 
277 /****************************************************************************/
278 /* FreeBSD device entry points.                                             */
279 /****************************************************************************/
280 static int  bce_probe			(device_t);
281 static int  bce_attach			(device_t);
282 static int  bce_detach			(device_t);
283 static int  bce_shutdown		(device_t);
284 
285 
286 /****************************************************************************/
287 /* BCE Debug Data Structure Dump Routines                                   */
288 /****************************************************************************/
289 #ifdef BCE_DEBUG
290 static u32  bce_reg_rd			(struct bce_softc *, u32);
291 static void bce_reg_wr			(struct bce_softc *, u32, u32);
292 static void bce_reg_wr16		(struct bce_softc *, u32, u16);
293 static u32  bce_ctx_rd			(struct bce_softc *, u32, u32);
294 static void bce_dump_enet		(struct bce_softc *, struct mbuf *);
295 static void bce_dump_mbuf		(struct bce_softc *, struct mbuf *);
296 static void bce_dump_tx_mbuf_chain	(struct bce_softc *, u16, int);
297 static void bce_dump_rx_mbuf_chain	(struct bce_softc *, u16, int);
298 #ifdef BCE_JUMBO_HDRSPLIT
299 static void bce_dump_pg_mbuf_chain	(struct bce_softc *, u16, int);
300 #endif
301 static void bce_dump_txbd		(struct bce_softc *,
302     int, struct tx_bd *);
303 static void bce_dump_rxbd		(struct bce_softc *,
304     int, struct rx_bd *);
305 #ifdef BCE_JUMBO_HDRSPLIT
306 static void bce_dump_pgbd		(struct bce_softc *,
307     int, struct rx_bd *);
308 #endif
309 static void bce_dump_l2fhdr		(struct bce_softc *,
310     int, struct l2_fhdr *);
311 static void bce_dump_ctx		(struct bce_softc *, u16);
312 static void bce_dump_ftqs		(struct bce_softc *);
313 static void bce_dump_tx_chain		(struct bce_softc *, u16, int);
314 static void bce_dump_rx_bd_chain	(struct bce_softc *, u16, int);
315 #ifdef BCE_JUMBO_HDRSPLIT
316 static void bce_dump_pg_chain		(struct bce_softc *, u16, int);
317 #endif
318 static void bce_dump_status_block	(struct bce_softc *);
319 static void bce_dump_stats_block	(struct bce_softc *);
320 static void bce_dump_driver_state	(struct bce_softc *);
321 static void bce_dump_hw_state		(struct bce_softc *);
322 static void bce_dump_mq_regs		(struct bce_softc *);
323 static void bce_dump_bc_state		(struct bce_softc *);
324 static void bce_dump_txp_state		(struct bce_softc *, int);
325 static void bce_dump_rxp_state		(struct bce_softc *, int);
326 static void bce_dump_tpat_state		(struct bce_softc *, int);
327 static void bce_dump_cp_state		(struct bce_softc *, int);
328 static void bce_dump_com_state		(struct bce_softc *, int);
329 static void bce_dump_rv2p_state		(struct bce_softc *);
330 static void bce_breakpoint		(struct bce_softc *);
331 #endif
332 
333 
334 /****************************************************************************/
335 /* BCE Register/Memory Access Routines                                      */
336 /****************************************************************************/
337 static u32  bce_reg_rd_ind		(struct bce_softc *, u32);
338 static void bce_reg_wr_ind		(struct bce_softc *, u32, u32);
339 static void bce_shmem_wr		(struct bce_softc *, u32, u32);
340 static u32  bce_shmem_rd		(struct bce_softc *, u32);
341 static void bce_ctx_wr			(struct bce_softc *, u32, u32, u32);
342 static int  bce_miibus_read_reg		(device_t, int, int);
343 static int  bce_miibus_write_reg	(device_t, int, int, int);
344 static void bce_miibus_statchg		(device_t);
345 
346 #ifdef BCE_DEBUG
347 static int sysctl_nvram_dump(SYSCTL_HANDLER_ARGS);
348 #ifdef BCE_NVRAM_WRITE_SUPPORT
349 static int sysctl_nvram_write(SYSCTL_HANDLER_ARGS);
350 #endif
351 #endif
352 
353 /****************************************************************************/
354 /* BCE NVRAM Access Routines                                                */
355 /****************************************************************************/
356 static int  bce_acquire_nvram_lock	(struct bce_softc *);
357 static int  bce_release_nvram_lock	(struct bce_softc *);
358 static void bce_enable_nvram_access	(struct bce_softc *);
359 static void bce_disable_nvram_access	(struct bce_softc *);
360 static int  bce_nvram_read_dword	(struct bce_softc *, u32, u8 *, u32);
361 static int  bce_init_nvram		(struct bce_softc *);
362 static int  bce_nvram_read		(struct bce_softc *, u32, u8 *, int);
363 static int  bce_nvram_test		(struct bce_softc *);
364 #ifdef BCE_NVRAM_WRITE_SUPPORT
365 static int  bce_enable_nvram_write	(struct bce_softc *);
366 static void bce_disable_nvram_write	(struct bce_softc *);
367 static int  bce_nvram_erase_page	(struct bce_softc *, u32);
368 static int  bce_nvram_write_dword	(struct bce_softc *, u32, u8 *, u32);
369 static int  bce_nvram_write		(struct bce_softc *, u32, u8 *, int);
370 #endif
371 
372 /****************************************************************************/
373 /*                                                                          */
374 /****************************************************************************/
375 static void bce_get_media		(struct bce_softc *);
376 static void bce_init_media		(struct bce_softc *);
377 static void bce_dma_map_addr		(void *,
378     bus_dma_segment_t *, int, int);
379 static int  bce_dma_alloc		(device_t);
380 static void bce_dma_free		(struct bce_softc *);
381 static void bce_release_resources	(struct bce_softc *);
382 
383 /****************************************************************************/
384 /* BCE Firmware Synchronization and Load                                    */
385 /****************************************************************************/
386 static int  bce_fw_sync			(struct bce_softc *, u32);
387 static void bce_load_rv2p_fw		(struct bce_softc *, u32 *, u32, u32);
388 static void bce_load_cpu_fw		(struct bce_softc *,
389     struct cpu_reg *, struct fw_info *);
390 static void bce_start_cpu		(struct bce_softc *, struct cpu_reg *);
391 static void bce_halt_cpu		(struct bce_softc *, struct cpu_reg *);
392 static void bce_start_rxp_cpu		(struct bce_softc *);
393 static void bce_init_rxp_cpu		(struct bce_softc *);
394 static void bce_init_txp_cpu 		(struct bce_softc *);
395 static void bce_init_tpat_cpu		(struct bce_softc *);
396 static void bce_init_cp_cpu	  	(struct bce_softc *);
397 static void bce_init_com_cpu	  	(struct bce_softc *);
398 static void bce_init_cpus		(struct bce_softc *);
399 
400 static void	bce_print_adapter_info	(struct bce_softc *);
401 static void bce_probe_pci_caps		(device_t, struct bce_softc *);
402 static void bce_stop			(struct bce_softc *);
403 static int  bce_reset			(struct bce_softc *, u32);
404 static int  bce_chipinit 		(struct bce_softc *);
405 static int  bce_blockinit 		(struct bce_softc *);
406 
407 static int  bce_init_tx_chain		(struct bce_softc *);
408 static void bce_free_tx_chain		(struct bce_softc *);
409 
410 static int  bce_get_rx_buf		(struct bce_softc *,
411     struct mbuf *, u16 *, u16 *, u32 *);
412 static int  bce_init_rx_chain		(struct bce_softc *);
413 static void bce_fill_rx_chain		(struct bce_softc *);
414 static void bce_free_rx_chain		(struct bce_softc *);
415 
416 #ifdef BCE_JUMBO_HDRSPLIT
417 static int  bce_get_pg_buf		(struct bce_softc *,
418     struct mbuf *, u16 *, u16 *);
419 static int  bce_init_pg_chain		(struct bce_softc *);
420 static void bce_fill_pg_chain		(struct bce_softc *);
421 static void bce_free_pg_chain		(struct bce_softc *);
422 #endif
423 
424 static struct mbuf *bce_tso_setup	(struct bce_softc *,
425     struct mbuf **, u16 *);
426 static int  bce_tx_encap		(struct bce_softc *, struct mbuf **);
427 static void bce_start_locked		(struct ifnet *);
428 static void bce_start			(struct ifnet *);
429 static int  bce_ioctl			(struct ifnet *, u_long, caddr_t);
430 static void bce_watchdog		(struct bce_softc *);
431 static int  bce_ifmedia_upd		(struct ifnet *);
432 static int  bce_ifmedia_upd_locked	(struct ifnet *);
433 static void bce_ifmedia_sts		(struct ifnet *, struct ifmediareq *);
434 static void bce_init_locked		(struct bce_softc *);
435 static void bce_init			(void *);
436 static void bce_mgmt_init_locked	(struct bce_softc *sc);
437 
438 static int  bce_init_ctx		(struct bce_softc *);
439 static void bce_get_mac_addr		(struct bce_softc *);
440 static void bce_set_mac_addr		(struct bce_softc *);
441 static void bce_phy_intr		(struct bce_softc *);
442 static inline u16 bce_get_hw_rx_cons	(struct bce_softc *);
443 static void bce_rx_intr			(struct bce_softc *);
444 static void bce_tx_intr			(struct bce_softc *);
445 static void bce_disable_intr		(struct bce_softc *);
446 static void bce_enable_intr		(struct bce_softc *, int);
447 
448 static void bce_intr			(void *);
449 static void bce_set_rx_mode		(struct bce_softc *);
450 static void bce_stats_update		(struct bce_softc *);
451 static void bce_tick			(void *);
452 static void bce_pulse			(void *);
453 static void bce_add_sysctls		(struct bce_softc *);
454 
455 
456 /****************************************************************************/
457 /* FreeBSD device dispatch table.                                           */
458 /****************************************************************************/
459 static device_method_t bce_methods[] = {
460 	/* Device interface (device_if.h) */
461 	DEVMETHOD(device_probe,		bce_probe),
462 	DEVMETHOD(device_attach,	bce_attach),
463 	DEVMETHOD(device_detach,	bce_detach),
464 	DEVMETHOD(device_shutdown,	bce_shutdown),
465 /* Supported by device interface but not used here. */
466 /*	DEVMETHOD(device_identify,	bce_identify),      */
467 /*	DEVMETHOD(device_suspend,	bce_suspend),       */
468 /*	DEVMETHOD(device_resume,	bce_resume),        */
469 /*	DEVMETHOD(device_quiesce,	bce_quiesce),       */
470 
471 	/* Bus interface (bus_if.h) */
472 	DEVMETHOD(bus_print_child,	bus_generic_print_child),
473 	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
474 
475 	/* MII interface (miibus_if.h) */
476 	DEVMETHOD(miibus_readreg,	bce_miibus_read_reg),
477 	DEVMETHOD(miibus_writereg,	bce_miibus_write_reg),
478 	DEVMETHOD(miibus_statchg,	bce_miibus_statchg),
479 /* Supported by MII interface but not used here.       */
480 /*	DEVMETHOD(miibus_linkchg,	bce_miibus_linkchg),   */
481 /*	DEVMETHOD(miibus_mediainit,	bce_miibus_mediainit), */
482 
483 	{ 0, 0 }
484 };
485 
486 static driver_t bce_driver = {
487 	"bce",
488 	bce_methods,
489 	sizeof(struct bce_softc)
490 };
491 
492 static devclass_t bce_devclass;
493 
494 MODULE_DEPEND(bce, pci, 1, 1, 1);
495 MODULE_DEPEND(bce, ether, 1, 1, 1);
496 MODULE_DEPEND(bce, miibus, 1, 1, 1);
497 
498 DRIVER_MODULE(bce, pci, bce_driver, bce_devclass, 0, 0);
499 DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, 0, 0);
500 
501 
502 /****************************************************************************/
503 /* Tunable device values                                                    */
504 /****************************************************************************/
505 SYSCTL_NODE(_hw, OID_AUTO, bce, CTLFLAG_RD, 0, "bce driver parameters");
506 
507 /* Allowable values are TRUE or FALSE */
508 static int bce_tso_enable = TRUE;
509 TUNABLE_INT("hw.bce.tso_enable", &bce_tso_enable);
510 SYSCTL_UINT(_hw_bce, OID_AUTO, tso_enable, CTLFLAG_RDTUN, &bce_tso_enable, 0,
511 "TSO Enable/Disable");
512 
513 /* Allowable values are 0 (IRQ), 1 (MSI/IRQ), and 2 (MSI-X/MSI/IRQ) */
514 /* ToDo: Add MSI-X support. */
515 static int bce_msi_enable = 1;
516 TUNABLE_INT("hw.bce.msi_enable", &bce_msi_enable);
517 SYSCTL_UINT(_hw_bce, OID_AUTO, msi_enable, CTLFLAG_RDTUN, &bce_msi_enable, 0,
518 "MSI-X|MSI|INTx selector");
519 
520 /* ToDo: Add tunable to enable/disable strict MTU handling. */
521 /* Currently allows "loose" RX MTU checking (i.e. sets the  */
522 /* H/W RX MTU to the size of the largest receive buffer, or */
523 /* 2048 bytes). This will cause a UNH failure but is more   */
524 /* desireable from a functional perspective.                */
525 
526 
527 /****************************************************************************/
528 /* Device probe function.                                                   */
529 /*                                                                          */
530 /* Compares the device to the driver's list of supported devices and        */
531 /* reports back to the OS whether this is the right driver for the device.  */
532 /*                                                                          */
533 /* Returns:                                                                 */
534 /*   BUS_PROBE_DEFAULT on success, positive value on failure.               */
535 /****************************************************************************/
536 static int
537 bce_probe(device_t dev)
538 {
539 	struct bce_type *t;
540 	struct bce_softc *sc;
541 	char *descbuf;
542 	u16 vid = 0, did = 0, svid = 0, sdid = 0;
543 
544 	t = bce_devs;
545 
546 	sc = device_get_softc(dev);
547 	bzero(sc, sizeof(struct bce_softc));
548 	sc->bce_unit = device_get_unit(dev);
549 	sc->bce_dev = dev;
550 
551 	/* Get the data for the device to be probed. */
552 	vid  = pci_get_vendor(dev);
553 	did  = pci_get_device(dev);
554 	svid = pci_get_subvendor(dev);
555 	sdid = pci_get_subdevice(dev);
556 
557 	DBPRINT(sc, BCE_EXTREME_LOAD,
558 	    "%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
559 	    "SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
560 
561 	/* Look through the list of known devices for a match. */
562 	while(t->bce_name != NULL) {
563 
564 		if ((vid == t->bce_vid) && (did == t->bce_did) &&
565 		    ((svid == t->bce_svid) || (t->bce_svid == PCI_ANY_ID)) &&
566 		    ((sdid == t->bce_sdid) || (t->bce_sdid == PCI_ANY_ID))) {
567 
568 			descbuf = malloc(BCE_DEVDESC_MAX, M_TEMP, M_NOWAIT);
569 
570 			if (descbuf == NULL)
571 				return(ENOMEM);
572 
573 			/* Print out the device identity. */
574 			snprintf(descbuf, BCE_DEVDESC_MAX, "%s (%c%d)",
575 			    t->bce_name, (((pci_read_config(dev,
576 			    PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
577 			    (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
578 
579 			device_set_desc_copy(dev, descbuf);
580 			free(descbuf, M_TEMP);
581 			return(BUS_PROBE_DEFAULT);
582 		}
583 		t++;
584 	}
585 
586 	return(ENXIO);
587 }
588 
589 
590 /****************************************************************************/
591 /* PCI Capabilities Probe Function.                                         */
592 /*                                                                          */
593 /* Walks the PCI capabiites list for the device to find what features are   */
594 /* supported.                                                               */
595 /*                                                                          */
596 /* Returns:                                                                 */
597 /*   None.                                                                  */
598 /****************************************************************************/
599 static void
600 bce_print_adapter_info(struct bce_softc *sc)
601 {
602 	int i = 0;
603 
604 	DBENTER(BCE_VERBOSE_LOAD);
605 
606 	if (bootverbose) {
607 		BCE_PRINTF("ASIC (0x%08X); ", sc->bce_chipid);
608 		printf("Rev (%c%d); ", ((BCE_CHIP_ID(sc) & 0xf000) >>
609 		    12) + 'A', ((BCE_CHIP_ID(sc) & 0x0ff0) >> 4));
610 
611 
612 		/* Bus info. */
613 		if (sc->bce_flags & BCE_PCIE_FLAG) {
614 			printf("Bus (PCIe x%d, ", sc->link_width);
615 			switch (sc->link_speed) {
616 			case 1: printf("2.5Gbps); "); break;
617 			case 2:	printf("5Gbps); "); break;
618 			default: printf("Unknown link speed); ");
619 			}
620 		} else {
621 			printf("Bus (PCI%s, %s, %dMHz); ",
622 			    ((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""),
623 			    ((sc->bce_flags & BCE_PCI_32BIT_FLAG) ?
624 			    "32-bit" : "64-bit"), sc->bus_speed_mhz);
625 		}
626 
627 		/* Firmware version and device features. */
628 		printf("B/C (%s); Flags (", sc->bce_bc_ver);
629 
630 	#ifdef BCE_JUMBO_HDRSPLIT
631 		printf("SPLT");
632 		i++;
633 	#endif
634 
635 		if (sc->bce_flags & BCE_USING_MSI_FLAG) {
636 			if (i > 0) printf("|");
637 			printf("MSI"); i++;
638 		}
639 
640 		if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
641 			if (i > 0) printf("|");
642 			printf("MSI-X"); i++;
643 		}
644 
645 		if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
646 			if (i > 0) printf("|");
647 			printf("2.5G"); i++;
648 		}
649 
650 		if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
651 			if (i > 0) printf("|");
652 			printf("MFW); MFW (%s)\n", sc->bce_mfw_ver);
653 		} else {
654 			printf(")\n");
655 		}
656 	}
657 
658 	DBEXIT(BCE_VERBOSE_LOAD);
659 }
660 
661 
662 /****************************************************************************/
663 /* PCI Capabilities Probe Function.                                         */
664 /*                                                                          */
665 /* Walks the PCI capabiites list for the device to find what features are   */
666 /* supported.                                                               */
667 /*                                                                          */
668 /* Returns:                                                                 */
669 /*   None.                                                                  */
670 /****************************************************************************/
671 static void
672 bce_probe_pci_caps(device_t dev, struct bce_softc *sc)
673 {
674 	u32 reg;
675 
676 	DBENTER(BCE_VERBOSE_LOAD);
677 
678 	/* Check if PCI-X capability is enabled. */
679 	if (pci_find_extcap(dev, PCIY_PCIX, &reg) == 0) {
680 		if (reg != 0)
681 			sc->bce_cap_flags |= BCE_PCIX_CAPABLE_FLAG;
682 	}
683 
684 	/* Check if PCIe capability is enabled. */
685 	if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
686 		if (reg != 0) {
687 			u16 link_status = pci_read_config(dev, reg + 0x12, 2);
688 			DBPRINT(sc, BCE_INFO_LOAD, "PCIe link_status = "
689 			    "0x%08X\n",	link_status);
690 			sc->link_speed = link_status & 0xf;
691 			sc->link_width = (link_status >> 4) & 0x3f;
692 			sc->bce_cap_flags |= BCE_PCIE_CAPABLE_FLAG;
693 			sc->bce_flags |= BCE_PCIE_FLAG;
694 		}
695 	}
696 
697 	/* Check if MSI capability is enabled. */
698 	if (pci_find_extcap(dev, PCIY_MSI, &reg) == 0) {
699 		if (reg != 0)
700 			sc->bce_cap_flags |= BCE_MSI_CAPABLE_FLAG;
701 	}
702 
703 	/* Check if MSI-X capability is enabled. */
704 	if (pci_find_extcap(dev, PCIY_MSIX, &reg) == 0) {
705 		if (reg != 0)
706 			sc->bce_cap_flags |= BCE_MSIX_CAPABLE_FLAG;
707 	}
708 
709 	DBEXIT(BCE_VERBOSE_LOAD);
710 }
711 
712 
713 /****************************************************************************/
714 /* Device attach function.                                                  */
715 /*                                                                          */
716 /* Allocates device resources, performs secondary chip identification,      */
717 /* resets and initializes the hardware, and initializes driver instance     */
718 /* variables.                                                               */
719 /*                                                                          */
720 /* Returns:                                                                 */
721 /*   0 on success, positive value on failure.                               */
722 /****************************************************************************/
723 static int
724 bce_attach(device_t dev)
725 {
726 	struct bce_softc *sc;
727 	struct ifnet *ifp;
728 	u32 val;
729 	int error, rid, rc = 0;
730 
731 	sc = device_get_softc(dev);
732 	sc->bce_dev = dev;
733 
734 	DBENTER(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
735 
736 	sc->bce_unit = device_get_unit(dev);
737 
738 	/* Set initial device and PHY flags */
739 	sc->bce_flags = 0;
740 	sc->bce_phy_flags = 0;
741 
742 	pci_enable_busmaster(dev);
743 
744 	/* Allocate PCI memory resources. */
745 	rid = PCIR_BAR(0);
746 	sc->bce_res_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
747 		&rid, RF_ACTIVE);
748 
749 	if (sc->bce_res_mem == NULL) {
750 		BCE_PRINTF("%s(%d): PCI memory allocation failed\n",
751 		    __FILE__, __LINE__);
752 		rc = ENXIO;
753 		goto bce_attach_fail;
754 	}
755 
756 	/* Get various resource handles. */
757 	sc->bce_btag    = rman_get_bustag(sc->bce_res_mem);
758 	sc->bce_bhandle = rman_get_bushandle(sc->bce_res_mem);
759 	sc->bce_vhandle = (vm_offset_t) rman_get_virtual(sc->bce_res_mem);
760 
761 	bce_probe_pci_caps(dev, sc);
762 
763 	rid = 1;
764 #if 0
765 	/* Try allocating MSI-X interrupts. */
766 	if ((sc->bce_cap_flags & BCE_MSIX_CAPABLE_FLAG) &&
767 		(bce_msi_enable >= 2) &&
768 		((sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
769 		&rid, RF_ACTIVE)) != NULL)) {
770 
771 		msi_needed = sc->bce_msi_count = 1;
772 
773 		if (((error = pci_alloc_msix(dev, &sc->bce_msi_count)) != 0) ||
774 			(sc->bce_msi_count != msi_needed)) {
775 			BCE_PRINTF("%s(%d): MSI-X allocation failed! Requested = %d,"
776 				"Received = %d, error = %d\n", __FILE__, __LINE__,
777 				msi_needed, sc->bce_msi_count, error);
778 			sc->bce_msi_count = 0;
779 			pci_release_msi(dev);
780 			bus_release_resource(dev, SYS_RES_MEMORY, rid,
781 				sc->bce_res_irq);
782 			sc->bce_res_irq = NULL;
783 		} else {
784 			DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI-X interrupt.\n",
785 				__FUNCTION__);
786 			sc->bce_flags |= BCE_USING_MSIX_FLAG;
787 			sc->bce_intr = bce_intr;
788 		}
789 	}
790 #endif
791 
792 	/* Try allocating a MSI interrupt. */
793 	if ((sc->bce_cap_flags & BCE_MSI_CAPABLE_FLAG) &&
794 		(bce_msi_enable >= 1) && (sc->bce_msi_count == 0)) {
795 		sc->bce_msi_count = 1;
796 		if ((error = pci_alloc_msi(dev, &sc->bce_msi_count)) != 0) {
797 			BCE_PRINTF("%s(%d): MSI allocation failed! "
798 			    "error = %d\n", __FILE__, __LINE__, error);
799 			sc->bce_msi_count = 0;
800 			pci_release_msi(dev);
801 		} else {
802 			DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI "
803 			    "interrupt.\n", __FUNCTION__);
804 			sc->bce_flags |= BCE_USING_MSI_FLAG;
805 			if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
806 				(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
807 				sc->bce_flags |= BCE_ONE_SHOT_MSI_FLAG;
808 			sc->bce_irq_rid = 1;
809 			sc->bce_intr = bce_intr;
810 		}
811 	}
812 
813 	/* Try allocating a legacy interrupt. */
814 	if (sc->bce_msi_count == 0) {
815 		DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using INTx interrupt.\n",
816 			__FUNCTION__);
817 		rid = 0;
818 		sc->bce_intr = bce_intr;
819 	}
820 
821 	sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
822 	    &rid, RF_SHAREABLE | RF_ACTIVE);
823 
824 	sc->bce_irq_rid = rid;
825 
826 	/* Report any IRQ allocation errors. */
827 	if (sc->bce_res_irq == NULL) {
828 		BCE_PRINTF("%s(%d): PCI map interrupt failed!\n",
829 		    __FILE__, __LINE__);
830 		rc = ENXIO;
831 		goto bce_attach_fail;
832 	}
833 
834 	/* Initialize mutex for the current device instance. */
835 	BCE_LOCK_INIT(sc, device_get_nameunit(dev));
836 
837 	/*
838 	 * Configure byte swap and enable indirect register access.
839 	 * Rely on CPU to do target byte swapping on big endian systems.
840 	 * Access to registers outside of PCI configurtion space are not
841 	 * valid until this is done.
842 	 */
843 	pci_write_config(dev, BCE_PCICFG_MISC_CONFIG,
844 	    BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
845 	    BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4);
846 
847 	/* Save ASIC revsion info. */
848 	sc->bce_chipid =  REG_RD(sc, BCE_MISC_ID);
849 
850 	/* Weed out any non-production controller revisions. */
851 	switch(BCE_CHIP_ID(sc)) {
852 	case BCE_CHIP_ID_5706_A0:
853 	case BCE_CHIP_ID_5706_A1:
854 	case BCE_CHIP_ID_5708_A0:
855 	case BCE_CHIP_ID_5708_B0:
856 	case BCE_CHIP_ID_5709_A0:
857 	case BCE_CHIP_ID_5709_B0:
858 	case BCE_CHIP_ID_5709_B1:
859 	case BCE_CHIP_ID_5709_B2:
860 		BCE_PRINTF("%s(%d): Unsupported controller "
861 		    "revision (%c%d)!\n", __FILE__, __LINE__,
862 		    (((pci_read_config(dev, PCIR_REVID, 4) &
863 		    0xf0) >> 4) + 'A'), (pci_read_config(dev,
864 		    PCIR_REVID, 4) & 0xf));
865 		rc = ENODEV;
866 		goto bce_attach_fail;
867 	}
868 
869 	/*
870 	 * The embedded PCIe to PCI-X bridge (EPB)
871 	 * in the 5708 cannot address memory above
872 	 * 40 bits (E7_5708CB1_23043 & E6_5708SB1_23043).
873 	 */
874 	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708)
875 		sc->max_bus_addr = BCE_BUS_SPACE_MAXADDR;
876 	else
877 		sc->max_bus_addr = BUS_SPACE_MAXADDR;
878 
879 	/*
880 	 * Find the base address for shared memory access.
881 	 * Newer versions of bootcode use a signature and offset
882 	 * while older versions use a fixed address.
883 	 */
884 	val = REG_RD_IND(sc, BCE_SHM_HDR_SIGNATURE);
885 	if ((val & BCE_SHM_HDR_SIGNATURE_SIG_MASK) == BCE_SHM_HDR_SIGNATURE_SIG)
886 		/* Multi-port devices use different offsets in shared memory. */
887 		sc->bce_shmem_base = REG_RD_IND(sc, BCE_SHM_HDR_ADDR_0 +
888 		    (pci_get_function(sc->bce_dev) << 2));
889 	else
890 		sc->bce_shmem_base = HOST_VIEW_SHMEM_BASE;
891 
892 	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): bce_shmem_base = 0x%08X\n",
893 	    __FUNCTION__, sc->bce_shmem_base);
894 
895 	/* Fetch the bootcode revision. */
896 	val = bce_shmem_rd(sc, BCE_DEV_INFO_BC_REV);
897 	for (int i = 0, j = 0; i < 3; i++) {
898 		u8 num;
899 
900 		num = (u8) (val >> (24 - (i * 8)));
901 		for (int k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
902 			if (num >= k || !skip0 || k == 1) {
903 				sc->bce_bc_ver[j++] = (num / k) + '0';
904 				skip0 = 0;
905 			}
906 		}
907 
908 		if (i != 2)
909 			sc->bce_bc_ver[j++] = '.';
910 	}
911 
912 	/* Check if any management firwmare is enabled. */
913 	val = bce_shmem_rd(sc, BCE_PORT_FEATURE);
914 	if (val & BCE_PORT_FEATURE_ASF_ENABLED) {
915 		sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
916 
917 		/* Allow time for firmware to enter the running state. */
918 		for (int i = 0; i < 30; i++) {
919 			val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
920 			if (val & BCE_CONDITION_MFW_RUN_MASK)
921 				break;
922 			DELAY(10000);
923 		}
924 
925 		/* Check if management firmware is running. */
926 		val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
927 		val &= BCE_CONDITION_MFW_RUN_MASK;
928 		if ((val != BCE_CONDITION_MFW_RUN_UNKNOWN) &&
929 		    (val != BCE_CONDITION_MFW_RUN_NONE)) {
930 			u32 addr = bce_shmem_rd(sc, BCE_MFW_VER_PTR);
931 			int i = 0;
932 
933 			/* Read the management firmware version string. */
934 			for (int j = 0; j < 3; j++) {
935 				val = bce_reg_rd_ind(sc, addr + j * 4);
936 				val = bswap32(val);
937 				memcpy(&sc->bce_mfw_ver[i], &val, 4);
938 				i += 4;
939 			}
940 		} else {
941 			/* May cause firmware synchronization timeouts. */
942 			BCE_PRINTF("%s(%d): Management firmware enabled "
943 			    "but not running!\n", __FILE__, __LINE__);
944 			strcpy(sc->bce_mfw_ver, "NOT RUNNING!");
945 
946 			/* ToDo: Any action the driver should take? */
947 		}
948 	}
949 
950 	/* Get PCI bus information (speed and type). */
951 	val = REG_RD(sc, BCE_PCICFG_MISC_STATUS);
952 	if (val & BCE_PCICFG_MISC_STATUS_PCIX_DET) {
953 		u32 clkreg;
954 
955 		sc->bce_flags |= BCE_PCIX_FLAG;
956 
957 		clkreg = REG_RD(sc, BCE_PCICFG_PCI_CLOCK_CONTROL_BITS);
958 
959 		clkreg &= BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
960 		switch (clkreg) {
961 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
962 			sc->bus_speed_mhz = 133;
963 			break;
964 
965 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
966 			sc->bus_speed_mhz = 100;
967 			break;
968 
969 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
970 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
971 			sc->bus_speed_mhz = 66;
972 			break;
973 
974 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
975 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
976 			sc->bus_speed_mhz = 50;
977 			break;
978 
979 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
980 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
981 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
982 			sc->bus_speed_mhz = 33;
983 			break;
984 		}
985 	} else {
986 		if (val & BCE_PCICFG_MISC_STATUS_M66EN)
987 			sc->bus_speed_mhz = 66;
988 		else
989 			sc->bus_speed_mhz = 33;
990 	}
991 
992 	if (val & BCE_PCICFG_MISC_STATUS_32BIT_DET)
993 		sc->bce_flags |= BCE_PCI_32BIT_FLAG;
994 
995 	/* Reset controller and announce to bootcode that driver is present. */
996 	if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
997 		BCE_PRINTF("%s(%d): Controller reset failed!\n",
998 		    __FILE__, __LINE__);
999 		rc = ENXIO;
1000 		goto bce_attach_fail;
1001 	}
1002 
1003 	/* Initialize the controller. */
1004 	if (bce_chipinit(sc)) {
1005 		BCE_PRINTF("%s(%d): Controller initialization failed!\n",
1006 		    __FILE__, __LINE__);
1007 		rc = ENXIO;
1008 		goto bce_attach_fail;
1009 	}
1010 
1011 	/* Perform NVRAM test. */
1012 	if (bce_nvram_test(sc)) {
1013 		BCE_PRINTF("%s(%d): NVRAM test failed!\n",
1014 		    __FILE__, __LINE__);
1015 		rc = ENXIO;
1016 		goto bce_attach_fail;
1017 	}
1018 
1019 	/* Fetch the permanent Ethernet MAC address. */
1020 	bce_get_mac_addr(sc);
1021 
1022 	/*
1023 	 * Trip points control how many BDs
1024 	 * should be ready before generating an
1025 	 * interrupt while ticks control how long
1026 	 * a BD can sit in the chain before
1027 	 * generating an interrupt.  Set the default
1028 	 * values for the RX and TX chains.
1029 	 */
1030 
1031 #ifdef BCE_DEBUG
1032 	/* Force more frequent interrupts. */
1033 	sc->bce_tx_quick_cons_trip_int = 1;
1034 	sc->bce_tx_quick_cons_trip     = 1;
1035 	sc->bce_tx_ticks_int           = 0;
1036 	sc->bce_tx_ticks               = 0;
1037 
1038 	sc->bce_rx_quick_cons_trip_int = 1;
1039 	sc->bce_rx_quick_cons_trip     = 1;
1040 	sc->bce_rx_ticks_int           = 0;
1041 	sc->bce_rx_ticks               = 0;
1042 #else
1043 	/* Improve throughput at the expense of increased latency. */
1044 	sc->bce_tx_quick_cons_trip_int = 20;
1045 	sc->bce_tx_quick_cons_trip     = 20;
1046 	sc->bce_tx_ticks_int           = 80;
1047 	sc->bce_tx_ticks               = 80;
1048 
1049 	sc->bce_rx_quick_cons_trip_int = 6;
1050 	sc->bce_rx_quick_cons_trip     = 6;
1051 	sc->bce_rx_ticks_int           = 18;
1052 	sc->bce_rx_ticks               = 18;
1053 #endif
1054 
1055 	/* Not used for L2. */
1056 	sc->bce_comp_prod_trip_int = 0;
1057 	sc->bce_comp_prod_trip = 0;
1058 	sc->bce_com_ticks_int = 0;
1059 	sc->bce_com_ticks = 0;
1060 	sc->bce_cmd_ticks_int = 0;
1061 	sc->bce_cmd_ticks = 0;
1062 
1063 	/* Update statistics once every second. */
1064 	sc->bce_stats_ticks = 1000000 & 0xffff00;
1065 
1066 	/* Find the media type for the adapter. */
1067 	bce_get_media(sc);
1068 
1069 	/* Store data needed by PHY driver for backplane applications */
1070 	sc->bce_shared_hw_cfg = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
1071 	sc->bce_port_hw_cfg   = bce_shmem_rd(sc, BCE_PORT_HW_CFG_CONFIG);
1072 
1073 	/* Allocate DMA memory resources. */
1074 	if (bce_dma_alloc(dev)) {
1075 		BCE_PRINTF("%s(%d): DMA resource allocation failed!\n",
1076 		    __FILE__, __LINE__);
1077 		rc = ENXIO;
1078 		goto bce_attach_fail;
1079 	}
1080 
1081 	/* Allocate an ifnet structure. */
1082 	ifp = sc->bce_ifp = if_alloc(IFT_ETHER);
1083 	if (ifp == NULL) {
1084 		BCE_PRINTF("%s(%d): Interface allocation failed!\n",
1085 		    __FILE__, __LINE__);
1086 		rc = ENXIO;
1087 		goto bce_attach_fail;
1088 	}
1089 
1090 	/* Initialize the ifnet interface. */
1091 	ifp->if_softc	= sc;
1092 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
1093 	ifp->if_flags	= IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1094 	ifp->if_ioctl	= bce_ioctl;
1095 	ifp->if_start	= bce_start;
1096 	ifp->if_init	= bce_init;
1097 	ifp->if_mtu	= ETHERMTU;
1098 
1099 	if (bce_tso_enable) {
1100 		ifp->if_hwassist = BCE_IF_HWASSIST | CSUM_TSO;
1101 		ifp->if_capabilities = BCE_IF_CAPABILITIES | IFCAP_TSO4 |
1102 		    IFCAP_VLAN_HWTSO;
1103 	} else {
1104 		ifp->if_hwassist = BCE_IF_HWASSIST;
1105 		ifp->if_capabilities = BCE_IF_CAPABILITIES;
1106 	}
1107 
1108 	ifp->if_capenable = ifp->if_capabilities;
1109 
1110 	/*
1111 	 * Assume standard mbuf sizes for buffer allocation.
1112 	 * This may change later if the MTU size is set to
1113 	 * something other than 1500.
1114 	 */
1115 #ifdef BCE_JUMBO_HDRSPLIT
1116 	sc->rx_bd_mbuf_alloc_size = MHLEN;
1117 	/* Make sure offset is 16 byte aligned for hardware. */
1118 	sc->rx_bd_mbuf_align_pad =
1119 	    roundup2((MSIZE - MHLEN), 16) - (MSIZE - MHLEN);
1120 	sc->rx_bd_mbuf_data_len = sc->rx_bd_mbuf_alloc_size -
1121 	    sc->rx_bd_mbuf_align_pad;
1122 	sc->pg_bd_mbuf_alloc_size = MCLBYTES;
1123 #else
1124 	sc->rx_bd_mbuf_alloc_size = MCLBYTES;
1125 	sc->rx_bd_mbuf_align_pad =
1126 	    roundup2(MCLBYTES, 16) - MCLBYTES;
1127 	sc->rx_bd_mbuf_data_len = sc->rx_bd_mbuf_alloc_size -
1128 	    sc->rx_bd_mbuf_align_pad;
1129 #endif
1130 
1131 	ifp->if_snd.ifq_drv_maxlen = USABLE_TX_BD;
1132 	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
1133 	IFQ_SET_READY(&ifp->if_snd);
1134 
1135 	if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
1136 		ifp->if_baudrate = IF_Mbps(2500ULL);
1137 	else
1138 		ifp->if_baudrate = IF_Mbps(1000);
1139 
1140 	/* Handle any special PHY initialization for SerDes PHYs. */
1141 	bce_init_media(sc);
1142 
1143 	/* MII child bus by attaching the PHY. */
1144 	rc = mii_attach(dev, &sc->bce_miibus, ifp, bce_ifmedia_upd,
1145 	    bce_ifmedia_sts, BMSR_DEFCAPMASK, sc->bce_phy_addr,
1146 	    MII_OFFSET_ANY, MIIF_DOPAUSE);
1147 	if (rc != 0) {
1148 		BCE_PRINTF("%s(%d): attaching PHYs failed\n", __FILE__,
1149 		    __LINE__);
1150 		goto bce_attach_fail;
1151 	}
1152 
1153 	/* Attach to the Ethernet interface list. */
1154 	ether_ifattach(ifp, sc->eaddr);
1155 
1156 #if __FreeBSD_version < 500000
1157 	callout_init(&sc->bce_tick_callout);
1158 	callout_init(&sc->bce_pulse_callout);
1159 #else
1160 	callout_init_mtx(&sc->bce_tick_callout, &sc->bce_mtx, 0);
1161 	callout_init_mtx(&sc->bce_pulse_callout, &sc->bce_mtx, 0);
1162 #endif
1163 
1164 	/* Hookup IRQ last. */
1165 	rc = bus_setup_intr(dev, sc->bce_res_irq, INTR_TYPE_NET | INTR_MPSAFE,
1166 		NULL, bce_intr, sc, &sc->bce_intrhand);
1167 
1168 	if (rc) {
1169 		BCE_PRINTF("%s(%d): Failed to setup IRQ!\n",
1170 		    __FILE__, __LINE__);
1171 		bce_detach(dev);
1172 		goto bce_attach_exit;
1173 	}
1174 
1175 	/*
1176 	 * At this point we've acquired all the resources
1177 	 * we need to run so there's no turning back, we're
1178 	 * cleared for launch.
1179 	 */
1180 
1181 	/* Print some important debugging info. */
1182 	DBRUNMSG(BCE_INFO, bce_dump_driver_state(sc));
1183 
1184 	/* Add the supported sysctls to the kernel. */
1185 	bce_add_sysctls(sc);
1186 
1187 	BCE_LOCK(sc);
1188 
1189 	/*
1190 	 * The chip reset earlier notified the bootcode that
1191 	 * a driver is present.  We now need to start our pulse
1192 	 * routine so that the bootcode is reminded that we're
1193 	 * still running.
1194 	 */
1195 	bce_pulse(sc);
1196 
1197 	bce_mgmt_init_locked(sc);
1198 	BCE_UNLOCK(sc);
1199 
1200 	/* Finally, print some useful adapter info */
1201 	bce_print_adapter_info(sc);
1202 	DBPRINT(sc, BCE_FATAL, "%s(): sc = %p\n",
1203 		__FUNCTION__, sc);
1204 
1205 	goto bce_attach_exit;
1206 
1207 bce_attach_fail:
1208 	bce_release_resources(sc);
1209 
1210 bce_attach_exit:
1211 
1212 	DBEXIT(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
1213 
1214 	return(rc);
1215 }
1216 
1217 
1218 /****************************************************************************/
1219 /* Device detach function.                                                  */
1220 /*                                                                          */
1221 /* Stops the controller, resets the controller, and releases resources.     */
1222 /*                                                                          */
1223 /* Returns:                                                                 */
1224 /*   0 on success, positive value on failure.                               */
1225 /****************************************************************************/
1226 static int
1227 bce_detach(device_t dev)
1228 {
1229 	struct bce_softc *sc = device_get_softc(dev);
1230 	struct ifnet *ifp;
1231 	u32 msg;
1232 
1233 	DBENTER(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
1234 
1235 	ifp = sc->bce_ifp;
1236 
1237 	/* Stop and reset the controller. */
1238 	BCE_LOCK(sc);
1239 
1240 	/* Stop the pulse so the bootcode can go to driver absent state. */
1241 	callout_stop(&sc->bce_pulse_callout);
1242 
1243 	bce_stop(sc);
1244 	if (sc->bce_flags & BCE_NO_WOL_FLAG)
1245 		msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
1246 	else
1247 		msg = BCE_DRV_MSG_CODE_UNLOAD;
1248 	bce_reset(sc, msg);
1249 
1250 	BCE_UNLOCK(sc);
1251 
1252 	ether_ifdetach(ifp);
1253 
1254 	/* If we have a child device on the MII bus remove it too. */
1255 	bus_generic_detach(dev);
1256 	device_delete_child(dev, sc->bce_miibus);
1257 
1258 	/* Release all remaining resources. */
1259 	bce_release_resources(sc);
1260 
1261 	DBEXIT(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
1262 
1263 	return(0);
1264 }
1265 
1266 
1267 /****************************************************************************/
1268 /* Device shutdown function.                                                */
1269 /*                                                                          */
1270 /* Stops and resets the controller.                                         */
1271 /*                                                                          */
1272 /* Returns:                                                                 */
1273 /*   0 on success, positive value on failure.                               */
1274 /****************************************************************************/
1275 static int
1276 bce_shutdown(device_t dev)
1277 {
1278 	struct bce_softc *sc = device_get_softc(dev);
1279 	u32 msg;
1280 
1281 	DBENTER(BCE_VERBOSE);
1282 
1283 	BCE_LOCK(sc);
1284 	bce_stop(sc);
1285 	if (sc->bce_flags & BCE_NO_WOL_FLAG)
1286 		msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
1287 	else
1288 		msg = BCE_DRV_MSG_CODE_UNLOAD;
1289 	bce_reset(sc, msg);
1290 	BCE_UNLOCK(sc);
1291 
1292 	DBEXIT(BCE_VERBOSE);
1293 
1294 	return (0);
1295 }
1296 
1297 
1298 #ifdef BCE_DEBUG
1299 /****************************************************************************/
1300 /* Register read.                                                           */
1301 /*                                                                          */
1302 /* Returns:                                                                 */
1303 /*   The value of the register.                                             */
1304 /****************************************************************************/
1305 static u32
1306 bce_reg_rd(struct bce_softc *sc, u32 offset)
1307 {
1308 	u32 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, offset);
1309 	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1310 		__FUNCTION__, offset, val);
1311 	return val;
1312 }
1313 
1314 
1315 /****************************************************************************/
1316 /* Register write (16 bit).                                                 */
1317 /*                                                                          */
1318 /* Returns:                                                                 */
1319 /*   Nothing.                                                               */
1320 /****************************************************************************/
1321 static void
1322 bce_reg_wr16(struct bce_softc *sc, u32 offset, u16 val)
1323 {
1324 	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%04X\n",
1325 		__FUNCTION__, offset, val);
1326 	bus_space_write_2(sc->bce_btag, sc->bce_bhandle, offset, val);
1327 }
1328 
1329 
1330 /****************************************************************************/
1331 /* Register write.                                                          */
1332 /*                                                                          */
1333 /* Returns:                                                                 */
1334 /*   Nothing.                                                               */
1335 /****************************************************************************/
1336 static void
1337 bce_reg_wr(struct bce_softc *sc, u32 offset, u32 val)
1338 {
1339 	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1340 		__FUNCTION__, offset, val);
1341 	bus_space_write_4(sc->bce_btag, sc->bce_bhandle, offset, val);
1342 }
1343 #endif
1344 
1345 /****************************************************************************/
1346 /* Indirect register read.                                                  */
1347 /*                                                                          */
1348 /* Reads NetXtreme II registers using an index/data register pair in PCI    */
1349 /* configuration space.  Using this mechanism avoids issues with posted     */
1350 /* reads but is much slower than memory-mapped I/O.                         */
1351 /*                                                                          */
1352 /* Returns:                                                                 */
1353 /*   The value of the register.                                             */
1354 /****************************************************************************/
1355 static u32
1356 bce_reg_rd_ind(struct bce_softc *sc, u32 offset)
1357 {
1358 	device_t dev;
1359 	dev = sc->bce_dev;
1360 
1361 	pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
1362 #ifdef BCE_DEBUG
1363 	{
1364 		u32 val;
1365 		val = pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
1366 		DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1367 			__FUNCTION__, offset, val);
1368 		return val;
1369 	}
1370 #else
1371 	return pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
1372 #endif
1373 }
1374 
1375 
1376 /****************************************************************************/
1377 /* Indirect register write.                                                 */
1378 /*                                                                          */
1379 /* Writes NetXtreme II registers using an index/data register pair in PCI   */
1380 /* configuration space.  Using this mechanism avoids issues with posted     */
1381 /* writes but is muchh slower than memory-mapped I/O.                       */
1382 /*                                                                          */
1383 /* Returns:                                                                 */
1384 /*   Nothing.                                                               */
1385 /****************************************************************************/
1386 static void
1387 bce_reg_wr_ind(struct bce_softc *sc, u32 offset, u32 val)
1388 {
1389 	device_t dev;
1390 	dev = sc->bce_dev;
1391 
1392 	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1393 		__FUNCTION__, offset, val);
1394 
1395 	pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
1396 	pci_write_config(dev, BCE_PCICFG_REG_WINDOW, val, 4);
1397 }
1398 
1399 
1400 /****************************************************************************/
1401 /* Shared memory write.                                                     */
1402 /*                                                                          */
1403 /* Writes NetXtreme II shared memory region.                                */
1404 /*                                                                          */
1405 /* Returns:                                                                 */
1406 /*   Nothing.                                                               */
1407 /****************************************************************************/
1408 static void
1409 bce_shmem_wr(struct bce_softc *sc, u32 offset, u32 val)
1410 {
1411 	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): Writing 0x%08X  to  "
1412 	    "0x%08X\n",	__FUNCTION__, val, offset);
1413 
1414 	bce_reg_wr_ind(sc, sc->bce_shmem_base + offset, val);
1415 }
1416 
1417 
1418 /****************************************************************************/
1419 /* Shared memory read.                                                      */
1420 /*                                                                          */
1421 /* Reads NetXtreme II shared memory region.                                 */
1422 /*                                                                          */
1423 /* Returns:                                                                 */
1424 /*   The 32 bit value read.                                                 */
1425 /****************************************************************************/
1426 static u32
1427 bce_shmem_rd(struct bce_softc *sc, u32 offset)
1428 {
1429 	u32 val = bce_reg_rd_ind(sc, sc->bce_shmem_base + offset);
1430 
1431 	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): Reading 0x%08X from "
1432 	    "0x%08X\n",	__FUNCTION__, val, offset);
1433 
1434 	return val;
1435 }
1436 
1437 
1438 #ifdef BCE_DEBUG
1439 /****************************************************************************/
1440 /* Context memory read.                                                     */
1441 /*                                                                          */
1442 /* The NetXtreme II controller uses context memory to track connection      */
1443 /* information for L2 and higher network protocols.                         */
1444 /*                                                                          */
1445 /* Returns:                                                                 */
1446 /*   The requested 32 bit value of context memory.                          */
1447 /****************************************************************************/
1448 static u32
1449 bce_ctx_rd(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset)
1450 {
1451 	u32 idx, offset, retry_cnt = 5, val;
1452 
1453 	DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 ||
1454 	    cid_addr & CTX_MASK), BCE_PRINTF("%s(): Invalid CID "
1455 	    "address: 0x%08X.\n", __FUNCTION__, cid_addr));
1456 
1457 	offset = ctx_offset + cid_addr;
1458 
1459 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
1460 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
1461 
1462 		REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_READ_REQ));
1463 
1464 		for (idx = 0; idx < retry_cnt; idx++) {
1465 			val = REG_RD(sc, BCE_CTX_CTX_CTRL);
1466 			if ((val & BCE_CTX_CTX_CTRL_READ_REQ) == 0)
1467 				break;
1468 			DELAY(5);
1469 		}
1470 
1471 		if (val & BCE_CTX_CTX_CTRL_READ_REQ)
1472 			BCE_PRINTF("%s(%d); Unable to read CTX memory: "
1473 			    "cid_addr = 0x%08X, offset = 0x%08X!\n",
1474 			    __FILE__, __LINE__, cid_addr, ctx_offset);
1475 
1476 		val = REG_RD(sc, BCE_CTX_CTX_DATA);
1477 	} else {
1478 		REG_WR(sc, BCE_CTX_DATA_ADR, offset);
1479 		val = REG_RD(sc, BCE_CTX_DATA);
1480 	}
1481 
1482 	DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
1483 		"val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, val);
1484 
1485 	return(val);
1486 }
1487 #endif
1488 
1489 
1490 /****************************************************************************/
1491 /* Context memory write.                                                    */
1492 /*                                                                          */
1493 /* The NetXtreme II controller uses context memory to track connection      */
1494 /* information for L2 and higher network protocols.                         */
1495 /*                                                                          */
1496 /* Returns:                                                                 */
1497 /*   Nothing.                                                               */
1498 /****************************************************************************/
1499 static void
1500 bce_ctx_wr(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset, u32 ctx_val)
1501 {
1502 	u32 idx, offset = ctx_offset + cid_addr;
1503 	u32 val, retry_cnt = 5;
1504 
1505 	DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
1506 		"val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, ctx_val);
1507 
1508 	DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 || cid_addr & CTX_MASK),
1509 		BCE_PRINTF("%s(): Invalid CID address: 0x%08X.\n",
1510 		    __FUNCTION__, cid_addr));
1511 
1512 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
1513 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
1514 
1515 		REG_WR(sc, BCE_CTX_CTX_DATA, ctx_val);
1516 		REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_WRITE_REQ));
1517 
1518 		for (idx = 0; idx < retry_cnt; idx++) {
1519 			val = REG_RD(sc, BCE_CTX_CTX_CTRL);
1520 			if ((val & BCE_CTX_CTX_CTRL_WRITE_REQ) == 0)
1521 				break;
1522 			DELAY(5);
1523 		}
1524 
1525 		if (val & BCE_CTX_CTX_CTRL_WRITE_REQ)
1526 			BCE_PRINTF("%s(%d); Unable to write CTX memory: "
1527 			    "cid_addr = 0x%08X, offset = 0x%08X!\n",
1528 			    __FILE__, __LINE__, cid_addr, ctx_offset);
1529 
1530 	} else {
1531 		REG_WR(sc, BCE_CTX_DATA_ADR, offset);
1532 		REG_WR(sc, BCE_CTX_DATA, ctx_val);
1533 	}
1534 }
1535 
1536 
1537 /****************************************************************************/
1538 /* PHY register read.                                                       */
1539 /*                                                                          */
1540 /* Implements register reads on the MII bus.                                */
1541 /*                                                                          */
1542 /* Returns:                                                                 */
1543 /*   The value of the register.                                             */
1544 /****************************************************************************/
1545 static int
1546 bce_miibus_read_reg(device_t dev, int phy, int reg)
1547 {
1548 	struct bce_softc *sc;
1549 	u32 val;
1550 	int i;
1551 
1552 	sc = device_get_softc(dev);
1553 
1554 	/* Make sure we are accessing the correct PHY address. */
1555 	if (phy != sc->bce_phy_addr) {
1556 		DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d "
1557 		    "for PHY read!\n", phy);
1558 		return(0);
1559 	}
1560 
1561     /*
1562      * The 5709S PHY is an IEEE Clause 45 PHY
1563      * with special mappings to work with IEEE
1564      * Clause 22 register accesses.
1565      */
1566 	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
1567 		if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
1568 			reg += 0x10;
1569 	}
1570 
1571     if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1572 		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1573 		val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1574 
1575 		REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1576 		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1577 
1578 		DELAY(40);
1579 	}
1580 
1581 
1582 	val = BCE_MIPHY(phy) | BCE_MIREG(reg) |
1583 	    BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT |
1584 	    BCE_EMAC_MDIO_COMM_START_BUSY;
1585 	REG_WR(sc, BCE_EMAC_MDIO_COMM, val);
1586 
1587 	for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1588 		DELAY(10);
1589 
1590 		val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1591 		if (!(val & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1592 			DELAY(5);
1593 
1594 			val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1595 			val &= BCE_EMAC_MDIO_COMM_DATA;
1596 
1597 			break;
1598 		}
1599 	}
1600 
1601 	if (val & BCE_EMAC_MDIO_COMM_START_BUSY) {
1602 		BCE_PRINTF("%s(%d): Error: PHY read timeout! phy = %d, "
1603 		    "reg = 0x%04X\n", __FILE__, __LINE__, phy, reg);
1604 		val = 0x0;
1605 	} else {
1606 		val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1607 	}
1608 
1609 
1610 	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1611 		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1612 		val |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1613 
1614 		REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1615 		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1616 
1617 		DELAY(40);
1618 	}
1619 
1620 	DB_PRINT_PHY_REG(reg, val);
1621 	return (val & 0xffff);
1622 
1623 }
1624 
1625 
1626 /****************************************************************************/
1627 /* PHY register write.                                                      */
1628 /*                                                                          */
1629 /* Implements register writes on the MII bus.                               */
1630 /*                                                                          */
1631 /* Returns:                                                                 */
1632 /*   The value of the register.                                             */
1633 /****************************************************************************/
1634 static int
1635 bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
1636 {
1637 	struct bce_softc *sc;
1638 	u32 val1;
1639 	int i;
1640 
1641 	sc = device_get_softc(dev);
1642 
1643 	/* Make sure we are accessing the correct PHY address. */
1644 	if (phy != sc->bce_phy_addr) {
1645 		DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d "
1646 		    "for PHY write!\n", phy);
1647 		return(0);
1648 	}
1649 
1650 	DB_PRINT_PHY_REG(reg, val);
1651 
1652 	/*
1653 	 * The 5709S PHY is an IEEE Clause 45 PHY
1654 	 * with special mappings to work with IEEE
1655 	 * Clause 22 register accesses.
1656 	 */
1657 	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
1658 		if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
1659 			reg += 0x10;
1660 	}
1661 
1662 	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1663 		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1664 		val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1665 
1666 		REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1667 		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1668 
1669 		DELAY(40);
1670 	}
1671 
1672 	val1 = BCE_MIPHY(phy) | BCE_MIREG(reg) | val |
1673 	    BCE_EMAC_MDIO_COMM_COMMAND_WRITE |
1674 	    BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT;
1675 	REG_WR(sc, BCE_EMAC_MDIO_COMM, val1);
1676 
1677 	for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1678 		DELAY(10);
1679 
1680 		val1 = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1681 		if (!(val1 & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1682 			DELAY(5);
1683 			break;
1684 		}
1685 	}
1686 
1687 	if (val1 & BCE_EMAC_MDIO_COMM_START_BUSY)
1688 		BCE_PRINTF("%s(%d): PHY write timeout!\n",
1689 		    __FILE__, __LINE__);
1690 
1691 	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1692 		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1693 		val1 |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1694 
1695 		REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1696 		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1697 
1698 		DELAY(40);
1699 	}
1700 
1701 	return 0;
1702 }
1703 
1704 
1705 /****************************************************************************/
1706 /* MII bus status change.                                                   */
1707 /*                                                                          */
1708 /* Called by the MII bus driver when the PHY establishes link to set the    */
1709 /* MAC interface registers.                                                 */
1710 /*                                                                          */
1711 /* Returns:                                                                 */
1712 /*   Nothing.                                                               */
1713 /****************************************************************************/
1714 static void
1715 bce_miibus_statchg(device_t dev)
1716 {
1717 	struct bce_softc *sc;
1718 	struct mii_data *mii;
1719 	int val;
1720 
1721 	sc = device_get_softc(dev);
1722 
1723 	DBENTER(BCE_VERBOSE_PHY);
1724 
1725 	mii = device_get_softc(sc->bce_miibus);
1726 
1727 	val = REG_RD(sc, BCE_EMAC_MODE);
1728 	val &= ~(BCE_EMAC_MODE_PORT | BCE_EMAC_MODE_HALF_DUPLEX |
1729 	    BCE_EMAC_MODE_MAC_LOOP | BCE_EMAC_MODE_FORCE_LINK |
1730 	    BCE_EMAC_MODE_25G);
1731 
1732 	/* Set MII or GMII interface based on the PHY speed. */
1733 	switch (IFM_SUBTYPE(mii->mii_media_active)) {
1734 	case IFM_10_T:
1735 		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
1736 			DBPRINT(sc, BCE_INFO_PHY,
1737 			    "Enabling 10Mb interface.\n");
1738 			val |= BCE_EMAC_MODE_PORT_MII_10;
1739 			break;
1740 		}
1741 		/* fall-through */
1742 	case IFM_100_TX:
1743 		DBPRINT(sc, BCE_INFO_PHY, "Enabling MII interface.\n");
1744 		val |= BCE_EMAC_MODE_PORT_MII;
1745 		break;
1746 	case IFM_2500_SX:
1747 		DBPRINT(sc, BCE_INFO_PHY, "Enabling 2.5G MAC mode.\n");
1748 		val |= BCE_EMAC_MODE_25G;
1749 		/* fall-through */
1750 	case IFM_1000_T:
1751 	case IFM_1000_SX:
1752 		DBPRINT(sc, BCE_INFO_PHY, "Enabling GMII interface.\n");
1753 		val |= BCE_EMAC_MODE_PORT_GMII;
1754 		break;
1755 	default:
1756 		DBPRINT(sc, BCE_INFO_PHY, "Unknown link speed, enabling "
1757 		    "default GMII interface.\n");
1758 		val |= BCE_EMAC_MODE_PORT_GMII;
1759 	}
1760 
1761 	/* Set half or full duplex based on PHY settings. */
1762 	if ((mii->mii_media_active & IFM_GMASK) == IFM_HDX) {
1763 		DBPRINT(sc, BCE_INFO_PHY,
1764 		    "Setting Half-Duplex interface.\n");
1765 		val |= BCE_EMAC_MODE_HALF_DUPLEX;
1766 	} else
1767 		DBPRINT(sc, BCE_INFO_PHY,
1768 		    "Setting Full-Duplex interface.\n");
1769 
1770 	REG_WR(sc, BCE_EMAC_MODE, val);
1771 
1772  	if ((mii->mii_media_active & IFM_ETH_RXPAUSE) != 0) {
1773 		DBPRINT(sc, BCE_INFO_PHY,
1774 		    "%s(): Enabling RX flow control.\n", __FUNCTION__);
1775 		BCE_SETBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
1776 	} else {
1777 		DBPRINT(sc, BCE_INFO_PHY,
1778 		    "%s(): Disabling RX flow control.\n", __FUNCTION__);
1779 		BCE_CLRBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
1780 	}
1781 
1782  	if ((mii->mii_media_active & IFM_ETH_TXPAUSE) != 0) {
1783 		DBPRINT(sc, BCE_INFO_PHY,
1784 		    "%s(): Enabling TX flow control.\n", __FUNCTION__);
1785 		BCE_SETBIT(sc, BCE_EMAC_TX_MODE, BCE_EMAC_TX_MODE_FLOW_EN);
1786 		sc->bce_flags |= BCE_USING_TX_FLOW_CONTROL;
1787 	} else {
1788 		DBPRINT(sc, BCE_INFO_PHY,
1789 		    "%s(): Disabling TX flow control.\n", __FUNCTION__);
1790 		BCE_CLRBIT(sc, BCE_EMAC_TX_MODE, BCE_EMAC_TX_MODE_FLOW_EN);
1791 		sc->bce_flags &= ~BCE_USING_TX_FLOW_CONTROL;
1792 	}
1793 
1794 	/* ToDo: Update watermarks in bce_init_rx_context(). */
1795 
1796 	DBEXIT(BCE_VERBOSE_PHY);
1797 }
1798 
1799 
1800 /****************************************************************************/
1801 /* Acquire NVRAM lock.                                                      */
1802 /*                                                                          */
1803 /* Before the NVRAM can be accessed the caller must acquire an NVRAM lock.  */
1804 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1805 /* for use by the driver.                                                   */
1806 /*                                                                          */
1807 /* Returns:                                                                 */
1808 /*   0 on success, positive value on failure.                               */
1809 /****************************************************************************/
1810 static int
1811 bce_acquire_nvram_lock(struct bce_softc *sc)
1812 {
1813 	u32 val;
1814 	int j, rc = 0;
1815 
1816 	DBENTER(BCE_VERBOSE_NVRAM);
1817 
1818 	/* Request access to the flash interface. */
1819 	REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_SET2);
1820 	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1821 		val = REG_RD(sc, BCE_NVM_SW_ARB);
1822 		if (val & BCE_NVM_SW_ARB_ARB_ARB2)
1823 			break;
1824 
1825 		DELAY(5);
1826 	}
1827 
1828 	if (j >= NVRAM_TIMEOUT_COUNT) {
1829 		DBPRINT(sc, BCE_WARN, "Timeout acquiring NVRAM lock!\n");
1830 		rc = EBUSY;
1831 	}
1832 
1833 	DBEXIT(BCE_VERBOSE_NVRAM);
1834 	return (rc);
1835 }
1836 
1837 
1838 /****************************************************************************/
1839 /* Release NVRAM lock.                                                      */
1840 /*                                                                          */
1841 /* When the caller is finished accessing NVRAM the lock must be released.   */
1842 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1843 /* for use by the driver.                                                   */
1844 /*                                                                          */
1845 /* Returns:                                                                 */
1846 /*   0 on success, positive value on failure.                               */
1847 /****************************************************************************/
1848 static int
1849 bce_release_nvram_lock(struct bce_softc *sc)
1850 {
1851 	u32 val;
1852 	int j, rc = 0;
1853 
1854 	DBENTER(BCE_VERBOSE_NVRAM);
1855 
1856 	/*
1857 	 * Relinquish nvram interface.
1858 	 */
1859 	REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_CLR2);
1860 
1861 	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1862 		val = REG_RD(sc, BCE_NVM_SW_ARB);
1863 		if (!(val & BCE_NVM_SW_ARB_ARB_ARB2))
1864 			break;
1865 
1866 		DELAY(5);
1867 	}
1868 
1869 	if (j >= NVRAM_TIMEOUT_COUNT) {
1870 		DBPRINT(sc, BCE_WARN, "Timeout releasing NVRAM lock!\n");
1871 		rc = EBUSY;
1872 	}
1873 
1874 	DBEXIT(BCE_VERBOSE_NVRAM);
1875 	return (rc);
1876 }
1877 
1878 
1879 #ifdef BCE_NVRAM_WRITE_SUPPORT
1880 /****************************************************************************/
1881 /* Enable NVRAM write access.                                               */
1882 /*                                                                          */
1883 /* Before writing to NVRAM the caller must enable NVRAM writes.             */
1884 /*                                                                          */
1885 /* Returns:                                                                 */
1886 /*   0 on success, positive value on failure.                               */
1887 /****************************************************************************/
1888 static int
1889 bce_enable_nvram_write(struct bce_softc *sc)
1890 {
1891 	u32 val;
1892 	int rc = 0;
1893 
1894 	DBENTER(BCE_VERBOSE_NVRAM);
1895 
1896 	val = REG_RD(sc, BCE_MISC_CFG);
1897 	REG_WR(sc, BCE_MISC_CFG, val | BCE_MISC_CFG_NVM_WR_EN_PCI);
1898 
1899 	if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
1900 		int j;
1901 
1902 		REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1903 		REG_WR(sc, BCE_NVM_COMMAND,	BCE_NVM_COMMAND_WREN | BCE_NVM_COMMAND_DOIT);
1904 
1905 		for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1906 			DELAY(5);
1907 
1908 			val = REG_RD(sc, BCE_NVM_COMMAND);
1909 			if (val & BCE_NVM_COMMAND_DONE)
1910 				break;
1911 		}
1912 
1913 		if (j >= NVRAM_TIMEOUT_COUNT) {
1914 			DBPRINT(sc, BCE_WARN, "Timeout writing NVRAM!\n");
1915 			rc = EBUSY;
1916 		}
1917 	}
1918 
1919 	DBENTER(BCE_VERBOSE_NVRAM);
1920 	return (rc);
1921 }
1922 
1923 
1924 /****************************************************************************/
1925 /* Disable NVRAM write access.                                              */
1926 /*                                                                          */
1927 /* When the caller is finished writing to NVRAM write access must be        */
1928 /* disabled.                                                                */
1929 /*                                                                          */
1930 /* Returns:                                                                 */
1931 /*   Nothing.                                                               */
1932 /****************************************************************************/
1933 static void
1934 bce_disable_nvram_write(struct bce_softc *sc)
1935 {
1936 	u32 val;
1937 
1938 	DBENTER(BCE_VERBOSE_NVRAM);
1939 
1940 	val = REG_RD(sc, BCE_MISC_CFG);
1941 	REG_WR(sc, BCE_MISC_CFG, val & ~BCE_MISC_CFG_NVM_WR_EN);
1942 
1943 	DBEXIT(BCE_VERBOSE_NVRAM);
1944 
1945 }
1946 #endif
1947 
1948 
1949 /****************************************************************************/
1950 /* Enable NVRAM access.                                                     */
1951 /*                                                                          */
1952 /* Before accessing NVRAM for read or write operations the caller must      */
1953 /* enabled NVRAM access.                                                    */
1954 /*                                                                          */
1955 /* Returns:                                                                 */
1956 /*   Nothing.                                                               */
1957 /****************************************************************************/
1958 static void
1959 bce_enable_nvram_access(struct bce_softc *sc)
1960 {
1961 	u32 val;
1962 
1963 	DBENTER(BCE_VERBOSE_NVRAM);
1964 
1965 	val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
1966 	/* Enable both bits, even on read. */
1967 	REG_WR(sc, BCE_NVM_ACCESS_ENABLE, val |
1968 	    BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN);
1969 
1970 	DBEXIT(BCE_VERBOSE_NVRAM);
1971 }
1972 
1973 
1974 /****************************************************************************/
1975 /* Disable NVRAM access.                                                    */
1976 /*                                                                          */
1977 /* When the caller is finished accessing NVRAM access must be disabled.     */
1978 /*                                                                          */
1979 /* Returns:                                                                 */
1980 /*   Nothing.                                                               */
1981 /****************************************************************************/
1982 static void
1983 bce_disable_nvram_access(struct bce_softc *sc)
1984 {
1985 	u32 val;
1986 
1987 	DBENTER(BCE_VERBOSE_NVRAM);
1988 
1989 	val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
1990 
1991 	/* Disable both bits, even after read. */
1992 	REG_WR(sc, BCE_NVM_ACCESS_ENABLE, val &
1993 	    ~(BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN));
1994 
1995 	DBEXIT(BCE_VERBOSE_NVRAM);
1996 }
1997 
1998 
1999 #ifdef BCE_NVRAM_WRITE_SUPPORT
2000 /****************************************************************************/
2001 /* Erase NVRAM page before writing.                                         */
2002 /*                                                                          */
2003 /* Non-buffered flash parts require that a page be erased before it is      */
2004 /* written.                                                                 */
2005 /*                                                                          */
2006 /* Returns:                                                                 */
2007 /*   0 on success, positive value on failure.                               */
2008 /****************************************************************************/
2009 static int
2010 bce_nvram_erase_page(struct bce_softc *sc, u32 offset)
2011 {
2012 	u32 cmd;
2013 	int j, rc = 0;
2014 
2015 	DBENTER(BCE_VERBOSE_NVRAM);
2016 
2017 	/* Buffered flash doesn't require an erase. */
2018 	if (sc->bce_flash_info->flags & BCE_NV_BUFFERED)
2019 		goto bce_nvram_erase_page_exit;
2020 
2021 	/* Build an erase command. */
2022 	cmd = BCE_NVM_COMMAND_ERASE | BCE_NVM_COMMAND_WR |
2023 	    BCE_NVM_COMMAND_DOIT;
2024 
2025 	/*
2026 	 * Clear the DONE bit separately, set the NVRAM adress to erase,
2027 	 * and issue the erase command.
2028 	 */
2029 	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2030 	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
2031 	REG_WR(sc, BCE_NVM_COMMAND, cmd);
2032 
2033 	/* Wait for completion. */
2034 	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2035 		u32 val;
2036 
2037 		DELAY(5);
2038 
2039 		val = REG_RD(sc, BCE_NVM_COMMAND);
2040 		if (val & BCE_NVM_COMMAND_DONE)
2041 			break;
2042 	}
2043 
2044 	if (j >= NVRAM_TIMEOUT_COUNT) {
2045 		DBPRINT(sc, BCE_WARN, "Timeout erasing NVRAM.\n");
2046 		rc = EBUSY;
2047 	}
2048 
2049 bce_nvram_erase_page_exit:
2050 	DBEXIT(BCE_VERBOSE_NVRAM);
2051 	return (rc);
2052 }
2053 #endif /* BCE_NVRAM_WRITE_SUPPORT */
2054 
2055 
2056 /****************************************************************************/
2057 /* Read a dword (32 bits) from NVRAM.                                       */
2058 /*                                                                          */
2059 /* Read a 32 bit word from NVRAM.  The caller is assumed to have already    */
2060 /* obtained the NVRAM lock and enabled the controller for NVRAM access.     */
2061 /*                                                                          */
2062 /* Returns:                                                                 */
2063 /*   0 on success and the 32 bit value read, positive value on failure.     */
2064 /****************************************************************************/
2065 static int
2066 bce_nvram_read_dword(struct bce_softc *sc,
2067     u32 offset, u8 *ret_val, u32 cmd_flags)
2068 {
2069 	u32 cmd;
2070 	int i, rc = 0;
2071 
2072 	DBENTER(BCE_EXTREME_NVRAM);
2073 
2074 	/* Build the command word. */
2075 	cmd = BCE_NVM_COMMAND_DOIT | cmd_flags;
2076 
2077 	/* Calculate the offset for buffered flash if translation is used. */
2078 	if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
2079 		offset = ((offset / sc->bce_flash_info->page_size) <<
2080 		    sc->bce_flash_info->page_bits) +
2081 		    (offset % sc->bce_flash_info->page_size);
2082 	}
2083 
2084 	/*
2085 	 * Clear the DONE bit separately, set the address to read,
2086 	 * and issue the read.
2087 	 */
2088 	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2089 	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
2090 	REG_WR(sc, BCE_NVM_COMMAND, cmd);
2091 
2092 	/* Wait for completion. */
2093 	for (i = 0; i < NVRAM_TIMEOUT_COUNT; i++) {
2094 		u32 val;
2095 
2096 		DELAY(5);
2097 
2098 		val = REG_RD(sc, BCE_NVM_COMMAND);
2099 		if (val & BCE_NVM_COMMAND_DONE) {
2100 			val = REG_RD(sc, BCE_NVM_READ);
2101 
2102 			val = bce_be32toh(val);
2103 			memcpy(ret_val, &val, 4);
2104 			break;
2105 		}
2106 	}
2107 
2108 	/* Check for errors. */
2109 	if (i >= NVRAM_TIMEOUT_COUNT) {
2110 		BCE_PRINTF("%s(%d): Timeout error reading NVRAM at "
2111 		    "offset 0x%08X!\n",	__FILE__, __LINE__, offset);
2112 		rc = EBUSY;
2113 	}
2114 
2115 	DBEXIT(BCE_EXTREME_NVRAM);
2116 	return(rc);
2117 }
2118 
2119 
2120 #ifdef BCE_NVRAM_WRITE_SUPPORT
2121 /****************************************************************************/
2122 /* Write a dword (32 bits) to NVRAM.                                        */
2123 /*                                                                          */
2124 /* Write a 32 bit word to NVRAM.  The caller is assumed to have already     */
2125 /* obtained the NVRAM lock, enabled the controller for NVRAM access, and    */
2126 /* enabled NVRAM write access.                                              */
2127 /*                                                                          */
2128 /* Returns:                                                                 */
2129 /*   0 on success, positive value on failure.                               */
2130 /****************************************************************************/
2131 static int
2132 bce_nvram_write_dword(struct bce_softc *sc, u32 offset, u8 *val,
2133 	u32 cmd_flags)
2134 {
2135 	u32 cmd, val32;
2136 	int j, rc = 0;
2137 
2138 	DBENTER(BCE_VERBOSE_NVRAM);
2139 
2140 	/* Build the command word. */
2141 	cmd = BCE_NVM_COMMAND_DOIT | BCE_NVM_COMMAND_WR | cmd_flags;
2142 
2143 	/* Calculate the offset for buffered flash if translation is used. */
2144 	if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
2145 		offset = ((offset / sc->bce_flash_info->page_size) <<
2146 		    sc->bce_flash_info->page_bits) +
2147 		    (offset % sc->bce_flash_info->page_size);
2148 	}
2149 
2150 	/*
2151 	 * Clear the DONE bit separately, convert NVRAM data to big-endian,
2152 	 * set the NVRAM address to write, and issue the write command
2153 	 */
2154 	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2155 	memcpy(&val32, val, 4);
2156 	val32 = htobe32(val32);
2157 	REG_WR(sc, BCE_NVM_WRITE, val32);
2158 	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
2159 	REG_WR(sc, BCE_NVM_COMMAND, cmd);
2160 
2161 	/* Wait for completion. */
2162 	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2163 		DELAY(5);
2164 
2165 		if (REG_RD(sc, BCE_NVM_COMMAND) & BCE_NVM_COMMAND_DONE)
2166 			break;
2167 	}
2168 	if (j >= NVRAM_TIMEOUT_COUNT) {
2169 		BCE_PRINTF("%s(%d): Timeout error writing NVRAM at "
2170 		    "offset 0x%08X\n", __FILE__, __LINE__, offset);
2171 		rc = EBUSY;
2172 	}
2173 
2174 	DBEXIT(BCE_VERBOSE_NVRAM);
2175 	return (rc);
2176 }
2177 #endif /* BCE_NVRAM_WRITE_SUPPORT */
2178 
2179 
2180 /****************************************************************************/
2181 /* Initialize NVRAM access.                                                 */
2182 /*                                                                          */
2183 /* Identify the NVRAM device in use and prepare the NVRAM interface to      */
2184 /* access that device.                                                      */
2185 /*                                                                          */
2186 /* Returns:                                                                 */
2187 /*   0 on success, positive value on failure.                               */
2188 /****************************************************************************/
2189 static int
2190 bce_init_nvram(struct bce_softc *sc)
2191 {
2192 	u32 val;
2193 	int j, entry_count, rc = 0;
2194 	struct flash_spec *flash;
2195 
2196 	DBENTER(BCE_VERBOSE_NVRAM);
2197 
2198 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
2199 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
2200 		sc->bce_flash_info = &flash_5709;
2201 		goto bce_init_nvram_get_flash_size;
2202 	}
2203 
2204 	/* Determine the selected interface. */
2205 	val = REG_RD(sc, BCE_NVM_CFG1);
2206 
2207 	entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
2208 
2209 	/*
2210 	 * Flash reconfiguration is required to support additional
2211 	 * NVRAM devices not directly supported in hardware.
2212 	 * Check if the flash interface was reconfigured
2213 	 * by the bootcode.
2214 	 */
2215 
2216 	if (val & 0x40000000) {
2217 		/* Flash interface reconfigured by bootcode. */
2218 
2219 		DBPRINT(sc,BCE_INFO_LOAD,
2220 			"bce_init_nvram(): Flash WAS reconfigured.\n");
2221 
2222 		for (j = 0, flash = &flash_table[0]; j < entry_count;
2223 		     j++, flash++) {
2224 			if ((val & FLASH_BACKUP_STRAP_MASK) ==
2225 			    (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
2226 				sc->bce_flash_info = flash;
2227 				break;
2228 			}
2229 		}
2230 	} else {
2231 		/* Flash interface not yet reconfigured. */
2232 		u32 mask;
2233 
2234 		DBPRINT(sc, BCE_INFO_LOAD, "%s(): Flash was NOT reconfigured.\n",
2235 			__FUNCTION__);
2236 
2237 		if (val & (1 << 23))
2238 			mask = FLASH_BACKUP_STRAP_MASK;
2239 		else
2240 			mask = FLASH_STRAP_MASK;
2241 
2242 		/* Look for the matching NVRAM device configuration data. */
2243 		for (j = 0, flash = &flash_table[0]; j < entry_count; j++, flash++) {
2244 
2245 			/* Check if the device matches any of the known devices. */
2246 			if ((val & mask) == (flash->strapping & mask)) {
2247 				/* Found a device match. */
2248 				sc->bce_flash_info = flash;
2249 
2250 				/* Request access to the flash interface. */
2251 				if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2252 					return rc;
2253 
2254 				/* Reconfigure the flash interface. */
2255 				bce_enable_nvram_access(sc);
2256 				REG_WR(sc, BCE_NVM_CFG1, flash->config1);
2257 				REG_WR(sc, BCE_NVM_CFG2, flash->config2);
2258 				REG_WR(sc, BCE_NVM_CFG3, flash->config3);
2259 				REG_WR(sc, BCE_NVM_WRITE1, flash->write1);
2260 				bce_disable_nvram_access(sc);
2261 				bce_release_nvram_lock(sc);
2262 
2263 				break;
2264 			}
2265 		}
2266 	}
2267 
2268 	/* Check if a matching device was found. */
2269 	if (j == entry_count) {
2270 		sc->bce_flash_info = NULL;
2271 		BCE_PRINTF("%s(%d): Unknown Flash NVRAM found!\n",
2272 		    __FILE__, __LINE__);
2273 		DBEXIT(BCE_VERBOSE_NVRAM);
2274 		return (ENODEV);
2275 	}
2276 
2277 bce_init_nvram_get_flash_size:
2278 	/* Write the flash config data to the shared memory interface. */
2279 	val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG2);
2280 	val &= BCE_SHARED_HW_CFG2_NVM_SIZE_MASK;
2281 	if (val)
2282 		sc->bce_flash_size = val;
2283 	else
2284 		sc->bce_flash_size = sc->bce_flash_info->total_size;
2285 
2286 	DBPRINT(sc, BCE_INFO_LOAD, "%s(): Found %s, size = 0x%08X\n",
2287 	    __FUNCTION__, sc->bce_flash_info->name,
2288 	    sc->bce_flash_info->total_size);
2289 
2290 	DBEXIT(BCE_VERBOSE_NVRAM);
2291 	return rc;
2292 }
2293 
2294 
2295 /****************************************************************************/
2296 /* Read an arbitrary range of data from NVRAM.                              */
2297 /*                                                                          */
2298 /* Prepares the NVRAM interface for access and reads the requested data     */
2299 /* into the supplied buffer.                                                */
2300 /*                                                                          */
2301 /* Returns:                                                                 */
2302 /*   0 on success and the data read, positive value on failure.             */
2303 /****************************************************************************/
2304 static int
2305 bce_nvram_read(struct bce_softc *sc, u32 offset, u8 *ret_buf,
2306 	int buf_size)
2307 {
2308 	int rc = 0;
2309 	u32 cmd_flags, offset32, len32, extra;
2310 
2311 	DBENTER(BCE_VERBOSE_NVRAM);
2312 
2313 	if (buf_size == 0)
2314 		goto bce_nvram_read_exit;
2315 
2316 	/* Request access to the flash interface. */
2317 	if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2318 		goto bce_nvram_read_exit;
2319 
2320 	/* Enable access to flash interface */
2321 	bce_enable_nvram_access(sc);
2322 
2323 	len32 = buf_size;
2324 	offset32 = offset;
2325 	extra = 0;
2326 
2327 	cmd_flags = 0;
2328 
2329 	if (offset32 & 3) {
2330 		u8 buf[4];
2331 		u32 pre_len;
2332 
2333 		offset32 &= ~3;
2334 		pre_len = 4 - (offset & 3);
2335 
2336 		if (pre_len >= len32) {
2337 			pre_len = len32;
2338 			cmd_flags = BCE_NVM_COMMAND_FIRST | BCE_NVM_COMMAND_LAST;
2339 		}
2340 		else {
2341 			cmd_flags = BCE_NVM_COMMAND_FIRST;
2342 		}
2343 
2344 		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2345 
2346 		if (rc)
2347 			return rc;
2348 
2349 		memcpy(ret_buf, buf + (offset & 3), pre_len);
2350 
2351 		offset32 += 4;
2352 		ret_buf += pre_len;
2353 		len32 -= pre_len;
2354 	}
2355 
2356 	if (len32 & 3) {
2357 		extra = 4 - (len32 & 3);
2358 		len32 = (len32 + 4) & ~3;
2359 	}
2360 
2361 	if (len32 == 4) {
2362 		u8 buf[4];
2363 
2364 		if (cmd_flags)
2365 			cmd_flags = BCE_NVM_COMMAND_LAST;
2366 		else
2367 			cmd_flags = BCE_NVM_COMMAND_FIRST |
2368 				    BCE_NVM_COMMAND_LAST;
2369 
2370 		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2371 
2372 		memcpy(ret_buf, buf, 4 - extra);
2373 	}
2374 	else if (len32 > 0) {
2375 		u8 buf[4];
2376 
2377 		/* Read the first word. */
2378 		if (cmd_flags)
2379 			cmd_flags = 0;
2380 		else
2381 			cmd_flags = BCE_NVM_COMMAND_FIRST;
2382 
2383 		rc = bce_nvram_read_dword(sc, offset32, ret_buf, cmd_flags);
2384 
2385 		/* Advance to the next dword. */
2386 		offset32 += 4;
2387 		ret_buf += 4;
2388 		len32 -= 4;
2389 
2390 		while (len32 > 4 && rc == 0) {
2391 			rc = bce_nvram_read_dword(sc, offset32, ret_buf, 0);
2392 
2393 			/* Advance to the next dword. */
2394 			offset32 += 4;
2395 			ret_buf += 4;
2396 			len32 -= 4;
2397 		}
2398 
2399 		if (rc)
2400 			goto bce_nvram_read_locked_exit;
2401 
2402 		cmd_flags = BCE_NVM_COMMAND_LAST;
2403 		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2404 
2405 		memcpy(ret_buf, buf, 4 - extra);
2406 	}
2407 
2408 bce_nvram_read_locked_exit:
2409 	/* Disable access to flash interface and release the lock. */
2410 	bce_disable_nvram_access(sc);
2411 	bce_release_nvram_lock(sc);
2412 
2413 bce_nvram_read_exit:
2414 	DBEXIT(BCE_VERBOSE_NVRAM);
2415 	return rc;
2416 }
2417 
2418 
2419 #ifdef BCE_NVRAM_WRITE_SUPPORT
2420 /****************************************************************************/
2421 /* Write an arbitrary range of data from NVRAM.                             */
2422 /*                                                                          */
2423 /* Prepares the NVRAM interface for write access and writes the requested   */
2424 /* data from the supplied buffer.  The caller is responsible for            */
2425 /* calculating any appropriate CRCs.                                        */
2426 /*                                                                          */
2427 /* Returns:                                                                 */
2428 /*   0 on success, positive value on failure.                               */
2429 /****************************************************************************/
2430 static int
2431 bce_nvram_write(struct bce_softc *sc, u32 offset, u8 *data_buf,
2432 	int buf_size)
2433 {
2434 	u32 written, offset32, len32;
2435 	u8 *buf, start[4], end[4];
2436 	int rc = 0;
2437 	int align_start, align_end;
2438 
2439 	DBENTER(BCE_VERBOSE_NVRAM);
2440 
2441 	buf = data_buf;
2442 	offset32 = offset;
2443 	len32 = buf_size;
2444 	align_start = align_end = 0;
2445 
2446 	if ((align_start = (offset32 & 3))) {
2447 		offset32 &= ~3;
2448 		len32 += align_start;
2449 		if ((rc = bce_nvram_read(sc, offset32, start, 4)))
2450 			goto bce_nvram_write_exit;
2451 	}
2452 
2453 	if (len32 & 3) {
2454 	       	if ((len32 > 4) || !align_start) {
2455 			align_end = 4 - (len32 & 3);
2456 			len32 += align_end;
2457 			if ((rc = bce_nvram_read(sc, offset32 + len32 - 4,
2458 				end, 4))) {
2459 				goto bce_nvram_write_exit;
2460 			}
2461 		}
2462 	}
2463 
2464 	if (align_start || align_end) {
2465 		buf = malloc(len32, M_DEVBUF, M_NOWAIT);
2466 		if (buf == 0) {
2467 			rc = ENOMEM;
2468 			goto bce_nvram_write_exit;
2469 		}
2470 
2471 		if (align_start) {
2472 			memcpy(buf, start, 4);
2473 		}
2474 
2475 		if (align_end) {
2476 			memcpy(buf + len32 - 4, end, 4);
2477 		}
2478 		memcpy(buf + align_start, data_buf, buf_size);
2479 	}
2480 
2481 	written = 0;
2482 	while ((written < len32) && (rc == 0)) {
2483 		u32 page_start, page_end, data_start, data_end;
2484 		u32 addr, cmd_flags;
2485 		int i;
2486 		u8 flash_buffer[264];
2487 
2488 	    /* Find the page_start addr */
2489 		page_start = offset32 + written;
2490 		page_start -= (page_start % sc->bce_flash_info->page_size);
2491 		/* Find the page_end addr */
2492 		page_end = page_start + sc->bce_flash_info->page_size;
2493 		/* Find the data_start addr */
2494 		data_start = (written == 0) ? offset32 : page_start;
2495 		/* Find the data_end addr */
2496 		data_end = (page_end > offset32 + len32) ?
2497 			(offset32 + len32) : page_end;
2498 
2499 		/* Request access to the flash interface. */
2500 		if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2501 			goto bce_nvram_write_exit;
2502 
2503 		/* Enable access to flash interface */
2504 		bce_enable_nvram_access(sc);
2505 
2506 		cmd_flags = BCE_NVM_COMMAND_FIRST;
2507 		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2508 			int j;
2509 
2510 			/* Read the whole page into the buffer
2511 			 * (non-buffer flash only) */
2512 			for (j = 0; j < sc->bce_flash_info->page_size; j += 4) {
2513 				if (j == (sc->bce_flash_info->page_size - 4)) {
2514 					cmd_flags |= BCE_NVM_COMMAND_LAST;
2515 				}
2516 				rc = bce_nvram_read_dword(sc,
2517 					page_start + j,
2518 					&flash_buffer[j],
2519 					cmd_flags);
2520 
2521 				if (rc)
2522 					goto bce_nvram_write_locked_exit;
2523 
2524 				cmd_flags = 0;
2525 			}
2526 		}
2527 
2528 		/* Enable writes to flash interface (unlock write-protect) */
2529 		if ((rc = bce_enable_nvram_write(sc)) != 0)
2530 			goto bce_nvram_write_locked_exit;
2531 
2532 		/* Erase the page */
2533 		if ((rc = bce_nvram_erase_page(sc, page_start)) != 0)
2534 			goto bce_nvram_write_locked_exit;
2535 
2536 		/* Re-enable the write again for the actual write */
2537 		bce_enable_nvram_write(sc);
2538 
2539 		/* Loop to write back the buffer data from page_start to
2540 		 * data_start */
2541 		i = 0;
2542 		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2543 			for (addr = page_start; addr < data_start;
2544 				addr += 4, i += 4) {
2545 
2546 				rc = bce_nvram_write_dword(sc, addr,
2547 					&flash_buffer[i], cmd_flags);
2548 
2549 				if (rc != 0)
2550 					goto bce_nvram_write_locked_exit;
2551 
2552 				cmd_flags = 0;
2553 			}
2554 		}
2555 
2556 		/* Loop to write the new data from data_start to data_end */
2557 		for (addr = data_start; addr < data_end; addr += 4, i++) {
2558 			if ((addr == page_end - 4) ||
2559 				((sc->bce_flash_info->flags & BCE_NV_BUFFERED) &&
2560 				(addr == data_end - 4))) {
2561 
2562 				cmd_flags |= BCE_NVM_COMMAND_LAST;
2563 			}
2564 			rc = bce_nvram_write_dword(sc, addr, buf,
2565 				cmd_flags);
2566 
2567 			if (rc != 0)
2568 				goto bce_nvram_write_locked_exit;
2569 
2570 			cmd_flags = 0;
2571 			buf += 4;
2572 		}
2573 
2574 		/* Loop to write back the buffer data from data_end
2575 		 * to page_end */
2576 		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2577 			for (addr = data_end; addr < page_end;
2578 				addr += 4, i += 4) {
2579 
2580 				if (addr == page_end-4) {
2581 					cmd_flags = BCE_NVM_COMMAND_LAST;
2582                 		}
2583 				rc = bce_nvram_write_dword(sc, addr,
2584 					&flash_buffer[i], cmd_flags);
2585 
2586 				if (rc != 0)
2587 					goto bce_nvram_write_locked_exit;
2588 
2589 				cmd_flags = 0;
2590 			}
2591 		}
2592 
2593 		/* Disable writes to flash interface (lock write-protect) */
2594 		bce_disable_nvram_write(sc);
2595 
2596 		/* Disable access to flash interface */
2597 		bce_disable_nvram_access(sc);
2598 		bce_release_nvram_lock(sc);
2599 
2600 		/* Increment written */
2601 		written += data_end - data_start;
2602 	}
2603 
2604 	goto bce_nvram_write_exit;
2605 
2606 bce_nvram_write_locked_exit:
2607 		bce_disable_nvram_write(sc);
2608 		bce_disable_nvram_access(sc);
2609 		bce_release_nvram_lock(sc);
2610 
2611 bce_nvram_write_exit:
2612 	if (align_start || align_end)
2613 		free(buf, M_DEVBUF);
2614 
2615 	DBEXIT(BCE_VERBOSE_NVRAM);
2616 	return (rc);
2617 }
2618 #endif /* BCE_NVRAM_WRITE_SUPPORT */
2619 
2620 
2621 /****************************************************************************/
2622 /* Verifies that NVRAM is accessible and contains valid data.               */
2623 /*                                                                          */
2624 /* Reads the configuration data from NVRAM and verifies that the CRC is     */
2625 /* correct.                                                                 */
2626 /*                                                                          */
2627 /* Returns:                                                                 */
2628 /*   0 on success, positive value on failure.                               */
2629 /****************************************************************************/
2630 static int
2631 bce_nvram_test(struct bce_softc *sc)
2632 {
2633 	u32 buf[BCE_NVRAM_SIZE / 4];
2634 	u8 *data = (u8 *) buf;
2635 	int rc = 0;
2636 	u32 magic, csum;
2637 
2638 	DBENTER(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
2639 
2640 	/*
2641 	 * Check that the device NVRAM is valid by reading
2642 	 * the magic value at offset 0.
2643 	 */
2644 	if ((rc = bce_nvram_read(sc, 0, data, 4)) != 0) {
2645 		BCE_PRINTF("%s(%d): Unable to read NVRAM!\n",
2646 		    __FILE__, __LINE__);
2647 		goto bce_nvram_test_exit;
2648 	}
2649 
2650 	/*
2651 	 * Verify that offset 0 of the NVRAM contains
2652 	 * a valid magic number.
2653 	 */
2654     magic = bce_be32toh(buf[0]);
2655 	if (magic != BCE_NVRAM_MAGIC) {
2656 		rc = ENODEV;
2657 		BCE_PRINTF("%s(%d): Invalid NVRAM magic value! "
2658 		    "Expected: 0x%08X, Found: 0x%08X\n",
2659 		    __FILE__, __LINE__, BCE_NVRAM_MAGIC, magic);
2660 		goto bce_nvram_test_exit;
2661 	}
2662 
2663 	/*
2664 	 * Verify that the device NVRAM includes valid
2665 	 * configuration data.
2666 	 */
2667 	if ((rc = bce_nvram_read(sc, 0x100, data, BCE_NVRAM_SIZE)) != 0) {
2668 		BCE_PRINTF("%s(%d): Unable to read manufacturing "
2669 		    "Information from  NVRAM!\n", __FILE__, __LINE__);
2670 		goto bce_nvram_test_exit;
2671 	}
2672 
2673 	csum = ether_crc32_le(data, 0x100);
2674 	if (csum != BCE_CRC32_RESIDUAL) {
2675 		rc = ENODEV;
2676 		BCE_PRINTF("%s(%d): Invalid manufacturing information "
2677 		    "NVRAM CRC!	Expected: 0x%08X, Found: 0x%08X\n",
2678 		    __FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
2679 		goto bce_nvram_test_exit;
2680 	}
2681 
2682 	csum = ether_crc32_le(data + 0x100, 0x100);
2683 	if (csum != BCE_CRC32_RESIDUAL) {
2684 		rc = ENODEV;
2685 		BCE_PRINTF("%s(%d): Invalid feature configuration "
2686 		    "information NVRAM CRC! Expected: 0x%08X, "
2687 		    "Found: 08%08X\n", __FILE__, __LINE__,
2688 		    BCE_CRC32_RESIDUAL, csum);
2689 	}
2690 
2691 bce_nvram_test_exit:
2692 	DBEXIT(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
2693 	return rc;
2694 }
2695 
2696 
2697 /****************************************************************************/
2698 /* Identifies the current media type of the controller and sets the PHY     */
2699 /* address.                                                                 */
2700 /*                                                                          */
2701 /* Returns:                                                                 */
2702 /*   Nothing.                                                               */
2703 /****************************************************************************/
2704 static void
2705 bce_get_media(struct bce_softc *sc)
2706 {
2707 	u32 val;
2708 
2709 	DBENTER(BCE_VERBOSE_PHY);
2710 
2711 	/* Assume PHY address for copper controllers. */
2712 	sc->bce_phy_addr = 1;
2713 
2714 	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
2715  		u32 val = REG_RD(sc, BCE_MISC_DUAL_MEDIA_CTRL);
2716 		u32 bond_id = val & BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID;
2717 		u32 strap;
2718 
2719 		/*
2720 		 * The BCM5709S is software configurable
2721 		 * for Copper or SerDes operation.
2722 		 */
2723 		if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_C) {
2724 			DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded "
2725 			    "for copper.\n");
2726 			goto bce_get_media_exit;
2727 		} else if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_S) {
2728 			DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded "
2729 			    "for dual media.\n");
2730 			sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2731 			goto bce_get_media_exit;
2732 		}
2733 
2734 		if (val & BCE_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE)
2735 			strap = (val &
2736 			    BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21;
2737 		else
2738 			strap = (val &
2739 			    BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8;
2740 
2741 		if (pci_get_function(sc->bce_dev) == 0) {
2742 			switch (strap) {
2743 			case 0x4:
2744 			case 0x5:
2745 			case 0x6:
2746 				DBPRINT(sc, BCE_INFO_LOAD,
2747 				    "BCM5709 s/w configured for SerDes.\n");
2748 				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2749 				break;
2750 			default:
2751 				DBPRINT(sc, BCE_INFO_LOAD,
2752 				    "BCM5709 s/w configured for Copper.\n");
2753 				break;
2754 			}
2755 		} else {
2756 			switch (strap) {
2757 			case 0x1:
2758 			case 0x2:
2759 			case 0x4:
2760 				DBPRINT(sc, BCE_INFO_LOAD,
2761 				    "BCM5709 s/w configured for SerDes.\n");
2762 				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2763 				break;
2764 			default:
2765 				DBPRINT(sc, BCE_INFO_LOAD,
2766 				    "BCM5709 s/w configured for Copper.\n");
2767 				break;
2768 			}
2769 		}
2770 
2771 	} else if (BCE_CHIP_BOND_ID(sc) & BCE_CHIP_BOND_ID_SERDES_BIT)
2772 		sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2773 
2774 	if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) {
2775 
2776 		sc->bce_flags |= BCE_NO_WOL_FLAG;
2777 
2778 		if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
2779 			sc->bce_phy_flags |= BCE_PHY_IEEE_CLAUSE_45_FLAG;
2780 
2781 		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
2782 			/* 5708S/09S/16S use a separate PHY for SerDes. */
2783 			sc->bce_phy_addr = 2;
2784 
2785 			val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
2786 			if (val & BCE_SHARED_HW_CFG_PHY_2_5G) {
2787 				sc->bce_phy_flags |=
2788 				    BCE_PHY_2_5G_CAPABLE_FLAG;
2789 				DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb "
2790 				    "capable adapter\n");
2791 			}
2792 		}
2793 	} else if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) ||
2794 	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708))
2795 		sc->bce_phy_flags |= BCE_PHY_CRC_FIX_FLAG;
2796 
2797 bce_get_media_exit:
2798 	DBPRINT(sc, (BCE_INFO_LOAD | BCE_INFO_PHY),
2799 		"Using PHY address %d.\n", sc->bce_phy_addr);
2800 
2801 	DBEXIT(BCE_VERBOSE_PHY);
2802 }
2803 
2804 
2805 /****************************************************************************/
2806 /* Performs PHY initialization required before MII drivers access the       */
2807 /* device.                                                                  */
2808 /*                                                                          */
2809 /* Returns:                                                                 */
2810 /*   Nothing.                                                               */
2811 /****************************************************************************/
2812 static void
2813 bce_init_media(struct bce_softc *sc)
2814 {
2815 	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
2816 		/*
2817 		 * Configure 5709S/5716S PHYs to use traditional IEEE
2818 		 * Clause 22 method. Otherwise we have no way to attach
2819 		 * the PHY in mii(4) layer. PHY specific configuration
2820 		 * is done in mii layer.
2821 		 */
2822 
2823 		/* Select auto-negotiation MMD of the PHY. */
2824 		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
2825 		    BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_ADDR_EXT);
2826 		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
2827 		    BRGPHY_ADDR_EXT, BRGPHY_ADDR_EXT_AN_MMD);
2828 
2829 		/* Set IEEE0 block of AN MMD (assumed in brgphy(4) code). */
2830 		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
2831 		    BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
2832 	}
2833 }
2834 
2835 
2836 /****************************************************************************/
2837 /* Free any DMA memory owned by the driver.                                 */
2838 /*                                                                          */
2839 /* Scans through each data structre that requires DMA memory and frees      */
2840 /* the memory if allocated.                                                 */
2841 /*                                                                          */
2842 /* Returns:                                                                 */
2843 /*   Nothing.                                                               */
2844 /****************************************************************************/
2845 static void
2846 bce_dma_free(struct bce_softc *sc)
2847 {
2848 	int i;
2849 
2850 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
2851 
2852 	/* Free, unmap, and destroy the status block. */
2853 	if (sc->status_block != NULL) {
2854 		bus_dmamem_free(
2855 		   sc->status_tag,
2856 		    sc->status_block,
2857 		    sc->status_map);
2858 		sc->status_block = NULL;
2859 	}
2860 
2861 	if (sc->status_map != NULL) {
2862 		bus_dmamap_unload(
2863 		    sc->status_tag,
2864 		    sc->status_map);
2865 		bus_dmamap_destroy(sc->status_tag,
2866 		    sc->status_map);
2867 		sc->status_map = NULL;
2868 	}
2869 
2870 	if (sc->status_tag != NULL) {
2871 		bus_dma_tag_destroy(sc->status_tag);
2872 		sc->status_tag = NULL;
2873 	}
2874 
2875 
2876 	/* Free, unmap, and destroy the statistics block. */
2877 	if (sc->stats_block != NULL) {
2878 		bus_dmamem_free(
2879 		    sc->stats_tag,
2880 		    sc->stats_block,
2881 		    sc->stats_map);
2882 		sc->stats_block = NULL;
2883 	}
2884 
2885 	if (sc->stats_map != NULL) {
2886 		bus_dmamap_unload(
2887 		    sc->stats_tag,
2888 		    sc->stats_map);
2889 		bus_dmamap_destroy(sc->stats_tag,
2890 		    sc->stats_map);
2891 		sc->stats_map = NULL;
2892 	}
2893 
2894 	if (sc->stats_tag != NULL) {
2895 		bus_dma_tag_destroy(sc->stats_tag);
2896 		sc->stats_tag = NULL;
2897 	}
2898 
2899 
2900 	/* Free, unmap and destroy all context memory pages. */
2901 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
2902 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
2903 		for (i = 0; i < sc->ctx_pages; i++ ) {
2904 			if (sc->ctx_block[i] != NULL) {
2905 				bus_dmamem_free(
2906 				    sc->ctx_tag,
2907 				    sc->ctx_block[i],
2908 				    sc->ctx_map[i]);
2909 				sc->ctx_block[i] = NULL;
2910 			}
2911 
2912 			if (sc->ctx_map[i] != NULL) {
2913 				bus_dmamap_unload(
2914 				    sc->ctx_tag,
2915 				    sc->ctx_map[i]);
2916 				bus_dmamap_destroy(
2917 				    sc->ctx_tag,
2918 				    sc->ctx_map[i]);
2919 				sc->ctx_map[i] = NULL;
2920 			}
2921 		}
2922 
2923 		/* Destroy the context memory tag. */
2924 		if (sc->ctx_tag != NULL) {
2925 			bus_dma_tag_destroy(sc->ctx_tag);
2926 			sc->ctx_tag = NULL;
2927 		}
2928 	}
2929 
2930 
2931 	/* Free, unmap and destroy all TX buffer descriptor chain pages. */
2932 	for (i = 0; i < TX_PAGES; i++ ) {
2933 		if (sc->tx_bd_chain[i] != NULL) {
2934 			bus_dmamem_free(
2935 			    sc->tx_bd_chain_tag,
2936 			    sc->tx_bd_chain[i],
2937 			    sc->tx_bd_chain_map[i]);
2938 			sc->tx_bd_chain[i] = NULL;
2939 		}
2940 
2941 		if (sc->tx_bd_chain_map[i] != NULL) {
2942 			bus_dmamap_unload(
2943 			    sc->tx_bd_chain_tag,
2944 			    sc->tx_bd_chain_map[i]);
2945 			bus_dmamap_destroy(
2946 			    sc->tx_bd_chain_tag,
2947 			    sc->tx_bd_chain_map[i]);
2948 			sc->tx_bd_chain_map[i] = NULL;
2949 		}
2950 	}
2951 
2952 	/* Destroy the TX buffer descriptor tag. */
2953 	if (sc->tx_bd_chain_tag != NULL) {
2954 		bus_dma_tag_destroy(sc->tx_bd_chain_tag);
2955 		sc->tx_bd_chain_tag = NULL;
2956 	}
2957 
2958 
2959 	/* Free, unmap and destroy all RX buffer descriptor chain pages. */
2960 	for (i = 0; i < RX_PAGES; i++ ) {
2961 		if (sc->rx_bd_chain[i] != NULL) {
2962 			bus_dmamem_free(
2963 			    sc->rx_bd_chain_tag,
2964 			    sc->rx_bd_chain[i],
2965 			    sc->rx_bd_chain_map[i]);
2966 			sc->rx_bd_chain[i] = NULL;
2967 		}
2968 
2969 		if (sc->rx_bd_chain_map[i] != NULL) {
2970 			bus_dmamap_unload(
2971 			    sc->rx_bd_chain_tag,
2972 			    sc->rx_bd_chain_map[i]);
2973 			bus_dmamap_destroy(
2974 			    sc->rx_bd_chain_tag,
2975 			    sc->rx_bd_chain_map[i]);
2976 			sc->rx_bd_chain_map[i] = NULL;
2977 		}
2978 	}
2979 
2980 	/* Destroy the RX buffer descriptor tag. */
2981 	if (sc->rx_bd_chain_tag != NULL) {
2982 		bus_dma_tag_destroy(sc->rx_bd_chain_tag);
2983 		sc->rx_bd_chain_tag = NULL;
2984 	}
2985 
2986 
2987 #ifdef BCE_JUMBO_HDRSPLIT
2988 	/* Free, unmap and destroy all page buffer descriptor chain pages. */
2989 	for (i = 0; i < PG_PAGES; i++ ) {
2990 		if (sc->pg_bd_chain[i] != NULL) {
2991 			bus_dmamem_free(
2992 			    sc->pg_bd_chain_tag,
2993 			    sc->pg_bd_chain[i],
2994 			    sc->pg_bd_chain_map[i]);
2995 			sc->pg_bd_chain[i] = NULL;
2996 		}
2997 
2998 		if (sc->pg_bd_chain_map[i] != NULL) {
2999 			bus_dmamap_unload(
3000 			    sc->pg_bd_chain_tag,
3001 			    sc->pg_bd_chain_map[i]);
3002 			bus_dmamap_destroy(
3003 			    sc->pg_bd_chain_tag,
3004 			    sc->pg_bd_chain_map[i]);
3005 			sc->pg_bd_chain_map[i] = NULL;
3006 		}
3007 	}
3008 
3009 	/* Destroy the page buffer descriptor tag. */
3010 	if (sc->pg_bd_chain_tag != NULL) {
3011 		bus_dma_tag_destroy(sc->pg_bd_chain_tag);
3012 		sc->pg_bd_chain_tag = NULL;
3013 	}
3014 #endif
3015 
3016 
3017 	/* Unload and destroy the TX mbuf maps. */
3018 	for (i = 0; i < TOTAL_TX_BD; i++) {
3019 		if (sc->tx_mbuf_map[i] != NULL) {
3020 			bus_dmamap_unload(sc->tx_mbuf_tag,
3021 			    sc->tx_mbuf_map[i]);
3022 			bus_dmamap_destroy(sc->tx_mbuf_tag,
3023 	 		    sc->tx_mbuf_map[i]);
3024 			sc->tx_mbuf_map[i] = NULL;
3025 		}
3026 	}
3027 
3028 	/* Destroy the TX mbuf tag. */
3029 	if (sc->tx_mbuf_tag != NULL) {
3030 		bus_dma_tag_destroy(sc->tx_mbuf_tag);
3031 		sc->tx_mbuf_tag = NULL;
3032 	}
3033 
3034 	/* Unload and destroy the RX mbuf maps. */
3035 	for (i = 0; i < TOTAL_RX_BD; i++) {
3036 		if (sc->rx_mbuf_map[i] != NULL) {
3037 			bus_dmamap_unload(sc->rx_mbuf_tag,
3038 			    sc->rx_mbuf_map[i]);
3039 			bus_dmamap_destroy(sc->rx_mbuf_tag,
3040 	 		    sc->rx_mbuf_map[i]);
3041 			sc->rx_mbuf_map[i] = NULL;
3042 		}
3043 	}
3044 
3045 	/* Destroy the RX mbuf tag. */
3046 	if (sc->rx_mbuf_tag != NULL) {
3047 		bus_dma_tag_destroy(sc->rx_mbuf_tag);
3048 		sc->rx_mbuf_tag = NULL;
3049 	}
3050 
3051 #ifdef BCE_JUMBO_HDRSPLIT
3052 	/* Unload and destroy the page mbuf maps. */
3053 	for (i = 0; i < TOTAL_PG_BD; i++) {
3054 		if (sc->pg_mbuf_map[i] != NULL) {
3055 			bus_dmamap_unload(sc->pg_mbuf_tag,
3056 			    sc->pg_mbuf_map[i]);
3057 			bus_dmamap_destroy(sc->pg_mbuf_tag,
3058 	 		    sc->pg_mbuf_map[i]);
3059 			sc->pg_mbuf_map[i] = NULL;
3060 		}
3061 	}
3062 
3063 	/* Destroy the page mbuf tag. */
3064 	if (sc->pg_mbuf_tag != NULL) {
3065 		bus_dma_tag_destroy(sc->pg_mbuf_tag);
3066 		sc->pg_mbuf_tag = NULL;
3067 	}
3068 #endif
3069 
3070 	/* Destroy the parent tag */
3071 	if (sc->parent_tag != NULL) {
3072 		bus_dma_tag_destroy(sc->parent_tag);
3073 		sc->parent_tag = NULL;
3074 	}
3075 
3076 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
3077 }
3078 
3079 
3080 /****************************************************************************/
3081 /* Get DMA memory from the OS.                                              */
3082 /*                                                                          */
3083 /* Validates that the OS has provided DMA buffers in response to a          */
3084 /* bus_dmamap_load() call and saves the physical address of those buffers.  */
3085 /* When the callback is used the OS will return 0 for the mapping function  */
3086 /* (bus_dmamap_load()) so we use the value of map_arg->maxsegs to pass any  */
3087 /* failures back to the caller.                                             */
3088 /*                                                                          */
3089 /* Returns:                                                                 */
3090 /*   Nothing.                                                               */
3091 /****************************************************************************/
3092 static void
3093 bce_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
3094 {
3095 	bus_addr_t *busaddr = arg;
3096 
3097 	KASSERT(nseg == 1, ("%s(): Too many segments returned (%d)!",
3098 	    __FUNCTION__, nseg));
3099 	/* Simulate a mapping failure. */
3100 	DBRUNIF(DB_RANDOMTRUE(dma_map_addr_failed_sim_control),
3101 	    error = ENOMEM);
3102 
3103 	/* ToDo: How to increment debug sim_count variable here? */
3104 
3105 	/* Check for an error and signal the caller that an error occurred. */
3106 	if (error) {
3107 		*busaddr = 0;
3108 	} else {
3109 		*busaddr = segs->ds_addr;
3110 	}
3111 
3112 	return;
3113 }
3114 
3115 
3116 /****************************************************************************/
3117 /* Allocate any DMA memory needed by the driver.                            */
3118 /*                                                                          */
3119 /* Allocates DMA memory needed for the various global structures needed by  */
3120 /* hardware.                                                                */
3121 /*                                                                          */
3122 /* Memory alignment requirements:                                           */
3123 /* +-----------------+----------+----------+----------+----------+          */
3124 /* |                 |   5706   |   5708   |   5709   |   5716   |          */
3125 /* +-----------------+----------+----------+----------+----------+          */
3126 /* |Status Block     | 8 bytes  | 8 bytes  | 16 bytes | 16 bytes |          */
3127 /* |Statistics Block | 8 bytes  | 8 bytes  | 16 bytes | 16 bytes |          */
3128 /* |RX Buffers       | 16 bytes | 16 bytes | 16 bytes | 16 bytes |          */
3129 /* |PG Buffers       |   none   |   none   |   none   |   none   |          */
3130 /* |TX Buffers       |   none   |   none   |   none   |   none   |          */
3131 /* |Chain Pages(1)   |   4KiB   |   4KiB   |   4KiB   |   4KiB   |          */
3132 /* |Context Memory   |          |          |          |          |          */
3133 /* +-----------------+----------+----------+----------+----------+          */
3134 /*                                                                          */
3135 /* (1) Must align with CPU page size (BCM_PAGE_SZIE).                       */
3136 /*                                                                          */
3137 /* Returns:                                                                 */
3138 /*   0 for success, positive value for failure.                             */
3139 /****************************************************************************/
3140 static int
3141 bce_dma_alloc(device_t dev)
3142 {
3143 	struct bce_softc *sc;
3144 	int i, error, rc = 0;
3145 	bus_size_t max_size, max_seg_size;
3146 	int max_segments;
3147 
3148 	sc = device_get_softc(dev);
3149 
3150 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
3151 
3152 	/*
3153 	 * Allocate the parent bus DMA tag appropriate for PCI.
3154 	 */
3155 	if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, BCE_DMA_BOUNDARY,
3156 	    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
3157 	    BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL,
3158 	    &sc->parent_tag)) {
3159 		BCE_PRINTF("%s(%d): Could not allocate parent DMA tag!\n",
3160 		    __FILE__, __LINE__);
3161 		rc = ENOMEM;
3162 		goto bce_dma_alloc_exit;
3163 	}
3164 
3165 	/*
3166 	 * Create a DMA tag for the status block, allocate and clear the
3167 	 * memory, map the memory into DMA space, and fetch the physical
3168 	 * address of the block.
3169 	 */
3170 	if (bus_dma_tag_create(sc->parent_tag, BCE_DMA_ALIGN,
3171 	    BCE_DMA_BOUNDARY, sc->max_bus_addr,	BUS_SPACE_MAXADDR,
3172 	    NULL, NULL,	BCE_STATUS_BLK_SZ, 1, BCE_STATUS_BLK_SZ,
3173 	    0, NULL, NULL, &sc->status_tag)) {
3174 		BCE_PRINTF("%s(%d): Could not allocate status block "
3175 		    "DMA tag!\n", __FILE__, __LINE__);
3176 		rc = ENOMEM;
3177 		goto bce_dma_alloc_exit;
3178 	}
3179 
3180 	if(bus_dmamem_alloc(sc->status_tag, (void **)&sc->status_block,
3181 	    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3182 	    &sc->status_map)) {
3183 		BCE_PRINTF("%s(%d): Could not allocate status block "
3184 		    "DMA memory!\n", __FILE__, __LINE__);
3185 		rc = ENOMEM;
3186 		goto bce_dma_alloc_exit;
3187 	}
3188 
3189 	error = bus_dmamap_load(sc->status_tag,	sc->status_map,
3190 	    sc->status_block, BCE_STATUS_BLK_SZ, bce_dma_map_addr,
3191 	    &sc->status_block_paddr, BUS_DMA_NOWAIT);
3192 
3193 	if (error) {
3194 		BCE_PRINTF("%s(%d): Could not map status block "
3195 		    "DMA memory!\n", __FILE__, __LINE__);
3196 		rc = ENOMEM;
3197 		goto bce_dma_alloc_exit;
3198 	}
3199 
3200 	DBPRINT(sc, BCE_INFO_LOAD, "%s(): status_block_paddr = 0x%jX\n",
3201 	    __FUNCTION__, (uintmax_t) sc->status_block_paddr);
3202 
3203 	/*
3204 	 * Create a DMA tag for the statistics block, allocate and clear the
3205 	 * memory, map the memory into DMA space, and fetch the physical
3206 	 * address of the block.
3207 	 */
3208 	if (bus_dma_tag_create(sc->parent_tag, BCE_DMA_ALIGN,
3209 	    BCE_DMA_BOUNDARY, sc->max_bus_addr,	BUS_SPACE_MAXADDR,
3210 	    NULL, NULL,	BCE_STATS_BLK_SZ, 1, BCE_STATS_BLK_SZ,
3211 	    0, NULL, NULL, &sc->stats_tag)) {
3212 		BCE_PRINTF("%s(%d): Could not allocate statistics block "
3213 		    "DMA tag!\n", __FILE__, __LINE__);
3214 		rc = ENOMEM;
3215 		goto bce_dma_alloc_exit;
3216 	}
3217 
3218 	if (bus_dmamem_alloc(sc->stats_tag, (void **)&sc->stats_block,
3219 	    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &sc->stats_map)) {
3220 		BCE_PRINTF("%s(%d): Could not allocate statistics block "
3221 		    "DMA memory!\n", __FILE__, __LINE__);
3222 		rc = ENOMEM;
3223 		goto bce_dma_alloc_exit;
3224 	}
3225 
3226 	error = bus_dmamap_load(sc->stats_tag, sc->stats_map,
3227 	    sc->stats_block, BCE_STATS_BLK_SZ, bce_dma_map_addr,
3228 	    &sc->stats_block_paddr, BUS_DMA_NOWAIT);
3229 
3230 	if(error) {
3231 		BCE_PRINTF("%s(%d): Could not map statistics block "
3232 		    "DMA memory!\n", __FILE__, __LINE__);
3233 		rc = ENOMEM;
3234 		goto bce_dma_alloc_exit;
3235 	}
3236 
3237 	DBPRINT(sc, BCE_INFO_LOAD, "%s(): stats_block_paddr = 0x%jX\n",
3238 	    __FUNCTION__, (uintmax_t) sc->stats_block_paddr);
3239 
3240 	/* BCM5709 uses host memory as cache for context memory. */
3241 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3242 	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3243 		sc->ctx_pages = 0x2000 / BCM_PAGE_SIZE;
3244 		if (sc->ctx_pages == 0)
3245 			sc->ctx_pages = 1;
3246 
3247 		DBRUNIF((sc->ctx_pages > 512),
3248 		    BCE_PRINTF("%s(%d): Too many CTX pages! %d > 512\n",
3249 		    __FILE__, __LINE__, sc->ctx_pages));
3250 
3251 		/*
3252 		 * Create a DMA tag for the context pages,
3253 		 * allocate and clear the memory, map the
3254 		 * memory into DMA space, and fetch the
3255 		 * physical address of the block.
3256 		 */
3257 		if(bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
3258 		    BCE_DMA_BOUNDARY, sc->max_bus_addr,	BUS_SPACE_MAXADDR,
3259 		    NULL, NULL,	BCM_PAGE_SIZE, 1, BCM_PAGE_SIZE,
3260 		    0, NULL, NULL, &sc->ctx_tag)) {
3261 			BCE_PRINTF("%s(%d): Could not allocate CTX "
3262 			    "DMA tag!\n", __FILE__, __LINE__);
3263 			rc = ENOMEM;
3264 			goto bce_dma_alloc_exit;
3265 		}
3266 
3267 		for (i = 0; i < sc->ctx_pages; i++) {
3268 
3269 			if(bus_dmamem_alloc(sc->ctx_tag,
3270 			    (void **)&sc->ctx_block[i],
3271 			    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3272 			    &sc->ctx_map[i])) {
3273 				BCE_PRINTF("%s(%d): Could not allocate CTX "
3274 				    "DMA memory!\n", __FILE__, __LINE__);
3275 				rc = ENOMEM;
3276 				goto bce_dma_alloc_exit;
3277 			}
3278 
3279 			error = bus_dmamap_load(sc->ctx_tag, sc->ctx_map[i],
3280 			    sc->ctx_block[i], BCM_PAGE_SIZE, bce_dma_map_addr,
3281 			    &sc->ctx_paddr[i], BUS_DMA_NOWAIT);
3282 
3283 			if (error) {
3284 				BCE_PRINTF("%s(%d): Could not map CTX "
3285 				    "DMA memory!\n", __FILE__, __LINE__);
3286 				rc = ENOMEM;
3287 				goto bce_dma_alloc_exit;
3288 			}
3289 
3290 			DBPRINT(sc, BCE_INFO_LOAD, "%s(): ctx_paddr[%d] "
3291 			    "= 0x%jX\n", __FUNCTION__, i,
3292 			    (uintmax_t) sc->ctx_paddr[i]);
3293 		}
3294 	}
3295 
3296 	/*
3297 	 * Create a DMA tag for the TX buffer descriptor chain,
3298 	 * allocate and clear the  memory, and fetch the
3299 	 * physical address of the block.
3300 	 */
3301 	if(bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE, BCE_DMA_BOUNDARY,
3302 	    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
3303 	    BCE_TX_CHAIN_PAGE_SZ, 1, BCE_TX_CHAIN_PAGE_SZ, 0,
3304 	    NULL, NULL,	&sc->tx_bd_chain_tag)) {
3305 		BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
3306 		    "chain DMA tag!\n", __FILE__, __LINE__);
3307 		rc = ENOMEM;
3308 		goto bce_dma_alloc_exit;
3309 	}
3310 
3311 	for (i = 0; i < TX_PAGES; i++) {
3312 
3313 		if(bus_dmamem_alloc(sc->tx_bd_chain_tag,
3314 		    (void **)&sc->tx_bd_chain[i],
3315 		    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3316 		    &sc->tx_bd_chain_map[i])) {
3317 			BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
3318 			    "chain DMA memory!\n", __FILE__, __LINE__);
3319 			rc = ENOMEM;
3320 			goto bce_dma_alloc_exit;
3321 		}
3322 
3323 		error = bus_dmamap_load(sc->tx_bd_chain_tag,
3324 		    sc->tx_bd_chain_map[i], sc->tx_bd_chain[i],
3325 		    BCE_TX_CHAIN_PAGE_SZ, bce_dma_map_addr,
3326 		    &sc->tx_bd_chain_paddr[i], BUS_DMA_NOWAIT);
3327 
3328 		if (error) {
3329 			BCE_PRINTF("%s(%d): Could not map TX descriptor "
3330 			    "chain DMA memory!\n", __FILE__, __LINE__);
3331 			rc = ENOMEM;
3332 			goto bce_dma_alloc_exit;
3333 		}
3334 
3335 		DBPRINT(sc, BCE_INFO_LOAD, "%s(): tx_bd_chain_paddr[%d] = "
3336 		    "0x%jX\n", __FUNCTION__, i,
3337 		    (uintmax_t) sc->tx_bd_chain_paddr[i]);
3338 	}
3339 
3340 	/* Check the required size before mapping to conserve resources. */
3341 	if (bce_tso_enable) {
3342 		max_size     = BCE_TSO_MAX_SIZE;
3343 		max_segments = BCE_MAX_SEGMENTS;
3344 		max_seg_size = BCE_TSO_MAX_SEG_SIZE;
3345 	} else {
3346 		max_size     = MCLBYTES * BCE_MAX_SEGMENTS;
3347 		max_segments = BCE_MAX_SEGMENTS;
3348 		max_seg_size = MCLBYTES;
3349 	}
3350 
3351 	/* Create a DMA tag for TX mbufs. */
3352 	if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
3353 	    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, max_size,
3354 	    max_segments, max_seg_size,	0, NULL, NULL, &sc->tx_mbuf_tag)) {
3355 		BCE_PRINTF("%s(%d): Could not allocate TX mbuf DMA tag!\n",
3356 		    __FILE__, __LINE__);
3357 		rc = ENOMEM;
3358 		goto bce_dma_alloc_exit;
3359 	}
3360 
3361 	/* Create DMA maps for the TX mbufs clusters. */
3362 	for (i = 0; i < TOTAL_TX_BD; i++) {
3363 		if (bus_dmamap_create(sc->tx_mbuf_tag, BUS_DMA_NOWAIT,
3364 			&sc->tx_mbuf_map[i])) {
3365 			BCE_PRINTF("%s(%d): Unable to create TX mbuf DMA "
3366 			    "map!\n", __FILE__, __LINE__);
3367 			rc = ENOMEM;
3368 			goto bce_dma_alloc_exit;
3369 		}
3370 	}
3371 
3372 	/*
3373 	 * Create a DMA tag for the RX buffer descriptor chain,
3374 	 * allocate and clear the memory, and fetch the physical
3375 	 * address of the blocks.
3376 	 */
3377 	if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
3378 			BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR,
3379 			sc->max_bus_addr, NULL, NULL,
3380 			BCE_RX_CHAIN_PAGE_SZ, 1, BCE_RX_CHAIN_PAGE_SZ,
3381 			0, NULL, NULL, &sc->rx_bd_chain_tag)) {
3382 		BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain "
3383 		    "DMA tag!\n", __FILE__, __LINE__);
3384 		rc = ENOMEM;
3385 		goto bce_dma_alloc_exit;
3386 	}
3387 
3388 	for (i = 0; i < RX_PAGES; i++) {
3389 
3390 		if (bus_dmamem_alloc(sc->rx_bd_chain_tag,
3391 		    (void **)&sc->rx_bd_chain[i],
3392 		    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3393 		    &sc->rx_bd_chain_map[i])) {
3394 			BCE_PRINTF("%s(%d): Could not allocate RX descriptor "
3395 			    "chain DMA memory!\n", __FILE__, __LINE__);
3396 			rc = ENOMEM;
3397 			goto bce_dma_alloc_exit;
3398 		}
3399 
3400 		error = bus_dmamap_load(sc->rx_bd_chain_tag,
3401 		    sc->rx_bd_chain_map[i], sc->rx_bd_chain[i],
3402 		    BCE_RX_CHAIN_PAGE_SZ, bce_dma_map_addr,
3403 		    &sc->rx_bd_chain_paddr[i], BUS_DMA_NOWAIT);
3404 
3405 		if (error) {
3406 			BCE_PRINTF("%s(%d): Could not map RX descriptor "
3407 			    "chain DMA memory!\n", __FILE__, __LINE__);
3408 			rc = ENOMEM;
3409 			goto bce_dma_alloc_exit;
3410 		}
3411 
3412 		DBPRINT(sc, BCE_INFO_LOAD, "%s(): rx_bd_chain_paddr[%d] = "
3413 		    "0x%jX\n", __FUNCTION__, i,
3414 		    (uintmax_t) sc->rx_bd_chain_paddr[i]);
3415 	}
3416 
3417 	/*
3418 	 * Create a DMA tag for RX mbufs.
3419 	 */
3420 #ifdef BCE_JUMBO_HDRSPLIT
3421 	max_size = max_seg_size = ((sc->rx_bd_mbuf_alloc_size < MCLBYTES) ?
3422 		MCLBYTES : sc->rx_bd_mbuf_alloc_size);
3423 #else
3424 	max_size = max_seg_size = MJUM9BYTES;
3425 #endif
3426 	max_segments = 1;
3427 
3428 	DBPRINT(sc, BCE_INFO_LOAD, "%s(): Creating rx_mbuf_tag "
3429 	    "(max size = 0x%jX max segments = %d, max segment "
3430 	    "size = 0x%jX)\n", __FUNCTION__, (uintmax_t) max_size,
3431 	     max_segments, (uintmax_t) max_seg_size);
3432 
3433 	if (bus_dma_tag_create(sc->parent_tag, BCE_RX_BUF_ALIGN,
3434 	    BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
3435 	    max_size, max_segments, max_seg_size, 0, NULL, NULL,
3436 	    &sc->rx_mbuf_tag)) {
3437 		BCE_PRINTF("%s(%d): Could not allocate RX mbuf DMA tag!\n",
3438 		    __FILE__, __LINE__);
3439 		rc = ENOMEM;
3440 		goto bce_dma_alloc_exit;
3441 	}
3442 
3443 	/* Create DMA maps for the RX mbuf clusters. */
3444 	for (i = 0; i < TOTAL_RX_BD; i++) {
3445 		if (bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_NOWAIT,
3446 		    &sc->rx_mbuf_map[i])) {
3447 			BCE_PRINTF("%s(%d): Unable to create RX mbuf "
3448 			    "DMA map!\n", __FILE__, __LINE__);
3449 			rc = ENOMEM;
3450 			goto bce_dma_alloc_exit;
3451 		}
3452 	}
3453 
3454 #ifdef BCE_JUMBO_HDRSPLIT
3455 	/*
3456 	 * Create a DMA tag for the page buffer descriptor chain,
3457 	 * allocate and clear the memory, and fetch the physical
3458 	 * address of the blocks.
3459 	 */
3460 	if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
3461 	    BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR, sc->max_bus_addr,
3462 	    NULL, NULL,	BCE_PG_CHAIN_PAGE_SZ, 1, BCE_PG_CHAIN_PAGE_SZ,
3463 	    0, NULL, NULL, &sc->pg_bd_chain_tag)) {
3464 		BCE_PRINTF("%s(%d): Could not allocate page descriptor "
3465 		    "chain DMA tag!\n",	__FILE__, __LINE__);
3466 		rc = ENOMEM;
3467 		goto bce_dma_alloc_exit;
3468 	}
3469 
3470 	for (i = 0; i < PG_PAGES; i++) {
3471 
3472 		if (bus_dmamem_alloc(sc->pg_bd_chain_tag,
3473 		    (void **)&sc->pg_bd_chain[i],
3474 		    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3475 		    &sc->pg_bd_chain_map[i])) {
3476 			BCE_PRINTF("%s(%d): Could not allocate page "
3477 			    "descriptor chain DMA memory!\n",
3478 			    __FILE__, __LINE__);
3479 			rc = ENOMEM;
3480 			goto bce_dma_alloc_exit;
3481 		}
3482 
3483 		error = bus_dmamap_load(sc->pg_bd_chain_tag,
3484 		    sc->pg_bd_chain_map[i], sc->pg_bd_chain[i],
3485 		    BCE_PG_CHAIN_PAGE_SZ, bce_dma_map_addr,
3486 		    &sc->pg_bd_chain_paddr[i], BUS_DMA_NOWAIT);
3487 
3488 		if (error) {
3489 			BCE_PRINTF("%s(%d): Could not map page descriptor "
3490 			    "chain DMA memory!\n", __FILE__, __LINE__);
3491 			rc = ENOMEM;
3492 			goto bce_dma_alloc_exit;
3493 		}
3494 
3495 		DBPRINT(sc, BCE_INFO_LOAD, "%s(): pg_bd_chain_paddr[%d] = "
3496 		    "0x%jX\n", __FUNCTION__, i,
3497 		    (uintmax_t) sc->pg_bd_chain_paddr[i]);
3498 	}
3499 
3500 	/*
3501 	 * Create a DMA tag for page mbufs.
3502 	 */
3503 	max_size = max_seg_size = ((sc->pg_bd_mbuf_alloc_size < MCLBYTES) ?
3504 	    MCLBYTES : sc->pg_bd_mbuf_alloc_size);
3505 
3506 	if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
3507 	    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
3508 	    max_size, 1, max_seg_size, 0, NULL, NULL, &sc->pg_mbuf_tag)) {
3509 		BCE_PRINTF("%s(%d): Could not allocate page mbuf "
3510 		    "DMA tag!\n", __FILE__, __LINE__);
3511 		rc = ENOMEM;
3512 		goto bce_dma_alloc_exit;
3513 	}
3514 
3515 	/* Create DMA maps for the page mbuf clusters. */
3516 	for (i = 0; i < TOTAL_PG_BD; i++) {
3517 		if (bus_dmamap_create(sc->pg_mbuf_tag, BUS_DMA_NOWAIT,
3518 		    &sc->pg_mbuf_map[i])) {
3519 			BCE_PRINTF("%s(%d): Unable to create page mbuf "
3520 			    "DMA map!\n", __FILE__, __LINE__);
3521 			rc = ENOMEM;
3522 			goto bce_dma_alloc_exit;
3523 		}
3524 	}
3525 #endif
3526 
3527 bce_dma_alloc_exit:
3528 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
3529 	return(rc);
3530 }
3531 
3532 
3533 /****************************************************************************/
3534 /* Release all resources used by the driver.                                */
3535 /*                                                                          */
3536 /* Releases all resources acquired by the driver including interrupts,      */
3537 /* interrupt handler, interfaces, mutexes, and DMA memory.                  */
3538 /*                                                                          */
3539 /* Returns:                                                                 */
3540 /*   Nothing.                                                               */
3541 /****************************************************************************/
3542 static void
3543 bce_release_resources(struct bce_softc *sc)
3544 {
3545 	device_t dev;
3546 
3547 	DBENTER(BCE_VERBOSE_RESET);
3548 
3549 	dev = sc->bce_dev;
3550 
3551 	bce_dma_free(sc);
3552 
3553 	if (sc->bce_intrhand != NULL) {
3554 		DBPRINT(sc, BCE_INFO_RESET, "Removing interrupt handler.\n");
3555 		bus_teardown_intr(dev, sc->bce_res_irq, sc->bce_intrhand);
3556 	}
3557 
3558 	if (sc->bce_res_irq != NULL) {
3559 		DBPRINT(sc, BCE_INFO_RESET, "Releasing IRQ.\n");
3560 		bus_release_resource(dev, SYS_RES_IRQ, sc->bce_irq_rid,
3561 		    sc->bce_res_irq);
3562 	}
3563 
3564 	if (sc->bce_flags & (BCE_USING_MSI_FLAG | BCE_USING_MSIX_FLAG)) {
3565 		DBPRINT(sc, BCE_INFO_RESET, "Releasing MSI/MSI-X vector.\n");
3566 		pci_release_msi(dev);
3567 	}
3568 
3569 	if (sc->bce_res_mem != NULL) {
3570 		DBPRINT(sc, BCE_INFO_RESET, "Releasing PCI memory.\n");
3571 		    bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0),
3572 		    sc->bce_res_mem);
3573 	}
3574 
3575 	if (sc->bce_ifp != NULL) {
3576 		DBPRINT(sc, BCE_INFO_RESET, "Releasing IF.\n");
3577 		if_free(sc->bce_ifp);
3578 	}
3579 
3580 	if (mtx_initialized(&sc->bce_mtx))
3581 		BCE_LOCK_DESTROY(sc);
3582 
3583 	DBEXIT(BCE_VERBOSE_RESET);
3584 }
3585 
3586 
3587 /****************************************************************************/
3588 /* Firmware synchronization.                                                */
3589 /*                                                                          */
3590 /* Before performing certain events such as a chip reset, synchronize with  */
3591 /* the firmware first.                                                      */
3592 /*                                                                          */
3593 /* Returns:                                                                 */
3594 /*   0 for success, positive value for failure.                             */
3595 /****************************************************************************/
3596 static int
3597 bce_fw_sync(struct bce_softc *sc, u32 msg_data)
3598 {
3599 	int i, rc = 0;
3600 	u32 val;
3601 
3602 	DBENTER(BCE_VERBOSE_RESET);
3603 
3604 	/* Don't waste any time if we've timed out before. */
3605 	if (sc->bce_fw_timed_out == TRUE) {
3606 		rc = EBUSY;
3607 		goto bce_fw_sync_exit;
3608 	}
3609 
3610 	/* Increment the message sequence number. */
3611 	sc->bce_fw_wr_seq++;
3612 	msg_data |= sc->bce_fw_wr_seq;
3613 
3614  	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "bce_fw_sync(): msg_data = "
3615 	    "0x%08X\n",	msg_data);
3616 
3617 	/* Send the message to the bootcode driver mailbox. */
3618 	bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
3619 
3620 	/* Wait for the bootcode to acknowledge the message. */
3621 	for (i = 0; i < FW_ACK_TIME_OUT_MS; i++) {
3622 		/* Check for a response in the bootcode firmware mailbox. */
3623 		val = bce_shmem_rd(sc, BCE_FW_MB);
3624 		if ((val & BCE_FW_MSG_ACK) == (msg_data & BCE_DRV_MSG_SEQ))
3625 			break;
3626 		DELAY(1000);
3627 	}
3628 
3629 	/* If we've timed out, tell bootcode that we've stopped waiting. */
3630 	if (((val & BCE_FW_MSG_ACK) != (msg_data & BCE_DRV_MSG_SEQ)) &&
3631 	    ((msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0)) {
3632 
3633 		BCE_PRINTF("%s(%d): Firmware synchronization timeout! "
3634 		    "msg_data = 0x%08X\n", __FILE__, __LINE__, msg_data);
3635 
3636 		msg_data &= ~BCE_DRV_MSG_CODE;
3637 		msg_data |= BCE_DRV_MSG_CODE_FW_TIMEOUT;
3638 
3639 		bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
3640 
3641 		sc->bce_fw_timed_out = TRUE;
3642 		rc = EBUSY;
3643 	}
3644 
3645 bce_fw_sync_exit:
3646 	DBEXIT(BCE_VERBOSE_RESET);
3647 	return (rc);
3648 }
3649 
3650 
3651 /****************************************************************************/
3652 /* Load Receive Virtual 2 Physical (RV2P) processor firmware.               */
3653 /*                                                                          */
3654 /* Returns:                                                                 */
3655 /*   Nothing.                                                               */
3656 /****************************************************************************/
3657 static void
3658 bce_load_rv2p_fw(struct bce_softc *sc, u32 *rv2p_code,
3659 	u32 rv2p_code_len, u32 rv2p_proc)
3660 {
3661 	int i;
3662 	u32 val;
3663 
3664 	DBENTER(BCE_VERBOSE_RESET);
3665 
3666 	/* Set the page size used by RV2P. */
3667 	if (rv2p_proc == RV2P_PROC2) {
3668 		BCE_RV2P_PROC2_CHG_MAX_BD_PAGE(USABLE_RX_BD_PER_PAGE);
3669 	}
3670 
3671 	for (i = 0; i < rv2p_code_len; i += 8) {
3672 		REG_WR(sc, BCE_RV2P_INSTR_HIGH, *rv2p_code);
3673 		rv2p_code++;
3674 		REG_WR(sc, BCE_RV2P_INSTR_LOW, *rv2p_code);
3675 		rv2p_code++;
3676 
3677 		if (rv2p_proc == RV2P_PROC1) {
3678 			val = (i / 8) | BCE_RV2P_PROC1_ADDR_CMD_RDWR;
3679 			REG_WR(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
3680 		}
3681 		else {
3682 			val = (i / 8) | BCE_RV2P_PROC2_ADDR_CMD_RDWR;
3683 			REG_WR(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
3684 		}
3685 	}
3686 
3687 	/* Reset the processor, un-stall is done later. */
3688 	if (rv2p_proc == RV2P_PROC1) {
3689 		REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC1_RESET);
3690 	}
3691 	else {
3692 		REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC2_RESET);
3693 	}
3694 
3695 	DBEXIT(BCE_VERBOSE_RESET);
3696 }
3697 
3698 
3699 /****************************************************************************/
3700 /* Load RISC processor firmware.                                            */
3701 /*                                                                          */
3702 /* Loads firmware from the file if_bcefw.h into the scratchpad memory       */
3703 /* associated with a particular processor.                                  */
3704 /*                                                                          */
3705 /* Returns:                                                                 */
3706 /*   Nothing.                                                               */
3707 /****************************************************************************/
3708 static void
3709 bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
3710 	struct fw_info *fw)
3711 {
3712 	u32 offset;
3713 
3714 	DBENTER(BCE_VERBOSE_RESET);
3715 
3716     bce_halt_cpu(sc, cpu_reg);
3717 
3718 	/* Load the Text area. */
3719 	offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
3720 	if (fw->text) {
3721 		int j;
3722 
3723 		for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
3724 			REG_WR_IND(sc, offset, fw->text[j]);
3725 	        }
3726 	}
3727 
3728 	/* Load the Data area. */
3729 	offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
3730 	if (fw->data) {
3731 		int j;
3732 
3733 		for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
3734 			REG_WR_IND(sc, offset, fw->data[j]);
3735 		}
3736 	}
3737 
3738 	/* Load the SBSS area. */
3739 	offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
3740 	if (fw->sbss) {
3741 		int j;
3742 
3743 		for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
3744 			REG_WR_IND(sc, offset, fw->sbss[j]);
3745 		}
3746 	}
3747 
3748 	/* Load the BSS area. */
3749 	offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
3750 	if (fw->bss) {
3751 		int j;
3752 
3753 		for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
3754 			REG_WR_IND(sc, offset, fw->bss[j]);
3755 		}
3756 	}
3757 
3758 	/* Load the Read-Only area. */
3759 	offset = cpu_reg->spad_base +
3760 		(fw->rodata_addr - cpu_reg->mips_view_base);
3761 	if (fw->rodata) {
3762 		int j;
3763 
3764 		for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
3765 			REG_WR_IND(sc, offset, fw->rodata[j]);
3766 		}
3767 	}
3768 
3769 	/* Clear the pre-fetch instruction and set the FW start address. */
3770 	REG_WR_IND(sc, cpu_reg->inst, 0);
3771 	REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
3772 
3773 	DBEXIT(BCE_VERBOSE_RESET);
3774 }
3775 
3776 
3777 /****************************************************************************/
3778 /* Starts the RISC processor.                                               */
3779 /*                                                                          */
3780 /* Assumes the CPU starting address has already been set.                   */
3781 /*                                                                          */
3782 /* Returns:                                                                 */
3783 /*   Nothing.                                                               */
3784 /****************************************************************************/
3785 static void
3786 bce_start_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
3787 {
3788 	u32 val;
3789 
3790 	DBENTER(BCE_VERBOSE_RESET);
3791 
3792 	/* Start the CPU. */
3793 	val = REG_RD_IND(sc, cpu_reg->mode);
3794 	val &= ~cpu_reg->mode_value_halt;
3795 	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
3796 	REG_WR_IND(sc, cpu_reg->mode, val);
3797 
3798 	DBEXIT(BCE_VERBOSE_RESET);
3799 }
3800 
3801 
3802 /****************************************************************************/
3803 /* Halts the RISC processor.                                                */
3804 /*                                                                          */
3805 /* Returns:                                                                 */
3806 /*   Nothing.                                                               */
3807 /****************************************************************************/
3808 static void
3809 bce_halt_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
3810 {
3811 	u32 val;
3812 
3813 	DBENTER(BCE_VERBOSE_RESET);
3814 
3815 	/* Halt the CPU. */
3816 	val = REG_RD_IND(sc, cpu_reg->mode);
3817 	val |= cpu_reg->mode_value_halt;
3818 	REG_WR_IND(sc, cpu_reg->mode, val);
3819 	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
3820 
3821 	DBEXIT(BCE_VERBOSE_RESET);
3822 }
3823 
3824 
3825 /****************************************************************************/
3826 /* Initialize the RX CPU.                                                   */
3827 /*                                                                          */
3828 /* Returns:                                                                 */
3829 /*   Nothing.                                                               */
3830 /****************************************************************************/
3831 static void
3832 bce_start_rxp_cpu(struct bce_softc *sc)
3833 {
3834 	struct cpu_reg cpu_reg;
3835 
3836 	DBENTER(BCE_VERBOSE_RESET);
3837 
3838 	cpu_reg.mode = BCE_RXP_CPU_MODE;
3839 	cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
3840 	cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
3841 	cpu_reg.state = BCE_RXP_CPU_STATE;
3842 	cpu_reg.state_value_clear = 0xffffff;
3843 	cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
3844 	cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
3845 	cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
3846 	cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
3847 	cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
3848 	cpu_reg.spad_base = BCE_RXP_SCRATCH;
3849 	cpu_reg.mips_view_base = 0x8000000;
3850 
3851 	DBPRINT(sc, BCE_INFO_RESET, "Starting RX firmware.\n");
3852 	bce_start_cpu(sc, &cpu_reg);
3853 
3854 	DBEXIT(BCE_VERBOSE_RESET);
3855 }
3856 
3857 
3858 /****************************************************************************/
3859 /* Initialize the RX CPU.                                                   */
3860 /*                                                                          */
3861 /* Returns:                                                                 */
3862 /*   Nothing.                                                               */
3863 /****************************************************************************/
3864 static void
3865 bce_init_rxp_cpu(struct bce_softc *sc)
3866 {
3867 	struct cpu_reg cpu_reg;
3868 	struct fw_info fw;
3869 
3870 	DBENTER(BCE_VERBOSE_RESET);
3871 
3872 	cpu_reg.mode = BCE_RXP_CPU_MODE;
3873 	cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
3874 	cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
3875 	cpu_reg.state = BCE_RXP_CPU_STATE;
3876 	cpu_reg.state_value_clear = 0xffffff;
3877 	cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
3878 	cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
3879 	cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
3880 	cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
3881 	cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
3882 	cpu_reg.spad_base = BCE_RXP_SCRATCH;
3883 	cpu_reg.mips_view_base = 0x8000000;
3884 
3885 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3886 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3887  		fw.ver_major = bce_RXP_b09FwReleaseMajor;
3888 		fw.ver_minor = bce_RXP_b09FwReleaseMinor;
3889 		fw.ver_fix = bce_RXP_b09FwReleaseFix;
3890 		fw.start_addr = bce_RXP_b09FwStartAddr;
3891 
3892 		fw.text_addr = bce_RXP_b09FwTextAddr;
3893 		fw.text_len = bce_RXP_b09FwTextLen;
3894 		fw.text_index = 0;
3895 		fw.text = bce_RXP_b09FwText;
3896 
3897 		fw.data_addr = bce_RXP_b09FwDataAddr;
3898 		fw.data_len = bce_RXP_b09FwDataLen;
3899 		fw.data_index = 0;
3900 		fw.data = bce_RXP_b09FwData;
3901 
3902 		fw.sbss_addr = bce_RXP_b09FwSbssAddr;
3903 		fw.sbss_len = bce_RXP_b09FwSbssLen;
3904 		fw.sbss_index = 0;
3905 		fw.sbss = bce_RXP_b09FwSbss;
3906 
3907 		fw.bss_addr = bce_RXP_b09FwBssAddr;
3908 		fw.bss_len = bce_RXP_b09FwBssLen;
3909 		fw.bss_index = 0;
3910 		fw.bss = bce_RXP_b09FwBss;
3911 
3912 		fw.rodata_addr = bce_RXP_b09FwRodataAddr;
3913 		fw.rodata_len = bce_RXP_b09FwRodataLen;
3914 		fw.rodata_index = 0;
3915 		fw.rodata = bce_RXP_b09FwRodata;
3916 	} else {
3917 		fw.ver_major = bce_RXP_b06FwReleaseMajor;
3918 		fw.ver_minor = bce_RXP_b06FwReleaseMinor;
3919 		fw.ver_fix = bce_RXP_b06FwReleaseFix;
3920 		fw.start_addr = bce_RXP_b06FwStartAddr;
3921 
3922 		fw.text_addr = bce_RXP_b06FwTextAddr;
3923 		fw.text_len = bce_RXP_b06FwTextLen;
3924 		fw.text_index = 0;
3925 		fw.text = bce_RXP_b06FwText;
3926 
3927 		fw.data_addr = bce_RXP_b06FwDataAddr;
3928 		fw.data_len = bce_RXP_b06FwDataLen;
3929 		fw.data_index = 0;
3930 		fw.data = bce_RXP_b06FwData;
3931 
3932 		fw.sbss_addr = bce_RXP_b06FwSbssAddr;
3933 		fw.sbss_len = bce_RXP_b06FwSbssLen;
3934 		fw.sbss_index = 0;
3935 		fw.sbss = bce_RXP_b06FwSbss;
3936 
3937 		fw.bss_addr = bce_RXP_b06FwBssAddr;
3938 		fw.bss_len = bce_RXP_b06FwBssLen;
3939 		fw.bss_index = 0;
3940 		fw.bss = bce_RXP_b06FwBss;
3941 
3942 		fw.rodata_addr = bce_RXP_b06FwRodataAddr;
3943 		fw.rodata_len = bce_RXP_b06FwRodataLen;
3944 		fw.rodata_index = 0;
3945 		fw.rodata = bce_RXP_b06FwRodata;
3946 	}
3947 
3948 	DBPRINT(sc, BCE_INFO_RESET, "Loading RX firmware.\n");
3949 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
3950 
3951     /* Delay RXP start until initialization is complete. */
3952 
3953 	DBEXIT(BCE_VERBOSE_RESET);
3954 }
3955 
3956 
3957 /****************************************************************************/
3958 /* Initialize the TX CPU.                                                   */
3959 /*                                                                          */
3960 /* Returns:                                                                 */
3961 /*   Nothing.                                                               */
3962 /****************************************************************************/
3963 static void
3964 bce_init_txp_cpu(struct bce_softc *sc)
3965 {
3966 	struct cpu_reg cpu_reg;
3967 	struct fw_info fw;
3968 
3969 	DBENTER(BCE_VERBOSE_RESET);
3970 
3971 	cpu_reg.mode = BCE_TXP_CPU_MODE;
3972 	cpu_reg.mode_value_halt = BCE_TXP_CPU_MODE_SOFT_HALT;
3973 	cpu_reg.mode_value_sstep = BCE_TXP_CPU_MODE_STEP_ENA;
3974 	cpu_reg.state = BCE_TXP_CPU_STATE;
3975 	cpu_reg.state_value_clear = 0xffffff;
3976 	cpu_reg.gpr0 = BCE_TXP_CPU_REG_FILE;
3977 	cpu_reg.evmask = BCE_TXP_CPU_EVENT_MASK;
3978 	cpu_reg.pc = BCE_TXP_CPU_PROGRAM_COUNTER;
3979 	cpu_reg.inst = BCE_TXP_CPU_INSTRUCTION;
3980 	cpu_reg.bp = BCE_TXP_CPU_HW_BREAKPOINT;
3981 	cpu_reg.spad_base = BCE_TXP_SCRATCH;
3982 	cpu_reg.mips_view_base = 0x8000000;
3983 
3984 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3985 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3986 		fw.ver_major = bce_TXP_b09FwReleaseMajor;
3987 		fw.ver_minor = bce_TXP_b09FwReleaseMinor;
3988 		fw.ver_fix = bce_TXP_b09FwReleaseFix;
3989 		fw.start_addr = bce_TXP_b09FwStartAddr;
3990 
3991 		fw.text_addr = bce_TXP_b09FwTextAddr;
3992 		fw.text_len = bce_TXP_b09FwTextLen;
3993 		fw.text_index = 0;
3994 		fw.text = bce_TXP_b09FwText;
3995 
3996 		fw.data_addr = bce_TXP_b09FwDataAddr;
3997 		fw.data_len = bce_TXP_b09FwDataLen;
3998 		fw.data_index = 0;
3999 		fw.data = bce_TXP_b09FwData;
4000 
4001 		fw.sbss_addr = bce_TXP_b09FwSbssAddr;
4002 		fw.sbss_len = bce_TXP_b09FwSbssLen;
4003 		fw.sbss_index = 0;
4004 		fw.sbss = bce_TXP_b09FwSbss;
4005 
4006 		fw.bss_addr = bce_TXP_b09FwBssAddr;
4007 		fw.bss_len = bce_TXP_b09FwBssLen;
4008 		fw.bss_index = 0;
4009 		fw.bss = bce_TXP_b09FwBss;
4010 
4011 		fw.rodata_addr = bce_TXP_b09FwRodataAddr;
4012 		fw.rodata_len = bce_TXP_b09FwRodataLen;
4013 		fw.rodata_index = 0;
4014 		fw.rodata = bce_TXP_b09FwRodata;
4015 	} else {
4016 		fw.ver_major = bce_TXP_b06FwReleaseMajor;
4017 		fw.ver_minor = bce_TXP_b06FwReleaseMinor;
4018 		fw.ver_fix = bce_TXP_b06FwReleaseFix;
4019 		fw.start_addr = bce_TXP_b06FwStartAddr;
4020 
4021 		fw.text_addr = bce_TXP_b06FwTextAddr;
4022 		fw.text_len = bce_TXP_b06FwTextLen;
4023 		fw.text_index = 0;
4024 		fw.text = bce_TXP_b06FwText;
4025 
4026 		fw.data_addr = bce_TXP_b06FwDataAddr;
4027 		fw.data_len = bce_TXP_b06FwDataLen;
4028 		fw.data_index = 0;
4029 		fw.data = bce_TXP_b06FwData;
4030 
4031 		fw.sbss_addr = bce_TXP_b06FwSbssAddr;
4032 		fw.sbss_len = bce_TXP_b06FwSbssLen;
4033 		fw.sbss_index = 0;
4034 		fw.sbss = bce_TXP_b06FwSbss;
4035 
4036 		fw.bss_addr = bce_TXP_b06FwBssAddr;
4037 		fw.bss_len = bce_TXP_b06FwBssLen;
4038 		fw.bss_index = 0;
4039 		fw.bss = bce_TXP_b06FwBss;
4040 
4041 		fw.rodata_addr = bce_TXP_b06FwRodataAddr;
4042 		fw.rodata_len = bce_TXP_b06FwRodataLen;
4043 		fw.rodata_index = 0;
4044 		fw.rodata = bce_TXP_b06FwRodata;
4045 	}
4046 
4047 	DBPRINT(sc, BCE_INFO_RESET, "Loading TX firmware.\n");
4048 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4049     bce_start_cpu(sc, &cpu_reg);
4050 
4051 	DBEXIT(BCE_VERBOSE_RESET);
4052 }
4053 
4054 
4055 /****************************************************************************/
4056 /* Initialize the TPAT CPU.                                                 */
4057 /*                                                                          */
4058 /* Returns:                                                                 */
4059 /*   Nothing.                                                               */
4060 /****************************************************************************/
4061 static void
4062 bce_init_tpat_cpu(struct bce_softc *sc)
4063 {
4064 	struct cpu_reg cpu_reg;
4065 	struct fw_info fw;
4066 
4067 	DBENTER(BCE_VERBOSE_RESET);
4068 
4069 	cpu_reg.mode = BCE_TPAT_CPU_MODE;
4070 	cpu_reg.mode_value_halt = BCE_TPAT_CPU_MODE_SOFT_HALT;
4071 	cpu_reg.mode_value_sstep = BCE_TPAT_CPU_MODE_STEP_ENA;
4072 	cpu_reg.state = BCE_TPAT_CPU_STATE;
4073 	cpu_reg.state_value_clear = 0xffffff;
4074 	cpu_reg.gpr0 = BCE_TPAT_CPU_REG_FILE;
4075 	cpu_reg.evmask = BCE_TPAT_CPU_EVENT_MASK;
4076 	cpu_reg.pc = BCE_TPAT_CPU_PROGRAM_COUNTER;
4077 	cpu_reg.inst = BCE_TPAT_CPU_INSTRUCTION;
4078 	cpu_reg.bp = BCE_TPAT_CPU_HW_BREAKPOINT;
4079 	cpu_reg.spad_base = BCE_TPAT_SCRATCH;
4080 	cpu_reg.mips_view_base = 0x8000000;
4081 
4082 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4083 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4084 		fw.ver_major = bce_TPAT_b09FwReleaseMajor;
4085 		fw.ver_minor = bce_TPAT_b09FwReleaseMinor;
4086 		fw.ver_fix = bce_TPAT_b09FwReleaseFix;
4087 		fw.start_addr = bce_TPAT_b09FwStartAddr;
4088 
4089 		fw.text_addr = bce_TPAT_b09FwTextAddr;
4090 		fw.text_len = bce_TPAT_b09FwTextLen;
4091 		fw.text_index = 0;
4092 		fw.text = bce_TPAT_b09FwText;
4093 
4094 		fw.data_addr = bce_TPAT_b09FwDataAddr;
4095 		fw.data_len = bce_TPAT_b09FwDataLen;
4096 		fw.data_index = 0;
4097 		fw.data = bce_TPAT_b09FwData;
4098 
4099 		fw.sbss_addr = bce_TPAT_b09FwSbssAddr;
4100 		fw.sbss_len = bce_TPAT_b09FwSbssLen;
4101 		fw.sbss_index = 0;
4102 		fw.sbss = bce_TPAT_b09FwSbss;
4103 
4104 		fw.bss_addr = bce_TPAT_b09FwBssAddr;
4105 		fw.bss_len = bce_TPAT_b09FwBssLen;
4106 		fw.bss_index = 0;
4107 		fw.bss = bce_TPAT_b09FwBss;
4108 
4109 		fw.rodata_addr = bce_TPAT_b09FwRodataAddr;
4110 		fw.rodata_len = bce_TPAT_b09FwRodataLen;
4111 		fw.rodata_index = 0;
4112 		fw.rodata = bce_TPAT_b09FwRodata;
4113 	} else {
4114 		fw.ver_major = bce_TPAT_b06FwReleaseMajor;
4115 		fw.ver_minor = bce_TPAT_b06FwReleaseMinor;
4116 		fw.ver_fix = bce_TPAT_b06FwReleaseFix;
4117 		fw.start_addr = bce_TPAT_b06FwStartAddr;
4118 
4119 		fw.text_addr = bce_TPAT_b06FwTextAddr;
4120 		fw.text_len = bce_TPAT_b06FwTextLen;
4121 		fw.text_index = 0;
4122 		fw.text = bce_TPAT_b06FwText;
4123 
4124 		fw.data_addr = bce_TPAT_b06FwDataAddr;
4125 		fw.data_len = bce_TPAT_b06FwDataLen;
4126 		fw.data_index = 0;
4127 		fw.data = bce_TPAT_b06FwData;
4128 
4129 		fw.sbss_addr = bce_TPAT_b06FwSbssAddr;
4130 		fw.sbss_len = bce_TPAT_b06FwSbssLen;
4131 		fw.sbss_index = 0;
4132 		fw.sbss = bce_TPAT_b06FwSbss;
4133 
4134 		fw.bss_addr = bce_TPAT_b06FwBssAddr;
4135 		fw.bss_len = bce_TPAT_b06FwBssLen;
4136 		fw.bss_index = 0;
4137 		fw.bss = bce_TPAT_b06FwBss;
4138 
4139 		fw.rodata_addr = bce_TPAT_b06FwRodataAddr;
4140 		fw.rodata_len = bce_TPAT_b06FwRodataLen;
4141 		fw.rodata_index = 0;
4142 		fw.rodata = bce_TPAT_b06FwRodata;
4143 	}
4144 
4145 	DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n");
4146 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4147 	bce_start_cpu(sc, &cpu_reg);
4148 
4149 	DBEXIT(BCE_VERBOSE_RESET);
4150 }
4151 
4152 
4153 /****************************************************************************/
4154 /* Initialize the CP CPU.                                                   */
4155 /*                                                                          */
4156 /* Returns:                                                                 */
4157 /*   Nothing.                                                               */
4158 /****************************************************************************/
4159 static void
4160 bce_init_cp_cpu(struct bce_softc *sc)
4161 {
4162 	struct cpu_reg cpu_reg;
4163 	struct fw_info fw;
4164 
4165 	DBENTER(BCE_VERBOSE_RESET);
4166 
4167 	cpu_reg.mode = BCE_CP_CPU_MODE;
4168 	cpu_reg.mode_value_halt = BCE_CP_CPU_MODE_SOFT_HALT;
4169 	cpu_reg.mode_value_sstep = BCE_CP_CPU_MODE_STEP_ENA;
4170 	cpu_reg.state = BCE_CP_CPU_STATE;
4171 	cpu_reg.state_value_clear = 0xffffff;
4172 	cpu_reg.gpr0 = BCE_CP_CPU_REG_FILE;
4173 	cpu_reg.evmask = BCE_CP_CPU_EVENT_MASK;
4174 	cpu_reg.pc = BCE_CP_CPU_PROGRAM_COUNTER;
4175 	cpu_reg.inst = BCE_CP_CPU_INSTRUCTION;
4176 	cpu_reg.bp = BCE_CP_CPU_HW_BREAKPOINT;
4177 	cpu_reg.spad_base = BCE_CP_SCRATCH;
4178 	cpu_reg.mips_view_base = 0x8000000;
4179 
4180 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4181 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4182 		fw.ver_major = bce_CP_b09FwReleaseMajor;
4183 		fw.ver_minor = bce_CP_b09FwReleaseMinor;
4184 		fw.ver_fix = bce_CP_b09FwReleaseFix;
4185 		fw.start_addr = bce_CP_b09FwStartAddr;
4186 
4187 		fw.text_addr = bce_CP_b09FwTextAddr;
4188 		fw.text_len = bce_CP_b09FwTextLen;
4189 		fw.text_index = 0;
4190 		fw.text = bce_CP_b09FwText;
4191 
4192 		fw.data_addr = bce_CP_b09FwDataAddr;
4193 		fw.data_len = bce_CP_b09FwDataLen;
4194 		fw.data_index = 0;
4195 		fw.data = bce_CP_b09FwData;
4196 
4197 		fw.sbss_addr = bce_CP_b09FwSbssAddr;
4198 		fw.sbss_len = bce_CP_b09FwSbssLen;
4199 		fw.sbss_index = 0;
4200 		fw.sbss = bce_CP_b09FwSbss;
4201 
4202 		fw.bss_addr = bce_CP_b09FwBssAddr;
4203 		fw.bss_len = bce_CP_b09FwBssLen;
4204 		fw.bss_index = 0;
4205 		fw.bss = bce_CP_b09FwBss;
4206 
4207 		fw.rodata_addr = bce_CP_b09FwRodataAddr;
4208 		fw.rodata_len = bce_CP_b09FwRodataLen;
4209 		fw.rodata_index = 0;
4210 		fw.rodata = bce_CP_b09FwRodata;
4211 	} else {
4212 		fw.ver_major = bce_CP_b06FwReleaseMajor;
4213 		fw.ver_minor = bce_CP_b06FwReleaseMinor;
4214 		fw.ver_fix = bce_CP_b06FwReleaseFix;
4215 		fw.start_addr = bce_CP_b06FwStartAddr;
4216 
4217 		fw.text_addr = bce_CP_b06FwTextAddr;
4218 		fw.text_len = bce_CP_b06FwTextLen;
4219 		fw.text_index = 0;
4220 		fw.text = bce_CP_b06FwText;
4221 
4222 		fw.data_addr = bce_CP_b06FwDataAddr;
4223 		fw.data_len = bce_CP_b06FwDataLen;
4224 		fw.data_index = 0;
4225 		fw.data = bce_CP_b06FwData;
4226 
4227 		fw.sbss_addr = bce_CP_b06FwSbssAddr;
4228 		fw.sbss_len = bce_CP_b06FwSbssLen;
4229 		fw.sbss_index = 0;
4230 		fw.sbss = bce_CP_b06FwSbss;
4231 
4232 		fw.bss_addr = bce_CP_b06FwBssAddr;
4233 		fw.bss_len = bce_CP_b06FwBssLen;
4234 		fw.bss_index = 0;
4235 		fw.bss = bce_CP_b06FwBss;
4236 
4237 		fw.rodata_addr = bce_CP_b06FwRodataAddr;
4238 		fw.rodata_len = bce_CP_b06FwRodataLen;
4239 		fw.rodata_index = 0;
4240 		fw.rodata = bce_CP_b06FwRodata;
4241 	}
4242 
4243 	DBPRINT(sc, BCE_INFO_RESET, "Loading CP firmware.\n");
4244 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4245 	bce_start_cpu(sc, &cpu_reg);
4246 
4247 	DBEXIT(BCE_VERBOSE_RESET);
4248 }
4249 
4250 
4251 /****************************************************************************/
4252 /* Initialize the COM CPU.                                                 */
4253 /*                                                                          */
4254 /* Returns:                                                                 */
4255 /*   Nothing.                                                               */
4256 /****************************************************************************/
4257 static void
4258 bce_init_com_cpu(struct bce_softc *sc)
4259 {
4260 	struct cpu_reg cpu_reg;
4261 	struct fw_info fw;
4262 
4263 	DBENTER(BCE_VERBOSE_RESET);
4264 
4265 	cpu_reg.mode = BCE_COM_CPU_MODE;
4266 	cpu_reg.mode_value_halt = BCE_COM_CPU_MODE_SOFT_HALT;
4267 	cpu_reg.mode_value_sstep = BCE_COM_CPU_MODE_STEP_ENA;
4268 	cpu_reg.state = BCE_COM_CPU_STATE;
4269 	cpu_reg.state_value_clear = 0xffffff;
4270 	cpu_reg.gpr0 = BCE_COM_CPU_REG_FILE;
4271 	cpu_reg.evmask = BCE_COM_CPU_EVENT_MASK;
4272 	cpu_reg.pc = BCE_COM_CPU_PROGRAM_COUNTER;
4273 	cpu_reg.inst = BCE_COM_CPU_INSTRUCTION;
4274 	cpu_reg.bp = BCE_COM_CPU_HW_BREAKPOINT;
4275 	cpu_reg.spad_base = BCE_COM_SCRATCH;
4276 	cpu_reg.mips_view_base = 0x8000000;
4277 
4278 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4279 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4280 		fw.ver_major = bce_COM_b09FwReleaseMajor;
4281 		fw.ver_minor = bce_COM_b09FwReleaseMinor;
4282 		fw.ver_fix = bce_COM_b09FwReleaseFix;
4283 		fw.start_addr = bce_COM_b09FwStartAddr;
4284 
4285 		fw.text_addr = bce_COM_b09FwTextAddr;
4286 		fw.text_len = bce_COM_b09FwTextLen;
4287 		fw.text_index = 0;
4288 		fw.text = bce_COM_b09FwText;
4289 
4290 		fw.data_addr = bce_COM_b09FwDataAddr;
4291 		fw.data_len = bce_COM_b09FwDataLen;
4292 		fw.data_index = 0;
4293 		fw.data = bce_COM_b09FwData;
4294 
4295 		fw.sbss_addr = bce_COM_b09FwSbssAddr;
4296 		fw.sbss_len = bce_COM_b09FwSbssLen;
4297 		fw.sbss_index = 0;
4298 		fw.sbss = bce_COM_b09FwSbss;
4299 
4300 		fw.bss_addr = bce_COM_b09FwBssAddr;
4301 		fw.bss_len = bce_COM_b09FwBssLen;
4302 		fw.bss_index = 0;
4303 		fw.bss = bce_COM_b09FwBss;
4304 
4305 		fw.rodata_addr = bce_COM_b09FwRodataAddr;
4306 		fw.rodata_len = bce_COM_b09FwRodataLen;
4307 		fw.rodata_index = 0;
4308 		fw.rodata = bce_COM_b09FwRodata;
4309 	} else {
4310 		fw.ver_major = bce_COM_b06FwReleaseMajor;
4311 		fw.ver_minor = bce_COM_b06FwReleaseMinor;
4312 		fw.ver_fix = bce_COM_b06FwReleaseFix;
4313 		fw.start_addr = bce_COM_b06FwStartAddr;
4314 
4315 		fw.text_addr = bce_COM_b06FwTextAddr;
4316 		fw.text_len = bce_COM_b06FwTextLen;
4317 		fw.text_index = 0;
4318 		fw.text = bce_COM_b06FwText;
4319 
4320 		fw.data_addr = bce_COM_b06FwDataAddr;
4321 		fw.data_len = bce_COM_b06FwDataLen;
4322 		fw.data_index = 0;
4323 		fw.data = bce_COM_b06FwData;
4324 
4325 		fw.sbss_addr = bce_COM_b06FwSbssAddr;
4326 		fw.sbss_len = bce_COM_b06FwSbssLen;
4327 		fw.sbss_index = 0;
4328 		fw.sbss = bce_COM_b06FwSbss;
4329 
4330 		fw.bss_addr = bce_COM_b06FwBssAddr;
4331 		fw.bss_len = bce_COM_b06FwBssLen;
4332 		fw.bss_index = 0;
4333 		fw.bss = bce_COM_b06FwBss;
4334 
4335 		fw.rodata_addr = bce_COM_b06FwRodataAddr;
4336 		fw.rodata_len = bce_COM_b06FwRodataLen;
4337 		fw.rodata_index = 0;
4338 		fw.rodata = bce_COM_b06FwRodata;
4339 	}
4340 
4341 	DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n");
4342 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4343 	bce_start_cpu(sc, &cpu_reg);
4344 
4345 	DBEXIT(BCE_VERBOSE_RESET);
4346 }
4347 
4348 
4349 /****************************************************************************/
4350 /* Initialize the RV2P, RX, TX, TPAT, COM, and CP CPUs.                     */
4351 /*                                                                          */
4352 /* Loads the firmware for each CPU and starts the CPU.                      */
4353 /*                                                                          */
4354 /* Returns:                                                                 */
4355 /*   Nothing.                                                               */
4356 /****************************************************************************/
4357 static void
4358 bce_init_cpus(struct bce_softc *sc)
4359 {
4360 	DBENTER(BCE_VERBOSE_RESET);
4361 
4362 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4363 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4364 
4365 		if ((BCE_CHIP_REV(sc) == BCE_CHIP_REV_Ax)) {
4366 			bce_load_rv2p_fw(sc, bce_xi90_rv2p_proc1,
4367 			    sizeof(bce_xi90_rv2p_proc1), RV2P_PROC1);
4368 			bce_load_rv2p_fw(sc, bce_xi90_rv2p_proc2,
4369 			    sizeof(bce_xi90_rv2p_proc2), RV2P_PROC2);
4370 		} else {
4371 			bce_load_rv2p_fw(sc, bce_xi_rv2p_proc1,
4372 			    sizeof(bce_xi_rv2p_proc1), RV2P_PROC1);
4373 			bce_load_rv2p_fw(sc, bce_xi_rv2p_proc2,
4374 			    sizeof(bce_xi_rv2p_proc2), RV2P_PROC2);
4375 		}
4376 
4377 	} else {
4378 		bce_load_rv2p_fw(sc, bce_rv2p_proc1,
4379 		    sizeof(bce_rv2p_proc1), RV2P_PROC1);
4380 		bce_load_rv2p_fw(sc, bce_rv2p_proc2,
4381 		    sizeof(bce_rv2p_proc2), RV2P_PROC2);
4382 	}
4383 
4384 	bce_init_rxp_cpu(sc);
4385 	bce_init_txp_cpu(sc);
4386 	bce_init_tpat_cpu(sc);
4387 	bce_init_com_cpu(sc);
4388 	bce_init_cp_cpu(sc);
4389 
4390 	DBEXIT(BCE_VERBOSE_RESET);
4391 }
4392 
4393 
4394 /****************************************************************************/
4395 /* Initialize context memory.                                               */
4396 /*                                                                          */
4397 /* Clears the memory associated with each Context ID (CID).                 */
4398 /*                                                                          */
4399 /* Returns:                                                                 */
4400 /*   Nothing.                                                               */
4401 /****************************************************************************/
4402 static int
4403 bce_init_ctx(struct bce_softc *sc)
4404 {
4405 	u32 offset, val, vcid_addr;
4406 	int i, j, rc, retry_cnt;
4407 
4408 	rc = 0;
4409 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
4410 
4411 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4412 	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4413 		retry_cnt = CTX_INIT_RETRY_COUNT;
4414 
4415 		DBPRINT(sc, BCE_INFO_CTX, "Initializing 5709 context.\n");
4416 
4417 		/*
4418 		 * BCM5709 context memory may be cached
4419 		 * in host memory so prepare the host memory
4420 		 * for access.
4421 		 */
4422 		val = BCE_CTX_COMMAND_ENABLED |
4423 		    BCE_CTX_COMMAND_MEM_INIT | (1 << 12);
4424 		val |= (BCM_PAGE_BITS - 8) << 16;
4425 		REG_WR(sc, BCE_CTX_COMMAND, val);
4426 
4427 		/* Wait for mem init command to complete. */
4428 		for (i = 0; i < retry_cnt; i++) {
4429 			val = REG_RD(sc, BCE_CTX_COMMAND);
4430 			if (!(val & BCE_CTX_COMMAND_MEM_INIT))
4431 				break;
4432 			DELAY(2);
4433 		}
4434 		if ((val & BCE_CTX_COMMAND_MEM_INIT) != 0) {
4435 			BCE_PRINTF("%s(): Context memory initialization failed!\n",
4436 			    __FUNCTION__);
4437 			rc = EBUSY;
4438 			goto init_ctx_fail;
4439 		}
4440 
4441 		for (i = 0; i < sc->ctx_pages; i++) {
4442 			/* Set the physical address of the context memory. */
4443 			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA0,
4444 			    BCE_ADDR_LO(sc->ctx_paddr[i] & 0xfffffff0) |
4445 			    BCE_CTX_HOST_PAGE_TBL_DATA0_VALID);
4446 			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA1,
4447 			    BCE_ADDR_HI(sc->ctx_paddr[i]));
4448 			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_CTRL, i |
4449 			    BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
4450 
4451 			/* Verify the context memory write was successful. */
4452 			for (j = 0; j < retry_cnt; j++) {
4453 				val = REG_RD(sc, BCE_CTX_HOST_PAGE_TBL_CTRL);
4454 				if ((val &
4455 				    BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) == 0)
4456 					break;
4457 				DELAY(5);
4458 			}
4459 			if ((val & BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) != 0) {
4460 				BCE_PRINTF("%s(): Failed to initialize "
4461 				    "context page %d!\n", __FUNCTION__, i);
4462 				rc = EBUSY;
4463 				goto init_ctx_fail;
4464 			}
4465 		}
4466 	} else {
4467 
4468 		DBPRINT(sc, BCE_INFO, "Initializing 5706/5708 context.\n");
4469 
4470 		/*
4471 		 * For the 5706/5708, context memory is local to
4472 		 * the controller, so initialize the controller
4473 		 * context memory.
4474 		 */
4475 
4476 		vcid_addr = GET_CID_ADDR(96);
4477 		while (vcid_addr) {
4478 
4479 			vcid_addr -= PHY_CTX_SIZE;
4480 
4481 			REG_WR(sc, BCE_CTX_VIRT_ADDR, 0);
4482 			REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
4483 
4484 			for(offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
4485 				CTX_WR(sc, 0x00, offset, 0);
4486 			}
4487 
4488 			REG_WR(sc, BCE_CTX_VIRT_ADDR, vcid_addr);
4489 			REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
4490 		}
4491 
4492 	}
4493 init_ctx_fail:
4494 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
4495 	return (rc);
4496 }
4497 
4498 
4499 /****************************************************************************/
4500 /* Fetch the permanent MAC address of the controller.                       */
4501 /*                                                                          */
4502 /* Returns:                                                                 */
4503 /*   Nothing.                                                               */
4504 /****************************************************************************/
4505 static void
4506 bce_get_mac_addr(struct bce_softc *sc)
4507 {
4508 	u32 mac_lo = 0, mac_hi = 0;
4509 
4510 	DBENTER(BCE_VERBOSE_RESET);
4511 
4512 	/*
4513 	 * The NetXtreme II bootcode populates various NIC
4514 	 * power-on and runtime configuration items in a
4515 	 * shared memory area.  The factory configured MAC
4516 	 * address is available from both NVRAM and the
4517 	 * shared memory area so we'll read the value from
4518 	 * shared memory for speed.
4519 	 */
4520 
4521 	mac_hi = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_UPPER);
4522 	mac_lo = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_LOWER);
4523 
4524 	if ((mac_lo == 0) && (mac_hi == 0)) {
4525 		BCE_PRINTF("%s(%d): Invalid Ethernet address!\n",
4526 		    __FILE__, __LINE__);
4527 	} else {
4528 		sc->eaddr[0] = (u_char)(mac_hi >> 8);
4529 		sc->eaddr[1] = (u_char)(mac_hi >> 0);
4530 		sc->eaddr[2] = (u_char)(mac_lo >> 24);
4531 		sc->eaddr[3] = (u_char)(mac_lo >> 16);
4532 		sc->eaddr[4] = (u_char)(mac_lo >> 8);
4533 		sc->eaddr[5] = (u_char)(mac_lo >> 0);
4534 	}
4535 
4536 	DBPRINT(sc, BCE_INFO_MISC, "Permanent Ethernet "
4537 	    "address = %6D\n", sc->eaddr, ":");
4538 	DBEXIT(BCE_VERBOSE_RESET);
4539 }
4540 
4541 
4542 /****************************************************************************/
4543 /* Program the MAC address.                                                 */
4544 /*                                                                          */
4545 /* Returns:                                                                 */
4546 /*   Nothing.                                                               */
4547 /****************************************************************************/
4548 static void
4549 bce_set_mac_addr(struct bce_softc *sc)
4550 {
4551 	u32 val;
4552 	u8 *mac_addr = sc->eaddr;
4553 
4554 	/* ToDo: Add support for setting multiple MAC addresses. */
4555 
4556 	DBENTER(BCE_VERBOSE_RESET);
4557 	DBPRINT(sc, BCE_INFO_MISC, "Setting Ethernet address = "
4558 	    "%6D\n", sc->eaddr, ":");
4559 
4560 	val = (mac_addr[0] << 8) | mac_addr[1];
4561 
4562 	REG_WR(sc, BCE_EMAC_MAC_MATCH0, val);
4563 
4564 	val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
4565 	    (mac_addr[4] << 8) | mac_addr[5];
4566 
4567 	REG_WR(sc, BCE_EMAC_MAC_MATCH1, val);
4568 
4569 	DBEXIT(BCE_VERBOSE_RESET);
4570 }
4571 
4572 
4573 /****************************************************************************/
4574 /* Stop the controller.                                                     */
4575 /*                                                                          */
4576 /* Returns:                                                                 */
4577 /*   Nothing.                                                               */
4578 /****************************************************************************/
4579 static void
4580 bce_stop(struct bce_softc *sc)
4581 {
4582 	struct ifnet *ifp;
4583 
4584 	DBENTER(BCE_VERBOSE_RESET);
4585 
4586 	BCE_LOCK_ASSERT(sc);
4587 
4588 	ifp = sc->bce_ifp;
4589 
4590 	callout_stop(&sc->bce_tick_callout);
4591 
4592 	/* Disable the transmit/receive blocks. */
4593 	REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS, BCE_MISC_ENABLE_CLR_DEFAULT);
4594 	REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
4595 	DELAY(20);
4596 
4597 	bce_disable_intr(sc);
4598 
4599 	/* Free RX buffers. */
4600 #ifdef BCE_JUMBO_HDRSPLIT
4601 	bce_free_pg_chain(sc);
4602 #endif
4603 	bce_free_rx_chain(sc);
4604 
4605 	/* Free TX buffers. */
4606 	bce_free_tx_chain(sc);
4607 
4608 	sc->watchdog_timer = 0;
4609 
4610 	sc->bce_link_up = FALSE;
4611 
4612 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
4613 
4614 	DBEXIT(BCE_VERBOSE_RESET);
4615 }
4616 
4617 
4618 static int
4619 bce_reset(struct bce_softc *sc, u32 reset_code)
4620 {
4621 	u32 val;
4622 	int i, rc = 0;
4623 
4624 	DBENTER(BCE_VERBOSE_RESET);
4625 
4626 	DBPRINT(sc, BCE_VERBOSE_RESET, "%s(): reset_code = 0x%08X\n",
4627 	    __FUNCTION__, reset_code);
4628 
4629 	/* Wait for pending PCI transactions to complete. */
4630 	REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS,
4631 	    BCE_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
4632 	    BCE_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
4633 	    BCE_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
4634 	    BCE_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
4635 	val = REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
4636 	DELAY(5);
4637 
4638 	/* Disable DMA */
4639 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4640 	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4641 		val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
4642 		val &= ~BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
4643 		REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
4644 	}
4645 
4646 	/* Assume bootcode is running. */
4647 	sc->bce_fw_timed_out = FALSE;
4648 	sc->bce_drv_cardiac_arrest = FALSE;
4649 
4650 	/* Give the firmware a chance to prepare for the reset. */
4651 	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT0 | reset_code);
4652 	if (rc)
4653 		goto bce_reset_exit;
4654 
4655 	/* Set a firmware reminder that this is a soft reset. */
4656 	bce_shmem_wr(sc, BCE_DRV_RESET_SIGNATURE, BCE_DRV_RESET_SIGNATURE_MAGIC);
4657 
4658 	/* Dummy read to force the chip to complete all current transactions. */
4659 	val = REG_RD(sc, BCE_MISC_ID);
4660 
4661 	/* Chip reset. */
4662 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4663 	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4664 		REG_WR(sc, BCE_MISC_COMMAND, BCE_MISC_COMMAND_SW_RESET);
4665 		REG_RD(sc, BCE_MISC_COMMAND);
4666 		DELAY(5);
4667 
4668 		val = BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
4669 		    BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
4670 
4671 		pci_write_config(sc->bce_dev, BCE_PCICFG_MISC_CONFIG, val, 4);
4672 	} else {
4673 		val = BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4674 		    BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
4675 		    BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
4676 		REG_WR(sc, BCE_PCICFG_MISC_CONFIG, val);
4677 
4678 		/* Allow up to 30us for reset to complete. */
4679 		for (i = 0; i < 10; i++) {
4680 			val = REG_RD(sc, BCE_PCICFG_MISC_CONFIG);
4681 			if ((val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4682 			    BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
4683 				break;
4684 			}
4685 			DELAY(10);
4686 		}
4687 
4688 		/* Check that reset completed successfully. */
4689 		if (val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4690 		    BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
4691 			BCE_PRINTF("%s(%d): Reset failed!\n",
4692 			    __FILE__, __LINE__);
4693 			rc = EBUSY;
4694 			goto bce_reset_exit;
4695 		}
4696 	}
4697 
4698 	/* Make sure byte swapping is properly configured. */
4699 	val = REG_RD(sc, BCE_PCI_SWAP_DIAG0);
4700 	if (val != 0x01020304) {
4701 		BCE_PRINTF("%s(%d): Byte swap is incorrect!\n",
4702 		    __FILE__, __LINE__);
4703 		rc = ENODEV;
4704 		goto bce_reset_exit;
4705 	}
4706 
4707 	/* Just completed a reset, assume that firmware is running again. */
4708 	sc->bce_fw_timed_out = FALSE;
4709 	sc->bce_drv_cardiac_arrest = FALSE;
4710 
4711 	/* Wait for the firmware to finish its initialization. */
4712 	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT1 | reset_code);
4713 	if (rc)
4714 		BCE_PRINTF("%s(%d): Firmware did not complete "
4715 		    "initialization!\n", __FILE__, __LINE__);
4716 
4717 bce_reset_exit:
4718 	DBEXIT(BCE_VERBOSE_RESET);
4719 	return (rc);
4720 }
4721 
4722 
4723 static int
4724 bce_chipinit(struct bce_softc *sc)
4725 {
4726 	u32 val;
4727 	int rc = 0;
4728 
4729 	DBENTER(BCE_VERBOSE_RESET);
4730 
4731 	bce_disable_intr(sc);
4732 
4733 	/*
4734 	 * Initialize DMA byte/word swapping, configure the number of DMA
4735 	 * channels and PCI clock compensation delay.
4736 	 */
4737 	val = BCE_DMA_CONFIG_DATA_BYTE_SWAP |
4738 	    BCE_DMA_CONFIG_DATA_WORD_SWAP |
4739 #if BYTE_ORDER == BIG_ENDIAN
4740 	    BCE_DMA_CONFIG_CNTL_BYTE_SWAP |
4741 #endif
4742 	    BCE_DMA_CONFIG_CNTL_WORD_SWAP |
4743 	    DMA_READ_CHANS << 12 |
4744 	    DMA_WRITE_CHANS << 16;
4745 
4746 	val |= (0x2 << 20) | BCE_DMA_CONFIG_CNTL_PCI_COMP_DLY;
4747 
4748 	if ((sc->bce_flags & BCE_PCIX_FLAG) && (sc->bus_speed_mhz == 133))
4749 		val |= BCE_DMA_CONFIG_PCI_FAST_CLK_CMP;
4750 
4751 	/*
4752 	 * This setting resolves a problem observed on certain Intel PCI
4753 	 * chipsets that cannot handle multiple outstanding DMA operations.
4754 	 * See errata E9_5706A1_65.
4755 	 */
4756 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
4757 	    (BCE_CHIP_ID(sc) != BCE_CHIP_ID_5706_A0) &&
4758 	    !(sc->bce_flags & BCE_PCIX_FLAG))
4759 		val |= BCE_DMA_CONFIG_CNTL_PING_PONG_DMA;
4760 
4761 	REG_WR(sc, BCE_DMA_CONFIG, val);
4762 
4763 	/* Enable the RX_V2P and Context state machines before access. */
4764 	REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
4765 	    BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
4766 	    BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
4767 	    BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
4768 
4769 	/* Initialize context mapping and zero out the quick contexts. */
4770 	if ((rc = bce_init_ctx(sc)) != 0)
4771 		goto bce_chipinit_exit;
4772 
4773 	/* Initialize the on-boards CPUs */
4774 	bce_init_cpus(sc);
4775 
4776 	/* Enable management frames (NC-SI) to flow to the MCP. */
4777 	if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
4778 		val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) | BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
4779 		REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
4780 	}
4781 
4782 	/* Prepare NVRAM for access. */
4783 	if ((rc = bce_init_nvram(sc)) != 0)
4784 		goto bce_chipinit_exit;
4785 
4786 	/* Set the kernel bypass block size */
4787 	val = REG_RD(sc, BCE_MQ_CONFIG);
4788 	val &= ~BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE;
4789 	val |= BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
4790 
4791 	/* Enable bins used on the 5709. */
4792 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4793 	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4794 		val |= BCE_MQ_CONFIG_BIN_MQ_MODE;
4795 		if (BCE_CHIP_ID(sc) == BCE_CHIP_ID_5709_A1)
4796 			val |= BCE_MQ_CONFIG_HALT_DIS;
4797 	}
4798 
4799 	REG_WR(sc, BCE_MQ_CONFIG, val);
4800 
4801 	val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
4802 	REG_WR(sc, BCE_MQ_KNL_BYP_WIND_START, val);
4803 	REG_WR(sc, BCE_MQ_KNL_WIND_END, val);
4804 
4805 	/* Set the page size and clear the RV2P processor stall bits. */
4806 	val = (BCM_PAGE_BITS - 8) << 24;
4807 	REG_WR(sc, BCE_RV2P_CONFIG, val);
4808 
4809 	/* Configure page size. */
4810 	val = REG_RD(sc, BCE_TBDR_CONFIG);
4811 	val &= ~BCE_TBDR_CONFIG_PAGE_SIZE;
4812 	val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
4813 	REG_WR(sc, BCE_TBDR_CONFIG, val);
4814 
4815 	/* Set the perfect match control register to default. */
4816 	REG_WR_IND(sc, BCE_RXP_PM_CTRL, 0);
4817 
4818 bce_chipinit_exit:
4819 	DBEXIT(BCE_VERBOSE_RESET);
4820 
4821 	return(rc);
4822 }
4823 
4824 
4825 /****************************************************************************/
4826 /* Initialize the controller in preparation to send/receive traffic.        */
4827 /*                                                                          */
4828 /* Returns:                                                                 */
4829 /*   0 for success, positive value for failure.                             */
4830 /****************************************************************************/
4831 static int
4832 bce_blockinit(struct bce_softc *sc)
4833 {
4834 	u32 reg, val;
4835 	int rc = 0;
4836 
4837 	DBENTER(BCE_VERBOSE_RESET);
4838 
4839 	/* Load the hardware default MAC address. */
4840 	bce_set_mac_addr(sc);
4841 
4842 	/* Set the Ethernet backoff seed value */
4843 	val = sc->eaddr[0]         + (sc->eaddr[1] << 8) +
4844 	      (sc->eaddr[2] << 16) + (sc->eaddr[3]     ) +
4845 	      (sc->eaddr[4] << 8)  + (sc->eaddr[5] << 16);
4846 	REG_WR(sc, BCE_EMAC_BACKOFF_SEED, val);
4847 
4848 	sc->last_status_idx = 0;
4849 	sc->rx_mode = BCE_EMAC_RX_MODE_SORT_MODE;
4850 
4851 	/* Set up link change interrupt generation. */
4852 	REG_WR(sc, BCE_EMAC_ATTENTION_ENA, BCE_EMAC_ATTENTION_ENA_LINK);
4853 
4854 	/* Program the physical address of the status block. */
4855 	REG_WR(sc, BCE_HC_STATUS_ADDR_L,
4856 	    BCE_ADDR_LO(sc->status_block_paddr));
4857 	REG_WR(sc, BCE_HC_STATUS_ADDR_H,
4858 	    BCE_ADDR_HI(sc->status_block_paddr));
4859 
4860 	/* Program the physical address of the statistics block. */
4861 	REG_WR(sc, BCE_HC_STATISTICS_ADDR_L,
4862 	    BCE_ADDR_LO(sc->stats_block_paddr));
4863 	REG_WR(sc, BCE_HC_STATISTICS_ADDR_H,
4864 	    BCE_ADDR_HI(sc->stats_block_paddr));
4865 
4866 	/* Program various host coalescing parameters. */
4867 	REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
4868 	    (sc->bce_tx_quick_cons_trip_int << 16) | sc->bce_tx_quick_cons_trip);
4869 	REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
4870 	    (sc->bce_rx_quick_cons_trip_int << 16) | sc->bce_rx_quick_cons_trip);
4871 	REG_WR(sc, BCE_HC_COMP_PROD_TRIP,
4872 	    (sc->bce_comp_prod_trip_int << 16) | sc->bce_comp_prod_trip);
4873 	REG_WR(sc, BCE_HC_TX_TICKS,
4874 	    (sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
4875 	REG_WR(sc, BCE_HC_RX_TICKS,
4876 	    (sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
4877 	REG_WR(sc, BCE_HC_COM_TICKS,
4878 	    (sc->bce_com_ticks_int << 16) | sc->bce_com_ticks);
4879 	REG_WR(sc, BCE_HC_CMD_TICKS,
4880 	    (sc->bce_cmd_ticks_int << 16) | sc->bce_cmd_ticks);
4881 	REG_WR(sc, BCE_HC_STATS_TICKS,
4882 	    (sc->bce_stats_ticks & 0xffff00));
4883 	REG_WR(sc, BCE_HC_STAT_COLLECT_TICKS, 0xbb8);  /* 3ms */
4884 
4885 	/* Configure the Host Coalescing block. */
4886 	val = BCE_HC_CONFIG_RX_TMR_MODE | BCE_HC_CONFIG_TX_TMR_MODE |
4887 	    BCE_HC_CONFIG_COLLECT_STATS;
4888 
4889 #if 0
4890 	/* ToDo: Add MSI-X support. */
4891 	if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
4892 		u32 base = ((BCE_TX_VEC - 1) * BCE_HC_SB_CONFIG_SIZE) +
4893 		    BCE_HC_SB_CONFIG_1;
4894 
4895 		REG_WR(sc, BCE_HC_MSIX_BIT_VECTOR, BCE_HC_MSIX_BIT_VECTOR_VAL);
4896 
4897 		REG_WR(sc, base, BCE_HC_SB_CONFIG_1_TX_TMR_MODE |
4898 		    BCE_HC_SB_CONFIG_1_ONE_SHOT);
4899 
4900 		REG_WR(sc, base + BCE_HC_TX_QUICK_CONS_TRIP_OFF,
4901 		    (sc->tx_quick_cons_trip_int << 16) |
4902 		     sc->tx_quick_cons_trip);
4903 
4904 		REG_WR(sc, base + BCE_HC_TX_TICKS_OFF,
4905 		    (sc->tx_ticks_int << 16) | sc->tx_ticks);
4906 
4907 		val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
4908 	}
4909 
4910 	/*
4911 	 * Tell the HC block to automatically set the
4912 	 * INT_MASK bit after an MSI/MSI-X interrupt
4913 	 * is generated so the driver doesn't have to.
4914 	 */
4915 	if (sc->bce_flags & BCE_ONE_SHOT_MSI_FLAG)
4916 		val |= BCE_HC_CONFIG_ONE_SHOT;
4917 
4918 	/* Set the MSI-X status blocks to 128 byte boundaries. */
4919 	if (sc->bce_flags & BCE_USING_MSIX_FLAG)
4920 		val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
4921 #endif
4922 
4923 	REG_WR(sc, BCE_HC_CONFIG, val);
4924 
4925 	/* Clear the internal statistics counters. */
4926 	REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
4927 
4928 	/* Verify that bootcode is running. */
4929 	reg = bce_shmem_rd(sc, BCE_DEV_INFO_SIGNATURE);
4930 
4931 	DBRUNIF(DB_RANDOMTRUE(bootcode_running_failure_sim_control),
4932 	    BCE_PRINTF("%s(%d): Simulating bootcode failure.\n",
4933 	    __FILE__, __LINE__);
4934 	    reg = 0);
4935 
4936 	if ((reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
4937 	    BCE_DEV_INFO_SIGNATURE_MAGIC) {
4938 		BCE_PRINTF("%s(%d): Bootcode not running! Found: 0x%08X, "
4939 		    "Expected: 08%08X\n", __FILE__, __LINE__,
4940 		    (reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK),
4941 		    BCE_DEV_INFO_SIGNATURE_MAGIC);
4942 		rc = ENODEV;
4943 		goto bce_blockinit_exit;
4944 	}
4945 
4946 	/* Enable DMA */
4947 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4948 	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4949 		val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
4950 		val |= BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
4951 		REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
4952 	}
4953 
4954 	/* Allow bootcode to apply additional fixes before enabling MAC. */
4955 	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 |
4956 	    BCE_DRV_MSG_CODE_RESET);
4957 
4958 	/* Enable link state change interrupt generation. */
4959 	REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
4960 
4961 	/* Enable the RXP. */
4962 	bce_start_rxp_cpu(sc);
4963 
4964 	/* Disable management frames (NC-SI) from flowing to the MCP. */
4965 	if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
4966 		val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) &
4967 		    ~BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
4968 		REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
4969 	}
4970 
4971 	/* Enable all remaining blocks in the MAC. */
4972 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4973 	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
4974 		REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
4975 		    BCE_MISC_ENABLE_DEFAULT_XI);
4976 	else
4977 		REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
4978 		    BCE_MISC_ENABLE_DEFAULT);
4979 
4980 	REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
4981 	DELAY(20);
4982 
4983 	/* Save the current host coalescing block settings. */
4984 	sc->hc_command = REG_RD(sc, BCE_HC_COMMAND);
4985 
4986 bce_blockinit_exit:
4987 	DBEXIT(BCE_VERBOSE_RESET);
4988 
4989 	return (rc);
4990 }
4991 
4992 
4993 /****************************************************************************/
4994 /* Encapsulate an mbuf into the rx_bd chain.                                */
4995 /*                                                                          */
4996 /* Returns:                                                                 */
4997 /*   0 for success, positive value for failure.                             */
4998 /****************************************************************************/
4999 static int
5000 bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
5001     u16 *chain_prod, u32 *prod_bseq)
5002 {
5003 	bus_dmamap_t map;
5004 	bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
5005 	struct mbuf *m_new = NULL;
5006 	struct rx_bd *rxbd;
5007 	int nsegs, error, rc = 0;
5008 #ifdef BCE_DEBUG
5009 	u16 debug_chain_prod = *chain_prod;
5010 #endif
5011 
5012 	DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5013 
5014 	/* Make sure the inputs are valid. */
5015 	DBRUNIF((*chain_prod > MAX_RX_BD),
5016 	    BCE_PRINTF("%s(%d): RX producer out of range: "
5017 	    "0x%04X > 0x%04X\n", __FILE__, __LINE__,
5018 	    *chain_prod, (u16) MAX_RX_BD));
5019 
5020 	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
5021 	    "chain_prod = 0x%04X, prod_bseq = 0x%08X\n", __FUNCTION__,
5022 	    *prod, *chain_prod, *prod_bseq);
5023 
5024 	/* Update some debug statistic counters */
5025 	DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
5026 	    sc->rx_low_watermark = sc->free_rx_bd);
5027 	DBRUNIF((sc->free_rx_bd == sc->max_rx_bd),
5028 	    sc->rx_empty_count++);
5029 
5030 	/* Check whether this is a new mbuf allocation. */
5031 	if (m == NULL) {
5032 
5033 		/* Simulate an mbuf allocation failure. */
5034 		DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
5035 		    sc->mbuf_alloc_failed_count++;
5036 		    sc->mbuf_alloc_failed_sim_count++;
5037 		    rc = ENOBUFS;
5038 		    goto bce_get_rx_buf_exit);
5039 
5040 		/* This is a new mbuf allocation. */
5041 #ifdef BCE_JUMBO_HDRSPLIT
5042 		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
5043 #else
5044 		m_new = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR,
5045 		    sc->rx_bd_mbuf_alloc_size);
5046 #endif
5047 
5048 		if (m_new == NULL) {
5049 			sc->mbuf_alloc_failed_count++;
5050 			rc = ENOBUFS;
5051 			goto bce_get_rx_buf_exit;
5052 		}
5053 
5054 		DBRUN(sc->debug_rx_mbuf_alloc++);
5055 	} else {
5056 		/* Reuse an existing mbuf. */
5057 		m_new = m;
5058 	}
5059 
5060 	/* Make sure we have a valid packet header. */
5061 	M_ASSERTPKTHDR(m_new);
5062 
5063 	/* Initialize the mbuf size and pad if necessary for alignment. */
5064 	m_new->m_pkthdr.len = m_new->m_len = sc->rx_bd_mbuf_alloc_size;
5065 	m_adj(m_new, sc->rx_bd_mbuf_align_pad);
5066 
5067 	/* ToDo: Consider calling m_fragment() to test error handling. */
5068 
5069 	/* Map the mbuf cluster into device memory. */
5070 	map = sc->rx_mbuf_map[*chain_prod];
5071 	error = bus_dmamap_load_mbuf_sg(sc->rx_mbuf_tag, map, m_new,
5072 	    segs, &nsegs, BUS_DMA_NOWAIT);
5073 
5074 	/* Handle any mapping errors. */
5075 	if (error) {
5076 		BCE_PRINTF("%s(%d): Error mapping mbuf into RX "
5077 		    "chain (%d)!\n", __FILE__, __LINE__, error);
5078 
5079 		sc->dma_map_addr_rx_failed_count++;
5080 		m_freem(m_new);
5081 
5082 		DBRUN(sc->debug_rx_mbuf_alloc--);
5083 
5084 		rc = ENOBUFS;
5085 		goto bce_get_rx_buf_exit;
5086 	}
5087 
5088 	/* All mbufs must map to a single segment. */
5089 	KASSERT(nsegs == 1, ("%s(): Too many segments returned (%d)!",
5090 	    __FUNCTION__, nsegs));
5091 
5092 	/* Setup the rx_bd for the segment. */
5093 	rxbd = &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
5094 
5095 	rxbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(segs[0].ds_addr));
5096 	rxbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(segs[0].ds_addr));
5097 	rxbd->rx_bd_len       = htole32(segs[0].ds_len);
5098 	rxbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
5099 	*prod_bseq += segs[0].ds_len;
5100 
5101 	/* Save the mbuf and update our counter. */
5102 	sc->rx_mbuf_ptr[*chain_prod] = m_new;
5103 	sc->free_rx_bd -= nsegs;
5104 
5105 	DBRUNMSG(BCE_INSANE_RECV,
5106 	    bce_dump_rx_mbuf_chain(sc, debug_chain_prod, nsegs));
5107 
5108 	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
5109 	    "chain_prod = 0x%04X, prod_bseq = 0x%08X\n",
5110 	    __FUNCTION__, *prod, *chain_prod, *prod_bseq);
5111 
5112 bce_get_rx_buf_exit:
5113 	DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5114 
5115 	return(rc);
5116 }
5117 
5118 
5119 #ifdef BCE_JUMBO_HDRSPLIT
5120 /****************************************************************************/
5121 /* Encapsulate an mbuf cluster into the page chain.                         */
5122 /*                                                                          */
5123 /* Returns:                                                                 */
5124 /*   0 for success, positive value for failure.                             */
5125 /****************************************************************************/
5126 static int
5127 bce_get_pg_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
5128 	u16 *prod_idx)
5129 {
5130 	bus_dmamap_t map;
5131 	bus_addr_t busaddr;
5132 	struct mbuf *m_new = NULL;
5133 	struct rx_bd *pgbd;
5134 	int error, rc = 0;
5135 #ifdef BCE_DEBUG
5136 	u16 debug_prod_idx = *prod_idx;
5137 #endif
5138 
5139 	DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5140 
5141 	/* Make sure the inputs are valid. */
5142 	DBRUNIF((*prod_idx > MAX_PG_BD),
5143 	    BCE_PRINTF("%s(%d): page producer out of range: "
5144 	    "0x%04X > 0x%04X\n", __FILE__, __LINE__,
5145 	    *prod_idx, (u16) MAX_PG_BD));
5146 
5147 	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
5148 	    "chain_prod = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
5149 
5150 	/* Update counters if we've hit a new low or run out of pages. */
5151 	DBRUNIF((sc->free_pg_bd < sc->pg_low_watermark),
5152 	    sc->pg_low_watermark = sc->free_pg_bd);
5153 	DBRUNIF((sc->free_pg_bd == sc->max_pg_bd), sc->pg_empty_count++);
5154 
5155 	/* Check whether this is a new mbuf allocation. */
5156 	if (m == NULL) {
5157 
5158 		/* Simulate an mbuf allocation failure. */
5159 		DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
5160 		    sc->mbuf_alloc_failed_count++;
5161 		    sc->mbuf_alloc_failed_sim_count++;
5162 		    rc = ENOBUFS;
5163 		    goto bce_get_pg_buf_exit);
5164 
5165 		/* This is a new mbuf allocation. */
5166 		m_new = m_getcl(M_DONTWAIT, MT_DATA, 0);
5167 		if (m_new == NULL) {
5168 			sc->mbuf_alloc_failed_count++;
5169 			rc = ENOBUFS;
5170 			goto bce_get_pg_buf_exit;
5171 		}
5172 
5173 		DBRUN(sc->debug_pg_mbuf_alloc++);
5174 	} else {
5175 		/* Reuse an existing mbuf. */
5176 		m_new = m;
5177 		m_new->m_data = m_new->m_ext.ext_buf;
5178 	}
5179 
5180 	m_new->m_len = sc->pg_bd_mbuf_alloc_size;
5181 
5182 	/* ToDo: Consider calling m_fragment() to test error handling. */
5183 
5184 	/* Map the mbuf cluster into device memory. */
5185 	map = sc->pg_mbuf_map[*prod_idx];
5186 	error = bus_dmamap_load(sc->pg_mbuf_tag, map, mtod(m_new, void *),
5187 	    sc->pg_bd_mbuf_alloc_size, bce_dma_map_addr,
5188 	    &busaddr, BUS_DMA_NOWAIT);
5189 
5190 	/* Handle any mapping errors. */
5191 	if (error) {
5192 		BCE_PRINTF("%s(%d): Error mapping mbuf into page chain!\n",
5193 		    __FILE__, __LINE__);
5194 
5195 		m_freem(m_new);
5196 		DBRUN(sc->debug_pg_mbuf_alloc--);
5197 
5198 		rc = ENOBUFS;
5199 		goto bce_get_pg_buf_exit;
5200 	}
5201 
5202 	/* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREREAD) here? */
5203 
5204 	/*
5205 	 * The page chain uses the same rx_bd data structure
5206 	 * as the receive chain but doesn't require a byte sequence (bseq).
5207 	 */
5208 	pgbd = &sc->pg_bd_chain[PG_PAGE(*prod_idx)][PG_IDX(*prod_idx)];
5209 
5210 	pgbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(busaddr));
5211 	pgbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(busaddr));
5212 	pgbd->rx_bd_len       = htole32(sc->pg_bd_mbuf_alloc_size);
5213 	pgbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
5214 
5215 	/* Save the mbuf and update our counter. */
5216 	sc->pg_mbuf_ptr[*prod_idx] = m_new;
5217 	sc->free_pg_bd--;
5218 
5219 	DBRUNMSG(BCE_INSANE_RECV,
5220 	    bce_dump_pg_mbuf_chain(sc, debug_prod_idx, 1));
5221 
5222 	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
5223 	    "prod_idx = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
5224 
5225 bce_get_pg_buf_exit:
5226 	DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5227 
5228 	return(rc);
5229 }
5230 #endif /* BCE_JUMBO_HDRSPLIT */
5231 
5232 
5233 /****************************************************************************/
5234 /* Initialize the TX context memory.                                        */
5235 /*                                                                          */
5236 /* Returns:                                                                 */
5237 /*   Nothing                                                                */
5238 /****************************************************************************/
5239 static void
5240 bce_init_tx_context(struct bce_softc *sc)
5241 {
5242 	u32 val;
5243 
5244 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
5245 
5246 	/* Initialize the context ID for an L2 TX chain. */
5247 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
5248 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
5249 		/* Set the CID type to support an L2 connection. */
5250 		val = BCE_L2CTX_TX_TYPE_TYPE_L2_XI |
5251 		    BCE_L2CTX_TX_TYPE_SIZE_L2_XI;
5252 		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE_XI, val);
5253 		val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2_XI | (8 << 16);
5254 		CTX_WR(sc, GET_CID_ADDR(TX_CID),
5255 		    BCE_L2CTX_TX_CMD_TYPE_XI, val);
5256 
5257 		/* Point the hardware to the first page in the chain. */
5258 		val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
5259 		CTX_WR(sc, GET_CID_ADDR(TX_CID),
5260 		    BCE_L2CTX_TX_TBDR_BHADDR_HI_XI, val);
5261 		val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
5262 		CTX_WR(sc, GET_CID_ADDR(TX_CID),
5263 		    BCE_L2CTX_TX_TBDR_BHADDR_LO_XI, val);
5264 	} else {
5265 		/* Set the CID type to support an L2 connection. */
5266 		val = BCE_L2CTX_TX_TYPE_TYPE_L2 | BCE_L2CTX_TX_TYPE_SIZE_L2;
5267 		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE, val);
5268 		val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2 | (8 << 16);
5269 		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_CMD_TYPE, val);
5270 
5271 		/* Point the hardware to the first page in the chain. */
5272 		val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
5273 		CTX_WR(sc, GET_CID_ADDR(TX_CID),
5274 		    BCE_L2CTX_TX_TBDR_BHADDR_HI, val);
5275 		val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
5276 		CTX_WR(sc, GET_CID_ADDR(TX_CID),
5277 		    BCE_L2CTX_TX_TBDR_BHADDR_LO, val);
5278 	}
5279 
5280 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
5281 }
5282 
5283 
5284 /****************************************************************************/
5285 /* Allocate memory and initialize the TX data structures.                   */
5286 /*                                                                          */
5287 /* Returns:                                                                 */
5288 /*   0 for success, positive value for failure.                             */
5289 /****************************************************************************/
5290 static int
5291 bce_init_tx_chain(struct bce_softc *sc)
5292 {
5293 	struct tx_bd *txbd;
5294 	int i, rc = 0;
5295 
5296 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
5297 
5298 	/* Set the initial TX producer/consumer indices. */
5299 	sc->tx_prod        = 0;
5300 	sc->tx_cons        = 0;
5301 	sc->tx_prod_bseq   = 0;
5302 	sc->used_tx_bd     = 0;
5303 	sc->max_tx_bd      = USABLE_TX_BD;
5304 	DBRUN(sc->tx_hi_watermark = 0);
5305 	DBRUN(sc->tx_full_count = 0);
5306 
5307 	/*
5308 	 * The NetXtreme II supports a linked-list structre called
5309 	 * a Buffer Descriptor Chain (or BD chain).  A BD chain
5310 	 * consists of a series of 1 or more chain pages, each of which
5311 	 * consists of a fixed number of BD entries.
5312 	 * The last BD entry on each page is a pointer to the next page
5313 	 * in the chain, and the last pointer in the BD chain
5314 	 * points back to the beginning of the chain.
5315 	 */
5316 
5317 	/* Set the TX next pointer chain entries. */
5318 	for (i = 0; i < TX_PAGES; i++) {
5319 		int j;
5320 
5321 		txbd = &sc->tx_bd_chain[i][USABLE_TX_BD_PER_PAGE];
5322 
5323 		/* Check if we've reached the last page. */
5324 		if (i == (TX_PAGES - 1))
5325 			j = 0;
5326 		else
5327 			j = i + 1;
5328 
5329 		txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->tx_bd_chain_paddr[j]));
5330 		txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->tx_bd_chain_paddr[j]));
5331 	}
5332 
5333 	bce_init_tx_context(sc);
5334 
5335 	DBRUNMSG(BCE_INSANE_SEND, bce_dump_tx_chain(sc, 0, TOTAL_TX_BD));
5336 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
5337 
5338 	return(rc);
5339 }
5340 
5341 
5342 /****************************************************************************/
5343 /* Free memory and clear the TX data structures.                            */
5344 /*                                                                          */
5345 /* Returns:                                                                 */
5346 /*   Nothing.                                                               */
5347 /****************************************************************************/
5348 static void
5349 bce_free_tx_chain(struct bce_softc *sc)
5350 {
5351 	int i;
5352 
5353 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
5354 
5355 	/* Unmap, unload, and free any mbufs still in the TX mbuf chain. */
5356 	for (i = 0; i < TOTAL_TX_BD; i++) {
5357 		if (sc->tx_mbuf_ptr[i] != NULL) {
5358 			if (sc->tx_mbuf_map[i] != NULL)
5359 				bus_dmamap_sync(sc->tx_mbuf_tag,
5360 				    sc->tx_mbuf_map[i],
5361 				    BUS_DMASYNC_POSTWRITE);
5362 			m_freem(sc->tx_mbuf_ptr[i]);
5363 			sc->tx_mbuf_ptr[i] = NULL;
5364 			DBRUN(sc->debug_tx_mbuf_alloc--);
5365 		}
5366 	}
5367 
5368 	/* Clear each TX chain page. */
5369 	for (i = 0; i < TX_PAGES; i++)
5370 		bzero((char *)sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ);
5371 
5372 	sc->used_tx_bd = 0;
5373 
5374 	/* Check if we lost any mbufs in the process. */
5375 	DBRUNIF((sc->debug_tx_mbuf_alloc),
5376 	    BCE_PRINTF("%s(%d): Memory leak! Lost %d mbufs "
5377 	    "from tx chain!\n",	__FILE__, __LINE__,
5378 	    sc->debug_tx_mbuf_alloc));
5379 
5380 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
5381 }
5382 
5383 
5384 /****************************************************************************/
5385 /* Initialize the RX context memory.                                        */
5386 /*                                                                          */
5387 /* Returns:                                                                 */
5388 /*   Nothing                                                                */
5389 /****************************************************************************/
5390 static void
5391 bce_init_rx_context(struct bce_softc *sc)
5392 {
5393 	u32 val;
5394 
5395 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
5396 
5397 	/* Init the type, size, and BD cache levels for the RX context. */
5398 	val = BCE_L2CTX_RX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE |
5399 	    BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 |
5400 	    (0x02 << BCE_L2CTX_RX_BD_PRE_READ_SHIFT);
5401 
5402 	/*
5403 	 * Set the level for generating pause frames
5404 	 * when the number of available rx_bd's gets
5405 	 * too low (the low watermark) and the level
5406 	 * when pause frames can be stopped (the high
5407 	 * watermark).
5408 	 */
5409 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
5410 	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
5411 		u32 lo_water, hi_water;
5412 
5413 		if (sc->bce_flags & BCE_USING_TX_FLOW_CONTROL) {
5414 			lo_water = BCE_L2CTX_RX_LO_WATER_MARK_DEFAULT;
5415 		} else {
5416 			lo_water = 0;
5417 		}
5418 
5419 		if (lo_water >= USABLE_RX_BD) {
5420 			lo_water = 0;
5421 		}
5422 
5423 		hi_water = USABLE_RX_BD / 4;
5424 
5425 		if (hi_water <= lo_water) {
5426 			lo_water = 0;
5427 		}
5428 
5429 		lo_water /= BCE_L2CTX_RX_LO_WATER_MARK_SCALE;
5430 		hi_water /= BCE_L2CTX_RX_HI_WATER_MARK_SCALE;
5431 
5432 		if (hi_water > 0xf)
5433 			hi_water = 0xf;
5434 		else if (hi_water == 0)
5435 			lo_water = 0;
5436 
5437 		val |= (lo_water << BCE_L2CTX_RX_LO_WATER_MARK_SHIFT) |
5438 		    (hi_water << BCE_L2CTX_RX_HI_WATER_MARK_SHIFT);
5439 	}
5440 
5441 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_CTX_TYPE, val);
5442 
5443 	/* Setup the MQ BIN mapping for l2_ctx_host_bseq. */
5444 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
5445 	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
5446 		val = REG_RD(sc, BCE_MQ_MAP_L2_5);
5447 		REG_WR(sc, BCE_MQ_MAP_L2_5, val | BCE_MQ_MAP_L2_5_ARM);
5448 	}
5449 
5450 	/* Point the hardware to the first page in the chain. */
5451 	val = BCE_ADDR_HI(sc->rx_bd_chain_paddr[0]);
5452 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_HI, val);
5453 	val = BCE_ADDR_LO(sc->rx_bd_chain_paddr[0]);
5454 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_LO, val);
5455 
5456 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
5457 }
5458 
5459 
5460 /****************************************************************************/
5461 /* Allocate memory and initialize the RX data structures.                   */
5462 /*                                                                          */
5463 /* Returns:                                                                 */
5464 /*   0 for success, positive value for failure.                             */
5465 /****************************************************************************/
5466 static int
5467 bce_init_rx_chain(struct bce_softc *sc)
5468 {
5469 	struct rx_bd *rxbd;
5470 	int i, rc = 0;
5471 
5472 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5473 	    BCE_VERBOSE_CTX);
5474 
5475 	/* Initialize the RX producer and consumer indices. */
5476 	sc->rx_prod        = 0;
5477 	sc->rx_cons        = 0;
5478 	sc->rx_prod_bseq   = 0;
5479 	sc->free_rx_bd     = USABLE_RX_BD;
5480 	sc->max_rx_bd      = USABLE_RX_BD;
5481 
5482 	/* Initialize the RX next pointer chain entries. */
5483 	for (i = 0; i < RX_PAGES; i++) {
5484 		int j;
5485 
5486 		rxbd = &sc->rx_bd_chain[i][USABLE_RX_BD_PER_PAGE];
5487 
5488 		/* Check if we've reached the last page. */
5489 		if (i == (RX_PAGES - 1))
5490 			j = 0;
5491 		else
5492 			j = i + 1;
5493 
5494 		/* Setup the chain page pointers. */
5495 		rxbd->rx_bd_haddr_hi =
5496 		    htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j]));
5497 		rxbd->rx_bd_haddr_lo =
5498 		    htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j]));
5499 	}
5500 
5501 	/* Fill up the RX chain. */
5502 	bce_fill_rx_chain(sc);
5503 
5504 	DBRUN(sc->rx_low_watermark = USABLE_RX_BD);
5505 	DBRUN(sc->rx_empty_count = 0);
5506 	for (i = 0; i < RX_PAGES; i++) {
5507 		bus_dmamap_sync(sc->rx_bd_chain_tag, sc->rx_bd_chain_map[i],
5508 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
5509 	}
5510 
5511 	bce_init_rx_context(sc);
5512 
5513 	DBRUNMSG(BCE_EXTREME_RECV, bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD));
5514 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5515 	    BCE_VERBOSE_CTX);
5516 
5517 	/* ToDo: Are there possible failure modes here? */
5518 
5519 	return(rc);
5520 }
5521 
5522 
5523 /****************************************************************************/
5524 /* Add mbufs to the RX chain until its full or an mbuf allocation error     */
5525 /* occurs.                                                                  */
5526 /*                                                                          */
5527 /* Returns:                                                                 */
5528 /*   Nothing                                                                */
5529 /****************************************************************************/
5530 static void
5531 bce_fill_rx_chain(struct bce_softc *sc)
5532 {
5533 	u16 prod, prod_idx;
5534 	u32 prod_bseq;
5535 
5536 	DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5537 	    BCE_VERBOSE_CTX);
5538 
5539 	/* Get the RX chain producer indices. */
5540 	prod      = sc->rx_prod;
5541 	prod_bseq = sc->rx_prod_bseq;
5542 
5543 	/* Keep filling the RX chain until it's full. */
5544 	while (sc->free_rx_bd > 0) {
5545 		prod_idx = RX_CHAIN_IDX(prod);
5546 		if (bce_get_rx_buf(sc, NULL, &prod, &prod_idx, &prod_bseq)) {
5547 			/* Bail out if we can't add an mbuf to the chain. */
5548 			break;
5549 		}
5550 		prod = NEXT_RX_BD(prod);
5551 	}
5552 
5553 	/* Save the RX chain producer indices. */
5554 	sc->rx_prod      = prod;
5555 	sc->rx_prod_bseq = prod_bseq;
5556 
5557 	/* We should never end up pointing to a next page pointer. */
5558 	DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
5559 	    BCE_PRINTF("%s(): Invalid rx_prod value: 0x%04X\n",
5560 	    __FUNCTION__, sc->rx_prod));
5561 
5562 	/* Write the mailbox and tell the chip about the waiting rx_bd's. */
5563 	REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) +
5564 	    BCE_L2MQ_RX_HOST_BDIDX, sc->rx_prod);
5565 	REG_WR(sc, MB_GET_CID_ADDR(RX_CID) +
5566 	    BCE_L2MQ_RX_HOST_BSEQ, sc->rx_prod_bseq);
5567 
5568 	DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5569 	    BCE_VERBOSE_CTX);
5570 }
5571 
5572 
5573 /****************************************************************************/
5574 /* Free memory and clear the RX data structures.                            */
5575 /*                                                                          */
5576 /* Returns:                                                                 */
5577 /*   Nothing.                                                               */
5578 /****************************************************************************/
5579 static void
5580 bce_free_rx_chain(struct bce_softc *sc)
5581 {
5582 	int i;
5583 
5584 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5585 
5586 	/* Free any mbufs still in the RX mbuf chain. */
5587 	for (i = 0; i < TOTAL_RX_BD; i++) {
5588 		if (sc->rx_mbuf_ptr[i] != NULL) {
5589 			if (sc->rx_mbuf_map[i] != NULL)
5590 				bus_dmamap_sync(sc->rx_mbuf_tag,
5591 				    sc->rx_mbuf_map[i],
5592 				    BUS_DMASYNC_POSTREAD);
5593 			m_freem(sc->rx_mbuf_ptr[i]);
5594 			sc->rx_mbuf_ptr[i] = NULL;
5595 			DBRUN(sc->debug_rx_mbuf_alloc--);
5596 		}
5597 	}
5598 
5599 	/* Clear each RX chain page. */
5600 	for (i = 0; i < RX_PAGES; i++)
5601 		if (sc->rx_bd_chain[i] != NULL) {
5602 			bzero((char *)sc->rx_bd_chain[i],
5603 			    BCE_RX_CHAIN_PAGE_SZ);
5604 		}
5605 
5606 	sc->free_rx_bd = sc->max_rx_bd;
5607 
5608 	/* Check if we lost any mbufs in the process. */
5609 	DBRUNIF((sc->debug_rx_mbuf_alloc),
5610 	    BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from rx chain!\n",
5611 	    __FUNCTION__, sc->debug_rx_mbuf_alloc));
5612 
5613 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5614 }
5615 
5616 
5617 #ifdef BCE_JUMBO_HDRSPLIT
5618 /****************************************************************************/
5619 /* Allocate memory and initialize the page data structures.                 */
5620 /* Assumes that bce_init_rx_chain() has not already been called.            */
5621 /*                                                                          */
5622 /* Returns:                                                                 */
5623 /*   0 for success, positive value for failure.                             */
5624 /****************************************************************************/
5625 static int
5626 bce_init_pg_chain(struct bce_softc *sc)
5627 {
5628 	struct rx_bd *pgbd;
5629 	int i, rc = 0;
5630 	u32 val;
5631 
5632 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5633 		BCE_VERBOSE_CTX);
5634 
5635 	/* Initialize the page producer and consumer indices. */
5636 	sc->pg_prod        = 0;
5637 	sc->pg_cons        = 0;
5638 	sc->free_pg_bd     = USABLE_PG_BD;
5639 	sc->max_pg_bd      = USABLE_PG_BD;
5640 	DBRUN(sc->pg_low_watermark = sc->max_pg_bd);
5641 	DBRUN(sc->pg_empty_count = 0);
5642 
5643 	/* Initialize the page next pointer chain entries. */
5644 	for (i = 0; i < PG_PAGES; i++) {
5645 		int j;
5646 
5647 		pgbd = &sc->pg_bd_chain[i][USABLE_PG_BD_PER_PAGE];
5648 
5649 		/* Check if we've reached the last page. */
5650 		if (i == (PG_PAGES - 1))
5651 			j = 0;
5652 		else
5653 			j = i + 1;
5654 
5655 		/* Setup the chain page pointers. */
5656 		pgbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->pg_bd_chain_paddr[j]));
5657 		pgbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->pg_bd_chain_paddr[j]));
5658 	}
5659 
5660 	/* Setup the MQ BIN mapping for host_pg_bidx. */
5661 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)	||
5662 		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
5663 		REG_WR(sc, BCE_MQ_MAP_L2_3, BCE_MQ_MAP_L2_3_DEFAULT);
5664 
5665 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, 0);
5666 
5667 	/* Configure the rx_bd and page chain mbuf cluster size. */
5668 	val = (sc->rx_bd_mbuf_data_len << 16) | sc->pg_bd_mbuf_alloc_size;
5669 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, val);
5670 
5671 	/* Configure the context reserved for jumbo support. */
5672 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_RBDC_KEY,
5673 		BCE_L2CTX_RX_RBDC_JUMBO_KEY);
5674 
5675 	/* Point the hardware to the first page in the page chain. */
5676 	val = BCE_ADDR_HI(sc->pg_bd_chain_paddr[0]);
5677 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_HI, val);
5678 	val = BCE_ADDR_LO(sc->pg_bd_chain_paddr[0]);
5679 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_LO, val);
5680 
5681 	/* Fill up the page chain. */
5682 	bce_fill_pg_chain(sc);
5683 
5684 	for (i = 0; i < PG_PAGES; i++) {
5685 		bus_dmamap_sync(sc->pg_bd_chain_tag, sc->pg_bd_chain_map[i],
5686 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
5687 	}
5688 
5689 	DBRUNMSG(BCE_EXTREME_RECV, bce_dump_pg_chain(sc, 0, TOTAL_PG_BD));
5690 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5691 		BCE_VERBOSE_CTX);
5692 	return(rc);
5693 }
5694 
5695 
5696 /****************************************************************************/
5697 /* Add mbufs to the page chain until its full or an mbuf allocation error   */
5698 /* occurs.                                                                  */
5699 /*                                                                          */
5700 /* Returns:                                                                 */
5701 /*   Nothing                                                                */
5702 /****************************************************************************/
5703 static void
5704 bce_fill_pg_chain(struct bce_softc *sc)
5705 {
5706 	u16 prod, prod_idx;
5707 
5708 	DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5709 	    BCE_VERBOSE_CTX);
5710 
5711 	/* Get the page chain prodcuer index. */
5712 	prod = sc->pg_prod;
5713 
5714 	/* Keep filling the page chain until it's full. */
5715 	while (sc->free_pg_bd > 0) {
5716 		prod_idx = PG_CHAIN_IDX(prod);
5717 		if (bce_get_pg_buf(sc, NULL, &prod, &prod_idx)) {
5718 			/* Bail out if we can't add an mbuf to the chain. */
5719 			break;
5720 		}
5721 		prod = NEXT_PG_BD(prod);
5722 	}
5723 
5724 	/* Save the page chain producer index. */
5725 	sc->pg_prod = prod;
5726 
5727 	DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
5728 	    BCE_PRINTF("%s(): Invalid pg_prod value: 0x%04X\n",
5729 	    __FUNCTION__, sc->pg_prod));
5730 
5731 	/*
5732 	 * Write the mailbox and tell the chip about
5733 	 * the new rx_bd's in the page chain.
5734 	 */
5735 	REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) +
5736 	    BCE_L2MQ_RX_HOST_PG_BDIDX, sc->pg_prod);
5737 
5738 	DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5739 	    BCE_VERBOSE_CTX);
5740 }
5741 
5742 
5743 /****************************************************************************/
5744 /* Free memory and clear the RX data structures.                            */
5745 /*                                                                          */
5746 /* Returns:                                                                 */
5747 /*   Nothing.                                                               */
5748 /****************************************************************************/
5749 static void
5750 bce_free_pg_chain(struct bce_softc *sc)
5751 {
5752 	int i;
5753 
5754 	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5755 
5756 	/* Free any mbufs still in the mbuf page chain. */
5757 	for (i = 0; i < TOTAL_PG_BD; i++) {
5758 		if (sc->pg_mbuf_ptr[i] != NULL) {
5759 			if (sc->pg_mbuf_map[i] != NULL)
5760 				bus_dmamap_sync(sc->pg_mbuf_tag,
5761 				    sc->pg_mbuf_map[i],
5762 				    BUS_DMASYNC_POSTREAD);
5763 			m_freem(sc->pg_mbuf_ptr[i]);
5764 			sc->pg_mbuf_ptr[i] = NULL;
5765 			DBRUN(sc->debug_pg_mbuf_alloc--);
5766 		}
5767 	}
5768 
5769 	/* Clear each page chain pages. */
5770 	for (i = 0; i < PG_PAGES; i++)
5771 		bzero((char *)sc->pg_bd_chain[i], BCE_PG_CHAIN_PAGE_SZ);
5772 
5773 	sc->free_pg_bd = sc->max_pg_bd;
5774 
5775 	/* Check if we lost any mbufs in the process. */
5776 	DBRUNIF((sc->debug_pg_mbuf_alloc),
5777 	    BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from page chain!\n",
5778 	    __FUNCTION__, sc->debug_pg_mbuf_alloc));
5779 
5780 	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5781 }
5782 #endif /* BCE_JUMBO_HDRSPLIT */
5783 
5784 
5785 /****************************************************************************/
5786 /* Set media options.                                                       */
5787 /*                                                                          */
5788 /* Returns:                                                                 */
5789 /*   0 for success, positive value for failure.                             */
5790 /****************************************************************************/
5791 static int
5792 bce_ifmedia_upd(struct ifnet *ifp)
5793 {
5794 	struct bce_softc *sc = ifp->if_softc;
5795 	int error;
5796 
5797 	DBENTER(BCE_VERBOSE);
5798 
5799 	BCE_LOCK(sc);
5800 	error = bce_ifmedia_upd_locked(ifp);
5801 	BCE_UNLOCK(sc);
5802 
5803 	DBEXIT(BCE_VERBOSE);
5804 	return (error);
5805 }
5806 
5807 
5808 /****************************************************************************/
5809 /* Set media options.                                                       */
5810 /*                                                                          */
5811 /* Returns:                                                                 */
5812 /*   Nothing.                                                               */
5813 /****************************************************************************/
5814 static int
5815 bce_ifmedia_upd_locked(struct ifnet *ifp)
5816 {
5817 	struct bce_softc *sc = ifp->if_softc;
5818 	struct mii_data *mii;
5819 	int error;
5820 
5821 	DBENTER(BCE_VERBOSE_PHY);
5822 
5823 	error = 0;
5824 	BCE_LOCK_ASSERT(sc);
5825 
5826 	mii = device_get_softc(sc->bce_miibus);
5827 
5828 	/* Make sure the MII bus has been enumerated. */
5829 	if (mii) {
5830 		sc->bce_link_up = FALSE;
5831 		if (mii->mii_instance) {
5832 			struct mii_softc *miisc;
5833 
5834 			LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
5835 			    mii_phy_reset(miisc);
5836 		}
5837 		error = mii_mediachg(mii);
5838 	}
5839 
5840 	DBEXIT(BCE_VERBOSE_PHY);
5841 	return (error);
5842 }
5843 
5844 
5845 /****************************************************************************/
5846 /* Reports current media status.                                            */
5847 /*                                                                          */
5848 /* Returns:                                                                 */
5849 /*   Nothing.                                                               */
5850 /****************************************************************************/
5851 static void
5852 bce_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
5853 {
5854 	struct bce_softc *sc = ifp->if_softc;
5855 	struct mii_data *mii;
5856 
5857 	DBENTER(BCE_VERBOSE_PHY);
5858 
5859 	BCE_LOCK(sc);
5860 
5861 	if ((ifp->if_flags & IFF_UP) == 0) {
5862 		BCE_UNLOCK(sc);
5863 		return;
5864 	}
5865 	mii = device_get_softc(sc->bce_miibus);
5866 
5867 	mii_pollstat(mii);
5868 	ifmr->ifm_active = mii->mii_media_active;
5869 	ifmr->ifm_status = mii->mii_media_status;
5870 
5871 	BCE_UNLOCK(sc);
5872 
5873 	DBEXIT(BCE_VERBOSE_PHY);
5874 }
5875 
5876 
5877 /****************************************************************************/
5878 /* Handles PHY generated interrupt events.                                  */
5879 /*                                                                          */
5880 /* Returns:                                                                 */
5881 /*   Nothing.                                                               */
5882 /****************************************************************************/
5883 static void
5884 bce_phy_intr(struct bce_softc *sc)
5885 {
5886 	u32 new_link_state, old_link_state;
5887 
5888 	DBENTER(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
5889 
5890 	DBRUN(sc->phy_interrupts++);
5891 
5892 	new_link_state = sc->status_block->status_attn_bits &
5893 	    STATUS_ATTN_BITS_LINK_STATE;
5894 	old_link_state = sc->status_block->status_attn_bits_ack &
5895 	    STATUS_ATTN_BITS_LINK_STATE;
5896 
5897 	/* Handle any changes if the link state has changed. */
5898 	if (new_link_state != old_link_state) {
5899 
5900 		/* Update the status_attn_bits_ack field. */
5901 		if (new_link_state) {
5902 			REG_WR(sc, BCE_PCICFG_STATUS_BIT_SET_CMD,
5903 			    STATUS_ATTN_BITS_LINK_STATE);
5904 			DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now UP.\n",
5905 			    __FUNCTION__);
5906 		}
5907 		else {
5908 			REG_WR(sc, BCE_PCICFG_STATUS_BIT_CLEAR_CMD,
5909 			    STATUS_ATTN_BITS_LINK_STATE);
5910 			DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now DOWN.\n",
5911 			    __FUNCTION__);
5912 		}
5913 
5914 		/*
5915 		 * Assume link is down and allow
5916 		 * tick routine to update the state
5917 		 * based on the actual media state.
5918 		 */
5919 		sc->bce_link_up = FALSE;
5920 		callout_stop(&sc->bce_tick_callout);
5921 		bce_tick(sc);
5922 	}
5923 
5924 	/* Acknowledge the link change interrupt. */
5925 	REG_WR(sc, BCE_EMAC_STATUS, BCE_EMAC_STATUS_LINK_CHANGE);
5926 
5927 	DBEXIT(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
5928 }
5929 
5930 
5931 /****************************************************************************/
5932 /* Reads the receive consumer value from the status block (skipping over    */
5933 /* chain page pointer if necessary).                                        */
5934 /*                                                                          */
5935 /* Returns:                                                                 */
5936 /*   hw_cons                                                                */
5937 /****************************************************************************/
5938 static inline u16
5939 bce_get_hw_rx_cons(struct bce_softc *sc)
5940 {
5941 	u16 hw_cons;
5942 
5943 	rmb();
5944 	hw_cons = sc->status_block->status_rx_quick_consumer_index0;
5945 	if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
5946 		hw_cons++;
5947 
5948 	return hw_cons;
5949 }
5950 
5951 /****************************************************************************/
5952 /* Handles received frame interrupt events.                                 */
5953 /*                                                                          */
5954 /* Returns:                                                                 */
5955 /*   Nothing.                                                               */
5956 /****************************************************************************/
5957 static void
5958 bce_rx_intr(struct bce_softc *sc)
5959 {
5960 	struct ifnet *ifp = sc->bce_ifp;
5961 	struct l2_fhdr *l2fhdr;
5962 	struct ether_vlan_header *vh;
5963 	unsigned int pkt_len;
5964 	u16 sw_rx_cons, sw_rx_cons_idx, hw_rx_cons;
5965 	u32 status;
5966 #ifdef BCE_JUMBO_HDRSPLIT
5967 	unsigned int rem_len;
5968 	u16 sw_pg_cons, sw_pg_cons_idx;
5969 #endif
5970 
5971 	DBENTER(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
5972 	DBRUN(sc->interrupts_rx++);
5973 	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): rx_prod = 0x%04X, "
5974 	    "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
5975 	    __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
5976 
5977 	/* Prepare the RX chain pages to be accessed by the host CPU. */
5978 	for (int i = 0; i < RX_PAGES; i++)
5979 		bus_dmamap_sync(sc->rx_bd_chain_tag,
5980 		    sc->rx_bd_chain_map[i], BUS_DMASYNC_POSTREAD);
5981 
5982 #ifdef BCE_JUMBO_HDRSPLIT
5983 	/* Prepare the page chain pages to be accessed by the host CPU. */
5984 	for (int i = 0; i < PG_PAGES; i++)
5985 		bus_dmamap_sync(sc->pg_bd_chain_tag,
5986 		    sc->pg_bd_chain_map[i], BUS_DMASYNC_POSTREAD);
5987 #endif
5988 
5989 	/* Get the hardware's view of the RX consumer index. */
5990 	hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
5991 
5992 	/* Get working copies of the driver's view of the consumer indices. */
5993 	sw_rx_cons = sc->rx_cons;
5994 
5995 #ifdef BCE_JUMBO_HDRSPLIT
5996 	sw_pg_cons = sc->pg_cons;
5997 #endif
5998 
5999 	/* Update some debug statistics counters */
6000 	DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
6001 	    sc->rx_low_watermark = sc->free_rx_bd);
6002 	DBRUNIF((sc->free_rx_bd == sc->max_rx_bd),
6003 	    sc->rx_empty_count++);
6004 
6005 	/* Scan through the receive chain as long as there is work to do */
6006 	/* ToDo: Consider setting a limit on the number of packets processed. */
6007 	rmb();
6008 	while (sw_rx_cons != hw_rx_cons) {
6009 		struct mbuf *m0;
6010 
6011 		/* Convert the producer/consumer indices to an actual rx_bd index. */
6012 		sw_rx_cons_idx = RX_CHAIN_IDX(sw_rx_cons);
6013 
6014 		/* Unmap the mbuf from DMA space. */
6015 		bus_dmamap_sync(sc->rx_mbuf_tag,
6016 		    sc->rx_mbuf_map[sw_rx_cons_idx],
6017 		    BUS_DMASYNC_POSTREAD);
6018 		bus_dmamap_unload(sc->rx_mbuf_tag,
6019 		    sc->rx_mbuf_map[sw_rx_cons_idx]);
6020 
6021 		/* Remove the mbuf from the RX chain. */
6022 		m0 = sc->rx_mbuf_ptr[sw_rx_cons_idx];
6023 		sc->rx_mbuf_ptr[sw_rx_cons_idx] = NULL;
6024 		DBRUN(sc->debug_rx_mbuf_alloc--);
6025 		sc->free_rx_bd++;
6026 
6027 		if(m0 == NULL) {
6028 			DBPRINT(sc, BCE_EXTREME_RECV,
6029 			    "%s(): Oops! Empty mbuf pointer "
6030 			    "found in sc->rx_mbuf_ptr[0x%04X]!\n",
6031 			    __FUNCTION__, sw_rx_cons_idx);
6032 			goto bce_rx_int_next_rx;
6033 		}
6034 
6035 		/*
6036  		 * Frames received on the NetXteme II are prepended
6037  		 * with an l2_fhdr structure which provides status
6038  		 * information about the received frame (including
6039  		 * VLAN tags and checksum info).  The frames are
6040 		 * also automatically adjusted to align the IP
6041  		 * header (i.e. two null bytes are inserted before
6042  		 * the Ethernet	header).  As a result the data
6043  		 * DMA'd by the controller into	the mbuf looks
6044 		 * like this:
6045 		 *
6046 		 * +---------+-----+---------------------+-----+
6047 		 * | l2_fhdr | pad | packet data         | FCS |
6048 		 * +---------+-----+---------------------+-----+
6049 		 *
6050  		 * The l2_fhdr needs to be checked and skipped and
6051  		 * the FCS needs to be stripped before sending the
6052 		 * packet up the stack.
6053 		 */
6054 		l2fhdr  = mtod(m0, struct l2_fhdr *);
6055 
6056 		/* Get the packet data + FCS length and the status. */
6057 		pkt_len = l2fhdr->l2_fhdr_pkt_len;
6058 		status  = l2fhdr->l2_fhdr_status;
6059 
6060 		/*
6061 		 * Skip over the l2_fhdr and pad, resulting in the
6062 		 * following data in the mbuf:
6063 		 * +---------------------+-----+
6064 		 * | packet data         | FCS |
6065 		 * +---------------------+-----+
6066 		 */
6067 		m_adj(m0, sizeof(struct l2_fhdr) + ETHER_ALIGN);
6068 
6069 #ifdef BCE_JUMBO_HDRSPLIT
6070 		/*
6071 		 * Check whether the received frame fits in a single
6072 		 * mbuf or not (i.e. packet data + FCS <=
6073 		 * sc->rx_bd_mbuf_data_len bytes).
6074 		 */
6075 		if (pkt_len > m0->m_len) {
6076 			/*
6077 			 * The received frame is larger than a single mbuf.
6078 			 * If the frame was a TCP frame then only the TCP
6079 			 * header is placed in the mbuf, the remaining
6080 			 * payload (including FCS) is placed in the page
6081 			 * chain, the SPLIT flag is set, and the header
6082 			 * length is placed in the IP checksum field.
6083 			 * If the frame is not a TCP frame then the mbuf
6084 			 * is filled and the remaining bytes are placed
6085 			 * in the page chain.
6086 			 */
6087 
6088 			DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a large "
6089 			    "packet.\n", __FUNCTION__);
6090 
6091 			/*
6092 			 * When the page chain is enabled and the TCP
6093 			 * header has been split from the TCP payload,
6094 			 * the ip_xsum structure will reflect the length
6095 			 * of the TCP header, not the IP checksum.  Set
6096 			 * the packet length of the mbuf accordingly.
6097 			 */
6098 		 	if (status & L2_FHDR_STATUS_SPLIT)
6099 				m0->m_len = l2fhdr->l2_fhdr_ip_xsum;
6100 
6101 			rem_len = pkt_len - m0->m_len;
6102 
6103 			/* Pull mbufs off the page chain for the remaining data. */
6104 			while (rem_len > 0) {
6105 				struct mbuf *m_pg;
6106 
6107 				sw_pg_cons_idx = PG_CHAIN_IDX(sw_pg_cons);
6108 
6109 				/* Remove the mbuf from the page chain. */
6110 				m_pg = sc->pg_mbuf_ptr[sw_pg_cons_idx];
6111 				sc->pg_mbuf_ptr[sw_pg_cons_idx] = NULL;
6112 				DBRUN(sc->debug_pg_mbuf_alloc--);
6113 				sc->free_pg_bd++;
6114 
6115 				/* Unmap the page chain mbuf from DMA space. */
6116 				bus_dmamap_sync(sc->pg_mbuf_tag,
6117 				    sc->pg_mbuf_map[sw_pg_cons_idx],
6118 				    BUS_DMASYNC_POSTREAD);
6119 				bus_dmamap_unload(sc->pg_mbuf_tag,
6120 				    sc->pg_mbuf_map[sw_pg_cons_idx]);
6121 
6122 				/* Adjust the mbuf length. */
6123 				if (rem_len < m_pg->m_len) {
6124 					/* The mbuf chain is complete. */
6125 					m_pg->m_len = rem_len;
6126 					rem_len = 0;
6127 				} else {
6128 					/* More packet data is waiting. */
6129 					rem_len -= m_pg->m_len;
6130 				}
6131 
6132 				/* Concatenate the mbuf cluster to the mbuf. */
6133 				m_cat(m0, m_pg);
6134 
6135 				sw_pg_cons = NEXT_PG_BD(sw_pg_cons);
6136 			}
6137 
6138 			/* Set the total packet length. */
6139 			m0->m_pkthdr.len = pkt_len;
6140 
6141 		} else {
6142 			/*
6143 			 * The received packet is small and fits in a
6144 			 * single mbuf (i.e. the l2_fhdr + pad + packet +
6145 			 * FCS <= MHLEN).  In other words, the packet is
6146 			 * 154 bytes or less in size.
6147 			 */
6148 
6149 			DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a small "
6150 			    "packet.\n", __FUNCTION__);
6151 
6152 			/* Set the total packet length. */
6153 			m0->m_pkthdr.len = m0->m_len = pkt_len;
6154 		}
6155 #else
6156 		/* Set the total packet length. */
6157 		m0->m_pkthdr.len = m0->m_len = pkt_len;
6158 #endif
6159 
6160 		/* Remove the trailing Ethernet FCS. */
6161 		m_adj(m0, -ETHER_CRC_LEN);
6162 
6163 		/* Check that the resulting mbuf chain is valid. */
6164 		DBRUN(m_sanity(m0, FALSE));
6165 		DBRUNIF(((m0->m_len < ETHER_HDR_LEN) |
6166 		    (m0->m_pkthdr.len > BCE_MAX_JUMBO_ETHER_MTU_VLAN)),
6167 		     BCE_PRINTF("Invalid Ethernet frame size!\n");
6168 		     m_print(m0, 128));
6169 
6170 		DBRUNIF(DB_RANDOMTRUE(l2fhdr_error_sim_control),
6171 		    sc->l2fhdr_error_sim_count++;
6172 		    status = status | L2_FHDR_ERRORS_PHY_DECODE);
6173 
6174 		/* Check the received frame for errors. */
6175 		if (status & (L2_FHDR_ERRORS_BAD_CRC |
6176 		    L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT |
6177 		    L2_FHDR_ERRORS_TOO_SHORT  | L2_FHDR_ERRORS_GIANT_FRAME)) {
6178 
6179 			/* Log the error and release the mbuf. */
6180 			ifp->if_ierrors++;
6181 			sc->l2fhdr_error_count++;
6182 
6183 			m_freem(m0);
6184 			m0 = NULL;
6185 			goto bce_rx_int_next_rx;
6186 		}
6187 
6188 		/* Send the packet to the appropriate interface. */
6189 		m0->m_pkthdr.rcvif = ifp;
6190 
6191 		/* Assume no hardware checksum. */
6192 		m0->m_pkthdr.csum_flags = 0;
6193 
6194 		/* Validate the checksum if offload enabled. */
6195 		if (ifp->if_capenable & IFCAP_RXCSUM) {
6196 
6197 			/* Check for an IP datagram. */
6198 		 	if (!(status & L2_FHDR_STATUS_SPLIT) &&
6199 			    (status & L2_FHDR_STATUS_IP_DATAGRAM)) {
6200 				m0->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
6201 				DBRUN(sc->csum_offload_ip++);
6202 				/* Check if the IP checksum is valid. */
6203 				if ((l2fhdr->l2_fhdr_ip_xsum ^ 0xffff) == 0)
6204 					m0->m_pkthdr.csum_flags |=
6205 					    CSUM_IP_VALID;
6206 			}
6207 
6208 			/* Check for a valid TCP/UDP frame. */
6209 			if (status & (L2_FHDR_STATUS_TCP_SEGMENT |
6210 			    L2_FHDR_STATUS_UDP_DATAGRAM)) {
6211 
6212 				/* Check for a good TCP/UDP checksum. */
6213 				if ((status & (L2_FHDR_ERRORS_TCP_XSUM |
6214 				    L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
6215 					DBRUN(sc->csum_offload_tcp_udp++);
6216 					m0->m_pkthdr.csum_data =
6217 					    l2fhdr->l2_fhdr_tcp_udp_xsum;
6218 					m0->m_pkthdr.csum_flags |=
6219 					    (CSUM_DATA_VALID
6220 					    | CSUM_PSEUDO_HDR);
6221 				}
6222 			}
6223 		}
6224 
6225 		/* Attach the VLAN tag.	*/
6226 		if (status & L2_FHDR_STATUS_L2_VLAN_TAG) {
6227 			if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
6228 #if __FreeBSD_version < 700000
6229 				VLAN_INPUT_TAG(ifp, m0,
6230 				    l2fhdr->l2_fhdr_vlan_tag, continue);
6231 #else
6232 				m0->m_pkthdr.ether_vtag =
6233 				    l2fhdr->l2_fhdr_vlan_tag;
6234 				m0->m_flags |= M_VLANTAG;
6235 #endif
6236 			} else {
6237 				/*
6238 				 * bce(4) controllers can't disable VLAN
6239 				 * tag stripping if management firmware
6240 				 * (ASF/IPMI/UMP) is running. So we always
6241 				 * strip VLAN tag and manually reconstruct
6242 				 * the VLAN frame by appending stripped
6243 				 * VLAN tag in driver if VLAN tag stripping
6244 				 * was disabled.
6245 				 *
6246 				 * TODO: LLC SNAP handling.
6247 				 */
6248 				bcopy(mtod(m0, uint8_t *),
6249 				    mtod(m0, uint8_t *) - ETHER_VLAN_ENCAP_LEN,
6250 				    ETHER_ADDR_LEN * 2);
6251 				m0->m_data -= ETHER_VLAN_ENCAP_LEN;
6252 				vh = mtod(m0, struct ether_vlan_header *);
6253 				vh->evl_encap_proto = htons(ETHERTYPE_VLAN);
6254 				vh->evl_tag = htons(l2fhdr->l2_fhdr_vlan_tag);
6255 				m0->m_pkthdr.len += ETHER_VLAN_ENCAP_LEN;
6256 				m0->m_len += ETHER_VLAN_ENCAP_LEN;
6257 			}
6258 		}
6259 
6260 		/* Increment received packet statistics. */
6261 		ifp->if_ipackets++;
6262 
6263 bce_rx_int_next_rx:
6264 		sw_rx_cons = NEXT_RX_BD(sw_rx_cons);
6265 
6266 		/* If we have a packet, pass it up the stack */
6267 		if (m0) {
6268 			/* Make sure we don't lose our place when we release the lock. */
6269 			sc->rx_cons = sw_rx_cons;
6270 #ifdef BCE_JUMBO_HDRSPLIT
6271 			sc->pg_cons = sw_pg_cons;
6272 #endif
6273 
6274 			BCE_UNLOCK(sc);
6275 			(*ifp->if_input)(ifp, m0);
6276 			BCE_LOCK(sc);
6277 
6278 			/* Recover our place. */
6279 			sw_rx_cons = sc->rx_cons;
6280 #ifdef BCE_JUMBO_HDRSPLIT
6281 			sw_pg_cons = sc->pg_cons;
6282 #endif
6283 		}
6284 
6285 		/* Refresh hw_cons to see if there's new work */
6286 		if (sw_rx_cons == hw_rx_cons)
6287 			hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
6288 	}
6289 
6290 #ifdef BCE_JUMBO_HDRSPLIT
6291 	/* No new packets.  Refill the page chain. */
6292 	sc->pg_cons = sw_pg_cons;
6293 	bce_fill_pg_chain(sc);
6294 #endif
6295 
6296 	/* No new packets.  Refill the RX chain. */
6297 	sc->rx_cons = sw_rx_cons;
6298 	bce_fill_rx_chain(sc);
6299 
6300 	/* Prepare the page chain pages to be accessed by the NIC. */
6301 	for (int i = 0; i < RX_PAGES; i++)
6302 		bus_dmamap_sync(sc->rx_bd_chain_tag,
6303 		    sc->rx_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
6304 
6305 #ifdef BCE_JUMBO_HDRSPLIT
6306 	for (int i = 0; i < PG_PAGES; i++)
6307 		bus_dmamap_sync(sc->pg_bd_chain_tag,
6308 		    sc->pg_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
6309 #endif
6310 
6311 	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): rx_prod = 0x%04X, "
6312 	    "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
6313 	    __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
6314 	DBEXIT(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
6315 }
6316 
6317 
6318 /****************************************************************************/
6319 /* Reads the transmit consumer value from the status block (skipping over   */
6320 /* chain page pointer if necessary).                                        */
6321 /*                                                                          */
6322 /* Returns:                                                                 */
6323 /*   hw_cons                                                                */
6324 /****************************************************************************/
6325 static inline u16
6326 bce_get_hw_tx_cons(struct bce_softc *sc)
6327 {
6328 	u16 hw_cons;
6329 
6330 	mb();
6331 	hw_cons = sc->status_block->status_tx_quick_consumer_index0;
6332 	if ((hw_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
6333 		hw_cons++;
6334 
6335 	return hw_cons;
6336 }
6337 
6338 
6339 /****************************************************************************/
6340 /* Handles transmit completion interrupt events.                            */
6341 /*                                                                          */
6342 /* Returns:                                                                 */
6343 /*   Nothing.                                                               */
6344 /****************************************************************************/
6345 static void
6346 bce_tx_intr(struct bce_softc *sc)
6347 {
6348 	struct ifnet *ifp = sc->bce_ifp;
6349 	u16 hw_tx_cons, sw_tx_cons, sw_tx_chain_cons;
6350 
6351 	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
6352 	DBRUN(sc->interrupts_tx++);
6353 	DBPRINT(sc, BCE_EXTREME_SEND, "%s(enter): tx_prod = 0x%04X, "
6354 	    "tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
6355 	    __FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
6356 
6357 	BCE_LOCK_ASSERT(sc);
6358 
6359 	/* Get the hardware's view of the TX consumer index. */
6360 	hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
6361 	sw_tx_cons = sc->tx_cons;
6362 
6363 	/* Prevent speculative reads of the status block. */
6364 	bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
6365 	    BUS_SPACE_BARRIER_READ);
6366 
6367 	/* Cycle through any completed TX chain page entries. */
6368 	while (sw_tx_cons != hw_tx_cons) {
6369 #ifdef BCE_DEBUG
6370 		struct tx_bd *txbd = NULL;
6371 #endif
6372 		sw_tx_chain_cons = TX_CHAIN_IDX(sw_tx_cons);
6373 
6374 		DBPRINT(sc, BCE_INFO_SEND,
6375 		    "%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, "
6376 		    "sw_tx_chain_cons = 0x%04X\n",
6377 		    __FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
6378 
6379 		DBRUNIF((sw_tx_chain_cons > MAX_TX_BD),
6380 		    BCE_PRINTF("%s(%d): TX chain consumer out of range! "
6381 		    " 0x%04X > 0x%04X\n", __FILE__, __LINE__, sw_tx_chain_cons,
6382 		    (int) MAX_TX_BD);
6383 		    bce_breakpoint(sc));
6384 
6385 		DBRUN(txbd = &sc->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)]
6386 		    [TX_IDX(sw_tx_chain_cons)]);
6387 
6388 		DBRUNIF((txbd == NULL),
6389 		    BCE_PRINTF("%s(%d): Unexpected NULL tx_bd[0x%04X]!\n",
6390 		    __FILE__, __LINE__, sw_tx_chain_cons);
6391 		    bce_breakpoint(sc));
6392 
6393 		DBRUNMSG(BCE_INFO_SEND, BCE_PRINTF("%s(): ", __FUNCTION__);
6394 		    bce_dump_txbd(sc, sw_tx_chain_cons, txbd));
6395 
6396 		/*
6397 		 * Free the associated mbuf. Remember
6398 		 * that only the last tx_bd of a packet
6399 		 * has an mbuf pointer and DMA map.
6400 		 */
6401 		if (sc->tx_mbuf_ptr[sw_tx_chain_cons] != NULL) {
6402 
6403 			/* Validate that this is the last tx_bd. */
6404 			DBRUNIF((!(txbd->tx_bd_flags & TX_BD_FLAGS_END)),
6405 			    BCE_PRINTF("%s(%d): tx_bd END flag not set but "
6406 			    "txmbuf == NULL!\n", __FILE__, __LINE__);
6407 			    bce_breakpoint(sc));
6408 
6409 			DBRUNMSG(BCE_INFO_SEND,
6410 			    BCE_PRINTF("%s(): Unloading map/freeing mbuf "
6411 			    "from tx_bd[0x%04X]\n", __FUNCTION__,
6412 			    sw_tx_chain_cons));
6413 
6414 			/* Unmap the mbuf. */
6415 			bus_dmamap_unload(sc->tx_mbuf_tag,
6416 			    sc->tx_mbuf_map[sw_tx_chain_cons]);
6417 
6418 			/* Free the mbuf. */
6419 			m_freem(sc->tx_mbuf_ptr[sw_tx_chain_cons]);
6420 			sc->tx_mbuf_ptr[sw_tx_chain_cons] = NULL;
6421 			DBRUN(sc->debug_tx_mbuf_alloc--);
6422 
6423 			ifp->if_opackets++;
6424 		}
6425 
6426 		sc->used_tx_bd--;
6427 		sw_tx_cons = NEXT_TX_BD(sw_tx_cons);
6428 
6429 		/* Refresh hw_cons to see if there's new work. */
6430 		hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
6431 
6432 		/* Prevent speculative reads of the status block. */
6433 		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
6434 		    BUS_SPACE_BARRIER_READ);
6435 	}
6436 
6437 	/* Clear the TX timeout timer. */
6438 	sc->watchdog_timer = 0;
6439 
6440 	/* Clear the tx hardware queue full flag. */
6441 	if (sc->used_tx_bd < sc->max_tx_bd) {
6442 		DBRUNIF((ifp->if_drv_flags & IFF_DRV_OACTIVE),
6443 		    DBPRINT(sc, BCE_INFO_SEND,
6444 		    "%s(): Open TX chain! %d/%d (used/total)\n",
6445 		    __FUNCTION__, sc->used_tx_bd, sc->max_tx_bd));
6446 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
6447 	}
6448 
6449 	sc->tx_cons = sw_tx_cons;
6450 
6451 	DBPRINT(sc, BCE_EXTREME_SEND, "%s(exit): tx_prod = 0x%04X, "
6452 	    "tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
6453 	    __FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
6454 	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
6455 }
6456 
6457 
6458 /****************************************************************************/
6459 /* Disables interrupt generation.                                           */
6460 /*                                                                          */
6461 /* Returns:                                                                 */
6462 /*   Nothing.                                                               */
6463 /****************************************************************************/
6464 static void
6465 bce_disable_intr(struct bce_softc *sc)
6466 {
6467 	DBENTER(BCE_VERBOSE_INTR);
6468 
6469 	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_MASK_INT);
6470 	REG_RD(sc, BCE_PCICFG_INT_ACK_CMD);
6471 
6472 	DBEXIT(BCE_VERBOSE_INTR);
6473 }
6474 
6475 
6476 /****************************************************************************/
6477 /* Enables interrupt generation.                                            */
6478 /*                                                                          */
6479 /* Returns:                                                                 */
6480 /*   Nothing.                                                               */
6481 /****************************************************************************/
6482 static void
6483 bce_enable_intr(struct bce_softc *sc, int coal_now)
6484 {
6485 	DBENTER(BCE_VERBOSE_INTR);
6486 
6487 	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
6488 	    BCE_PCICFG_INT_ACK_CMD_INDEX_VALID |
6489 	    BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
6490 
6491 	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
6492 	    BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
6493 
6494 	/* Force an immediate interrupt (whether there is new data or not). */
6495 	if (coal_now)
6496 		REG_WR(sc, BCE_HC_COMMAND, sc->hc_command | BCE_HC_COMMAND_COAL_NOW);
6497 
6498 	DBEXIT(BCE_VERBOSE_INTR);
6499 }
6500 
6501 
6502 /****************************************************************************/
6503 /* Handles controller initialization.                                       */
6504 /*                                                                          */
6505 /* Returns:                                                                 */
6506 /*   Nothing.                                                               */
6507 /****************************************************************************/
6508 static void
6509 bce_init_locked(struct bce_softc *sc)
6510 {
6511 	struct ifnet *ifp;
6512 	u32 ether_mtu = 0;
6513 
6514 	DBENTER(BCE_VERBOSE_RESET);
6515 
6516 	BCE_LOCK_ASSERT(sc);
6517 
6518 	ifp = sc->bce_ifp;
6519 
6520 	/* Check if the driver is still running and bail out if it is. */
6521 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
6522 		goto bce_init_locked_exit;
6523 
6524 	bce_stop(sc);
6525 
6526 	if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
6527 		BCE_PRINTF("%s(%d): Controller reset failed!\n",
6528 		    __FILE__, __LINE__);
6529 		goto bce_init_locked_exit;
6530 	}
6531 
6532 	if (bce_chipinit(sc)) {
6533 		BCE_PRINTF("%s(%d): Controller initialization failed!\n",
6534 		    __FILE__, __LINE__);
6535 		goto bce_init_locked_exit;
6536 	}
6537 
6538 	if (bce_blockinit(sc)) {
6539 		BCE_PRINTF("%s(%d): Block initialization failed!\n",
6540 		    __FILE__, __LINE__);
6541 		goto bce_init_locked_exit;
6542 	}
6543 
6544 	/* Load our MAC address. */
6545 	bcopy(IF_LLADDR(sc->bce_ifp), sc->eaddr, ETHER_ADDR_LEN);
6546 	bce_set_mac_addr(sc);
6547 
6548 	/*
6549 	 * Calculate and program the hardware Ethernet MTU
6550 	 * size. Be generous on the receive if we have room.
6551 	 */
6552 #ifdef BCE_JUMBO_HDRSPLIT
6553 	if (ifp->if_mtu <= (sc->rx_bd_mbuf_data_len +
6554 	    sc->pg_bd_mbuf_alloc_size))
6555 		ether_mtu = sc->rx_bd_mbuf_data_len +
6556 		    sc->pg_bd_mbuf_alloc_size;
6557 #else
6558 	if (ifp->if_mtu <= sc->rx_bd_mbuf_data_len)
6559 		ether_mtu = sc->rx_bd_mbuf_data_len;
6560 #endif
6561 	else
6562 		ether_mtu = ifp->if_mtu;
6563 
6564 	ether_mtu += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN;
6565 
6566 	DBPRINT(sc, BCE_INFO_MISC, "%s(): setting h/w mtu = %d\n",
6567 	    __FUNCTION__, ether_mtu);
6568 
6569 	/* Program the mtu, enabling jumbo frame support if necessary. */
6570 	if (ether_mtu > (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN))
6571 		REG_WR(sc, BCE_EMAC_RX_MTU_SIZE,
6572 		    min(ether_mtu, BCE_MAX_JUMBO_ETHER_MTU) |
6573 		    BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA);
6574 	else
6575 		REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu);
6576 
6577 	DBPRINT(sc, BCE_INFO_LOAD,
6578 	    "%s(): rx_bd_mbuf_alloc_size = %d, rx_bce_mbuf_data_len = %d, "
6579 	    "rx_bd_mbuf_align_pad = %d\n", __FUNCTION__,
6580 	    sc->rx_bd_mbuf_alloc_size, sc->rx_bd_mbuf_data_len,
6581 	    sc->rx_bd_mbuf_align_pad);
6582 
6583 	/* Program appropriate promiscuous/multicast filtering. */
6584 	bce_set_rx_mode(sc);
6585 
6586 #ifdef BCE_JUMBO_HDRSPLIT
6587 	DBPRINT(sc, BCE_INFO_LOAD, "%s(): pg_bd_mbuf_alloc_size = %d\n",
6588 	    __FUNCTION__, sc->pg_bd_mbuf_alloc_size);
6589 
6590 	/* Init page buffer descriptor chain. */
6591 	bce_init_pg_chain(sc);
6592 #endif
6593 
6594 	/* Init RX buffer descriptor chain. */
6595 	bce_init_rx_chain(sc);
6596 
6597 	/* Init TX buffer descriptor chain. */
6598 	bce_init_tx_chain(sc);
6599 
6600 	/* Enable host interrupts. */
6601 	bce_enable_intr(sc, 1);
6602 
6603 	bce_ifmedia_upd_locked(ifp);
6604 
6605 	/* Let the OS know the driver is up and running. */
6606 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
6607 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
6608 
6609 	callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
6610 
6611 bce_init_locked_exit:
6612 	DBEXIT(BCE_VERBOSE_RESET);
6613 }
6614 
6615 
6616 /****************************************************************************/
6617 /* Initialize the controller just enough so that any management firmware    */
6618 /* running on the device will continue to operate correctly.                */
6619 /*                                                                          */
6620 /* Returns:                                                                 */
6621 /*   Nothing.                                                               */
6622 /****************************************************************************/
6623 static void
6624 bce_mgmt_init_locked(struct bce_softc *sc)
6625 {
6626 	struct ifnet *ifp;
6627 
6628 	DBENTER(BCE_VERBOSE_RESET);
6629 
6630 	BCE_LOCK_ASSERT(sc);
6631 
6632 	/* Bail out if management firmware is not running. */
6633 	if (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)) {
6634 		DBPRINT(sc, BCE_VERBOSE_SPECIAL,
6635 		    "No management firmware running...\n");
6636 		goto bce_mgmt_init_locked_exit;
6637 	}
6638 
6639 	ifp = sc->bce_ifp;
6640 
6641 	/* Enable all critical blocks in the MAC. */
6642 	REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT);
6643 	REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
6644 	DELAY(20);
6645 
6646 	bce_ifmedia_upd_locked(ifp);
6647 
6648 bce_mgmt_init_locked_exit:
6649 	DBEXIT(BCE_VERBOSE_RESET);
6650 }
6651 
6652 
6653 /****************************************************************************/
6654 /* Handles controller initialization when called from an unlocked routine.  */
6655 /*                                                                          */
6656 /* Returns:                                                                 */
6657 /*   Nothing.                                                               */
6658 /****************************************************************************/
6659 static void
6660 bce_init(void *xsc)
6661 {
6662 	struct bce_softc *sc = xsc;
6663 
6664 	DBENTER(BCE_VERBOSE_RESET);
6665 
6666 	BCE_LOCK(sc);
6667 	bce_init_locked(sc);
6668 	BCE_UNLOCK(sc);
6669 
6670 	DBEXIT(BCE_VERBOSE_RESET);
6671 }
6672 
6673 
6674 /****************************************************************************/
6675 /* Modifies an mbuf for TSO on the hardware.                                */
6676 /*                                                                          */
6677 /* Returns:                                                                 */
6678 /*   Pointer to a modified mbuf.                                            */
6679 /****************************************************************************/
6680 static struct mbuf *
6681 bce_tso_setup(struct bce_softc *sc, struct mbuf **m_head, u16 *flags)
6682 {
6683 	struct mbuf *m;
6684 	struct ether_header *eh;
6685 	struct ip *ip;
6686 	struct tcphdr *th;
6687 	u16 etype;
6688 	int hdr_len, ip_hlen = 0, tcp_hlen = 0, ip_len = 0;
6689 
6690 	DBRUN(sc->tso_frames_requested++);
6691 
6692 	/* Controller may modify mbuf chains. */
6693 	if (M_WRITABLE(*m_head) == 0) {
6694 		m = m_dup(*m_head, M_DONTWAIT);
6695 		m_freem(*m_head);
6696 		if (m == NULL) {
6697 			sc->mbuf_alloc_failed_count++;
6698 			*m_head = NULL;
6699 			return (NULL);
6700 		}
6701 		*m_head = m;
6702 	}
6703 
6704 	/*
6705 	 * For TSO the controller needs two pieces of info,
6706 	 * the MSS and the IP+TCP options length.
6707 	 */
6708 	m = m_pullup(*m_head, sizeof(struct ether_header) + sizeof(struct ip));
6709 	if (m == NULL) {
6710 		*m_head = NULL;
6711 		return (NULL);
6712 	}
6713 	eh = mtod(m, struct ether_header *);
6714 	etype = ntohs(eh->ether_type);
6715 
6716 	/* Check for supported TSO Ethernet types (only IPv4 for now) */
6717 	switch (etype) {
6718 	case ETHERTYPE_IP:
6719 		ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
6720 		/* TSO only supported for TCP protocol. */
6721 		if (ip->ip_p != IPPROTO_TCP) {
6722 			BCE_PRINTF("%s(%d): TSO enabled for non-TCP frame!.\n",
6723 			    __FILE__, __LINE__);
6724 			m_freem(*m_head);
6725 			*m_head = NULL;
6726 			return (NULL);
6727 		}
6728 
6729 		/* Get IP header length in bytes (min 20) */
6730 		ip_hlen = ip->ip_hl << 2;
6731 		m = m_pullup(*m_head, sizeof(struct ether_header) + ip_hlen +
6732 		    sizeof(struct tcphdr));
6733 		if (m == NULL) {
6734 			*m_head = NULL;
6735 			return (NULL);
6736 		}
6737 
6738 		/* Get the TCP header length in bytes (min 20) */
6739 		ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
6740 		th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
6741 		tcp_hlen = (th->th_off << 2);
6742 
6743 		/* Make sure all IP/TCP options live in the same buffer. */
6744 		m = m_pullup(*m_head,  sizeof(struct ether_header)+ ip_hlen +
6745 		    tcp_hlen);
6746 		if (m == NULL) {
6747 			*m_head = NULL;
6748 			return (NULL);
6749 		}
6750 
6751 		/* IP header length and checksum will be calc'd by hardware */
6752 		ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
6753 		ip_len = ip->ip_len;
6754 		ip->ip_len = 0;
6755 		ip->ip_sum = 0;
6756 		break;
6757 	case ETHERTYPE_IPV6:
6758 		BCE_PRINTF("%s(%d): TSO over IPv6 not supported!.\n",
6759 		    __FILE__, __LINE__);
6760 		m_freem(*m_head);
6761 		*m_head = NULL;
6762 		return (NULL);
6763 		/* NOT REACHED */
6764 	default:
6765 		BCE_PRINTF("%s(%d): TSO enabled for unsupported protocol!.\n",
6766 		    __FILE__, __LINE__);
6767 		m_freem(*m_head);
6768 		*m_head = NULL;
6769 		return (NULL);
6770 	}
6771 
6772 	hdr_len = sizeof(struct ether_header) + ip_hlen + tcp_hlen;
6773 
6774 	DBPRINT(sc, BCE_EXTREME_SEND, "%s(): hdr_len = %d, e_hlen = %d, "
6775 	    "ip_hlen = %d, tcp_hlen = %d, ip_len = %d\n",
6776 	    __FUNCTION__, hdr_len, (int) sizeof(struct ether_header), ip_hlen,
6777 	    tcp_hlen, ip_len);
6778 
6779 	/* Set the LSO flag in the TX BD */
6780 	*flags |= TX_BD_FLAGS_SW_LSO;
6781 
6782 	/* Set the length of IP + TCP options (in 32 bit words) */
6783 	*flags |= (((ip_hlen + tcp_hlen - sizeof(struct ip) -
6784 	    sizeof(struct tcphdr)) >> 2) << 8);
6785 
6786 	DBRUN(sc->tso_frames_completed++);
6787 	return (*m_head);
6788 }
6789 
6790 
6791 /****************************************************************************/
6792 /* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
6793 /* memory visible to the controller.                                        */
6794 /*                                                                          */
6795 /* Returns:                                                                 */
6796 /*   0 for success, positive value for failure.                             */
6797 /* Modified:                                                                */
6798 /*   m_head: May be set to NULL if MBUF is excessively fragmented.          */
6799 /****************************************************************************/
6800 static int
6801 bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
6802 {
6803 	bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
6804 	bus_dmamap_t map;
6805 	struct tx_bd *txbd = NULL;
6806 	struct mbuf *m0;
6807 	u16 prod, chain_prod, mss = 0, vlan_tag = 0, flags = 0;
6808 	u32 prod_bseq;
6809 
6810 #ifdef BCE_DEBUG
6811 	u16 debug_prod;
6812 #endif
6813 
6814 	int i, error, nsegs, rc = 0;
6815 
6816 	DBENTER(BCE_VERBOSE_SEND);
6817 
6818 	/* Make sure we have room in the TX chain. */
6819 	if (sc->used_tx_bd >= sc->max_tx_bd)
6820 		goto bce_tx_encap_exit;
6821 
6822 	/* Transfer any checksum offload flags to the bd. */
6823 	m0 = *m_head;
6824 	if (m0->m_pkthdr.csum_flags) {
6825 		if (m0->m_pkthdr.csum_flags & CSUM_TSO) {
6826 			m0 = bce_tso_setup(sc, m_head, &flags);
6827 			if (m0 == NULL) {
6828 				DBRUN(sc->tso_frames_failed++);
6829 				goto bce_tx_encap_exit;
6830 			}
6831 			mss = htole16(m0->m_pkthdr.tso_segsz);
6832 		} else {
6833 			if (m0->m_pkthdr.csum_flags & CSUM_IP)
6834 				flags |= TX_BD_FLAGS_IP_CKSUM;
6835 			if (m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
6836 				flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
6837 		}
6838 	}
6839 
6840 	/* Transfer any VLAN tags to the bd. */
6841 	if (m0->m_flags & M_VLANTAG) {
6842 		flags |= TX_BD_FLAGS_VLAN_TAG;
6843 		vlan_tag = m0->m_pkthdr.ether_vtag;
6844 	}
6845 
6846 	/* Map the mbuf into DMAable memory. */
6847 	prod = sc->tx_prod;
6848 	chain_prod = TX_CHAIN_IDX(prod);
6849 	map = sc->tx_mbuf_map[chain_prod];
6850 
6851 	/* Map the mbuf into our DMA address space. */
6852 	error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag, map, m0,
6853 	    segs, &nsegs, BUS_DMA_NOWAIT);
6854 
6855 	/* Check if the DMA mapping was successful */
6856 	if (error == EFBIG) {
6857 		sc->mbuf_frag_count++;
6858 
6859 		/* Try to defrag the mbuf. */
6860 		m0 = m_collapse(*m_head, M_DONTWAIT, BCE_MAX_SEGMENTS);
6861 		if (m0 == NULL) {
6862 			/* Defrag was unsuccessful */
6863 			m_freem(*m_head);
6864 			*m_head = NULL;
6865 			sc->mbuf_alloc_failed_count++;
6866 			rc = ENOBUFS;
6867 			goto bce_tx_encap_exit;
6868 		}
6869 
6870 		/* Defrag was successful, try mapping again */
6871 		*m_head = m0;
6872 		error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag,
6873 		    map, m0, segs, &nsegs, BUS_DMA_NOWAIT);
6874 
6875 		/* Still getting an error after a defrag. */
6876 		if (error == ENOMEM) {
6877 			/* Insufficient DMA buffers available. */
6878 			sc->dma_map_addr_tx_failed_count++;
6879 			rc = error;
6880 			goto bce_tx_encap_exit;
6881 		} else if (error != 0) {
6882 			/* Release it and return an error. */
6883 			BCE_PRINTF("%s(%d): Unknown error mapping mbuf into "
6884 			    "TX chain!\n", __FILE__, __LINE__);
6885 			m_freem(m0);
6886 			*m_head = NULL;
6887 			sc->dma_map_addr_tx_failed_count++;
6888 			rc = ENOBUFS;
6889 			goto bce_tx_encap_exit;
6890 		}
6891 	} else if (error == ENOMEM) {
6892 		/* Insufficient DMA buffers available. */
6893 		sc->dma_map_addr_tx_failed_count++;
6894 		rc = error;
6895 		goto bce_tx_encap_exit;
6896 	} else if (error != 0) {
6897 		m_freem(m0);
6898 		*m_head = NULL;
6899 		sc->dma_map_addr_tx_failed_count++;
6900 		rc = error;
6901 		goto bce_tx_encap_exit;
6902 	}
6903 
6904 	/* Make sure there's room in the chain */
6905 	if (nsegs > (sc->max_tx_bd - sc->used_tx_bd)) {
6906 		bus_dmamap_unload(sc->tx_mbuf_tag, map);
6907 		rc = ENOBUFS;
6908 		goto bce_tx_encap_exit;
6909 	}
6910 
6911 	/* prod points to an empty tx_bd at this point. */
6912 	prod_bseq  = sc->tx_prod_bseq;
6913 
6914 #ifdef BCE_DEBUG
6915 	debug_prod = chain_prod;
6916 #endif
6917 
6918 	DBPRINT(sc, BCE_INFO_SEND,
6919 	    "%s(start): prod = 0x%04X, chain_prod = 0x%04X, "
6920 	    "prod_bseq = 0x%08X\n",
6921 	    __FUNCTION__, prod, chain_prod, prod_bseq);
6922 
6923 	/*
6924 	 * Cycle through each mbuf segment that makes up
6925 	 * the outgoing frame, gathering the mapping info
6926 	 * for that segment and creating a tx_bd for
6927 	 * the mbuf.
6928 	 */
6929 	for (i = 0; i < nsegs ; i++) {
6930 
6931 		chain_prod = TX_CHAIN_IDX(prod);
6932 		txbd= &sc->tx_bd_chain[TX_PAGE(chain_prod)]
6933 		    [TX_IDX(chain_prod)];
6934 
6935 		txbd->tx_bd_haddr_lo =
6936 		    htole32(BCE_ADDR_LO(segs[i].ds_addr));
6937 		txbd->tx_bd_haddr_hi =
6938 		    htole32(BCE_ADDR_HI(segs[i].ds_addr));
6939 		txbd->tx_bd_mss_nbytes = htole32(mss << 16) |
6940 		    htole16(segs[i].ds_len);
6941 		txbd->tx_bd_vlan_tag = htole16(vlan_tag);
6942 		txbd->tx_bd_flags = htole16(flags);
6943 		prod_bseq += segs[i].ds_len;
6944 		if (i == 0)
6945 			txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_START);
6946 		prod = NEXT_TX_BD(prod);
6947 	}
6948 
6949 	/* Set the END flag on the last TX buffer descriptor. */
6950 	txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_END);
6951 
6952 	DBRUNMSG(BCE_EXTREME_SEND,
6953 	    bce_dump_tx_chain(sc, debug_prod, nsegs));
6954 
6955 	/*
6956 	 * Ensure that the mbuf pointer for this transmission
6957 	 * is placed at the array index of the last
6958 	 * descriptor in this chain.  This is done
6959 	 * because a single map is used for all
6960 	 * segments of the mbuf and we don't want to
6961 	 * unload the map before all of the segments
6962 	 * have been freed.
6963 	 */
6964 	sc->tx_mbuf_ptr[chain_prod] = m0;
6965 	sc->used_tx_bd += nsegs;
6966 
6967 	/* Update some debug statistic counters */
6968 	DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
6969 	    sc->tx_hi_watermark = sc->used_tx_bd);
6970 	DBRUNIF((sc->used_tx_bd == sc->max_tx_bd), sc->tx_full_count++);
6971 	DBRUNIF(sc->debug_tx_mbuf_alloc++);
6972 
6973 	DBRUNMSG(BCE_EXTREME_SEND, bce_dump_tx_mbuf_chain(sc, chain_prod, 1));
6974 
6975 	/* prod points to the next free tx_bd at this point. */
6976 	sc->tx_prod = prod;
6977 	sc->tx_prod_bseq = prod_bseq;
6978 
6979 	/* Tell the chip about the waiting TX frames. */
6980 	REG_WR16(sc, MB_GET_CID_ADDR(TX_CID) +
6981 	    BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
6982 	REG_WR(sc, MB_GET_CID_ADDR(TX_CID) +
6983 	    BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
6984 
6985 bce_tx_encap_exit:
6986 	DBEXIT(BCE_VERBOSE_SEND);
6987 	return(rc);
6988 }
6989 
6990 
6991 /****************************************************************************/
6992 /* Main transmit routine when called from another routine with a lock.      */
6993 /*                                                                          */
6994 /* Returns:                                                                 */
6995 /*   Nothing.                                                               */
6996 /****************************************************************************/
6997 static void
6998 bce_start_locked(struct ifnet *ifp)
6999 {
7000 	struct bce_softc *sc = ifp->if_softc;
7001 	struct mbuf *m_head = NULL;
7002 	int count = 0;
7003 	u16 tx_prod, tx_chain_prod;
7004 
7005 	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
7006 
7007 	BCE_LOCK_ASSERT(sc);
7008 
7009 	/* prod points to the next free tx_bd. */
7010 	tx_prod = sc->tx_prod;
7011 	tx_chain_prod = TX_CHAIN_IDX(tx_prod);
7012 
7013 	DBPRINT(sc, BCE_INFO_SEND,
7014 	    "%s(enter): tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
7015 	    "tx_prod_bseq = 0x%08X\n",
7016 	    __FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
7017 
7018 	/* If there's no link or the transmit queue is empty then just exit. */
7019 	if (sc->bce_link_up == FALSE) {
7020 		DBPRINT(sc, BCE_INFO_SEND, "%s(): No link.\n",
7021 		    __FUNCTION__);
7022 		goto bce_start_locked_exit;
7023 	}
7024 
7025 	if (IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
7026 		DBPRINT(sc, BCE_INFO_SEND, "%s(): Transmit queue empty.\n",
7027 		    __FUNCTION__);
7028 		goto bce_start_locked_exit;
7029 	}
7030 
7031 	/*
7032 	 * Keep adding entries while there is space in the ring.
7033 	 */
7034 	while (sc->used_tx_bd < sc->max_tx_bd) {
7035 
7036 		/* Check for any frames to send. */
7037 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
7038 
7039 		/* Stop when the transmit queue is empty. */
7040 		if (m_head == NULL)
7041 			break;
7042 
7043 		/*
7044 		 * Pack the data into the transmit ring. If we
7045 		 * don't have room, place the mbuf back at the
7046 		 * head of the queue and set the OACTIVE flag
7047 		 * to wait for the NIC to drain the chain.
7048 		 */
7049 		if (bce_tx_encap(sc, &m_head)) {
7050 			if (m_head != NULL)
7051 				IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
7052 			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
7053 			DBPRINT(sc, BCE_INFO_SEND,
7054 			    "TX chain is closed for business! Total "
7055 			    "tx_bd used = %d\n", sc->used_tx_bd);
7056 			break;
7057 		}
7058 
7059 		count++;
7060 
7061 		/* Send a copy of the frame to any BPF listeners. */
7062 		ETHER_BPF_MTAP(ifp, m_head);
7063 	}
7064 
7065 	/* Exit if no packets were dequeued. */
7066 	if (count == 0) {
7067 		DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were "
7068 		    "dequeued\n", __FUNCTION__);
7069 		goto bce_start_locked_exit;
7070 	}
7071 
7072 	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): Inserted %d frames into "
7073 	    "send queue.\n", __FUNCTION__, count);
7074 
7075 	/* Set the tx timeout. */
7076 	sc->watchdog_timer = BCE_TX_TIMEOUT;
7077 
7078 	DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_ctx(sc, TX_CID));
7079 	DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_mq_regs(sc));
7080 
7081 bce_start_locked_exit:
7082 	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
7083 	return;
7084 }
7085 
7086 
7087 /****************************************************************************/
7088 /* Main transmit routine when called from another routine without a lock.   */
7089 /*                                                                          */
7090 /* Returns:                                                                 */
7091 /*   Nothing.                                                               */
7092 /****************************************************************************/
7093 static void
7094 bce_start(struct ifnet *ifp)
7095 {
7096 	struct bce_softc *sc = ifp->if_softc;
7097 
7098 	DBENTER(BCE_VERBOSE_SEND);
7099 
7100 	BCE_LOCK(sc);
7101 	bce_start_locked(ifp);
7102 	BCE_UNLOCK(sc);
7103 
7104 	DBEXIT(BCE_VERBOSE_SEND);
7105 }
7106 
7107 
7108 /****************************************************************************/
7109 /* Handles any IOCTL calls from the operating system.                       */
7110 /*                                                                          */
7111 /* Returns:                                                                 */
7112 /*   0 for success, positive value for failure.                             */
7113 /****************************************************************************/
7114 static int
7115 bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
7116 {
7117 	struct bce_softc *sc = ifp->if_softc;
7118 	struct ifreq *ifr = (struct ifreq *) data;
7119 	struct mii_data *mii;
7120 	int mask, error = 0, reinit;
7121 
7122 	DBENTER(BCE_VERBOSE_MISC);
7123 
7124 	switch(command) {
7125 
7126 	/* Set the interface MTU. */
7127 	case SIOCSIFMTU:
7128 		/* Check that the MTU setting is supported. */
7129 		if ((ifr->ifr_mtu < BCE_MIN_MTU) ||
7130 			(ifr->ifr_mtu > BCE_MAX_JUMBO_MTU)) {
7131 			error = EINVAL;
7132 			break;
7133 		}
7134 
7135 		DBPRINT(sc, BCE_INFO_MISC,
7136 		    "SIOCSIFMTU: Changing MTU from %d to %d\n",
7137 		    (int) ifp->if_mtu, (int) ifr->ifr_mtu);
7138 
7139 		BCE_LOCK(sc);
7140 		ifp->if_mtu = ifr->ifr_mtu;
7141 		reinit = 0;
7142 		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
7143 			/*
7144 			 * Because allocation size is used in RX
7145 			 * buffer allocation, stop controller if
7146 			 * it is already running.
7147 			 */
7148 			bce_stop(sc);
7149 			reinit = 1;
7150 		}
7151 #ifdef BCE_JUMBO_HDRSPLIT
7152 		/* No buffer allocation size changes are necessary. */
7153 #else
7154 		/* Recalculate our buffer allocation sizes. */
7155 		if ((ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN +
7156 		     ETHER_CRC_LEN) > MCLBYTES) {
7157 			sc->rx_bd_mbuf_alloc_size = MJUM9BYTES;
7158 			sc->rx_bd_mbuf_align_pad  =
7159 			    roundup2(MJUM9BYTES, 16) - MJUM9BYTES;
7160 			sc->rx_bd_mbuf_data_len =
7161 			    sc->rx_bd_mbuf_alloc_size -
7162 			    sc->rx_bd_mbuf_align_pad;
7163 		} else {
7164 			sc->rx_bd_mbuf_alloc_size = MCLBYTES;
7165 			sc->rx_bd_mbuf_align_pad  =
7166 			    roundup2(MCLBYTES, 16) - MCLBYTES;
7167 			sc->rx_bd_mbuf_data_len =
7168 			    sc->rx_bd_mbuf_alloc_size -
7169 			    sc->rx_bd_mbuf_align_pad;
7170 		}
7171 #endif
7172 
7173 		if (reinit != 0)
7174 			bce_init_locked(sc);
7175 		BCE_UNLOCK(sc);
7176 		break;
7177 
7178 	/* Set interface flags. */
7179 	case SIOCSIFFLAGS:
7180 		DBPRINT(sc, BCE_VERBOSE_SPECIAL, "Received SIOCSIFFLAGS\n");
7181 
7182 		BCE_LOCK(sc);
7183 
7184 		/* Check if the interface is up. */
7185 		if (ifp->if_flags & IFF_UP) {
7186 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
7187 				/* Change promiscuous/multicast flags as necessary. */
7188 				bce_set_rx_mode(sc);
7189 			} else {
7190 				/* Start the HW */
7191 				bce_init_locked(sc);
7192 			}
7193 		} else {
7194 			/* The interface is down, check if driver is running. */
7195 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
7196 				bce_stop(sc);
7197 
7198 				/* If MFW is running, restart the controller a bit. */
7199 				if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
7200 					bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
7201 					bce_chipinit(sc);
7202 					bce_mgmt_init_locked(sc);
7203 				}
7204 			}
7205 		}
7206 
7207 		BCE_UNLOCK(sc);
7208 		break;
7209 
7210 	/* Add/Delete multicast address */
7211 	case SIOCADDMULTI:
7212 	case SIOCDELMULTI:
7213 		DBPRINT(sc, BCE_VERBOSE_MISC,
7214 		    "Received SIOCADDMULTI/SIOCDELMULTI\n");
7215 
7216 		BCE_LOCK(sc);
7217 		if (ifp->if_drv_flags & IFF_DRV_RUNNING)
7218 			bce_set_rx_mode(sc);
7219 		BCE_UNLOCK(sc);
7220 
7221 		break;
7222 
7223 	/* Set/Get Interface media */
7224 	case SIOCSIFMEDIA:
7225 	case SIOCGIFMEDIA:
7226 		DBPRINT(sc, BCE_VERBOSE_MISC,
7227 		    "Received SIOCSIFMEDIA/SIOCGIFMEDIA\n");
7228 
7229 		mii = device_get_softc(sc->bce_miibus);
7230 		error = ifmedia_ioctl(ifp, ifr,
7231 		    &mii->mii_media, command);
7232 		break;
7233 
7234 	/* Set interface capability */
7235 	case SIOCSIFCAP:
7236 		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
7237 		DBPRINT(sc, BCE_INFO_MISC,
7238 		    "Received SIOCSIFCAP = 0x%08X\n", (u32) mask);
7239 
7240 		/* Toggle the TX checksum capabilities enable flag. */
7241 		if (mask & IFCAP_TXCSUM &&
7242 		    ifp->if_capabilities & IFCAP_TXCSUM) {
7243 			ifp->if_capenable ^= IFCAP_TXCSUM;
7244 			if (IFCAP_TXCSUM & ifp->if_capenable)
7245 				ifp->if_hwassist |= BCE_IF_HWASSIST;
7246 			else
7247 				ifp->if_hwassist &= ~BCE_IF_HWASSIST;
7248 		}
7249 
7250 		/* Toggle the RX checksum capabilities enable flag. */
7251 		if (mask & IFCAP_RXCSUM &&
7252 		    ifp->if_capabilities & IFCAP_RXCSUM)
7253 			ifp->if_capenable ^= IFCAP_RXCSUM;
7254 
7255 		/* Toggle the TSO capabilities enable flag. */
7256 		if (bce_tso_enable && (mask & IFCAP_TSO4) &&
7257 		    ifp->if_capabilities & IFCAP_TSO4) {
7258 			ifp->if_capenable ^= IFCAP_TSO4;
7259 			if (IFCAP_TSO4 & ifp->if_capenable)
7260 				ifp->if_hwassist |= CSUM_TSO;
7261 			else
7262 				ifp->if_hwassist &= ~CSUM_TSO;
7263 		}
7264 
7265 		if (mask & IFCAP_VLAN_HWCSUM &&
7266 		    ifp->if_capabilities & IFCAP_VLAN_HWCSUM)
7267 			ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
7268 
7269 		if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
7270 		    (ifp->if_capabilities & IFCAP_VLAN_HWTSO) != 0)
7271 			ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
7272 		/*
7273 		 * Don't actually disable VLAN tag stripping as
7274 		 * management firmware (ASF/IPMI/UMP) requires the
7275 		 * feature. If VLAN tag stripping is disabled driver
7276 		 * will manually reconstruct the VLAN frame by
7277 		 * appending stripped VLAN tag.
7278 		 */
7279 		if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
7280 		    (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)) {
7281 			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
7282 			if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING)
7283 			    == 0)
7284 				ifp->if_capenable &= ~IFCAP_VLAN_HWTSO;
7285 		}
7286 		VLAN_CAPABILITIES(ifp);
7287 		break;
7288 	default:
7289 		/* We don't know how to handle the IOCTL, pass it on. */
7290 		error = ether_ioctl(ifp, command, data);
7291 		break;
7292 	}
7293 
7294 	DBEXIT(BCE_VERBOSE_MISC);
7295 	return(error);
7296 }
7297 
7298 
7299 /****************************************************************************/
7300 /* Transmit timeout handler.                                                */
7301 /*                                                                          */
7302 /* Returns:                                                                 */
7303 /*   Nothing.                                                               */
7304 /****************************************************************************/
7305 static void
7306 bce_watchdog(struct bce_softc *sc)
7307 {
7308 	DBENTER(BCE_EXTREME_SEND);
7309 
7310 	BCE_LOCK_ASSERT(sc);
7311 
7312 	/* If the watchdog timer hasn't expired then just exit. */
7313 	if (sc->watchdog_timer == 0 || --sc->watchdog_timer)
7314 		goto bce_watchdog_exit;
7315 
7316 	/* If pause frames are active then don't reset the hardware. */
7317 	/* ToDo: Should we reset the timer here? */
7318 	if (REG_RD(sc, BCE_EMAC_TX_STATUS) & BCE_EMAC_TX_STATUS_XOFFED)
7319 		goto bce_watchdog_exit;
7320 
7321 	BCE_PRINTF("%s(%d): Watchdog timeout occurred, resetting!\n",
7322 	    __FILE__, __LINE__);
7323 
7324 	DBRUNMSG(BCE_INFO,
7325 	    bce_dump_driver_state(sc);
7326 	    bce_dump_status_block(sc);
7327 	    bce_dump_stats_block(sc);
7328 	    bce_dump_ftqs(sc);
7329 	    bce_dump_txp_state(sc, 0);
7330 	    bce_dump_rxp_state(sc, 0);
7331 	    bce_dump_tpat_state(sc, 0);
7332 	    bce_dump_cp_state(sc, 0);
7333 	    bce_dump_com_state(sc, 0));
7334 
7335 	DBRUN(bce_breakpoint(sc));
7336 
7337 	sc->bce_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
7338 
7339 	bce_init_locked(sc);
7340 	sc->bce_ifp->if_oerrors++;
7341 
7342 bce_watchdog_exit:
7343 	DBEXIT(BCE_EXTREME_SEND);
7344 }
7345 
7346 
7347 /*
7348  * Interrupt handler.
7349  */
7350 /****************************************************************************/
7351 /* Main interrupt entry point.  Verifies that the controller generated the  */
7352 /* interrupt and then calls a separate routine for handle the various       */
7353 /* interrupt causes (PHY, TX, RX).                                          */
7354 /*                                                                          */
7355 /* Returns:                                                                 */
7356 /*   0 for success, positive value for failure.                             */
7357 /****************************************************************************/
7358 static void
7359 bce_intr(void *xsc)
7360 {
7361 	struct bce_softc *sc;
7362 	struct ifnet *ifp;
7363 	u32 status_attn_bits;
7364 	u16 hw_rx_cons, hw_tx_cons;
7365 
7366 	sc = xsc;
7367 	ifp = sc->bce_ifp;
7368 
7369 	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
7370 	DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_status_block(sc));
7371 	DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_stats_block(sc));
7372 
7373 	BCE_LOCK(sc);
7374 
7375 	DBRUN(sc->interrupts_generated++);
7376 
7377 	/* Synchnorize before we read from interface's status block */
7378 	bus_dmamap_sync(sc->status_tag, sc->status_map,
7379 	    BUS_DMASYNC_POSTREAD);
7380 
7381 	/*
7382 	 * If the hardware status block index
7383 	 * matches the last value read by the
7384 	 * driver and we haven't asserted our
7385 	 * interrupt then there's nothing to do.
7386 	 */
7387 	if ((sc->status_block->status_idx == sc->last_status_idx) &&
7388 	    (REG_RD(sc, BCE_PCICFG_MISC_STATUS) &
7389 	     BCE_PCICFG_MISC_STATUS_INTA_VALUE)) {
7390 		DBPRINT(sc, BCE_VERBOSE_INTR, "%s(): Spurious interrupt.\n",
7391 		    __FUNCTION__);
7392 		goto bce_intr_exit;
7393 	}
7394 
7395 	/* Ack the interrupt and stop others from occuring. */
7396 	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
7397 	    BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
7398 	    BCE_PCICFG_INT_ACK_CMD_MASK_INT);
7399 
7400 	/* Check if the hardware has finished any work. */
7401 	hw_rx_cons = bce_get_hw_rx_cons(sc);
7402 	hw_tx_cons = bce_get_hw_tx_cons(sc);
7403 
7404 	/* Keep processing data as long as there is work to do. */
7405 	for (;;) {
7406 
7407 		status_attn_bits = sc->status_block->status_attn_bits;
7408 
7409 		DBRUNIF(DB_RANDOMTRUE(unexpected_attention_sim_control),
7410 		    BCE_PRINTF("Simulating unexpected status attention "
7411 		    "bit set.");
7412 		    sc->unexpected_attention_sim_count++;
7413 		    status_attn_bits = status_attn_bits |
7414 		    STATUS_ATTN_BITS_PARITY_ERROR);
7415 
7416 		/* Was it a link change interrupt? */
7417 		if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
7418 		    (sc->status_block->status_attn_bits_ack &
7419 		     STATUS_ATTN_BITS_LINK_STATE)) {
7420 			bce_phy_intr(sc);
7421 
7422 			/* Clear transient updates during link state change. */
7423 			REG_WR(sc, BCE_HC_COMMAND, sc->hc_command |
7424 			    BCE_HC_COMMAND_COAL_NOW_WO_INT);
7425 			REG_RD(sc, BCE_HC_COMMAND);
7426 		}
7427 
7428 		/* If any other attention is asserted, the chip is toast. */
7429 		if (((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
7430 		    (sc->status_block->status_attn_bits_ack &
7431 		    ~STATUS_ATTN_BITS_LINK_STATE))) {
7432 
7433 			sc->unexpected_attention_count++;
7434 
7435 			BCE_PRINTF("%s(%d): Fatal attention detected: "
7436 			    "0x%08X\n",	__FILE__, __LINE__,
7437 			    sc->status_block->status_attn_bits);
7438 
7439 			DBRUNMSG(BCE_FATAL,
7440 			    if (unexpected_attention_sim_control == 0)
7441 				bce_breakpoint(sc));
7442 
7443 			bce_init_locked(sc);
7444 			goto bce_intr_exit;
7445 		}
7446 
7447 		/* Check for any completed RX frames. */
7448 		if (hw_rx_cons != sc->hw_rx_cons)
7449 			bce_rx_intr(sc);
7450 
7451 		/* Check for any completed TX frames. */
7452 		if (hw_tx_cons != sc->hw_tx_cons)
7453 			bce_tx_intr(sc);
7454 
7455 		/* Save status block index value for the next interrupt. */
7456 		sc->last_status_idx = sc->status_block->status_idx;
7457 
7458  		/*
7459  		 * Prevent speculative reads from getting
7460  		 * ahead of the status block.
7461 		 */
7462 		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
7463 		    BUS_SPACE_BARRIER_READ);
7464 
7465  		/*
7466  		 * If there's no work left then exit the
7467  		 * interrupt service routine.
7468 		 */
7469 		hw_rx_cons = bce_get_hw_rx_cons(sc);
7470 		hw_tx_cons = bce_get_hw_tx_cons(sc);
7471 
7472 		if ((hw_rx_cons == sc->hw_rx_cons) &&
7473 		    (hw_tx_cons == sc->hw_tx_cons))
7474 			break;
7475 
7476 	}
7477 
7478 	bus_dmamap_sync(sc->status_tag,	sc->status_map,
7479 	    BUS_DMASYNC_PREREAD);
7480 
7481 	/* Re-enable interrupts. */
7482 	bce_enable_intr(sc, 0);
7483 
7484 	/* Handle any frames that arrived while handling the interrupt. */
7485 	if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
7486 	    !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
7487 		bce_start_locked(ifp);
7488 
7489 bce_intr_exit:
7490 	BCE_UNLOCK(sc);
7491 
7492 	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
7493 }
7494 
7495 
7496 /****************************************************************************/
7497 /* Programs the various packet receive modes (broadcast and multicast).     */
7498 /*                                                                          */
7499 /* Returns:                                                                 */
7500 /*   Nothing.                                                               */
7501 /****************************************************************************/
7502 static void
7503 bce_set_rx_mode(struct bce_softc *sc)
7504 {
7505 	struct ifnet *ifp;
7506 	struct ifmultiaddr *ifma;
7507 	u32 hashes[NUM_MC_HASH_REGISTERS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
7508 	u32 rx_mode, sort_mode;
7509 	int h, i;
7510 
7511 	DBENTER(BCE_VERBOSE_MISC);
7512 
7513 	BCE_LOCK_ASSERT(sc);
7514 
7515 	ifp = sc->bce_ifp;
7516 
7517 	/* Initialize receive mode default settings. */
7518 	rx_mode   = sc->rx_mode & ~(BCE_EMAC_RX_MODE_PROMISCUOUS |
7519 	    BCE_EMAC_RX_MODE_KEEP_VLAN_TAG);
7520 	sort_mode = 1 | BCE_RPM_SORT_USER0_BC_EN;
7521 
7522 	/*
7523 	 * ASF/IPMI/UMP firmware requires that VLAN tag stripping
7524 	 * be enbled.
7525 	 */
7526 	if (!(BCE_IF_CAPABILITIES & IFCAP_VLAN_HWTAGGING) &&
7527 	    (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)))
7528 		rx_mode |= BCE_EMAC_RX_MODE_KEEP_VLAN_TAG;
7529 
7530 	/*
7531 	 * Check for promiscuous, all multicast, or selected
7532 	 * multicast address filtering.
7533 	 */
7534 	if (ifp->if_flags & IFF_PROMISC) {
7535 		DBPRINT(sc, BCE_INFO_MISC, "Enabling promiscuous mode.\n");
7536 
7537 		/* Enable promiscuous mode. */
7538 		rx_mode |= BCE_EMAC_RX_MODE_PROMISCUOUS;
7539 		sort_mode |= BCE_RPM_SORT_USER0_PROM_EN;
7540 	} else if (ifp->if_flags & IFF_ALLMULTI) {
7541 		DBPRINT(sc, BCE_INFO_MISC, "Enabling all multicast mode.\n");
7542 
7543 		/* Enable all multicast addresses. */
7544 		for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
7545 			REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), 0xffffffff);
7546        	}
7547 		sort_mode |= BCE_RPM_SORT_USER0_MC_EN;
7548 	} else {
7549 		/* Accept one or more multicast(s). */
7550 		DBPRINT(sc, BCE_INFO_MISC, "Enabling selective multicast mode.\n");
7551 
7552 		if_maddr_rlock(ifp);
7553 		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
7554 			if (ifma->ifma_addr->sa_family != AF_LINK)
7555 				continue;
7556 			h = ether_crc32_le(LLADDR((struct sockaddr_dl *)
7557 			    ifma->ifma_addr), ETHER_ADDR_LEN) & 0xFF;
7558 			    hashes[(h & 0xE0) >> 5] |= 1 << (h & 0x1F);
7559 		}
7560 		if_maddr_runlock(ifp);
7561 
7562 		for (i = 0; i < NUM_MC_HASH_REGISTERS; i++)
7563 			REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), hashes[i]);
7564 
7565 		sort_mode |= BCE_RPM_SORT_USER0_MC_HSH_EN;
7566 	}
7567 
7568 	/* Only make changes if the recive mode has actually changed. */
7569 	if (rx_mode != sc->rx_mode) {
7570 		DBPRINT(sc, BCE_VERBOSE_MISC, "Enabling new receive mode: "
7571 		    "0x%08X\n", rx_mode);
7572 
7573 		sc->rx_mode = rx_mode;
7574 		REG_WR(sc, BCE_EMAC_RX_MODE, rx_mode);
7575 	}
7576 
7577 	/* Disable and clear the exisitng sort before enabling a new sort. */
7578 	REG_WR(sc, BCE_RPM_SORT_USER0, 0x0);
7579 	REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode);
7580 	REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode | BCE_RPM_SORT_USER0_ENA);
7581 
7582 	DBEXIT(BCE_VERBOSE_MISC);
7583 }
7584 
7585 
7586 /****************************************************************************/
7587 /* Called periodically to updates statistics from the controllers           */
7588 /* statistics block.                                                        */
7589 /*                                                                          */
7590 /* Returns:                                                                 */
7591 /*   Nothing.                                                               */
7592 /****************************************************************************/
7593 static void
7594 bce_stats_update(struct bce_softc *sc)
7595 {
7596 	struct ifnet *ifp;
7597 	struct statistics_block *stats;
7598 
7599 	DBENTER(BCE_EXTREME_MISC);
7600 
7601 	ifp = sc->bce_ifp;
7602 
7603 	stats = (struct statistics_block *) sc->stats_block;
7604 
7605 	/*
7606 	 * Certain controllers don't report
7607 	 * carrier sense errors correctly.
7608 	 * See errata E11_5708CA0_1165.
7609 	 */
7610 	if (!(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
7611 	    !(BCE_CHIP_ID(sc) == BCE_CHIP_ID_5708_A0))
7612 		ifp->if_oerrors +=
7613 		    (u_long) stats->stat_Dot3StatsCarrierSenseErrors;
7614 
7615 	/*
7616 	 * Update the sysctl statistics from the
7617 	 * hardware statistics.
7618 	 */
7619 	sc->stat_IfHCInOctets =
7620 	    ((u64) stats->stat_IfHCInOctets_hi << 32) +
7621 	     (u64) stats->stat_IfHCInOctets_lo;
7622 
7623 	sc->stat_IfHCInBadOctets =
7624 	    ((u64) stats->stat_IfHCInBadOctets_hi << 32) +
7625 	     (u64) stats->stat_IfHCInBadOctets_lo;
7626 
7627 	sc->stat_IfHCOutOctets =
7628 	    ((u64) stats->stat_IfHCOutOctets_hi << 32) +
7629 	     (u64) stats->stat_IfHCOutOctets_lo;
7630 
7631 	sc->stat_IfHCOutBadOctets =
7632 	    ((u64) stats->stat_IfHCOutBadOctets_hi << 32) +
7633 	     (u64) stats->stat_IfHCOutBadOctets_lo;
7634 
7635 	sc->stat_IfHCInUcastPkts =
7636 	    ((u64) stats->stat_IfHCInUcastPkts_hi << 32) +
7637 	     (u64) stats->stat_IfHCInUcastPkts_lo;
7638 
7639 	sc->stat_IfHCInMulticastPkts =
7640 	    ((u64) stats->stat_IfHCInMulticastPkts_hi << 32) +
7641 	     (u64) stats->stat_IfHCInMulticastPkts_lo;
7642 
7643 	sc->stat_IfHCInBroadcastPkts =
7644 	    ((u64) stats->stat_IfHCInBroadcastPkts_hi << 32) +
7645 	     (u64) stats->stat_IfHCInBroadcastPkts_lo;
7646 
7647 	sc->stat_IfHCOutUcastPkts =
7648 	    ((u64) stats->stat_IfHCOutUcastPkts_hi << 32) +
7649 	     (u64) stats->stat_IfHCOutUcastPkts_lo;
7650 
7651 	sc->stat_IfHCOutMulticastPkts =
7652 	    ((u64) stats->stat_IfHCOutMulticastPkts_hi << 32) +
7653 	     (u64) stats->stat_IfHCOutMulticastPkts_lo;
7654 
7655 	sc->stat_IfHCOutBroadcastPkts =
7656 	    ((u64) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
7657 	     (u64) stats->stat_IfHCOutBroadcastPkts_lo;
7658 
7659 	/* ToDo: Preserve counters beyond 32 bits? */
7660 	/* ToDo: Read the statistics from auto-clear regs? */
7661 
7662 	sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors =
7663 	    stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
7664 
7665 	sc->stat_Dot3StatsCarrierSenseErrors =
7666 	    stats->stat_Dot3StatsCarrierSenseErrors;
7667 
7668 	sc->stat_Dot3StatsFCSErrors =
7669 	    stats->stat_Dot3StatsFCSErrors;
7670 
7671 	sc->stat_Dot3StatsAlignmentErrors =
7672 	    stats->stat_Dot3StatsAlignmentErrors;
7673 
7674 	sc->stat_Dot3StatsSingleCollisionFrames =
7675 	    stats->stat_Dot3StatsSingleCollisionFrames;
7676 
7677 	sc->stat_Dot3StatsMultipleCollisionFrames =
7678 	    stats->stat_Dot3StatsMultipleCollisionFrames;
7679 
7680 	sc->stat_Dot3StatsDeferredTransmissions =
7681 	    stats->stat_Dot3StatsDeferredTransmissions;
7682 
7683 	sc->stat_Dot3StatsExcessiveCollisions =
7684 	    stats->stat_Dot3StatsExcessiveCollisions;
7685 
7686 	sc->stat_Dot3StatsLateCollisions =
7687 	    stats->stat_Dot3StatsLateCollisions;
7688 
7689 	sc->stat_EtherStatsCollisions =
7690 	    stats->stat_EtherStatsCollisions;
7691 
7692 	sc->stat_EtherStatsFragments =
7693 	    stats->stat_EtherStatsFragments;
7694 
7695 	sc->stat_EtherStatsJabbers =
7696 	    stats->stat_EtherStatsJabbers;
7697 
7698 	sc->stat_EtherStatsUndersizePkts =
7699 	    stats->stat_EtherStatsUndersizePkts;
7700 
7701 	sc->stat_EtherStatsOversizePkts =
7702 	     stats->stat_EtherStatsOversizePkts;
7703 
7704 	sc->stat_EtherStatsPktsRx64Octets =
7705 	    stats->stat_EtherStatsPktsRx64Octets;
7706 
7707 	sc->stat_EtherStatsPktsRx65Octetsto127Octets =
7708 	    stats->stat_EtherStatsPktsRx65Octetsto127Octets;
7709 
7710 	sc->stat_EtherStatsPktsRx128Octetsto255Octets =
7711 	    stats->stat_EtherStatsPktsRx128Octetsto255Octets;
7712 
7713 	sc->stat_EtherStatsPktsRx256Octetsto511Octets =
7714 	    stats->stat_EtherStatsPktsRx256Octetsto511Octets;
7715 
7716 	sc->stat_EtherStatsPktsRx512Octetsto1023Octets =
7717 	    stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
7718 
7719 	sc->stat_EtherStatsPktsRx1024Octetsto1522Octets =
7720 	    stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
7721 
7722 	sc->stat_EtherStatsPktsRx1523Octetsto9022Octets =
7723 	    stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
7724 
7725 	sc->stat_EtherStatsPktsTx64Octets =
7726 	    stats->stat_EtherStatsPktsTx64Octets;
7727 
7728 	sc->stat_EtherStatsPktsTx65Octetsto127Octets =
7729 	    stats->stat_EtherStatsPktsTx65Octetsto127Octets;
7730 
7731 	sc->stat_EtherStatsPktsTx128Octetsto255Octets =
7732 	    stats->stat_EtherStatsPktsTx128Octetsto255Octets;
7733 
7734 	sc->stat_EtherStatsPktsTx256Octetsto511Octets =
7735 	    stats->stat_EtherStatsPktsTx256Octetsto511Octets;
7736 
7737 	sc->stat_EtherStatsPktsTx512Octetsto1023Octets =
7738 	    stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
7739 
7740 	sc->stat_EtherStatsPktsTx1024Octetsto1522Octets =
7741 	    stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
7742 
7743 	sc->stat_EtherStatsPktsTx1523Octetsto9022Octets =
7744 	    stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
7745 
7746 	sc->stat_XonPauseFramesReceived =
7747 	    stats->stat_XonPauseFramesReceived;
7748 
7749 	sc->stat_XoffPauseFramesReceived =
7750 	    stats->stat_XoffPauseFramesReceived;
7751 
7752 	sc->stat_OutXonSent =
7753 	    stats->stat_OutXonSent;
7754 
7755 	sc->stat_OutXoffSent =
7756 	    stats->stat_OutXoffSent;
7757 
7758 	sc->stat_FlowControlDone =
7759 	    stats->stat_FlowControlDone;
7760 
7761 	sc->stat_MacControlFramesReceived =
7762 	    stats->stat_MacControlFramesReceived;
7763 
7764 	sc->stat_XoffStateEntered =
7765 	    stats->stat_XoffStateEntered;
7766 
7767 	sc->stat_IfInFramesL2FilterDiscards =
7768 	    stats->stat_IfInFramesL2FilterDiscards;
7769 
7770 	sc->stat_IfInRuleCheckerDiscards =
7771 	    stats->stat_IfInRuleCheckerDiscards;
7772 
7773 	sc->stat_IfInFTQDiscards =
7774 	    stats->stat_IfInFTQDiscards;
7775 
7776 	sc->stat_IfInMBUFDiscards =
7777 	    stats->stat_IfInMBUFDiscards;
7778 
7779 	sc->stat_IfInRuleCheckerP4Hit =
7780 	    stats->stat_IfInRuleCheckerP4Hit;
7781 
7782 	sc->stat_CatchupInRuleCheckerDiscards =
7783 	    stats->stat_CatchupInRuleCheckerDiscards;
7784 
7785 	sc->stat_CatchupInFTQDiscards =
7786 	    stats->stat_CatchupInFTQDiscards;
7787 
7788 	sc->stat_CatchupInMBUFDiscards =
7789 	    stats->stat_CatchupInMBUFDiscards;
7790 
7791 	sc->stat_CatchupInRuleCheckerP4Hit =
7792 	    stats->stat_CatchupInRuleCheckerP4Hit;
7793 
7794 	sc->com_no_buffers = REG_RD_IND(sc, 0x120084);
7795 
7796 	/*
7797 	 * Update the interface statistics from the
7798 	 * hardware statistics.
7799 	 */
7800 	ifp->if_collisions =
7801 	    (u_long) sc->stat_EtherStatsCollisions;
7802 
7803 	/* ToDo: This method loses soft errors. */
7804 	ifp->if_ierrors =
7805 	    (u_long) sc->stat_EtherStatsUndersizePkts +
7806 	    (u_long) sc->stat_EtherStatsOversizePkts +
7807 	    (u_long) sc->stat_IfInMBUFDiscards +
7808 	    (u_long) sc->stat_Dot3StatsAlignmentErrors +
7809 	    (u_long) sc->stat_Dot3StatsFCSErrors +
7810 	    (u_long) sc->stat_IfInRuleCheckerDiscards +
7811 	    (u_long) sc->stat_IfInFTQDiscards +
7812 	    (u_long) sc->com_no_buffers;
7813 
7814 	/* ToDo: This method loses soft errors. */
7815 	ifp->if_oerrors =
7816 	    (u_long) sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
7817 	    (u_long) sc->stat_Dot3StatsExcessiveCollisions +
7818 	    (u_long) sc->stat_Dot3StatsLateCollisions;
7819 
7820 	/* ToDo: Add additional statistics? */
7821 
7822 	DBEXIT(BCE_EXTREME_MISC);
7823 }
7824 
7825 
7826 /****************************************************************************/
7827 /* Periodic function to notify the bootcode that the driver is still        */
7828 /* present.                                                                 */
7829 /*                                                                          */
7830 /* Returns:                                                                 */
7831 /*   Nothing.                                                               */
7832 /****************************************************************************/
7833 static void
7834 bce_pulse(void *xsc)
7835 {
7836 	struct bce_softc *sc = xsc;
7837 	u32 msg;
7838 
7839 	DBENTER(BCE_EXTREME_MISC);
7840 
7841 	BCE_LOCK_ASSERT(sc);
7842 
7843 	/* Tell the firmware that the driver is still running. */
7844 	msg = (u32) ++sc->bce_fw_drv_pulse_wr_seq;
7845 	bce_shmem_wr(sc, BCE_DRV_PULSE_MB, msg);
7846 
7847 	/* Update the bootcode condition. */
7848 	sc->bc_state = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
7849 
7850 	/* Report whether the bootcode still knows the driver is running. */
7851 	if (bootverbose) {
7852 		if (sc->bce_drv_cardiac_arrest == FALSE) {
7853 			if (!(sc->bc_state & BCE_CONDITION_DRV_PRESENT)) {
7854 				sc->bce_drv_cardiac_arrest = TRUE;
7855 				BCE_PRINTF("%s(): Warning: bootcode "
7856 				    "thinks driver is absent! "
7857 				    "(bc_state = 0x%08X)\n",
7858 				    __FUNCTION__, sc->bc_state);
7859 			}
7860 		} else {
7861 			/*
7862 			 * Not supported by all bootcode versions.
7863 			 * (v5.0.11+ and v5.2.1+)  Older bootcode
7864 			 * will require the driver to reset the
7865 			 * controller to clear this condition.
7866 			 */
7867 			if (sc->bc_state & BCE_CONDITION_DRV_PRESENT) {
7868 				sc->bce_drv_cardiac_arrest = FALSE;
7869 				BCE_PRINTF("%s(): Bootcode found the "
7870 				    "driver pulse! (bc_state = 0x%08X)\n",
7871 				    __FUNCTION__, sc->bc_state);
7872 			}
7873 		}
7874 	}
7875 
7876 
7877 	/* Schedule the next pulse. */
7878 	callout_reset(&sc->bce_pulse_callout, hz, bce_pulse, sc);
7879 
7880 	DBEXIT(BCE_EXTREME_MISC);
7881 }
7882 
7883 
7884 /****************************************************************************/
7885 /* Periodic function to perform maintenance tasks.                          */
7886 /*                                                                          */
7887 /* Returns:                                                                 */
7888 /*   Nothing.                                                               */
7889 /****************************************************************************/
7890 static void
7891 bce_tick(void *xsc)
7892 {
7893 	struct bce_softc *sc = xsc;
7894 	struct mii_data *mii;
7895 	struct ifnet *ifp;
7896 
7897 	ifp = sc->bce_ifp;
7898 
7899 	DBENTER(BCE_EXTREME_MISC);
7900 
7901 	BCE_LOCK_ASSERT(sc);
7902 
7903 	/* Schedule the next tick. */
7904 	callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
7905 
7906 	/* Update the statistics from the hardware statistics block. */
7907 	bce_stats_update(sc);
7908 
7909 	/* Top off the receive and page chains. */
7910 #ifdef BCE_JUMBO_HDRSPLIT
7911 	bce_fill_pg_chain(sc);
7912 #endif
7913 	bce_fill_rx_chain(sc);
7914 
7915 	/* Check that chip hasn't hung. */
7916 	bce_watchdog(sc);
7917 
7918 	/* If link is up already up then we're done. */
7919 	if (sc->bce_link_up == TRUE)
7920 		goto bce_tick_exit;
7921 
7922 	/* Link is down.  Check what the PHY's doing. */
7923 	mii = device_get_softc(sc->bce_miibus);
7924 	mii_tick(mii);
7925 
7926 	/* Check if the link has come up. */
7927 	if ((mii->mii_media_status & IFM_ACTIVE) &&
7928 	    (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)) {
7929 		DBPRINT(sc, BCE_VERBOSE_MISC,
7930 		    "%s(): Link up!\n", __FUNCTION__);
7931 		sc->bce_link_up = TRUE;
7932 		if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
7933 		    IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX ||
7934 		    IFM_SUBTYPE(mii->mii_media_active) == IFM_2500_SX) &&
7935 		    bootverbose)
7936 			BCE_PRINTF("Gigabit link up!\n");
7937 
7938 		/* Now that link is up, handle any outstanding TX traffic. */
7939 		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
7940 			DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Found "
7941 			    "pending TX traffic.\n", __FUNCTION__);
7942 			bce_start_locked(ifp);
7943 		}
7944 	}
7945 
7946 bce_tick_exit:
7947 	DBEXIT(BCE_EXTREME_MISC);
7948 	return;
7949 }
7950 
7951 
7952 #ifdef BCE_DEBUG
7953 /****************************************************************************/
7954 /* Allows the driver state to be dumped through the sysctl interface.       */
7955 /*                                                                          */
7956 /* Returns:                                                                 */
7957 /*   0 for success, positive value for failure.                             */
7958 /****************************************************************************/
7959 static int
7960 bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS)
7961 {
7962 	int error;
7963 	int result;
7964 	struct bce_softc *sc;
7965 
7966 	result = -1;
7967 	error = sysctl_handle_int(oidp, &result, 0, req);
7968 
7969 	if (error || !req->newptr)
7970 		return (error);
7971 
7972 	if (result == 1) {
7973 		sc = (struct bce_softc *)arg1;
7974 		bce_dump_driver_state(sc);
7975 	}
7976 
7977 	return error;
7978 }
7979 
7980 
7981 /****************************************************************************/
7982 /* Allows the hardware state to be dumped through the sysctl interface.     */
7983 /*                                                                          */
7984 /* Returns:                                                                 */
7985 /*   0 for success, positive value for failure.                             */
7986 /****************************************************************************/
7987 static int
7988 bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS)
7989 {
7990 	int error;
7991 	int result;
7992 	struct bce_softc *sc;
7993 
7994 	result = -1;
7995 	error = sysctl_handle_int(oidp, &result, 0, req);
7996 
7997 	if (error || !req->newptr)
7998 		return (error);
7999 
8000 	if (result == 1) {
8001 		sc = (struct bce_softc *)arg1;
8002 		bce_dump_hw_state(sc);
8003 	}
8004 
8005 	return error;
8006 }
8007 
8008 
8009 /****************************************************************************/
8010 /* Allows the status block to be dumped through the sysctl interface.       */
8011 /*                                                                          */
8012 /* Returns:                                                                 */
8013 /*   0 for success, positive value for failure.                             */
8014 /****************************************************************************/
8015 static int
8016 bce_sysctl_status_block(SYSCTL_HANDLER_ARGS)
8017 {
8018 	int error;
8019 	int result;
8020 	struct bce_softc *sc;
8021 
8022 	result = -1;
8023 	error = sysctl_handle_int(oidp, &result, 0, req);
8024 
8025 	if (error || !req->newptr)
8026 		return (error);
8027 
8028 	if (result == 1) {
8029 		sc = (struct bce_softc *)arg1;
8030 		bce_dump_status_block(sc);
8031 	}
8032 
8033 	return error;
8034 }
8035 
8036 
8037 /****************************************************************************/
8038 /* Allows the stats block to be dumped through the sysctl interface.        */
8039 /*                                                                          */
8040 /* Returns:                                                                 */
8041 /*   0 for success, positive value for failure.                             */
8042 /****************************************************************************/
8043 static int
8044 bce_sysctl_stats_block(SYSCTL_HANDLER_ARGS)
8045 {
8046 	int error;
8047 	int result;
8048 	struct bce_softc *sc;
8049 
8050 	result = -1;
8051 	error = sysctl_handle_int(oidp, &result, 0, req);
8052 
8053 	if (error || !req->newptr)
8054 		return (error);
8055 
8056 	if (result == 1) {
8057 		sc = (struct bce_softc *)arg1;
8058 		bce_dump_stats_block(sc);
8059 	}
8060 
8061 	return error;
8062 }
8063 
8064 
8065 /****************************************************************************/
8066 /* Allows the stat counters to be cleared without unloading/reloading the   */
8067 /* driver.                                                                  */
8068 /*                                                                          */
8069 /* Returns:                                                                 */
8070 /*   0 for success, positive value for failure.                             */
8071 /****************************************************************************/
8072 static int
8073 bce_sysctl_stats_clear(SYSCTL_HANDLER_ARGS)
8074 {
8075 	int error;
8076 	int result;
8077 	struct bce_softc *sc;
8078 
8079 	result = -1;
8080 	error = sysctl_handle_int(oidp, &result, 0, req);
8081 
8082 	if (error || !req->newptr)
8083 		return (error);
8084 
8085 	if (result == 1) {
8086 		sc = (struct bce_softc *)arg1;
8087 
8088 		/* Clear the internal H/W statistics counters. */
8089 		REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
8090 
8091 		/* Reset the driver maintained statistics. */
8092 		sc->interrupts_rx =
8093 		    sc->interrupts_tx = 0;
8094 		sc->tso_frames_requested =
8095 		    sc->tso_frames_completed =
8096 		    sc->tso_frames_failed = 0;
8097 		sc->rx_empty_count =
8098 		    sc->tx_full_count = 0;
8099 		sc->rx_low_watermark = USABLE_RX_BD;
8100 		sc->tx_hi_watermark = 0;
8101 		sc->l2fhdr_error_count =
8102 		    sc->l2fhdr_error_sim_count = 0;
8103 		sc->mbuf_alloc_failed_count =
8104 		    sc->mbuf_alloc_failed_sim_count = 0;
8105 		sc->dma_map_addr_rx_failed_count =
8106 		    sc->dma_map_addr_tx_failed_count = 0;
8107 		sc->mbuf_frag_count = 0;
8108 		sc->csum_offload_tcp_udp =
8109 		   sc->csum_offload_ip = 0;
8110 		sc->vlan_tagged_frames_rcvd =
8111 		   sc->vlan_tagged_frames_stripped = 0;
8112 
8113 		/* Clear firmware maintained statistics. */
8114 		REG_WR_IND(sc, 0x120084, 0);
8115 	}
8116 
8117 	return error;
8118 }
8119 
8120 
8121 /****************************************************************************/
8122 /* Allows the bootcode state to be dumped through the sysctl interface.     */
8123 /*                                                                          */
8124 /* Returns:                                                                 */
8125 /*   0 for success, positive value for failure.                             */
8126 /****************************************************************************/
8127 static int
8128 bce_sysctl_bc_state(SYSCTL_HANDLER_ARGS)
8129 {
8130 	int error;
8131 	int result;
8132 	struct bce_softc *sc;
8133 
8134 	result = -1;
8135 	error = sysctl_handle_int(oidp, &result, 0, req);
8136 
8137 	if (error || !req->newptr)
8138 		return (error);
8139 
8140 	if (result == 1) {
8141 		sc = (struct bce_softc *)arg1;
8142 		bce_dump_bc_state(sc);
8143 	}
8144 
8145 	return error;
8146 }
8147 
8148 
8149 /****************************************************************************/
8150 /* Provides a sysctl interface to allow dumping the RX BD chain.            */
8151 /*                                                                          */
8152 /* Returns:                                                                 */
8153 /*   0 for success, positive value for failure.                             */
8154 /****************************************************************************/
8155 static int
8156 bce_sysctl_dump_rx_bd_chain(SYSCTL_HANDLER_ARGS)
8157 {
8158 	int error;
8159 	int result;
8160 	struct bce_softc *sc;
8161 
8162 	result = -1;
8163 	error = sysctl_handle_int(oidp, &result, 0, req);
8164 
8165 	if (error || !req->newptr)
8166 		return (error);
8167 
8168 	if (result == 1) {
8169 		sc = (struct bce_softc *)arg1;
8170 		bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD);
8171 	}
8172 
8173 	return error;
8174 }
8175 
8176 
8177 /****************************************************************************/
8178 /* Provides a sysctl interface to allow dumping the RX MBUF chain.          */
8179 /*                                                                          */
8180 /* Returns:                                                                 */
8181 /*   0 for success, positive value for failure.                             */
8182 /****************************************************************************/
8183 static int
8184 bce_sysctl_dump_rx_mbuf_chain(SYSCTL_HANDLER_ARGS)
8185 {
8186 	int error;
8187 	int result;
8188 	struct bce_softc *sc;
8189 
8190 	result = -1;
8191 	error = sysctl_handle_int(oidp, &result, 0, req);
8192 
8193 	if (error || !req->newptr)
8194 		return (error);
8195 
8196 	if (result == 1) {
8197 		sc = (struct bce_softc *)arg1;
8198 		bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD);
8199 	}
8200 
8201 	return error;
8202 }
8203 
8204 
8205 /****************************************************************************/
8206 /* Provides a sysctl interface to allow dumping the TX chain.               */
8207 /*                                                                          */
8208 /* Returns:                                                                 */
8209 /*   0 for success, positive value for failure.                             */
8210 /****************************************************************************/
8211 static int
8212 bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
8213 {
8214 	int error;
8215 	int result;
8216 	struct bce_softc *sc;
8217 
8218 	result = -1;
8219 	error = sysctl_handle_int(oidp, &result, 0, req);
8220 
8221 	if (error || !req->newptr)
8222 		return (error);
8223 
8224 	if (result == 1) {
8225 		sc = (struct bce_softc *)arg1;
8226 		bce_dump_tx_chain(sc, 0, TOTAL_TX_BD);
8227 	}
8228 
8229 	return error;
8230 }
8231 
8232 
8233 #ifdef BCE_JUMBO_HDRSPLIT
8234 /****************************************************************************/
8235 /* Provides a sysctl interface to allow dumping the page chain.             */
8236 /*                                                                          */
8237 /* Returns:                                                                 */
8238 /*   0 for success, positive value for failure.                             */
8239 /****************************************************************************/
8240 static int
8241 bce_sysctl_dump_pg_chain(SYSCTL_HANDLER_ARGS)
8242 {
8243 	int error;
8244 	int result;
8245 	struct bce_softc *sc;
8246 
8247 	result = -1;
8248 	error = sysctl_handle_int(oidp, &result, 0, req);
8249 
8250 	if (error || !req->newptr)
8251 		return (error);
8252 
8253 	if (result == 1) {
8254 		sc = (struct bce_softc *)arg1;
8255 		bce_dump_pg_chain(sc, 0, TOTAL_PG_BD);
8256 	}
8257 
8258 	return error;
8259 }
8260 #endif
8261 
8262 /****************************************************************************/
8263 /* Provides a sysctl interface to allow reading arbitrary NVRAM offsets in  */
8264 /* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
8265 /*                                                                          */
8266 /* Returns:                                                                 */
8267 /*   0 for success, positive value for failure.                             */
8268 /****************************************************************************/
8269 static int
8270 bce_sysctl_nvram_read(SYSCTL_HANDLER_ARGS)
8271 {
8272 	struct bce_softc *sc = (struct bce_softc *)arg1;
8273 	int error;
8274 	u32 result;
8275 	u32 val[1];
8276 	u8 *data = (u8 *) val;
8277 
8278 	result = -1;
8279 	error = sysctl_handle_int(oidp, &result, 0, req);
8280 	if (error || (req->newptr == NULL))
8281 		return (error);
8282 
8283 	bce_nvram_read(sc, result, data, 4);
8284 	BCE_PRINTF("offset 0x%08X = 0x%08X\n", result, bce_be32toh(val[0]));
8285 
8286 	return (error);
8287 }
8288 
8289 
8290 /****************************************************************************/
8291 /* Provides a sysctl interface to allow reading arbitrary registers in the  */
8292 /* device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                            */
8293 /*                                                                          */
8294 /* Returns:                                                                 */
8295 /*   0 for success, positive value for failure.                             */
8296 /****************************************************************************/
8297 static int
8298 bce_sysctl_reg_read(SYSCTL_HANDLER_ARGS)
8299 {
8300 	struct bce_softc *sc = (struct bce_softc *)arg1;
8301 	int error;
8302 	u32 val, result;
8303 
8304 	result = -1;
8305 	error = sysctl_handle_int(oidp, &result, 0, req);
8306 	if (error || (req->newptr == NULL))
8307 		return (error);
8308 
8309 	/* Make sure the register is accessible. */
8310 	if (result < 0x8000) {
8311 		val = REG_RD(sc, result);
8312 		BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
8313 	} else if (result < 0x0280000) {
8314 		val = REG_RD_IND(sc, result);
8315 		BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
8316 	}
8317 
8318 	return (error);
8319 }
8320 
8321 
8322 /****************************************************************************/
8323 /* Provides a sysctl interface to allow reading arbitrary PHY registers in  */
8324 /* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
8325 /*                                                                          */
8326 /* Returns:                                                                 */
8327 /*   0 for success, positive value for failure.                             */
8328 /****************************************************************************/
8329 static int
8330 bce_sysctl_phy_read(SYSCTL_HANDLER_ARGS)
8331 {
8332 	struct bce_softc *sc;
8333 	device_t dev;
8334 	int error, result;
8335 	u16 val;
8336 
8337 	result = -1;
8338 	error = sysctl_handle_int(oidp, &result, 0, req);
8339 	if (error || (req->newptr == NULL))
8340 		return (error);
8341 
8342 	/* Make sure the register is accessible. */
8343 	if (result < 0x20) {
8344 		sc = (struct bce_softc *)arg1;
8345 		dev = sc->bce_dev;
8346 		val = bce_miibus_read_reg(dev, sc->bce_phy_addr, result);
8347 		BCE_PRINTF("phy 0x%02X = 0x%04X\n", result, val);
8348 	}
8349 	return (error);
8350 }
8351 
8352 
8353 static int
8354 sysctl_nvram_dump(SYSCTL_HANDLER_ARGS)
8355 {
8356 	struct bce_softc *sc = (struct bce_softc *)arg1;
8357 	int error, i;
8358 
8359 	if (sc->nvram_buf == NULL) {
8360 		sc->nvram_buf = malloc(sc->bce_flash_size,
8361 				       M_TEMP, M_ZERO | M_WAITOK);
8362 	}
8363 	if (sc->nvram_buf == NULL) {
8364 		return(ENOMEM);
8365 	}
8366 	if (req->oldlen == sc->bce_flash_size) {
8367 		for (i = 0; i < sc->bce_flash_size; i++) {
8368 			bce_nvram_read(sc, i, &sc->nvram_buf[i], 1);
8369 		}
8370 	}
8371 
8372 	error = SYSCTL_OUT(req, sc->nvram_buf, sc->bce_flash_size);
8373 
8374 	return error;
8375 }
8376 
8377 #ifdef BCE_NVRAM_WRITE_SUPPORT
8378 static int
8379 sysctl_nvram_write(SYSCTL_HANDLER_ARGS)
8380 {
8381 	struct bce_softc *sc = (struct bce_softc *)arg1;
8382 	int error;
8383 
8384 	if (sc->nvram_buf == NULL) {
8385 		sc->nvram_buf = malloc(sc->bce_flash_size,
8386 				       M_TEMP, M_ZERO | M_WAITOK);
8387 	}
8388 	if (sc->nvram_buf == NULL) {
8389 		return(ENOMEM);
8390 	}
8391 	bzero(sc->nvram_buf, sc->bce_flash_size);
8392 	error = SYSCTL_IN(req, sc->nvram_buf, sc->bce_flash_size);
8393 
8394 	if (req->newlen == sc->bce_flash_size) {
8395 		bce_nvram_write(sc, 0, sc->nvram_buf , sc->bce_flash_size);
8396 	}
8397 
8398 
8399 	return error;
8400 }
8401 #endif
8402 
8403 
8404 /****************************************************************************/
8405 /* Provides a sysctl interface to allow reading a CID.                      */
8406 /*                                                                          */
8407 /* Returns:                                                                 */
8408 /*   0 for success, positive value for failure.                             */
8409 /****************************************************************************/
8410 static int
8411 bce_sysctl_dump_ctx(SYSCTL_HANDLER_ARGS)
8412 {
8413 	struct bce_softc *sc;
8414 	int error, result;
8415 
8416 	result = -1;
8417 	error = sysctl_handle_int(oidp, &result, 0, req);
8418 	if (error || (req->newptr == NULL))
8419 		return (error);
8420 
8421 	/* Make sure the register is accessible. */
8422 	if (result <= TX_CID) {
8423 		sc = (struct bce_softc *)arg1;
8424 		bce_dump_ctx(sc, result);
8425 	}
8426 
8427 	return (error);
8428 }
8429 
8430 
8431  /****************************************************************************/
8432 /* Provides a sysctl interface to forcing the driver to dump state and      */
8433 /* enter the debugger.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                */
8434 /*                                                                          */
8435 /* Returns:                                                                 */
8436 /*   0 for success, positive value for failure.                             */
8437 /****************************************************************************/
8438 static int
8439 bce_sysctl_breakpoint(SYSCTL_HANDLER_ARGS)
8440 {
8441 	int error;
8442 	int result;
8443 	struct bce_softc *sc;
8444 
8445 	result = -1;
8446 	error = sysctl_handle_int(oidp, &result, 0, req);
8447 
8448 	if (error || !req->newptr)
8449 		return (error);
8450 
8451 	if (result == 1) {
8452 		sc = (struct bce_softc *)arg1;
8453 		bce_breakpoint(sc);
8454 	}
8455 
8456 	return error;
8457 }
8458 #endif
8459 
8460 
8461 /****************************************************************************/
8462 /* Adds any sysctl parameters for tuning or debugging purposes.             */
8463 /*                                                                          */
8464 /* Returns:                                                                 */
8465 /*   0 for success, positive value for failure.                             */
8466 /****************************************************************************/
8467 static void
8468 bce_add_sysctls(struct bce_softc *sc)
8469 {
8470 	struct sysctl_ctx_list *ctx;
8471 	struct sysctl_oid_list *children;
8472 
8473 	DBENTER(BCE_VERBOSE_MISC);
8474 
8475 	ctx = device_get_sysctl_ctx(sc->bce_dev);
8476 	children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->bce_dev));
8477 
8478 #ifdef BCE_DEBUG
8479 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8480 	    "l2fhdr_error_sim_control",
8481 	    CTLFLAG_RW, &l2fhdr_error_sim_control,
8482 	    0, "Debug control to force l2fhdr errors");
8483 
8484 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8485 	    "l2fhdr_error_sim_count",
8486 	    CTLFLAG_RD, &sc->l2fhdr_error_sim_count,
8487 	    0, "Number of simulated l2_fhdr errors");
8488 #endif
8489 
8490 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8491 	    "l2fhdr_error_count",
8492 	    CTLFLAG_RD, &sc->l2fhdr_error_count,
8493 	    0, "Number of l2_fhdr errors");
8494 
8495 #ifdef BCE_DEBUG
8496 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8497 	    "mbuf_alloc_failed_sim_control",
8498 	    CTLFLAG_RW, &mbuf_alloc_failed_sim_control,
8499 	    0, "Debug control to force mbuf allocation failures");
8500 
8501 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8502 	    "mbuf_alloc_failed_sim_count",
8503 	    CTLFLAG_RD, &sc->mbuf_alloc_failed_sim_count,
8504 	    0, "Number of simulated mbuf cluster allocation failures");
8505 #endif
8506 
8507 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8508 	    "mbuf_alloc_failed_count",
8509 	    CTLFLAG_RD, &sc->mbuf_alloc_failed_count,
8510 	    0, "Number of mbuf allocation failures");
8511 
8512 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8513 	    "mbuf_frag_count",
8514 	    CTLFLAG_RD, &sc->mbuf_frag_count,
8515 	    0, "Number of fragmented mbufs");
8516 
8517 #ifdef BCE_DEBUG
8518 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8519 	    "dma_map_addr_failed_sim_control",
8520 	    CTLFLAG_RW, &dma_map_addr_failed_sim_control,
8521 	    0, "Debug control to force DMA mapping failures");
8522 
8523 	/* ToDo: Figure out how to update this value in bce_dma_map_addr(). */
8524 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8525 	    "dma_map_addr_failed_sim_count",
8526 	    CTLFLAG_RD, &sc->dma_map_addr_failed_sim_count,
8527 	    0, "Number of simulated DMA mapping failures");
8528 
8529 #endif
8530 
8531 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8532 	    "dma_map_addr_rx_failed_count",
8533 	    CTLFLAG_RD, &sc->dma_map_addr_rx_failed_count,
8534 	    0, "Number of RX DMA mapping failures");
8535 
8536 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8537 	    "dma_map_addr_tx_failed_count",
8538 	    CTLFLAG_RD, &sc->dma_map_addr_tx_failed_count,
8539 	    0, "Number of TX DMA mapping failures");
8540 
8541 #ifdef BCE_DEBUG
8542 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8543 	    "unexpected_attention_sim_control",
8544 	    CTLFLAG_RW, &unexpected_attention_sim_control,
8545 	    0, "Debug control to simulate unexpected attentions");
8546 
8547 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8548 	    "unexpected_attention_sim_count",
8549 	    CTLFLAG_RW, &sc->unexpected_attention_sim_count,
8550 	    0, "Number of simulated unexpected attentions");
8551 #endif
8552 
8553 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8554 	    "unexpected_attention_count",
8555 	    CTLFLAG_RW, &sc->unexpected_attention_count,
8556 	    0, "Number of unexpected attentions");
8557 
8558 #ifdef BCE_DEBUG
8559 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8560 	    "debug_bootcode_running_failure",
8561 	    CTLFLAG_RW, &bootcode_running_failure_sim_control,
8562 	    0, "Debug control to force bootcode running failures");
8563 
8564 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8565 	    "rx_low_watermark",
8566 	    CTLFLAG_RD, &sc->rx_low_watermark,
8567 	    0, "Lowest level of free rx_bd's");
8568 
8569 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8570 	    "rx_empty_count",
8571 	    CTLFLAG_RD, &sc->rx_empty_count,
8572 	    0, "Number of times the RX chain was empty");
8573 
8574 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8575 	    "tx_hi_watermark",
8576 	    CTLFLAG_RD, &sc->tx_hi_watermark,
8577 	    0, "Highest level of used tx_bd's");
8578 
8579 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8580 	    "tx_full_count",
8581 	    CTLFLAG_RD, &sc->tx_full_count,
8582 	    0, "Number of times the TX chain was full");
8583 
8584 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8585 	    "tso_frames_requested",
8586 	    CTLFLAG_RD, &sc->tso_frames_requested,
8587 	    0, "Number of TSO frames requested");
8588 
8589 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8590 	    "tso_frames_completed",
8591 	    CTLFLAG_RD, &sc->tso_frames_completed,
8592 	    0, "Number of TSO frames completed");
8593 
8594 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8595 	    "tso_frames_failed",
8596 	    CTLFLAG_RD, &sc->tso_frames_failed,
8597 	    0, "Number of TSO frames failed");
8598 
8599 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8600 	    "csum_offload_ip",
8601 	    CTLFLAG_RD, &sc->csum_offload_ip,
8602 	    0, "Number of IP checksum offload frames");
8603 
8604 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8605 	    "csum_offload_tcp_udp",
8606 	    CTLFLAG_RD, &sc->csum_offload_tcp_udp,
8607 	    0, "Number of TCP/UDP checksum offload frames");
8608 
8609 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8610 	    "vlan_tagged_frames_rcvd",
8611 	    CTLFLAG_RD, &sc->vlan_tagged_frames_rcvd,
8612 	    0, "Number of VLAN tagged frames received");
8613 
8614 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8615 	    "vlan_tagged_frames_stripped",
8616 	    CTLFLAG_RD, &sc->vlan_tagged_frames_stripped,
8617 	    0, "Number of VLAN tagged frames stripped");
8618 
8619 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8620 	    "interrupts_rx",
8621 	    CTLFLAG_RD, &sc->interrupts_rx,
8622 	    0, "Number of RX interrupts");
8623 
8624 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8625 	    "interrupts_tx",
8626 	    CTLFLAG_RD, &sc->interrupts_tx,
8627 	    0, "Number of TX interrupts");
8628 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8629 	    "nvram_dump", CTLTYPE_OPAQUE | CTLFLAG_RD,
8630 	    (void *)sc, 0,
8631 	    sysctl_nvram_dump, "S", "");
8632 #ifdef BCE_NVRAM_WRITE_SUPPORT
8633 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8634 	    "nvram_write", CTLTYPE_OPAQUE | CTLFLAG_WR,
8635 	    (void *)sc, 0,
8636 	    sysctl_nvram_write, "S", "");
8637 #endif
8638 #endif
8639 
8640 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8641 	    "stat_IfHcInOctets",
8642 	    CTLFLAG_RD, &sc->stat_IfHCInOctets,
8643 	    "Bytes received");
8644 
8645 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8646 	    "stat_IfHCInBadOctets",
8647 	    CTLFLAG_RD, &sc->stat_IfHCInBadOctets,
8648 	    "Bad bytes received");
8649 
8650 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8651 	    "stat_IfHCOutOctets",
8652 	    CTLFLAG_RD, &sc->stat_IfHCOutOctets,
8653 	    "Bytes sent");
8654 
8655 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8656 	    "stat_IfHCOutBadOctets",
8657 	    CTLFLAG_RD, &sc->stat_IfHCOutBadOctets,
8658 	    "Bad bytes sent");
8659 
8660 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8661 	    "stat_IfHCInUcastPkts",
8662 	    CTLFLAG_RD, &sc->stat_IfHCInUcastPkts,
8663 	    "Unicast packets received");
8664 
8665 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8666 	    "stat_IfHCInMulticastPkts",
8667 	    CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts,
8668 	    "Multicast packets received");
8669 
8670 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8671 	    "stat_IfHCInBroadcastPkts",
8672 	    CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts,
8673 	    "Broadcast packets received");
8674 
8675 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8676 	    "stat_IfHCOutUcastPkts",
8677 	    CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts,
8678 	    "Unicast packets sent");
8679 
8680 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8681 	    "stat_IfHCOutMulticastPkts",
8682 	    CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts,
8683 	    "Multicast packets sent");
8684 
8685 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8686 	    "stat_IfHCOutBroadcastPkts",
8687 	    CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts,
8688 	    "Broadcast packets sent");
8689 
8690 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8691 	    "stat_emac_tx_stat_dot3statsinternalmactransmiterrors",
8692 	    CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors,
8693 	    0, "Internal MAC transmit errors");
8694 
8695 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8696 	    "stat_Dot3StatsCarrierSenseErrors",
8697 	    CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors,
8698 	    0, "Carrier sense errors");
8699 
8700 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8701 	    "stat_Dot3StatsFCSErrors",
8702 	    CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors,
8703 	    0, "Frame check sequence errors");
8704 
8705 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8706 	    "stat_Dot3StatsAlignmentErrors",
8707 	    CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors,
8708 	    0, "Alignment errors");
8709 
8710 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8711 	    "stat_Dot3StatsSingleCollisionFrames",
8712 	    CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames,
8713 	    0, "Single Collision Frames");
8714 
8715 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8716 	    "stat_Dot3StatsMultipleCollisionFrames",
8717 	    CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames,
8718 	    0, "Multiple Collision Frames");
8719 
8720 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8721 	    "stat_Dot3StatsDeferredTransmissions",
8722 	    CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions,
8723 	    0, "Deferred Transmissions");
8724 
8725 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8726 	    "stat_Dot3StatsExcessiveCollisions",
8727 	    CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions,
8728 	    0, "Excessive Collisions");
8729 
8730 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8731 	    "stat_Dot3StatsLateCollisions",
8732 	    CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions,
8733 	    0, "Late Collisions");
8734 
8735 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8736 	    "stat_EtherStatsCollisions",
8737 	    CTLFLAG_RD, &sc->stat_EtherStatsCollisions,
8738 	    0, "Collisions");
8739 
8740 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8741 	    "stat_EtherStatsFragments",
8742 	    CTLFLAG_RD, &sc->stat_EtherStatsFragments,
8743 	    0, "Fragments");
8744 
8745 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8746 	    "stat_EtherStatsJabbers",
8747 	    CTLFLAG_RD, &sc->stat_EtherStatsJabbers,
8748 	    0, "Jabbers");
8749 
8750 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8751 	    "stat_EtherStatsUndersizePkts",
8752 	    CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts,
8753 	    0, "Undersize packets");
8754 
8755 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8756 	    "stat_EtherStatsOversizePkts",
8757 	    CTLFLAG_RD, &sc->stat_EtherStatsOversizePkts,
8758 	    0, "stat_EtherStatsOversizePkts");
8759 
8760 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8761 	    "stat_EtherStatsPktsRx64Octets",
8762 	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets,
8763 	    0, "Bytes received in 64 byte packets");
8764 
8765 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8766 	    "stat_EtherStatsPktsRx65Octetsto127Octets",
8767 	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets,
8768 	    0, "Bytes received in 65 to 127 byte packets");
8769 
8770 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8771 	    "stat_EtherStatsPktsRx128Octetsto255Octets",
8772 	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets,
8773 	    0, "Bytes received in 128 to 255 byte packets");
8774 
8775 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8776 	    "stat_EtherStatsPktsRx256Octetsto511Octets",
8777 	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets,
8778 	    0, "Bytes received in 256 to 511 byte packets");
8779 
8780 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8781 	    "stat_EtherStatsPktsRx512Octetsto1023Octets",
8782 	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets,
8783 	    0, "Bytes received in 512 to 1023 byte packets");
8784 
8785 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8786 	    "stat_EtherStatsPktsRx1024Octetsto1522Octets",
8787 	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets,
8788 	    0, "Bytes received in 1024 t0 1522 byte packets");
8789 
8790 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8791 	    "stat_EtherStatsPktsRx1523Octetsto9022Octets",
8792 	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets,
8793 	    0, "Bytes received in 1523 to 9022 byte packets");
8794 
8795 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8796 	    "stat_EtherStatsPktsTx64Octets",
8797 	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets,
8798 	    0, "Bytes sent in 64 byte packets");
8799 
8800 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8801 	    "stat_EtherStatsPktsTx65Octetsto127Octets",
8802 	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets,
8803 	    0, "Bytes sent in 65 to 127 byte packets");
8804 
8805 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8806 	    "stat_EtherStatsPktsTx128Octetsto255Octets",
8807 	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets,
8808 	    0, "Bytes sent in 128 to 255 byte packets");
8809 
8810 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8811 	    "stat_EtherStatsPktsTx256Octetsto511Octets",
8812 	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets,
8813 	    0, "Bytes sent in 256 to 511 byte packets");
8814 
8815 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8816 	    "stat_EtherStatsPktsTx512Octetsto1023Octets",
8817 	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets,
8818 	    0, "Bytes sent in 512 to 1023 byte packets");
8819 
8820 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8821 	    "stat_EtherStatsPktsTx1024Octetsto1522Octets",
8822 	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets,
8823 	    0, "Bytes sent in 1024 to 1522 byte packets");
8824 
8825 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8826 	    "stat_EtherStatsPktsTx1523Octetsto9022Octets",
8827 	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets,
8828 	    0, "Bytes sent in 1523 to 9022 byte packets");
8829 
8830 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8831 	    "stat_XonPauseFramesReceived",
8832 	    CTLFLAG_RD, &sc->stat_XonPauseFramesReceived,
8833 	    0, "XON pause frames receved");
8834 
8835 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8836 	    "stat_XoffPauseFramesReceived",
8837 	    CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived,
8838 	    0, "XOFF pause frames received");
8839 
8840 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8841 	    "stat_OutXonSent",
8842 	    CTLFLAG_RD, &sc->stat_OutXonSent,
8843 	    0, "XON pause frames sent");
8844 
8845 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8846 	    "stat_OutXoffSent",
8847 	    CTLFLAG_RD, &sc->stat_OutXoffSent,
8848 	    0, "XOFF pause frames sent");
8849 
8850 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8851 	    "stat_FlowControlDone",
8852 	    CTLFLAG_RD, &sc->stat_FlowControlDone,
8853 	    0, "Flow control done");
8854 
8855 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8856 	    "stat_MacControlFramesReceived",
8857 	    CTLFLAG_RD, &sc->stat_MacControlFramesReceived,
8858 	    0, "MAC control frames received");
8859 
8860 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8861 	    "stat_XoffStateEntered",
8862 	    CTLFLAG_RD, &sc->stat_XoffStateEntered,
8863 	    0, "XOFF state entered");
8864 
8865 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8866 	    "stat_IfInFramesL2FilterDiscards",
8867 	    CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards,
8868 	    0, "Received L2 packets discarded");
8869 
8870 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8871 	    "stat_IfInRuleCheckerDiscards",
8872 	    CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards,
8873 	    0, "Received packets discarded by rule");
8874 
8875 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8876 	    "stat_IfInFTQDiscards",
8877 	    CTLFLAG_RD, &sc->stat_IfInFTQDiscards,
8878 	    0, "Received packet FTQ discards");
8879 
8880 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8881 	    "stat_IfInMBUFDiscards",
8882 	    CTLFLAG_RD, &sc->stat_IfInMBUFDiscards,
8883 	    0, "Received packets discarded due to lack "
8884 	    "of controller buffer memory");
8885 
8886 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8887 	    "stat_IfInRuleCheckerP4Hit",
8888 	    CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit,
8889 	    0, "Received packets rule checker hits");
8890 
8891 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8892 	    "stat_CatchupInRuleCheckerDiscards",
8893 	    CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards,
8894 	    0, "Received packets discarded in Catchup path");
8895 
8896 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8897 	    "stat_CatchupInFTQDiscards",
8898 	    CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards,
8899 	    0, "Received packets discarded in FTQ in Catchup path");
8900 
8901 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8902 	    "stat_CatchupInMBUFDiscards",
8903 	    CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards,
8904 	    0, "Received packets discarded in controller "
8905 	    "buffer memory in Catchup path");
8906 
8907 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8908 	    "stat_CatchupInRuleCheckerP4Hit",
8909 	    CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit,
8910 	    0, "Received packets rule checker hits in Catchup path");
8911 
8912 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8913 	    "com_no_buffers",
8914 	    CTLFLAG_RD, &sc->com_no_buffers,
8915 	    0, "Valid packets received but no RX buffers available");
8916 
8917 #ifdef BCE_DEBUG
8918 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8919 	    "driver_state", CTLTYPE_INT | CTLFLAG_RW,
8920 	    (void *)sc, 0,
8921 	    bce_sysctl_driver_state, "I", "Drive state information");
8922 
8923 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8924 	    "hw_state", CTLTYPE_INT | CTLFLAG_RW,
8925 	    (void *)sc, 0,
8926 	    bce_sysctl_hw_state, "I", "Hardware state information");
8927 
8928 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8929 	    "status_block", CTLTYPE_INT | CTLFLAG_RW,
8930 	    (void *)sc, 0,
8931 	    bce_sysctl_status_block, "I", "Dump status block");
8932 
8933 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8934 	    "stats_block", CTLTYPE_INT | CTLFLAG_RW,
8935 	    (void *)sc, 0,
8936 	    bce_sysctl_stats_block, "I", "Dump statistics block");
8937 
8938 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8939 	    "stats_clear", CTLTYPE_INT | CTLFLAG_RW,
8940 	    (void *)sc, 0,
8941 	    bce_sysctl_stats_clear, "I", "Clear statistics block");
8942 
8943 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8944 	    "bc_state", CTLTYPE_INT | CTLFLAG_RW,
8945 	    (void *)sc, 0,
8946 	    bce_sysctl_bc_state, "I", "Bootcode state information");
8947 
8948 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8949 	    "dump_rx_bd_chain", CTLTYPE_INT | CTLFLAG_RW,
8950 	    (void *)sc, 0,
8951 	    bce_sysctl_dump_rx_bd_chain, "I", "Dump RX BD chain");
8952 
8953 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8954 	    "dump_rx_mbuf_chain", CTLTYPE_INT | CTLFLAG_RW,
8955 	    (void *)sc, 0,
8956 	    bce_sysctl_dump_rx_mbuf_chain, "I", "Dump RX MBUF chain");
8957 
8958 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8959 	    "dump_tx_chain", CTLTYPE_INT | CTLFLAG_RW,
8960 	    (void *)sc, 0,
8961 	    bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
8962 
8963 #ifdef BCE_JUMBO_HDRSPLIT
8964 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8965 	    "dump_pg_chain", CTLTYPE_INT | CTLFLAG_RW,
8966 	    (void *)sc, 0,
8967 	    bce_sysctl_dump_pg_chain, "I", "Dump page chain");
8968 #endif
8969 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8970 	    "dump_ctx", CTLTYPE_INT | CTLFLAG_RW,
8971 	    (void *)sc, 0,
8972 	    bce_sysctl_dump_ctx, "I", "Dump context memory");
8973 
8974 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8975 	    "breakpoint", CTLTYPE_INT | CTLFLAG_RW,
8976 	    (void *)sc, 0,
8977 	    bce_sysctl_breakpoint, "I", "Driver breakpoint");
8978 
8979 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8980 	    "reg_read", CTLTYPE_INT | CTLFLAG_RW,
8981 	    (void *)sc, 0,
8982 	    bce_sysctl_reg_read, "I", "Register read");
8983 
8984 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8985 	    "nvram_read", CTLTYPE_INT | CTLFLAG_RW,
8986 	    (void *)sc, 0,
8987 	    bce_sysctl_nvram_read, "I", "NVRAM read");
8988 
8989 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8990 	    "phy_read", CTLTYPE_INT | CTLFLAG_RW,
8991 	    (void *)sc, 0,
8992 	    bce_sysctl_phy_read, "I", "PHY register read");
8993 
8994 #endif
8995 
8996 	DBEXIT(BCE_VERBOSE_MISC);
8997 }
8998 
8999 
9000 /****************************************************************************/
9001 /* BCE Debug Routines                                                       */
9002 /****************************************************************************/
9003 #ifdef BCE_DEBUG
9004 
9005 /****************************************************************************/
9006 /* Freezes the controller to allow for a cohesive state dump.               */
9007 /*                                                                          */
9008 /* Returns:                                                                 */
9009 /*   Nothing.                                                               */
9010 /****************************************************************************/
9011 static __attribute__ ((noinline)) void
9012 bce_freeze_controller(struct bce_softc *sc)
9013 {
9014 	u32 val;
9015 	val = REG_RD(sc, BCE_MISC_COMMAND);
9016 	val |= BCE_MISC_COMMAND_DISABLE_ALL;
9017 	REG_WR(sc, BCE_MISC_COMMAND, val);
9018 }
9019 
9020 
9021 /****************************************************************************/
9022 /* Unfreezes the controller after a freeze operation.  This may not always  */
9023 /* work and the controller will require a reset!                            */
9024 /*                                                                          */
9025 /* Returns:                                                                 */
9026 /*   Nothing.                                                               */
9027 /****************************************************************************/
9028 static __attribute__ ((noinline)) void
9029 bce_unfreeze_controller(struct bce_softc *sc)
9030 {
9031 	u32 val;
9032 	val = REG_RD(sc, BCE_MISC_COMMAND);
9033 	val |= BCE_MISC_COMMAND_ENABLE_ALL;
9034 	REG_WR(sc, BCE_MISC_COMMAND, val);
9035 }
9036 
9037 
9038 /****************************************************************************/
9039 /* Prints out Ethernet frame information from an mbuf.                      */
9040 /*                                                                          */
9041 /* Partially decode an Ethernet frame to look at some important headers.    */
9042 /*                                                                          */
9043 /* Returns:                                                                 */
9044 /*   Nothing.                                                               */
9045 /****************************************************************************/
9046 static __attribute__ ((noinline)) void
9047 bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
9048 {
9049 	struct ether_vlan_header *eh;
9050 	u16 etype;
9051 	int ehlen;
9052 	struct ip *ip;
9053 	struct tcphdr *th;
9054 	struct udphdr *uh;
9055 	struct arphdr *ah;
9056 
9057 	BCE_PRINTF(
9058 	    "-----------------------------"
9059 	    " Frame Decode "
9060 	    "-----------------------------\n");
9061 
9062 	eh = mtod(m, struct ether_vlan_header *);
9063 
9064 	/* Handle VLAN encapsulation if present. */
9065 	if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
9066 		etype = ntohs(eh->evl_proto);
9067 		ehlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
9068 	} else {
9069 		etype = ntohs(eh->evl_encap_proto);
9070 		ehlen = ETHER_HDR_LEN;
9071 	}
9072 
9073 	/* ToDo: Add VLAN output. */
9074 	BCE_PRINTF("enet: dest = %6D, src = %6D, type = 0x%04X, hlen = %d\n",
9075 	    eh->evl_dhost, ":", eh->evl_shost, ":", etype, ehlen);
9076 
9077 	switch (etype) {
9078 	case ETHERTYPE_IP:
9079 		ip = (struct ip *)(m->m_data + ehlen);
9080 		BCE_PRINTF("--ip: dest = 0x%08X , src = 0x%08X, "
9081 		    "len = %d bytes, protocol = 0x%02X, xsum = 0x%04X\n",
9082 		    ntohl(ip->ip_dst.s_addr), ntohl(ip->ip_src.s_addr),
9083 		    ntohs(ip->ip_len), ip->ip_p, ntohs(ip->ip_sum));
9084 
9085 		switch (ip->ip_p) {
9086 		case IPPROTO_TCP:
9087 			th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
9088 			BCE_PRINTF("-tcp: dest = %d, src = %d, hlen = "
9089 			    "%d bytes, flags = 0x%b, csum = 0x%04X\n",
9090 			    ntohs(th->th_dport), ntohs(th->th_sport),
9091 			    (th->th_off << 2), th->th_flags,
9092 			    "\20\10CWR\07ECE\06URG\05ACK\04PSH\03RST"
9093 			    "\02SYN\01FIN", ntohs(th->th_sum));
9094 			break;
9095 		case IPPROTO_UDP:
9096 			uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
9097 			BCE_PRINTF("-udp: dest = %d, src = %d, len = %d "
9098 			    "bytes, csum = 0x%04X\n", ntohs(uh->uh_dport),
9099 			    ntohs(uh->uh_sport), ntohs(uh->uh_ulen),
9100 			    ntohs(uh->uh_sum));
9101 			break;
9102 		case IPPROTO_ICMP:
9103 			BCE_PRINTF("icmp:\n");
9104 			break;
9105 		default:
9106 			BCE_PRINTF("----: Other IP protocol.\n");
9107 			}
9108 		break;
9109 	case ETHERTYPE_IPV6:
9110 		BCE_PRINTF("ipv6: No decode supported.\n");
9111 		break;
9112 	case ETHERTYPE_ARP:
9113 		BCE_PRINTF("-arp: ");
9114 		ah = (struct arphdr *) (m->m_data + ehlen);
9115 		switch (ntohs(ah->ar_op)) {
9116 		case ARPOP_REVREQUEST:
9117 			printf("reverse ARP request\n");
9118 			break;
9119 		case ARPOP_REVREPLY:
9120 			printf("reverse ARP reply\n");
9121 			break;
9122 		case ARPOP_REQUEST:
9123 			printf("ARP request\n");
9124 			break;
9125 		case ARPOP_REPLY:
9126 			printf("ARP reply\n");
9127 			break;
9128 		default:
9129 			printf("other ARP operation\n");
9130 		}
9131 		break;
9132 	default:
9133 		BCE_PRINTF("----: Other protocol.\n");
9134 	}
9135 
9136 	BCE_PRINTF(
9137 		"-----------------------------"
9138 		"--------------"
9139 		"-----------------------------\n");
9140 }
9141 
9142 
9143 /****************************************************************************/
9144 /* Prints out information about an mbuf.                                    */
9145 /*                                                                          */
9146 /* Returns:                                                                 */
9147 /*   Nothing.                                                               */
9148 /****************************************************************************/
9149 static __attribute__ ((noinline)) void
9150 bce_dump_mbuf(struct bce_softc *sc, struct mbuf *m)
9151 {
9152 	struct mbuf *mp = m;
9153 
9154 	if (m == NULL) {
9155 		BCE_PRINTF("mbuf: null pointer\n");
9156 		return;
9157 	}
9158 
9159 	while (mp) {
9160 		BCE_PRINTF("mbuf: %p, m_len = %d, m_flags = 0x%b, "
9161 		    "m_data = %p\n", mp, mp->m_len, mp->m_flags,
9162 		    "\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY", mp->m_data);
9163 
9164 		if (mp->m_flags & M_PKTHDR) {
9165 			BCE_PRINTF("- m_pkthdr: len = %d, flags = 0x%b, "
9166 			    "csum_flags = %b\n", mp->m_pkthdr.len,
9167 			    mp->m_flags, "\20\12M_BCAST\13M_MCAST\14M_FRAG"
9168 			    "\15M_FIRSTFRAG\16M_LASTFRAG\21M_VLANTAG"
9169 			    "\22M_PROMISC\23M_NOFREE",
9170 			    mp->m_pkthdr.csum_flags,
9171 			    "\20\1CSUM_IP\2CSUM_TCP\3CSUM_UDP\4CSUM_IP_FRAGS"
9172 			    "\5CSUM_FRAGMENT\6CSUM_TSO\11CSUM_IP_CHECKED"
9173 			    "\12CSUM_IP_VALID\13CSUM_DATA_VALID"
9174 			    "\14CSUM_PSEUDO_HDR");
9175 		}
9176 
9177 		if (mp->m_flags & M_EXT) {
9178 			BCE_PRINTF("- m_ext: %p, ext_size = %d, type = ",
9179 			    mp->m_ext.ext_buf, mp->m_ext.ext_size);
9180 			switch (mp->m_ext.ext_type) {
9181 			case EXT_CLUSTER:
9182 				printf("EXT_CLUSTER\n"); break;
9183 			case EXT_SFBUF:
9184 				printf("EXT_SFBUF\n"); break;
9185 			case EXT_JUMBO9:
9186 				printf("EXT_JUMBO9\n"); break;
9187 			case EXT_JUMBO16:
9188 				printf("EXT_JUMBO16\n"); break;
9189 			case EXT_PACKET:
9190 				printf("EXT_PACKET\n"); break;
9191 			case EXT_MBUF:
9192 				printf("EXT_MBUF\n"); break;
9193 			case EXT_NET_DRV:
9194 				printf("EXT_NET_DRV\n"); break;
9195 			case EXT_MOD_TYPE:
9196 				printf("EXT_MDD_TYPE\n"); break;
9197 			case EXT_DISPOSABLE:
9198 				printf("EXT_DISPOSABLE\n"); break;
9199 			case EXT_EXTREF:
9200 				printf("EXT_EXTREF\n"); break;
9201 			default:
9202 				printf("UNKNOWN\n");
9203 			}
9204 		}
9205 
9206 		mp = mp->m_next;
9207 	}
9208 }
9209 
9210 
9211 /****************************************************************************/
9212 /* Prints out the mbufs in the TX mbuf chain.                               */
9213 /*                                                                          */
9214 /* Returns:                                                                 */
9215 /*   Nothing.                                                               */
9216 /****************************************************************************/
9217 static __attribute__ ((noinline)) void
9218 bce_dump_tx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
9219 {
9220 	struct mbuf *m;
9221 
9222 	BCE_PRINTF(
9223 		"----------------------------"
9224 		"  tx mbuf data  "
9225 		"----------------------------\n");
9226 
9227 	for (int i = 0; i < count; i++) {
9228 	 	m = sc->tx_mbuf_ptr[chain_prod];
9229 		BCE_PRINTF("txmbuf[0x%04X]\n", chain_prod);
9230 		bce_dump_mbuf(sc, m);
9231 		chain_prod = TX_CHAIN_IDX(NEXT_TX_BD(chain_prod));
9232 	}
9233 
9234 	BCE_PRINTF(
9235 		"----------------------------"
9236 		"----------------"
9237 		"----------------------------\n");
9238 }
9239 
9240 
9241 /****************************************************************************/
9242 /* Prints out the mbufs in the RX mbuf chain.                               */
9243 /*                                                                          */
9244 /* Returns:                                                                 */
9245 /*   Nothing.                                                               */
9246 /****************************************************************************/
9247 static __attribute__ ((noinline)) void
9248 bce_dump_rx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
9249 {
9250 	struct mbuf *m;
9251 
9252 	BCE_PRINTF(
9253 		"----------------------------"
9254 		"  rx mbuf data  "
9255 		"----------------------------\n");
9256 
9257 	for (int i = 0; i < count; i++) {
9258 	 	m = sc->rx_mbuf_ptr[chain_prod];
9259 		BCE_PRINTF("rxmbuf[0x%04X]\n", chain_prod);
9260 		bce_dump_mbuf(sc, m);
9261 		chain_prod = RX_CHAIN_IDX(NEXT_RX_BD(chain_prod));
9262 	}
9263 
9264 
9265 	BCE_PRINTF(
9266 		"----------------------------"
9267 		"----------------"
9268 		"----------------------------\n");
9269 }
9270 
9271 
9272 #ifdef BCE_JUMBO_HDRSPLIT
9273 /****************************************************************************/
9274 /* Prints out the mbufs in the mbuf page chain.                             */
9275 /*                                                                          */
9276 /* Returns:                                                                 */
9277 /*   Nothing.                                                               */
9278 /****************************************************************************/
9279 static __attribute__ ((noinline)) void
9280 bce_dump_pg_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
9281 {
9282 	struct mbuf *m;
9283 
9284 	BCE_PRINTF(
9285 		"----------------------------"
9286 		"  pg mbuf data  "
9287 		"----------------------------\n");
9288 
9289 	for (int i = 0; i < count; i++) {
9290 	 	m = sc->pg_mbuf_ptr[chain_prod];
9291 		BCE_PRINTF("pgmbuf[0x%04X]\n", chain_prod);
9292 		bce_dump_mbuf(sc, m);
9293 		chain_prod = PG_CHAIN_IDX(NEXT_PG_BD(chain_prod));
9294 	}
9295 
9296 
9297 	BCE_PRINTF(
9298 		"----------------------------"
9299 		"----------------"
9300 		"----------------------------\n");
9301 }
9302 #endif
9303 
9304 
9305 /****************************************************************************/
9306 /* Prints out a tx_bd structure.                                            */
9307 /*                                                                          */
9308 /* Returns:                                                                 */
9309 /*   Nothing.                                                               */
9310 /****************************************************************************/
9311 static __attribute__ ((noinline)) void
9312 bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
9313 {
9314 	int i = 0;
9315 
9316 	if (idx > MAX_TX_BD)
9317 		/* Index out of range. */
9318 		BCE_PRINTF("tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
9319 	else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
9320 		/* TX Chain page pointer. */
9321 		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
9322 		    "pointer\n", idx, txbd->tx_bd_haddr_hi,
9323 		    txbd->tx_bd_haddr_lo);
9324 	else {
9325 		/* Normal tx_bd entry. */
9326 		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, "
9327 		    "mss_nbytes = 0x%08X, vlan tag = 0x%04X, flags = "
9328 		    "0x%04X (", idx, txbd->tx_bd_haddr_hi,
9329 		    txbd->tx_bd_haddr_lo, txbd->tx_bd_mss_nbytes,
9330 		    txbd->tx_bd_vlan_tag, txbd->tx_bd_flags);
9331 
9332 		if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT) {
9333 			if (i>0)
9334 				printf("|");
9335 			printf("CONN_FAULT");
9336 			i++;
9337 		}
9338 
9339 		if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM) {
9340 			if (i>0)
9341 				printf("|");
9342 			printf("TCP_UDP_CKSUM");
9343 			i++;
9344 		}
9345 
9346 		if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM) {
9347 			if (i>0)
9348 				printf("|");
9349 			printf("IP_CKSUM");
9350 			i++;
9351 		}
9352 
9353 		if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG) {
9354 			if (i>0)
9355 				printf("|");
9356 			printf("VLAN");
9357 			i++;
9358 		}
9359 
9360 		if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW) {
9361 			if (i>0)
9362 				printf("|");
9363 			printf("COAL_NOW");
9364 			i++;
9365 		}
9366 
9367 		if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC) {
9368 			if (i>0)
9369 				printf("|");
9370 			printf("DONT_GEN_CRC");
9371 			i++;
9372 		}
9373 
9374 		if (txbd->tx_bd_flags & TX_BD_FLAGS_START) {
9375 			if (i>0)
9376 				printf("|");
9377 			printf("START");
9378 			i++;
9379 		}
9380 
9381 		if (txbd->tx_bd_flags & TX_BD_FLAGS_END) {
9382 			if (i>0)
9383 				printf("|");
9384 			printf("END");
9385 			i++;
9386 		}
9387 
9388 		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO) {
9389 			if (i>0)
9390 				printf("|");
9391 			printf("LSO");
9392 			i++;
9393 		}
9394 
9395 		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD) {
9396 			if (i>0)
9397 				printf("|");
9398 			printf("SW_OPTION=%d", ((txbd->tx_bd_flags &
9399 			    TX_BD_FLAGS_SW_OPTION_WORD) >> 8)); i++;
9400 		}
9401 
9402 		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS) {
9403 			if (i>0)
9404 				printf("|");
9405 			printf("SW_FLAGS");
9406 			i++;
9407 		}
9408 
9409 		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP) {
9410 			if (i>0)
9411 				printf("|");
9412 			printf("SNAP)");
9413 		} else {
9414 			printf(")\n");
9415 		}
9416 	}
9417 }
9418 
9419 
9420 /****************************************************************************/
9421 /* Prints out a rx_bd structure.                                            */
9422 /*                                                                          */
9423 /* Returns:                                                                 */
9424 /*   Nothing.                                                               */
9425 /****************************************************************************/
9426 static __attribute__ ((noinline)) void
9427 bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd)
9428 {
9429 	if (idx > MAX_RX_BD)
9430 		/* Index out of range. */
9431 		BCE_PRINTF("rx_bd[0x%04X]: Invalid rx_bd index!\n", idx);
9432 	else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
9433 		/* RX Chain page pointer. */
9434 		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
9435 		    "pointer\n", idx, rxbd->rx_bd_haddr_hi,
9436 		    rxbd->rx_bd_haddr_lo);
9437 	else
9438 		/* Normal rx_bd entry. */
9439 		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = "
9440 		    "0x%08X, flags = 0x%08X\n", idx, rxbd->rx_bd_haddr_hi,
9441 		    rxbd->rx_bd_haddr_lo, rxbd->rx_bd_len,
9442 		    rxbd->rx_bd_flags);
9443 }
9444 
9445 
9446 #ifdef BCE_JUMBO_HDRSPLIT
9447 /****************************************************************************/
9448 /* Prints out a rx_bd structure in the page chain.                          */
9449 /*                                                                          */
9450 /* Returns:                                                                 */
9451 /*   Nothing.                                                               */
9452 /****************************************************************************/
9453 static __attribute__ ((noinline)) void
9454 bce_dump_pgbd(struct bce_softc *sc, int idx, struct rx_bd *pgbd)
9455 {
9456 	if (idx > MAX_PG_BD)
9457 		/* Index out of range. */
9458 		BCE_PRINTF("pg_bd[0x%04X]: Invalid pg_bd index!\n", idx);
9459 	else if ((idx & USABLE_PG_BD_PER_PAGE) == USABLE_PG_BD_PER_PAGE)
9460 		/* Page Chain page pointer. */
9461 		BCE_PRINTF("px_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
9462 			idx, pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo);
9463 	else
9464 		/* Normal rx_bd entry. */
9465 		BCE_PRINTF("pg_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
9466 			"flags = 0x%08X\n", idx,
9467 			pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo,
9468 			pgbd->rx_bd_len, pgbd->rx_bd_flags);
9469 }
9470 #endif
9471 
9472 
9473 /****************************************************************************/
9474 /* Prints out a l2_fhdr structure.                                          */
9475 /*                                                                          */
9476 /* Returns:                                                                 */
9477 /*   Nothing.                                                               */
9478 /****************************************************************************/
9479 static __attribute__ ((noinline)) void
9480 bce_dump_l2fhdr(struct bce_softc *sc, int idx, struct l2_fhdr *l2fhdr)
9481 {
9482 	BCE_PRINTF("l2_fhdr[0x%04X]: status = 0x%b, "
9483 		"pkt_len = %d, vlan = 0x%04x, ip_xsum/hdr_len = 0x%04X, "
9484 		"tcp_udp_xsum = 0x%04X\n", idx,
9485 		l2fhdr->l2_fhdr_status, BCE_L2FHDR_PRINTFB,
9486 		l2fhdr->l2_fhdr_pkt_len, l2fhdr->l2_fhdr_vlan_tag,
9487 		l2fhdr->l2_fhdr_ip_xsum, l2fhdr->l2_fhdr_tcp_udp_xsum);
9488 }
9489 
9490 
9491 /****************************************************************************/
9492 /* Prints out context memory info.  (Only useful for CID 0 to 16.)          */
9493 /*                                                                          */
9494 /* Returns:                                                                 */
9495 /*   Nothing.                                                               */
9496 /****************************************************************************/
9497 static __attribute__ ((noinline)) void
9498 bce_dump_ctx(struct bce_softc *sc, u16 cid)
9499 {
9500 	if (cid > TX_CID) {
9501 		BCE_PRINTF(" Unknown CID\n");
9502 		return;
9503 	}
9504 
9505 	BCE_PRINTF(
9506 	    "----------------------------"
9507 	    "    CTX Data    "
9508 	    "----------------------------\n");
9509 
9510 	BCE_PRINTF("     0x%04X - (CID) Context ID\n", cid);
9511 
9512 	if (cid == RX_CID) {
9513 		BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BDIDX) host rx "
9514 		   "producer index\n",
9515 		    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BDIDX));
9516 		BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BSEQ) host "
9517 		    "byte sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
9518 		    BCE_L2CTX_RX_HOST_BSEQ));
9519 		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BSEQ) h/w byte sequence\n",
9520 		    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BSEQ));
9521 		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_HI) h/w buffer "
9522 		    "descriptor address\n",
9523  		    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_HI));
9524 		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_LO) h/w buffer "
9525 		    "descriptor address\n",
9526 		    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_LO));
9527 		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDIDX) h/w rx consumer "
9528 		    "index\n", CTX_RD(sc, GET_CID_ADDR(cid),
9529 		    BCE_L2CTX_RX_NX_BDIDX));
9530 		BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_PG_BDIDX) host page "
9531 		    "producer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
9532 		    BCE_L2CTX_RX_HOST_PG_BDIDX));
9533 		BCE_PRINTF(" 0x%08X - (L2CTX_RX_PG_BUF_SIZE) host rx_bd/page "
9534 		    "buffer size\n", CTX_RD(sc, GET_CID_ADDR(cid),
9535 		    BCE_L2CTX_RX_PG_BUF_SIZE));
9536 		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_HI) h/w page "
9537 		    "chain address\n", CTX_RD(sc, GET_CID_ADDR(cid),
9538 		    BCE_L2CTX_RX_NX_PG_BDHADDR_HI));
9539 		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_LO) h/w page "
9540 		    "chain address\n", CTX_RD(sc, GET_CID_ADDR(cid),
9541 		    BCE_L2CTX_RX_NX_PG_BDHADDR_LO));
9542 		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDIDX) h/w page "
9543 		    "consumer index\n",	CTX_RD(sc, GET_CID_ADDR(cid),
9544 		    BCE_L2CTX_RX_NX_PG_BDIDX));
9545 	} else if (cid == TX_CID) {
9546 		if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
9547 		    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
9548 			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE_XI) ctx type\n",
9549 			    CTX_RD(sc, GET_CID_ADDR(cid),
9550 			    BCE_L2CTX_TX_TYPE_XI));
9551 			BCE_PRINTF(" 0x%08X - (L2CTX_CMD_TX_TYPE_XI) ctx "
9552 			    "cmd\n", CTX_RD(sc, GET_CID_ADDR(cid),
9553 			    BCE_L2CTX_TX_CMD_TYPE_XI));
9554 			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI_XI) "
9555 			    "h/w buffer descriptor address\n",
9556 			    CTX_RD(sc, GET_CID_ADDR(cid),
9557 			    BCE_L2CTX_TX_TBDR_BHADDR_HI_XI));
9558 			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO_XI) "
9559 			    "h/w buffer	descriptor address\n",
9560 			    CTX_RD(sc, GET_CID_ADDR(cid),
9561 			    BCE_L2CTX_TX_TBDR_BHADDR_LO_XI));
9562 			BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX_XI) "
9563 			    "host producer index\n",
9564 			    CTX_RD(sc, GET_CID_ADDR(cid),
9565 			    BCE_L2CTX_TX_HOST_BIDX_XI));
9566 			BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ_XI) "
9567 			    "host byte sequence\n",
9568 			    CTX_RD(sc, GET_CID_ADDR(cid),
9569 			    BCE_L2CTX_TX_HOST_BSEQ_XI));
9570 		} else {
9571 			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE) ctx type\n",
9572 			    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE));
9573 			BCE_PRINTF(" 0x%08X - (L2CTX_TX_CMD_TYPE) ctx cmd\n",
9574 			    CTX_RD(sc, GET_CID_ADDR(cid),
9575 			    BCE_L2CTX_TX_CMD_TYPE));
9576 			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI) "
9577 			    "h/w buffer	descriptor address\n",
9578 			    CTX_RD(sc, GET_CID_ADDR(cid),
9579 			    BCE_L2CTX_TX_TBDR_BHADDR_HI));
9580 			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO) "
9581 			    "h/w buffer	descriptor address\n",
9582 			    CTX_RD(sc, GET_CID_ADDR(cid),
9583 			    BCE_L2CTX_TX_TBDR_BHADDR_LO));
9584 			BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX) host "
9585 			    "producer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
9586 			    BCE_L2CTX_TX_HOST_BIDX));
9587 			BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ) host byte "
9588 			    "sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
9589 			    BCE_L2CTX_TX_HOST_BSEQ));
9590 		}
9591 	}
9592 
9593 	BCE_PRINTF(
9594 	   "----------------------------"
9595 	   "    Raw CTX     "
9596 	   "----------------------------\n");
9597 
9598 	for (int i = 0x0; i < 0x300; i += 0x10) {
9599 		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n", i,
9600 		   CTX_RD(sc, GET_CID_ADDR(cid), i),
9601 		   CTX_RD(sc, GET_CID_ADDR(cid), i + 0x4),
9602 		   CTX_RD(sc, GET_CID_ADDR(cid), i + 0x8),
9603 		   CTX_RD(sc, GET_CID_ADDR(cid), i + 0xc));
9604 	}
9605 
9606 
9607 	BCE_PRINTF(
9608 	   "----------------------------"
9609 	   "----------------"
9610 	   "----------------------------\n");
9611 }
9612 
9613 
9614 /****************************************************************************/
9615 /* Prints out the FTQ data.                                                 */
9616 /*                                                                          */
9617 /* Returns:                                                                */
9618 /*   Nothing.                                                               */
9619 /****************************************************************************/
9620 static __attribute__ ((noinline)) void
9621 bce_dump_ftqs(struct bce_softc *sc)
9622 {
9623 	u32 cmd, ctl, cur_depth, max_depth, valid_cnt, val;
9624 
9625 	BCE_PRINTF(
9626 	    "----------------------------"
9627 	    "    FTQ Data    "
9628 	    "----------------------------\n");
9629 
9630 	BCE_PRINTF("   FTQ    Command    Control   Depth_Now  "
9631 	    "Max_Depth  Valid_Cnt \n");
9632 	BCE_PRINTF(" ------- ---------- ---------- ---------- "
9633 	    "---------- ----------\n");
9634 
9635 	/* Setup the generic statistic counters for the FTQ valid count. */
9636 	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PPQ_VALID_CNT << 24) |
9637 	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT  << 16) |
9638 	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT   <<  8) |
9639 	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT);
9640 	REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
9641 
9642 	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCHQ_VALID_CNT  << 24) |
9643 	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT  << 16) |
9644 	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT <<  8) |
9645 	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT);
9646 	REG_WR(sc, BCE_HC_STAT_GEN_SEL_1, val);
9647 
9648 	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPATQ_VALID_CNT  << 24) |
9649 	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT  << 16) |
9650 	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT   <<  8) |
9651 	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT);
9652 	REG_WR(sc, BCE_HC_STAT_GEN_SEL_2, val);
9653 
9654 	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMQ_VALID_CNT   << 24) |
9655 	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT  << 16) |
9656 	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT  <<  8) |
9657 	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT);
9658 	REG_WR(sc, BCE_HC_STAT_GEN_SEL_3, val);
9659 
9660 	/* Input queue to the Receive Lookup state machine */
9661 	cmd = REG_RD(sc, BCE_RLUP_FTQ_CMD);
9662 	ctl = REG_RD(sc, BCE_RLUP_FTQ_CTL);
9663 	cur_depth = (ctl & BCE_RLUP_FTQ_CTL_CUR_DEPTH) >> 22;
9664 	max_depth = (ctl & BCE_RLUP_FTQ_CTL_MAX_DEPTH) >> 12;
9665 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
9666 	BCE_PRINTF(" RLUP    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9667 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9668 
9669 	/* Input queue to the Receive Processor */
9670 	cmd = REG_RD_IND(sc, BCE_RXP_FTQ_CMD);
9671 	ctl = REG_RD_IND(sc, BCE_RXP_FTQ_CTL);
9672 	cur_depth = (ctl & BCE_RXP_FTQ_CTL_CUR_DEPTH) >> 22;
9673 	max_depth = (ctl & BCE_RXP_FTQ_CTL_MAX_DEPTH) >> 12;
9674 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
9675 	BCE_PRINTF(" RXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9676 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9677 
9678 	/* Input queue to the Recevie Processor */
9679 	cmd = REG_RD_IND(sc, BCE_RXP_CFTQ_CMD);
9680 	ctl = REG_RD_IND(sc, BCE_RXP_CFTQ_CTL);
9681 	cur_depth = (ctl & BCE_RXP_CFTQ_CTL_CUR_DEPTH) >> 22;
9682 	max_depth = (ctl & BCE_RXP_CFTQ_CTL_MAX_DEPTH) >> 12;
9683 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
9684 	BCE_PRINTF(" RXPC    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9685 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9686 
9687 	/* Input queue to the Receive Virtual to Physical state machine */
9688 	cmd = REG_RD(sc, BCE_RV2P_PFTQ_CMD);
9689 	ctl = REG_RD(sc, BCE_RV2P_PFTQ_CTL);
9690 	cur_depth = (ctl & BCE_RV2P_PFTQ_CTL_CUR_DEPTH) >> 22;
9691 	max_depth = (ctl & BCE_RV2P_PFTQ_CTL_MAX_DEPTH) >> 12;
9692 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
9693 	BCE_PRINTF(" RV2PP   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9694 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9695 
9696 	/* Input queue to the Recevie Virtual to Physical state machine */
9697 	cmd = REG_RD(sc, BCE_RV2P_MFTQ_CMD);
9698 	ctl = REG_RD(sc, BCE_RV2P_MFTQ_CTL);
9699 	cur_depth = (ctl & BCE_RV2P_MFTQ_CTL_CUR_DEPTH) >> 22;
9700 	max_depth = (ctl & BCE_RV2P_MFTQ_CTL_MAX_DEPTH) >> 12;
9701 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT4);
9702 	BCE_PRINTF(" RV2PM   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9703 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9704 
9705 	/* Input queue to the Receive Virtual to Physical state machine */
9706 	cmd = REG_RD(sc, BCE_RV2P_TFTQ_CMD);
9707 	ctl = REG_RD(sc, BCE_RV2P_TFTQ_CTL);
9708 	cur_depth = (ctl & BCE_RV2P_TFTQ_CTL_CUR_DEPTH) >> 22;
9709 	max_depth = (ctl & BCE_RV2P_TFTQ_CTL_MAX_DEPTH) >> 12;
9710 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT5);
9711 	BCE_PRINTF(" RV2PT   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9712 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9713 
9714 	/* Input queue to the Receive DMA state machine */
9715 	cmd = REG_RD(sc, BCE_RDMA_FTQ_CMD);
9716 	ctl = REG_RD(sc, BCE_RDMA_FTQ_CTL);
9717 	cur_depth = (ctl & BCE_RDMA_FTQ_CTL_CUR_DEPTH) >> 22;
9718 	max_depth = (ctl & BCE_RDMA_FTQ_CTL_MAX_DEPTH) >> 12;
9719 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT6);
9720 	BCE_PRINTF(" RDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9721 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9722 
9723 	/* Input queue to the Transmit Scheduler state machine */
9724 	cmd = REG_RD(sc, BCE_TSCH_FTQ_CMD);
9725 	ctl = REG_RD(sc, BCE_TSCH_FTQ_CTL);
9726 	cur_depth = (ctl & BCE_TSCH_FTQ_CTL_CUR_DEPTH) >> 22;
9727 	max_depth = (ctl & BCE_TSCH_FTQ_CTL_MAX_DEPTH) >> 12;
9728 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT7);
9729 	BCE_PRINTF(" TSCH    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9730 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9731 
9732 	/* Input queue to the Transmit Buffer Descriptor state machine */
9733 	cmd = REG_RD(sc, BCE_TBDR_FTQ_CMD);
9734 	ctl = REG_RD(sc, BCE_TBDR_FTQ_CTL);
9735 	cur_depth = (ctl & BCE_TBDR_FTQ_CTL_CUR_DEPTH) >> 22;
9736 	max_depth = (ctl & BCE_TBDR_FTQ_CTL_MAX_DEPTH) >> 12;
9737 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT8);
9738 	BCE_PRINTF(" TBDR    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9739 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9740 
9741 	/* Input queue to the Transmit Processor */
9742 	cmd = REG_RD_IND(sc, BCE_TXP_FTQ_CMD);
9743 	ctl = REG_RD_IND(sc, BCE_TXP_FTQ_CTL);
9744 	cur_depth = (ctl & BCE_TXP_FTQ_CTL_CUR_DEPTH) >> 22;
9745 	max_depth = (ctl & BCE_TXP_FTQ_CTL_MAX_DEPTH) >> 12;
9746 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT9);
9747 	BCE_PRINTF(" TXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9748 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9749 
9750 	/* Input queue to the Transmit DMA state machine */
9751 	cmd = REG_RD(sc, BCE_TDMA_FTQ_CMD);
9752 	ctl = REG_RD(sc, BCE_TDMA_FTQ_CTL);
9753 	cur_depth = (ctl & BCE_TDMA_FTQ_CTL_CUR_DEPTH) >> 22;
9754 	max_depth = (ctl & BCE_TDMA_FTQ_CTL_MAX_DEPTH) >> 12;
9755 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT10);
9756 	BCE_PRINTF(" TDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9757 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9758 
9759 	/* Input queue to the Transmit Patch-Up Processor */
9760 	cmd = REG_RD_IND(sc, BCE_TPAT_FTQ_CMD);
9761 	ctl = REG_RD_IND(sc, BCE_TPAT_FTQ_CTL);
9762 	cur_depth = (ctl & BCE_TPAT_FTQ_CTL_CUR_DEPTH) >> 22;
9763 	max_depth = (ctl & BCE_TPAT_FTQ_CTL_MAX_DEPTH) >> 12;
9764 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT11);
9765 	BCE_PRINTF(" TPAT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9766 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9767 
9768 	/* Input queue to the Transmit Assembler state machine */
9769 	cmd = REG_RD_IND(sc, BCE_TAS_FTQ_CMD);
9770 	ctl = REG_RD_IND(sc, BCE_TAS_FTQ_CTL);
9771 	cur_depth = (ctl & BCE_TAS_FTQ_CTL_CUR_DEPTH) >> 22;
9772 	max_depth = (ctl & BCE_TAS_FTQ_CTL_MAX_DEPTH) >> 12;
9773 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT12);
9774 	BCE_PRINTF(" TAS     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9775 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9776 
9777 	/* Input queue to the Completion Processor */
9778 	cmd = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CMD);
9779 	ctl = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CTL);
9780 	cur_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_CUR_DEPTH) >> 22;
9781 	max_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_MAX_DEPTH) >> 12;
9782 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT13);
9783 	BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9784 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9785 
9786 	/* Input queue to the Completion Processor */
9787 	cmd = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CMD);
9788 	ctl = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CTL);
9789 	cur_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_CUR_DEPTH) >> 22;
9790 	max_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_MAX_DEPTH) >> 12;
9791 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT14);
9792 	BCE_PRINTF(" COMT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9793 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9794 
9795 	/* Input queue to the Completion Processor */
9796 	cmd = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CMD);
9797 	ctl = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CTL);
9798 	cur_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_CUR_DEPTH) >> 22;
9799 	max_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_MAX_DEPTH) >> 12;
9800 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT15);
9801 	BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9802 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9803 
9804 	/* Setup the generic statistic counters for the FTQ valid count. */
9805 	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSQ_VALID_CNT  << 16) |
9806 	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT  <<  8) |
9807 	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT);
9808 
9809 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
9810 	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
9811 		val = val |
9812 		    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCSQ_VALID_CNT_XI <<
9813 		     24);
9814 	REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
9815 
9816 	/* Input queue to the Management Control Processor */
9817 	cmd = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CMD);
9818 	ctl = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CTL);
9819 	cur_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_CUR_DEPTH) >> 22;
9820 	max_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_MAX_DEPTH) >> 12;
9821 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
9822 	BCE_PRINTF(" MCP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9823 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9824 
9825 	/* Input queue to the Command Processor */
9826 	cmd = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CMD);
9827 	ctl = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CTL);
9828 	cur_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_CUR_DEPTH) >> 22;
9829 	max_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_MAX_DEPTH) >> 12;
9830 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
9831 	BCE_PRINTF(" CP      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9832 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9833 
9834 	/* Input queue to the Completion Scheduler state machine */
9835 	cmd = REG_RD(sc, BCE_CSCH_CH_FTQ_CMD);
9836 	ctl = REG_RD(sc, BCE_CSCH_CH_FTQ_CTL);
9837 	cur_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_CUR_DEPTH) >> 22;
9838 	max_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_MAX_DEPTH) >> 12;
9839 	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
9840 	BCE_PRINTF(" CS      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9841 	    cmd, ctl, cur_depth, max_depth, valid_cnt);
9842 
9843 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
9844 	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
9845 		/* Input queue to the RV2P Command Scheduler */
9846 		cmd = REG_RD(sc, BCE_RV2PCSR_FTQ_CMD);
9847 		ctl = REG_RD(sc, BCE_RV2PCSR_FTQ_CTL);
9848 		cur_depth = (ctl & 0xFFC00000) >> 22;
9849 		max_depth = (ctl & 0x003FF000) >> 12;
9850 		valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
9851 		BCE_PRINTF(" RV2PCSR 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9852 		    cmd, ctl, cur_depth, max_depth, valid_cnt);
9853 	}
9854 
9855 	BCE_PRINTF(
9856 	    "----------------------------"
9857 	    "----------------"
9858 	    "----------------------------\n");
9859 }
9860 
9861 
9862 /****************************************************************************/
9863 /* Prints out the TX chain.                                                 */
9864 /*                                                                          */
9865 /* Returns:                                                                 */
9866 /*   Nothing.                                                               */
9867 /****************************************************************************/
9868 static __attribute__ ((noinline)) void
9869 bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count)
9870 {
9871 	struct tx_bd *txbd;
9872 
9873 	/* First some info about the tx_bd chain structure. */
9874 	BCE_PRINTF(
9875 	    "----------------------------"
9876 	    "  tx_bd  chain  "
9877 	    "----------------------------\n");
9878 
9879 	BCE_PRINTF("page size      = 0x%08X, tx chain pages        = 0x%08X\n",
9880 	    (u32) BCM_PAGE_SIZE, (u32) TX_PAGES);
9881 	BCE_PRINTF("tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
9882 	    (u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
9883 	BCE_PRINTF("total tx_bd    = 0x%08X\n", (u32) TOTAL_TX_BD);
9884 
9885 	BCE_PRINTF(
9886 	    "----------------------------"
9887 	    "   tx_bd data   "
9888 	    "----------------------------\n");
9889 
9890 	/* Now print out a decoded list of TX buffer descriptors. */
9891 	for (int i = 0; i < count; i++) {
9892 	 	txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
9893 		bce_dump_txbd(sc, tx_prod, txbd);
9894 		tx_prod++;
9895 	}
9896 
9897 	BCE_PRINTF(
9898 	    "----------------------------"
9899 	    "----------------"
9900 	    "----------------------------\n");
9901 }
9902 
9903 
9904 /****************************************************************************/
9905 /* Prints out the RX chain.                                                 */
9906 /*                                                                          */
9907 /* Returns:                                                                 */
9908 /*   Nothing.                                                               */
9909 /****************************************************************************/
9910 static __attribute__ ((noinline)) void
9911 bce_dump_rx_bd_chain(struct bce_softc *sc, u16 rx_prod, int count)
9912 {
9913 	struct rx_bd *rxbd;
9914 
9915 	/* First some info about the rx_bd chain structure. */
9916 	BCE_PRINTF(
9917 	    "----------------------------"
9918 	    "  rx_bd  chain  "
9919 	    "----------------------------\n");
9920 
9921 	BCE_PRINTF("page size      = 0x%08X, rx chain pages        = 0x%08X\n",
9922 	    (u32) BCM_PAGE_SIZE, (u32) RX_PAGES);
9923 
9924 	BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
9925 	    (u32) TOTAL_RX_BD_PER_PAGE, (u32) USABLE_RX_BD_PER_PAGE);
9926 
9927 	BCE_PRINTF("total rx_bd    = 0x%08X\n", (u32) TOTAL_RX_BD);
9928 
9929 	BCE_PRINTF(
9930 	    "----------------------------"
9931 	    "   rx_bd data   "
9932 	    "----------------------------\n");
9933 
9934 	/* Now print out the rx_bd's themselves. */
9935 	for (int i = 0; i < count; i++) {
9936 		rxbd = &sc->rx_bd_chain[RX_PAGE(rx_prod)][RX_IDX(rx_prod)];
9937 		bce_dump_rxbd(sc, rx_prod, rxbd);
9938 		rx_prod = RX_CHAIN_IDX(rx_prod + 1);
9939 	}
9940 
9941 	BCE_PRINTF(
9942 	    "----------------------------"
9943 	    "----------------"
9944 	    "----------------------------\n");
9945 }
9946 
9947 
9948 #ifdef BCE_JUMBO_HDRSPLIT
9949 /****************************************************************************/
9950 /* Prints out the page chain.                                               */
9951 /*                                                                          */
9952 /* Returns:                                                                 */
9953 /*   Nothing.                                                               */
9954 /****************************************************************************/
9955 static __attribute__ ((noinline)) void
9956 bce_dump_pg_chain(struct bce_softc *sc, u16 pg_prod, int count)
9957 {
9958 	struct rx_bd *pgbd;
9959 
9960 	/* First some info about the page chain structure. */
9961 	BCE_PRINTF(
9962 	    "----------------------------"
9963 	    "   page chain   "
9964 	    "----------------------------\n");
9965 
9966 	BCE_PRINTF("page size      = 0x%08X, pg chain pages        = 0x%08X\n",
9967 	    (u32) BCM_PAGE_SIZE, (u32) PG_PAGES);
9968 
9969 	BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
9970 	    (u32) TOTAL_PG_BD_PER_PAGE, (u32) USABLE_PG_BD_PER_PAGE);
9971 
9972 	BCE_PRINTF("total rx_bd    = 0x%08X, max_pg_bd             = 0x%08X\n",
9973 	    (u32) TOTAL_PG_BD, (u32) MAX_PG_BD);
9974 
9975 	BCE_PRINTF(
9976 	    "----------------------------"
9977 	    "   page data    "
9978 	    "----------------------------\n");
9979 
9980 	/* Now print out the rx_bd's themselves. */
9981 	for (int i = 0; i < count; i++) {
9982 		pgbd = &sc->pg_bd_chain[PG_PAGE(pg_prod)][PG_IDX(pg_prod)];
9983 		bce_dump_pgbd(sc, pg_prod, pgbd);
9984 		pg_prod = PG_CHAIN_IDX(pg_prod + 1);
9985 	}
9986 
9987 	BCE_PRINTF(
9988 	    "----------------------------"
9989 	    "----------------"
9990 	    "----------------------------\n");
9991 }
9992 #endif
9993 
9994 
9995 #define BCE_PRINT_RX_CONS(arg)						\
9996 if (sblk->status_rx_quick_consumer_index##arg)				\
9997 	BCE_PRINTF("0x%04X(0x%04X) - rx_quick_consumer_index%d\n",	\
9998 	    sblk->status_rx_quick_consumer_index##arg, (u16)		\
9999 	    RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index##arg),	\
10000 	    arg);
10001 
10002 
10003 #define BCE_PRINT_TX_CONS(arg)						\
10004 if (sblk->status_tx_quick_consumer_index##arg)				\
10005 	BCE_PRINTF("0x%04X(0x%04X) - tx_quick_consumer_index%d\n",	\
10006 	    sblk->status_tx_quick_consumer_index##arg, (u16)		\
10007 	    TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index##arg),	\
10008 	    arg);
10009 
10010 /****************************************************************************/
10011 /* Prints out the status block from host memory.                            */
10012 /*                                                                          */
10013 /* Returns:                                                                 */
10014 /*   Nothing.                                                               */
10015 /****************************************************************************/
10016 static __attribute__ ((noinline)) void
10017 bce_dump_status_block(struct bce_softc *sc)
10018 {
10019 	struct status_block *sblk;
10020 
10021 	sblk = sc->status_block;
10022 
10023 	BCE_PRINTF(
10024 	    "----------------------------"
10025 	    "  Status Block  "
10026 	    "----------------------------\n");
10027 
10028 	/* Theses indices are used for normal L2 drivers. */
10029 	BCE_PRINTF("    0x%08X - attn_bits\n",
10030 	    sblk->status_attn_bits);
10031 
10032 	BCE_PRINTF("    0x%08X - attn_bits_ack\n",
10033 	    sblk->status_attn_bits_ack);
10034 
10035 	BCE_PRINT_RX_CONS(0);
10036 	BCE_PRINT_TX_CONS(0)
10037 
10038 	BCE_PRINTF("        0x%04X - status_idx\n", sblk->status_idx);
10039 
10040 	/* Theses indices are not used for normal L2 drivers. */
10041 	BCE_PRINT_RX_CONS(1);   BCE_PRINT_RX_CONS(2);   BCE_PRINT_RX_CONS(3);
10042 	BCE_PRINT_RX_CONS(4);   BCE_PRINT_RX_CONS(5);   BCE_PRINT_RX_CONS(6);
10043 	BCE_PRINT_RX_CONS(7);   BCE_PRINT_RX_CONS(8);   BCE_PRINT_RX_CONS(9);
10044 	BCE_PRINT_RX_CONS(10);  BCE_PRINT_RX_CONS(11);  BCE_PRINT_RX_CONS(12);
10045 	BCE_PRINT_RX_CONS(13);  BCE_PRINT_RX_CONS(14);  BCE_PRINT_RX_CONS(15);
10046 
10047 	BCE_PRINT_TX_CONS(1);   BCE_PRINT_TX_CONS(2);   BCE_PRINT_TX_CONS(3);
10048 
10049 	if (sblk->status_completion_producer_index ||
10050 	    sblk->status_cmd_consumer_index)
10051 		BCE_PRINTF("com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
10052 		    sblk->status_completion_producer_index,
10053 		    sblk->status_cmd_consumer_index);
10054 
10055 	BCE_PRINTF(
10056 	    "----------------------------"
10057 	    "----------------"
10058 	    "----------------------------\n");
10059 }
10060 
10061 
10062 #define BCE_PRINT_64BIT_STAT(arg) 				\
10063 if (sblk->arg##_lo || sblk->arg##_hi)				\
10064 	BCE_PRINTF("0x%08X:%08X : %s\n", sblk->arg##_hi,	\
10065 	    sblk->arg##_lo, #arg);
10066 
10067 #define BCE_PRINT_32BIT_STAT(arg)				\
10068 if (sblk->arg)							\
10069 	BCE_PRINTF("         0x%08X : %s\n", 			\
10070 	    sblk->arg, #arg);
10071 
10072 /****************************************************************************/
10073 /* Prints out the statistics block from host memory.                        */
10074 /*                                                                          */
10075 /* Returns:                                                                 */
10076 /*   Nothing.                                                               */
10077 /****************************************************************************/
10078 static __attribute__ ((noinline)) void
10079 bce_dump_stats_block(struct bce_softc *sc)
10080 {
10081 	struct statistics_block *sblk;
10082 
10083 	sblk = sc->stats_block;
10084 
10085 	BCE_PRINTF(
10086 	    "---------------"
10087 	    " Stats Block  (All Stats Not Shown Are 0) "
10088 	    "---------------\n");
10089 
10090 	BCE_PRINT_64BIT_STAT(stat_IfHCInOctets);
10091 	BCE_PRINT_64BIT_STAT(stat_IfHCInBadOctets);
10092 	BCE_PRINT_64BIT_STAT(stat_IfHCOutOctets);
10093 	BCE_PRINT_64BIT_STAT(stat_IfHCOutBadOctets);
10094 	BCE_PRINT_64BIT_STAT(stat_IfHCInUcastPkts);
10095 	BCE_PRINT_64BIT_STAT(stat_IfHCInBroadcastPkts);
10096 	BCE_PRINT_64BIT_STAT(stat_IfHCInMulticastPkts);
10097 	BCE_PRINT_64BIT_STAT(stat_IfHCOutUcastPkts);
10098 	BCE_PRINT_64BIT_STAT(stat_IfHCOutBroadcastPkts);
10099 	BCE_PRINT_64BIT_STAT(stat_IfHCOutMulticastPkts);
10100 	BCE_PRINT_32BIT_STAT(
10101 	    stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
10102 	BCE_PRINT_32BIT_STAT(stat_Dot3StatsCarrierSenseErrors);
10103 	BCE_PRINT_32BIT_STAT(stat_Dot3StatsFCSErrors);
10104 	BCE_PRINT_32BIT_STAT(stat_Dot3StatsAlignmentErrors);
10105 	BCE_PRINT_32BIT_STAT(stat_Dot3StatsSingleCollisionFrames);
10106 	BCE_PRINT_32BIT_STAT(stat_Dot3StatsMultipleCollisionFrames);
10107 	BCE_PRINT_32BIT_STAT(stat_Dot3StatsDeferredTransmissions);
10108 	BCE_PRINT_32BIT_STAT(stat_Dot3StatsExcessiveCollisions);
10109 	BCE_PRINT_32BIT_STAT(stat_Dot3StatsLateCollisions);
10110 	BCE_PRINT_32BIT_STAT(stat_EtherStatsCollisions);
10111 	BCE_PRINT_32BIT_STAT(stat_EtherStatsFragments);
10112 	BCE_PRINT_32BIT_STAT(stat_EtherStatsJabbers);
10113 	BCE_PRINT_32BIT_STAT(stat_EtherStatsUndersizePkts);
10114 	BCE_PRINT_32BIT_STAT(stat_EtherStatsOversizePkts);
10115 	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx64Octets);
10116 	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx65Octetsto127Octets);
10117 	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx128Octetsto255Octets);
10118 	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx256Octetsto511Octets);
10119 	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx512Octetsto1023Octets);
10120 	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1024Octetsto1522Octets);
10121 	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1523Octetsto9022Octets);
10122 	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx64Octets);
10123 	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx65Octetsto127Octets);
10124 	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx128Octetsto255Octets);
10125 	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx256Octetsto511Octets);
10126 	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx512Octetsto1023Octets);
10127 	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1024Octetsto1522Octets);
10128 	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1523Octetsto9022Octets);
10129 	BCE_PRINT_32BIT_STAT(stat_XonPauseFramesReceived);
10130 	BCE_PRINT_32BIT_STAT(stat_XoffPauseFramesReceived);
10131 	BCE_PRINT_32BIT_STAT(stat_OutXonSent);
10132 	BCE_PRINT_32BIT_STAT(stat_OutXoffSent);
10133 	BCE_PRINT_32BIT_STAT(stat_FlowControlDone);
10134 	BCE_PRINT_32BIT_STAT(stat_MacControlFramesReceived);
10135 	BCE_PRINT_32BIT_STAT(stat_XoffStateEntered);
10136 	BCE_PRINT_32BIT_STAT(stat_IfInFramesL2FilterDiscards);
10137 	BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerDiscards);
10138 	BCE_PRINT_32BIT_STAT(stat_IfInFTQDiscards);
10139 	BCE_PRINT_32BIT_STAT(stat_IfInMBUFDiscards);
10140 	BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerP4Hit);
10141 	BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerDiscards);
10142 	BCE_PRINT_32BIT_STAT(stat_CatchupInFTQDiscards);
10143 	BCE_PRINT_32BIT_STAT(stat_CatchupInMBUFDiscards);
10144 	BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerP4Hit);
10145 
10146 	BCE_PRINTF(
10147 	    "----------------------------"
10148 	    "----------------"
10149 	    "----------------------------\n");
10150 }
10151 
10152 
10153 /****************************************************************************/
10154 /* Prints out a summary of the driver state.                                */
10155 /*                                                                          */
10156 /* Returns:                                                                 */
10157 /*   Nothing.                                                               */
10158 /****************************************************************************/
10159 static __attribute__ ((noinline)) void
10160 bce_dump_driver_state(struct bce_softc *sc)
10161 {
10162 	u32 val_hi, val_lo;
10163 
10164 	BCE_PRINTF(
10165 	    "-----------------------------"
10166 	    " Driver State "
10167 	    "-----------------------------\n");
10168 
10169 	val_hi = BCE_ADDR_HI(sc);
10170 	val_lo = BCE_ADDR_LO(sc);
10171 	BCE_PRINTF("0x%08X:%08X - (sc) driver softc structure virtual "
10172 	    "address\n", val_hi, val_lo);
10173 
10174 	val_hi = BCE_ADDR_HI(sc->bce_vhandle);
10175 	val_lo = BCE_ADDR_LO(sc->bce_vhandle);
10176 	BCE_PRINTF("0x%08X:%08X - (sc->bce_vhandle) PCI BAR virtual "
10177 	    "address\n", val_hi, val_lo);
10178 
10179 	val_hi = BCE_ADDR_HI(sc->status_block);
10180 	val_lo = BCE_ADDR_LO(sc->status_block);
10181 	BCE_PRINTF("0x%08X:%08X - (sc->status_block) status block "
10182 	    "virtual address\n",	val_hi, val_lo);
10183 
10184 	val_hi = BCE_ADDR_HI(sc->stats_block);
10185 	val_lo = BCE_ADDR_LO(sc->stats_block);
10186 	BCE_PRINTF("0x%08X:%08X - (sc->stats_block) statistics block "
10187 	    "virtual address\n", val_hi, val_lo);
10188 
10189 	val_hi = BCE_ADDR_HI(sc->tx_bd_chain);
10190 	val_lo = BCE_ADDR_LO(sc->tx_bd_chain);
10191 	BCE_PRINTF("0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain "
10192 	    "virtual adddress\n", val_hi, val_lo);
10193 
10194 	val_hi = BCE_ADDR_HI(sc->rx_bd_chain);
10195 	val_lo = BCE_ADDR_LO(sc->rx_bd_chain);
10196 	BCE_PRINTF("0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain "
10197 	    "virtual address\n", val_hi, val_lo);
10198 
10199 #ifdef BCE_JUMBO_HDRSPLIT
10200 	val_hi = BCE_ADDR_HI(sc->pg_bd_chain);
10201 	val_lo = BCE_ADDR_LO(sc->pg_bd_chain);
10202 	BCE_PRINTF("0x%08X:%08X - (sc->pg_bd_chain) page chain "
10203 	    "virtual address\n", val_hi, val_lo);
10204 #endif
10205 
10206 	val_hi = BCE_ADDR_HI(sc->tx_mbuf_ptr);
10207 	val_lo = BCE_ADDR_LO(sc->tx_mbuf_ptr);
10208 	BCE_PRINTF("0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain "
10209 	    "virtual address\n",	val_hi, val_lo);
10210 
10211 	val_hi = BCE_ADDR_HI(sc->rx_mbuf_ptr);
10212 	val_lo = BCE_ADDR_LO(sc->rx_mbuf_ptr);
10213 	BCE_PRINTF("0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain "
10214 	    "virtual address\n", val_hi, val_lo);
10215 
10216 #ifdef BCE_JUMBO_HDRSPLIT
10217 	val_hi = BCE_ADDR_HI(sc->pg_mbuf_ptr);
10218 	val_lo = BCE_ADDR_LO(sc->pg_mbuf_ptr);
10219 	BCE_PRINTF("0x%08X:%08X - (sc->pg_mbuf_ptr) page mbuf chain "
10220 	    "virtual address\n", val_hi, val_lo);
10221 #endif
10222 
10223 	BCE_PRINTF("         0x%08X - (sc->interrupts_generated) "
10224 	    "h/w intrs\n", sc->interrupts_generated);
10225 
10226 	BCE_PRINTF("         0x%08X - (sc->interrupts_rx) "
10227 	    "rx interrupts handled\n", sc->interrupts_rx);
10228 
10229 	BCE_PRINTF("         0x%08X - (sc->interrupts_tx) "
10230 	    "tx interrupts handled\n", sc->interrupts_tx);
10231 
10232 	BCE_PRINTF("         0x%08X - (sc->phy_interrupts) "
10233 	    "phy interrupts handled\n", sc->phy_interrupts);
10234 
10235 	BCE_PRINTF("         0x%08X - (sc->last_status_idx) "
10236 	    "status block index\n", sc->last_status_idx);
10237 
10238 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_prod) tx producer "
10239 	    "index\n", sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod));
10240 
10241 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_cons) tx consumer "
10242 	    "index\n", sc->tx_cons, (u16) TX_CHAIN_IDX(sc->tx_cons));
10243 
10244 	BCE_PRINTF("         0x%08X - (sc->tx_prod_bseq) tx producer "
10245 	    "byte seq index\n",	sc->tx_prod_bseq);
10246 
10247 	BCE_PRINTF("         0x%08X - (sc->debug_tx_mbuf_alloc) tx "
10248 	    "mbufs allocated\n", sc->debug_tx_mbuf_alloc);
10249 
10250 	BCE_PRINTF("         0x%08X - (sc->used_tx_bd) used "
10251 	    "tx_bd's\n", sc->used_tx_bd);
10252 
10253 	BCE_PRINTF("0x%08X/%08X - (sc->tx_hi_watermark) tx hi "
10254 	    "watermark\n", sc->tx_hi_watermark, sc->max_tx_bd);
10255 
10256 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_prod) rx producer "
10257 	    "index\n", sc->rx_prod, (u16) RX_CHAIN_IDX(sc->rx_prod));
10258 
10259 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_cons) rx consumer "
10260 	    "index\n", sc->rx_cons, (u16) RX_CHAIN_IDX(sc->rx_cons));
10261 
10262 	BCE_PRINTF("         0x%08X - (sc->rx_prod_bseq) rx producer "
10263 	    "byte seq index\n",	sc->rx_prod_bseq);
10264 
10265 	BCE_PRINTF("         0x%08X - (sc->debug_rx_mbuf_alloc) rx "
10266 	    "mbufs allocated\n", sc->debug_rx_mbuf_alloc);
10267 
10268 	BCE_PRINTF("         0x%08X - (sc->free_rx_bd) free "
10269 	    "rx_bd's\n", sc->free_rx_bd);
10270 
10271 #ifdef BCE_JUMBO_HDRSPLIT
10272 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_prod) page producer "
10273 	    "index\n", sc->pg_prod, (u16) PG_CHAIN_IDX(sc->pg_prod));
10274 
10275 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_cons) page consumer "
10276 	    "index\n", sc->pg_cons, (u16) PG_CHAIN_IDX(sc->pg_cons));
10277 
10278 	BCE_PRINTF("         0x%08X - (sc->debug_pg_mbuf_alloc) page "
10279 	    "mbufs allocated\n", sc->debug_pg_mbuf_alloc);
10280 
10281 	BCE_PRINTF("         0x%08X - (sc->free_pg_bd) free page "
10282 	    "rx_bd's\n", sc->free_pg_bd);
10283 
10284 	BCE_PRINTF("0x%08X/%08X - (sc->pg_low_watermark) page low "
10285 	    "watermark\n", sc->pg_low_watermark, sc->max_pg_bd);
10286 #endif
10287 
10288 	BCE_PRINTF("         0x%08X - (sc->mbuf_alloc_failed_count) "
10289 	    "mbuf alloc failures\n", sc->mbuf_alloc_failed_count);
10290 
10291 	BCE_PRINTF("         0x%08X - (sc->bce_flags) "
10292 	    "bce mac flags\n", sc->bce_flags);
10293 
10294 	BCE_PRINTF("         0x%08X - (sc->bce_phy_flags) "
10295 	    "bce phy flags\n", sc->bce_phy_flags);
10296 
10297 	BCE_PRINTF(
10298 	    "----------------------------"
10299 	    "----------------"
10300 	    "----------------------------\n");
10301 }
10302 
10303 
10304 /****************************************************************************/
10305 /* Prints out the hardware state through a summary of important register,   */
10306 /* followed by a complete register dump.                                    */
10307 /*                                                                          */
10308 /* Returns:                                                                 */
10309 /*   Nothing.                                                               */
10310 /****************************************************************************/
10311 static __attribute__ ((noinline)) void
10312 bce_dump_hw_state(struct bce_softc *sc)
10313 {
10314 	u32 val;
10315 
10316 	BCE_PRINTF(
10317 	    "----------------------------"
10318 	    " Hardware State "
10319 	    "----------------------------\n");
10320 
10321 	BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
10322 
10323 	val = REG_RD(sc, BCE_MISC_ENABLE_STATUS_BITS);
10324 	BCE_PRINTF("0x%08X - (0x%06X) misc_enable_status_bits\n",
10325 	    val, BCE_MISC_ENABLE_STATUS_BITS);
10326 
10327 	val = REG_RD(sc, BCE_DMA_STATUS);
10328 	BCE_PRINTF("0x%08X - (0x%06X) dma_status\n",
10329 	    val, BCE_DMA_STATUS);
10330 
10331 	val = REG_RD(sc, BCE_CTX_STATUS);
10332 	BCE_PRINTF("0x%08X - (0x%06X) ctx_status\n",
10333 	    val, BCE_CTX_STATUS);
10334 
10335 	val = REG_RD(sc, BCE_EMAC_STATUS);
10336 	BCE_PRINTF("0x%08X - (0x%06X) emac_status\n",
10337 	    val, BCE_EMAC_STATUS);
10338 
10339 	val = REG_RD(sc, BCE_RPM_STATUS);
10340 	BCE_PRINTF("0x%08X - (0x%06X) rpm_status\n",
10341 	    val, BCE_RPM_STATUS);
10342 
10343 	/* ToDo: Create a #define for this constant. */
10344 	val = REG_RD(sc, 0x2004);
10345 	BCE_PRINTF("0x%08X - (0x%06X) rlup_status\n",
10346 	    val, 0x2004);
10347 
10348 	val = REG_RD(sc, BCE_RV2P_STATUS);
10349 	BCE_PRINTF("0x%08X - (0x%06X) rv2p_status\n",
10350 	    val, BCE_RV2P_STATUS);
10351 
10352 	/* ToDo: Create a #define for this constant. */
10353 	val = REG_RD(sc, 0x2c04);
10354 	BCE_PRINTF("0x%08X - (0x%06X) rdma_status\n",
10355 	    val, 0x2c04);
10356 
10357 	val = REG_RD(sc, BCE_TBDR_STATUS);
10358 	BCE_PRINTF("0x%08X - (0x%06X) tbdr_status\n",
10359 	    val, BCE_TBDR_STATUS);
10360 
10361 	val = REG_RD(sc, BCE_TDMA_STATUS);
10362 	BCE_PRINTF("0x%08X - (0x%06X) tdma_status\n",
10363 	    val, BCE_TDMA_STATUS);
10364 
10365 	val = REG_RD(sc, BCE_HC_STATUS);
10366 	BCE_PRINTF("0x%08X - (0x%06X) hc_status\n",
10367 	    val, BCE_HC_STATUS);
10368 
10369 	val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
10370 	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n",
10371 	    val, BCE_TXP_CPU_STATE);
10372 
10373 	val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
10374 	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n",
10375 	    val, BCE_TPAT_CPU_STATE);
10376 
10377 	val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
10378 	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n",
10379 	    val, BCE_RXP_CPU_STATE);
10380 
10381 	val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
10382 	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n",
10383 	    val, BCE_COM_CPU_STATE);
10384 
10385 	val = REG_RD_IND(sc, BCE_MCP_CPU_STATE);
10386 	BCE_PRINTF("0x%08X - (0x%06X) mcp_cpu_state\n",
10387 	    val, BCE_MCP_CPU_STATE);
10388 
10389 	val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
10390 	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n",
10391 	    val, BCE_CP_CPU_STATE);
10392 
10393 	BCE_PRINTF(
10394 	    "----------------------------"
10395 	    "----------------"
10396 	    "----------------------------\n");
10397 
10398 	BCE_PRINTF(
10399 	    "----------------------------"
10400 	    " Register  Dump "
10401 	    "----------------------------\n");
10402 
10403 	for (int i = 0x400; i < 0x8000; i += 0x10) {
10404 		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10405 		    i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
10406 		    REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
10407 	}
10408 
10409 	BCE_PRINTF(
10410 	    "----------------------------"
10411 	    "----------------"
10412 	    "----------------------------\n");
10413 }
10414 
10415 
10416 /****************************************************************************/
10417 /* Prints out the mailbox queue registers.                                  */
10418 /*                                                                          */
10419 /* Returns:                                                                 */
10420 /*   Nothing.                                                               */
10421 /****************************************************************************/
10422 static __attribute__ ((noinline)) void
10423 bce_dump_mq_regs(struct bce_softc *sc)
10424 {
10425 	BCE_PRINTF(
10426 	    "----------------------------"
10427 	    "    MQ Regs     "
10428 	    "----------------------------\n");
10429 
10430 	BCE_PRINTF(
10431 	    "----------------------------"
10432 	    "----------------"
10433 	    "----------------------------\n");
10434 
10435 	for (int i = 0x3c00; i < 0x4000; i += 0x10) {
10436 		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10437 		    i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
10438 		    REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
10439 	}
10440 
10441 	BCE_PRINTF(
10442 	    "----------------------------"
10443 	    "----------------"
10444 	    "----------------------------\n");
10445 }
10446 
10447 
10448 /****************************************************************************/
10449 /* Prints out the bootcode state.                                           */
10450 /*                                                                          */
10451 /* Returns:                                                                 */
10452 /*   Nothing.                                                               */
10453 /****************************************************************************/
10454 static __attribute__ ((noinline)) void
10455 bce_dump_bc_state(struct bce_softc *sc)
10456 {
10457 	u32 val;
10458 
10459 	BCE_PRINTF(
10460 	    "----------------------------"
10461 	    " Bootcode State "
10462 	    "----------------------------\n");
10463 
10464 	BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
10465 
10466 	val = bce_shmem_rd(sc, BCE_BC_RESET_TYPE);
10467 	BCE_PRINTF("0x%08X - (0x%06X) reset_type\n",
10468 	    val, BCE_BC_RESET_TYPE);
10469 
10470 	val = bce_shmem_rd(sc, BCE_BC_STATE);
10471 	BCE_PRINTF("0x%08X - (0x%06X) state\n",
10472 	    val, BCE_BC_STATE);
10473 
10474 	val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
10475 	BCE_PRINTF("0x%08X - (0x%06X) condition\n",
10476 	    val, BCE_BC_STATE_CONDITION);
10477 
10478 	val = bce_shmem_rd(sc, BCE_BC_STATE_DEBUG_CMD);
10479 	BCE_PRINTF("0x%08X - (0x%06X) debug_cmd\n",
10480 	    val, BCE_BC_STATE_DEBUG_CMD);
10481 
10482 	BCE_PRINTF(
10483 	    "----------------------------"
10484 	    "----------------"
10485 	    "----------------------------\n");
10486 }
10487 
10488 
10489 /****************************************************************************/
10490 /* Prints out the TXP processor state.                                      */
10491 /*                                                                          */
10492 /* Returns:                                                                 */
10493 /*   Nothing.                                                               */
10494 /****************************************************************************/
10495 static __attribute__ ((noinline)) void
10496 bce_dump_txp_state(struct bce_softc *sc, int regs)
10497 {
10498 	u32 val;
10499 	u32 fw_version[3];
10500 
10501 	BCE_PRINTF(
10502 	    "----------------------------"
10503 	    "   TXP  State   "
10504 	    "----------------------------\n");
10505 
10506 	for (int i = 0; i < 3; i++)
10507 		fw_version[i] = htonl(REG_RD_IND(sc,
10508 		    (BCE_TXP_SCRATCH + 0x10 + i * 4)));
10509 	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10510 
10511 	val = REG_RD_IND(sc, BCE_TXP_CPU_MODE);
10512 	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_mode\n",
10513 	    val, BCE_TXP_CPU_MODE);
10514 
10515 	val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
10516 	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n",
10517 	    val, BCE_TXP_CPU_STATE);
10518 
10519 	val = REG_RD_IND(sc, BCE_TXP_CPU_EVENT_MASK);
10520 	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_event_mask\n",
10521 	    val, BCE_TXP_CPU_EVENT_MASK);
10522 
10523 	if (regs) {
10524 		BCE_PRINTF(
10525 		    "----------------------------"
10526 		    " Register  Dump "
10527 		    "----------------------------\n");
10528 
10529 		for (int i = BCE_TXP_CPU_MODE; i < 0x68000; i += 0x10) {
10530 			/* Skip the big blank spaces */
10531 			if (i < 0x454000 && i > 0x5ffff)
10532 				BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
10533 				    "0x%08X 0x%08X\n", i,
10534 				    REG_RD_IND(sc, i),
10535 				    REG_RD_IND(sc, i + 0x4),
10536 				    REG_RD_IND(sc, i + 0x8),
10537 				    REG_RD_IND(sc, i + 0xC));
10538 		}
10539 	}
10540 
10541 	BCE_PRINTF(
10542 	    "----------------------------"
10543 	    "----------------"
10544 	    "----------------------------\n");
10545 }
10546 
10547 
10548 /****************************************************************************/
10549 /* Prints out the RXP processor state.                                      */
10550 /*                                                                          */
10551 /* Returns:                                                                 */
10552 /*   Nothing.                                                               */
10553 /****************************************************************************/
10554 static __attribute__ ((noinline)) void
10555 bce_dump_rxp_state(struct bce_softc *sc, int regs)
10556 {
10557 	u32 val;
10558 	u32 fw_version[3];
10559 
10560 	BCE_PRINTF(
10561 	    "----------------------------"
10562 	    "   RXP  State   "
10563 	    "----------------------------\n");
10564 
10565 	for (int i = 0; i < 3; i++)
10566 		fw_version[i] = htonl(REG_RD_IND(sc,
10567 		    (BCE_RXP_SCRATCH + 0x10 + i * 4)));
10568 
10569 	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10570 
10571 	val = REG_RD_IND(sc, BCE_RXP_CPU_MODE);
10572 	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_mode\n",
10573 	    val, BCE_RXP_CPU_MODE);
10574 
10575 	val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
10576 	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n",
10577 	    val, BCE_RXP_CPU_STATE);
10578 
10579 	val = REG_RD_IND(sc, BCE_RXP_CPU_EVENT_MASK);
10580 	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_event_mask\n",
10581 	    val, BCE_RXP_CPU_EVENT_MASK);
10582 
10583 	if (regs) {
10584 		BCE_PRINTF(
10585 		    "----------------------------"
10586 		    " Register  Dump "
10587 		    "----------------------------\n");
10588 
10589 		for (int i = BCE_RXP_CPU_MODE; i < 0xe8fff; i += 0x10) {
10590 			/* Skip the big blank sapces */
10591 			if (i < 0xc5400 && i > 0xdffff)
10592 				BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
10593 				    "0x%08X 0x%08X\n", i,
10594 				    REG_RD_IND(sc, i),
10595 				    REG_RD_IND(sc, i + 0x4),
10596 				    REG_RD_IND(sc, i + 0x8),
10597 				    REG_RD_IND(sc, i + 0xC));
10598 		}
10599 	}
10600 
10601 	BCE_PRINTF(
10602 	    "----------------------------"
10603 	    "----------------"
10604 	    "----------------------------\n");
10605 }
10606 
10607 
10608 /****************************************************************************/
10609 /* Prints out the TPAT processor state.                                     */
10610 /*                                                                          */
10611 /* Returns:                                                                 */
10612 /*   Nothing.                                                               */
10613 /****************************************************************************/
10614 static __attribute__ ((noinline)) void
10615 bce_dump_tpat_state(struct bce_softc *sc, int regs)
10616 {
10617 	u32 val;
10618 	u32 fw_version[3];
10619 
10620 	BCE_PRINTF(
10621 	    "----------------------------"
10622 	    "   TPAT State   "
10623 	    "----------------------------\n");
10624 
10625 	for (int i = 0; i < 3; i++)
10626 		fw_version[i] = htonl(REG_RD_IND(sc,
10627 		    (BCE_TPAT_SCRATCH + 0x410 + i * 4)));
10628 
10629 	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10630 
10631 	val = REG_RD_IND(sc, BCE_TPAT_CPU_MODE);
10632 	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_mode\n",
10633 	    val, BCE_TPAT_CPU_MODE);
10634 
10635 	val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
10636 	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n",
10637 	    val, BCE_TPAT_CPU_STATE);
10638 
10639 	val = REG_RD_IND(sc, BCE_TPAT_CPU_EVENT_MASK);
10640 	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_event_mask\n",
10641 	    val, BCE_TPAT_CPU_EVENT_MASK);
10642 
10643 	if (regs) {
10644 		BCE_PRINTF(
10645 		    "----------------------------"
10646 		    " Register  Dump "
10647 		    "----------------------------\n");
10648 
10649 		for (int i = BCE_TPAT_CPU_MODE; i < 0xa3fff; i += 0x10) {
10650 			/* Skip the big blank spaces */
10651 			if (i < 0x854000 && i > 0x9ffff)
10652 				BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
10653 				    "0x%08X 0x%08X\n", i,
10654 				    REG_RD_IND(sc, i),
10655 				    REG_RD_IND(sc, i + 0x4),
10656 				    REG_RD_IND(sc, i + 0x8),
10657 				    REG_RD_IND(sc, i + 0xC));
10658 		}
10659 	}
10660 
10661 	BCE_PRINTF(
10662 		"----------------------------"
10663 		"----------------"
10664 		"----------------------------\n");
10665 }
10666 
10667 
10668 /****************************************************************************/
10669 /* Prints out the Command Procesor (CP) state.                              */
10670 /*                                                                          */
10671 /* Returns:                                                                 */
10672 /*   Nothing.                                                               */
10673 /****************************************************************************/
10674 static __attribute__ ((noinline)) void
10675 bce_dump_cp_state(struct bce_softc *sc, int regs)
10676 {
10677 	u32 val;
10678 	u32 fw_version[3];
10679 
10680 	BCE_PRINTF(
10681 	    "----------------------------"
10682 	    "    CP State    "
10683 	    "----------------------------\n");
10684 
10685 	for (int i = 0; i < 3; i++)
10686 		fw_version[i] = htonl(REG_RD_IND(sc,
10687 		    (BCE_CP_SCRATCH + 0x10 + i * 4)));
10688 
10689 	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10690 
10691 	val = REG_RD_IND(sc, BCE_CP_CPU_MODE);
10692 	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_mode\n",
10693 	    val, BCE_CP_CPU_MODE);
10694 
10695 	val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
10696 	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n",
10697 	    val, BCE_CP_CPU_STATE);
10698 
10699 	val = REG_RD_IND(sc, BCE_CP_CPU_EVENT_MASK);
10700 	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_event_mask\n", val,
10701 	    BCE_CP_CPU_EVENT_MASK);
10702 
10703 	if (regs) {
10704 		BCE_PRINTF(
10705 		    "----------------------------"
10706 		    " Register  Dump "
10707 		    "----------------------------\n");
10708 
10709 		for (int i = BCE_CP_CPU_MODE; i < 0x1aa000; i += 0x10) {
10710 			/* Skip the big blank spaces */
10711 			if (i < 0x185400 && i > 0x19ffff)
10712 				BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
10713 				    "0x%08X 0x%08X\n", i,
10714 				    REG_RD_IND(sc, i),
10715 				    REG_RD_IND(sc, i + 0x4),
10716 				    REG_RD_IND(sc, i + 0x8),
10717 				    REG_RD_IND(sc, i + 0xC));
10718 		}
10719 	}
10720 
10721 	BCE_PRINTF(
10722 	    "----------------------------"
10723 	    "----------------"
10724 	    "----------------------------\n");
10725 }
10726 
10727 
10728 /****************************************************************************/
10729 /* Prints out the Completion Procesor (COM) state.                          */
10730 /*                                                                          */
10731 /* Returns:                                                                 */
10732 /*   Nothing.                                                               */
10733 /****************************************************************************/
10734 static __attribute__ ((noinline)) void
10735 bce_dump_com_state(struct bce_softc *sc, int regs)
10736 {
10737 	u32 val;
10738 	u32 fw_version[4];
10739 
10740 	BCE_PRINTF(
10741 	    "----------------------------"
10742 	    "   COM State    "
10743 	    "----------------------------\n");
10744 
10745 	for (int i = 0; i < 3; i++)
10746 		fw_version[i] = htonl(REG_RD_IND(sc,
10747 		    (BCE_COM_SCRATCH + 0x10 + i * 4)));
10748 
10749 	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10750 
10751 	val = REG_RD_IND(sc, BCE_COM_CPU_MODE);
10752 	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_mode\n",
10753 	    val, BCE_COM_CPU_MODE);
10754 
10755 	val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
10756 	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n",
10757 	    val, BCE_COM_CPU_STATE);
10758 
10759 	val = REG_RD_IND(sc, BCE_COM_CPU_EVENT_MASK);
10760 	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_event_mask\n", val,
10761 	    BCE_COM_CPU_EVENT_MASK);
10762 
10763 	if (regs) {
10764 		BCE_PRINTF(
10765 		    "----------------------------"
10766 		    " Register  Dump "
10767 		    "----------------------------\n");
10768 
10769 		for (int i = BCE_COM_CPU_MODE; i < 0x1053e8; i += 0x10) {
10770 			BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
10771 			    "0x%08X 0x%08X\n", i,
10772 			    REG_RD_IND(sc, i),
10773 			    REG_RD_IND(sc, i + 0x4),
10774 			    REG_RD_IND(sc, i + 0x8),
10775 			    REG_RD_IND(sc, i + 0xC));
10776 		}
10777 	}
10778 
10779 	BCE_PRINTF(
10780 		"----------------------------"
10781 		"----------------"
10782 		"----------------------------\n");
10783 }
10784 
10785 
10786 /****************************************************************************/
10787 /* Prints out the Receive Virtual 2 Physical (RV2P) state.                  */
10788 /*                                                                          */
10789 /* Returns:                                                                 */
10790 /*   Nothing.                                                               */
10791 /****************************************************************************/
10792 static __attribute__ ((noinline)) void
10793 bce_dump_rv2p_state(struct bce_softc *sc)
10794 {
10795 	u32 val, pc1, pc2, fw_ver_high, fw_ver_low;
10796 
10797 	BCE_PRINTF(
10798 	    "----------------------------"
10799 	    "   RV2P State   "
10800 	    "----------------------------\n");
10801 
10802 	/* Stall the RV2P processors. */
10803 	val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
10804 	val |= BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2;
10805 	REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
10806 
10807 	/* Read the firmware version. */
10808 	val = 0x00000001;
10809 	REG_WR_IND(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
10810 	fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
10811 	fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) &
10812 	    BCE_RV2P_INSTR_HIGH_HIGH;
10813 	BCE_PRINTF("RV2P1 Firmware version - 0x%08X:0x%08X\n",
10814 	    fw_ver_high, fw_ver_low);
10815 
10816 	val = 0x00000001;
10817 	REG_WR_IND(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
10818 	fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
10819 	fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) &
10820 	    BCE_RV2P_INSTR_HIGH_HIGH;
10821 	BCE_PRINTF("RV2P2 Firmware version - 0x%08X:0x%08X\n",
10822 	    fw_ver_high, fw_ver_low);
10823 
10824 	/* Resume the RV2P processors. */
10825 	val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
10826 	val &= ~(BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2);
10827 	REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
10828 
10829 	/* Fetch the program counter value. */
10830 	val = 0x68007800;
10831 	REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
10832 	val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
10833 	pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
10834 	pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
10835 	BCE_PRINTF("0x%08X - RV2P1 program counter (1st read)\n", pc1);
10836 	BCE_PRINTF("0x%08X - RV2P2 program counter (1st read)\n", pc2);
10837 
10838 	/* Fetch the program counter value again to see if it is advancing. */
10839 	val = 0x68007800;
10840 	REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
10841 	val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
10842 	pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
10843 	pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
10844 	BCE_PRINTF("0x%08X - RV2P1 program counter (2nd read)\n", pc1);
10845 	BCE_PRINTF("0x%08X - RV2P2 program counter (2nd read)\n", pc2);
10846 
10847 	BCE_PRINTF(
10848 	    "----------------------------"
10849 	    "----------------"
10850 	    "----------------------------\n");
10851 }
10852 
10853 
10854 /****************************************************************************/
10855 /* Prints out the driver state and then enters the debugger.                */
10856 /*                                                                          */
10857 /* Returns:                                                                 */
10858 /*   Nothing.                                                               */
10859 /****************************************************************************/
10860 static __attribute__ ((noinline)) void
10861 bce_breakpoint(struct bce_softc *sc)
10862 {
10863 
10864 	/*
10865 	 * Unreachable code to silence compiler warnings
10866 	 * about unused functions.
10867 	 */
10868 	if (0) {
10869 		bce_freeze_controller(sc);
10870 		bce_unfreeze_controller(sc);
10871 		bce_dump_enet(sc, NULL);
10872 		bce_dump_txbd(sc, 0, NULL);
10873 		bce_dump_rxbd(sc, 0, NULL);
10874 		bce_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD);
10875 		bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD);
10876 		bce_dump_l2fhdr(sc, 0, NULL);
10877 		bce_dump_ctx(sc, RX_CID);
10878 		bce_dump_ftqs(sc);
10879 		bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
10880 		bce_dump_rx_bd_chain(sc, 0, USABLE_RX_BD);
10881 		bce_dump_status_block(sc);
10882 		bce_dump_stats_block(sc);
10883 		bce_dump_driver_state(sc);
10884 		bce_dump_hw_state(sc);
10885 		bce_dump_bc_state(sc);
10886 		bce_dump_txp_state(sc, 0);
10887 		bce_dump_rxp_state(sc, 0);
10888 		bce_dump_tpat_state(sc, 0);
10889 		bce_dump_cp_state(sc, 0);
10890 		bce_dump_com_state(sc, 0);
10891 		bce_dump_rv2p_state(sc);
10892 
10893 #ifdef BCE_JUMBO_HDRSPLIT
10894 		bce_dump_pgbd(sc, 0, NULL);
10895 		bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD);
10896 		bce_dump_pg_chain(sc, 0, USABLE_PG_BD);
10897 #endif
10898 	}
10899 
10900 	bce_dump_status_block(sc);
10901 	bce_dump_driver_state(sc);
10902 
10903 	/* Call the debugger. */
10904 	breakpoint();
10905 
10906 	return;
10907 }
10908 #endif
10909 
10910