if_bce.c revision 187133
1/*-
2 * Copyright (c) 2006-2008 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: head/sys/dev/bce/if_bce.c 187133 2009-01-13 07:12:32Z delphij $");
33
34/*
35 * The following controllers are supported by this driver:
36 *   BCM5706C A2, A3
37 *   BCM5706S A2, A3
38 *   BCM5708C B1, B2
39 *   BCM5708S B1, B2
40 *   BCM5709C A1, C0
41 *   BCM5716  C0
42 *
43 * The following controllers are not supported by this driver:
44 *   BCM5706C A0, A1 (pre-production)
45 *   BCM5706S A0, A1 (pre-production)
46 *   BCM5708C A0, B0 (pre-production)
47 *   BCM5708S A0, B0 (pre-production)
48 *   BCM5709C A0  B0, B1, B2 (pre-production)
49 *   BCM5709S A0, A1, B0, B1, B2, C0 (pre-production)
50 */
51
52#include "opt_bce.h"
53
54#include <dev/bce/if_bcereg.h>
55#include <dev/bce/if_bcefw.h>
56
57/****************************************************************************/
58/* BCE Debug Options                                                        */
59/****************************************************************************/
60#ifdef BCE_DEBUG
61	u32 bce_debug = BCE_WARN;
62
63	/*          0 = Never              */
64	/*          1 = 1 in 2,147,483,648 */
65	/*        256 = 1 in     8,388,608 */
66	/*       2048 = 1 in     1,048,576 */
67	/*      65536 = 1 in        32,768 */
68	/*    1048576 = 1 in         2,048 */
69	/*  268435456 =	1 in             8 */
70	/*  536870912 = 1 in             4 */
71	/* 1073741824 = 1 in             2 */
72
73	/* Controls how often the l2_fhdr frame error check will fail. */
74	int bce_debug_l2fhdr_status_check = 0;
75
76	/* Controls how often the unexpected attention check will fail. */
77	int bce_debug_unexpected_attention = 0;
78
79	/* Controls how often to simulate an mbuf allocation failure. */
80	int bce_debug_mbuf_allocation_failure = 0;
81
82	/* Controls how often to simulate a DMA mapping failure. */
83	int bce_debug_dma_map_addr_failure = 0;
84
85	/* Controls how often to simulate a bootcode failure. */
86	int bce_debug_bootcode_running_failure = 0;
87#endif
88
89/****************************************************************************/
90/* BCE Build Time Options                                                   */
91/****************************************************************************/
92#define BCE_USE_SPLIT_HEADER 1
93/* #define BCE_NVRAM_WRITE_SUPPORT 1 */
94
95
96/****************************************************************************/
97/* PCI Device ID Table                                                      */
98/*                                                                          */
99/* Used by bce_probe() to identify the devices supported by this driver.    */
100/****************************************************************************/
101#define BCE_DEVDESC_MAX		64
102
103static struct bce_type bce_devs[] = {
104	/* BCM5706C Controllers and OEM boards. */
105	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3101,
106		"HP NC370T Multifunction Gigabit Server Adapter" },
107	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3106,
108		"HP NC370i Multifunction Gigabit Server Adapter" },
109	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3070,
110		"HP NC380T PCI Express Dual Port Multifunction Gigabit Server Adapter" },
111	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  PCI_ANY_ID,  PCI_ANY_ID,
112		"Broadcom NetXtreme II BCM5706 1000Base-T" },
113
114	/* BCM5706S controllers and OEM boards. */
115	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, HP_VENDORID, 0x3102,
116		"HP NC370F Multifunction Gigabit Server Adapter" },
117	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, PCI_ANY_ID,  PCI_ANY_ID,
118		"Broadcom NetXtreme II BCM5706 1000Base-SX" },
119
120	/* BCM5708C controllers and OEM boards. */
121	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7037,
122		"HP NC373T PCI Express Multifunction Gigabit Server Adapter" },
123	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7038,
124		"HP NC373i Integrated Multifunction Gigabit Server Adapter" },
125	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  PCI_ANY_ID,  PCI_ANY_ID,
126		"Broadcom NetXtreme II BCM5708 1000Base-T" },
127
128	/* BCM5708S controllers and OEM boards. */
129	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x1706,
130                "HP NC373m Multifunction Gigabit Server Adapter" },
131	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x7038,
132                "HP NC373i PCI Express Multifunction Gigabit Server Adapter" },
133	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703b,
134                "HP NC373i Integrated Multifunction Gigabit Server Adapter" },
135	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703d,
136                "HP NC373F PCI Express Multifunction Gigabit Server Adapter" },
137	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  PCI_ANY_ID,  PCI_ANY_ID,
138		"Broadcom NetXtreme II BCM5708 1000Base-SX" },
139
140	/* BCM5709C controllers and OEM boards. */
141	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7055,
142		"HP NC382i Integrated Quad Port PCI Express Gigabit Server Adapter" },
143	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7059,
144		"HP NC382T PCI Express Dual Port Multifunction Gigabit Server Adapter" },
145	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  PCI_ANY_ID,  PCI_ANY_ID,
146		"Broadcom NetXtreme II BCM5709 1000Base-T" },
147
148	/* BCM5709S controllers and OEM boards. */
149	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x171d,
150		"HP NC382m Dual Port 1GbE Multifunction BL-c Adapter" },
151	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x7056,
152		"HP NC382i Integrated Quad Port PCI Express Gigabit Server Adapter" },
153	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  PCI_ANY_ID,  PCI_ANY_ID,
154		"Broadcom NetXtreme II BCM5709 1000Base-SX" },
155
156	/* BCM5716 controllers and OEM boards. */
157	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5716,  PCI_ANY_ID,  PCI_ANY_ID,
158		"Broadcom NetXtreme II BCM5716 1000Base-T" },
159
160	{ 0, 0, 0, 0, NULL }
161};
162
163
164/****************************************************************************/
165/* Supported Flash NVRAM device data.                                       */
166/****************************************************************************/
167static struct flash_spec flash_table[] =
168{
169#define BUFFERED_FLAGS		(BCE_NV_BUFFERED | BCE_NV_TRANSLATE)
170#define NONBUFFERED_FLAGS	(BCE_NV_WREN)
171
172	/* Slow EEPROM */
173	{0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
174	 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
175	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
176	 "EEPROM - slow"},
177	/* Expansion entry 0001 */
178	{0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
179	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
180	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
181	 "Entry 0001"},
182	/* Saifun SA25F010 (non-buffered flash) */
183	/* strap, cfg1, & write1 need updates */
184	{0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
185	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
186	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
187	 "Non-buffered flash (128kB)"},
188	/* Saifun SA25F020 (non-buffered flash) */
189	/* strap, cfg1, & write1 need updates */
190	{0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
191	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
192	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
193	 "Non-buffered flash (256kB)"},
194	/* Expansion entry 0100 */
195	{0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
196	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
197	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
198	 "Entry 0100"},
199	/* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
200	{0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
201	 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
202	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
203	 "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
204	/* Entry 0110: ST M45PE20 (non-buffered flash)*/
205	{0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
206	 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
207	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
208	 "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
209	/* Saifun SA25F005 (non-buffered flash) */
210	/* strap, cfg1, & write1 need updates */
211	{0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
212	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
213	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
214	 "Non-buffered flash (64kB)"},
215	/* Fast EEPROM */
216	{0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
217	 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
218	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
219	 "EEPROM - fast"},
220	/* Expansion entry 1001 */
221	{0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
222	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
223	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
224	 "Entry 1001"},
225	/* Expansion entry 1010 */
226	{0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
227	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
228	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
229	 "Entry 1010"},
230	/* ATMEL AT45DB011B (buffered flash) */
231	{0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
232	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
233	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
234	 "Buffered flash (128kB)"},
235	/* Expansion entry 1100 */
236	{0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
237	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
238	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
239	 "Entry 1100"},
240	/* Expansion entry 1101 */
241	{0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
242	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
243	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
244	 "Entry 1101"},
245	/* Ateml Expansion entry 1110 */
246	{0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
247	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
248	 BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
249	 "Entry 1110 (Atmel)"},
250	/* ATMEL AT45DB021B (buffered flash) */
251	{0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
252	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
253	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
254	 "Buffered flash (256kB)"},
255};
256
257/*
258 * The BCM5709 controllers transparently handle the
259 * differences between Atmel 264 byte pages and all
260 * flash devices which use 256 byte pages, so no
261 * logical-to-physical mapping is required in the
262 * driver.
263 */
264static struct flash_spec flash_5709 = {
265	.flags		= BCE_NV_BUFFERED,
266	.page_bits	= BCM5709_FLASH_PAGE_BITS,
267	.page_size	= BCM5709_FLASH_PAGE_SIZE,
268	.addr_mask	= BCM5709_FLASH_BYTE_ADDR_MASK,
269	.total_size	= BUFFERED_FLASH_TOTAL_SIZE * 2,
270	.name		= "5709/5716 buffered flash (256kB)",
271};
272
273
274/****************************************************************************/
275/* FreeBSD device entry points.                                             */
276/****************************************************************************/
277static int  bce_probe				(device_t);
278static int  bce_attach				(device_t);
279static int  bce_detach				(device_t);
280static int  bce_shutdown			(device_t);
281
282
283/****************************************************************************/
284/* BCE Debug Data Structure Dump Routines                                   */
285/****************************************************************************/
286#ifdef BCE_DEBUG
287static u32	bce_reg_rd				(struct bce_softc *, u32);
288static void	bce_reg_wr				(struct bce_softc *, u32, u32);
289static void	bce_reg_wr16			(struct bce_softc *, u32, u16);
290static u32  bce_ctx_rd				(struct bce_softc *, u32, u32);
291static void bce_dump_enet           (struct bce_softc *, struct mbuf *);
292static void bce_dump_mbuf 			(struct bce_softc *, struct mbuf *);
293static void bce_dump_tx_mbuf_chain	(struct bce_softc *, u16, int);
294static void bce_dump_rx_mbuf_chain	(struct bce_softc *, u16, int);
295#ifdef BCE_USE_SPLIT_HEADER
296static void bce_dump_pg_mbuf_chain	(struct bce_softc *, u16, int);
297#endif
298static void bce_dump_txbd			(struct bce_softc *, int, struct tx_bd *);
299static void bce_dump_rxbd			(struct bce_softc *, int, struct rx_bd *);
300#ifdef BCE_USE_SPLIT_HEADER
301static void bce_dump_pgbd			(struct bce_softc *, int, struct rx_bd *);
302#endif
303static void bce_dump_l2fhdr			(struct bce_softc *, int, struct l2_fhdr *);
304static void bce_dump_ctx			(struct bce_softc *, u16);
305static void bce_dump_ftqs			(struct bce_softc *);
306static void bce_dump_tx_chain		(struct bce_softc *, u16, int);
307static void bce_dump_rx_chain		(struct bce_softc *, u16, int);
308#ifdef BCE_USE_SPLIT_HEADER
309static void bce_dump_pg_chain		(struct bce_softc *, u16, int);
310#endif
311static void bce_dump_status_block	(struct bce_softc *);
312static void bce_dump_stats_block	(struct bce_softc *);
313static void bce_dump_driver_state	(struct bce_softc *);
314static void bce_dump_hw_state		(struct bce_softc *);
315static void bce_dump_mq_regs        (struct bce_softc *);
316static void bce_dump_bc_state		(struct bce_softc *);
317static void bce_dump_txp_state		(struct bce_softc *, int);
318static void bce_dump_rxp_state		(struct bce_softc *, int);
319static void bce_dump_tpat_state		(struct bce_softc *, int);
320static void bce_dump_cp_state		(struct bce_softc *, int);
321static void bce_dump_com_state		(struct bce_softc *, int);
322static void bce_breakpoint			(struct bce_softc *);
323#endif
324
325
326/****************************************************************************/
327/* BCE Register/Memory Access Routines                                      */
328/****************************************************************************/
329static u32  bce_reg_rd_ind			(struct bce_softc *, u32);
330static void bce_reg_wr_ind			(struct bce_softc *, u32, u32);
331static void bce_ctx_wr				(struct bce_softc *, u32, u32, u32);
332static int  bce_miibus_read_reg		(device_t, int, int);
333static int  bce_miibus_write_reg	(device_t, int, int, int);
334static void bce_miibus_statchg		(device_t);
335
336
337/****************************************************************************/
338/* BCE NVRAM Access Routines                                                */
339/****************************************************************************/
340static int  bce_acquire_nvram_lock	(struct bce_softc *);
341static int  bce_release_nvram_lock	(struct bce_softc *);
342static void bce_enable_nvram_access	(struct bce_softc *);
343static void	bce_disable_nvram_access(struct bce_softc *);
344static int  bce_nvram_read_dword	(struct bce_softc *, u32, u8 *, u32);
345static int  bce_init_nvram			(struct bce_softc *);
346static int  bce_nvram_read			(struct bce_softc *, u32, u8 *, int);
347static int  bce_nvram_test			(struct bce_softc *);
348#ifdef BCE_NVRAM_WRITE_SUPPORT
349static int  bce_enable_nvram_write	(struct bce_softc *);
350static void bce_disable_nvram_write	(struct bce_softc *);
351static int  bce_nvram_erase_page	(struct bce_softc *, u32);
352static int  bce_nvram_write_dword	(struct bce_softc *, u32, u8 *, u32);
353static int  bce_nvram_write			(struct bce_softc *, u32, u8 *, int);
354#endif
355
356/****************************************************************************/
357/*                                                                          */
358/****************************************************************************/
359static void bce_get_media			(struct bce_softc *);
360static void bce_dma_map_addr		(void *, bus_dma_segment_t *, int, int);
361static int  bce_dma_alloc			(device_t);
362static void bce_dma_free			(struct bce_softc *);
363static void bce_release_resources	(struct bce_softc *);
364
365/****************************************************************************/
366/* BCE Firmware Synchronization and Load                                    */
367/****************************************************************************/
368static int  bce_fw_sync				(struct bce_softc *, u32);
369static void bce_load_rv2p_fw		(struct bce_softc *, u32 *, u32, u32);
370static void bce_load_cpu_fw			(struct bce_softc *, struct cpu_reg *, struct fw_info *);
371static void bce_init_rxp_cpu		(struct bce_softc *);
372static void bce_init_txp_cpu 		(struct bce_softc *);
373static void bce_init_tpat_cpu		(struct bce_softc *);
374static void bce_init_cp_cpu		  	(struct bce_softc *);
375static void bce_init_com_cpu	  	(struct bce_softc *);
376static void bce_init_cpus			(struct bce_softc *);
377
378static void	bce_print_adapter_info	(struct bce_softc *);
379static void bce_probe_pci_caps		(device_t, struct bce_softc *);
380static void bce_stop				(struct bce_softc *);
381static int  bce_reset				(struct bce_softc *, u32);
382static int  bce_chipinit 			(struct bce_softc *);
383static int  bce_blockinit 			(struct bce_softc *);
384
385static int  bce_init_tx_chain		(struct bce_softc *);
386static void bce_free_tx_chain		(struct bce_softc *);
387
388static int  bce_get_rx_buf			(struct bce_softc *, struct mbuf *, u16 *, u16 *, u32 *);
389static int  bce_init_rx_chain		(struct bce_softc *);
390static void bce_fill_rx_chain		(struct bce_softc *);
391static void bce_free_rx_chain		(struct bce_softc *);
392
393#ifdef BCE_USE_SPLIT_HEADER
394static int  bce_get_pg_buf			(struct bce_softc *, struct mbuf *, u16 *, u16 *);
395static int  bce_init_pg_chain		(struct bce_softc *);
396static void bce_fill_pg_chain		(struct bce_softc *);
397static void bce_free_pg_chain		(struct bce_softc *);
398#endif
399
400static int  bce_tx_encap			(struct bce_softc *, struct mbuf **);
401static void bce_start_locked		(struct ifnet *);
402static void bce_start				(struct ifnet *);
403static int  bce_ioctl				(struct ifnet *, u_long, caddr_t);
404static void bce_watchdog			(struct bce_softc *);
405static int  bce_ifmedia_upd			(struct ifnet *);
406static void bce_ifmedia_upd_locked	(struct ifnet *);
407static void bce_ifmedia_sts			(struct ifnet *, struct ifmediareq *);
408static void bce_init_locked			(struct bce_softc *);
409static void bce_init				(void *);
410static void bce_mgmt_init_locked	(struct bce_softc *sc);
411
412static void bce_init_ctx			(struct bce_softc *);
413static void bce_get_mac_addr		(struct bce_softc *);
414static void bce_set_mac_addr		(struct bce_softc *);
415static void bce_phy_intr			(struct bce_softc *);
416static inline u16 bce_get_hw_rx_cons(struct bce_softc *);
417static void bce_rx_intr				(struct bce_softc *);
418static void bce_tx_intr				(struct bce_softc *);
419static void bce_disable_intr		(struct bce_softc *);
420static void bce_enable_intr			(struct bce_softc *, int);
421
422static void bce_intr				(void *);
423static void bce_set_rx_mode			(struct bce_softc *);
424static void bce_stats_update		(struct bce_softc *);
425static void bce_tick				(void *);
426static void bce_pulse				(void *);
427static void bce_add_sysctls			(struct bce_softc *);
428
429
430/****************************************************************************/
431/* FreeBSD device dispatch table.                                           */
432/****************************************************************************/
433static device_method_t bce_methods[] = {
434	/* Device interface (device_if.h) */
435	DEVMETHOD(device_probe,		bce_probe),
436	DEVMETHOD(device_attach,	bce_attach),
437	DEVMETHOD(device_detach,	bce_detach),
438	DEVMETHOD(device_shutdown,	bce_shutdown),
439/* Supported by device interface but not used here. */
440/*	DEVMETHOD(device_identify,	bce_identify),      */
441/*	DEVMETHOD(device_suspend,	bce_suspend),       */
442/*	DEVMETHOD(device_resume,	bce_resume),        */
443/*	DEVMETHOD(device_quiesce,	bce_quiesce),       */
444
445	/* Bus interface (bus_if.h) */
446	DEVMETHOD(bus_print_child,	bus_generic_print_child),
447	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
448
449	/* MII interface (miibus_if.h) */
450	DEVMETHOD(miibus_readreg,	bce_miibus_read_reg),
451	DEVMETHOD(miibus_writereg,	bce_miibus_write_reg),
452	DEVMETHOD(miibus_statchg,	bce_miibus_statchg),
453/* Supported by MII interface but not used here.       */
454/*	DEVMETHOD(miibus_linkchg,	bce_miibus_linkchg),   */
455/*	DEVMETHOD(miibus_mediainit,	bce_miibus_mediainit), */
456
457	{ 0, 0 }
458};
459
460static driver_t bce_driver = {
461	"bce",
462	bce_methods,
463	sizeof(struct bce_softc)
464};
465
466static devclass_t bce_devclass;
467
468MODULE_DEPEND(bce, pci, 1, 1, 1);
469MODULE_DEPEND(bce, ether, 1, 1, 1);
470MODULE_DEPEND(bce, miibus, 1, 1, 1);
471
472DRIVER_MODULE(bce, pci, bce_driver, bce_devclass, 0, 0);
473DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, 0, 0);
474
475
476/****************************************************************************/
477/* Tunable device values                                                    */
478/****************************************************************************/
479SYSCTL_NODE(_hw, OID_AUTO, bce, CTLFLAG_RD, 0, "bce driver parameters");
480
481/* Allowable values are TRUE or FALSE */
482static int bce_tso_enable = TRUE;
483TUNABLE_INT("hw.bce.tso_enable", &bce_tso_enable);
484SYSCTL_UINT(_hw_bce, OID_AUTO, tso_enable, CTLFLAG_RDTUN, &bce_tso_enable, 0,
485"TSO Enable/Disable");
486
487/* Allowable values are 0 (IRQ), 1 (MSI/IRQ), and 2 (MSI-X/MSI/IRQ) */
488/* ToDo: Add MSI-X support. */
489static int bce_msi_enable = 1;
490TUNABLE_INT("hw.bce.msi_enable", &bce_msi_enable);
491SYSCTL_UINT(_hw_bce, OID_AUTO, msi_enable, CTLFLAG_RDTUN, &bce_msi_enable, 0,
492"MSI-X|MSI|INTx selector");
493
494/* ToDo: Add tunable to enable/disable strict MTU handling. */
495/* Currently allows "loose" RX MTU checking (i.e. sets the  */
496/* H/W RX MTU to the size of the largest receive buffer, or */
497/* 2048 bytes).                                             */
498
499
500/****************************************************************************/
501/* Device probe function.                                                   */
502/*                                                                          */
503/* Compares the device to the driver's list of supported devices and        */
504/* reports back to the OS whether this is the right driver for the device.  */
505/*                                                                          */
506/* Returns:                                                                 */
507/*   BUS_PROBE_DEFAULT on success, positive value on failure.               */
508/****************************************************************************/
509static int
510bce_probe(device_t dev)
511{
512	struct bce_type *t;
513	struct bce_softc *sc;
514	char *descbuf;
515	u16 vid = 0, did = 0, svid = 0, sdid = 0;
516
517	t = bce_devs;
518
519	sc = device_get_softc(dev);
520	bzero(sc, sizeof(struct bce_softc));
521	sc->bce_unit = device_get_unit(dev);
522	sc->bce_dev = dev;
523
524	/* Get the data for the device to be probed. */
525	vid  = pci_get_vendor(dev);
526	did  = pci_get_device(dev);
527	svid = pci_get_subvendor(dev);
528	sdid = pci_get_subdevice(dev);
529
530	DBPRINT(sc, BCE_EXTREME_LOAD,
531		"%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
532		"SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
533
534	/* Look through the list of known devices for a match. */
535	while(t->bce_name != NULL) {
536
537		if ((vid == t->bce_vid) && (did == t->bce_did) &&
538			((svid == t->bce_svid) || (t->bce_svid == PCI_ANY_ID)) &&
539			((sdid == t->bce_sdid) || (t->bce_sdid == PCI_ANY_ID))) {
540
541			descbuf = malloc(BCE_DEVDESC_MAX, M_TEMP, M_NOWAIT);
542
543			if (descbuf == NULL)
544				return(ENOMEM);
545
546			/* Print out the device identity. */
547			snprintf(descbuf, BCE_DEVDESC_MAX, "%s (%c%d)",
548				t->bce_name,
549			    (((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
550			    (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
551
552			device_set_desc_copy(dev, descbuf);
553			free(descbuf, M_TEMP);
554			return(BUS_PROBE_DEFAULT);
555		}
556		t++;
557	}
558
559	return(ENXIO);
560}
561
562
563/****************************************************************************/
564/* PCI Capabilities Probe Function.                                         */
565/*                                                                          */
566/* Walks the PCI capabiites list for the device to find what features are   */
567/* supported.                                                               */
568/*                                                                          */
569/* Returns:                                                                 */
570/*   None.                                                                  */
571/****************************************************************************/
572static void
573bce_print_adapter_info(struct bce_softc *sc)
574{
575	DBENTER(BCE_VERBOSE_LOAD);
576
577	BCE_PRINTF("ASIC (0x%08X); ", sc->bce_chipid);
578	printf("Rev (%c%d); ", ((BCE_CHIP_ID(sc) & 0xf000) >> 12) + 'A',
579		((BCE_CHIP_ID(sc) & 0x0ff0) >> 4));
580
581	/* Bus info. */
582	if (sc->bce_flags & BCE_PCIE_FLAG) {
583		printf("Bus (PCIe x%d, ", sc->link_width);
584		switch (sc->link_speed) {
585			case 1: printf("2.5Gbps); "); break;
586			case 2:	printf("5Gbps); "); break;
587			default: printf("Unknown link speed); ");
588		}
589	} else {
590		printf("Bus (PCI%s, %s, %dMHz); ",
591			((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""),
592			((sc->bce_flags & BCE_PCI_32BIT_FLAG) ? "32-bit" : "64-bit"),
593			sc->bus_speed_mhz);
594	}
595
596	/* Firmware version and device features. */
597	printf("F/W (0x%08X); Flags( ", sc->bce_fw_ver);
598#ifdef BCE_USE_SPLIT_HEADER
599	printf("SPLT ");
600#endif
601	if (sc->bce_flags & BCE_MFW_ENABLE_FLAG)
602		printf("MFW ");
603	if (sc->bce_flags & BCE_USING_MSI_FLAG)
604		printf("MSI ");
605	if (sc->bce_flags & BCE_USING_MSIX_FLAG)
606		printf("MSI-X ");
607	if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
608		printf("2.5G ");
609	printf(")\n");
610
611	DBEXIT(BCE_VERBOSE_LOAD);
612}
613
614
615/****************************************************************************/
616/* PCI Capabilities Probe Function.                                         */
617/*                                                                          */
618/* Walks the PCI capabiites list for the device to find what features are   */
619/* supported.                                                               */
620/*                                                                          */
621/* Returns:                                                                 */
622/*   None.                                                                  */
623/****************************************************************************/
624static void
625bce_probe_pci_caps(device_t dev, struct bce_softc *sc)
626{
627	u32 reg;
628
629	DBENTER(BCE_VERBOSE_LOAD);
630
631	/* Check if PCI-X capability is enabled. */
632	if (pci_find_extcap(dev, PCIY_PCIX, &reg) == 0) {
633		if (reg != 0)
634			sc->bce_cap_flags |= BCE_PCIX_CAPABLE_FLAG;
635	}
636
637	/* Check if PCIe capability is enabled. */
638	if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
639		if (reg != 0) {
640			u16 link_status = pci_read_config(dev, reg + 0x12, 2);
641			DBPRINT(sc, BCE_INFO_LOAD, "PCIe link_status = 0x%08X\n",
642				link_status);
643			sc->link_speed = link_status & 0xf;
644			sc->link_width = (link_status >> 4) & 0x3f;
645			sc->bce_cap_flags |= BCE_PCIE_CAPABLE_FLAG;
646			sc->bce_flags |= BCE_PCIE_FLAG;
647		}
648	}
649
650	/* Check if MSI capability is enabled. */
651	if (pci_find_extcap(dev, PCIY_MSI, &reg) == 0) {
652		if (reg != 0)
653			sc->bce_cap_flags |= BCE_MSI_CAPABLE_FLAG;
654	}
655
656	/* Check if MSI-X capability is enabled. */
657	if (pci_find_extcap(dev, PCIY_MSIX, &reg) == 0) {
658		if (reg != 0)
659			sc->bce_cap_flags |= BCE_MSIX_CAPABLE_FLAG;
660	}
661
662	DBEXIT(BCE_VERBOSE_LOAD);
663}
664
665
666/****************************************************************************/
667/* Device attach function.                                                  */
668/*                                                                          */
669/* Allocates device resources, performs secondary chip identification,      */
670/* resets and initializes the hardware, and initializes driver instance     */
671/* variables.                                                               */
672/*                                                                          */
673/* Returns:                                                                 */
674/*   0 on success, positive value on failure.                               */
675/****************************************************************************/
676static int
677bce_attach(device_t dev)
678{
679	struct bce_softc *sc;
680	struct ifnet *ifp;
681	u32 val;
682	int error, rid, rc = 0;
683
684	sc = device_get_softc(dev);
685	sc->bce_dev = dev;
686
687	DBENTER(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
688
689	sc->bce_unit = device_get_unit(dev);
690
691	/* Set initial device and PHY flags */
692	sc->bce_flags = 0;
693	sc->bce_phy_flags = 0;
694
695	pci_enable_busmaster(dev);
696
697	/* Allocate PCI memory resources. */
698	rid = PCIR_BAR(0);
699	sc->bce_res_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
700		&rid, RF_ACTIVE);
701
702	if (sc->bce_res_mem == NULL) {
703		BCE_PRINTF("%s(%d): PCI memory allocation failed\n",
704			__FILE__, __LINE__);
705		rc = ENXIO;
706		goto bce_attach_fail;
707	}
708
709	/* Get various resource handles. */
710	sc->bce_btag    = rman_get_bustag(sc->bce_res_mem);
711	sc->bce_bhandle = rman_get_bushandle(sc->bce_res_mem);
712	sc->bce_vhandle = (vm_offset_t) rman_get_virtual(sc->bce_res_mem);
713
714	bce_probe_pci_caps(dev, sc);
715
716	rid = 1;
717#if 0
718	/* Try allocating MSI-X interrupts. */
719	if ((sc->bce_cap_flags & BCE_MSIX_CAPABLE_FLAG) &&
720		(bce_msi_enable >= 2) &&
721		((sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
722		&rid, RF_ACTIVE)) != NULL)) {
723
724		msi_needed = sc->bce_msi_count = 1;
725
726		if (((error = pci_alloc_msix(dev, &sc->bce_msi_count)) != 0) ||
727			(sc->bce_msi_count != msi_needed)) {
728			BCE_PRINTF("%s(%d): MSI-X allocation failed! Requested = %d,"
729				"Received = %d, error = %d\n", __FILE__, __LINE__,
730				msi_needed, sc->bce_msi_count, error);
731			sc->bce_msi_count = 0;
732			pci_release_msi(dev);
733			bus_release_resource(dev, SYS_RES_MEMORY, rid,
734				sc->bce_res_irq);
735			sc->bce_res_irq = NULL;
736		} else {
737			DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI-X interrupt.\n",
738				__FUNCTION__);
739			sc->bce_flags |= BCE_USING_MSIX_FLAG;
740			sc->bce_intr = bce_intr;
741		}
742	}
743#endif
744
745	/* Try allocating a MSI interrupt. */
746	if ((sc->bce_cap_flags & BCE_MSI_CAPABLE_FLAG) &&
747		(bce_msi_enable >= 1) && (sc->bce_msi_count == 0)) {
748		sc->bce_msi_count = 1;
749		if ((error = pci_alloc_msi(dev, &sc->bce_msi_count)) != 0) {
750			BCE_PRINTF("%s(%d): MSI allocation failed! error = %d\n",
751				__FILE__, __LINE__, error);
752			sc->bce_msi_count = 0;
753			pci_release_msi(dev);
754		} else {
755			DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI interrupt.\n",
756				__FUNCTION__);
757			sc->bce_flags |= BCE_USING_MSI_FLAG;
758			if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
759				(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
760				sc->bce_flags |= BCE_ONE_SHOT_MSI_FLAG;
761			sc->bce_irq_rid = 1;
762			sc->bce_intr = bce_intr;
763		}
764	}
765
766	/* Try allocating a legacy interrupt. */
767	if (sc->bce_msi_count == 0) {
768		DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using INTx interrupt.\n",
769			__FUNCTION__);
770		rid = 0;
771		sc->bce_intr = bce_intr;
772	}
773
774	sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
775		&rid, RF_SHAREABLE | RF_ACTIVE);
776
777	sc->bce_irq_rid = rid;
778
779	/* Report any IRQ allocation errors. */
780	if (sc->bce_res_irq == NULL) {
781		BCE_PRINTF("%s(%d): PCI map interrupt failed!\n",
782			__FILE__, __LINE__);
783		rc = ENXIO;
784		goto bce_attach_fail;
785	}
786
787	/* Initialize mutex for the current device instance. */
788	BCE_LOCK_INIT(sc, device_get_nameunit(dev));
789
790	/*
791	 * Configure byte swap and enable indirect register access.
792	 * Rely on CPU to do target byte swapping on big endian systems.
793	 * Access to registers outside of PCI configurtion space are not
794	 * valid until this is done.
795	 */
796	pci_write_config(dev, BCE_PCICFG_MISC_CONFIG,
797			       BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
798			       BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4);
799
800	/* Save ASIC revsion info. */
801	sc->bce_chipid =  REG_RD(sc, BCE_MISC_ID);
802
803	/* Weed out any non-production controller revisions. */
804	switch(BCE_CHIP_ID(sc)) {
805		case BCE_CHIP_ID_5706_A0:
806		case BCE_CHIP_ID_5706_A1:
807		case BCE_CHIP_ID_5708_A0:
808		case BCE_CHIP_ID_5708_B0:
809		case BCE_CHIP_ID_5709_A0:
810		case BCE_CHIP_ID_5709_B0:
811		case BCE_CHIP_ID_5709_B1:
812		case BCE_CHIP_ID_5709_B2:
813			BCE_PRINTF("%s(%d): Unsupported controller revision (%c%d)!\n",
814				__FILE__, __LINE__,
815				(((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
816			    (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
817			rc = ENODEV;
818			goto bce_attach_fail;
819	}
820
821	/*
822	 * The embedded PCIe to PCI-X bridge (EPB)
823	 * in the 5708 cannot address memory above
824	 * 40 bits (E7_5708CB1_23043 & E6_5708SB1_23043).
825	 */
826	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708)
827		sc->max_bus_addr = BCE_BUS_SPACE_MAXADDR;
828	else
829		sc->max_bus_addr = BUS_SPACE_MAXADDR;
830
831	/*
832	 * Find the base address for shared memory access.
833	 * Newer versions of bootcode use a signature and offset
834	 * while older versions use a fixed address.
835	 */
836	val = REG_RD_IND(sc, BCE_SHM_HDR_SIGNATURE);
837	if ((val & BCE_SHM_HDR_SIGNATURE_SIG_MASK) == BCE_SHM_HDR_SIGNATURE_SIG)
838		/* Multi-port devices use different offsets in shared memory. */
839		sc->bce_shmem_base = REG_RD_IND(sc, BCE_SHM_HDR_ADDR_0 +
840			(pci_get_function(sc->bce_dev) << 2));
841	else
842		sc->bce_shmem_base = HOST_VIEW_SHMEM_BASE;
843
844	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): bce_shmem_base = 0x%08X\n",
845		__FUNCTION__, sc->bce_shmem_base);
846
847	/* Fetch the bootcode revision. */
848	sc->bce_fw_ver = REG_RD_IND(sc, sc->bce_shmem_base +
849		BCE_DEV_INFO_BC_REV);
850
851	/* Check if any management firmware is running. */
852	val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_PORT_FEATURE);
853	if (val & (BCE_PORT_FEATURE_ASF_ENABLED | BCE_PORT_FEATURE_IMD_ENABLED))
854		sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
855
856	/* Get PCI bus information (speed and type). */
857	val = REG_RD(sc, BCE_PCICFG_MISC_STATUS);
858	if (val & BCE_PCICFG_MISC_STATUS_PCIX_DET) {
859		u32 clkreg;
860
861		sc->bce_flags |= BCE_PCIX_FLAG;
862
863		clkreg = REG_RD(sc, BCE_PCICFG_PCI_CLOCK_CONTROL_BITS);
864
865		clkreg &= BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
866		switch (clkreg) {
867		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
868			sc->bus_speed_mhz = 133;
869			break;
870
871		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
872			sc->bus_speed_mhz = 100;
873			break;
874
875		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
876		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
877			sc->bus_speed_mhz = 66;
878			break;
879
880		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
881		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
882			sc->bus_speed_mhz = 50;
883			break;
884
885		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
886		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
887		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
888			sc->bus_speed_mhz = 33;
889			break;
890		}
891	} else {
892		if (val & BCE_PCICFG_MISC_STATUS_M66EN)
893			sc->bus_speed_mhz = 66;
894		else
895			sc->bus_speed_mhz = 33;
896	}
897
898	if (val & BCE_PCICFG_MISC_STATUS_32BIT_DET)
899		sc->bce_flags |= BCE_PCI_32BIT_FLAG;
900
901	/* Reset the controller and announce to bootcode that driver is present. */
902	if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
903		BCE_PRINTF("%s(%d): Controller reset failed!\n",
904			__FILE__, __LINE__);
905		rc = ENXIO;
906		goto bce_attach_fail;
907	}
908
909	/* Initialize the controller. */
910	if (bce_chipinit(sc)) {
911		BCE_PRINTF("%s(%d): Controller initialization failed!\n",
912			__FILE__, __LINE__);
913		rc = ENXIO;
914		goto bce_attach_fail;
915	}
916
917	/* Perform NVRAM test. */
918	if (bce_nvram_test(sc)) {
919		BCE_PRINTF("%s(%d): NVRAM test failed!\n",
920			__FILE__, __LINE__);
921		rc = ENXIO;
922		goto bce_attach_fail;
923	}
924
925	/* Fetch the permanent Ethernet MAC address. */
926	bce_get_mac_addr(sc);
927
928	/*
929	 * Trip points control how many BDs
930	 * should be ready before generating an
931	 * interrupt while ticks control how long
932	 * a BD can sit in the chain before
933	 * generating an interrupt.  Set the default
934	 * values for the RX and TX chains.
935	 */
936
937#ifdef BCE_DEBUG
938	/* Force more frequent interrupts. */
939	sc->bce_tx_quick_cons_trip_int = 1;
940	sc->bce_tx_quick_cons_trip     = 1;
941	sc->bce_tx_ticks_int           = 0;
942	sc->bce_tx_ticks               = 0;
943
944	sc->bce_rx_quick_cons_trip_int = 1;
945	sc->bce_rx_quick_cons_trip     = 1;
946	sc->bce_rx_ticks_int           = 0;
947	sc->bce_rx_ticks               = 0;
948#else
949	/* Improve throughput at the expense of increased latency. */
950	sc->bce_tx_quick_cons_trip_int = 20;
951	sc->bce_tx_quick_cons_trip     = 20;
952	sc->bce_tx_ticks_int           = 80;
953	sc->bce_tx_ticks               = 80;
954
955	sc->bce_rx_quick_cons_trip_int = 6;
956	sc->bce_rx_quick_cons_trip     = 6;
957	sc->bce_rx_ticks_int           = 18;
958	sc->bce_rx_ticks               = 18;
959#endif
960
961	/* Update statistics once every second. */
962	sc->bce_stats_ticks = 1000000 & 0xffff00;
963
964	/* Find the media type for the adapter. */
965	bce_get_media(sc);
966
967	/* Store data needed by PHY driver for backplane applications */
968	sc->bce_shared_hw_cfg = REG_RD_IND(sc, sc->bce_shmem_base +
969		BCE_SHARED_HW_CFG_CONFIG);
970	sc->bce_port_hw_cfg   = REG_RD_IND(sc, sc->bce_shmem_base +
971		BCE_PORT_HW_CFG_CONFIG);
972
973	/* Allocate DMA memory resources. */
974	if (bce_dma_alloc(dev)) {
975		BCE_PRINTF("%s(%d): DMA resource allocation failed!\n",
976		    __FILE__, __LINE__);
977		rc = ENXIO;
978		goto bce_attach_fail;
979	}
980
981	/* Allocate an ifnet structure. */
982	ifp = sc->bce_ifp = if_alloc(IFT_ETHER);
983	if (ifp == NULL) {
984		BCE_PRINTF("%s(%d): Interface allocation failed!\n",
985			__FILE__, __LINE__);
986		rc = ENXIO;
987		goto bce_attach_fail;
988	}
989
990	/* Initialize the ifnet interface. */
991	ifp->if_softc        = sc;
992	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
993	ifp->if_flags        = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
994	ifp->if_ioctl        = bce_ioctl;
995	ifp->if_start        = bce_start;
996	ifp->if_init         = bce_init;
997	ifp->if_mtu          = ETHERMTU;
998
999	if (bce_tso_enable) {
1000		ifp->if_hwassist = BCE_IF_HWASSIST | CSUM_TSO;
1001		ifp->if_capabilities = BCE_IF_CAPABILITIES | IFCAP_TSO4;
1002	} else {
1003		ifp->if_hwassist = BCE_IF_HWASSIST;
1004		ifp->if_capabilities = BCE_IF_CAPABILITIES;
1005	}
1006
1007	ifp->if_capenable    = ifp->if_capabilities;
1008
1009	/*
1010	 * Assume standard mbuf sizes for buffer allocation.
1011	 * This may change later if the MTU size is set to
1012	 * something other than 1500.
1013	 */
1014#ifdef BCE_USE_SPLIT_HEADER
1015	sc->rx_bd_mbuf_alloc_size = MHLEN;
1016	/* Make sure offset is 16 byte aligned for hardware. */
1017	sc->rx_bd_mbuf_align_pad  = roundup2((MSIZE - MHLEN), 16) -
1018		(MSIZE - MHLEN);
1019	sc->rx_bd_mbuf_data_len   = sc->rx_bd_mbuf_alloc_size -
1020		sc->rx_bd_mbuf_align_pad;
1021	sc->pg_bd_mbuf_alloc_size = MCLBYTES;
1022#else
1023	sc->rx_bd_mbuf_alloc_size = MCLBYTES;
1024	sc->rx_bd_mbuf_align_pad  = roundup2(MCLBYTES, 16) - MCLBYTES;
1025	sc->rx_bd_mbuf_data_len   = sc->rx_bd_mbuf_alloc_size -
1026		sc->rx_bd_mbuf_align_pad;
1027#endif
1028
1029	ifp->if_snd.ifq_drv_maxlen = USABLE_TX_BD;
1030	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
1031	IFQ_SET_READY(&ifp->if_snd);
1032
1033	if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
1034		ifp->if_baudrate = IF_Mbps(2500ULL);
1035	else
1036		ifp->if_baudrate = IF_Mbps(1000);
1037
1038	/* Check for an MII child bus by probing the PHY. */
1039	if (mii_phy_probe(dev, &sc->bce_miibus, bce_ifmedia_upd,
1040		bce_ifmedia_sts)) {
1041		BCE_PRINTF("%s(%d): No PHY found on child MII bus!\n",
1042			__FILE__, __LINE__);
1043		rc = ENXIO;
1044		goto bce_attach_fail;
1045	}
1046
1047	/* Attach to the Ethernet interface list. */
1048	ether_ifattach(ifp, sc->eaddr);
1049
1050#if __FreeBSD_version < 500000
1051	callout_init(&sc->bce_tick_callout);
1052	callout_init(&sc->bce_pulse_callout);
1053#else
1054	callout_init_mtx(&sc->bce_tick_callout, &sc->bce_mtx, 0);
1055	callout_init_mtx(&sc->bce_pulse_callout, &sc->bce_mtx, 0);
1056#endif
1057
1058	/* Hookup IRQ last. */
1059	rc = bus_setup_intr(dev, sc->bce_res_irq, INTR_TYPE_NET | INTR_MPSAFE,
1060		NULL, bce_intr, sc, &sc->bce_intrhand);
1061
1062	if (rc) {
1063		BCE_PRINTF("%s(%d): Failed to setup IRQ!\n",
1064			__FILE__, __LINE__);
1065		bce_detach(dev);
1066		goto bce_attach_exit;
1067	}
1068
1069	/*
1070	 * At this point we've acquired all the resources
1071	 * we need to run so there's no turning back, we're
1072	 * cleared for launch.
1073	 */
1074
1075	/* Print some important debugging info. */
1076	DBRUNMSG(BCE_INFO, bce_dump_driver_state(sc));
1077
1078	/* Add the supported sysctls to the kernel. */
1079	bce_add_sysctls(sc);
1080
1081	BCE_LOCK(sc);
1082
1083	/*
1084	 * The chip reset earlier notified the bootcode that
1085	 * a driver is present.  We now need to start our pulse
1086	 * routine so that the bootcode is reminded that we're
1087	 * still running.
1088	 */
1089	bce_pulse(sc);
1090
1091	bce_mgmt_init_locked(sc);
1092	BCE_UNLOCK(sc);
1093
1094	/* Finally, print some useful adapter info */
1095	bce_print_adapter_info(sc);
1096	DBPRINT(sc, BCE_FATAL, "%s(): sc = %p\n",
1097		__FUNCTION__, sc);
1098
1099	goto bce_attach_exit;
1100
1101bce_attach_fail:
1102	bce_release_resources(sc);
1103
1104bce_attach_exit:
1105
1106	DBEXIT(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
1107
1108	return(rc);
1109}
1110
1111
1112/****************************************************************************/
1113/* Device detach function.                                                  */
1114/*                                                                          */
1115/* Stops the controller, resets the controller, and releases resources.     */
1116/*                                                                          */
1117/* Returns:                                                                 */
1118/*   0 on success, positive value on failure.                               */
1119/****************************************************************************/
1120static int
1121bce_detach(device_t dev)
1122{
1123	struct bce_softc *sc = device_get_softc(dev);
1124	struct ifnet *ifp;
1125	u32 msg;
1126
1127	DBENTER(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
1128
1129	ifp = sc->bce_ifp;
1130
1131	/* Stop and reset the controller. */
1132	BCE_LOCK(sc);
1133
1134	/* Stop the pulse so the bootcode can go to driver absent state. */
1135	callout_stop(&sc->bce_pulse_callout);
1136
1137	bce_stop(sc);
1138	if (sc->bce_flags & BCE_NO_WOL_FLAG)
1139		msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
1140	else
1141		msg = BCE_DRV_MSG_CODE_UNLOAD;
1142	bce_reset(sc, msg);
1143
1144	BCE_UNLOCK(sc);
1145
1146	ether_ifdetach(ifp);
1147
1148	/* If we have a child device on the MII bus remove it too. */
1149	bus_generic_detach(dev);
1150	device_delete_child(dev, sc->bce_miibus);
1151
1152	/* Release all remaining resources. */
1153	bce_release_resources(sc);
1154
1155	DBEXIT(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
1156
1157	return(0);
1158}
1159
1160
1161/****************************************************************************/
1162/* Device shutdown function.                                                */
1163/*                                                                          */
1164/* Stops and resets the controller.                                         */
1165/*                                                                          */
1166/* Returns:                                                                 */
1167/*   0 on success, positive value on failure.                               */
1168/****************************************************************************/
1169static int
1170bce_shutdown(device_t dev)
1171{
1172	struct bce_softc *sc = device_get_softc(dev);
1173	u32 msg;
1174
1175	DBENTER(BCE_VERBOSE);
1176
1177	BCE_LOCK(sc);
1178	bce_stop(sc);
1179	if (sc->bce_flags & BCE_NO_WOL_FLAG)
1180		msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
1181	else
1182		msg = BCE_DRV_MSG_CODE_UNLOAD;
1183	bce_reset(sc, msg);
1184	BCE_UNLOCK(sc);
1185
1186	DBEXIT(BCE_VERBOSE);
1187
1188	return (0);
1189}
1190
1191
1192#ifdef BCE_DEBUG
1193/****************************************************************************/
1194/* Register read.                                                           */
1195/*                                                                          */
1196/* Returns:                                                                 */
1197/*   The value of the register.                                             */
1198/****************************************************************************/
1199static u32
1200bce_reg_rd(struct bce_softc *sc, u32 offset)
1201{
1202	u32 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, offset);
1203	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1204		__FUNCTION__, offset, val);
1205	return val;
1206}
1207
1208
1209/****************************************************************************/
1210/* Register write (16 bit).                                                 */
1211/*                                                                          */
1212/* Returns:                                                                 */
1213/*   Nothing.                                                               */
1214/****************************************************************************/
1215static void
1216bce_reg_wr16(struct bce_softc *sc, u32 offset, u16 val)
1217{
1218	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%04X\n",
1219		__FUNCTION__, offset, val);
1220	bus_space_write_2(sc->bce_btag, sc->bce_bhandle, offset, val);
1221}
1222
1223
1224/****************************************************************************/
1225/* Register write.                                                          */
1226/*                                                                          */
1227/* Returns:                                                                 */
1228/*   Nothing.                                                               */
1229/****************************************************************************/
1230static void
1231bce_reg_wr(struct bce_softc *sc, u32 offset, u32 val)
1232{
1233	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1234		__FUNCTION__, offset, val);
1235	bus_space_write_4(sc->bce_btag, sc->bce_bhandle, offset, val);
1236}
1237#endif
1238
1239/****************************************************************************/
1240/* Indirect register read.                                                  */
1241/*                                                                          */
1242/* Reads NetXtreme II registers using an index/data register pair in PCI    */
1243/* configuration space.  Using this mechanism avoids issues with posted     */
1244/* reads but is much slower than memory-mapped I/O.                         */
1245/*                                                                          */
1246/* Returns:                                                                 */
1247/*   The value of the register.                                             */
1248/****************************************************************************/
1249static u32
1250bce_reg_rd_ind(struct bce_softc *sc, u32 offset)
1251{
1252	device_t dev;
1253	dev = sc->bce_dev;
1254
1255	pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
1256#ifdef BCE_DEBUG
1257	{
1258		u32 val;
1259		val = pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
1260		DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1261			__FUNCTION__, offset, val);
1262		return val;
1263	}
1264#else
1265	return pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
1266#endif
1267}
1268
1269
1270/****************************************************************************/
1271/* Indirect register write.                                                 */
1272/*                                                                          */
1273/* Writes NetXtreme II registers using an index/data register pair in PCI   */
1274/* configuration space.  Using this mechanism avoids issues with posted     */
1275/* writes but is muchh slower than memory-mapped I/O.                       */
1276/*                                                                          */
1277/* Returns:                                                                 */
1278/*   Nothing.                                                               */
1279/****************************************************************************/
1280static void
1281bce_reg_wr_ind(struct bce_softc *sc, u32 offset, u32 val)
1282{
1283	device_t dev;
1284	dev = sc->bce_dev;
1285
1286	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1287		__FUNCTION__, offset, val);
1288
1289	pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
1290	pci_write_config(dev, BCE_PCICFG_REG_WINDOW, val, 4);
1291}
1292
1293
1294#ifdef BCE_DEBUG
1295/****************************************************************************/
1296/* Context memory read.                                                     */
1297/*                                                                          */
1298/* The NetXtreme II controller uses context memory to track connection      */
1299/* information for L2 and higher network protocols.                         */
1300/*                                                                          */
1301/* Returns:                                                                 */
1302/*   The requested 32 bit value of context memory.                          */
1303/****************************************************************************/
1304static u32
1305bce_ctx_rd(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset)
1306{
1307	u32 idx, offset, retry_cnt = 5, val;
1308
1309	DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 || cid_addr & CTX_MASK),
1310		BCE_PRINTF("%s(): Invalid CID address: 0x%08X.\n",
1311			__FUNCTION__, cid_addr));
1312
1313	offset = ctx_offset + cid_addr;
1314
1315	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
1316		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
1317
1318		REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_READ_REQ));
1319
1320		for (idx = 0; idx < retry_cnt; idx++) {
1321			val = REG_RD(sc, BCE_CTX_CTX_CTRL);
1322			if ((val & BCE_CTX_CTX_CTRL_READ_REQ) == 0)
1323				break;
1324			DELAY(5);
1325		}
1326
1327		if (val & BCE_CTX_CTX_CTRL_READ_REQ)
1328			BCE_PRINTF("%s(%d); Unable to read CTX memory: "
1329				"cid_addr = 0x%08X, offset = 0x%08X!\n",
1330				__FILE__, __LINE__, cid_addr, ctx_offset);
1331
1332		val = REG_RD(sc, BCE_CTX_CTX_DATA);
1333	} else {
1334		REG_WR(sc, BCE_CTX_DATA_ADR, offset);
1335		val = REG_RD(sc, BCE_CTX_DATA);
1336	}
1337
1338	DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
1339		"val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, val);
1340
1341	return(val);
1342}
1343#endif
1344
1345
1346/****************************************************************************/
1347/* Context memory write.                                                    */
1348/*                                                                          */
1349/* The NetXtreme II controller uses context memory to track connection      */
1350/* information for L2 and higher network protocols.                         */
1351/*                                                                          */
1352/* Returns:                                                                 */
1353/*   Nothing.                                                               */
1354/****************************************************************************/
1355static void
1356bce_ctx_wr(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset, u32 ctx_val)
1357{
1358	u32 idx, offset = ctx_offset + cid_addr;
1359	u32 val, retry_cnt = 5;
1360
1361	DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
1362		"val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, ctx_val);
1363
1364	DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 || cid_addr & CTX_MASK),
1365		BCE_PRINTF("%s(): Invalid CID address: 0x%08X.\n",
1366			__FUNCTION__, cid_addr));
1367
1368	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
1369		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
1370
1371		REG_WR(sc, BCE_CTX_CTX_DATA, ctx_val);
1372		REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_WRITE_REQ));
1373
1374		for (idx = 0; idx < retry_cnt; idx++) {
1375			val = REG_RD(sc, BCE_CTX_CTX_CTRL);
1376			if ((val & BCE_CTX_CTX_CTRL_WRITE_REQ) == 0)
1377				break;
1378			DELAY(5);
1379		}
1380
1381		if (val & BCE_CTX_CTX_CTRL_WRITE_REQ)
1382			BCE_PRINTF("%s(%d); Unable to write CTX memory: "
1383				"cid_addr = 0x%08X, offset = 0x%08X!\n",
1384				__FILE__, __LINE__, cid_addr, ctx_offset);
1385
1386	} else {
1387		REG_WR(sc, BCE_CTX_DATA_ADR, offset);
1388		REG_WR(sc, BCE_CTX_DATA, ctx_val);
1389	}
1390}
1391
1392
1393/****************************************************************************/
1394/* PHY register read.                                                       */
1395/*                                                                          */
1396/* Implements register reads on the MII bus.                                */
1397/*                                                                          */
1398/* Returns:                                                                 */
1399/*   The value of the register.                                             */
1400/****************************************************************************/
1401static int
1402bce_miibus_read_reg(device_t dev, int phy, int reg)
1403{
1404	struct bce_softc *sc;
1405	u32 val;
1406	int i;
1407
1408	sc = device_get_softc(dev);
1409
1410	/* Make sure we are accessing the correct PHY address. */
1411	if (phy != sc->bce_phy_addr) {
1412		DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d for PHY read!\n", phy);
1413		return(0);
1414	}
1415
1416	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1417		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1418		val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1419
1420		REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1421		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1422
1423		DELAY(40);
1424	}
1425
1426
1427	val = BCE_MIPHY(phy) | BCE_MIREG(reg) |
1428		BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT |
1429		BCE_EMAC_MDIO_COMM_START_BUSY;
1430	REG_WR(sc, BCE_EMAC_MDIO_COMM, val);
1431
1432	for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1433		DELAY(10);
1434
1435		val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1436		if (!(val & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1437			DELAY(5);
1438
1439			val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1440			val &= BCE_EMAC_MDIO_COMM_DATA;
1441
1442			break;
1443		}
1444	}
1445
1446	if (val & BCE_EMAC_MDIO_COMM_START_BUSY) {
1447		BCE_PRINTF("%s(%d): Error: PHY read timeout! phy = %d, reg = 0x%04X\n",
1448			__FILE__, __LINE__, phy, reg);
1449		val = 0x0;
1450	} else {
1451		val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1452	}
1453
1454
1455	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1456		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1457		val |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1458
1459		REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1460		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1461
1462		DELAY(40);
1463	}
1464
1465	DB_PRINT_PHY_REG(reg, val);
1466	return (val & 0xffff);
1467
1468}
1469
1470
1471/****************************************************************************/
1472/* PHY register write.                                                      */
1473/*                                                                          */
1474/* Implements register writes on the MII bus.                               */
1475/*                                                                          */
1476/* Returns:                                                                 */
1477/*   The value of the register.                                             */
1478/****************************************************************************/
1479static int
1480bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
1481{
1482	struct bce_softc *sc;
1483	u32 val1;
1484	int i;
1485
1486	sc = device_get_softc(dev);
1487
1488	/* Make sure we are accessing the correct PHY address. */
1489	if (phy != sc->bce_phy_addr) {
1490		DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d for PHY write!\n", phy);
1491		return(0);
1492	}
1493
1494	DB_PRINT_PHY_REG(reg, val);
1495
1496	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1497		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1498		val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1499
1500		REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1501		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1502
1503		DELAY(40);
1504	}
1505
1506	val1 = BCE_MIPHY(phy) | BCE_MIREG(reg) | val |
1507		BCE_EMAC_MDIO_COMM_COMMAND_WRITE |
1508		BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT;
1509	REG_WR(sc, BCE_EMAC_MDIO_COMM, val1);
1510
1511	for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1512		DELAY(10);
1513
1514		val1 = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1515		if (!(val1 & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1516			DELAY(5);
1517			break;
1518		}
1519	}
1520
1521	if (val1 & BCE_EMAC_MDIO_COMM_START_BUSY)
1522		BCE_PRINTF("%s(%d): PHY write timeout!\n",
1523			__FILE__, __LINE__);
1524
1525	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1526		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1527		val1 |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1528
1529		REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1530		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1531
1532		DELAY(40);
1533	}
1534
1535	return 0;
1536}
1537
1538
1539/****************************************************************************/
1540/* MII bus status change.                                                   */
1541/*                                                                          */
1542/* Called by the MII bus driver when the PHY establishes link to set the    */
1543/* MAC interface registers.                                                 */
1544/*                                                                          */
1545/* Returns:                                                                 */
1546/*   Nothing.                                                               */
1547/****************************************************************************/
1548static void
1549bce_miibus_statchg(device_t dev)
1550{
1551	struct bce_softc *sc;
1552	struct mii_data *mii;
1553	int val;
1554
1555	sc = device_get_softc(dev);
1556
1557	DBENTER(BCE_VERBOSE_PHY);
1558
1559	mii = device_get_softc(sc->bce_miibus);
1560
1561	val = REG_RD(sc, BCE_EMAC_MODE);
1562	val &= ~(BCE_EMAC_MODE_PORT | BCE_EMAC_MODE_HALF_DUPLEX |
1563		BCE_EMAC_MODE_MAC_LOOP | BCE_EMAC_MODE_FORCE_LINK |
1564		BCE_EMAC_MODE_25G);
1565
1566	/* Set MII or GMII interface based on the speed negotiated by the PHY. */
1567	switch (IFM_SUBTYPE(mii->mii_media_active)) {
1568	case IFM_10_T:
1569		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
1570			DBPRINT(sc, BCE_INFO, "Enabling 10Mb interface.\n");
1571			val |= BCE_EMAC_MODE_PORT_MII_10;
1572			break;
1573		}
1574		/* fall-through */
1575	case IFM_100_TX:
1576		DBPRINT(sc, BCE_INFO, "Enabling MII interface.\n");
1577		val |= BCE_EMAC_MODE_PORT_MII;
1578		break;
1579	case IFM_2500_SX:
1580		DBPRINT(sc, BCE_INFO, "Enabling 2.5G MAC mode.\n");
1581		val |= BCE_EMAC_MODE_25G;
1582		/* fall-through */
1583	case IFM_1000_T:
1584	case IFM_1000_SX:
1585		DBPRINT(sc, BCE_INFO, "Enabling GMII interface.\n");
1586		val |= BCE_EMAC_MODE_PORT_GMII;
1587		break;
1588	default:
1589		DBPRINT(sc, BCE_INFO, "Unknown speed, enabling default GMII "
1590			"interface.\n");
1591		val |= BCE_EMAC_MODE_PORT_GMII;
1592	}
1593
1594	/* Set half or full duplex based on the duplicity negotiated by the PHY. */
1595	if ((mii->mii_media_active & IFM_GMASK) == IFM_HDX) {
1596		DBPRINT(sc, BCE_INFO, "Setting Half-Duplex interface.\n");
1597		val |= BCE_EMAC_MODE_HALF_DUPLEX;
1598	} else
1599		DBPRINT(sc, BCE_INFO, "Setting Full-Duplex interface.\n");
1600
1601	REG_WR(sc, BCE_EMAC_MODE, val);
1602
1603#if 0
1604	/* ToDo: Enable flow control support in brgphy and bge. */
1605	/* FLAG0 is set if RX is enabled and FLAG1 if TX is enabled */
1606	if (mii->mii_media_active & IFM_FLAG0)
1607		BCE_SETBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
1608	if (mii->mii_media_active & IFM_FLAG1)
1609		BCE_SETBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_TX_MODE_FLOW_EN);
1610#endif
1611
1612	DBEXIT(BCE_VERBOSE_PHY);
1613}
1614
1615
1616/****************************************************************************/
1617/* Acquire NVRAM lock.                                                      */
1618/*                                                                          */
1619/* Before the NVRAM can be accessed the caller must acquire an NVRAM lock.  */
1620/* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1621/* for use by the driver.                                                   */
1622/*                                                                          */
1623/* Returns:                                                                 */
1624/*   0 on success, positive value on failure.                               */
1625/****************************************************************************/
1626static int
1627bce_acquire_nvram_lock(struct bce_softc *sc)
1628{
1629	u32 val;
1630	int j, rc = 0;
1631
1632	DBENTER(BCE_VERBOSE_NVRAM);
1633
1634	/* Request access to the flash interface. */
1635	REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_SET2);
1636	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1637		val = REG_RD(sc, BCE_NVM_SW_ARB);
1638		if (val & BCE_NVM_SW_ARB_ARB_ARB2)
1639			break;
1640
1641		DELAY(5);
1642	}
1643
1644	if (j >= NVRAM_TIMEOUT_COUNT) {
1645		DBPRINT(sc, BCE_WARN, "Timeout acquiring NVRAM lock!\n");
1646		rc = EBUSY;
1647	}
1648
1649	DBEXIT(BCE_VERBOSE_NVRAM);
1650	return (rc);
1651}
1652
1653
1654/****************************************************************************/
1655/* Release NVRAM lock.                                                      */
1656/*                                                                          */
1657/* When the caller is finished accessing NVRAM the lock must be released.   */
1658/* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1659/* for use by the driver.                                                   */
1660/*                                                                          */
1661/* Returns:                                                                 */
1662/*   0 on success, positive value on failure.                               */
1663/****************************************************************************/
1664static int
1665bce_release_nvram_lock(struct bce_softc *sc)
1666{
1667	u32 val;
1668	int j, rc = 0;
1669
1670	DBENTER(BCE_VERBOSE_NVRAM);
1671
1672	/*
1673	 * Relinquish nvram interface.
1674	 */
1675	REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_CLR2);
1676
1677	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1678		val = REG_RD(sc, BCE_NVM_SW_ARB);
1679		if (!(val & BCE_NVM_SW_ARB_ARB_ARB2))
1680			break;
1681
1682		DELAY(5);
1683	}
1684
1685	if (j >= NVRAM_TIMEOUT_COUNT) {
1686		DBPRINT(sc, BCE_WARN, "Timeout releasing NVRAM lock!\n");
1687		rc = EBUSY;
1688	}
1689
1690	DBEXIT(BCE_VERBOSE_NVRAM);
1691	return (rc);
1692}
1693
1694
1695#ifdef BCE_NVRAM_WRITE_SUPPORT
1696/****************************************************************************/
1697/* Enable NVRAM write access.                                               */
1698/*                                                                          */
1699/* Before writing to NVRAM the caller must enable NVRAM writes.             */
1700/*                                                                          */
1701/* Returns:                                                                 */
1702/*   0 on success, positive value on failure.                               */
1703/****************************************************************************/
1704static int
1705bce_enable_nvram_write(struct bce_softc *sc)
1706{
1707	u32 val;
1708	int rc = 0;
1709
1710	DBENTER(BCE_VERBOSE_NVRAM);
1711
1712	val = REG_RD(sc, BCE_MISC_CFG);
1713	REG_WR(sc, BCE_MISC_CFG, val | BCE_MISC_CFG_NVM_WR_EN_PCI);
1714
1715	if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
1716		int j;
1717
1718		REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1719		REG_WR(sc, BCE_NVM_COMMAND,	BCE_NVM_COMMAND_WREN | BCE_NVM_COMMAND_DOIT);
1720
1721		for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1722			DELAY(5);
1723
1724			val = REG_RD(sc, BCE_NVM_COMMAND);
1725			if (val & BCE_NVM_COMMAND_DONE)
1726				break;
1727		}
1728
1729		if (j >= NVRAM_TIMEOUT_COUNT) {
1730			DBPRINT(sc, BCE_WARN, "Timeout writing NVRAM!\n");
1731			rc = EBUSY;
1732		}
1733	}
1734
1735	DBENTER(BCE_VERBOSE_NVRAM);
1736	return (rc);
1737}
1738
1739
1740/****************************************************************************/
1741/* Disable NVRAM write access.                                              */
1742/*                                                                          */
1743/* When the caller is finished writing to NVRAM write access must be        */
1744/* disabled.                                                                */
1745/*                                                                          */
1746/* Returns:                                                                 */
1747/*   Nothing.                                                               */
1748/****************************************************************************/
1749static void
1750bce_disable_nvram_write(struct bce_softc *sc)
1751{
1752	u32 val;
1753
1754	DBENTER(BCE_VERBOSE_NVRAM);
1755
1756	val = REG_RD(sc, BCE_MISC_CFG);
1757	REG_WR(sc, BCE_MISC_CFG, val & ~BCE_MISC_CFG_NVM_WR_EN);
1758
1759	DBEXIT(BCE_VERBOSE_NVRAM);
1760
1761}
1762#endif
1763
1764
1765/****************************************************************************/
1766/* Enable NVRAM access.                                                     */
1767/*                                                                          */
1768/* Before accessing NVRAM for read or write operations the caller must      */
1769/* enabled NVRAM access.                                                    */
1770/*                                                                          */
1771/* Returns:                                                                 */
1772/*   Nothing.                                                               */
1773/****************************************************************************/
1774static void
1775bce_enable_nvram_access(struct bce_softc *sc)
1776{
1777	u32 val;
1778
1779	DBENTER(BCE_VERBOSE_NVRAM);
1780
1781	val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
1782	/* Enable both bits, even on read. */
1783	REG_WR(sc, BCE_NVM_ACCESS_ENABLE,
1784	       val | BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN);
1785
1786	DBEXIT(BCE_VERBOSE_NVRAM);
1787}
1788
1789
1790/****************************************************************************/
1791/* Disable NVRAM access.                                                    */
1792/*                                                                          */
1793/* When the caller is finished accessing NVRAM access must be disabled.     */
1794/*                                                                          */
1795/* Returns:                                                                 */
1796/*   Nothing.                                                               */
1797/****************************************************************************/
1798static void
1799bce_disable_nvram_access(struct bce_softc *sc)
1800{
1801	u32 val;
1802
1803	DBENTER(BCE_VERBOSE_NVRAM);
1804
1805	val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
1806
1807	/* Disable both bits, even after read. */
1808	REG_WR(sc, BCE_NVM_ACCESS_ENABLE,
1809		val & ~(BCE_NVM_ACCESS_ENABLE_EN |
1810			BCE_NVM_ACCESS_ENABLE_WR_EN));
1811
1812	DBEXIT(BCE_VERBOSE_NVRAM);
1813}
1814
1815
1816#ifdef BCE_NVRAM_WRITE_SUPPORT
1817/****************************************************************************/
1818/* Erase NVRAM page before writing.                                         */
1819/*                                                                          */
1820/* Non-buffered flash parts require that a page be erased before it is      */
1821/* written.                                                                 */
1822/*                                                                          */
1823/* Returns:                                                                 */
1824/*   0 on success, positive value on failure.                               */
1825/****************************************************************************/
1826static int
1827bce_nvram_erase_page(struct bce_softc *sc, u32 offset)
1828{
1829	u32 cmd;
1830	int j, rc = 0;
1831
1832	DBENTER(BCE_VERBOSE_NVRAM);
1833
1834	/* Buffered flash doesn't require an erase. */
1835	if (sc->bce_flash_info->flags & BCE_NV_BUFFERED)
1836		goto bce_nvram_erase_page_exit;
1837
1838	/* Build an erase command. */
1839	cmd = BCE_NVM_COMMAND_ERASE | BCE_NVM_COMMAND_WR |
1840	      BCE_NVM_COMMAND_DOIT;
1841
1842	/*
1843	 * Clear the DONE bit separately, set the NVRAM adress to erase,
1844	 * and issue the erase command.
1845	 */
1846	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1847	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1848	REG_WR(sc, BCE_NVM_COMMAND, cmd);
1849
1850	/* Wait for completion. */
1851	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1852		u32 val;
1853
1854		DELAY(5);
1855
1856		val = REG_RD(sc, BCE_NVM_COMMAND);
1857		if (val & BCE_NVM_COMMAND_DONE)
1858			break;
1859	}
1860
1861	if (j >= NVRAM_TIMEOUT_COUNT) {
1862		DBPRINT(sc, BCE_WARN, "Timeout erasing NVRAM.\n");
1863		rc = EBUSY;
1864	}
1865
1866bce_nvram_erase_page_exit:
1867	DBEXIT(BCE_VERBOSE_NVRAM);
1868	return (rc);
1869}
1870#endif /* BCE_NVRAM_WRITE_SUPPORT */
1871
1872
1873/****************************************************************************/
1874/* Read a dword (32 bits) from NVRAM.                                       */
1875/*                                                                          */
1876/* Read a 32 bit word from NVRAM.  The caller is assumed to have already    */
1877/* obtained the NVRAM lock and enabled the controller for NVRAM access.     */
1878/*                                                                          */
1879/* Returns:                                                                 */
1880/*   0 on success and the 32 bit value read, positive value on failure.     */
1881/****************************************************************************/
1882static int
1883bce_nvram_read_dword(struct bce_softc *sc, u32 offset, u8 *ret_val,
1884							u32 cmd_flags)
1885{
1886	u32 cmd;
1887	int i, rc = 0;
1888
1889	DBENTER(BCE_EXTREME_NVRAM);
1890
1891	/* Build the command word. */
1892	cmd = BCE_NVM_COMMAND_DOIT | cmd_flags;
1893
1894	/* Calculate the offset for buffered flash if translation is used. */
1895	if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
1896		offset = ((offset / sc->bce_flash_info->page_size) <<
1897			   sc->bce_flash_info->page_bits) +
1898			  (offset % sc->bce_flash_info->page_size);
1899	}
1900
1901	/*
1902	 * Clear the DONE bit separately, set the address to read,
1903	 * and issue the read.
1904	 */
1905	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1906	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1907	REG_WR(sc, BCE_NVM_COMMAND, cmd);
1908
1909	/* Wait for completion. */
1910	for (i = 0; i < NVRAM_TIMEOUT_COUNT; i++) {
1911		u32 val;
1912
1913		DELAY(5);
1914
1915		val = REG_RD(sc, BCE_NVM_COMMAND);
1916		if (val & BCE_NVM_COMMAND_DONE) {
1917			val = REG_RD(sc, BCE_NVM_READ);
1918
1919			val = bce_be32toh(val);
1920			memcpy(ret_val, &val, 4);
1921			break;
1922		}
1923	}
1924
1925	/* Check for errors. */
1926	if (i >= NVRAM_TIMEOUT_COUNT) {
1927		BCE_PRINTF("%s(%d): Timeout error reading NVRAM at offset 0x%08X!\n",
1928			__FILE__, __LINE__, offset);
1929		rc = EBUSY;
1930	}
1931
1932	DBEXIT(BCE_EXTREME_NVRAM);
1933	return(rc);
1934}
1935
1936
1937#ifdef BCE_NVRAM_WRITE_SUPPORT
1938/****************************************************************************/
1939/* Write a dword (32 bits) to NVRAM.                                        */
1940/*                                                                          */
1941/* Write a 32 bit word to NVRAM.  The caller is assumed to have already     */
1942/* obtained the NVRAM lock, enabled the controller for NVRAM access, and    */
1943/* enabled NVRAM write access.                                              */
1944/*                                                                          */
1945/* Returns:                                                                 */
1946/*   0 on success, positive value on failure.                               */
1947/****************************************************************************/
1948static int
1949bce_nvram_write_dword(struct bce_softc *sc, u32 offset, u8 *val,
1950	u32 cmd_flags)
1951{
1952	u32 cmd, val32;
1953	int j, rc = 0;
1954
1955	DBENTER(BCE_VERBOSE_NVRAM);
1956
1957	/* Build the command word. */
1958	cmd = BCE_NVM_COMMAND_DOIT | BCE_NVM_COMMAND_WR | cmd_flags;
1959
1960	/* Calculate the offset for buffered flash if translation is used. */
1961	if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
1962		offset = ((offset / sc->bce_flash_info->page_size) <<
1963			  sc->bce_flash_info->page_bits) +
1964			 (offset % sc->bce_flash_info->page_size);
1965	}
1966
1967	/*
1968	 * Clear the DONE bit separately, convert NVRAM data to big-endian,
1969	 * set the NVRAM address to write, and issue the write command
1970	 */
1971	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1972	memcpy(&val32, val, 4);
1973	val32 = htobe32(val32);
1974	REG_WR(sc, BCE_NVM_WRITE, val32);
1975	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1976	REG_WR(sc, BCE_NVM_COMMAND, cmd);
1977
1978	/* Wait for completion. */
1979	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1980		DELAY(5);
1981
1982		if (REG_RD(sc, BCE_NVM_COMMAND) & BCE_NVM_COMMAND_DONE)
1983			break;
1984	}
1985	if (j >= NVRAM_TIMEOUT_COUNT) {
1986		BCE_PRINTF("%s(%d): Timeout error writing NVRAM at offset 0x%08X\n",
1987			__FILE__, __LINE__, offset);
1988		rc = EBUSY;
1989	}
1990
1991	DBEXIT(BCE_VERBOSE_NVRAM);
1992	return (rc);
1993}
1994#endif /* BCE_NVRAM_WRITE_SUPPORT */
1995
1996
1997/****************************************************************************/
1998/* Initialize NVRAM access.                                                 */
1999/*                                                                          */
2000/* Identify the NVRAM device in use and prepare the NVRAM interface to      */
2001/* access that device.                                                      */
2002/*                                                                          */
2003/* Returns:                                                                 */
2004/*   0 on success, positive value on failure.                               */
2005/****************************************************************************/
2006static int
2007bce_init_nvram(struct bce_softc *sc)
2008{
2009	u32 val;
2010	int j, entry_count, rc = 0;
2011	struct flash_spec *flash;
2012
2013	DBENTER(BCE_VERBOSE_NVRAM);
2014
2015	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
2016		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
2017		sc->bce_flash_info = &flash_5709;
2018		goto bce_init_nvram_get_flash_size;
2019	}
2020
2021	/* Determine the selected interface. */
2022	val = REG_RD(sc, BCE_NVM_CFG1);
2023
2024	entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
2025
2026	/*
2027	 * Flash reconfiguration is required to support additional
2028	 * NVRAM devices not directly supported in hardware.
2029	 * Check if the flash interface was reconfigured
2030	 * by the bootcode.
2031	 */
2032
2033	if (val & 0x40000000) {
2034		/* Flash interface reconfigured by bootcode. */
2035
2036		DBPRINT(sc,BCE_INFO_LOAD,
2037			"bce_init_nvram(): Flash WAS reconfigured.\n");
2038
2039		for (j = 0, flash = &flash_table[0]; j < entry_count;
2040		     j++, flash++) {
2041			if ((val & FLASH_BACKUP_STRAP_MASK) ==
2042			    (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
2043				sc->bce_flash_info = flash;
2044				break;
2045			}
2046		}
2047	} else {
2048		/* Flash interface not yet reconfigured. */
2049		u32 mask;
2050
2051		DBPRINT(sc, BCE_INFO_LOAD, "%s(): Flash was NOT reconfigured.\n",
2052			__FUNCTION__);
2053
2054		if (val & (1 << 23))
2055			mask = FLASH_BACKUP_STRAP_MASK;
2056		else
2057			mask = FLASH_STRAP_MASK;
2058
2059		/* Look for the matching NVRAM device configuration data. */
2060		for (j = 0, flash = &flash_table[0]; j < entry_count; j++, flash++) {
2061
2062			/* Check if the device matches any of the known devices. */
2063			if ((val & mask) == (flash->strapping & mask)) {
2064				/* Found a device match. */
2065				sc->bce_flash_info = flash;
2066
2067				/* Request access to the flash interface. */
2068				if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2069					return rc;
2070
2071				/* Reconfigure the flash interface. */
2072				bce_enable_nvram_access(sc);
2073				REG_WR(sc, BCE_NVM_CFG1, flash->config1);
2074				REG_WR(sc, BCE_NVM_CFG2, flash->config2);
2075				REG_WR(sc, BCE_NVM_CFG3, flash->config3);
2076				REG_WR(sc, BCE_NVM_WRITE1, flash->write1);
2077				bce_disable_nvram_access(sc);
2078				bce_release_nvram_lock(sc);
2079
2080				break;
2081			}
2082		}
2083	}
2084
2085	/* Check if a matching device was found. */
2086	if (j == entry_count) {
2087		sc->bce_flash_info = NULL;
2088		BCE_PRINTF("%s(%d): Unknown Flash NVRAM found!\n",
2089			__FILE__, __LINE__);
2090		rc = ENODEV;
2091	}
2092
2093bce_init_nvram_get_flash_size:
2094	/* Write the flash config data to the shared memory interface. */
2095	val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_SHARED_HW_CFG_CONFIG2);
2096	val &= BCE_SHARED_HW_CFG2_NVM_SIZE_MASK;
2097	if (val)
2098		sc->bce_flash_size = val;
2099	else
2100		sc->bce_flash_size = sc->bce_flash_info->total_size;
2101
2102	DBPRINT(sc, BCE_INFO_LOAD, "%s(): Found %s, size = 0x%08X\n",
2103		__FUNCTION__, sc->bce_flash_info->name,
2104		sc->bce_flash_info->total_size);
2105
2106	DBEXIT(BCE_VERBOSE_NVRAM);
2107	return rc;
2108}
2109
2110
2111/****************************************************************************/
2112/* Read an arbitrary range of data from NVRAM.                              */
2113/*                                                                          */
2114/* Prepares the NVRAM interface for access and reads the requested data     */
2115/* into the supplied buffer.                                                */
2116/*                                                                          */
2117/* Returns:                                                                 */
2118/*   0 on success and the data read, positive value on failure.             */
2119/****************************************************************************/
2120static int
2121bce_nvram_read(struct bce_softc *sc, u32 offset, u8 *ret_buf,
2122	int buf_size)
2123{
2124	int rc = 0;
2125	u32 cmd_flags, offset32, len32, extra;
2126
2127	DBENTER(BCE_VERBOSE_NVRAM);
2128
2129	if (buf_size == 0)
2130		goto bce_nvram_read_exit;
2131
2132	/* Request access to the flash interface. */
2133	if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2134		goto bce_nvram_read_exit;
2135
2136	/* Enable access to flash interface */
2137	bce_enable_nvram_access(sc);
2138
2139	len32 = buf_size;
2140	offset32 = offset;
2141	extra = 0;
2142
2143	cmd_flags = 0;
2144
2145	if (offset32 & 3) {
2146		u8 buf[4];
2147		u32 pre_len;
2148
2149		offset32 &= ~3;
2150		pre_len = 4 - (offset & 3);
2151
2152		if (pre_len >= len32) {
2153			pre_len = len32;
2154			cmd_flags = BCE_NVM_COMMAND_FIRST | BCE_NVM_COMMAND_LAST;
2155		}
2156		else {
2157			cmd_flags = BCE_NVM_COMMAND_FIRST;
2158		}
2159
2160		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2161
2162		if (rc)
2163			return rc;
2164
2165		memcpy(ret_buf, buf + (offset & 3), pre_len);
2166
2167		offset32 += 4;
2168		ret_buf += pre_len;
2169		len32 -= pre_len;
2170	}
2171
2172	if (len32 & 3) {
2173		extra = 4 - (len32 & 3);
2174		len32 = (len32 + 4) & ~3;
2175	}
2176
2177	if (len32 == 4) {
2178		u8 buf[4];
2179
2180		if (cmd_flags)
2181			cmd_flags = BCE_NVM_COMMAND_LAST;
2182		else
2183			cmd_flags = BCE_NVM_COMMAND_FIRST |
2184				    BCE_NVM_COMMAND_LAST;
2185
2186		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2187
2188		memcpy(ret_buf, buf, 4 - extra);
2189	}
2190	else if (len32 > 0) {
2191		u8 buf[4];
2192
2193		/* Read the first word. */
2194		if (cmd_flags)
2195			cmd_flags = 0;
2196		else
2197			cmd_flags = BCE_NVM_COMMAND_FIRST;
2198
2199		rc = bce_nvram_read_dword(sc, offset32, ret_buf, cmd_flags);
2200
2201		/* Advance to the next dword. */
2202		offset32 += 4;
2203		ret_buf += 4;
2204		len32 -= 4;
2205
2206		while (len32 > 4 && rc == 0) {
2207			rc = bce_nvram_read_dword(sc, offset32, ret_buf, 0);
2208
2209			/* Advance to the next dword. */
2210			offset32 += 4;
2211			ret_buf += 4;
2212			len32 -= 4;
2213		}
2214
2215		if (rc)
2216			goto bce_nvram_read_locked_exit;
2217
2218		cmd_flags = BCE_NVM_COMMAND_LAST;
2219		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2220
2221		memcpy(ret_buf, buf, 4 - extra);
2222	}
2223
2224bce_nvram_read_locked_exit:
2225	/* Disable access to flash interface and release the lock. */
2226	bce_disable_nvram_access(sc);
2227	bce_release_nvram_lock(sc);
2228
2229bce_nvram_read_exit:
2230	DBEXIT(BCE_VERBOSE_NVRAM);
2231	return rc;
2232}
2233
2234
2235#ifdef BCE_NVRAM_WRITE_SUPPORT
2236/****************************************************************************/
2237/* Write an arbitrary range of data from NVRAM.                             */
2238/*                                                                          */
2239/* Prepares the NVRAM interface for write access and writes the requested   */
2240/* data from the supplied buffer.  The caller is responsible for            */
2241/* calculating any appropriate CRCs.                                        */
2242/*                                                                          */
2243/* Returns:                                                                 */
2244/*   0 on success, positive value on failure.                               */
2245/****************************************************************************/
2246static int
2247bce_nvram_write(struct bce_softc *sc, u32 offset, u8 *data_buf,
2248	int buf_size)
2249{
2250	u32 written, offset32, len32;
2251	u8 *buf, start[4], end[4];
2252	int rc = 0;
2253	int align_start, align_end;
2254
2255	DBENTER(BCE_VERBOSE_NVRAM);
2256
2257	buf = data_buf;
2258	offset32 = offset;
2259	len32 = buf_size;
2260	align_start = align_end = 0;
2261
2262	if ((align_start = (offset32 & 3))) {
2263		offset32 &= ~3;
2264		len32 += align_start;
2265		if ((rc = bce_nvram_read(sc, offset32, start, 4)))
2266			goto bce_nvram_write_exit;
2267	}
2268
2269	if (len32 & 3) {
2270	       	if ((len32 > 4) || !align_start) {
2271			align_end = 4 - (len32 & 3);
2272			len32 += align_end;
2273			if ((rc = bce_nvram_read(sc, offset32 + len32 - 4,
2274				end, 4))) {
2275				goto bce_nvram_write_exit;
2276			}
2277		}
2278	}
2279
2280	if (align_start || align_end) {
2281		buf = malloc(len32, M_DEVBUF, M_NOWAIT);
2282		if (buf == 0) {
2283			rc = ENOMEM;
2284			goto bce_nvram_write_exit;
2285		}
2286
2287		if (align_start) {
2288			memcpy(buf, start, 4);
2289		}
2290
2291		if (align_end) {
2292			memcpy(buf + len32 - 4, end, 4);
2293		}
2294		memcpy(buf + align_start, data_buf, buf_size);
2295	}
2296
2297	written = 0;
2298	while ((written < len32) && (rc == 0)) {
2299		u32 page_start, page_end, data_start, data_end;
2300		u32 addr, cmd_flags;
2301		int i;
2302		u8 flash_buffer[264];
2303
2304	    /* Find the page_start addr */
2305		page_start = offset32 + written;
2306		page_start -= (page_start % sc->bce_flash_info->page_size);
2307		/* Find the page_end addr */
2308		page_end = page_start + sc->bce_flash_info->page_size;
2309		/* Find the data_start addr */
2310		data_start = (written == 0) ? offset32 : page_start;
2311		/* Find the data_end addr */
2312		data_end = (page_end > offset32 + len32) ?
2313			(offset32 + len32) : page_end;
2314
2315		/* Request access to the flash interface. */
2316		if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2317			goto bce_nvram_write_exit;
2318
2319		/* Enable access to flash interface */
2320		bce_enable_nvram_access(sc);
2321
2322		cmd_flags = BCE_NVM_COMMAND_FIRST;
2323		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2324			int j;
2325
2326			/* Read the whole page into the buffer
2327			 * (non-buffer flash only) */
2328			for (j = 0; j < sc->bce_flash_info->page_size; j += 4) {
2329				if (j == (sc->bce_flash_info->page_size - 4)) {
2330					cmd_flags |= BCE_NVM_COMMAND_LAST;
2331				}
2332				rc = bce_nvram_read_dword(sc,
2333					page_start + j,
2334					&flash_buffer[j],
2335					cmd_flags);
2336
2337				if (rc)
2338					goto bce_nvram_write_locked_exit;
2339
2340				cmd_flags = 0;
2341			}
2342		}
2343
2344		/* Enable writes to flash interface (unlock write-protect) */
2345		if ((rc = bce_enable_nvram_write(sc)) != 0)
2346			goto bce_nvram_write_locked_exit;
2347
2348		/* Erase the page */
2349		if ((rc = bce_nvram_erase_page(sc, page_start)) != 0)
2350			goto bce_nvram_write_locked_exit;
2351
2352		/* Re-enable the write again for the actual write */
2353		bce_enable_nvram_write(sc);
2354
2355		/* Loop to write back the buffer data from page_start to
2356		 * data_start */
2357		i = 0;
2358		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2359			for (addr = page_start; addr < data_start;
2360				addr += 4, i += 4) {
2361
2362				rc = bce_nvram_write_dword(sc, addr,
2363					&flash_buffer[i], cmd_flags);
2364
2365				if (rc != 0)
2366					goto bce_nvram_write_locked_exit;
2367
2368				cmd_flags = 0;
2369			}
2370		}
2371
2372		/* Loop to write the new data from data_start to data_end */
2373		for (addr = data_start; addr < data_end; addr += 4, i++) {
2374			if ((addr == page_end - 4) ||
2375				((sc->bce_flash_info->flags & BCE_NV_BUFFERED) &&
2376				(addr == data_end - 4))) {
2377
2378				cmd_flags |= BCE_NVM_COMMAND_LAST;
2379			}
2380			rc = bce_nvram_write_dword(sc, addr, buf,
2381				cmd_flags);
2382
2383			if (rc != 0)
2384				goto bce_nvram_write_locked_exit;
2385
2386			cmd_flags = 0;
2387			buf += 4;
2388		}
2389
2390		/* Loop to write back the buffer data from data_end
2391		 * to page_end */
2392		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2393			for (addr = data_end; addr < page_end;
2394				addr += 4, i += 4) {
2395
2396				if (addr == page_end-4) {
2397					cmd_flags = BCE_NVM_COMMAND_LAST;
2398                		}
2399				rc = bce_nvram_write_dword(sc, addr,
2400					&flash_buffer[i], cmd_flags);
2401
2402				if (rc != 0)
2403					goto bce_nvram_write_locked_exit;
2404
2405				cmd_flags = 0;
2406			}
2407		}
2408
2409		/* Disable writes to flash interface (lock write-protect) */
2410		bce_disable_nvram_write(sc);
2411
2412		/* Disable access to flash interface */
2413		bce_disable_nvram_access(sc);
2414		bce_release_nvram_lock(sc);
2415
2416		/* Increment written */
2417		written += data_end - data_start;
2418	}
2419
2420	goto bce_nvram_write_exit;
2421
2422bce_nvram_write_locked_exit:
2423		bce_disable_nvram_write(sc);
2424		bce_disable_nvram_access(sc);
2425		bce_release_nvram_lock(sc);
2426
2427bce_nvram_write_exit:
2428	if (align_start || align_end)
2429		free(buf, M_DEVBUF);
2430
2431	DBEXIT(BCE_VERBOSE_NVRAM);
2432	return (rc);
2433}
2434#endif /* BCE_NVRAM_WRITE_SUPPORT */
2435
2436
2437/****************************************************************************/
2438/* Verifies that NVRAM is accessible and contains valid data.               */
2439/*                                                                          */
2440/* Reads the configuration data from NVRAM and verifies that the CRC is     */
2441/* correct.                                                                 */
2442/*                                                                          */
2443/* Returns:                                                                 */
2444/*   0 on success, positive value on failure.                               */
2445/****************************************************************************/
2446static int
2447bce_nvram_test(struct bce_softc *sc)
2448{
2449	u32 buf[BCE_NVRAM_SIZE / 4];
2450	u8 *data = (u8 *) buf;
2451	int rc = 0;
2452	u32 magic, csum;
2453
2454	DBENTER(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
2455
2456	/*
2457	 * Check that the device NVRAM is valid by reading
2458	 * the magic value at offset 0.
2459	 */
2460	if ((rc = bce_nvram_read(sc, 0, data, 4)) != 0) {
2461		BCE_PRINTF("%s(%d): Unable to read NVRAM!\n", __FILE__, __LINE__);
2462		goto bce_nvram_test_exit;
2463	}
2464
2465	/*
2466	 * Verify that offset 0 of the NVRAM contains
2467	 * a valid magic number.
2468	 */
2469    magic = bce_be32toh(buf[0]);
2470	if (magic != BCE_NVRAM_MAGIC) {
2471		rc = ENODEV;
2472		BCE_PRINTF("%s(%d): Invalid NVRAM magic value! Expected: 0x%08X, "
2473			"Found: 0x%08X\n",
2474			__FILE__, __LINE__, BCE_NVRAM_MAGIC, magic);
2475		goto bce_nvram_test_exit;
2476	}
2477
2478	/*
2479	 * Verify that the device NVRAM includes valid
2480	 * configuration data.
2481	 */
2482	if ((rc = bce_nvram_read(sc, 0x100, data, BCE_NVRAM_SIZE)) != 0) {
2483		BCE_PRINTF("%s(%d): Unable to read Manufacturing Information from "
2484			"NVRAM!\n", __FILE__, __LINE__);
2485		goto bce_nvram_test_exit;
2486	}
2487
2488	csum = ether_crc32_le(data, 0x100);
2489	if (csum != BCE_CRC32_RESIDUAL) {
2490		rc = ENODEV;
2491		BCE_PRINTF("%s(%d): Invalid Manufacturing Information NVRAM CRC! "
2492			"Expected: 0x%08X, Found: 0x%08X\n",
2493			__FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
2494		goto bce_nvram_test_exit;
2495	}
2496
2497	csum = ether_crc32_le(data + 0x100, 0x100);
2498	if (csum != BCE_CRC32_RESIDUAL) {
2499		rc = ENODEV;
2500		BCE_PRINTF("%s(%d): Invalid Feature Configuration Information "
2501			"NVRAM CRC! Expected: 0x%08X, Found: 08%08X\n",
2502			__FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
2503	}
2504
2505bce_nvram_test_exit:
2506	DBEXIT(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
2507	return rc;
2508}
2509
2510
2511/****************************************************************************/
2512/* Identifies the current media type of the controller and sets the PHY     */
2513/* address.                                                                 */
2514/*                                                                          */
2515/* Returns:                                                                 */
2516/*   Nothing.                                                               */
2517/****************************************************************************/
2518static void
2519bce_get_media(struct bce_softc *sc)
2520{
2521	u32 val;
2522
2523	DBENTER(BCE_VERBOSE);
2524
2525	/* Assume PHY address for copper controllers. */
2526	sc->bce_phy_addr = 1;
2527
2528	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
2529 		u32 val = REG_RD(sc, BCE_MISC_DUAL_MEDIA_CTRL);
2530		u32 bond_id = val & BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID;
2531		u32 strap;
2532
2533		/*
2534		 * The BCM5709S is software configurable
2535		 * for Copper or SerDes operation.
2536		 */
2537		if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_C) {
2538			DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded for copper.\n");
2539			goto bce_get_media_exit;
2540		} else if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_S) {
2541			DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded for dual media.\n");
2542			sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2543			goto bce_get_media_exit;
2544		}
2545
2546		if (val & BCE_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE)
2547			strap = (val & BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21;
2548		else
2549			strap = (val & BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8;
2550
2551		if (pci_get_function(sc->bce_dev) == 0) {
2552			switch (strap) {
2553			case 0x4:
2554			case 0x5:
2555			case 0x6:
2556				DBPRINT(sc, BCE_INFO_LOAD,
2557					"BCM5709 s/w configured for SerDes.\n");
2558				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2559			default:
2560				DBPRINT(sc, BCE_INFO_LOAD,
2561					"BCM5709 s/w configured for Copper.\n");
2562			}
2563		} else {
2564			switch (strap) {
2565			case 0x1:
2566			case 0x2:
2567			case 0x4:
2568				DBPRINT(sc, BCE_INFO_LOAD,
2569					"BCM5709 s/w configured for SerDes.\n");
2570				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2571			default:
2572				DBPRINT(sc, BCE_INFO_LOAD,
2573					"BCM5709 s/w configured for Copper.\n");
2574			}
2575		}
2576
2577	} else if (BCE_CHIP_BOND_ID(sc) & BCE_CHIP_BOND_ID_SERDES_BIT)
2578		sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2579
2580	if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) {
2581		sc->bce_flags |= BCE_NO_WOL_FLAG;
2582		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
2583			sc->bce_phy_addr = 2;
2584			val = REG_RD_IND(sc, sc->bce_shmem_base +
2585				 BCE_SHARED_HW_CFG_CONFIG);
2586			if (val & BCE_SHARED_HW_CFG_PHY_2_5G) {
2587				sc->bce_phy_flags |= BCE_PHY_2_5G_CAPABLE_FLAG;
2588				DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb capable adapter\n");
2589			}
2590		}
2591	} else if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) ||
2592		   (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708))
2593		sc->bce_phy_flags |= BCE_PHY_CRC_FIX_FLAG;
2594
2595bce_get_media_exit:
2596	DBPRINT(sc, (BCE_INFO_LOAD | BCE_INFO_PHY),
2597		"Using PHY address %d.\n", sc->bce_phy_addr);
2598
2599	DBEXIT(BCE_VERBOSE);
2600}
2601
2602
2603/****************************************************************************/
2604/* Free any DMA memory owned by the driver.                                 */
2605/*                                                                          */
2606/* Scans through each data structre that requires DMA memory and frees      */
2607/* the memory if allocated.                                                 */
2608/*                                                                          */
2609/* Returns:                                                                 */
2610/*   Nothing.                                                               */
2611/****************************************************************************/
2612static void
2613bce_dma_free(struct bce_softc *sc)
2614{
2615	int i;
2616
2617	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
2618
2619	/* Free, unmap, and destroy the status block. */
2620	if (sc->status_block != NULL) {
2621		bus_dmamem_free(
2622			sc->status_tag,
2623		    sc->status_block,
2624		    sc->status_map);
2625		sc->status_block = NULL;
2626	}
2627
2628	if (sc->status_map != NULL) {
2629		bus_dmamap_unload(
2630			sc->status_tag,
2631		    sc->status_map);
2632		bus_dmamap_destroy(sc->status_tag,
2633		    sc->status_map);
2634		sc->status_map = NULL;
2635	}
2636
2637	if (sc->status_tag != NULL) {
2638		bus_dma_tag_destroy(sc->status_tag);
2639		sc->status_tag = NULL;
2640	}
2641
2642
2643	/* Free, unmap, and destroy the statistics block. */
2644	if (sc->stats_block != NULL) {
2645		bus_dmamem_free(
2646			sc->stats_tag,
2647		    sc->stats_block,
2648		    sc->stats_map);
2649		sc->stats_block = NULL;
2650	}
2651
2652	if (sc->stats_map != NULL) {
2653		bus_dmamap_unload(
2654			sc->stats_tag,
2655		    sc->stats_map);
2656		bus_dmamap_destroy(sc->stats_tag,
2657		    sc->stats_map);
2658		sc->stats_map = NULL;
2659	}
2660
2661	if (sc->stats_tag != NULL) {
2662		bus_dma_tag_destroy(sc->stats_tag);
2663		sc->stats_tag = NULL;
2664	}
2665
2666
2667	/* Free, unmap and destroy all context memory pages. */
2668	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
2669		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
2670		for (i = 0; i < sc->ctx_pages; i++ ) {
2671			if (sc->ctx_block[i] != NULL) {
2672				bus_dmamem_free(
2673					sc->ctx_tag,
2674				    sc->ctx_block[i],
2675				    sc->ctx_map[i]);
2676				sc->ctx_block[i] = NULL;
2677			}
2678
2679			if (sc->ctx_map[i] != NULL) {
2680				bus_dmamap_unload(
2681					sc->ctx_tag,
2682		    		sc->ctx_map[i]);
2683				bus_dmamap_destroy(
2684					sc->ctx_tag,
2685				    sc->ctx_map[i]);
2686				sc->ctx_map[i] = NULL;
2687			}
2688		}
2689
2690		/* Destroy the context memory tag. */
2691		if (sc->ctx_tag != NULL) {
2692			bus_dma_tag_destroy(sc->ctx_tag);
2693			sc->ctx_tag = NULL;
2694		}
2695	}
2696
2697
2698	/* Free, unmap and destroy all TX buffer descriptor chain pages. */
2699	for (i = 0; i < TX_PAGES; i++ ) {
2700		if (sc->tx_bd_chain[i] != NULL) {
2701			bus_dmamem_free(
2702				sc->tx_bd_chain_tag,
2703			    sc->tx_bd_chain[i],
2704			    sc->tx_bd_chain_map[i]);
2705			sc->tx_bd_chain[i] = NULL;
2706		}
2707
2708		if (sc->tx_bd_chain_map[i] != NULL) {
2709			bus_dmamap_unload(
2710				sc->tx_bd_chain_tag,
2711		    	sc->tx_bd_chain_map[i]);
2712			bus_dmamap_destroy(
2713				sc->tx_bd_chain_tag,
2714			    sc->tx_bd_chain_map[i]);
2715			sc->tx_bd_chain_map[i] = NULL;
2716		}
2717	}
2718
2719	/* Destroy the TX buffer descriptor tag. */
2720	if (sc->tx_bd_chain_tag != NULL) {
2721		bus_dma_tag_destroy(sc->tx_bd_chain_tag);
2722		sc->tx_bd_chain_tag = NULL;
2723	}
2724
2725
2726	/* Free, unmap and destroy all RX buffer descriptor chain pages. */
2727	for (i = 0; i < RX_PAGES; i++ ) {
2728		if (sc->rx_bd_chain[i] != NULL) {
2729			bus_dmamem_free(
2730				sc->rx_bd_chain_tag,
2731			    sc->rx_bd_chain[i],
2732			    sc->rx_bd_chain_map[i]);
2733			sc->rx_bd_chain[i] = NULL;
2734		}
2735
2736		if (sc->rx_bd_chain_map[i] != NULL) {
2737			bus_dmamap_unload(
2738				sc->rx_bd_chain_tag,
2739		    	sc->rx_bd_chain_map[i]);
2740			bus_dmamap_destroy(
2741				sc->rx_bd_chain_tag,
2742			    sc->rx_bd_chain_map[i]);
2743			sc->rx_bd_chain_map[i] = NULL;
2744		}
2745	}
2746
2747	/* Destroy the RX buffer descriptor tag. */
2748	if (sc->rx_bd_chain_tag != NULL) {
2749		bus_dma_tag_destroy(sc->rx_bd_chain_tag);
2750		sc->rx_bd_chain_tag = NULL;
2751	}
2752
2753
2754#ifdef BCE_USE_SPLIT_HEADER
2755	/* Free, unmap and destroy all page buffer descriptor chain pages. */
2756	for (i = 0; i < PG_PAGES; i++ ) {
2757		if (sc->pg_bd_chain[i] != NULL) {
2758			bus_dmamem_free(
2759				sc->pg_bd_chain_tag,
2760			    sc->pg_bd_chain[i],
2761			    sc->pg_bd_chain_map[i]);
2762			sc->pg_bd_chain[i] = NULL;
2763		}
2764
2765		if (sc->pg_bd_chain_map[i] != NULL) {
2766			bus_dmamap_unload(
2767				sc->pg_bd_chain_tag,
2768		    	sc->pg_bd_chain_map[i]);
2769			bus_dmamap_destroy(
2770				sc->pg_bd_chain_tag,
2771			    sc->pg_bd_chain_map[i]);
2772			sc->pg_bd_chain_map[i] = NULL;
2773		}
2774	}
2775
2776	/* Destroy the page buffer descriptor tag. */
2777	if (sc->pg_bd_chain_tag != NULL) {
2778		bus_dma_tag_destroy(sc->pg_bd_chain_tag);
2779		sc->pg_bd_chain_tag = NULL;
2780	}
2781#endif
2782
2783
2784	/* Unload and destroy the TX mbuf maps. */
2785	for (i = 0; i < TOTAL_TX_BD; i++) {
2786		if (sc->tx_mbuf_map[i] != NULL) {
2787			bus_dmamap_unload(sc->tx_mbuf_tag,
2788				sc->tx_mbuf_map[i]);
2789			bus_dmamap_destroy(sc->tx_mbuf_tag,
2790	 			sc->tx_mbuf_map[i]);
2791			sc->tx_mbuf_map[i] = NULL;
2792		}
2793	}
2794
2795	/* Destroy the TX mbuf tag. */
2796	if (sc->tx_mbuf_tag != NULL) {
2797		bus_dma_tag_destroy(sc->tx_mbuf_tag);
2798		sc->tx_mbuf_tag = NULL;
2799	}
2800
2801	/* Unload and destroy the RX mbuf maps. */
2802	for (i = 0; i < TOTAL_RX_BD; i++) {
2803		if (sc->rx_mbuf_map[i] != NULL) {
2804			bus_dmamap_unload(sc->rx_mbuf_tag,
2805				sc->rx_mbuf_map[i]);
2806			bus_dmamap_destroy(sc->rx_mbuf_tag,
2807	 			sc->rx_mbuf_map[i]);
2808			sc->rx_mbuf_map[i] = NULL;
2809		}
2810	}
2811
2812	/* Destroy the RX mbuf tag. */
2813	if (sc->rx_mbuf_tag != NULL) {
2814		bus_dma_tag_destroy(sc->rx_mbuf_tag);
2815		sc->rx_mbuf_tag = NULL;
2816	}
2817
2818#ifdef BCE_USE_SPLIT_HEADER
2819	/* Unload and destroy the page mbuf maps. */
2820	for (i = 0; i < TOTAL_PG_BD; i++) {
2821		if (sc->pg_mbuf_map[i] != NULL) {
2822			bus_dmamap_unload(sc->pg_mbuf_tag,
2823				sc->pg_mbuf_map[i]);
2824			bus_dmamap_destroy(sc->pg_mbuf_tag,
2825	 			sc->pg_mbuf_map[i]);
2826			sc->pg_mbuf_map[i] = NULL;
2827		}
2828	}
2829
2830	/* Destroy the page mbuf tag. */
2831	if (sc->pg_mbuf_tag != NULL) {
2832		bus_dma_tag_destroy(sc->pg_mbuf_tag);
2833		sc->pg_mbuf_tag = NULL;
2834	}
2835#endif
2836
2837	/* Destroy the parent tag */
2838	if (sc->parent_tag != NULL) {
2839		bus_dma_tag_destroy(sc->parent_tag);
2840		sc->parent_tag = NULL;
2841	}
2842
2843	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
2844}
2845
2846
2847/****************************************************************************/
2848/* Get DMA memory from the OS.                                              */
2849/*                                                                          */
2850/* Validates that the OS has provided DMA buffers in response to a          */
2851/* bus_dmamap_load() call and saves the physical address of those buffers.  */
2852/* When the callback is used the OS will return 0 for the mapping function  */
2853/* (bus_dmamap_load()) so we use the value of map_arg->maxsegs to pass any  */
2854/* failures back to the caller.                                             */
2855/*                                                                          */
2856/* Returns:                                                                 */
2857/*   Nothing.                                                               */
2858/****************************************************************************/
2859static void
2860bce_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
2861{
2862	bus_addr_t *busaddr = arg;
2863
2864	/* Simulate a mapping failure. */
2865	DBRUNIF(DB_RANDOMTRUE(bce_debug_dma_map_addr_failure),
2866		printf("bce: %s(%d): Simulating DMA mapping error.\n",
2867			__FILE__, __LINE__);
2868		error = ENOMEM);
2869
2870	/* Check for an error and signal the caller that an error occurred. */
2871	if (error) {
2872		printf("bce %s(%d): DMA mapping error! error = %d, "
2873		    "nseg = %d\n", __FILE__, __LINE__, error, nseg);
2874		*busaddr = 0;
2875		return;
2876	}
2877
2878	*busaddr = segs->ds_addr;
2879	return;
2880}
2881
2882
2883/****************************************************************************/
2884/* Allocate any DMA memory needed by the driver.                            */
2885/*                                                                          */
2886/* Allocates DMA memory needed for the various global structures needed by  */
2887/* hardware.                                                                */
2888/*                                                                          */
2889/* Memory alignment requirements:                                           */
2890/* +-----------------+----------+----------+----------+----------+          */
2891/* |                 |   5706   |   5708   |   5709   |   5716   |          */
2892/* +-----------------+----------+----------+----------+----------+          */
2893/* |Status Block     | 8 bytes  | 8 bytes  | 16 bytes | 16 bytes |          */
2894/* |Statistics Block | 8 bytes  | 8 bytes  | 16 bytes | 16 bytes |          */
2895/* |RX Buffers       | 16 bytes | 16 bytes | 16 bytes | 16 bytes |          */
2896/* |PG Buffers       |   none   |   none   |   none   |   none   |          */
2897/* |TX Buffers       |   none   |   none   |   none   |   none   |          */
2898/* |Chain Pages(1)   |   4KiB   |   4KiB   |   4KiB   |   4KiB   |          */
2899/* +-----------------+----------+----------+----------+----------+          */
2900/*                                                                          */
2901/* (1) Must align with CPU page size (BCM_PAGE_SZIE).                       */
2902/*                                                                          */
2903/* Returns:                                                                 */
2904/*   0 for success, positive value for failure.                             */
2905/****************************************************************************/
2906static int
2907bce_dma_alloc(device_t dev)
2908{
2909	struct bce_softc *sc;
2910	int i, error, rc = 0;
2911	bus_addr_t busaddr;
2912	bus_size_t max_size, max_seg_size;
2913	int max_segments;
2914
2915	sc = device_get_softc(dev);
2916
2917	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
2918
2919	/*
2920	 * Allocate the parent bus DMA tag appropriate for PCI.
2921	 */
2922	if (bus_dma_tag_create(NULL,
2923			1,
2924			BCE_DMA_BOUNDARY,
2925			sc->max_bus_addr,
2926			BUS_SPACE_MAXADDR,
2927			NULL, NULL,
2928			MAXBSIZE,
2929			BUS_SPACE_UNRESTRICTED,
2930			BUS_SPACE_MAXSIZE_32BIT,
2931			0,
2932			NULL, NULL,
2933			&sc->parent_tag)) {
2934		BCE_PRINTF("%s(%d): Could not allocate parent DMA tag!\n",
2935			__FILE__, __LINE__);
2936		rc = ENOMEM;
2937		goto bce_dma_alloc_exit;
2938	}
2939
2940	/*
2941	 * Create a DMA tag for the status block, allocate and clear the
2942	 * memory, map the memory into DMA space, and fetch the physical
2943	 * address of the block.
2944	 */
2945	if (bus_dma_tag_create(sc->parent_tag,
2946	    	BCE_DMA_ALIGN,
2947	    	BCE_DMA_BOUNDARY,
2948	    	sc->max_bus_addr,
2949	    	BUS_SPACE_MAXADDR,
2950	    	NULL, NULL,
2951	    	BCE_STATUS_BLK_SZ,
2952	    	1,
2953	    	BCE_STATUS_BLK_SZ,
2954	    	0,
2955	    	NULL, NULL,
2956	    	&sc->status_tag)) {
2957		BCE_PRINTF("%s(%d): Could not allocate status block DMA tag!\n",
2958			__FILE__, __LINE__);
2959		rc = ENOMEM;
2960		goto bce_dma_alloc_exit;
2961	}
2962
2963	if(bus_dmamem_alloc(sc->status_tag,
2964	    	(void **)&sc->status_block,
2965	    	BUS_DMA_NOWAIT,
2966	    	&sc->status_map)) {
2967		BCE_PRINTF("%s(%d): Could not allocate status block DMA memory!\n",
2968			__FILE__, __LINE__);
2969		rc = ENOMEM;
2970		goto bce_dma_alloc_exit;
2971	}
2972
2973	bzero((char *)sc->status_block, BCE_STATUS_BLK_SZ);
2974
2975	error = bus_dmamap_load(sc->status_tag,
2976	    	sc->status_map,
2977	    	sc->status_block,
2978	    	BCE_STATUS_BLK_SZ,
2979	    	bce_dma_map_addr,
2980	    	&busaddr,
2981	    	BUS_DMA_NOWAIT);
2982
2983	if (error) {
2984		BCE_PRINTF("%s(%d): Could not map status block DMA memory!\n",
2985			__FILE__, __LINE__);
2986		rc = ENOMEM;
2987		goto bce_dma_alloc_exit;
2988	}
2989
2990	sc->status_block_paddr = busaddr;
2991	DBPRINT(sc, BCE_INFO, "%s(): status_block_paddr = 0x%jX\n",
2992		__FUNCTION__, (uintmax_t) sc->status_block_paddr);
2993
2994	/*
2995	 * Create a DMA tag for the statistics block, allocate and clear the
2996	 * memory, map the memory into DMA space, and fetch the physical
2997	 * address of the block.
2998	 */
2999	if (bus_dma_tag_create(sc->parent_tag,
3000	    	BCE_DMA_ALIGN,
3001	    	BCE_DMA_BOUNDARY,
3002	    	sc->max_bus_addr,
3003	    	BUS_SPACE_MAXADDR,
3004	    	NULL, NULL,
3005	    	BCE_STATS_BLK_SZ,
3006	    	1,
3007	    	BCE_STATS_BLK_SZ,
3008	    	0,
3009	    	NULL, NULL,
3010	    	&sc->stats_tag)) {
3011		BCE_PRINTF("%s(%d): Could not allocate statistics block DMA tag!\n",
3012			__FILE__, __LINE__);
3013		rc = ENOMEM;
3014		goto bce_dma_alloc_exit;
3015	}
3016
3017	if (bus_dmamem_alloc(sc->stats_tag,
3018	    	(void **)&sc->stats_block,
3019	    	BUS_DMA_NOWAIT,
3020	    	&sc->stats_map)) {
3021		BCE_PRINTF("%s(%d): Could not allocate statistics block DMA memory!\n",
3022			__FILE__, __LINE__);
3023		rc = ENOMEM;
3024		goto bce_dma_alloc_exit;
3025	}
3026
3027	bzero((char *)sc->stats_block, BCE_STATS_BLK_SZ);
3028
3029	error = bus_dmamap_load(sc->stats_tag,
3030	    	sc->stats_map,
3031	    	sc->stats_block,
3032	    	BCE_STATS_BLK_SZ,
3033	    	bce_dma_map_addr,
3034	    	&busaddr,
3035	    	BUS_DMA_NOWAIT);
3036
3037	if(error) {
3038		BCE_PRINTF("%s(%d): Could not map statistics block DMA memory!\n",
3039			__FILE__, __LINE__);
3040		rc = ENOMEM;
3041		goto bce_dma_alloc_exit;
3042	}
3043
3044	sc->stats_block_paddr = busaddr;
3045	DBPRINT(sc, BCE_INFO, "%s(): stats_block_paddr = 0x%jX\n",
3046		__FUNCTION__, (uintmax_t) sc->stats_block_paddr);
3047
3048	/* BCM5709 uses host memory as cache for context memory. */
3049	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3050		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3051		sc->ctx_pages = 0x2000 / BCM_PAGE_SIZE;
3052		if (sc->ctx_pages == 0)
3053			sc->ctx_pages = 1;
3054
3055		DBRUNIF((sc->ctx_pages > 512),
3056			BCE_PRINTF("%s(%d): Too many CTX pages! %d > 512\n",
3057				__FILE__, __LINE__, sc->ctx_pages));
3058
3059		/*
3060		 * Create a DMA tag for the context pages,
3061		 * allocate and clear the memory, map the
3062		 * memory into DMA space, and fetch the
3063		 * physical address of the block.
3064		 */
3065		if(bus_dma_tag_create(sc->parent_tag,
3066			BCM_PAGE_SIZE,
3067		    BCE_DMA_BOUNDARY,
3068			sc->max_bus_addr,
3069			BUS_SPACE_MAXADDR,
3070			NULL, NULL,
3071			BCM_PAGE_SIZE,
3072			1,
3073			BCM_PAGE_SIZE,
3074			0,
3075			NULL, NULL,
3076			&sc->ctx_tag)) {
3077			BCE_PRINTF("%s(%d): Could not allocate CTX DMA tag!\n",
3078				__FILE__, __LINE__);
3079			rc = ENOMEM;
3080			goto bce_dma_alloc_exit;
3081		}
3082
3083		for (i = 0; i < sc->ctx_pages; i++) {
3084
3085			if(bus_dmamem_alloc(sc->ctx_tag,
3086		    		(void **)&sc->ctx_block[i],
3087	    		BUS_DMA_NOWAIT,
3088		    	&sc->ctx_map[i])) {
3089				BCE_PRINTF("%s(%d): Could not allocate CTX "
3090					"DMA memory!\n", __FILE__, __LINE__);
3091				rc = ENOMEM;
3092				goto bce_dma_alloc_exit;
3093			}
3094
3095			bzero((char *)sc->ctx_block[i], BCM_PAGE_SIZE);
3096
3097			error = bus_dmamap_load(sc->ctx_tag,
3098	    		sc->ctx_map[i],
3099	    		sc->ctx_block[i],
3100		    	BCM_PAGE_SIZE,
3101		    	bce_dma_map_addr,
3102	    		&busaddr,
3103	    		BUS_DMA_NOWAIT);
3104
3105			if (error) {
3106				BCE_PRINTF("%s(%d): Could not map CTX DMA memory!\n",
3107					__FILE__, __LINE__);
3108				rc = ENOMEM;
3109				goto bce_dma_alloc_exit;
3110			}
3111
3112			sc->ctx_paddr[i] = busaddr;
3113			DBPRINT(sc, BCE_INFO, "%s(): ctx_paddr[%d] = 0x%jX\n",
3114				__FUNCTION__, i, (uintmax_t) sc->ctx_paddr[i]);
3115		}
3116	}
3117
3118	/*
3119	 * Create a DMA tag for the TX buffer descriptor chain,
3120	 * allocate and clear the  memory, and fetch the
3121	 * physical address of the block.
3122	 */
3123	if(bus_dma_tag_create(sc->parent_tag,
3124			BCM_PAGE_SIZE,
3125		    BCE_DMA_BOUNDARY,
3126			sc->max_bus_addr,
3127			BUS_SPACE_MAXADDR,
3128			NULL, NULL,
3129			BCE_TX_CHAIN_PAGE_SZ,
3130			1,
3131			BCE_TX_CHAIN_PAGE_SZ,
3132			0,
3133			NULL, NULL,
3134			&sc->tx_bd_chain_tag)) {
3135		BCE_PRINTF("%s(%d): Could not allocate TX descriptor chain DMA tag!\n",
3136			__FILE__, __LINE__);
3137		rc = ENOMEM;
3138		goto bce_dma_alloc_exit;
3139	}
3140
3141	for (i = 0; i < TX_PAGES; i++) {
3142
3143		if(bus_dmamem_alloc(sc->tx_bd_chain_tag,
3144	    		(void **)&sc->tx_bd_chain[i],
3145	    		BUS_DMA_NOWAIT,
3146		    	&sc->tx_bd_chain_map[i])) {
3147			BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
3148				"chain DMA memory!\n", __FILE__, __LINE__);
3149			rc = ENOMEM;
3150			goto bce_dma_alloc_exit;
3151		}
3152
3153		error = bus_dmamap_load(sc->tx_bd_chain_tag,
3154	    		sc->tx_bd_chain_map[i],
3155	    		sc->tx_bd_chain[i],
3156		    	BCE_TX_CHAIN_PAGE_SZ,
3157		    	bce_dma_map_addr,
3158	    		&busaddr,
3159	    		BUS_DMA_NOWAIT);
3160
3161		if (error) {
3162			BCE_PRINTF("%s(%d): Could not map TX descriptor chain DMA memory!\n",
3163				__FILE__, __LINE__);
3164			rc = ENOMEM;
3165			goto bce_dma_alloc_exit;
3166		}
3167
3168		sc->tx_bd_chain_paddr[i] = busaddr;
3169		DBPRINT(sc, BCE_INFO, "%s(): tx_bd_chain_paddr[%d] = 0x%jX\n",
3170			__FUNCTION__, i, (uintmax_t) sc->tx_bd_chain_paddr[i]);
3171	}
3172
3173	/* Check the required size before mapping to conserve resources. */
3174	if (bce_tso_enable) {
3175		max_size     = BCE_TSO_MAX_SIZE;
3176		max_segments = BCE_MAX_SEGMENTS;
3177		max_seg_size = BCE_TSO_MAX_SEG_SIZE;
3178	} else {
3179		max_size     = MCLBYTES * BCE_MAX_SEGMENTS;
3180		max_segments = BCE_MAX_SEGMENTS;
3181		max_seg_size = MCLBYTES;
3182	}
3183
3184	/* Create a DMA tag for TX mbufs. */
3185	if (bus_dma_tag_create(sc->parent_tag,
3186			1,
3187			BCE_DMA_BOUNDARY,
3188			sc->max_bus_addr,
3189			BUS_SPACE_MAXADDR,
3190			NULL, NULL,
3191			max_size,
3192			max_segments,
3193			max_seg_size,
3194			0,
3195			NULL, NULL,
3196			&sc->tx_mbuf_tag)) {
3197		BCE_PRINTF("%s(%d): Could not allocate TX mbuf DMA tag!\n",
3198			__FILE__, __LINE__);
3199		rc = ENOMEM;
3200		goto bce_dma_alloc_exit;
3201	}
3202
3203	/* Create DMA maps for the TX mbufs clusters. */
3204	for (i = 0; i < TOTAL_TX_BD; i++) {
3205		if (bus_dmamap_create(sc->tx_mbuf_tag, BUS_DMA_NOWAIT,
3206			&sc->tx_mbuf_map[i])) {
3207			BCE_PRINTF("%s(%d): Unable to create TX mbuf DMA map!\n",
3208				__FILE__, __LINE__);
3209			rc = ENOMEM;
3210			goto bce_dma_alloc_exit;
3211		}
3212	}
3213
3214	/*
3215	 * Create a DMA tag for the RX buffer descriptor chain,
3216	 * allocate and clear the memory, and fetch the physical
3217	 * address of the blocks.
3218	 */
3219	if (bus_dma_tag_create(sc->parent_tag,
3220			BCM_PAGE_SIZE,
3221			BCE_DMA_BOUNDARY,
3222			BUS_SPACE_MAXADDR,
3223			sc->max_bus_addr,
3224			NULL, NULL,
3225			BCE_RX_CHAIN_PAGE_SZ,
3226			1,
3227			BCE_RX_CHAIN_PAGE_SZ,
3228			0,
3229			NULL, NULL,
3230			&sc->rx_bd_chain_tag)) {
3231		BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain DMA tag!\n",
3232			__FILE__, __LINE__);
3233		rc = ENOMEM;
3234		goto bce_dma_alloc_exit;
3235	}
3236
3237	for (i = 0; i < RX_PAGES; i++) {
3238
3239		if (bus_dmamem_alloc(sc->rx_bd_chain_tag,
3240	    		(void **)&sc->rx_bd_chain[i],
3241	    		BUS_DMA_NOWAIT,
3242		    	&sc->rx_bd_chain_map[i])) {
3243			BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain "
3244				"DMA memory!\n", __FILE__, __LINE__);
3245			rc = ENOMEM;
3246			goto bce_dma_alloc_exit;
3247		}
3248
3249		bzero((char *)sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ);
3250
3251		error = bus_dmamap_load(sc->rx_bd_chain_tag,
3252	    		sc->rx_bd_chain_map[i],
3253	    		sc->rx_bd_chain[i],
3254		    	BCE_RX_CHAIN_PAGE_SZ,
3255		    	bce_dma_map_addr,
3256	    		&busaddr,
3257	    		BUS_DMA_NOWAIT);
3258
3259		if (error) {
3260			BCE_PRINTF("%s(%d): Could not map RX descriptor chain DMA memory!\n",
3261				__FILE__, __LINE__);
3262			rc = ENOMEM;
3263			goto bce_dma_alloc_exit;
3264		}
3265
3266		sc->rx_bd_chain_paddr[i] = busaddr;
3267		DBPRINT(sc, BCE_INFO, "%s(): rx_bd_chain_paddr[%d] = 0x%jX\n",
3268			__FUNCTION__, i, (uintmax_t) sc->rx_bd_chain_paddr[i]);
3269	}
3270
3271	/*
3272	 * Create a DMA tag for RX mbufs.
3273	 */
3274#ifdef BCE_USE_SPLIT_HEADER
3275	max_size = max_seg_size = ((sc->rx_bd_mbuf_alloc_size < MCLBYTES) ?
3276		MCLBYTES : sc->rx_bd_mbuf_alloc_size);
3277#else
3278	max_size = max_seg_size = MJUM9BYTES;
3279#endif
3280
3281	if (bus_dma_tag_create(sc->parent_tag,
3282			1,
3283			BCE_DMA_BOUNDARY,
3284			sc->max_bus_addr,
3285			BUS_SPACE_MAXADDR,
3286			NULL, NULL,
3287			max_size,
3288			1,
3289			max_seg_size,
3290			0,
3291			NULL, NULL,
3292	    	&sc->rx_mbuf_tag)) {
3293		BCE_PRINTF("%s(%d): Could not allocate RX mbuf DMA tag!\n",
3294			__FILE__, __LINE__);
3295		rc = ENOMEM;
3296		goto bce_dma_alloc_exit;
3297	}
3298
3299	/* Create DMA maps for the RX mbuf clusters. */
3300	for (i = 0; i < TOTAL_RX_BD; i++) {
3301		if (bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_NOWAIT,
3302				&sc->rx_mbuf_map[i])) {
3303			BCE_PRINTF("%s(%d): Unable to create RX mbuf DMA map!\n",
3304				__FILE__, __LINE__);
3305			rc = ENOMEM;
3306			goto bce_dma_alloc_exit;
3307		}
3308	}
3309
3310#ifdef BCE_USE_SPLIT_HEADER
3311	/*
3312	 * Create a DMA tag for the page buffer descriptor chain,
3313	 * allocate and clear the memory, and fetch the physical
3314	 * address of the blocks.
3315	 */
3316	if (bus_dma_tag_create(sc->parent_tag,
3317			BCM_PAGE_SIZE,
3318			BCE_DMA_BOUNDARY,
3319			BUS_SPACE_MAXADDR,
3320			sc->max_bus_addr,
3321			NULL, NULL,
3322			BCE_PG_CHAIN_PAGE_SZ,
3323			1,
3324			BCE_PG_CHAIN_PAGE_SZ,
3325			0,
3326			NULL, NULL,
3327			&sc->pg_bd_chain_tag)) {
3328		BCE_PRINTF("%s(%d): Could not allocate page descriptor chain DMA tag!\n",
3329			__FILE__, __LINE__);
3330		rc = ENOMEM;
3331		goto bce_dma_alloc_exit;
3332	}
3333
3334	for (i = 0; i < PG_PAGES; i++) {
3335
3336		if (bus_dmamem_alloc(sc->pg_bd_chain_tag,
3337	    		(void **)&sc->pg_bd_chain[i],
3338	    		BUS_DMA_NOWAIT,
3339		    	&sc->pg_bd_chain_map[i])) {
3340			BCE_PRINTF("%s(%d): Could not allocate page descriptor chain "
3341				"DMA memory!\n", __FILE__, __LINE__);
3342			rc = ENOMEM;
3343			goto bce_dma_alloc_exit;
3344		}
3345
3346		bzero((char *)sc->pg_bd_chain[i], BCE_PG_CHAIN_PAGE_SZ);
3347
3348		error = bus_dmamap_load(sc->pg_bd_chain_tag,
3349	    		sc->pg_bd_chain_map[i],
3350	    		sc->pg_bd_chain[i],
3351		    	BCE_PG_CHAIN_PAGE_SZ,
3352		    	bce_dma_map_addr,
3353	    		&busaddr,
3354	    		BUS_DMA_NOWAIT);
3355
3356		if (error) {
3357			BCE_PRINTF("%s(%d): Could not map page descriptor chain DMA memory!\n",
3358				__FILE__, __LINE__);
3359			rc = ENOMEM;
3360			goto bce_dma_alloc_exit;
3361		}
3362
3363		sc->pg_bd_chain_paddr[i] = busaddr;
3364		DBPRINT(sc, BCE_INFO, "%s(): pg_bd_chain_paddr[%d] = 0x%jX\n",
3365			__FUNCTION__, i, (uintmax_t) sc->pg_bd_chain_paddr[i]);
3366	}
3367
3368	/*
3369	 * Create a DMA tag for page mbufs.
3370	 */
3371	max_size = max_seg_size = ((sc->pg_bd_mbuf_alloc_size < MCLBYTES) ?
3372		MCLBYTES : sc->pg_bd_mbuf_alloc_size);
3373
3374	if (bus_dma_tag_create(sc->parent_tag,
3375			1,
3376			BCE_DMA_BOUNDARY,
3377			sc->max_bus_addr,
3378			BUS_SPACE_MAXADDR,
3379			NULL, NULL,
3380			max_size,
3381			1,
3382			max_seg_size,
3383			0,
3384			NULL, NULL,
3385	    	&sc->pg_mbuf_tag)) {
3386		BCE_PRINTF("%s(%d): Could not allocate page mbuf DMA tag!\n",
3387			__FILE__, __LINE__);
3388		rc = ENOMEM;
3389		goto bce_dma_alloc_exit;
3390	}
3391
3392	/* Create DMA maps for the page mbuf clusters. */
3393	for (i = 0; i < TOTAL_PG_BD; i++) {
3394		if (bus_dmamap_create(sc->pg_mbuf_tag, BUS_DMA_NOWAIT,
3395				&sc->pg_mbuf_map[i])) {
3396			BCE_PRINTF("%s(%d): Unable to create page mbuf DMA map!\n",
3397				__FILE__, __LINE__);
3398			rc = ENOMEM;
3399			goto bce_dma_alloc_exit;
3400		}
3401	}
3402#endif
3403
3404bce_dma_alloc_exit:
3405	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
3406	return(rc);
3407}
3408
3409
3410/****************************************************************************/
3411/* Release all resources used by the driver.                                */
3412/*                                                                          */
3413/* Releases all resources acquired by the driver including interrupts,      */
3414/* interrupt handler, interfaces, mutexes, and DMA memory.                  */
3415/*                                                                          */
3416/* Returns:                                                                 */
3417/*   Nothing.                                                               */
3418/****************************************************************************/
3419static void
3420bce_release_resources(struct bce_softc *sc)
3421{
3422	device_t dev;
3423
3424	DBENTER(BCE_VERBOSE_RESET);
3425
3426	dev = sc->bce_dev;
3427
3428	bce_dma_free(sc);
3429
3430	if (sc->bce_intrhand != NULL) {
3431		DBPRINT(sc, BCE_INFO_RESET, "Removing interrupt handler.\n");
3432		bus_teardown_intr(dev, sc->bce_res_irq, sc->bce_intrhand);
3433	}
3434
3435	if (sc->bce_res_irq != NULL) {
3436		DBPRINT(sc, BCE_INFO_RESET, "Releasing IRQ.\n");
3437		bus_release_resource(dev, SYS_RES_IRQ, sc->bce_irq_rid,
3438			sc->bce_res_irq);
3439	}
3440
3441	if (sc->bce_flags & (BCE_USING_MSI_FLAG | BCE_USING_MSIX_FLAG)) {
3442		DBPRINT(sc, BCE_INFO_RESET, "Releasing MSI/MSI-X vector.\n");
3443		pci_release_msi(dev);
3444	}
3445
3446	if (sc->bce_res_mem != NULL) {
3447		DBPRINT(sc, BCE_INFO_RESET, "Releasing PCI memory.\n");
3448		bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), sc->bce_res_mem);
3449	}
3450
3451	if (sc->bce_ifp != NULL) {
3452		DBPRINT(sc, BCE_INFO_RESET, "Releasing IF.\n");
3453		if_free(sc->bce_ifp);
3454	}
3455
3456	if (mtx_initialized(&sc->bce_mtx))
3457		BCE_LOCK_DESTROY(sc);
3458
3459	DBEXIT(BCE_VERBOSE_RESET);
3460}
3461
3462
3463/****************************************************************************/
3464/* Firmware synchronization.                                                */
3465/*                                                                          */
3466/* Before performing certain events such as a chip reset, synchronize with  */
3467/* the firmware first.                                                      */
3468/*                                                                          */
3469/* Returns:                                                                 */
3470/*   0 for success, positive value for failure.                             */
3471/****************************************************************************/
3472static int
3473bce_fw_sync(struct bce_softc *sc, u32 msg_data)
3474{
3475	int i, rc = 0;
3476	u32 val;
3477
3478	DBENTER(BCE_VERBOSE_RESET);
3479
3480	/* Don't waste any time if we've timed out before. */
3481	if (sc->bce_fw_timed_out) {
3482		rc = EBUSY;
3483		goto bce_fw_sync_exit;
3484	}
3485
3486	/* Increment the message sequence number. */
3487	sc->bce_fw_wr_seq++;
3488	msg_data |= sc->bce_fw_wr_seq;
3489
3490 	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "bce_fw_sync(): msg_data = 0x%08X\n",
3491 		msg_data);
3492
3493	/* Send the message to the bootcode driver mailbox. */
3494	REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_MB, msg_data);
3495
3496	/* Wait for the bootcode to acknowledge the message. */
3497	for (i = 0; i < FW_ACK_TIME_OUT_MS; i++) {
3498		/* Check for a response in the bootcode firmware mailbox. */
3499		val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_FW_MB);
3500		if ((val & BCE_FW_MSG_ACK) == (msg_data & BCE_DRV_MSG_SEQ))
3501			break;
3502		DELAY(1000);
3503	}
3504
3505	/* If we've timed out, tell the bootcode that we've stopped waiting. */
3506	if (((val & BCE_FW_MSG_ACK) != (msg_data & BCE_DRV_MSG_SEQ)) &&
3507		((msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0)) {
3508
3509		BCE_PRINTF("%s(%d): Firmware synchronization timeout! "
3510			"msg_data = 0x%08X\n",
3511			__FILE__, __LINE__, msg_data);
3512
3513		msg_data &= ~BCE_DRV_MSG_CODE;
3514		msg_data |= BCE_DRV_MSG_CODE_FW_TIMEOUT;
3515
3516		REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_MB, msg_data);
3517
3518		sc->bce_fw_timed_out = 1;
3519		rc = EBUSY;
3520	}
3521
3522bce_fw_sync_exit:
3523	DBEXIT(BCE_VERBOSE_RESET);
3524	return (rc);
3525}
3526
3527
3528/****************************************************************************/
3529/* Load Receive Virtual 2 Physical (RV2P) processor firmware.               */
3530/*                                                                          */
3531/* Returns:                                                                 */
3532/*   Nothing.                                                               */
3533/****************************************************************************/
3534static void
3535bce_load_rv2p_fw(struct bce_softc *sc, u32 *rv2p_code,
3536	u32 rv2p_code_len, u32 rv2p_proc)
3537{
3538	int i;
3539	u32 val;
3540
3541	DBENTER(BCE_VERBOSE_RESET);
3542
3543	/* Set the page size used by RV2P. */
3544	if (rv2p_proc == RV2P_PROC2) {
3545		BCE_RV2P_PROC2_CHG_MAX_BD_PAGE(USABLE_RX_BD_PER_PAGE);
3546	}
3547
3548	for (i = 0; i < rv2p_code_len; i += 8) {
3549		REG_WR(sc, BCE_RV2P_INSTR_HIGH, *rv2p_code);
3550		rv2p_code++;
3551		REG_WR(sc, BCE_RV2P_INSTR_LOW, *rv2p_code);
3552		rv2p_code++;
3553
3554		if (rv2p_proc == RV2P_PROC1) {
3555			val = (i / 8) | BCE_RV2P_PROC1_ADDR_CMD_RDWR;
3556			REG_WR(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
3557		}
3558		else {
3559			val = (i / 8) | BCE_RV2P_PROC2_ADDR_CMD_RDWR;
3560			REG_WR(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
3561		}
3562	}
3563
3564	/* Reset the processor, un-stall is done later. */
3565	if (rv2p_proc == RV2P_PROC1) {
3566		REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC1_RESET);
3567	}
3568	else {
3569		REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC2_RESET);
3570	}
3571
3572	DBEXIT(BCE_VERBOSE_RESET);
3573}
3574
3575
3576/****************************************************************************/
3577/* Load RISC processor firmware.                                            */
3578/*                                                                          */
3579/* Loads firmware from the file if_bcefw.h into the scratchpad memory       */
3580/* associated with a particular processor.                                  */
3581/*                                                                          */
3582/* Returns:                                                                 */
3583/*   Nothing.                                                               */
3584/****************************************************************************/
3585static void
3586bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
3587	struct fw_info *fw)
3588{
3589	u32 offset;
3590	u32 val;
3591
3592	DBENTER(BCE_VERBOSE_RESET);
3593
3594	/* Halt the CPU. */
3595	val = REG_RD_IND(sc, cpu_reg->mode);
3596	val |= cpu_reg->mode_value_halt;
3597	REG_WR_IND(sc, cpu_reg->mode, val);
3598	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
3599
3600	/* Load the Text area. */
3601	offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
3602	if (fw->text) {
3603		int j;
3604
3605		for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
3606			REG_WR_IND(sc, offset, fw->text[j]);
3607	        }
3608	}
3609
3610	/* Load the Data area. */
3611	offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
3612	if (fw->data) {
3613		int j;
3614
3615		for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
3616			REG_WR_IND(sc, offset, fw->data[j]);
3617		}
3618	}
3619
3620	/* Load the SBSS area. */
3621	offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
3622	if (fw->sbss) {
3623		int j;
3624
3625		for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
3626			REG_WR_IND(sc, offset, fw->sbss[j]);
3627		}
3628	}
3629
3630	/* Load the BSS area. */
3631	offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
3632	if (fw->bss) {
3633		int j;
3634
3635		for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
3636			REG_WR_IND(sc, offset, fw->bss[j]);
3637		}
3638	}
3639
3640	/* Load the Read-Only area. */
3641	offset = cpu_reg->spad_base +
3642		(fw->rodata_addr - cpu_reg->mips_view_base);
3643	if (fw->rodata) {
3644		int j;
3645
3646		for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
3647			REG_WR_IND(sc, offset, fw->rodata[j]);
3648		}
3649	}
3650
3651	/* Clear the pre-fetch instruction. */
3652	REG_WR_IND(sc, cpu_reg->inst, 0);
3653	REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
3654
3655	/* Start the CPU. */
3656	val = REG_RD_IND(sc, cpu_reg->mode);
3657	val &= ~cpu_reg->mode_value_halt;
3658	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
3659	REG_WR_IND(sc, cpu_reg->mode, val);
3660
3661	DBEXIT(BCE_VERBOSE_RESET);
3662}
3663
3664
3665/****************************************************************************/
3666/* Initialize the RX CPU.                                                   */
3667/*                                                                          */
3668/* Returns:                                                                 */
3669/*   Nothing.                                                               */
3670/****************************************************************************/
3671static void
3672bce_init_rxp_cpu(struct bce_softc *sc)
3673{
3674	struct cpu_reg cpu_reg;
3675	struct fw_info fw;
3676
3677	DBENTER(BCE_VERBOSE_RESET);
3678
3679	cpu_reg.mode = BCE_RXP_CPU_MODE;
3680	cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
3681	cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
3682	cpu_reg.state = BCE_RXP_CPU_STATE;
3683	cpu_reg.state_value_clear = 0xffffff;
3684	cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
3685	cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
3686	cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
3687	cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
3688	cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
3689	cpu_reg.spad_base = BCE_RXP_SCRATCH;
3690	cpu_reg.mips_view_base = 0x8000000;
3691
3692	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3693		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3694 		fw.ver_major = bce_RXP_b09FwReleaseMajor;
3695		fw.ver_minor = bce_RXP_b09FwReleaseMinor;
3696		fw.ver_fix = bce_RXP_b09FwReleaseFix;
3697		fw.start_addr = bce_RXP_b09FwStartAddr;
3698
3699		fw.text_addr = bce_RXP_b09FwTextAddr;
3700		fw.text_len = bce_RXP_b09FwTextLen;
3701		fw.text_index = 0;
3702		fw.text = bce_RXP_b09FwText;
3703
3704		fw.data_addr = bce_RXP_b09FwDataAddr;
3705		fw.data_len = bce_RXP_b09FwDataLen;
3706		fw.data_index = 0;
3707		fw.data = bce_RXP_b09FwData;
3708
3709		fw.sbss_addr = bce_RXP_b09FwSbssAddr;
3710		fw.sbss_len = bce_RXP_b09FwSbssLen;
3711		fw.sbss_index = 0;
3712		fw.sbss = bce_RXP_b09FwSbss;
3713
3714		fw.bss_addr = bce_RXP_b09FwBssAddr;
3715		fw.bss_len = bce_RXP_b09FwBssLen;
3716		fw.bss_index = 0;
3717		fw.bss = bce_RXP_b09FwBss;
3718
3719		fw.rodata_addr = bce_RXP_b09FwRodataAddr;
3720		fw.rodata_len = bce_RXP_b09FwRodataLen;
3721		fw.rodata_index = 0;
3722		fw.rodata = bce_RXP_b09FwRodata;
3723	} else {
3724		fw.ver_major = bce_RXP_b06FwReleaseMajor;
3725		fw.ver_minor = bce_RXP_b06FwReleaseMinor;
3726		fw.ver_fix = bce_RXP_b06FwReleaseFix;
3727		fw.start_addr = bce_RXP_b06FwStartAddr;
3728
3729		fw.text_addr = bce_RXP_b06FwTextAddr;
3730		fw.text_len = bce_RXP_b06FwTextLen;
3731		fw.text_index = 0;
3732		fw.text = bce_RXP_b06FwText;
3733
3734		fw.data_addr = bce_RXP_b06FwDataAddr;
3735		fw.data_len = bce_RXP_b06FwDataLen;
3736		fw.data_index = 0;
3737		fw.data = bce_RXP_b06FwData;
3738
3739		fw.sbss_addr = bce_RXP_b06FwSbssAddr;
3740		fw.sbss_len = bce_RXP_b06FwSbssLen;
3741		fw.sbss_index = 0;
3742		fw.sbss = bce_RXP_b06FwSbss;
3743
3744		fw.bss_addr = bce_RXP_b06FwBssAddr;
3745		fw.bss_len = bce_RXP_b06FwBssLen;
3746		fw.bss_index = 0;
3747		fw.bss = bce_RXP_b06FwBss;
3748
3749		fw.rodata_addr = bce_RXP_b06FwRodataAddr;
3750		fw.rodata_len = bce_RXP_b06FwRodataLen;
3751		fw.rodata_index = 0;
3752		fw.rodata = bce_RXP_b06FwRodata;
3753	}
3754
3755	DBPRINT(sc, BCE_INFO_RESET, "Loading RX firmware.\n");
3756	bce_load_cpu_fw(sc, &cpu_reg, &fw);
3757
3758	DBEXIT(BCE_VERBOSE_RESET);
3759}
3760
3761
3762/****************************************************************************/
3763/* Initialize the TX CPU.                                                   */
3764/*                                                                          */
3765/* Returns:                                                                 */
3766/*   Nothing.                                                               */
3767/****************************************************************************/
3768static void
3769bce_init_txp_cpu(struct bce_softc *sc)
3770{
3771	struct cpu_reg cpu_reg;
3772	struct fw_info fw;
3773
3774	DBENTER(BCE_VERBOSE_RESET);
3775
3776	cpu_reg.mode = BCE_TXP_CPU_MODE;
3777	cpu_reg.mode_value_halt = BCE_TXP_CPU_MODE_SOFT_HALT;
3778	cpu_reg.mode_value_sstep = BCE_TXP_CPU_MODE_STEP_ENA;
3779	cpu_reg.state = BCE_TXP_CPU_STATE;
3780	cpu_reg.state_value_clear = 0xffffff;
3781	cpu_reg.gpr0 = BCE_TXP_CPU_REG_FILE;
3782	cpu_reg.evmask = BCE_TXP_CPU_EVENT_MASK;
3783	cpu_reg.pc = BCE_TXP_CPU_PROGRAM_COUNTER;
3784	cpu_reg.inst = BCE_TXP_CPU_INSTRUCTION;
3785	cpu_reg.bp = BCE_TXP_CPU_HW_BREAKPOINT;
3786	cpu_reg.spad_base = BCE_TXP_SCRATCH;
3787	cpu_reg.mips_view_base = 0x8000000;
3788
3789	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3790		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3791		fw.ver_major = bce_TXP_b09FwReleaseMajor;
3792		fw.ver_minor = bce_TXP_b09FwReleaseMinor;
3793		fw.ver_fix = bce_TXP_b09FwReleaseFix;
3794		fw.start_addr = bce_TXP_b09FwStartAddr;
3795
3796		fw.text_addr = bce_TXP_b09FwTextAddr;
3797		fw.text_len = bce_TXP_b09FwTextLen;
3798		fw.text_index = 0;
3799		fw.text = bce_TXP_b09FwText;
3800
3801		fw.data_addr = bce_TXP_b09FwDataAddr;
3802		fw.data_len = bce_TXP_b09FwDataLen;
3803		fw.data_index = 0;
3804		fw.data = bce_TXP_b09FwData;
3805
3806		fw.sbss_addr = bce_TXP_b09FwSbssAddr;
3807		fw.sbss_len = bce_TXP_b09FwSbssLen;
3808		fw.sbss_index = 0;
3809		fw.sbss = bce_TXP_b09FwSbss;
3810
3811		fw.bss_addr = bce_TXP_b09FwBssAddr;
3812		fw.bss_len = bce_TXP_b09FwBssLen;
3813		fw.bss_index = 0;
3814		fw.bss = bce_TXP_b09FwBss;
3815
3816		fw.rodata_addr = bce_TXP_b09FwRodataAddr;
3817		fw.rodata_len = bce_TXP_b09FwRodataLen;
3818		fw.rodata_index = 0;
3819		fw.rodata = bce_TXP_b09FwRodata;
3820	} else {
3821		fw.ver_major = bce_TXP_b06FwReleaseMajor;
3822		fw.ver_minor = bce_TXP_b06FwReleaseMinor;
3823		fw.ver_fix = bce_TXP_b06FwReleaseFix;
3824		fw.start_addr = bce_TXP_b06FwStartAddr;
3825
3826		fw.text_addr = bce_TXP_b06FwTextAddr;
3827		fw.text_len = bce_TXP_b06FwTextLen;
3828		fw.text_index = 0;
3829		fw.text = bce_TXP_b06FwText;
3830
3831		fw.data_addr = bce_TXP_b06FwDataAddr;
3832		fw.data_len = bce_TXP_b06FwDataLen;
3833		fw.data_index = 0;
3834		fw.data = bce_TXP_b06FwData;
3835
3836		fw.sbss_addr = bce_TXP_b06FwSbssAddr;
3837		fw.sbss_len = bce_TXP_b06FwSbssLen;
3838		fw.sbss_index = 0;
3839		fw.sbss = bce_TXP_b06FwSbss;
3840
3841		fw.bss_addr = bce_TXP_b06FwBssAddr;
3842		fw.bss_len = bce_TXP_b06FwBssLen;
3843		fw.bss_index = 0;
3844		fw.bss = bce_TXP_b06FwBss;
3845
3846		fw.rodata_addr = bce_TXP_b06FwRodataAddr;
3847		fw.rodata_len = bce_TXP_b06FwRodataLen;
3848		fw.rodata_index = 0;
3849		fw.rodata = bce_TXP_b06FwRodata;
3850	}
3851
3852	DBPRINT(sc, BCE_INFO_RESET, "Loading TX firmware.\n");
3853	bce_load_cpu_fw(sc, &cpu_reg, &fw);
3854
3855	DBEXIT(BCE_VERBOSE_RESET);
3856}
3857
3858
3859/****************************************************************************/
3860/* Initialize the TPAT CPU.                                                 */
3861/*                                                                          */
3862/* Returns:                                                                 */
3863/*   Nothing.                                                               */
3864/****************************************************************************/
3865static void
3866bce_init_tpat_cpu(struct bce_softc *sc)
3867{
3868	struct cpu_reg cpu_reg;
3869	struct fw_info fw;
3870
3871	DBENTER(BCE_VERBOSE_RESET);
3872
3873	cpu_reg.mode = BCE_TPAT_CPU_MODE;
3874	cpu_reg.mode_value_halt = BCE_TPAT_CPU_MODE_SOFT_HALT;
3875	cpu_reg.mode_value_sstep = BCE_TPAT_CPU_MODE_STEP_ENA;
3876	cpu_reg.state = BCE_TPAT_CPU_STATE;
3877	cpu_reg.state_value_clear = 0xffffff;
3878	cpu_reg.gpr0 = BCE_TPAT_CPU_REG_FILE;
3879	cpu_reg.evmask = BCE_TPAT_CPU_EVENT_MASK;
3880	cpu_reg.pc = BCE_TPAT_CPU_PROGRAM_COUNTER;
3881	cpu_reg.inst = BCE_TPAT_CPU_INSTRUCTION;
3882	cpu_reg.bp = BCE_TPAT_CPU_HW_BREAKPOINT;
3883	cpu_reg.spad_base = BCE_TPAT_SCRATCH;
3884	cpu_reg.mips_view_base = 0x8000000;
3885
3886	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3887		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3888		fw.ver_major = bce_TPAT_b09FwReleaseMajor;
3889		fw.ver_minor = bce_TPAT_b09FwReleaseMinor;
3890		fw.ver_fix = bce_TPAT_b09FwReleaseFix;
3891		fw.start_addr = bce_TPAT_b09FwStartAddr;
3892
3893		fw.text_addr = bce_TPAT_b09FwTextAddr;
3894		fw.text_len = bce_TPAT_b09FwTextLen;
3895		fw.text_index = 0;
3896		fw.text = bce_TPAT_b09FwText;
3897
3898		fw.data_addr = bce_TPAT_b09FwDataAddr;
3899		fw.data_len = bce_TPAT_b09FwDataLen;
3900		fw.data_index = 0;
3901		fw.data = bce_TPAT_b09FwData;
3902
3903		fw.sbss_addr = bce_TPAT_b09FwSbssAddr;
3904		fw.sbss_len = bce_TPAT_b09FwSbssLen;
3905		fw.sbss_index = 0;
3906		fw.sbss = bce_TPAT_b09FwSbss;
3907
3908		fw.bss_addr = bce_TPAT_b09FwBssAddr;
3909		fw.bss_len = bce_TPAT_b09FwBssLen;
3910		fw.bss_index = 0;
3911		fw.bss = bce_TPAT_b09FwBss;
3912
3913		fw.rodata_addr = bce_TPAT_b09FwRodataAddr;
3914		fw.rodata_len = bce_TPAT_b09FwRodataLen;
3915		fw.rodata_index = 0;
3916		fw.rodata = bce_TPAT_b09FwRodata;
3917	} else {
3918		fw.ver_major = bce_TPAT_b06FwReleaseMajor;
3919		fw.ver_minor = bce_TPAT_b06FwReleaseMinor;
3920		fw.ver_fix = bce_TPAT_b06FwReleaseFix;
3921		fw.start_addr = bce_TPAT_b06FwStartAddr;
3922
3923		fw.text_addr = bce_TPAT_b06FwTextAddr;
3924		fw.text_len = bce_TPAT_b06FwTextLen;
3925		fw.text_index = 0;
3926		fw.text = bce_TPAT_b06FwText;
3927
3928		fw.data_addr = bce_TPAT_b06FwDataAddr;
3929		fw.data_len = bce_TPAT_b06FwDataLen;
3930		fw.data_index = 0;
3931		fw.data = bce_TPAT_b06FwData;
3932
3933		fw.sbss_addr = bce_TPAT_b06FwSbssAddr;
3934		fw.sbss_len = bce_TPAT_b06FwSbssLen;
3935		fw.sbss_index = 0;
3936		fw.sbss = bce_TPAT_b06FwSbss;
3937
3938		fw.bss_addr = bce_TPAT_b06FwBssAddr;
3939		fw.bss_len = bce_TPAT_b06FwBssLen;
3940		fw.bss_index = 0;
3941		fw.bss = bce_TPAT_b06FwBss;
3942
3943		fw.rodata_addr = bce_TPAT_b06FwRodataAddr;
3944		fw.rodata_len = bce_TPAT_b06FwRodataLen;
3945		fw.rodata_index = 0;
3946		fw.rodata = bce_TPAT_b06FwRodata;
3947	}
3948
3949	DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n");
3950	bce_load_cpu_fw(sc, &cpu_reg, &fw);
3951
3952	DBEXIT(BCE_VERBOSE_RESET);
3953}
3954
3955
3956/****************************************************************************/
3957/* Initialize the CP CPU.                                                   */
3958/*                                                                          */
3959/* Returns:                                                                 */
3960/*   Nothing.                                                               */
3961/****************************************************************************/
3962static void
3963bce_init_cp_cpu(struct bce_softc *sc)
3964{
3965	struct cpu_reg cpu_reg;
3966	struct fw_info fw;
3967
3968	DBENTER(BCE_VERBOSE_RESET);
3969
3970	cpu_reg.mode = BCE_CP_CPU_MODE;
3971	cpu_reg.mode_value_halt = BCE_CP_CPU_MODE_SOFT_HALT;
3972	cpu_reg.mode_value_sstep = BCE_CP_CPU_MODE_STEP_ENA;
3973	cpu_reg.state = BCE_CP_CPU_STATE;
3974	cpu_reg.state_value_clear = 0xffffff;
3975	cpu_reg.gpr0 = BCE_CP_CPU_REG_FILE;
3976	cpu_reg.evmask = BCE_CP_CPU_EVENT_MASK;
3977	cpu_reg.pc = BCE_CP_CPU_PROGRAM_COUNTER;
3978	cpu_reg.inst = BCE_CP_CPU_INSTRUCTION;
3979	cpu_reg.bp = BCE_CP_CPU_HW_BREAKPOINT;
3980	cpu_reg.spad_base = BCE_CP_SCRATCH;
3981	cpu_reg.mips_view_base = 0x8000000;
3982
3983	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3984		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3985		fw.ver_major = bce_CP_b09FwReleaseMajor;
3986		fw.ver_minor = bce_CP_b09FwReleaseMinor;
3987		fw.ver_fix = bce_CP_b09FwReleaseFix;
3988		fw.start_addr = bce_CP_b09FwStartAddr;
3989
3990		fw.text_addr = bce_CP_b09FwTextAddr;
3991		fw.text_len = bce_CP_b09FwTextLen;
3992		fw.text_index = 0;
3993		fw.text = bce_CP_b09FwText;
3994
3995		fw.data_addr = bce_CP_b09FwDataAddr;
3996		fw.data_len = bce_CP_b09FwDataLen;
3997		fw.data_index = 0;
3998		fw.data = bce_CP_b09FwData;
3999
4000		fw.sbss_addr = bce_CP_b09FwSbssAddr;
4001		fw.sbss_len = bce_CP_b09FwSbssLen;
4002		fw.sbss_index = 0;
4003		fw.sbss = bce_CP_b09FwSbss;
4004
4005		fw.bss_addr = bce_CP_b09FwBssAddr;
4006		fw.bss_len = bce_CP_b09FwBssLen;
4007		fw.bss_index = 0;
4008		fw.bss = bce_CP_b09FwBss;
4009
4010		fw.rodata_addr = bce_CP_b09FwRodataAddr;
4011		fw.rodata_len = bce_CP_b09FwRodataLen;
4012		fw.rodata_index = 0;
4013		fw.rodata = bce_CP_b09FwRodata;
4014	} else {
4015		fw.ver_major = bce_CP_b06FwReleaseMajor;
4016		fw.ver_minor = bce_CP_b06FwReleaseMinor;
4017		fw.ver_fix = bce_CP_b06FwReleaseFix;
4018		fw.start_addr = bce_CP_b06FwStartAddr;
4019
4020		fw.text_addr = bce_CP_b06FwTextAddr;
4021		fw.text_len = bce_CP_b06FwTextLen;
4022		fw.text_index = 0;
4023		fw.text = bce_CP_b06FwText;
4024
4025		fw.data_addr = bce_CP_b06FwDataAddr;
4026		fw.data_len = bce_CP_b06FwDataLen;
4027		fw.data_index = 0;
4028		fw.data = bce_CP_b06FwData;
4029
4030		fw.sbss_addr = bce_CP_b06FwSbssAddr;
4031		fw.sbss_len = bce_CP_b06FwSbssLen;
4032		fw.sbss_index = 0;
4033		fw.sbss = bce_CP_b06FwSbss;
4034
4035		fw.bss_addr = bce_CP_b06FwBssAddr;
4036		fw.bss_len = bce_CP_b06FwBssLen;
4037		fw.bss_index = 0;
4038		fw.bss = bce_CP_b06FwBss;
4039
4040		fw.rodata_addr = bce_CP_b06FwRodataAddr;
4041		fw.rodata_len = bce_CP_b06FwRodataLen;
4042		fw.rodata_index = 0;
4043		fw.rodata = bce_CP_b06FwRodata;
4044	}
4045
4046	DBPRINT(sc, BCE_INFO_RESET, "Loading CP firmware.\n");
4047	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4048
4049	DBEXIT(BCE_VERBOSE_RESET);
4050}
4051
4052
4053/****************************************************************************/
4054/* Initialize the COM CPU.                                                 */
4055/*                                                                          */
4056/* Returns:                                                                 */
4057/*   Nothing.                                                               */
4058/****************************************************************************/
4059static void
4060bce_init_com_cpu(struct bce_softc *sc)
4061{
4062	struct cpu_reg cpu_reg;
4063	struct fw_info fw;
4064
4065	DBENTER(BCE_VERBOSE_RESET);
4066
4067	cpu_reg.mode = BCE_COM_CPU_MODE;
4068	cpu_reg.mode_value_halt = BCE_COM_CPU_MODE_SOFT_HALT;
4069	cpu_reg.mode_value_sstep = BCE_COM_CPU_MODE_STEP_ENA;
4070	cpu_reg.state = BCE_COM_CPU_STATE;
4071	cpu_reg.state_value_clear = 0xffffff;
4072	cpu_reg.gpr0 = BCE_COM_CPU_REG_FILE;
4073	cpu_reg.evmask = BCE_COM_CPU_EVENT_MASK;
4074	cpu_reg.pc = BCE_COM_CPU_PROGRAM_COUNTER;
4075	cpu_reg.inst = BCE_COM_CPU_INSTRUCTION;
4076	cpu_reg.bp = BCE_COM_CPU_HW_BREAKPOINT;
4077	cpu_reg.spad_base = BCE_COM_SCRATCH;
4078	cpu_reg.mips_view_base = 0x8000000;
4079
4080	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4081		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4082		fw.ver_major = bce_COM_b09FwReleaseMajor;
4083		fw.ver_minor = bce_COM_b09FwReleaseMinor;
4084		fw.ver_fix = bce_COM_b09FwReleaseFix;
4085		fw.start_addr = bce_COM_b09FwStartAddr;
4086
4087		fw.text_addr = bce_COM_b09FwTextAddr;
4088		fw.text_len = bce_COM_b09FwTextLen;
4089		fw.text_index = 0;
4090		fw.text = bce_COM_b09FwText;
4091
4092		fw.data_addr = bce_COM_b09FwDataAddr;
4093		fw.data_len = bce_COM_b09FwDataLen;
4094		fw.data_index = 0;
4095		fw.data = bce_COM_b09FwData;
4096
4097		fw.sbss_addr = bce_COM_b09FwSbssAddr;
4098		fw.sbss_len = bce_COM_b09FwSbssLen;
4099		fw.sbss_index = 0;
4100		fw.sbss = bce_COM_b09FwSbss;
4101
4102		fw.bss_addr = bce_COM_b09FwBssAddr;
4103		fw.bss_len = bce_COM_b09FwBssLen;
4104		fw.bss_index = 0;
4105		fw.bss = bce_COM_b09FwBss;
4106
4107		fw.rodata_addr = bce_COM_b09FwRodataAddr;
4108		fw.rodata_len = bce_COM_b09FwRodataLen;
4109		fw.rodata_index = 0;
4110		fw.rodata = bce_COM_b09FwRodata;
4111	} else {
4112		fw.ver_major = bce_COM_b06FwReleaseMajor;
4113		fw.ver_minor = bce_COM_b06FwReleaseMinor;
4114		fw.ver_fix = bce_COM_b06FwReleaseFix;
4115		fw.start_addr = bce_COM_b06FwStartAddr;
4116
4117		fw.text_addr = bce_COM_b06FwTextAddr;
4118		fw.text_len = bce_COM_b06FwTextLen;
4119		fw.text_index = 0;
4120		fw.text = bce_COM_b06FwText;
4121
4122		fw.data_addr = bce_COM_b06FwDataAddr;
4123		fw.data_len = bce_COM_b06FwDataLen;
4124		fw.data_index = 0;
4125		fw.data = bce_COM_b06FwData;
4126
4127		fw.sbss_addr = bce_COM_b06FwSbssAddr;
4128		fw.sbss_len = bce_COM_b06FwSbssLen;
4129		fw.sbss_index = 0;
4130		fw.sbss = bce_COM_b06FwSbss;
4131
4132		fw.bss_addr = bce_COM_b06FwBssAddr;
4133		fw.bss_len = bce_COM_b06FwBssLen;
4134		fw.bss_index = 0;
4135		fw.bss = bce_COM_b06FwBss;
4136
4137		fw.rodata_addr = bce_COM_b06FwRodataAddr;
4138		fw.rodata_len = bce_COM_b06FwRodataLen;
4139		fw.rodata_index = 0;
4140		fw.rodata = bce_COM_b06FwRodata;
4141	}
4142
4143	DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n");
4144	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4145
4146	DBEXIT(BCE_VERBOSE_RESET);
4147}
4148
4149
4150/****************************************************************************/
4151/* Initialize the RV2P, RX, TX, TPAT, COM, and CP CPUs.                     */
4152/*                                                                          */
4153/* Loads the firmware for each CPU and starts the CPU.                      */
4154/*                                                                          */
4155/* Returns:                                                                 */
4156/*   Nothing.                                                               */
4157/****************************************************************************/
4158static void
4159bce_init_cpus(struct bce_softc *sc)
4160{
4161	DBENTER(BCE_VERBOSE_RESET);
4162
4163	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4164		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4165		bce_load_rv2p_fw(sc, bce_xi_rv2p_proc1, sizeof(bce_xi_rv2p_proc1),
4166			RV2P_PROC1);
4167		bce_load_rv2p_fw(sc, bce_xi_rv2p_proc2, sizeof(bce_xi_rv2p_proc2),
4168			RV2P_PROC2);
4169	} else {
4170		bce_load_rv2p_fw(sc, bce_rv2p_proc1, sizeof(bce_rv2p_proc1),
4171			RV2P_PROC1);
4172		bce_load_rv2p_fw(sc, bce_rv2p_proc2, sizeof(bce_rv2p_proc2),
4173			RV2P_PROC2);
4174	}
4175
4176	bce_init_rxp_cpu(sc);
4177	bce_init_txp_cpu(sc);
4178	bce_init_tpat_cpu(sc);
4179	bce_init_com_cpu(sc);
4180	bce_init_cp_cpu(sc);
4181
4182	DBEXIT(BCE_VERBOSE_RESET);
4183}
4184
4185
4186/****************************************************************************/
4187/* Initialize context memory.                                               */
4188/*                                                                          */
4189/* Clears the memory associated with each Context ID (CID).                 */
4190/*                                                                          */
4191/* Returns:                                                                 */
4192/*   Nothing.                                                               */
4193/****************************************************************************/
4194static void
4195bce_init_ctx(struct bce_softc *sc)
4196{
4197
4198	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
4199
4200	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4201		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4202		/* DRC: Replace this constant value with a #define. */
4203		int i, retry_cnt = 10;
4204		u32 val;
4205
4206		DBPRINT(sc, BCE_INFO_CTX, "Initializing 5709 context.\n");
4207
4208		/*
4209		 * BCM5709 context memory may be cached
4210		 * in host memory so prepare the host memory
4211		 * for access.
4212		 */
4213		val = BCE_CTX_COMMAND_ENABLED | BCE_CTX_COMMAND_MEM_INIT | (1 << 12);
4214		val |= (BCM_PAGE_BITS - 8) << 16;
4215		REG_WR(sc, BCE_CTX_COMMAND, val);
4216
4217		/* Wait for mem init command to complete. */
4218		for (i = 0; i < retry_cnt; i++) {
4219			val = REG_RD(sc, BCE_CTX_COMMAND);
4220			if (!(val & BCE_CTX_COMMAND_MEM_INIT))
4221				break;
4222			DELAY(2);
4223		}
4224
4225		/* ToDo: Consider returning an error here. */
4226		DBRUNIF((val & BCE_CTX_COMMAND_MEM_INIT),
4227			BCE_PRINTF("%s(): Context memory initialization failed!\n",
4228			__FUNCTION__));
4229
4230		for (i = 0; i < sc->ctx_pages; i++) {
4231			int j;
4232
4233			/* Set the physical address of the context memory cache. */
4234			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA0,
4235				BCE_ADDR_LO(sc->ctx_paddr[i] & 0xfffffff0) |
4236				BCE_CTX_HOST_PAGE_TBL_DATA0_VALID);
4237			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA1,
4238				BCE_ADDR_HI(sc->ctx_paddr[i]));
4239			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_CTRL, i |
4240				BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
4241
4242			/* Verify that the context memory write was successful. */
4243			for (j = 0; j < retry_cnt; j++) {
4244				val = REG_RD(sc, BCE_CTX_HOST_PAGE_TBL_CTRL);
4245				if ((val & BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) == 0)
4246					break;
4247				DELAY(5);
4248			}
4249
4250			/* ToDo: Consider returning an error here. */
4251			DBRUNIF((val & BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ),
4252				BCE_PRINTF("%s(): Failed to initialize context page %d!\n",
4253				__FUNCTION__, i));
4254		}
4255	} else {
4256		u32 vcid_addr, offset;
4257
4258		DBPRINT(sc, BCE_INFO, "Initializing 5706/5708 context.\n");
4259
4260		/*
4261		 * For the 5706/5708, context memory is local to
4262		 * the controller, so initialize the controller
4263		 * context memory.
4264		 */
4265
4266		vcid_addr = GET_CID_ADDR(96);
4267		while (vcid_addr) {
4268
4269			vcid_addr -= PHY_CTX_SIZE;
4270
4271			REG_WR(sc, BCE_CTX_VIRT_ADDR, 0);
4272			REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
4273
4274            for(offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
4275                CTX_WR(sc, 0x00, offset, 0);
4276            }
4277
4278			REG_WR(sc, BCE_CTX_VIRT_ADDR, vcid_addr);
4279			REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
4280		}
4281
4282	}
4283	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
4284}
4285
4286
4287/****************************************************************************/
4288/* Fetch the permanent MAC address of the controller.                       */
4289/*                                                                          */
4290/* Returns:                                                                 */
4291/*   Nothing.                                                               */
4292/****************************************************************************/
4293static void
4294bce_get_mac_addr(struct bce_softc *sc)
4295{
4296	u32 mac_lo = 0, mac_hi = 0;
4297
4298	DBENTER(BCE_VERBOSE_RESET);
4299	/*
4300	 * The NetXtreme II bootcode populates various NIC
4301	 * power-on and runtime configuration items in a
4302	 * shared memory area.  The factory configured MAC
4303	 * address is available from both NVRAM and the
4304	 * shared memory area so we'll read the value from
4305	 * shared memory for speed.
4306	 */
4307
4308	mac_hi = REG_RD_IND(sc, sc->bce_shmem_base +
4309		BCE_PORT_HW_CFG_MAC_UPPER);
4310	mac_lo = REG_RD_IND(sc, sc->bce_shmem_base +
4311		BCE_PORT_HW_CFG_MAC_LOWER);
4312
4313	if ((mac_lo == 0) && (mac_hi == 0)) {
4314		BCE_PRINTF("%s(%d): Invalid Ethernet address!\n",
4315			__FILE__, __LINE__);
4316	} else {
4317		sc->eaddr[0] = (u_char)(mac_hi >> 8);
4318		sc->eaddr[1] = (u_char)(mac_hi >> 0);
4319		sc->eaddr[2] = (u_char)(mac_lo >> 24);
4320		sc->eaddr[3] = (u_char)(mac_lo >> 16);
4321		sc->eaddr[4] = (u_char)(mac_lo >> 8);
4322		sc->eaddr[5] = (u_char)(mac_lo >> 0);
4323	}
4324
4325	DBPRINT(sc, BCE_INFO_MISC, "Permanent Ethernet address = %6D\n", sc->eaddr, ":");
4326	DBEXIT(BCE_VERBOSE_RESET);
4327}
4328
4329
4330/****************************************************************************/
4331/* Program the MAC address.                                                 */
4332/*                                                                          */
4333/* Returns:                                                                 */
4334/*   Nothing.                                                               */
4335/****************************************************************************/
4336static void
4337bce_set_mac_addr(struct bce_softc *sc)
4338{
4339	u32 val;
4340	u8 *mac_addr = sc->eaddr;
4341
4342	/* ToDo: Add support for setting multiple MAC addresses. */
4343
4344	DBENTER(BCE_VERBOSE_RESET);
4345	DBPRINT(sc, BCE_INFO_MISC, "Setting Ethernet address = %6D\n", sc->eaddr, ":");
4346
4347	val = (mac_addr[0] << 8) | mac_addr[1];
4348
4349	REG_WR(sc, BCE_EMAC_MAC_MATCH0, val);
4350
4351	val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
4352		(mac_addr[4] << 8) | mac_addr[5];
4353
4354	REG_WR(sc, BCE_EMAC_MAC_MATCH1, val);
4355
4356	DBEXIT(BCE_VERBOSE_RESET);
4357}
4358
4359
4360/****************************************************************************/
4361/* Stop the controller.                                                     */
4362/*                                                                          */
4363/* Returns:                                                                 */
4364/*   Nothing.                                                               */
4365/****************************************************************************/
4366static void
4367bce_stop(struct bce_softc *sc)
4368{
4369	struct ifnet *ifp;
4370	struct ifmedia_entry *ifm;
4371	struct mii_data *mii = NULL;
4372	int mtmp, itmp;
4373
4374	DBENTER(BCE_VERBOSE_RESET);
4375
4376	BCE_LOCK_ASSERT(sc);
4377
4378	ifp = sc->bce_ifp;
4379
4380	mii = device_get_softc(sc->bce_miibus);
4381
4382	callout_stop(&sc->bce_tick_callout);
4383
4384	/* Disable the transmit/receive blocks. */
4385	REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS, BCE_MISC_ENABLE_CLR_DEFAULT);
4386	REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
4387	DELAY(20);
4388
4389	bce_disable_intr(sc);
4390
4391	/* Free RX buffers. */
4392#ifdef BCE_USE_SPLIT_HEADER
4393	bce_free_pg_chain(sc);
4394#endif
4395	bce_free_rx_chain(sc);
4396
4397	/* Free TX buffers. */
4398	bce_free_tx_chain(sc);
4399
4400	/*
4401	 * Isolate/power down the PHY, but leave the media selection
4402	 * unchanged so that things will be put back to normal when
4403	 * we bring the interface back up.
4404	 */
4405
4406	itmp = ifp->if_flags;
4407	ifp->if_flags |= IFF_UP;
4408
4409	/* If we are called from bce_detach(), mii is already NULL. */
4410	if (mii != NULL) {
4411		ifm = mii->mii_media.ifm_cur;
4412		mtmp = ifm->ifm_media;
4413		ifm->ifm_media = IFM_ETHER | IFM_NONE;
4414		mii_mediachg(mii);
4415		ifm->ifm_media = mtmp;
4416	}
4417
4418	ifp->if_flags = itmp;
4419	sc->watchdog_timer = 0;
4420
4421	sc->bce_link = 0;
4422
4423	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
4424
4425	DBEXIT(BCE_VERBOSE_RESET);
4426}
4427
4428
4429static int
4430bce_reset(struct bce_softc *sc, u32 reset_code)
4431{
4432	u32 val;
4433	int i, rc = 0;
4434
4435	DBENTER(BCE_VERBOSE_RESET);
4436
4437	DBPRINT(sc, BCE_VERBOSE_RESET, "%s(): reset_code = 0x%08X\n",
4438		__FUNCTION__, reset_code);
4439
4440	/* Wait for pending PCI transactions to complete. */
4441	REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS,
4442	       BCE_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
4443	       BCE_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
4444	       BCE_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
4445	       BCE_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
4446	val = REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
4447	DELAY(5);
4448
4449	/* Disable DMA */
4450	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4451		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4452		val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
4453		val &= ~BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
4454		REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
4455	}
4456
4457	/* Assume bootcode is running. */
4458	sc->bce_fw_timed_out = 0;
4459
4460	/* Give the firmware a chance to prepare for the reset. */
4461	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT0 | reset_code);
4462	if (rc)
4463		goto bce_reset_exit;
4464
4465	/* Set a firmware reminder that this is a soft reset. */
4466	REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_RESET_SIGNATURE,
4467		   BCE_DRV_RESET_SIGNATURE_MAGIC);
4468
4469	/* Dummy read to force the chip to complete all current transactions. */
4470	val = REG_RD(sc, BCE_MISC_ID);
4471
4472	/* Chip reset. */
4473	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4474		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4475		REG_WR(sc, BCE_MISC_COMMAND, BCE_MISC_COMMAND_SW_RESET);
4476		REG_RD(sc, BCE_MISC_COMMAND);
4477		DELAY(5);
4478
4479		val = BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
4480		      BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
4481
4482		pci_write_config(sc->bce_dev, BCE_PCICFG_MISC_CONFIG, val, 4);
4483	} else {
4484		val = BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4485			BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
4486			BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
4487		REG_WR(sc, BCE_PCICFG_MISC_CONFIG, val);
4488
4489		/* Allow up to 30us for reset to complete. */
4490		for (i = 0; i < 10; i++) {
4491			val = REG_RD(sc, BCE_PCICFG_MISC_CONFIG);
4492			if ((val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4493				BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
4494				break;
4495			}
4496			DELAY(10);
4497		}
4498
4499		/* Check that reset completed successfully. */
4500		if (val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4501			BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
4502			BCE_PRINTF("%s(%d): Reset failed!\n",
4503				__FILE__, __LINE__);
4504			rc = EBUSY;
4505			goto bce_reset_exit;
4506		}
4507	}
4508
4509	/* Make sure byte swapping is properly configured. */
4510	val = REG_RD(sc, BCE_PCI_SWAP_DIAG0);
4511	if (val != 0x01020304) {
4512		BCE_PRINTF("%s(%d): Byte swap is incorrect!\n",
4513			__FILE__, __LINE__);
4514		rc = ENODEV;
4515		goto bce_reset_exit;
4516	}
4517
4518	/* Just completed a reset, assume that firmware is running again. */
4519	sc->bce_fw_timed_out = 0;
4520
4521	/* Wait for the firmware to finish its initialization. */
4522	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT1 | reset_code);
4523	if (rc)
4524		BCE_PRINTF("%s(%d): Firmware did not complete initialization!\n",
4525			__FILE__, __LINE__);
4526
4527bce_reset_exit:
4528	DBEXIT(BCE_VERBOSE_RESET);
4529	return (rc);
4530}
4531
4532
4533static int
4534bce_chipinit(struct bce_softc *sc)
4535{
4536	u32 val;
4537	int rc = 0;
4538
4539	DBENTER(BCE_VERBOSE_RESET);
4540
4541	bce_disable_intr(sc);
4542
4543	/*
4544	 * Initialize DMA byte/word swapping, configure the number of DMA
4545	 * channels and PCI clock compensation delay.
4546	 */
4547	val = BCE_DMA_CONFIG_DATA_BYTE_SWAP |
4548	      BCE_DMA_CONFIG_DATA_WORD_SWAP |
4549#if BYTE_ORDER == BIG_ENDIAN
4550	      BCE_DMA_CONFIG_CNTL_BYTE_SWAP |
4551#endif
4552	      BCE_DMA_CONFIG_CNTL_WORD_SWAP |
4553	      DMA_READ_CHANS << 12 |
4554	      DMA_WRITE_CHANS << 16;
4555
4556	val |= (0x2 << 20) | BCE_DMA_CONFIG_CNTL_PCI_COMP_DLY;
4557
4558	if ((sc->bce_flags & BCE_PCIX_FLAG) && (sc->bus_speed_mhz == 133))
4559		val |= BCE_DMA_CONFIG_PCI_FAST_CLK_CMP;
4560
4561	/*
4562	 * This setting resolves a problem observed on certain Intel PCI
4563	 * chipsets that cannot handle multiple outstanding DMA operations.
4564	 * See errata E9_5706A1_65.
4565	 */
4566	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
4567	    (BCE_CHIP_ID(sc) != BCE_CHIP_ID_5706_A0) &&
4568	    !(sc->bce_flags & BCE_PCIX_FLAG))
4569		val |= BCE_DMA_CONFIG_CNTL_PING_PONG_DMA;
4570
4571	REG_WR(sc, BCE_DMA_CONFIG, val);
4572
4573	/* Enable the RX_V2P and Context state machines before access. */
4574	REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
4575	       BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
4576	       BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
4577	       BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
4578
4579	/* Initialize context mapping and zero out the quick contexts. */
4580	bce_init_ctx(sc);
4581
4582	/* Initialize the on-boards CPUs */
4583	bce_init_cpus(sc);
4584
4585	/* Prepare NVRAM for access. */
4586	if (bce_init_nvram(sc)) {
4587		rc = ENODEV;
4588		goto bce_chipinit_exit;
4589	}
4590
4591	/* Set the kernel bypass block size */
4592	val = REG_RD(sc, BCE_MQ_CONFIG);
4593	val &= ~BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE;
4594	val |= BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
4595
4596	/* Enable bins used on the 5709. */
4597	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4598		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4599		val |= BCE_MQ_CONFIG_BIN_MQ_MODE;
4600		if (BCE_CHIP_ID(sc) == BCE_CHIP_ID_5709_A1)
4601			val |= BCE_MQ_CONFIG_HALT_DIS;
4602	}
4603
4604	REG_WR(sc, BCE_MQ_CONFIG, val);
4605
4606	val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
4607	REG_WR(sc, BCE_MQ_KNL_BYP_WIND_START, val);
4608	REG_WR(sc, BCE_MQ_KNL_WIND_END, val);
4609
4610	/* Set the page size and clear the RV2P processor stall bits. */
4611	val = (BCM_PAGE_BITS - 8) << 24;
4612	REG_WR(sc, BCE_RV2P_CONFIG, val);
4613
4614	/* Configure page size. */
4615	val = REG_RD(sc, BCE_TBDR_CONFIG);
4616	val &= ~BCE_TBDR_CONFIG_PAGE_SIZE;
4617	val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
4618	REG_WR(sc, BCE_TBDR_CONFIG, val);
4619
4620	/* Set the perfect match control register to default. */
4621	REG_WR_IND(sc, BCE_RXP_PM_CTRL, 0);
4622
4623bce_chipinit_exit:
4624	DBEXIT(BCE_VERBOSE_RESET);
4625
4626	return(rc);
4627}
4628
4629
4630/****************************************************************************/
4631/* Initialize the controller in preparation to send/receive traffic.        */
4632/*                                                                          */
4633/* Returns:                                                                 */
4634/*   0 for success, positive value for failure.                             */
4635/****************************************************************************/
4636static int
4637bce_blockinit(struct bce_softc *sc)
4638{
4639	u32 reg, val;
4640	int rc = 0;
4641
4642	DBENTER(BCE_VERBOSE_RESET);
4643
4644	/* Load the hardware default MAC address. */
4645	bce_set_mac_addr(sc);
4646
4647	/* Set the Ethernet backoff seed value */
4648	val = sc->eaddr[0]         + (sc->eaddr[1] << 8) +
4649	      (sc->eaddr[2] << 16) + (sc->eaddr[3]     ) +
4650	      (sc->eaddr[4] << 8)  + (sc->eaddr[5] << 16);
4651	REG_WR(sc, BCE_EMAC_BACKOFF_SEED, val);
4652
4653	sc->last_status_idx = 0;
4654	sc->rx_mode = BCE_EMAC_RX_MODE_SORT_MODE;
4655
4656	/* Set up link change interrupt generation. */
4657	REG_WR(sc, BCE_EMAC_ATTENTION_ENA, BCE_EMAC_ATTENTION_ENA_LINK);
4658
4659	/* Program the physical address of the status block. */
4660	REG_WR(sc, BCE_HC_STATUS_ADDR_L,
4661		BCE_ADDR_LO(sc->status_block_paddr));
4662	REG_WR(sc, BCE_HC_STATUS_ADDR_H,
4663		BCE_ADDR_HI(sc->status_block_paddr));
4664
4665	/* Program the physical address of the statistics block. */
4666	REG_WR(sc, BCE_HC_STATISTICS_ADDR_L,
4667		BCE_ADDR_LO(sc->stats_block_paddr));
4668	REG_WR(sc, BCE_HC_STATISTICS_ADDR_H,
4669		BCE_ADDR_HI(sc->stats_block_paddr));
4670
4671	/* Program various host coalescing parameters. */
4672	REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
4673		(sc->bce_tx_quick_cons_trip_int << 16) | sc->bce_tx_quick_cons_trip);
4674	REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
4675		(sc->bce_rx_quick_cons_trip_int << 16) | sc->bce_rx_quick_cons_trip);
4676	REG_WR(sc, BCE_HC_COMP_PROD_TRIP,
4677		(sc->bce_comp_prod_trip_int << 16) | sc->bce_comp_prod_trip);
4678	REG_WR(sc, BCE_HC_TX_TICKS,
4679		(sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
4680	REG_WR(sc, BCE_HC_RX_TICKS,
4681		(sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
4682	REG_WR(sc, BCE_HC_COM_TICKS,
4683		(sc->bce_com_ticks_int << 16) | sc->bce_com_ticks);
4684	REG_WR(sc, BCE_HC_CMD_TICKS,
4685		(sc->bce_cmd_ticks_int << 16) | sc->bce_cmd_ticks);
4686	REG_WR(sc, BCE_HC_STATS_TICKS,
4687		(sc->bce_stats_ticks & 0xffff00));
4688	REG_WR(sc, BCE_HC_STAT_COLLECT_TICKS, 0xbb8);  /* 3ms */
4689
4690	/* Configure the Host Coalescing block. */
4691	val = BCE_HC_CONFIG_RX_TMR_MODE | BCE_HC_CONFIG_TX_TMR_MODE |
4692		      BCE_HC_CONFIG_COLLECT_STATS;
4693
4694#if 0
4695	/* ToDo: Add MSI-X support. */
4696	if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
4697		u32 base = ((BCE_TX_VEC - 1) * BCE_HC_SB_CONFIG_SIZE) +
4698			   BCE_HC_SB_CONFIG_1;
4699
4700		REG_WR(sc, BCE_HC_MSIX_BIT_VECTOR, BCE_HC_MSIX_BIT_VECTOR_VAL);
4701
4702		REG_WR(sc, base, BCE_HC_SB_CONFIG_1_TX_TMR_MODE |
4703			BCE_HC_SB_CONFIG_1_ONE_SHOT);
4704
4705		REG_WR(sc, base + BCE_HC_TX_QUICK_CONS_TRIP_OFF,
4706			(sc->tx_quick_cons_trip_int << 16) |
4707			 sc->tx_quick_cons_trip);
4708
4709		REG_WR(sc, base + BCE_HC_TX_TICKS_OFF,
4710			(sc->tx_ticks_int << 16) | sc->tx_ticks);
4711
4712		val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
4713	}
4714
4715	/*
4716	 * Tell the HC block to automatically set the
4717	 * INT_MASK bit after an MSI/MSI-X interrupt
4718	 * is generated so the driver doesn't have to.
4719	 */
4720	if (sc->bce_flags & BCE_ONE_SHOT_MSI_FLAG)
4721		val |= BCE_HC_CONFIG_ONE_SHOT;
4722
4723	/* Set the MSI-X status blocks to 128 byte boundaries. */
4724	if (sc->bce_flags & BCE_USING_MSIX_FLAG)
4725		val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
4726#endif
4727
4728	REG_WR(sc, BCE_HC_CONFIG, val);
4729
4730	/* Clear the internal statistics counters. */
4731	REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
4732
4733	/* Verify that bootcode is running. */
4734	reg = REG_RD_IND(sc, sc->bce_shmem_base + BCE_DEV_INFO_SIGNATURE);
4735
4736	DBRUNIF(DB_RANDOMTRUE(bce_debug_bootcode_running_failure),
4737		BCE_PRINTF("%s(%d): Simulating bootcode failure.\n",
4738			__FILE__, __LINE__);
4739		reg = 0);
4740
4741	if ((reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
4742	    BCE_DEV_INFO_SIGNATURE_MAGIC) {
4743		BCE_PRINTF("%s(%d): Bootcode not running! Found: 0x%08X, "
4744			"Expected: 08%08X\n", __FILE__, __LINE__,
4745			(reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK),
4746			BCE_DEV_INFO_SIGNATURE_MAGIC);
4747		rc = ENODEV;
4748		goto bce_blockinit_exit;
4749	}
4750
4751	/* Enable DMA */
4752	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4753		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4754		val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
4755		val |= BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
4756		REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
4757	}
4758
4759	/* Allow bootcode to apply any additional fixes before enabling MAC. */
4760	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 | BCE_DRV_MSG_CODE_RESET);
4761
4762	/* Enable link state change interrupt generation. */
4763	REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
4764
4765	/* Enable all remaining blocks in the MAC. */
4766	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)	||
4767		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
4768		REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT_XI);
4769	else
4770		REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT);
4771
4772	REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
4773	DELAY(20);
4774
4775	/* Save the current host coalescing block settings. */
4776	sc->hc_command = REG_RD(sc, BCE_HC_COMMAND);
4777
4778bce_blockinit_exit:
4779	DBEXIT(BCE_VERBOSE_RESET);
4780
4781	return (rc);
4782}
4783
4784
4785/****************************************************************************/
4786/* Encapsulate an mbuf into the rx_bd chain.                                */
4787/*                                                                          */
4788/* Returns:                                                                 */
4789/*   0 for success, positive value for failure.                             */
4790/****************************************************************************/
4791static int
4792bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
4793	u16 *chain_prod, u32 *prod_bseq)
4794{
4795	bus_dmamap_t map;
4796	bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
4797	struct mbuf *m_new = NULL;
4798	struct rx_bd *rxbd;
4799	int nsegs, error, rc = 0;
4800#ifdef BCE_DEBUG
4801	u16 debug_chain_prod = *chain_prod;
4802#endif
4803
4804	DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
4805
4806	/* Make sure the inputs are valid. */
4807	DBRUNIF((*chain_prod > MAX_RX_BD),
4808		BCE_PRINTF("%s(%d): RX producer out of range: 0x%04X > 0x%04X\n",
4809		__FILE__, __LINE__, *chain_prod, (u16) MAX_RX_BD));
4810
4811	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, chain_prod = 0x%04X, "
4812		"prod_bseq = 0x%08X\n", __FUNCTION__, *prod, *chain_prod, *prod_bseq);
4813
4814	/* Update some debug statistic counters */
4815	DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
4816		sc->rx_low_watermark = sc->free_rx_bd);
4817	DBRUNIF((sc->free_rx_bd == sc->max_rx_bd), sc->rx_empty_count++);
4818
4819	/* Check whether this is a new mbuf allocation. */
4820	if (m == NULL) {
4821
4822		/* Simulate an mbuf allocation failure. */
4823		DBRUNIF(DB_RANDOMTRUE(bce_debug_mbuf_allocation_failure),
4824			sc->mbuf_alloc_failed++;
4825			sc->debug_mbuf_sim_alloc_failed++;
4826			rc = ENOBUFS;
4827			goto bce_get_rx_buf_exit);
4828
4829		/* This is a new mbuf allocation. */
4830#ifdef BCE_USE_SPLIT_HEADER
4831		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
4832#else
4833		if (sc->rx_bd_mbuf_alloc_size <= MCLBYTES)
4834			m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
4835		else
4836			m_new = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, sc->rx_bd_mbuf_alloc_size);
4837#endif
4838
4839		if (m_new == NULL) {
4840			sc->mbuf_alloc_failed++;
4841			rc = ENOBUFS;
4842			goto bce_get_rx_buf_exit;
4843		}
4844
4845		DBRUN(sc->debug_rx_mbuf_alloc++);
4846	} else {
4847		/* Reuse an existing mbuf. */
4848		m_new = m;
4849	}
4850
4851	/* Make sure we have a valid packet header. */
4852	M_ASSERTPKTHDR(m_new);
4853
4854	/* Initialize the mbuf size and pad if necessary for alignment. */
4855	m_new->m_pkthdr.len = m_new->m_len = sc->rx_bd_mbuf_alloc_size;
4856	m_adj(m_new, sc->rx_bd_mbuf_align_pad);
4857
4858	/* ToDo: Consider calling m_fragment() to test error handling. */
4859
4860	/* Map the mbuf cluster into device memory. */
4861	map = sc->rx_mbuf_map[*chain_prod];
4862	error = bus_dmamap_load_mbuf_sg(sc->rx_mbuf_tag, map, m_new,
4863	    segs, &nsegs, BUS_DMA_NOWAIT);
4864
4865	/* Handle any mapping errors. */
4866	if (error) {
4867		BCE_PRINTF("%s(%d): Error mapping mbuf into RX chain (%d)!\n",
4868			__FILE__, __LINE__, error);
4869
4870		m_freem(m_new);
4871		DBRUN(sc->debug_rx_mbuf_alloc--);
4872
4873		rc = ENOBUFS;
4874		goto bce_get_rx_buf_exit;
4875	}
4876
4877	/* All mbufs must map to a single segment. */
4878	KASSERT(nsegs == 1, ("%s(): Too many segments returned (%d)!",
4879		 __FUNCTION__, nsegs));
4880
4881	/* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREWRITE) here? */
4882
4883	/* Setup the rx_bd for the segment. */
4884	rxbd = &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
4885
4886	rxbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(segs[0].ds_addr));
4887	rxbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(segs[0].ds_addr));
4888	rxbd->rx_bd_len       = htole32(segs[0].ds_len);
4889	rxbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
4890	*prod_bseq += segs[0].ds_len;
4891
4892	/* Save the mbuf and update our counter. */
4893	sc->rx_mbuf_ptr[*chain_prod] = m_new;
4894	sc->free_rx_bd -= nsegs;
4895
4896	DBRUNMSG(BCE_INSANE_RECV, bce_dump_rx_mbuf_chain(sc, debug_chain_prod,
4897		nsegs));
4898
4899	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, chain_prod = 0x%04X, "
4900		"prod_bseq = 0x%08X\n", __FUNCTION__, *prod, *chain_prod, *prod_bseq);
4901
4902bce_get_rx_buf_exit:
4903	DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
4904
4905	return(rc);
4906}
4907
4908
4909#ifdef BCE_USE_SPLIT_HEADER
4910/****************************************************************************/
4911/* Encapsulate an mbuf cluster into the page chain.                        */
4912/*                                                                          */
4913/* Returns:                                                                 */
4914/*   0 for success, positive value for failure.                             */
4915/****************************************************************************/
4916static int
4917bce_get_pg_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
4918	u16 *prod_idx)
4919{
4920	bus_dmamap_t map;
4921	bus_addr_t busaddr;
4922	struct mbuf *m_new = NULL;
4923	struct rx_bd *pgbd;
4924	int error, rc = 0;
4925#ifdef BCE_DEBUG
4926	u16 debug_prod_idx = *prod_idx;
4927#endif
4928
4929	DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
4930
4931	/* Make sure the inputs are valid. */
4932	DBRUNIF((*prod_idx > MAX_PG_BD),
4933		BCE_PRINTF("%s(%d): page producer out of range: 0x%04X > 0x%04X\n",
4934		__FILE__, __LINE__, *prod_idx, (u16) MAX_PG_BD));
4935
4936	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
4937		"chain_prod = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
4938
4939	/* Update counters if we've hit a new low or run out of pages. */
4940	DBRUNIF((sc->free_pg_bd < sc->pg_low_watermark),
4941		sc->pg_low_watermark = sc->free_pg_bd);
4942	DBRUNIF((sc->free_pg_bd == sc->max_pg_bd), sc->pg_empty_count++);
4943
4944	/* Check whether this is a new mbuf allocation. */
4945	if (m == NULL) {
4946
4947		/* Simulate an mbuf allocation failure. */
4948		DBRUNIF(DB_RANDOMTRUE(bce_debug_mbuf_allocation_failure),
4949			sc->mbuf_alloc_failed++;
4950			sc->debug_mbuf_sim_alloc_failed++;
4951			rc = ENOBUFS;
4952			goto bce_get_pg_buf_exit);
4953
4954		/* This is a new mbuf allocation. */
4955		m_new = m_getcl(M_DONTWAIT, MT_DATA, 0);
4956		if (m_new == NULL) {
4957			sc->mbuf_alloc_failed++;
4958			rc = ENOBUFS;
4959			goto bce_get_pg_buf_exit;
4960		}
4961
4962		DBRUN(sc->debug_pg_mbuf_alloc++);
4963	} else {
4964		/* Reuse an existing mbuf. */
4965		m_new = m;
4966		m_new->m_data = m_new->m_ext.ext_buf;
4967	}
4968
4969	m_new->m_len = sc->pg_bd_mbuf_alloc_size;
4970
4971	/* ToDo: Consider calling m_fragment() to test error handling. */
4972
4973	/* Map the mbuf cluster into device memory. */
4974	map = sc->pg_mbuf_map[*prod_idx];
4975	error = bus_dmamap_load(sc->pg_mbuf_tag, map, mtod(m_new, void *),
4976	    sc->pg_bd_mbuf_alloc_size, bce_dma_map_addr, &busaddr, BUS_DMA_NOWAIT);
4977
4978	/* Handle any mapping errors. */
4979	if (error) {
4980		BCE_PRINTF("%s(%d): Error mapping mbuf into page chain!\n",
4981			__FILE__, __LINE__);
4982
4983		m_freem(m_new);
4984		DBRUN(sc->debug_pg_mbuf_alloc--);
4985
4986		rc = ENOBUFS;
4987		goto bce_get_pg_buf_exit;
4988	}
4989
4990	/* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREWRITE) here? */
4991
4992	/*
4993	 * The page chain uses the same rx_bd data structure
4994	 * as the receive chain but doesn't require a byte sequence (bseq).
4995	 */
4996	pgbd = &sc->pg_bd_chain[PG_PAGE(*prod_idx)][PG_IDX(*prod_idx)];
4997
4998	pgbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(busaddr));
4999	pgbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(busaddr));
5000	pgbd->rx_bd_len       = htole32(sc->pg_bd_mbuf_alloc_size);
5001	pgbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
5002
5003	/* Save the mbuf and update our counter. */
5004	sc->pg_mbuf_ptr[*prod_idx] = m_new;
5005	sc->free_pg_bd--;
5006
5007	DBRUNMSG(BCE_INSANE_RECV, bce_dump_pg_mbuf_chain(sc, debug_prod_idx,
5008		1));
5009
5010	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
5011		"prod_idx = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
5012
5013bce_get_pg_buf_exit:
5014	DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5015
5016	return(rc);
5017}
5018#endif /* BCE_USE_SPLIT_HEADER */
5019
5020/****************************************************************************/
5021/* Initialize the TX context memory.                                        */
5022/*                                                                          */
5023/* Returns:                                                                 */
5024/*   Nothing                                                                */
5025/****************************************************************************/
5026static void
5027bce_init_tx_context(struct bce_softc *sc)
5028{
5029	u32 val;
5030
5031	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
5032
5033	/* Initialize the context ID for an L2 TX chain. */
5034	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
5035		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
5036		/* Set the CID type to support an L2 connection. */
5037		val = BCE_L2CTX_TX_TYPE_TYPE_L2_XI | BCE_L2CTX_TX_TYPE_SIZE_L2_XI;
5038		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE_XI, val);
5039		val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2_XI | (8 << 16);
5040		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_CMD_TYPE_XI, val);
5041
5042		/* Point the hardware to the first page in the chain. */
5043		val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
5044		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_HI_XI, val);
5045		val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
5046		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_LO_XI, val);
5047	} else {
5048		/* Set the CID type to support an L2 connection. */
5049		val = BCE_L2CTX_TX_TYPE_TYPE_L2 | BCE_L2CTX_TX_TYPE_SIZE_L2;
5050		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE, val);
5051		val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2 | (8 << 16);
5052		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_CMD_TYPE, val);
5053
5054		/* Point the hardware to the first page in the chain. */
5055		val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
5056		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_HI, val);
5057		val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
5058		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_LO, val);
5059	}
5060
5061	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
5062}
5063
5064
5065/****************************************************************************/
5066/* Allocate memory and initialize the TX data structures.                   */
5067/*                                                                          */
5068/* Returns:                                                                 */
5069/*   0 for success, positive value for failure.                             */
5070/****************************************************************************/
5071static int
5072bce_init_tx_chain(struct bce_softc *sc)
5073{
5074	struct tx_bd *txbd;
5075	int i, rc = 0;
5076
5077	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
5078
5079	/* Set the initial TX producer/consumer indices. */
5080	sc->tx_prod        = 0;
5081	sc->tx_cons        = 0;
5082	sc->tx_prod_bseq   = 0;
5083	sc->used_tx_bd     = 0;
5084	sc->max_tx_bd      = USABLE_TX_BD;
5085	DBRUN(sc->tx_hi_watermark = USABLE_TX_BD);
5086	DBRUN(sc->tx_full_count = 0);
5087
5088	/*
5089	 * The NetXtreme II supports a linked-list structre called
5090	 * a Buffer Descriptor Chain (or BD chain).  A BD chain
5091	 * consists of a series of 1 or more chain pages, each of which
5092	 * consists of a fixed number of BD entries.
5093	 * The last BD entry on each page is a pointer to the next page
5094	 * in the chain, and the last pointer in the BD chain
5095	 * points back to the beginning of the chain.
5096	 */
5097
5098	/* Set the TX next pointer chain entries. */
5099	for (i = 0; i < TX_PAGES; i++) {
5100		int j;
5101
5102		txbd = &sc->tx_bd_chain[i][USABLE_TX_BD_PER_PAGE];
5103
5104		/* Check if we've reached the last page. */
5105		if (i == (TX_PAGES - 1))
5106			j = 0;
5107		else
5108			j = i + 1;
5109
5110		txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->tx_bd_chain_paddr[j]));
5111		txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->tx_bd_chain_paddr[j]));
5112	}
5113
5114	bce_init_tx_context(sc);
5115
5116	DBRUNMSG(BCE_INSANE_SEND, bce_dump_tx_chain(sc, 0, TOTAL_TX_BD));
5117	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
5118
5119	return(rc);
5120}
5121
5122
5123/****************************************************************************/
5124/* Free memory and clear the TX data structures.                            */
5125/*                                                                          */
5126/* Returns:                                                                 */
5127/*   Nothing.                                                               */
5128/****************************************************************************/
5129static void
5130bce_free_tx_chain(struct bce_softc *sc)
5131{
5132	int i;
5133
5134	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
5135
5136	/* Unmap, unload, and free any mbufs still in the TX mbuf chain. */
5137	for (i = 0; i < TOTAL_TX_BD; i++) {
5138		if (sc->tx_mbuf_ptr[i] != NULL) {
5139			if (sc->tx_mbuf_map[i] != NULL)
5140				bus_dmamap_sync(sc->tx_mbuf_tag, sc->tx_mbuf_map[i],
5141					BUS_DMASYNC_POSTWRITE);
5142			m_freem(sc->tx_mbuf_ptr[i]);
5143			sc->tx_mbuf_ptr[i] = NULL;
5144			DBRUN(sc->debug_tx_mbuf_alloc--);
5145		}
5146	}
5147
5148	/* Clear each TX chain page. */
5149	for (i = 0; i < TX_PAGES; i++)
5150		bzero((char *)sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ);
5151
5152	sc->used_tx_bd     = 0;
5153
5154	/* Check if we lost any mbufs in the process. */
5155	DBRUNIF((sc->debug_tx_mbuf_alloc),
5156		BCE_PRINTF("%s(%d): Memory leak! Lost %d mbufs "
5157			"from tx chain!\n",
5158			__FILE__, __LINE__, sc->debug_tx_mbuf_alloc));
5159
5160	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
5161}
5162
5163
5164/****************************************************************************/
5165/* Initialize the RX context memory.                                        */
5166/*                                                                          */
5167/* Returns:                                                                 */
5168/*   Nothing                                                                */
5169/****************************************************************************/
5170static void
5171bce_init_rx_context(struct bce_softc *sc)
5172{
5173	u32 val;
5174
5175	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
5176
5177	/* Initialize the type, size, and BD cache levels for the RX context. */
5178	val = BCE_L2CTX_RX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE |
5179		BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 |
5180		(0x02 << BCE_L2CTX_RX_BD_PRE_READ_SHIFT);
5181
5182	/*
5183	 * Set the level for generating pause frames
5184	 * when the number of available rx_bd's gets
5185	 * too low (the low watermark) and the level
5186	 * when pause frames can be stopped (the high
5187	 * watermark).
5188	 */
5189	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
5190		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
5191		u32 lo_water, hi_water;
5192
5193		lo_water = BCE_L2CTX_RX_LO_WATER_MARK_DEFAULT;
5194		hi_water = USABLE_RX_BD / 4;
5195
5196		lo_water /= BCE_L2CTX_RX_LO_WATER_MARK_SCALE;
5197		hi_water /= BCE_L2CTX_RX_HI_WATER_MARK_SCALE;
5198
5199		if (hi_water > 0xf)
5200			hi_water = 0xf;
5201		else if (hi_water == 0)
5202			lo_water = 0;
5203		val |= (lo_water << BCE_L2CTX_RX_LO_WATER_MARK_SHIFT) |
5204			(hi_water << BCE_L2CTX_RX_HI_WATER_MARK_SHIFT);
5205	}
5206
5207 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_CTX_TYPE, val);
5208
5209	/* Setup the MQ BIN mapping for l2_ctx_host_bseq. */
5210	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
5211		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
5212		val = REG_RD(sc, BCE_MQ_MAP_L2_5);
5213		REG_WR(sc, BCE_MQ_MAP_L2_5, val | BCE_MQ_MAP_L2_5_ARM);
5214	}
5215
5216	/* Point the hardware to the first page in the chain. */
5217	val = BCE_ADDR_HI(sc->rx_bd_chain_paddr[0]);
5218	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_HI, val);
5219	val = BCE_ADDR_LO(sc->rx_bd_chain_paddr[0]);
5220	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_LO, val);
5221
5222	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
5223}
5224
5225
5226/****************************************************************************/
5227/* Allocate memory and initialize the RX data structures.                   */
5228/*                                                                          */
5229/* Returns:                                                                 */
5230/*   0 for success, positive value for failure.                             */
5231/****************************************************************************/
5232static int
5233bce_init_rx_chain(struct bce_softc *sc)
5234{
5235	struct rx_bd *rxbd;
5236	int i, rc = 0;
5237
5238	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5239		BCE_VERBOSE_CTX);
5240
5241	/* Initialize the RX producer and consumer indices. */
5242	sc->rx_prod        = 0;
5243	sc->rx_cons        = 0;
5244	sc->rx_prod_bseq   = 0;
5245	sc->free_rx_bd     = USABLE_RX_BD;
5246	sc->max_rx_bd      = USABLE_RX_BD;
5247	DBRUN(sc->rx_low_watermark = sc->max_rx_bd);
5248	DBRUN(sc->rx_empty_count = 0);
5249
5250	/* Initialize the RX next pointer chain entries. */
5251	for (i = 0; i < RX_PAGES; i++) {
5252		int j;
5253
5254		rxbd = &sc->rx_bd_chain[i][USABLE_RX_BD_PER_PAGE];
5255
5256		/* Check if we've reached the last page. */
5257		if (i == (RX_PAGES - 1))
5258			j = 0;
5259		else
5260			j = i + 1;
5261
5262		/* Setup the chain page pointers. */
5263		rxbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j]));
5264		rxbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j]));
5265	}
5266
5267/* Fill up the RX chain. */
5268	bce_fill_rx_chain(sc);
5269
5270	for (i = 0; i < RX_PAGES; i++) {
5271		bus_dmamap_sync(
5272			sc->rx_bd_chain_tag,
5273	    	sc->rx_bd_chain_map[i],
5274		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
5275	}
5276
5277	bce_init_rx_context(sc);
5278
5279	DBRUNMSG(BCE_EXTREME_RECV, bce_dump_rx_chain(sc, 0, TOTAL_RX_BD));
5280	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5281		BCE_VERBOSE_CTX);
5282	/* ToDo: Are there possible failure modes here? */
5283	return(rc);
5284}
5285
5286
5287/****************************************************************************/
5288/* Add mbufs to the RX chain until its full or an mbuf allocation error     */
5289/* occurs.                                                                  */
5290/*                                                                          */
5291/* Returns:                                                                 */
5292/*   Nothing                                                                */
5293/****************************************************************************/
5294static void
5295bce_fill_rx_chain(struct bce_softc *sc)
5296{
5297	u16 prod, prod_idx;
5298	u32 prod_bseq;
5299
5300	DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5301		BCE_VERBOSE_CTX);
5302
5303	/* Get the RX chain producer indices. */
5304	prod      = sc->rx_prod;
5305	prod_bseq = sc->rx_prod_bseq;
5306
5307	/* Keep filling the RX chain until it's full. */
5308	while (sc->free_rx_bd > 0) {
5309		prod_idx = RX_CHAIN_IDX(prod);
5310		if (bce_get_rx_buf(sc, NULL, &prod, &prod_idx, &prod_bseq)) {
5311			/* Bail out if we can't add an mbuf to the chain. */
5312			break;
5313		}
5314		prod = NEXT_RX_BD(prod);
5315	}
5316
5317	/* Save the RX chain producer indices. */
5318	sc->rx_prod      = prod;
5319	sc->rx_prod_bseq = prod_bseq;
5320
5321	DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
5322		BCE_PRINTF("%s(): Invalid rx_prod value: 0x%04X\n",
5323		__FUNCTION__, sc->rx_prod));
5324
5325	/* Write the mailbox and tell the chip about the waiting rx_bd's. */
5326	REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BDIDX,
5327		sc->rx_prod);
5328	REG_WR(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BSEQ,
5329		sc->rx_prod_bseq);
5330
5331	DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5332		BCE_VERBOSE_CTX);
5333}
5334
5335
5336/****************************************************************************/
5337/* Free memory and clear the RX data structures.                            */
5338/*                                                                          */
5339/* Returns:                                                                 */
5340/*   Nothing.                                                               */
5341/****************************************************************************/
5342static void
5343bce_free_rx_chain(struct bce_softc *sc)
5344{
5345	int i;
5346
5347	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5348
5349	/* Free any mbufs still in the RX mbuf chain. */
5350	for (i = 0; i < TOTAL_RX_BD; i++) {
5351		if (sc->rx_mbuf_ptr[i] != NULL) {
5352			if (sc->rx_mbuf_map[i] != NULL)
5353				bus_dmamap_sync(sc->rx_mbuf_tag, sc->rx_mbuf_map[i],
5354					BUS_DMASYNC_POSTREAD);
5355			m_freem(sc->rx_mbuf_ptr[i]);
5356			sc->rx_mbuf_ptr[i] = NULL;
5357			DBRUN(sc->debug_rx_mbuf_alloc--);
5358		}
5359	}
5360
5361	/* Clear each RX chain page. */
5362	for (i = 0; i < RX_PAGES; i++)
5363		bzero((char *)sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ);
5364
5365	sc->free_rx_bd = sc->max_rx_bd;
5366
5367	/* Check if we lost any mbufs in the process. */
5368	DBRUNIF((sc->debug_rx_mbuf_alloc),
5369		BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from rx chain!\n",
5370			__FUNCTION__, sc->debug_rx_mbuf_alloc));
5371
5372	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5373}
5374
5375
5376#ifdef BCE_USE_SPLIT_HEADER
5377/****************************************************************************/
5378/* Allocate memory and initialize the page data structures.                 */
5379/* Assumes that bce_init_rx_chain() has not already been called.            */
5380/*                                                                          */
5381/* Returns:                                                                 */
5382/*   0 for success, positive value for failure.                             */
5383/****************************************************************************/
5384static int
5385bce_init_pg_chain(struct bce_softc *sc)
5386{
5387	struct rx_bd *pgbd;
5388	int i, rc = 0;
5389	u32 val;
5390
5391	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5392		BCE_VERBOSE_CTX);
5393
5394	/* Initialize the page producer and consumer indices. */
5395	sc->pg_prod        = 0;
5396	sc->pg_cons        = 0;
5397	sc->free_pg_bd     = USABLE_PG_BD;
5398	sc->max_pg_bd      = USABLE_PG_BD;
5399	DBRUN(sc->pg_low_watermark = sc->max_pg_bd);
5400	DBRUN(sc->pg_empty_count = 0);
5401
5402	/* Initialize the page next pointer chain entries. */
5403	for (i = 0; i < PG_PAGES; i++) {
5404		int j;
5405
5406		pgbd = &sc->pg_bd_chain[i][USABLE_PG_BD_PER_PAGE];
5407
5408		/* Check if we've reached the last page. */
5409		if (i == (PG_PAGES - 1))
5410			j = 0;
5411		else
5412			j = i + 1;
5413
5414		/* Setup the chain page pointers. */
5415		pgbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->pg_bd_chain_paddr[j]));
5416		pgbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->pg_bd_chain_paddr[j]));
5417	}
5418
5419	/* Setup the MQ BIN mapping for host_pg_bidx. */
5420	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)	||
5421		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
5422		REG_WR(sc, BCE_MQ_MAP_L2_3, BCE_MQ_MAP_L2_3_DEFAULT);
5423
5424	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, 0);
5425
5426	/* Configure the rx_bd and page chain mbuf cluster size. */
5427	val = (sc->rx_bd_mbuf_data_len << 16) | sc->pg_bd_mbuf_alloc_size;
5428	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, val);
5429
5430	/* Configure the context reserved for jumbo support. */
5431	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_RBDC_KEY,
5432		BCE_L2CTX_RX_RBDC_JUMBO_KEY);
5433
5434	/* Point the hardware to the first page in the page chain. */
5435	val = BCE_ADDR_HI(sc->pg_bd_chain_paddr[0]);
5436	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_HI, val);
5437	val = BCE_ADDR_LO(sc->pg_bd_chain_paddr[0]);
5438	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_LO, val);
5439
5440	/* Fill up the page chain. */
5441	bce_fill_pg_chain(sc);
5442
5443	for (i = 0; i < PG_PAGES; i++) {
5444		bus_dmamap_sync(
5445			sc->pg_bd_chain_tag,
5446	    	sc->pg_bd_chain_map[i],
5447		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
5448	}
5449
5450	DBRUNMSG(BCE_EXTREME_RECV, bce_dump_pg_chain(sc, 0, TOTAL_PG_BD));
5451	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5452		BCE_VERBOSE_CTX);
5453	return(rc);
5454}
5455
5456
5457/****************************************************************************/
5458/* Add mbufs to the page chain until its full or an mbuf allocation error   */
5459/* occurs.                                                                  */
5460/*                                                                          */
5461/* Returns:                                                                 */
5462/*   Nothing                                                                */
5463/****************************************************************************/
5464static void
5465bce_fill_pg_chain(struct bce_softc *sc)
5466{
5467	u16 prod, prod_idx;
5468
5469	DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5470		BCE_VERBOSE_CTX);
5471
5472	/* Get the page chain prodcuer index. */
5473	prod = sc->pg_prod;
5474
5475	/* Keep filling the page chain until it's full. */
5476	while (sc->free_pg_bd > 0) {
5477		prod_idx = PG_CHAIN_IDX(prod);
5478		if (bce_get_pg_buf(sc, NULL, &prod, &prod_idx)) {
5479			/* Bail out if we can't add an mbuf to the chain. */
5480			break;
5481		}
5482		prod = NEXT_PG_BD(prod);
5483	}
5484
5485	/* Save the page chain producer index. */
5486	sc->pg_prod = prod;
5487
5488	DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
5489		BCE_PRINTF("%s(): Invalid pg_prod value: 0x%04X\n",
5490		__FUNCTION__, sc->pg_prod));
5491
5492	/*
5493	 * Write the mailbox and tell the chip about
5494	 * the new rx_bd's in the page chain.
5495	 */
5496	REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_PG_BDIDX,
5497		sc->pg_prod);
5498
5499	DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5500		BCE_VERBOSE_CTX);
5501}
5502
5503
5504/****************************************************************************/
5505/* Free memory and clear the RX data structures.                            */
5506/*                                                                          */
5507/* Returns:                                                                 */
5508/*   Nothing.                                                               */
5509/****************************************************************************/
5510static void
5511bce_free_pg_chain(struct bce_softc *sc)
5512{
5513	int i;
5514
5515	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5516
5517	/* Free any mbufs still in the mbuf page chain. */
5518	for (i = 0; i < TOTAL_PG_BD; i++) {
5519		if (sc->pg_mbuf_ptr[i] != NULL) {
5520			if (sc->pg_mbuf_map[i] != NULL)
5521				bus_dmamap_sync(sc->pg_mbuf_tag, sc->pg_mbuf_map[i],
5522					BUS_DMASYNC_POSTREAD);
5523			m_freem(sc->pg_mbuf_ptr[i]);
5524			sc->pg_mbuf_ptr[i] = NULL;
5525			DBRUN(sc->debug_pg_mbuf_alloc--);
5526		}
5527	}
5528
5529	/* Clear each page chain pages. */
5530	for (i = 0; i < PG_PAGES; i++)
5531		bzero((char *)sc->pg_bd_chain[i], BCE_PG_CHAIN_PAGE_SZ);
5532
5533	sc->free_pg_bd = sc->max_pg_bd;
5534
5535	/* Check if we lost any mbufs in the process. */
5536	DBRUNIF((sc->debug_pg_mbuf_alloc),
5537		BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from page chain!\n",
5538			__FUNCTION__, sc->debug_pg_mbuf_alloc));
5539
5540	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5541}
5542#endif /* BCE_USE_SPLIT_HEADER */
5543
5544
5545/****************************************************************************/
5546/* Set media options.                                                       */
5547/*                                                                          */
5548/* Returns:                                                                 */
5549/*   0 for success, positive value for failure.                             */
5550/****************************************************************************/
5551static int
5552bce_ifmedia_upd(struct ifnet *ifp)
5553{
5554	struct bce_softc *sc = ifp->if_softc;
5555
5556	DBENTER(BCE_VERBOSE);
5557
5558	BCE_LOCK(sc);
5559	bce_ifmedia_upd_locked(ifp);
5560	BCE_UNLOCK(sc);
5561
5562	DBEXIT(BCE_VERBOSE);
5563	return (0);
5564}
5565
5566
5567/****************************************************************************/
5568/* Set media options.                                                       */
5569/*                                                                          */
5570/* Returns:                                                                 */
5571/*   Nothing.                                                               */
5572/****************************************************************************/
5573static void
5574bce_ifmedia_upd_locked(struct ifnet *ifp)
5575{
5576	struct bce_softc *sc = ifp->if_softc;
5577	struct mii_data *mii;
5578
5579	DBENTER(BCE_VERBOSE);
5580
5581	BCE_LOCK_ASSERT(sc);
5582
5583	mii = device_get_softc(sc->bce_miibus);
5584
5585	/* Make sure the MII bus has been enumerated. */
5586	if (mii) {
5587		sc->bce_link = 0;
5588		if (mii->mii_instance) {
5589			struct mii_softc *miisc;
5590
5591			LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
5592				mii_phy_reset(miisc);
5593		}
5594		mii_mediachg(mii);
5595	}
5596
5597	DBEXIT(BCE_VERBOSE);
5598}
5599
5600
5601/****************************************************************************/
5602/* Reports current media status.                                            */
5603/*                                                                          */
5604/* Returns:                                                                 */
5605/*   Nothing.                                                               */
5606/****************************************************************************/
5607static void
5608bce_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
5609{
5610	struct bce_softc *sc = ifp->if_softc;
5611	struct mii_data *mii;
5612
5613	DBENTER(BCE_VERBOSE);
5614
5615	BCE_LOCK(sc);
5616
5617	mii = device_get_softc(sc->bce_miibus);
5618
5619	mii_pollstat(mii);
5620	ifmr->ifm_active = mii->mii_media_active;
5621	ifmr->ifm_status = mii->mii_media_status;
5622
5623	BCE_UNLOCK(sc);
5624
5625	DBEXIT(BCE_VERBOSE);
5626}
5627
5628
5629/****************************************************************************/
5630/* Handles PHY generated interrupt events.                                  */
5631/*                                                                          */
5632/* Returns:                                                                 */
5633/*   Nothing.                                                               */
5634/****************************************************************************/
5635static void
5636bce_phy_intr(struct bce_softc *sc)
5637{
5638	u32 new_link_state, old_link_state;
5639
5640	DBENTER(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
5641
5642	new_link_state = sc->status_block->status_attn_bits &
5643		STATUS_ATTN_BITS_LINK_STATE;
5644	old_link_state = sc->status_block->status_attn_bits_ack &
5645		STATUS_ATTN_BITS_LINK_STATE;
5646
5647	/* Handle any changes if the link state has changed. */
5648	if (new_link_state != old_link_state) {
5649
5650		/* Update the status_attn_bits_ack field in the status block. */
5651		if (new_link_state) {
5652			REG_WR(sc, BCE_PCICFG_STATUS_BIT_SET_CMD,
5653				STATUS_ATTN_BITS_LINK_STATE);
5654			DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now UP.\n",
5655				__FUNCTION__);
5656		}
5657		else {
5658			REG_WR(sc, BCE_PCICFG_STATUS_BIT_CLEAR_CMD,
5659				STATUS_ATTN_BITS_LINK_STATE);
5660			DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now DOWN.\n",
5661				__FUNCTION__);
5662		}
5663
5664		/*
5665		 * Assume link is down and allow
5666		 * tick routine to update the state
5667		 * based on the actual media state.
5668		 */
5669		sc->bce_link = 0;
5670		callout_stop(&sc->bce_tick_callout);
5671		bce_tick(sc);
5672	}
5673
5674	/* Acknowledge the link change interrupt. */
5675	REG_WR(sc, BCE_EMAC_STATUS, BCE_EMAC_STATUS_LINK_CHANGE);
5676
5677	DBEXIT(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
5678}
5679
5680
5681/****************************************************************************/
5682/* Reads the receive consumer value from the status block (skipping over    */
5683/* chain page pointer if necessary).                                        */
5684/*                                                                          */
5685/* Returns:                                                                 */
5686/*   hw_cons                                                                */
5687/****************************************************************************/
5688static inline u16
5689bce_get_hw_rx_cons(struct bce_softc *sc)
5690{
5691	u16 hw_cons;
5692
5693	rmb();
5694	hw_cons = sc->status_block->status_rx_quick_consumer_index0;
5695	if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
5696		hw_cons++;
5697
5698	return hw_cons;
5699}
5700
5701/****************************************************************************/
5702/* Handles received frame interrupt events.                                 */
5703/*                                                                          */
5704/* Returns:                                                                 */
5705/*   Nothing.                                                               */
5706/****************************************************************************/
5707static void
5708bce_rx_intr(struct bce_softc *sc)
5709{
5710	struct ifnet *ifp = sc->bce_ifp;
5711	struct l2_fhdr *l2fhdr;
5712	unsigned int pkt_len;
5713	u16 sw_rx_cons, sw_rx_cons_idx, hw_rx_cons;
5714	u32 status;
5715#ifdef BCE_USE_SPLIT_HEADER
5716	unsigned int rem_len;
5717	u16 sw_pg_cons, sw_pg_cons_idx;
5718#endif
5719
5720	DBENTER(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
5721	DBRUN(sc->rx_interrupts++);
5722	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): rx_prod = 0x%04X, "
5723		"rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
5724		__FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
5725
5726	/* Prepare the RX chain pages to be accessed by the host CPU. */
5727	for (int i = 0; i < RX_PAGES; i++)
5728		bus_dmamap_sync(sc->rx_bd_chain_tag,
5729		    sc->rx_bd_chain_map[i], BUS_DMASYNC_POSTWRITE);
5730
5731#ifdef BCE_USE_SPLIT_HEADER
5732	/* Prepare the page chain pages to be accessed by the host CPU. */
5733	for (int i = 0; i < PG_PAGES; i++)
5734		bus_dmamap_sync(sc->pg_bd_chain_tag,
5735		    sc->pg_bd_chain_map[i], BUS_DMASYNC_POSTWRITE);
5736#endif
5737
5738	/* Get the hardware's view of the RX consumer index. */
5739	hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
5740
5741	/* Get working copies of the driver's view of the consumer indices. */
5742	sw_rx_cons = sc->rx_cons;
5743#ifdef BCE_USE_SPLIT_HEADER
5744	sw_pg_cons = sc->pg_cons;
5745#endif
5746
5747	/* Update some debug statistics counters */
5748	DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
5749		sc->rx_low_watermark = sc->free_rx_bd);
5750	DBRUNIF((sc->free_rx_bd == sc->max_rx_bd), sc->rx_empty_count++);
5751
5752	/* Scan through the receive chain as long as there is work to do */
5753	/* ToDo: Consider setting a limit on the number of packets processed. */
5754	rmb();
5755	while (sw_rx_cons != hw_rx_cons) {
5756		struct mbuf *m0;
5757
5758		/* Convert the producer/consumer indices to an actual rx_bd index. */
5759		sw_rx_cons_idx = RX_CHAIN_IDX(sw_rx_cons);
5760
5761		/* Unmap the mbuf from DMA space. */
5762		bus_dmamap_sync(sc->rx_mbuf_tag,
5763		    sc->rx_mbuf_map[sw_rx_cons_idx],
5764	    	BUS_DMASYNC_POSTREAD);
5765		bus_dmamap_unload(sc->rx_mbuf_tag,
5766		    sc->rx_mbuf_map[sw_rx_cons_idx]);
5767
5768		/* Remove the mbuf from the RX chain. */
5769		m0 = sc->rx_mbuf_ptr[sw_rx_cons_idx];
5770		sc->rx_mbuf_ptr[sw_rx_cons_idx] = NULL;
5771		DBRUN(sc->debug_rx_mbuf_alloc--);
5772		sc->free_rx_bd++;
5773
5774		/*
5775		 * Frames received on the NetXteme II are prepended
5776		 * with an l2_fhdr structure which provides status
5777		 * information about the received frame (including
5778		 * VLAN tags and checksum info).  The frames are also
5779		 * automatically adjusted to align the IP header
5780		 * (i.e. two null bytes are inserted before the
5781		 * Ethernet header).  As a result the data DMA'd by
5782		 * the controller into the mbuf is as follows:
5783		 * +---------+-----+---------------------+-----+
5784		 * | l2_fhdr | pad | packet data         | FCS |
5785		 * +---------+-----+---------------------+-----+
5786		 * The l2_fhdr needs to be checked and skipped and
5787		 * the FCS needs to be stripped before sending the
5788		 * packet up the stack.
5789		 */
5790		l2fhdr  = mtod(m0, struct l2_fhdr *);
5791
5792		/* Get the packet data + FCS length and the status. */
5793		pkt_len = l2fhdr->l2_fhdr_pkt_len;
5794		status  = l2fhdr->l2_fhdr_status;
5795
5796		/*
5797		 * Skip over the l2_fhdr and pad, resulting in the
5798		 * following data in the mbuf:
5799		 * +---------------------+-----+
5800		 * | packet data         | FCS |
5801		 * +---------------------+-----+
5802		 */
5803		m_adj(m0, sizeof(struct l2_fhdr) + ETHER_ALIGN);
5804
5805#ifdef BCE_USE_SPLIT_HEADER
5806		/*
5807		 * Check whether the received frame fits in a single
5808		 * mbuf or not (i.e. packet data + FCS <=
5809		 * sc->rx_bd_mbuf_data_len bytes).
5810		 */
5811		if (pkt_len > m0->m_len) {
5812			/*
5813			 * The received frame is larger than a single mbuf.
5814			 * If the frame was a TCP frame then only the TCP
5815			 * header is placed in the mbuf, the remaining
5816			 * payload (including FCS) is placed in the page
5817			 * chain, the SPLIT flag is set, and the header
5818			 * length is placed in the IP checksum field.
5819			 * If the frame is not a TCP frame then the mbuf
5820			 * is filled and the remaining bytes are placed
5821			 * in the page chain.
5822			 */
5823
5824			DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a large packet.\n",
5825				__FUNCTION__);
5826
5827			/*
5828			 * When the page chain is enabled and the TCP
5829			 * header has been split from the TCP payload,
5830			 * the ip_xsum structure will reflect the length
5831			 * of the TCP header, not the IP checksum.  Set
5832			 * the packet length of the mbuf accordingly.
5833			 */
5834		 	if (status & L2_FHDR_STATUS_SPLIT)
5835				m0->m_len = l2fhdr->l2_fhdr_ip_xsum;
5836
5837			rem_len = pkt_len - m0->m_len;
5838
5839			/* Pull mbufs off the page chain for the remaining data. */
5840			while (rem_len > 0) {
5841				struct mbuf *m_pg;
5842
5843				sw_pg_cons_idx = PG_CHAIN_IDX(sw_pg_cons);
5844
5845				/* Remove the mbuf from the page chain. */
5846				m_pg = sc->pg_mbuf_ptr[sw_pg_cons_idx];
5847				sc->pg_mbuf_ptr[sw_pg_cons_idx] = NULL;
5848				DBRUN(sc->debug_pg_mbuf_alloc--);
5849				sc->free_pg_bd++;
5850
5851				/* Unmap the page chain mbuf from DMA space. */
5852				bus_dmamap_sync(sc->pg_mbuf_tag,
5853					sc->pg_mbuf_map[sw_pg_cons_idx],
5854					BUS_DMASYNC_POSTREAD);
5855				bus_dmamap_unload(sc->pg_mbuf_tag,
5856					sc->pg_mbuf_map[sw_pg_cons_idx]);
5857
5858				/* Adjust the mbuf length. */
5859				if (rem_len < m_pg->m_len) {
5860					/* The mbuf chain is complete. */
5861					m_pg->m_len = rem_len;
5862					rem_len = 0;
5863				} else {
5864					/* More packet data is waiting. */
5865					rem_len -= m_pg->m_len;
5866				}
5867
5868				/* Concatenate the mbuf cluster to the mbuf. */
5869				m_cat(m0, m_pg);
5870
5871				sw_pg_cons = NEXT_PG_BD(sw_pg_cons);
5872			}
5873
5874			/* Set the total packet length. */
5875			m0->m_pkthdr.len = pkt_len;
5876
5877		} else {
5878			/*
5879			 * The received packet is small and fits in a
5880			 * single mbuf (i.e. the l2_fhdr + pad + packet +
5881			 * FCS <= MHLEN).  In other words, the packet is
5882			 * 154 bytes or less in size.
5883			 */
5884
5885			DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a small packet.\n",
5886				__FUNCTION__);
5887
5888			/* Set the total packet length. */
5889			m0->m_pkthdr.len = m0->m_len = pkt_len;
5890		}
5891#endif
5892
5893		/* Remove the trailing Ethernet FCS. */
5894		m_adj(m0, -ETHER_CRC_LEN);
5895
5896		/* Check that the resulting mbuf chain is valid. */
5897		DBRUN(m_sanity(m0, FALSE));
5898		DBRUNIF(((m0->m_len < ETHER_HDR_LEN) |
5899			(m0->m_pkthdr.len > BCE_MAX_JUMBO_ETHER_MTU_VLAN)),
5900			BCE_PRINTF("Invalid Ethernet frame size!\n");
5901			m_print(m0, 128));
5902
5903		DBRUNIF(DB_RANDOMTRUE(bce_debug_l2fhdr_status_check),
5904			BCE_PRINTF("Simulating l2_fhdr status error.\n");
5905			status = status | L2_FHDR_ERRORS_PHY_DECODE);
5906
5907		/* Check the received frame for errors. */
5908		if (status & (L2_FHDR_ERRORS_BAD_CRC |
5909			L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT |
5910			L2_FHDR_ERRORS_TOO_SHORT  | L2_FHDR_ERRORS_GIANT_FRAME)) {
5911
5912			/* Log the error and release the mbuf. */
5913			ifp->if_ierrors++;
5914			DBRUN(sc->l2fhdr_status_errors++);
5915
5916			m_freem(m0);
5917			m0 = NULL;
5918			goto bce_rx_int_next_rx;
5919		}
5920
5921		/* Send the packet to the appropriate interface. */
5922		m0->m_pkthdr.rcvif = ifp;
5923
5924		/* Assume no hardware checksum. */
5925		m0->m_pkthdr.csum_flags = 0;
5926
5927		/* Validate the checksum if offload enabled. */
5928		if (ifp->if_capenable & IFCAP_RXCSUM) {
5929
5930			/* Check for an IP datagram. */
5931		 	if (!(status & L2_FHDR_STATUS_SPLIT) &&
5932				(status & L2_FHDR_STATUS_IP_DATAGRAM)) {
5933				m0->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
5934
5935				/* Check if the IP checksum is valid. */
5936				if ((l2fhdr->l2_fhdr_ip_xsum ^ 0xffff) == 0)
5937					m0->m_pkthdr.csum_flags |= CSUM_IP_VALID;
5938			}
5939
5940			/* Check for a valid TCP/UDP frame. */
5941			if (status & (L2_FHDR_STATUS_TCP_SEGMENT |
5942				L2_FHDR_STATUS_UDP_DATAGRAM)) {
5943
5944				/* Check for a good TCP/UDP checksum. */
5945				if ((status & (L2_FHDR_ERRORS_TCP_XSUM |
5946					      L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
5947					m0->m_pkthdr.csum_data =
5948					    l2fhdr->l2_fhdr_tcp_udp_xsum;
5949					m0->m_pkthdr.csum_flags |= (CSUM_DATA_VALID
5950						| CSUM_PSEUDO_HDR);
5951				}
5952			}
5953		}
5954
5955		/*
5956		 * If we received a packet with a vlan tag,
5957		 * attach that information to the packet.
5958		 */
5959		if (status & L2_FHDR_STATUS_L2_VLAN_TAG) {
5960#if __FreeBSD_version < 700000
5961			VLAN_INPUT_TAG(ifp, m0, l2fhdr->l2_fhdr_vlan_tag, continue);
5962#else
5963			m0->m_pkthdr.ether_vtag = l2fhdr->l2_fhdr_vlan_tag;
5964			m0->m_flags |= M_VLANTAG;
5965#endif
5966		}
5967
5968		/* Pass the mbuf off to the upper layers. */
5969		ifp->if_ipackets++;
5970
5971bce_rx_int_next_rx:
5972		sw_rx_cons = NEXT_RX_BD(sw_rx_cons);
5973
5974		/* If we have a packet, pass it up the stack */
5975		if (m0) {
5976			/* Make sure we don't lose our place when we release the lock. */
5977			sc->rx_cons = sw_rx_cons;
5978#ifdef BCE_USE_SPLIT_HEADER
5979			sc->pg_cons = sw_pg_cons;
5980#endif
5981
5982			BCE_UNLOCK(sc);
5983			(*ifp->if_input)(ifp, m0);
5984			BCE_LOCK(sc);
5985
5986			/* Recover our place. */
5987			sw_rx_cons = sc->rx_cons;
5988#ifdef BCE_USE_SPLIT_HEADER
5989			sw_pg_cons = sc->pg_cons;
5990#endif
5991		}
5992
5993		/* Refresh hw_cons to see if there's new work */
5994		if (sw_rx_cons == hw_rx_cons)
5995			hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
5996	}
5997
5998	/* No new packets to process.  Refill the RX and page chains and exit. */
5999#ifdef BCE_USE_SPLIT_HEADER
6000	sc->pg_cons = sw_pg_cons;
6001	bce_fill_pg_chain(sc);
6002#endif
6003
6004	sc->rx_cons = sw_rx_cons;
6005	bce_fill_rx_chain(sc);
6006
6007	for (int i = 0; i < RX_PAGES; i++)
6008		bus_dmamap_sync(sc->rx_bd_chain_tag,
6009		    sc->rx_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
6010
6011#ifdef BCE_USE_SPLIT_HEADER
6012	for (int i = 0; i < PG_PAGES; i++)
6013		bus_dmamap_sync(sc->pg_bd_chain_tag,
6014		    sc->pg_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
6015#endif
6016
6017	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): rx_prod = 0x%04X, "
6018		"rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
6019		__FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
6020	DBEXIT(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
6021}
6022
6023
6024/****************************************************************************/
6025/* Reads the transmit consumer value from the status block (skipping over   */
6026/* chain page pointer if necessary).                                        */
6027/*                                                                          */
6028/* Returns:                                                                 */
6029/*   hw_cons                                                                */
6030/****************************************************************************/
6031static inline u16
6032bce_get_hw_tx_cons(struct bce_softc *sc)
6033{
6034	u16 hw_cons;
6035
6036	mb();
6037	hw_cons = sc->status_block->status_tx_quick_consumer_index0;
6038	if ((hw_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
6039		hw_cons++;
6040
6041	return hw_cons;
6042}
6043
6044
6045/****************************************************************************/
6046/* Handles transmit completion interrupt events.                            */
6047/*                                                                          */
6048/* Returns:                                                                 */
6049/*   Nothing.                                                               */
6050/****************************************************************************/
6051static void
6052bce_tx_intr(struct bce_softc *sc)
6053{
6054	struct ifnet *ifp = sc->bce_ifp;
6055	u16 hw_tx_cons, sw_tx_cons, sw_tx_chain_cons;
6056
6057	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
6058	DBRUN(sc->tx_interrupts++);
6059	DBPRINT(sc, BCE_EXTREME_SEND, "%s(enter): tx_prod = 0x%04X, "
6060		"tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
6061		__FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
6062
6063	BCE_LOCK_ASSERT(sc);
6064
6065	/* Get the hardware's view of the TX consumer index. */
6066	hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
6067	sw_tx_cons = sc->tx_cons;
6068
6069	/* Prevent speculative reads from getting ahead of the status block. */
6070	bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
6071		BUS_SPACE_BARRIER_READ);
6072
6073	/* Cycle through any completed TX chain page entries. */
6074	while (sw_tx_cons != hw_tx_cons) {
6075#ifdef BCE_DEBUG
6076		struct tx_bd *txbd = NULL;
6077#endif
6078		sw_tx_chain_cons = TX_CHAIN_IDX(sw_tx_cons);
6079
6080		DBPRINT(sc, BCE_INFO_SEND,
6081			"%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, "
6082			"sw_tx_chain_cons = 0x%04X\n",
6083			__FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
6084
6085		DBRUNIF((sw_tx_chain_cons > MAX_TX_BD),
6086			BCE_PRINTF("%s(%d): TX chain consumer out of range! "
6087				" 0x%04X > 0x%04X\n", __FILE__, __LINE__, sw_tx_chain_cons,
6088				(int) MAX_TX_BD);
6089			bce_breakpoint(sc));
6090
6091		DBRUN(txbd = &sc->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)]
6092				[TX_IDX(sw_tx_chain_cons)]);
6093
6094		DBRUNIF((txbd == NULL),
6095			BCE_PRINTF("%s(%d): Unexpected NULL tx_bd[0x%04X]!\n",
6096				__FILE__, __LINE__, sw_tx_chain_cons);
6097			bce_breakpoint(sc));
6098
6099		DBRUNMSG(BCE_INFO_SEND, BCE_PRINTF("%s(): ", __FUNCTION__);
6100			bce_dump_txbd(sc, sw_tx_chain_cons, txbd));
6101
6102		/*
6103		 * Free the associated mbuf. Remember
6104		 * that only the last tx_bd of a packet
6105		 * has an mbuf pointer and DMA map.
6106		 */
6107		if (sc->tx_mbuf_ptr[sw_tx_chain_cons] != NULL) {
6108
6109			/* Validate that this is the last tx_bd. */
6110			DBRUNIF((!(txbd->tx_bd_flags & TX_BD_FLAGS_END)),
6111				BCE_PRINTF("%s(%d): tx_bd END flag not set but "
6112				"txmbuf == NULL!\n", __FILE__, __LINE__);
6113				bce_breakpoint(sc));
6114
6115			DBRUNMSG(BCE_INFO_SEND,
6116				BCE_PRINTF("%s(): Unloading map/freeing mbuf "
6117					"from tx_bd[0x%04X]\n", __FUNCTION__, sw_tx_chain_cons));
6118
6119			/* Unmap the mbuf. */
6120			bus_dmamap_unload(sc->tx_mbuf_tag,
6121			    sc->tx_mbuf_map[sw_tx_chain_cons]);
6122
6123			/* Free the mbuf. */
6124			m_freem(sc->tx_mbuf_ptr[sw_tx_chain_cons]);
6125			sc->tx_mbuf_ptr[sw_tx_chain_cons] = NULL;
6126			DBRUN(sc->debug_tx_mbuf_alloc--);
6127
6128			ifp->if_opackets++;
6129		}
6130
6131		sc->used_tx_bd--;
6132		sw_tx_cons = NEXT_TX_BD(sw_tx_cons);
6133
6134		/* Refresh hw_cons to see if there's new work. */
6135		hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
6136
6137		/* Prevent speculative reads from getting ahead of the status block. */
6138		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
6139			BUS_SPACE_BARRIER_READ);
6140	}
6141
6142	/* Clear the TX timeout timer. */
6143	sc->watchdog_timer = 0;
6144
6145	/* Clear the tx hardware queue full flag. */
6146	if (sc->used_tx_bd < sc->max_tx_bd) {
6147		DBRUNIF((ifp->if_drv_flags & IFF_DRV_OACTIVE),
6148			DBPRINT(sc, BCE_INFO_SEND,
6149				"%s(): Open TX chain! %d/%d (used/total)\n",
6150				__FUNCTION__, sc->used_tx_bd, sc->max_tx_bd));
6151		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
6152	}
6153
6154	sc->tx_cons = sw_tx_cons;
6155
6156	DBPRINT(sc, BCE_EXTREME_SEND, "%s(exit): tx_prod = 0x%04X, "
6157		"tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
6158		__FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
6159	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
6160}
6161
6162
6163/****************************************************************************/
6164/* Disables interrupt generation.                                           */
6165/*                                                                          */
6166/* Returns:                                                                 */
6167/*   Nothing.                                                               */
6168/****************************************************************************/
6169static void
6170bce_disable_intr(struct bce_softc *sc)
6171{
6172	DBENTER(BCE_VERBOSE_INTR);
6173
6174	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_MASK_INT);
6175	REG_RD(sc, BCE_PCICFG_INT_ACK_CMD);
6176
6177	DBEXIT(BCE_VERBOSE_INTR);
6178}
6179
6180
6181/****************************************************************************/
6182/* Enables interrupt generation.                                            */
6183/*                                                                          */
6184/* Returns:                                                                 */
6185/*   Nothing.                                                               */
6186/****************************************************************************/
6187static void
6188bce_enable_intr(struct bce_softc *sc, int coal_now)
6189{
6190	DBENTER(BCE_VERBOSE_INTR);
6191
6192	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
6193	       BCE_PCICFG_INT_ACK_CMD_INDEX_VALID |
6194	       BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
6195
6196	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
6197	       BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
6198
6199	/* Force an immediate interrupt (whether there is new data or not). */
6200	if (coal_now)
6201		REG_WR(sc, BCE_HC_COMMAND, sc->hc_command | BCE_HC_COMMAND_COAL_NOW);
6202
6203	DBEXIT(BCE_VERBOSE_INTR);
6204}
6205
6206
6207/****************************************************************************/
6208/* Handles controller initialization.                                       */
6209/*                                                                          */
6210/* Returns:                                                                 */
6211/*   Nothing.                                                               */
6212/****************************************************************************/
6213static void
6214bce_init_locked(struct bce_softc *sc)
6215{
6216	struct ifnet *ifp;
6217	u32 ether_mtu = 0;
6218
6219	DBENTER(BCE_VERBOSE_RESET);
6220
6221	BCE_LOCK_ASSERT(sc);
6222
6223	ifp = sc->bce_ifp;
6224
6225	/* Check if the driver is still running and bail out if it is. */
6226	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
6227		goto bce_init_locked_exit;
6228
6229	bce_stop(sc);
6230
6231	if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
6232		BCE_PRINTF("%s(%d): Controller reset failed!\n",
6233			__FILE__, __LINE__);
6234		goto bce_init_locked_exit;
6235	}
6236
6237	if (bce_chipinit(sc)) {
6238		BCE_PRINTF("%s(%d): Controller initialization failed!\n",
6239			__FILE__, __LINE__);
6240		goto bce_init_locked_exit;
6241	}
6242
6243	if (bce_blockinit(sc)) {
6244		BCE_PRINTF("%s(%d): Block initialization failed!\n",
6245			__FILE__, __LINE__);
6246		goto bce_init_locked_exit;
6247	}
6248
6249	/* Load our MAC address. */
6250	bcopy(IF_LLADDR(sc->bce_ifp), sc->eaddr, ETHER_ADDR_LEN);
6251	bce_set_mac_addr(sc);
6252
6253	/*
6254	 * Calculate and program the hardware Ethernet MTU
6255	 * size. Be generous on the receive if we have room.
6256	 */
6257#ifdef BCE_USE_SPLIT_HEADER
6258	if (ifp->if_mtu <= (sc->rx_bd_mbuf_data_len + sc->pg_bd_mbuf_alloc_size))
6259		ether_mtu = sc->rx_bd_mbuf_data_len + sc->pg_bd_mbuf_alloc_size;
6260#else
6261	if (ifp->if_mtu <= sc->rx_bd_mbuf_data_len)
6262		ether_mtu = sc->rx_bd_mbuf_data_len;
6263#endif
6264	else
6265		ether_mtu = ifp->if_mtu;
6266
6267	ether_mtu += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN;
6268
6269	DBPRINT(sc, BCE_INFO_MISC, "%s(): setting h/w mtu = %d\n", __FUNCTION__,
6270		ether_mtu);
6271
6272	/* Program the mtu, enabling jumbo frame support if necessary. */
6273	if (ether_mtu > (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN))
6274		REG_WR(sc, BCE_EMAC_RX_MTU_SIZE,
6275			min(ether_mtu, BCE_MAX_JUMBO_ETHER_MTU) |
6276			BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA);
6277	else
6278		REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu);
6279
6280	DBPRINT(sc, BCE_INFO_LOAD,
6281		"%s(): rx_bd_mbuf_alloc_size = %d, rx_bce_mbuf_data_len = %d, "
6282		"rx_bd_mbuf_align_pad = %d, pg_bd_mbuf_alloc_size = %d\n",
6283		__FUNCTION__, sc->rx_bd_mbuf_alloc_size, sc->rx_bd_mbuf_data_len,
6284		sc->rx_bd_mbuf_align_pad, sc->pg_bd_mbuf_alloc_size);
6285
6286	/* Program appropriate promiscuous/multicast filtering. */
6287	bce_set_rx_mode(sc);
6288
6289#ifdef BCE_USE_SPLIT_HEADER
6290	/* Init page buffer descriptor chain. */
6291	bce_init_pg_chain(sc);
6292#endif
6293
6294	/* Init RX buffer descriptor chain. */
6295	bce_init_rx_chain(sc);
6296
6297	/* Init TX buffer descriptor chain. */
6298	bce_init_tx_chain(sc);
6299
6300	/* Enable host interrupts. */
6301	bce_enable_intr(sc, 1);
6302
6303	bce_ifmedia_upd_locked(ifp);
6304
6305	ifp->if_drv_flags |= IFF_DRV_RUNNING;
6306	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
6307
6308	callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
6309
6310bce_init_locked_exit:
6311	DBEXIT(BCE_VERBOSE_RESET);
6312}
6313
6314
6315/****************************************************************************/
6316/* Initialize the controller just enough so that any management firmware    */
6317/* running on the device will continue to operate correctly.                */
6318/*                                                                          */
6319/* Returns:                                                                 */
6320/*   Nothing.                                                               */
6321/****************************************************************************/
6322static void
6323bce_mgmt_init_locked(struct bce_softc *sc)
6324{
6325	struct ifnet *ifp;
6326
6327	DBENTER(BCE_VERBOSE_RESET);
6328
6329	BCE_LOCK_ASSERT(sc);
6330
6331	/* Bail out if management firmware is not running. */
6332	if (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)) {
6333		DBPRINT(sc, BCE_VERBOSE_SPECIAL,
6334			"No management firmware running...\n");
6335		goto bce_mgmt_init_locked_exit;
6336	}
6337
6338	ifp = sc->bce_ifp;
6339
6340	/* Enable all critical blocks in the MAC. */
6341	REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT);
6342	REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
6343	DELAY(20);
6344
6345	bce_ifmedia_upd_locked(ifp);
6346
6347bce_mgmt_init_locked_exit:
6348	DBEXIT(BCE_VERBOSE_RESET);
6349}
6350
6351
6352/****************************************************************************/
6353/* Handles controller initialization when called from an unlocked routine.  */
6354/*                                                                          */
6355/* Returns:                                                                 */
6356/*   Nothing.                                                               */
6357/****************************************************************************/
6358static void
6359bce_init(void *xsc)
6360{
6361	struct bce_softc *sc = xsc;
6362
6363	DBENTER(BCE_VERBOSE_RESET);
6364
6365	BCE_LOCK(sc);
6366	bce_init_locked(sc);
6367	BCE_UNLOCK(sc);
6368
6369	DBEXIT(BCE_VERBOSE_RESET);
6370}
6371
6372
6373/****************************************************************************/
6374/* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
6375/* memory visible to the controller.                                        */
6376/*                                                                          */
6377/* Returns:                                                                 */
6378/*   0 for success, positive value for failure.                             */
6379/* Modified:                                                                */
6380/*   m_head: May be set to NULL if MBUF is excessively fragmented.          */
6381/****************************************************************************/
6382static int
6383bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
6384{
6385	bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
6386	bus_dmamap_t map;
6387	struct tx_bd *txbd = NULL;
6388	struct mbuf *m0;
6389	struct ether_vlan_header *eh;
6390	struct ip *ip;
6391	struct tcphdr *th;
6392	u16 prod, chain_prod, etype, mss = 0, vlan_tag = 0, flags = 0;
6393	u32 prod_bseq;
6394	int hdr_len = 0, e_hlen = 0, ip_hlen = 0, tcp_hlen = 0, ip_len = 0;
6395
6396#ifdef BCE_DEBUG
6397	u16 debug_prod;
6398#endif
6399	int i, error, nsegs, rc = 0;
6400
6401	DBENTER(BCE_VERBOSE_SEND);
6402	DBPRINT(sc, BCE_INFO_SEND,
6403		"%s(enter): tx_prod = 0x%04X, tx_chain_prod = %04X, "
6404		"tx_prod_bseq = 0x%08X\n",
6405		__FUNCTION__, sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod),
6406		sc->tx_prod_bseq);
6407
6408	/* Transfer any checksum offload flags to the bd. */
6409	m0 = *m_head;
6410	if (m0->m_pkthdr.csum_flags) {
6411		if (m0->m_pkthdr.csum_flags & CSUM_IP)
6412			flags |= TX_BD_FLAGS_IP_CKSUM;
6413		if (m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
6414			flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
6415		if (m0->m_pkthdr.csum_flags & CSUM_TSO) {
6416			/* For TSO the controller needs two pieces of info, */
6417			/* the MSS and the IP+TCP options length.           */
6418			mss = htole16(m0->m_pkthdr.tso_segsz);
6419
6420			/* Map the header and find the Ethernet type & header length */
6421			eh = mtod(m0, struct ether_vlan_header *);
6422			if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
6423				etype = ntohs(eh->evl_proto);
6424				e_hlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
6425			} else {
6426				etype = ntohs(eh->evl_encap_proto);
6427				e_hlen = ETHER_HDR_LEN;
6428			}
6429
6430			/* Check for supported TSO Ethernet types (only IPv4 for now) */
6431			switch (etype) {
6432				case ETHERTYPE_IP:
6433					ip = (struct ip *)(m0->m_data + e_hlen);
6434
6435					/* TSO only supported for TCP protocol */
6436					if (ip->ip_p != IPPROTO_TCP) {
6437						BCE_PRINTF("%s(%d): TSO enabled for non-TCP frame!.\n",
6438							__FILE__, __LINE__);
6439						goto bce_tx_encap_skip_tso;
6440					}
6441
6442					/* Get IP header length in bytes (min 20) */
6443					ip_hlen = ip->ip_hl << 2;
6444
6445					/* Get the TCP header length in bytes (min 20) */
6446					th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
6447					tcp_hlen = (th->th_off << 2);
6448
6449					/* IP header length and checksum will be calc'd by hardware */
6450					ip_len = ip->ip_len;
6451					ip->ip_len = 0;
6452					ip->ip_sum = 0;
6453					break;
6454				case ETHERTYPE_IPV6:
6455					BCE_PRINTF("%s(%d): TSO over IPv6 not supported!.\n",
6456						__FILE__, __LINE__);
6457					goto bce_tx_encap_skip_tso;
6458				default:
6459					BCE_PRINTF("%s(%d): TSO enabled for unsupported protocol!.\n",
6460						__FILE__, __LINE__);
6461					goto bce_tx_encap_skip_tso;
6462			}
6463
6464			hdr_len = e_hlen + ip_hlen + tcp_hlen;
6465
6466			DBPRINT(sc, BCE_EXTREME_SEND,
6467				"%s(): hdr_len = %d, e_hlen = %d, ip_hlen = %d, tcp_hlen = %d, ip_len = %d\n",
6468				 __FUNCTION__, hdr_len, e_hlen, ip_hlen, tcp_hlen, ip_len);
6469
6470			/* Set the LSO flag in the TX BD */
6471			flags |= TX_BD_FLAGS_SW_LSO;
6472			/* Set the length of IP + TCP options (in 32 bit words) */
6473			flags |= (((ip_hlen + tcp_hlen - 40) >> 2) << 8);
6474
6475bce_tx_encap_skip_tso:
6476			DBRUN(sc->requested_tso_frames++);
6477		}
6478	}
6479
6480	/* Transfer any VLAN tags to the bd. */
6481	if (m0->m_flags & M_VLANTAG) {
6482		flags |= TX_BD_FLAGS_VLAN_TAG;
6483		vlan_tag = m0->m_pkthdr.ether_vtag;
6484	}
6485
6486	/* Map the mbuf into DMAable memory. */
6487	prod = sc->tx_prod;
6488	chain_prod = TX_CHAIN_IDX(prod);
6489	map = sc->tx_mbuf_map[chain_prod];
6490
6491	/* Map the mbuf into our DMA address space. */
6492	error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag, map, m0,
6493	    segs, &nsegs, BUS_DMA_NOWAIT);
6494
6495	/* Check if the DMA mapping was successful */
6496	if (error == EFBIG) {
6497
6498		/* The mbuf is too fragmented for our DMA mapping. */
6499   		DBPRINT(sc, BCE_WARN, "%s(): fragmented mbuf (%d pieces)\n",
6500			__FUNCTION__, nsegs);
6501		DBRUN(bce_dump_mbuf(sc, m0););
6502
6503		/* Try to defrag the mbuf. */
6504		m0 = m_defrag(*m_head, M_DONTWAIT);
6505		if (m0 == NULL) {
6506			/* Defrag was unsuccessful */
6507			m_freem(*m_head);
6508			*m_head = NULL;
6509			sc->mbuf_alloc_failed++;
6510			rc = ENOBUFS;
6511			goto bce_tx_encap_exit;
6512		}
6513
6514		/* Defrag was successful, try mapping again */
6515		*m_head = m0;
6516		error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag, map, m0,
6517		    segs, &nsegs, BUS_DMA_NOWAIT);
6518
6519		/* Still getting an error after a defrag. */
6520		if (error == ENOMEM) {
6521			/* Insufficient DMA buffers available. */
6522			sc->tx_dma_map_failures++;
6523			rc = error;
6524			goto bce_tx_encap_exit;
6525		} else if (error != 0) {
6526			/* Still can't map the mbuf, release it and return an error. */
6527			BCE_PRINTF(
6528			    "%s(%d): Unknown error mapping mbuf into TX chain!\n",
6529			    __FILE__, __LINE__);
6530			m_freem(m0);
6531			*m_head = NULL;
6532			sc->tx_dma_map_failures++;
6533			rc = ENOBUFS;
6534			goto bce_tx_encap_exit;
6535		}
6536	} else if (error == ENOMEM) {
6537		/* Insufficient DMA buffers available. */
6538		sc->tx_dma_map_failures++;
6539		rc = error;
6540		goto bce_tx_encap_exit;
6541	} else if (error != 0) {
6542		m_freem(m0);
6543		*m_head = NULL;
6544		sc->tx_dma_map_failures++;
6545		rc = error;
6546		goto bce_tx_encap_exit;
6547	}
6548
6549	/* Make sure there's room in the chain */
6550	if (nsegs > (sc->max_tx_bd - sc->used_tx_bd)) {
6551		bus_dmamap_unload(sc->tx_mbuf_tag, map);
6552		rc = ENOBUFS;
6553		goto bce_tx_encap_exit;
6554	}
6555
6556	/* prod points to an empty tx_bd at this point. */
6557	prod_bseq  = sc->tx_prod_bseq;
6558
6559#ifdef BCE_DEBUG
6560	debug_prod = chain_prod;
6561#endif
6562
6563	DBPRINT(sc, BCE_INFO_SEND,
6564		"%s(start): prod = 0x%04X, chain_prod = 0x%04X, "
6565		"prod_bseq = 0x%08X\n",
6566		__FUNCTION__, prod, chain_prod, prod_bseq);
6567
6568	/*
6569	 * Cycle through each mbuf segment that makes up
6570	 * the outgoing frame, gathering the mapping info
6571	 * for that segment and creating a tx_bd for
6572	 * the mbuf.
6573	 */
6574	for (i = 0; i < nsegs ; i++) {
6575
6576		chain_prod = TX_CHAIN_IDX(prod);
6577		txbd= &sc->tx_bd_chain[TX_PAGE(chain_prod)][TX_IDX(chain_prod)];
6578
6579		txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(segs[i].ds_addr));
6580		txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(segs[i].ds_addr));
6581		txbd->tx_bd_mss_nbytes = htole32(mss << 16) | htole16(segs[i].ds_len);
6582		txbd->tx_bd_vlan_tag = htole16(vlan_tag);
6583		txbd->tx_bd_flags = htole16(flags);
6584		prod_bseq += segs[i].ds_len;
6585		if (i == 0)
6586			txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_START);
6587		prod = NEXT_TX_BD(prod);
6588	}
6589
6590	/* Set the END flag on the last TX buffer descriptor. */
6591	txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_END);
6592
6593	DBRUNMSG(BCE_EXTREME_SEND, bce_dump_tx_chain(sc, debug_prod, nsegs));
6594
6595	DBPRINT(sc, BCE_INFO_SEND,
6596		"%s( end ): prod = 0x%04X, chain_prod = 0x%04X, "
6597		"prod_bseq = 0x%08X\n",
6598		__FUNCTION__, prod, chain_prod, prod_bseq);
6599
6600	/*
6601	 * Ensure that the mbuf pointer for this transmission
6602	 * is placed at the array index of the last
6603	 * descriptor in this chain.  This is done
6604	 * because a single map is used for all
6605	 * segments of the mbuf and we don't want to
6606	 * unload the map before all of the segments
6607	 * have been freed.
6608	 */
6609	sc->tx_mbuf_ptr[chain_prod] = m0;
6610	sc->used_tx_bd += nsegs;
6611
6612	/* Update some debug statistic counters */
6613	DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
6614		sc->tx_hi_watermark = sc->used_tx_bd);
6615	DBRUNIF((sc->used_tx_bd == sc->max_tx_bd), sc->tx_full_count++);
6616	DBRUNIF(sc->debug_tx_mbuf_alloc++);
6617
6618	DBRUNMSG(BCE_EXTREME_SEND, bce_dump_tx_mbuf_chain(sc, chain_prod, 1));
6619
6620	/* prod points to the next free tx_bd at this point. */
6621	sc->tx_prod = prod;
6622	sc->tx_prod_bseq = prod_bseq;
6623
6624	DBPRINT(sc, BCE_INFO_SEND,
6625		"%s(exit): prod = 0x%04X, chain_prod = %04X, "
6626		"prod_bseq = 0x%08X\n",
6627		__FUNCTION__, sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod),
6628		sc->tx_prod_bseq);
6629
6630bce_tx_encap_exit:
6631	DBEXIT(BCE_VERBOSE_SEND);
6632	return(rc);
6633}
6634
6635
6636/****************************************************************************/
6637/* Main transmit routine when called from another routine with a lock.      */
6638/*                                                                          */
6639/* Returns:                                                                 */
6640/*   Nothing.                                                               */
6641/****************************************************************************/
6642static void
6643bce_start_locked(struct ifnet *ifp)
6644{
6645	struct bce_softc *sc = ifp->if_softc;
6646	struct mbuf *m_head = NULL;
6647	int count = 0;
6648	u16 tx_prod, tx_chain_prod;
6649
6650	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
6651
6652	BCE_LOCK_ASSERT(sc);
6653
6654	/* prod points to the next free tx_bd. */
6655	tx_prod = sc->tx_prod;
6656	tx_chain_prod = TX_CHAIN_IDX(tx_prod);
6657
6658	DBPRINT(sc, BCE_INFO_SEND,
6659		"%s(enter): tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
6660		"tx_prod_bseq = 0x%08X\n",
6661		__FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
6662
6663	/* If there's no link or the transmit queue is empty then just exit. */
6664	if (!sc->bce_link) {
6665		DBPRINT(sc, BCE_INFO_SEND, "%s(): No link.\n",
6666			__FUNCTION__);
6667		goto bce_start_locked_exit;
6668	}
6669
6670	if (IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
6671		DBPRINT(sc, BCE_INFO_SEND, "%s(): Transmit queue empty.\n",
6672			__FUNCTION__);
6673		goto bce_start_locked_exit;
6674	}
6675
6676	/*
6677	 * Keep adding entries while there is space in the ring.
6678	 */
6679	while (sc->used_tx_bd < sc->max_tx_bd) {
6680
6681		/* Check for any frames to send. */
6682		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
6683
6684		/* Stop when the transmit queue is empty. */
6685		if (m_head == NULL)
6686			break;
6687
6688		/*
6689		 * Pack the data into the transmit ring. If we
6690		 * don't have room, place the mbuf back at the
6691		 * head of the queue and set the OACTIVE flag
6692		 * to wait for the NIC to drain the chain.
6693		 */
6694		if (bce_tx_encap(sc, &m_head)) {
6695			/* No room, put the frame back on the transmit queue. */
6696			if (m_head != NULL)
6697				IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
6698			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
6699			DBPRINT(sc, BCE_INFO_SEND,
6700				"TX chain is closed for business! Total tx_bd used = %d\n",
6701				sc->used_tx_bd);
6702			break;
6703		}
6704
6705		count++;
6706
6707		/* Send a copy of the frame to any BPF listeners. */
6708		ETHER_BPF_MTAP(ifp, m_head);
6709	}
6710
6711	/* Exit if no packets were dequeued. */
6712	if (count == 0) {
6713		DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were dequeued\n",
6714			__FUNCTION__);
6715		goto bce_start_locked_exit;
6716	}
6717
6718	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): Inserted %d frames into send queue.\n",
6719		__FUNCTION__, count);
6720
6721	REG_WR(sc, BCE_MQ_COMMAND, REG_RD(sc, BCE_MQ_COMMAND) | BCE_MQ_COMMAND_NO_MAP_ERROR);
6722
6723	/* Write the mailbox and tell the chip about the waiting tx_bd's. */
6724	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): MB_GET_CID_ADDR(TX_CID) = 0x%08X; "
6725		"BCE_L2MQ_TX_HOST_BIDX = 0x%08X, sc->tx_prod = 0x%04X\n",
6726		__FUNCTION__,
6727		MB_GET_CID_ADDR(TX_CID), BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
6728	REG_WR16(sc, MB_GET_CID_ADDR(TX_CID) + BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
6729	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): MB_GET_CID_ADDR(TX_CID) = 0x%08X; "
6730		"BCE_L2MQ_TX_HOST_BSEQ = 0x%08X, sc->tx_prod_bseq = 0x%04X\n",
6731		__FUNCTION__,
6732		MB_GET_CID_ADDR(TX_CID), BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
6733	REG_WR(sc, MB_GET_CID_ADDR(TX_CID) + BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
6734
6735	/* Set the tx timeout. */
6736	sc->watchdog_timer = BCE_TX_TIMEOUT;
6737
6738	DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_ctx(sc, TX_CID));
6739	DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_mq_regs(sc));
6740
6741bce_start_locked_exit:
6742	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
6743	return;
6744}
6745
6746
6747/****************************************************************************/
6748/* Main transmit routine when called from another routine without a lock.   */
6749/*                                                                          */
6750/* Returns:                                                                 */
6751/*   Nothing.                                                               */
6752/****************************************************************************/
6753static void
6754bce_start(struct ifnet *ifp)
6755{
6756	struct bce_softc *sc = ifp->if_softc;
6757
6758	DBENTER(BCE_VERBOSE_SEND);
6759
6760	BCE_LOCK(sc);
6761	bce_start_locked(ifp);
6762	BCE_UNLOCK(sc);
6763
6764	DBEXIT(BCE_VERBOSE_SEND);
6765}
6766
6767
6768/****************************************************************************/
6769/* Handles any IOCTL calls from the operating system.                       */
6770/*                                                                          */
6771/* Returns:                                                                 */
6772/*   0 for success, positive value for failure.                             */
6773/****************************************************************************/
6774static int
6775bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
6776{
6777	struct bce_softc *sc = ifp->if_softc;
6778	struct ifreq *ifr = (struct ifreq *) data;
6779	struct mii_data *mii;
6780	int mask, error = 0;
6781
6782	DBENTER(BCE_VERBOSE_MISC);
6783
6784	switch(command) {
6785
6786		/* Set the interface MTU. */
6787		case SIOCSIFMTU:
6788			/* Check that the MTU setting is supported. */
6789			if ((ifr->ifr_mtu < BCE_MIN_MTU) ||
6790				(ifr->ifr_mtu > BCE_MAX_JUMBO_MTU)) {
6791				error = EINVAL;
6792				break;
6793			}
6794
6795			DBPRINT(sc, BCE_INFO_MISC,
6796				"SIOCSIFMTU: Changing MTU from %d to %d\n",
6797				(int) ifp->if_mtu, (int) ifr->ifr_mtu);
6798
6799			BCE_LOCK(sc);
6800			ifp->if_mtu = ifr->ifr_mtu;
6801			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
6802#ifdef BCE_USE_SPLIT_HEADER
6803			/* No buffer allocation size changes are necessary. */
6804#else
6805			/* Recalculate our buffer allocation sizes. */
6806			if ((ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN) > MCLBYTES) {
6807				sc->rx_bd_mbuf_alloc_size = MJUM9BYTES;
6808				sc->rx_bd_mbuf_align_pad  = roundup2(MJUM9BYTES, 16) - MJUM9BYTES;
6809				sc->rx_bd_mbuf_data_len   = sc->rx_bd_mbuf_alloc_size -
6810					sc->rx_bd_mbuf_align_pad;
6811			} else {
6812				sc->rx_bd_mbuf_alloc_size = MCLBYTES;
6813				sc->rx_bd_mbuf_align_pad  = roundup2(MCLBYTES, 16) - MCLBYTES;
6814				sc->rx_bd_mbuf_data_len   = sc->rx_bd_mbuf_alloc_size -
6815					sc->rx_bd_mbuf_align_pad;
6816			}
6817#endif
6818
6819			bce_init_locked(sc);
6820			BCE_UNLOCK(sc);
6821			break;
6822
6823		/* Set interface flags. */
6824		case SIOCSIFFLAGS:
6825			DBPRINT(sc, BCE_VERBOSE_SPECIAL, "Received SIOCSIFFLAGS\n");
6826
6827			BCE_LOCK(sc);
6828
6829			/* Check if the interface is up. */
6830			if (ifp->if_flags & IFF_UP) {
6831				if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
6832					/* Change promiscuous/multicast flags as necessary. */
6833					bce_set_rx_mode(sc);
6834				} else {
6835					/* Start the HW */
6836					bce_init_locked(sc);
6837				}
6838			} else {
6839				/* The interface is down, check if driver is running. */
6840				if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
6841					bce_stop(sc);
6842
6843					/* If MFW is running, restart the controller a bit. */
6844					if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
6845						bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
6846						bce_chipinit(sc);
6847						bce_mgmt_init_locked(sc);
6848					}
6849				}
6850			}
6851
6852			BCE_UNLOCK(sc);
6853			error = 0;
6854
6855			break;
6856
6857		/* Add/Delete multicast address */
6858		case SIOCADDMULTI:
6859		case SIOCDELMULTI:
6860			DBPRINT(sc, BCE_VERBOSE_MISC, "Received SIOCADDMULTI/SIOCDELMULTI\n");
6861
6862			BCE_LOCK(sc);
6863			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
6864				bce_set_rx_mode(sc);
6865				error = 0;
6866			}
6867			BCE_UNLOCK(sc);
6868
6869			break;
6870
6871		/* Set/Get Interface media */
6872		case SIOCSIFMEDIA:
6873		case SIOCGIFMEDIA:
6874			DBPRINT(sc, BCE_VERBOSE_MISC, "Received SIOCSIFMEDIA/SIOCGIFMEDIA\n");
6875
6876			mii = device_get_softc(sc->bce_miibus);
6877			error = ifmedia_ioctl(ifp, ifr,
6878			    &mii->mii_media, command);
6879			break;
6880
6881		/* Set interface capability */
6882		case SIOCSIFCAP:
6883			mask = ifr->ifr_reqcap ^ ifp->if_capenable;
6884			DBPRINT(sc, BCE_INFO_MISC, "Received SIOCSIFCAP = 0x%08X\n", (u32) mask);
6885
6886			/* Toggle the TX checksum capabilites enable flag. */
6887			if (mask & IFCAP_TXCSUM) {
6888				ifp->if_capenable ^= IFCAP_TXCSUM;
6889				if (IFCAP_TXCSUM & ifp->if_capenable)
6890					ifp->if_hwassist = BCE_IF_HWASSIST;
6891				else
6892					ifp->if_hwassist = 0;
6893			}
6894
6895			/* Toggle the RX checksum capabilities enable flag. */
6896			if (mask & IFCAP_RXCSUM) {
6897				ifp->if_capenable ^= IFCAP_RXCSUM;
6898				if (IFCAP_RXCSUM & ifp->if_capenable)
6899					ifp->if_hwassist = BCE_IF_HWASSIST;
6900				else
6901					ifp->if_hwassist = 0;
6902			}
6903
6904			/* Toggle the TSO capabilities enable flag. */
6905			if (bce_tso_enable && (mask & IFCAP_TSO4)) {
6906				ifp->if_capenable ^= IFCAP_TSO4;
6907				if (IFCAP_RXCSUM & ifp->if_capenable)
6908					ifp->if_hwassist = BCE_IF_HWASSIST;
6909				else
6910					ifp->if_hwassist = 0;
6911			}
6912
6913			/* Toggle VLAN_MTU capabilities enable flag. */
6914			if (mask & IFCAP_VLAN_MTU) {
6915				BCE_PRINTF("%s(%d): Changing VLAN_MTU not supported.\n",
6916					__FILE__, __LINE__);
6917			}
6918
6919			/* Toggle VLANHWTAG capabilities enabled flag. */
6920			if (mask & IFCAP_VLAN_HWTAGGING) {
6921				if (sc->bce_flags & BCE_MFW_ENABLE_FLAG)
6922					BCE_PRINTF("%s(%d): Cannot change VLAN_HWTAGGING while "
6923						"management firmware (ASF/IPMI/UMP) is running!\n",
6924						__FILE__, __LINE__);
6925				else
6926					BCE_PRINTF("%s(%d): Changing VLAN_HWTAGGING not supported!\n",
6927						__FILE__, __LINE__);
6928			}
6929
6930			break;
6931		default:
6932			/* We don't know how to handle the IOCTL, pass it on. */
6933			error = ether_ioctl(ifp, command, data);
6934			break;
6935	}
6936
6937	DBEXIT(BCE_VERBOSE_MISC);
6938	return(error);
6939}
6940
6941
6942/****************************************************************************/
6943/* Transmit timeout handler.                                                */
6944/*                                                                          */
6945/* Returns:                                                                 */
6946/*   Nothing.                                                               */
6947/****************************************************************************/
6948static void
6949bce_watchdog(struct bce_softc *sc)
6950{
6951	DBENTER(BCE_EXTREME_SEND);
6952
6953	BCE_LOCK_ASSERT(sc);
6954
6955	/* If the watchdog timer hasn't expired then just exit. */
6956	if (sc->watchdog_timer == 0 || --sc->watchdog_timer)
6957		goto bce_watchdog_exit;
6958
6959	/* If pause frames are active then don't reset the hardware. */
6960	/* ToDo: Should we reset the timer here? */
6961	if (REG_RD(sc, BCE_EMAC_TX_STATUS) & BCE_EMAC_TX_STATUS_XOFFED)
6962		goto bce_watchdog_exit;
6963
6964	BCE_PRINTF("%s(%d): Watchdog timeout occurred, resetting!\n",
6965		__FILE__, __LINE__);
6966
6967	DBRUNMSG(BCE_INFO,
6968		bce_dump_driver_state(sc);
6969		bce_dump_status_block(sc);
6970		bce_dump_stats_block(sc);
6971		bce_dump_ftqs(sc);
6972		bce_dump_txp_state(sc, 0);
6973		bce_dump_rxp_state(sc, 0);
6974		bce_dump_tpat_state(sc, 0);
6975		bce_dump_cp_state(sc, 0);
6976		bce_dump_com_state(sc, 0));
6977
6978	DBRUN(bce_breakpoint(sc));
6979
6980	sc->bce_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
6981
6982	bce_init_locked(sc);
6983	sc->bce_ifp->if_oerrors++;
6984
6985bce_watchdog_exit:
6986	DBEXIT(BCE_EXTREME_SEND);
6987}
6988
6989
6990/*
6991 * Interrupt handler.
6992 */
6993/****************************************************************************/
6994/* Main interrupt entry point.  Verifies that the controller generated the  */
6995/* interrupt and then calls a separate routine for handle the various       */
6996/* interrupt causes (PHY, TX, RX).                                          */
6997/*                                                                          */
6998/* Returns:                                                                 */
6999/*   0 for success, positive value for failure.                             */
7000/****************************************************************************/
7001static void
7002bce_intr(void *xsc)
7003{
7004	struct bce_softc *sc;
7005	struct ifnet *ifp;
7006	u32 status_attn_bits;
7007	u16 hw_rx_cons, hw_tx_cons;
7008
7009	sc = xsc;
7010	ifp = sc->bce_ifp;
7011
7012	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
7013	DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_status_block(sc));
7014
7015	BCE_LOCK(sc);
7016
7017	DBRUN(sc->interrupts_generated++);
7018
7019	bus_dmamap_sync(sc->status_tag, sc->status_map,
7020	    BUS_DMASYNC_POSTWRITE);
7021
7022	/*
7023	 * If the hardware status block index
7024	 * matches the last value read by the
7025	 * driver and we haven't asserted our
7026	 * interrupt then there's nothing to do.
7027	 */
7028	if ((sc->status_block->status_idx == sc->last_status_idx) &&
7029		(REG_RD(sc, BCE_PCICFG_MISC_STATUS) & BCE_PCICFG_MISC_STATUS_INTA_VALUE)) {
7030			DBPRINT(sc, BCE_VERBOSE_INTR, "%s(): Spurious interrupt.\n",
7031				__FUNCTION__);
7032			goto bce_intr_exit;
7033	}
7034
7035	/* Ack the interrupt and stop others from occuring. */
7036	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
7037		BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
7038		BCE_PCICFG_INT_ACK_CMD_MASK_INT);
7039
7040	/* Check if the hardware has finished any work. */
7041	hw_rx_cons = bce_get_hw_rx_cons(sc);
7042	hw_tx_cons = bce_get_hw_tx_cons(sc);
7043
7044	/* Keep processing data as long as there is work to do. */
7045	for (;;) {
7046
7047		status_attn_bits = sc->status_block->status_attn_bits;
7048
7049		DBRUNIF(DB_RANDOMTRUE(bce_debug_unexpected_attention),
7050			BCE_PRINTF("Simulating unexpected status attention bit set.");
7051			status_attn_bits = status_attn_bits | STATUS_ATTN_BITS_PARITY_ERROR);
7052
7053		/* Was it a link change interrupt? */
7054		if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
7055			(sc->status_block->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE)) {
7056			bce_phy_intr(sc);
7057
7058			/* Clear any transient status updates during link state change. */
7059			REG_WR(sc, BCE_HC_COMMAND,
7060				sc->hc_command | BCE_HC_COMMAND_COAL_NOW_WO_INT);
7061			REG_RD(sc, BCE_HC_COMMAND);
7062		}
7063
7064		/* If any other attention is asserted then the chip is toast. */
7065		if (((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
7066			(sc->status_block->status_attn_bits_ack &
7067			~STATUS_ATTN_BITS_LINK_STATE))) {
7068
7069			DBRUN(sc->unexpected_attentions++);
7070
7071			BCE_PRINTF("%s(%d): Fatal attention detected: 0x%08X\n",
7072				__FILE__, __LINE__, sc->status_block->status_attn_bits);
7073
7074			DBRUNMSG(BCE_FATAL,
7075				if (bce_debug_unexpected_attention == 0)
7076					bce_breakpoint(sc));
7077
7078			bce_init_locked(sc);
7079			goto bce_intr_exit;
7080		}
7081
7082		/* Check for any completed RX frames. */
7083		if (hw_rx_cons != sc->hw_rx_cons)
7084			bce_rx_intr(sc);
7085
7086		/* Check for any completed TX frames. */
7087		if (hw_tx_cons != sc->hw_tx_cons)
7088			bce_tx_intr(sc);
7089
7090		/* Save the status block index value for use during the next interrupt. */
7091		sc->last_status_idx = sc->status_block->status_idx;
7092
7093		/* Prevent speculative reads from getting ahead of the status block. */
7094		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
7095			BUS_SPACE_BARRIER_READ);
7096
7097		/* If there's no work left then exit the interrupt service routine. */
7098		hw_rx_cons = bce_get_hw_rx_cons(sc);
7099		hw_tx_cons = bce_get_hw_tx_cons(sc);
7100
7101		if ((hw_rx_cons == sc->hw_rx_cons) && (hw_tx_cons == sc->hw_tx_cons))
7102			break;
7103
7104	}
7105
7106	bus_dmamap_sync(sc->status_tag,	sc->status_map,
7107	    BUS_DMASYNC_PREWRITE);
7108
7109	/* Re-enable interrupts. */
7110	bce_enable_intr(sc, 0);
7111
7112	/* Handle any frames that arrived while handling the interrupt. */
7113	if (ifp->if_drv_flags & IFF_DRV_RUNNING && !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
7114		bce_start_locked(ifp);
7115
7116bce_intr_exit:
7117	BCE_UNLOCK(sc);
7118
7119	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
7120}
7121
7122
7123/****************************************************************************/
7124/* Programs the various packet receive modes (broadcast and multicast).     */
7125/*                                                                          */
7126/* Returns:                                                                 */
7127/*   Nothing.                                                               */
7128/****************************************************************************/
7129static void
7130bce_set_rx_mode(struct bce_softc *sc)
7131{
7132	struct ifnet *ifp;
7133	struct ifmultiaddr *ifma;
7134	u32 hashes[NUM_MC_HASH_REGISTERS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
7135	u32 rx_mode, sort_mode;
7136	int h, i;
7137
7138	DBENTER(BCE_VERBOSE_MISC);
7139
7140	BCE_LOCK_ASSERT(sc);
7141
7142	ifp = sc->bce_ifp;
7143
7144	/* Initialize receive mode default settings. */
7145	rx_mode   = sc->rx_mode & ~(BCE_EMAC_RX_MODE_PROMISCUOUS |
7146			    BCE_EMAC_RX_MODE_KEEP_VLAN_TAG);
7147	sort_mode = 1 | BCE_RPM_SORT_USER0_BC_EN;
7148
7149	/*
7150	 * ASF/IPMI/UMP firmware requires that VLAN tag stripping
7151	 * be enbled.
7152	 */
7153	if (!(BCE_IF_CAPABILITIES & IFCAP_VLAN_HWTAGGING) &&
7154		(!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)))
7155		rx_mode |= BCE_EMAC_RX_MODE_KEEP_VLAN_TAG;
7156
7157	/*
7158	 * Check for promiscuous, all multicast, or selected
7159	 * multicast address filtering.
7160	 */
7161	if (ifp->if_flags & IFF_PROMISC) {
7162		DBPRINT(sc, BCE_INFO_MISC, "Enabling promiscuous mode.\n");
7163
7164		/* Enable promiscuous mode. */
7165		rx_mode |= BCE_EMAC_RX_MODE_PROMISCUOUS;
7166		sort_mode |= BCE_RPM_SORT_USER0_PROM_EN;
7167	} else if (ifp->if_flags & IFF_ALLMULTI) {
7168		DBPRINT(sc, BCE_INFO_MISC, "Enabling all multicast mode.\n");
7169
7170		/* Enable all multicast addresses. */
7171		for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
7172			REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), 0xffffffff);
7173       	}
7174		sort_mode |= BCE_RPM_SORT_USER0_MC_EN;
7175	} else {
7176		/* Accept one or more multicast(s). */
7177		DBPRINT(sc, BCE_INFO_MISC, "Enabling selective multicast mode.\n");
7178
7179		IF_ADDR_LOCK(ifp);
7180		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
7181			if (ifma->ifma_addr->sa_family != AF_LINK)
7182				continue;
7183			h = ether_crc32_le(LLADDR((struct sockaddr_dl *)
7184			    ifma->ifma_addr), ETHER_ADDR_LEN) & 0xFF;
7185			    hashes[(h & 0xE0) >> 5] |= 1 << (h & 0x1F);
7186		}
7187		IF_ADDR_UNLOCK(ifp);
7188
7189		for (i = 0; i < NUM_MC_HASH_REGISTERS; i++)
7190			REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), hashes[i]);
7191
7192		sort_mode |= BCE_RPM_SORT_USER0_MC_HSH_EN;
7193	}
7194
7195	/* Only make changes if the recive mode has actually changed. */
7196	if (rx_mode != sc->rx_mode) {
7197		DBPRINT(sc, BCE_VERBOSE_MISC, "Enabling new receive mode: 0x%08X\n",
7198			rx_mode);
7199
7200		sc->rx_mode = rx_mode;
7201		REG_WR(sc, BCE_EMAC_RX_MODE, rx_mode);
7202	}
7203
7204	/* Disable and clear the exisitng sort before enabling a new sort. */
7205	REG_WR(sc, BCE_RPM_SORT_USER0, 0x0);
7206	REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode);
7207	REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode | BCE_RPM_SORT_USER0_ENA);
7208
7209	DBEXIT(BCE_VERBOSE_MISC);
7210}
7211
7212
7213/****************************************************************************/
7214/* Called periodically to updates statistics from the controllers           */
7215/* statistics block.                                                        */
7216/*                                                                          */
7217/* Returns:                                                                 */
7218/*   Nothing.                                                               */
7219/****************************************************************************/
7220static void
7221bce_stats_update(struct bce_softc *sc)
7222{
7223	struct ifnet *ifp;
7224	struct statistics_block *stats;
7225
7226	DBENTER(BCE_EXTREME_MISC);
7227
7228	ifp = sc->bce_ifp;
7229
7230	stats = (struct statistics_block *) sc->stats_block;
7231
7232	/*
7233	 * Certain controllers don't report
7234	 * carrier sense errors correctly.
7235	 * See errata E11_5708CA0_1165.
7236	 */
7237	if (!(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
7238	    !(BCE_CHIP_ID(sc) == BCE_CHIP_ID_5708_A0))
7239		ifp->if_oerrors += (u_long) stats->stat_Dot3StatsCarrierSenseErrors;
7240
7241	/*
7242	 * Update the sysctl statistics from the
7243	 * hardware statistics.
7244	 */
7245	sc->stat_IfHCInOctets =
7246		((u64) stats->stat_IfHCInOctets_hi << 32) +
7247		 (u64) stats->stat_IfHCInOctets_lo;
7248
7249	sc->stat_IfHCInBadOctets =
7250		((u64) stats->stat_IfHCInBadOctets_hi << 32) +
7251		 (u64) stats->stat_IfHCInBadOctets_lo;
7252
7253	sc->stat_IfHCOutOctets =
7254		((u64) stats->stat_IfHCOutOctets_hi << 32) +
7255		 (u64) stats->stat_IfHCOutOctets_lo;
7256
7257	sc->stat_IfHCOutBadOctets =
7258		((u64) stats->stat_IfHCOutBadOctets_hi << 32) +
7259		 (u64) stats->stat_IfHCOutBadOctets_lo;
7260
7261	sc->stat_IfHCInUcastPkts =
7262		((u64) stats->stat_IfHCInUcastPkts_hi << 32) +
7263		 (u64) stats->stat_IfHCInUcastPkts_lo;
7264
7265	sc->stat_IfHCInMulticastPkts =
7266		((u64) stats->stat_IfHCInMulticastPkts_hi << 32) +
7267		 (u64) stats->stat_IfHCInMulticastPkts_lo;
7268
7269	sc->stat_IfHCInBroadcastPkts =
7270		((u64) stats->stat_IfHCInBroadcastPkts_hi << 32) +
7271		 (u64) stats->stat_IfHCInBroadcastPkts_lo;
7272
7273	sc->stat_IfHCOutUcastPkts =
7274		((u64) stats->stat_IfHCOutUcastPkts_hi << 32) +
7275		 (u64) stats->stat_IfHCOutUcastPkts_lo;
7276
7277	sc->stat_IfHCOutMulticastPkts =
7278		((u64) stats->stat_IfHCOutMulticastPkts_hi << 32) +
7279		 (u64) stats->stat_IfHCOutMulticastPkts_lo;
7280
7281	sc->stat_IfHCOutBroadcastPkts =
7282		((u64) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
7283		 (u64) stats->stat_IfHCOutBroadcastPkts_lo;
7284
7285	sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors =
7286		stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
7287
7288	sc->stat_Dot3StatsCarrierSenseErrors =
7289		stats->stat_Dot3StatsCarrierSenseErrors;
7290
7291	sc->stat_Dot3StatsFCSErrors =
7292		stats->stat_Dot3StatsFCSErrors;
7293
7294	sc->stat_Dot3StatsAlignmentErrors =
7295		stats->stat_Dot3StatsAlignmentErrors;
7296
7297	sc->stat_Dot3StatsSingleCollisionFrames =
7298		stats->stat_Dot3StatsSingleCollisionFrames;
7299
7300	sc->stat_Dot3StatsMultipleCollisionFrames =
7301		stats->stat_Dot3StatsMultipleCollisionFrames;
7302
7303	sc->stat_Dot3StatsDeferredTransmissions =
7304		stats->stat_Dot3StatsDeferredTransmissions;
7305
7306	sc->stat_Dot3StatsExcessiveCollisions =
7307		stats->stat_Dot3StatsExcessiveCollisions;
7308
7309	sc->stat_Dot3StatsLateCollisions =
7310		stats->stat_Dot3StatsLateCollisions;
7311
7312	sc->stat_EtherStatsCollisions =
7313		stats->stat_EtherStatsCollisions;
7314
7315	sc->stat_EtherStatsFragments =
7316		stats->stat_EtherStatsFragments;
7317
7318	sc->stat_EtherStatsJabbers =
7319		stats->stat_EtherStatsJabbers;
7320
7321	sc->stat_EtherStatsUndersizePkts =
7322		stats->stat_EtherStatsUndersizePkts;
7323
7324	sc->stat_EtherStatsOverrsizePkts =
7325		stats->stat_EtherStatsOverrsizePkts;
7326
7327	sc->stat_EtherStatsPktsRx64Octets =
7328		stats->stat_EtherStatsPktsRx64Octets;
7329
7330	sc->stat_EtherStatsPktsRx65Octetsto127Octets =
7331		stats->stat_EtherStatsPktsRx65Octetsto127Octets;
7332
7333	sc->stat_EtherStatsPktsRx128Octetsto255Octets =
7334		stats->stat_EtherStatsPktsRx128Octetsto255Octets;
7335
7336	sc->stat_EtherStatsPktsRx256Octetsto511Octets =
7337		stats->stat_EtherStatsPktsRx256Octetsto511Octets;
7338
7339	sc->stat_EtherStatsPktsRx512Octetsto1023Octets =
7340		stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
7341
7342	sc->stat_EtherStatsPktsRx1024Octetsto1522Octets =
7343		stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
7344
7345	sc->stat_EtherStatsPktsRx1523Octetsto9022Octets =
7346		stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
7347
7348	sc->stat_EtherStatsPktsTx64Octets =
7349		stats->stat_EtherStatsPktsTx64Octets;
7350
7351	sc->stat_EtherStatsPktsTx65Octetsto127Octets =
7352		stats->stat_EtherStatsPktsTx65Octetsto127Octets;
7353
7354	sc->stat_EtherStatsPktsTx128Octetsto255Octets =
7355		stats->stat_EtherStatsPktsTx128Octetsto255Octets;
7356
7357	sc->stat_EtherStatsPktsTx256Octetsto511Octets =
7358		stats->stat_EtherStatsPktsTx256Octetsto511Octets;
7359
7360	sc->stat_EtherStatsPktsTx512Octetsto1023Octets =
7361		stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
7362
7363	sc->stat_EtherStatsPktsTx1024Octetsto1522Octets =
7364		stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
7365
7366	sc->stat_EtherStatsPktsTx1523Octetsto9022Octets =
7367		stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
7368
7369	sc->stat_XonPauseFramesReceived =
7370		stats->stat_XonPauseFramesReceived;
7371
7372	sc->stat_XoffPauseFramesReceived =
7373		stats->stat_XoffPauseFramesReceived;
7374
7375	sc->stat_OutXonSent =
7376		stats->stat_OutXonSent;
7377
7378	sc->stat_OutXoffSent =
7379		stats->stat_OutXoffSent;
7380
7381	sc->stat_FlowControlDone =
7382		stats->stat_FlowControlDone;
7383
7384	sc->stat_MacControlFramesReceived =
7385		stats->stat_MacControlFramesReceived;
7386
7387	sc->stat_XoffStateEntered =
7388		stats->stat_XoffStateEntered;
7389
7390	sc->stat_IfInFramesL2FilterDiscards =
7391		stats->stat_IfInFramesL2FilterDiscards;
7392
7393	sc->stat_IfInRuleCheckerDiscards =
7394		stats->stat_IfInRuleCheckerDiscards;
7395
7396	sc->stat_IfInFTQDiscards =
7397		stats->stat_IfInFTQDiscards;
7398
7399	sc->stat_IfInMBUFDiscards =
7400		stats->stat_IfInMBUFDiscards;
7401
7402	sc->stat_IfInRuleCheckerP4Hit =
7403		stats->stat_IfInRuleCheckerP4Hit;
7404
7405	sc->stat_CatchupInRuleCheckerDiscards =
7406		stats->stat_CatchupInRuleCheckerDiscards;
7407
7408	sc->stat_CatchupInFTQDiscards =
7409		stats->stat_CatchupInFTQDiscards;
7410
7411	sc->stat_CatchupInMBUFDiscards =
7412		stats->stat_CatchupInMBUFDiscards;
7413
7414	sc->stat_CatchupInRuleCheckerP4Hit =
7415		stats->stat_CatchupInRuleCheckerP4Hit;
7416
7417	sc->com_no_buffers = REG_RD_IND(sc, 0x120084);
7418
7419	/*
7420	 * Update the interface statistics from the
7421	 * hardware statistics.
7422	 */
7423	ifp->if_collisions =
7424		(u_long) sc->stat_EtherStatsCollisions;
7425
7426	/* ToDo: This method loses soft errors. */
7427	ifp->if_ierrors =
7428		(u_long) sc->stat_EtherStatsUndersizePkts +
7429		(u_long) sc->stat_EtherStatsOverrsizePkts +
7430		(u_long) sc->stat_IfInMBUFDiscards +
7431		(u_long) sc->stat_Dot3StatsAlignmentErrors +
7432		(u_long) sc->stat_Dot3StatsFCSErrors +
7433		(u_long) sc->stat_IfInRuleCheckerDiscards +
7434		(u_long) sc->stat_IfInFTQDiscards +
7435		(u_long) sc->com_no_buffers;
7436
7437	/* ToDo: This method loses soft errors. */
7438	ifp->if_oerrors =
7439		(u_long) sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
7440		(u_long) sc->stat_Dot3StatsExcessiveCollisions +
7441		(u_long) sc->stat_Dot3StatsLateCollisions;
7442
7443	/* ToDo: Add additional statistics. */
7444
7445	DBEXIT(BCE_EXTREME_MISC);
7446}
7447
7448
7449/****************************************************************************/
7450/* Periodic function to notify the bootcode that the driver is still        */
7451/* present.                                                                 */
7452/*                                                                          */
7453/* Returns:                                                                 */
7454/*   Nothing.                                                               */
7455/****************************************************************************/
7456static void
7457bce_pulse(void *xsc)
7458{
7459	struct bce_softc *sc = xsc;
7460	u32 msg;
7461
7462	DBENTER(BCE_EXTREME_MISC);
7463
7464	BCE_LOCK_ASSERT(sc);
7465
7466	/* Tell the firmware that the driver is still running. */
7467	msg = (u32) ++sc->bce_fw_drv_pulse_wr_seq;
7468	REG_WR_IND(sc, sc->bce_shmem_base + BCE_DRV_PULSE_MB, msg);
7469
7470	/* Schedule the next pulse. */
7471	callout_reset(&sc->bce_pulse_callout, hz, bce_pulse, sc);
7472
7473	DBEXIT(BCE_EXTREME_MISC);
7474}
7475
7476
7477/****************************************************************************/
7478/* Periodic function to perform maintenance tasks.                          */
7479/*                                                                          */
7480/* Returns:                                                                 */
7481/*   Nothing.                                                               */
7482/****************************************************************************/
7483static void
7484bce_tick(void *xsc)
7485{
7486	struct bce_softc *sc = xsc;
7487	struct mii_data *mii;
7488	struct ifnet *ifp;
7489
7490	ifp = sc->bce_ifp;
7491
7492	DBENTER(BCE_EXTREME_MISC);
7493
7494	BCE_LOCK_ASSERT(sc);
7495
7496	/* Schedule the next tick. */
7497	callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
7498
7499	/* Update the statistics from the hardware statistics block. */
7500	bce_stats_update(sc);
7501
7502	/* Top off the receive and page chains. */
7503#ifdef BCE_USE_SPLIT_HEADER
7504	bce_fill_pg_chain(sc);
7505#endif
7506	bce_fill_rx_chain(sc);
7507
7508	/* Check that chip hasn't hung. */
7509	bce_watchdog(sc);
7510
7511	/* If link is up already up then we're done. */
7512	if (sc->bce_link)
7513		goto bce_tick_exit;
7514
7515	/* Link is down.  Check what the PHY's doing. */
7516	mii = device_get_softc(sc->bce_miibus);
7517	mii_tick(mii);
7518
7519	/* Check if the link has come up. */
7520	if ((mii->mii_media_status & IFM_ACTIVE) &&
7521	    (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)) {
7522		DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Link up!\n", __FUNCTION__);
7523		sc->bce_link++;
7524		if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
7525		    IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX) &&
7526		    bootverbose)
7527			BCE_PRINTF("Gigabit link up!\n");
7528		/* Now that link is up, handle any outstanding TX traffic. */
7529		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
7530			DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Found pending TX traffic.\n",
7531				 __FUNCTION__);
7532			bce_start_locked(ifp);
7533		}
7534	}
7535
7536bce_tick_exit:
7537	DBEXIT(BCE_EXTREME_MISC);
7538	return;
7539}
7540
7541
7542#ifdef BCE_DEBUG
7543/****************************************************************************/
7544/* Allows the driver state to be dumped through the sysctl interface.       */
7545/*                                                                          */
7546/* Returns:                                                                 */
7547/*   0 for success, positive value for failure.                             */
7548/****************************************************************************/
7549static int
7550bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS)
7551{
7552        int error;
7553        int result;
7554        struct bce_softc *sc;
7555
7556        result = -1;
7557        error = sysctl_handle_int(oidp, &result, 0, req);
7558
7559        if (error || !req->newptr)
7560                return (error);
7561
7562        if (result == 1) {
7563                sc = (struct bce_softc *)arg1;
7564                bce_dump_driver_state(sc);
7565        }
7566
7567        return error;
7568}
7569
7570
7571/****************************************************************************/
7572/* Allows the hardware state to be dumped through the sysctl interface.     */
7573/*                                                                          */
7574/* Returns:                                                                 */
7575/*   0 for success, positive value for failure.                             */
7576/****************************************************************************/
7577static int
7578bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS)
7579{
7580        int error;
7581        int result;
7582        struct bce_softc *sc;
7583
7584        result = -1;
7585        error = sysctl_handle_int(oidp, &result, 0, req);
7586
7587        if (error || !req->newptr)
7588                return (error);
7589
7590        if (result == 1) {
7591                sc = (struct bce_softc *)arg1;
7592                bce_dump_hw_state(sc);
7593        }
7594
7595        return error;
7596}
7597
7598
7599/****************************************************************************/
7600/* Allows the bootcode state to be dumped through the sysctl interface.     */
7601/*                                                                          */
7602/* Returns:                                                                 */
7603/*   0 for success, positive value for failure.                             */
7604/****************************************************************************/
7605static int
7606bce_sysctl_bc_state(SYSCTL_HANDLER_ARGS)
7607{
7608        int error;
7609        int result;
7610        struct bce_softc *sc;
7611
7612        result = -1;
7613        error = sysctl_handle_int(oidp, &result, 0, req);
7614
7615        if (error || !req->newptr)
7616                return (error);
7617
7618        if (result == 1) {
7619                sc = (struct bce_softc *)arg1;
7620                bce_dump_bc_state(sc);
7621        }
7622
7623        return error;
7624}
7625
7626
7627/****************************************************************************/
7628/* Provides a sysctl interface to allow dumping the RX chain.               */
7629/*                                                                          */
7630/* Returns:                                                                 */
7631/*   0 for success, positive value for failure.                             */
7632/****************************************************************************/
7633static int
7634bce_sysctl_dump_rx_chain(SYSCTL_HANDLER_ARGS)
7635{
7636        int error;
7637        int result;
7638        struct bce_softc *sc;
7639
7640        result = -1;
7641        error = sysctl_handle_int(oidp, &result, 0, req);
7642
7643        if (error || !req->newptr)
7644                return (error);
7645
7646        if (result == 1) {
7647                sc = (struct bce_softc *)arg1;
7648                bce_dump_rx_chain(sc, 0, TOTAL_RX_BD);
7649        }
7650
7651        return error;
7652}
7653
7654
7655/****************************************************************************/
7656/* Provides a sysctl interface to allow dumping the TX chain.               */
7657/*                                                                          */
7658/* Returns:                                                                 */
7659/*   0 for success, positive value for failure.                             */
7660/****************************************************************************/
7661static int
7662bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
7663{
7664        int error;
7665        int result;
7666        struct bce_softc *sc;
7667
7668        result = -1;
7669        error = sysctl_handle_int(oidp, &result, 0, req);
7670
7671        if (error || !req->newptr)
7672                return (error);
7673
7674        if (result == 1) {
7675                sc = (struct bce_softc *)arg1;
7676                bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
7677        }
7678
7679        return error;
7680}
7681
7682
7683#ifdef BCE_USE_SPLIT_HEADER
7684/****************************************************************************/
7685/* Provides a sysctl interface to allow dumping the page chain.             */
7686/*                                                                          */
7687/* Returns:                                                                 */
7688/*   0 for success, positive value for failure.                             */
7689/****************************************************************************/
7690static int
7691bce_sysctl_dump_pg_chain(SYSCTL_HANDLER_ARGS)
7692{
7693        int error;
7694        int result;
7695        struct bce_softc *sc;
7696
7697        result = -1;
7698        error = sysctl_handle_int(oidp, &result, 0, req);
7699
7700        if (error || !req->newptr)
7701                return (error);
7702
7703        if (result == 1) {
7704                sc = (struct bce_softc *)arg1;
7705                bce_dump_pg_chain(sc, 0, TOTAL_PG_BD);
7706        }
7707
7708        return error;
7709}
7710#endif
7711
7712/****************************************************************************/
7713/* Provides a sysctl interface to allow reading arbitrary NVRAM offsets in  */
7714/* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
7715/*                                                                          */
7716/* Returns:                                                                 */
7717/*   0 for success, positive value for failure.                             */
7718/****************************************************************************/
7719static int
7720bce_sysctl_nvram_read(SYSCTL_HANDLER_ARGS)
7721{
7722	struct bce_softc *sc = (struct bce_softc *)arg1;
7723	int error;
7724	u32 result;
7725	u32 val[1];
7726	u8 *data = (u8 *) val;
7727
7728	result = -1;
7729	error = sysctl_handle_int(oidp, &result, 0, req);
7730	if (error || (req->newptr == NULL))
7731		return (error);
7732
7733	bce_nvram_read(sc, result, data, 4);
7734	BCE_PRINTF("offset 0x%08X = 0x%08X\n", result, bce_be32toh(val[0]));
7735
7736	return (error);
7737}
7738
7739
7740/****************************************************************************/
7741/* Provides a sysctl interface to allow reading arbitrary registers in the  */
7742/* device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                            */
7743/*                                                                          */
7744/* Returns:                                                                 */
7745/*   0 for success, positive value for failure.                             */
7746/****************************************************************************/
7747static int
7748bce_sysctl_reg_read(SYSCTL_HANDLER_ARGS)
7749{
7750	struct bce_softc *sc = (struct bce_softc *)arg1;
7751	int error;
7752	u32 val, result;
7753
7754	result = -1;
7755	error = sysctl_handle_int(oidp, &result, 0, req);
7756	if (error || (req->newptr == NULL))
7757		return (error);
7758
7759	/* Make sure the register is accessible. */
7760	if (result < 0x8000) {
7761		val = REG_RD(sc, result);
7762		BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
7763	} else if (result < 0x0280000) {
7764		val = REG_RD_IND(sc, result);
7765		BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
7766	}
7767
7768	return (error);
7769}
7770
7771
7772/****************************************************************************/
7773/* Provides a sysctl interface to allow reading arbitrary PHY registers in  */
7774/* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
7775/*                                                                          */
7776/* Returns:                                                                 */
7777/*   0 for success, positive value for failure.                             */
7778/****************************************************************************/
7779static int
7780bce_sysctl_phy_read(SYSCTL_HANDLER_ARGS)
7781{
7782	struct bce_softc *sc;
7783	device_t dev;
7784	int error, result;
7785	u16 val;
7786
7787	result = -1;
7788	error = sysctl_handle_int(oidp, &result, 0, req);
7789	if (error || (req->newptr == NULL))
7790		return (error);
7791
7792	/* Make sure the register is accessible. */
7793	if (result < 0x20) {
7794		sc = (struct bce_softc *)arg1;
7795		dev = sc->bce_dev;
7796		val = bce_miibus_read_reg(dev, sc->bce_phy_addr, result);
7797		BCE_PRINTF("phy 0x%02X = 0x%04X\n", result, val);
7798	}
7799	return (error);
7800}
7801
7802
7803/****************************************************************************/
7804/* Provides a sysctl interface to allow reading a CID.                      */
7805/*                                                                          */
7806/* Returns:                                                                 */
7807/*   0 for success, positive value for failure.                             */
7808/****************************************************************************/
7809static int
7810bce_sysctl_dump_ctx(SYSCTL_HANDLER_ARGS)
7811{
7812	struct bce_softc *sc;
7813	int error;
7814	u16 result;
7815
7816	result = -1;
7817	error = sysctl_handle_int(oidp, &result, 0, req);
7818	if (error || (req->newptr == NULL))
7819		return (error);
7820
7821	/* Make sure the register is accessible. */
7822	if (result <= TX_CID) {
7823		sc = (struct bce_softc *)arg1;
7824		bce_dump_ctx(sc, result);
7825	}
7826
7827	return (error);
7828}
7829
7830
7831 /****************************************************************************/
7832/* Provides a sysctl interface to forcing the driver to dump state and      */
7833/* enter the debugger.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                */
7834/*                                                                          */
7835/* Returns:                                                                 */
7836/*   0 for success, positive value for failure.                             */
7837/****************************************************************************/
7838static int
7839bce_sysctl_breakpoint(SYSCTL_HANDLER_ARGS)
7840{
7841        int error;
7842        int result;
7843        struct bce_softc *sc;
7844
7845        result = -1;
7846        error = sysctl_handle_int(oidp, &result, 0, req);
7847
7848        if (error || !req->newptr)
7849                return (error);
7850
7851        if (result == 1) {
7852                sc = (struct bce_softc *)arg1;
7853                bce_breakpoint(sc);
7854        }
7855
7856        return error;
7857}
7858#endif
7859
7860
7861/****************************************************************************/
7862/* Adds any sysctl parameters for tuning or debugging purposes.             */
7863/*                                                                          */
7864/* Returns:                                                                 */
7865/*   0 for success, positive value for failure.                             */
7866/****************************************************************************/
7867static void
7868bce_add_sysctls(struct bce_softc *sc)
7869{
7870	struct sysctl_ctx_list *ctx;
7871	struct sysctl_oid_list *children;
7872
7873	DBENTER(BCE_VERBOSE_MISC);
7874
7875	ctx = device_get_sysctl_ctx(sc->bce_dev);
7876	children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->bce_dev));
7877
7878#ifdef BCE_DEBUG
7879	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7880		"rx_low_watermark",
7881		CTLFLAG_RD, &sc->rx_low_watermark,
7882		0, "Lowest level of free rx_bd's");
7883
7884	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7885		"rx_empty_count",
7886		CTLFLAG_RD, &sc->rx_empty_count,
7887		0, "Number of times the RX chain was empty");
7888
7889	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7890		"tx_hi_watermark",
7891		CTLFLAG_RD, &sc->tx_hi_watermark,
7892		0, "Highest level of used tx_bd's");
7893
7894	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7895		"tx_full_count",
7896		CTLFLAG_RD, &sc->tx_full_count,
7897		0, "Number of times the TX chain was full");
7898
7899	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7900		"l2fhdr_status_errors",
7901		CTLFLAG_RD, &sc->l2fhdr_status_errors,
7902		0, "l2_fhdr status errors");
7903
7904	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7905		"unexpected_attentions",
7906		CTLFLAG_RD, &sc->unexpected_attentions,
7907		0, "Unexpected attentions");
7908
7909	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7910		"lost_status_block_updates",
7911		CTLFLAG_RD, &sc->lost_status_block_updates,
7912		0, "Lost status block updates");
7913
7914	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7915		"debug_mbuf_sim_alloc_failed",
7916		CTLFLAG_RD, &sc->debug_mbuf_sim_alloc_failed,
7917		0, "Simulated mbuf cluster allocation failures");
7918
7919	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7920		"requested_tso_frames",
7921		CTLFLAG_RD, &sc->requested_tso_frames,
7922		0, "Number of TSO frames received");
7923
7924	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
7925		"rx_interrupts",
7926		CTLFLAG_RD, &sc->rx_interrupts,
7927		0, "Number of RX interrupts");
7928
7929	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
7930		"tx_interrupts",
7931		CTLFLAG_RD, &sc->tx_interrupts,
7932		0, "Number of TX interrupts");
7933
7934	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7935		"rx_intr_time",
7936		CTLFLAG_RD, &sc->rx_intr_time,
7937		"RX interrupt time");
7938
7939	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7940		"tx_intr_time",
7941		CTLFLAG_RD, &sc->tx_intr_time,
7942		"TX interrupt time");
7943#endif
7944
7945	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7946		"mbuf_alloc_failed",
7947		CTLFLAG_RD, &sc->mbuf_alloc_failed,
7948		0, "mbuf cluster allocation failures");
7949
7950	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
7951		"tx_dma_map_failures",
7952		CTLFLAG_RD, &sc->tx_dma_map_failures,
7953		0, "tx dma mapping failures");
7954
7955	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7956		"stat_IfHcInOctets",
7957		CTLFLAG_RD, &sc->stat_IfHCInOctets,
7958		"Bytes received");
7959
7960	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7961		"stat_IfHCInBadOctets",
7962		CTLFLAG_RD, &sc->stat_IfHCInBadOctets,
7963		"Bad bytes received");
7964
7965	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7966		"stat_IfHCOutOctets",
7967		CTLFLAG_RD, &sc->stat_IfHCOutOctets,
7968		"Bytes sent");
7969
7970	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7971		"stat_IfHCOutBadOctets",
7972		CTLFLAG_RD, &sc->stat_IfHCOutBadOctets,
7973		"Bad bytes sent");
7974
7975	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7976		"stat_IfHCInUcastPkts",
7977		CTLFLAG_RD, &sc->stat_IfHCInUcastPkts,
7978		"Unicast packets received");
7979
7980	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7981		"stat_IfHCInMulticastPkts",
7982		CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts,
7983		"Multicast packets received");
7984
7985	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7986		"stat_IfHCInBroadcastPkts",
7987		CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts,
7988		"Broadcast packets received");
7989
7990	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7991		"stat_IfHCOutUcastPkts",
7992		CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts,
7993		"Unicast packets sent");
7994
7995	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
7996		"stat_IfHCOutMulticastPkts",
7997		CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts,
7998		"Multicast packets sent");
7999
8000	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8001		"stat_IfHCOutBroadcastPkts",
8002		CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts,
8003		"Broadcast packets sent");
8004
8005	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8006		"stat_emac_tx_stat_dot3statsinternalmactransmiterrors",
8007		CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors,
8008		0, "Internal MAC transmit errors");
8009
8010	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8011		"stat_Dot3StatsCarrierSenseErrors",
8012		CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors,
8013		0, "Carrier sense errors");
8014
8015	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8016		"stat_Dot3StatsFCSErrors",
8017		CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors,
8018		0, "Frame check sequence errors");
8019
8020	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8021		"stat_Dot3StatsAlignmentErrors",
8022		CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors,
8023		0, "Alignment errors");
8024
8025	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8026		"stat_Dot3StatsSingleCollisionFrames",
8027		CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames,
8028		0, "Single Collision Frames");
8029
8030	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8031		"stat_Dot3StatsMultipleCollisionFrames",
8032		CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames,
8033		0, "Multiple Collision Frames");
8034
8035	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8036		"stat_Dot3StatsDeferredTransmissions",
8037		CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions,
8038		0, "Deferred Transmissions");
8039
8040	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8041		"stat_Dot3StatsExcessiveCollisions",
8042		CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions,
8043		0, "Excessive Collisions");
8044
8045	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8046		"stat_Dot3StatsLateCollisions",
8047		CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions,
8048		0, "Late Collisions");
8049
8050	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8051		"stat_EtherStatsCollisions",
8052		CTLFLAG_RD, &sc->stat_EtherStatsCollisions,
8053		0, "Collisions");
8054
8055	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8056		"stat_EtherStatsFragments",
8057		CTLFLAG_RD, &sc->stat_EtherStatsFragments,
8058		0, "Fragments");
8059
8060	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8061		"stat_EtherStatsJabbers",
8062		CTLFLAG_RD, &sc->stat_EtherStatsJabbers,
8063		0, "Jabbers");
8064
8065	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8066		"stat_EtherStatsUndersizePkts",
8067		CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts,
8068		0, "Undersize packets");
8069
8070	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8071		"stat_EtherStatsOverrsizePkts",
8072		CTLFLAG_RD, &sc->stat_EtherStatsOverrsizePkts,
8073		0, "stat_EtherStatsOverrsizePkts");
8074
8075	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8076		"stat_EtherStatsPktsRx64Octets",
8077		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets,
8078		0, "Bytes received in 64 byte packets");
8079
8080	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8081		"stat_EtherStatsPktsRx65Octetsto127Octets",
8082		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets,
8083		0, "Bytes received in 65 to 127 byte packets");
8084
8085	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8086		"stat_EtherStatsPktsRx128Octetsto255Octets",
8087		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets,
8088		0, "Bytes received in 128 to 255 byte packets");
8089
8090	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8091		"stat_EtherStatsPktsRx256Octetsto511Octets",
8092		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets,
8093		0, "Bytes received in 256 to 511 byte packets");
8094
8095	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8096		"stat_EtherStatsPktsRx512Octetsto1023Octets",
8097		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets,
8098		0, "Bytes received in 512 to 1023 byte packets");
8099
8100	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8101		"stat_EtherStatsPktsRx1024Octetsto1522Octets",
8102		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets,
8103		0, "Bytes received in 1024 t0 1522 byte packets");
8104
8105	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8106		"stat_EtherStatsPktsRx1523Octetsto9022Octets",
8107		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets,
8108		0, "Bytes received in 1523 to 9022 byte packets");
8109
8110	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8111		"stat_EtherStatsPktsTx64Octets",
8112		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets,
8113		0, "Bytes sent in 64 byte packets");
8114
8115	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8116		"stat_EtherStatsPktsTx65Octetsto127Octets",
8117		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets,
8118		0, "Bytes sent in 65 to 127 byte packets");
8119
8120	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8121		"stat_EtherStatsPktsTx128Octetsto255Octets",
8122		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets,
8123		0, "Bytes sent in 128 to 255 byte packets");
8124
8125	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8126		"stat_EtherStatsPktsTx256Octetsto511Octets",
8127		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets,
8128		0, "Bytes sent in 256 to 511 byte packets");
8129
8130	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8131		"stat_EtherStatsPktsTx512Octetsto1023Octets",
8132		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets,
8133		0, "Bytes sent in 512 to 1023 byte packets");
8134
8135	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8136		"stat_EtherStatsPktsTx1024Octetsto1522Octets",
8137		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets,
8138		0, "Bytes sent in 1024 to 1522 byte packets");
8139
8140	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8141		"stat_EtherStatsPktsTx1523Octetsto9022Octets",
8142		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets,
8143		0, "Bytes sent in 1523 to 9022 byte packets");
8144
8145	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8146		"stat_XonPauseFramesReceived",
8147		CTLFLAG_RD, &sc->stat_XonPauseFramesReceived,
8148		0, "XON pause frames receved");
8149
8150	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8151		"stat_XoffPauseFramesReceived",
8152		CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived,
8153		0, "XOFF pause frames received");
8154
8155	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8156		"stat_OutXonSent",
8157		CTLFLAG_RD, &sc->stat_OutXonSent,
8158		0, "XON pause frames sent");
8159
8160	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8161		"stat_OutXoffSent",
8162		CTLFLAG_RD, &sc->stat_OutXoffSent,
8163		0, "XOFF pause frames sent");
8164
8165	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8166		"stat_FlowControlDone",
8167		CTLFLAG_RD, &sc->stat_FlowControlDone,
8168		0, "Flow control done");
8169
8170	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8171		"stat_MacControlFramesReceived",
8172		CTLFLAG_RD, &sc->stat_MacControlFramesReceived,
8173		0, "MAC control frames received");
8174
8175	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8176		"stat_XoffStateEntered",
8177		CTLFLAG_RD, &sc->stat_XoffStateEntered,
8178		0, "XOFF state entered");
8179
8180	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8181		"stat_IfInFramesL2FilterDiscards",
8182		CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards,
8183		0, "Received L2 packets discarded");
8184
8185	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8186		"stat_IfInRuleCheckerDiscards",
8187		CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards,
8188		0, "Received packets discarded by rule");
8189
8190	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8191		"stat_IfInFTQDiscards",
8192		CTLFLAG_RD, &sc->stat_IfInFTQDiscards,
8193		0, "Received packet FTQ discards");
8194
8195	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8196		"stat_IfInMBUFDiscards",
8197		CTLFLAG_RD, &sc->stat_IfInMBUFDiscards,
8198		0, "Received packets discarded due to lack of controller buffer memory");
8199
8200	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8201		"stat_IfInRuleCheckerP4Hit",
8202		CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit,
8203		0, "Received packets rule checker hits");
8204
8205	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8206		"stat_CatchupInRuleCheckerDiscards",
8207		CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards,
8208		0, "Received packets discarded in Catchup path");
8209
8210	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8211		"stat_CatchupInFTQDiscards",
8212		CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards,
8213		0, "Received packets discarded in FTQ in Catchup path");
8214
8215	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8216		"stat_CatchupInMBUFDiscards",
8217		CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards,
8218		0, "Received packets discarded in controller buffer memory in Catchup path");
8219
8220	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8221		"stat_CatchupInRuleCheckerP4Hit",
8222		CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit,
8223		0, "Received packets rule checker hits in Catchup path");
8224
8225	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8226		"com_no_buffers",
8227		CTLFLAG_RD, &sc->com_no_buffers,
8228		0, "Valid packets received but no RX buffers available");
8229
8230#ifdef BCE_DEBUG
8231	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8232		"driver_state", CTLTYPE_INT | CTLFLAG_RW,
8233		(void *)sc, 0,
8234		bce_sysctl_driver_state, "I", "Drive state information");
8235
8236	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8237		"hw_state", CTLTYPE_INT | CTLFLAG_RW,
8238		(void *)sc, 0,
8239		bce_sysctl_hw_state, "I", "Hardware state information");
8240
8241	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8242		"bc_state", CTLTYPE_INT | CTLFLAG_RW,
8243		(void *)sc, 0,
8244		bce_sysctl_bc_state, "I", "Bootcode state information");
8245
8246	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8247		"dump_rx_chain", CTLTYPE_INT | CTLFLAG_RW,
8248		(void *)sc, 0,
8249		bce_sysctl_dump_rx_chain, "I", "Dump rx_bd chain");
8250
8251	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8252		"dump_tx_chain", CTLTYPE_INT | CTLFLAG_RW,
8253		(void *)sc, 0,
8254		bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
8255
8256#ifdef BCE_USE_SPLIT_HEADER
8257	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8258		"dump_pg_chain", CTLTYPE_INT | CTLFLAG_RW,
8259		(void *)sc, 0,
8260		bce_sysctl_dump_pg_chain, "I", "Dump page chain");
8261#endif
8262	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8263		"dump_ctx", CTLTYPE_INT | CTLFLAG_RW,
8264		(void *)sc, 0,
8265		bce_sysctl_dump_ctx, "I", "Dump context memory");
8266
8267	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8268		"breakpoint", CTLTYPE_INT | CTLFLAG_RW,
8269		(void *)sc, 0,
8270		bce_sysctl_breakpoint, "I", "Driver breakpoint");
8271
8272	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8273		"reg_read", CTLTYPE_INT | CTLFLAG_RW,
8274		(void *)sc, 0,
8275		bce_sysctl_reg_read, "I", "Register read");
8276
8277	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8278		"nvram_read", CTLTYPE_INT | CTLFLAG_RW,
8279		(void *)sc, 0,
8280		bce_sysctl_nvram_read, "I", "NVRAM read");
8281
8282	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8283		"phy_read", CTLTYPE_INT | CTLFLAG_RW,
8284		(void *)sc, 0,
8285		bce_sysctl_phy_read, "I", "PHY register read");
8286
8287#endif
8288
8289	DBEXIT(BCE_VERBOSE_MISC);
8290}
8291
8292
8293/****************************************************************************/
8294/* BCE Debug Routines                                                       */
8295/****************************************************************************/
8296#ifdef BCE_DEBUG
8297
8298/****************************************************************************/
8299/* Freezes the controller to allow for a cohesive state dump.               */
8300/*                                                                          */
8301/* Returns:                                                                 */
8302/*   Nothing.                                                               */
8303/****************************************************************************/
8304static void
8305bce_freeze_controller(struct bce_softc *sc)
8306{
8307	u32 val;
8308	val = REG_RD(sc, BCE_MISC_COMMAND);
8309	val |= BCE_MISC_COMMAND_DISABLE_ALL;
8310	REG_WR(sc, BCE_MISC_COMMAND, val);
8311}
8312
8313
8314/****************************************************************************/
8315/* Unfreezes the controller after a freeze operation.  This may not always  */
8316/* work and the controller will require a reset!                            */
8317/*                                                                          */
8318/* Returns:                                                                 */
8319/*   Nothing.                                                               */
8320/****************************************************************************/
8321static void
8322bce_unfreeze_controller(struct bce_softc *sc)
8323{
8324	u32 val;
8325	val = REG_RD(sc, BCE_MISC_COMMAND);
8326	val |= BCE_MISC_COMMAND_ENABLE_ALL;
8327	REG_WR(sc, BCE_MISC_COMMAND, val);
8328}
8329
8330
8331/****************************************************************************/
8332/* Prints out Ethernet frame information from an mbuf.                      */
8333/*                                                                          */
8334/* Partially decode an Ethernet frame to look at some important headers.    */
8335/*                                                                          */
8336/* Returns:                                                                 */
8337/*   Nothing.                                                               */
8338/****************************************************************************/
8339static void
8340bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
8341{
8342	struct ether_vlan_header *eh;
8343	u16 etype;
8344	int ehlen;
8345	struct ip *ip;
8346	struct tcphdr *th;
8347	struct udphdr *uh;
8348	struct arphdr *ah;
8349
8350		BCE_PRINTF(
8351			"-----------------------------"
8352			" Frame Decode "
8353			"-----------------------------\n");
8354
8355	eh = mtod(m, struct ether_vlan_header *);
8356
8357	/* Handle VLAN encapsulation if present. */
8358	if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
8359		etype = ntohs(eh->evl_proto);
8360		ehlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
8361	} else {
8362		etype = ntohs(eh->evl_encap_proto);
8363		ehlen = ETHER_HDR_LEN;
8364	}
8365
8366	/* ToDo: Add VLAN output. */
8367	BCE_PRINTF("enet: dest = %6D, src = %6D, type = 0x%04X, hlen = %d\n",
8368		eh->evl_dhost, ":", eh->evl_shost, ":", etype, ehlen);
8369
8370	switch (etype) {
8371		case ETHERTYPE_IP:
8372			ip = (struct ip *)(m->m_data + ehlen);
8373			BCE_PRINTF("--ip: dest = 0x%08X , src = 0x%08X, len = %d bytes, "
8374				"protocol = 0x%02X, xsum = 0x%04X\n",
8375				ntohl(ip->ip_dst.s_addr), ntohl(ip->ip_src.s_addr),
8376				ntohs(ip->ip_len), ip->ip_p, ntohs(ip->ip_sum));
8377
8378			switch (ip->ip_p) {
8379				case IPPROTO_TCP:
8380					th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
8381					BCE_PRINTF("-tcp: dest = %d, src = %d, hlen = %d bytes, "
8382						"flags = 0x%b, csum = 0x%04X\n",
8383						ntohs(th->th_dport), ntohs(th->th_sport), (th->th_off << 2),
8384						th->th_flags, "\20\10CWR\07ECE\06URG\05ACK\04PSH\03RST\02SYN\01FIN",
8385						ntohs(th->th_sum));
8386					break;
8387				case IPPROTO_UDP:
8388        		    uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
8389					BCE_PRINTF("-udp: dest = %d, src = %d, len = %d bytes, "
8390						"csum = 0x%04X\n", ntohs(uh->uh_dport), ntohs(uh->uh_sport),
8391						ntohs(uh->uh_ulen), ntohs(uh->uh_sum));
8392					break;
8393				case IPPROTO_ICMP:
8394					BCE_PRINTF("icmp:\n");
8395					break;
8396				default:
8397					BCE_PRINTF("----: Other IP protocol.\n");
8398			}
8399			break;
8400		case ETHERTYPE_IPV6:
8401			BCE_PRINTF("ipv6: No decode supported.\n");
8402			break;
8403		case ETHERTYPE_ARP:
8404			BCE_PRINTF("-arp: ");
8405			ah = (struct arphdr *) (m->m_data + ehlen);
8406			switch (ntohs(ah->ar_op)) {
8407				case ARPOP_REVREQUEST:
8408					printf("reverse ARP request\n");
8409					break;
8410				case ARPOP_REVREPLY:
8411					printf("reverse ARP reply\n");
8412					break;
8413				case ARPOP_REQUEST:
8414					printf("ARP request\n");
8415					break;
8416				case ARPOP_REPLY:
8417					printf("ARP reply\n");
8418					break;
8419				default:
8420					printf("other ARP operation\n");
8421			}
8422			break;
8423		default:
8424			BCE_PRINTF("----: Other protocol.\n");
8425	}
8426
8427	BCE_PRINTF(
8428		"-----------------------------"
8429		"--------------"
8430		"-----------------------------\n");
8431}
8432
8433
8434/****************************************************************************/
8435/* Prints out information about an mbuf.                                    */
8436/*                                                                          */
8437/* Returns:                                                                 */
8438/*   Nothing.                                                               */
8439/****************************************************************************/
8440static __attribute__ ((noinline)) void
8441bce_dump_mbuf(struct bce_softc *sc, struct mbuf *m)
8442{
8443	struct mbuf *mp = m;
8444
8445	if (m == NULL) {
8446		BCE_PRINTF("mbuf: null pointer\n");
8447		return;
8448	}
8449
8450	while (mp) {
8451		BCE_PRINTF("mbuf: %p, m_len = %d, m_flags = 0x%b, m_data = %p\n",
8452			mp, mp->m_len, mp->m_flags,
8453			"\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY",
8454			mp->m_data);
8455
8456		if (mp->m_flags & M_PKTHDR) {
8457			BCE_PRINTF("- m_pkthdr: len = %d, flags = 0x%b, csum_flags = %b\n",
8458				mp->m_pkthdr.len, mp->m_flags,
8459				"\20\12M_BCAST\13M_MCAST\14M_FRAG\15M_FIRSTFRAG"
8460				"\16M_LASTFRAG\21M_VLANTAG\22M_PROMISC\23M_NOFREE",
8461				mp->m_pkthdr.csum_flags,
8462				"\20\1CSUM_IP\2CSUM_TCP\3CSUM_UDP\4CSUM_IP_FRAGS"
8463				"\5CSUM_FRAGMENT\6CSUM_TSO\11CSUM_IP_CHECKED"
8464				"\12CSUM_IP_VALID\13CSUM_DATA_VALID\14CSUM_PSEUDO_HDR");
8465		}
8466
8467		if (mp->m_flags & M_EXT) {
8468			BCE_PRINTF("- m_ext: %p, ext_size = %d, type = ",
8469				mp->m_ext.ext_buf, mp->m_ext.ext_size);
8470			switch (mp->m_ext.ext_type) {
8471				case EXT_CLUSTER:    printf("EXT_CLUSTER\n"); break;
8472				case EXT_SFBUF:      printf("EXT_SFBUF\n"); break;
8473				case EXT_JUMBO9:     printf("EXT_JUMBO9\n"); break;
8474				case EXT_JUMBO16:    printf("EXT_JUMBO16\n"); break;
8475				case EXT_PACKET:     printf("EXT_PACKET\n"); break;
8476				case EXT_MBUF:       printf("EXT_MBUF\n"); break;
8477				case EXT_NET_DRV:    printf("EXT_NET_DRV\n"); break;
8478				case EXT_MOD_TYPE:   printf("EXT_MDD_TYPE\n"); break;
8479				case EXT_DISPOSABLE: printf("EXT_DISPOSABLE\n"); break;
8480				case EXT_EXTREF:     printf("EXT_EXTREF\n"); break;
8481				default:             printf("UNKNOWN\n");
8482			}
8483		}
8484
8485		mp = mp->m_next;
8486	}
8487}
8488
8489
8490/****************************************************************************/
8491/* Prints out the mbufs in the TX mbuf chain.                               */
8492/*                                                                          */
8493/* Returns:                                                                 */
8494/*   Nothing.                                                               */
8495/****************************************************************************/
8496static __attribute__ ((noinline)) void
8497bce_dump_tx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
8498{
8499	struct mbuf *m;
8500
8501	BCE_PRINTF(
8502		"----------------------------"
8503		"  tx mbuf data  "
8504		"----------------------------\n");
8505
8506	for (int i = 0; i < count; i++) {
8507	 	m = sc->tx_mbuf_ptr[chain_prod];
8508		BCE_PRINTF("txmbuf[0x%04X]\n", chain_prod);
8509		bce_dump_mbuf(sc, m);
8510		chain_prod = TX_CHAIN_IDX(NEXT_TX_BD(chain_prod));
8511	}
8512
8513	BCE_PRINTF(
8514		"----------------------------"
8515		"----------------"
8516		"----------------------------\n");
8517}
8518
8519
8520/****************************************************************************/
8521/* Prints out the mbufs in the RX mbuf chain.                               */
8522/*                                                                          */
8523/* Returns:                                                                 */
8524/*   Nothing.                                                               */
8525/****************************************************************************/
8526static __attribute__ ((noinline)) void
8527bce_dump_rx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
8528{
8529	struct mbuf *m;
8530
8531	BCE_PRINTF(
8532		"----------------------------"
8533		"  rx mbuf data  "
8534		"----------------------------\n");
8535
8536	for (int i = 0; i < count; i++) {
8537	 	m = sc->rx_mbuf_ptr[chain_prod];
8538		BCE_PRINTF("rxmbuf[0x%04X]\n", chain_prod);
8539		bce_dump_mbuf(sc, m);
8540		chain_prod = RX_CHAIN_IDX(NEXT_RX_BD(chain_prod));
8541	}
8542
8543
8544	BCE_PRINTF(
8545		"----------------------------"
8546		"----------------"
8547		"----------------------------\n");
8548}
8549
8550
8551#ifdef BCE_USE_SPLIT_HEADER
8552/****************************************************************************/
8553/* Prints out the mbufs in the mbuf page chain.                             */
8554/*                                                                          */
8555/* Returns:                                                                 */
8556/*   Nothing.                                                               */
8557/****************************************************************************/
8558static __attribute__ ((noinline)) void
8559bce_dump_pg_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
8560{
8561	struct mbuf *m;
8562
8563	BCE_PRINTF(
8564		"----------------------------"
8565		"  pg mbuf data  "
8566		"----------------------------\n");
8567
8568	for (int i = 0; i < count; i++) {
8569	 	m = sc->pg_mbuf_ptr[chain_prod];
8570		BCE_PRINTF("pgmbuf[0x%04X]\n", chain_prod);
8571		bce_dump_mbuf(sc, m);
8572		chain_prod = PG_CHAIN_IDX(NEXT_PG_BD(chain_prod));
8573	}
8574
8575
8576	BCE_PRINTF(
8577		"----------------------------"
8578		"----------------"
8579		"----------------------------\n");
8580}
8581#endif
8582
8583
8584/****************************************************************************/
8585/* Prints out a tx_bd structure.                                            */
8586/*                                                                          */
8587/* Returns:                                                                 */
8588/*   Nothing.                                                               */
8589/****************************************************************************/
8590static __attribute__ ((noinline)) void
8591bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
8592{
8593	if (idx > MAX_TX_BD)
8594		/* Index out of range. */
8595		BCE_PRINTF("tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
8596	else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
8597		/* TX Chain page pointer. */
8598		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
8599			idx, txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo);
8600	else {
8601			/* Normal tx_bd entry. */
8602			BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
8603				"vlan tag= 0x%04X, flags = 0x%04X (", idx,
8604				txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
8605				txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag,
8606				txbd->tx_bd_flags);
8607
8608			if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT)
8609				printf(" CONN_FAULT");
8610
8611			if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM)
8612				printf(" TCP_UDP_CKSUM");
8613
8614			if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM)
8615				printf(" IP_CKSUM");
8616
8617			if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG)
8618				printf("  VLAN");
8619
8620			if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW)
8621				printf(" COAL_NOW");
8622
8623			if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC)
8624				printf(" DONT_GEN_CRC");
8625
8626			if (txbd->tx_bd_flags & TX_BD_FLAGS_START)
8627				printf(" START");
8628
8629			if (txbd->tx_bd_flags & TX_BD_FLAGS_END)
8630				printf(" END");
8631
8632			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO)
8633				printf(" LSO");
8634
8635			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD)
8636				printf(" OPTION_WORD");
8637
8638			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS)
8639				printf(" FLAGS");
8640
8641			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP)
8642				printf(" SNAP");
8643
8644			printf(" )\n");
8645		}
8646
8647}
8648
8649
8650/****************************************************************************/
8651/* Prints out a rx_bd structure.                                            */
8652/*                                                                          */
8653/* Returns:                                                                 */
8654/*   Nothing.                                                               */
8655/****************************************************************************/
8656static __attribute__ ((noinline)) void
8657bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd)
8658{
8659	if (idx > MAX_RX_BD)
8660		/* Index out of range. */
8661		BCE_PRINTF("rx_bd[0x%04X]: Invalid rx_bd index!\n", idx);
8662	else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
8663		/* RX Chain page pointer. */
8664		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
8665			idx, rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo);
8666	else
8667		/* Normal rx_bd entry. */
8668		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
8669			"flags = 0x%08X\n", idx,
8670			rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo,
8671			rxbd->rx_bd_len, rxbd->rx_bd_flags);
8672}
8673
8674
8675#ifdef BCE_USE_SPLIT_HEADER
8676/****************************************************************************/
8677/* Prints out a rx_bd structure in the page chain.                          */
8678/*                                                                          */
8679/* Returns:                                                                 */
8680/*   Nothing.                                                               */
8681/****************************************************************************/
8682static __attribute__ ((noinline)) void
8683bce_dump_pgbd(struct bce_softc *sc, int idx, struct rx_bd *pgbd)
8684{
8685	if (idx > MAX_PG_BD)
8686		/* Index out of range. */
8687		BCE_PRINTF("pg_bd[0x%04X]: Invalid pg_bd index!\n", idx);
8688	else if ((idx & USABLE_PG_BD_PER_PAGE) == USABLE_PG_BD_PER_PAGE)
8689		/* Page Chain page pointer. */
8690		BCE_PRINTF("px_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
8691			idx, pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo);
8692	else
8693		/* Normal rx_bd entry. */
8694		BCE_PRINTF("pg_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
8695			"flags = 0x%08X\n", idx,
8696			pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo,
8697			pgbd->rx_bd_len, pgbd->rx_bd_flags);
8698}
8699#endif
8700
8701
8702/****************************************************************************/
8703/* Prints out a l2_fhdr structure.                                          */
8704/*                                                                          */
8705/* Returns:                                                                 */
8706/*   Nothing.                                                               */
8707/****************************************************************************/
8708static __attribute__ ((noinline)) void
8709bce_dump_l2fhdr(struct bce_softc *sc, int idx, struct l2_fhdr *l2fhdr)
8710{
8711	BCE_PRINTF("l2_fhdr[0x%04X]: status = 0x%b, "
8712		"pkt_len = %d, vlan = 0x%04x, ip_xsum/hdr_len = 0x%04X, "
8713		"tcp_udp_xsum = 0x%04X\n", idx,
8714		l2fhdr->l2_fhdr_status, BCE_L2FHDR_PRINTFB,
8715		l2fhdr->l2_fhdr_pkt_len, l2fhdr->l2_fhdr_vlan_tag,
8716		l2fhdr->l2_fhdr_ip_xsum, l2fhdr->l2_fhdr_tcp_udp_xsum);
8717}
8718
8719
8720/****************************************************************************/
8721/* Prints out context memory info.  (Only useful for CID 0 to 16.)          */
8722/*                                                                          */
8723/* Returns:                                                                 */
8724/*   Nothing.                                                               */
8725/****************************************************************************/
8726static __attribute__ ((noinline)) void
8727bce_dump_ctx(struct bce_softc *sc, u16 cid)
8728{
8729	if (cid <= TX_CID) {
8730		BCE_PRINTF(
8731			"----------------------------"
8732			"    CTX Data    "
8733			"----------------------------\n");
8734
8735		BCE_PRINTF("     0x%04X - (CID) Context ID\n", cid);
8736
8737		if (cid == RX_CID) {
8738			BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BDIDX) host rx "
8739				"producer index\n",
8740				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BDIDX));
8741			BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BSEQ) host byte sequence\n",
8742				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BSEQ));
8743			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BSEQ) h/w byte sequence\n",
8744				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BSEQ));
8745			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_HI) h/w buffer "
8746				"descriptor address\n",
8747 				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_HI));
8748			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_LO) h/w buffer "
8749				"descriptor address\n",
8750				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_LO));
8751			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDIDX) h/w rx consumer index\n",
8752				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDIDX));
8753			BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_PG_BDIDX) host page "
8754				"producer index\n",
8755				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_PG_BDIDX));
8756			BCE_PRINTF(" 0x%08X - (L2CTX_RX_PG_BUF_SIZE) host rx_bd/page "
8757				"buffer size\n",
8758				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_PG_BUF_SIZE));
8759			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_HI) h/w page "
8760				"chain address\n",
8761				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_PG_BDHADDR_HI));
8762			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_LO) h/w page "
8763				"chain address\n",
8764				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_PG_BDHADDR_LO));
8765			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDIDX) h/w page "
8766				"consumer index\n",
8767				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_PG_BDIDX));
8768		} else if (cid == TX_CID) {
8769			if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
8770				(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
8771				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE_XI) ctx type\n",
8772					CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE_XI));
8773				BCE_PRINTF(" 0x%08X - (L2CTX_CMD_TX_TYPE_XI) ctx cmd\n",
8774					CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_CMD_TYPE_XI));
8775				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI_XI) h/w buffer "
8776					"descriptor address\n",	CTX_RD(sc,
8777					GET_CID_ADDR(cid), BCE_L2CTX_TX_TBDR_BHADDR_HI_XI));
8778				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO_XI) h/w buffer "
8779					"descriptor address\n", CTX_RD(sc,
8780					GET_CID_ADDR(cid), BCE_L2CTX_TX_TBDR_BHADDR_LO_XI));
8781				BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX_XI) host producer "
8782					"index\n", CTX_RD(sc, GET_CID_ADDR(cid),
8783					BCE_L2CTX_TX_HOST_BIDX_XI));
8784				BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ_XI) host byte "
8785					"sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
8786					BCE_L2CTX_TX_HOST_BSEQ_XI));
8787			} else {
8788				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE) ctx type\n",
8789					CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE));
8790				BCE_PRINTF(" 0x%08X - (L2CTX_TX_CMD_TYPE) ctx cmd\n",
8791					CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_CMD_TYPE));
8792				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI) h/w buffer "
8793					"descriptor address\n", CTX_RD(sc, GET_CID_ADDR(cid),
8794					BCE_L2CTX_TX_TBDR_BHADDR_HI));
8795				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO) h/w buffer "
8796					"descriptor address\n", CTX_RD(sc, GET_CID_ADDR(cid),
8797					BCE_L2CTX_TX_TBDR_BHADDR_LO));
8798				BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX) host producer "
8799					"index\n", CTX_RD(sc, GET_CID_ADDR(cid),
8800					BCE_L2CTX_TX_HOST_BIDX));
8801				BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ) host byte "
8802					"sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
8803					BCE_L2CTX_TX_HOST_BSEQ));
8804			}
8805		} else
8806			BCE_PRINTF(" Unknown CID\n");
8807
8808		BCE_PRINTF(
8809			"----------------------------"
8810			"    Raw CTX     "
8811			"----------------------------\n");
8812
8813		for (int i = 0x0; i < 0x300; i += 0x10) {
8814			BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n", i,
8815				CTX_RD(sc, GET_CID_ADDR(cid), i),
8816				CTX_RD(sc, GET_CID_ADDR(cid), i + 0x4),
8817				CTX_RD(sc, GET_CID_ADDR(cid), i + 0x8),
8818				CTX_RD(sc, GET_CID_ADDR(cid), i + 0xc));
8819		}
8820
8821
8822		BCE_PRINTF(
8823			"----------------------------"
8824			"----------------"
8825			"----------------------------\n");
8826	}
8827}
8828
8829
8830/****************************************************************************/
8831/* Prints out the FTQ data.                                                 */
8832/*                                                                          */
8833/* Returns:                                                                */
8834/*   Nothing.                                                               */
8835/****************************************************************************/
8836static __attribute__ ((noinline)) void
8837bce_dump_ftqs(struct bce_softc *sc)
8838{
8839	u32 cmd, ctl, cur_depth, max_depth, valid_cnt, val;
8840
8841	BCE_PRINTF(
8842		"----------------------------"
8843		"    FTQ Data    "
8844		"----------------------------\n");
8845
8846	BCE_PRINTF("   FTQ    Command    Control   Depth_Now  Max_Depth  Valid_Cnt \n");
8847	BCE_PRINTF(" ------- ---------- ---------- ---------- ---------- ----------\n");
8848
8849	/* Setup the generic statistic counters for the FTQ valid count. */
8850	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PPQ_VALID_CNT << 24) |
8851		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT  << 16) |
8852		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT   <<  8) |
8853		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT);
8854	REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
8855
8856	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCHQ_VALID_CNT  << 24) |
8857		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT  << 16) |
8858		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT <<  8) |
8859		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT);
8860	REG_WR(sc, BCE_HC_STAT_GEN_SEL_1, val);
8861
8862	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPATQ_VALID_CNT  << 24) |
8863		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT  << 16) |
8864		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT   <<  8) |
8865		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT);
8866	REG_WR(sc, BCE_HC_STAT_GEN_SEL_2, val);
8867
8868	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMQ_VALID_CNT   << 24) |
8869		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT  << 16) |
8870		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT  <<  8) |
8871		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT);
8872	REG_WR(sc, BCE_HC_STAT_GEN_SEL_3, val);
8873
8874	/* Input queue to the Receive Lookup state machine */
8875	cmd = REG_RD(sc, BCE_RLUP_FTQ_CMD);
8876	ctl = REG_RD(sc, BCE_RLUP_FTQ_CTL);
8877	cur_depth = (ctl & BCE_RLUP_FTQ_CTL_CUR_DEPTH) >> 22;
8878	max_depth = (ctl & BCE_RLUP_FTQ_CTL_MAX_DEPTH) >> 12;
8879	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
8880	BCE_PRINTF(" RLUP    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8881		cmd, ctl, cur_depth, max_depth, valid_cnt);
8882
8883	/* Input queue to the Receive Processor */
8884	cmd = REG_RD_IND(sc, BCE_RXP_FTQ_CMD);
8885	ctl = REG_RD_IND(sc, BCE_RXP_FTQ_CTL);
8886	cur_depth = (ctl & BCE_RXP_FTQ_CTL_CUR_DEPTH) >> 22;
8887	max_depth = (ctl & BCE_RXP_FTQ_CTL_MAX_DEPTH) >> 12;
8888	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
8889	BCE_PRINTF(" RXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8890		cmd, ctl, cur_depth, max_depth, valid_cnt);
8891
8892	/* Input queue to the Recevie Processor */
8893	cmd = REG_RD_IND(sc, BCE_RXP_CFTQ_CMD);
8894	ctl = REG_RD_IND(sc, BCE_RXP_CFTQ_CTL);
8895	cur_depth = (ctl & BCE_RXP_CFTQ_CTL_CUR_DEPTH) >> 22;
8896	max_depth = (ctl & BCE_RXP_CFTQ_CTL_MAX_DEPTH) >> 12;
8897	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
8898	BCE_PRINTF(" RXPC    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8899		cmd, ctl, cur_depth, max_depth, valid_cnt);
8900
8901	/* Input queue to the Receive Virtual to Physical state machine */
8902	cmd = REG_RD(sc, BCE_RV2P_PFTQ_CMD);
8903	ctl = REG_RD(sc, BCE_RV2P_PFTQ_CTL);
8904	cur_depth = (ctl & BCE_RV2P_PFTQ_CTL_CUR_DEPTH) >> 22;
8905	max_depth = (ctl & BCE_RV2P_PFTQ_CTL_MAX_DEPTH) >> 12;
8906	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
8907	BCE_PRINTF(" RV2PP   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8908		cmd, ctl, cur_depth, max_depth, valid_cnt);
8909
8910	/* Input queue to the Recevie Virtual to Physical state machine */
8911	cmd = REG_RD(sc, BCE_RV2P_MFTQ_CMD);
8912	ctl = REG_RD(sc, BCE_RV2P_MFTQ_CTL);
8913	cur_depth = (ctl & BCE_RV2P_MFTQ_CTL_CUR_DEPTH) >> 22;
8914	max_depth = (ctl & BCE_RV2P_MFTQ_CTL_MAX_DEPTH) >> 12;
8915	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT4);
8916	BCE_PRINTF(" RV2PM   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8917		cmd, ctl, cur_depth, max_depth, valid_cnt);
8918
8919	/* Input queue to the Receive Virtual to Physical state machine */
8920	cmd = REG_RD(sc, BCE_RV2P_TFTQ_CMD);
8921	ctl = REG_RD(sc, BCE_RV2P_TFTQ_CTL);
8922	cur_depth = (ctl & BCE_RV2P_TFTQ_CTL_CUR_DEPTH) >> 22;
8923	max_depth = (ctl & BCE_RV2P_TFTQ_CTL_MAX_DEPTH) >> 12;
8924	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT5);
8925	BCE_PRINTF(" RV2PT   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8926		cmd, ctl, cur_depth, max_depth, valid_cnt);
8927
8928	/* Input queue to the Receive DMA state machine */
8929	cmd = REG_RD(sc, BCE_RDMA_FTQ_CMD);
8930	ctl = REG_RD(sc, BCE_RDMA_FTQ_CTL);
8931	cur_depth = (ctl & BCE_RDMA_FTQ_CTL_CUR_DEPTH) >> 22;
8932	max_depth = (ctl & BCE_RDMA_FTQ_CTL_MAX_DEPTH) >> 12;
8933	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT6);
8934	BCE_PRINTF(" RDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8935		cmd, ctl, cur_depth, max_depth, valid_cnt);
8936
8937	/* Input queue to the Transmit Scheduler state machine */
8938	cmd = REG_RD(sc, BCE_TSCH_FTQ_CMD);
8939	ctl = REG_RD(sc, BCE_TSCH_FTQ_CTL);
8940	cur_depth = (ctl & BCE_TSCH_FTQ_CTL_CUR_DEPTH) >> 22;
8941	max_depth = (ctl & BCE_TSCH_FTQ_CTL_MAX_DEPTH) >> 12;
8942	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT7);
8943	BCE_PRINTF(" TSCH    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8944		cmd, ctl, cur_depth, max_depth, valid_cnt);
8945
8946	/* Input queue to the Transmit Buffer Descriptor state machine */
8947	cmd = REG_RD(sc, BCE_TBDR_FTQ_CMD);
8948	ctl = REG_RD(sc, BCE_TBDR_FTQ_CTL);
8949	cur_depth = (ctl & BCE_TBDR_FTQ_CTL_CUR_DEPTH) >> 22;
8950	max_depth = (ctl & BCE_TBDR_FTQ_CTL_MAX_DEPTH) >> 12;
8951	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT8);
8952	BCE_PRINTF(" TBDR    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8953		cmd, ctl, cur_depth, max_depth, valid_cnt);
8954
8955	/* Input queue to the Transmit Processor */
8956	cmd = REG_RD_IND(sc, BCE_TXP_FTQ_CMD);
8957	ctl = REG_RD_IND(sc, BCE_TXP_FTQ_CTL);
8958	cur_depth = (ctl & BCE_TXP_FTQ_CTL_CUR_DEPTH) >> 22;
8959	max_depth = (ctl & BCE_TXP_FTQ_CTL_MAX_DEPTH) >> 12;
8960	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT9);
8961	BCE_PRINTF(" TXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8962		cmd, ctl, cur_depth, max_depth, valid_cnt);
8963
8964	/* Input queue to the Transmit DMA state machine */
8965	cmd = REG_RD(sc, BCE_TDMA_FTQ_CMD);
8966	ctl = REG_RD(sc, BCE_TDMA_FTQ_CTL);
8967	cur_depth = (ctl & BCE_TDMA_FTQ_CTL_CUR_DEPTH) >> 22;
8968	max_depth = (ctl & BCE_TDMA_FTQ_CTL_MAX_DEPTH) >> 12;
8969	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT10);
8970	BCE_PRINTF(" TDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8971		cmd, ctl, cur_depth, max_depth, valid_cnt);
8972
8973	/* Input queue to the Transmit Patch-Up Processor */
8974	cmd = REG_RD_IND(sc, BCE_TPAT_FTQ_CMD);
8975	ctl = REG_RD_IND(sc, BCE_TPAT_FTQ_CTL);
8976	cur_depth = (ctl & BCE_TPAT_FTQ_CTL_CUR_DEPTH) >> 22;
8977	max_depth = (ctl & BCE_TPAT_FTQ_CTL_MAX_DEPTH) >> 12;
8978	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT11);
8979	BCE_PRINTF(" TPAT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8980		cmd, ctl, cur_depth, max_depth, valid_cnt);
8981
8982	/* Input queue to the Transmit Assembler state machine */
8983	cmd = REG_RD_IND(sc, BCE_TAS_FTQ_CMD);
8984	ctl = REG_RD_IND(sc, BCE_TAS_FTQ_CTL);
8985	cur_depth = (ctl & BCE_TAS_FTQ_CTL_CUR_DEPTH) >> 22;
8986	max_depth = (ctl & BCE_TAS_FTQ_CTL_MAX_DEPTH) >> 12;
8987	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT12);
8988	BCE_PRINTF(" TAS     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8989		cmd, ctl, cur_depth, max_depth, valid_cnt);
8990
8991	/* Input queue to the Completion Processor */
8992	cmd = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CMD);
8993	ctl = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CTL);
8994	cur_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_CUR_DEPTH) >> 22;
8995	max_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_MAX_DEPTH) >> 12;
8996	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT13);
8997	BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
8998		cmd, ctl, cur_depth, max_depth, valid_cnt);
8999
9000	/* Input queue to the Completion Processor */
9001	cmd = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CMD);
9002	ctl = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CTL);
9003	cur_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_CUR_DEPTH) >> 22;
9004	max_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_MAX_DEPTH) >> 12;
9005	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT14);
9006	BCE_PRINTF(" COMT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9007		cmd, ctl, cur_depth, max_depth, valid_cnt);
9008
9009	/* Input queue to the Completion Processor */
9010	cmd = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CMD);
9011	ctl = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CTL);
9012	cur_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_CUR_DEPTH) >> 22;
9013	max_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_MAX_DEPTH) >> 12;
9014	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT15);
9015	BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9016		cmd, ctl, cur_depth, max_depth, valid_cnt);
9017
9018	/* Setup the generic statistic counters for the FTQ valid count. */
9019	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSQ_VALID_CNT  << 16) |
9020		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT  <<  8) |
9021		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT);
9022
9023	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)	||
9024		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
9025		val = val | (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCSQ_VALID_CNT_XI << 24);
9026		REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
9027
9028	/* Input queue to the Management Control Processor */
9029	cmd = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CMD);
9030	ctl = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CTL);
9031	cur_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_CUR_DEPTH) >> 22;
9032	max_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_MAX_DEPTH) >> 12;
9033	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
9034	BCE_PRINTF(" MCP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9035		cmd, ctl, cur_depth, max_depth, valid_cnt);
9036
9037	/* Input queue to the Command Processor */
9038	cmd = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CMD);
9039	ctl = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CTL);
9040	cur_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_CUR_DEPTH) >> 22;
9041	max_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_MAX_DEPTH) >> 12;
9042	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
9043	BCE_PRINTF(" CP      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9044		cmd, ctl, cur_depth, max_depth, valid_cnt);
9045
9046	/* Input queue to the Completion Scheduler state machine */
9047	cmd = REG_RD(sc, BCE_CSCH_CH_FTQ_CMD);
9048	ctl = REG_RD(sc, BCE_CSCH_CH_FTQ_CTL);
9049	cur_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_CUR_DEPTH) >> 22;
9050	max_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_MAX_DEPTH) >> 12;
9051	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
9052	BCE_PRINTF(" CS      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9053		cmd, ctl, cur_depth, max_depth, valid_cnt);
9054
9055	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
9056		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
9057		/* Input queue to the Receive Virtual to Physical Command Scheduler */
9058		cmd = REG_RD(sc, BCE_RV2PCSR_FTQ_CMD);
9059		ctl = REG_RD(sc, BCE_RV2PCSR_FTQ_CTL);
9060		cur_depth = (ctl & 0xFFC00000) >> 22;
9061		max_depth = (ctl & 0x003FF000) >> 12;
9062		valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
9063		BCE_PRINTF(" RV2PCSR 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9064			cmd, ctl, cur_depth, max_depth, valid_cnt);
9065	}
9066
9067	BCE_PRINTF(
9068		"----------------------------"
9069		"----------------"
9070		"----------------------------\n");
9071}
9072
9073
9074/****************************************************************************/
9075/* Prints out the TX chain.                                                 */
9076/*                                                                          */
9077/* Returns:                                                                 */
9078/*   Nothing.                                                               */
9079/****************************************************************************/
9080static __attribute__ ((noinline)) void
9081bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count)
9082{
9083	struct tx_bd *txbd;
9084
9085	/* First some info about the tx_bd chain structure. */
9086	BCE_PRINTF(
9087		"----------------------------"
9088		"  tx_bd  chain  "
9089		"----------------------------\n");
9090
9091	BCE_PRINTF("page size      = 0x%08X, tx chain pages        = 0x%08X\n",
9092		(u32) BCM_PAGE_SIZE, (u32) TX_PAGES);
9093
9094	BCE_PRINTF("tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
9095		(u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
9096
9097	BCE_PRINTF("total tx_bd    = 0x%08X\n", (u32) TOTAL_TX_BD);
9098
9099	BCE_PRINTF(
9100		"----------------------------"
9101		"   tx_bd data   "
9102		"----------------------------\n");
9103
9104	/* Now print out the tx_bd's themselves. */
9105	for (int i = 0; i < count; i++) {
9106	 	txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
9107		bce_dump_txbd(sc, tx_prod, txbd);
9108		tx_prod = NEXT_TX_BD(tx_prod);
9109	}
9110
9111	BCE_PRINTF(
9112		"----------------------------"
9113		"----------------"
9114		"----------------------------\n");
9115}
9116
9117
9118/****************************************************************************/
9119/* Prints out the RX chain.                                                 */
9120/*                                                                          */
9121/* Returns:                                                                 */
9122/*   Nothing.                                                               */
9123/****************************************************************************/
9124static __attribute__ ((noinline)) void
9125bce_dump_rx_chain(struct bce_softc *sc, u16 rx_prod, int count)
9126{
9127	struct rx_bd *rxbd;
9128
9129	/* First some info about the rx_bd chain structure. */
9130	BCE_PRINTF(
9131		"----------------------------"
9132		"  rx_bd  chain  "
9133		"----------------------------\n");
9134
9135	BCE_PRINTF("page size      = 0x%08X, rx chain pages        = 0x%08X\n",
9136		(u32) BCM_PAGE_SIZE, (u32) RX_PAGES);
9137
9138	BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
9139		(u32) TOTAL_RX_BD_PER_PAGE, (u32) USABLE_RX_BD_PER_PAGE);
9140
9141	BCE_PRINTF("total rx_bd    = 0x%08X\n", (u32) TOTAL_RX_BD);
9142
9143	BCE_PRINTF(
9144		"----------------------------"
9145		"   rx_bd data   "
9146		"----------------------------\n");
9147
9148	/* Now print out the rx_bd's themselves. */
9149	for (int i = 0; i < count; i++) {
9150		rxbd = &sc->rx_bd_chain[RX_PAGE(rx_prod)][RX_IDX(rx_prod)];
9151		bce_dump_rxbd(sc, rx_prod, rxbd);
9152		rx_prod = RX_CHAIN_IDX(rx_prod + 1);
9153	}
9154
9155	BCE_PRINTF(
9156		"----------------------------"
9157		"----------------"
9158		"----------------------------\n");
9159}
9160
9161
9162#ifdef BCE_USE_SPLIT_HEADER
9163/****************************************************************************/
9164/* Prints out the page chain.                                               */
9165/*                                                                          */
9166/* Returns:                                                                 */
9167/*   Nothing.                                                               */
9168/****************************************************************************/
9169static __attribute__ ((noinline)) void
9170bce_dump_pg_chain(struct bce_softc *sc, u16 pg_prod, int count)
9171{
9172	struct rx_bd *pgbd;
9173
9174	/* First some info about the page chain structure. */
9175	BCE_PRINTF(
9176		"----------------------------"
9177		"   page chain   "
9178		"----------------------------\n");
9179
9180	BCE_PRINTF("page size      = 0x%08X, pg chain pages        = 0x%08X\n",
9181		(u32) BCM_PAGE_SIZE, (u32) PG_PAGES);
9182
9183	BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
9184		(u32) TOTAL_PG_BD_PER_PAGE, (u32) USABLE_PG_BD_PER_PAGE);
9185
9186	BCE_PRINTF("total rx_bd    = 0x%08X, max_pg_bd             = 0x%08X\n",
9187		(u32) TOTAL_PG_BD, (u32) MAX_PG_BD);
9188
9189	BCE_PRINTF(
9190		"----------------------------"
9191		"   page data    "
9192		"----------------------------\n");
9193
9194	/* Now print out the rx_bd's themselves. */
9195	for (int i = 0; i < count; i++) {
9196		pgbd = &sc->pg_bd_chain[PG_PAGE(pg_prod)][PG_IDX(pg_prod)];
9197		bce_dump_pgbd(sc, pg_prod, pgbd);
9198		pg_prod = PG_CHAIN_IDX(pg_prod + 1);
9199	}
9200
9201	BCE_PRINTF(
9202		"----------------------------"
9203		"----------------"
9204		"----------------------------\n");
9205}
9206#endif
9207
9208
9209/****************************************************************************/
9210/* Prints out the status block from host memory.                            */
9211/*                                                                          */
9212/* Returns:                                                                 */
9213/*   Nothing.                                                               */
9214/****************************************************************************/
9215static __attribute__ ((noinline)) void
9216bce_dump_status_block(struct bce_softc *sc)
9217{
9218	struct status_block *sblk;
9219
9220	sblk = sc->status_block;
9221
9222   	BCE_PRINTF(
9223		"----------------------------"
9224		"  Status Block  "
9225		"----------------------------\n");
9226
9227	BCE_PRINTF("    0x%08X - attn_bits\n",
9228		sblk->status_attn_bits);
9229
9230	BCE_PRINTF("    0x%08X - attn_bits_ack\n",
9231		sblk->status_attn_bits_ack);
9232
9233	BCE_PRINTF("0x%04X(0x%04X) - rx_cons0\n",
9234		sblk->status_rx_quick_consumer_index0,
9235		(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index0));
9236
9237	BCE_PRINTF("0x%04X(0x%04X) - tx_cons0\n",
9238		sblk->status_tx_quick_consumer_index0,
9239		(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index0));
9240
9241	BCE_PRINTF("        0x%04X - status_idx\n", sblk->status_idx);
9242
9243	/* Theses indices are not used for normal L2 drivers. */
9244	if (sblk->status_rx_quick_consumer_index1)
9245		BCE_PRINTF("0x%04X(0x%04X) - rx_cons1\n",
9246			sblk->status_rx_quick_consumer_index1,
9247			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index1));
9248
9249	if (sblk->status_tx_quick_consumer_index1)
9250		BCE_PRINTF("0x%04X(0x%04X) - tx_cons1\n",
9251			sblk->status_tx_quick_consumer_index1,
9252			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index1));
9253
9254	if (sblk->status_rx_quick_consumer_index2)
9255		BCE_PRINTF("0x%04X(0x%04X)- rx_cons2\n",
9256			sblk->status_rx_quick_consumer_index2,
9257			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index2));
9258
9259	if (sblk->status_tx_quick_consumer_index2)
9260		BCE_PRINTF("0x%04X(0x%04X) - tx_cons2\n",
9261			sblk->status_tx_quick_consumer_index2,
9262			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index2));
9263
9264	if (sblk->status_rx_quick_consumer_index3)
9265		BCE_PRINTF("0x%04X(0x%04X) - rx_cons3\n",
9266			sblk->status_rx_quick_consumer_index3,
9267			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index3));
9268
9269	if (sblk->status_tx_quick_consumer_index3)
9270		BCE_PRINTF("0x%04X(0x%04X) - tx_cons3\n",
9271			sblk->status_tx_quick_consumer_index3,
9272			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index3));
9273
9274	if (sblk->status_rx_quick_consumer_index4 ||
9275		sblk->status_rx_quick_consumer_index5)
9276		BCE_PRINTF("rx_cons4  = 0x%08X, rx_cons5      = 0x%08X\n",
9277			sblk->status_rx_quick_consumer_index4,
9278			sblk->status_rx_quick_consumer_index5);
9279
9280	if (sblk->status_rx_quick_consumer_index6 ||
9281		sblk->status_rx_quick_consumer_index7)
9282		BCE_PRINTF("rx_cons6  = 0x%08X, rx_cons7      = 0x%08X\n",
9283			sblk->status_rx_quick_consumer_index6,
9284			sblk->status_rx_quick_consumer_index7);
9285
9286	if (sblk->status_rx_quick_consumer_index8 ||
9287		sblk->status_rx_quick_consumer_index9)
9288		BCE_PRINTF("rx_cons8  = 0x%08X, rx_cons9      = 0x%08X\n",
9289			sblk->status_rx_quick_consumer_index8,
9290			sblk->status_rx_quick_consumer_index9);
9291
9292	if (sblk->status_rx_quick_consumer_index10 ||
9293		sblk->status_rx_quick_consumer_index11)
9294		BCE_PRINTF("rx_cons10 = 0x%08X, rx_cons11     = 0x%08X\n",
9295			sblk->status_rx_quick_consumer_index10,
9296			sblk->status_rx_quick_consumer_index11);
9297
9298	if (sblk->status_rx_quick_consumer_index12 ||
9299		sblk->status_rx_quick_consumer_index13)
9300		BCE_PRINTF("rx_cons12 = 0x%08X, rx_cons13     = 0x%08X\n",
9301			sblk->status_rx_quick_consumer_index12,
9302			sblk->status_rx_quick_consumer_index13);
9303
9304	if (sblk->status_rx_quick_consumer_index14 ||
9305		sblk->status_rx_quick_consumer_index15)
9306		BCE_PRINTF("rx_cons14 = 0x%08X, rx_cons15     = 0x%08X\n",
9307			sblk->status_rx_quick_consumer_index14,
9308			sblk->status_rx_quick_consumer_index15);
9309
9310	if (sblk->status_completion_producer_index ||
9311		sblk->status_cmd_consumer_index)
9312		BCE_PRINTF("com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
9313			sblk->status_completion_producer_index,
9314			sblk->status_cmd_consumer_index);
9315
9316	BCE_PRINTF(
9317		"----------------------------"
9318		"----------------"
9319		"----------------------------\n");
9320}
9321
9322
9323/****************************************************************************/
9324/* Prints out the statistics block from host memory.                        */
9325/*                                                                          */
9326/* Returns:                                                                 */
9327/*   Nothing.                                                               */
9328/****************************************************************************/
9329static __attribute__ ((noinline)) void
9330bce_dump_stats_block(struct bce_softc *sc)
9331{
9332	struct statistics_block *sblk;
9333
9334	sblk = sc->stats_block;
9335
9336	BCE_PRINTF(
9337		"---------------"
9338		" Stats Block  (All Stats Not Shown Are 0) "
9339		"---------------\n");
9340
9341	if (sblk->stat_IfHCInOctets_hi
9342		|| sblk->stat_IfHCInOctets_lo)
9343		BCE_PRINTF("0x%08X:%08X : "
9344			"IfHcInOctets\n",
9345			sblk->stat_IfHCInOctets_hi,
9346			sblk->stat_IfHCInOctets_lo);
9347
9348	if (sblk->stat_IfHCInBadOctets_hi
9349		|| sblk->stat_IfHCInBadOctets_lo)
9350		BCE_PRINTF("0x%08X:%08X : "
9351			"IfHcInBadOctets\n",
9352			sblk->stat_IfHCInBadOctets_hi,
9353			sblk->stat_IfHCInBadOctets_lo);
9354
9355	if (sblk->stat_IfHCOutOctets_hi
9356		|| sblk->stat_IfHCOutOctets_lo)
9357		BCE_PRINTF("0x%08X:%08X : "
9358			"IfHcOutOctets\n",
9359			sblk->stat_IfHCOutOctets_hi,
9360			sblk->stat_IfHCOutOctets_lo);
9361
9362	if (sblk->stat_IfHCOutBadOctets_hi
9363		|| sblk->stat_IfHCOutBadOctets_lo)
9364		BCE_PRINTF("0x%08X:%08X : "
9365			"IfHcOutBadOctets\n",
9366			sblk->stat_IfHCOutBadOctets_hi,
9367			sblk->stat_IfHCOutBadOctets_lo);
9368
9369	if (sblk->stat_IfHCInUcastPkts_hi
9370		|| sblk->stat_IfHCInUcastPkts_lo)
9371		BCE_PRINTF("0x%08X:%08X : "
9372			"IfHcInUcastPkts\n",
9373			sblk->stat_IfHCInUcastPkts_hi,
9374			sblk->stat_IfHCInUcastPkts_lo);
9375
9376	if (sblk->stat_IfHCInBroadcastPkts_hi
9377		|| sblk->stat_IfHCInBroadcastPkts_lo)
9378		BCE_PRINTF("0x%08X:%08X : "
9379			"IfHcInBroadcastPkts\n",
9380			sblk->stat_IfHCInBroadcastPkts_hi,
9381			sblk->stat_IfHCInBroadcastPkts_lo);
9382
9383	if (sblk->stat_IfHCInMulticastPkts_hi
9384		|| sblk->stat_IfHCInMulticastPkts_lo)
9385		BCE_PRINTF("0x%08X:%08X : "
9386			"IfHcInMulticastPkts\n",
9387			sblk->stat_IfHCInMulticastPkts_hi,
9388			sblk->stat_IfHCInMulticastPkts_lo);
9389
9390	if (sblk->stat_IfHCOutUcastPkts_hi
9391		|| sblk->stat_IfHCOutUcastPkts_lo)
9392		BCE_PRINTF("0x%08X:%08X : "
9393			"IfHcOutUcastPkts\n",
9394			sblk->stat_IfHCOutUcastPkts_hi,
9395			sblk->stat_IfHCOutUcastPkts_lo);
9396
9397	if (sblk->stat_IfHCOutBroadcastPkts_hi
9398		|| sblk->stat_IfHCOutBroadcastPkts_lo)
9399		BCE_PRINTF("0x%08X:%08X : "
9400			"IfHcOutBroadcastPkts\n",
9401			sblk->stat_IfHCOutBroadcastPkts_hi,
9402			sblk->stat_IfHCOutBroadcastPkts_lo);
9403
9404	if (sblk->stat_IfHCOutMulticastPkts_hi
9405		|| sblk->stat_IfHCOutMulticastPkts_lo)
9406		BCE_PRINTF("0x%08X:%08X : "
9407			"IfHcOutMulticastPkts\n",
9408			sblk->stat_IfHCOutMulticastPkts_hi,
9409			sblk->stat_IfHCOutMulticastPkts_lo);
9410
9411	if (sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors)
9412		BCE_PRINTF("         0x%08X : "
9413			"emac_tx_stat_dot3statsinternalmactransmiterrors\n",
9414			sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
9415
9416	if (sblk->stat_Dot3StatsCarrierSenseErrors)
9417		BCE_PRINTF("         0x%08X : Dot3StatsCarrierSenseErrors\n",
9418			sblk->stat_Dot3StatsCarrierSenseErrors);
9419
9420	if (sblk->stat_Dot3StatsFCSErrors)
9421		BCE_PRINTF("         0x%08X : Dot3StatsFCSErrors\n",
9422			sblk->stat_Dot3StatsFCSErrors);
9423
9424	if (sblk->stat_Dot3StatsAlignmentErrors)
9425		BCE_PRINTF("         0x%08X : Dot3StatsAlignmentErrors\n",
9426			sblk->stat_Dot3StatsAlignmentErrors);
9427
9428	if (sblk->stat_Dot3StatsSingleCollisionFrames)
9429		BCE_PRINTF("         0x%08X : Dot3StatsSingleCollisionFrames\n",
9430			sblk->stat_Dot3StatsSingleCollisionFrames);
9431
9432	if (sblk->stat_Dot3StatsMultipleCollisionFrames)
9433		BCE_PRINTF("         0x%08X : Dot3StatsMultipleCollisionFrames\n",
9434			sblk->stat_Dot3StatsMultipleCollisionFrames);
9435
9436	if (sblk->stat_Dot3StatsDeferredTransmissions)
9437		BCE_PRINTF("         0x%08X : Dot3StatsDeferredTransmissions\n",
9438			sblk->stat_Dot3StatsDeferredTransmissions);
9439
9440	if (sblk->stat_Dot3StatsExcessiveCollisions)
9441		BCE_PRINTF("         0x%08X : Dot3StatsExcessiveCollisions\n",
9442			sblk->stat_Dot3StatsExcessiveCollisions);
9443
9444	if (sblk->stat_Dot3StatsLateCollisions)
9445		BCE_PRINTF("         0x%08X : Dot3StatsLateCollisions\n",
9446			sblk->stat_Dot3StatsLateCollisions);
9447
9448	if (sblk->stat_EtherStatsCollisions)
9449		BCE_PRINTF("         0x%08X : EtherStatsCollisions\n",
9450			sblk->stat_EtherStatsCollisions);
9451
9452	if (sblk->stat_EtherStatsFragments)
9453		BCE_PRINTF("         0x%08X : EtherStatsFragments\n",
9454			sblk->stat_EtherStatsFragments);
9455
9456	if (sblk->stat_EtherStatsJabbers)
9457		BCE_PRINTF("         0x%08X : EtherStatsJabbers\n",
9458			sblk->stat_EtherStatsJabbers);
9459
9460	if (sblk->stat_EtherStatsUndersizePkts)
9461		BCE_PRINTF("         0x%08X : EtherStatsUndersizePkts\n",
9462			sblk->stat_EtherStatsUndersizePkts);
9463
9464	if (sblk->stat_EtherStatsOverrsizePkts)
9465		BCE_PRINTF("         0x%08X : EtherStatsOverrsizePkts\n",
9466			sblk->stat_EtherStatsOverrsizePkts);
9467
9468	if (sblk->stat_EtherStatsPktsRx64Octets)
9469		BCE_PRINTF("         0x%08X : EtherStatsPktsRx64Octets\n",
9470			sblk->stat_EtherStatsPktsRx64Octets);
9471
9472	if (sblk->stat_EtherStatsPktsRx65Octetsto127Octets)
9473		BCE_PRINTF("         0x%08X : EtherStatsPktsRx65Octetsto127Octets\n",
9474			sblk->stat_EtherStatsPktsRx65Octetsto127Octets);
9475
9476	if (sblk->stat_EtherStatsPktsRx128Octetsto255Octets)
9477		BCE_PRINTF("         0x%08X : EtherStatsPktsRx128Octetsto255Octets\n",
9478			sblk->stat_EtherStatsPktsRx128Octetsto255Octets);
9479
9480	if (sblk->stat_EtherStatsPktsRx256Octetsto511Octets)
9481		BCE_PRINTF("         0x%08X : EtherStatsPktsRx256Octetsto511Octets\n",
9482			sblk->stat_EtherStatsPktsRx256Octetsto511Octets);
9483
9484	if (sblk->stat_EtherStatsPktsRx512Octetsto1023Octets)
9485		BCE_PRINTF("         0x%08X : EtherStatsPktsRx512Octetsto1023Octets\n",
9486			sblk->stat_EtherStatsPktsRx512Octetsto1023Octets);
9487
9488	if (sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets)
9489		BCE_PRINTF("         0x%08X : EtherStatsPktsRx1024Octetsto1522Octets\n",
9490			sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets);
9491
9492	if (sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets)
9493		BCE_PRINTF("         0x%08X : EtherStatsPktsRx1523Octetsto9022Octets\n",
9494			sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets);
9495
9496	if (sblk->stat_EtherStatsPktsTx64Octets)
9497		BCE_PRINTF("         0x%08X : EtherStatsPktsTx64Octets\n",
9498			sblk->stat_EtherStatsPktsTx64Octets);
9499
9500	if (sblk->stat_EtherStatsPktsTx65Octetsto127Octets)
9501		BCE_PRINTF("         0x%08X : EtherStatsPktsTx65Octetsto127Octets\n",
9502			sblk->stat_EtherStatsPktsTx65Octetsto127Octets);
9503
9504	if (sblk->stat_EtherStatsPktsTx128Octetsto255Octets)
9505		BCE_PRINTF("         0x%08X : EtherStatsPktsTx128Octetsto255Octets\n",
9506			sblk->stat_EtherStatsPktsTx128Octetsto255Octets);
9507
9508	if (sblk->stat_EtherStatsPktsTx256Octetsto511Octets)
9509		BCE_PRINTF("         0x%08X : EtherStatsPktsTx256Octetsto511Octets\n",
9510			sblk->stat_EtherStatsPktsTx256Octetsto511Octets);
9511
9512	if (sblk->stat_EtherStatsPktsTx512Octetsto1023Octets)
9513		BCE_PRINTF("         0x%08X : EtherStatsPktsTx512Octetsto1023Octets\n",
9514			sblk->stat_EtherStatsPktsTx512Octetsto1023Octets);
9515
9516	if (sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets)
9517		BCE_PRINTF("         0x%08X : EtherStatsPktsTx1024Octetsto1522Octets\n",
9518			sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets);
9519
9520	if (sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets)
9521		BCE_PRINTF("         0x%08X : EtherStatsPktsTx1523Octetsto9022Octets\n",
9522			sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets);
9523
9524	if (sblk->stat_XonPauseFramesReceived)
9525		BCE_PRINTF("         0x%08X : XonPauseFramesReceived\n",
9526			sblk->stat_XonPauseFramesReceived);
9527
9528	if (sblk->stat_XoffPauseFramesReceived)
9529	   BCE_PRINTF("          0x%08X : XoffPauseFramesReceived\n",
9530			sblk->stat_XoffPauseFramesReceived);
9531
9532	if (sblk->stat_OutXonSent)
9533		BCE_PRINTF("         0x%08X : OutXonSent\n",
9534			sblk->stat_OutXonSent);
9535
9536	if (sblk->stat_OutXoffSent)
9537		BCE_PRINTF("         0x%08X : OutXoffSent\n",
9538			sblk->stat_OutXoffSent);
9539
9540	if (sblk->stat_FlowControlDone)
9541		BCE_PRINTF("         0x%08X : FlowControlDone\n",
9542			sblk->stat_FlowControlDone);
9543
9544	if (sblk->stat_MacControlFramesReceived)
9545		BCE_PRINTF("         0x%08X : MacControlFramesReceived\n",
9546			sblk->stat_MacControlFramesReceived);
9547
9548	if (sblk->stat_XoffStateEntered)
9549		BCE_PRINTF("         0x%08X : XoffStateEntered\n",
9550			sblk->stat_XoffStateEntered);
9551
9552	if (sblk->stat_IfInFramesL2FilterDiscards)
9553		BCE_PRINTF("         0x%08X : IfInFramesL2FilterDiscards\n",
9554			sblk->stat_IfInFramesL2FilterDiscards);
9555
9556	if (sblk->stat_IfInRuleCheckerDiscards)
9557		BCE_PRINTF("         0x%08X : IfInRuleCheckerDiscards\n",
9558			sblk->stat_IfInRuleCheckerDiscards);
9559
9560	if (sblk->stat_IfInFTQDiscards)
9561		BCE_PRINTF("         0x%08X : IfInFTQDiscards\n",
9562			sblk->stat_IfInFTQDiscards);
9563
9564	if (sblk->stat_IfInMBUFDiscards)
9565		BCE_PRINTF("         0x%08X : IfInMBUFDiscards\n",
9566			sblk->stat_IfInMBUFDiscards);
9567
9568	if (sblk->stat_IfInRuleCheckerP4Hit)
9569		BCE_PRINTF("         0x%08X : IfInRuleCheckerP4Hit\n",
9570			sblk->stat_IfInRuleCheckerP4Hit);
9571
9572	if (sblk->stat_CatchupInRuleCheckerDiscards)
9573		BCE_PRINTF("         0x%08X : CatchupInRuleCheckerDiscards\n",
9574			sblk->stat_CatchupInRuleCheckerDiscards);
9575
9576	if (sblk->stat_CatchupInFTQDiscards)
9577		BCE_PRINTF("         0x%08X : CatchupInFTQDiscards\n",
9578			sblk->stat_CatchupInFTQDiscards);
9579
9580	if (sblk->stat_CatchupInMBUFDiscards)
9581		BCE_PRINTF("         0x%08X : CatchupInMBUFDiscards\n",
9582			sblk->stat_CatchupInMBUFDiscards);
9583
9584	if (sblk->stat_CatchupInRuleCheckerP4Hit)
9585		BCE_PRINTF("         0x%08X : CatchupInRuleCheckerP4Hit\n",
9586			sblk->stat_CatchupInRuleCheckerP4Hit);
9587
9588	BCE_PRINTF(
9589		"----------------------------"
9590		"----------------"
9591		"----------------------------\n");
9592}
9593
9594
9595/****************************************************************************/
9596/* Prints out a summary of the driver state.                                */
9597/*                                                                          */
9598/* Returns:                                                                 */
9599/*   Nothing.                                                               */
9600/****************************************************************************/
9601static __attribute__ ((noinline)) void
9602bce_dump_driver_state(struct bce_softc *sc)
9603{
9604	u32 val_hi, val_lo;
9605
9606	BCE_PRINTF(
9607		"-----------------------------"
9608		" Driver State "
9609		"-----------------------------\n");
9610
9611	val_hi = BCE_ADDR_HI(sc);
9612	val_lo = BCE_ADDR_LO(sc);
9613	BCE_PRINTF("0x%08X:%08X - (sc) driver softc structure virtual address\n",
9614		val_hi, val_lo);
9615
9616	val_hi = BCE_ADDR_HI(sc->bce_vhandle);
9617	val_lo = BCE_ADDR_LO(sc->bce_vhandle);
9618	BCE_PRINTF("0x%08X:%08X - (sc->bce_vhandle) PCI BAR virtual address\n",
9619		val_hi, val_lo);
9620
9621	val_hi = BCE_ADDR_HI(sc->status_block);
9622	val_lo = BCE_ADDR_LO(sc->status_block);
9623	BCE_PRINTF("0x%08X:%08X - (sc->status_block) status block virtual address\n",
9624		val_hi, val_lo);
9625
9626	val_hi = BCE_ADDR_HI(sc->stats_block);
9627	val_lo = BCE_ADDR_LO(sc->stats_block);
9628	BCE_PRINTF("0x%08X:%08X - (sc->stats_block) statistics block virtual address\n",
9629		val_hi, val_lo);
9630
9631	val_hi = BCE_ADDR_HI(sc->tx_bd_chain);
9632	val_lo = BCE_ADDR_LO(sc->tx_bd_chain);
9633	BCE_PRINTF(
9634		"0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain virtual adddress\n",
9635		val_hi, val_lo);
9636
9637	val_hi = BCE_ADDR_HI(sc->rx_bd_chain);
9638	val_lo = BCE_ADDR_LO(sc->rx_bd_chain);
9639	BCE_PRINTF(
9640		"0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain virtual address\n",
9641		val_hi, val_lo);
9642
9643#ifdef BCE_USE_SPLIT_HEADER
9644	val_hi = BCE_ADDR_HI(sc->pg_bd_chain);
9645	val_lo = BCE_ADDR_LO(sc->pg_bd_chain);
9646	BCE_PRINTF(
9647		"0x%08X:%08X - (sc->pg_bd_chain) page chain virtual address\n",
9648		val_hi, val_lo);
9649#endif
9650
9651	val_hi = BCE_ADDR_HI(sc->tx_mbuf_ptr);
9652	val_lo = BCE_ADDR_LO(sc->tx_mbuf_ptr);
9653	BCE_PRINTF(
9654		"0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain virtual address\n",
9655		val_hi, val_lo);
9656
9657	val_hi = BCE_ADDR_HI(sc->rx_mbuf_ptr);
9658	val_lo = BCE_ADDR_LO(sc->rx_mbuf_ptr);
9659	BCE_PRINTF(
9660		"0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain virtual address\n",
9661		val_hi, val_lo);
9662
9663#ifdef BCE_USE_SPLIT_HEADER
9664	val_hi = BCE_ADDR_HI(sc->pg_mbuf_ptr);
9665	val_lo = BCE_ADDR_LO(sc->pg_mbuf_ptr);
9666	BCE_PRINTF(
9667		"0x%08X:%08X - (sc->pg_mbuf_ptr) page mbuf chain virtual address\n",
9668		val_hi, val_lo);
9669#endif
9670
9671	BCE_PRINTF("         0x%08X - (sc->interrupts_generated) h/w intrs\n",
9672		sc->interrupts_generated);
9673
9674	BCE_PRINTF("         0x%08X - (sc->rx_interrupts) rx interrupts handled\n",
9675		sc->rx_interrupts);
9676
9677	BCE_PRINTF("         0x%08X - (sc->tx_interrupts) tx interrupts handled\n",
9678		sc->tx_interrupts);
9679
9680	BCE_PRINTF("         0x%08X - (sc->last_status_idx) status block index\n",
9681		sc->last_status_idx);
9682
9683	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_prod) tx producer index\n",
9684		sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod));
9685
9686	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_cons) tx consumer index\n",
9687		sc->tx_cons, (u16) TX_CHAIN_IDX(sc->tx_cons));
9688
9689	BCE_PRINTF("         0x%08X - (sc->tx_prod_bseq) tx producer bseq index\n",
9690		sc->tx_prod_bseq);
9691
9692	BCE_PRINTF("         0x%08X - (sc->debug_tx_mbuf_alloc) tx mbufs allocated\n",
9693		sc->debug_tx_mbuf_alloc);
9694
9695	BCE_PRINTF("         0x%08X - (sc->used_tx_bd) used tx_bd's\n",
9696		sc->used_tx_bd);
9697
9698	BCE_PRINTF("0x%08X/%08X - (sc->tx_hi_watermark) tx hi watermark\n",
9699		sc->tx_hi_watermark, sc->max_tx_bd);
9700
9701	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_prod) rx producer index\n",
9702		sc->rx_prod, (u16) RX_CHAIN_IDX(sc->rx_prod));
9703
9704	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_cons) rx consumer index\n",
9705		sc->rx_cons, (u16) RX_CHAIN_IDX(sc->rx_cons));
9706
9707	BCE_PRINTF("         0x%08X - (sc->rx_prod_bseq) rx producer bseq index\n",
9708		sc->rx_prod_bseq);
9709
9710	BCE_PRINTF("         0x%08X - (sc->debug_rx_mbuf_alloc) rx mbufs allocated\n",
9711		sc->debug_rx_mbuf_alloc);
9712
9713	BCE_PRINTF("         0x%08X - (sc->free_rx_bd) free rx_bd's\n",
9714		sc->free_rx_bd);
9715
9716#ifdef BCE_USE_SPLIT_HEADER
9717	BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_prod) page producer index\n",
9718		sc->pg_prod, (u16) PG_CHAIN_IDX(sc->pg_prod));
9719
9720	BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_cons) page consumer index\n",
9721		sc->pg_cons, (u16) PG_CHAIN_IDX(sc->pg_cons));
9722
9723	BCE_PRINTF("         0x%08X - (sc->debug_pg_mbuf_alloc) page mbufs allocated\n",
9724		sc->debug_pg_mbuf_alloc);
9725
9726	BCE_PRINTF("         0x%08X - (sc->free_pg_bd) free page rx_bd's\n",
9727		sc->free_pg_bd);
9728
9729	BCE_PRINTF("0x%08X/%08X - (sc->pg_low_watermark) page low watermark\n",
9730		sc->pg_low_watermark, sc->max_pg_bd);
9731#endif
9732
9733	BCE_PRINTF("         0x%08X - (sc->mbuf_alloc_failed) "
9734		"mbuf alloc failures\n",
9735		sc->mbuf_alloc_failed);
9736
9737	BCE_PRINTF("         0x%08X - (sc->debug_mbuf_sim_alloc_failed) "
9738		"simulated mbuf alloc failures\n",
9739		sc->debug_mbuf_sim_alloc_failed);
9740
9741	BCE_PRINTF("         0x%08X - (sc->bce_flags) bce mac flags\n",
9742		sc->bce_flags);
9743
9744	BCE_PRINTF("         0x%08X - (sc->bce_phy_flags) bce phy flags\n",
9745		sc->bce_phy_flags);
9746
9747	BCE_PRINTF(
9748		"----------------------------"
9749		"----------------"
9750		"----------------------------\n");
9751}
9752
9753
9754/****************************************************************************/
9755/* Prints out the hardware state through a summary of important register,   */
9756/* followed by a complete register dump.                                    */
9757/*                                                                          */
9758/* Returns:                                                                 */
9759/*   Nothing.                                                               */
9760/****************************************************************************/
9761static __attribute__ ((noinline)) void
9762bce_dump_hw_state(struct bce_softc *sc)
9763{
9764	u32 val;
9765
9766	BCE_PRINTF(
9767		"----------------------------"
9768		" Hardware State "
9769		"----------------------------\n");
9770
9771	BCE_PRINTF("0x%08X - bootcode version\n", sc->bce_fw_ver);
9772
9773	val = REG_RD(sc, BCE_MISC_ENABLE_STATUS_BITS);
9774	BCE_PRINTF("0x%08X - (0x%06X) misc_enable_status_bits\n",
9775		val, BCE_MISC_ENABLE_STATUS_BITS);
9776
9777	val = REG_RD(sc, BCE_DMA_STATUS);
9778	BCE_PRINTF("0x%08X - (0x%06X) dma_status\n", val, BCE_DMA_STATUS);
9779
9780	val = REG_RD(sc, BCE_CTX_STATUS);
9781	BCE_PRINTF("0x%08X - (0x%06X) ctx_status\n", val, BCE_CTX_STATUS);
9782
9783	val = REG_RD(sc, BCE_EMAC_STATUS);
9784	BCE_PRINTF("0x%08X - (0x%06X) emac_status\n", val, BCE_EMAC_STATUS);
9785
9786	val = REG_RD(sc, BCE_RPM_STATUS);
9787	BCE_PRINTF("0x%08X - (0x%06X) rpm_status\n", val, BCE_RPM_STATUS);
9788
9789	val = REG_RD(sc, 0x2004);
9790	BCE_PRINTF("0x%08X - (0x%06X) rlup_status\n", val, 0x2004);
9791
9792	val = REG_RD(sc, BCE_RV2P_STATUS);
9793	BCE_PRINTF("0x%08X - (0x%06X) rv2p_status\n", val, BCE_RV2P_STATUS);
9794
9795	val = REG_RD(sc, 0x2c04);
9796	BCE_PRINTF("0x%08X - (0x%06X) rdma_status\n", val, 0x2c04);
9797
9798	val = REG_RD(sc, BCE_TBDR_STATUS);
9799	BCE_PRINTF("0x%08X - (0x%06X) tbdr_status\n", val, BCE_TBDR_STATUS);
9800
9801	val = REG_RD(sc, BCE_TDMA_STATUS);
9802	BCE_PRINTF("0x%08X - (0x%06X) tdma_status\n", val, BCE_TDMA_STATUS);
9803
9804	val = REG_RD(sc, BCE_HC_STATUS);
9805	BCE_PRINTF("0x%08X - (0x%06X) hc_status\n", val, BCE_HC_STATUS);
9806
9807	val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
9808	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n", val, BCE_TXP_CPU_STATE);
9809
9810	val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
9811	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n", val, BCE_TPAT_CPU_STATE);
9812
9813	val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
9814	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n", val, BCE_RXP_CPU_STATE);
9815
9816	val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
9817	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n", val, BCE_COM_CPU_STATE);
9818
9819	val = REG_RD_IND(sc, BCE_MCP_CPU_STATE);
9820	BCE_PRINTF("0x%08X - (0x%06X) mcp_cpu_state\n", val, BCE_MCP_CPU_STATE);
9821
9822	val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
9823	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n", val, BCE_CP_CPU_STATE);
9824
9825	BCE_PRINTF(
9826		"----------------------------"
9827		"----------------"
9828		"----------------------------\n");
9829
9830	BCE_PRINTF(
9831		"----------------------------"
9832		" Register  Dump "
9833		"----------------------------\n");
9834
9835	for (int i = 0x400; i < 0x8000; i += 0x10) {
9836		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
9837			i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
9838			REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
9839	}
9840
9841	BCE_PRINTF(
9842		"----------------------------"
9843		"----------------"
9844		"----------------------------\n");
9845}
9846
9847
9848/****************************************************************************/
9849/* Prints out the mailbox queue registers.                                  */
9850/*                                                                          */
9851/* Returns:                                                                 */
9852/*   Nothing.                                                               */
9853/****************************************************************************/
9854static __attribute__ ((noinline)) void
9855bce_dump_mq_regs(struct bce_softc *sc)
9856{
9857	BCE_PRINTF(
9858		"----------------------------"
9859		"    MQ Regs     "
9860		"----------------------------\n");
9861
9862	BCE_PRINTF(
9863		"----------------------------"
9864		"----------------"
9865		"----------------------------\n");
9866
9867	for (int i = 0x3c00; i < 0x4000; i += 0x10) {
9868		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
9869			i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
9870			REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
9871	}
9872
9873	BCE_PRINTF(
9874		"----------------------------"
9875		"----------------"
9876		"----------------------------\n");
9877}
9878
9879
9880/****************************************************************************/
9881/* Prints out the bootcode state.                                           */
9882/*                                                                          */
9883/* Returns:                                                                 */
9884/*   Nothing.                                                               */
9885/****************************************************************************/
9886static __attribute__ ((noinline)) void
9887bce_dump_bc_state(struct bce_softc *sc)
9888{
9889	u32 val;
9890
9891	BCE_PRINTF(
9892		"----------------------------"
9893		" Bootcode State "
9894		"----------------------------\n");
9895
9896	BCE_PRINTF("0x%08X - bootcode version\n", sc->bce_fw_ver);
9897
9898	val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_BC_RESET_TYPE);
9899	BCE_PRINTF("0x%08X - (0x%06X) reset_type\n",
9900		val, BCE_BC_RESET_TYPE);
9901
9902	val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_BC_STATE);
9903	BCE_PRINTF("0x%08X - (0x%06X) state\n",
9904		val, BCE_BC_STATE);
9905
9906	val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_BC_CONDITION);
9907	BCE_PRINTF("0x%08X - (0x%06X) condition\n",
9908		val, BCE_BC_CONDITION);
9909
9910	val = REG_RD_IND(sc, sc->bce_shmem_base + BCE_BC_STATE_DEBUG_CMD);
9911	BCE_PRINTF("0x%08X - (0x%06X) debug_cmd\n",
9912		val, BCE_BC_STATE_DEBUG_CMD);
9913
9914	BCE_PRINTF(
9915		"----------------------------"
9916		"----------------"
9917		"----------------------------\n");
9918}
9919
9920
9921/****************************************************************************/
9922/* Prints out the TXP processor state.                                      */
9923/*                                                                          */
9924/* Returns:                                                                 */
9925/*   Nothing.                                                               */
9926/****************************************************************************/
9927static __attribute__ ((noinline)) void
9928bce_dump_txp_state(struct bce_softc *sc, int regs)
9929{
9930	u32 val;
9931	u32 fw_version[3];
9932
9933	BCE_PRINTF(
9934		"----------------------------"
9935		"   TXP  State   "
9936		"----------------------------\n");
9937
9938	for (int i = 0; i < 3; i++)
9939		fw_version[i] = htonl(REG_RD_IND(sc,
9940			(BCE_TXP_SCRATCH + 0x10 + i * 4)));
9941	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
9942
9943	val = REG_RD_IND(sc, BCE_TXP_CPU_MODE);
9944	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_mode\n", val, BCE_TXP_CPU_MODE);
9945
9946	val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
9947	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n", val, BCE_TXP_CPU_STATE);
9948
9949	val = REG_RD_IND(sc, BCE_TXP_CPU_EVENT_MASK);
9950	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_event_mask\n", val,
9951		BCE_TXP_CPU_EVENT_MASK);
9952
9953	if (regs) {
9954		BCE_PRINTF(
9955			"----------------------------"
9956			" Register  Dump "
9957			"----------------------------\n");
9958
9959		for (int i = BCE_TXP_CPU_MODE; i < 0x68000; i += 0x10) {
9960			/* Skip the big blank spaces */
9961			if (i < 0x454000 && i > 0x5ffff)
9962				BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
9963					i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
9964					REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
9965		}
9966	}
9967
9968	BCE_PRINTF(
9969		"----------------------------"
9970		"----------------"
9971		"----------------------------\n");
9972}
9973
9974
9975/****************************************************************************/
9976/* Prints out the RXP processor state.                                      */
9977/*                                                                          */
9978/* Returns:                                                                 */
9979/*   Nothing.                                                               */
9980/****************************************************************************/
9981static __attribute__ ((noinline)) void
9982bce_dump_rxp_state(struct bce_softc *sc, int regs)
9983{
9984	u32 val;
9985	u32 fw_version[3];
9986
9987	BCE_PRINTF(
9988		"----------------------------"
9989		"   RXP  State   "
9990		"----------------------------\n");
9991
9992	for (int i = 0; i < 3; i++)
9993		fw_version[i] = htonl(REG_RD_IND(sc,
9994			(BCE_RXP_SCRATCH + 0x10 + i * 4)));
9995	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
9996
9997	val = REG_RD_IND(sc, BCE_RXP_CPU_MODE);
9998	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_mode\n", val, BCE_RXP_CPU_MODE);
9999
10000	val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
10001	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n", val, BCE_RXP_CPU_STATE);
10002
10003	val = REG_RD_IND(sc, BCE_RXP_CPU_EVENT_MASK);
10004	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_event_mask\n", val,
10005		BCE_RXP_CPU_EVENT_MASK);
10006
10007	if (regs) {
10008		BCE_PRINTF(
10009			"----------------------------"
10010			" Register  Dump "
10011			"----------------------------\n");
10012
10013		for (int i = BCE_RXP_CPU_MODE; i < 0xe8fff; i += 0x10) {
10014			/* Skip the big blank sapces */
10015			if (i < 0xc5400 && i > 0xdffff)
10016				BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10017	 				i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
10018					REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
10019		}
10020	}
10021
10022	BCE_PRINTF(
10023		"----------------------------"
10024		"----------------"
10025		"----------------------------\n");
10026}
10027
10028
10029/****************************************************************************/
10030/* Prints out the TPAT processor state.                                     */
10031/*                                                                          */
10032/* Returns:                                                                 */
10033/*   Nothing.                                                               */
10034/****************************************************************************/
10035static __attribute__ ((noinline)) void
10036bce_dump_tpat_state(struct bce_softc *sc, int regs)
10037{
10038	u32 val;
10039	u32 fw_version[3];
10040
10041	BCE_PRINTF(
10042		"----------------------------"
10043		"   TPAT State   "
10044		"----------------------------\n");
10045
10046	for (int i = 0; i < 3; i++)
10047		fw_version[i] = htonl(REG_RD_IND(sc,
10048			(BCE_TPAT_SCRATCH + 0x410 + i * 4)));
10049	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10050
10051	val = REG_RD_IND(sc, BCE_TPAT_CPU_MODE);
10052	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_mode\n", val, BCE_TPAT_CPU_MODE);
10053
10054	val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
10055	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n", val, BCE_TPAT_CPU_STATE);
10056
10057	val = REG_RD_IND(sc, BCE_TPAT_CPU_EVENT_MASK);
10058	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_event_mask\n", val,
10059		BCE_TPAT_CPU_EVENT_MASK);
10060
10061	if (regs) {
10062		BCE_PRINTF(
10063			"----------------------------"
10064			" Register  Dump "
10065			"----------------------------\n");
10066
10067		for (int i = BCE_TPAT_CPU_MODE; i < 0xa3fff; i += 0x10) {
10068			/* Skip the big blank spaces */
10069			if (i < 0x854000 && i > 0x9ffff)
10070				BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10071					i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
10072					REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
10073		}
10074	}
10075
10076	BCE_PRINTF(
10077		"----------------------------"
10078		"----------------"
10079		"----------------------------\n");
10080}
10081
10082
10083/****************************************************************************/
10084/* Prints out the Command Procesor (CP) state.                              */
10085/*                                                                          */
10086/* Returns:                                                                 */
10087/*   Nothing.                                                               */
10088/****************************************************************************/
10089static __attribute__ ((noinline)) void
10090bce_dump_cp_state(struct bce_softc *sc, int regs)
10091{
10092	u32 val;
10093	u32 fw_version[3];
10094
10095	BCE_PRINTF(
10096		"----------------------------"
10097		"    CP State    "
10098		"----------------------------\n");
10099
10100	for (int i = 0; i < 3; i++)
10101		fw_version[i] = htonl(REG_RD_IND(sc,
10102			(BCE_CP_SCRATCH + 0x10 + i * 4)));
10103	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10104
10105	val = REG_RD_IND(sc, BCE_CP_CPU_MODE);
10106	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_mode\n", val, BCE_CP_CPU_MODE);
10107
10108	val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
10109	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n", val, BCE_CP_CPU_STATE);
10110
10111	val = REG_RD_IND(sc, BCE_CP_CPU_EVENT_MASK);
10112	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_event_mask\n", val,
10113		BCE_CP_CPU_EVENT_MASK);
10114
10115	if (regs) {
10116		BCE_PRINTF(
10117			"----------------------------"
10118			" Register  Dump "
10119			"----------------------------\n");
10120
10121		for (int i = BCE_CP_CPU_MODE; i < 0x1aa000; i += 0x10) {
10122			/* Skip the big blank spaces */
10123			if (i < 0x185400 && i > 0x19ffff)
10124				BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10125					i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
10126					REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
10127		}
10128	}
10129
10130	BCE_PRINTF(
10131		"----------------------------"
10132		"----------------"
10133		"----------------------------\n");
10134}
10135
10136
10137/****************************************************************************/
10138/* Prints out the Completion Procesor (COM) state.                          */
10139/*                                                                          */
10140/* Returns:                                                                 */
10141/*   Nothing.                                                               */
10142/****************************************************************************/
10143static __attribute__ ((noinline)) void
10144bce_dump_com_state(struct bce_softc *sc, int regs)
10145{
10146	u32 val;
10147	u32 fw_version[3];
10148
10149	BCE_PRINTF(
10150		"----------------------------"
10151		"   COM State    "
10152		"----------------------------\n");
10153
10154	for (int i = 0; i < 3; i++)
10155		fw_version[i] = htonl(REG_RD_IND(sc,
10156			(BCE_COM_SCRATCH + 0x10 + i * 4)));
10157	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10158
10159	val = REG_RD_IND(sc, BCE_COM_CPU_MODE);
10160	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_mode\n", val, BCE_COM_CPU_MODE);
10161
10162	val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
10163	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n", val, BCE_COM_CPU_STATE);
10164
10165	val = REG_RD_IND(sc, BCE_COM_CPU_EVENT_MASK);
10166	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_event_mask\n", val,
10167		BCE_COM_CPU_EVENT_MASK);
10168
10169	if (regs) {
10170		BCE_PRINTF(
10171			"----------------------------"
10172			" Register  Dump "
10173			"----------------------------\n");
10174
10175		for (int i = BCE_COM_CPU_MODE; i < 0x1053e8; i += 0x10) {
10176			BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10177				i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
10178				REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
10179		}
10180	}
10181
10182	BCE_PRINTF(
10183		"----------------------------"
10184		"----------------"
10185		"----------------------------\n");
10186}
10187
10188
10189/****************************************************************************/
10190/* Prints out the driver state and then enters the debugger.                */
10191/*                                                                          */
10192/* Returns:                                                                 */
10193/*   Nothing.                                                               */
10194/****************************************************************************/
10195static void
10196bce_breakpoint(struct bce_softc *sc)
10197{
10198
10199	/*
10200	 * Unreachable code to silence compiler warnings
10201	 * about unused functions.
10202	 */
10203	if (0) {
10204		bce_freeze_controller(sc);
10205		bce_unfreeze_controller(sc);
10206		bce_dump_enet(sc, NULL);
10207   		bce_dump_txbd(sc, 0, NULL);
10208		bce_dump_rxbd(sc, 0, NULL);
10209		bce_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD);
10210		bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD);
10211		bce_dump_l2fhdr(sc, 0, NULL);
10212		bce_dump_ctx(sc, RX_CID);
10213		bce_dump_ftqs(sc);
10214		bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
10215		bce_dump_rx_chain(sc, 0, USABLE_RX_BD);
10216		bce_dump_status_block(sc);
10217		bce_dump_stats_block(sc);
10218		bce_dump_driver_state(sc);
10219		bce_dump_hw_state(sc);
10220		bce_dump_bc_state(sc);
10221		bce_dump_txp_state(sc, 0);
10222		bce_dump_rxp_state(sc, 0);
10223		bce_dump_tpat_state(sc, 0);
10224		bce_dump_cp_state(sc, 0);
10225		bce_dump_com_state(sc, 0);
10226#ifdef BCE_USE_SPLIT_HEADER
10227		bce_dump_pgbd(sc, 0, NULL);
10228		bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD);
10229		bce_dump_pg_chain(sc, 0, USABLE_PG_BD);
10230#endif
10231	}
10232
10233	bce_dump_status_block(sc);
10234	bce_dump_driver_state(sc);
10235
10236	/* Call the debugger. */
10237	breakpoint();
10238
10239	return;
10240}
10241#endif
10242
10243