xref: /freebsd/sys/dev/bce/if_bce.c (revision 94942af266ac119ede0ca836f9aa5a5ac0582938)
1 /*-
2  * Copyright (c) 2006-2007 Broadcom Corporation
3  *	David Christensen <davidch@broadcom.com>.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of Broadcom Corporation nor the name of its contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written consent.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 /*
35  * The following controllers are supported by this driver:
36  *   BCM5706C A2, A3
37  *   BCM5708C B1, B2
38  *
39  * The following controllers are not supported by this driver:
40  *   BCM5706C A0, A1
41  *   BCM5706S A0, A1, A2, A3
42  *   BCM5708C A0, B0
43  *   BCM5708S A0, B0, B1, B2
44  */
45 
46 #include "opt_bce.h"
47 
48 #include <dev/bce/if_bcereg.h>
49 #include <dev/bce/if_bcefw.h>
50 
51 /****************************************************************************/
52 /* BCE Debug Options                                                        */
53 /****************************************************************************/
54 #ifdef BCE_DEBUG
55 	u32 bce_debug = BCE_WARN;
56 
57 	/*          0 = Never              */
58 	/*          1 = 1 in 2,147,483,648 */
59 	/*        256 = 1 in     8,388,608 */
60 	/*       2048 = 1 in     1,048,576 */
61 	/*      65536 = 1 in        32,768 */
62 	/*    1048576 = 1 in         2,048 */
63 	/*  268435456 =	1 in             8 */
64 	/*  536870912 = 1 in             4 */
65 	/* 1073741824 = 1 in             2 */
66 
67 	/* Controls how often the l2_fhdr frame error check will fail. */
68 	int bce_debug_l2fhdr_status_check = 0;
69 
70 	/* Controls how often the unexpected attention check will fail. */
71 	int bce_debug_unexpected_attention = 0;
72 
73 	/* Controls how often to simulate an mbuf allocation failure. */
74 	int bce_debug_mbuf_allocation_failure = 0;
75 
76 	/* Controls how often to simulate a DMA mapping failure. */
77 	int bce_debug_dma_map_addr_failure = 0;
78 
79 	/* Controls how often to simulate a bootcode failure. */
80 	int bce_debug_bootcode_running_failure = 0;
81 #endif
82 
83 
84 /****************************************************************************/
85 /* PCI Device ID Table                                                      */
86 /*                                                                          */
87 /* Used by bce_probe() to identify the devices supported by this driver.    */
88 /****************************************************************************/
89 #define BCE_DEVDESC_MAX		64
90 
91 static struct bce_type bce_devs[] = {
92 	/* BCM5706C Controllers and OEM boards. */
93 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3101,
94 		"HP NC370T Multifunction Gigabit Server Adapter" },
95 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3106,
96 		"HP NC370i Multifunction Gigabit Server Adapter" },
97 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  PCI_ANY_ID,  PCI_ANY_ID,
98 		"Broadcom NetXtreme II BCM5706 1000Base-T" },
99 
100 	/* BCM5706S controllers and OEM boards. */
101 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, HP_VENDORID, 0x3102,
102 		"HP NC370F Multifunction Gigabit Server Adapter" },
103 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, PCI_ANY_ID,  PCI_ANY_ID,
104 		"Broadcom NetXtreme II BCM5706 1000Base-SX" },
105 
106 	/* BCM5708C controllers and OEM boards. */
107 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  PCI_ANY_ID,  PCI_ANY_ID,
108 		"Broadcom NetXtreme II BCM5708 1000Base-T" },
109 
110 	/* BCM5708S controllers and OEM boards. */
111 	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  PCI_ANY_ID,  PCI_ANY_ID,
112 		"Broadcom NetXtreme II BCM5708S 1000Base-T" },
113 	{ 0, 0, 0, 0, NULL }
114 };
115 
116 
117 /****************************************************************************/
118 /* Supported Flash NVRAM device data.                                       */
119 /****************************************************************************/
120 static struct flash_spec flash_table[] =
121 {
122 	/* Slow EEPROM */
123 	{0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
124 	 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
125 	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
126 	 "EEPROM - slow"},
127 	/* Expansion entry 0001 */
128 	{0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
129 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
130 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
131 	 "Entry 0001"},
132 	/* Saifun SA25F010 (non-buffered flash) */
133 	/* strap, cfg1, & write1 need updates */
134 	{0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
135 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
136 	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
137 	 "Non-buffered flash (128kB)"},
138 	/* Saifun SA25F020 (non-buffered flash) */
139 	/* strap, cfg1, & write1 need updates */
140 	{0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
141 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
142 	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
143 	 "Non-buffered flash (256kB)"},
144 	/* Expansion entry 0100 */
145 	{0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
146 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
147 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
148 	 "Entry 0100"},
149 	/* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
150 	{0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
151 	 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
152 	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
153 	 "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
154 	/* Entry 0110: ST M45PE20 (non-buffered flash)*/
155 	{0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
156 	 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
157 	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
158 	 "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
159 	/* Saifun SA25F005 (non-buffered flash) */
160 	/* strap, cfg1, & write1 need updates */
161 	{0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
162 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
163 	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
164 	 "Non-buffered flash (64kB)"},
165 	/* Fast EEPROM */
166 	{0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
167 	 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
168 	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
169 	 "EEPROM - fast"},
170 	/* Expansion entry 1001 */
171 	{0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
172 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
173 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
174 	 "Entry 1001"},
175 	/* Expansion entry 1010 */
176 	{0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
177 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
178 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
179 	 "Entry 1010"},
180 	/* ATMEL AT45DB011B (buffered flash) */
181 	{0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
182 	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
183 	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
184 	 "Buffered flash (128kB)"},
185 	/* Expansion entry 1100 */
186 	{0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
187 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
188 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
189 	 "Entry 1100"},
190 	/* Expansion entry 1101 */
191 	{0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
192 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
193 	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
194 	 "Entry 1101"},
195 	/* Ateml Expansion entry 1110 */
196 	{0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
197 	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
198 	 BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
199 	 "Entry 1110 (Atmel)"},
200 	/* ATMEL AT45DB021B (buffered flash) */
201 	{0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
202 	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
203 	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
204 	 "Buffered flash (256kB)"},
205 };
206 
207 
208 /****************************************************************************/
209 /* FreeBSD device entry points.                                             */
210 /****************************************************************************/
211 static int  bce_probe				(device_t);
212 static int  bce_attach				(device_t);
213 static int  bce_detach				(device_t);
214 static void bce_shutdown			(device_t);
215 
216 
217 /****************************************************************************/
218 /* BCE Debug Data Structure Dump Routines                                   */
219 /****************************************************************************/
220 #ifdef BCE_DEBUG
221 static void bce_dump_mbuf 			(struct bce_softc *, struct mbuf *);
222 static void bce_dump_tx_mbuf_chain	(struct bce_softc *, int, int);
223 static void bce_dump_rx_mbuf_chain	(struct bce_softc *, int, int);
224 static void bce_dump_txbd			(struct bce_softc *, int, struct tx_bd *);
225 static void bce_dump_rxbd			(struct bce_softc *, int, struct rx_bd *);
226 static void bce_dump_l2fhdr			(struct bce_softc *, int, struct l2_fhdr *);
227 static void bce_dump_tx_chain		(struct bce_softc *, int, int);
228 static void bce_dump_rx_chain		(struct bce_softc *, int, int);
229 static void bce_dump_status_block	(struct bce_softc *);
230 static void bce_dump_stats_block	(struct bce_softc *);
231 static void bce_dump_driver_state	(struct bce_softc *);
232 static void bce_dump_hw_state		(struct bce_softc *);
233 static void bce_breakpoint			(struct bce_softc *);
234 #endif
235 
236 
237 /****************************************************************************/
238 /* BCE Register/Memory Access Routines                                      */
239 /****************************************************************************/
240 static u32  bce_reg_rd_ind			(struct bce_softc *, u32);
241 static void bce_reg_wr_ind			(struct bce_softc *, u32, u32);
242 static void bce_ctx_wr				(struct bce_softc *, u32, u32, u32);
243 static int  bce_miibus_read_reg		(device_t, int, int);
244 static int  bce_miibus_write_reg	(device_t, int, int, int);
245 static void bce_miibus_statchg		(device_t);
246 
247 
248 /****************************************************************************/
249 /* BCE NVRAM Access Routines                                                */
250 /****************************************************************************/
251 static int  bce_acquire_nvram_lock	(struct bce_softc *);
252 static int  bce_release_nvram_lock	(struct bce_softc *);
253 static void bce_enable_nvram_access	(struct bce_softc *);
254 static void	bce_disable_nvram_access(struct bce_softc *);
255 static int  bce_nvram_read_dword	(struct bce_softc *, u32, u8 *, u32);
256 static int  bce_init_nvram			(struct bce_softc *);
257 static int  bce_nvram_read			(struct bce_softc *, u32, u8 *, int);
258 static int  bce_nvram_test			(struct bce_softc *);
259 #ifdef BCE_NVRAM_WRITE_SUPPORT
260 static int  bce_enable_nvram_write	(struct bce_softc *);
261 static void bce_disable_nvram_write	(struct bce_softc *);
262 static int  bce_nvram_erase_page	(struct bce_softc *, u32);
263 static int  bce_nvram_write_dword	(struct bce_softc *, u32, u8 *, u32);
264 static int  bce_nvram_write			(struct bce_softc *, u32, u8 *, int);
265 #endif
266 
267 /****************************************************************************/
268 /*                                                                          */
269 /****************************************************************************/
270 static void bce_dma_map_addr		(void *, bus_dma_segment_t *, int, int);
271 static int  bce_dma_alloc			(device_t);
272 static void bce_dma_free			(struct bce_softc *);
273 static void bce_release_resources	(struct bce_softc *);
274 
275 /****************************************************************************/
276 /* BCE Firmware Synchronization and Load                                    */
277 /****************************************************************************/
278 static int  bce_fw_sync				(struct bce_softc *, u32);
279 static void bce_load_rv2p_fw		(struct bce_softc *, u32 *, u32, u32);
280 static void bce_load_cpu_fw			(struct bce_softc *, struct cpu_reg *, struct fw_info *);
281 static void bce_init_cpus			(struct bce_softc *);
282 
283 static void bce_stop				(struct bce_softc *);
284 static int  bce_reset				(struct bce_softc *, u32);
285 static int  bce_chipinit 			(struct bce_softc *);
286 static int  bce_blockinit 			(struct bce_softc *);
287 static int  bce_get_buf				(struct bce_softc *, struct mbuf *, u16 *, u16 *, u32 *);
288 
289 static int  bce_init_tx_chain		(struct bce_softc *);
290 static int  bce_init_rx_chain		(struct bce_softc *);
291 static void bce_free_rx_chain		(struct bce_softc *);
292 static void bce_free_tx_chain		(struct bce_softc *);
293 
294 static int  bce_tx_encap		(struct bce_softc *, struct mbuf **);
295 static void bce_start_locked		(struct ifnet *);
296 static void bce_start				(struct ifnet *);
297 static int  bce_ioctl				(struct ifnet *, u_long, caddr_t);
298 static void bce_watchdog			(struct bce_softc *);
299 static int  bce_ifmedia_upd			(struct ifnet *);
300 static void bce_ifmedia_upd_locked		(struct ifnet *);
301 static void bce_ifmedia_sts			(struct ifnet *, struct ifmediareq *);
302 static void bce_init_locked			(struct bce_softc *);
303 static void bce_init				(void *);
304 static void bce_mgmt_init_locked(struct bce_softc *sc);
305 
306 static void bce_init_context		(struct bce_softc *);
307 static void bce_get_mac_addr		(struct bce_softc *);
308 static void bce_set_mac_addr		(struct bce_softc *);
309 static void bce_phy_intr			(struct bce_softc *);
310 static void bce_rx_intr				(struct bce_softc *);
311 static void bce_tx_intr				(struct bce_softc *);
312 static void bce_disable_intr		(struct bce_softc *);
313 static void bce_enable_intr			(struct bce_softc *);
314 
315 #ifdef DEVICE_POLLING
316 static void bce_poll_locked			(struct ifnet *, enum poll_cmd, int);
317 static void bce_poll				(struct ifnet *, enum poll_cmd, int);
318 #endif
319 static void bce_intr				(void *);
320 static void bce_set_rx_mode			(struct bce_softc *);
321 static void bce_stats_update		(struct bce_softc *);
322 static void bce_tick				(void *);
323 static void bce_add_sysctls			(struct bce_softc *);
324 
325 
326 /****************************************************************************/
327 /* FreeBSD device dispatch table.                                           */
328 /****************************************************************************/
329 static device_method_t bce_methods[] = {
330 	/* Device interface */
331 	DEVMETHOD(device_probe,		bce_probe),
332 	DEVMETHOD(device_attach,	bce_attach),
333 	DEVMETHOD(device_detach,	bce_detach),
334 	DEVMETHOD(device_shutdown,	bce_shutdown),
335 
336 	/* bus interface */
337 	DEVMETHOD(bus_print_child,	bus_generic_print_child),
338 	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
339 
340 	/* MII interface */
341 	DEVMETHOD(miibus_readreg,	bce_miibus_read_reg),
342 	DEVMETHOD(miibus_writereg,	bce_miibus_write_reg),
343 	DEVMETHOD(miibus_statchg,	bce_miibus_statchg),
344 
345 	{ 0, 0 }
346 };
347 
348 static driver_t bce_driver = {
349 	"bce",
350 	bce_methods,
351 	sizeof(struct bce_softc)
352 };
353 
354 static devclass_t bce_devclass;
355 
356 MODULE_DEPEND(bce, pci, 1, 1, 1);
357 MODULE_DEPEND(bce, ether, 1, 1, 1);
358 MODULE_DEPEND(bce, miibus, 1, 1, 1);
359 
360 DRIVER_MODULE(bce, pci, bce_driver, bce_devclass, 0, 0);
361 DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, 0, 0);
362 
363 
364 /****************************************************************************/
365 /* Tunable device values                                                    */
366 /****************************************************************************/
367 static int bce_tso_enable = TRUE;
368 static int bce_msi_enable = 1;
369 
370 /* Allowable values are TRUE or FALSE */
371 TUNABLE_INT("hw.bce.tso_enable", &bce_tso_enable);
372 /* Allowable values are 0 (IRQ only) and 1 (IRQ or MSI) */
373 TUNABLE_INT("hw.bce.msi_enable", &bce_msi_enable);
374 
375 SYSCTL_NODE(_hw, OID_AUTO, bce, CTLFLAG_RD, 0, "bce driver parameters");
376 SYSCTL_UINT(_hw_bce, OID_AUTO, tso_enable, CTLFLAG_RDTUN, &bce_tso_enable, 0,
377 "TSO Enable/Disable");
378 SYSCTL_UINT(_hw_bce, OID_AUTO, msi_enable, CTLFLAG_RDTUN, &bce_msi_enable, 0,
379 "MSI | INTx selector");
380 
381 /****************************************************************************/
382 /* Device probe function.                                                   */
383 /*                                                                          */
384 /* Compares the device to the driver's list of supported devices and        */
385 /* reports back to the OS whether this is the right driver for the device.  */
386 /*                                                                          */
387 /* Returns:                                                                 */
388 /*   BUS_PROBE_DEFAULT on success, positive value on failure.               */
389 /****************************************************************************/
390 static int
391 bce_probe(device_t dev)
392 {
393 	struct bce_type *t;
394 	struct bce_softc *sc;
395 	char *descbuf;
396 	u16 vid = 0, did = 0, svid = 0, sdid = 0;
397 
398 	t = bce_devs;
399 
400 	sc = device_get_softc(dev);
401 	bzero(sc, sizeof(struct bce_softc));
402 	sc->bce_unit = device_get_unit(dev);
403 	sc->bce_dev = dev;
404 
405 	/* Get the data for the device to be probed. */
406 	vid  = pci_get_vendor(dev);
407 	did  = pci_get_device(dev);
408 	svid = pci_get_subvendor(dev);
409 	sdid = pci_get_subdevice(dev);
410 
411 	DBPRINT(sc, BCE_VERBOSE_LOAD,
412 		"%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
413 		"SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
414 
415 	/* Look through the list of known devices for a match. */
416 	while(t->bce_name != NULL) {
417 
418 		if ((vid == t->bce_vid) && (did == t->bce_did) &&
419 			((svid == t->bce_svid) || (t->bce_svid == PCI_ANY_ID)) &&
420 			((sdid == t->bce_sdid) || (t->bce_sdid == PCI_ANY_ID))) {
421 
422 			descbuf = malloc(BCE_DEVDESC_MAX, M_TEMP, M_NOWAIT);
423 
424 			if (descbuf == NULL)
425 				return(ENOMEM);
426 
427 			/* Print out the device identity. */
428 			snprintf(descbuf, BCE_DEVDESC_MAX, "%s (%c%d)",
429 				t->bce_name,
430 			    (((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
431 			    (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
432 
433 			device_set_desc_copy(dev, descbuf);
434 			free(descbuf, M_TEMP);
435 			return(BUS_PROBE_DEFAULT);
436 		}
437 		t++;
438 	}
439 
440 	DBPRINT(sc, BCE_VERBOSE_LOAD, "%s(%d): No IOCTL match found!\n",
441 		__FILE__, __LINE__);
442 
443 	return(ENXIO);
444 }
445 
446 
447 /****************************************************************************/
448 /* Device attach function.                                                  */
449 /*                                                                          */
450 /* Allocates device resources, performs secondary chip identification,      */
451 /* resets and initializes the hardware, and initializes driver instance     */
452 /* variables.                                                               */
453 /*                                                                          */
454 /* Returns:                                                                 */
455 /*   0 on success, positive value on failure.                               */
456 /****************************************************************************/
457 static int
458 bce_attach(device_t dev)
459 {
460 	struct bce_softc *sc;
461 	struct ifnet *ifp;
462 	u32 val;
463 	int count, mbuf, rid, rc = 0;
464 
465 	sc = device_get_softc(dev);
466 	sc->bce_dev = dev;
467 
468 	DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
469 
470 	mbuf = device_get_unit(dev);
471 
472 	/* Set initial device and PHY flags */
473 	sc->bce_flags = 0;
474 	sc->bce_phy_flags = 0;
475 
476 	sc->bce_unit = mbuf;
477 
478 	pci_enable_busmaster(dev);
479 
480 	/* Allocate PCI memory resources. */
481 	rid = PCIR_BAR(0);
482 	sc->bce_res_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
483 		&rid, RF_ACTIVE | PCI_RF_DENSE);
484 
485 	if (sc->bce_res_mem == NULL) {
486 		BCE_PRINTF("%s(%d): PCI memory allocation failed\n",
487 			__FILE__, __LINE__);
488 		rc = ENXIO;
489 		goto bce_attach_fail;
490 	}
491 
492 	/* Get various resource handles. */
493 	sc->bce_btag    = rman_get_bustag(sc->bce_res_mem);
494 	sc->bce_bhandle = rman_get_bushandle(sc->bce_res_mem);
495 	sc->bce_vhandle = (vm_offset_t) rman_get_virtual(sc->bce_res_mem);
496 
497 	/* If MSI is enabled in the driver, get the vector count. */
498 	count = bce_msi_enable ? pci_msi_count(dev) : 0;
499 
500 	/* Allocate PCI IRQ resources. */
501 	if (count == 1 && pci_alloc_msi(dev, &count) == 0 && count == 1) {
502 		rid = 1;
503 		sc->bce_flags |= BCE_USING_MSI_FLAG;
504 		DBPRINT(sc, BCE_INFO, "Allocating %d MSI interrupt(s).\n", count);
505 	} else {
506 		rid = 0;
507 		DBPRINT(sc, BCE_INFO, "Allocating IRQ interrupt.\n");
508 	}
509 
510 	sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
511 	    RF_SHAREABLE | RF_ACTIVE);
512 
513 	if (sc->bce_res_irq == NULL) {
514 		BCE_PRINTF("%s(%d): PCI map interrupt failed!\n",
515 			__FILE__, __LINE__);
516 		rc = ENXIO;
517 		goto bce_attach_fail;
518 	}
519 
520 	/* Initialize mutex for the current device instance. */
521 	BCE_LOCK_INIT(sc, device_get_nameunit(dev));
522 
523 	/*
524 	 * Configure byte swap and enable indirect register access.
525 	 * Rely on CPU to do target byte swapping on big endian systems.
526 	 * Access to registers outside of PCI configurtion space are not
527 	 * valid until this is done.
528 	 */
529 	pci_write_config(dev, BCE_PCICFG_MISC_CONFIG,
530 			       BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
531 			       BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4);
532 
533 	/* Save ASIC revsion info. */
534 	sc->bce_chipid =  REG_RD(sc, BCE_MISC_ID);
535 
536 	/* Weed out any non-production controller revisions. */
537 	switch(BCE_CHIP_ID(sc)) {
538 		case BCE_CHIP_ID_5706_A0:
539 		case BCE_CHIP_ID_5706_A1:
540 		case BCE_CHIP_ID_5708_A0:
541 		case BCE_CHIP_ID_5708_B0:
542 			BCE_PRINTF("%s(%d): Unsupported controller revision (%c%d)!\n",
543 				__FILE__, __LINE__,
544 				(((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
545 			    (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
546 			rc = ENODEV;
547 			goto bce_attach_fail;
548 	}
549 
550 	/*
551 	 * The embedded PCIe to PCI-X bridge (EPB)
552 	 * in the 5708 cannot address memory above
553 	 * 40 bits (E7_5708CB1_23043 & E6_5708SB1_23043).
554 	 */
555 	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708)
556 		sc->max_bus_addr = BCE_BUS_SPACE_MAXADDR;
557 	else
558 		sc->max_bus_addr = BUS_SPACE_MAXADDR;
559 
560 	/*
561 	 * Find the base address for shared memory access.
562 	 * Newer versions of bootcode use a signature and offset
563 	 * while older versions use a fixed address.
564 	 */
565 	val = REG_RD_IND(sc, BCE_SHM_HDR_SIGNATURE);
566 	if ((val & BCE_SHM_HDR_SIGNATURE_SIG_MASK) == BCE_SHM_HDR_SIGNATURE_SIG)
567 		sc->bce_shmem_base = REG_RD_IND(sc, BCE_SHM_HDR_ADDR_0);
568 	else
569 		sc->bce_shmem_base = HOST_VIEW_SHMEM_BASE;
570 
571 	DBPRINT(sc, BCE_INFO, "bce_shmem_base = 0x%08X\n", sc->bce_shmem_base);
572 
573 	/* Get PCI bus information (speed and type). */
574 	val = REG_RD(sc, BCE_PCICFG_MISC_STATUS);
575 	if (val & BCE_PCICFG_MISC_STATUS_PCIX_DET) {
576 		u32 clkreg;
577 
578 		sc->bce_flags |= BCE_PCIX_FLAG;
579 
580 		clkreg = REG_RD(sc, BCE_PCICFG_PCI_CLOCK_CONTROL_BITS);
581 
582 		clkreg &= BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
583 		switch (clkreg) {
584 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
585 			sc->bus_speed_mhz = 133;
586 			break;
587 
588 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
589 			sc->bus_speed_mhz = 100;
590 			break;
591 
592 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
593 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
594 			sc->bus_speed_mhz = 66;
595 			break;
596 
597 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
598 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
599 			sc->bus_speed_mhz = 50;
600 			break;
601 
602 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
603 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
604 		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
605 			sc->bus_speed_mhz = 33;
606 			break;
607 		}
608 	} else {
609 		if (val & BCE_PCICFG_MISC_STATUS_M66EN)
610 			sc->bus_speed_mhz = 66;
611 		else
612 			sc->bus_speed_mhz = 33;
613 	}
614 
615 	if (val & BCE_PCICFG_MISC_STATUS_32BIT_DET)
616 		sc->bce_flags |= BCE_PCI_32BIT_FLAG;
617 
618 	BCE_PRINTF("ASIC ID 0x%08X; Revision (%c%d); PCI%s %s %dMHz\n",
619 		sc->bce_chipid,
620 		((BCE_CHIP_ID(sc) & 0xf000) >> 12) + 'A',
621 		((BCE_CHIP_ID(sc) & 0x0ff0) >> 4),
622 		((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""),
623 		((sc->bce_flags & BCE_PCI_32BIT_FLAG) ? "32-bit" : "64-bit"),
624 		sc->bus_speed_mhz);
625 
626 	/* Reset the controller. */
627 	if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
628 		rc = ENXIO;
629 		goto bce_attach_fail;
630 	}
631 
632 	/* Initialize the controller. */
633 	if (bce_chipinit(sc)) {
634 		BCE_PRINTF("%s(%d): Controller initialization failed!\n",
635 			__FILE__, __LINE__);
636 		rc = ENXIO;
637 		goto bce_attach_fail;
638 	}
639 
640 	/* Perform NVRAM test. */
641 	if (bce_nvram_test(sc)) {
642 		BCE_PRINTF("%s(%d): NVRAM test failed!\n",
643 			__FILE__, __LINE__);
644 		rc = ENXIO;
645 		goto bce_attach_fail;
646 	}
647 
648 	/* Fetch the permanent Ethernet MAC address. */
649 	bce_get_mac_addr(sc);
650 
651 	/*
652 	 * Trip points control how many BDs
653 	 * should be ready before generating an
654 	 * interrupt while ticks control how long
655 	 * a BD can sit in the chain before
656 	 * generating an interrupt.  Set the default
657 	 * values for the RX and TX rings.
658 	 */
659 
660 #ifdef BCE_DRBUG
661 	/* Force more frequent interrupts. */
662 	sc->bce_tx_quick_cons_trip_int = 1;
663 	sc->bce_tx_quick_cons_trip     = 1;
664 	sc->bce_tx_ticks_int           = 0;
665 	sc->bce_tx_ticks               = 0;
666 
667 	sc->bce_rx_quick_cons_trip_int = 1;
668 	sc->bce_rx_quick_cons_trip     = 1;
669 	sc->bce_rx_ticks_int           = 0;
670 	sc->bce_rx_ticks               = 0;
671 #else
672 	sc->bce_tx_quick_cons_trip_int = 20;
673 	sc->bce_tx_quick_cons_trip     = 20;
674 	sc->bce_tx_ticks_int           = 80;
675 	sc->bce_tx_ticks               = 80;
676 
677 	sc->bce_rx_quick_cons_trip_int = 6;
678 	sc->bce_rx_quick_cons_trip     = 6;
679 	sc->bce_rx_ticks_int           = 18;
680 	sc->bce_rx_ticks               = 18;
681 #endif
682 
683 	/* Update statistics once every second. */
684 	sc->bce_stats_ticks = 1000000 & 0xffff00;
685 
686 	/*
687 	 * The copper based NetXtreme II controllers
688 	 * use an integrated PHY at address 1 while
689 	 * the SerDes controllers use a PHY at
690 	 * address 2.
691 	 */
692 	sc->bce_phy_addr = 1;
693 
694 	if (BCE_CHIP_BOND_ID(sc) & BCE_CHIP_BOND_ID_SERDES_BIT) {
695 		sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
696 		sc->bce_flags |= BCE_NO_WOL_FLAG;
697 		if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708) {
698 			sc->bce_phy_addr = 2;
699 			val = REG_RD_IND(sc, sc->bce_shmem_base +
700 					 BCE_SHARED_HW_CFG_CONFIG);
701 			if (val & BCE_SHARED_HW_CFG_PHY_2_5G)
702 				sc->bce_phy_flags |= BCE_PHY_2_5G_CAPABLE_FLAG;
703 		}
704 	}
705 
706 	/* Allocate DMA memory resources. */
707 	if (bce_dma_alloc(dev)) {
708 		BCE_PRINTF("%s(%d): DMA resource allocation failed!\n",
709 		    __FILE__, __LINE__);
710 		rc = ENXIO;
711 		goto bce_attach_fail;
712 	}
713 
714 	/* Allocate an ifnet structure. */
715 	ifp = sc->bce_ifp = if_alloc(IFT_ETHER);
716 	if (ifp == NULL) {
717 		BCE_PRINTF("%s(%d): Interface allocation failed!\n",
718 			__FILE__, __LINE__);
719 		rc = ENXIO;
720 		goto bce_attach_fail;
721 	}
722 
723 	/* Initialize the ifnet interface. */
724 	ifp->if_softc        = sc;
725 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
726 	ifp->if_flags        = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
727 	ifp->if_ioctl        = bce_ioctl;
728 	ifp->if_start        = bce_start;
729 	ifp->if_init         = bce_init;
730 	ifp->if_mtu          = ETHERMTU;
731 
732 	if (bce_tso_enable) {
733 		ifp->if_hwassist = BCE_IF_HWASSIST | CSUM_TSO;
734 		ifp->if_capabilities = BCE_IF_CAPABILITIES | IFCAP_TSO4;
735 	} else {
736 		ifp->if_hwassist = BCE_IF_HWASSIST;
737 		ifp->if_capabilities = BCE_IF_CAPABILITIES;
738 	}
739 
740 	ifp->if_capenable    = ifp->if_capabilities;
741 
742 	/* Assume a standard 1500 byte MTU size for mbuf allocations. */
743 	sc->mbuf_alloc_size  = MCLBYTES;
744 #ifdef DEVICE_POLLING
745 	ifp->if_capabilities |= IFCAP_POLLING;
746 #endif
747 
748 	ifp->if_snd.ifq_drv_maxlen = USABLE_TX_BD;
749 	if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
750 		ifp->if_baudrate = IF_Gbps(2.5);
751 	else
752 		ifp->if_baudrate = IF_Gbps(1);
753 
754 	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
755 	IFQ_SET_READY(&ifp->if_snd);
756 
757 	/* Look for our PHY. */
758 	if (mii_phy_probe(dev, &sc->bce_miibus, bce_ifmedia_upd,
759 		bce_ifmedia_sts)) {
760 		BCE_PRINTF("%s(%d): PHY probe failed!\n",
761 			__FILE__, __LINE__);
762 		rc = ENXIO;
763 		goto bce_attach_fail;
764 	}
765 
766 	/* Attach to the Ethernet interface list. */
767 	ether_ifattach(ifp, sc->eaddr);
768 
769 #if __FreeBSD_version < 500000
770 	callout_init(&sc->bce_stat_ch);
771 #else
772 	callout_init_mtx(&sc->bce_stat_ch, &sc->bce_mtx, 0);
773 #endif
774 
775 	/* Hookup IRQ last. */
776 	rc = bus_setup_intr(dev, sc->bce_res_irq, INTR_TYPE_NET | INTR_MPSAFE, NULL,
777 	   bce_intr, sc, &sc->bce_intrhand);
778 
779 	if (rc) {
780 		BCE_PRINTF("%s(%d): Failed to setup IRQ!\n",
781 			__FILE__, __LINE__);
782 		bce_detach(dev);
783 		goto bce_attach_exit;
784 	}
785 
786 	/* Print some important debugging info. */
787 	DBRUN(BCE_INFO, bce_dump_driver_state(sc));
788 
789 	/* Add the supported sysctls to the kernel. */
790 	bce_add_sysctls(sc);
791 
792 	/* Get the firmware running so IPMI still works */
793  	BCE_LOCK(sc);
794 	bce_mgmt_init_locked(sc);
795 	BCE_UNLOCK(sc);
796 
797 	goto bce_attach_exit;
798 
799 bce_attach_fail:
800 	bce_release_resources(sc);
801 
802 bce_attach_exit:
803 
804 	DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
805 
806 	return(rc);
807 }
808 
809 
810 /****************************************************************************/
811 /* Device detach function.                                                  */
812 /*                                                                          */
813 /* Stops the controller, resets the controller, and releases resources.     */
814 /*                                                                          */
815 /* Returns:                                                                 */
816 /*   0 on success, positive value on failure.                               */
817 /****************************************************************************/
818 static int
819 bce_detach(device_t dev)
820 {
821 	struct bce_softc *sc;
822 	struct ifnet *ifp;
823 
824 	sc = device_get_softc(dev);
825 
826 	DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
827 
828 	ifp = sc->bce_ifp;
829 
830 #ifdef DEVICE_POLLING
831 	if (ifp->if_capenable & IFCAP_POLLING)
832 		ether_poll_deregister(ifp);
833 #endif
834 
835 	/* Stop and reset the controller. */
836 	BCE_LOCK(sc);
837 	bce_stop(sc);
838 	bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
839 	BCE_UNLOCK(sc);
840 
841 	ether_ifdetach(ifp);
842 
843 	/* If we have a child device on the MII bus remove it too. */
844 	bus_generic_detach(dev);
845 	device_delete_child(dev, sc->bce_miibus);
846 
847 	/* Release all remaining resources. */
848 	bce_release_resources(sc);
849 
850 	DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
851 
852 	return(0);
853 }
854 
855 
856 /****************************************************************************/
857 /* Device shutdown function.                                                */
858 /*                                                                          */
859 /* Stops and resets the controller.                                         */
860 /*                                                                          */
861 /* Returns:                                                                 */
862 /*   Nothing                                                                */
863 /****************************************************************************/
864 static void
865 bce_shutdown(device_t dev)
866 {
867 	struct bce_softc *sc = device_get_softc(dev);
868 
869 	BCE_LOCK(sc);
870 	bce_stop(sc);
871 	bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
872 	BCE_UNLOCK(sc);
873 }
874 
875 
876 /****************************************************************************/
877 /* Indirect register read.                                                  */
878 /*                                                                          */
879 /* Reads NetXtreme II registers using an index/data register pair in PCI    */
880 /* configuration space.  Using this mechanism avoids issues with posted     */
881 /* reads but is much slower than memory-mapped I/O.                         */
882 /*                                                                          */
883 /* Returns:                                                                 */
884 /*   The value of the register.                                             */
885 /****************************************************************************/
886 static u32
887 bce_reg_rd_ind(struct bce_softc *sc, u32 offset)
888 {
889 	device_t dev;
890 	dev = sc->bce_dev;
891 
892 	pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
893 #ifdef BCE_DEBUG
894 	{
895 		u32 val;
896 		val = pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
897 		DBPRINT(sc, BCE_EXCESSIVE, "%s(); offset = 0x%08X, val = 0x%08X\n",
898 			__FUNCTION__, offset, val);
899 		return val;
900 	}
901 #else
902 	return pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
903 #endif
904 }
905 
906 
907 /****************************************************************************/
908 /* Indirect register write.                                                 */
909 /*                                                                          */
910 /* Writes NetXtreme II registers using an index/data register pair in PCI   */
911 /* configuration space.  Using this mechanism avoids issues with posted     */
912 /* writes but is muchh slower than memory-mapped I/O.                       */
913 /*                                                                          */
914 /* Returns:                                                                 */
915 /*   Nothing.                                                               */
916 /****************************************************************************/
917 static void
918 bce_reg_wr_ind(struct bce_softc *sc, u32 offset, u32 val)
919 {
920 	device_t dev;
921 	dev = sc->bce_dev;
922 
923 	DBPRINT(sc, BCE_EXCESSIVE, "%s(); offset = 0x%08X, val = 0x%08X\n",
924 		__FUNCTION__, offset, val);
925 
926 	pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
927 	pci_write_config(dev, BCE_PCICFG_REG_WINDOW, val, 4);
928 }
929 
930 
931 /****************************************************************************/
932 /* Context memory write.                                                    */
933 /*                                                                          */
934 /* The NetXtreme II controller uses context memory to track connection      */
935 /* information for L2 and higher network protocols.                         */
936 /*                                                                          */
937 /* Returns:                                                                 */
938 /*   Nothing.                                                               */
939 /****************************************************************************/
940 static void
941 bce_ctx_wr(struct bce_softc *sc, u32 cid_addr, u32 offset, u32 val)
942 {
943 
944 	DBPRINT(sc, BCE_EXCESSIVE, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
945 		"val = 0x%08X\n", __FUNCTION__, cid_addr, offset, val);
946 
947 	offset += cid_addr;
948 	REG_WR(sc, BCE_CTX_DATA_ADR, offset);
949 	REG_WR(sc, BCE_CTX_DATA, val);
950 }
951 
952 
953 /****************************************************************************/
954 /* PHY register read.                                                       */
955 /*                                                                          */
956 /* Implements register reads on the MII bus.                                */
957 /*                                                                          */
958 /* Returns:                                                                 */
959 /*   The value of the register.                                             */
960 /****************************************************************************/
961 static int
962 bce_miibus_read_reg(device_t dev, int phy, int reg)
963 {
964 	struct bce_softc *sc;
965 	u32 val;
966 	int i;
967 
968 	sc = device_get_softc(dev);
969 
970 	/* Make sure we are accessing the correct PHY address. */
971 	if (phy != sc->bce_phy_addr) {
972 		DBPRINT(sc, BCE_VERBOSE, "Invalid PHY address %d for PHY read!\n", phy);
973 		return(0);
974 	}
975 
976 	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
977 		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
978 		val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
979 
980 		REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
981 		REG_RD(sc, BCE_EMAC_MDIO_MODE);
982 
983 		DELAY(40);
984 	}
985 
986 	val = BCE_MIPHY(phy) | BCE_MIREG(reg) |
987 		BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT |
988 		BCE_EMAC_MDIO_COMM_START_BUSY;
989 	REG_WR(sc, BCE_EMAC_MDIO_COMM, val);
990 
991 	for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
992 		DELAY(10);
993 
994 		val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
995 		if (!(val & BCE_EMAC_MDIO_COMM_START_BUSY)) {
996 			DELAY(5);
997 
998 			val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
999 			val &= BCE_EMAC_MDIO_COMM_DATA;
1000 
1001 			break;
1002 		}
1003 	}
1004 
1005 	if (val & BCE_EMAC_MDIO_COMM_START_BUSY) {
1006 		BCE_PRINTF("%s(%d): Error: PHY read timeout! phy = %d, reg = 0x%04X\n",
1007 			__FILE__, __LINE__, phy, reg);
1008 		val = 0x0;
1009 	} else {
1010 		val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1011 	}
1012 
1013 	DBPRINT(sc, BCE_EXCESSIVE, "%s(): phy = %d, reg = 0x%04X, val = 0x%04X\n",
1014 		__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff);
1015 
1016 	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1017 		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1018 		val |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1019 
1020 		REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1021 		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1022 
1023 		DELAY(40);
1024 	}
1025 
1026 	return (val & 0xffff);
1027 
1028 }
1029 
1030 
1031 /****************************************************************************/
1032 /* PHY register write.                                                      */
1033 /*                                                                          */
1034 /* Implements register writes on the MII bus.                               */
1035 /*                                                                          */
1036 /* Returns:                                                                 */
1037 /*   The value of the register.                                             */
1038 /****************************************************************************/
1039 static int
1040 bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
1041 {
1042 	struct bce_softc *sc;
1043 	u32 val1;
1044 	int i;
1045 
1046 	sc = device_get_softc(dev);
1047 
1048 	/* Make sure we are accessing the correct PHY address. */
1049 	if (phy != sc->bce_phy_addr) {
1050 		DBPRINT(sc, BCE_WARN, "Invalid PHY address %d for PHY write!\n", phy);
1051 		return(0);
1052 	}
1053 
1054 	DBPRINT(sc, BCE_EXCESSIVE, "%s(): phy = %d, reg = 0x%04X, val = 0x%04X\n",
1055 		__FUNCTION__, phy, (u16) reg & 0xffff, (u16) val & 0xffff);
1056 
1057 	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1058 		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1059 		val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1060 
1061 		REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1062 		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1063 
1064 		DELAY(40);
1065 	}
1066 
1067 	val1 = BCE_MIPHY(phy) | BCE_MIREG(reg) | val |
1068 		BCE_EMAC_MDIO_COMM_COMMAND_WRITE |
1069 		BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT;
1070 	REG_WR(sc, BCE_EMAC_MDIO_COMM, val1);
1071 
1072 	for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1073 		DELAY(10);
1074 
1075 		val1 = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1076 		if (!(val1 & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1077 			DELAY(5);
1078 			break;
1079 		}
1080 	}
1081 
1082 	if (val1 & BCE_EMAC_MDIO_COMM_START_BUSY)
1083 		BCE_PRINTF("%s(%d): PHY write timeout!\n",
1084 			__FILE__, __LINE__);
1085 
1086 	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1087 		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1088 		val1 |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1089 
1090 		REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1091 		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1092 
1093 		DELAY(40);
1094 	}
1095 
1096 	return 0;
1097 }
1098 
1099 
1100 /****************************************************************************/
1101 /* MII bus status change.                                                   */
1102 /*                                                                          */
1103 /* Called by the MII bus driver when the PHY establishes link to set the    */
1104 /* MAC interface registers.                                                 */
1105 /*                                                                          */
1106 /* Returns:                                                                 */
1107 /*   Nothing.                                                               */
1108 /****************************************************************************/
1109 static void
1110 bce_miibus_statchg(device_t dev)
1111 {
1112 	struct bce_softc *sc;
1113 	struct mii_data *mii;
1114 
1115 	sc = device_get_softc(dev);
1116 
1117 	mii = device_get_softc(sc->bce_miibus);
1118 
1119 	DBPRINT(sc, BCE_INFO, "mii_media_active = 0x%08X\n",
1120 		mii->mii_media_active);
1121 
1122 #ifdef BCE_DEBUG
1123 	/* Decode the interface media flags. */
1124 	BCE_PRINTF("Media: ( ");
1125 	switch(IFM_TYPE(mii->mii_media_active)) {
1126 		case IFM_ETHER: printf("Ethernet )");
1127 			break;
1128 		default: printf("Unknown )");
1129 	}
1130 
1131 	printf(" Media Options: ( ");
1132 	switch(IFM_SUBTYPE(mii->mii_media_active)) {
1133 		case IFM_AUTO:    printf("Autoselect )"); break;
1134 		case IFM_MANUAL:  printf("Manual )"); break;
1135 		case IFM_NONE:    printf("None )"); break;
1136 		case IFM_10_T:    printf("10Base-T )"); break;
1137 		case IFM_100_TX:  printf("100Base-TX )"); break;
1138 		case IFM_1000_SX: printf("1000Base-SX )"); break;
1139 		case IFM_1000_T:  printf("1000Base-T )"); break;
1140 		default: printf("Other )");
1141 	}
1142 
1143 	printf(" Global Options: (");
1144 	if (mii->mii_media_active & IFM_FDX)
1145 		printf(" FullDuplex");
1146 	if (mii->mii_media_active & IFM_HDX)
1147 		printf(" HalfDuplex");
1148 	if (mii->mii_media_active & IFM_LOOP)
1149 		printf(" Loopback");
1150 	if (mii->mii_media_active & IFM_FLAG0)
1151 		printf(" Flag0");
1152 	if (mii->mii_media_active & IFM_FLAG1)
1153 		printf(" Flag1");
1154 	if (mii->mii_media_active & IFM_FLAG2)
1155 		printf(" Flag2");
1156 	printf(" )\n");
1157 #endif
1158 
1159 	BCE_CLRBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_PORT);
1160 
1161 	/* Set MII or GMII interface based on the speed negotiated by the PHY. */
1162 	if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
1163 	    IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX) {
1164 		DBPRINT(sc, BCE_INFO, "Setting GMII interface.\n");
1165 		BCE_SETBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_PORT_GMII);
1166 	} else {
1167 		DBPRINT(sc, BCE_INFO, "Setting MII interface.\n");
1168 		BCE_SETBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_PORT_MII);
1169 	}
1170 
1171 	/* Set half or full duplex based on the duplicity negotiated by the PHY. */
1172 	if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
1173 		DBPRINT(sc, BCE_INFO, "Setting Full-Duplex interface.\n");
1174 		BCE_CLRBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_HALF_DUPLEX);
1175 	} else {
1176 		DBPRINT(sc, BCE_INFO, "Setting Half-Duplex interface.\n");
1177 		BCE_SETBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_HALF_DUPLEX);
1178 	}
1179 }
1180 
1181 
1182 /****************************************************************************/
1183 /* Acquire NVRAM lock.                                                      */
1184 /*                                                                          */
1185 /* Before the NVRAM can be accessed the caller must acquire an NVRAM lock.  */
1186 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1187 /* for use by the driver.                                                   */
1188 /*                                                                          */
1189 /* Returns:                                                                 */
1190 /*   0 on success, positive value on failure.                               */
1191 /****************************************************************************/
1192 static int
1193 bce_acquire_nvram_lock(struct bce_softc *sc)
1194 {
1195 	u32 val;
1196 	int j;
1197 
1198 	DBPRINT(sc, BCE_VERBOSE, "Acquiring NVRAM lock.\n");
1199 
1200 	/* Request access to the flash interface. */
1201 	REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_SET2);
1202 	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1203 		val = REG_RD(sc, BCE_NVM_SW_ARB);
1204 		if (val & BCE_NVM_SW_ARB_ARB_ARB2)
1205 			break;
1206 
1207 		DELAY(5);
1208 	}
1209 
1210 	if (j >= NVRAM_TIMEOUT_COUNT) {
1211 		DBPRINT(sc, BCE_WARN, "Timeout acquiring NVRAM lock!\n");
1212 		return EBUSY;
1213 	}
1214 
1215 	return 0;
1216 }
1217 
1218 
1219 /****************************************************************************/
1220 /* Release NVRAM lock.                                                      */
1221 /*                                                                          */
1222 /* When the caller is finished accessing NVRAM the lock must be released.   */
1223 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1224 /* for use by the driver.                                                   */
1225 /*                                                                          */
1226 /* Returns:                                                                 */
1227 /*   0 on success, positive value on failure.                               */
1228 /****************************************************************************/
1229 static int
1230 bce_release_nvram_lock(struct bce_softc *sc)
1231 {
1232 	int j;
1233 	u32 val;
1234 
1235 	DBPRINT(sc, BCE_VERBOSE, "Releasing NVRAM lock.\n");
1236 
1237 	/*
1238 	 * Relinquish nvram interface.
1239 	 */
1240 	REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_CLR2);
1241 
1242 	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1243 		val = REG_RD(sc, BCE_NVM_SW_ARB);
1244 		if (!(val & BCE_NVM_SW_ARB_ARB_ARB2))
1245 			break;
1246 
1247 		DELAY(5);
1248 	}
1249 
1250 	if (j >= NVRAM_TIMEOUT_COUNT) {
1251 		DBPRINT(sc, BCE_WARN, "Timeout reeasing NVRAM lock!\n");
1252 		return EBUSY;
1253 	}
1254 
1255 	return 0;
1256 }
1257 
1258 
1259 #ifdef BCE_NVRAM_WRITE_SUPPORT
1260 /****************************************************************************/
1261 /* Enable NVRAM write access.                                               */
1262 /*                                                                          */
1263 /* Before writing to NVRAM the caller must enable NVRAM writes.             */
1264 /*                                                                          */
1265 /* Returns:                                                                 */
1266 /*   0 on success, positive value on failure.                               */
1267 /****************************************************************************/
1268 static int
1269 bce_enable_nvram_write(struct bce_softc *sc)
1270 {
1271 	u32 val;
1272 
1273 	DBPRINT(sc, BCE_VERBOSE, "Enabling NVRAM write.\n");
1274 
1275 	val = REG_RD(sc, BCE_MISC_CFG);
1276 	REG_WR(sc, BCE_MISC_CFG, val | BCE_MISC_CFG_NVM_WR_EN_PCI);
1277 
1278 	if (!sc->bce_flash_info->buffered) {
1279 		int j;
1280 
1281 		REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1282 		REG_WR(sc, BCE_NVM_COMMAND,	BCE_NVM_COMMAND_WREN | BCE_NVM_COMMAND_DOIT);
1283 
1284 		for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1285 			DELAY(5);
1286 
1287 			val = REG_RD(sc, BCE_NVM_COMMAND);
1288 			if (val & BCE_NVM_COMMAND_DONE)
1289 				break;
1290 		}
1291 
1292 		if (j >= NVRAM_TIMEOUT_COUNT) {
1293 			DBPRINT(sc, BCE_WARN, "Timeout writing NVRAM!\n");
1294 			return EBUSY;
1295 		}
1296 	}
1297 	return 0;
1298 }
1299 
1300 
1301 /****************************************************************************/
1302 /* Disable NVRAM write access.                                              */
1303 /*                                                                          */
1304 /* When the caller is finished writing to NVRAM write access must be        */
1305 /* disabled.                                                                */
1306 /*                                                                          */
1307 /* Returns:                                                                 */
1308 /*   Nothing.                                                               */
1309 /****************************************************************************/
1310 static void
1311 bce_disable_nvram_write(struct bce_softc *sc)
1312 {
1313 	u32 val;
1314 
1315 	DBPRINT(sc, BCE_VERBOSE,  "Disabling NVRAM write.\n");
1316 
1317 	val = REG_RD(sc, BCE_MISC_CFG);
1318 	REG_WR(sc, BCE_MISC_CFG, val & ~BCE_MISC_CFG_NVM_WR_EN);
1319 }
1320 #endif
1321 
1322 
1323 /****************************************************************************/
1324 /* Enable NVRAM access.                                                     */
1325 /*                                                                          */
1326 /* Before accessing NVRAM for read or write operations the caller must      */
1327 /* enabled NVRAM access.                                                    */
1328 /*                                                                          */
1329 /* Returns:                                                                 */
1330 /*   Nothing.                                                               */
1331 /****************************************************************************/
1332 static void
1333 bce_enable_nvram_access(struct bce_softc *sc)
1334 {
1335 	u32 val;
1336 
1337 	DBPRINT(sc, BCE_VERBOSE, "Enabling NVRAM access.\n");
1338 
1339 	val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
1340 	/* Enable both bits, even on read. */
1341 	REG_WR(sc, BCE_NVM_ACCESS_ENABLE,
1342 	       val | BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN);
1343 }
1344 
1345 
1346 /****************************************************************************/
1347 /* Disable NVRAM access.                                                    */
1348 /*                                                                          */
1349 /* When the caller is finished accessing NVRAM access must be disabled.     */
1350 /*                                                                          */
1351 /* Returns:                                                                 */
1352 /*   Nothing.                                                               */
1353 /****************************************************************************/
1354 static void
1355 bce_disable_nvram_access(struct bce_softc *sc)
1356 {
1357 	u32 val;
1358 
1359 	DBPRINT(sc, BCE_VERBOSE, "Disabling NVRAM access.\n");
1360 
1361 	val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
1362 
1363 	/* Disable both bits, even after read. */
1364 	REG_WR(sc, BCE_NVM_ACCESS_ENABLE,
1365 		val & ~(BCE_NVM_ACCESS_ENABLE_EN |
1366 			BCE_NVM_ACCESS_ENABLE_WR_EN));
1367 }
1368 
1369 
1370 #ifdef BCE_NVRAM_WRITE_SUPPORT
1371 /****************************************************************************/
1372 /* Erase NVRAM page before writing.                                         */
1373 /*                                                                          */
1374 /* Non-buffered flash parts require that a page be erased before it is      */
1375 /* written.                                                                 */
1376 /*                                                                          */
1377 /* Returns:                                                                 */
1378 /*   0 on success, positive value on failure.                               */
1379 /****************************************************************************/
1380 static int
1381 bce_nvram_erase_page(struct bce_softc *sc, u32 offset)
1382 {
1383 	u32 cmd;
1384 	int j;
1385 
1386 	/* Buffered flash doesn't require an erase. */
1387 	if (sc->bce_flash_info->buffered)
1388 		return 0;
1389 
1390 	DBPRINT(sc, BCE_VERBOSE, "Erasing NVRAM page.\n");
1391 
1392 	/* Build an erase command. */
1393 	cmd = BCE_NVM_COMMAND_ERASE | BCE_NVM_COMMAND_WR |
1394 	      BCE_NVM_COMMAND_DOIT;
1395 
1396 	/*
1397 	 * Clear the DONE bit separately, set the NVRAM adress to erase,
1398 	 * and issue the erase command.
1399 	 */
1400 	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1401 	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1402 	REG_WR(sc, BCE_NVM_COMMAND, cmd);
1403 
1404 	/* Wait for completion. */
1405 	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1406 		u32 val;
1407 
1408 		DELAY(5);
1409 
1410 		val = REG_RD(sc, BCE_NVM_COMMAND);
1411 		if (val & BCE_NVM_COMMAND_DONE)
1412 			break;
1413 	}
1414 
1415 	if (j >= NVRAM_TIMEOUT_COUNT) {
1416 		DBPRINT(sc, BCE_WARN, "Timeout erasing NVRAM.\n");
1417 		return EBUSY;
1418 	}
1419 
1420 	return 0;
1421 }
1422 #endif /* BCE_NVRAM_WRITE_SUPPORT */
1423 
1424 
1425 /****************************************************************************/
1426 /* Read a dword (32 bits) from NVRAM.                                       */
1427 /*                                                                          */
1428 /* Read a 32 bit word from NVRAM.  The caller is assumed to have already    */
1429 /* obtained the NVRAM lock and enabled the controller for NVRAM access.     */
1430 /*                                                                          */
1431 /* Returns:                                                                 */
1432 /*   0 on success and the 32 bit value read, positive value on failure.     */
1433 /****************************************************************************/
1434 static int
1435 bce_nvram_read_dword(struct bce_softc *sc, u32 offset, u8 *ret_val,
1436 							u32 cmd_flags)
1437 {
1438 	u32 cmd;
1439 	int i, rc = 0;
1440 
1441 	/* Build the command word. */
1442 	cmd = BCE_NVM_COMMAND_DOIT | cmd_flags;
1443 
1444 	/* Calculate the offset for buffered flash. */
1445 	if (sc->bce_flash_info->buffered) {
1446 		offset = ((offset / sc->bce_flash_info->page_size) <<
1447 			   sc->bce_flash_info->page_bits) +
1448 			  (offset % sc->bce_flash_info->page_size);
1449 	}
1450 
1451 	/*
1452 	 * Clear the DONE bit separately, set the address to read,
1453 	 * and issue the read.
1454 	 */
1455 	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1456 	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1457 	REG_WR(sc, BCE_NVM_COMMAND, cmd);
1458 
1459 	/* Wait for completion. */
1460 	for (i = 0; i < NVRAM_TIMEOUT_COUNT; i++) {
1461 		u32 val;
1462 
1463 		DELAY(5);
1464 
1465 		val = REG_RD(sc, BCE_NVM_COMMAND);
1466 		if (val & BCE_NVM_COMMAND_DONE) {
1467 			val = REG_RD(sc, BCE_NVM_READ);
1468 
1469 			val = bce_be32toh(val);
1470 			memcpy(ret_val, &val, 4);
1471 			break;
1472 		}
1473 	}
1474 
1475 	/* Check for errors. */
1476 	if (i >= NVRAM_TIMEOUT_COUNT) {
1477 		BCE_PRINTF("%s(%d): Timeout error reading NVRAM at offset 0x%08X!\n",
1478 			__FILE__, __LINE__, offset);
1479 		rc = EBUSY;
1480 	}
1481 
1482 	return(rc);
1483 }
1484 
1485 
1486 #ifdef BCE_NVRAM_WRITE_SUPPORT
1487 /****************************************************************************/
1488 /* Write a dword (32 bits) to NVRAM.                                        */
1489 /*                                                                          */
1490 /* Write a 32 bit word to NVRAM.  The caller is assumed to have already     */
1491 /* obtained the NVRAM lock, enabled the controller for NVRAM access, and    */
1492 /* enabled NVRAM write access.                                              */
1493 /*                                                                          */
1494 /* Returns:                                                                 */
1495 /*   0 on success, positive value on failure.                               */
1496 /****************************************************************************/
1497 static int
1498 bce_nvram_write_dword(struct bce_softc *sc, u32 offset, u8 *val,
1499 	u32 cmd_flags)
1500 {
1501 	u32 cmd, val32;
1502 	int j;
1503 
1504 	/* Build the command word. */
1505 	cmd = BCE_NVM_COMMAND_DOIT | BCE_NVM_COMMAND_WR | cmd_flags;
1506 
1507 	/* Calculate the offset for buffered flash. */
1508 	if (sc->bce_flash_info->buffered) {
1509 		offset = ((offset / sc->bce_flash_info->page_size) <<
1510 			  sc->bce_flash_info->page_bits) +
1511 			 (offset % sc->bce_flash_info->page_size);
1512 	}
1513 
1514 	/*
1515 	 * Clear the DONE bit separately, convert NVRAM data to big-endian,
1516 	 * set the NVRAM address to write, and issue the write command
1517 	 */
1518 	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1519 	memcpy(&val32, val, 4);
1520 	val32 = htobe32(val32);
1521 	REG_WR(sc, BCE_NVM_WRITE, val32);
1522 	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1523 	REG_WR(sc, BCE_NVM_COMMAND, cmd);
1524 
1525 	/* Wait for completion. */
1526 	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1527 		DELAY(5);
1528 
1529 		if (REG_RD(sc, BCE_NVM_COMMAND) & BCE_NVM_COMMAND_DONE)
1530 			break;
1531 	}
1532 	if (j >= NVRAM_TIMEOUT_COUNT) {
1533 		BCE_PRINTF("%s(%d): Timeout error writing NVRAM at offset 0x%08X\n",
1534 			__FILE__, __LINE__, offset);
1535 		return EBUSY;
1536 	}
1537 
1538 	return 0;
1539 }
1540 #endif /* BCE_NVRAM_WRITE_SUPPORT */
1541 
1542 
1543 /****************************************************************************/
1544 /* Initialize NVRAM access.                                                 */
1545 /*                                                                          */
1546 /* Identify the NVRAM device in use and prepare the NVRAM interface to      */
1547 /* access that device.                                                      */
1548 /*                                                                          */
1549 /* Returns:                                                                 */
1550 /*   0 on success, positive value on failure.                               */
1551 /****************************************************************************/
1552 static int
1553 bce_init_nvram(struct bce_softc *sc)
1554 {
1555 	u32 val;
1556 	int j, entry_count, rc;
1557 	struct flash_spec *flash;
1558 
1559 	DBPRINT(sc,BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
1560 
1561 	/* Determine the selected interface. */
1562 	val = REG_RD(sc, BCE_NVM_CFG1);
1563 
1564 	entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
1565 
1566 	rc = 0;
1567 
1568 	/*
1569 	 * Flash reconfiguration is required to support additional
1570 	 * NVRAM devices not directly supported in hardware.
1571 	 * Check if the flash interface was reconfigured
1572 	 * by the bootcode.
1573 	 */
1574 
1575 	if (val & 0x40000000) {
1576 		/* Flash interface reconfigured by bootcode. */
1577 
1578 		DBPRINT(sc,BCE_INFO_LOAD,
1579 			"bce_init_nvram(): Flash WAS reconfigured.\n");
1580 
1581 		for (j = 0, flash = &flash_table[0]; j < entry_count;
1582 		     j++, flash++) {
1583 			if ((val & FLASH_BACKUP_STRAP_MASK) ==
1584 			    (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
1585 				sc->bce_flash_info = flash;
1586 				break;
1587 			}
1588 		}
1589 	} else {
1590 		/* Flash interface not yet reconfigured. */
1591 		u32 mask;
1592 
1593 		DBPRINT(sc,BCE_INFO_LOAD,
1594 			"bce_init_nvram(): Flash was NOT reconfigured.\n");
1595 
1596 		if (val & (1 << 23))
1597 			mask = FLASH_BACKUP_STRAP_MASK;
1598 		else
1599 			mask = FLASH_STRAP_MASK;
1600 
1601 		/* Look for the matching NVRAM device configuration data. */
1602 		for (j = 0, flash = &flash_table[0]; j < entry_count; j++, flash++) {
1603 
1604 			/* Check if the device matches any of the known devices. */
1605 			if ((val & mask) == (flash->strapping & mask)) {
1606 				/* Found a device match. */
1607 				sc->bce_flash_info = flash;
1608 
1609 				/* Request access to the flash interface. */
1610 				if ((rc = bce_acquire_nvram_lock(sc)) != 0)
1611 					return rc;
1612 
1613 				/* Reconfigure the flash interface. */
1614 				bce_enable_nvram_access(sc);
1615 				REG_WR(sc, BCE_NVM_CFG1, flash->config1);
1616 				REG_WR(sc, BCE_NVM_CFG2, flash->config2);
1617 				REG_WR(sc, BCE_NVM_CFG3, flash->config3);
1618 				REG_WR(sc, BCE_NVM_WRITE1, flash->write1);
1619 				bce_disable_nvram_access(sc);
1620 				bce_release_nvram_lock(sc);
1621 
1622 				break;
1623 			}
1624 		}
1625 	}
1626 
1627 	/* Check if a matching device was found. */
1628 	if (j == entry_count) {
1629 		sc->bce_flash_info = NULL;
1630 		BCE_PRINTF("%s(%d): Unknown Flash NVRAM found!\n",
1631 			__FILE__, __LINE__);
1632 		rc = ENODEV;
1633 	}
1634 
1635 	/* Write the flash config data to the shared memory interface. */
1636 	val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_SHARED_HW_CFG_CONFIG2);
1637 	val &= BCE_SHARED_HW_CFG2_NVM_SIZE_MASK;
1638 	if (val)
1639 		sc->bce_flash_size = val;
1640 	else
1641 		sc->bce_flash_size = sc->bce_flash_info->total_size;
1642 
1643 	DBPRINT(sc, BCE_INFO_LOAD, "bce_init_nvram() flash->total_size = 0x%08X\n",
1644 		sc->bce_flash_info->total_size);
1645 
1646 	DBPRINT(sc,BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
1647 
1648 	return rc;
1649 }
1650 
1651 
1652 /****************************************************************************/
1653 /* Read an arbitrary range of data from NVRAM.                              */
1654 /*                                                                          */
1655 /* Prepares the NVRAM interface for access and reads the requested data     */
1656 /* into the supplied buffer.                                                */
1657 /*                                                                          */
1658 /* Returns:                                                                 */
1659 /*   0 on success and the data read, positive value on failure.             */
1660 /****************************************************************************/
1661 static int
1662 bce_nvram_read(struct bce_softc *sc, u32 offset, u8 *ret_buf,
1663 	int buf_size)
1664 {
1665 	int rc = 0;
1666 	u32 cmd_flags, offset32, len32, extra;
1667 
1668 	if (buf_size == 0)
1669 		return 0;
1670 
1671 	/* Request access to the flash interface. */
1672 	if ((rc = bce_acquire_nvram_lock(sc)) != 0)
1673 		return rc;
1674 
1675 	/* Enable access to flash interface */
1676 	bce_enable_nvram_access(sc);
1677 
1678 	len32 = buf_size;
1679 	offset32 = offset;
1680 	extra = 0;
1681 
1682 	cmd_flags = 0;
1683 
1684 	if (offset32 & 3) {
1685 		u8 buf[4];
1686 		u32 pre_len;
1687 
1688 		offset32 &= ~3;
1689 		pre_len = 4 - (offset & 3);
1690 
1691 		if (pre_len >= len32) {
1692 			pre_len = len32;
1693 			cmd_flags = BCE_NVM_COMMAND_FIRST | BCE_NVM_COMMAND_LAST;
1694 		}
1695 		else {
1696 			cmd_flags = BCE_NVM_COMMAND_FIRST;
1697 		}
1698 
1699 		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
1700 
1701 		if (rc)
1702 			return rc;
1703 
1704 		memcpy(ret_buf, buf + (offset & 3), pre_len);
1705 
1706 		offset32 += 4;
1707 		ret_buf += pre_len;
1708 		len32 -= pre_len;
1709 	}
1710 
1711 	if (len32 & 3) {
1712 		extra = 4 - (len32 & 3);
1713 		len32 = (len32 + 4) & ~3;
1714 	}
1715 
1716 	if (len32 == 4) {
1717 		u8 buf[4];
1718 
1719 		if (cmd_flags)
1720 			cmd_flags = BCE_NVM_COMMAND_LAST;
1721 		else
1722 			cmd_flags = BCE_NVM_COMMAND_FIRST |
1723 				    BCE_NVM_COMMAND_LAST;
1724 
1725 		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
1726 
1727 		memcpy(ret_buf, buf, 4 - extra);
1728 	}
1729 	else if (len32 > 0) {
1730 		u8 buf[4];
1731 
1732 		/* Read the first word. */
1733 		if (cmd_flags)
1734 			cmd_flags = 0;
1735 		else
1736 			cmd_flags = BCE_NVM_COMMAND_FIRST;
1737 
1738 		rc = bce_nvram_read_dword(sc, offset32, ret_buf, cmd_flags);
1739 
1740 		/* Advance to the next dword. */
1741 		offset32 += 4;
1742 		ret_buf += 4;
1743 		len32 -= 4;
1744 
1745 		while (len32 > 4 && rc == 0) {
1746 			rc = bce_nvram_read_dword(sc, offset32, ret_buf, 0);
1747 
1748 			/* Advance to the next dword. */
1749 			offset32 += 4;
1750 			ret_buf += 4;
1751 			len32 -= 4;
1752 		}
1753 
1754 		if (rc)
1755 			return rc;
1756 
1757 		cmd_flags = BCE_NVM_COMMAND_LAST;
1758 		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
1759 
1760 		memcpy(ret_buf, buf, 4 - extra);
1761 	}
1762 
1763 	/* Disable access to flash interface and release the lock. */
1764 	bce_disable_nvram_access(sc);
1765 	bce_release_nvram_lock(sc);
1766 
1767 	return rc;
1768 }
1769 
1770 
1771 #ifdef BCE_NVRAM_WRITE_SUPPORT
1772 /****************************************************************************/
1773 /* Write an arbitrary range of data from NVRAM.                             */
1774 /*                                                                          */
1775 /* Prepares the NVRAM interface for write access and writes the requested   */
1776 /* data from the supplied buffer.  The caller is responsible for            */
1777 /* calculating any appropriate CRCs.                                        */
1778 /*                                                                          */
1779 /* Returns:                                                                 */
1780 /*   0 on success, positive value on failure.                               */
1781 /****************************************************************************/
1782 static int
1783 bce_nvram_write(struct bce_softc *sc, u32 offset, u8 *data_buf,
1784 	int buf_size)
1785 {
1786 	u32 written, offset32, len32;
1787 	u8 *buf, start[4], end[4];
1788 	int rc = 0;
1789 	int align_start, align_end;
1790 
1791 	buf = data_buf;
1792 	offset32 = offset;
1793 	len32 = buf_size;
1794 	align_start = align_end = 0;
1795 
1796 	if ((align_start = (offset32 & 3))) {
1797 		offset32 &= ~3;
1798 		len32 += align_start;
1799 		if ((rc = bce_nvram_read(sc, offset32, start, 4)))
1800 			return rc;
1801 	}
1802 
1803 	if (len32 & 3) {
1804 	       	if ((len32 > 4) || !align_start) {
1805 			align_end = 4 - (len32 & 3);
1806 			len32 += align_end;
1807 			if ((rc = bce_nvram_read(sc, offset32 + len32 - 4,
1808 				end, 4))) {
1809 				return rc;
1810 			}
1811 		}
1812 	}
1813 
1814 	if (align_start || align_end) {
1815 		buf = malloc(len32, M_DEVBUF, M_NOWAIT);
1816 		if (buf == 0)
1817 			return ENOMEM;
1818 		if (align_start) {
1819 			memcpy(buf, start, 4);
1820 		}
1821 		if (align_end) {
1822 			memcpy(buf + len32 - 4, end, 4);
1823 		}
1824 		memcpy(buf + align_start, data_buf, buf_size);
1825 	}
1826 
1827 	written = 0;
1828 	while ((written < len32) && (rc == 0)) {
1829 		u32 page_start, page_end, data_start, data_end;
1830 		u32 addr, cmd_flags;
1831 		int i;
1832 		u8 flash_buffer[264];
1833 
1834 	    /* Find the page_start addr */
1835 		page_start = offset32 + written;
1836 		page_start -= (page_start % sc->bce_flash_info->page_size);
1837 		/* Find the page_end addr */
1838 		page_end = page_start + sc->bce_flash_info->page_size;
1839 		/* Find the data_start addr */
1840 		data_start = (written == 0) ? offset32 : page_start;
1841 		/* Find the data_end addr */
1842 		data_end = (page_end > offset32 + len32) ?
1843 			(offset32 + len32) : page_end;
1844 
1845 		/* Request access to the flash interface. */
1846 		if ((rc = bce_acquire_nvram_lock(sc)) != 0)
1847 			goto nvram_write_end;
1848 
1849 		/* Enable access to flash interface */
1850 		bce_enable_nvram_access(sc);
1851 
1852 		cmd_flags = BCE_NVM_COMMAND_FIRST;
1853 		if (sc->bce_flash_info->buffered == 0) {
1854 			int j;
1855 
1856 			/* Read the whole page into the buffer
1857 			 * (non-buffer flash only) */
1858 			for (j = 0; j < sc->bce_flash_info->page_size; j += 4) {
1859 				if (j == (sc->bce_flash_info->page_size - 4)) {
1860 					cmd_flags |= BCE_NVM_COMMAND_LAST;
1861 				}
1862 				rc = bce_nvram_read_dword(sc,
1863 					page_start + j,
1864 					&flash_buffer[j],
1865 					cmd_flags);
1866 
1867 				if (rc)
1868 					goto nvram_write_end;
1869 
1870 				cmd_flags = 0;
1871 			}
1872 		}
1873 
1874 		/* Enable writes to flash interface (unlock write-protect) */
1875 		if ((rc = bce_enable_nvram_write(sc)) != 0)
1876 			goto nvram_write_end;
1877 
1878 		/* Erase the page */
1879 		if ((rc = bce_nvram_erase_page(sc, page_start)) != 0)
1880 			goto nvram_write_end;
1881 
1882 		/* Re-enable the write again for the actual write */
1883 		bce_enable_nvram_write(sc);
1884 
1885 		/* Loop to write back the buffer data from page_start to
1886 		 * data_start */
1887 		i = 0;
1888 		if (sc->bce_flash_info->buffered == 0) {
1889 			for (addr = page_start; addr < data_start;
1890 				addr += 4, i += 4) {
1891 
1892 				rc = bce_nvram_write_dword(sc, addr,
1893 					&flash_buffer[i], cmd_flags);
1894 
1895 				if (rc != 0)
1896 					goto nvram_write_end;
1897 
1898 				cmd_flags = 0;
1899 			}
1900 		}
1901 
1902 		/* Loop to write the new data from data_start to data_end */
1903 		for (addr = data_start; addr < data_end; addr += 4, i++) {
1904 			if ((addr == page_end - 4) ||
1905 				((sc->bce_flash_info->buffered) &&
1906 				 (addr == data_end - 4))) {
1907 
1908 				cmd_flags |= BCE_NVM_COMMAND_LAST;
1909 			}
1910 			rc = bce_nvram_write_dword(sc, addr, buf,
1911 				cmd_flags);
1912 
1913 			if (rc != 0)
1914 				goto nvram_write_end;
1915 
1916 			cmd_flags = 0;
1917 			buf += 4;
1918 		}
1919 
1920 		/* Loop to write back the buffer data from data_end
1921 		 * to page_end */
1922 		if (sc->bce_flash_info->buffered == 0) {
1923 			for (addr = data_end; addr < page_end;
1924 				addr += 4, i += 4) {
1925 
1926 				if (addr == page_end-4) {
1927 					cmd_flags = BCE_NVM_COMMAND_LAST;
1928                 		}
1929 				rc = bce_nvram_write_dword(sc, addr,
1930 					&flash_buffer[i], cmd_flags);
1931 
1932 				if (rc != 0)
1933 					goto nvram_write_end;
1934 
1935 				cmd_flags = 0;
1936 			}
1937 		}
1938 
1939 		/* Disable writes to flash interface (lock write-protect) */
1940 		bce_disable_nvram_write(sc);
1941 
1942 		/* Disable access to flash interface */
1943 		bce_disable_nvram_access(sc);
1944 		bce_release_nvram_lock(sc);
1945 
1946 		/* Increment written */
1947 		written += data_end - data_start;
1948 	}
1949 
1950 nvram_write_end:
1951 	if (align_start || align_end)
1952 		free(buf, M_DEVBUF);
1953 
1954 	return rc;
1955 }
1956 #endif /* BCE_NVRAM_WRITE_SUPPORT */
1957 
1958 
1959 /****************************************************************************/
1960 /* Verifies that NVRAM is accessible and contains valid data.               */
1961 /*                                                                          */
1962 /* Reads the configuration data from NVRAM and verifies that the CRC is     */
1963 /* correct.                                                                 */
1964 /*                                                                          */
1965 /* Returns:                                                                 */
1966 /*   0 on success, positive value on failure.                               */
1967 /****************************************************************************/
1968 static int
1969 bce_nvram_test(struct bce_softc *sc)
1970 {
1971 	u32 buf[BCE_NVRAM_SIZE / 4];
1972 	u8 *data = (u8 *) buf;
1973 	int rc = 0;
1974 	u32 magic, csum;
1975 
1976 
1977 	/*
1978 	 * Check that the device NVRAM is valid by reading
1979 	 * the magic value at offset 0.
1980 	 */
1981 	if ((rc = bce_nvram_read(sc, 0, data, 4)) != 0)
1982 		goto bce_nvram_test_done;
1983 
1984 
1985     magic = bce_be32toh(buf[0]);
1986 	if (magic != BCE_NVRAM_MAGIC) {
1987 		rc = ENODEV;
1988 		BCE_PRINTF("%s(%d): Invalid NVRAM magic value! Expected: 0x%08X, "
1989 			"Found: 0x%08X\n",
1990 			__FILE__, __LINE__, BCE_NVRAM_MAGIC, magic);
1991 		goto bce_nvram_test_done;
1992 	}
1993 
1994 	/*
1995 	 * Verify that the device NVRAM includes valid
1996 	 * configuration data.
1997 	 */
1998 	if ((rc = bce_nvram_read(sc, 0x100, data, BCE_NVRAM_SIZE)) != 0)
1999 		goto bce_nvram_test_done;
2000 
2001 	csum = ether_crc32_le(data, 0x100);
2002 	if (csum != BCE_CRC32_RESIDUAL) {
2003 		rc = ENODEV;
2004 		BCE_PRINTF("%s(%d): Invalid Manufacturing Information NVRAM CRC! "
2005 			"Expected: 0x%08X, Found: 0x%08X\n",
2006 			__FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
2007 		goto bce_nvram_test_done;
2008 	}
2009 
2010 	csum = ether_crc32_le(data + 0x100, 0x100);
2011 	if (csum != BCE_CRC32_RESIDUAL) {
2012 		BCE_PRINTF("%s(%d): Invalid Feature Configuration Information "
2013 			"NVRAM CRC! Expected: 0x%08X, Found: 08%08X\n",
2014 			__FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
2015 		rc = ENODEV;
2016 	}
2017 
2018 bce_nvram_test_done:
2019 	return rc;
2020 }
2021 
2022 
2023 /****************************************************************************/
2024 /* Free any DMA memory owned by the driver.                                 */
2025 /*                                                                          */
2026 /* Scans through each data structre that requires DMA memory and frees      */
2027 /* the memory if allocated.                                                 */
2028 /*                                                                          */
2029 /* Returns:                                                                 */
2030 /*   Nothing.                                                               */
2031 /****************************************************************************/
2032 static void
2033 bce_dma_free(struct bce_softc *sc)
2034 {
2035 	int i;
2036 
2037 	DBPRINT(sc,BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
2038 
2039 	/* Destroy the status block. */
2040 	if (sc->status_block != NULL)
2041 		bus_dmamem_free(
2042 			sc->status_tag,
2043 		    sc->status_block,
2044 		    sc->status_map);
2045 
2046 	if (sc->status_map != NULL) {
2047 		bus_dmamap_unload(
2048 			sc->status_tag,
2049 		    sc->status_map);
2050 		bus_dmamap_destroy(sc->status_tag,
2051 		    sc->status_map);
2052 	}
2053 
2054 	if (sc->status_tag != NULL)
2055 		bus_dma_tag_destroy(sc->status_tag);
2056 
2057 
2058 	/* Destroy the statistics block. */
2059 	if (sc->stats_block != NULL)
2060 		bus_dmamem_free(
2061 			sc->stats_tag,
2062 		    sc->stats_block,
2063 		    sc->stats_map);
2064 
2065 	if (sc->stats_map != NULL) {
2066 		bus_dmamap_unload(
2067 			sc->stats_tag,
2068 		    sc->stats_map);
2069 		bus_dmamap_destroy(sc->stats_tag,
2070 		    sc->stats_map);
2071 	}
2072 
2073 	if (sc->stats_tag != NULL)
2074 		bus_dma_tag_destroy(sc->stats_tag);
2075 
2076 
2077 	/* Free, unmap and destroy all TX buffer descriptor chain pages. */
2078 	for (i = 0; i < TX_PAGES; i++ ) {
2079 		if (sc->tx_bd_chain[i] != NULL)
2080 			bus_dmamem_free(
2081 				sc->tx_bd_chain_tag,
2082 			    sc->tx_bd_chain[i],
2083 			    sc->tx_bd_chain_map[i]);
2084 
2085 		if (sc->tx_bd_chain_map[i] != NULL) {
2086 			bus_dmamap_unload(
2087 				sc->tx_bd_chain_tag,
2088 		    	sc->tx_bd_chain_map[i]);
2089 			bus_dmamap_destroy(
2090 				sc->tx_bd_chain_tag,
2091 			    sc->tx_bd_chain_map[i]);
2092 		}
2093 
2094 	}
2095 
2096 	/* Destroy the TX buffer descriptor tag. */
2097 	if (sc->tx_bd_chain_tag != NULL)
2098 		bus_dma_tag_destroy(sc->tx_bd_chain_tag);
2099 
2100 
2101 	/* Free, unmap and destroy all RX buffer descriptor chain pages. */
2102 	for (i = 0; i < RX_PAGES; i++ ) {
2103 		if (sc->rx_bd_chain[i] != NULL)
2104 			bus_dmamem_free(
2105 				sc->rx_bd_chain_tag,
2106 			    sc->rx_bd_chain[i],
2107 			    sc->rx_bd_chain_map[i]);
2108 
2109 		if (sc->rx_bd_chain_map[i] != NULL) {
2110 			bus_dmamap_unload(
2111 				sc->rx_bd_chain_tag,
2112 		    	sc->rx_bd_chain_map[i]);
2113 			bus_dmamap_destroy(
2114 				sc->rx_bd_chain_tag,
2115 			    sc->rx_bd_chain_map[i]);
2116 		}
2117 	}
2118 
2119 	/* Destroy the RX buffer descriptor tag. */
2120 	if (sc->rx_bd_chain_tag != NULL)
2121 		bus_dma_tag_destroy(sc->rx_bd_chain_tag);
2122 
2123 
2124 	/* Unload and destroy the TX mbuf maps. */
2125 	for (i = 0; i < TOTAL_TX_BD; i++) {
2126 		if (sc->tx_mbuf_map[i] != NULL) {
2127 			bus_dmamap_unload(sc->tx_mbuf_tag,
2128 				sc->tx_mbuf_map[i]);
2129 			bus_dmamap_destroy(sc->tx_mbuf_tag,
2130 	 			sc->tx_mbuf_map[i]);
2131 		}
2132 	}
2133 
2134 	/* Destroy the TX mbuf tag. */
2135 	if (sc->tx_mbuf_tag != NULL)
2136 		bus_dma_tag_destroy(sc->tx_mbuf_tag);
2137 
2138 
2139 	/* Unload and destroy the RX mbuf maps. */
2140 	for (i = 0; i < TOTAL_RX_BD; i++) {
2141 		if (sc->rx_mbuf_map[i] != NULL) {
2142 			bus_dmamap_unload(sc->rx_mbuf_tag,
2143 				sc->rx_mbuf_map[i]);
2144 			bus_dmamap_destroy(sc->rx_mbuf_tag,
2145 	 			sc->rx_mbuf_map[i]);
2146 		}
2147 	}
2148 
2149 	/* Destroy the RX mbuf tag. */
2150 	if (sc->rx_mbuf_tag != NULL)
2151 		bus_dma_tag_destroy(sc->rx_mbuf_tag);
2152 
2153 
2154 	/* Destroy the parent tag */
2155 	if (sc->parent_tag != NULL)
2156 		bus_dma_tag_destroy(sc->parent_tag);
2157 
2158 	DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
2159 
2160 }
2161 
2162 
2163 /****************************************************************************/
2164 /* Get DMA memory from the OS.                                              */
2165 /*                                                                          */
2166 /* Validates that the OS has provided DMA buffers in response to a          */
2167 /* bus_dmamap_load() call and saves the physical address of those buffers.  */
2168 /* When the callback is used the OS will return 0 for the mapping function  */
2169 /* (bus_dmamap_load()) so we use the value of map_arg->maxsegs to pass any  */
2170 /* failures back to the caller.                                             */
2171 /*                                                                          */
2172 /* Returns:                                                                 */
2173 /*   Nothing.                                                               */
2174 /****************************************************************************/
2175 static void
2176 bce_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
2177 {
2178 	bus_addr_t *busaddr = arg;
2179 
2180 	/* Simulate a mapping failure. */
2181 	DBRUNIF(DB_RANDOMTRUE(bce_debug_dma_map_addr_failure),
2182 		printf("bce: %s(%d): Simulating DMA mapping error.\n",
2183 			__FILE__, __LINE__);
2184 		error = ENOMEM);
2185 
2186 	/* Check for an error and signal the caller that an error occurred. */
2187 	if (error) {
2188 		printf("bce %s(%d): DMA mapping error! error = %d, "
2189 		    "nseg = %d\n", __FILE__, __LINE__, error, nseg);
2190 		*busaddr = 0;
2191 		return;
2192 	}
2193 
2194 	*busaddr = segs->ds_addr;
2195 	return;
2196 }
2197 
2198 
2199 /****************************************************************************/
2200 /* Allocate any DMA memory needed by the driver.                            */
2201 /*                                                                          */
2202 /* Allocates DMA memory needed for the various global structures needed by  */
2203 /* hardware.                                                                */
2204 /*                                                                          */
2205 /* Returns:                                                                 */
2206 /*   0 for success, positive value for failure.                             */
2207 /****************************************************************************/
2208 static int
2209 bce_dma_alloc(device_t dev)
2210 {
2211 	struct bce_softc *sc;
2212 	int i, error, rc = 0;
2213 	bus_addr_t busaddr;
2214 	bus_size_t max_size, max_seg_size;
2215 	int max_segments;
2216 
2217 	sc = device_get_softc(dev);
2218 
2219 	DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
2220 
2221 	/*
2222 	 * Allocate the parent bus DMA tag appropriate for PCI.
2223 	 */
2224 	if (bus_dma_tag_create(NULL,
2225 			1,
2226 			BCE_DMA_BOUNDARY,
2227 			sc->max_bus_addr,
2228 			BUS_SPACE_MAXADDR,
2229 			NULL, NULL,
2230 			MAXBSIZE,
2231 			BUS_SPACE_UNRESTRICTED,
2232 			BUS_SPACE_MAXSIZE_32BIT,
2233 			0,
2234 			NULL, NULL,
2235 			&sc->parent_tag)) {
2236 		BCE_PRINTF("%s(%d): Could not allocate parent DMA tag!\n",
2237 			__FILE__, __LINE__);
2238 		rc = ENOMEM;
2239 		goto bce_dma_alloc_exit;
2240 	}
2241 
2242 	/*
2243 	 * Create a DMA tag for the status block, allocate and clear the
2244 	 * memory, map the memory into DMA space, and fetch the physical
2245 	 * address of the block.
2246 	 */
2247 	if (bus_dma_tag_create(sc->parent_tag,
2248 	    	BCE_DMA_ALIGN,
2249 	    	BCE_DMA_BOUNDARY,
2250 	    	sc->max_bus_addr,
2251 	    	BUS_SPACE_MAXADDR,
2252 	    	NULL, NULL,
2253 	    	BCE_STATUS_BLK_SZ,
2254 	    	1,
2255 	    	BCE_STATUS_BLK_SZ,
2256 	    	0,
2257 	    	NULL, NULL,
2258 	    	&sc->status_tag)) {
2259 		BCE_PRINTF("%s(%d): Could not allocate status block DMA tag!\n",
2260 			__FILE__, __LINE__);
2261 		rc = ENOMEM;
2262 		goto bce_dma_alloc_exit;
2263 	}
2264 
2265 	if(bus_dmamem_alloc(sc->status_tag,
2266 	    	(void **)&sc->status_block,
2267 	    	BUS_DMA_NOWAIT,
2268 	    	&sc->status_map)) {
2269 		BCE_PRINTF("%s(%d): Could not allocate status block DMA memory!\n",
2270 			__FILE__, __LINE__);
2271 		rc = ENOMEM;
2272 		goto bce_dma_alloc_exit;
2273 	}
2274 
2275 	bzero((char *)sc->status_block, BCE_STATUS_BLK_SZ);
2276 
2277 	error = bus_dmamap_load(sc->status_tag,
2278 	    	sc->status_map,
2279 	    	sc->status_block,
2280 	    	BCE_STATUS_BLK_SZ,
2281 	    	bce_dma_map_addr,
2282 	    	&busaddr,
2283 	    	BUS_DMA_NOWAIT);
2284 
2285 	if (error) {
2286 		BCE_PRINTF("%s(%d): Could not map status block DMA memory!\n",
2287 			__FILE__, __LINE__);
2288 		rc = ENOMEM;
2289 		goto bce_dma_alloc_exit;
2290 	}
2291 
2292 	sc->status_block_paddr = busaddr;
2293 	/* DRC - Fix for 64 bit addresses. */
2294 	DBPRINT(sc, BCE_INFO, "status_block_paddr = 0x%08X\n",
2295 		(u32) sc->status_block_paddr);
2296 
2297 	/*
2298 	 * Create a DMA tag for the statistics block, allocate and clear the
2299 	 * memory, map the memory into DMA space, and fetch the physical
2300 	 * address of the block.
2301 	 */
2302 	if (bus_dma_tag_create(sc->parent_tag,
2303 	    	BCE_DMA_ALIGN,
2304 	    	BCE_DMA_BOUNDARY,
2305 	    	sc->max_bus_addr,
2306 	    	BUS_SPACE_MAXADDR,
2307 	    	NULL, NULL,
2308 	    	BCE_STATS_BLK_SZ,
2309 	    	1,
2310 	    	BCE_STATS_BLK_SZ,
2311 	    	0,
2312 	    	NULL, NULL,
2313 	    	&sc->stats_tag)) {
2314 		BCE_PRINTF("%s(%d): Could not allocate statistics block DMA tag!\n",
2315 			__FILE__, __LINE__);
2316 		rc = ENOMEM;
2317 		goto bce_dma_alloc_exit;
2318 	}
2319 
2320 	if (bus_dmamem_alloc(sc->stats_tag,
2321 	    	(void **)&sc->stats_block,
2322 	    	BUS_DMA_NOWAIT,
2323 	    	&sc->stats_map)) {
2324 		BCE_PRINTF("%s(%d): Could not allocate statistics block DMA memory!\n",
2325 			__FILE__, __LINE__);
2326 		rc = ENOMEM;
2327 		goto bce_dma_alloc_exit;
2328 	}
2329 
2330 	bzero((char *)sc->stats_block, BCE_STATS_BLK_SZ);
2331 
2332 	error = bus_dmamap_load(sc->stats_tag,
2333 	    	sc->stats_map,
2334 	    	sc->stats_block,
2335 	    	BCE_STATS_BLK_SZ,
2336 	    	bce_dma_map_addr,
2337 	    	&busaddr,
2338 	    	BUS_DMA_NOWAIT);
2339 
2340 	if(error) {
2341 		BCE_PRINTF("%s(%d): Could not map statistics block DMA memory!\n",
2342 			__FILE__, __LINE__);
2343 		rc = ENOMEM;
2344 		goto bce_dma_alloc_exit;
2345 	}
2346 
2347 	sc->stats_block_paddr = busaddr;
2348 	/* DRC - Fix for 64 bit address. */
2349 	DBPRINT(sc,BCE_INFO, "stats_block_paddr = 0x%08X\n",
2350 		(u32) sc->stats_block_paddr);
2351 
2352 	/*
2353 	 * Create a DMA tag for the TX buffer descriptor chain,
2354 	 * allocate and clear the  memory, and fetch the
2355 	 * physical address of the block.
2356 	 */
2357 	if(bus_dma_tag_create(sc->parent_tag,
2358 			BCM_PAGE_SIZE,
2359 		    BCE_DMA_BOUNDARY,
2360 			sc->max_bus_addr,
2361 			BUS_SPACE_MAXADDR,
2362 			NULL, NULL,
2363 			BCE_TX_CHAIN_PAGE_SZ,
2364 			1,
2365 			BCE_TX_CHAIN_PAGE_SZ,
2366 			0,
2367 			NULL, NULL,
2368 			&sc->tx_bd_chain_tag)) {
2369 		BCE_PRINTF("%s(%d): Could not allocate TX descriptor chain DMA tag!\n",
2370 			__FILE__, __LINE__);
2371 		rc = ENOMEM;
2372 		goto bce_dma_alloc_exit;
2373 	}
2374 
2375 	for (i = 0; i < TX_PAGES; i++) {
2376 
2377 		if(bus_dmamem_alloc(sc->tx_bd_chain_tag,
2378 	    		(void **)&sc->tx_bd_chain[i],
2379 	    		BUS_DMA_NOWAIT,
2380 		    	&sc->tx_bd_chain_map[i])) {
2381 			BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
2382 				"chain DMA memory!\n", __FILE__, __LINE__);
2383 			rc = ENOMEM;
2384 			goto bce_dma_alloc_exit;
2385 		}
2386 
2387 		error = bus_dmamap_load(sc->tx_bd_chain_tag,
2388 	    		sc->tx_bd_chain_map[i],
2389 	    		sc->tx_bd_chain[i],
2390 		    	BCE_TX_CHAIN_PAGE_SZ,
2391 		    	bce_dma_map_addr,
2392 	    		&busaddr,
2393 	    		BUS_DMA_NOWAIT);
2394 
2395 		if (error) {
2396 			BCE_PRINTF("%s(%d): Could not map TX descriptor chain DMA memory!\n",
2397 				__FILE__, __LINE__);
2398 			rc = ENOMEM;
2399 			goto bce_dma_alloc_exit;
2400 		}
2401 
2402 		sc->tx_bd_chain_paddr[i] = busaddr;
2403 		/* DRC - Fix for 64 bit systems. */
2404 		DBPRINT(sc, BCE_INFO, "tx_bd_chain_paddr[%d] = 0x%08X\n",
2405 			i, (u32) sc->tx_bd_chain_paddr[i]);
2406 	}
2407 
2408 	/* Check the required size before mapping to conserve resources. */
2409 	if (bce_tso_enable) {
2410 		max_size     = BCE_TSO_MAX_SIZE;
2411 		max_segments = BCE_MAX_SEGMENTS;
2412 		max_seg_size = BCE_TSO_MAX_SEG_SIZE;
2413 	} else {
2414 		max_size     = MCLBYTES * BCE_MAX_SEGMENTS;
2415 		max_segments = BCE_MAX_SEGMENTS;
2416 		max_seg_size = MCLBYTES;
2417 	}
2418 
2419 	/* Create a DMA tag for TX mbufs. */
2420 	if (bus_dma_tag_create(sc->parent_tag,
2421 			1,
2422 			BCE_DMA_BOUNDARY,
2423 			sc->max_bus_addr,
2424 			BUS_SPACE_MAXADDR,
2425 			NULL, NULL,
2426 			max_size,
2427 			max_segments,
2428 			max_seg_size,
2429 			0,
2430 			NULL, NULL,
2431 			&sc->tx_mbuf_tag)) {
2432 		BCE_PRINTF("%s(%d): Could not allocate TX mbuf DMA tag!\n",
2433 			__FILE__, __LINE__);
2434 		rc = ENOMEM;
2435 		goto bce_dma_alloc_exit;
2436 	}
2437 
2438 	/* Create DMA maps for the TX mbufs clusters. */
2439 	for (i = 0; i < TOTAL_TX_BD; i++) {
2440 		if (bus_dmamap_create(sc->tx_mbuf_tag, BUS_DMA_NOWAIT,
2441 			&sc->tx_mbuf_map[i])) {
2442 			BCE_PRINTF("%s(%d): Unable to create TX mbuf DMA map!\n",
2443 				__FILE__, __LINE__);
2444 			rc = ENOMEM;
2445 			goto bce_dma_alloc_exit;
2446 		}
2447 	}
2448 
2449 	/*
2450 	 * Create a DMA tag for the RX buffer descriptor chain,
2451 	 * allocate and clear the  memory, and fetch the physical
2452 	 * address of the blocks.
2453 	 */
2454 	if (bus_dma_tag_create(sc->parent_tag,
2455 			BCM_PAGE_SIZE,
2456 			BCE_DMA_BOUNDARY,
2457 			BUS_SPACE_MAXADDR,
2458 			sc->max_bus_addr,
2459 			NULL, NULL,
2460 			BCE_RX_CHAIN_PAGE_SZ,
2461 			1,
2462 			BCE_RX_CHAIN_PAGE_SZ,
2463 			0,
2464 			NULL, NULL,
2465 			&sc->rx_bd_chain_tag)) {
2466 		BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain DMA tag!\n",
2467 			__FILE__, __LINE__);
2468 		rc = ENOMEM;
2469 		goto bce_dma_alloc_exit;
2470 	}
2471 
2472 	for (i = 0; i < RX_PAGES; i++) {
2473 
2474 		if (bus_dmamem_alloc(sc->rx_bd_chain_tag,
2475 	    		(void **)&sc->rx_bd_chain[i],
2476 	    		BUS_DMA_NOWAIT,
2477 		    	&sc->rx_bd_chain_map[i])) {
2478 			BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain "
2479 				"DMA memory!\n", __FILE__, __LINE__);
2480 			rc = ENOMEM;
2481 			goto bce_dma_alloc_exit;
2482 		}
2483 
2484 		bzero((char *)sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ);
2485 
2486 		error = bus_dmamap_load(sc->rx_bd_chain_tag,
2487 	    		sc->rx_bd_chain_map[i],
2488 	    		sc->rx_bd_chain[i],
2489 		    	BCE_RX_CHAIN_PAGE_SZ,
2490 		    	bce_dma_map_addr,
2491 	    		&busaddr,
2492 	    		BUS_DMA_NOWAIT);
2493 
2494 		if (error) {
2495 			BCE_PRINTF("%s(%d): Could not map RX descriptor chain DMA memory!\n",
2496 				__FILE__, __LINE__);
2497 			rc = ENOMEM;
2498 			goto bce_dma_alloc_exit;
2499 		}
2500 
2501 		sc->rx_bd_chain_paddr[i] = busaddr;
2502 		/* DRC - Fix for 64 bit systems. */
2503 		DBPRINT(sc, BCE_INFO, "rx_bd_chain_paddr[%d] = 0x%08X\n",
2504 			i, (u32) sc->rx_bd_chain_paddr[i]);
2505 	}
2506 
2507 	/*
2508 	 * Create a DMA tag for RX mbufs.
2509 	 */
2510 	if (bus_dma_tag_create(sc->parent_tag,
2511 			1,
2512 			BCE_DMA_BOUNDARY,
2513 			sc->max_bus_addr,
2514 			BUS_SPACE_MAXADDR,
2515 			NULL, NULL,
2516 			MJUM9BYTES,
2517 			BCE_MAX_SEGMENTS,
2518 			MJUM9BYTES,
2519 			0,
2520 			NULL, NULL,
2521 	    	&sc->rx_mbuf_tag)) {
2522 		BCE_PRINTF("%s(%d): Could not allocate RX mbuf DMA tag!\n",
2523 			__FILE__, __LINE__);
2524 		rc = ENOMEM;
2525 		goto bce_dma_alloc_exit;
2526 	}
2527 
2528 	/* Create DMA maps for the RX mbuf clusters. */
2529 	for (i = 0; i < TOTAL_RX_BD; i++) {
2530 		if (bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_NOWAIT,
2531 				&sc->rx_mbuf_map[i])) {
2532 			BCE_PRINTF("%s(%d): Unable to create RX mbuf DMA map!\n",
2533 				__FILE__, __LINE__);
2534 			rc = ENOMEM;
2535 			goto bce_dma_alloc_exit;
2536 		}
2537 	}
2538 
2539 bce_dma_alloc_exit:
2540 	DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
2541 
2542 	return(rc);
2543 }
2544 
2545 
2546 /****************************************************************************/
2547 /* Release all resources used by the driver.                                */
2548 /*                                                                          */
2549 /* Releases all resources acquired by the driver including interrupts,      */
2550 /* interrupt handler, interfaces, mutexes, and DMA memory.                  */
2551 /*                                                                          */
2552 /* Returns:                                                                 */
2553 /*   Nothing.                                                               */
2554 /****************************************************************************/
2555 static void
2556 bce_release_resources(struct bce_softc *sc)
2557 {
2558 	device_t dev;
2559 
2560 	DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
2561 
2562 	dev = sc->bce_dev;
2563 
2564 	bce_dma_free(sc);
2565 
2566 	if (sc->bce_intrhand != NULL) {
2567 		DBPRINT(sc, BCE_INFO_RESET, "Removing interrupt handler.\n");
2568 		bus_teardown_intr(dev, sc->bce_res_irq, sc->bce_intrhand);
2569 	}
2570 
2571 	if (sc->bce_res_irq != NULL) {
2572 		DBPRINT(sc, BCE_INFO_RESET, "Releasing IRQ.\n");
2573 		bus_release_resource(dev, SYS_RES_IRQ, sc->bce_flags & BCE_USING_MSI_FLAG ? 1 : 0,
2574 			sc->bce_res_irq);
2575 	}
2576 
2577 	if (sc->bce_flags & BCE_USING_MSI_FLAG) {
2578 		DBPRINT(sc, BCE_INFO_RESET, "Releasing MSI vector.\n");
2579 		pci_release_msi(dev);
2580 	}
2581 
2582 	if (sc->bce_res_mem != NULL) {
2583 		DBPRINT(sc, BCE_INFO_RESET, "Releasing PCI memory.\n");
2584 		bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), sc->bce_res_mem);
2585 	}
2586 
2587 	if (sc->bce_ifp != NULL) {
2588 		DBPRINT(sc, BCE_INFO_RESET, "Releasing IF.\n");
2589 		if_free(sc->bce_ifp);
2590 	}
2591 
2592 	if (mtx_initialized(&sc->bce_mtx))
2593 		BCE_LOCK_DESTROY(sc);
2594 
2595 	DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
2596 
2597 }
2598 
2599 
2600 /****************************************************************************/
2601 /* Firmware synchronization.                                                */
2602 /*                                                                          */
2603 /* Before performing certain events such as a chip reset, synchronize with  */
2604 /* the firmware first.                                                      */
2605 /*                                                                          */
2606 /* Returns:                                                                 */
2607 /*   0 for success, positive value for failure.                             */
2608 /****************************************************************************/
2609 static int
2610 bce_fw_sync(struct bce_softc *sc, u32 msg_data)
2611 {
2612 	int i, rc = 0;
2613 	u32 val;
2614 
2615 	/* Don't waste any time if we've timed out before. */
2616 	if (sc->bce_fw_timed_out) {
2617 		rc = EBUSY;
2618 		goto bce_fw_sync_exit;
2619 	}
2620 
2621 	/* Increment the message sequence number. */
2622 	sc->bce_fw_wr_seq++;
2623 	msg_data |= sc->bce_fw_wr_seq;
2624 
2625  	DBPRINT(sc, BCE_VERBOSE, "bce_fw_sync(): msg_data = 0x%08X\n", msg_data);
2626 
2627 	/* Send the message to the bootcode driver mailbox. */
2628 	REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_MB, msg_data);
2629 
2630 	/* Wait for the bootcode to acknowledge the message. */
2631 	for (i = 0; i < FW_ACK_TIME_OUT_MS; i++) {
2632 		/* Check for a response in the bootcode firmware mailbox. */
2633 		val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_FW_MB);
2634 		if ((val & BCE_FW_MSG_ACK) == (msg_data & BCE_DRV_MSG_SEQ))
2635 			break;
2636 		DELAY(1000);
2637 	}
2638 
2639 	/* If we've timed out, tell the bootcode that we've stopped waiting. */
2640 	if (((val & BCE_FW_MSG_ACK) != (msg_data & BCE_DRV_MSG_SEQ)) &&
2641 		((msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0)) {
2642 
2643 		BCE_PRINTF("%s(%d): Firmware synchronization timeout! "
2644 			"msg_data = 0x%08X\n",
2645 			__FILE__, __LINE__, msg_data);
2646 
2647 		msg_data &= ~BCE_DRV_MSG_CODE;
2648 		msg_data |= BCE_DRV_MSG_CODE_FW_TIMEOUT;
2649 
2650 		REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_MB, msg_data);
2651 
2652 		sc->bce_fw_timed_out = 1;
2653 		rc = EBUSY;
2654 	}
2655 
2656 bce_fw_sync_exit:
2657 	return (rc);
2658 }
2659 
2660 
2661 /****************************************************************************/
2662 /* Load Receive Virtual 2 Physical (RV2P) processor firmware.               */
2663 /*                                                                          */
2664 /* Returns:                                                                 */
2665 /*   Nothing.                                                               */
2666 /****************************************************************************/
2667 static void
2668 bce_load_rv2p_fw(struct bce_softc *sc, u32 *rv2p_code,
2669 	u32 rv2p_code_len, u32 rv2p_proc)
2670 {
2671 	int i;
2672 	u32 val;
2673 
2674 	for (i = 0; i < rv2p_code_len; i += 8) {
2675 		REG_WR(sc, BCE_RV2P_INSTR_HIGH, *rv2p_code);
2676 		rv2p_code++;
2677 		REG_WR(sc, BCE_RV2P_INSTR_LOW, *rv2p_code);
2678 		rv2p_code++;
2679 
2680 		if (rv2p_proc == RV2P_PROC1) {
2681 			val = (i / 8) | BCE_RV2P_PROC1_ADDR_CMD_RDWR;
2682 			REG_WR(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
2683 		}
2684 		else {
2685 			val = (i / 8) | BCE_RV2P_PROC2_ADDR_CMD_RDWR;
2686 			REG_WR(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
2687 		}
2688 	}
2689 
2690 	/* Reset the processor, un-stall is done later. */
2691 	if (rv2p_proc == RV2P_PROC1) {
2692 		REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC1_RESET);
2693 	}
2694 	else {
2695 		REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC2_RESET);
2696 	}
2697 }
2698 
2699 
2700 /****************************************************************************/
2701 /* Load RISC processor firmware.                                            */
2702 /*                                                                          */
2703 /* Loads firmware from the file if_bcefw.h into the scratchpad memory       */
2704 /* associated with a particular processor.                                  */
2705 /*                                                                          */
2706 /* Returns:                                                                 */
2707 /*   Nothing.                                                               */
2708 /****************************************************************************/
2709 static void
2710 bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
2711 	struct fw_info *fw)
2712 {
2713 	u32 offset;
2714 	u32 val;
2715 
2716 	/* Halt the CPU. */
2717 	val = REG_RD_IND(sc, cpu_reg->mode);
2718 	val |= cpu_reg->mode_value_halt;
2719 	REG_WR_IND(sc, cpu_reg->mode, val);
2720 	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
2721 
2722 	/* Load the Text area. */
2723 	offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
2724 	if (fw->text) {
2725 		int j;
2726 
2727 		for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
2728 			REG_WR_IND(sc, offset, fw->text[j]);
2729 	        }
2730 	}
2731 
2732 	/* Load the Data area. */
2733 	offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
2734 	if (fw->data) {
2735 		int j;
2736 
2737 		for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
2738 			REG_WR_IND(sc, offset, fw->data[j]);
2739 		}
2740 	}
2741 
2742 	/* Load the SBSS area. */
2743 	offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
2744 	if (fw->sbss) {
2745 		int j;
2746 
2747 		for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
2748 			REG_WR_IND(sc, offset, fw->sbss[j]);
2749 		}
2750 	}
2751 
2752 	/* Load the BSS area. */
2753 	offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
2754 	if (fw->bss) {
2755 		int j;
2756 
2757 		for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
2758 			REG_WR_IND(sc, offset, fw->bss[j]);
2759 		}
2760 	}
2761 
2762 	/* Load the Read-Only area. */
2763 	offset = cpu_reg->spad_base +
2764 		(fw->rodata_addr - cpu_reg->mips_view_base);
2765 	if (fw->rodata) {
2766 		int j;
2767 
2768 		for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
2769 			REG_WR_IND(sc, offset, fw->rodata[j]);
2770 		}
2771 	}
2772 
2773 	/* Clear the pre-fetch instruction. */
2774 	REG_WR_IND(sc, cpu_reg->inst, 0);
2775 	REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
2776 
2777 	/* Start the CPU. */
2778 	val = REG_RD_IND(sc, cpu_reg->mode);
2779 	val &= ~cpu_reg->mode_value_halt;
2780 	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
2781 	REG_WR_IND(sc, cpu_reg->mode, val);
2782 }
2783 
2784 
2785 /****************************************************************************/
2786 /* Initialize the RV2P, RX, TX, TPAT, and COM CPUs.                         */
2787 /*                                                                          */
2788 /* Loads the firmware for each CPU and starts the CPU.                      */
2789 /*                                                                          */
2790 /* Returns:                                                                 */
2791 /*   Nothing.                                                               */
2792 /****************************************************************************/
2793 static void
2794 bce_init_cpus(struct bce_softc *sc)
2795 {
2796 	struct cpu_reg cpu_reg;
2797 	struct fw_info fw;
2798 
2799 	/* Initialize the RV2P processor. */
2800 	bce_load_rv2p_fw(sc, bce_rv2p_proc1, sizeof(bce_rv2p_proc1), RV2P_PROC1);
2801 	bce_load_rv2p_fw(sc, bce_rv2p_proc2, sizeof(bce_rv2p_proc2), RV2P_PROC2);
2802 
2803 	/* Initialize the RX Processor. */
2804 	cpu_reg.mode = BCE_RXP_CPU_MODE;
2805 	cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
2806 	cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
2807 	cpu_reg.state = BCE_RXP_CPU_STATE;
2808 	cpu_reg.state_value_clear = 0xffffff;
2809 	cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
2810 	cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
2811 	cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
2812 	cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
2813 	cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
2814 	cpu_reg.spad_base = BCE_RXP_SCRATCH;
2815 	cpu_reg.mips_view_base = 0x8000000;
2816 
2817 	fw.ver_major = bce_RXP_b06FwReleaseMajor;
2818 	fw.ver_minor = bce_RXP_b06FwReleaseMinor;
2819 	fw.ver_fix = bce_RXP_b06FwReleaseFix;
2820 	fw.start_addr = bce_RXP_b06FwStartAddr;
2821 
2822 	fw.text_addr = bce_RXP_b06FwTextAddr;
2823 	fw.text_len = bce_RXP_b06FwTextLen;
2824 	fw.text_index = 0;
2825 	fw.text = bce_RXP_b06FwText;
2826 
2827 	fw.data_addr = bce_RXP_b06FwDataAddr;
2828 	fw.data_len = bce_RXP_b06FwDataLen;
2829 	fw.data_index = 0;
2830 	fw.data = bce_RXP_b06FwData;
2831 
2832 	fw.sbss_addr = bce_RXP_b06FwSbssAddr;
2833 	fw.sbss_len = bce_RXP_b06FwSbssLen;
2834 	fw.sbss_index = 0;
2835 	fw.sbss = bce_RXP_b06FwSbss;
2836 
2837 	fw.bss_addr = bce_RXP_b06FwBssAddr;
2838 	fw.bss_len = bce_RXP_b06FwBssLen;
2839 	fw.bss_index = 0;
2840 	fw.bss = bce_RXP_b06FwBss;
2841 
2842 	fw.rodata_addr = bce_RXP_b06FwRodataAddr;
2843 	fw.rodata_len = bce_RXP_b06FwRodataLen;
2844 	fw.rodata_index = 0;
2845 	fw.rodata = bce_RXP_b06FwRodata;
2846 
2847 	DBPRINT(sc, BCE_INFO_RESET, "Loading RX firmware.\n");
2848 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
2849 
2850 	/* Initialize the TX Processor. */
2851 	cpu_reg.mode = BCE_TXP_CPU_MODE;
2852 	cpu_reg.mode_value_halt = BCE_TXP_CPU_MODE_SOFT_HALT;
2853 	cpu_reg.mode_value_sstep = BCE_TXP_CPU_MODE_STEP_ENA;
2854 	cpu_reg.state = BCE_TXP_CPU_STATE;
2855 	cpu_reg.state_value_clear = 0xffffff;
2856 	cpu_reg.gpr0 = BCE_TXP_CPU_REG_FILE;
2857 	cpu_reg.evmask = BCE_TXP_CPU_EVENT_MASK;
2858 	cpu_reg.pc = BCE_TXP_CPU_PROGRAM_COUNTER;
2859 	cpu_reg.inst = BCE_TXP_CPU_INSTRUCTION;
2860 	cpu_reg.bp = BCE_TXP_CPU_HW_BREAKPOINT;
2861 	cpu_reg.spad_base = BCE_TXP_SCRATCH;
2862 	cpu_reg.mips_view_base = 0x8000000;
2863 
2864 	fw.ver_major = bce_TXP_b06FwReleaseMajor;
2865 	fw.ver_minor = bce_TXP_b06FwReleaseMinor;
2866 	fw.ver_fix = bce_TXP_b06FwReleaseFix;
2867 	fw.start_addr = bce_TXP_b06FwStartAddr;
2868 
2869 	fw.text_addr = bce_TXP_b06FwTextAddr;
2870 	fw.text_len = bce_TXP_b06FwTextLen;
2871 	fw.text_index = 0;
2872 	fw.text = bce_TXP_b06FwText;
2873 
2874 	fw.data_addr = bce_TXP_b06FwDataAddr;
2875 	fw.data_len = bce_TXP_b06FwDataLen;
2876 	fw.data_index = 0;
2877 	fw.data = bce_TXP_b06FwData;
2878 
2879 	fw.sbss_addr = bce_TXP_b06FwSbssAddr;
2880 	fw.sbss_len = bce_TXP_b06FwSbssLen;
2881 	fw.sbss_index = 0;
2882 	fw.sbss = bce_TXP_b06FwSbss;
2883 
2884 	fw.bss_addr = bce_TXP_b06FwBssAddr;
2885 	fw.bss_len = bce_TXP_b06FwBssLen;
2886 	fw.bss_index = 0;
2887 	fw.bss = bce_TXP_b06FwBss;
2888 
2889 	fw.rodata_addr = bce_TXP_b06FwRodataAddr;
2890 	fw.rodata_len = bce_TXP_b06FwRodataLen;
2891 	fw.rodata_index = 0;
2892 	fw.rodata = bce_TXP_b06FwRodata;
2893 
2894 	DBPRINT(sc, BCE_INFO_RESET, "Loading TX firmware.\n");
2895 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
2896 
2897 	/* Initialize the TX Patch-up Processor. */
2898 	cpu_reg.mode = BCE_TPAT_CPU_MODE;
2899 	cpu_reg.mode_value_halt = BCE_TPAT_CPU_MODE_SOFT_HALT;
2900 	cpu_reg.mode_value_sstep = BCE_TPAT_CPU_MODE_STEP_ENA;
2901 	cpu_reg.state = BCE_TPAT_CPU_STATE;
2902 	cpu_reg.state_value_clear = 0xffffff;
2903 	cpu_reg.gpr0 = BCE_TPAT_CPU_REG_FILE;
2904 	cpu_reg.evmask = BCE_TPAT_CPU_EVENT_MASK;
2905 	cpu_reg.pc = BCE_TPAT_CPU_PROGRAM_COUNTER;
2906 	cpu_reg.inst = BCE_TPAT_CPU_INSTRUCTION;
2907 	cpu_reg.bp = BCE_TPAT_CPU_HW_BREAKPOINT;
2908 	cpu_reg.spad_base = BCE_TPAT_SCRATCH;
2909 	cpu_reg.mips_view_base = 0x8000000;
2910 
2911 	fw.ver_major = bce_TPAT_b06FwReleaseMajor;
2912 	fw.ver_minor = bce_TPAT_b06FwReleaseMinor;
2913 	fw.ver_fix = bce_TPAT_b06FwReleaseFix;
2914 	fw.start_addr = bce_TPAT_b06FwStartAddr;
2915 
2916 	fw.text_addr = bce_TPAT_b06FwTextAddr;
2917 	fw.text_len = bce_TPAT_b06FwTextLen;
2918 	fw.text_index = 0;
2919 	fw.text = bce_TPAT_b06FwText;
2920 
2921 	fw.data_addr = bce_TPAT_b06FwDataAddr;
2922 	fw.data_len = bce_TPAT_b06FwDataLen;
2923 	fw.data_index = 0;
2924 	fw.data = bce_TPAT_b06FwData;
2925 
2926 	fw.sbss_addr = bce_TPAT_b06FwSbssAddr;
2927 	fw.sbss_len = bce_TPAT_b06FwSbssLen;
2928 	fw.sbss_index = 0;
2929 	fw.sbss = bce_TPAT_b06FwSbss;
2930 
2931 	fw.bss_addr = bce_TPAT_b06FwBssAddr;
2932 	fw.bss_len = bce_TPAT_b06FwBssLen;
2933 	fw.bss_index = 0;
2934 	fw.bss = bce_TPAT_b06FwBss;
2935 
2936 	fw.rodata_addr = bce_TPAT_b06FwRodataAddr;
2937 	fw.rodata_len = bce_TPAT_b06FwRodataLen;
2938 	fw.rodata_index = 0;
2939 	fw.rodata = bce_TPAT_b06FwRodata;
2940 
2941 	DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n");
2942 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
2943 
2944 	/* Initialize the Completion Processor. */
2945 	cpu_reg.mode = BCE_COM_CPU_MODE;
2946 	cpu_reg.mode_value_halt = BCE_COM_CPU_MODE_SOFT_HALT;
2947 	cpu_reg.mode_value_sstep = BCE_COM_CPU_MODE_STEP_ENA;
2948 	cpu_reg.state = BCE_COM_CPU_STATE;
2949 	cpu_reg.state_value_clear = 0xffffff;
2950 	cpu_reg.gpr0 = BCE_COM_CPU_REG_FILE;
2951 	cpu_reg.evmask = BCE_COM_CPU_EVENT_MASK;
2952 	cpu_reg.pc = BCE_COM_CPU_PROGRAM_COUNTER;
2953 	cpu_reg.inst = BCE_COM_CPU_INSTRUCTION;
2954 	cpu_reg.bp = BCE_COM_CPU_HW_BREAKPOINT;
2955 	cpu_reg.spad_base = BCE_COM_SCRATCH;
2956 	cpu_reg.mips_view_base = 0x8000000;
2957 
2958 	fw.ver_major = bce_COM_b06FwReleaseMajor;
2959 	fw.ver_minor = bce_COM_b06FwReleaseMinor;
2960 	fw.ver_fix = bce_COM_b06FwReleaseFix;
2961 	fw.start_addr = bce_COM_b06FwStartAddr;
2962 
2963 	fw.text_addr = bce_COM_b06FwTextAddr;
2964 	fw.text_len = bce_COM_b06FwTextLen;
2965 	fw.text_index = 0;
2966 	fw.text = bce_COM_b06FwText;
2967 
2968 	fw.data_addr = bce_COM_b06FwDataAddr;
2969 	fw.data_len = bce_COM_b06FwDataLen;
2970 	fw.data_index = 0;
2971 	fw.data = bce_COM_b06FwData;
2972 
2973 	fw.sbss_addr = bce_COM_b06FwSbssAddr;
2974 	fw.sbss_len = bce_COM_b06FwSbssLen;
2975 	fw.sbss_index = 0;
2976 	fw.sbss = bce_COM_b06FwSbss;
2977 
2978 	fw.bss_addr = bce_COM_b06FwBssAddr;
2979 	fw.bss_len = bce_COM_b06FwBssLen;
2980 	fw.bss_index = 0;
2981 	fw.bss = bce_COM_b06FwBss;
2982 
2983 	fw.rodata_addr = bce_COM_b06FwRodataAddr;
2984 	fw.rodata_len = bce_COM_b06FwRodataLen;
2985 	fw.rodata_index = 0;
2986 	fw.rodata = bce_COM_b06FwRodata;
2987 
2988 	DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n");
2989 	bce_load_cpu_fw(sc, &cpu_reg, &fw);
2990 }
2991 
2992 
2993 /****************************************************************************/
2994 /* Initialize context memory.                                               */
2995 /*                                                                          */
2996 /* Clears the memory associated with each Context ID (CID).                 */
2997 /*                                                                          */
2998 /* Returns:                                                                 */
2999 /*   Nothing.                                                               */
3000 /****************************************************************************/
3001 static void
3002 bce_init_context(struct bce_softc *sc)
3003 {
3004 	u32 vcid;
3005 
3006 	vcid = 96;
3007 	while (vcid) {
3008 		u32 vcid_addr, pcid_addr, offset;
3009 
3010 		vcid--;
3011 
3012    		vcid_addr = GET_CID_ADDR(vcid);
3013 		pcid_addr = vcid_addr;
3014 
3015 		REG_WR(sc, BCE_CTX_VIRT_ADDR, 0x00);
3016 		REG_WR(sc, BCE_CTX_PAGE_TBL, pcid_addr);
3017 
3018 		/* Zero out the context. */
3019 		for (offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
3020 			CTX_WR(sc, 0x00, offset, 0);
3021 		}
3022 
3023 		REG_WR(sc, BCE_CTX_VIRT_ADDR, vcid_addr);
3024 		REG_WR(sc, BCE_CTX_PAGE_TBL, pcid_addr);
3025 	}
3026 }
3027 
3028 
3029 /****************************************************************************/
3030 /* Fetch the permanent MAC address of the controller.                       */
3031 /*                                                                          */
3032 /* Returns:                                                                 */
3033 /*   Nothing.                                                               */
3034 /****************************************************************************/
3035 static void
3036 bce_get_mac_addr(struct bce_softc *sc)
3037 {
3038 	u32 mac_lo = 0, mac_hi = 0;
3039 
3040 	/*
3041 	 * The NetXtreme II bootcode populates various NIC
3042 	 * power-on and runtime configuration items in a
3043 	 * shared memory area.  The factory configured MAC
3044 	 * address is available from both NVRAM and the
3045 	 * shared memory area so we'll read the value from
3046 	 * shared memory for speed.
3047 	 */
3048 
3049 	mac_hi = REG_RD_IND(sc, sc->bce_shmem_base +
3050 		BCE_PORT_HW_CFG_MAC_UPPER);
3051 	mac_lo = REG_RD_IND(sc, sc->bce_shmem_base +
3052 		BCE_PORT_HW_CFG_MAC_LOWER);
3053 
3054 	if ((mac_lo == 0) && (mac_hi == 0)) {
3055 		BCE_PRINTF("%s(%d): Invalid Ethernet address!\n",
3056 			__FILE__, __LINE__);
3057 	} else {
3058 		sc->eaddr[0] = (u_char)(mac_hi >> 8);
3059 		sc->eaddr[1] = (u_char)(mac_hi >> 0);
3060 		sc->eaddr[2] = (u_char)(mac_lo >> 24);
3061 		sc->eaddr[3] = (u_char)(mac_lo >> 16);
3062 		sc->eaddr[4] = (u_char)(mac_lo >> 8);
3063 		sc->eaddr[5] = (u_char)(mac_lo >> 0);
3064 	}
3065 
3066 	DBPRINT(sc, BCE_INFO, "Permanent Ethernet address = %6D\n", sc->eaddr, ":");
3067 }
3068 
3069 
3070 /****************************************************************************/
3071 /* Program the MAC address.                                                 */
3072 /*                                                                          */
3073 /* Returns:                                                                 */
3074 /*   Nothing.                                                               */
3075 /****************************************************************************/
3076 static void
3077 bce_set_mac_addr(struct bce_softc *sc)
3078 {
3079 	u32 val;
3080 	u8 *mac_addr = sc->eaddr;
3081 
3082 	DBPRINT(sc, BCE_INFO, "Setting Ethernet address = %6D\n", sc->eaddr, ":");
3083 
3084 	val = (mac_addr[0] << 8) | mac_addr[1];
3085 
3086 	REG_WR(sc, BCE_EMAC_MAC_MATCH0, val);
3087 
3088 	val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
3089 		(mac_addr[4] << 8) | mac_addr[5];
3090 
3091 	REG_WR(sc, BCE_EMAC_MAC_MATCH1, val);
3092 }
3093 
3094 
3095 /****************************************************************************/
3096 /* Stop the controller.                                                     */
3097 /*                                                                          */
3098 /* Returns:                                                                 */
3099 /*   Nothing.                                                               */
3100 /****************************************************************************/
3101 static void
3102 bce_stop(struct bce_softc *sc)
3103 {
3104 	struct ifnet *ifp;
3105 	struct ifmedia_entry *ifm;
3106 	struct mii_data *mii = NULL;
3107 	int mtmp, itmp;
3108 
3109 	DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
3110 
3111 	BCE_LOCK_ASSERT(sc);
3112 
3113 	ifp = sc->bce_ifp;
3114 
3115 	mii = device_get_softc(sc->bce_miibus);
3116 
3117 	callout_stop(&sc->bce_stat_ch);
3118 
3119 	/* Disable the transmit/receive blocks. */
3120 	REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS, 0x5ffffff);
3121 	REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
3122 	DELAY(20);
3123 
3124 	bce_disable_intr(sc);
3125 
3126 	/* Tell firmware that the driver is going away. */
3127 	bce_reset(sc, BCE_DRV_MSG_CODE_SUSPEND_NO_WOL);
3128 
3129 	/* Free the RX lists. */
3130 	bce_free_rx_chain(sc);
3131 
3132 	/* Free TX buffers. */
3133 	bce_free_tx_chain(sc);
3134 
3135 	/*
3136 	 * Isolate/power down the PHY, but leave the media selection
3137 	 * unchanged so that things will be put back to normal when
3138 	 * we bring the interface back up.
3139 	 */
3140 
3141 	itmp = ifp->if_flags;
3142 	ifp->if_flags |= IFF_UP;
3143 	/*
3144 	 * If we are called from bce_detach(), mii is already NULL.
3145 	 */
3146 	if (mii != NULL) {
3147 		ifm = mii->mii_media.ifm_cur;
3148 		mtmp = ifm->ifm_media;
3149 		ifm->ifm_media = IFM_ETHER | IFM_NONE;
3150 		mii_mediachg(mii);
3151 		ifm->ifm_media = mtmp;
3152 	}
3153 
3154 	ifp->if_flags = itmp;
3155 	sc->watchdog_timer = 0;
3156 
3157 	sc->bce_link = 0;
3158 
3159 	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
3160 
3161 	DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
3162 
3163 	bce_mgmt_init_locked(sc);
3164 }
3165 
3166 
3167 static int
3168 bce_reset(struct bce_softc *sc, u32 reset_code)
3169 {
3170 	u32 val;
3171 	int i, rc = 0;
3172 
3173 	DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
3174 
3175 	/* Wait for pending PCI transactions to complete. */
3176 	REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS,
3177 	       BCE_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
3178 	       BCE_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
3179 	       BCE_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
3180 	       BCE_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
3181 	val = REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
3182 	DELAY(5);
3183 
3184 	/* Assume bootcode is running. */
3185 	sc->bce_fw_timed_out = 0;
3186 
3187 	/* Give the firmware a chance to prepare for the reset. */
3188 	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT0 | reset_code);
3189 	if (rc)
3190 		goto bce_reset_exit;
3191 
3192 	/* Set a firmware reminder that this is a soft reset. */
3193 	REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_RESET_SIGNATURE,
3194 		   BCE_DRV_RESET_SIGNATURE_MAGIC);
3195 
3196 	/* Dummy read to force the chip to complete all current transactions. */
3197 	val = REG_RD(sc, BCE_MISC_ID);
3198 
3199 	/* Chip reset. */
3200 	val = BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
3201 	      BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
3202 	      BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
3203 	REG_WR(sc, BCE_PCICFG_MISC_CONFIG, val);
3204 
3205 	/* Allow up to 30us for reset to complete. */
3206 	for (i = 0; i < 10; i++) {
3207 		val = REG_RD(sc, BCE_PCICFG_MISC_CONFIG);
3208 		if ((val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
3209 			    BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
3210 			break;
3211 		}
3212 		DELAY(10);
3213 	}
3214 
3215 	/* Check that reset completed successfully. */
3216 	if (val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
3217 		   BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
3218 		BCE_PRINTF("%s(%d): Reset failed!\n",
3219 			__FILE__, __LINE__);
3220 		rc = EBUSY;
3221 		goto bce_reset_exit;
3222 	}
3223 
3224 	/* Make sure byte swapping is properly configured. */
3225 	val = REG_RD(sc, BCE_PCI_SWAP_DIAG0);
3226 	if (val != 0x01020304) {
3227 		BCE_PRINTF("%s(%d): Byte swap is incorrect!\n",
3228 			__FILE__, __LINE__);
3229 		rc = ENODEV;
3230 		goto bce_reset_exit;
3231 	}
3232 
3233 	/* Just completed a reset, assume that firmware is running again. */
3234 	sc->bce_fw_timed_out = 0;
3235 
3236 	/* Wait for the firmware to finish its initialization. */
3237 	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT1 | reset_code);
3238 	if (rc)
3239 		BCE_PRINTF("%s(%d): Firmware did not complete initialization!\n",
3240 			__FILE__, __LINE__);
3241 
3242 bce_reset_exit:
3243 	DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
3244 
3245 	return (rc);
3246 }
3247 
3248 
3249 static int
3250 bce_chipinit(struct bce_softc *sc)
3251 {
3252 	u32 val;
3253 	int rc = 0;
3254 
3255 	DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
3256 
3257 	/* Make sure the interrupt is not active. */
3258 	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_MASK_INT);
3259 
3260 	/*
3261 	 * Initialize DMA byte/word swapping, configure the number of DMA
3262 	 * channels and PCI clock compensation delay.
3263 	 */
3264 	val = BCE_DMA_CONFIG_DATA_BYTE_SWAP |
3265 	      BCE_DMA_CONFIG_DATA_WORD_SWAP |
3266 #if BYTE_ORDER == BIG_ENDIAN
3267 	      BCE_DMA_CONFIG_CNTL_BYTE_SWAP |
3268 #endif
3269 	      BCE_DMA_CONFIG_CNTL_WORD_SWAP |
3270 	      DMA_READ_CHANS << 12 |
3271 	      DMA_WRITE_CHANS << 16;
3272 
3273 	val |= (0x2 << 20) | BCE_DMA_CONFIG_CNTL_PCI_COMP_DLY;
3274 
3275 	if ((sc->bce_flags & BCE_PCIX_FLAG) && (sc->bus_speed_mhz == 133))
3276 		val |= BCE_DMA_CONFIG_PCI_FAST_CLK_CMP;
3277 
3278 	/*
3279 	 * This setting resolves a problem observed on certain Intel PCI
3280 	 * chipsets that cannot handle multiple outstanding DMA operations.
3281 	 * See errata E9_5706A1_65.
3282 	 */
3283 	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
3284 	    (BCE_CHIP_ID(sc) != BCE_CHIP_ID_5706_A0) &&
3285 	    !(sc->bce_flags & BCE_PCIX_FLAG))
3286 		val |= BCE_DMA_CONFIG_CNTL_PING_PONG_DMA;
3287 
3288 	REG_WR(sc, BCE_DMA_CONFIG, val);
3289 
3290 	/* Clear the PCI-X relaxed ordering bit. See errata E3_5708CA0_570. */
3291 	if (sc->bce_flags & BCE_PCIX_FLAG) {
3292 		u16 val;
3293 
3294 		val = pci_read_config(sc->bce_dev, BCE_PCI_PCIX_CMD, 2);
3295 		pci_write_config(sc->bce_dev, BCE_PCI_PCIX_CMD, val & ~0x2, 2);
3296 	}
3297 
3298 	/* Enable the RX_V2P and Context state machines before access. */
3299 	REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
3300 	       BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
3301 	       BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
3302 	       BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
3303 
3304 	/* Initialize context mapping and zero out the quick contexts. */
3305 	bce_init_context(sc);
3306 
3307 	/* Initialize the on-boards CPUs */
3308 	bce_init_cpus(sc);
3309 
3310 	/* Prepare NVRAM for access. */
3311 	if (bce_init_nvram(sc)) {
3312 		rc = ENODEV;
3313 		goto bce_chipinit_exit;
3314 	}
3315 
3316 	/* Set the kernel bypass block size */
3317 	val = REG_RD(sc, BCE_MQ_CONFIG);
3318 	val &= ~BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE;
3319 	val |= BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
3320 	REG_WR(sc, BCE_MQ_CONFIG, val);
3321 
3322 	val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
3323 	REG_WR(sc, BCE_MQ_KNL_BYP_WIND_START, val);
3324 	REG_WR(sc, BCE_MQ_KNL_WIND_END, val);
3325 
3326 	/* Set the page size and clear the RV2P processor stall bits. */
3327 	val = (BCM_PAGE_BITS - 8) << 24;
3328 	REG_WR(sc, BCE_RV2P_CONFIG, val);
3329 
3330 	/* Configure page size. */
3331 	val = REG_RD(sc, BCE_TBDR_CONFIG);
3332 	val &= ~BCE_TBDR_CONFIG_PAGE_SIZE;
3333 	val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
3334 	REG_WR(sc, BCE_TBDR_CONFIG, val);
3335 
3336 bce_chipinit_exit:
3337 	DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
3338 
3339 	return(rc);
3340 }
3341 
3342 
3343 /****************************************************************************/
3344 /* Initialize the controller in preparation to send/receive traffic.        */
3345 /*                                                                          */
3346 /* Returns:                                                                 */
3347 /*   0 for success, positive value for failure.                             */
3348 /****************************************************************************/
3349 static int
3350 bce_blockinit(struct bce_softc *sc)
3351 {
3352 	u32 reg, val;
3353 	int rc = 0;
3354 
3355 	DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
3356 
3357 	/* Load the hardware default MAC address. */
3358 	bce_set_mac_addr(sc);
3359 
3360 	/* Set the Ethernet backoff seed value */
3361 	val = sc->eaddr[0]         + (sc->eaddr[1] << 8) +
3362 	      (sc->eaddr[2] << 16) + (sc->eaddr[3]     ) +
3363 	      (sc->eaddr[4] << 8)  + (sc->eaddr[5] << 16);
3364 	REG_WR(sc, BCE_EMAC_BACKOFF_SEED, val);
3365 
3366 	sc->last_status_idx = 0;
3367 	sc->rx_mode = BCE_EMAC_RX_MODE_SORT_MODE;
3368 
3369 	/* Set up link change interrupt generation. */
3370 	REG_WR(sc, BCE_EMAC_ATTENTION_ENA, BCE_EMAC_ATTENTION_ENA_LINK);
3371 
3372 	/* Program the physical address of the status block. */
3373 	REG_WR(sc, BCE_HC_STATUS_ADDR_L,
3374 		BCE_ADDR_LO(sc->status_block_paddr));
3375 	REG_WR(sc, BCE_HC_STATUS_ADDR_H,
3376 		BCE_ADDR_HI(sc->status_block_paddr));
3377 
3378 	/* Program the physical address of the statistics block. */
3379 	REG_WR(sc, BCE_HC_STATISTICS_ADDR_L,
3380 		BCE_ADDR_LO(sc->stats_block_paddr));
3381 	REG_WR(sc, BCE_HC_STATISTICS_ADDR_H,
3382 		BCE_ADDR_HI(sc->stats_block_paddr));
3383 
3384 	/* Program various host coalescing parameters. */
3385 	REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
3386 		(sc->bce_tx_quick_cons_trip_int << 16) | sc->bce_tx_quick_cons_trip);
3387 	REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
3388 		(sc->bce_rx_quick_cons_trip_int << 16) | sc->bce_rx_quick_cons_trip);
3389 	REG_WR(sc, BCE_HC_COMP_PROD_TRIP,
3390 		(sc->bce_comp_prod_trip_int << 16) | sc->bce_comp_prod_trip);
3391 	REG_WR(sc, BCE_HC_TX_TICKS,
3392 		(sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
3393 	REG_WR(sc, BCE_HC_RX_TICKS,
3394 		(sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
3395 	REG_WR(sc, BCE_HC_COM_TICKS,
3396 		(sc->bce_com_ticks_int << 16) | sc->bce_com_ticks);
3397 	REG_WR(sc, BCE_HC_CMD_TICKS,
3398 		(sc->bce_cmd_ticks_int << 16) | sc->bce_cmd_ticks);
3399 	REG_WR(sc, BCE_HC_STATS_TICKS,
3400 		(sc->bce_stats_ticks & 0xffff00));
3401 	REG_WR(sc, BCE_HC_STAT_COLLECT_TICKS,
3402 		0xbb8);  /* 3ms */
3403 	REG_WR(sc, BCE_HC_CONFIG,
3404 		(BCE_HC_CONFIG_RX_TMR_MODE | BCE_HC_CONFIG_TX_TMR_MODE |
3405 		BCE_HC_CONFIG_COLLECT_STATS));
3406 
3407 	/* Clear the internal statistics counters. */
3408 	REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
3409 
3410 	/* Verify that bootcode is running. */
3411 	reg = REG_RD_IND(sc, sc->bce_shmem_base + BCE_DEV_INFO_SIGNATURE);
3412 
3413 	DBRUNIF(DB_RANDOMTRUE(bce_debug_bootcode_running_failure),
3414 		BCE_PRINTF("%s(%d): Simulating bootcode failure.\n",
3415 			__FILE__, __LINE__);
3416 		reg = 0);
3417 
3418 	if ((reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
3419 	    BCE_DEV_INFO_SIGNATURE_MAGIC) {
3420 		BCE_PRINTF("%s(%d): Bootcode not running! Found: 0x%08X, "
3421 			"Expected: 08%08X\n", __FILE__, __LINE__,
3422 			(reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK),
3423 			BCE_DEV_INFO_SIGNATURE_MAGIC);
3424 		rc = ENODEV;
3425 		goto bce_blockinit_exit;
3426 	}
3427 
3428 	/* Check if any management firmware is running. */
3429 	reg = REG_RD_IND(sc, sc->bce_shmem_base + BCE_PORT_FEATURE);
3430 	if (reg & (BCE_PORT_FEATURE_ASF_ENABLED | BCE_PORT_FEATURE_IMD_ENABLED)) {
3431 		DBPRINT(sc, BCE_INFO, "Management F/W Enabled.\n");
3432 		sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
3433 	}
3434 
3435 	sc->bce_fw_ver = REG_RD_IND(sc, sc->bce_shmem_base + BCE_DEV_INFO_BC_REV);
3436 	DBPRINT(sc, BCE_INFO, "bootcode rev = 0x%08X\n", sc->bce_fw_ver);
3437 
3438 	/* Allow bootcode to apply any additional fixes before enabling MAC. */
3439 	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 | BCE_DRV_MSG_CODE_RESET);
3440 
3441 	/* Enable link state change interrupt generation. */
3442 	REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
3443 
3444 	/* Enable all remaining blocks in the MAC. */
3445 	REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, 0x5ffffff);
3446 	REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
3447 	DELAY(20);
3448 
3449 bce_blockinit_exit:
3450 	DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
3451 
3452 	return (rc);
3453 }
3454 
3455 
3456 /****************************************************************************/
3457 /* Encapsulate an mbuf cluster into the rx_bd chain.                        */
3458 /*                                                                          */
3459 /* The NetXtreme II can support Jumbo frames by using multiple rx_bd's.     */
3460 /* This routine will map an mbuf cluster into 1 or more rx_bd's as          */
3461 /* necessary.                                                               */
3462 /*                                                                          */
3463 /* Returns:                                                                 */
3464 /*   0 for success, positive value for failure.                             */
3465 /****************************************************************************/
3466 static int
3467 bce_get_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod, u16 *chain_prod,
3468 	u32 *prod_bseq)
3469 {
3470 	bus_dmamap_t		map;
3471 	bus_dma_segment_t	segs[4];
3472 	struct mbuf *m_new = NULL;
3473 	struct rx_bd		*rxbd;
3474 	int i, nsegs, error, rc = 0;
3475 #ifdef BCE_DEBUG
3476 	u16 debug_chain_prod = *chain_prod;
3477 #endif
3478 
3479 	DBPRINT(sc, (BCE_VERBOSE_RESET | BCE_VERBOSE_RECV), "Entering %s()\n",
3480 		__FUNCTION__);
3481 
3482 	/* Make sure the inputs are valid. */
3483 	DBRUNIF((*chain_prod > MAX_RX_BD),
3484 		BCE_PRINTF("%s(%d): RX producer out of range: 0x%04X > 0x%04X\n",
3485 		__FILE__, __LINE__, *chain_prod, (u16) MAX_RX_BD));
3486 
3487 	DBPRINT(sc, BCE_VERBOSE_RECV, "%s(enter): prod = 0x%04X, chain_prod = 0x%04X, "
3488 		"prod_bseq = 0x%08X\n", __FUNCTION__, *prod, *chain_prod, *prod_bseq);
3489 
3490 	if (m == NULL) {
3491 
3492 		DBRUNIF(DB_RANDOMTRUE(bce_debug_mbuf_allocation_failure),
3493 			BCE_PRINTF("%s(%d): Simulating mbuf allocation failure.\n",
3494 				__FILE__, __LINE__);
3495 			sc->mbuf_alloc_failed++;
3496 			rc = ENOBUFS;
3497 			goto bce_get_buf_exit);
3498 
3499 		/* This is a new mbuf allocation. */
3500 		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
3501 		if (m_new == NULL) {
3502 
3503 			DBPRINT(sc, BCE_WARN, "%s(%d): RX mbuf header allocation failed!\n",
3504 				__FILE__, __LINE__);
3505 
3506 			DBRUNIF(1, sc->mbuf_alloc_failed++);
3507 
3508 			rc = ENOBUFS;
3509 			goto bce_get_buf_exit;
3510 		}
3511 
3512 		DBRUNIF(1, sc->rx_mbuf_alloc++);
3513 		m_cljget(m_new, M_DONTWAIT, sc->mbuf_alloc_size);
3514 		if (!(m_new->m_flags & M_EXT)) {
3515 
3516 			DBPRINT(sc, BCE_WARN, "%s(%d): RX mbuf chain allocation failed!\n",
3517 				__FILE__, __LINE__);
3518 
3519 			m_freem(m_new);
3520 
3521 			DBRUNIF(1, sc->rx_mbuf_alloc--);
3522 			DBRUNIF(1, sc->mbuf_alloc_failed++);
3523 
3524 			rc = ENOBUFS;
3525 			goto bce_get_buf_exit;
3526 		}
3527 
3528 		m_new->m_len = m_new->m_pkthdr.len = sc->mbuf_alloc_size;
3529 	} else {
3530 		m_new = m;
3531 		m_new->m_len = m_new->m_pkthdr.len = sc->mbuf_alloc_size;
3532 		m_new->m_data = m_new->m_ext.ext_buf;
3533 	}
3534 
3535 	/* Map the mbuf cluster into device memory. */
3536 	map = sc->rx_mbuf_map[*chain_prod];
3537 	error = bus_dmamap_load_mbuf_sg(sc->rx_mbuf_tag, map, m_new,
3538 	    segs, &nsegs, BUS_DMA_NOWAIT);
3539 
3540 	if (error) {
3541 		BCE_PRINTF("%s(%d): Error mapping mbuf into RX chain!\n",
3542 			__FILE__, __LINE__);
3543 
3544 		m_freem(m_new);
3545 
3546 		DBRUNIF(1, sc->rx_mbuf_alloc--);
3547 
3548 		rc = ENOBUFS;
3549 		goto bce_get_buf_exit;
3550 	}
3551 
3552 	/* Watch for overflow. */
3553 	DBRUNIF((sc->free_rx_bd > USABLE_RX_BD),
3554 		BCE_PRINTF("%s(%d): Too many free rx_bd (0x%04X > 0x%04X)!\n",
3555 			__FILE__, __LINE__, sc->free_rx_bd, (u16) USABLE_RX_BD));
3556 
3557 	/* Update some debug statistic counters */
3558 	DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
3559 		sc->rx_low_watermark = sc->free_rx_bd);
3560 	DBRUNIF((sc->free_rx_bd == 0), sc->rx_empty_count++);
3561 
3562 	/* Setup the rx_bd for the first segment. */
3563 	rxbd = &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
3564 
3565 	rxbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(segs[0].ds_addr));
3566 	rxbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(segs[0].ds_addr));
3567 	rxbd->rx_bd_len       = htole32(segs[0].ds_len);
3568 	rxbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START);
3569 	*prod_bseq += segs[0].ds_len;
3570 
3571 	for (i = 1; i < nsegs; i++) {
3572 
3573 		*prod = NEXT_RX_BD(*prod);
3574 		*chain_prod = RX_CHAIN_IDX(*prod);
3575 
3576 		rxbd = &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
3577 
3578 		rxbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(segs[i].ds_addr));
3579 		rxbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(segs[i].ds_addr));
3580 		rxbd->rx_bd_len       = htole32(segs[i].ds_len);
3581 		rxbd->rx_bd_flags     = 0;
3582 		*prod_bseq += segs[i].ds_len;
3583 	}
3584 
3585 	rxbd->rx_bd_flags |= htole32(RX_BD_FLAGS_END);
3586 
3587 	/* Save the mbuf and update our counter. */
3588 	sc->rx_mbuf_ptr[*chain_prod] = m_new;
3589 	sc->free_rx_bd -= nsegs;
3590 
3591 	DBRUN(BCE_VERBOSE_RECV, bce_dump_rx_mbuf_chain(sc, debug_chain_prod,
3592 		nsegs));
3593 
3594 	DBPRINT(sc, BCE_VERBOSE_RECV, "%s(exit): prod = 0x%04X, chain_prod = 0x%04X, "
3595 		"prod_bseq = 0x%08X\n", __FUNCTION__, *prod, *chain_prod, *prod_bseq);
3596 
3597 bce_get_buf_exit:
3598 	DBPRINT(sc, (BCE_VERBOSE_RESET | BCE_VERBOSE_RECV), "Exiting %s()\n",
3599 		__FUNCTION__);
3600 
3601 	return(rc);
3602 }
3603 
3604 
3605 /****************************************************************************/
3606 /* Allocate memory and initialize the TX data structures.                   */
3607 /*                                                                          */
3608 /* Returns:                                                                 */
3609 /*   0 for success, positive value for failure.                             */
3610 /****************************************************************************/
3611 static int
3612 bce_init_tx_chain(struct bce_softc *sc)
3613 {
3614 	struct tx_bd *txbd;
3615 	u32 val;
3616 	int i, rc = 0;
3617 
3618 	DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
3619 
3620 	/* Set the initial TX producer/consumer indices. */
3621 	sc->tx_prod        = 0;
3622 	sc->tx_cons        = 0;
3623 	sc->tx_prod_bseq   = 0;
3624 	sc->used_tx_bd     = 0;
3625 	sc->max_tx_bd      = USABLE_TX_BD;
3626 	DBRUNIF(1, sc->tx_hi_watermark = USABLE_TX_BD);
3627 	DBRUNIF(1, sc->tx_full_count = 0);
3628 
3629 	/*
3630 	 * The NetXtreme II supports a linked-list structre called
3631 	 * a Buffer Descriptor Chain (or BD chain).  A BD chain
3632 	 * consists of a series of 1 or more chain pages, each of which
3633 	 * consists of a fixed number of BD entries.
3634 	 * The last BD entry on each page is a pointer to the next page
3635 	 * in the chain, and the last pointer in the BD chain
3636 	 * points back to the beginning of the chain.
3637 	 */
3638 
3639 	/* Set the TX next pointer chain entries. */
3640 	for (i = 0; i < TX_PAGES; i++) {
3641 		int j;
3642 
3643 		txbd = &sc->tx_bd_chain[i][USABLE_TX_BD_PER_PAGE];
3644 
3645 		/* Check if we've reached the last page. */
3646 		if (i == (TX_PAGES - 1))
3647 			j = 0;
3648 		else
3649 			j = i + 1;
3650 
3651 		txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->tx_bd_chain_paddr[j]));
3652 		txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->tx_bd_chain_paddr[j]));
3653 	}
3654 
3655 	/* Initialize the context ID for an L2 TX chain. */
3656 	val = BCE_L2CTX_TYPE_TYPE_L2;
3657 	val |= BCE_L2CTX_TYPE_SIZE_L2;
3658 	CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TYPE, val);
3659 
3660 	val = BCE_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16);
3661 	CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_CMD_TYPE, val);
3662 
3663 	/* Point the hardware to the first page in the chain. */
3664 	val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
3665 	CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TBDR_BHADDR_HI, val);
3666 	val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
3667 	CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TBDR_BHADDR_LO, val);
3668 
3669 	DBRUN(BCE_VERBOSE_SEND, bce_dump_tx_chain(sc, 0, TOTAL_TX_BD));
3670 
3671 	DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
3672 
3673 	return(rc);
3674 }
3675 
3676 
3677 /****************************************************************************/
3678 /* Free memory and clear the TX data structures.                            */
3679 /*                                                                          */
3680 /* Returns:                                                                 */
3681 /*   Nothing.                                                               */
3682 /****************************************************************************/
3683 static void
3684 bce_free_tx_chain(struct bce_softc *sc)
3685 {
3686 	int i;
3687 
3688 	DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
3689 
3690 	/* Unmap, unload, and free any mbufs still in the TX mbuf chain. */
3691 	for (i = 0; i < TOTAL_TX_BD; i++) {
3692 		if (sc->tx_mbuf_ptr[i] != NULL) {
3693 			if (sc->tx_mbuf_map != NULL)
3694 				bus_dmamap_sync(sc->tx_mbuf_tag, sc->tx_mbuf_map[i],
3695 					BUS_DMASYNC_POSTWRITE);
3696 			m_freem(sc->tx_mbuf_ptr[i]);
3697 			sc->tx_mbuf_ptr[i] = NULL;
3698 			DBRUNIF(1, sc->tx_mbuf_alloc--);
3699 		}
3700 	}
3701 
3702 	/* Clear each TX chain page. */
3703 	for (i = 0; i < TX_PAGES; i++)
3704 		bzero((char *)sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ);
3705 
3706 	/* Check if we lost any mbufs in the process. */
3707 	DBRUNIF((sc->tx_mbuf_alloc),
3708 		BCE_PRINTF("%s(%d): Memory leak! Lost %d mbufs "
3709 			"from tx chain!\n",
3710 			__FILE__, __LINE__, sc->tx_mbuf_alloc));
3711 
3712 	DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
3713 }
3714 
3715 
3716 /****************************************************************************/
3717 /* Allocate memory and initialize the RX data structures.                   */
3718 /*                                                                          */
3719 /* Returns:                                                                 */
3720 /*   0 for success, positive value for failure.                             */
3721 /****************************************************************************/
3722 static int
3723 bce_init_rx_chain(struct bce_softc *sc)
3724 {
3725 	struct rx_bd *rxbd;
3726 	int i, rc = 0;
3727 	u16 prod, chain_prod;
3728 	u32 prod_bseq, val;
3729 
3730 	DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
3731 
3732 	/* Initialize the RX producer and consumer indices. */
3733 	sc->rx_prod        = 0;
3734 	sc->rx_cons        = 0;
3735 	sc->rx_prod_bseq   = 0;
3736 	sc->free_rx_bd     = USABLE_RX_BD;
3737 	sc->max_rx_bd      = USABLE_RX_BD;
3738 	DBRUNIF(1, sc->rx_low_watermark = USABLE_RX_BD);
3739 	DBRUNIF(1, sc->rx_empty_count = 0);
3740 
3741 	/* Initialize the RX next pointer chain entries. */
3742 	for (i = 0; i < RX_PAGES; i++) {
3743 		int j;
3744 
3745 		rxbd = &sc->rx_bd_chain[i][USABLE_RX_BD_PER_PAGE];
3746 
3747 		/* Check if we've reached the last page. */
3748 		if (i == (RX_PAGES - 1))
3749 			j = 0;
3750 		else
3751 			j = i + 1;
3752 
3753 		/* Setup the chain page pointers. */
3754 		rxbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j]));
3755 		rxbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j]));
3756 	}
3757 
3758 	/* Initialize the context ID for an L2 RX chain. */
3759 	val = BCE_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
3760 	val |= BCE_L2CTX_CTX_TYPE_SIZE_L2;
3761 	val |= 0x02 << 8;
3762 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_CTX_TYPE, val);
3763 
3764 	/* Point the hardware to the first page in the chain. */
3765 	val = BCE_ADDR_HI(sc->rx_bd_chain_paddr[0]);
3766 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_NX_BDHADDR_HI, val);
3767 	val = BCE_ADDR_LO(sc->rx_bd_chain_paddr[0]);
3768 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_NX_BDHADDR_LO, val);
3769 
3770 	/* Allocate mbuf clusters for the rx_bd chain. */
3771 	prod = prod_bseq = 0;
3772 	while (prod < TOTAL_RX_BD) {
3773 		chain_prod = RX_CHAIN_IDX(prod);
3774 		if (bce_get_buf(sc, NULL, &prod, &chain_prod, &prod_bseq)) {
3775 			BCE_PRINTF("%s(%d): Error filling RX chain: rx_bd[0x%04X]!\n",
3776 				__FILE__, __LINE__, chain_prod);
3777 			rc = ENOBUFS;
3778 			break;
3779 		}
3780 		prod = NEXT_RX_BD(prod);
3781 	}
3782 
3783 	/* Save the RX chain producer index. */
3784 	sc->rx_prod      = prod;
3785 	sc->rx_prod_bseq = prod_bseq;
3786 
3787 	for (i = 0; i < RX_PAGES; i++) {
3788 		bus_dmamap_sync(
3789 			sc->rx_bd_chain_tag,
3790 	    	sc->rx_bd_chain_map[i],
3791 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
3792 	}
3793 
3794 	/* Tell the chip about the waiting rx_bd's. */
3795 	REG_WR16(sc, MB_RX_CID_ADDR + BCE_L2CTX_HOST_BDIDX, sc->rx_prod);
3796 	REG_WR(sc, MB_RX_CID_ADDR + BCE_L2CTX_HOST_BSEQ, sc->rx_prod_bseq);
3797 
3798 	DBRUN(BCE_VERBOSE_RECV, bce_dump_rx_chain(sc, 0, TOTAL_RX_BD));
3799 
3800 	DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
3801 
3802 	return(rc);
3803 }
3804 
3805 
3806 /****************************************************************************/
3807 /* Free memory and clear the RX data structures.                            */
3808 /*                                                                          */
3809 /* Returns:                                                                 */
3810 /*   Nothing.                                                               */
3811 /****************************************************************************/
3812 static void
3813 bce_free_rx_chain(struct bce_softc *sc)
3814 {
3815 	int i;
3816 
3817 	DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
3818 
3819 	/* Free any mbufs still in the RX mbuf chain. */
3820 	for (i = 0; i < TOTAL_RX_BD; i++) {
3821 		if (sc->rx_mbuf_ptr[i] != NULL) {
3822 			if (sc->rx_mbuf_map[i] != NULL)
3823 				bus_dmamap_sync(sc->rx_mbuf_tag, sc->rx_mbuf_map[i],
3824 					BUS_DMASYNC_POSTREAD);
3825 			m_freem(sc->rx_mbuf_ptr[i]);
3826 			sc->rx_mbuf_ptr[i] = NULL;
3827 			DBRUNIF(1, sc->rx_mbuf_alloc--);
3828 		}
3829 	}
3830 
3831 	/* Clear each RX chain page. */
3832 	for (i = 0; i < RX_PAGES; i++)
3833 		bzero((char *)sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ);
3834 
3835 	/* Check if we lost any mbufs in the process. */
3836 	DBRUNIF((sc->rx_mbuf_alloc),
3837 		BCE_PRINTF("%s(%d): Memory leak! Lost %d mbufs from rx chain!\n",
3838 			__FILE__, __LINE__, sc->rx_mbuf_alloc));
3839 
3840 	DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
3841 }
3842 
3843 
3844 /****************************************************************************/
3845 /* Set media options.                                                       */
3846 /*                                                                          */
3847 /* Returns:                                                                 */
3848 /*   0 for success, positive value for failure.                             */
3849 /****************************************************************************/
3850 static int
3851 bce_ifmedia_upd(struct ifnet *ifp)
3852 {
3853 	struct bce_softc *sc;
3854 
3855 	sc = ifp->if_softc;
3856 	BCE_LOCK(sc);
3857 	bce_ifmedia_upd_locked(ifp);
3858 	BCE_UNLOCK(sc);
3859 	return (0);
3860 }
3861 
3862 
3863 /****************************************************************************/
3864 /* Set media options.                                                       */
3865 /*                                                                          */
3866 /* Returns:                                                                 */
3867 /*   Nothing.                                                               */
3868 /****************************************************************************/
3869 static void
3870 bce_ifmedia_upd_locked(struct ifnet *ifp)
3871 {
3872 	struct bce_softc *sc;
3873 	struct mii_data *mii;
3874 	struct ifmedia *ifm;
3875 
3876 	sc = ifp->if_softc;
3877 	ifm = &sc->bce_ifmedia;
3878 	BCE_LOCK_ASSERT(sc);
3879 
3880 	mii = device_get_softc(sc->bce_miibus);
3881 
3882 	/* Make sure the MII bus has been enumerated. */
3883 	if (mii) {
3884 		sc->bce_link = 0;
3885 		if (mii->mii_instance) {
3886 			struct mii_softc *miisc;
3887 
3888 			LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
3889 				mii_phy_reset(miisc);
3890 		}
3891 		mii_mediachg(mii);
3892 	}
3893 }
3894 
3895 
3896 /****************************************************************************/
3897 /* Reports current media status.                                            */
3898 /*                                                                          */
3899 /* Returns:                                                                 */
3900 /*   Nothing.                                                               */
3901 /****************************************************************************/
3902 static void
3903 bce_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
3904 {
3905 	struct bce_softc *sc;
3906 	struct mii_data *mii;
3907 
3908 	sc = ifp->if_softc;
3909 
3910 	BCE_LOCK(sc);
3911 
3912 	mii = device_get_softc(sc->bce_miibus);
3913 
3914 	mii_pollstat(mii);
3915 	ifmr->ifm_active = mii->mii_media_active;
3916 	ifmr->ifm_status = mii->mii_media_status;
3917 
3918 	BCE_UNLOCK(sc);
3919 }
3920 
3921 
3922 /****************************************************************************/
3923 /* Handles PHY generated interrupt events.                                  */
3924 /*                                                                          */
3925 /* Returns:                                                                 */
3926 /*   Nothing.                                                               */
3927 /****************************************************************************/
3928 static void
3929 bce_phy_intr(struct bce_softc *sc)
3930 {
3931 	u32 new_link_state, old_link_state;
3932 
3933 	new_link_state = sc->status_block->status_attn_bits &
3934 		STATUS_ATTN_BITS_LINK_STATE;
3935 	old_link_state = sc->status_block->status_attn_bits_ack &
3936 		STATUS_ATTN_BITS_LINK_STATE;
3937 
3938 	/* Handle any changes if the link state has changed. */
3939 	if (new_link_state != old_link_state) {
3940 
3941 		DBRUN(BCE_VERBOSE_INTR, bce_dump_status_block(sc));
3942 
3943 		sc->bce_link = 0;
3944 		callout_stop(&sc->bce_stat_ch);
3945 		bce_tick(sc);
3946 
3947 		/* Update the status_attn_bits_ack field in the status block. */
3948 		if (new_link_state) {
3949 			REG_WR(sc, BCE_PCICFG_STATUS_BIT_SET_CMD,
3950 				STATUS_ATTN_BITS_LINK_STATE);
3951 			DBPRINT(sc, BCE_INFO, "Link is now UP.\n");
3952 		}
3953 		else {
3954 			REG_WR(sc, BCE_PCICFG_STATUS_BIT_CLEAR_CMD,
3955 				STATUS_ATTN_BITS_LINK_STATE);
3956 			DBPRINT(sc, BCE_INFO, "Link is now DOWN.\n");
3957 		}
3958 
3959 	}
3960 
3961 	/* Acknowledge the link change interrupt. */
3962 	REG_WR(sc, BCE_EMAC_STATUS, BCE_EMAC_STATUS_LINK_CHANGE);
3963 }
3964 
3965 
3966 /****************************************************************************/
3967 /* Handles received frame interrupt events.                                 */
3968 /*                                                                          */
3969 /* Returns:                                                                 */
3970 /*   Nothing.                                                               */
3971 /****************************************************************************/
3972 static void
3973 bce_rx_intr(struct bce_softc *sc)
3974 {
3975 	struct status_block *sblk = sc->status_block;
3976 	struct ifnet *ifp = sc->bce_ifp;
3977 	u16 hw_cons, sw_cons, sw_chain_cons, sw_prod, sw_chain_prod;
3978 	u32 sw_prod_bseq;
3979 	struct l2_fhdr *l2fhdr;
3980 
3981 	DBRUNIF(1, sc->rx_interrupts++);
3982 
3983 	/* Prepare the RX chain pages to be accessed by the host CPU. */
3984 	for (int i = 0; i < RX_PAGES; i++)
3985 		bus_dmamap_sync(sc->rx_bd_chain_tag,
3986 		    sc->rx_bd_chain_map[i], BUS_DMASYNC_POSTWRITE);
3987 
3988 	/* Get the hardware's view of the RX consumer index. */
3989 	hw_cons = sc->hw_rx_cons = sblk->status_rx_quick_consumer_index0;
3990 	if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
3991 		hw_cons++;
3992 
3993 	/* Get working copies of the driver's view of the RX indices. */
3994 	sw_cons = sc->rx_cons;
3995 	sw_prod = sc->rx_prod;
3996 	sw_prod_bseq = sc->rx_prod_bseq;
3997 
3998 	DBPRINT(sc, BCE_INFO_RECV, "%s(enter): sw_prod = 0x%04X, "
3999 		"sw_cons = 0x%04X, sw_prod_bseq = 0x%08X\n",
4000 		__FUNCTION__, sw_prod, sw_cons,
4001 		sw_prod_bseq);
4002 
4003 	/* Prevent speculative reads from getting ahead of the status block. */
4004 	bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
4005 		BUS_SPACE_BARRIER_READ);
4006 
4007 	/* Update some debug statistics counters */
4008 	DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
4009 		sc->rx_low_watermark = sc->free_rx_bd);
4010 	DBRUNIF((sc->free_rx_bd == 0), sc->rx_empty_count++);
4011 
4012 	/* Scan through the receive chain as long as there is work to do */
4013 	while (sw_cons != hw_cons) {
4014 		struct mbuf *m;
4015 		struct rx_bd *rxbd;
4016 		unsigned int len;
4017 		u32 status;
4018 
4019 		/* Clear the mbuf pointer. */
4020 		m = NULL;
4021 
4022 		/* Convert the producer/consumer indices to an actual rx_bd index. */
4023 		sw_chain_cons = RX_CHAIN_IDX(sw_cons);
4024 		sw_chain_prod = RX_CHAIN_IDX(sw_prod);
4025 
4026 		/* Get the used rx_bd. */
4027 		rxbd = &sc->rx_bd_chain[RX_PAGE(sw_chain_cons)][RX_IDX(sw_chain_cons)];
4028 		sc->free_rx_bd++;
4029 
4030 		DBRUN(BCE_VERBOSE_RECV,
4031 			BCE_PRINTF("%s(): ", __FUNCTION__);
4032 			bce_dump_rxbd(sc, sw_chain_cons, rxbd));
4033 
4034 #ifdef DEVICE_POLLING
4035 		if (ifp->if_capenable & IFCAP_POLLING) {
4036 			if (sc->bce_rxcycles <= 0)
4037 				break;
4038 			sc->bce_rxcycles--;
4039 		}
4040 #endif
4041 
4042 		/* The mbuf is stored with the last rx_bd entry of a packet. */
4043 		if (sc->rx_mbuf_ptr[sw_chain_cons] != NULL) {
4044 
4045 			/* Validate that this is the last rx_bd. */
4046 			DBRUNIF((!(rxbd->rx_bd_flags & RX_BD_FLAGS_END)),
4047 				BCE_PRINTF("%s(%d): Unexpected mbuf found in rx_bd[0x%04X]!\n",
4048 				__FILE__, __LINE__, sw_chain_cons);
4049 				bce_breakpoint(sc));
4050 
4051 			/*
4052 			 * ToDo: If the received packet is small enough
4053 			 * to fit into a single, non-M_EXT mbuf,
4054 			 * allocate a new mbuf here, copy the data to
4055 			 * that mbuf, and recycle the mapped jumbo frame.
4056 			 */
4057 
4058 			/* Unmap the mbuf from DMA space. */
4059 			bus_dmamap_sync(sc->rx_mbuf_tag,
4060 			    sc->rx_mbuf_map[sw_chain_cons],
4061 		    	BUS_DMASYNC_POSTREAD);
4062 			bus_dmamap_unload(sc->rx_mbuf_tag,
4063 			    sc->rx_mbuf_map[sw_chain_cons]);
4064 
4065 			/* Remove the mbuf from the driver's chain. */
4066 			m = sc->rx_mbuf_ptr[sw_chain_cons];
4067 			sc->rx_mbuf_ptr[sw_chain_cons] = NULL;
4068 
4069 			/*
4070 			 * Frames received on the NetXteme II are prepended
4071 			 * with an l2_fhdr structure which provides status
4072 			 * information about the received frame (including
4073 			 * VLAN tags and checksum info).  The frames are also
4074 			 * automatically adjusted to align the IP header
4075 			 * (i.e. two null bytes are inserted before the
4076 			 * Ethernet header).
4077 			 */
4078 			l2fhdr = mtod(m, struct l2_fhdr *);
4079 
4080 			len    = l2fhdr->l2_fhdr_pkt_len;
4081 			status = l2fhdr->l2_fhdr_status;
4082 
4083 			DBRUNIF(DB_RANDOMTRUE(bce_debug_l2fhdr_status_check),
4084 				BCE_PRINTF("Simulating l2_fhdr status error.\n");
4085 				status = status | L2_FHDR_ERRORS_PHY_DECODE);
4086 
4087 			/* Watch for unusual sized frames. */
4088 			DBRUNIF(((len < BCE_MIN_MTU) || (len > BCE_MAX_JUMBO_ETHER_MTU_VLAN)),
4089 				BCE_PRINTF("%s(%d): Unusual frame size found. "
4090 					"Min(%d), Actual(%d), Max(%d)\n",
4091 					__FILE__, __LINE__, (int) BCE_MIN_MTU,
4092 					len, (int) BCE_MAX_JUMBO_ETHER_MTU_VLAN);
4093 				bce_dump_mbuf(sc, m);
4094 		 		bce_breakpoint(sc));
4095 
4096 			len -= ETHER_CRC_LEN;
4097 
4098 			/* Check the received frame for errors. */
4099 			if (status &  (L2_FHDR_ERRORS_BAD_CRC |
4100 				L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT |
4101 				L2_FHDR_ERRORS_TOO_SHORT  | L2_FHDR_ERRORS_GIANT_FRAME)) {
4102 
4103 				ifp->if_ierrors++;
4104 				DBRUNIF(1, sc->l2fhdr_status_errors++);
4105 
4106 				/* Reuse the mbuf for a new frame. */
4107 				if (bce_get_buf(sc, m, &sw_prod, &sw_chain_prod, &sw_prod_bseq)) {
4108 
4109 					DBRUNIF(1, bce_breakpoint(sc));
4110 					panic("bce%d: Can't reuse RX mbuf!\n", sc->bce_unit);
4111 
4112 				}
4113 				goto bce_rx_int_next_rx;
4114 			}
4115 
4116 			/*
4117 			 * Get a new mbuf for the rx_bd.   If no new
4118 			 * mbufs are available then reuse the current mbuf,
4119 			 * log an ierror on the interface, and generate
4120 			 * an error in the system log.
4121 			 */
4122 			if (bce_get_buf(sc, NULL, &sw_prod, &sw_chain_prod, &sw_prod_bseq)) {
4123 
4124 				DBRUN(BCE_WARN,
4125 					BCE_PRINTF("%s(%d): Failed to allocate "
4126 					"new mbuf, incoming frame dropped!\n",
4127 					__FILE__, __LINE__));
4128 
4129 				ifp->if_ierrors++;
4130 
4131 				/* Try and reuse the exisitng mbuf. */
4132 				if (bce_get_buf(sc, m, &sw_prod, &sw_chain_prod, &sw_prod_bseq)) {
4133 
4134 					DBRUNIF(1, bce_breakpoint(sc));
4135 					panic("bce%d: Double mbuf allocation failure!", sc->bce_unit);
4136 
4137 				}
4138 				goto bce_rx_int_next_rx;
4139 			}
4140 
4141 			/* Skip over the l2_fhdr when passing the data up the stack. */
4142 			m_adj(m, sizeof(struct l2_fhdr) + ETHER_ALIGN);
4143 
4144 			/* Adjust the packet length to match the received data. */
4145 			m->m_pkthdr.len = m->m_len = len;
4146 
4147 			/* Send the packet to the appropriate interface. */
4148 			m->m_pkthdr.rcvif = ifp;
4149 
4150 			DBRUN(BCE_VERBOSE_RECV,
4151 				struct ether_header *eh;
4152 				eh = mtod(m, struct ether_header *);
4153 				BCE_PRINTF("%s(): to: %6D, from: %6D, type: 0x%04X\n",
4154 					__FUNCTION__, eh->ether_dhost, ":",
4155 					eh->ether_shost, ":", htons(eh->ether_type)));
4156 
4157 			/* Validate the checksum if offload enabled. */
4158 			if (ifp->if_capenable & IFCAP_RXCSUM) {
4159 
4160 				/* Check for an IP datagram. */
4161 				if (status & L2_FHDR_STATUS_IP_DATAGRAM) {
4162 					m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
4163 
4164 					/* Check if the IP checksum is valid. */
4165 					if ((l2fhdr->l2_fhdr_ip_xsum ^ 0xffff) == 0)
4166 						m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
4167 					else
4168 						DBPRINT(sc, BCE_WARN_RECV,
4169 							"%s(): Invalid IP checksum = 0x%04X!\n",
4170 							__FUNCTION__, l2fhdr->l2_fhdr_ip_xsum);
4171 				}
4172 
4173 				/* Check for a valid TCP/UDP frame. */
4174 				if (status & (L2_FHDR_STATUS_TCP_SEGMENT |
4175 					L2_FHDR_STATUS_UDP_DATAGRAM)) {
4176 
4177 					/* Check for a good TCP/UDP checksum. */
4178 					if ((status & (L2_FHDR_ERRORS_TCP_XSUM |
4179 						      L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
4180 						m->m_pkthdr.csum_data =
4181 						    l2fhdr->l2_fhdr_tcp_udp_xsum;
4182 						m->m_pkthdr.csum_flags |= (CSUM_DATA_VALID
4183 							| CSUM_PSEUDO_HDR);
4184 					} else
4185 						DBPRINT(sc, BCE_WARN_RECV,
4186 							"%s(): Invalid TCP/UDP checksum = 0x%04X!\n",
4187 							__FUNCTION__, l2fhdr->l2_fhdr_tcp_udp_xsum);
4188 				}
4189 			}
4190 
4191 
4192 			/*
4193 			 * If we received a packet with a vlan tag,
4194 			 * attach that information to the packet.
4195 			 */
4196 			if (status & L2_FHDR_STATUS_L2_VLAN_TAG) {
4197 				DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): VLAN tag = 0x%04X\n",
4198 					__FUNCTION__, l2fhdr->l2_fhdr_vlan_tag);
4199 #if __FreeBSD_version < 700000
4200 				VLAN_INPUT_TAG(ifp, m, l2fhdr->l2_fhdr_vlan_tag, continue);
4201 #else
4202 				m->m_pkthdr.ether_vtag = l2fhdr->l2_fhdr_vlan_tag;
4203 				m->m_flags |= M_VLANTAG;
4204 #endif
4205 			}
4206 
4207 			/* Pass the mbuf off to the upper layers. */
4208 			ifp->if_ipackets++;
4209 
4210 bce_rx_int_next_rx:
4211 			sw_prod = NEXT_RX_BD(sw_prod);
4212 		}
4213 
4214 		sw_cons = NEXT_RX_BD(sw_cons);
4215 
4216 		/* If we have a packet, pass it up the stack */
4217 		if (m) {
4218 			/* Make sure we don't lose our place when we release the lock. */
4219 			sc->rx_cons = sw_cons;
4220 			sc->rx_prod = sw_prod;
4221 			sc->rx_prod_bseq = sw_prod_bseq;
4222 
4223 			DBPRINT(sc, BCE_VERBOSE_RECV, "%s(): Passing received frame up.\n",
4224 				__FUNCTION__);
4225 			BCE_UNLOCK(sc);
4226 			(*ifp->if_input)(ifp, m);
4227 			DBRUNIF(1, sc->rx_mbuf_alloc--);
4228 			BCE_LOCK(sc);
4229 
4230 			/* Recover our place. */
4231 			sw_cons = sc->rx_cons;
4232 			sw_prod = sc->rx_prod;
4233 			sw_prod_bseq = sc->rx_prod_bseq;
4234 			hw_cons = sc->hw_rx_cons = sblk->status_rx_quick_consumer_index0;
4235 			if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
4236 				hw_cons++;
4237 		}
4238 
4239 		/* Refresh hw_cons to see if there's new work */
4240 		if (sw_cons == hw_cons) {
4241 			hw_cons = sc->hw_rx_cons = sblk->status_rx_quick_consumer_index0;
4242 			if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
4243 				hw_cons++;
4244 		}
4245 
4246 		/* Prevent speculative reads from getting ahead of the status block. */
4247 		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
4248 			BUS_SPACE_BARRIER_READ);
4249 	}
4250 
4251 	for (int i = 0; i < RX_PAGES; i++)
4252 		bus_dmamap_sync(sc->rx_bd_chain_tag,
4253 		    sc->rx_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
4254 
4255 	sc->rx_cons = sw_cons;
4256 	sc->rx_prod = sw_prod;
4257 	sc->rx_prod_bseq = sw_prod_bseq;
4258 
4259 	REG_WR16(sc, MB_RX_CID_ADDR + BCE_L2CTX_HOST_BDIDX, sc->rx_prod);
4260 	REG_WR(sc, MB_RX_CID_ADDR + BCE_L2CTX_HOST_BSEQ, sc->rx_prod_bseq);
4261 
4262 	DBPRINT(sc, BCE_INFO_RECV, "%s(exit): rx_prod = 0x%04X, "
4263 		"rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
4264 		__FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
4265 }
4266 
4267 
4268 /****************************************************************************/
4269 /* Handles transmit completion interrupt events.                            */
4270 /*                                                                          */
4271 /* Returns:                                                                 */
4272 /*   Nothing.                                                               */
4273 /****************************************************************************/
4274 static void
4275 bce_tx_intr(struct bce_softc *sc)
4276 {
4277 	struct status_block *sblk = sc->status_block;
4278 	struct ifnet *ifp = sc->bce_ifp;
4279 	u16 hw_tx_cons, sw_tx_cons, sw_tx_chain_cons;
4280 
4281 	BCE_LOCK_ASSERT(sc);
4282 
4283 	DBRUNIF(1, sc->tx_interrupts++);
4284 
4285 	/* Get the hardware's view of the TX consumer index. */
4286 	hw_tx_cons = sc->hw_tx_cons = sblk->status_tx_quick_consumer_index0;
4287 
4288 	/* Skip to the next entry if this is a chain page pointer. */
4289 	if ((hw_tx_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
4290 		hw_tx_cons++;
4291 
4292 	sw_tx_cons = sc->tx_cons;
4293 
4294 	/* Prevent speculative reads from getting ahead of the status block. */
4295 	bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
4296 		BUS_SPACE_BARRIER_READ);
4297 
4298 	/* Cycle through any completed TX chain page entries. */
4299 	while (sw_tx_cons != hw_tx_cons) {
4300 #ifdef BCE_DEBUG
4301 		struct tx_bd *txbd = NULL;
4302 #endif
4303 		sw_tx_chain_cons = TX_CHAIN_IDX(sw_tx_cons);
4304 
4305 		DBPRINT(sc, BCE_INFO_SEND,
4306 			"%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, "
4307 			"sw_tx_chain_cons = 0x%04X\n",
4308 			__FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
4309 
4310 		DBRUNIF((sw_tx_chain_cons > MAX_TX_BD),
4311 			BCE_PRINTF("%s(%d): TX chain consumer out of range! "
4312 				" 0x%04X > 0x%04X\n", __FILE__, __LINE__, sw_tx_chain_cons,
4313 				(int) MAX_TX_BD);
4314 			bce_breakpoint(sc));
4315 
4316 		DBRUNIF(1, txbd = &sc->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)]
4317 				[TX_IDX(sw_tx_chain_cons)]);
4318 
4319 		DBRUNIF((txbd == NULL),
4320 			BCE_PRINTF("%s(%d): Unexpected NULL tx_bd[0x%04X]!\n",
4321 				__FILE__, __LINE__, sw_tx_chain_cons);
4322 			bce_breakpoint(sc));
4323 
4324 		DBRUN(BCE_INFO_SEND, BCE_PRINTF("%s(): ", __FUNCTION__);
4325 			bce_dump_txbd(sc, sw_tx_chain_cons, txbd));
4326 
4327 		/*
4328 		 * Free the associated mbuf. Remember
4329 		 * that only the last tx_bd of a packet
4330 		 * has an mbuf pointer and DMA map.
4331 		 */
4332 		if (sc->tx_mbuf_ptr[sw_tx_chain_cons] != NULL) {
4333 
4334 			/* Validate that this is the last tx_bd. */
4335 			DBRUNIF((!(txbd->tx_bd_flags & TX_BD_FLAGS_END)),
4336 				BCE_PRINTF("%s(%d): tx_bd END flag not set but "
4337 				"txmbuf == NULL!\n", __FILE__, __LINE__);
4338 				bce_breakpoint(sc));
4339 
4340 			DBRUN(BCE_INFO_SEND,
4341 				BCE_PRINTF("%s(): Unloading map/freeing mbuf "
4342 					"from tx_bd[0x%04X]\n", __FUNCTION__, sw_tx_chain_cons));
4343 
4344 			/* Unmap the mbuf. */
4345 			bus_dmamap_unload(sc->tx_mbuf_tag,
4346 			    sc->tx_mbuf_map[sw_tx_chain_cons]);
4347 
4348 			/* Free the mbuf. */
4349 			m_freem(sc->tx_mbuf_ptr[sw_tx_chain_cons]);
4350 			sc->tx_mbuf_ptr[sw_tx_chain_cons] = NULL;
4351 			DBRUNIF(1, sc->tx_mbuf_alloc--);
4352 
4353 			ifp->if_opackets++;
4354 		}
4355 
4356 		sc->used_tx_bd--;
4357 		sw_tx_cons = NEXT_TX_BD(sw_tx_cons);
4358 
4359 		/* Refresh hw_cons to see if there's new work. */
4360 		hw_tx_cons = sc->hw_tx_cons = sblk->status_tx_quick_consumer_index0;
4361 		if ((hw_tx_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
4362 			hw_tx_cons++;
4363 
4364 		/* Prevent speculative reads from getting ahead of the status block. */
4365 		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
4366 			BUS_SPACE_BARRIER_READ);
4367 	}
4368 
4369 	/* Clear the TX timeout timer. */
4370 	sc->watchdog_timer = 0;
4371 
4372 	/* Clear the tx hardware queue full flag. */
4373 	if (sc->used_tx_bd < sc->max_tx_bd) {
4374 		DBRUNIF((ifp->if_drv_flags & IFF_DRV_OACTIVE),
4375 			DBPRINT(sc, BCE_WARN_SEND,
4376 				"%s(): Open TX chain! %d/%d (used/total)\n",
4377 				__FUNCTION__, sc->used_tx_bd, sc->max_tx_bd));
4378 		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4379 	}
4380 
4381 	sc->tx_cons = sw_tx_cons;
4382 }
4383 
4384 
4385 /****************************************************************************/
4386 /* Disables interrupt generation.                                           */
4387 /*                                                                          */
4388 /* Returns:                                                                 */
4389 /*   Nothing.                                                               */
4390 /****************************************************************************/
4391 static void
4392 bce_disable_intr(struct bce_softc *sc)
4393 {
4394 	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
4395 	       BCE_PCICFG_INT_ACK_CMD_MASK_INT);
4396 	REG_RD(sc, BCE_PCICFG_INT_ACK_CMD);
4397 }
4398 
4399 
4400 /****************************************************************************/
4401 /* Enables interrupt generation.                                            */
4402 /*                                                                          */
4403 /* Returns:                                                                 */
4404 /*   Nothing.                                                               */
4405 /****************************************************************************/
4406 static void
4407 bce_enable_intr(struct bce_softc *sc)
4408 {
4409 	u32 val;
4410 
4411 	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
4412 	       BCE_PCICFG_INT_ACK_CMD_INDEX_VALID |
4413 	       BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
4414 
4415 	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
4416 	       BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
4417 
4418 	val = REG_RD(sc, BCE_HC_COMMAND);
4419 	REG_WR(sc, BCE_HC_COMMAND, val | BCE_HC_COMMAND_COAL_NOW);
4420 }
4421 
4422 
4423 /****************************************************************************/
4424 /* Handles controller initialization.                                       */
4425 /*                                                                          */
4426 /* Returns:                                                                 */
4427 /*   Nothing.                                                               */
4428 /****************************************************************************/
4429 static void
4430 bce_init_locked(struct bce_softc *sc)
4431 {
4432 	struct ifnet *ifp;
4433 	u32 ether_mtu;
4434 
4435 	DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
4436 
4437 	BCE_LOCK_ASSERT(sc);
4438 
4439 	ifp = sc->bce_ifp;
4440 
4441 	/* Check if the driver is still running and bail out if it is. */
4442 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
4443 		goto bce_init_locked_exit;
4444 
4445 	bce_stop(sc);
4446 
4447 	if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
4448 		BCE_PRINTF("%s(%d): Controller reset failed!\n",
4449 			__FILE__, __LINE__);
4450 		goto bce_init_locked_exit;
4451 	}
4452 
4453 	if (bce_chipinit(sc)) {
4454 		BCE_PRINTF("%s(%d): Controller initialization failed!\n",
4455 			__FILE__, __LINE__);
4456 		goto bce_init_locked_exit;
4457 	}
4458 
4459 	if (bce_blockinit(sc)) {
4460 		BCE_PRINTF("%s(%d): Block initialization failed!\n",
4461 			__FILE__, __LINE__);
4462 		goto bce_init_locked_exit;
4463 	}
4464 
4465 	/* Load our MAC address. */
4466 	bcopy(IF_LLADDR(sc->bce_ifp), sc->eaddr, ETHER_ADDR_LEN);
4467 	bce_set_mac_addr(sc);
4468 
4469 	/* Calculate and program the Ethernet MTU size. */
4470 	ether_mtu = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ifp->if_mtu +
4471 		ETHER_CRC_LEN;
4472 
4473 	DBPRINT(sc, BCE_INFO, "%s(): setting mtu = %d\n",__FUNCTION__, ether_mtu);
4474 
4475 	/*
4476 	 * Program the mtu, enabling jumbo frame
4477 	 * support if necessary.  Also set the mbuf
4478 	 * allocation count for RX frames.
4479 	 */
4480 	if (ether_mtu > ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN) {
4481 		REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, min(ether_mtu, BCE_MAX_JUMBO_ETHER_MTU) |
4482 			BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA);
4483 		sc->mbuf_alloc_size = MJUM9BYTES;
4484 	} else {
4485 		REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu);
4486 		sc->mbuf_alloc_size = MCLBYTES;
4487 	}
4488 
4489 	/* Calculate the RX Ethernet frame size for rx_bd's. */
4490 	sc->max_frame_size = sizeof(struct l2_fhdr) + 2 + ether_mtu + 8;
4491 
4492 	DBPRINT(sc, BCE_INFO,
4493 		"%s(): mclbytes = %d, mbuf_alloc_size = %d, "
4494 		"max_frame_size = %d\n",
4495 		__FUNCTION__, (int) MCLBYTES, sc->mbuf_alloc_size, sc->max_frame_size);
4496 
4497 	/* Program appropriate promiscuous/multicast filtering. */
4498 	bce_set_rx_mode(sc);
4499 
4500 	/* Init RX buffer descriptor chain. */
4501 	bce_init_rx_chain(sc);
4502 
4503 	/* Init TX buffer descriptor chain. */
4504 	bce_init_tx_chain(sc);
4505 
4506 #ifdef DEVICE_POLLING
4507 	/* Disable interrupts if we are polling. */
4508 	if (ifp->if_capenable & IFCAP_POLLING) {
4509 		bce_disable_intr(sc);
4510 
4511 		REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
4512 			(1 << 16) | sc->bce_rx_quick_cons_trip);
4513 		REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
4514 			(1 << 16) | sc->bce_tx_quick_cons_trip);
4515 	} else
4516 #endif
4517 	/* Enable host interrupts. */
4518 	bce_enable_intr(sc);
4519 
4520 	bce_ifmedia_upd_locked(ifp);
4521 
4522 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
4523 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
4524 
4525 	callout_reset(&sc->bce_stat_ch, hz, bce_tick, sc);
4526 
4527 bce_init_locked_exit:
4528 	DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
4529 
4530 	return;
4531 }
4532 
4533 
4534 /****************************************************************************/
4535 /* Initialize the controller just enough so that any management firmware    */
4536 /* running on the device will continue to operate corectly.                 */
4537 /*                                                                          */
4538 /* Returns:                                                                 */
4539 /*   Nothing.                                                               */
4540 /****************************************************************************/
4541 static void
4542 bce_mgmt_init_locked(struct bce_softc *sc)
4543 {
4544 	u32 val;
4545 	struct ifnet *ifp;
4546 
4547 	DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
4548 
4549 	BCE_LOCK_ASSERT(sc);
4550 
4551 	ifp = sc->bce_ifp;
4552 
4553 	/* Check if the driver is still running and bail out if it is. */
4554 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
4555 		goto bce_mgmt_init_locked_exit;
4556 
4557 	/* Initialize the on-boards CPUs */
4558 	bce_init_cpus(sc);
4559 
4560 	/* Set the page size and clear the RV2P processor stall bits. */
4561 	val = (BCM_PAGE_BITS - 8) << 24;
4562 	REG_WR(sc, BCE_RV2P_CONFIG, val);
4563 
4564 	/* Enable all critical blocks in the MAC. */
4565 	REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
4566 	       BCE_MISC_ENABLE_SET_BITS_RX_V2P_ENABLE |
4567 	       BCE_MISC_ENABLE_SET_BITS_RX_DMA_ENABLE |
4568 	       BCE_MISC_ENABLE_SET_BITS_COMPLETION_ENABLE);
4569 	REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
4570 	DELAY(20);
4571 
4572 	bce_ifmedia_upd_locked(ifp);
4573 bce_mgmt_init_locked_exit:
4574 	DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
4575 
4576 	return;
4577 }
4578 
4579 
4580 /****************************************************************************/
4581 /* Handles controller initialization when called from an unlocked routine.  */
4582 /*                                                                          */
4583 /* Returns:                                                                 */
4584 /*   Nothing.                                                               */
4585 /****************************************************************************/
4586 static void
4587 bce_init(void *xsc)
4588 {
4589 	struct bce_softc *sc = xsc;
4590 
4591 	BCE_LOCK(sc);
4592 	bce_init_locked(sc);
4593 	BCE_UNLOCK(sc);
4594 }
4595 
4596 
4597 /****************************************************************************/
4598 /* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
4599 /* memory visible to the controller.                                        */
4600 /*                                                                          */
4601 /* Returns:                                                                 */
4602 /*   0 for success, positive value for failure.                             */
4603 /****************************************************************************/
4604 static int
4605 bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
4606 {
4607 	bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
4608 	bus_dmamap_t map;
4609 	struct tx_bd *txbd = NULL;
4610 	struct mbuf *m0;
4611 	struct ether_vlan_header *eh;
4612 	struct ip *ip;
4613 	struct tcphdr *th;
4614 	u16 prod, chain_prod, etype, mss = 0, vlan_tag = 0, flags = 0;
4615 	u32 prod_bseq;
4616 	int hdr_len = 0, e_hlen = 0, ip_hlen = 0, tcp_hlen = 0, ip_len = 0;
4617 
4618 
4619 #ifdef BCE_DEBUG
4620 	u16 debug_prod;
4621 #endif
4622 	int i, error, nsegs, rc = 0;
4623 
4624 	/* Transfer any checksum offload flags to the bd. */
4625 	m0 = *m_head;
4626 	if (m0->m_pkthdr.csum_flags) {
4627 		if (m0->m_pkthdr.csum_flags & CSUM_IP)
4628 			flags |= TX_BD_FLAGS_IP_CKSUM;
4629 		if (m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
4630 			flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
4631 		if (m0->m_pkthdr.csum_flags & CSUM_TSO) {
4632 			/* For TSO the controller needs two pieces of info, */
4633 			/* the MSS and the IP+TCP options length.           */
4634 			mss = htole16(m0->m_pkthdr.tso_segsz);
4635 
4636 			/* Map the header and find the Ethernet type & header length */
4637 			eh = mtod(m0, struct ether_vlan_header *);
4638 			if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
4639 				etype = ntohs(eh->evl_proto);
4640 				e_hlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
4641 			} else {
4642 				etype = ntohs(eh->evl_encap_proto);
4643 				e_hlen = ETHER_HDR_LEN;
4644 			}
4645 
4646 			/* Check for supported TSO Ethernet types (only IPv4 for now) */
4647 			switch (etype) {
4648 				case ETHERTYPE_IP:
4649 					ip = (struct ip *)(m0->m_data + e_hlen);
4650 
4651 					/* TSO only supported for TCP protocol */
4652 					if (ip->ip_p != IPPROTO_TCP) {
4653 						BCE_PRINTF("%s(%d): TSO enabled for non-TCP frame!.\n",
4654 							__FILE__, __LINE__);
4655 						goto bce_tx_encap_skip_tso;
4656 					}
4657 
4658 					/* Get IP header length in bytes (min 20) */
4659 					ip_hlen = ip->ip_hl << 2;
4660 
4661 					/* Get the TCP header length in bytes (min 20) */
4662 					th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
4663 					tcp_hlen = (th->th_off << 2);
4664 
4665 					/* IP header length and checksum will be calc'd by hardware */
4666 					ip_len = ip->ip_len;
4667 					ip->ip_len = 0;
4668 					ip->ip_sum = 0;
4669 					break;
4670 				case ETHERTYPE_IPV6:
4671 					BCE_PRINTF("%s(%d): TSO over IPv6 not supported!.\n",
4672 						__FILE__, __LINE__);
4673 					goto bce_tx_encap_skip_tso;
4674 				default:
4675 					BCE_PRINTF("%s(%d): TSO enabled for unsupported protocol!.\n",
4676 						__FILE__, __LINE__);
4677 					goto bce_tx_encap_skip_tso;
4678 			}
4679 
4680 			hdr_len = e_hlen + ip_hlen + tcp_hlen;
4681 
4682 			DBPRINT(sc, BCE_EXCESSIVE_SEND,
4683 				"%s(): hdr_len = %d, e_hlen = %d, ip_hlen = %d, tcp_hlen = %d, ip_len = %d\n",
4684 				 __FUNCTION__, hdr_len, e_hlen, ip_hlen, tcp_hlen, ip_len);
4685 
4686 			/* Set the LSO flag in the TX BD */
4687 			flags |= TX_BD_FLAGS_SW_LSO;
4688 			/* Set the length of IP + TCP options (in 32 bit words) */
4689 			flags |= (((ip_hlen + tcp_hlen - 40) >> 2) << 8);
4690 
4691 bce_tx_encap_skip_tso:
4692 			DBRUNIF(1, sc->requested_tso_frames++);
4693 		}
4694 	}
4695 
4696 	/* Transfer any VLAN tags to the bd. */
4697 	if (m0->m_flags & M_VLANTAG) {
4698 		flags |= TX_BD_FLAGS_VLAN_TAG;
4699 		vlan_tag = m0->m_pkthdr.ether_vtag;
4700 	}
4701 
4702 	/* Map the mbuf into DMAable memory. */
4703 	prod = sc->tx_prod;
4704 	chain_prod = TX_CHAIN_IDX(prod);
4705 	map = sc->tx_mbuf_map[chain_prod];
4706 
4707 	/* Map the mbuf into our DMA address space. */
4708 	error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag, map, m0,
4709 	    segs, &nsegs, BUS_DMA_NOWAIT);
4710 
4711 	/* Check if the DMA mapping was successful */
4712 	if (error == EFBIG) {
4713 
4714         DBPRINT(sc, BCE_WARN, "%s(): fragmented mbuf (%d pieces)\n",
4715 			__FUNCTION__, nsegs);
4716 		DBRUNIF(1, bce_dump_mbuf(sc, m0););
4717 
4718 		/* Try to defrag the mbuf if there are too many segments. */
4719 		m0 = m_defrag(*m_head, M_DONTWAIT);
4720         if (m0 == NULL) {
4721 			/* Defrag was unsuccessful */
4722 			m_freem(*m_head);
4723 			*m_head = NULL;
4724 			return (ENOBUFS);
4725 		}
4726 
4727 		/* Defrag was successful, try mapping again */
4728 		*m_head = m0;
4729 		error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag, map, m0,
4730 		    segs, &nsegs, BUS_DMA_NOWAIT);
4731 
4732 		/* Still getting an error after a defrag. */
4733 		if (error == ENOMEM) {
4734 			return (error);
4735 		} else if (error != 0) {
4736 			BCE_PRINTF(
4737 			    "%s(%d): Unknown error mapping mbuf into TX chain!\n",
4738 			    __FILE__, __LINE__);
4739 			m_freem(m0);
4740 			*m_head = NULL;
4741 			return (ENOBUFS);
4742 		}
4743 	} else if (error == ENOMEM) {
4744 		return (error);
4745 	} else if (error != 0) {
4746 		m_freem(m0);
4747 		*m_head = NULL;
4748 		return (error);
4749 	}
4750 
4751 	/* Make sure there's room in the chain */
4752 	if (nsegs > (sc->max_tx_bd - sc->used_tx_bd)) {
4753 		bus_dmamap_unload(sc->tx_mbuf_tag, map);
4754 		return (ENOBUFS);
4755 	}
4756 
4757 	/* prod points to an empty tx_bd at this point. */
4758 	prod_bseq  = sc->tx_prod_bseq;
4759 
4760 #ifdef BCE_DEBUG
4761 	debug_prod = chain_prod;
4762 #endif
4763 
4764 	DBPRINT(sc, BCE_INFO_SEND,
4765 		"%s(): Start: prod = 0x%04X, chain_prod = %04X, "
4766 		"prod_bseq = 0x%08X\n",
4767 		__FUNCTION__, prod, chain_prod, prod_bseq);
4768 
4769 	/*
4770 	 * Cycle through each mbuf segment that makes up
4771 	 * the outgoing frame, gathering the mapping info
4772 	 * for that segment and creating a tx_bd to for
4773 	 * the mbuf.
4774 	 */
4775 	for (i = 0; i < nsegs ; i++) {
4776 
4777 		chain_prod = TX_CHAIN_IDX(prod);
4778 		txbd= &sc->tx_bd_chain[TX_PAGE(chain_prod)][TX_IDX(chain_prod)];
4779 
4780 		txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(segs[i].ds_addr));
4781 		txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(segs[i].ds_addr));
4782 		txbd->tx_bd_mss_nbytes = htole32(mss << 16) | htole16(segs[i].ds_len);
4783 		txbd->tx_bd_vlan_tag = htole16(vlan_tag);
4784 		txbd->tx_bd_flags = htole16(flags);
4785 		prod_bseq += segs[i].ds_len;
4786 		if (i == 0)
4787 			txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_START);
4788 		prod = NEXT_TX_BD(prod);
4789 	}
4790 
4791 	/* Set the END flag on the last TX buffer descriptor. */
4792 	txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_END);
4793 
4794 	DBRUN(BCE_EXCESSIVE_SEND, bce_dump_tx_chain(sc, debug_prod, nsegs));
4795 
4796 	DBPRINT(sc, BCE_INFO_SEND,
4797 		"%s(): End: prod = 0x%04X, chain_prod = %04X, "
4798 		"prod_bseq = 0x%08X\n",
4799 		__FUNCTION__, prod, chain_prod, prod_bseq);
4800 
4801 	/*
4802 	 * Ensure that the mbuf pointer for this transmission
4803 	 * is placed at the array index of the last
4804 	 * descriptor in this chain.  This is done
4805 	 * because a single map is used for all
4806 	 * segments of the mbuf and we don't want to
4807 	 * unload the map before all of the segments
4808 	 * have been freed.
4809 	 */
4810 	sc->tx_mbuf_ptr[chain_prod] = m0;
4811 	sc->used_tx_bd += nsegs;
4812 
4813 	/* Update some debug statistic counters */
4814 	DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
4815 		sc->tx_hi_watermark = sc->used_tx_bd);
4816 	DBRUNIF((sc->used_tx_bd == sc->max_tx_bd), sc->tx_full_count++);
4817 	DBRUNIF(1, sc->tx_mbuf_alloc++);
4818 
4819 	DBRUN(BCE_VERBOSE_SEND, bce_dump_tx_mbuf_chain(sc, chain_prod, nsegs));
4820 
4821 	/* prod points to the next free tx_bd at this point. */
4822 	sc->tx_prod = prod;
4823 	sc->tx_prod_bseq = prod_bseq;
4824 
4825 	return(rc);
4826 }
4827 
4828 
4829 /****************************************************************************/
4830 /* Main transmit routine when called from another routine with a lock.      */
4831 /*                                                                          */
4832 /* Returns:                                                                 */
4833 /*   Nothing.                                                               */
4834 /****************************************************************************/
4835 static void
4836 bce_start_locked(struct ifnet *ifp)
4837 {
4838 	struct bce_softc *sc = ifp->if_softc;
4839 	struct mbuf *m_head = NULL;
4840 	int count = 0;
4841 	u16 tx_prod, tx_chain_prod;
4842 
4843 	/* If there's no link or the transmit queue is empty then just exit. */
4844 	if (!sc->bce_link || IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
4845 		DBPRINT(sc, BCE_INFO_SEND, "%s(): No link or transmit queue empty.\n",
4846 			__FUNCTION__);
4847 		goto bce_start_locked_exit;
4848 	}
4849 
4850 	/* prod points to the next free tx_bd. */
4851 	tx_prod = sc->tx_prod;
4852 	tx_chain_prod = TX_CHAIN_IDX(tx_prod);
4853 
4854 	DBPRINT(sc, BCE_INFO_SEND,
4855 		"%s(): Start: tx_prod = 0x%04X, tx_chain_prod = %04X, "
4856 		"tx_prod_bseq = 0x%08X\n",
4857 		__FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
4858 
4859 	/*
4860 	 * Keep adding entries while there is space in the ring.
4861 	 */
4862 	while (sc->used_tx_bd < sc->max_tx_bd) {
4863 
4864 		/* Check for any frames to send. */
4865 		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
4866 		if (m_head == NULL)
4867 			break;
4868 
4869 		/*
4870 		 * Pack the data into the transmit ring. If we
4871 		 * don't have room, place the mbuf back at the
4872 		 * head of the queue and set the OACTIVE flag
4873 		 * to wait for the NIC to drain the chain.
4874 		 */
4875 		if (bce_tx_encap(sc, &m_head)) {
4876 			IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
4877 			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
4878 			DBPRINT(sc, BCE_INFO_SEND,
4879 				"TX chain is closed for business! Total tx_bd used = %d\n",
4880 				sc->used_tx_bd);
4881 			break;
4882 		}
4883 
4884 		count++;
4885 
4886 		/* Send a copy of the frame to any BPF listeners. */
4887 		ETHER_BPF_MTAP(ifp, m_head);
4888 	}
4889 
4890 	if (count == 0) {
4891 		/* no packets were dequeued */
4892 		DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were dequeued\n",
4893 			__FUNCTION__);
4894 		goto bce_start_locked_exit;
4895 	}
4896 
4897 	/* Update the driver's counters. */
4898 	tx_chain_prod = TX_CHAIN_IDX(sc->tx_prod);
4899 
4900 	DBPRINT(sc, BCE_INFO_SEND,
4901 		"%s(): End: tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
4902 		"tx_prod_bseq = 0x%08X\n",
4903 		__FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
4904 
4905 	/* Start the transmit. */
4906 	REG_WR16(sc, MB_TX_CID_ADDR + BCE_L2CTX_TX_HOST_BIDX, sc->tx_prod);
4907 	REG_WR(sc, MB_TX_CID_ADDR + BCE_L2CTX_TX_HOST_BSEQ, sc->tx_prod_bseq);
4908 
4909 	/* Set the tx timeout. */
4910 	sc->watchdog_timer = BCE_TX_TIMEOUT;
4911 
4912 bce_start_locked_exit:
4913 	return;
4914 }
4915 
4916 
4917 /****************************************************************************/
4918 /* Main transmit routine when called from another routine without a lock.   */
4919 /*                                                                          */
4920 /* Returns:                                                                 */
4921 /*   Nothing.                                                               */
4922 /****************************************************************************/
4923 static void
4924 bce_start(struct ifnet *ifp)
4925 {
4926 	struct bce_softc *sc = ifp->if_softc;
4927 
4928 	BCE_LOCK(sc);
4929 	bce_start_locked(ifp);
4930 	BCE_UNLOCK(sc);
4931 }
4932 
4933 
4934 /****************************************************************************/
4935 /* Handles any IOCTL calls from the operating system.                       */
4936 /*                                                                          */
4937 /* Returns:                                                                 */
4938 /*   0 for success, positive value for failure.                             */
4939 /****************************************************************************/
4940 static int
4941 bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
4942 {
4943 	struct bce_softc *sc = ifp->if_softc;
4944 	struct ifreq *ifr = (struct ifreq *) data;
4945 	struct mii_data *mii;
4946 	int mask, error = 0;
4947 
4948 	DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
4949 
4950 	switch(command) {
4951 
4952 		/* Set the MTU. */
4953 		case SIOCSIFMTU:
4954 			/* Check that the MTU setting is supported. */
4955 			if ((ifr->ifr_mtu < BCE_MIN_MTU) ||
4956 				(ifr->ifr_mtu > BCE_MAX_JUMBO_MTU)) {
4957 				error = EINVAL;
4958 				break;
4959 			}
4960 
4961 			DBPRINT(sc, BCE_INFO, "Setting new MTU of %d\n", ifr->ifr_mtu);
4962 
4963 			BCE_LOCK(sc);
4964 			ifp->if_mtu = ifr->ifr_mtu;
4965 			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
4966 			bce_init_locked(sc);
4967 			BCE_UNLOCK(sc);
4968 			break;
4969 
4970 		/* Set interface. */
4971 		case SIOCSIFFLAGS:
4972 			DBPRINT(sc, BCE_VERBOSE, "Received SIOCSIFFLAGS\n");
4973 
4974 			BCE_LOCK(sc);
4975 
4976 			/* Check if the interface is up. */
4977 			if (ifp->if_flags & IFF_UP) {
4978 				if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
4979 					/* Change the promiscuous/multicast flags as necessary. */
4980 					bce_set_rx_mode(sc);
4981 				} else {
4982 					/* Start the HW */
4983 					bce_init_locked(sc);
4984 				}
4985 			} else {
4986 				/* The interface is down.  Check if the driver is running. */
4987 				if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
4988 					bce_stop(sc);
4989 				}
4990 			}
4991 
4992 			BCE_UNLOCK(sc);
4993 			error = 0;
4994 
4995 			break;
4996 
4997 		/* Add/Delete multicast address */
4998 		case SIOCADDMULTI:
4999 		case SIOCDELMULTI:
5000 			DBPRINT(sc, BCE_VERBOSE, "Received SIOCADDMULTI/SIOCDELMULTI\n");
5001 
5002 			BCE_LOCK(sc);
5003 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
5004 				bce_set_rx_mode(sc);
5005 				error = 0;
5006 			}
5007 			BCE_UNLOCK(sc);
5008 
5009 			break;
5010 
5011 		/* Set/Get Interface media */
5012 		case SIOCSIFMEDIA:
5013 		case SIOCGIFMEDIA:
5014 			DBPRINT(sc, BCE_VERBOSE, "Received SIOCSIFMEDIA/SIOCGIFMEDIA\n");
5015 
5016 			DBPRINT(sc, BCE_VERBOSE, "bce_phy_flags = 0x%08X\n",
5017 				sc->bce_phy_flags);
5018 
5019 			DBPRINT(sc, BCE_VERBOSE, "Copper media set/get\n");
5020 			mii = device_get_softc(sc->bce_miibus);
5021 			error = ifmedia_ioctl(ifp, ifr,
5022 			    &mii->mii_media, command);
5023 			break;
5024 
5025 		/* Set interface capability */
5026 		case SIOCSIFCAP:
5027 			mask = ifr->ifr_reqcap ^ ifp->if_capenable;
5028 			DBPRINT(sc, BCE_INFO, "Received SIOCSIFCAP = 0x%08X\n", (u32) mask);
5029 
5030 #ifdef DEVICE_POLLING
5031 			if (mask & IFCAP_POLLING) {
5032 				if (ifr->ifr_reqcap & IFCAP_POLLING) {
5033 
5034 					/* Setup the poll routine to call. */
5035 					error = ether_poll_register(bce_poll, ifp);
5036 					if (error) {
5037 						BCE_PRINTF("%s(%d): Error registering poll function!\n",
5038 							__FILE__, __LINE__);
5039 						goto bce_ioctl_exit;
5040 					}
5041 
5042 					/* Clear the interrupt. */
5043 					BCE_LOCK(sc);
5044 					bce_disable_intr(sc);
5045 
5046 					REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
5047 						(1 << 16) | sc->bce_rx_quick_cons_trip);
5048 					REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
5049 						(1 << 16) | sc->bce_tx_quick_cons_trip);
5050 
5051 					ifp->if_capenable |= IFCAP_POLLING;
5052 					BCE_UNLOCK(sc);
5053 				} else {
5054 					/* Clear the poll routine. */
5055 					error = ether_poll_deregister(ifp);
5056 
5057 					/* Enable interrupt even in error case */
5058 					BCE_LOCK(sc);
5059 					bce_enable_intr(sc);
5060 
5061 					REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
5062 						(sc->bce_tx_quick_cons_trip_int << 16) |
5063 						sc->bce_tx_quick_cons_trip);
5064 					REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
5065 						(sc->bce_rx_quick_cons_trip_int << 16) |
5066 						sc->bce_rx_quick_cons_trip);
5067 
5068 					ifp->if_capenable &= ~IFCAP_POLLING;
5069 					BCE_UNLOCK(sc);
5070 				}
5071 			}
5072 #endif /*DEVICE_POLLING */
5073 
5074 			/* Toggle the TX checksum capabilites enable flag. */
5075 			if (mask & IFCAP_TXCSUM) {
5076 				ifp->if_capenable ^= IFCAP_TXCSUM;
5077 				if (IFCAP_TXCSUM & ifp->if_capenable)
5078 					ifp->if_hwassist = BCE_IF_HWASSIST;
5079 				else
5080 					ifp->if_hwassist = 0;
5081 			}
5082 
5083 			/* Toggle the RX checksum capabilities enable flag. */
5084 			if (mask & IFCAP_RXCSUM) {
5085 				ifp->if_capenable ^= IFCAP_RXCSUM;
5086 				if (IFCAP_RXCSUM & ifp->if_capenable)
5087 					ifp->if_hwassist = BCE_IF_HWASSIST;
5088 				else
5089 					ifp->if_hwassist = 0;
5090 			}
5091 
5092 			/* Toggle the TSO capabilities enable flag. */
5093 			if (bce_tso_enable && (mask & IFCAP_TSO4)) {
5094 				ifp->if_capenable ^= IFCAP_TSO4;
5095 				if (IFCAP_RXCSUM & ifp->if_capenable)
5096 					ifp->if_hwassist = BCE_IF_HWASSIST;
5097 				else
5098 					ifp->if_hwassist = 0;
5099 			}
5100 
5101 			/* Toggle VLAN_MTU capabilities enable flag. */
5102 			if (mask & IFCAP_VLAN_MTU) {
5103 				BCE_PRINTF("%s(%d): Changing VLAN_MTU not supported.\n",
5104 					__FILE__, __LINE__);
5105 			}
5106 
5107 			/* Toggle VLANHWTAG capabilities enabled flag. */
5108 			if (mask & IFCAP_VLAN_HWTAGGING) {
5109 				if (sc->bce_flags & BCE_MFW_ENABLE_FLAG)
5110 					BCE_PRINTF("%s(%d): Cannot change VLAN_HWTAGGING while "
5111 						"management firmware (ASF/IPMI/UMP) is running!\n",
5112 						__FILE__, __LINE__);
5113 				else
5114 					BCE_PRINTF("%s(%d): Changing VLAN_HWTAGGING not supported!\n",
5115 						__FILE__, __LINE__);
5116 			}
5117 
5118 			break;
5119 		default:
5120 			DBPRINT(sc, BCE_INFO, "Received unsupported IOCTL: 0x%08X\n",
5121 				(u32) command);
5122 
5123 			/* We don't know how to handle the IOCTL, pass it on. */
5124 			error = ether_ioctl(ifp, command, data);
5125 			break;
5126 	}
5127 
5128 #ifdef DEVICE_POLLING
5129 bce_ioctl_exit:
5130 #endif
5131 
5132 	DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
5133 
5134 	return(error);
5135 }
5136 
5137 
5138 /****************************************************************************/
5139 /* Transmit timeout handler.                                                */
5140 /*                                                                          */
5141 /* Returns:                                                                 */
5142 /*   Nothing.                                                               */
5143 /****************************************************************************/
5144 static void
5145 bce_watchdog(struct bce_softc *sc)
5146 {
5147 
5148 	DBRUN(BCE_VERBOSE_SEND,
5149 		bce_dump_driver_state(sc);
5150 		bce_dump_status_block(sc));
5151 
5152 	BCE_LOCK_ASSERT(sc);
5153 
5154 	if (sc->watchdog_timer == 0 || --sc->watchdog_timer)
5155 		return;
5156 
5157 	/*
5158 	 * If we are in this routine because of pause frames, then
5159 	 * don't reset the hardware.
5160 	 */
5161 	if (REG_RD(sc, BCE_EMAC_TX_STATUS) & BCE_EMAC_TX_STATUS_XOFFED)
5162 		return;
5163 
5164 	BCE_PRINTF("%s(%d): Watchdog timeout occurred, resetting!\n",
5165 		__FILE__, __LINE__);
5166 
5167 	/* DBRUN(BCE_FATAL, bce_breakpoint(sc)); */
5168 
5169 	sc->bce_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
5170 
5171 	bce_init_locked(sc);
5172 	sc->bce_ifp->if_oerrors++;
5173 
5174 }
5175 
5176 
5177 #ifdef DEVICE_POLLING
5178 static void
5179 bce_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count)
5180 {
5181 	struct bce_softc *sc = ifp->if_softc;
5182 
5183 	BCE_LOCK_ASSERT(sc);
5184 
5185 	sc->bce_rxcycles = count;
5186 
5187 	bus_dmamap_sync(sc->status_tag, sc->status_map,
5188 	    BUS_DMASYNC_POSTWRITE);
5189 
5190 	/* Check for any completed RX frames. */
5191 	if (sc->status_block->status_rx_quick_consumer_index0 !=
5192 		sc->hw_rx_cons)
5193 		bce_rx_intr(sc);
5194 
5195 	/* Check for any completed TX frames. */
5196 	if (sc->status_block->status_tx_quick_consumer_index0 !=
5197 		sc->hw_tx_cons)
5198 		bce_tx_intr(sc);
5199 
5200 	/* Check for new frames to transmit. */
5201 	if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
5202 		bce_start_locked(ifp);
5203 
5204 }
5205 
5206 
5207 static void
5208 bce_poll(struct ifnet *ifp, enum poll_cmd cmd, int count)
5209 {
5210 	struct bce_softc *sc = ifp->if_softc;
5211 
5212 	BCE_LOCK(sc);
5213 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
5214 		bce_poll_locked(ifp, cmd, count);
5215 	BCE_UNLOCK(sc);
5216 }
5217 #endif /* DEVICE_POLLING */
5218 
5219 
5220 #if 0
5221 static inline int
5222 bce_has_work(struct bce_softc *sc)
5223 {
5224 	struct status_block *stat = sc->status_block;
5225 
5226 	if ((stat->status_rx_quick_consumer_index0 != sc->hw_rx_cons) ||
5227 	    (stat->status_tx_quick_consumer_index0 != sc->hw_tx_cons))
5228 		return 1;
5229 
5230 	if (((stat->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) != 0) !=
5231 	    bp->link_up)
5232 		return 1;
5233 
5234 	return 0;
5235 }
5236 #endif
5237 
5238 
5239 /*
5240  * Interrupt handler.
5241  */
5242 /****************************************************************************/
5243 /* Main interrupt entry point.  Verifies that the controller generated the  */
5244 /* interrupt and then calls a separate routine for handle the various       */
5245 /* interrupt causes (PHY, TX, RX).                                          */
5246 /*                                                                          */
5247 /* Returns:                                                                 */
5248 /*   0 for success, positive value for failure.                             */
5249 /****************************************************************************/
5250 static void
5251 bce_intr(void *xsc)
5252 {
5253 	struct bce_softc *sc;
5254 	struct ifnet *ifp;
5255 	u32 status_attn_bits;
5256 
5257 	sc = xsc;
5258 	ifp = sc->bce_ifp;
5259 
5260 	DBPRINT(sc, BCE_EXCESSIVE, "Entering %s()\n", __FUNCTION__);
5261 	BCE_LOCK(sc);
5262 
5263 	DBRUNIF(1, sc->interrupts_generated++);
5264 
5265 #ifdef DEVICE_POLLING
5266 	if (ifp->if_capenable & IFCAP_POLLING) {
5267 		DBPRINT(sc, BCE_INFO, "Polling enabled!\n");
5268 		goto bce_intr_exit;
5269 	}
5270 #endif
5271 
5272 	bus_dmamap_sync(sc->status_tag, sc->status_map,
5273 	    BUS_DMASYNC_POSTWRITE);
5274 
5275 	/*
5276 	 * If the hardware status block index
5277 	 * matches the last value read by the
5278 	 * driver and we haven't asserted our
5279 	 * interrupt then there's nothing to do.
5280 	 */
5281 	if ((sc->status_block->status_idx == sc->last_status_idx) &&
5282 		(REG_RD(sc, BCE_PCICFG_MISC_STATUS) & BCE_PCICFG_MISC_STATUS_INTA_VALUE))
5283 		goto bce_intr_exit;
5284 
5285 	/* Ack the interrupt and stop others from occuring. */
5286 	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
5287 		BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
5288 		BCE_PCICFG_INT_ACK_CMD_MASK_INT);
5289 
5290 	/* Keep processing data as long as there is work to do. */
5291 	for (;;) {
5292 
5293 		status_attn_bits = sc->status_block->status_attn_bits;
5294 
5295 		DBRUNIF(DB_RANDOMTRUE(bce_debug_unexpected_attention),
5296 			BCE_PRINTF("Simulating unexpected status attention bit set.");
5297 			status_attn_bits = status_attn_bits | STATUS_ATTN_BITS_PARITY_ERROR);
5298 
5299 		/* Was it a link change interrupt? */
5300 		if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
5301 			(sc->status_block->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE))
5302 			bce_phy_intr(sc);
5303 
5304 		/* If any other attention is asserted then the chip is toast. */
5305 		if (((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
5306 			(sc->status_block->status_attn_bits_ack &
5307 			~STATUS_ATTN_BITS_LINK_STATE))) {
5308 
5309 			DBRUN(1, sc->unexpected_attentions++);
5310 
5311 			BCE_PRINTF("%s(%d): Fatal attention detected: 0x%08X\n",
5312 				__FILE__, __LINE__, sc->status_block->status_attn_bits);
5313 
5314 			DBRUN(BCE_FATAL,
5315 				if (bce_debug_unexpected_attention == 0)
5316 					bce_breakpoint(sc));
5317 
5318 			bce_init_locked(sc);
5319 			goto bce_intr_exit;
5320 		}
5321 
5322 		/* Check for any completed RX frames. */
5323 		if (sc->status_block->status_rx_quick_consumer_index0 != sc->hw_rx_cons)
5324 			bce_rx_intr(sc);
5325 
5326 		/* Check for any completed TX frames. */
5327 		if (sc->status_block->status_tx_quick_consumer_index0 != sc->hw_tx_cons)
5328 			bce_tx_intr(sc);
5329 
5330 		/* Save the status block index value for use during the next interrupt. */
5331 		sc->last_status_idx = sc->status_block->status_idx;
5332 
5333 		/* Prevent speculative reads from getting ahead of the status block. */
5334 		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
5335 			BUS_SPACE_BARRIER_READ);
5336 
5337 		/* If there's no work left then exit the interrupt service routine. */
5338 		if ((sc->status_block->status_rx_quick_consumer_index0 == sc->hw_rx_cons) &&
5339 	    	(sc->status_block->status_tx_quick_consumer_index0 == sc->hw_tx_cons))
5340 			break;
5341 
5342 	}
5343 
5344 	bus_dmamap_sync(sc->status_tag,	sc->status_map,
5345 	    BUS_DMASYNC_PREWRITE);
5346 
5347 	/* Re-enable interrupts. */
5348 	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
5349 	       BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx |
5350 	       BCE_PCICFG_INT_ACK_CMD_MASK_INT);
5351 	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
5352 	       BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
5353 
5354 	/* Handle any frames that arrived while handling the interrupt. */
5355 	if (ifp->if_drv_flags & IFF_DRV_RUNNING && !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
5356 		bce_start_locked(ifp);
5357 
5358 bce_intr_exit:
5359 	BCE_UNLOCK(sc);
5360 }
5361 
5362 
5363 /****************************************************************************/
5364 /* Programs the various packet receive modes (broadcast and multicast).     */
5365 /*                                                                          */
5366 /* Returns:                                                                 */
5367 /*   Nothing.                                                               */
5368 /****************************************************************************/
5369 static void
5370 bce_set_rx_mode(struct bce_softc *sc)
5371 {
5372 	struct ifnet *ifp;
5373 	struct ifmultiaddr *ifma;
5374 	u32 hashes[NUM_MC_HASH_REGISTERS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
5375 	u32 rx_mode, sort_mode;
5376 	int h, i;
5377 
5378 	BCE_LOCK_ASSERT(sc);
5379 
5380 	ifp = sc->bce_ifp;
5381 
5382 	/* Initialize receive mode default settings. */
5383 	rx_mode   = sc->rx_mode & ~(BCE_EMAC_RX_MODE_PROMISCUOUS |
5384 			    BCE_EMAC_RX_MODE_KEEP_VLAN_TAG);
5385 	sort_mode = 1 | BCE_RPM_SORT_USER0_BC_EN;
5386 
5387 	/*
5388 	 * ASF/IPMI/UMP firmware requires that VLAN tag stripping
5389 	 * be enbled.
5390 	 */
5391 	if (!(BCE_IF_CAPABILITIES & IFCAP_VLAN_HWTAGGING) &&
5392 		(!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)))
5393 		rx_mode |= BCE_EMAC_RX_MODE_KEEP_VLAN_TAG;
5394 
5395 	/*
5396 	 * Check for promiscuous, all multicast, or selected
5397 	 * multicast address filtering.
5398 	 */
5399 	if (ifp->if_flags & IFF_PROMISC) {
5400 		DBPRINT(sc, BCE_INFO, "Enabling promiscuous mode.\n");
5401 
5402 		/* Enable promiscuous mode. */
5403 		rx_mode |= BCE_EMAC_RX_MODE_PROMISCUOUS;
5404 		sort_mode |= BCE_RPM_SORT_USER0_PROM_EN;
5405 	} else if (ifp->if_flags & IFF_ALLMULTI) {
5406 		DBPRINT(sc, BCE_INFO, "Enabling all multicast mode.\n");
5407 
5408 		/* Enable all multicast addresses. */
5409 		for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
5410 			REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), 0xffffffff);
5411        	}
5412 		sort_mode |= BCE_RPM_SORT_USER0_MC_EN;
5413 	} else {
5414 		/* Accept one or more multicast(s). */
5415 		DBPRINT(sc, BCE_INFO, "Enabling selective multicast mode.\n");
5416 
5417 		IF_ADDR_LOCK(ifp);
5418 		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
5419 			if (ifma->ifma_addr->sa_family != AF_LINK)
5420 				continue;
5421 			h = ether_crc32_le(LLADDR((struct sockaddr_dl *)
5422 			    ifma->ifma_addr), ETHER_ADDR_LEN) & 0xFF;
5423 			    hashes[(h & 0xE0) >> 5] |= 1 << (h & 0x1F);
5424 		}
5425 		IF_ADDR_UNLOCK(ifp);
5426 
5427 		for (i = 0; i < NUM_MC_HASH_REGISTERS; i++)
5428 			REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), hashes[i]);
5429 
5430 		sort_mode |= BCE_RPM_SORT_USER0_MC_HSH_EN;
5431 	}
5432 
5433 	/* Only make changes if the recive mode has actually changed. */
5434 	if (rx_mode != sc->rx_mode) {
5435 		DBPRINT(sc, BCE_VERBOSE, "Enabling new receive mode: 0x%08X\n",
5436 			rx_mode);
5437 
5438 		sc->rx_mode = rx_mode;
5439 		REG_WR(sc, BCE_EMAC_RX_MODE, rx_mode);
5440 	}
5441 
5442 	/* Disable and clear the exisitng sort before enabling a new sort. */
5443 	REG_WR(sc, BCE_RPM_SORT_USER0, 0x0);
5444 	REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode);
5445 	REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode | BCE_RPM_SORT_USER0_ENA);
5446 }
5447 
5448 
5449 /****************************************************************************/
5450 /* Called periodically to updates statistics from the controllers           */
5451 /* statistics block.                                                        */
5452 /*                                                                          */
5453 /* Returns:                                                                 */
5454 /*   Nothing.                                                               */
5455 /****************************************************************************/
5456 static void
5457 bce_stats_update(struct bce_softc *sc)
5458 {
5459 	struct ifnet *ifp;
5460 	struct statistics_block *stats;
5461 
5462 	DBPRINT(sc, BCE_EXCESSIVE, "Entering %s()\n", __FUNCTION__);
5463 
5464 	ifp = sc->bce_ifp;
5465 
5466 	stats = (struct statistics_block *) sc->stats_block;
5467 
5468 	/*
5469 	 * Update the interface statistics from the
5470 	 * hardware statistics.
5471 	 */
5472 	ifp->if_collisions = (u_long) stats->stat_EtherStatsCollisions;
5473 
5474 	ifp->if_ierrors = (u_long) stats->stat_EtherStatsUndersizePkts +
5475 				      (u_long) stats->stat_EtherStatsOverrsizePkts +
5476 					  (u_long) stats->stat_IfInMBUFDiscards +
5477 					  (u_long) stats->stat_Dot3StatsAlignmentErrors +
5478 					  (u_long) stats->stat_Dot3StatsFCSErrors;
5479 
5480 	ifp->if_oerrors = (u_long) stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
5481 					  (u_long) stats->stat_Dot3StatsExcessiveCollisions +
5482 					  (u_long) stats->stat_Dot3StatsLateCollisions;
5483 
5484 	/*
5485 	 * Certain controllers don't report
5486 	 * carrier sense errors correctly.
5487 	 * See errata E11_5708CA0_1165.
5488 	 */
5489 	if (!(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
5490 	    !(BCE_CHIP_ID(sc) == BCE_CHIP_ID_5708_A0))
5491 		ifp->if_oerrors += (u_long) stats->stat_Dot3StatsCarrierSenseErrors;
5492 
5493 	/*
5494 	 * Update the sysctl statistics from the
5495 	 * hardware statistics.
5496 	 */
5497 	sc->stat_IfHCInOctets =
5498 		((u64) stats->stat_IfHCInOctets_hi << 32) +
5499 		 (u64) stats->stat_IfHCInOctets_lo;
5500 
5501 	sc->stat_IfHCInBadOctets =
5502 		((u64) stats->stat_IfHCInBadOctets_hi << 32) +
5503 		 (u64) stats->stat_IfHCInBadOctets_lo;
5504 
5505 	sc->stat_IfHCOutOctets =
5506 		((u64) stats->stat_IfHCOutOctets_hi << 32) +
5507 		 (u64) stats->stat_IfHCOutOctets_lo;
5508 
5509 	sc->stat_IfHCOutBadOctets =
5510 		((u64) stats->stat_IfHCOutBadOctets_hi << 32) +
5511 		 (u64) stats->stat_IfHCOutBadOctets_lo;
5512 
5513 	sc->stat_IfHCInUcastPkts =
5514 		((u64) stats->stat_IfHCInUcastPkts_hi << 32) +
5515 		 (u64) stats->stat_IfHCInUcastPkts_lo;
5516 
5517 	sc->stat_IfHCInMulticastPkts =
5518 		((u64) stats->stat_IfHCInMulticastPkts_hi << 32) +
5519 		 (u64) stats->stat_IfHCInMulticastPkts_lo;
5520 
5521 	sc->stat_IfHCInBroadcastPkts =
5522 		((u64) stats->stat_IfHCInBroadcastPkts_hi << 32) +
5523 		 (u64) stats->stat_IfHCInBroadcastPkts_lo;
5524 
5525 	sc->stat_IfHCOutUcastPkts =
5526 		((u64) stats->stat_IfHCOutUcastPkts_hi << 32) +
5527 		 (u64) stats->stat_IfHCOutUcastPkts_lo;
5528 
5529 	sc->stat_IfHCOutMulticastPkts =
5530 		((u64) stats->stat_IfHCOutMulticastPkts_hi << 32) +
5531 		 (u64) stats->stat_IfHCOutMulticastPkts_lo;
5532 
5533 	sc->stat_IfHCOutBroadcastPkts =
5534 		((u64) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
5535 		 (u64) stats->stat_IfHCOutBroadcastPkts_lo;
5536 
5537 	sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors =
5538 		stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
5539 
5540 	sc->stat_Dot3StatsCarrierSenseErrors =
5541 		stats->stat_Dot3StatsCarrierSenseErrors;
5542 
5543 	sc->stat_Dot3StatsFCSErrors =
5544 		stats->stat_Dot3StatsFCSErrors;
5545 
5546 	sc->stat_Dot3StatsAlignmentErrors =
5547 		stats->stat_Dot3StatsAlignmentErrors;
5548 
5549 	sc->stat_Dot3StatsSingleCollisionFrames =
5550 		stats->stat_Dot3StatsSingleCollisionFrames;
5551 
5552 	sc->stat_Dot3StatsMultipleCollisionFrames =
5553 		stats->stat_Dot3StatsMultipleCollisionFrames;
5554 
5555 	sc->stat_Dot3StatsDeferredTransmissions =
5556 		stats->stat_Dot3StatsDeferredTransmissions;
5557 
5558 	sc->stat_Dot3StatsExcessiveCollisions =
5559 		stats->stat_Dot3StatsExcessiveCollisions;
5560 
5561 	sc->stat_Dot3StatsLateCollisions =
5562 		stats->stat_Dot3StatsLateCollisions;
5563 
5564 	sc->stat_EtherStatsCollisions =
5565 		stats->stat_EtherStatsCollisions;
5566 
5567 	sc->stat_EtherStatsFragments =
5568 		stats->stat_EtherStatsFragments;
5569 
5570 	sc->stat_EtherStatsJabbers =
5571 		stats->stat_EtherStatsJabbers;
5572 
5573 	sc->stat_EtherStatsUndersizePkts =
5574 		stats->stat_EtherStatsUndersizePkts;
5575 
5576 	sc->stat_EtherStatsOverrsizePkts =
5577 		stats->stat_EtherStatsOverrsizePkts;
5578 
5579 	sc->stat_EtherStatsPktsRx64Octets =
5580 		stats->stat_EtherStatsPktsRx64Octets;
5581 
5582 	sc->stat_EtherStatsPktsRx65Octetsto127Octets =
5583 		stats->stat_EtherStatsPktsRx65Octetsto127Octets;
5584 
5585 	sc->stat_EtherStatsPktsRx128Octetsto255Octets =
5586 		stats->stat_EtherStatsPktsRx128Octetsto255Octets;
5587 
5588 	sc->stat_EtherStatsPktsRx256Octetsto511Octets =
5589 		stats->stat_EtherStatsPktsRx256Octetsto511Octets;
5590 
5591 	sc->stat_EtherStatsPktsRx512Octetsto1023Octets =
5592 		stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
5593 
5594 	sc->stat_EtherStatsPktsRx1024Octetsto1522Octets =
5595 		stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
5596 
5597 	sc->stat_EtherStatsPktsRx1523Octetsto9022Octets =
5598 		stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
5599 
5600 	sc->stat_EtherStatsPktsTx64Octets =
5601 		stats->stat_EtherStatsPktsTx64Octets;
5602 
5603 	sc->stat_EtherStatsPktsTx65Octetsto127Octets =
5604 		stats->stat_EtherStatsPktsTx65Octetsto127Octets;
5605 
5606 	sc->stat_EtherStatsPktsTx128Octetsto255Octets =
5607 		stats->stat_EtherStatsPktsTx128Octetsto255Octets;
5608 
5609 	sc->stat_EtherStatsPktsTx256Octetsto511Octets =
5610 		stats->stat_EtherStatsPktsTx256Octetsto511Octets;
5611 
5612 	sc->stat_EtherStatsPktsTx512Octetsto1023Octets =
5613 		stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
5614 
5615 	sc->stat_EtherStatsPktsTx1024Octetsto1522Octets =
5616 		stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
5617 
5618 	sc->stat_EtherStatsPktsTx1523Octetsto9022Octets =
5619 		stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
5620 
5621 	sc->stat_XonPauseFramesReceived =
5622 		stats->stat_XonPauseFramesReceived;
5623 
5624 	sc->stat_XoffPauseFramesReceived =
5625 		stats->stat_XoffPauseFramesReceived;
5626 
5627 	sc->stat_OutXonSent =
5628 		stats->stat_OutXonSent;
5629 
5630 	sc->stat_OutXoffSent =
5631 		stats->stat_OutXoffSent;
5632 
5633 	sc->stat_FlowControlDone =
5634 		stats->stat_FlowControlDone;
5635 
5636 	sc->stat_MacControlFramesReceived =
5637 		stats->stat_MacControlFramesReceived;
5638 
5639 	sc->stat_XoffStateEntered =
5640 		stats->stat_XoffStateEntered;
5641 
5642 	sc->stat_IfInFramesL2FilterDiscards =
5643 		stats->stat_IfInFramesL2FilterDiscards;
5644 
5645 	sc->stat_IfInRuleCheckerDiscards =
5646 		stats->stat_IfInRuleCheckerDiscards;
5647 
5648 	sc->stat_IfInFTQDiscards =
5649 		stats->stat_IfInFTQDiscards;
5650 
5651 	sc->stat_IfInMBUFDiscards =
5652 		stats->stat_IfInMBUFDiscards;
5653 
5654 	sc->stat_IfInRuleCheckerP4Hit =
5655 		stats->stat_IfInRuleCheckerP4Hit;
5656 
5657 	sc->stat_CatchupInRuleCheckerDiscards =
5658 		stats->stat_CatchupInRuleCheckerDiscards;
5659 
5660 	sc->stat_CatchupInFTQDiscards =
5661 		stats->stat_CatchupInFTQDiscards;
5662 
5663 	sc->stat_CatchupInMBUFDiscards =
5664 		stats->stat_CatchupInMBUFDiscards;
5665 
5666 	sc->stat_CatchupInRuleCheckerP4Hit =
5667 		stats->stat_CatchupInRuleCheckerP4Hit;
5668 
5669 	sc->com_no_buffers = REG_RD_IND(sc, 0x120084);
5670 
5671 	DBPRINT(sc, BCE_EXCESSIVE, "Exiting %s()\n", __FUNCTION__);
5672 }
5673 
5674 
5675 /****************************************************************************/
5676 /* Periodic function to perform maintenance tasks.                          */
5677 /*                                                                          */
5678 /* Returns:                                                                 */
5679 /*   Nothing.                                                               */
5680 /****************************************************************************/
5681 static void
5682 bce_tick(void *xsc)
5683 {
5684 	struct bce_softc *sc = xsc;
5685 	struct mii_data *mii;
5686 	struct ifnet *ifp;
5687 	u32 msg;
5688 
5689 	ifp = sc->bce_ifp;
5690 
5691 	BCE_LOCK_ASSERT(sc);
5692 
5693 	/* Tell the firmware that the driver is still running. */
5694 #ifdef BCE_DEBUG
5695 	msg = (u32) BCE_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE;
5696 #else
5697 	msg = (u32) ++sc->bce_fw_drv_pulse_wr_seq;
5698 #endif
5699 	REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_PULSE_MB, msg);
5700 
5701 	/* Update the statistics from the hardware statistics block. */
5702 	bce_stats_update(sc);
5703 
5704 	/* Check that chip hasn't hung. */
5705 	bce_watchdog(sc);
5706 
5707 	/* Schedule the next tick. */
5708 	callout_reset(
5709 		&sc->bce_stat_ch,		/* callout */
5710 		hz, 					/* ticks */
5711 		bce_tick, 				/* function */
5712 		sc);					/* function argument */
5713 
5714 	/* If link is up already up then we're done. */
5715 	if (sc->bce_link)
5716 		goto bce_tick_locked_exit;
5717 
5718 	mii = device_get_softc(sc->bce_miibus);
5719 	mii_tick(mii);
5720 
5721 	/* Check if the link has come up. */
5722 	if (!sc->bce_link && mii->mii_media_status & IFM_ACTIVE &&
5723 	    IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
5724 		sc->bce_link++;
5725 		if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
5726 		    IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX) &&
5727 		    bootverbose)
5728 			BCE_PRINTF("Gigabit link up\n");
5729 		/* Now that link is up, handle any outstanding TX traffic. */
5730 		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd))
5731 			bce_start_locked(ifp);
5732 	}
5733 
5734 bce_tick_locked_exit:
5735 	return;
5736 }
5737 
5738 
5739 #ifdef BCE_DEBUG
5740 /****************************************************************************/
5741 /* Allows the driver state to be dumped through the sysctl interface.       */
5742 /*                                                                          */
5743 /* Returns:                                                                 */
5744 /*   0 for success, positive value for failure.                             */
5745 /****************************************************************************/
5746 static int
5747 bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS)
5748 {
5749         int error;
5750         int result;
5751         struct bce_softc *sc;
5752 
5753         result = -1;
5754         error = sysctl_handle_int(oidp, &result, 0, req);
5755 
5756         if (error || !req->newptr)
5757                 return (error);
5758 
5759         if (result == 1) {
5760                 sc = (struct bce_softc *)arg1;
5761                 bce_dump_driver_state(sc);
5762         }
5763 
5764         return error;
5765 }
5766 
5767 
5768 /****************************************************************************/
5769 /* Allows the hardware state to be dumped through the sysctl interface.     */
5770 /*                                                                          */
5771 /* Returns:                                                                 */
5772 /*   0 for success, positive value for failure.                             */
5773 /****************************************************************************/
5774 static int
5775 bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS)
5776 {
5777         int error;
5778         int result;
5779         struct bce_softc *sc;
5780 
5781         result = -1;
5782         error = sysctl_handle_int(oidp, &result, 0, req);
5783 
5784         if (error || !req->newptr)
5785                 return (error);
5786 
5787         if (result == 1) {
5788                 sc = (struct bce_softc *)arg1;
5789                 bce_dump_hw_state(sc);
5790         }
5791 
5792         return error;
5793 }
5794 
5795 
5796 /****************************************************************************/
5797 /* Provides a sysctl interface to allows dumping the RX chain.              */
5798 /*                                                                          */
5799 /* Returns:                                                                 */
5800 /*   0 for success, positive value for failure.                             */
5801 /****************************************************************************/
5802 static int
5803 bce_sysctl_dump_rx_chain(SYSCTL_HANDLER_ARGS)
5804 {
5805         int error;
5806         int result;
5807         struct bce_softc *sc;
5808 
5809         result = -1;
5810         error = sysctl_handle_int(oidp, &result, 0, req);
5811 
5812         if (error || !req->newptr)
5813                 return (error);
5814 
5815         if (result == 1) {
5816                 sc = (struct bce_softc *)arg1;
5817                 bce_dump_rx_chain(sc, 0, USABLE_RX_BD);
5818         }
5819 
5820         return error;
5821 }
5822 
5823 
5824 /****************************************************************************/
5825 /* Provides a sysctl interface to allows dumping the TX chain.              */
5826 /*                                                                          */
5827 /* Returns:                                                                 */
5828 /*   0 for success, positive value for failure.                             */
5829 /****************************************************************************/
5830 static int
5831 bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
5832 {
5833         int error;
5834         int result;
5835         struct bce_softc *sc;
5836 
5837         result = -1;
5838         error = sysctl_handle_int(oidp, &result, 0, req);
5839 
5840         if (error || !req->newptr)
5841                 return (error);
5842 
5843         if (result == 1) {
5844                 sc = (struct bce_softc *)arg1;
5845                 bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
5846         }
5847 
5848         return error;
5849 }
5850 
5851 
5852 /****************************************************************************/
5853 /* Provides a sysctl interface to allow reading arbitrary registers in the  */
5854 /* device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                            */
5855 /*                                                                          */
5856 /* Returns:                                                                 */
5857 /*   0 for success, positive value for failure.                             */
5858 /****************************************************************************/
5859 static int
5860 bce_sysctl_reg_read(SYSCTL_HANDLER_ARGS)
5861 {
5862 	struct bce_softc *sc;
5863 	int error;
5864 	uint32_t val, result;
5865 
5866 	result = -1;
5867 	error = sysctl_handle_int(oidp, &result, 0, req);
5868 	if (error || (req->newptr == NULL))
5869 		return (error);
5870 
5871 	/* Make sure the register is accessible. */
5872 	if (result < 0x8000) {
5873 		sc = (struct bce_softc *)arg1;
5874 		val = REG_RD(sc, result);
5875 		BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
5876 	} else if (result < 0x0280000) {
5877 		sc = (struct bce_softc *)arg1;
5878 		val = REG_RD_IND(sc, result);
5879 		BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
5880 	}
5881 
5882 	return (error);
5883 }
5884 
5885 
5886 /****************************************************************************/
5887 /* Provides a sysctl interface to allow reading arbitrary PHY registers in  */
5888 /* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
5889 /*                                                                          */
5890 /* Returns:                                                                 */
5891 /*   0 for success, positive value for failure.                             */
5892 /****************************************************************************/
5893 static int
5894 bce_sysctl_phy_read(SYSCTL_HANDLER_ARGS)
5895 {
5896 	struct bce_softc *sc;
5897 	device_t dev;
5898 	int error, result;
5899 	u16 val;
5900 
5901 	result = -1;
5902 	error = sysctl_handle_int(oidp, &result, 0, req);
5903 	if (error || (req->newptr == NULL))
5904 		return (error);
5905 
5906 	/* Make sure the register is accessible. */
5907 	if (result < 0x20) {
5908 		sc = (struct bce_softc *)arg1;
5909 		dev = sc->bce_dev;
5910 		val = bce_miibus_read_reg(dev, sc->bce_phy_addr, result);
5911 		BCE_PRINTF("phy 0x%02X = 0x%04X\n", result, val);
5912 	}
5913 	return (error);
5914 }
5915 
5916 
5917 /****************************************************************************/
5918 /* Provides a sysctl interface to forcing the driver to dump state and      */
5919 /* enter the debugger.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                */
5920 /*                                                                          */
5921 /* Returns:                                                                 */
5922 /*   0 for success, positive value for failure.                             */
5923 /****************************************************************************/
5924 static int
5925 bce_sysctl_breakpoint(SYSCTL_HANDLER_ARGS)
5926 {
5927         int error;
5928         int result;
5929         struct bce_softc *sc;
5930 
5931         result = -1;
5932         error = sysctl_handle_int(oidp, &result, 0, req);
5933 
5934         if (error || !req->newptr)
5935                 return (error);
5936 
5937         if (result == 1) {
5938                 sc = (struct bce_softc *)arg1;
5939                 bce_breakpoint(sc);
5940         }
5941 
5942         return error;
5943 }
5944 #endif
5945 
5946 
5947 /****************************************************************************/
5948 /* Adds any sysctl parameters for tuning or debugging purposes.             */
5949 /*                                                                          */
5950 /* Returns:                                                                 */
5951 /*   0 for success, positive value for failure.                             */
5952 /****************************************************************************/
5953 static void
5954 bce_add_sysctls(struct bce_softc *sc)
5955 {
5956 	struct sysctl_ctx_list *ctx;
5957 	struct sysctl_oid_list *children;
5958 
5959 	ctx = device_get_sysctl_ctx(sc->bce_dev);
5960 	children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->bce_dev));
5961 
5962 #ifdef BCE_DEBUG
5963 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
5964 		"rx_low_watermark",
5965 		CTLFLAG_RD, &sc->rx_low_watermark,
5966 		0, "Lowest level of free rx_bd's");
5967 
5968 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
5969 		"rx_empty_count",
5970 		CTLFLAG_RD, &sc->rx_empty_count,
5971 		0, "Number of times the RX chain was empty");
5972 
5973 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
5974 		"tx_hi_watermark",
5975 		CTLFLAG_RD, &sc->tx_hi_watermark,
5976 		0, "Highest level of used tx_bd's");
5977 
5978 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
5979 		"tx_full_count",
5980 		CTLFLAG_RD, &sc->tx_full_count,
5981 		0, "Number of times the TX chain was full");
5982 
5983 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
5984 		"l2fhdr_status_errors",
5985 		CTLFLAG_RD, &sc->l2fhdr_status_errors,
5986 		0, "l2_fhdr status errors");
5987 
5988 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
5989 		"unexpected_attentions",
5990 		CTLFLAG_RD, &sc->unexpected_attentions,
5991 		0, "unexpected attentions");
5992 
5993 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
5994 		"lost_status_block_updates",
5995 		CTLFLAG_RD, &sc->lost_status_block_updates,
5996 		0, "lost status block updates");
5997 
5998 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
5999 		"mbuf_alloc_failed",
6000 		CTLFLAG_RD, &sc->mbuf_alloc_failed,
6001 		0, "mbuf cluster allocation failures");
6002 
6003 	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
6004 		"requested_tso_frames",
6005 		CTLFLAG_RD, &sc->requested_tso_frames,
6006 		0, "The number of TSO frames received");
6007 #endif
6008 
6009 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
6010 		"stat_IfHcInOctets",
6011 		CTLFLAG_RD, &sc->stat_IfHCInOctets,
6012 		"Bytes received");
6013 
6014 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
6015 		"stat_IfHCInBadOctets",
6016 		CTLFLAG_RD, &sc->stat_IfHCInBadOctets,
6017 		"Bad bytes received");
6018 
6019 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
6020 		"stat_IfHCOutOctets",
6021 		CTLFLAG_RD, &sc->stat_IfHCOutOctets,
6022 		"Bytes sent");
6023 
6024 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
6025 		"stat_IfHCOutBadOctets",
6026 		CTLFLAG_RD, &sc->stat_IfHCOutBadOctets,
6027 		"Bad bytes sent");
6028 
6029 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
6030 		"stat_IfHCInUcastPkts",
6031 		CTLFLAG_RD, &sc->stat_IfHCInUcastPkts,
6032 		"Unicast packets received");
6033 
6034 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
6035 		"stat_IfHCInMulticastPkts",
6036 		CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts,
6037 		"Multicast packets received");
6038 
6039 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
6040 		"stat_IfHCInBroadcastPkts",
6041 		CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts,
6042 		"Broadcast packets received");
6043 
6044 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
6045 		"stat_IfHCOutUcastPkts",
6046 		CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts,
6047 		"Unicast packets sent");
6048 
6049 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
6050 		"stat_IfHCOutMulticastPkts",
6051 		CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts,
6052 		"Multicast packets sent");
6053 
6054 	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
6055 		"stat_IfHCOutBroadcastPkts",
6056 		CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts,
6057 		"Broadcast packets sent");
6058 
6059 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6060 		"stat_emac_tx_stat_dot3statsinternalmactransmiterrors",
6061 		CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors,
6062 		0, "Internal MAC transmit errors");
6063 
6064 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6065 		"stat_Dot3StatsCarrierSenseErrors",
6066 		CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors,
6067 		0, "Carrier sense errors");
6068 
6069 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6070 		"stat_Dot3StatsFCSErrors",
6071 		CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors,
6072 		0, "Frame check sequence errors");
6073 
6074 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6075 		"stat_Dot3StatsAlignmentErrors",
6076 		CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors,
6077 		0, "Alignment errors");
6078 
6079 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6080 		"stat_Dot3StatsSingleCollisionFrames",
6081 		CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames,
6082 		0, "Single Collision Frames");
6083 
6084 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6085 		"stat_Dot3StatsMultipleCollisionFrames",
6086 		CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames,
6087 		0, "Multiple Collision Frames");
6088 
6089 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6090 		"stat_Dot3StatsDeferredTransmissions",
6091 		CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions,
6092 		0, "Deferred Transmissions");
6093 
6094 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6095 		"stat_Dot3StatsExcessiveCollisions",
6096 		CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions,
6097 		0, "Excessive Collisions");
6098 
6099 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6100 		"stat_Dot3StatsLateCollisions",
6101 		CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions,
6102 		0, "Late Collisions");
6103 
6104 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6105 		"stat_EtherStatsCollisions",
6106 		CTLFLAG_RD, &sc->stat_EtherStatsCollisions,
6107 		0, "Collisions");
6108 
6109 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6110 		"stat_EtherStatsFragments",
6111 		CTLFLAG_RD, &sc->stat_EtherStatsFragments,
6112 		0, "Fragments");
6113 
6114 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6115 		"stat_EtherStatsJabbers",
6116 		CTLFLAG_RD, &sc->stat_EtherStatsJabbers,
6117 		0, "Jabbers");
6118 
6119 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6120 		"stat_EtherStatsUndersizePkts",
6121 		CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts,
6122 		0, "Undersize packets");
6123 
6124 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6125 		"stat_EtherStatsOverrsizePkts",
6126 		CTLFLAG_RD, &sc->stat_EtherStatsOverrsizePkts,
6127 		0, "stat_EtherStatsOverrsizePkts");
6128 
6129 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6130 		"stat_EtherStatsPktsRx64Octets",
6131 		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets,
6132 		0, "Bytes received in 64 byte packets");
6133 
6134 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6135 		"stat_EtherStatsPktsRx65Octetsto127Octets",
6136 		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets,
6137 		0, "Bytes received in 65 to 127 byte packets");
6138 
6139 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6140 		"stat_EtherStatsPktsRx128Octetsto255Octets",
6141 		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets,
6142 		0, "Bytes received in 128 to 255 byte packets");
6143 
6144 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6145 		"stat_EtherStatsPktsRx256Octetsto511Octets",
6146 		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets,
6147 		0, "Bytes received in 256 to 511 byte packets");
6148 
6149 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6150 		"stat_EtherStatsPktsRx512Octetsto1023Octets",
6151 		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets,
6152 		0, "Bytes received in 512 to 1023 byte packets");
6153 
6154 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6155 		"stat_EtherStatsPktsRx1024Octetsto1522Octets",
6156 		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets,
6157 		0, "Bytes received in 1024 t0 1522 byte packets");
6158 
6159 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6160 		"stat_EtherStatsPktsRx1523Octetsto9022Octets",
6161 		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets,
6162 		0, "Bytes received in 1523 to 9022 byte packets");
6163 
6164 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6165 		"stat_EtherStatsPktsTx64Octets",
6166 		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets,
6167 		0, "Bytes sent in 64 byte packets");
6168 
6169 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6170 		"stat_EtherStatsPktsTx65Octetsto127Octets",
6171 		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets,
6172 		0, "Bytes sent in 65 to 127 byte packets");
6173 
6174 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6175 		"stat_EtherStatsPktsTx128Octetsto255Octets",
6176 		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets,
6177 		0, "Bytes sent in 128 to 255 byte packets");
6178 
6179 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6180 		"stat_EtherStatsPktsTx256Octetsto511Octets",
6181 		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets,
6182 		0, "Bytes sent in 256 to 511 byte packets");
6183 
6184 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6185 		"stat_EtherStatsPktsTx512Octetsto1023Octets",
6186 		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets,
6187 		0, "Bytes sent in 512 to 1023 byte packets");
6188 
6189 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6190 		"stat_EtherStatsPktsTx1024Octetsto1522Octets",
6191 		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets,
6192 		0, "Bytes sent in 1024 to 1522 byte packets");
6193 
6194 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6195 		"stat_EtherStatsPktsTx1523Octetsto9022Octets",
6196 		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets,
6197 		0, "Bytes sent in 1523 to 9022 byte packets");
6198 
6199 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6200 		"stat_XonPauseFramesReceived",
6201 		CTLFLAG_RD, &sc->stat_XonPauseFramesReceived,
6202 		0, "XON pause frames receved");
6203 
6204 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6205 		"stat_XoffPauseFramesReceived",
6206 		CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived,
6207 		0, "XOFF pause frames received");
6208 
6209 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6210 		"stat_OutXonSent",
6211 		CTLFLAG_RD, &sc->stat_OutXonSent,
6212 		0, "XON pause frames sent");
6213 
6214 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6215 		"stat_OutXoffSent",
6216 		CTLFLAG_RD, &sc->stat_OutXoffSent,
6217 		0, "XOFF pause frames sent");
6218 
6219 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6220 		"stat_FlowControlDone",
6221 		CTLFLAG_RD, &sc->stat_FlowControlDone,
6222 		0, "Flow control done");
6223 
6224 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6225 		"stat_MacControlFramesReceived",
6226 		CTLFLAG_RD, &sc->stat_MacControlFramesReceived,
6227 		0, "MAC control frames received");
6228 
6229 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6230 		"stat_XoffStateEntered",
6231 		CTLFLAG_RD, &sc->stat_XoffStateEntered,
6232 		0, "XOFF state entered");
6233 
6234 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6235 		"stat_IfInFramesL2FilterDiscards",
6236 		CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards,
6237 		0, "Received L2 packets discarded");
6238 
6239 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6240 		"stat_IfInRuleCheckerDiscards",
6241 		CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards,
6242 		0, "Received packets discarded by rule");
6243 
6244 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6245 		"stat_IfInFTQDiscards",
6246 		CTLFLAG_RD, &sc->stat_IfInFTQDiscards,
6247 		0, "Received packet FTQ discards");
6248 
6249 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6250 		"stat_IfInMBUFDiscards",
6251 		CTLFLAG_RD, &sc->stat_IfInMBUFDiscards,
6252 		0, "Received packets discarded due to lack of controller buffer memory");
6253 
6254 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6255 		"stat_IfInRuleCheckerP4Hit",
6256 		CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit,
6257 		0, "Received packets rule checker hits");
6258 
6259 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6260 		"stat_CatchupInRuleCheckerDiscards",
6261 		CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards,
6262 		0, "Received packets discarded in Catchup path");
6263 
6264 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6265 		"stat_CatchupInFTQDiscards",
6266 		CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards,
6267 		0, "Received packets discarded in FTQ in Catchup path");
6268 
6269 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6270 		"stat_CatchupInMBUFDiscards",
6271 		CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards,
6272 		0, "Received packets discarded in controller buffer memory in Catchup path");
6273 
6274 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6275 		"stat_CatchupInRuleCheckerP4Hit",
6276 		CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit,
6277 		0, "Received packets rule checker hits in Catchup path");
6278 
6279 	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
6280 		"com_no_buffers",
6281 		CTLFLAG_RD, &sc->com_no_buffers,
6282 		0, "Valid packets received but no RX buffers available");
6283 
6284 #ifdef BCE_DEBUG
6285 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
6286 		"driver_state", CTLTYPE_INT | CTLFLAG_RW,
6287 		(void *)sc, 0,
6288 		bce_sysctl_driver_state, "I", "Drive state information");
6289 
6290 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
6291 		"hw_state", CTLTYPE_INT | CTLFLAG_RW,
6292 		(void *)sc, 0,
6293 		bce_sysctl_hw_state, "I", "Hardware state information");
6294 
6295 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
6296 		"dump_rx_chain", CTLTYPE_INT | CTLFLAG_RW,
6297 		(void *)sc, 0,
6298 		bce_sysctl_dump_rx_chain, "I", "Dump rx_bd chain");
6299 
6300 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
6301 		"dump_tx_chain", CTLTYPE_INT | CTLFLAG_RW,
6302 		(void *)sc, 0,
6303 		bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
6304 
6305 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
6306 		"breakpoint", CTLTYPE_INT | CTLFLAG_RW,
6307 		(void *)sc, 0,
6308 		bce_sysctl_breakpoint, "I", "Driver breakpoint");
6309 
6310 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
6311 		"reg_read", CTLTYPE_INT | CTLFLAG_RW,
6312 		(void *)sc, 0,
6313 		bce_sysctl_reg_read, "I", "Register read");
6314 
6315 	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
6316 		"phy_read", CTLTYPE_INT | CTLFLAG_RW,
6317 		(void *)sc, 0,
6318 		bce_sysctl_phy_read, "I", "PHY register read");
6319 
6320 #endif
6321 
6322 }
6323 
6324 
6325 /****************************************************************************/
6326 /* BCE Debug Routines                                                       */
6327 /****************************************************************************/
6328 #ifdef BCE_DEBUG
6329 
6330 /****************************************************************************/
6331 /* Freezes the controller to allow for a cohesive state dump.               */
6332 /*                                                                          */
6333 /* Returns:                                                                 */
6334 /*   Nothing.                                                               */
6335 /****************************************************************************/
6336 static void
6337 bce_freeze_controller(struct bce_softc *sc)
6338 {
6339 	u32 val;
6340 	val = REG_RD(sc, BCE_MISC_COMMAND);
6341 	val |= BCE_MISC_COMMAND_DISABLE_ALL;
6342 	REG_WR(sc, BCE_MISC_COMMAND, val);
6343 
6344 }
6345 
6346 
6347 /****************************************************************************/
6348 /* Unfreezes the controller after a freeze operation.  This may not always  */
6349 /* work and the controller will require a reset!                            */
6350 /*                                                                          */
6351 /* Returns:                                                                 */
6352 /*   Nothing.                                                               */
6353 /****************************************************************************/
6354 static void
6355 bce_unfreeze_controller(struct bce_softc *sc)
6356 {
6357 	u32 val;
6358 	val = REG_RD(sc, BCE_MISC_COMMAND);
6359 	val |= BCE_MISC_COMMAND_ENABLE_ALL;
6360 	REG_WR(sc, BCE_MISC_COMMAND, val);
6361 
6362 }
6363 
6364 /****************************************************************************/
6365 /* Prints out information about an mbuf.                                    */
6366 /*                                                                          */
6367 /* Returns:                                                                 */
6368 /*   Nothing.                                                               */
6369 /****************************************************************************/
6370 static void
6371 bce_dump_mbuf(struct bce_softc *sc, struct mbuf *m)
6372 {
6373 	u32 val_hi, val_lo;
6374 	struct mbuf *mp = m;
6375 
6376 	if (m == NULL) {
6377 		BCE_PRINTF("mbuf: null pointer\n");
6378 		return;
6379 	}
6380 
6381 	while (mp) {
6382 		val_hi = BCE_ADDR_HI(mp);
6383 		val_lo = BCE_ADDR_LO(mp);
6384 		BCE_PRINTF("mbuf: vaddr = 0x%08X:%08X, m_len = %d, m_flags = ( ",
6385 			   val_hi, val_lo, mp->m_len);
6386 
6387 		if (mp->m_flags & M_EXT)
6388 			printf("M_EXT ");
6389 		if (mp->m_flags & M_PKTHDR)
6390 			printf("M_PKTHDR ");
6391 		if (mp->m_flags & M_EOR)
6392 			printf("M_EOR ");
6393 		if (mp->m_flags & M_RDONLY)
6394 			printf("M_RDONLY ");
6395 
6396 		val_hi = BCE_ADDR_HI(mp->m_data);
6397 		val_lo = BCE_ADDR_LO(mp->m_data);
6398 		printf(") m_data = 0x%08X:%08X\n",
6399 			   val_hi, val_lo);
6400 
6401 		if (mp->m_flags & M_PKTHDR) {
6402 			BCE_PRINTF("- m_pkthdr: flags = ( ");
6403 			if (mp->m_flags & M_BCAST)
6404 				printf("M_BCAST ");
6405 			if (mp->m_flags & M_MCAST)
6406 				printf("M_MCAST ");
6407 			if (mp->m_flags & M_FRAG)
6408 				printf("M_FRAG ");
6409 			if (mp->m_flags & M_FIRSTFRAG)
6410 				printf("M_FIRSTFRAG ");
6411 			if (mp->m_flags & M_LASTFRAG)
6412 				printf("M_LASTFRAG ");
6413 			if (mp->m_flags & M_VLANTAG)
6414 				printf("M_VLANTAG ");
6415 			if (mp->m_flags & M_PROMISC)
6416 				printf("M_PROMISC ");
6417 			printf(") csum_flags = ( ");
6418 			if (mp->m_pkthdr.csum_flags & CSUM_IP)
6419 				printf("CSUM_IP ");
6420 			if (mp->m_pkthdr.csum_flags & CSUM_TCP)
6421 				printf("CSUM_TCP ");
6422 			if (mp->m_pkthdr.csum_flags & CSUM_UDP)
6423 				printf("CSUM_UDP ");
6424 			if (mp->m_pkthdr.csum_flags & CSUM_IP_FRAGS)
6425 				printf("CSUM_IP_FRAGS ");
6426 			if (mp->m_pkthdr.csum_flags & CSUM_FRAGMENT)
6427 				printf("CSUM_FRAGMENT ");
6428 			if (mp->m_pkthdr.csum_flags & CSUM_TSO)
6429 				printf("CSUM_TSO ");
6430 			if (mp->m_pkthdr.csum_flags & CSUM_IP_CHECKED)
6431 				printf("CSUM_IP_CHECKED ");
6432 			if (mp->m_pkthdr.csum_flags & CSUM_IP_VALID)
6433 				printf("CSUM_IP_VALID ");
6434 			if (mp->m_pkthdr.csum_flags & CSUM_DATA_VALID)
6435 				printf("CSUM_DATA_VALID ");
6436 			printf(")\n");
6437 		}
6438 
6439 		if (mp->m_flags & M_EXT) {
6440 			val_hi = BCE_ADDR_HI(mp->m_ext.ext_buf);
6441 			val_lo = BCE_ADDR_LO(mp->m_ext.ext_buf);
6442 			BCE_PRINTF("- m_ext: vaddr = 0x%08X:%08X, ext_size = %d, type = ",
6443 				val_hi, val_lo, mp->m_ext.ext_size);
6444 			switch (mp->m_ext.ext_type) {
6445 				case EXT_CLUSTER:    printf("EXT_CLUSTER\n"); break;
6446 				case EXT_SFBUF:      printf("EXT_SFBUF\n"); break;
6447 				case EXT_JUMBO9:     printf("EXT_JUMBO9\n"); break;
6448 				case EXT_JUMBO16:    printf("EXT_JUMBO16\n"); break;
6449 				case EXT_PACKET:     printf("EXT_PACKET\n"); break;
6450 				case EXT_MBUF:       printf("EXT_MBUF\n"); break;
6451 				case EXT_NET_DRV:    printf("EXT_NET_DRV\n"); break;
6452 				case EXT_MOD_TYPE:   printf("EXT_MDD_TYPE\n"); break;
6453 				case EXT_DISPOSABLE: printf("EXT_DISPOSABLE\n"); break;
6454 				case EXT_EXTREF:     printf("EXT_EXTREF\n"); break;
6455 				default:             printf("UNKNOWN\n");
6456 			}
6457 		}
6458 
6459 		mp = mp->m_next;
6460 	}
6461 }
6462 
6463 
6464 /****************************************************************************/
6465 /* Prints out the mbufs in the TX mbuf chain.                               */
6466 /*                                                                          */
6467 /* Returns:                                                                 */
6468 /*   Nothing.                                                               */
6469 /****************************************************************************/
6470 static void
6471 bce_dump_tx_mbuf_chain(struct bce_softc *sc, int chain_prod, int count)
6472 {
6473 	struct mbuf *m;
6474 
6475 	BCE_PRINTF(
6476 		"----------------------------"
6477 		"  tx mbuf data  "
6478 		"----------------------------\n");
6479 
6480 	for (int i = 0; i < count; i++) {
6481 	 	m = sc->tx_mbuf_ptr[chain_prod];
6482 		BCE_PRINTF("txmbuf[%d]\n", chain_prod);
6483 		bce_dump_mbuf(sc, m);
6484 		chain_prod = TX_CHAIN_IDX(NEXT_TX_BD(chain_prod));
6485 	}
6486 
6487 	BCE_PRINTF(
6488 		"----------------------------"
6489 		"----------------"
6490 		"----------------------------\n");
6491 }
6492 
6493 
6494 /****************************************************************************/
6495 /* Prints out the mbufs in the RX mbuf chain.                               */
6496 /*                                                                          */
6497 /* Returns:                                                                 */
6498 /*   Nothing.                                                               */
6499 /****************************************************************************/
6500 static void
6501 bce_dump_rx_mbuf_chain(struct bce_softc *sc, int chain_prod, int count)
6502 {
6503 	struct mbuf *m;
6504 
6505 	BCE_PRINTF(
6506 		"----------------------------"
6507 		"  rx mbuf data  "
6508 		"----------------------------\n");
6509 
6510 	for (int i = 0; i < count; i++) {
6511 	 	m = sc->rx_mbuf_ptr[chain_prod];
6512 		BCE_PRINTF("rxmbuf[0x%04X]\n", chain_prod);
6513 		bce_dump_mbuf(sc, m);
6514 		chain_prod = RX_CHAIN_IDX(NEXT_RX_BD(chain_prod));
6515 	}
6516 
6517 
6518 	BCE_PRINTF(
6519 		"----------------------------"
6520 		"----------------"
6521 		"----------------------------\n");
6522 }
6523 
6524 
6525 /****************************************************************************/
6526 /* Prints out a tx_bd structure.                                            */
6527 /*                                                                          */
6528 /* Returns:                                                                 */
6529 /*   Nothing.                                                               */
6530 /****************************************************************************/
6531 static void
6532 bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
6533 {
6534 	if (idx > MAX_TX_BD)
6535 		/* Index out of range. */
6536 		BCE_PRINTF("tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
6537 	else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
6538 		/* TX Chain page pointer. */
6539 		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
6540 			idx, txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo);
6541 	else {
6542 			/* Normal tx_bd entry. */
6543 			BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
6544 				"vlan tag= 0x%04X, flags = 0x%04X (", idx,
6545 				txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
6546 				txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag,
6547 				txbd->tx_bd_flags);
6548 
6549 			if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT)
6550 				printf(" CONN_FAULT");
6551 
6552 			if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM)
6553 				printf(" TCP_UDP_CKSUM");
6554 
6555 			if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM)
6556 				printf(" IP_CKSUM");
6557 
6558 			if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG)
6559 				printf("  VLAN");
6560 
6561 			if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW)
6562 				printf(" COAL_NOW");
6563 
6564 			if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC)
6565 				printf(" DONT_GEN_CRC");
6566 
6567 			if (txbd->tx_bd_flags & TX_BD_FLAGS_START)
6568 				printf(" START");
6569 
6570 			if (txbd->tx_bd_flags & TX_BD_FLAGS_END)
6571 				printf(" END");
6572 
6573 			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO)
6574 				printf(" LSO");
6575 
6576 			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD)
6577 				printf(" OPTION_WORD");
6578 
6579 			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS)
6580 				printf(" FLAGS");
6581 
6582 			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP)
6583 				printf(" SNAP");
6584 
6585 			printf(" )\n");
6586 		}
6587 
6588 }
6589 
6590 
6591 /****************************************************************************/
6592 /* Prints out a rx_bd structure.                                            */
6593 /*                                                                          */
6594 /* Returns:                                                                 */
6595 /*   Nothing.                                                               */
6596 /****************************************************************************/
6597 static void
6598 bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd)
6599 {
6600 	if (idx > MAX_RX_BD)
6601 		/* Index out of range. */
6602 		BCE_PRINTF("rx_bd[0x%04X]: Invalid rx_bd index!\n", idx);
6603 	else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
6604 		/* TX Chain page pointer. */
6605 		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
6606 			idx, rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo);
6607 	else
6608 		/* Normal tx_bd entry. */
6609 		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
6610 			"flags = 0x%08X\n", idx,
6611 			rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo,
6612 			rxbd->rx_bd_len, rxbd->rx_bd_flags);
6613 }
6614 
6615 
6616 /****************************************************************************/
6617 /* Prints out a l2_fhdr structure.                                            */
6618 /*                                                                          */
6619 /* Returns:                                                                 */
6620 /*   Nothing.                                                               */
6621 /****************************************************************************/
6622 static void
6623 bce_dump_l2fhdr(struct bce_softc *sc, int idx, struct l2_fhdr *l2fhdr)
6624 {
6625 
6626 	BCE_PRINTF("l2_fhdr[0x%04X]: status = 0x%08X, "
6627 		"pkt_len = 0x%04X, vlan = 0x%04x, ip_xsum = 0x%04X, "
6628 		"tcp_udp_xsum = 0x%04X\n", idx,
6629 		l2fhdr->l2_fhdr_status, l2fhdr->l2_fhdr_pkt_len,
6630 		l2fhdr->l2_fhdr_vlan_tag, l2fhdr->l2_fhdr_ip_xsum,
6631 		l2fhdr->l2_fhdr_tcp_udp_xsum);
6632 }
6633 
6634 
6635 /****************************************************************************/
6636 /* Prints out the tx chain.                                                 */
6637 /*                                                                          */
6638 /* Returns:                                                                 */
6639 /*   Nothing.                                                               */
6640 /****************************************************************************/
6641 static void
6642 bce_dump_tx_chain(struct bce_softc *sc, int tx_prod, int count)
6643 {
6644 	struct tx_bd *txbd;
6645 
6646 	/* First some info about the tx_bd chain structure. */
6647 	BCE_PRINTF(
6648 		"----------------------------"
6649 		"  tx_bd  chain  "
6650 		"----------------------------\n");
6651 
6652 	BCE_PRINTF("page size      = 0x%08X, tx chain pages        = 0x%08X\n",
6653 		(u32) BCM_PAGE_SIZE, (u32) TX_PAGES);
6654 
6655 	BCE_PRINTF("tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
6656 		(u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
6657 
6658 	BCE_PRINTF("total tx_bd    = 0x%08X\n", (u32) TOTAL_TX_BD);
6659 
6660 	BCE_PRINTF(""
6661 		"----------------------------"
6662 		"   tx_bd data   "
6663 		"----------------------------\n");
6664 
6665 	/* Now print out the tx_bd's themselves. */
6666 	for (int i = 0; i < count; i++) {
6667 	 	txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
6668 		bce_dump_txbd(sc, tx_prod, txbd);
6669 		tx_prod = TX_CHAIN_IDX(NEXT_TX_BD(tx_prod));
6670 	}
6671 
6672 	BCE_PRINTF(
6673 		"----------------------------"
6674 		"----------------"
6675 		"----------------------------\n");
6676 }
6677 
6678 
6679 /****************************************************************************/
6680 /* Prints out the rx chain.                                                 */
6681 /*                                                                          */
6682 /* Returns:                                                                 */
6683 /*   Nothing.                                                               */
6684 /****************************************************************************/
6685 static void
6686 bce_dump_rx_chain(struct bce_softc *sc, int rx_prod, int count)
6687 {
6688 	struct rx_bd *rxbd;
6689 
6690 	/* First some info about the tx_bd chain structure. */
6691 	BCE_PRINTF(
6692 		"----------------------------"
6693 		"  rx_bd  chain  "
6694 		"----------------------------\n");
6695 
6696 	BCE_PRINTF("page size      = 0x%08X, rx chain pages        = 0x%08X\n",
6697 		(u32) BCM_PAGE_SIZE, (u32) RX_PAGES);
6698 
6699 	BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
6700 		(u32) TOTAL_RX_BD_PER_PAGE, (u32) USABLE_RX_BD_PER_PAGE);
6701 
6702 	BCE_PRINTF("total rx_bd    = 0x%08X\n", (u32) TOTAL_RX_BD);
6703 
6704 	BCE_PRINTF(
6705 		"----------------------------"
6706 		"   rx_bd data   "
6707 		"----------------------------\n");
6708 
6709 	/* Now print out the rx_bd's themselves. */
6710 	for (int i = 0; i < count; i++) {
6711 		rxbd = &sc->rx_bd_chain[RX_PAGE(rx_prod)][RX_IDX(rx_prod)];
6712 		bce_dump_rxbd(sc, rx_prod, rxbd);
6713 		rx_prod = RX_CHAIN_IDX(NEXT_RX_BD(rx_prod));
6714 	}
6715 
6716 	BCE_PRINTF(
6717 		"----------------------------"
6718 		"----------------"
6719 		"----------------------------\n");
6720 }
6721 
6722 
6723 /****************************************************************************/
6724 /* Prints out the status block from host memory.                            */
6725 /*                                                                          */
6726 /* Returns:                                                                 */
6727 /*   Nothing.                                                               */
6728 /****************************************************************************/
6729 static void
6730 bce_dump_status_block(struct bce_softc *sc)
6731 {
6732 	struct status_block *sblk;
6733 
6734 	sblk = sc->status_block;
6735 
6736    	BCE_PRINTF(
6737 		"----------------------------"
6738 		"  Status Block  "
6739 		"----------------------------\n");
6740 
6741 	BCE_PRINTF("    0x%08X - attn_bits\n",
6742 		sblk->status_attn_bits);
6743 
6744 	BCE_PRINTF("    0x%08X - attn_bits_ack\n",
6745 		sblk->status_attn_bits_ack);
6746 
6747 	BCE_PRINTF("0x%04X(0x%04X) - rx_cons0\n",
6748 		sblk->status_rx_quick_consumer_index0,
6749 		(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index0));
6750 
6751 	BCE_PRINTF("0x%04X(0x%04X) - tx_cons0\n",
6752 		sblk->status_tx_quick_consumer_index0,
6753 		(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index0));
6754 
6755 	BCE_PRINTF("        0x%04X - status_idx\n", sblk->status_idx);
6756 
6757 	/* Theses indices are not used for normal L2 drivers. */
6758 	if (sblk->status_rx_quick_consumer_index1)
6759 		BCE_PRINTF("0x%04X(0x%04X) - rx_cons1\n",
6760 			sblk->status_rx_quick_consumer_index1,
6761 			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index1));
6762 
6763 	if (sblk->status_tx_quick_consumer_index1)
6764 		BCE_PRINTF("0x%04X(0x%04X) - tx_cons1\n",
6765 			sblk->status_tx_quick_consumer_index1,
6766 			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index1));
6767 
6768 	if (sblk->status_rx_quick_consumer_index2)
6769 		BCE_PRINTF("0x%04X(0x%04X)- rx_cons2\n",
6770 			sblk->status_rx_quick_consumer_index2,
6771 			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index2));
6772 
6773 	if (sblk->status_tx_quick_consumer_index2)
6774 		BCE_PRINTF("0x%04X(0x%04X) - tx_cons2\n",
6775 			sblk->status_tx_quick_consumer_index2,
6776 			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index2));
6777 
6778 	if (sblk->status_rx_quick_consumer_index3)
6779 		BCE_PRINTF("0x%04X(0x%04X) - rx_cons3\n",
6780 			sblk->status_rx_quick_consumer_index3,
6781 			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index3));
6782 
6783 	if (sblk->status_tx_quick_consumer_index3)
6784 		BCE_PRINTF("0x%04X(0x%04X) - tx_cons3\n",
6785 			sblk->status_tx_quick_consumer_index3,
6786 			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index3));
6787 
6788 	if (sblk->status_rx_quick_consumer_index4 ||
6789 		sblk->status_rx_quick_consumer_index5)
6790 		BCE_PRINTF("rx_cons4  = 0x%08X, rx_cons5      = 0x%08X\n",
6791 			sblk->status_rx_quick_consumer_index4,
6792 			sblk->status_rx_quick_consumer_index5);
6793 
6794 	if (sblk->status_rx_quick_consumer_index6 ||
6795 		sblk->status_rx_quick_consumer_index7)
6796 		BCE_PRINTF("rx_cons6  = 0x%08X, rx_cons7      = 0x%08X\n",
6797 			sblk->status_rx_quick_consumer_index6,
6798 			sblk->status_rx_quick_consumer_index7);
6799 
6800 	if (sblk->status_rx_quick_consumer_index8 ||
6801 		sblk->status_rx_quick_consumer_index9)
6802 		BCE_PRINTF("rx_cons8  = 0x%08X, rx_cons9      = 0x%08X\n",
6803 			sblk->status_rx_quick_consumer_index8,
6804 			sblk->status_rx_quick_consumer_index9);
6805 
6806 	if (sblk->status_rx_quick_consumer_index10 ||
6807 		sblk->status_rx_quick_consumer_index11)
6808 		BCE_PRINTF("rx_cons10 = 0x%08X, rx_cons11     = 0x%08X\n",
6809 			sblk->status_rx_quick_consumer_index10,
6810 			sblk->status_rx_quick_consumer_index11);
6811 
6812 	if (sblk->status_rx_quick_consumer_index12 ||
6813 		sblk->status_rx_quick_consumer_index13)
6814 		BCE_PRINTF("rx_cons12 = 0x%08X, rx_cons13     = 0x%08X\n",
6815 			sblk->status_rx_quick_consumer_index12,
6816 			sblk->status_rx_quick_consumer_index13);
6817 
6818 	if (sblk->status_rx_quick_consumer_index14 ||
6819 		sblk->status_rx_quick_consumer_index15)
6820 		BCE_PRINTF("rx_cons14 = 0x%08X, rx_cons15     = 0x%08X\n",
6821 			sblk->status_rx_quick_consumer_index14,
6822 			sblk->status_rx_quick_consumer_index15);
6823 
6824 	if (sblk->status_completion_producer_index ||
6825 		sblk->status_cmd_consumer_index)
6826 		BCE_PRINTF("com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
6827 			sblk->status_completion_producer_index,
6828 			sblk->status_cmd_consumer_index);
6829 
6830 	BCE_PRINTF(
6831 		"----------------------------"
6832 		"----------------"
6833 		"----------------------------\n");
6834 }
6835 
6836 
6837 /****************************************************************************/
6838 /* Prints out the statistics block.                                         */
6839 /*                                                                          */
6840 /* Returns:                                                                 */
6841 /*   Nothing.                                                               */
6842 /****************************************************************************/
6843 static void
6844 bce_dump_stats_block(struct bce_softc *sc)
6845 {
6846 	struct statistics_block *sblk;
6847 
6848 	sblk = sc->stats_block;
6849 
6850 	BCE_PRINTF(
6851 		"---------------"
6852 		" Stats Block  (All Stats Not Shown Are 0) "
6853 		"---------------\n");
6854 
6855 	if (sblk->stat_IfHCInOctets_hi
6856 		|| sblk->stat_IfHCInOctets_lo)
6857 		BCE_PRINTF("0x%08X:%08X : "
6858 			"IfHcInOctets\n",
6859 			sblk->stat_IfHCInOctets_hi,
6860 			sblk->stat_IfHCInOctets_lo);
6861 
6862 	if (sblk->stat_IfHCInBadOctets_hi
6863 		|| sblk->stat_IfHCInBadOctets_lo)
6864 		BCE_PRINTF("0x%08X:%08X : "
6865 			"IfHcInBadOctets\n",
6866 			sblk->stat_IfHCInBadOctets_hi,
6867 			sblk->stat_IfHCInBadOctets_lo);
6868 
6869 	if (sblk->stat_IfHCOutOctets_hi
6870 		|| sblk->stat_IfHCOutOctets_lo)
6871 		BCE_PRINTF("0x%08X:%08X : "
6872 			"IfHcOutOctets\n",
6873 			sblk->stat_IfHCOutOctets_hi,
6874 			sblk->stat_IfHCOutOctets_lo);
6875 
6876 	if (sblk->stat_IfHCOutBadOctets_hi
6877 		|| sblk->stat_IfHCOutBadOctets_lo)
6878 		BCE_PRINTF("0x%08X:%08X : "
6879 			"IfHcOutBadOctets\n",
6880 			sblk->stat_IfHCOutBadOctets_hi,
6881 			sblk->stat_IfHCOutBadOctets_lo);
6882 
6883 	if (sblk->stat_IfHCInUcastPkts_hi
6884 		|| sblk->stat_IfHCInUcastPkts_lo)
6885 		BCE_PRINTF("0x%08X:%08X : "
6886 			"IfHcInUcastPkts\n",
6887 			sblk->stat_IfHCInUcastPkts_hi,
6888 			sblk->stat_IfHCInUcastPkts_lo);
6889 
6890 	if (sblk->stat_IfHCInBroadcastPkts_hi
6891 		|| sblk->stat_IfHCInBroadcastPkts_lo)
6892 		BCE_PRINTF("0x%08X:%08X : "
6893 			"IfHcInBroadcastPkts\n",
6894 			sblk->stat_IfHCInBroadcastPkts_hi,
6895 			sblk->stat_IfHCInBroadcastPkts_lo);
6896 
6897 	if (sblk->stat_IfHCInMulticastPkts_hi
6898 		|| sblk->stat_IfHCInMulticastPkts_lo)
6899 		BCE_PRINTF("0x%08X:%08X : "
6900 			"IfHcInMulticastPkts\n",
6901 			sblk->stat_IfHCInMulticastPkts_hi,
6902 			sblk->stat_IfHCInMulticastPkts_lo);
6903 
6904 	if (sblk->stat_IfHCOutUcastPkts_hi
6905 		|| sblk->stat_IfHCOutUcastPkts_lo)
6906 		BCE_PRINTF("0x%08X:%08X : "
6907 			"IfHcOutUcastPkts\n",
6908 			sblk->stat_IfHCOutUcastPkts_hi,
6909 			sblk->stat_IfHCOutUcastPkts_lo);
6910 
6911 	if (sblk->stat_IfHCOutBroadcastPkts_hi
6912 		|| sblk->stat_IfHCOutBroadcastPkts_lo)
6913 		BCE_PRINTF("0x%08X:%08X : "
6914 			"IfHcOutBroadcastPkts\n",
6915 			sblk->stat_IfHCOutBroadcastPkts_hi,
6916 			sblk->stat_IfHCOutBroadcastPkts_lo);
6917 
6918 	if (sblk->stat_IfHCOutMulticastPkts_hi
6919 		|| sblk->stat_IfHCOutMulticastPkts_lo)
6920 		BCE_PRINTF("0x%08X:%08X : "
6921 			"IfHcOutMulticastPkts\n",
6922 			sblk->stat_IfHCOutMulticastPkts_hi,
6923 			sblk->stat_IfHCOutMulticastPkts_lo);
6924 
6925 	if (sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors)
6926 		BCE_PRINTF("         0x%08X : "
6927 			"emac_tx_stat_dot3statsinternalmactransmiterrors\n",
6928 			sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
6929 
6930 	if (sblk->stat_Dot3StatsCarrierSenseErrors)
6931 		BCE_PRINTF("         0x%08X : Dot3StatsCarrierSenseErrors\n",
6932 			sblk->stat_Dot3StatsCarrierSenseErrors);
6933 
6934 	if (sblk->stat_Dot3StatsFCSErrors)
6935 		BCE_PRINTF("         0x%08X : Dot3StatsFCSErrors\n",
6936 			sblk->stat_Dot3StatsFCSErrors);
6937 
6938 	if (sblk->stat_Dot3StatsAlignmentErrors)
6939 		BCE_PRINTF("         0x%08X : Dot3StatsAlignmentErrors\n",
6940 			sblk->stat_Dot3StatsAlignmentErrors);
6941 
6942 	if (sblk->stat_Dot3StatsSingleCollisionFrames)
6943 		BCE_PRINTF("         0x%08X : Dot3StatsSingleCollisionFrames\n",
6944 			sblk->stat_Dot3StatsSingleCollisionFrames);
6945 
6946 	if (sblk->stat_Dot3StatsMultipleCollisionFrames)
6947 		BCE_PRINTF("         0x%08X : Dot3StatsMultipleCollisionFrames\n",
6948 			sblk->stat_Dot3StatsMultipleCollisionFrames);
6949 
6950 	if (sblk->stat_Dot3StatsDeferredTransmissions)
6951 		BCE_PRINTF("         0x%08X : Dot3StatsDeferredTransmissions\n",
6952 			sblk->stat_Dot3StatsDeferredTransmissions);
6953 
6954 	if (sblk->stat_Dot3StatsExcessiveCollisions)
6955 		BCE_PRINTF("         0x%08X : Dot3StatsExcessiveCollisions\n",
6956 			sblk->stat_Dot3StatsExcessiveCollisions);
6957 
6958 	if (sblk->stat_Dot3StatsLateCollisions)
6959 		BCE_PRINTF("         0x%08X : Dot3StatsLateCollisions\n",
6960 			sblk->stat_Dot3StatsLateCollisions);
6961 
6962 	if (sblk->stat_EtherStatsCollisions)
6963 		BCE_PRINTF("         0x%08X : EtherStatsCollisions\n",
6964 			sblk->stat_EtherStatsCollisions);
6965 
6966 	if (sblk->stat_EtherStatsFragments)
6967 		BCE_PRINTF("         0x%08X : EtherStatsFragments\n",
6968 			sblk->stat_EtherStatsFragments);
6969 
6970 	if (sblk->stat_EtherStatsJabbers)
6971 		BCE_PRINTF("         0x%08X : EtherStatsJabbers\n",
6972 			sblk->stat_EtherStatsJabbers);
6973 
6974 	if (sblk->stat_EtherStatsUndersizePkts)
6975 		BCE_PRINTF("         0x%08X : EtherStatsUndersizePkts\n",
6976 			sblk->stat_EtherStatsUndersizePkts);
6977 
6978 	if (sblk->stat_EtherStatsOverrsizePkts)
6979 		BCE_PRINTF("         0x%08X : EtherStatsOverrsizePkts\n",
6980 			sblk->stat_EtherStatsOverrsizePkts);
6981 
6982 	if (sblk->stat_EtherStatsPktsRx64Octets)
6983 		BCE_PRINTF("         0x%08X : EtherStatsPktsRx64Octets\n",
6984 			sblk->stat_EtherStatsPktsRx64Octets);
6985 
6986 	if (sblk->stat_EtherStatsPktsRx65Octetsto127Octets)
6987 		BCE_PRINTF("         0x%08X : EtherStatsPktsRx65Octetsto127Octets\n",
6988 			sblk->stat_EtherStatsPktsRx65Octetsto127Octets);
6989 
6990 	if (sblk->stat_EtherStatsPktsRx128Octetsto255Octets)
6991 		BCE_PRINTF("         0x%08X : EtherStatsPktsRx128Octetsto255Octets\n",
6992 			sblk->stat_EtherStatsPktsRx128Octetsto255Octets);
6993 
6994 	if (sblk->stat_EtherStatsPktsRx256Octetsto511Octets)
6995 		BCE_PRINTF("         0x%08X : EtherStatsPktsRx256Octetsto511Octets\n",
6996 			sblk->stat_EtherStatsPktsRx256Octetsto511Octets);
6997 
6998 	if (sblk->stat_EtherStatsPktsRx512Octetsto1023Octets)
6999 		BCE_PRINTF("         0x%08X : EtherStatsPktsRx512Octetsto1023Octets\n",
7000 			sblk->stat_EtherStatsPktsRx512Octetsto1023Octets);
7001 
7002 	if (sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets)
7003 		BCE_PRINTF("         0x%08X : EtherStatsPktsRx1024Octetsto1522Octets\n",
7004 			sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets);
7005 
7006 	if (sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets)
7007 		BCE_PRINTF("         0x%08X : EtherStatsPktsRx1523Octetsto9022Octets\n",
7008 			sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets);
7009 
7010 	if (sblk->stat_EtherStatsPktsTx64Octets)
7011 		BCE_PRINTF("         0x%08X : EtherStatsPktsTx64Octets\n",
7012 			sblk->stat_EtherStatsPktsTx64Octets);
7013 
7014 	if (sblk->stat_EtherStatsPktsTx65Octetsto127Octets)
7015 		BCE_PRINTF("         0x%08X : EtherStatsPktsTx65Octetsto127Octets\n",
7016 			sblk->stat_EtherStatsPktsTx65Octetsto127Octets);
7017 
7018 	if (sblk->stat_EtherStatsPktsTx128Octetsto255Octets)
7019 		BCE_PRINTF("         0x%08X : EtherStatsPktsTx128Octetsto255Octets\n",
7020 			sblk->stat_EtherStatsPktsTx128Octetsto255Octets);
7021 
7022 	if (sblk->stat_EtherStatsPktsTx256Octetsto511Octets)
7023 		BCE_PRINTF("         0x%08X : EtherStatsPktsTx256Octetsto511Octets\n",
7024 			sblk->stat_EtherStatsPktsTx256Octetsto511Octets);
7025 
7026 	if (sblk->stat_EtherStatsPktsTx512Octetsto1023Octets)
7027 		BCE_PRINTF("         0x%08X : EtherStatsPktsTx512Octetsto1023Octets\n",
7028 			sblk->stat_EtherStatsPktsTx512Octetsto1023Octets);
7029 
7030 	if (sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets)
7031 		BCE_PRINTF("         0x%08X : EtherStatsPktsTx1024Octetsto1522Octets\n",
7032 			sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets);
7033 
7034 	if (sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets)
7035 		BCE_PRINTF("         0x%08X : EtherStatsPktsTx1523Octetsto9022Octets\n",
7036 			sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets);
7037 
7038 	if (sblk->stat_XonPauseFramesReceived)
7039 		BCE_PRINTF("         0x%08X : XonPauseFramesReceived\n",
7040 			sblk->stat_XonPauseFramesReceived);
7041 
7042 	if (sblk->stat_XoffPauseFramesReceived)
7043 	   BCE_PRINTF("          0x%08X : XoffPauseFramesReceived\n",
7044 			sblk->stat_XoffPauseFramesReceived);
7045 
7046 	if (sblk->stat_OutXonSent)
7047 		BCE_PRINTF("         0x%08X : OutXonSent\n",
7048 			sblk->stat_OutXonSent);
7049 
7050 	if (sblk->stat_OutXoffSent)
7051 		BCE_PRINTF("         0x%08X : OutXoffSent\n",
7052 			sblk->stat_OutXoffSent);
7053 
7054 	if (sblk->stat_FlowControlDone)
7055 		BCE_PRINTF("         0x%08X : FlowControlDone\n",
7056 			sblk->stat_FlowControlDone);
7057 
7058 	if (sblk->stat_MacControlFramesReceived)
7059 		BCE_PRINTF("         0x%08X : MacControlFramesReceived\n",
7060 			sblk->stat_MacControlFramesReceived);
7061 
7062 	if (sblk->stat_XoffStateEntered)
7063 		BCE_PRINTF("         0x%08X : XoffStateEntered\n",
7064 			sblk->stat_XoffStateEntered);
7065 
7066 	if (sblk->stat_IfInFramesL2FilterDiscards)
7067 		BCE_PRINTF("         0x%08X : IfInFramesL2FilterDiscards\n",
7068 			sblk->stat_IfInFramesL2FilterDiscards);
7069 
7070 	if (sblk->stat_IfInRuleCheckerDiscards)
7071 		BCE_PRINTF("         0x%08X : IfInRuleCheckerDiscards\n",
7072 			sblk->stat_IfInRuleCheckerDiscards);
7073 
7074 	if (sblk->stat_IfInFTQDiscards)
7075 		BCE_PRINTF("         0x%08X : IfInFTQDiscards\n",
7076 			sblk->stat_IfInFTQDiscards);
7077 
7078 	if (sblk->stat_IfInMBUFDiscards)
7079 		BCE_PRINTF("         0x%08X : IfInMBUFDiscards\n",
7080 			sblk->stat_IfInMBUFDiscards);
7081 
7082 	if (sblk->stat_IfInRuleCheckerP4Hit)
7083 		BCE_PRINTF("         0x%08X : IfInRuleCheckerP4Hit\n",
7084 			sblk->stat_IfInRuleCheckerP4Hit);
7085 
7086 	if (sblk->stat_CatchupInRuleCheckerDiscards)
7087 		BCE_PRINTF("         0x%08X : CatchupInRuleCheckerDiscards\n",
7088 			sblk->stat_CatchupInRuleCheckerDiscards);
7089 
7090 	if (sblk->stat_CatchupInFTQDiscards)
7091 		BCE_PRINTF("         0x%08X : CatchupInFTQDiscards\n",
7092 			sblk->stat_CatchupInFTQDiscards);
7093 
7094 	if (sblk->stat_CatchupInMBUFDiscards)
7095 		BCE_PRINTF("         0x%08X : CatchupInMBUFDiscards\n",
7096 			sblk->stat_CatchupInMBUFDiscards);
7097 
7098 	if (sblk->stat_CatchupInRuleCheckerP4Hit)
7099 		BCE_PRINTF("         0x%08X : CatchupInRuleCheckerP4Hit\n",
7100 			sblk->stat_CatchupInRuleCheckerP4Hit);
7101 
7102 	BCE_PRINTF(
7103 		"----------------------------"
7104 		"----------------"
7105 		"----------------------------\n");
7106 }
7107 
7108 
7109 /****************************************************************************/
7110 /* Prints out a summary of the driver state.                                */
7111 /*                                                                          */
7112 /* Returns:                                                                 */
7113 /*   Nothing.                                                               */
7114 /****************************************************************************/
7115 static void
7116 bce_dump_driver_state(struct bce_softc *sc)
7117 {
7118 	u32 val_hi, val_lo;
7119 
7120 	BCE_PRINTF(
7121 		"-----------------------------"
7122 		" Driver State "
7123 		"-----------------------------\n");
7124 
7125 	val_hi = BCE_ADDR_HI(sc);
7126 	val_lo = BCE_ADDR_LO(sc);
7127 	BCE_PRINTF("0x%08X:%08X - (sc) driver softc structure virtual address\n",
7128 		val_hi, val_lo);
7129 
7130 	val_hi = BCE_ADDR_HI(sc->bce_vhandle);
7131 	val_lo = BCE_ADDR_LO(sc->bce_vhandle);
7132 	BCE_PRINTF("0x%08X:%08X - (sc->bce_vhandle) PCI BAR virtual address\n",
7133 		val_hi, val_lo);
7134 
7135 	val_hi = BCE_ADDR_HI(sc->status_block);
7136 	val_lo = BCE_ADDR_LO(sc->status_block);
7137 	BCE_PRINTF("0x%08X:%08X - (sc->status_block) status block virtual address\n",
7138 		val_hi, val_lo);
7139 
7140 	val_hi = BCE_ADDR_HI(sc->stats_block);
7141 	val_lo = BCE_ADDR_LO(sc->stats_block);
7142 	BCE_PRINTF("0x%08X:%08X - (sc->stats_block) statistics block virtual address\n",
7143 		val_hi, val_lo);
7144 
7145 	val_hi = BCE_ADDR_HI(sc->tx_bd_chain);
7146 	val_lo = BCE_ADDR_LO(sc->tx_bd_chain);
7147 	BCE_PRINTF(
7148 		"0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain virtual adddress\n",
7149 		val_hi, val_lo);
7150 
7151 	val_hi = BCE_ADDR_HI(sc->rx_bd_chain);
7152 	val_lo = BCE_ADDR_LO(sc->rx_bd_chain);
7153 	BCE_PRINTF(
7154 		"0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain virtual address\n",
7155 		val_hi, val_lo);
7156 
7157 	val_hi = BCE_ADDR_HI(sc->tx_mbuf_ptr);
7158 	val_lo = BCE_ADDR_LO(sc->tx_mbuf_ptr);
7159 	BCE_PRINTF(
7160 		"0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain virtual address\n",
7161 		val_hi, val_lo);
7162 
7163 	val_hi = BCE_ADDR_HI(sc->rx_mbuf_ptr);
7164 	val_lo = BCE_ADDR_LO(sc->rx_mbuf_ptr);
7165 	BCE_PRINTF(
7166 		"0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain virtual address\n",
7167 		val_hi, val_lo);
7168 
7169 	BCE_PRINTF("         0x%08X - (sc->interrupts_generated) h/w intrs\n",
7170 		sc->interrupts_generated);
7171 
7172 	BCE_PRINTF("         0x%08X - (sc->rx_interrupts) rx interrupts handled\n",
7173 		sc->rx_interrupts);
7174 
7175 	BCE_PRINTF("         0x%08X - (sc->tx_interrupts) tx interrupts handled\n",
7176 		sc->tx_interrupts);
7177 
7178 	BCE_PRINTF("         0x%08X - (sc->last_status_idx) status block index\n",
7179 		sc->last_status_idx);
7180 
7181 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_prod) tx producer index\n",
7182 		sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod));
7183 
7184 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_cons) tx consumer index\n",
7185 		sc->tx_cons, (u16) TX_CHAIN_IDX(sc->tx_cons));
7186 
7187 	BCE_PRINTF("         0x%08X - (sc->tx_prod_bseq) tx producer bseq index\n",
7188 		sc->tx_prod_bseq);
7189 
7190 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_prod) rx producer index\n",
7191 		sc->rx_prod, (u16) RX_CHAIN_IDX(sc->rx_prod));
7192 
7193 	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_cons) rx consumer index\n",
7194 		sc->rx_cons, (u16) RX_CHAIN_IDX(sc->rx_cons));
7195 
7196 	BCE_PRINTF("         0x%08X - (sc->rx_prod_bseq) rx producer bseq index\n",
7197 		sc->rx_prod_bseq);
7198 
7199 	BCE_PRINTF("         0x%08X - (sc->rx_mbuf_alloc) rx mbufs allocated\n",
7200 		sc->rx_mbuf_alloc);
7201 
7202 	BCE_PRINTF("         0x%08X - (sc->free_rx_bd) free rx_bd's\n",
7203 		sc->free_rx_bd);
7204 
7205 	BCE_PRINTF("0x%08X/%08X - (sc->rx_low_watermark) rx low watermark\n",
7206 		sc->rx_low_watermark, sc->max_rx_bd);
7207 
7208 	BCE_PRINTF("         0x%08X - (sc->txmbuf_alloc) tx mbufs allocated\n",
7209 		sc->tx_mbuf_alloc);
7210 
7211 	BCE_PRINTF("         0x%08X - (sc->rx_mbuf_alloc) rx mbufs allocated\n",
7212 		sc->rx_mbuf_alloc);
7213 
7214 	BCE_PRINTF("         0x%08X - (sc->used_tx_bd) used tx_bd's\n",
7215 		sc->used_tx_bd);
7216 
7217 	BCE_PRINTF("0x%08X/%08X - (sc->tx_hi_watermark) tx hi watermark\n",
7218 		sc->tx_hi_watermark, sc->max_tx_bd);
7219 
7220 	BCE_PRINTF("         0x%08X - (sc->mbuf_alloc_failed) failed mbuf alloc\n",
7221 		sc->mbuf_alloc_failed);
7222 
7223 	BCE_PRINTF(
7224 		"----------------------------"
7225 		"----------------"
7226 		"----------------------------\n");
7227 }
7228 
7229 
7230 /****************************************************************************/
7231 /* Prints out the hardware state through a summary of important registers,  */
7232 /* followed by a complete register dump.                                    */
7233 /*                                                                          */
7234 /* Returns:                                                                 */
7235 /*   Nothing.                                                               */
7236 /****************************************************************************/
7237 static void
7238 bce_dump_hw_state(struct bce_softc *sc)
7239 {
7240 	u32 val1;
7241 
7242 	BCE_PRINTF(
7243 		"----------------------------"
7244 		" Hardware State "
7245 		"----------------------------\n");
7246 
7247 	BCE_PRINTF("0x%08X - bootcode version\n", sc->bce_fw_ver);
7248 
7249 	val1 = REG_RD(sc, BCE_MISC_ENABLE_STATUS_BITS);
7250 	BCE_PRINTF("0x%08X - (0x%06X) misc_enable_status_bits\n",
7251 		val1, BCE_MISC_ENABLE_STATUS_BITS);
7252 
7253 	val1 = REG_RD(sc, BCE_DMA_STATUS);
7254 	BCE_PRINTF("0x%08X - (0x%06X) dma_status\n", val1, BCE_DMA_STATUS);
7255 
7256 	val1 = REG_RD(sc, BCE_CTX_STATUS);
7257 	BCE_PRINTF("0x%08X - (0x%06X) ctx_status\n", val1, BCE_CTX_STATUS);
7258 
7259 	val1 = REG_RD(sc, BCE_EMAC_STATUS);
7260 	BCE_PRINTF("0x%08X - (0x%06X) emac_status\n", val1, BCE_EMAC_STATUS);
7261 
7262 	val1 = REG_RD(sc, BCE_RPM_STATUS);
7263 	BCE_PRINTF("0x%08X - (0x%06X) rpm_status\n", val1, BCE_RPM_STATUS);
7264 
7265 	val1 = REG_RD(sc, BCE_TBDR_STATUS);
7266 	BCE_PRINTF("0x%08X - (0x%06X) tbdr_status\n", val1, BCE_TBDR_STATUS);
7267 
7268 	val1 = REG_RD(sc, BCE_TDMA_STATUS);
7269 	BCE_PRINTF("0x%08X - (0x%06X) tdma_status\n", val1, BCE_TDMA_STATUS);
7270 
7271 	val1 = REG_RD(sc, BCE_HC_STATUS);
7272 	BCE_PRINTF("0x%08X - (0x%06X) hc_status\n", val1, BCE_HC_STATUS);
7273 
7274 	val1 = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
7275 	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n", val1, BCE_TXP_CPU_STATE);
7276 
7277 	val1 = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
7278 	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n", val1, BCE_TPAT_CPU_STATE);
7279 
7280 	val1 = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
7281 	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n", val1, BCE_RXP_CPU_STATE);
7282 
7283 	val1 = REG_RD_IND(sc, BCE_COM_CPU_STATE);
7284 	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n", val1, BCE_COM_CPU_STATE);
7285 
7286 	val1 = REG_RD_IND(sc, BCE_MCP_CPU_STATE);
7287 	BCE_PRINTF("0x%08X - (0x%06X) mcp_cpu_state\n", val1, BCE_MCP_CPU_STATE);
7288 
7289 	val1 = REG_RD_IND(sc, BCE_CP_CPU_STATE);
7290 	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n", val1, BCE_CP_CPU_STATE);
7291 
7292 	BCE_PRINTF(
7293 		"----------------------------"
7294 		"----------------"
7295 		"----------------------------\n");
7296 
7297 	BCE_PRINTF(
7298 		"----------------------------"
7299 		" Register  Dump "
7300 		"----------------------------\n");
7301 
7302 	for (int i = 0x400; i < 0x8000; i += 0x10)
7303 		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
7304 			i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
7305 			REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
7306 
7307 	BCE_PRINTF(
7308 		"----------------------------"
7309 		"----------------"
7310 		"----------------------------\n");
7311 }
7312 
7313 
7314 /****************************************************************************/
7315 /* Prints out the TXP state.                                                */
7316 /*                                                                          */
7317 /* Returns:                                                                 */
7318 /*   Nothing.                                                               */
7319 /****************************************************************************/
7320 static void
7321 bce_dump_txp_state(struct bce_softc *sc)
7322 {
7323 	u32 val1;
7324 
7325 	BCE_PRINTF(
7326 		"----------------------------"
7327 		"   TXP  State   "
7328 		"----------------------------\n");
7329 
7330 	val1 = REG_RD_IND(sc, BCE_TXP_CPU_MODE);
7331 	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_mode\n", val1, BCE_TXP_CPU_MODE);
7332 
7333 	val1 = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
7334 	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n", val1, BCE_TXP_CPU_STATE);
7335 
7336 	val1 = REG_RD_IND(sc, BCE_TXP_CPU_EVENT_MASK);
7337 	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_event_mask\n", val1, BCE_TXP_CPU_EVENT_MASK);
7338 
7339 	BCE_PRINTF(
7340 		"----------------------------"
7341 		" Register  Dump "
7342 		"----------------------------\n");
7343 
7344 	for (int i = BCE_TXP_CPU_MODE; i < 0x68000; i += 0x10) {
7345 		/* Skip the big blank spaces */
7346 		if (i < 0x454000 && i > 0x5ffff)
7347 			BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
7348 				i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
7349 				REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
7350 	}
7351 
7352 	BCE_PRINTF(
7353 		"----------------------------"
7354 		"----------------"
7355 		"----------------------------\n");
7356 }
7357 
7358 
7359 /****************************************************************************/
7360 /* Prints out the RXP state.                                                */
7361 /*                                                                          */
7362 /* Returns:                                                                 */
7363 /*   Nothing.                                                               */
7364 /****************************************************************************/
7365 static void
7366 bce_dump_rxp_state(struct bce_softc *sc)
7367 {
7368 	u32 val1;
7369 
7370 	BCE_PRINTF(
7371 		"----------------------------"
7372 		"   RXP  State   "
7373 		"----------------------------\n");
7374 
7375 	val1 = REG_RD_IND(sc, BCE_RXP_CPU_MODE);
7376 	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_mode\n", val1, BCE_RXP_CPU_MODE);
7377 
7378 	val1 = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
7379 	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n", val1, BCE_RXP_CPU_STATE);
7380 
7381 	val1 = REG_RD_IND(sc, BCE_RXP_CPU_EVENT_MASK);
7382 	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_event_mask\n", val1, BCE_RXP_CPU_EVENT_MASK);
7383 
7384 	BCE_PRINTF(
7385 		"----------------------------"
7386 		" Register  Dump "
7387 		"----------------------------\n");
7388 
7389 	for (int i = BCE_RXP_CPU_MODE; i < 0xe8fff; i += 0x10) {
7390 		/* Skip the big blank sapces */
7391 		if (i < 0xc5400 && i > 0xdffff)
7392 			BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
7393 	 			i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
7394 				REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
7395 	}
7396 
7397 	BCE_PRINTF(
7398 		"----------------------------"
7399 		"----------------"
7400 		"----------------------------\n");
7401 }
7402 
7403 
7404 /****************************************************************************/
7405 /* Prints out the TPAT state.                                               */
7406 /*                                                                          */
7407 /* Returns:                                                                 */
7408 /*   Nothing.                                                               */
7409 /****************************************************************************/
7410 static void
7411 bce_dump_tpat_state(struct bce_softc *sc)
7412 {
7413 	u32 val1;
7414 
7415 	BCE_PRINTF(
7416 		"----------------------------"
7417 		"   TPAT State   "
7418 		"----------------------------\n");
7419 
7420 	val1 = REG_RD_IND(sc, BCE_TPAT_CPU_MODE);
7421 	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_mode\n", val1, BCE_TPAT_CPU_MODE);
7422 
7423 	val1 = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
7424 	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n", val1, BCE_TPAT_CPU_STATE);
7425 
7426 	val1 = REG_RD_IND(sc, BCE_TPAT_CPU_EVENT_MASK);
7427 	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_event_mask\n", val1, BCE_TPAT_CPU_EVENT_MASK);
7428 
7429 	BCE_PRINTF(
7430 		"----------------------------"
7431 		" Register  Dump "
7432 		"----------------------------\n");
7433 
7434 	for (int i = BCE_TPAT_CPU_MODE; i < 0xa3fff; i += 0x10) {
7435 		/* Skip the big blank spaces */
7436 		if (i < 0x854000 && i > 0x9ffff)
7437 			BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
7438 				i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
7439 				REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
7440 	}
7441 
7442 	BCE_PRINTF(
7443 		"----------------------------"
7444 		"----------------"
7445 		"----------------------------\n");
7446 }
7447 
7448 
7449 /****************************************************************************/
7450 /* Prints out the driver state and then enters the debugger.                */
7451 /*                                                                          */
7452 /* Returns:                                                                 */
7453 /*   Nothing.                                                               */
7454 /****************************************************************************/
7455 static void
7456 bce_breakpoint(struct bce_softc *sc)
7457 {
7458 
7459 	/* Unreachable code to shut the compiler up about unused functions. */
7460 	if (0) {
7461 		bce_freeze_controller(sc);
7462 		bce_unfreeze_controller(sc);
7463    		bce_dump_txbd(sc, 0, NULL);
7464 		bce_dump_rxbd(sc, 0, NULL);
7465 		bce_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD);
7466 		bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD);
7467 		bce_dump_l2fhdr(sc, 0, NULL);
7468 		bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
7469 		bce_dump_rx_chain(sc, 0, USABLE_RX_BD);
7470 		bce_dump_status_block(sc);
7471 		bce_dump_stats_block(sc);
7472 		bce_dump_driver_state(sc);
7473 		bce_dump_hw_state(sc);
7474 		bce_dump_txp_state(sc);
7475 		bce_dump_rxp_state(sc);
7476 		bce_dump_tpat_state(sc);
7477 	}
7478 
7479 /*	bce_freeze_controller(sc); */
7480 	bce_dump_driver_state(sc);
7481 	bce_dump_status_block(sc);
7482 	bce_dump_tx_chain(sc, 0, TOTAL_TX_BD);
7483 	bce_dump_hw_state(sc);
7484 	bce_dump_txp_state(sc);
7485 /*	bce_unfreeze_controller(sc); */
7486 
7487 	/* Call the debugger. */
7488 	breakpoint();
7489 
7490 	return;
7491 }
7492 #endif
7493