xref: /netbsd-src/sys/dev/pci/if_bnx.c (revision cac8e449158efc7261bebc8657cbb0125a2cfdde)
1 /*	$NetBSD: if_bnx.c,v 1.18 2008/02/07 01:21:55 dyoung Exp $	*/
2 /*	$OpenBSD: if_bnx.c,v 1.43 2007/01/30 03:21:10 krw Exp $	*/
3 
4 /*-
5  * Copyright (c) 2006 Broadcom Corporation
6  *	David Christensen <davidch@broadcom.com>.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of Broadcom Corporation nor the name of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written consent.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31  * THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #include <sys/cdefs.h>
35 #if 0
36 __FBSDID("$FreeBSD: src/sys/dev/bce/if_bce.c,v 1.3 2006/04/13 14:12:26 ru Exp $");
37 #endif
38 __KERNEL_RCSID(0, "$NetBSD: if_bnx.c,v 1.18 2008/02/07 01:21:55 dyoung Exp $");
39 
40 /*
41  * The following controllers are supported by this driver:
42  *   BCM5706C A2, A3
43  *   BCM5708C B1
44  *
45  * The following controllers are not supported by this driver:
46  * (These are not "Production" versions of the controller.)
47  *
48  *   BCM5706C A0, A1
49  *   BCM5706S A0, A1, A2, A3
50  *   BCM5708C A0, B0
51  *   BCM5708S A0, B0, B1
52  */
53 
54 #include <sys/callout.h>
55 
56 #include <dev/pci/if_bnxreg.h>
57 #include <dev/microcode/bnx/bnxfw.h>
58 
59 /****************************************************************************/
60 /* BNX Driver Version                                                       */
61 /****************************************************************************/
62 const char bnx_driver_version[] = "v0.9.6";
63 
64 /****************************************************************************/
65 /* BNX Debug Options                                                        */
66 /****************************************************************************/
67 #ifdef BNX_DEBUG
68 	u_int32_t bnx_debug = /*BNX_WARN*/ BNX_VERBOSE_SEND;
69 
70 	/*          0 = Never              */
71 	/*          1 = 1 in 2,147,483,648 */
72 	/*        256 = 1 in     8,388,608 */
73 	/*       2048 = 1 in     1,048,576 */
74 	/*      65536 = 1 in        32,768 */
75 	/*    1048576 = 1 in         2,048 */
76 	/*  268435456 =	1 in             8 */
77 	/*  536870912 = 1 in             4 */
78 	/* 1073741824 = 1 in             2 */
79 
80 	/* Controls how often the l2_fhdr frame error check will fail. */
81 	int bnx_debug_l2fhdr_status_check = 0;
82 
83 	/* Controls how often the unexpected attention check will fail. */
84 	int bnx_debug_unexpected_attention = 0;
85 
86 	/* Controls how often to simulate an mbuf allocation failure. */
87 	int bnx_debug_mbuf_allocation_failure = 0;
88 
89 	/* Controls how often to simulate a DMA mapping failure. */
90 	int bnx_debug_dma_map_addr_failure = 0;
91 
92 	/* Controls how often to simulate a bootcode failure. */
93 	int bnx_debug_bootcode_running_failure = 0;
94 #endif
95 
96 /****************************************************************************/
97 /* PCI Device ID Table                                                      */
98 /*                                                                          */
99 /* Used by bnx_probe() to identify the devices supported by this driver.    */
100 /****************************************************************************/
101 static const struct bnx_product {
102 	pci_vendor_id_t		bp_vendor;
103 	pci_product_id_t	bp_product;
104 	pci_vendor_id_t		bp_subvendor;
105 	pci_product_id_t	bp_subproduct;
106 	const char		*bp_name;
107 } bnx_devices[] = {
108 #ifdef PCI_SUBPRODUCT_HP_NC370T
109 	{
110 	  PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5706,
111 	  PCI_VENDOR_HP, PCI_SUBPRODUCT_HP_NC370T,
112 	  "HP NC370T Multifunction Gigabit Server Adapter"
113 	},
114 #endif
115 #ifdef PCI_SUBPRODUCT_HP_NC370i
116 	{
117 	  PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5706,
118 	  PCI_VENDOR_HP, PCI_SUBPRODUCT_HP_NC370i,
119 	  "HP NC370i Multifunction Gigabit Server Adapter"
120 	},
121 #endif
122 	{
123 	  PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5706,
124 	  0, 0,
125 	  "Broadcom NetXtreme II BCM5706 1000Base-T"
126 	},
127 #ifdef PCI_SUBPRODUCT_HP_NC370F
128 	{
129 	  PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5706S,
130 	  PCI_VENDOR_HP, PCI_SUBPRODUCT_HP_NC370F,
131 	  "HP NC370F Multifunction Gigabit Server Adapter"
132 	},
133 #endif
134 	{
135 	  PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5706S,
136 	  0, 0,
137 	  "Broadcom NetXtreme II BCM5706 1000Base-SX"
138 	},
139 	{
140 	  PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5708,
141 	  0, 0,
142 	  "Broadcom NetXtreme II BCM5708 1000Base-T"
143 	},
144 	{
145 	  PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5708S,
146 	  0, 0,
147 	  "Broadcom NetXtreme II BCM5708 1000Base-SX"
148 	},
149 };
150 
151 /****************************************************************************/
152 /* Supported Flash NVRAM device data.                                       */
153 /****************************************************************************/
154 static struct flash_spec flash_table[] =
155 {
156 	/* Slow EEPROM */
157 	{0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
158 	 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
159 	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
160 	 "EEPROM - slow"},
161 	/* Expansion entry 0001 */
162 	{0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
163 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
164 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
165 	 "Entry 0001"},
166 	/* Saifun SA25F010 (non-buffered flash) */
167 	/* strap, cfg1, & write1 need updates */
168 	{0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
169 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
170 	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
171 	 "Non-buffered flash (128kB)"},
172 	/* Saifun SA25F020 (non-buffered flash) */
173 	/* strap, cfg1, & write1 need updates */
174 	{0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
175 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
176 	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
177 	 "Non-buffered flash (256kB)"},
178 	/* Expansion entry 0100 */
179 	{0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
180 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
181 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
182 	 "Entry 0100"},
183 	/* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
184 	{0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
185 	 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
186 	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
187 	 "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
188 	/* Entry 0110: ST M45PE20 (non-buffered flash)*/
189 	{0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
190 	 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
191 	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
192 	 "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
193 	/* Saifun SA25F005 (non-buffered flash) */
194 	/* strap, cfg1, & write1 need updates */
195 	{0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
196 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
197 	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
198 	 "Non-buffered flash (64kB)"},
199 	/* Fast EEPROM */
200 	{0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
201 	 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
202 	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
203 	 "EEPROM - fast"},
204 	/* Expansion entry 1001 */
205 	{0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
206 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
207 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
208 	 "Entry 1001"},
209 	/* Expansion entry 1010 */
210 	{0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
211 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
212 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
213 	 "Entry 1010"},
214 	/* ATMEL AT45DB011B (buffered flash) */
215 	{0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
216 	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
217 	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
218 	 "Buffered flash (128kB)"},
219 	/* Expansion entry 1100 */
220 	{0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
221 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
222 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
223 	 "Entry 1100"},
224 	/* Expansion entry 1101 */
225 	{0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
226 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
227 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
228 	 "Entry 1101"},
229 	/* Ateml Expansion entry 1110 */
230 	{0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
231 	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
232 	 BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
233 	 "Entry 1110 (Atmel)"},
234 	/* ATMEL AT45DB021B (buffered flash) */
235 	{0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
236 	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
237 	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
238 	 "Buffered flash (256kB)"},
239 };
240 
241 /****************************************************************************/
242 /* OpenBSD device entry points.                                             */
243 /****************************************************************************/
244 static int	bnx_probe(device_t, cfdata_t, void *);
245 void	bnx_attach(device_t, device_t, void *);
246 int	bnx_detach(device_t, int);
247 
248 /****************************************************************************/
249 /* BNX Debug Data Structure Dump Routines                                   */
250 /****************************************************************************/
251 #ifdef BNX_DEBUG
252 void	bnx_dump_mbuf(struct bnx_softc *, struct mbuf *);
253 void	bnx_dump_tx_mbuf_chain(struct bnx_softc *, int, int);
254 void	bnx_dump_rx_mbuf_chain(struct bnx_softc *, int, int);
255 void	bnx_dump_txbd(struct bnx_softc *, int, struct tx_bd *);
256 void	bnx_dump_rxbd(struct bnx_softc *, int, struct rx_bd *);
257 void	bnx_dump_l2fhdr(struct bnx_softc *, int, struct l2_fhdr *);
258 void	bnx_dump_tx_chain(struct bnx_softc *, int, int);
259 void	bnx_dump_rx_chain(struct bnx_softc *, int, int);
260 void	bnx_dump_status_block(struct bnx_softc *);
261 void	bnx_dump_stats_block(struct bnx_softc *);
262 void	bnx_dump_driver_state(struct bnx_softc *);
263 void	bnx_dump_hw_state(struct bnx_softc *);
264 void	bnx_breakpoint(struct bnx_softc *);
265 #endif
266 
267 /****************************************************************************/
268 /* BNX Register/Memory Access Routines                                      */
269 /****************************************************************************/
270 u_int32_t	bnx_reg_rd_ind(struct bnx_softc *, u_int32_t);
271 void	bnx_reg_wr_ind(struct bnx_softc *, u_int32_t, u_int32_t);
272 void	bnx_ctx_wr(struct bnx_softc *, u_int32_t, u_int32_t, u_int32_t);
273 int	bnx_miibus_read_reg(device_t, int, int);
274 void	bnx_miibus_write_reg(device_t, int, int, int);
275 void	bnx_miibus_statchg(device_t);
276 
277 /****************************************************************************/
278 /* BNX NVRAM Access Routines                                                */
279 /****************************************************************************/
280 int	bnx_acquire_nvram_lock(struct bnx_softc *);
281 int	bnx_release_nvram_lock(struct bnx_softc *);
282 void	bnx_enable_nvram_access(struct bnx_softc *);
283 void	bnx_disable_nvram_access(struct bnx_softc *);
284 int	bnx_nvram_read_dword(struct bnx_softc *, u_int32_t, u_int8_t *,
285 	    u_int32_t);
286 int	bnx_init_nvram(struct bnx_softc *);
287 int	bnx_nvram_read(struct bnx_softc *, u_int32_t, u_int8_t *, int);
288 int	bnx_nvram_test(struct bnx_softc *);
289 #ifdef BNX_NVRAM_WRITE_SUPPORT
290 int	bnx_enable_nvram_write(struct bnx_softc *);
291 void	bnx_disable_nvram_write(struct bnx_softc *);
292 int	bnx_nvram_erase_page(struct bnx_softc *, u_int32_t);
293 int	bnx_nvram_write_dword(struct bnx_softc *, u_int32_t, u_int8_t *,
294 	    u_int32_t);
295 int	bnx_nvram_write(struct bnx_softc *, u_int32_t, u_int8_t *, int);
296 #endif
297 
298 /****************************************************************************/
299 /*                                                                          */
300 /****************************************************************************/
301 int	bnx_dma_alloc(struct bnx_softc *);
302 void	bnx_dma_free(struct bnx_softc *);
303 void	bnx_release_resources(struct bnx_softc *);
304 
305 /****************************************************************************/
306 /* BNX Firmware Synchronization and Load                                    */
307 /****************************************************************************/
308 int	bnx_fw_sync(struct bnx_softc *, u_int32_t);
309 void	bnx_load_rv2p_fw(struct bnx_softc *, u_int32_t *, u_int32_t,
310 	    u_int32_t);
311 void	bnx_load_cpu_fw(struct bnx_softc *, struct cpu_reg *,
312 	    struct fw_info *);
313 void	bnx_init_cpus(struct bnx_softc *);
314 
315 void	bnx_stop(struct ifnet *, int);
316 int	bnx_reset(struct bnx_softc *, u_int32_t);
317 int	bnx_chipinit(struct bnx_softc *);
318 int	bnx_blockinit(struct bnx_softc *);
319 int	bnx_get_buf(struct bnx_softc *, struct mbuf *, u_int16_t *,
320 	    u_int16_t *, u_int32_t *);
321 
322 int	bnx_init_tx_chain(struct bnx_softc *);
323 int	bnx_init_rx_chain(struct bnx_softc *);
324 void	bnx_free_rx_chain(struct bnx_softc *);
325 void	bnx_free_tx_chain(struct bnx_softc *);
326 
327 int	bnx_tx_encap(struct bnx_softc *, struct mbuf **);
328 void	bnx_start(struct ifnet *);
329 int	bnx_ioctl(struct ifnet *, u_long, void *);
330 void	bnx_watchdog(struct ifnet *);
331 int	bnx_init(struct ifnet *);
332 
333 void	bnx_init_context(struct bnx_softc *);
334 void	bnx_get_mac_addr(struct bnx_softc *);
335 void	bnx_set_mac_addr(struct bnx_softc *);
336 void	bnx_phy_intr(struct bnx_softc *);
337 void	bnx_rx_intr(struct bnx_softc *);
338 void	bnx_tx_intr(struct bnx_softc *);
339 void	bnx_disable_intr(struct bnx_softc *);
340 void	bnx_enable_intr(struct bnx_softc *);
341 
342 int	bnx_intr(void *);
343 void	bnx_set_rx_mode(struct bnx_softc *);
344 void	bnx_stats_update(struct bnx_softc *);
345 void	bnx_tick(void *);
346 
347 /****************************************************************************/
348 /* OpenBSD device dispatch table.                                           */
349 /****************************************************************************/
350 CFATTACH_DECL_NEW(bnx, sizeof(struct bnx_softc),
351     bnx_probe, bnx_attach, bnx_detach, NULL);
352 
353 /****************************************************************************/
354 /* Device probe function.                                                   */
355 /*                                                                          */
356 /* Compares the device to the driver's list of supported devices and        */
357 /* reports back to the OS whether this is the right driver for the device.  */
358 /*                                                                          */
359 /* Returns:                                                                 */
360 /*   BUS_PROBE_DEFAULT on success, positive value on failure.               */
361 /****************************************************************************/
362 static const struct bnx_product *
363 bnx_lookup(const struct pci_attach_args *pa)
364 {
365 	int i;
366 	pcireg_t subid;
367 
368 	for (i = 0; i < __arraycount(bnx_devices); i++) {
369 		if (PCI_VENDOR(pa->pa_id) != bnx_devices[i].bp_vendor ||
370 		    PCI_PRODUCT(pa->pa_id) != bnx_devices[i].bp_product)
371 			continue;
372 		if (!bnx_devices[i].bp_subvendor)
373 			return &bnx_devices[i];
374 		subid = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
375 		if (PCI_VENDOR(subid) == bnx_devices[i].bp_subvendor &&
376 		    PCI_PRODUCT(subid) == bnx_devices[i].bp_subproduct)
377 			return &bnx_devices[i];
378 	}
379 
380 	return NULL;
381 }
382 static int
383 bnx_probe(device_t parent, cfdata_t match, void *aux)
384 {
385 	struct pci_attach_args *pa = (struct pci_attach_args *)aux;
386 
387 	if (bnx_lookup(pa) != NULL)
388 		return (1);
389 
390 	return (0);
391 }
392 
393 /****************************************************************************/
394 /* Device attach function.                                                  */
395 /*                                                                          */
396 /* Allocates device resources, performs secondary chip identification,      */
397 /* resets and initializes the hardware, and initializes driver instance     */
398 /* variables.                                                               */
399 /*                                                                          */
400 /* Returns:                                                                 */
401 /*   0 on success, positive value on failure.                               */
402 /****************************************************************************/
403 void
404 bnx_attach(device_t parent, device_t self, void *aux)
405 {
406 	const struct bnx_product *bp;
407 	struct bnx_softc	*sc = device_private(self);
408 	struct pci_attach_args	*pa = aux;
409 	pci_chipset_tag_t	pc = pa->pa_pc;
410 	pci_intr_handle_t	ih;
411 	const char 		*intrstr = NULL;
412 	u_int32_t		command;
413 	struct ifnet		*ifp;
414 	u_int32_t		val;
415 	pcireg_t		memtype;
416 
417 	bp = bnx_lookup(pa);
418 	if (bp == NULL)
419 		panic("unknown device");
420 
421 	sc->bnx_dev = self;
422 
423 	aprint_naive("\n");
424 	aprint_normal(": %s\n", bp->bp_name);
425 
426 	sc->bnx_pa = *pa;
427 
428 	/*
429 	 * Map control/status registers.
430 	*/
431 	command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
432 	command |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE;
433 	pci_conf_write(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG, command);
434 	command = pci_conf_read(pc, pa->pa_tag, PCI_COMMAND_STATUS_REG);
435 
436 	if (!(command & PCI_COMMAND_MEM_ENABLE)) {
437 		aprint_error_dev(sc->bnx_dev,
438 		    "failed to enable memory mapping!\n");
439 		return;
440 	}
441 
442 	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BNX_PCI_BAR0);
443 	switch (memtype) {
444 	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
445 	case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
446 		if (pci_mapreg_map(pa, BNX_PCI_BAR0,
447 		    memtype, 0, &sc->bnx_btag, &sc->bnx_bhandle,
448 		    NULL, &sc->bnx_size) == 0)
449 			break;
450 	default:
451 		aprint_error_dev(sc->bnx_dev, "can't find mem space\n");
452 		return;
453 	}
454 
455 	if (pci_intr_map(pa, &ih)) {
456 		aprint_error_dev(sc->bnx_dev, "couldn't map interrupt\n");
457 		goto bnx_attach_fail;
458 	}
459 
460 	intrstr = pci_intr_string(pc, ih);
461 
462 	/*
463 	 * Configure byte swap and enable indirect register access.
464 	 * Rely on CPU to do target byte swapping on big endian systems.
465 	 * Access to registers outside of PCI configurtion space are not
466 	 * valid until this is done.
467 	 */
468 	pci_conf_write(pa->pa_pc, pa->pa_tag, BNX_PCICFG_MISC_CONFIG,
469 	    BNX_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
470 	    BNX_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP);
471 
472 	/* Save ASIC revsion info. */
473 	sc->bnx_chipid =  REG_RD(sc, BNX_MISC_ID);
474 
475 	/* Weed out any non-production controller revisions. */
476 	switch(BNX_CHIP_ID(sc)) {
477 	case BNX_CHIP_ID_5706_A0:
478 	case BNX_CHIP_ID_5706_A1:
479 	case BNX_CHIP_ID_5708_A0:
480 	case BNX_CHIP_ID_5708_B0:
481 		aprint_error_dev(sc->bnx_dev,
482 		    "unsupported controller revision (%c%d)!\n",
483 		    ((PCI_REVISION(pa->pa_class) & 0xf0) >> 4) + 'A',
484 		    PCI_REVISION(pa->pa_class) & 0x0f);
485 		goto bnx_attach_fail;
486 	}
487 
488 	if (BNX_CHIP_BOND_ID(sc) & BNX_CHIP_BOND_ID_SERDES_BIT) {
489 		aprint_error_dev(sc->bnx_dev,
490 		    "SerDes controllers are not supported!\n");
491 		goto bnx_attach_fail;
492 	}
493 
494 	/*
495 	 * Find the base address for shared memory access.
496 	 * Newer versions of bootcode use a signature and offset
497 	 * while older versions use a fixed address.
498 	 */
499 	val = REG_RD_IND(sc, BNX_SHM_HDR_SIGNATURE);
500 	if ((val & BNX_SHM_HDR_SIGNATURE_SIG_MASK) == BNX_SHM_HDR_SIGNATURE_SIG)
501 		sc->bnx_shmem_base = REG_RD_IND(sc, BNX_SHM_HDR_ADDR_0);
502 	else
503 		sc->bnx_shmem_base = HOST_VIEW_SHMEM_BASE;
504 
505 	DBPRINT(sc, BNX_INFO, "bnx_shmem_base = 0x%08X\n", sc->bnx_shmem_base);
506 
507 	/* Set initial device and PHY flags */
508 	sc->bnx_flags = 0;
509 	sc->bnx_phy_flags = 0;
510 
511 	/* Get PCI bus information (speed and type). */
512 	val = REG_RD(sc, BNX_PCICFG_MISC_STATUS);
513 	if (val & BNX_PCICFG_MISC_STATUS_PCIX_DET) {
514 		u_int32_t clkreg;
515 
516 		sc->bnx_flags |= BNX_PCIX_FLAG;
517 
518 		clkreg = REG_RD(sc, BNX_PCICFG_PCI_CLOCK_CONTROL_BITS);
519 
520 		clkreg &= BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
521 		switch (clkreg) {
522 		case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
523 			sc->bus_speed_mhz = 133;
524 			break;
525 
526 		case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
527 			sc->bus_speed_mhz = 100;
528 			break;
529 
530 		case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
531 		case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
532 			sc->bus_speed_mhz = 66;
533 			break;
534 
535 		case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
536 		case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
537 			sc->bus_speed_mhz = 50;
538 			break;
539 
540 		case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
541 		case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
542 		case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
543 			sc->bus_speed_mhz = 33;
544 			break;
545 		}
546 	} else if (val & BNX_PCICFG_MISC_STATUS_M66EN)
547 			sc->bus_speed_mhz = 66;
548 		else
549 			sc->bus_speed_mhz = 33;
550 
551 	if (val & BNX_PCICFG_MISC_STATUS_32BIT_DET)
552 		sc->bnx_flags |= BNX_PCI_32BIT_FLAG;
553 
554 	/* Reset the controller. */
555 	if (bnx_reset(sc, BNX_DRV_MSG_CODE_RESET))
556 		goto bnx_attach_fail;
557 
558 	/* Initialize the controller. */
559 	if (bnx_chipinit(sc)) {
560 		aprint_error_dev(sc->bnx_dev,
561 		    "Controller initialization failed!\n");
562 		goto bnx_attach_fail;
563 	}
564 
565 	/* Perform NVRAM test. */
566 	if (bnx_nvram_test(sc)) {
567 		aprint_error_dev(sc->bnx_dev, "NVRAM test failed!\n");
568 		goto bnx_attach_fail;
569 	}
570 
571 	/* Fetch the permanent Ethernet MAC address. */
572 	bnx_get_mac_addr(sc);
573 	aprint_normal_dev(sc->bnx_dev, "Ethernet address %s\n",
574 	    ether_sprintf(sc->eaddr));
575 
576 	/*
577 	 * Trip points control how many BDs
578 	 * should be ready before generating an
579 	 * interrupt while ticks control how long
580 	 * a BD can sit in the chain before
581 	 * generating an interrupt.  Set the default
582 	 * values for the RX and TX rings.
583 	 */
584 
585 #ifdef BNX_DEBUG
586 	/* Force more frequent interrupts. */
587 	sc->bnx_tx_quick_cons_trip_int = 1;
588 	sc->bnx_tx_quick_cons_trip     = 1;
589 	sc->bnx_tx_ticks_int           = 0;
590 	sc->bnx_tx_ticks               = 0;
591 
592 	sc->bnx_rx_quick_cons_trip_int = 1;
593 	sc->bnx_rx_quick_cons_trip     = 1;
594 	sc->bnx_rx_ticks_int           = 0;
595 	sc->bnx_rx_ticks               = 0;
596 #else
597 	sc->bnx_tx_quick_cons_trip_int = 20;
598 	sc->bnx_tx_quick_cons_trip     = 20;
599 	sc->bnx_tx_ticks_int           = 80;
600 	sc->bnx_tx_ticks               = 80;
601 
602 	sc->bnx_rx_quick_cons_trip_int = 6;
603 	sc->bnx_rx_quick_cons_trip     = 6;
604 	sc->bnx_rx_ticks_int           = 18;
605 	sc->bnx_rx_ticks               = 18;
606 #endif
607 
608 	/* Update statistics once every second. */
609 	sc->bnx_stats_ticks = 1000000 & 0xffff00;
610 
611 	/*
612 	 * The copper based NetXtreme II controllers
613 	 * use an integrated PHY at address 1 while
614 	 * the SerDes controllers use a PHY at
615 	 * address 2.
616 	 */
617 	sc->bnx_phy_addr = 1;
618 
619 	if (BNX_CHIP_BOND_ID(sc) & BNX_CHIP_BOND_ID_SERDES_BIT) {
620 		sc->bnx_phy_flags |= BNX_PHY_SERDES_FLAG;
621 		sc->bnx_flags |= BNX_NO_WOL_FLAG;
622 		if (BNX_CHIP_NUM(sc) == BNX_CHIP_NUM_5708) {
623 			sc->bnx_phy_addr = 2;
624 			val = REG_RD_IND(sc, sc->bnx_shmem_base +
625 					 BNX_SHARED_HW_CFG_CONFIG);
626 			if (val & BNX_SHARED_HW_CFG_PHY_2_5G)
627 				sc->bnx_phy_flags |= BNX_PHY_2_5G_CAPABLE_FLAG;
628 		}
629 	}
630 
631 	if (sc->bnx_phy_flags & BNX_PHY_SERDES_FLAG) {
632 		aprint_error_dev(sc->bnx_dev,
633 		    "SerDes is not supported by this driver!\n");
634 		goto bnx_attach_fail;
635 	}
636 
637 	/* Allocate DMA memory resources. */
638 	sc->bnx_dmatag = pa->pa_dmat;
639 	if (bnx_dma_alloc(sc)) {
640 		aprint_error_dev(sc->bnx_dev,
641 		    "DMA resource allocation failed!\n");
642 		goto bnx_attach_fail;
643 	}
644 
645 	/* Initialize the ifnet interface. */
646 	ifp = &sc->bnx_ec.ec_if;
647 	ifp->if_softc = sc;
648 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
649 	ifp->if_ioctl = bnx_ioctl;
650 	ifp->if_stop = bnx_stop;
651 	ifp->if_start = bnx_start;
652 	ifp->if_init = bnx_init;
653 	ifp->if_timer = 0;
654 	ifp->if_watchdog = bnx_watchdog;
655         if (sc->bnx_phy_flags & BNX_PHY_2_5G_CAPABLE_FLAG)
656                 ifp->if_baudrate = IF_Gbps(2.5);
657         else
658                 ifp->if_baudrate = IF_Gbps(1);
659 	IFQ_SET_MAXLEN(&ifp->if_snd, USABLE_TX_BD - 1);
660 	IFQ_SET_READY(&ifp->if_snd);
661 	memcpy(ifp->if_xname, device_xname(self), IFNAMSIZ);
662 
663 	sc->bnx_ec.ec_capabilities |= ETHERCAP_JUMBO_MTU |
664 	    ETHERCAP_VLAN_MTU | ETHERCAP_VLAN_HWTAGGING;
665 
666 	ifp->if_capabilities |=
667 	    IFCAP_CSUM_IPv4_Tx | IFCAP_CSUM_IPv4_Rx |
668 	    IFCAP_CSUM_TCPv4_Tx | IFCAP_CSUM_TCPv4_Rx |
669 	    IFCAP_CSUM_UDPv4_Tx | IFCAP_CSUM_UDPv4_Rx;
670 
671 	/* Hookup IRQ last. */
672 	sc->bnx_intrhand = pci_intr_establish(pc, ih, IPL_NET, bnx_intr, sc);
673 	if (sc->bnx_intrhand == NULL) {
674 		aprint_error_dev(self, "couldn't establish interrupt");
675 		if (intrstr != NULL)
676 			aprint_error(" at %s", intrstr);
677 		aprint_error("\n");
678 		goto bnx_attach_fail;
679 	}
680 
681 	sc->bnx_mii.mii_ifp = ifp;
682 	sc->bnx_mii.mii_readreg = bnx_miibus_read_reg;
683 	sc->bnx_mii.mii_writereg = bnx_miibus_write_reg;
684 	sc->bnx_mii.mii_statchg = bnx_miibus_statchg;
685 
686 	sc->bnx_ec.ec_mii = &sc->bnx_mii;
687 	ifmedia_init(&sc->bnx_mii.mii_media, 0, ether_mediachange,
688 	    ether_mediastatus);
689 	mii_attach(self, &sc->bnx_mii, 0xffffffff,
690 	    MII_PHY_ANY, MII_OFFSET_ANY, MIIF_FORCEANEG);
691 
692 	if (LIST_EMPTY(&sc->bnx_mii.mii_phys)) {
693 		aprint_error_dev(self, "no PHY found!\n");
694 		ifmedia_add(&sc->bnx_mii.mii_media,
695 		    IFM_ETHER|IFM_MANUAL, 0, NULL);
696 		ifmedia_set(&sc->bnx_mii.mii_media,
697 		    IFM_ETHER|IFM_MANUAL);
698 	} else {
699 		ifmedia_set(&sc->bnx_mii.mii_media,
700 		    IFM_ETHER|IFM_AUTO);
701 	}
702 
703 	/* Attach to the Ethernet interface list. */
704 	if_attach(ifp);
705 	ether_ifattach(ifp,sc->eaddr);
706 
707 	callout_init(&sc->bnx_timeout, 0);
708 
709 	if (!pmf_device_register(self, NULL, NULL))
710 		aprint_error_dev(self, "couldn't establish power handler\n");
711 	else
712 		pmf_class_network_register(self, ifp);
713 
714 	/* Print some important debugging info. */
715 	DBRUN(BNX_INFO, bnx_dump_driver_state(sc));
716 
717 	goto bnx_attach_exit;
718 
719 bnx_attach_fail:
720 	bnx_release_resources(sc);
721 
722 bnx_attach_exit:
723 	DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __func__);
724 }
725 
726 /****************************************************************************/
727 /* Device detach function.                                                  */
728 /*                                                                          */
729 /* Stops the controller, resets the controller, and releases resources.     */
730 /*                                                                          */
731 /* Returns:                                                                 */
732 /*   0 on success, positive value on failure.                               */
733 /****************************************************************************/
734 int
735 bnx_detach(device_t dev, int flags)
736 {
737 	int s;
738 	struct bnx_softc *sc;
739 	struct ifnet *ifp;
740 
741 	sc = device_private(dev);
742 	ifp = &sc->bnx_ec.ec_if;
743 
744 	DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __func__);
745 
746 	/* Stop and reset the controller. */
747 	s = splnet();
748 	if (ifp->if_flags & IFF_RUNNING)
749 		bnx_stop(ifp, 1);
750 	splx(s);
751 
752 	pmf_device_deregister(dev);
753 	ether_ifdetach(ifp);
754 	if_detach(ifp);
755 	mii_detach(&sc->bnx_mii, MII_PHY_ANY, MII_OFFSET_ANY);
756 
757 	/* Release all remaining resources. */
758 	bnx_release_resources(sc);
759 
760 	DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __func__);
761 
762 	return(0);
763 }
764 
765 /****************************************************************************/
766 /* Indirect register read.                                                  */
767 /*                                                                          */
768 /* Reads NetXtreme II registers using an index/data register pair in PCI    */
769 /* configuration space.  Using this mechanism avoids issues with posted     */
770 /* reads but is much slower than memory-mapped I/O.                         */
771 /*                                                                          */
772 /* Returns:                                                                 */
773 /*   The value of the register.                                             */
774 /****************************************************************************/
775 u_int32_t
776 bnx_reg_rd_ind(struct bnx_softc *sc, u_int32_t offset)
777 {
778 	struct pci_attach_args	*pa = &(sc->bnx_pa);
779 
780 	pci_conf_write(pa->pa_pc, pa->pa_tag, BNX_PCICFG_REG_WINDOW_ADDRESS,
781 	    offset);
782 #ifdef BNX_DEBUG
783 	{
784 		u_int32_t val;
785 		val = pci_conf_read(pa->pa_pc, pa->pa_tag,
786 		    BNX_PCICFG_REG_WINDOW);
787 		DBPRINT(sc, BNX_EXCESSIVE, "%s(); offset = 0x%08X, "
788 		    "val = 0x%08X\n", __func__, offset, val);
789 		return (val);
790 	}
791 #else
792 	return pci_conf_read(pa->pa_pc, pa->pa_tag, BNX_PCICFG_REG_WINDOW);
793 #endif
794 }
795 
796 /****************************************************************************/
797 /* Indirect register write.                                                 */
798 /*                                                                          */
799 /* Writes NetXtreme II registers using an index/data register pair in PCI   */
800 /* configuration space.  Using this mechanism avoids issues with posted     */
801 /* writes but is muchh slower than memory-mapped I/O.                       */
802 /*                                                                          */
803 /* Returns:                                                                 */
804 /*   Nothing.                                                               */
805 /****************************************************************************/
806 void
807 bnx_reg_wr_ind(struct bnx_softc *sc, u_int32_t offset, u_int32_t val)
808 {
809 	struct pci_attach_args  *pa = &(sc->bnx_pa);
810 
811 	DBPRINT(sc, BNX_EXCESSIVE, "%s(); offset = 0x%08X, val = 0x%08X\n",
812 		__func__, offset, val);
813 
814 	pci_conf_write(pa->pa_pc, pa->pa_tag, BNX_PCICFG_REG_WINDOW_ADDRESS,
815 	    offset);
816 	pci_conf_write(pa->pa_pc, pa->pa_tag, BNX_PCICFG_REG_WINDOW, val);
817 }
818 
819 /****************************************************************************/
820 /* Context memory write.                                                    */
821 /*                                                                          */
822 /* The NetXtreme II controller uses context memory to track connection      */
823 /* information for L2 and higher network protocols.                         */
824 /*                                                                          */
825 /* Returns:                                                                 */
826 /*   Nothing.                                                               */
827 /****************************************************************************/
828 void
829 bnx_ctx_wr(struct bnx_softc *sc, u_int32_t cid_addr, u_int32_t offset,
830     u_int32_t val)
831 {
832 
833 	DBPRINT(sc, BNX_EXCESSIVE, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
834 		"val = 0x%08X\n", __func__, cid_addr, offset, val);
835 
836 	offset += cid_addr;
837 	REG_WR(sc, BNX_CTX_DATA_ADR, offset);
838 	REG_WR(sc, BNX_CTX_DATA, val);
839 }
840 
841 /****************************************************************************/
842 /* PHY register read.                                                       */
843 /*                                                                          */
844 /* Implements register reads on the MII bus.                                */
845 /*                                                                          */
846 /* Returns:                                                                 */
847 /*   The value of the register.                                             */
848 /****************************************************************************/
849 int
850 bnx_miibus_read_reg(device_t dev, int phy, int reg)
851 {
852 	struct bnx_softc	*sc = device_private(dev);
853 	u_int32_t		val;
854 	int			i;
855 
856 	/* Make sure we are accessing the correct PHY address. */
857 	if (phy != sc->bnx_phy_addr) {
858 		DBPRINT(sc, BNX_VERBOSE,
859 		    "Invalid PHY address %d for PHY read!\n", phy);
860 		return(0);
861 	}
862 
863 	if (sc->bnx_phy_flags & BNX_PHY_INT_MODE_AUTO_POLLING_FLAG) {
864 		val = REG_RD(sc, BNX_EMAC_MDIO_MODE);
865 		val &= ~BNX_EMAC_MDIO_MODE_AUTO_POLL;
866 
867 		REG_WR(sc, BNX_EMAC_MDIO_MODE, val);
868 		REG_RD(sc, BNX_EMAC_MDIO_MODE);
869 
870 		DELAY(40);
871 	}
872 
873 	val = BNX_MIPHY(phy) | BNX_MIREG(reg) |
874 	    BNX_EMAC_MDIO_COMM_COMMAND_READ | BNX_EMAC_MDIO_COMM_DISEXT |
875 	    BNX_EMAC_MDIO_COMM_START_BUSY;
876 	REG_WR(sc, BNX_EMAC_MDIO_COMM, val);
877 
878 	for (i = 0; i < BNX_PHY_TIMEOUT; i++) {
879 		DELAY(10);
880 
881 		val = REG_RD(sc, BNX_EMAC_MDIO_COMM);
882 		if (!(val & BNX_EMAC_MDIO_COMM_START_BUSY)) {
883 			DELAY(5);
884 
885 			val = REG_RD(sc, BNX_EMAC_MDIO_COMM);
886 			val &= BNX_EMAC_MDIO_COMM_DATA;
887 
888 			break;
889 		}
890 	}
891 
892 	if (val & BNX_EMAC_MDIO_COMM_START_BUSY) {
893 		BNX_PRINTF(sc, "%s(%d): Error: PHY read timeout! phy = %d, "
894 		    "reg = 0x%04X\n", __FILE__, __LINE__, phy, reg);
895 		val = 0x0;
896 	} else
897 		val = REG_RD(sc, BNX_EMAC_MDIO_COMM);
898 
899 	DBPRINT(sc, BNX_EXCESSIVE,
900 	    "%s(): phy = %d, reg = 0x%04X, val = 0x%04X\n", __func__, phy,
901 	    (u_int16_t) reg & 0xffff, (u_int16_t) val & 0xffff);
902 
903 	if (sc->bnx_phy_flags & BNX_PHY_INT_MODE_AUTO_POLLING_FLAG) {
904 		val = REG_RD(sc, BNX_EMAC_MDIO_MODE);
905 		val |= BNX_EMAC_MDIO_MODE_AUTO_POLL;
906 
907 		REG_WR(sc, BNX_EMAC_MDIO_MODE, val);
908 		REG_RD(sc, BNX_EMAC_MDIO_MODE);
909 
910 		DELAY(40);
911 	}
912 
913 	return (val & 0xffff);
914 }
915 
916 /****************************************************************************/
917 /* PHY register write.                                                      */
918 /*                                                                          */
919 /* Implements register writes on the MII bus.                               */
920 /*                                                                          */
921 /* Returns:                                                                 */
922 /*   The value of the register.                                             */
923 /****************************************************************************/
924 void
925 bnx_miibus_write_reg(device_t dev, int phy, int reg, int val)
926 {
927 	struct bnx_softc	*sc = device_private(dev);
928 	u_int32_t		val1;
929 	int			i;
930 
931 	/* Make sure we are accessing the correct PHY address. */
932 	if (phy != sc->bnx_phy_addr) {
933 		DBPRINT(sc, BNX_WARN, "Invalid PHY address %d for PHY write!\n",
934 		    phy);
935 		return;
936 	}
937 
938 	DBPRINT(sc, BNX_EXCESSIVE, "%s(): phy = %d, reg = 0x%04X, "
939 	    "val = 0x%04X\n", __func__,
940 	    phy, (u_int16_t) reg & 0xffff, (u_int16_t) val & 0xffff);
941 
942 	if (sc->bnx_phy_flags & BNX_PHY_INT_MODE_AUTO_POLLING_FLAG) {
943 		val1 = REG_RD(sc, BNX_EMAC_MDIO_MODE);
944 		val1 &= ~BNX_EMAC_MDIO_MODE_AUTO_POLL;
945 
946 		REG_WR(sc, BNX_EMAC_MDIO_MODE, val1);
947 		REG_RD(sc, BNX_EMAC_MDIO_MODE);
948 
949 		DELAY(40);
950 	}
951 
952 	val1 = BNX_MIPHY(phy) | BNX_MIREG(reg) | val |
953 	    BNX_EMAC_MDIO_COMM_COMMAND_WRITE |
954 	    BNX_EMAC_MDIO_COMM_START_BUSY | BNX_EMAC_MDIO_COMM_DISEXT;
955 	REG_WR(sc, BNX_EMAC_MDIO_COMM, val1);
956 
957 	for (i = 0; i < BNX_PHY_TIMEOUT; i++) {
958 		DELAY(10);
959 
960 		val1 = REG_RD(sc, BNX_EMAC_MDIO_COMM);
961 		if (!(val1 & BNX_EMAC_MDIO_COMM_START_BUSY)) {
962 			DELAY(5);
963 			break;
964 		}
965 	}
966 
967 	if (val1 & BNX_EMAC_MDIO_COMM_START_BUSY) {
968 		BNX_PRINTF(sc, "%s(%d): PHY write timeout!\n", __FILE__,
969 		    __LINE__);
970 	}
971 
972 	if (sc->bnx_phy_flags & BNX_PHY_INT_MODE_AUTO_POLLING_FLAG) {
973 		val1 = REG_RD(sc, BNX_EMAC_MDIO_MODE);
974 		val1 |= BNX_EMAC_MDIO_MODE_AUTO_POLL;
975 
976 		REG_WR(sc, BNX_EMAC_MDIO_MODE, val1);
977 		REG_RD(sc, BNX_EMAC_MDIO_MODE);
978 
979 		DELAY(40);
980 	}
981 }
982 
983 /****************************************************************************/
984 /* MII bus status change.                                                   */
985 /*                                                                          */
986 /* Called by the MII bus driver when the PHY establishes link to set the    */
987 /* MAC interface registers.                                                 */
988 /*                                                                          */
989 /* Returns:                                                                 */
990 /*   Nothing.                                                               */
991 /****************************************************************************/
992 void
993 bnx_miibus_statchg(device_t dev)
994 {
995 	struct bnx_softc	*sc = device_private(dev);
996 	struct mii_data		*mii = &sc->bnx_mii;
997 
998 	BNX_CLRBIT(sc, BNX_EMAC_MODE, BNX_EMAC_MODE_PORT);
999 
1000 	/* Set MII or GMII inerface based on the speed negotiated by the PHY. */
1001 	if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) {
1002 		DBPRINT(sc, BNX_INFO, "Setting GMII interface.\n");
1003 		BNX_SETBIT(sc, BNX_EMAC_MODE, BNX_EMAC_MODE_PORT_GMII);
1004 	} else {
1005 		DBPRINT(sc, BNX_INFO, "Setting MII interface.\n");
1006 		BNX_SETBIT(sc, BNX_EMAC_MODE, BNX_EMAC_MODE_PORT_MII);
1007 	}
1008 
1009 	/* Set half or full duplex based on the duplicity
1010 	 * negotiated by the PHY.
1011 	 */
1012 	if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
1013 		DBPRINT(sc, BNX_INFO, "Setting Full-Duplex interface.\n");
1014 		BNX_CLRBIT(sc, BNX_EMAC_MODE, BNX_EMAC_MODE_HALF_DUPLEX);
1015 	} else {
1016 		DBPRINT(sc, BNX_INFO, "Setting Half-Duplex interface.\n");
1017 		BNX_SETBIT(sc, BNX_EMAC_MODE, BNX_EMAC_MODE_HALF_DUPLEX);
1018 	}
1019 }
1020 
1021 /****************************************************************************/
1022 /* Acquire NVRAM lock.                                                      */
1023 /*                                                                          */
1024 /* Before the NVRAM can be accessed the caller must acquire an NVRAM lock.  */
1025 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1026 /* for use by the driver.                                                   */
1027 /*                                                                          */
1028 /* Returns:                                                                 */
1029 /*   0 on success, positive value on failure.                               */
1030 /****************************************************************************/
1031 int
1032 bnx_acquire_nvram_lock(struct bnx_softc *sc)
1033 {
1034 	u_int32_t		val;
1035 	int			j;
1036 
1037 	DBPRINT(sc, BNX_VERBOSE, "Acquiring NVRAM lock.\n");
1038 
1039 	/* Request access to the flash interface. */
1040 	REG_WR(sc, BNX_NVM_SW_ARB, BNX_NVM_SW_ARB_ARB_REQ_SET2);
1041 	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1042 		val = REG_RD(sc, BNX_NVM_SW_ARB);
1043 		if (val & BNX_NVM_SW_ARB_ARB_ARB2)
1044 			break;
1045 
1046 		DELAY(5);
1047 	}
1048 
1049 	if (j >= NVRAM_TIMEOUT_COUNT) {
1050 		DBPRINT(sc, BNX_WARN, "Timeout acquiring NVRAM lock!\n");
1051 		return (EBUSY);
1052 	}
1053 
1054 	return (0);
1055 }
1056 
1057 /****************************************************************************/
1058 /* Release NVRAM lock.                                                      */
1059 /*                                                                          */
1060 /* When the caller is finished accessing NVRAM the lock must be released.   */
1061 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1062 /* for use by the driver.                                                   */
1063 /*                                                                          */
1064 /* Returns:                                                                 */
1065 /*   0 on success, positive value on failure.                               */
1066 /****************************************************************************/
1067 int
1068 bnx_release_nvram_lock(struct bnx_softc *sc)
1069 {
1070 	int			j;
1071 	u_int32_t		val;
1072 
1073 	DBPRINT(sc, BNX_VERBOSE, "Releasing NVRAM lock.\n");
1074 
1075 	/* Relinquish nvram interface. */
1076 	REG_WR(sc, BNX_NVM_SW_ARB, BNX_NVM_SW_ARB_ARB_REQ_CLR2);
1077 
1078 	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1079 		val = REG_RD(sc, BNX_NVM_SW_ARB);
1080 		if (!(val & BNX_NVM_SW_ARB_ARB_ARB2))
1081 			break;
1082 
1083 		DELAY(5);
1084 	}
1085 
1086 	if (j >= NVRAM_TIMEOUT_COUNT) {
1087 		DBPRINT(sc, BNX_WARN, "Timeout reeasing NVRAM lock!\n");
1088 		return (EBUSY);
1089 	}
1090 
1091 	return (0);
1092 }
1093 
1094 #ifdef BNX_NVRAM_WRITE_SUPPORT
1095 /****************************************************************************/
1096 /* Enable NVRAM write access.                                               */
1097 /*                                                                          */
1098 /* Before writing to NVRAM the caller must enable NVRAM writes.             */
1099 /*                                                                          */
1100 /* Returns:                                                                 */
1101 /*   0 on success, positive value on failure.                               */
1102 /****************************************************************************/
1103 int
1104 bnx_enable_nvram_write(struct bnx_softc *sc)
1105 {
1106 	u_int32_t		val;
1107 
1108 	DBPRINT(sc, BNX_VERBOSE, "Enabling NVRAM write.\n");
1109 
1110 	val = REG_RD(sc, BNX_MISC_CFG);
1111 	REG_WR(sc, BNX_MISC_CFG, val | BNX_MISC_CFG_NVM_WR_EN_PCI);
1112 
1113 	if (!sc->bnx_flash_info->buffered) {
1114 		int j;
1115 
1116 		REG_WR(sc, BNX_NVM_COMMAND, BNX_NVM_COMMAND_DONE);
1117 		REG_WR(sc, BNX_NVM_COMMAND,
1118 		    BNX_NVM_COMMAND_WREN | BNX_NVM_COMMAND_DOIT);
1119 
1120 		for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1121 			DELAY(5);
1122 
1123 			val = REG_RD(sc, BNX_NVM_COMMAND);
1124 			if (val & BNX_NVM_COMMAND_DONE)
1125 				break;
1126 		}
1127 
1128 		if (j >= NVRAM_TIMEOUT_COUNT) {
1129 			DBPRINT(sc, BNX_WARN, "Timeout writing NVRAM!\n");
1130 			return (EBUSY);
1131 		}
1132 	}
1133 
1134 	return (0);
1135 }
1136 
1137 /****************************************************************************/
1138 /* Disable NVRAM write access.                                              */
1139 /*                                                                          */
1140 /* When the caller is finished writing to NVRAM write access must be        */
1141 /* disabled.                                                                */
1142 /*                                                                          */
1143 /* Returns:                                                                 */
1144 /*   Nothing.                                                               */
1145 /****************************************************************************/
1146 void
1147 bnx_disable_nvram_write(struct bnx_softc *sc)
1148 {
1149 	u_int32_t		val;
1150 
1151 	DBPRINT(sc, BNX_VERBOSE,  "Disabling NVRAM write.\n");
1152 
1153 	val = REG_RD(sc, BNX_MISC_CFG);
1154 	REG_WR(sc, BNX_MISC_CFG, val & ~BNX_MISC_CFG_NVM_WR_EN);
1155 }
1156 #endif
1157 
1158 /****************************************************************************/
1159 /* Enable NVRAM access.                                                     */
1160 /*                                                                          */
1161 /* Before accessing NVRAM for read or write operations the caller must      */
1162 /* enabled NVRAM access.                                                    */
1163 /*                                                                          */
1164 /* Returns:                                                                 */
1165 /*   Nothing.                                                               */
1166 /****************************************************************************/
1167 void
1168 bnx_enable_nvram_access(struct bnx_softc *sc)
1169 {
1170 	u_int32_t		val;
1171 
1172 	DBPRINT(sc, BNX_VERBOSE, "Enabling NVRAM access.\n");
1173 
1174 	val = REG_RD(sc, BNX_NVM_ACCESS_ENABLE);
1175 	/* Enable both bits, even on read. */
1176 	REG_WR(sc, BNX_NVM_ACCESS_ENABLE,
1177 	    val | BNX_NVM_ACCESS_ENABLE_EN | BNX_NVM_ACCESS_ENABLE_WR_EN);
1178 }
1179 
1180 /****************************************************************************/
1181 /* Disable NVRAM access.                                                    */
1182 /*                                                                          */
1183 /* When the caller is finished accessing NVRAM access must be disabled.     */
1184 /*                                                                          */
1185 /* Returns:                                                                 */
1186 /*   Nothing.                                                               */
1187 /****************************************************************************/
1188 void
1189 bnx_disable_nvram_access(struct bnx_softc *sc)
1190 {
1191 	u_int32_t		val;
1192 
1193 	DBPRINT(sc, BNX_VERBOSE, "Disabling NVRAM access.\n");
1194 
1195 	val = REG_RD(sc, BNX_NVM_ACCESS_ENABLE);
1196 
1197 	/* Disable both bits, even after read. */
1198 	REG_WR(sc, BNX_NVM_ACCESS_ENABLE,
1199 	    val & ~(BNX_NVM_ACCESS_ENABLE_EN | BNX_NVM_ACCESS_ENABLE_WR_EN));
1200 }
1201 
1202 #ifdef BNX_NVRAM_WRITE_SUPPORT
1203 /****************************************************************************/
1204 /* Erase NVRAM page before writing.                                         */
1205 /*                                                                          */
1206 /* Non-buffered flash parts require that a page be erased before it is      */
1207 /* written.                                                                 */
1208 /*                                                                          */
1209 /* Returns:                                                                 */
1210 /*   0 on success, positive value on failure.                               */
1211 /****************************************************************************/
1212 int
1213 bnx_nvram_erase_page(struct bnx_softc *sc, u_int32_t offset)
1214 {
1215 	u_int32_t		cmd;
1216 	int			j;
1217 
1218 	/* Buffered flash doesn't require an erase. */
1219 	if (sc->bnx_flash_info->buffered)
1220 		return (0);
1221 
1222 	DBPRINT(sc, BNX_VERBOSE, "Erasing NVRAM page.\n");
1223 
1224 	/* Build an erase command. */
1225 	cmd = BNX_NVM_COMMAND_ERASE | BNX_NVM_COMMAND_WR |
1226 	    BNX_NVM_COMMAND_DOIT;
1227 
1228 	/*
1229 	 * Clear the DONE bit separately, set the NVRAM adress to erase,
1230 	 * and issue the erase command.
1231 	 */
1232 	REG_WR(sc, BNX_NVM_COMMAND, BNX_NVM_COMMAND_DONE);
1233 	REG_WR(sc, BNX_NVM_ADDR, offset & BNX_NVM_ADDR_NVM_ADDR_VALUE);
1234 	REG_WR(sc, BNX_NVM_COMMAND, cmd);
1235 
1236 	/* Wait for completion. */
1237 	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1238 		u_int32_t val;
1239 
1240 		DELAY(5);
1241 
1242 		val = REG_RD(sc, BNX_NVM_COMMAND);
1243 		if (val & BNX_NVM_COMMAND_DONE)
1244 			break;
1245 	}
1246 
1247 	if (j >= NVRAM_TIMEOUT_COUNT) {
1248 		DBPRINT(sc, BNX_WARN, "Timeout erasing NVRAM.\n");
1249 		return (EBUSY);
1250 	}
1251 
1252 	return (0);
1253 }
1254 #endif /* BNX_NVRAM_WRITE_SUPPORT */
1255 
1256 /****************************************************************************/
1257 /* Read a dword (32 bits) from NVRAM.                                       */
1258 /*                                                                          */
1259 /* Read a 32 bit word from NVRAM.  The caller is assumed to have already    */
1260 /* obtained the NVRAM lock and enabled the controller for NVRAM access.     */
1261 /*                                                                          */
1262 /* Returns:                                                                 */
1263 /*   0 on success and the 32 bit value read, positive value on failure.     */
1264 /****************************************************************************/
1265 int
1266 bnx_nvram_read_dword(struct bnx_softc *sc, u_int32_t offset,
1267     u_int8_t *ret_val, u_int32_t cmd_flags)
1268 {
1269 	u_int32_t		cmd;
1270 	int			i, rc = 0;
1271 
1272 	/* Build the command word. */
1273 	cmd = BNX_NVM_COMMAND_DOIT | cmd_flags;
1274 
1275 	/* Calculate the offset for buffered flash. */
1276 	if (sc->bnx_flash_info->buffered)
1277 		offset = ((offset / sc->bnx_flash_info->page_size) <<
1278 		    sc->bnx_flash_info->page_bits) +
1279 		    (offset % sc->bnx_flash_info->page_size);
1280 
1281 	/*
1282 	 * Clear the DONE bit separately, set the address to read,
1283 	 * and issue the read.
1284 	 */
1285 	REG_WR(sc, BNX_NVM_COMMAND, BNX_NVM_COMMAND_DONE);
1286 	REG_WR(sc, BNX_NVM_ADDR, offset & BNX_NVM_ADDR_NVM_ADDR_VALUE);
1287 	REG_WR(sc, BNX_NVM_COMMAND, cmd);
1288 
1289 	/* Wait for completion. */
1290 	for (i = 0; i < NVRAM_TIMEOUT_COUNT; i++) {
1291 		u_int32_t val;
1292 
1293 		DELAY(5);
1294 
1295 		val = REG_RD(sc, BNX_NVM_COMMAND);
1296 		if (val & BNX_NVM_COMMAND_DONE) {
1297 			val = REG_RD(sc, BNX_NVM_READ);
1298 
1299 			val = bnx_be32toh(val);
1300 			memcpy(ret_val, &val, 4);
1301 			break;
1302 		}
1303 	}
1304 
1305 	/* Check for errors. */
1306 	if (i >= NVRAM_TIMEOUT_COUNT) {
1307 		BNX_PRINTF(sc, "%s(%d): Timeout error reading NVRAM at "
1308 		    "offset 0x%08X!\n", __FILE__, __LINE__, offset);
1309 		rc = EBUSY;
1310 	}
1311 
1312 	return(rc);
1313 }
1314 
1315 #ifdef BNX_NVRAM_WRITE_SUPPORT
1316 /****************************************************************************/
1317 /* Write a dword (32 bits) to NVRAM.                                        */
1318 /*                                                                          */
1319 /* Write a 32 bit word to NVRAM.  The caller is assumed to have already     */
1320 /* obtained the NVRAM lock, enabled the controller for NVRAM access, and    */
1321 /* enabled NVRAM write access.                                              */
1322 /*                                                                          */
1323 /* Returns:                                                                 */
1324 /*   0 on success, positive value on failure.                               */
1325 /****************************************************************************/
1326 int
1327 bnx_nvram_write_dword(struct bnx_softc *sc, u_int32_t offset, u_int8_t *val,
1328     u_int32_t cmd_flags)
1329 {
1330 	u_int32_t		cmd, val32;
1331 	int			j;
1332 
1333 	/* Build the command word. */
1334 	cmd = BNX_NVM_COMMAND_DOIT | BNX_NVM_COMMAND_WR | cmd_flags;
1335 
1336 	/* Calculate the offset for buffered flash. */
1337 	if (sc->bnx_flash_info->buffered)
1338 		offset = ((offset / sc->bnx_flash_info->page_size) <<
1339 		    sc->bnx_flash_info->page_bits) +
1340 		    (offset % sc->bnx_flash_info->page_size);
1341 
1342 	/*
1343 	 * Clear the DONE bit separately, convert NVRAM data to big-endian,
1344 	 * set the NVRAM address to write, and issue the write command
1345 	 */
1346 	REG_WR(sc, BNX_NVM_COMMAND, BNX_NVM_COMMAND_DONE);
1347 	memcpy(&val32, val, 4);
1348 	val32 = htobe32(val32);
1349 	REG_WR(sc, BNX_NVM_WRITE, val32);
1350 	REG_WR(sc, BNX_NVM_ADDR, offset & BNX_NVM_ADDR_NVM_ADDR_VALUE);
1351 	REG_WR(sc, BNX_NVM_COMMAND, cmd);
1352 
1353 	/* Wait for completion. */
1354 	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1355 		DELAY(5);
1356 
1357 		if (REG_RD(sc, BNX_NVM_COMMAND) & BNX_NVM_COMMAND_DONE)
1358 			break;
1359 	}
1360 	if (j >= NVRAM_TIMEOUT_COUNT) {
1361 		BNX_PRINTF(sc, "%s(%d): Timeout error writing NVRAM at "
1362 		    "offset 0x%08X\n", __FILE__, __LINE__, offset);
1363 		return (EBUSY);
1364 	}
1365 
1366 	return (0);
1367 }
1368 #endif /* BNX_NVRAM_WRITE_SUPPORT */
1369 
1370 /****************************************************************************/
1371 /* Initialize NVRAM access.                                                 */
1372 /*                                                                          */
1373 /* Identify the NVRAM device in use and prepare the NVRAM interface to      */
1374 /* access that device.                                                      */
1375 /*                                                                          */
1376 /* Returns:                                                                 */
1377 /*   0 on success, positive value on failure.                               */
1378 /****************************************************************************/
1379 int
1380 bnx_init_nvram(struct bnx_softc *sc)
1381 {
1382 	u_int32_t		val;
1383 	int			j, entry_count, rc;
1384 	struct flash_spec	*flash;
1385 
1386 	DBPRINT(sc,BNX_VERBOSE_RESET, "Entering %s()\n", __func__);
1387 
1388 	/* Determine the selected interface. */
1389 	val = REG_RD(sc, BNX_NVM_CFG1);
1390 
1391 	entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
1392 
1393 	rc = 0;
1394 
1395 	/*
1396 	 * Flash reconfiguration is required to support additional
1397 	 * NVRAM devices not directly supported in hardware.
1398 	 * Check if the flash interface was reconfigured
1399 	 * by the bootcode.
1400 	 */
1401 
1402 	if (val & 0x40000000) {
1403 		/* Flash interface reconfigured by bootcode. */
1404 
1405 		DBPRINT(sc,BNX_INFO_LOAD,
1406 			"bnx_init_nvram(): Flash WAS reconfigured.\n");
1407 
1408 		for (j = 0, flash = &flash_table[0]; j < entry_count;
1409 		     j++, flash++) {
1410 			if ((val & FLASH_BACKUP_STRAP_MASK) ==
1411 			    (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
1412 				sc->bnx_flash_info = flash;
1413 				break;
1414 			}
1415 		}
1416 	} else {
1417 		/* Flash interface not yet reconfigured. */
1418 		u_int32_t mask;
1419 
1420 		DBPRINT(sc,BNX_INFO_LOAD,
1421 			"bnx_init_nvram(): Flash was NOT reconfigured.\n");
1422 
1423 		if (val & (1 << 23))
1424 			mask = FLASH_BACKUP_STRAP_MASK;
1425 		else
1426 			mask = FLASH_STRAP_MASK;
1427 
1428 		/* Look for the matching NVRAM device configuration data. */
1429 		for (j = 0, flash = &flash_table[0]; j < entry_count;
1430 		    j++, flash++) {
1431 			/* Check if the dev matches any of the known devices. */
1432 			if ((val & mask) == (flash->strapping & mask)) {
1433 				/* Found a device match. */
1434 				sc->bnx_flash_info = flash;
1435 
1436 				/* Request access to the flash interface. */
1437 				if ((rc = bnx_acquire_nvram_lock(sc)) != 0)
1438 					return (rc);
1439 
1440 				/* Reconfigure the flash interface. */
1441 				bnx_enable_nvram_access(sc);
1442 				REG_WR(sc, BNX_NVM_CFG1, flash->config1);
1443 				REG_WR(sc, BNX_NVM_CFG2, flash->config2);
1444 				REG_WR(sc, BNX_NVM_CFG3, flash->config3);
1445 				REG_WR(sc, BNX_NVM_WRITE1, flash->write1);
1446 				bnx_disable_nvram_access(sc);
1447 				bnx_release_nvram_lock(sc);
1448 
1449 				break;
1450 			}
1451 		}
1452 	}
1453 
1454 	/* Check if a matching device was found. */
1455 	if (j == entry_count) {
1456 		sc->bnx_flash_info = NULL;
1457 		BNX_PRINTF(sc, "%s(%d): Unknown Flash NVRAM found!\n",
1458 			__FILE__, __LINE__);
1459 		rc = ENODEV;
1460 	}
1461 
1462 	/* Write the flash config data to the shared memory interface. */
1463 	val = REG_RD_IND(sc, sc->bnx_shmem_base + BNX_SHARED_HW_CFG_CONFIG2);
1464 	val &= BNX_SHARED_HW_CFG2_NVM_SIZE_MASK;
1465 	if (val)
1466 		sc->bnx_flash_size = val;
1467 	else
1468 		sc->bnx_flash_size = sc->bnx_flash_info->total_size;
1469 
1470 	DBPRINT(sc, BNX_INFO_LOAD, "bnx_init_nvram() flash->total_size = "
1471 	    "0x%08X\n", sc->bnx_flash_info->total_size);
1472 
1473 	DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __func__);
1474 
1475 	return (rc);
1476 }
1477 
1478 /****************************************************************************/
1479 /* Read an arbitrary range of data from NVRAM.                              */
1480 /*                                                                          */
1481 /* Prepares the NVRAM interface for access and reads the requested data     */
1482 /* into the supplied buffer.                                                */
1483 /*                                                                          */
1484 /* Returns:                                                                 */
1485 /*   0 on success and the data read, positive value on failure.             */
1486 /****************************************************************************/
1487 int
1488 bnx_nvram_read(struct bnx_softc *sc, u_int32_t offset, u_int8_t *ret_buf,
1489     int buf_size)
1490 {
1491 	int			rc = 0;
1492 	u_int32_t		cmd_flags, offset32, len32, extra;
1493 
1494 	if (buf_size == 0)
1495 		return (0);
1496 
1497 	/* Request access to the flash interface. */
1498 	if ((rc = bnx_acquire_nvram_lock(sc)) != 0)
1499 		return (rc);
1500 
1501 	/* Enable access to flash interface */
1502 	bnx_enable_nvram_access(sc);
1503 
1504 	len32 = buf_size;
1505 	offset32 = offset;
1506 	extra = 0;
1507 
1508 	cmd_flags = 0;
1509 
1510 	if (offset32 & 3) {
1511 		u_int8_t buf[4];
1512 		u_int32_t pre_len;
1513 
1514 		offset32 &= ~3;
1515 		pre_len = 4 - (offset & 3);
1516 
1517 		if (pre_len >= len32) {
1518 			pre_len = len32;
1519 			cmd_flags =
1520 			    BNX_NVM_COMMAND_FIRST | BNX_NVM_COMMAND_LAST;
1521 		} else
1522 			cmd_flags = BNX_NVM_COMMAND_FIRST;
1523 
1524 		rc = bnx_nvram_read_dword(sc, offset32, buf, cmd_flags);
1525 
1526 		if (rc)
1527 			return (rc);
1528 
1529 		memcpy(ret_buf, buf + (offset & 3), pre_len);
1530 
1531 		offset32 += 4;
1532 		ret_buf += pre_len;
1533 		len32 -= pre_len;
1534 	}
1535 
1536 	if (len32 & 3) {
1537 		extra = 4 - (len32 & 3);
1538 		len32 = (len32 + 4) & ~3;
1539 	}
1540 
1541 	if (len32 == 4) {
1542 		u_int8_t buf[4];
1543 
1544 		if (cmd_flags)
1545 			cmd_flags = BNX_NVM_COMMAND_LAST;
1546 		else
1547 			cmd_flags =
1548 			    BNX_NVM_COMMAND_FIRST | BNX_NVM_COMMAND_LAST;
1549 
1550 		rc = bnx_nvram_read_dword(sc, offset32, buf, cmd_flags);
1551 
1552 		memcpy(ret_buf, buf, 4 - extra);
1553 	} else if (len32 > 0) {
1554 		u_int8_t buf[4];
1555 
1556 		/* Read the first word. */
1557 		if (cmd_flags)
1558 			cmd_flags = 0;
1559 		else
1560 			cmd_flags = BNX_NVM_COMMAND_FIRST;
1561 
1562 		rc = bnx_nvram_read_dword(sc, offset32, ret_buf, cmd_flags);
1563 
1564 		/* Advance to the next dword. */
1565 		offset32 += 4;
1566 		ret_buf += 4;
1567 		len32 -= 4;
1568 
1569 		while (len32 > 4 && rc == 0) {
1570 			rc = bnx_nvram_read_dword(sc, offset32, ret_buf, 0);
1571 
1572 			/* Advance to the next dword. */
1573 			offset32 += 4;
1574 			ret_buf += 4;
1575 			len32 -= 4;
1576 		}
1577 
1578 		if (rc)
1579 			return (rc);
1580 
1581 		cmd_flags = BNX_NVM_COMMAND_LAST;
1582 		rc = bnx_nvram_read_dword(sc, offset32, buf, cmd_flags);
1583 
1584 		memcpy(ret_buf, buf, 4 - extra);
1585 	}
1586 
1587 	/* Disable access to flash interface and release the lock. */
1588 	bnx_disable_nvram_access(sc);
1589 	bnx_release_nvram_lock(sc);
1590 
1591 	return (rc);
1592 }
1593 
1594 #ifdef BNX_NVRAM_WRITE_SUPPORT
1595 /****************************************************************************/
1596 /* Write an arbitrary range of data from NVRAM.                             */
1597 /*                                                                          */
1598 /* Prepares the NVRAM interface for write access and writes the requested   */
1599 /* data from the supplied buffer.  The caller is responsible for            */
1600 /* calculating any appropriate CRCs.                                        */
1601 /*                                                                          */
1602 /* Returns:                                                                 */
1603 /*   0 on success, positive value on failure.                               */
1604 /****************************************************************************/
1605 int
1606 bnx_nvram_write(struct bnx_softc *sc, u_int32_t offset, u_int8_t *data_buf,
1607     int buf_size)
1608 {
1609 	u_int32_t		written, offset32, len32;
1610 	u_int8_t		*buf, start[4], end[4];
1611 	int			rc = 0;
1612 	int			align_start, align_end;
1613 
1614 	buf = data_buf;
1615 	offset32 = offset;
1616 	len32 = buf_size;
1617 	align_start = align_end = 0;
1618 
1619 	if ((align_start = (offset32 & 3))) {
1620 		offset32 &= ~3;
1621 		len32 += align_start;
1622 		if ((rc = bnx_nvram_read(sc, offset32, start, 4)))
1623 			return (rc);
1624 	}
1625 
1626 	if (len32 & 3) {
1627 	       	if ((len32 > 4) || !align_start) {
1628 			align_end = 4 - (len32 & 3);
1629 			len32 += align_end;
1630 			if ((rc = bnx_nvram_read(sc, offset32 + len32 - 4,
1631 			    end, 4))) {
1632 				return (rc);
1633 			}
1634 		}
1635 	}
1636 
1637 	if (align_start || align_end) {
1638 		buf = malloc(len32, M_DEVBUF, M_NOWAIT);
1639 		if (buf == 0)
1640 			return (ENOMEM);
1641 
1642 		if (align_start)
1643 			memcpy(buf, start, 4);
1644 
1645 		if (align_end)
1646 			memcpy(buf + len32 - 4, end, 4);
1647 
1648 		memcpy(buf + align_start, data_buf, buf_size);
1649 	}
1650 
1651 	written = 0;
1652 	while ((written < len32) && (rc == 0)) {
1653 		u_int32_t page_start, page_end, data_start, data_end;
1654 		u_int32_t addr, cmd_flags;
1655 		int i;
1656 		u_int8_t flash_buffer[264];
1657 
1658 	    /* Find the page_start addr */
1659 		page_start = offset32 + written;
1660 		page_start -= (page_start % sc->bnx_flash_info->page_size);
1661 		/* Find the page_end addr */
1662 		page_end = page_start + sc->bnx_flash_info->page_size;
1663 		/* Find the data_start addr */
1664 		data_start = (written == 0) ? offset32 : page_start;
1665 		/* Find the data_end addr */
1666 		data_end = (page_end > offset32 + len32) ?
1667 		    (offset32 + len32) : page_end;
1668 
1669 		/* Request access to the flash interface. */
1670 		if ((rc = bnx_acquire_nvram_lock(sc)) != 0)
1671 			goto nvram_write_end;
1672 
1673 		/* Enable access to flash interface */
1674 		bnx_enable_nvram_access(sc);
1675 
1676 		cmd_flags = BNX_NVM_COMMAND_FIRST;
1677 		if (sc->bnx_flash_info->buffered == 0) {
1678 			int j;
1679 
1680 			/* Read the whole page into the buffer
1681 			 * (non-buffer flash only) */
1682 			for (j = 0; j < sc->bnx_flash_info->page_size; j += 4) {
1683 				if (j == (sc->bnx_flash_info->page_size - 4))
1684 					cmd_flags |= BNX_NVM_COMMAND_LAST;
1685 
1686 				rc = bnx_nvram_read_dword(sc,
1687 					page_start + j,
1688 					&flash_buffer[j],
1689 					cmd_flags);
1690 
1691 				if (rc)
1692 					goto nvram_write_end;
1693 
1694 				cmd_flags = 0;
1695 			}
1696 		}
1697 
1698 		/* Enable writes to flash interface (unlock write-protect) */
1699 		if ((rc = bnx_enable_nvram_write(sc)) != 0)
1700 			goto nvram_write_end;
1701 
1702 		/* Erase the page */
1703 		if ((rc = bnx_nvram_erase_page(sc, page_start)) != 0)
1704 			goto nvram_write_end;
1705 
1706 		/* Re-enable the write again for the actual write */
1707 		bnx_enable_nvram_write(sc);
1708 
1709 		/* Loop to write back the buffer data from page_start to
1710 		 * data_start */
1711 		i = 0;
1712 		if (sc->bnx_flash_info->buffered == 0) {
1713 			for (addr = page_start; addr < data_start;
1714 				addr += 4, i += 4) {
1715 
1716 				rc = bnx_nvram_write_dword(sc, addr,
1717 				    &flash_buffer[i], cmd_flags);
1718 
1719 				if (rc != 0)
1720 					goto nvram_write_end;
1721 
1722 				cmd_flags = 0;
1723 			}
1724 		}
1725 
1726 		/* Loop to write the new data from data_start to data_end */
1727 		for (addr = data_start; addr < data_end; addr += 4, i++) {
1728 			if ((addr == page_end - 4) ||
1729 			    ((sc->bnx_flash_info->buffered) &&
1730 			    (addr == data_end - 4))) {
1731 
1732 				cmd_flags |= BNX_NVM_COMMAND_LAST;
1733 			}
1734 
1735 			rc = bnx_nvram_write_dword(sc, addr, buf, cmd_flags);
1736 
1737 			if (rc != 0)
1738 				goto nvram_write_end;
1739 
1740 			cmd_flags = 0;
1741 			buf += 4;
1742 		}
1743 
1744 		/* Loop to write back the buffer data from data_end
1745 		 * to page_end */
1746 		if (sc->bnx_flash_info->buffered == 0) {
1747 			for (addr = data_end; addr < page_end;
1748 			    addr += 4, i += 4) {
1749 
1750 				if (addr == page_end-4)
1751 					cmd_flags = BNX_NVM_COMMAND_LAST;
1752 
1753 				rc = bnx_nvram_write_dword(sc, addr,
1754 				    &flash_buffer[i], cmd_flags);
1755 
1756 				if (rc != 0)
1757 					goto nvram_write_end;
1758 
1759 				cmd_flags = 0;
1760 			}
1761 		}
1762 
1763 		/* Disable writes to flash interface (lock write-protect) */
1764 		bnx_disable_nvram_write(sc);
1765 
1766 		/* Disable access to flash interface */
1767 		bnx_disable_nvram_access(sc);
1768 		bnx_release_nvram_lock(sc);
1769 
1770 		/* Increment written */
1771 		written += data_end - data_start;
1772 	}
1773 
1774 nvram_write_end:
1775 	if (align_start || align_end)
1776 		free(buf, M_DEVBUF);
1777 
1778 	return (rc);
1779 }
1780 #endif /* BNX_NVRAM_WRITE_SUPPORT */
1781 
1782 /****************************************************************************/
1783 /* Verifies that NVRAM is accessible and contains valid data.               */
1784 /*                                                                          */
1785 /* Reads the configuration data from NVRAM and verifies that the CRC is     */
1786 /* correct.                                                                 */
1787 /*                                                                          */
1788 /* Returns:                                                                 */
1789 /*   0 on success, positive value on failure.                               */
1790 /****************************************************************************/
1791 int
1792 bnx_nvram_test(struct bnx_softc *sc)
1793 {
1794 	u_int32_t		buf[BNX_NVRAM_SIZE / 4];
1795 	u_int8_t		*data = (u_int8_t *) buf;
1796 	int			rc = 0;
1797 	u_int32_t		magic, csum;
1798 
1799 	/*
1800 	 * Check that the device NVRAM is valid by reading
1801 	 * the magic value at offset 0.
1802 	 */
1803 	if ((rc = bnx_nvram_read(sc, 0, data, 4)) != 0)
1804 		goto bnx_nvram_test_done;
1805 
1806 	magic = bnx_be32toh(buf[0]);
1807 	if (magic != BNX_NVRAM_MAGIC) {
1808 		rc = ENODEV;
1809 		BNX_PRINTF(sc, "%s(%d): Invalid NVRAM magic value! "
1810 		    "Expected: 0x%08X, Found: 0x%08X\n",
1811 		    __FILE__, __LINE__, BNX_NVRAM_MAGIC, magic);
1812 		goto bnx_nvram_test_done;
1813 	}
1814 
1815 	/*
1816 	 * Verify that the device NVRAM includes valid
1817 	 * configuration data.
1818 	 */
1819 	if ((rc = bnx_nvram_read(sc, 0x100, data, BNX_NVRAM_SIZE)) != 0)
1820 		goto bnx_nvram_test_done;
1821 
1822 	csum = ether_crc32_le(data, 0x100);
1823 	if (csum != BNX_CRC32_RESIDUAL) {
1824 		rc = ENODEV;
1825 		BNX_PRINTF(sc, "%s(%d): Invalid Manufacturing Information "
1826 		    "NVRAM CRC! Expected: 0x%08X, Found: 0x%08X\n",
1827 		    __FILE__, __LINE__, BNX_CRC32_RESIDUAL, csum);
1828 		goto bnx_nvram_test_done;
1829 	}
1830 
1831 	csum = ether_crc32_le(data + 0x100, 0x100);
1832 	if (csum != BNX_CRC32_RESIDUAL) {
1833 		BNX_PRINTF(sc, "%s(%d): Invalid Feature Configuration "
1834 		    "Information NVRAM CRC! Expected: 0x%08X, Found: 08%08X\n",
1835 		    __FILE__, __LINE__, BNX_CRC32_RESIDUAL, csum);
1836 		rc = ENODEV;
1837 	}
1838 
1839 bnx_nvram_test_done:
1840 	return (rc);
1841 }
1842 
1843 /****************************************************************************/
1844 /* Free any DMA memory owned by the driver.                                 */
1845 /*                                                                          */
1846 /* Scans through each data structre that requires DMA memory and frees      */
1847 /* the memory if allocated.                                                 */
1848 /*                                                                          */
1849 /* Returns:                                                                 */
1850 /*   Nothing.                                                               */
1851 /****************************************************************************/
1852 void
1853 bnx_dma_free(struct bnx_softc *sc)
1854 {
1855 	int			i;
1856 
1857 	DBPRINT(sc,BNX_VERBOSE_RESET, "Entering %s()\n", __func__);
1858 
1859 	/* Destroy the status block. */
1860 	if (sc->status_block != NULL && sc->status_map != NULL) {
1861 		bus_dmamap_unload(sc->bnx_dmatag, sc->status_map);
1862 		bus_dmamem_unmap(sc->bnx_dmatag, (void *)sc->status_block,
1863 		    BNX_STATUS_BLK_SZ);
1864 		bus_dmamem_free(sc->bnx_dmatag, &sc->status_seg,
1865 		    sc->status_rseg);
1866 		bus_dmamap_destroy(sc->bnx_dmatag, sc->status_map);
1867 		sc->status_block = NULL;
1868 		sc->status_map = NULL;
1869 	}
1870 
1871 	/* Destroy the statistics block. */
1872 	if (sc->stats_block != NULL && sc->stats_map != NULL) {
1873 		bus_dmamap_unload(sc->bnx_dmatag, sc->stats_map);
1874 		bus_dmamem_unmap(sc->bnx_dmatag, (void *)sc->stats_block,
1875 		    BNX_STATS_BLK_SZ);
1876 		bus_dmamem_free(sc->bnx_dmatag, &sc->stats_seg,
1877 		    sc->stats_rseg);
1878 		bus_dmamap_destroy(sc->bnx_dmatag, sc->stats_map);
1879 		sc->stats_block = NULL;
1880 		sc->stats_map = NULL;
1881 	}
1882 
1883 	/* Free, unmap and destroy all TX buffer descriptor chain pages. */
1884 	for (i = 0; i < TX_PAGES; i++ ) {
1885 		if (sc->tx_bd_chain[i] != NULL &&
1886 		    sc->tx_bd_chain_map[i] != NULL) {
1887 			bus_dmamap_unload(sc->bnx_dmatag,
1888 			    sc->tx_bd_chain_map[i]);
1889 			bus_dmamem_unmap(sc->bnx_dmatag,
1890 			    (void *)sc->tx_bd_chain[i], BNX_TX_CHAIN_PAGE_SZ);
1891 			bus_dmamem_free(sc->bnx_dmatag, &sc->tx_bd_chain_seg[i],
1892 			    sc->tx_bd_chain_rseg[i]);
1893 			bus_dmamap_destroy(sc->bnx_dmatag,
1894 			    sc->tx_bd_chain_map[i]);
1895 			sc->tx_bd_chain[i] = NULL;
1896 			sc->tx_bd_chain_map[i] = NULL;
1897 		}
1898 	}
1899 
1900 	/* Unload and destroy the TX mbuf maps. */
1901 	for (i = 0; i < TOTAL_TX_BD; i++) {
1902 		if (sc->tx_mbuf_map[i] != NULL) {
1903 			bus_dmamap_unload(sc->bnx_dmatag, sc->tx_mbuf_map[i]);
1904 			bus_dmamap_destroy(sc->bnx_dmatag, sc->tx_mbuf_map[i]);
1905 		}
1906 	}
1907 
1908 	/* Free, unmap and destroy all RX buffer descriptor chain pages. */
1909 	for (i = 0; i < RX_PAGES; i++ ) {
1910 		if (sc->rx_bd_chain[i] != NULL &&
1911 		    sc->rx_bd_chain_map[i] != NULL) {
1912 			bus_dmamap_unload(sc->bnx_dmatag,
1913 			    sc->rx_bd_chain_map[i]);
1914 			bus_dmamem_unmap(sc->bnx_dmatag,
1915 			    (void *)sc->rx_bd_chain[i], BNX_RX_CHAIN_PAGE_SZ);
1916 			bus_dmamem_free(sc->bnx_dmatag, &sc->rx_bd_chain_seg[i],
1917 			    sc->rx_bd_chain_rseg[i]);
1918 
1919 			bus_dmamap_destroy(sc->bnx_dmatag,
1920 			    sc->rx_bd_chain_map[i]);
1921 			sc->rx_bd_chain[i] = NULL;
1922 			sc->rx_bd_chain_map[i] = NULL;
1923 		}
1924 	}
1925 
1926 	/* Unload and destroy the RX mbuf maps. */
1927 	for (i = 0; i < TOTAL_RX_BD; i++) {
1928 		if (sc->rx_mbuf_map[i] != NULL) {
1929 			bus_dmamap_unload(sc->bnx_dmatag, sc->rx_mbuf_map[i]);
1930 			bus_dmamap_destroy(sc->bnx_dmatag, sc->rx_mbuf_map[i]);
1931 		}
1932 	}
1933 
1934 	DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __func__);
1935 }
1936 
1937 /****************************************************************************/
1938 /* Allocate any DMA memory needed by the driver.                            */
1939 /*                                                                          */
1940 /* Allocates DMA memory needed for the various global structures needed by  */
1941 /* hardware.                                                                */
1942 /*                                                                          */
1943 /* Returns:                                                                 */
1944 /*   0 for success, positive value for failure.                             */
1945 /****************************************************************************/
1946 int
1947 bnx_dma_alloc(struct bnx_softc *sc)
1948 {
1949 	int			i, rc = 0;
1950 
1951 	DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __func__);
1952 
1953 	/*
1954 	 * Allocate DMA memory for the status block, map the memory into DMA
1955 	 * space, and fetch the physical address of the block.
1956 	 */
1957 	if (bus_dmamap_create(sc->bnx_dmatag, BNX_STATUS_BLK_SZ, 1,
1958 	    BNX_STATUS_BLK_SZ, 0, BUS_DMA_NOWAIT, &sc->status_map)) {
1959 		aprint_error_dev(sc->bnx_dev,
1960 		    "Could not create status block DMA map!\n");
1961 		rc = ENOMEM;
1962 		goto bnx_dma_alloc_exit;
1963 	}
1964 
1965 	if (bus_dmamem_alloc(sc->bnx_dmatag, BNX_STATUS_BLK_SZ,
1966 	    BNX_DMA_ALIGN, BNX_DMA_BOUNDARY, &sc->status_seg, 1,
1967 	    &sc->status_rseg, BUS_DMA_NOWAIT)) {
1968 		aprint_error_dev(sc->bnx_dev,
1969 		    "Could not allocate status block DMA memory!\n");
1970 		rc = ENOMEM;
1971 		goto bnx_dma_alloc_exit;
1972 	}
1973 
1974 	if (bus_dmamem_map(sc->bnx_dmatag, &sc->status_seg, sc->status_rseg,
1975 	    BNX_STATUS_BLK_SZ, (void **)&sc->status_block, BUS_DMA_NOWAIT)) {
1976 		aprint_error_dev(sc->bnx_dev,
1977 		    "Could not map status block DMA memory!\n");
1978 		rc = ENOMEM;
1979 		goto bnx_dma_alloc_exit;
1980 	}
1981 
1982 	if (bus_dmamap_load(sc->bnx_dmatag, sc->status_map,
1983 	    sc->status_block, BNX_STATUS_BLK_SZ, NULL, BUS_DMA_NOWAIT)) {
1984 		aprint_error_dev(sc->bnx_dev,
1985 		    "Could not load status block DMA memory!\n");
1986 		rc = ENOMEM;
1987 		goto bnx_dma_alloc_exit;
1988 	}
1989 
1990 	sc->status_block_paddr = sc->status_map->dm_segs[0].ds_addr;
1991 	bzero(sc->status_block, BNX_STATUS_BLK_SZ);
1992 
1993 	/* DRC - Fix for 64 bit addresses. */
1994 	DBPRINT(sc, BNX_INFO, "status_block_paddr = 0x%08X\n",
1995 		(u_int32_t) sc->status_block_paddr);
1996 
1997 	/*
1998 	 * Allocate DMA memory for the statistics block, map the memory into
1999 	 * DMA space, and fetch the physical address of the block.
2000 	 */
2001 	if (bus_dmamap_create(sc->bnx_dmatag, BNX_STATS_BLK_SZ, 1,
2002 	    BNX_STATS_BLK_SZ, 0, BUS_DMA_NOWAIT, &sc->stats_map)) {
2003 		aprint_error_dev(sc->bnx_dev,
2004 		    "Could not create stats block DMA map!\n");
2005 		rc = ENOMEM;
2006 		goto bnx_dma_alloc_exit;
2007 	}
2008 
2009 	if (bus_dmamem_alloc(sc->bnx_dmatag, BNX_STATS_BLK_SZ,
2010 	    BNX_DMA_ALIGN, BNX_DMA_BOUNDARY, &sc->stats_seg, 1,
2011 	    &sc->stats_rseg, BUS_DMA_NOWAIT)) {
2012 		aprint_error_dev(sc->bnx_dev,
2013 		    "Could not allocate stats block DMA memory!\n");
2014 		rc = ENOMEM;
2015 		goto bnx_dma_alloc_exit;
2016 	}
2017 
2018 	if (bus_dmamem_map(sc->bnx_dmatag, &sc->stats_seg, sc->stats_rseg,
2019 	    BNX_STATS_BLK_SZ, (void **)&sc->stats_block, BUS_DMA_NOWAIT)) {
2020 		aprint_error_dev(sc->bnx_dev,
2021 		    "Could not map stats block DMA memory!\n");
2022 		rc = ENOMEM;
2023 		goto bnx_dma_alloc_exit;
2024 	}
2025 
2026 	if (bus_dmamap_load(sc->bnx_dmatag, sc->stats_map,
2027 	    sc->stats_block, BNX_STATS_BLK_SZ, NULL, BUS_DMA_NOWAIT)) {
2028 		aprint_error_dev(sc->bnx_dev,
2029 		    "Could not load status block DMA memory!\n");
2030 		rc = ENOMEM;
2031 		goto bnx_dma_alloc_exit;
2032 	}
2033 
2034 	sc->stats_block_paddr = sc->stats_map->dm_segs[0].ds_addr;
2035 	bzero(sc->stats_block, BNX_STATS_BLK_SZ);
2036 
2037 	/* DRC - Fix for 64 bit address. */
2038 	DBPRINT(sc,BNX_INFO, "stats_block_paddr = 0x%08X\n",
2039 	    (u_int32_t) sc->stats_block_paddr);
2040 
2041 	/*
2042 	 * Allocate DMA memory for the TX buffer descriptor chain,
2043 	 * and fetch the physical address of the block.
2044 	 */
2045 	for (i = 0; i < TX_PAGES; i++) {
2046 		if (bus_dmamap_create(sc->bnx_dmatag, BNX_TX_CHAIN_PAGE_SZ, 1,
2047 		    BNX_TX_CHAIN_PAGE_SZ, 0, BUS_DMA_NOWAIT,
2048 		    &sc->tx_bd_chain_map[i])) {
2049 			aprint_error_dev(sc->bnx_dev,
2050 			    "Could not create Tx desc %d DMA map!\n", i);
2051 			rc = ENOMEM;
2052 			goto bnx_dma_alloc_exit;
2053 		}
2054 
2055 		if (bus_dmamem_alloc(sc->bnx_dmatag, BNX_TX_CHAIN_PAGE_SZ,
2056 		    BCM_PAGE_SIZE, BNX_DMA_BOUNDARY, &sc->tx_bd_chain_seg[i], 1,
2057 		    &sc->tx_bd_chain_rseg[i], BUS_DMA_NOWAIT)) {
2058 			aprint_error_dev(sc->bnx_dev,
2059 			    "Could not allocate TX desc %d DMA memory!\n",
2060 			    i);
2061 			rc = ENOMEM;
2062 			goto bnx_dma_alloc_exit;
2063 		}
2064 
2065 		if (bus_dmamem_map(sc->bnx_dmatag, &sc->tx_bd_chain_seg[i],
2066 		    sc->tx_bd_chain_rseg[i], BNX_TX_CHAIN_PAGE_SZ,
2067 		    (void **)&sc->tx_bd_chain[i], BUS_DMA_NOWAIT)) {
2068 			aprint_error_dev(sc->bnx_dev,
2069 			    "Could not map TX desc %d DMA memory!\n", i);
2070 			rc = ENOMEM;
2071 			goto bnx_dma_alloc_exit;
2072 		}
2073 
2074 		if (bus_dmamap_load(sc->bnx_dmatag, sc->tx_bd_chain_map[i],
2075 		    (void *)sc->tx_bd_chain[i], BNX_TX_CHAIN_PAGE_SZ, NULL,
2076 		    BUS_DMA_NOWAIT)) {
2077 			aprint_error_dev(sc->bnx_dev,
2078 			    "Could not load TX desc %d DMA memory!\n", i);
2079 			rc = ENOMEM;
2080 			goto bnx_dma_alloc_exit;
2081 		}
2082 
2083 		sc->tx_bd_chain_paddr[i] =
2084 		    sc->tx_bd_chain_map[i]->dm_segs[0].ds_addr;
2085 
2086 		/* DRC - Fix for 64 bit systems. */
2087 		DBPRINT(sc, BNX_INFO, "tx_bd_chain_paddr[%d] = 0x%08X\n",
2088 		    i, (u_int32_t) sc->tx_bd_chain_paddr[i]);
2089 	}
2090 
2091 	/*
2092 	 * Create DMA maps for the TX buffer mbufs.
2093 	 */
2094 	for (i = 0; i < TOTAL_TX_BD; i++) {
2095 		if (bus_dmamap_create(sc->bnx_dmatag,
2096 		    MCLBYTES * BNX_MAX_SEGMENTS,
2097 		    USABLE_TX_BD - BNX_TX_SLACK_SPACE,
2098 		    MCLBYTES, 0, BUS_DMA_NOWAIT,
2099 		    &sc->tx_mbuf_map[i])) {
2100 			aprint_error_dev(sc->bnx_dev,
2101 			    "Could not create Tx mbuf %d DMA map!\n", i);
2102 			rc = ENOMEM;
2103 			goto bnx_dma_alloc_exit;
2104 		}
2105 	}
2106 
2107 	/*
2108 	 * Allocate DMA memory for the Rx buffer descriptor chain,
2109 	 * and fetch the physical address of the block.
2110 	 */
2111 	for (i = 0; i < RX_PAGES; i++) {
2112 		if (bus_dmamap_create(sc->bnx_dmatag, BNX_RX_CHAIN_PAGE_SZ, 1,
2113 		    BNX_RX_CHAIN_PAGE_SZ, 0, BUS_DMA_NOWAIT,
2114 		    &sc->rx_bd_chain_map[i])) {
2115 			aprint_error_dev(sc->bnx_dev,
2116 			    "Could not create Rx desc %d DMA map!\n", i);
2117 			rc = ENOMEM;
2118 			goto bnx_dma_alloc_exit;
2119 		}
2120 
2121 		if (bus_dmamem_alloc(sc->bnx_dmatag, BNX_RX_CHAIN_PAGE_SZ,
2122 		    BCM_PAGE_SIZE, BNX_DMA_BOUNDARY, &sc->rx_bd_chain_seg[i], 1,
2123 		    &sc->rx_bd_chain_rseg[i], BUS_DMA_NOWAIT)) {
2124 			aprint_error_dev(sc->bnx_dev,
2125 			    "Could not allocate Rx desc %d DMA memory!\n", i);
2126 			rc = ENOMEM;
2127 			goto bnx_dma_alloc_exit;
2128 		}
2129 
2130 		if (bus_dmamem_map(sc->bnx_dmatag, &sc->rx_bd_chain_seg[i],
2131 		    sc->rx_bd_chain_rseg[i], BNX_RX_CHAIN_PAGE_SZ,
2132 		    (void **)&sc->rx_bd_chain[i], BUS_DMA_NOWAIT)) {
2133 			aprint_error_dev(sc->bnx_dev,
2134 			    "Could not map Rx desc %d DMA memory!\n", i);
2135 			rc = ENOMEM;
2136 			goto bnx_dma_alloc_exit;
2137 		}
2138 
2139 		if (bus_dmamap_load(sc->bnx_dmatag, sc->rx_bd_chain_map[i],
2140 		    (void *)sc->rx_bd_chain[i], BNX_RX_CHAIN_PAGE_SZ, NULL,
2141 		    BUS_DMA_NOWAIT)) {
2142 			aprint_error_dev(sc->bnx_dev,
2143 			    "Could not load Rx desc %d DMA memory!\n", i);
2144 			rc = ENOMEM;
2145 			goto bnx_dma_alloc_exit;
2146 		}
2147 
2148 		bzero(sc->rx_bd_chain[i], BNX_RX_CHAIN_PAGE_SZ);
2149 		sc->rx_bd_chain_paddr[i] =
2150 		    sc->rx_bd_chain_map[i]->dm_segs[0].ds_addr;
2151 
2152 		/* DRC - Fix for 64 bit systems. */
2153 		DBPRINT(sc, BNX_INFO, "rx_bd_chain_paddr[%d] = 0x%08X\n",
2154 		    i, (u_int32_t) sc->rx_bd_chain_paddr[i]);
2155 		bus_dmamap_sync(sc->bnx_dmatag, sc->rx_bd_chain_map[i],
2156 		    0, BNX_RX_CHAIN_PAGE_SZ,
2157 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
2158 	}
2159 
2160 	/*
2161 	 * Create DMA maps for the Rx buffer mbufs.
2162 	 */
2163 	for (i = 0; i < TOTAL_RX_BD; i++) {
2164 		if (bus_dmamap_create(sc->bnx_dmatag, BNX_MAX_MRU,
2165 		    BNX_MAX_SEGMENTS, BNX_MAX_MRU, 0, BUS_DMA_NOWAIT,
2166 		    &sc->rx_mbuf_map[i])) {
2167 			aprint_error_dev(sc->bnx_dev,
2168 			    "Could not create Rx mbuf %d DMA map!\n", i);
2169 			rc = ENOMEM;
2170 			goto bnx_dma_alloc_exit;
2171 		}
2172 	}
2173 
2174  bnx_dma_alloc_exit:
2175 	DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __func__);
2176 
2177 	return(rc);
2178 }
2179 
2180 /****************************************************************************/
2181 /* Release all resources used by the driver.                                */
2182 /*                                                                          */
2183 /* Releases all resources acquired by the driver including interrupts,      */
2184 /* interrupt handler, interfaces, mutexes, and DMA memory.                  */
2185 /*                                                                          */
2186 /* Returns:                                                                 */
2187 /*   Nothing.                                                               */
2188 /****************************************************************************/
2189 void
2190 bnx_release_resources(struct bnx_softc *sc)
2191 {
2192 	int i;
2193 	struct pci_attach_args	*pa = &(sc->bnx_pa);
2194 
2195 	DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __func__);
2196 
2197 	bnx_dma_free(sc);
2198 
2199 	if (sc->bnx_intrhand != NULL)
2200 		pci_intr_disestablish(pa->pa_pc, sc->bnx_intrhand);
2201 
2202 	if (sc->bnx_size)
2203 		bus_space_unmap(sc->bnx_btag, sc->bnx_bhandle, sc->bnx_size);
2204 
2205 	for (i = 0; i < TOTAL_RX_BD; i++)
2206 		bus_dmamap_destroy(sc->bnx_dmatag, sc->rx_mbuf_map[i]);
2207 
2208 	DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __func__);
2209 }
2210 
2211 /****************************************************************************/
2212 /* Firmware synchronization.                                                */
2213 /*                                                                          */
2214 /* Before performing certain events such as a chip reset, synchronize with  */
2215 /* the firmware first.                                                      */
2216 /*                                                                          */
2217 /* Returns:                                                                 */
2218 /*   0 for success, positive value for failure.                             */
2219 /****************************************************************************/
2220 int
2221 bnx_fw_sync(struct bnx_softc *sc, u_int32_t msg_data)
2222 {
2223 	int			i, rc = 0;
2224 	u_int32_t		val;
2225 
2226 	/* Don't waste any time if we've timed out before. */
2227 	if (sc->bnx_fw_timed_out) {
2228 		rc = EBUSY;
2229 		goto bnx_fw_sync_exit;
2230 	}
2231 
2232 	/* Increment the message sequence number. */
2233 	sc->bnx_fw_wr_seq++;
2234 	msg_data |= sc->bnx_fw_wr_seq;
2235 
2236  	DBPRINT(sc, BNX_VERBOSE, "bnx_fw_sync(): msg_data = 0x%08X\n",
2237 	    msg_data);
2238 
2239 	/* Send the message to the bootcode driver mailbox. */
2240 	REG_WR_IND(sc, sc->bnx_shmem_base + BNX_DRV_MB, msg_data);
2241 
2242 	/* Wait for the bootcode to acknowledge the message. */
2243 	for (i = 0; i < FW_ACK_TIME_OUT_MS; i++) {
2244 		/* Check for a response in the bootcode firmware mailbox. */
2245 		val = REG_RD_IND(sc, sc->bnx_shmem_base + BNX_FW_MB);
2246 		if ((val & BNX_FW_MSG_ACK) == (msg_data & BNX_DRV_MSG_SEQ))
2247 			break;
2248 		DELAY(1000);
2249 	}
2250 
2251 	/* If we've timed out, tell the bootcode that we've stopped waiting. */
2252 	if (((val & BNX_FW_MSG_ACK) != (msg_data & BNX_DRV_MSG_SEQ)) &&
2253 		((msg_data & BNX_DRV_MSG_DATA) != BNX_DRV_MSG_DATA_WAIT0)) {
2254 		BNX_PRINTF(sc, "%s(%d): Firmware synchronization timeout! "
2255 		    "msg_data = 0x%08X\n", __FILE__, __LINE__, msg_data);
2256 
2257 		msg_data &= ~BNX_DRV_MSG_CODE;
2258 		msg_data |= BNX_DRV_MSG_CODE_FW_TIMEOUT;
2259 
2260 		REG_WR_IND(sc, sc->bnx_shmem_base + BNX_DRV_MB, msg_data);
2261 
2262 		sc->bnx_fw_timed_out = 1;
2263 		rc = EBUSY;
2264 	}
2265 
2266 bnx_fw_sync_exit:
2267 	return (rc);
2268 }
2269 
2270 /****************************************************************************/
2271 /* Load Receive Virtual 2 Physical (RV2P) processor firmware.               */
2272 /*                                                                          */
2273 /* Returns:                                                                 */
2274 /*   Nothing.                                                               */
2275 /****************************************************************************/
2276 void
2277 bnx_load_rv2p_fw(struct bnx_softc *sc, u_int32_t *rv2p_code,
2278     u_int32_t rv2p_code_len, u_int32_t rv2p_proc)
2279 {
2280 	int			i;
2281 	u_int32_t		val;
2282 
2283 	for (i = 0; i < rv2p_code_len; i += 8) {
2284 		REG_WR(sc, BNX_RV2P_INSTR_HIGH, *rv2p_code);
2285 		rv2p_code++;
2286 		REG_WR(sc, BNX_RV2P_INSTR_LOW, *rv2p_code);
2287 		rv2p_code++;
2288 
2289 		if (rv2p_proc == RV2P_PROC1) {
2290 			val = (i / 8) | BNX_RV2P_PROC1_ADDR_CMD_RDWR;
2291 			REG_WR(sc, BNX_RV2P_PROC1_ADDR_CMD, val);
2292 		}
2293 		else {
2294 			val = (i / 8) | BNX_RV2P_PROC2_ADDR_CMD_RDWR;
2295 			REG_WR(sc, BNX_RV2P_PROC2_ADDR_CMD, val);
2296 		}
2297 	}
2298 
2299 	/* Reset the processor, un-stall is done later. */
2300 	if (rv2p_proc == RV2P_PROC1)
2301 		REG_WR(sc, BNX_RV2P_COMMAND, BNX_RV2P_COMMAND_PROC1_RESET);
2302 	else
2303 		REG_WR(sc, BNX_RV2P_COMMAND, BNX_RV2P_COMMAND_PROC2_RESET);
2304 }
2305 
2306 /****************************************************************************/
2307 /* Load RISC processor firmware.                                            */
2308 /*                                                                          */
2309 /* Loads firmware from the file if_bnxfw.h into the scratchpad memory       */
2310 /* associated with a particular processor.                                  */
2311 /*                                                                          */
2312 /* Returns:                                                                 */
2313 /*   Nothing.                                                               */
2314 /****************************************************************************/
2315 void
2316 bnx_load_cpu_fw(struct bnx_softc *sc, struct cpu_reg *cpu_reg,
2317     struct fw_info *fw)
2318 {
2319 	u_int32_t		offset;
2320 	u_int32_t		val;
2321 
2322 	/* Halt the CPU. */
2323 	val = REG_RD_IND(sc, cpu_reg->mode);
2324 	val |= cpu_reg->mode_value_halt;
2325 	REG_WR_IND(sc, cpu_reg->mode, val);
2326 	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
2327 
2328 	/* Load the Text area. */
2329 	offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
2330 	if (fw->text) {
2331 		int j;
2332 
2333 		for (j = 0; j < (fw->text_len / 4); j++, offset += 4)
2334 			REG_WR_IND(sc, offset, fw->text[j]);
2335 	}
2336 
2337 	/* Load the Data area. */
2338 	offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
2339 	if (fw->data) {
2340 		int j;
2341 
2342 		for (j = 0; j < (fw->data_len / 4); j++, offset += 4)
2343 			REG_WR_IND(sc, offset, fw->data[j]);
2344 	}
2345 
2346 	/* Load the SBSS area. */
2347 	offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
2348 	if (fw->sbss) {
2349 		int j;
2350 
2351 		for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4)
2352 			REG_WR_IND(sc, offset, fw->sbss[j]);
2353 	}
2354 
2355 	/* Load the BSS area. */
2356 	offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
2357 	if (fw->bss) {
2358 		int j;
2359 
2360 		for (j = 0; j < (fw->bss_len/4); j++, offset += 4)
2361 			REG_WR_IND(sc, offset, fw->bss[j]);
2362 	}
2363 
2364 	/* Load the Read-Only area. */
2365 	offset = cpu_reg->spad_base +
2366 	    (fw->rodata_addr - cpu_reg->mips_view_base);
2367 	if (fw->rodata) {
2368 		int j;
2369 
2370 		for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4)
2371 			REG_WR_IND(sc, offset, fw->rodata[j]);
2372 	}
2373 
2374 	/* Clear the pre-fetch instruction. */
2375 	REG_WR_IND(sc, cpu_reg->inst, 0);
2376 	REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
2377 
2378 	/* Start the CPU. */
2379 	val = REG_RD_IND(sc, cpu_reg->mode);
2380 	val &= ~cpu_reg->mode_value_halt;
2381 	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
2382 	REG_WR_IND(sc, cpu_reg->mode, val);
2383 }
2384 
2385 /****************************************************************************/
2386 /* Initialize the RV2P, RX, TX, TPAT, and COM CPUs.                         */
2387 /*                                                                          */
2388 /* Loads the firmware for each CPU and starts the CPU.                      */
2389 /*                                                                          */
2390 /* Returns:                                                                 */
2391 /*   Nothing.                                                               */
2392 /****************************************************************************/
2393 void
2394 bnx_init_cpus(struct bnx_softc *sc)
2395 {
2396 	struct cpu_reg cpu_reg;
2397 	struct fw_info fw;
2398 
2399 	/* Initialize the RV2P processor. */
2400 	bnx_load_rv2p_fw(sc, bnx_rv2p_proc1, sizeof(bnx_rv2p_proc1),
2401 	    RV2P_PROC1);
2402 	bnx_load_rv2p_fw(sc, bnx_rv2p_proc2, sizeof(bnx_rv2p_proc2),
2403 	    RV2P_PROC2);
2404 
2405 	/* Initialize the RX Processor. */
2406 	cpu_reg.mode = BNX_RXP_CPU_MODE;
2407 	cpu_reg.mode_value_halt = BNX_RXP_CPU_MODE_SOFT_HALT;
2408 	cpu_reg.mode_value_sstep = BNX_RXP_CPU_MODE_STEP_ENA;
2409 	cpu_reg.state = BNX_RXP_CPU_STATE;
2410 	cpu_reg.state_value_clear = 0xffffff;
2411 	cpu_reg.gpr0 = BNX_RXP_CPU_REG_FILE;
2412 	cpu_reg.evmask = BNX_RXP_CPU_EVENT_MASK;
2413 	cpu_reg.pc = BNX_RXP_CPU_PROGRAM_COUNTER;
2414 	cpu_reg.inst = BNX_RXP_CPU_INSTRUCTION;
2415 	cpu_reg.bp = BNX_RXP_CPU_HW_BREAKPOINT;
2416 	cpu_reg.spad_base = BNX_RXP_SCRATCH;
2417 	cpu_reg.mips_view_base = 0x8000000;
2418 
2419 	fw.ver_major = bnx_RXP_b06FwReleaseMajor;
2420 	fw.ver_minor = bnx_RXP_b06FwReleaseMinor;
2421 	fw.ver_fix = bnx_RXP_b06FwReleaseFix;
2422 	fw.start_addr = bnx_RXP_b06FwStartAddr;
2423 
2424 	fw.text_addr = bnx_RXP_b06FwTextAddr;
2425 	fw.text_len = bnx_RXP_b06FwTextLen;
2426 	fw.text_index = 0;
2427 	fw.text = bnx_RXP_b06FwText;
2428 
2429 	fw.data_addr = bnx_RXP_b06FwDataAddr;
2430 	fw.data_len = bnx_RXP_b06FwDataLen;
2431 	fw.data_index = 0;
2432 	fw.data = bnx_RXP_b06FwData;
2433 
2434 	fw.sbss_addr = bnx_RXP_b06FwSbssAddr;
2435 	fw.sbss_len = bnx_RXP_b06FwSbssLen;
2436 	fw.sbss_index = 0;
2437 	fw.sbss = bnx_RXP_b06FwSbss;
2438 
2439 	fw.bss_addr = bnx_RXP_b06FwBssAddr;
2440 	fw.bss_len = bnx_RXP_b06FwBssLen;
2441 	fw.bss_index = 0;
2442 	fw.bss = bnx_RXP_b06FwBss;
2443 
2444 	fw.rodata_addr = bnx_RXP_b06FwRodataAddr;
2445 	fw.rodata_len = bnx_RXP_b06FwRodataLen;
2446 	fw.rodata_index = 0;
2447 	fw.rodata = bnx_RXP_b06FwRodata;
2448 
2449 	DBPRINT(sc, BNX_INFO_RESET, "Loading RX firmware.\n");
2450 	bnx_load_cpu_fw(sc, &cpu_reg, &fw);
2451 
2452 	/* Initialize the TX Processor. */
2453 	cpu_reg.mode = BNX_TXP_CPU_MODE;
2454 	cpu_reg.mode_value_halt = BNX_TXP_CPU_MODE_SOFT_HALT;
2455 	cpu_reg.mode_value_sstep = BNX_TXP_CPU_MODE_STEP_ENA;
2456 	cpu_reg.state = BNX_TXP_CPU_STATE;
2457 	cpu_reg.state_value_clear = 0xffffff;
2458 	cpu_reg.gpr0 = BNX_TXP_CPU_REG_FILE;
2459 	cpu_reg.evmask = BNX_TXP_CPU_EVENT_MASK;
2460 	cpu_reg.pc = BNX_TXP_CPU_PROGRAM_COUNTER;
2461 	cpu_reg.inst = BNX_TXP_CPU_INSTRUCTION;
2462 	cpu_reg.bp = BNX_TXP_CPU_HW_BREAKPOINT;
2463 	cpu_reg.spad_base = BNX_TXP_SCRATCH;
2464 	cpu_reg.mips_view_base = 0x8000000;
2465 
2466 	fw.ver_major = bnx_TXP_b06FwReleaseMajor;
2467 	fw.ver_minor = bnx_TXP_b06FwReleaseMinor;
2468 	fw.ver_fix = bnx_TXP_b06FwReleaseFix;
2469 	fw.start_addr = bnx_TXP_b06FwStartAddr;
2470 
2471 	fw.text_addr = bnx_TXP_b06FwTextAddr;
2472 	fw.text_len = bnx_TXP_b06FwTextLen;
2473 	fw.text_index = 0;
2474 	fw.text = bnx_TXP_b06FwText;
2475 
2476 	fw.data_addr = bnx_TXP_b06FwDataAddr;
2477 	fw.data_len = bnx_TXP_b06FwDataLen;
2478 	fw.data_index = 0;
2479 	fw.data = bnx_TXP_b06FwData;
2480 
2481 	fw.sbss_addr = bnx_TXP_b06FwSbssAddr;
2482 	fw.sbss_len = bnx_TXP_b06FwSbssLen;
2483 	fw.sbss_index = 0;
2484 	fw.sbss = bnx_TXP_b06FwSbss;
2485 
2486 	fw.bss_addr = bnx_TXP_b06FwBssAddr;
2487 	fw.bss_len = bnx_TXP_b06FwBssLen;
2488 	fw.bss_index = 0;
2489 	fw.bss = bnx_TXP_b06FwBss;
2490 
2491 	fw.rodata_addr = bnx_TXP_b06FwRodataAddr;
2492 	fw.rodata_len = bnx_TXP_b06FwRodataLen;
2493 	fw.rodata_index = 0;
2494 	fw.rodata = bnx_TXP_b06FwRodata;
2495 
2496 	DBPRINT(sc, BNX_INFO_RESET, "Loading TX firmware.\n");
2497 	bnx_load_cpu_fw(sc, &cpu_reg, &fw);
2498 
2499 	/* Initialize the TX Patch-up Processor. */
2500 	cpu_reg.mode = BNX_TPAT_CPU_MODE;
2501 	cpu_reg.mode_value_halt = BNX_TPAT_CPU_MODE_SOFT_HALT;
2502 	cpu_reg.mode_value_sstep = BNX_TPAT_CPU_MODE_STEP_ENA;
2503 	cpu_reg.state = BNX_TPAT_CPU_STATE;
2504 	cpu_reg.state_value_clear = 0xffffff;
2505 	cpu_reg.gpr0 = BNX_TPAT_CPU_REG_FILE;
2506 	cpu_reg.evmask = BNX_TPAT_CPU_EVENT_MASK;
2507 	cpu_reg.pc = BNX_TPAT_CPU_PROGRAM_COUNTER;
2508 	cpu_reg.inst = BNX_TPAT_CPU_INSTRUCTION;
2509 	cpu_reg.bp = BNX_TPAT_CPU_HW_BREAKPOINT;
2510 	cpu_reg.spad_base = BNX_TPAT_SCRATCH;
2511 	cpu_reg.mips_view_base = 0x8000000;
2512 
2513 	fw.ver_major = bnx_TPAT_b06FwReleaseMajor;
2514 	fw.ver_minor = bnx_TPAT_b06FwReleaseMinor;
2515 	fw.ver_fix = bnx_TPAT_b06FwReleaseFix;
2516 	fw.start_addr = bnx_TPAT_b06FwStartAddr;
2517 
2518 	fw.text_addr = bnx_TPAT_b06FwTextAddr;
2519 	fw.text_len = bnx_TPAT_b06FwTextLen;
2520 	fw.text_index = 0;
2521 	fw.text = bnx_TPAT_b06FwText;
2522 
2523 	fw.data_addr = bnx_TPAT_b06FwDataAddr;
2524 	fw.data_len = bnx_TPAT_b06FwDataLen;
2525 	fw.data_index = 0;
2526 	fw.data = bnx_TPAT_b06FwData;
2527 
2528 	fw.sbss_addr = bnx_TPAT_b06FwSbssAddr;
2529 	fw.sbss_len = bnx_TPAT_b06FwSbssLen;
2530 	fw.sbss_index = 0;
2531 	fw.sbss = bnx_TPAT_b06FwSbss;
2532 
2533 	fw.bss_addr = bnx_TPAT_b06FwBssAddr;
2534 	fw.bss_len = bnx_TPAT_b06FwBssLen;
2535 	fw.bss_index = 0;
2536 	fw.bss = bnx_TPAT_b06FwBss;
2537 
2538 	fw.rodata_addr = bnx_TPAT_b06FwRodataAddr;
2539 	fw.rodata_len = bnx_TPAT_b06FwRodataLen;
2540 	fw.rodata_index = 0;
2541 	fw.rodata = bnx_TPAT_b06FwRodata;
2542 
2543 	DBPRINT(sc, BNX_INFO_RESET, "Loading TPAT firmware.\n");
2544 	bnx_load_cpu_fw(sc, &cpu_reg, &fw);
2545 
2546 	/* Initialize the Completion Processor. */
2547 	cpu_reg.mode = BNX_COM_CPU_MODE;
2548 	cpu_reg.mode_value_halt = BNX_COM_CPU_MODE_SOFT_HALT;
2549 	cpu_reg.mode_value_sstep = BNX_COM_CPU_MODE_STEP_ENA;
2550 	cpu_reg.state = BNX_COM_CPU_STATE;
2551 	cpu_reg.state_value_clear = 0xffffff;
2552 	cpu_reg.gpr0 = BNX_COM_CPU_REG_FILE;
2553 	cpu_reg.evmask = BNX_COM_CPU_EVENT_MASK;
2554 	cpu_reg.pc = BNX_COM_CPU_PROGRAM_COUNTER;
2555 	cpu_reg.inst = BNX_COM_CPU_INSTRUCTION;
2556 	cpu_reg.bp = BNX_COM_CPU_HW_BREAKPOINT;
2557 	cpu_reg.spad_base = BNX_COM_SCRATCH;
2558 	cpu_reg.mips_view_base = 0x8000000;
2559 
2560 	fw.ver_major = bnx_COM_b06FwReleaseMajor;
2561 	fw.ver_minor = bnx_COM_b06FwReleaseMinor;
2562 	fw.ver_fix = bnx_COM_b06FwReleaseFix;
2563 	fw.start_addr = bnx_COM_b06FwStartAddr;
2564 
2565 	fw.text_addr = bnx_COM_b06FwTextAddr;
2566 	fw.text_len = bnx_COM_b06FwTextLen;
2567 	fw.text_index = 0;
2568 	fw.text = bnx_COM_b06FwText;
2569 
2570 	fw.data_addr = bnx_COM_b06FwDataAddr;
2571 	fw.data_len = bnx_COM_b06FwDataLen;
2572 	fw.data_index = 0;
2573 	fw.data = bnx_COM_b06FwData;
2574 
2575 	fw.sbss_addr = bnx_COM_b06FwSbssAddr;
2576 	fw.sbss_len = bnx_COM_b06FwSbssLen;
2577 	fw.sbss_index = 0;
2578 	fw.sbss = bnx_COM_b06FwSbss;
2579 
2580 	fw.bss_addr = bnx_COM_b06FwBssAddr;
2581 	fw.bss_len = bnx_COM_b06FwBssLen;
2582 	fw.bss_index = 0;
2583 	fw.bss = bnx_COM_b06FwBss;
2584 
2585 	fw.rodata_addr = bnx_COM_b06FwRodataAddr;
2586 	fw.rodata_len = bnx_COM_b06FwRodataLen;
2587 	fw.rodata_index = 0;
2588 	fw.rodata = bnx_COM_b06FwRodata;
2589 
2590 	DBPRINT(sc, BNX_INFO_RESET, "Loading COM firmware.\n");
2591 	bnx_load_cpu_fw(sc, &cpu_reg, &fw);
2592 }
2593 
2594 /****************************************************************************/
2595 /* Initialize context memory.                                               */
2596 /*                                                                          */
2597 /* Clears the memory associated with each Context ID (CID).                 */
2598 /*                                                                          */
2599 /* Returns:                                                                 */
2600 /*   Nothing.                                                               */
2601 /****************************************************************************/
2602 void
2603 bnx_init_context(struct bnx_softc *sc)
2604 {
2605 	u_int32_t		vcid;
2606 
2607 	vcid = 96;
2608 	while (vcid) {
2609 		u_int32_t vcid_addr, pcid_addr, offset;
2610 
2611 		vcid--;
2612 
2613    		vcid_addr = GET_CID_ADDR(vcid);
2614 		pcid_addr = vcid_addr;
2615 
2616 		REG_WR(sc, BNX_CTX_VIRT_ADDR, 0x00);
2617 		REG_WR(sc, BNX_CTX_PAGE_TBL, pcid_addr);
2618 
2619 		/* Zero out the context. */
2620 		for (offset = 0; offset < PHY_CTX_SIZE; offset += 4)
2621 			CTX_WR(sc, 0x00, offset, 0);
2622 
2623 		REG_WR(sc, BNX_CTX_VIRT_ADDR, vcid_addr);
2624 		REG_WR(sc, BNX_CTX_PAGE_TBL, pcid_addr);
2625 	}
2626 }
2627 
2628 /****************************************************************************/
2629 /* Fetch the permanent MAC address of the controller.                       */
2630 /*                                                                          */
2631 /* Returns:                                                                 */
2632 /*   Nothing.                                                               */
2633 /****************************************************************************/
2634 void
2635 bnx_get_mac_addr(struct bnx_softc *sc)
2636 {
2637 	u_int32_t		mac_lo = 0, mac_hi = 0;
2638 
2639 	/*
2640 	 * The NetXtreme II bootcode populates various NIC
2641 	 * power-on and runtime configuration items in a
2642 	 * shared memory area.  The factory configured MAC
2643 	 * address is available from both NVRAM and the
2644 	 * shared memory area so we'll read the value from
2645 	 * shared memory for speed.
2646 	 */
2647 
2648 	mac_hi = REG_RD_IND(sc, sc->bnx_shmem_base + BNX_PORT_HW_CFG_MAC_UPPER);
2649 	mac_lo = REG_RD_IND(sc, sc->bnx_shmem_base + BNX_PORT_HW_CFG_MAC_LOWER);
2650 
2651 	if ((mac_lo == 0) && (mac_hi == 0)) {
2652 		BNX_PRINTF(sc, "%s(%d): Invalid Ethernet address!\n",
2653 		    __FILE__, __LINE__);
2654 	} else {
2655 		sc->eaddr[0] = (u_char)(mac_hi >> 8);
2656 		sc->eaddr[1] = (u_char)(mac_hi >> 0);
2657 		sc->eaddr[2] = (u_char)(mac_lo >> 24);
2658 		sc->eaddr[3] = (u_char)(mac_lo >> 16);
2659 		sc->eaddr[4] = (u_char)(mac_lo >> 8);
2660 		sc->eaddr[5] = (u_char)(mac_lo >> 0);
2661 	}
2662 
2663 	DBPRINT(sc, BNX_INFO, "Permanent Ethernet address = "
2664 	    "%s\n", ether_sprintf(sc->eaddr));
2665 }
2666 
2667 /****************************************************************************/
2668 /* Program the MAC address.                                                 */
2669 /*                                                                          */
2670 /* Returns:                                                                 */
2671 /*   Nothing.                                                               */
2672 /****************************************************************************/
2673 void
2674 bnx_set_mac_addr(struct bnx_softc *sc)
2675 {
2676 	u_int32_t		val;
2677 	const u_int8_t		*mac_addr = CLLADDR(sc->bnx_ec.ec_if.if_sadl);
2678 
2679 	DBPRINT(sc, BNX_INFO, "Setting Ethernet address = "
2680 	    "%s\n", ether_sprintf(sc->eaddr));
2681 
2682 	val = (mac_addr[0] << 8) | mac_addr[1];
2683 
2684 	REG_WR(sc, BNX_EMAC_MAC_MATCH0, val);
2685 
2686 	val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
2687 		(mac_addr[4] << 8) | mac_addr[5];
2688 
2689 	REG_WR(sc, BNX_EMAC_MAC_MATCH1, val);
2690 }
2691 
2692 /****************************************************************************/
2693 /* Stop the controller.                                                     */
2694 /*                                                                          */
2695 /* Returns:                                                                 */
2696 /*   Nothing.                                                               */
2697 /****************************************************************************/
2698 void
2699 bnx_stop(struct ifnet *ifp, int disable)
2700 {
2701 	struct bnx_softc *sc = ifp->if_softc;
2702 
2703 	DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __func__);
2704 
2705 	if ((ifp->if_flags & IFF_RUNNING) == 0)
2706 		return;
2707 
2708 	callout_stop(&sc->bnx_timeout);
2709 
2710 	mii_down(&sc->bnx_mii);
2711 
2712 	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
2713 
2714 	/* Disable the transmit/receive blocks. */
2715 	REG_WR(sc, BNX_MISC_ENABLE_CLR_BITS, 0x5ffffff);
2716 	REG_RD(sc, BNX_MISC_ENABLE_CLR_BITS);
2717 	DELAY(20);
2718 
2719 	bnx_disable_intr(sc);
2720 
2721 	/* Tell firmware that the driver is going away. */
2722 	if (disable)
2723 		bnx_reset(sc, BNX_DRV_MSG_CODE_RESET);
2724 	else
2725 		bnx_reset(sc, BNX_DRV_MSG_CODE_SUSPEND_NO_WOL);
2726 
2727 	/* Free the RX lists. */
2728 	bnx_free_rx_chain(sc);
2729 
2730 	/* Free TX buffers. */
2731 	bnx_free_tx_chain(sc);
2732 
2733 	ifp->if_timer = 0;
2734 
2735 	DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __func__);
2736 
2737 }
2738 
2739 int
2740 bnx_reset(struct bnx_softc *sc, u_int32_t reset_code)
2741 {
2742 	u_int32_t		val;
2743 	int			i, rc = 0;
2744 
2745 	DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __func__);
2746 
2747 	/* Wait for pending PCI transactions to complete. */
2748 	REG_WR(sc, BNX_MISC_ENABLE_CLR_BITS,
2749 	    BNX_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
2750 	    BNX_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
2751 	    BNX_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
2752 	    BNX_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
2753 	val = REG_RD(sc, BNX_MISC_ENABLE_CLR_BITS);
2754 	DELAY(5);
2755 
2756 	/* Assume bootcode is running. */
2757 	sc->bnx_fw_timed_out = 0;
2758 
2759 	/* Give the firmware a chance to prepare for the reset. */
2760 	rc = bnx_fw_sync(sc, BNX_DRV_MSG_DATA_WAIT0 | reset_code);
2761 	if (rc)
2762 		goto bnx_reset_exit;
2763 
2764 	/* Set a firmware reminder that this is a soft reset. */
2765 	REG_WR_IND(sc, sc->bnx_shmem_base + BNX_DRV_RESET_SIGNATURE,
2766 	    BNX_DRV_RESET_SIGNATURE_MAGIC);
2767 
2768 	/* Dummy read to force the chip to complete all current transactions. */
2769 	val = REG_RD(sc, BNX_MISC_ID);
2770 
2771 	/* Chip reset. */
2772 	val = BNX_PCICFG_MISC_CONFIG_CORE_RST_REQ |
2773 	    BNX_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
2774 	    BNX_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
2775 	REG_WR(sc, BNX_PCICFG_MISC_CONFIG, val);
2776 
2777 	/* Allow up to 30us for reset to complete. */
2778 	for (i = 0; i < 10; i++) {
2779 		val = REG_RD(sc, BNX_PCICFG_MISC_CONFIG);
2780 		if ((val & (BNX_PCICFG_MISC_CONFIG_CORE_RST_REQ |
2781 		    BNX_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0)
2782 			break;
2783 
2784 		DELAY(10);
2785 	}
2786 
2787 	/* Check that reset completed successfully. */
2788 	if (val & (BNX_PCICFG_MISC_CONFIG_CORE_RST_REQ |
2789 	    BNX_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
2790 		BNX_PRINTF(sc, "%s(%d): Reset failed!\n", __FILE__, __LINE__);
2791 		rc = EBUSY;
2792 		goto bnx_reset_exit;
2793 	}
2794 
2795 	/* Make sure byte swapping is properly configured. */
2796 	val = REG_RD(sc, BNX_PCI_SWAP_DIAG0);
2797 	if (val != 0x01020304) {
2798 		BNX_PRINTF(sc, "%s(%d): Byte swap is incorrect!\n",
2799 		    __FILE__, __LINE__);
2800 		rc = ENODEV;
2801 		goto bnx_reset_exit;
2802 	}
2803 
2804 	/* Just completed a reset, assume that firmware is running again. */
2805 	sc->bnx_fw_timed_out = 0;
2806 
2807 	/* Wait for the firmware to finish its initialization. */
2808 	rc = bnx_fw_sync(sc, BNX_DRV_MSG_DATA_WAIT1 | reset_code);
2809 	if (rc)
2810 		BNX_PRINTF(sc, "%s(%d): Firmware did not complete "
2811 		    "initialization!\n", __FILE__, __LINE__);
2812 
2813 bnx_reset_exit:
2814 	DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __func__);
2815 
2816 	return (rc);
2817 }
2818 
2819 int
2820 bnx_chipinit(struct bnx_softc *sc)
2821 {
2822 	struct pci_attach_args	*pa = &(sc->bnx_pa);
2823 	u_int32_t		val;
2824 	int			rc = 0;
2825 
2826 	DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __func__);
2827 
2828 	/* Make sure the interrupt is not active. */
2829 	REG_WR(sc, BNX_PCICFG_INT_ACK_CMD, BNX_PCICFG_INT_ACK_CMD_MASK_INT);
2830 
2831 	/* Initialize DMA byte/word swapping, configure the number of DMA  */
2832 	/* channels and PCI clock compensation delay.                      */
2833 	val = BNX_DMA_CONFIG_DATA_BYTE_SWAP |
2834 	    BNX_DMA_CONFIG_DATA_WORD_SWAP |
2835 #if BYTE_ORDER == BIG_ENDIAN
2836 	    BNX_DMA_CONFIG_CNTL_BYTE_SWAP |
2837 #endif
2838 	    BNX_DMA_CONFIG_CNTL_WORD_SWAP |
2839 	    DMA_READ_CHANS << 12 |
2840 	    DMA_WRITE_CHANS << 16;
2841 
2842 	val |= (0x2 << 20) | BNX_DMA_CONFIG_CNTL_PCI_COMP_DLY;
2843 
2844 	if ((sc->bnx_flags & BNX_PCIX_FLAG) && (sc->bus_speed_mhz == 133))
2845 		val |= BNX_DMA_CONFIG_PCI_FAST_CLK_CMP;
2846 
2847 	/*
2848 	 * This setting resolves a problem observed on certain Intel PCI
2849 	 * chipsets that cannot handle multiple outstanding DMA operations.
2850 	 * See errata E9_5706A1_65.
2851 	 */
2852 	if ((BNX_CHIP_NUM(sc) == BNX_CHIP_NUM_5706) &&
2853 	    (BNX_CHIP_ID(sc) != BNX_CHIP_ID_5706_A0) &&
2854 	    !(sc->bnx_flags & BNX_PCIX_FLAG))
2855 		val |= BNX_DMA_CONFIG_CNTL_PING_PONG_DMA;
2856 
2857 	REG_WR(sc, BNX_DMA_CONFIG, val);
2858 
2859 	/* Clear the PCI-X relaxed ordering bit. See errata E3_5708CA0_570. */
2860 	if (sc->bnx_flags & BNX_PCIX_FLAG) {
2861 		u_int16_t nval;
2862 
2863 		nval = pci_conf_read(pa->pa_pc, pa->pa_tag, BNX_PCI_PCIX_CMD);
2864 		pci_conf_write(pa->pa_pc, pa->pa_tag, BNX_PCI_PCIX_CMD,
2865 		    nval & ~0x20000);
2866 	}
2867 
2868 	/* Enable the RX_V2P and Context state machines before access. */
2869 	REG_WR(sc, BNX_MISC_ENABLE_SET_BITS,
2870 	    BNX_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
2871 	    BNX_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
2872 	    BNX_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
2873 
2874 	/* Initialize context mapping and zero out the quick contexts. */
2875 	bnx_init_context(sc);
2876 
2877 	/* Initialize the on-boards CPUs */
2878 	bnx_init_cpus(sc);
2879 
2880 	/* Prepare NVRAM for access. */
2881 	if (bnx_init_nvram(sc)) {
2882 		rc = ENODEV;
2883 		goto bnx_chipinit_exit;
2884 	}
2885 
2886 	/* Set the kernel bypass block size */
2887 	val = REG_RD(sc, BNX_MQ_CONFIG);
2888 	val &= ~BNX_MQ_CONFIG_KNL_BYP_BLK_SIZE;
2889 	val |= BNX_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
2890 	REG_WR(sc, BNX_MQ_CONFIG, val);
2891 
2892 	val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
2893 	REG_WR(sc, BNX_MQ_KNL_BYP_WIND_START, val);
2894 	REG_WR(sc, BNX_MQ_KNL_WIND_END, val);
2895 
2896 	val = (BCM_PAGE_BITS - 8) << 24;
2897 	REG_WR(sc, BNX_RV2P_CONFIG, val);
2898 
2899 	/* Configure page size. */
2900 	val = REG_RD(sc, BNX_TBDR_CONFIG);
2901 	val &= ~BNX_TBDR_CONFIG_PAGE_SIZE;
2902 	val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
2903 	REG_WR(sc, BNX_TBDR_CONFIG, val);
2904 
2905 bnx_chipinit_exit:
2906 	DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __func__);
2907 
2908 	return(rc);
2909 }
2910 
2911 /****************************************************************************/
2912 /* Initialize the controller in preparation to send/receive traffic.        */
2913 /*                                                                          */
2914 /* Returns:                                                                 */
2915 /*   0 for success, positive value for failure.                             */
2916 /****************************************************************************/
2917 int
2918 bnx_blockinit(struct bnx_softc *sc)
2919 {
2920 	u_int32_t		reg, val;
2921 	int 			rc = 0;
2922 
2923 	DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __func__);
2924 
2925 	/* Load the hardware default MAC address. */
2926 	bnx_set_mac_addr(sc);
2927 
2928 	/* Set the Ethernet backoff seed value */
2929 	val = sc->eaddr[0] + (sc->eaddr[1] << 8) + (sc->eaddr[2] << 16) +
2930 	    (sc->eaddr[3]) + (sc->eaddr[4] << 8) + (sc->eaddr[5] << 16);
2931 	REG_WR(sc, BNX_EMAC_BACKOFF_SEED, val);
2932 
2933 	sc->last_status_idx = 0;
2934 	sc->rx_mode = BNX_EMAC_RX_MODE_SORT_MODE;
2935 
2936 	/* Set up link change interrupt generation. */
2937 	REG_WR(sc, BNX_EMAC_ATTENTION_ENA, BNX_EMAC_ATTENTION_ENA_LINK);
2938 
2939 	/* Program the physical address of the status block. */
2940 	REG_WR(sc, BNX_HC_STATUS_ADDR_L, (u_int32_t)(sc->status_block_paddr));
2941 	REG_WR(sc, BNX_HC_STATUS_ADDR_H,
2942 	    (u_int32_t)((u_int64_t)sc->status_block_paddr >> 32));
2943 
2944 	/* Program the physical address of the statistics block. */
2945 	REG_WR(sc, BNX_HC_STATISTICS_ADDR_L,
2946 	    (u_int32_t)(sc->stats_block_paddr));
2947 	REG_WR(sc, BNX_HC_STATISTICS_ADDR_H,
2948 	    (u_int32_t)((u_int64_t)sc->stats_block_paddr >> 32));
2949 
2950 	/* Program various host coalescing parameters. */
2951 	REG_WR(sc, BNX_HC_TX_QUICK_CONS_TRIP, (sc->bnx_tx_quick_cons_trip_int
2952 	    << 16) | sc->bnx_tx_quick_cons_trip);
2953 	REG_WR(sc, BNX_HC_RX_QUICK_CONS_TRIP, (sc->bnx_rx_quick_cons_trip_int
2954 	    << 16) | sc->bnx_rx_quick_cons_trip);
2955 	REG_WR(sc, BNX_HC_COMP_PROD_TRIP, (sc->bnx_comp_prod_trip_int << 16) |
2956 	    sc->bnx_comp_prod_trip);
2957 	REG_WR(sc, BNX_HC_TX_TICKS, (sc->bnx_tx_ticks_int << 16) |
2958 	    sc->bnx_tx_ticks);
2959 	REG_WR(sc, BNX_HC_RX_TICKS, (sc->bnx_rx_ticks_int << 16) |
2960 	    sc->bnx_rx_ticks);
2961 	REG_WR(sc, BNX_HC_COM_TICKS, (sc->bnx_com_ticks_int << 16) |
2962 	    sc->bnx_com_ticks);
2963 	REG_WR(sc, BNX_HC_CMD_TICKS, (sc->bnx_cmd_ticks_int << 16) |
2964 	    sc->bnx_cmd_ticks);
2965 	REG_WR(sc, BNX_HC_STATS_TICKS, (sc->bnx_stats_ticks & 0xffff00));
2966 	REG_WR(sc, BNX_HC_STAT_COLLECT_TICKS, 0xbb8);  /* 3ms */
2967 	REG_WR(sc, BNX_HC_CONFIG,
2968 	    (BNX_HC_CONFIG_RX_TMR_MODE | BNX_HC_CONFIG_TX_TMR_MODE |
2969 	    BNX_HC_CONFIG_COLLECT_STATS));
2970 
2971 	/* Clear the internal statistics counters. */
2972 	REG_WR(sc, BNX_HC_COMMAND, BNX_HC_COMMAND_CLR_STAT_NOW);
2973 
2974 	/* Verify that bootcode is running. */
2975 	reg = REG_RD_IND(sc, sc->bnx_shmem_base + BNX_DEV_INFO_SIGNATURE);
2976 
2977 	DBRUNIF(DB_RANDOMTRUE(bnx_debug_bootcode_running_failure),
2978 	    BNX_PRINTF(sc, "%s(%d): Simulating bootcode failure.\n",
2979 	    __FILE__, __LINE__); reg = 0);
2980 
2981 	if ((reg & BNX_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
2982 	    BNX_DEV_INFO_SIGNATURE_MAGIC) {
2983 		BNX_PRINTF(sc, "%s(%d): Bootcode not running! Found: 0x%08X, "
2984 		    "Expected: 08%08X\n", __FILE__, __LINE__,
2985 		    (reg & BNX_DEV_INFO_SIGNATURE_MAGIC_MASK),
2986 		    BNX_DEV_INFO_SIGNATURE_MAGIC);
2987 		rc = ENODEV;
2988 		goto bnx_blockinit_exit;
2989 	}
2990 
2991 	/* Check if any management firmware is running. */
2992 	reg = REG_RD_IND(sc, sc->bnx_shmem_base + BNX_PORT_FEATURE);
2993 	if (reg & (BNX_PORT_FEATURE_ASF_ENABLED |
2994 	    BNX_PORT_FEATURE_IMD_ENABLED)) {
2995 		DBPRINT(sc, BNX_INFO, "Management F/W Enabled.\n");
2996 		sc->bnx_flags |= BNX_MFW_ENABLE_FLAG;
2997 	}
2998 
2999 	sc->bnx_fw_ver = REG_RD_IND(sc, sc->bnx_shmem_base +
3000 	    BNX_DEV_INFO_BC_REV);
3001 
3002 	DBPRINT(sc, BNX_INFO, "bootcode rev = 0x%08X\n", sc->bnx_fw_ver);
3003 
3004 	/* Allow bootcode to apply any additional fixes before enabling MAC. */
3005 	rc = bnx_fw_sync(sc, BNX_DRV_MSG_DATA_WAIT2 | BNX_DRV_MSG_CODE_RESET);
3006 
3007 	/* Enable link state change interrupt generation. */
3008 	REG_WR(sc, BNX_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
3009 
3010 	/* Enable all remaining blocks in the MAC. */
3011 	REG_WR(sc, BNX_MISC_ENABLE_SET_BITS, 0x5ffffff);
3012 	REG_RD(sc, BNX_MISC_ENABLE_SET_BITS);
3013 	DELAY(20);
3014 
3015 bnx_blockinit_exit:
3016 	DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __func__);
3017 
3018 	return (rc);
3019 }
3020 
3021 /****************************************************************************/
3022 /* Encapsulate an mbuf cluster into the rx_bd chain.                        */
3023 /*                                                                          */
3024 /* The NetXtreme II can support Jumbo frames by using multiple rx_bd's.     */
3025 /* This routine will map an mbuf cluster into 1 or more rx_bd's as          */
3026 /* necessary.                                                               */
3027 /*                                                                          */
3028 /* Returns:                                                                 */
3029 /*   0 for success, positive value for failure.                             */
3030 /****************************************************************************/
3031 int
3032 bnx_get_buf(struct bnx_softc *sc, struct mbuf *m, u_int16_t *prod,
3033     u_int16_t *chain_prod, u_int32_t *prod_bseq)
3034 {
3035 	bus_dmamap_t		map;
3036 	struct mbuf 		*m_new = NULL;
3037 	struct rx_bd		*rxbd;
3038 	int			i, rc = 0;
3039 	u_int32_t		addr;
3040 #ifdef BNX_DEBUG
3041 	u_int16_t debug_chain_prod =	*chain_prod;
3042 #endif
3043 	u_int16_t first_chain_prod;
3044 	u_int16_t min_free_bd;
3045 
3046 	DBPRINT(sc, (BNX_VERBOSE_RESET | BNX_VERBOSE_RECV), "Entering %s()\n",
3047 	    __func__);
3048 
3049 	/* Make sure the inputs are valid. */
3050 	DBRUNIF((*chain_prod > MAX_RX_BD),
3051 	    aprint_error_dev(sc->bnx_dev,
3052 	        "RX producer out of range: 0x%04X > 0x%04X\n",
3053 		*chain_prod, (u_int16_t)MAX_RX_BD));
3054 
3055 	DBPRINT(sc, BNX_VERBOSE_RECV, "%s(enter): prod = 0x%04X, chain_prod = "
3056 	    "0x%04X, prod_bseq = 0x%08X\n", __func__, *prod, *chain_prod,
3057 	    *prod_bseq);
3058 
3059 	/* try to get in as many mbufs as possible */
3060 	if (sc->mbuf_alloc_size == MCLBYTES)
3061 		min_free_bd = (MCLBYTES + PAGE_SIZE - 1) / PAGE_SIZE;
3062 	else
3063 		min_free_bd = (BNX_MAX_MRU + PAGE_SIZE - 1) / PAGE_SIZE;
3064 	while (sc->free_rx_bd >= min_free_bd) {
3065 		if (m == NULL) {
3066 			DBRUNIF(DB_RANDOMTRUE(bnx_debug_mbuf_allocation_failure),
3067 			    BNX_PRINTF(sc, "Simulating mbuf allocation failure.\n");
3068 
3069 				sc->mbuf_alloc_failed++;
3070 				rc = ENOBUFS;
3071 				goto bnx_get_buf_exit);
3072 
3073 			/* This is a new mbuf allocation. */
3074 			MGETHDR(m_new, M_DONTWAIT, MT_DATA);
3075 			if (m_new == NULL) {
3076 				DBPRINT(sc, BNX_WARN,
3077 				    "%s(%d): RX mbuf header allocation failed!\n",
3078 				    __FILE__, __LINE__);
3079 
3080 				DBRUNIF(1, sc->mbuf_alloc_failed++);
3081 
3082 				rc = ENOBUFS;
3083 				goto bnx_get_buf_exit;
3084 			}
3085 
3086 			DBRUNIF(1, sc->rx_mbuf_alloc++);
3087 			if (sc->mbuf_alloc_size == MCLBYTES)
3088 				MCLGET(m_new, M_DONTWAIT);
3089 			else
3090 				MEXTMALLOC(m_new, sc->mbuf_alloc_size,
3091 				    M_DONTWAIT);
3092 			if (!(m_new->m_flags & M_EXT)) {
3093 				DBPRINT(sc, BNX_WARN,
3094 				    "%s(%d): RX mbuf chain allocation failed!\n",
3095 				    __FILE__, __LINE__);
3096 
3097 				m_freem(m_new);
3098 
3099 				DBRUNIF(1, sc->rx_mbuf_alloc--);
3100 				DBRUNIF(1, sc->mbuf_alloc_failed++);
3101 
3102 				rc = ENOBUFS;
3103 				goto bnx_get_buf_exit;
3104 			}
3105 
3106 		} else {
3107 			m_new = m;
3108 			m = NULL;
3109 			m_new->m_data = m_new->m_ext.ext_buf;
3110 		}
3111 		m_new->m_len = m_new->m_pkthdr.len = sc->mbuf_alloc_size;
3112 
3113 		/* Map the mbuf cluster into device memory. */
3114 		map = sc->rx_mbuf_map[*chain_prod];
3115 		first_chain_prod = *chain_prod;
3116 		if (bus_dmamap_load_mbuf(sc->bnx_dmatag, map, m_new, BUS_DMA_NOWAIT)) {
3117 			BNX_PRINTF(sc, "%s(%d): Error mapping mbuf into RX chain!\n",
3118 			    __FILE__, __LINE__);
3119 
3120 			m_freem(m_new);
3121 
3122 			DBRUNIF(1, sc->rx_mbuf_alloc--);
3123 
3124 			rc = ENOBUFS;
3125 			goto bnx_get_buf_exit;
3126 		}
3127 		bus_dmamap_sync(sc->bnx_dmatag, map, 0, map->dm_mapsize,
3128 		    BUS_DMASYNC_PREREAD);
3129 
3130 		/* Watch for overflow. */
3131 		DBRUNIF((sc->free_rx_bd > USABLE_RX_BD),
3132 		    aprint_error_dev(sc->bnx_dev,
3133 		        "Too many free rx_bd (0x%04X > 0x%04X)!\n",
3134 			sc->free_rx_bd, (u_int16_t)USABLE_RX_BD));
3135 
3136 		DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
3137 		    sc->rx_low_watermark = sc->free_rx_bd);
3138 
3139 		/*
3140 		 * Setup the rx_bd for the first segment
3141 		 */
3142 		rxbd = &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
3143 
3144 		addr = (u_int32_t)(map->dm_segs[0].ds_addr);
3145 		rxbd->rx_bd_haddr_lo = htole32(addr);
3146 		addr = (u_int32_t)((u_int64_t)map->dm_segs[0].ds_addr >> 32);
3147 		rxbd->rx_bd_haddr_hi = htole32(addr);
3148 		rxbd->rx_bd_len = htole32(map->dm_segs[0].ds_len);
3149 		rxbd->rx_bd_flags = htole32(RX_BD_FLAGS_START);
3150 		*prod_bseq += map->dm_segs[0].ds_len;
3151 		bus_dmamap_sync(sc->bnx_dmatag,
3152 		    sc->rx_bd_chain_map[RX_PAGE(*chain_prod)],
3153 		    sizeof(struct rx_bd) * RX_IDX(*chain_prod), sizeof(struct rx_bd),
3154 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3155 
3156 		for (i = 1; i < map->dm_nsegs; i++) {
3157 			*prod = NEXT_RX_BD(*prod);
3158 			*chain_prod = RX_CHAIN_IDX(*prod);
3159 
3160 			rxbd =
3161 			    &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
3162 
3163 			addr = (u_int32_t)(map->dm_segs[i].ds_addr);
3164 			rxbd->rx_bd_haddr_lo = htole32(addr);
3165 			addr = (u_int32_t)((u_int64_t)map->dm_segs[i].ds_addr >> 32);
3166 			rxbd->rx_bd_haddr_hi = htole32(addr);
3167 			rxbd->rx_bd_len = htole32(map->dm_segs[i].ds_len);
3168 			rxbd->rx_bd_flags = 0;
3169 			*prod_bseq += map->dm_segs[i].ds_len;
3170 			bus_dmamap_sync(sc->bnx_dmatag,
3171 			    sc->rx_bd_chain_map[RX_PAGE(*chain_prod)],
3172 			    sizeof(struct rx_bd) * RX_IDX(*chain_prod),
3173 			    sizeof(struct rx_bd), BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3174 		}
3175 
3176 		rxbd->rx_bd_flags |= htole32(RX_BD_FLAGS_END);
3177 		bus_dmamap_sync(sc->bnx_dmatag,
3178 		    sc->rx_bd_chain_map[RX_PAGE(*chain_prod)],
3179 		    sizeof(struct rx_bd) * RX_IDX(*chain_prod),
3180 		    sizeof(struct rx_bd), BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3181 
3182 		/*
3183 		 * Save the mbuf, ajust the map pointer (swap map for first and
3184 		 * last rx_bd entry to that rx_mbuf_ptr and rx_mbuf_map matches)
3185 		 * and update counter.
3186 		 */
3187 		sc->rx_mbuf_ptr[*chain_prod] = m_new;
3188 		sc->rx_mbuf_map[first_chain_prod] = sc->rx_mbuf_map[*chain_prod];
3189 		sc->rx_mbuf_map[*chain_prod] = map;
3190 		sc->free_rx_bd -= map->dm_nsegs;
3191 
3192 		DBRUN(BNX_VERBOSE_RECV, bnx_dump_rx_mbuf_chain(sc, debug_chain_prod,
3193 		    map->dm_nsegs));
3194 		*prod = NEXT_RX_BD(*prod);
3195 		*chain_prod = RX_CHAIN_IDX(*prod);
3196 	}
3197 
3198 bnx_get_buf_exit:
3199 	DBPRINT(sc, BNX_VERBOSE_RECV, "%s(exit): prod = 0x%04X, chain_prod "
3200 	    "= 0x%04X, prod_bseq = 0x%08X\n", __func__, *prod,
3201 	    *chain_prod, *prod_bseq);
3202 
3203 	DBPRINT(sc, (BNX_VERBOSE_RESET | BNX_VERBOSE_RECV), "Exiting %s()\n",
3204 	    __func__);
3205 
3206 	return(rc);
3207 }
3208 
3209 /****************************************************************************/
3210 /* Allocate memory and initialize the TX data structures.                   */
3211 /*                                                                          */
3212 /* Returns:                                                                 */
3213 /*   0 for success, positive value for failure.                             */
3214 /****************************************************************************/
3215 int
3216 bnx_init_tx_chain(struct bnx_softc *sc)
3217 {
3218 	struct tx_bd		*txbd;
3219 	u_int32_t		val, addr;
3220 	int			i, rc = 0;
3221 
3222 	DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __func__);
3223 
3224 	/* Set the initial TX producer/consumer indices. */
3225 	sc->tx_prod = 0;
3226 	sc->tx_cons = 0;
3227 	sc->tx_prod_bseq = 0;
3228 	sc->used_tx_bd = 0;
3229 	DBRUNIF(1, sc->tx_hi_watermark = USABLE_TX_BD);
3230 
3231 	/*
3232 	 * The NetXtreme II supports a linked-list structure called
3233 	 * a Buffer Descriptor Chain (or BD chain).  A BD chain
3234 	 * consists of a series of 1 or more chain pages, each of which
3235 	 * consists of a fixed number of BD entries.
3236 	 * The last BD entry on each page is a pointer to the next page
3237 	 * in the chain, and the last pointer in the BD chain
3238 	 * points back to the beginning of the chain.
3239 	 */
3240 
3241 	/* Set the TX next pointer chain entries. */
3242 	for (i = 0; i < TX_PAGES; i++) {
3243 		int j;
3244 
3245 		txbd = &sc->tx_bd_chain[i][USABLE_TX_BD_PER_PAGE];
3246 
3247 		/* Check if we've reached the last page. */
3248 		if (i == (TX_PAGES - 1))
3249 			j = 0;
3250 		else
3251 			j = i + 1;
3252 
3253 		addr = (u_int32_t)(sc->tx_bd_chain_paddr[j]);
3254 		txbd->tx_bd_haddr_lo = htole32(addr);
3255 		addr = (u_int32_t)((u_int64_t)sc->tx_bd_chain_paddr[j] >> 32);
3256 		txbd->tx_bd_haddr_hi = htole32(addr);
3257 		bus_dmamap_sync(sc->bnx_dmatag, sc->tx_bd_chain_map[i], 0,
3258 		    BNX_TX_CHAIN_PAGE_SZ, BUS_DMASYNC_PREWRITE);
3259 	}
3260 
3261 	/*
3262 	 * Initialize the context ID for an L2 TX chain.
3263 	 */
3264 	val = BNX_L2CTX_TYPE_TYPE_L2;
3265 	val |= BNX_L2CTX_TYPE_SIZE_L2;
3266 	CTX_WR(sc, GET_CID_ADDR(TX_CID), BNX_L2CTX_TYPE, val);
3267 
3268 	val = BNX_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16);
3269 	CTX_WR(sc, GET_CID_ADDR(TX_CID), BNX_L2CTX_CMD_TYPE, val);
3270 
3271 	/* Point the hardware to the first page in the chain. */
3272 	val = (u_int32_t)((u_int64_t)sc->tx_bd_chain_paddr[0] >> 32);
3273 	CTX_WR(sc, GET_CID_ADDR(TX_CID), BNX_L2CTX_TBDR_BHADDR_HI, val);
3274 	val = (u_int32_t)(sc->tx_bd_chain_paddr[0]);
3275 	CTX_WR(sc, GET_CID_ADDR(TX_CID), BNX_L2CTX_TBDR_BHADDR_LO, val);
3276 
3277 	DBRUN(BNX_VERBOSE_SEND, bnx_dump_tx_chain(sc, 0, TOTAL_TX_BD));
3278 
3279 	DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __func__);
3280 
3281 	return(rc);
3282 }
3283 
3284 /****************************************************************************/
3285 /* Free memory and clear the TX data structures.                            */
3286 /*                                                                          */
3287 /* Returns:                                                                 */
3288 /*   Nothing.                                                               */
3289 /****************************************************************************/
3290 void
3291 bnx_free_tx_chain(struct bnx_softc *sc)
3292 {
3293 	int			i;
3294 
3295 	DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __func__);
3296 
3297 	/* Unmap, unload, and free any mbufs still in the TX mbuf chain. */
3298 	for (i = 0; i < TOTAL_TX_BD; i++) {
3299 		if (sc->tx_mbuf_ptr[i] != NULL) {
3300 			if (sc->tx_mbuf_map != NULL)
3301 				bus_dmamap_sync(sc->bnx_dmatag,
3302 				    sc->tx_mbuf_map[i], 0,
3303 				    sc->tx_mbuf_map[i]->dm_mapsize,
3304 				    BUS_DMASYNC_POSTWRITE);
3305 			m_freem(sc->tx_mbuf_ptr[i]);
3306 			sc->tx_mbuf_ptr[i] = NULL;
3307 			DBRUNIF(1, sc->tx_mbuf_alloc--);
3308 		}
3309 	}
3310 
3311 	/* Clear each TX chain page. */
3312 	for (i = 0; i < TX_PAGES; i++) {
3313 		bzero((char *)sc->tx_bd_chain[i], BNX_TX_CHAIN_PAGE_SZ);
3314 		bus_dmamap_sync(sc->bnx_dmatag, sc->tx_bd_chain_map[i], 0,
3315 		    BNX_TX_CHAIN_PAGE_SZ, BUS_DMASYNC_PREWRITE);
3316 	}
3317 
3318 	/* Check if we lost any mbufs in the process. */
3319 	DBRUNIF((sc->tx_mbuf_alloc),
3320 	    aprint_error_dev(sc->bnx_dev,
3321 	        "Memory leak! Lost %d mbufs from tx chain!\n",
3322 		sc->tx_mbuf_alloc));
3323 
3324 	DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __func__);
3325 }
3326 
3327 /****************************************************************************/
3328 /* Allocate memory and initialize the RX data structures.                   */
3329 /*                                                                          */
3330 /* Returns:                                                                 */
3331 /*   0 for success, positive value for failure.                             */
3332 /****************************************************************************/
3333 int
3334 bnx_init_rx_chain(struct bnx_softc *sc)
3335 {
3336 	struct rx_bd		*rxbd;
3337 	int			i, rc = 0;
3338 	u_int16_t		prod, chain_prod;
3339 	u_int32_t		prod_bseq, val, addr;
3340 
3341 	DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __func__);
3342 
3343 	/* Initialize the RX producer and consumer indices. */
3344 	sc->rx_prod = 0;
3345 	sc->rx_cons = 0;
3346 	sc->rx_prod_bseq = 0;
3347 	sc->free_rx_bd = BNX_RX_SLACK_SPACE;
3348 	DBRUNIF(1, sc->rx_low_watermark = USABLE_RX_BD);
3349 
3350 	/* Initialize the RX next pointer chain entries. */
3351 	for (i = 0; i < RX_PAGES; i++) {
3352 		int j;
3353 
3354 		rxbd = &sc->rx_bd_chain[i][USABLE_RX_BD_PER_PAGE];
3355 
3356 		/* Check if we've reached the last page. */
3357 		if (i == (RX_PAGES - 1))
3358 			j = 0;
3359 		else
3360 			j = i + 1;
3361 
3362 		/* Setup the chain page pointers. */
3363 		addr = (u_int32_t)((u_int64_t)sc->rx_bd_chain_paddr[j] >> 32);
3364 		rxbd->rx_bd_haddr_hi = htole32(addr);
3365 		addr = (u_int32_t)(sc->rx_bd_chain_paddr[j]);
3366 		rxbd->rx_bd_haddr_lo = htole32(addr);
3367 		bus_dmamap_sync(sc->bnx_dmatag, sc->rx_bd_chain_map[i],
3368 		    0, BNX_RX_CHAIN_PAGE_SZ,
3369 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3370 	}
3371 
3372 	/* Initialize the context ID for an L2 RX chain. */
3373 	val = BNX_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
3374 	val |= BNX_L2CTX_CTX_TYPE_SIZE_L2;
3375 	val |= 0x02 << 8;
3376 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BNX_L2CTX_CTX_TYPE, val);
3377 
3378 	/* Point the hardware to the first page in the chain. */
3379 	val = (u_int32_t)((u_int64_t)sc->rx_bd_chain_paddr[0] >> 32);
3380 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BNX_L2CTX_NX_BDHADDR_HI, val);
3381 	val = (u_int32_t)(sc->rx_bd_chain_paddr[0]);
3382 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BNX_L2CTX_NX_BDHADDR_LO, val);
3383 
3384 	/* Allocate mbuf clusters for the rx_bd chain. */
3385 	prod = prod_bseq = 0;
3386 	chain_prod = RX_CHAIN_IDX(prod);
3387 	if (bnx_get_buf(sc, NULL, &prod, &chain_prod, &prod_bseq)) {
3388 		BNX_PRINTF(sc,
3389 		    "Error filling RX chain: rx_bd[0x%04X]!\n", chain_prod);
3390 	}
3391 
3392 	/* Save the RX chain producer index. */
3393 	sc->rx_prod = prod;
3394 	sc->rx_prod_bseq = prod_bseq;
3395 
3396 	for (i = 0; i < RX_PAGES; i++)
3397 		bus_dmamap_sync(sc->bnx_dmatag, sc->rx_bd_chain_map[i], 0,
3398 		    sc->rx_bd_chain_map[i]->dm_mapsize,
3399 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3400 
3401 	/* Tell the chip about the waiting rx_bd's. */
3402 	REG_WR16(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BDIDX, sc->rx_prod);
3403 	REG_WR(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BSEQ, sc->rx_prod_bseq);
3404 
3405 	DBRUN(BNX_VERBOSE_RECV, bnx_dump_rx_chain(sc, 0, TOTAL_RX_BD));
3406 
3407 	DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __func__);
3408 
3409 	return(rc);
3410 }
3411 
3412 /****************************************************************************/
3413 /* Free memory and clear the RX data structures.                            */
3414 /*                                                                          */
3415 /* Returns:                                                                 */
3416 /*   Nothing.                                                               */
3417 /****************************************************************************/
3418 void
3419 bnx_free_rx_chain(struct bnx_softc *sc)
3420 {
3421 	int			i;
3422 
3423 	DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __func__);
3424 
3425 	/* Free any mbufs still in the RX mbuf chain. */
3426 	for (i = 0; i < TOTAL_RX_BD; i++) {
3427 		if (sc->rx_mbuf_ptr[i] != NULL) {
3428 			if (sc->rx_mbuf_map[i] != NULL)
3429 				bus_dmamap_sync(sc->bnx_dmatag,
3430 				    sc->rx_mbuf_map[i],	0,
3431 				    sc->rx_mbuf_map[i]->dm_mapsize,
3432 				    BUS_DMASYNC_POSTREAD);
3433 			m_freem(sc->rx_mbuf_ptr[i]);
3434 			sc->rx_mbuf_ptr[i] = NULL;
3435 			DBRUNIF(1, sc->rx_mbuf_alloc--);
3436 		}
3437 	}
3438 
3439 	/* Clear each RX chain page. */
3440 	for (i = 0; i < RX_PAGES; i++)
3441 		bzero((char *)sc->rx_bd_chain[i], BNX_RX_CHAIN_PAGE_SZ);
3442 
3443 	/* Check if we lost any mbufs in the process. */
3444 	DBRUNIF((sc->rx_mbuf_alloc),
3445 	    aprint_error_dev(sc->bnx_dev,
3446 	        "Memory leak! Lost %d mbufs from rx chain!\n",
3447 		sc->rx_mbuf_alloc));
3448 
3449 	DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __func__);
3450 }
3451 
3452 /****************************************************************************/
3453 /* Handles PHY generated interrupt events.                                  */
3454 /*                                                                          */
3455 /* Returns:                                                                 */
3456 /*   Nothing.                                                               */
3457 /****************************************************************************/
3458 void
3459 bnx_phy_intr(struct bnx_softc *sc)
3460 {
3461 	u_int32_t		new_link_state, old_link_state;
3462 
3463 	bus_dmamap_sync(sc->bnx_dmatag, sc->status_map, 0, BNX_STATUS_BLK_SZ,
3464 	    BUS_DMASYNC_POSTREAD);
3465 	new_link_state = sc->status_block->status_attn_bits &
3466 	    STATUS_ATTN_BITS_LINK_STATE;
3467 	old_link_state = sc->status_block->status_attn_bits_ack &
3468 	    STATUS_ATTN_BITS_LINK_STATE;
3469 
3470 	/* Handle any changes if the link state has changed. */
3471 	if (new_link_state != old_link_state) {
3472 		DBRUN(BNX_VERBOSE_INTR, bnx_dump_status_block(sc));
3473 
3474 		callout_stop(&sc->bnx_timeout);
3475 		bnx_tick(sc);
3476 
3477 		/* Update the status_attn_bits_ack field in the status block. */
3478 		if (new_link_state) {
3479 			REG_WR(sc, BNX_PCICFG_STATUS_BIT_SET_CMD,
3480 			    STATUS_ATTN_BITS_LINK_STATE);
3481 			DBPRINT(sc, BNX_INFO, "Link is now UP.\n");
3482 		} else {
3483 			REG_WR(sc, BNX_PCICFG_STATUS_BIT_CLEAR_CMD,
3484 			    STATUS_ATTN_BITS_LINK_STATE);
3485 			DBPRINT(sc, BNX_INFO, "Link is now DOWN.\n");
3486 		}
3487 	}
3488 
3489 	/* Acknowledge the link change interrupt. */
3490 	REG_WR(sc, BNX_EMAC_STATUS, BNX_EMAC_STATUS_LINK_CHANGE);
3491 }
3492 
3493 /****************************************************************************/
3494 /* Handles received frame interrupt events.                                 */
3495 /*                                                                          */
3496 /* Returns:                                                                 */
3497 /*   Nothing.                                                               */
3498 /****************************************************************************/
3499 void
3500 bnx_rx_intr(struct bnx_softc *sc)
3501 {
3502 	struct status_block	*sblk = sc->status_block;
3503 	struct ifnet		*ifp = &sc->bnx_ec.ec_if;
3504 	u_int16_t		hw_cons, sw_cons, sw_chain_cons;
3505 	u_int16_t		sw_prod, sw_chain_prod;
3506 	u_int32_t		sw_prod_bseq;
3507 	struct l2_fhdr		*l2fhdr;
3508 	int			i;
3509 
3510 	DBRUNIF(1, sc->rx_interrupts++);
3511 	bus_dmamap_sync(sc->bnx_dmatag, sc->status_map, 0, BNX_STATUS_BLK_SZ,
3512 	    BUS_DMASYNC_POSTREAD);
3513 
3514 	/* Prepare the RX chain pages to be accessed by the host CPU. */
3515 	for (i = 0; i < RX_PAGES; i++)
3516 		bus_dmamap_sync(sc->bnx_dmatag,
3517 		    sc->rx_bd_chain_map[i], 0,
3518 		    sc->rx_bd_chain_map[i]->dm_mapsize,
3519 		    BUS_DMASYNC_POSTWRITE);
3520 
3521 	/* Get the hardware's view of the RX consumer index. */
3522 	hw_cons = sc->hw_rx_cons = sblk->status_rx_quick_consumer_index0;
3523 	if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
3524 		hw_cons++;
3525 
3526 	/* Get working copies of the driver's view of the RX indices. */
3527 	sw_cons = sc->rx_cons;
3528 	sw_prod = sc->rx_prod;
3529 	sw_prod_bseq = sc->rx_prod_bseq;
3530 
3531 	DBPRINT(sc, BNX_INFO_RECV, "%s(enter): sw_prod = 0x%04X, "
3532 	    "sw_cons = 0x%04X, sw_prod_bseq = 0x%08X\n",
3533 	    __func__, sw_prod, sw_cons, sw_prod_bseq);
3534 
3535 	/* Prevent speculative reads from getting ahead of the status block. */
3536 	bus_space_barrier(sc->bnx_btag, sc->bnx_bhandle, 0, 0,
3537 	    BUS_SPACE_BARRIER_READ);
3538 
3539 	DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
3540 	    sc->rx_low_watermark = sc->free_rx_bd);
3541 
3542 	/*
3543 	 * Scan through the receive chain as long
3544 	 * as there is work to do.
3545 	 */
3546 	while (sw_cons != hw_cons) {
3547 		struct mbuf *m;
3548 		struct rx_bd *rxbd;
3549 		unsigned int len;
3550 		u_int32_t status;
3551 
3552 		/* Convert the producer/consumer indices to an actual
3553 		 * rx_bd index.
3554 		 */
3555 		sw_chain_cons = RX_CHAIN_IDX(sw_cons);
3556 		sw_chain_prod = RX_CHAIN_IDX(sw_prod);
3557 
3558 		/* Get the used rx_bd. */
3559 		rxbd = &sc->rx_bd_chain[RX_PAGE(sw_chain_cons)][RX_IDX(sw_chain_cons)];
3560 		sc->free_rx_bd++;
3561 
3562 		DBRUN(BNX_VERBOSE_RECV, aprint_error("%s(): ", __func__);
3563 		bnx_dump_rxbd(sc, sw_chain_cons, rxbd));
3564 
3565 		/* The mbuf is stored with the last rx_bd entry of a packet. */
3566 		if (sc->rx_mbuf_ptr[sw_chain_cons] != NULL) {
3567 #ifdef DIAGNOSTIC
3568 			/* Validate that this is the last rx_bd. */
3569 			if ((rxbd->rx_bd_flags & RX_BD_FLAGS_END) == 0) {
3570 			    printf("%s: Unexpected mbuf found in "
3571 			        "rx_bd[0x%04X]!\n", device_xname(sc->bnx_dev),
3572 			        sw_chain_cons);
3573 			}
3574 #endif
3575 
3576 			/* DRC - ToDo: If the received packet is small, say less
3577 			 *             than 128 bytes, allocate a new mbuf here,
3578 			 *             copy the data to that mbuf, and recycle
3579 			 *             the mapped jumbo frame.
3580 			 */
3581 
3582 			/* Unmap the mbuf from DMA space. */
3583 #ifdef DIAGNOSTIC
3584 			if (sc->rx_mbuf_map[sw_chain_cons]->dm_mapsize == 0) {
3585 				printf("invalid map sw_cons 0x%x "
3586 				"sw_prod 0x%x "
3587 				"sw_chain_cons 0x%x "
3588 				"sw_chain_prod 0x%x "
3589 				"hw_cons 0x%x "
3590 				"TOTAL_RX_BD_PER_PAGE 0x%x "
3591 				"TOTAL_RX_BD 0x%x\n",
3592 				sw_cons, sw_prod, sw_chain_cons, sw_chain_prod,
3593 				hw_cons,
3594 				(int)TOTAL_RX_BD_PER_PAGE, (int)TOTAL_RX_BD);
3595 			}
3596 #endif
3597 			bus_dmamap_sync(sc->bnx_dmatag,
3598 			    sc->rx_mbuf_map[sw_chain_cons], 0,
3599 			    sc->rx_mbuf_map[sw_chain_cons]->dm_mapsize,
3600 			    BUS_DMASYNC_POSTREAD);
3601 			bus_dmamap_unload(sc->bnx_dmatag,
3602 			    sc->rx_mbuf_map[sw_chain_cons]);
3603 
3604 			/* Remove the mbuf from the driver's chain. */
3605 			m = sc->rx_mbuf_ptr[sw_chain_cons];
3606 			sc->rx_mbuf_ptr[sw_chain_cons] = NULL;
3607 
3608 			/*
3609 			 * Frames received on the NetXteme II are prepended
3610 			 * with the l2_fhdr structure which provides status
3611 			 * information about the received frame (including
3612 			 * VLAN tags and checksum info) and are also
3613 			 * automatically adjusted to align the IP header
3614 			 * (i.e. two null bytes are inserted before the
3615 			 * Ethernet header).
3616 			 */
3617 			l2fhdr = mtod(m, struct l2_fhdr *);
3618 
3619 			len    = l2fhdr->l2_fhdr_pkt_len;
3620 			status = l2fhdr->l2_fhdr_status;
3621 
3622 			DBRUNIF(DB_RANDOMTRUE(bnx_debug_l2fhdr_status_check),
3623 			    aprint_error("Simulating l2_fhdr status error.\n");
3624 			    status = status | L2_FHDR_ERRORS_PHY_DECODE);
3625 
3626 			/* Watch for unusual sized frames. */
3627 			DBRUNIF(((len < BNX_MIN_MTU) ||
3628 			    (len > BNX_MAX_JUMBO_ETHER_MTU_VLAN)),
3629 			    aprint_error_dev(sc->bnx_dev,
3630 			        "Unusual frame size found. "
3631 				"Min(%d), Actual(%d), Max(%d)\n",
3632 				(int)BNX_MIN_MTU, len,
3633 				(int)BNX_MAX_JUMBO_ETHER_MTU_VLAN);
3634 
3635 			bnx_dump_mbuf(sc, m);
3636 			bnx_breakpoint(sc));
3637 
3638 			len -= ETHER_CRC_LEN;
3639 
3640 			/* Check the received frame for errors. */
3641 			if ((status &  (L2_FHDR_ERRORS_BAD_CRC |
3642 			    L2_FHDR_ERRORS_PHY_DECODE |
3643 			    L2_FHDR_ERRORS_ALIGNMENT |
3644 			    L2_FHDR_ERRORS_TOO_SHORT |
3645 			    L2_FHDR_ERRORS_GIANT_FRAME)) ||
3646 			    len < (BNX_MIN_MTU - ETHER_CRC_LEN) ||
3647 			    len >
3648 			    (BNX_MAX_JUMBO_ETHER_MTU_VLAN - ETHER_CRC_LEN)) {
3649 				ifp->if_ierrors++;
3650 				DBRUNIF(1, sc->l2fhdr_status_errors++);
3651 
3652 				/* Reuse the mbuf for a new frame. */
3653 				if (bnx_get_buf(sc, m, &sw_prod,
3654 				    &sw_chain_prod, &sw_prod_bseq)) {
3655 					DBRUNIF(1, bnx_breakpoint(sc));
3656 					panic("%s: Can't reuse RX mbuf!\n",
3657 					    device_xname(sc->bnx_dev));
3658 				}
3659 				continue;
3660 			}
3661 
3662 			/*
3663 			 * Get a new mbuf for the rx_bd.   If no new
3664 			 * mbufs are available then reuse the current mbuf,
3665 			 * log an ierror on the interface, and generate
3666 			 * an error in the system log.
3667 			 */
3668 			if (bnx_get_buf(sc, NULL, &sw_prod, &sw_chain_prod,
3669 			    &sw_prod_bseq)) {
3670 				DBRUN(BNX_WARN, BNX_PRINTF(sc, "Failed to allocate "
3671 					"new mbuf, incoming frame dropped!\n"));
3672 
3673 				ifp->if_ierrors++;
3674 
3675 				/* Try and reuse the exisitng mbuf. */
3676 				if (bnx_get_buf(sc, m, &sw_prod,
3677 				    &sw_chain_prod, &sw_prod_bseq)) {
3678 					DBRUNIF(1, bnx_breakpoint(sc));
3679 					panic("%s: Double mbuf allocation "
3680 					    "failure!",
3681 					    device_xname(sc->bnx_dev));
3682 				}
3683 				continue;
3684 			}
3685 
3686 			/* Skip over the l2_fhdr when passing the data up
3687 			 * the stack.
3688 			 */
3689 			m_adj(m, sizeof(struct l2_fhdr) + ETHER_ALIGN);
3690 
3691 			/* Adjust the pckt length to match the received data. */
3692 			m->m_pkthdr.len = m->m_len = len;
3693 
3694 			/* Send the packet to the appropriate interface. */
3695 			m->m_pkthdr.rcvif = ifp;
3696 
3697 			DBRUN(BNX_VERBOSE_RECV,
3698 			    struct ether_header *eh;
3699 			    eh = mtod(m, struct ether_header *);
3700 			    aprint_error("%s: to: %s, from: %s, type: 0x%04X\n",
3701 			    __func__, ether_sprintf(eh->ether_dhost),
3702 			    ether_sprintf(eh->ether_shost),
3703 			    htons(eh->ether_type)));
3704 
3705 			/* Validate the checksum. */
3706 
3707 			/* Check for an IP datagram. */
3708 			if (status & L2_FHDR_STATUS_IP_DATAGRAM) {
3709 				/* Check if the IP checksum is valid. */
3710 				if ((l2fhdr->l2_fhdr_ip_xsum ^ 0xffff)
3711 				    == 0)
3712 					m->m_pkthdr.csum_flags |=
3713 					    M_CSUM_IPv4;
3714 #ifdef BNX_DEBUG
3715 				else
3716 					DBPRINT(sc, BNX_WARN_SEND,
3717 					    "%s(): Invalid IP checksum "
3718 					        "= 0x%04X!\n",
3719 						__func__,
3720 						l2fhdr->l2_fhdr_ip_xsum
3721 						);
3722 #endif
3723 			}
3724 
3725 			/* Check for a valid TCP/UDP frame. */
3726 			if (status & (L2_FHDR_STATUS_TCP_SEGMENT |
3727 			    L2_FHDR_STATUS_UDP_DATAGRAM)) {
3728 				/* Check for a good TCP/UDP checksum. */
3729 				if ((status &
3730 				    (L2_FHDR_ERRORS_TCP_XSUM |
3731 				    L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
3732 					m->m_pkthdr.csum_flags |=
3733 					    M_CSUM_TCPv4 |
3734 					    M_CSUM_UDPv4;
3735 				} else {
3736 					DBPRINT(sc, BNX_WARN_SEND,
3737 					    "%s(): Invalid TCP/UDP "
3738 					    "checksum = 0x%04X!\n",
3739 					    __func__,
3740 					    l2fhdr->l2_fhdr_tcp_udp_xsum);
3741 				}
3742 			}
3743 
3744 			/*
3745 			 * If we received a packet with a vlan tag,
3746 			 * attach that information to the packet.
3747 			 */
3748 			if (status & L2_FHDR_STATUS_L2_VLAN_TAG) {
3749 #if 0
3750 				struct ether_vlan_header vh;
3751 
3752 				DBPRINT(sc, BNX_VERBOSE_SEND,
3753 				    "%s(): VLAN tag = 0x%04X\n",
3754 				    __func__,
3755 				    l2fhdr->l2_fhdr_vlan_tag);
3756 
3757 				if (m->m_pkthdr.len < ETHER_HDR_LEN) {
3758 					m_freem(m);
3759 					continue;
3760 				}
3761 				m_copydata(m, 0, ETHER_HDR_LEN, (void *)&vh);
3762 				vh.evl_proto = vh.evl_encap_proto;
3763 				vh.evl_tag = l2fhdr->l2_fhdr_vlan_tag;
3764 				vh.evl_encap_proto = htons(ETHERTYPE_VLAN);
3765 				m_adj(m, ETHER_HDR_LEN);
3766 				if ((m = m_prepend(m, sizeof(vh), M_DONTWAIT)) == NULL)
3767 					continue;
3768 				m->m_pkthdr.len += sizeof(vh);
3769 				if (m->m_len < sizeof(vh) &&
3770 				    (m = m_pullup(m, sizeof(vh))) == NULL)
3771 					goto bnx_rx_int_next_rx;
3772 				m_copyback(m, 0, sizeof(vh), &vh);
3773 #else
3774 				VLAN_INPUT_TAG(ifp, m,
3775 				    l2fhdr->l2_fhdr_vlan_tag,
3776 				    continue);
3777 #endif
3778 			}
3779 
3780 #if NBPFILTER > 0
3781 			/*
3782 			 * Handle BPF listeners. Let the BPF
3783 			 * user see the packet.
3784 			 */
3785 			if (ifp->if_bpf)
3786 				bpf_mtap(ifp->if_bpf, m);
3787 #endif
3788 
3789 			/* Pass the mbuf off to the upper layers. */
3790 			ifp->if_ipackets++;
3791 			DBPRINT(sc, BNX_VERBOSE_RECV,
3792 			    "%s(): Passing received frame up.\n", __func__);
3793 			(*ifp->if_input)(ifp, m);
3794 			DBRUNIF(1, sc->rx_mbuf_alloc--);
3795 
3796 		}
3797 
3798 		sw_cons = NEXT_RX_BD(sw_cons);
3799 
3800 		/* Refresh hw_cons to see if there's new work */
3801 		if (sw_cons == hw_cons) {
3802 			hw_cons = sc->hw_rx_cons =
3803 			    sblk->status_rx_quick_consumer_index0;
3804 			if ((hw_cons & USABLE_RX_BD_PER_PAGE) ==
3805 			    USABLE_RX_BD_PER_PAGE)
3806 				hw_cons++;
3807 		}
3808 
3809 		/* Prevent speculative reads from getting ahead of
3810 		 * the status block.
3811 		 */
3812 		bus_space_barrier(sc->bnx_btag, sc->bnx_bhandle, 0, 0,
3813 		    BUS_SPACE_BARRIER_READ);
3814 	}
3815 
3816 	for (i = 0; i < RX_PAGES; i++)
3817 		bus_dmamap_sync(sc->bnx_dmatag,
3818 		    sc->rx_bd_chain_map[i], 0,
3819 		    sc->rx_bd_chain_map[i]->dm_mapsize,
3820 		    BUS_DMASYNC_PREWRITE);
3821 
3822 	sc->rx_cons = sw_cons;
3823 	sc->rx_prod = sw_prod;
3824 	sc->rx_prod_bseq = sw_prod_bseq;
3825 
3826 	REG_WR16(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BDIDX, sc->rx_prod);
3827 	REG_WR(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BSEQ, sc->rx_prod_bseq);
3828 
3829 	DBPRINT(sc, BNX_INFO_RECV, "%s(exit): rx_prod = 0x%04X, "
3830 	    "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
3831 	    __func__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
3832 }
3833 
3834 /****************************************************************************/
3835 /* Handles transmit completion interrupt events.                            */
3836 /*                                                                          */
3837 /* Returns:                                                                 */
3838 /*   Nothing.                                                               */
3839 /****************************************************************************/
3840 void
3841 bnx_tx_intr(struct bnx_softc *sc)
3842 {
3843 	struct status_block	*sblk = sc->status_block;
3844 	struct ifnet		*ifp = &sc->bnx_ec.ec_if;
3845 	u_int16_t		hw_tx_cons, sw_tx_cons, sw_tx_chain_cons;
3846 
3847 	DBRUNIF(1, sc->tx_interrupts++);
3848 	bus_dmamap_sync(sc->bnx_dmatag, sc->status_map, 0, BNX_STATUS_BLK_SZ,
3849 	    BUS_DMASYNC_POSTREAD);
3850 
3851 	/* Get the hardware's view of the TX consumer index. */
3852 	hw_tx_cons = sc->hw_tx_cons = sblk->status_tx_quick_consumer_index0;
3853 
3854 	/* Skip to the next entry if this is a chain page pointer. */
3855 	if ((hw_tx_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
3856 		hw_tx_cons++;
3857 
3858 	sw_tx_cons = sc->tx_cons;
3859 
3860 	/* Prevent speculative reads from getting ahead of the status block. */
3861 	bus_space_barrier(sc->bnx_btag, sc->bnx_bhandle, 0, 0,
3862 	    BUS_SPACE_BARRIER_READ);
3863 
3864 	/* Cycle through any completed TX chain page entries. */
3865 	while (sw_tx_cons != hw_tx_cons) {
3866 #ifdef BNX_DEBUG
3867 		struct tx_bd *txbd = NULL;
3868 #endif
3869 		sw_tx_chain_cons = TX_CHAIN_IDX(sw_tx_cons);
3870 
3871 		DBPRINT(sc, BNX_INFO_SEND, "%s(): hw_tx_cons = 0x%04X, "
3872 		    "sw_tx_cons = 0x%04X, sw_tx_chain_cons = 0x%04X\n",
3873 		    __func__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
3874 
3875 		DBRUNIF((sw_tx_chain_cons > MAX_TX_BD),
3876 		    aprint_error_dev(sc->bnx_dev,
3877 		        "TX chain consumer out of range! 0x%04X > 0x%04X\n",
3878 			sw_tx_chain_cons, (int)MAX_TX_BD); bnx_breakpoint(sc));
3879 
3880 		DBRUNIF(1, txbd = &sc->tx_bd_chain
3881 		    [TX_PAGE(sw_tx_chain_cons)][TX_IDX(sw_tx_chain_cons)]);
3882 
3883 		DBRUNIF((txbd == NULL),
3884 		    aprint_error_dev(sc->bnx_dev,
3885 		        "Unexpected NULL tx_bd[0x%04X]!\n", sw_tx_chain_cons);
3886 		    bnx_breakpoint(sc));
3887 
3888 		DBRUN(BNX_INFO_SEND, aprint_debug("%s: ", __func__);
3889 		    bnx_dump_txbd(sc, sw_tx_chain_cons, txbd));
3890 
3891 		/*
3892 		 * Free the associated mbuf. Remember
3893 		 * that only the last tx_bd of a packet
3894 		 * has an mbuf pointer and DMA map.
3895 		 */
3896 		if (sc->tx_mbuf_ptr[sw_tx_chain_cons] != NULL) {
3897 			/* Validate that this is the last tx_bd. */
3898 			DBRUNIF((!(txbd->tx_bd_vlan_tag_flags &
3899 			    TX_BD_FLAGS_END)),
3900 			    aprint_error_dev(sc->bnx_dev,
3901 			        "tx_bd END flag not set but txmbuf == NULL!\n");
3902 			    bnx_breakpoint(sc));
3903 
3904 			DBRUN(BNX_INFO_SEND,
3905 			    aprint_debug("%s: Unloading map/freeing mbuf "
3906 			    "from tx_bd[0x%04X]\n",
3907 			    __func__, sw_tx_chain_cons));
3908 
3909 			/* Unmap the mbuf. */
3910 			bus_dmamap_unload(sc->bnx_dmatag,
3911 			    sc->tx_mbuf_map[sw_tx_chain_cons]);
3912 
3913 			/* Free the mbuf. */
3914 			m_freem(sc->tx_mbuf_ptr[sw_tx_chain_cons]);
3915 			sc->tx_mbuf_ptr[sw_tx_chain_cons] = NULL;
3916 			DBRUNIF(1, sc->tx_mbuf_alloc--);
3917 
3918 			ifp->if_opackets++;
3919 		}
3920 
3921 		sc->used_tx_bd--;
3922 		sw_tx_cons = NEXT_TX_BD(sw_tx_cons);
3923 
3924 		/* Refresh hw_cons to see if there's new work. */
3925 		hw_tx_cons = sc->hw_tx_cons =
3926 		    sblk->status_tx_quick_consumer_index0;
3927 		if ((hw_tx_cons & USABLE_TX_BD_PER_PAGE) ==
3928 		    USABLE_TX_BD_PER_PAGE)
3929 			hw_tx_cons++;
3930 
3931 		/* Prevent speculative reads from getting ahead of
3932 		 * the status block.
3933 		 */
3934 		bus_space_barrier(sc->bnx_btag, sc->bnx_bhandle, 0, 0,
3935 		    BUS_SPACE_BARRIER_READ);
3936 	}
3937 
3938 	/* Clear the TX timeout timer. */
3939 	ifp->if_timer = 0;
3940 
3941 	/* Clear the tx hardware queue full flag. */
3942 	if ((sc->used_tx_bd + BNX_TX_SLACK_SPACE) < USABLE_TX_BD) {
3943 		DBRUNIF((ifp->if_flags & IFF_OACTIVE),
3944 		    aprint_debug_dev(sc->bnx_dev,
3945 		        "TX chain is open for business! Used tx_bd = %d\n",
3946 			sc->used_tx_bd));
3947 		ifp->if_flags &= ~IFF_OACTIVE;
3948 	}
3949 
3950 	sc->tx_cons = sw_tx_cons;
3951 }
3952 
3953 /****************************************************************************/
3954 /* Disables interrupt generation.                                           */
3955 /*                                                                          */
3956 /* Returns:                                                                 */
3957 /*   Nothing.                                                               */
3958 /****************************************************************************/
3959 void
3960 bnx_disable_intr(struct bnx_softc *sc)
3961 {
3962 	REG_WR(sc, BNX_PCICFG_INT_ACK_CMD, BNX_PCICFG_INT_ACK_CMD_MASK_INT);
3963 	REG_RD(sc, BNX_PCICFG_INT_ACK_CMD);
3964 }
3965 
3966 /****************************************************************************/
3967 /* Enables interrupt generation.                                            */
3968 /*                                                                          */
3969 /* Returns:                                                                 */
3970 /*   Nothing.                                                               */
3971 /****************************************************************************/
3972 void
3973 bnx_enable_intr(struct bnx_softc *sc)
3974 {
3975 	u_int32_t		val;
3976 
3977 	REG_WR(sc, BNX_PCICFG_INT_ACK_CMD, BNX_PCICFG_INT_ACK_CMD_INDEX_VALID |
3978 	    BNX_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
3979 
3980 	REG_WR(sc, BNX_PCICFG_INT_ACK_CMD, BNX_PCICFG_INT_ACK_CMD_INDEX_VALID |
3981 	    sc->last_status_idx);
3982 
3983 	val = REG_RD(sc, BNX_HC_COMMAND);
3984 	REG_WR(sc, BNX_HC_COMMAND, val | BNX_HC_COMMAND_COAL_NOW);
3985 }
3986 
3987 /****************************************************************************/
3988 /* Handles controller initialization.                                       */
3989 /*                                                                          */
3990 /****************************************************************************/
3991 int
3992 bnx_init(struct ifnet *ifp)
3993 {
3994 	struct bnx_softc	*sc = ifp->if_softc;
3995 	u_int32_t		ether_mtu;
3996 	int			s, error = 0;
3997 
3998 	DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __func__);
3999 
4000 	s = splnet();
4001 
4002 	bnx_stop(ifp, 0);
4003 
4004 	if ((error = bnx_reset(sc, BNX_DRV_MSG_CODE_RESET)) != 0) {
4005 		aprint_error("bnx: Controller reset failed!\n");
4006 		goto bnx_init_exit;
4007 	}
4008 
4009 	if ((error = bnx_chipinit(sc)) != 0) {
4010 		aprint_error("bnx: Controller initialization failed!\n");
4011 		goto bnx_init_exit;
4012 	}
4013 
4014 	if ((error = bnx_blockinit(sc)) != 0) {
4015 		aprint_error("bnx: Block initialization failed!\n");
4016 		goto bnx_init_exit;
4017 	}
4018 
4019 	/* Calculate and program the Ethernet MRU size. */
4020 	if (ifp->if_mtu <= ETHERMTU) {
4021 		ether_mtu = BNX_MAX_STD_ETHER_MTU_VLAN;
4022 		sc->mbuf_alloc_size = MCLBYTES;
4023 	} else {
4024 		ether_mtu = BNX_MAX_JUMBO_ETHER_MTU_VLAN;
4025 		sc->mbuf_alloc_size = BNX_MAX_MRU;
4026 	}
4027 
4028 
4029 	DBPRINT(sc, BNX_INFO, "%s(): setting MRU = %d\n",
4030 	    __func__, ether_mtu);
4031 
4032 	/*
4033 	 * Program the MRU and enable Jumbo frame
4034 	 * support.
4035 	 */
4036 	REG_WR(sc, BNX_EMAC_RX_MTU_SIZE, ether_mtu |
4037 		BNX_EMAC_RX_MTU_SIZE_JUMBO_ENA);
4038 
4039 	/* Calculate the RX Ethernet frame size for rx_bd's. */
4040 	sc->max_frame_size = sizeof(struct l2_fhdr) + 2 + ether_mtu + 8;
4041 
4042 	DBPRINT(sc, BNX_INFO, "%s(): mclbytes = %d, mbuf_alloc_size = %d, "
4043 	    "max_frame_size = %d\n", __func__, (int)MCLBYTES,
4044 	    sc->mbuf_alloc_size, sc->max_frame_size);
4045 
4046 	/* Program appropriate promiscuous/multicast filtering. */
4047 	bnx_set_rx_mode(sc);
4048 
4049 	/* Init RX buffer descriptor chain. */
4050 	bnx_init_rx_chain(sc);
4051 
4052 	/* Init TX buffer descriptor chain. */
4053 	bnx_init_tx_chain(sc);
4054 
4055 	/* Enable host interrupts. */
4056 	bnx_enable_intr(sc);
4057 
4058 	if ((error = ether_mediachange(ifp)) != 0)
4059 		goto bnx_init_exit;
4060 
4061 	ifp->if_flags |= IFF_RUNNING;
4062 	ifp->if_flags &= ~IFF_OACTIVE;
4063 
4064 	callout_reset(&sc->bnx_timeout, hz, bnx_tick, sc);
4065 
4066 bnx_init_exit:
4067 	DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __func__);
4068 
4069 	splx(s);
4070 
4071 	return(error);
4072 }
4073 
4074 /****************************************************************************/
4075 /* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
4076 /* memory visible to the controller.                                        */
4077 /*                                                                          */
4078 /* Returns:                                                                 */
4079 /*   0 for success, positive value for failure.                             */
4080 /****************************************************************************/
4081 int
4082 bnx_tx_encap(struct bnx_softc *sc, struct mbuf **m_head)
4083 {
4084 	bus_dmamap_t		map;
4085 	struct tx_bd		*txbd = NULL;
4086 	struct mbuf		*m0;
4087 	u_int16_t		vlan_tag = 0, flags = 0;
4088 	u_int16_t		chain_prod, prod;
4089 #ifdef BNX_DEBUG
4090 	u_int16_t		debug_prod;
4091 #endif
4092 	u_int32_t		addr, prod_bseq;
4093 	int			i, error, rc = 0;
4094 	struct m_tag		*mtag;
4095 
4096 	m0 = *m_head;
4097 
4098 	/* Transfer any checksum offload flags to the bd. */
4099 	if (m0->m_pkthdr.csum_flags) {
4100 		if (m0->m_pkthdr.csum_flags & M_CSUM_IPv4)
4101 			flags |= TX_BD_FLAGS_IP_CKSUM;
4102 		if (m0->m_pkthdr.csum_flags &
4103 		    (M_CSUM_TCPv4 | M_CSUM_UDPv4))
4104 			flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
4105 	}
4106 
4107 	/* Transfer any VLAN tags to the bd. */
4108 	mtag = VLAN_OUTPUT_TAG(&sc->bnx_ec, m0);
4109 	if (mtag != NULL) {
4110 		flags |= TX_BD_FLAGS_VLAN_TAG;
4111 		vlan_tag = VLAN_TAG_VALUE(mtag);
4112 	}
4113 
4114 	/* Map the mbuf into DMAable memory. */
4115 	prod = sc->tx_prod;
4116 	chain_prod = TX_CHAIN_IDX(prod);
4117 	map = sc->tx_mbuf_map[chain_prod];
4118 
4119 	/* Map the mbuf into our DMA address space. */
4120 	error = bus_dmamap_load_mbuf(sc->bnx_dmatag, map, m0, BUS_DMA_NOWAIT);
4121 	if (error != 0) {
4122 		aprint_error_dev(sc->bnx_dev,
4123 		    "Error mapping mbuf into TX chain!\n");
4124 		m_freem(m0);
4125 		*m_head = NULL;
4126 		return (error);
4127 	}
4128 	bus_dmamap_sync(sc->bnx_dmatag, map, 0, map->dm_mapsize,
4129 	    BUS_DMASYNC_PREWRITE);
4130         /*
4131          * The chip seems to require that at least 16 descriptors be kept
4132          * empty at all times.  Make sure we honor that.
4133          * XXX Would it be faster to assume worst case scenario for
4134          * map->dm_nsegs and do this calculation higher up?
4135          */
4136         if (map->dm_nsegs > (USABLE_TX_BD - sc->used_tx_bd - BNX_TX_SLACK_SPACE)) {
4137                 bus_dmamap_unload(sc->bnx_dmatag, map);
4138                 return (ENOBUFS);
4139         }
4140 
4141 	/* prod points to an empty tx_bd at this point. */
4142 	prod_bseq = sc->tx_prod_bseq;
4143 #ifdef BNX_DEBUG
4144 	debug_prod = chain_prod;
4145 #endif
4146 	DBPRINT(sc, BNX_INFO_SEND,
4147 		"%s(): Start: prod = 0x%04X, chain_prod = %04X, "
4148 		"prod_bseq = 0x%08X\n",
4149 		__func__, *prod, chain_prod, prod_bseq);
4150 
4151 	/*
4152 	 * Cycle through each mbuf segment that makes up
4153 	 * the outgoing frame, gathering the mapping info
4154 	 * for that segment and creating a tx_bd for the
4155 	 * mbuf.
4156 	 */
4157 	for (i = 0; i < map->dm_nsegs ; i++) {
4158 		chain_prod = TX_CHAIN_IDX(prod);
4159 		txbd = &sc->tx_bd_chain[TX_PAGE(chain_prod)][TX_IDX(chain_prod)];
4160 
4161 		addr = (u_int32_t)(map->dm_segs[i].ds_addr);
4162 		txbd->tx_bd_haddr_lo = htole32(addr);
4163 		addr = (u_int32_t)((u_int64_t)map->dm_segs[i].ds_addr >> 32);
4164 		txbd->tx_bd_haddr_hi = htole32(addr);
4165 		txbd->tx_bd_mss_nbytes = htole16(map->dm_segs[i].ds_len);
4166 		txbd->tx_bd_vlan_tag = htole16(vlan_tag);
4167 		txbd->tx_bd_flags = htole16(flags);
4168 		prod_bseq += map->dm_segs[i].ds_len;
4169 		if (i == 0)
4170 			txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_START);
4171 		prod = NEXT_TX_BD(prod);
4172 	}
4173 	/* Set the END flag on the last TX buffer descriptor. */
4174 	txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_END);
4175 
4176 	DBRUN(BNX_INFO_SEND, bnx_dump_tx_chain(sc, debug_prod, nseg));
4177 
4178 	DBPRINT(sc, BNX_INFO_SEND,
4179 		"%s(): End: prod = 0x%04X, chain_prod = %04X, "
4180 		"prod_bseq = 0x%08X\n",
4181 		__func__, prod, chain_prod, prod_bseq);
4182 
4183 	/*
4184 	 * Ensure that the mbuf pointer for this
4185 	 * transmission is placed at the array
4186 	 * index of the last descriptor in this
4187 	 * chain.  This is done because a single
4188 	 * map is used for all segments of the mbuf
4189 	 * and we don't want to unload the map before
4190 	 * all of the segments have been freed.
4191 	 */
4192 	sc->tx_mbuf_ptr[chain_prod] = m0;
4193 	sc->used_tx_bd += map->dm_nsegs;
4194 
4195 	DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
4196 	    sc->tx_hi_watermark = sc->used_tx_bd);
4197 
4198 	DBRUNIF(1, sc->tx_mbuf_alloc++);
4199 
4200 	DBRUN(BNX_VERBOSE_SEND, bnx_dump_tx_mbuf_chain(sc, chain_prod,
4201 	    map_arg.maxsegs));
4202 
4203 	/* prod points to the next free tx_bd at this point. */
4204 	sc->tx_prod = prod;
4205 	sc->tx_prod_bseq = prod_bseq;
4206 
4207 	return (rc);
4208 }
4209 
4210 /****************************************************************************/
4211 /* Main transmit routine.                                                   */
4212 /*                                                                          */
4213 /* Returns:                                                                 */
4214 /*   Nothing.                                                               */
4215 /****************************************************************************/
4216 void
4217 bnx_start(struct ifnet *ifp)
4218 {
4219 	struct bnx_softc	*sc = ifp->if_softc;
4220 	struct mbuf		*m_head = NULL;
4221 	int			count = 0;
4222 	u_int16_t		tx_prod, tx_chain_prod;
4223 
4224 	/* If there's no link or the transmit queue is empty then just exit. */
4225 	if ((ifp->if_flags & (IFF_OACTIVE|IFF_RUNNING)) != IFF_RUNNING) {
4226 		DBPRINT(sc, BNX_INFO_SEND,
4227 		    "%s(): output active or device not running.\n", __func__);
4228 		goto bnx_start_exit;
4229 	}
4230 
4231 	/* prod points to the next free tx_bd. */
4232 	tx_prod = sc->tx_prod;
4233 	tx_chain_prod = TX_CHAIN_IDX(tx_prod);
4234 
4235 	DBPRINT(sc, BNX_INFO_SEND, "%s(): Start: tx_prod = 0x%04X, "
4236 	    "tx_chain_prod = %04X, tx_prod_bseq = 0x%08X\n",
4237 	    __func__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
4238 
4239 	/*
4240 	 * Keep adding entries while there is space in the ring.  We keep
4241 	 * BNX_TX_SLACK_SPACE entries unused at all times.
4242 	 */
4243 	while (sc->used_tx_bd < USABLE_TX_BD - BNX_TX_SLACK_SPACE) {
4244 		/* Check for any frames to send. */
4245 		IFQ_POLL(&ifp->if_snd, m_head);
4246 		if (m_head == NULL)
4247 			break;
4248 
4249 		/*
4250 		 * Pack the data into the transmit ring. If we
4251 		 * don't have room, set the OACTIVE flag to wait
4252 		 * for the NIC to drain the chain.
4253 		 */
4254 		if (bnx_tx_encap(sc, &m_head)) {
4255 			ifp->if_flags |= IFF_OACTIVE;
4256 			DBPRINT(sc, BNX_INFO_SEND, "TX chain is closed for "
4257 			    "business! Total tx_bd used = %d\n",
4258 			    sc->used_tx_bd);
4259 			break;
4260 		}
4261 
4262 		IFQ_DEQUEUE(&ifp->if_snd, m_head);
4263 		count++;
4264 
4265 #if NBPFILTER > 0
4266 		/* Send a copy of the frame to any BPF listeners. */
4267 		if (ifp->if_bpf)
4268 			bpf_mtap(ifp->if_bpf, m_head);
4269 #endif
4270 	}
4271 
4272 	if (count == 0) {
4273 		/* no packets were dequeued */
4274 		DBPRINT(sc, BNX_VERBOSE_SEND,
4275 		    "%s(): No packets were dequeued\n", __func__);
4276 		goto bnx_start_exit;
4277 	}
4278 
4279 	/* Update the driver's counters. */
4280 	tx_chain_prod = TX_CHAIN_IDX(sc->tx_prod);
4281 
4282 	DBPRINT(sc, BNX_INFO_SEND, "%s(): End: tx_prod = 0x%04X, tx_chain_prod "
4283 	    "= 0x%04X, tx_prod_bseq = 0x%08X\n", __func__, tx_prod,
4284 	    tx_chain_prod, sc->tx_prod_bseq);
4285 
4286 	/* Start the transmit. */
4287 	REG_WR16(sc, MB_TX_CID_ADDR + BNX_L2CTX_TX_HOST_BIDX, sc->tx_prod);
4288 	REG_WR(sc, MB_TX_CID_ADDR + BNX_L2CTX_TX_HOST_BSEQ, sc->tx_prod_bseq);
4289 
4290 	/* Set the tx timeout. */
4291 	ifp->if_timer = BNX_TX_TIMEOUT;
4292 
4293 bnx_start_exit:
4294 	return;
4295 }
4296 
4297 /****************************************************************************/
4298 /* Handles any IOCTL calls from the operating system.                       */
4299 /*                                                                          */
4300 /* Returns:                                                                 */
4301 /*   0 for success, positive value for failure.                             */
4302 /****************************************************************************/
4303 int
4304 bnx_ioctl(struct ifnet *ifp, u_long command, void *data)
4305 {
4306 	struct bnx_softc	*sc = ifp->if_softc;
4307 	struct ifreq		*ifr = (struct ifreq *) data;
4308 	struct mii_data		*mii;
4309 	int			s, error = 0;
4310 
4311 	s = splnet();
4312 
4313 	switch (command) {
4314 	case SIOCSIFFLAGS:
4315 		if (ifp->if_flags & IFF_UP) {
4316 			if ((ifp->if_flags & IFF_RUNNING) &&
4317 			    ((ifp->if_flags ^ sc->bnx_if_flags) &
4318 			    (IFF_ALLMULTI | IFF_PROMISC)) != 0) {
4319 				bnx_set_rx_mode(sc);
4320 			} else if (!(ifp->if_flags & IFF_RUNNING))
4321 				bnx_init(ifp);
4322 
4323 		} else if (ifp->if_flags & IFF_RUNNING)
4324 			bnx_stop(ifp, 1);
4325 
4326 		sc->bnx_if_flags = ifp->if_flags;
4327 		break;
4328 
4329 	case SIOCSIFMEDIA:
4330 	case SIOCGIFMEDIA:
4331 		DBPRINT(sc, BNX_VERBOSE, "bnx_phy_flags = 0x%08X\n",
4332 		    sc->bnx_phy_flags);
4333 
4334 		if (sc->bnx_phy_flags & BNX_PHY_SERDES_FLAG)
4335 			error = ifmedia_ioctl(ifp, ifr,
4336 			    &sc->bnx_ifmedia, command);
4337 		else {
4338 			mii = &sc->bnx_mii;
4339 			error = ifmedia_ioctl(ifp, ifr,
4340 			    &mii->mii_media, command);
4341 		}
4342 		break;
4343 
4344 	default:
4345 		if ((error = ether_ioctl(ifp, command, data)) != ENETRESET)
4346 			break;
4347 
4348 		error = 0;
4349 
4350 		if (command != SIOCADDMULTI && command && SIOCDELMULTI)
4351 			;
4352 		else if (ifp->if_flags & IFF_RUNNING) {
4353 			/* reload packet filter if running */
4354 			bnx_set_rx_mode(sc);
4355 		}
4356 		break;
4357 	}
4358 
4359 	splx(s);
4360 
4361 	return (error);
4362 }
4363 
4364 /****************************************************************************/
4365 /* Transmit timeout handler.                                                */
4366 /*                                                                          */
4367 /* Returns:                                                                 */
4368 /*   Nothing.                                                               */
4369 /****************************************************************************/
4370 void
4371 bnx_watchdog(struct ifnet *ifp)
4372 {
4373 	struct bnx_softc	*sc = ifp->if_softc;
4374 
4375 	DBRUN(BNX_WARN_SEND, bnx_dump_driver_state(sc);
4376 	    bnx_dump_status_block(sc));
4377 
4378 	aprint_error_dev(sc->bnx_dev, "Watchdog timeout -- resetting!\n");
4379 
4380 	/* DBRUN(BNX_FATAL, bnx_breakpoint(sc)); */
4381 
4382 	bnx_init(ifp);
4383 
4384 	ifp->if_oerrors++;
4385 }
4386 
4387 /*
4388  * Interrupt handler.
4389  */
4390 /****************************************************************************/
4391 /* Main interrupt entry point.  Verifies that the controller generated the  */
4392 /* interrupt and then calls a separate routine for handle the various       */
4393 /* interrupt causes (PHY, TX, RX).                                          */
4394 /*                                                                          */
4395 /* Returns:                                                                 */
4396 /*   0 for success, positive value for failure.                             */
4397 /****************************************************************************/
4398 int
4399 bnx_intr(void *xsc)
4400 {
4401 	struct bnx_softc	*sc;
4402 	struct ifnet		*ifp;
4403 	u_int32_t		status_attn_bits;
4404 	const struct status_block *sblk;
4405 
4406 	sc = xsc;
4407 	if (!device_is_active(sc->bnx_dev))
4408 		return 0;
4409 
4410 	ifp = &sc->bnx_ec.ec_if;
4411 
4412 	DBRUNIF(1, sc->interrupts_generated++);
4413 
4414 	bus_dmamap_sync(sc->bnx_dmatag, sc->status_map, 0,
4415 	    sc->status_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
4416 
4417 	/*
4418 	 * If the hardware status block index
4419 	 * matches the last value read by the
4420 	 * driver and we haven't asserted our
4421 	 * interrupt then there's nothing to do.
4422 	 */
4423 	if ((sc->status_block->status_idx == sc->last_status_idx) &&
4424 	    (REG_RD(sc, BNX_PCICFG_MISC_STATUS) &
4425 	    BNX_PCICFG_MISC_STATUS_INTA_VALUE))
4426 		return (0);
4427 
4428 	/* Ack the interrupt and stop others from occuring. */
4429 	REG_WR(sc, BNX_PCICFG_INT_ACK_CMD,
4430 	    BNX_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
4431 	    BNX_PCICFG_INT_ACK_CMD_MASK_INT);
4432 
4433 	/* Keep processing data as long as there is work to do. */
4434 	for (;;) {
4435 		sblk = sc->status_block;
4436 		status_attn_bits = sblk->status_attn_bits;
4437 
4438 		DBRUNIF(DB_RANDOMTRUE(bnx_debug_unexpected_attention),
4439 		    aprint_debug("Simulating unexpected status attention bit set.");
4440 		    status_attn_bits = status_attn_bits |
4441 		    STATUS_ATTN_BITS_PARITY_ERROR);
4442 
4443 		/* Was it a link change interrupt? */
4444 		if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
4445 		    (sblk->status_attn_bits_ack &
4446 		    STATUS_ATTN_BITS_LINK_STATE))
4447 			bnx_phy_intr(sc);
4448 
4449 		/* If any other attention is asserted then the chip is toast. */
4450 		if (((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
4451 		    (sblk->status_attn_bits_ack &
4452 		    ~STATUS_ATTN_BITS_LINK_STATE))) {
4453 			DBRUN(1, sc->unexpected_attentions++);
4454 
4455 			aprint_error_dev(sc->bnx_dev,
4456 			    "Fatal attention detected: 0x%08X\n",
4457 			    sblk->status_attn_bits);
4458 
4459 			DBRUN(BNX_FATAL,
4460 			    if (bnx_debug_unexpected_attention == 0)
4461 			    bnx_breakpoint(sc));
4462 
4463 			bnx_init(ifp);
4464 			return (1);
4465 		}
4466 
4467 		/* Check for any completed RX frames. */
4468 		if (sblk->status_rx_quick_consumer_index0 !=
4469 		    sc->hw_rx_cons)
4470 			bnx_rx_intr(sc);
4471 
4472 		/* Check for any completed TX frames. */
4473 		if (sblk->status_tx_quick_consumer_index0 !=
4474 		    sc->hw_tx_cons)
4475 			bnx_tx_intr(sc);
4476 
4477 		/* Save the status block index value for use during the
4478 		 * next interrupt.
4479 		 */
4480 		sc->last_status_idx = sblk->status_idx;
4481 
4482 		/* Prevent speculative reads from getting ahead of the
4483 		 * status block.
4484 		 */
4485 		bus_space_barrier(sc->bnx_btag, sc->bnx_bhandle, 0, 0,
4486 		    BUS_SPACE_BARRIER_READ);
4487 
4488 		/* If there's no work left then exit the isr. */
4489 		if ((sblk->status_rx_quick_consumer_index0 ==
4490 		    sc->hw_rx_cons) &&
4491 		    (sblk->status_tx_quick_consumer_index0 ==
4492 		    sc->hw_tx_cons))
4493 			break;
4494 	}
4495 
4496 	bus_dmamap_sync(sc->bnx_dmatag, sc->status_map, 0,
4497 	    sc->status_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
4498 
4499 	/* Re-enable interrupts. */
4500 	REG_WR(sc, BNX_PCICFG_INT_ACK_CMD,
4501 	    BNX_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx |
4502 	    BNX_PCICFG_INT_ACK_CMD_MASK_INT);
4503 	REG_WR(sc, BNX_PCICFG_INT_ACK_CMD,
4504 	    BNX_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
4505 
4506 	/* Handle any frames that arrived while handling the interrupt. */
4507 	if (!IFQ_IS_EMPTY(&ifp->if_snd))
4508 		bnx_start(ifp);
4509 
4510 	return (1);
4511 }
4512 
4513 /****************************************************************************/
4514 /* Programs the various packet receive modes (broadcast and multicast).     */
4515 /*                                                                          */
4516 /* Returns:                                                                 */
4517 /*   Nothing.                                                               */
4518 /****************************************************************************/
4519 void
4520 bnx_set_rx_mode(struct bnx_softc *sc)
4521 {
4522 	struct ethercom		*ec = &sc->bnx_ec;
4523 	struct ifnet		*ifp = &ec->ec_if;
4524 	struct ether_multi	*enm;
4525 	struct ether_multistep	step;
4526 	u_int32_t		hashes[NUM_MC_HASH_REGISTERS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
4527 	u_int32_t		rx_mode, sort_mode;
4528 	int			h, i;
4529 
4530 	/* Initialize receive mode default settings. */
4531 	rx_mode = sc->rx_mode & ~(BNX_EMAC_RX_MODE_PROMISCUOUS |
4532 	    BNX_EMAC_RX_MODE_KEEP_VLAN_TAG);
4533 	sort_mode = 1 | BNX_RPM_SORT_USER0_BC_EN;
4534 
4535 	/*
4536 	 * ASF/IPMI/UMP firmware requires that VLAN tag stripping
4537 	 * be enbled.
4538 	 */
4539 	if (!(sc->bnx_flags & BNX_MFW_ENABLE_FLAG))
4540 		rx_mode |= BNX_EMAC_RX_MODE_KEEP_VLAN_TAG;
4541 
4542 	/*
4543 	 * Check for promiscuous, all multicast, or selected
4544 	 * multicast address filtering.
4545 	 */
4546 	if (ifp->if_flags & IFF_PROMISC) {
4547 		DBPRINT(sc, BNX_INFO, "Enabling promiscuous mode.\n");
4548 
4549 		/* Enable promiscuous mode. */
4550 		rx_mode |= BNX_EMAC_RX_MODE_PROMISCUOUS;
4551 		sort_mode |= BNX_RPM_SORT_USER0_PROM_EN;
4552 	} else if (ifp->if_flags & IFF_ALLMULTI) {
4553 allmulti:
4554 		DBPRINT(sc, BNX_INFO, "Enabling all multicast mode.\n");
4555 
4556 		/* Enable all multicast addresses. */
4557 		for (i = 0; i < NUM_MC_HASH_REGISTERS; i++)
4558 			REG_WR(sc, BNX_EMAC_MULTICAST_HASH0 + (i * 4),
4559 			    0xffffffff);
4560 		sort_mode |= BNX_RPM_SORT_USER0_MC_EN;
4561 	} else {
4562 		/* Accept one or more multicast(s). */
4563 		DBPRINT(sc, BNX_INFO, "Enabling selective multicast mode.\n");
4564 
4565 		ETHER_FIRST_MULTI(step, ec, enm);
4566 		while (enm != NULL) {
4567 			if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
4568 			    ETHER_ADDR_LEN)) {
4569 				ifp->if_flags |= IFF_ALLMULTI;
4570 				goto allmulti;
4571 			}
4572 			h = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN) &
4573 			    0xFF;
4574 			hashes[(h & 0xE0) >> 5] |= 1 << (h & 0x1F);
4575 			ETHER_NEXT_MULTI(step, enm);
4576 		}
4577 
4578 		for (i = 0; i < NUM_MC_HASH_REGISTERS; i++)
4579 			REG_WR(sc, BNX_EMAC_MULTICAST_HASH0 + (i * 4),
4580 			    hashes[i]);
4581 
4582 		sort_mode |= BNX_RPM_SORT_USER0_MC_HSH_EN;
4583 	}
4584 
4585 	/* Only make changes if the recive mode has actually changed. */
4586 	if (rx_mode != sc->rx_mode) {
4587 		DBPRINT(sc, BNX_VERBOSE, "Enabling new receive mode: 0x%08X\n",
4588 		    rx_mode);
4589 
4590 		sc->rx_mode = rx_mode;
4591 		REG_WR(sc, BNX_EMAC_RX_MODE, rx_mode);
4592 	}
4593 
4594 	/* Disable and clear the exisitng sort before enabling a new sort. */
4595 	REG_WR(sc, BNX_RPM_SORT_USER0, 0x0);
4596 	REG_WR(sc, BNX_RPM_SORT_USER0, sort_mode);
4597 	REG_WR(sc, BNX_RPM_SORT_USER0, sort_mode | BNX_RPM_SORT_USER0_ENA);
4598 }
4599 
4600 /****************************************************************************/
4601 /* Called periodically to updates statistics from the controllers           */
4602 /* statistics block.                                                        */
4603 /*                                                                          */
4604 /* Returns:                                                                 */
4605 /*   Nothing.                                                               */
4606 /****************************************************************************/
4607 void
4608 bnx_stats_update(struct bnx_softc *sc)
4609 {
4610 	struct ifnet		*ifp = &sc->bnx_ec.ec_if;
4611 	struct statistics_block	*stats;
4612 
4613 	DBPRINT(sc, BNX_EXCESSIVE, "Entering %s()\n", __func__);
4614 	bus_dmamap_sync(sc->bnx_dmatag, sc->status_map, 0, BNX_STATUS_BLK_SZ,
4615 	    BUS_DMASYNC_POSTREAD);
4616 
4617 	stats = (struct statistics_block *)sc->stats_block;
4618 
4619 	/*
4620 	 * Update the interface statistics from the
4621 	 * hardware statistics.
4622 	 */
4623 	ifp->if_collisions = (u_long)stats->stat_EtherStatsCollisions;
4624 
4625 	ifp->if_ierrors = (u_long)stats->stat_EtherStatsUndersizePkts +
4626 	    (u_long)stats->stat_EtherStatsOverrsizePkts +
4627 	    (u_long)stats->stat_IfInMBUFDiscards +
4628 	    (u_long)stats->stat_Dot3StatsAlignmentErrors +
4629 	    (u_long)stats->stat_Dot3StatsFCSErrors;
4630 
4631 	ifp->if_oerrors = (u_long)
4632 	    stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
4633 	    (u_long)stats->stat_Dot3StatsExcessiveCollisions +
4634 	    (u_long)stats->stat_Dot3StatsLateCollisions;
4635 
4636 	/*
4637 	 * Certain controllers don't report
4638 	 * carrier sense errors correctly.
4639 	 * See errata E11_5708CA0_1165.
4640 	 */
4641 	if (!(BNX_CHIP_NUM(sc) == BNX_CHIP_NUM_5706) &&
4642 	    !(BNX_CHIP_ID(sc) == BNX_CHIP_ID_5708_A0))
4643 		ifp->if_oerrors += (u_long) stats->stat_Dot3StatsCarrierSenseErrors;
4644 
4645 	/*
4646 	 * Update the sysctl statistics from the
4647 	 * hardware statistics.
4648 	 */
4649 	sc->stat_IfHCInOctets = ((u_int64_t)stats->stat_IfHCInOctets_hi << 32) +
4650 	    (u_int64_t) stats->stat_IfHCInOctets_lo;
4651 
4652 	sc->stat_IfHCInBadOctets =
4653 	    ((u_int64_t) stats->stat_IfHCInBadOctets_hi << 32) +
4654 	    (u_int64_t) stats->stat_IfHCInBadOctets_lo;
4655 
4656 	sc->stat_IfHCOutOctets =
4657 	    ((u_int64_t) stats->stat_IfHCOutOctets_hi << 32) +
4658 	    (u_int64_t) stats->stat_IfHCOutOctets_lo;
4659 
4660 	sc->stat_IfHCOutBadOctets =
4661 	    ((u_int64_t) stats->stat_IfHCOutBadOctets_hi << 32) +
4662 	    (u_int64_t) stats->stat_IfHCOutBadOctets_lo;
4663 
4664 	sc->stat_IfHCInUcastPkts =
4665 	    ((u_int64_t) stats->stat_IfHCInUcastPkts_hi << 32) +
4666 	    (u_int64_t) stats->stat_IfHCInUcastPkts_lo;
4667 
4668 	sc->stat_IfHCInMulticastPkts =
4669 	    ((u_int64_t) stats->stat_IfHCInMulticastPkts_hi << 32) +
4670 	    (u_int64_t) stats->stat_IfHCInMulticastPkts_lo;
4671 
4672 	sc->stat_IfHCInBroadcastPkts =
4673 	    ((u_int64_t) stats->stat_IfHCInBroadcastPkts_hi << 32) +
4674 	    (u_int64_t) stats->stat_IfHCInBroadcastPkts_lo;
4675 
4676 	sc->stat_IfHCOutUcastPkts =
4677 	   ((u_int64_t) stats->stat_IfHCOutUcastPkts_hi << 32) +
4678 	    (u_int64_t) stats->stat_IfHCOutUcastPkts_lo;
4679 
4680 	sc->stat_IfHCOutMulticastPkts =
4681 	    ((u_int64_t) stats->stat_IfHCOutMulticastPkts_hi << 32) +
4682 	    (u_int64_t) stats->stat_IfHCOutMulticastPkts_lo;
4683 
4684 	sc->stat_IfHCOutBroadcastPkts =
4685 	    ((u_int64_t) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
4686 	    (u_int64_t) stats->stat_IfHCOutBroadcastPkts_lo;
4687 
4688 	sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors =
4689 	    stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
4690 
4691 	sc->stat_Dot3StatsCarrierSenseErrors =
4692 	    stats->stat_Dot3StatsCarrierSenseErrors;
4693 
4694 	sc->stat_Dot3StatsFCSErrors = stats->stat_Dot3StatsFCSErrors;
4695 
4696 	sc->stat_Dot3StatsAlignmentErrors =
4697 	    stats->stat_Dot3StatsAlignmentErrors;
4698 
4699 	sc->stat_Dot3StatsSingleCollisionFrames =
4700 	    stats->stat_Dot3StatsSingleCollisionFrames;
4701 
4702 	sc->stat_Dot3StatsMultipleCollisionFrames =
4703 	    stats->stat_Dot3StatsMultipleCollisionFrames;
4704 
4705 	sc->stat_Dot3StatsDeferredTransmissions =
4706 	    stats->stat_Dot3StatsDeferredTransmissions;
4707 
4708 	sc->stat_Dot3StatsExcessiveCollisions =
4709 	    stats->stat_Dot3StatsExcessiveCollisions;
4710 
4711 	sc->stat_Dot3StatsLateCollisions = stats->stat_Dot3StatsLateCollisions;
4712 
4713 	sc->stat_EtherStatsCollisions = stats->stat_EtherStatsCollisions;
4714 
4715 	sc->stat_EtherStatsFragments = stats->stat_EtherStatsFragments;
4716 
4717 	sc->stat_EtherStatsJabbers = stats->stat_EtherStatsJabbers;
4718 
4719 	sc->stat_EtherStatsUndersizePkts = stats->stat_EtherStatsUndersizePkts;
4720 
4721 	sc->stat_EtherStatsOverrsizePkts = stats->stat_EtherStatsOverrsizePkts;
4722 
4723 	sc->stat_EtherStatsPktsRx64Octets =
4724 	    stats->stat_EtherStatsPktsRx64Octets;
4725 
4726 	sc->stat_EtherStatsPktsRx65Octetsto127Octets =
4727 	    stats->stat_EtherStatsPktsRx65Octetsto127Octets;
4728 
4729 	sc->stat_EtherStatsPktsRx128Octetsto255Octets =
4730 	    stats->stat_EtherStatsPktsRx128Octetsto255Octets;
4731 
4732 	sc->stat_EtherStatsPktsRx256Octetsto511Octets =
4733 	    stats->stat_EtherStatsPktsRx256Octetsto511Octets;
4734 
4735 	sc->stat_EtherStatsPktsRx512Octetsto1023Octets =
4736 	    stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
4737 
4738 	sc->stat_EtherStatsPktsRx1024Octetsto1522Octets =
4739 	    stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
4740 
4741 	sc->stat_EtherStatsPktsRx1523Octetsto9022Octets =
4742 	    stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
4743 
4744 	sc->stat_EtherStatsPktsTx64Octets =
4745 	    stats->stat_EtherStatsPktsTx64Octets;
4746 
4747 	sc->stat_EtherStatsPktsTx65Octetsto127Octets =
4748 	    stats->stat_EtherStatsPktsTx65Octetsto127Octets;
4749 
4750 	sc->stat_EtherStatsPktsTx128Octetsto255Octets =
4751 	    stats->stat_EtherStatsPktsTx128Octetsto255Octets;
4752 
4753 	sc->stat_EtherStatsPktsTx256Octetsto511Octets =
4754 	    stats->stat_EtherStatsPktsTx256Octetsto511Octets;
4755 
4756 	sc->stat_EtherStatsPktsTx512Octetsto1023Octets =
4757 	    stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
4758 
4759 	sc->stat_EtherStatsPktsTx1024Octetsto1522Octets =
4760 	    stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
4761 
4762 	sc->stat_EtherStatsPktsTx1523Octetsto9022Octets =
4763 	    stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
4764 
4765 	sc->stat_XonPauseFramesReceived = stats->stat_XonPauseFramesReceived;
4766 
4767 	sc->stat_XoffPauseFramesReceived = stats->stat_XoffPauseFramesReceived;
4768 
4769 	sc->stat_OutXonSent = stats->stat_OutXonSent;
4770 
4771 	sc->stat_OutXoffSent = stats->stat_OutXoffSent;
4772 
4773 	sc->stat_FlowControlDone = stats->stat_FlowControlDone;
4774 
4775 	sc->stat_MacControlFramesReceived =
4776 	    stats->stat_MacControlFramesReceived;
4777 
4778 	sc->stat_XoffStateEntered = stats->stat_XoffStateEntered;
4779 
4780 	sc->stat_IfInFramesL2FilterDiscards =
4781 	    stats->stat_IfInFramesL2FilterDiscards;
4782 
4783 	sc->stat_IfInRuleCheckerDiscards = stats->stat_IfInRuleCheckerDiscards;
4784 
4785 	sc->stat_IfInFTQDiscards = stats->stat_IfInFTQDiscards;
4786 
4787 	sc->stat_IfInMBUFDiscards = stats->stat_IfInMBUFDiscards;
4788 
4789 	sc->stat_IfInRuleCheckerP4Hit = stats->stat_IfInRuleCheckerP4Hit;
4790 
4791 	sc->stat_CatchupInRuleCheckerDiscards =
4792 	    stats->stat_CatchupInRuleCheckerDiscards;
4793 
4794 	sc->stat_CatchupInFTQDiscards = stats->stat_CatchupInFTQDiscards;
4795 
4796 	sc->stat_CatchupInMBUFDiscards = stats->stat_CatchupInMBUFDiscards;
4797 
4798 	sc->stat_CatchupInRuleCheckerP4Hit =
4799 	    stats->stat_CatchupInRuleCheckerP4Hit;
4800 
4801 	DBPRINT(sc, BNX_EXCESSIVE, "Exiting %s()\n", __func__);
4802 }
4803 
4804 void
4805 bnx_tick(void *xsc)
4806 {
4807 	struct bnx_softc	*sc = xsc;
4808 	struct mii_data		*mii;
4809 	u_int32_t		msg;
4810 	u_int16_t		prod, chain_prod;
4811 	u_int32_t		prod_bseq;
4812 	int s = splnet();
4813 
4814 	/* Tell the firmware that the driver is still running. */
4815 #ifdef BNX_DEBUG
4816 	msg = (u_int32_t)BNX_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE;
4817 #else
4818 	msg = (u_int32_t)++sc->bnx_fw_drv_pulse_wr_seq;
4819 #endif
4820 	REG_WR_IND(sc, sc->bnx_shmem_base + BNX_DRV_PULSE_MB, msg);
4821 
4822 	/* Update the statistics from the hardware statistics block. */
4823 	bnx_stats_update(sc);
4824 
4825 	/* Schedule the next tick. */
4826 	callout_reset(&sc->bnx_timeout, hz, bnx_tick, sc);
4827 
4828 	/* DRC - ToDo: Add SerDes support and check SerDes link here. */
4829 
4830 	mii = &sc->bnx_mii;
4831 	mii_tick(mii);
4832 
4833 	/* try to get more RX buffers, just in case */
4834 	prod = sc->rx_prod;
4835 	prod_bseq = sc->rx_prod_bseq;
4836 	chain_prod = RX_CHAIN_IDX(prod);
4837 	bnx_get_buf(sc, NULL, &prod, &chain_prod, &prod_bseq);
4838 	sc->rx_prod = prod;
4839 	sc->rx_prod_bseq = prod_bseq;
4840 	splx(s);
4841 	return;
4842 }
4843 
4844 /****************************************************************************/
4845 /* BNX Debug Routines                                                       */
4846 /****************************************************************************/
4847 #ifdef BNX_DEBUG
4848 
4849 /****************************************************************************/
4850 /* Prints out information about an mbuf.                                    */
4851 /*                                                                          */
4852 /* Returns:                                                                 */
4853 /*   Nothing.                                                               */
4854 /****************************************************************************/
4855 void
4856 bnx_dump_mbuf(struct bnx_softc *sc, struct mbuf *m)
4857 {
4858 	struct mbuf		*mp = m;
4859 
4860 	if (m == NULL) {
4861 		/* Index out of range. */
4862 		aprint_error("mbuf ptr is null!\n");
4863 		return;
4864 	}
4865 
4866 	while (mp) {
4867 		aprint_debug("mbuf: vaddr = %p, m_len = %d, m_flags = ",
4868 		    mp, mp->m_len);
4869 
4870 		if (mp->m_flags & M_EXT)
4871 			aprint_debug("M_EXT ");
4872 		if (mp->m_flags & M_PKTHDR)
4873 			aprint_debug("M_PKTHDR ");
4874 		aprint_debug("\n");
4875 
4876 		if (mp->m_flags & M_EXT)
4877 			aprint_debug("- m_ext: vaddr = %p, ext_size = 0x%04zX\n",
4878 			    mp, mp->m_ext.ext_size);
4879 
4880 		mp = mp->m_next;
4881 	}
4882 }
4883 
4884 /****************************************************************************/
4885 /* Prints out the mbufs in the TX mbuf chain.                               */
4886 /*                                                                          */
4887 /* Returns:                                                                 */
4888 /*   Nothing.                                                               */
4889 /****************************************************************************/
4890 void
4891 bnx_dump_tx_mbuf_chain(struct bnx_softc *sc, int chain_prod, int count)
4892 {
4893 	struct mbuf		*m;
4894 	int			i;
4895 
4896 	BNX_PRINTF(sc,
4897 	    "----------------------------"
4898 	    "  tx mbuf data  "
4899 	    "----------------------------\n");
4900 
4901 	for (i = 0; i < count; i++) {
4902 	 	m = sc->tx_mbuf_ptr[chain_prod];
4903 		BNX_PRINTF(sc, "txmbuf[%d]\n", chain_prod);
4904 		bnx_dump_mbuf(sc, m);
4905 		chain_prod = TX_CHAIN_IDX(NEXT_TX_BD(chain_prod));
4906 	}
4907 
4908 	BNX_PRINTF(sc,
4909 	    "--------------------------------------------"
4910 	    "----------------------------\n");
4911 }
4912 
4913 /*
4914  * This routine prints the RX mbuf chain.
4915  */
4916 void
4917 bnx_dump_rx_mbuf_chain(struct bnx_softc *sc, int chain_prod, int count)
4918 {
4919 	struct mbuf		*m;
4920 	int			i;
4921 
4922 	BNX_PRINTF(sc,
4923 	    "----------------------------"
4924 	    "  rx mbuf data  "
4925 	    "----------------------------\n");
4926 
4927 	for (i = 0; i < count; i++) {
4928 	 	m = sc->rx_mbuf_ptr[chain_prod];
4929 		BNX_PRINTF(sc, "rxmbuf[0x%04X]\n", chain_prod);
4930 		bnx_dump_mbuf(sc, m);
4931 		chain_prod = RX_CHAIN_IDX(NEXT_RX_BD(chain_prod));
4932 	}
4933 
4934 
4935 	BNX_PRINTF(sc,
4936 	    "--------------------------------------------"
4937 	    "----------------------------\n");
4938 }
4939 
4940 void
4941 bnx_dump_txbd(struct bnx_softc *sc, int idx, struct tx_bd *txbd)
4942 {
4943 	if (idx > MAX_TX_BD)
4944 		/* Index out of range. */
4945 		BNX_PRINTF(sc, "tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
4946 	else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
4947 		/* TX Chain page pointer. */
4948 		BNX_PRINTF(sc, "tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain "
4949 		    "page pointer\n", idx, txbd->tx_bd_haddr_hi,
4950 		    txbd->tx_bd_haddr_lo);
4951 	else
4952 		/* Normal tx_bd entry. */
4953 		BNX_PRINTF(sc, "tx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = "
4954 		    "0x%08X, vlan tag = 0x%4X, flags = 0x%08X\n", idx,
4955 		    txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
4956 		    txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag,
4957 		    txbd->tx_bd_flags);
4958 }
4959 
4960 void
4961 bnx_dump_rxbd(struct bnx_softc *sc, int idx, struct rx_bd *rxbd)
4962 {
4963 	if (idx > MAX_RX_BD)
4964 		/* Index out of range. */
4965 		BNX_PRINTF(sc, "rx_bd[0x%04X]: Invalid rx_bd index!\n", idx);
4966 	else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
4967 		/* TX Chain page pointer. */
4968 		BNX_PRINTF(sc, "rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
4969 		    "pointer\n", idx, rxbd->rx_bd_haddr_hi,
4970 		    rxbd->rx_bd_haddr_lo);
4971 	else
4972 		/* Normal tx_bd entry. */
4973 		BNX_PRINTF(sc, "rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = "
4974 		    "0x%08X, flags = 0x%08X\n", idx,
4975 			rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo,
4976 			rxbd->rx_bd_len, rxbd->rx_bd_flags);
4977 }
4978 
4979 void
4980 bnx_dump_l2fhdr(struct bnx_softc *sc, int idx, struct l2_fhdr *l2fhdr)
4981 {
4982 	BNX_PRINTF(sc, "l2_fhdr[0x%04X]: status = 0x%08X, "
4983 	    "pkt_len = 0x%04X, vlan = 0x%04x, ip_xsum = 0x%04X, "
4984 	    "tcp_udp_xsum = 0x%04X\n", idx,
4985 	    l2fhdr->l2_fhdr_status, l2fhdr->l2_fhdr_pkt_len,
4986 	    l2fhdr->l2_fhdr_vlan_tag, l2fhdr->l2_fhdr_ip_xsum,
4987 	    l2fhdr->l2_fhdr_tcp_udp_xsum);
4988 }
4989 
4990 /*
4991  * This routine prints the TX chain.
4992  */
4993 void
4994 bnx_dump_tx_chain(struct bnx_softc *sc, int tx_prod, int count)
4995 {
4996 	struct tx_bd		*txbd;
4997 	int			i;
4998 
4999 	/* First some info about the tx_bd chain structure. */
5000 	BNX_PRINTF(sc,
5001 	    "----------------------------"
5002 	    "  tx_bd  chain  "
5003 	    "----------------------------\n");
5004 
5005 	BNX_PRINTF(sc,
5006 	    "page size      = 0x%08X, tx chain pages        = 0x%08X\n",
5007 	    (u_int32_t)BCM_PAGE_SIZE, (u_int32_t) TX_PAGES);
5008 
5009 	BNX_PRINTF(sc,
5010 	    "tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
5011 	    (u_int32_t)TOTAL_TX_BD_PER_PAGE, (u_int32_t)USABLE_TX_BD_PER_PAGE);
5012 
5013 	BNX_PRINTF(sc, "total tx_bd    = 0x%08X\n", (u_int32_t)TOTAL_TX_BD);
5014 
5015 	BNX_PRINTF(sc, ""
5016 	    "-----------------------------"
5017 	    "   tx_bd data   "
5018 	    "-----------------------------\n");
5019 
5020 	/* Now print out the tx_bd's themselves. */
5021 	for (i = 0; i < count; i++) {
5022 	 	txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
5023 		bnx_dump_txbd(sc, tx_prod, txbd);
5024 		tx_prod = TX_CHAIN_IDX(NEXT_TX_BD(tx_prod));
5025 	}
5026 
5027 	BNX_PRINTF(sc,
5028 	    "-----------------------------"
5029 	    "--------------"
5030 	    "-----------------------------\n");
5031 }
5032 
5033 /*
5034  * This routine prints the RX chain.
5035  */
5036 void
5037 bnx_dump_rx_chain(struct bnx_softc *sc, int rx_prod, int count)
5038 {
5039 	struct rx_bd		*rxbd;
5040 	int			i;
5041 
5042 	/* First some info about the tx_bd chain structure. */
5043 	BNX_PRINTF(sc,
5044 	    "----------------------------"
5045 	    "  rx_bd  chain  "
5046 	    "----------------------------\n");
5047 
5048 	BNX_PRINTF(sc, "----- RX_BD Chain -----\n");
5049 
5050 	BNX_PRINTF(sc,
5051 	    "page size      = 0x%08X, rx chain pages        = 0x%08X\n",
5052 	    (u_int32_t)BCM_PAGE_SIZE, (u_int32_t)RX_PAGES);
5053 
5054 	BNX_PRINTF(sc,
5055 	    "rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
5056 	    (u_int32_t)TOTAL_RX_BD_PER_PAGE, (u_int32_t)USABLE_RX_BD_PER_PAGE);
5057 
5058 	BNX_PRINTF(sc, "total rx_bd    = 0x%08X\n", (u_int32_t)TOTAL_RX_BD);
5059 
5060 	BNX_PRINTF(sc,
5061 	    "----------------------------"
5062 	    "   rx_bd data   "
5063 	    "----------------------------\n");
5064 
5065 	/* Now print out the rx_bd's themselves. */
5066 	for (i = 0; i < count; i++) {
5067 		rxbd = &sc->rx_bd_chain[RX_PAGE(rx_prod)][RX_IDX(rx_prod)];
5068 		bnx_dump_rxbd(sc, rx_prod, rxbd);
5069 		rx_prod = RX_CHAIN_IDX(NEXT_RX_BD(rx_prod));
5070 	}
5071 
5072 	BNX_PRINTF(sc,
5073 	    "----------------------------"
5074 	    "--------------"
5075 	    "----------------------------\n");
5076 }
5077 
5078 /*
5079  * This routine prints the status block.
5080  */
5081 void
5082 bnx_dump_status_block(struct bnx_softc *sc)
5083 {
5084 	struct status_block	*sblk;
5085 	bus_dmamap_sync(sc->bnx_dmatag, sc->status_map, 0, BNX_STATUS_BLK_SZ,
5086 	    BUS_DMASYNC_POSTREAD);
5087 
5088 	sblk = sc->status_block;
5089 
5090    	BNX_PRINTF(sc, "----------------------------- Status Block "
5091 	    "-----------------------------\n");
5092 
5093 	BNX_PRINTF(sc,
5094 	    "attn_bits  = 0x%08X, attn_bits_ack = 0x%08X, index = 0x%04X\n",
5095 	    sblk->status_attn_bits, sblk->status_attn_bits_ack,
5096 	    sblk->status_idx);
5097 
5098 	BNX_PRINTF(sc, "rx_cons0   = 0x%08X, tx_cons0      = 0x%08X\n",
5099 	    sblk->status_rx_quick_consumer_index0,
5100 	    sblk->status_tx_quick_consumer_index0);
5101 
5102 	BNX_PRINTF(sc, "status_idx = 0x%04X\n", sblk->status_idx);
5103 
5104 	/* Theses indices are not used for normal L2 drivers. */
5105 	if (sblk->status_rx_quick_consumer_index1 ||
5106 		sblk->status_tx_quick_consumer_index1)
5107 		BNX_PRINTF(sc, "rx_cons1  = 0x%08X, tx_cons1      = 0x%08X\n",
5108 		    sblk->status_rx_quick_consumer_index1,
5109 		    sblk->status_tx_quick_consumer_index1);
5110 
5111 	if (sblk->status_rx_quick_consumer_index2 ||
5112 		sblk->status_tx_quick_consumer_index2)
5113 		BNX_PRINTF(sc, "rx_cons2  = 0x%08X, tx_cons2      = 0x%08X\n",
5114 		    sblk->status_rx_quick_consumer_index2,
5115 		    sblk->status_tx_quick_consumer_index2);
5116 
5117 	if (sblk->status_rx_quick_consumer_index3 ||
5118 		sblk->status_tx_quick_consumer_index3)
5119 		BNX_PRINTF(sc, "rx_cons3  = 0x%08X, tx_cons3      = 0x%08X\n",
5120 		    sblk->status_rx_quick_consumer_index3,
5121 		    sblk->status_tx_quick_consumer_index3);
5122 
5123 	if (sblk->status_rx_quick_consumer_index4 ||
5124 		sblk->status_rx_quick_consumer_index5)
5125 		BNX_PRINTF(sc, "rx_cons4  = 0x%08X, rx_cons5      = 0x%08X\n",
5126 		    sblk->status_rx_quick_consumer_index4,
5127 		    sblk->status_rx_quick_consumer_index5);
5128 
5129 	if (sblk->status_rx_quick_consumer_index6 ||
5130 		sblk->status_rx_quick_consumer_index7)
5131 		BNX_PRINTF(sc, "rx_cons6  = 0x%08X, rx_cons7      = 0x%08X\n",
5132 		    sblk->status_rx_quick_consumer_index6,
5133 		    sblk->status_rx_quick_consumer_index7);
5134 
5135 	if (sblk->status_rx_quick_consumer_index8 ||
5136 		sblk->status_rx_quick_consumer_index9)
5137 		BNX_PRINTF(sc, "rx_cons8  = 0x%08X, rx_cons9      = 0x%08X\n",
5138 		    sblk->status_rx_quick_consumer_index8,
5139 		    sblk->status_rx_quick_consumer_index9);
5140 
5141 	if (sblk->status_rx_quick_consumer_index10 ||
5142 		sblk->status_rx_quick_consumer_index11)
5143 		BNX_PRINTF(sc, "rx_cons10 = 0x%08X, rx_cons11     = 0x%08X\n",
5144 		    sblk->status_rx_quick_consumer_index10,
5145 		    sblk->status_rx_quick_consumer_index11);
5146 
5147 	if (sblk->status_rx_quick_consumer_index12 ||
5148 		sblk->status_rx_quick_consumer_index13)
5149 		BNX_PRINTF(sc, "rx_cons12 = 0x%08X, rx_cons13     = 0x%08X\n",
5150 		    sblk->status_rx_quick_consumer_index12,
5151 		    sblk->status_rx_quick_consumer_index13);
5152 
5153 	if (sblk->status_rx_quick_consumer_index14 ||
5154 		sblk->status_rx_quick_consumer_index15)
5155 		BNX_PRINTF(sc, "rx_cons14 = 0x%08X, rx_cons15     = 0x%08X\n",
5156 		    sblk->status_rx_quick_consumer_index14,
5157 		    sblk->status_rx_quick_consumer_index15);
5158 
5159 	if (sblk->status_completion_producer_index ||
5160 		sblk->status_cmd_consumer_index)
5161 		BNX_PRINTF(sc, "com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
5162 		    sblk->status_completion_producer_index,
5163 		    sblk->status_cmd_consumer_index);
5164 
5165 	BNX_PRINTF(sc, "-------------------------------------------"
5166 	    "-----------------------------\n");
5167 }
5168 
5169 /*
5170  * This routine prints the statistics block.
5171  */
5172 void
5173 bnx_dump_stats_block(struct bnx_softc *sc)
5174 {
5175 	struct statistics_block	*sblk;
5176 	bus_dmamap_sync(sc->bnx_dmatag, sc->status_map, 0, BNX_STATUS_BLK_SZ,
5177 	    BUS_DMASYNC_POSTREAD);
5178 
5179 	sblk = sc->stats_block;
5180 
5181 	BNX_PRINTF(sc, ""
5182 	    "-----------------------------"
5183 	    " Stats  Block "
5184 	    "-----------------------------\n");
5185 
5186 	BNX_PRINTF(sc, "IfHcInOctets         = 0x%08X:%08X, "
5187 	    "IfHcInBadOctets      = 0x%08X:%08X\n",
5188 	    sblk->stat_IfHCInOctets_hi, sblk->stat_IfHCInOctets_lo,
5189 	    sblk->stat_IfHCInBadOctets_hi, sblk->stat_IfHCInBadOctets_lo);
5190 
5191 	BNX_PRINTF(sc, "IfHcOutOctets        = 0x%08X:%08X, "
5192 	    "IfHcOutBadOctets     = 0x%08X:%08X\n",
5193 	    sblk->stat_IfHCOutOctets_hi, sblk->stat_IfHCOutOctets_lo,
5194 	    sblk->stat_IfHCOutBadOctets_hi, sblk->stat_IfHCOutBadOctets_lo);
5195 
5196 	BNX_PRINTF(sc, "IfHcInUcastPkts      = 0x%08X:%08X, "
5197 	    "IfHcInMulticastPkts  = 0x%08X:%08X\n",
5198 	    sblk->stat_IfHCInUcastPkts_hi, sblk->stat_IfHCInUcastPkts_lo,
5199 	    sblk->stat_IfHCInMulticastPkts_hi,
5200 	    sblk->stat_IfHCInMulticastPkts_lo);
5201 
5202 	BNX_PRINTF(sc, "IfHcInBroadcastPkts  = 0x%08X:%08X, "
5203 	    "IfHcOutUcastPkts     = 0x%08X:%08X\n",
5204 	    sblk->stat_IfHCInBroadcastPkts_hi,
5205 	    sblk->stat_IfHCInBroadcastPkts_lo,
5206 	    sblk->stat_IfHCOutUcastPkts_hi,
5207 	    sblk->stat_IfHCOutUcastPkts_lo);
5208 
5209 	BNX_PRINTF(sc, "IfHcOutMulticastPkts = 0x%08X:%08X, "
5210 	    "IfHcOutBroadcastPkts = 0x%08X:%08X\n",
5211 	    sblk->stat_IfHCOutMulticastPkts_hi,
5212 	    sblk->stat_IfHCOutMulticastPkts_lo,
5213 	    sblk->stat_IfHCOutBroadcastPkts_hi,
5214 	    sblk->stat_IfHCOutBroadcastPkts_lo);
5215 
5216 	if (sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors)
5217 		BNX_PRINTF(sc, "0x%08X : "
5218 		    "emac_tx_stat_dot3statsinternalmactransmiterrors\n",
5219 		    sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
5220 
5221 	if (sblk->stat_Dot3StatsCarrierSenseErrors)
5222 		BNX_PRINTF(sc, "0x%08X : Dot3StatsCarrierSenseErrors\n",
5223 		    sblk->stat_Dot3StatsCarrierSenseErrors);
5224 
5225 	if (sblk->stat_Dot3StatsFCSErrors)
5226 		BNX_PRINTF(sc, "0x%08X : Dot3StatsFCSErrors\n",
5227 		    sblk->stat_Dot3StatsFCSErrors);
5228 
5229 	if (sblk->stat_Dot3StatsAlignmentErrors)
5230 		BNX_PRINTF(sc, "0x%08X : Dot3StatsAlignmentErrors\n",
5231 		    sblk->stat_Dot3StatsAlignmentErrors);
5232 
5233 	if (sblk->stat_Dot3StatsSingleCollisionFrames)
5234 		BNX_PRINTF(sc, "0x%08X : Dot3StatsSingleCollisionFrames\n",
5235 		    sblk->stat_Dot3StatsSingleCollisionFrames);
5236 
5237 	if (sblk->stat_Dot3StatsMultipleCollisionFrames)
5238 		BNX_PRINTF(sc, "0x%08X : Dot3StatsMultipleCollisionFrames\n",
5239 		    sblk->stat_Dot3StatsMultipleCollisionFrames);
5240 
5241 	if (sblk->stat_Dot3StatsDeferredTransmissions)
5242 		BNX_PRINTF(sc, "0x%08X : Dot3StatsDeferredTransmissions\n",
5243 		    sblk->stat_Dot3StatsDeferredTransmissions);
5244 
5245 	if (sblk->stat_Dot3StatsExcessiveCollisions)
5246 		BNX_PRINTF(sc, "0x%08X : Dot3StatsExcessiveCollisions\n",
5247 		    sblk->stat_Dot3StatsExcessiveCollisions);
5248 
5249 	if (sblk->stat_Dot3StatsLateCollisions)
5250 		BNX_PRINTF(sc, "0x%08X : Dot3StatsLateCollisions\n",
5251 		    sblk->stat_Dot3StatsLateCollisions);
5252 
5253 	if (sblk->stat_EtherStatsCollisions)
5254 		BNX_PRINTF(sc, "0x%08X : EtherStatsCollisions\n",
5255 		    sblk->stat_EtherStatsCollisions);
5256 
5257 	if (sblk->stat_EtherStatsFragments)
5258 		BNX_PRINTF(sc, "0x%08X : EtherStatsFragments\n",
5259 		    sblk->stat_EtherStatsFragments);
5260 
5261 	if (sblk->stat_EtherStatsJabbers)
5262 		BNX_PRINTF(sc, "0x%08X : EtherStatsJabbers\n",
5263 		    sblk->stat_EtherStatsJabbers);
5264 
5265 	if (sblk->stat_EtherStatsUndersizePkts)
5266 		BNX_PRINTF(sc, "0x%08X : EtherStatsUndersizePkts\n",
5267 		    sblk->stat_EtherStatsUndersizePkts);
5268 
5269 	if (sblk->stat_EtherStatsOverrsizePkts)
5270 		BNX_PRINTF(sc, "0x%08X : EtherStatsOverrsizePkts\n",
5271 		    sblk->stat_EtherStatsOverrsizePkts);
5272 
5273 	if (sblk->stat_EtherStatsPktsRx64Octets)
5274 		BNX_PRINTF(sc, "0x%08X : EtherStatsPktsRx64Octets\n",
5275 		    sblk->stat_EtherStatsPktsRx64Octets);
5276 
5277 	if (sblk->stat_EtherStatsPktsRx65Octetsto127Octets)
5278 		BNX_PRINTF(sc, "0x%08X : EtherStatsPktsRx65Octetsto127Octets\n",
5279 		    sblk->stat_EtherStatsPktsRx65Octetsto127Octets);
5280 
5281 	if (sblk->stat_EtherStatsPktsRx128Octetsto255Octets)
5282 		BNX_PRINTF(sc, "0x%08X : "
5283 		    "EtherStatsPktsRx128Octetsto255Octets\n",
5284 		    sblk->stat_EtherStatsPktsRx128Octetsto255Octets);
5285 
5286 	if (sblk->stat_EtherStatsPktsRx256Octetsto511Octets)
5287 		BNX_PRINTF(sc, "0x%08X : "
5288 		    "EtherStatsPktsRx256Octetsto511Octets\n",
5289 		    sblk->stat_EtherStatsPktsRx256Octetsto511Octets);
5290 
5291 	if (sblk->stat_EtherStatsPktsRx512Octetsto1023Octets)
5292 		BNX_PRINTF(sc, "0x%08X : "
5293 		    "EtherStatsPktsRx512Octetsto1023Octets\n",
5294 		    sblk->stat_EtherStatsPktsRx512Octetsto1023Octets);
5295 
5296 	if (sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets)
5297 		BNX_PRINTF(sc, "0x%08X : "
5298 		    "EtherStatsPktsRx1024Octetsto1522Octets\n",
5299 		sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets);
5300 
5301 	if (sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets)
5302 		BNX_PRINTF(sc, "0x%08X : "
5303 		    "EtherStatsPktsRx1523Octetsto9022Octets\n",
5304 		    sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets);
5305 
5306 	if (sblk->stat_EtherStatsPktsTx64Octets)
5307 		BNX_PRINTF(sc, "0x%08X : EtherStatsPktsTx64Octets\n",
5308 		    sblk->stat_EtherStatsPktsTx64Octets);
5309 
5310 	if (sblk->stat_EtherStatsPktsTx65Octetsto127Octets)
5311 		BNX_PRINTF(sc, "0x%08X : EtherStatsPktsTx65Octetsto127Octets\n",
5312 		    sblk->stat_EtherStatsPktsTx65Octetsto127Octets);
5313 
5314 	if (sblk->stat_EtherStatsPktsTx128Octetsto255Octets)
5315 		BNX_PRINTF(sc, "0x%08X : "
5316 		    "EtherStatsPktsTx128Octetsto255Octets\n",
5317 		    sblk->stat_EtherStatsPktsTx128Octetsto255Octets);
5318 
5319 	if (sblk->stat_EtherStatsPktsTx256Octetsto511Octets)
5320 		BNX_PRINTF(sc, "0x%08X : "
5321 		    "EtherStatsPktsTx256Octetsto511Octets\n",
5322 		    sblk->stat_EtherStatsPktsTx256Octetsto511Octets);
5323 
5324 	if (sblk->stat_EtherStatsPktsTx512Octetsto1023Octets)
5325 		BNX_PRINTF(sc, "0x%08X : "
5326 		    "EtherStatsPktsTx512Octetsto1023Octets\n",
5327 		    sblk->stat_EtherStatsPktsTx512Octetsto1023Octets);
5328 
5329 	if (sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets)
5330 		BNX_PRINTF(sc, "0x%08X : "
5331 		    "EtherStatsPktsTx1024Octetsto1522Octets\n",
5332 		    sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets);
5333 
5334 	if (sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets)
5335 		BNX_PRINTF(sc, "0x%08X : "
5336 		    "EtherStatsPktsTx1523Octetsto9022Octets\n",
5337 		    sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets);
5338 
5339 	if (sblk->stat_XonPauseFramesReceived)
5340 		BNX_PRINTF(sc, "0x%08X : XonPauseFramesReceived\n",
5341 		    sblk->stat_XonPauseFramesReceived);
5342 
5343 	if (sblk->stat_XoffPauseFramesReceived)
5344 		BNX_PRINTF(sc, "0x%08X : XoffPauseFramesReceived\n",
5345 		    sblk->stat_XoffPauseFramesReceived);
5346 
5347 	if (sblk->stat_OutXonSent)
5348 		BNX_PRINTF(sc, "0x%08X : OutXonSent\n",
5349 		    sblk->stat_OutXonSent);
5350 
5351 	if (sblk->stat_OutXoffSent)
5352 		BNX_PRINTF(sc, "0x%08X : OutXoffSent\n",
5353 		    sblk->stat_OutXoffSent);
5354 
5355 	if (sblk->stat_FlowControlDone)
5356 		BNX_PRINTF(sc, "0x%08X : FlowControlDone\n",
5357 		    sblk->stat_FlowControlDone);
5358 
5359 	if (sblk->stat_MacControlFramesReceived)
5360 		BNX_PRINTF(sc, "0x%08X : MacControlFramesReceived\n",
5361 		    sblk->stat_MacControlFramesReceived);
5362 
5363 	if (sblk->stat_XoffStateEntered)
5364 		BNX_PRINTF(sc, "0x%08X : XoffStateEntered\n",
5365 		    sblk->stat_XoffStateEntered);
5366 
5367 	if (sblk->stat_IfInFramesL2FilterDiscards)
5368 		BNX_PRINTF(sc, "0x%08X : IfInFramesL2FilterDiscards\n",
5369 		    sblk->stat_IfInFramesL2FilterDiscards);
5370 
5371 	if (sblk->stat_IfInRuleCheckerDiscards)
5372 		BNX_PRINTF(sc, "0x%08X : IfInRuleCheckerDiscards\n",
5373 		    sblk->stat_IfInRuleCheckerDiscards);
5374 
5375 	if (sblk->stat_IfInFTQDiscards)
5376 		BNX_PRINTF(sc, "0x%08X : IfInFTQDiscards\n",
5377 		    sblk->stat_IfInFTQDiscards);
5378 
5379 	if (sblk->stat_IfInMBUFDiscards)
5380 		BNX_PRINTF(sc, "0x%08X : IfInMBUFDiscards\n",
5381 		    sblk->stat_IfInMBUFDiscards);
5382 
5383 	if (sblk->stat_IfInRuleCheckerP4Hit)
5384 		BNX_PRINTF(sc, "0x%08X : IfInRuleCheckerP4Hit\n",
5385 		    sblk->stat_IfInRuleCheckerP4Hit);
5386 
5387 	if (sblk->stat_CatchupInRuleCheckerDiscards)
5388 		BNX_PRINTF(sc, "0x%08X : CatchupInRuleCheckerDiscards\n",
5389 		    sblk->stat_CatchupInRuleCheckerDiscards);
5390 
5391 	if (sblk->stat_CatchupInFTQDiscards)
5392 		BNX_PRINTF(sc, "0x%08X : CatchupInFTQDiscards\n",
5393 		    sblk->stat_CatchupInFTQDiscards);
5394 
5395 	if (sblk->stat_CatchupInMBUFDiscards)
5396 		BNX_PRINTF(sc, "0x%08X : CatchupInMBUFDiscards\n",
5397 		    sblk->stat_CatchupInMBUFDiscards);
5398 
5399 	if (sblk->stat_CatchupInRuleCheckerP4Hit)
5400 		BNX_PRINTF(sc, "0x%08X : CatchupInRuleCheckerP4Hit\n",
5401 		    sblk->stat_CatchupInRuleCheckerP4Hit);
5402 
5403 	BNX_PRINTF(sc,
5404 	    "-----------------------------"
5405 	    "--------------"
5406 	    "-----------------------------\n");
5407 }
5408 
5409 void
5410 bnx_dump_driver_state(struct bnx_softc *sc)
5411 {
5412 	BNX_PRINTF(sc,
5413 	    "-----------------------------"
5414 	    " Driver State "
5415 	    "-----------------------------\n");
5416 
5417 	BNX_PRINTF(sc, "%p - (sc) driver softc structure virtual "
5418 	    "address\n", sc);
5419 
5420 	BNX_PRINTF(sc, "%p - (sc->status_block) status block virtual address\n",
5421 	    sc->status_block);
5422 
5423 	BNX_PRINTF(sc, "%p - (sc->stats_block) statistics block virtual "
5424 	    "address\n", sc->stats_block);
5425 
5426 	BNX_PRINTF(sc, "%p - (sc->tx_bd_chain) tx_bd chain virtual "
5427 	    "adddress\n", sc->tx_bd_chain);
5428 
5429 	BNX_PRINTF(sc, "%p - (sc->rx_bd_chain) rx_bd chain virtual address\n",
5430 	    sc->rx_bd_chain);
5431 
5432 	BNX_PRINTF(sc, "%p - (sc->tx_mbuf_ptr) tx mbuf chain virtual address\n",
5433 	    sc->tx_mbuf_ptr);
5434 
5435 	BNX_PRINTF(sc, "%p - (sc->rx_mbuf_ptr) rx mbuf chain virtual address\n",
5436 	    sc->rx_mbuf_ptr);
5437 
5438 	BNX_PRINTF(sc,
5439 	    "         0x%08X - (sc->interrupts_generated) h/w intrs\n",
5440 	    sc->interrupts_generated);
5441 
5442 	BNX_PRINTF(sc,
5443 	    "         0x%08X - (sc->rx_interrupts) rx interrupts handled\n",
5444 	    sc->rx_interrupts);
5445 
5446 	BNX_PRINTF(sc,
5447 	    "         0x%08X - (sc->tx_interrupts) tx interrupts handled\n",
5448 	    sc->tx_interrupts);
5449 
5450 	BNX_PRINTF(sc,
5451 	    "         0x%08X - (sc->last_status_idx) status block index\n",
5452 	    sc->last_status_idx);
5453 
5454 	BNX_PRINTF(sc, "         0x%08X - (sc->tx_prod) tx producer index\n",
5455 	    sc->tx_prod);
5456 
5457 	BNX_PRINTF(sc, "         0x%08X - (sc->tx_cons) tx consumer index\n",
5458 	    sc->tx_cons);
5459 
5460 	BNX_PRINTF(sc,
5461 	    "         0x%08X - (sc->tx_prod_bseq) tx producer bseq index\n",
5462 	    sc->tx_prod_bseq);
5463 
5464 	BNX_PRINTF(sc, "         0x%08X - (sc->rx_prod) rx producer index\n",
5465 	    sc->rx_prod);
5466 
5467 	BNX_PRINTF(sc, "         0x%08X - (sc->rx_cons) rx consumer index\n",
5468 	    sc->rx_cons);
5469 
5470 	BNX_PRINTF(sc,
5471 	    "         0x%08X - (sc->rx_prod_bseq) rx producer bseq index\n",
5472 	    sc->rx_prod_bseq);
5473 
5474 	BNX_PRINTF(sc,
5475 	    "         0x%08X - (sc->rx_mbuf_alloc) rx mbufs allocated\n",
5476 	    sc->rx_mbuf_alloc);
5477 
5478 	BNX_PRINTF(sc, "         0x%08X - (sc->free_rx_bd) free rx_bd's\n",
5479 	    sc->free_rx_bd);
5480 
5481 	BNX_PRINTF(sc,
5482 	    "0x%08X/%08X - (sc->rx_low_watermark) rx low watermark\n",
5483 	    sc->rx_low_watermark, (u_int32_t) USABLE_RX_BD);
5484 
5485 	BNX_PRINTF(sc,
5486 	    "         0x%08X - (sc->txmbuf_alloc) tx mbufs allocated\n",
5487 	    sc->tx_mbuf_alloc);
5488 
5489 	BNX_PRINTF(sc,
5490 	    "         0x%08X - (sc->rx_mbuf_alloc) rx mbufs allocated\n",
5491 	    sc->rx_mbuf_alloc);
5492 
5493 	BNX_PRINTF(sc, "         0x%08X - (sc->used_tx_bd) used tx_bd's\n",
5494 	    sc->used_tx_bd);
5495 
5496 	BNX_PRINTF(sc, "0x%08X/%08X - (sc->tx_hi_watermark) tx hi watermark\n",
5497 	    sc->tx_hi_watermark, (u_int32_t) USABLE_TX_BD);
5498 
5499 	BNX_PRINTF(sc,
5500 	    "         0x%08X - (sc->mbuf_alloc_failed) failed mbuf alloc\n",
5501 	    sc->mbuf_alloc_failed);
5502 
5503 	BNX_PRINTF(sc, "-------------------------------------------"
5504 	    "-----------------------------\n");
5505 }
5506 
5507 void
5508 bnx_dump_hw_state(struct bnx_softc *sc)
5509 {
5510 	u_int32_t		val1;
5511 	int			i;
5512 
5513 	BNX_PRINTF(sc,
5514 	    "----------------------------"
5515 	    " Hardware State "
5516 	    "----------------------------\n");
5517 
5518 	BNX_PRINTF(sc, "0x%08X : bootcode version\n", sc->bnx_fw_ver);
5519 
5520 	val1 = REG_RD(sc, BNX_MISC_ENABLE_STATUS_BITS);
5521 	BNX_PRINTF(sc, "0x%08X : (0x%04X) misc_enable_status_bits\n",
5522 	    val1, BNX_MISC_ENABLE_STATUS_BITS);
5523 
5524 	val1 = REG_RD(sc, BNX_DMA_STATUS);
5525 	BNX_PRINTF(sc, "0x%08X : (0x%04X) dma_status\n", val1, BNX_DMA_STATUS);
5526 
5527 	val1 = REG_RD(sc, BNX_CTX_STATUS);
5528 	BNX_PRINTF(sc, "0x%08X : (0x%04X) ctx_status\n", val1, BNX_CTX_STATUS);
5529 
5530 	val1 = REG_RD(sc, BNX_EMAC_STATUS);
5531 	BNX_PRINTF(sc, "0x%08X : (0x%04X) emac_status\n", val1,
5532 	    BNX_EMAC_STATUS);
5533 
5534 	val1 = REG_RD(sc, BNX_RPM_STATUS);
5535 	BNX_PRINTF(sc, "0x%08X : (0x%04X) rpm_status\n", val1, BNX_RPM_STATUS);
5536 
5537 	val1 = REG_RD(sc, BNX_TBDR_STATUS);
5538 	BNX_PRINTF(sc, "0x%08X : (0x%04X) tbdr_status\n", val1,
5539 	    BNX_TBDR_STATUS);
5540 
5541 	val1 = REG_RD(sc, BNX_TDMA_STATUS);
5542 	BNX_PRINTF(sc, "0x%08X : (0x%04X) tdma_status\n", val1,
5543 	    BNX_TDMA_STATUS);
5544 
5545 	val1 = REG_RD(sc, BNX_HC_STATUS);
5546 	BNX_PRINTF(sc, "0x%08X : (0x%04X) hc_status\n", val1, BNX_HC_STATUS);
5547 
5548 	BNX_PRINTF(sc,
5549 	    "----------------------------"
5550 	    "----------------"
5551 	    "----------------------------\n");
5552 
5553 	BNX_PRINTF(sc,
5554 	    "----------------------------"
5555 	    " Register  Dump "
5556 	    "----------------------------\n");
5557 
5558 	for (i = 0x400; i < 0x8000; i += 0x10)
5559 		BNX_PRINTF(sc, "0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
5560 		    i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
5561 		    REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
5562 
5563 	BNX_PRINTF(sc,
5564 	    "----------------------------"
5565 	    "----------------"
5566 	    "----------------------------\n");
5567 }
5568 
5569 void
5570 bnx_breakpoint(struct bnx_softc *sc)
5571 {
5572 	/* Unreachable code to shut the compiler up about unused functions. */
5573 	if (0) {
5574    		bnx_dump_txbd(sc, 0, NULL);
5575 		bnx_dump_rxbd(sc, 0, NULL);
5576 		bnx_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD);
5577 		bnx_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD);
5578 		bnx_dump_l2fhdr(sc, 0, NULL);
5579 		bnx_dump_tx_chain(sc, 0, USABLE_TX_BD);
5580 		bnx_dump_rx_chain(sc, 0, USABLE_RX_BD);
5581 		bnx_dump_status_block(sc);
5582 		bnx_dump_stats_block(sc);
5583 		bnx_dump_driver_state(sc);
5584 		bnx_dump_hw_state(sc);
5585 	}
5586 
5587 	bnx_dump_driver_state(sc);
5588 	/* Print the important status block fields. */
5589 	bnx_dump_status_block(sc);
5590 
5591 #if 0
5592 	/* Call the debugger. */
5593 	breakpoint();
5594 #endif
5595 
5596 	return;
5597 }
5598 #endif
5599