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