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