if_bce.c revision 204372
1/*-
2 * Copyright (c) 2006-2009 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 204372 2010-02-26 20:41:28Z yongari $");
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 * 	 BCM5716C 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 l2fhdr_error_sim_control = 0;
75
76	/* Controls how often the unexpected attention check will fail. */
77	int unexpected_attention_sim_control = 0;
78
79	/* Controls how often to simulate an mbuf allocation failure. */
80	int mbuf_alloc_failed_sim_control = 0;
81
82	/* Controls how often to simulate a DMA mapping failure. */
83	int dma_map_addr_failed_sim_control = 0;
84
85	/* Controls how often to simulate a bootcode failure. */
86	int bootcode_running_failure_sim_control = 0;
87#endif
88
89/****************************************************************************/
90/* BCE Build Time Options                                                   */
91/****************************************************************************/
92/* #define BCE_NVRAM_WRITE_SUPPORT 1 */
93
94
95/****************************************************************************/
96/* PCI Device ID Table                                                      */
97/*                                                                          */
98/* Used by bce_probe() to identify the devices supported by this driver.    */
99/****************************************************************************/
100#define BCE_DEVDESC_MAX		64
101
102static struct bce_type bce_devs[] = {
103	/* BCM5706C Controllers and OEM boards. */
104	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3101,
105		"HP NC370T Multifunction Gigabit Server Adapter" },
106	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3106,
107		"HP NC370i Multifunction Gigabit Server Adapter" },
108	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3070,
109		"HP NC380T PCIe DP Multifunc Gig Server Adapter" },
110	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x1709,
111		"HP NC371i Multifunction Gigabit Server Adapter" },
112	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  PCI_ANY_ID,  PCI_ANY_ID,
113		"Broadcom NetXtreme II BCM5706 1000Base-T" },
114
115	/* BCM5706S controllers and OEM boards. */
116	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, HP_VENDORID, 0x3102,
117		"HP NC370F Multifunction Gigabit Server Adapter" },
118	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, PCI_ANY_ID,  PCI_ANY_ID,
119		"Broadcom NetXtreme II BCM5706 1000Base-SX" },
120
121	/* BCM5708C controllers and OEM boards. */
122	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7037,
123		"HP NC373T PCIe Multifunction Gig Server Adapter" },
124	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7038,
125		"HP NC373i Multifunction Gigabit Server Adapter" },
126	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7045,
127		"HP NC374m PCIe Multifunction Adapter" },
128	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  PCI_ANY_ID,  PCI_ANY_ID,
129		"Broadcom NetXtreme II BCM5708 1000Base-T" },
130
131	/* BCM5708S controllers and OEM boards. */
132	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x1706,
133		"HP NC373m Multifunction Gigabit Server Adapter" },
134	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703b,
135		"HP NC373i Multifunction Gigabit Server Adapter" },
136	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703d,
137		"HP NC373F PCIe Multifunc Giga Server Adapter" },
138	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  PCI_ANY_ID,  PCI_ANY_ID,
139		"Broadcom NetXtreme II BCM5708 1000Base-SX" },
140
141	/* BCM5709C controllers and OEM boards. */
142	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7055,
143		"HP NC382i DP Multifunction Gigabit Server Adapter" },
144	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7059,
145		"HP NC382T PCIe DP Multifunction Gigabit Server Adapter" },
146	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  PCI_ANY_ID,  PCI_ANY_ID,
147		"Broadcom NetXtreme II BCM5709 1000Base-T" },
148
149	/* BCM5709S controllers and OEM boards. */
150	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x171d,
151		"HP NC382m DP 1GbE Multifunction BL-c Adapter" },
152	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x7056,
153		"HP NC382i DP Multifunction Gigabit Server Adapter" },
154	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  PCI_ANY_ID,  PCI_ANY_ID,
155		"Broadcom NetXtreme II BCM5709 1000Base-SX" },
156
157	/* BCM5716 controllers and OEM boards. */
158	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5716,  PCI_ANY_ID,  PCI_ANY_ID,
159		"Broadcom NetXtreme II BCM5716 1000Base-T" },
160
161	{ 0, 0, 0, 0, NULL }
162};
163
164
165/****************************************************************************/
166/* Supported Flash NVRAM device data.                                       */
167/****************************************************************************/
168static struct flash_spec flash_table[] =
169{
170#define BUFFERED_FLAGS		(BCE_NV_BUFFERED | BCE_NV_TRANSLATE)
171#define NONBUFFERED_FLAGS	(BCE_NV_WREN)
172
173	/* Slow EEPROM */
174	{0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
175	 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
176	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
177	 "EEPROM - slow"},
178	/* Expansion entry 0001 */
179	{0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
180	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
181	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
182	 "Entry 0001"},
183	/* Saifun SA25F010 (non-buffered flash) */
184	/* strap, cfg1, & write1 need updates */
185	{0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
186	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
187	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
188	 "Non-buffered flash (128kB)"},
189	/* Saifun SA25F020 (non-buffered flash) */
190	/* strap, cfg1, & write1 need updates */
191	{0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
192	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
193	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
194	 "Non-buffered flash (256kB)"},
195	/* Expansion entry 0100 */
196	{0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
197	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
198	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
199	 "Entry 0100"},
200	/* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
201	{0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
202	 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
203	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
204	 "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
205	/* Entry 0110: ST M45PE20 (non-buffered flash)*/
206	{0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
207	 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
208	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
209	 "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
210	/* Saifun SA25F005 (non-buffered flash) */
211	/* strap, cfg1, & write1 need updates */
212	{0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
213	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
214	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
215	 "Non-buffered flash (64kB)"},
216	/* Fast EEPROM */
217	{0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
218	 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
219	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
220	 "EEPROM - fast"},
221	/* Expansion entry 1001 */
222	{0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
223	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
224	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
225	 "Entry 1001"},
226	/* Expansion entry 1010 */
227	{0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
228	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
229	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
230	 "Entry 1010"},
231	/* ATMEL AT45DB011B (buffered flash) */
232	{0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
233	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
234	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
235	 "Buffered flash (128kB)"},
236	/* Expansion entry 1100 */
237	{0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
238	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
239	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
240	 "Entry 1100"},
241	/* Expansion entry 1101 */
242	{0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
243	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
244	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
245	 "Entry 1101"},
246	/* Ateml Expansion entry 1110 */
247	{0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
248	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
249	 BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
250	 "Entry 1110 (Atmel)"},
251	/* ATMEL AT45DB021B (buffered flash) */
252	{0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
253	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
254	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
255	 "Buffered flash (256kB)"},
256};
257
258/*
259 * The BCM5709 controllers transparently handle the
260 * differences between Atmel 264 byte pages and all
261 * flash devices which use 256 byte pages, so no
262 * logical-to-physical mapping is required in the
263 * driver.
264 */
265static struct flash_spec flash_5709 = {
266	.flags		= BCE_NV_BUFFERED,
267	.page_bits	= BCM5709_FLASH_PAGE_BITS,
268	.page_size	= BCM5709_FLASH_PAGE_SIZE,
269	.addr_mask	= BCM5709_FLASH_BYTE_ADDR_MASK,
270	.total_size	= BUFFERED_FLASH_TOTAL_SIZE * 2,
271	.name		= "5709/5716 buffered flash (256kB)",
272};
273
274
275/****************************************************************************/
276/* FreeBSD device entry points.                                             */
277/****************************************************************************/
278static int  bce_probe				(device_t);
279static int  bce_attach				(device_t);
280static int  bce_detach				(device_t);
281static int  bce_shutdown			(device_t);
282
283
284/****************************************************************************/
285/* BCE Debug Data Structure Dump Routines                                   */
286/****************************************************************************/
287#ifdef BCE_DEBUG
288static u32	bce_reg_rd				(struct bce_softc *, u32);
289static void	bce_reg_wr				(struct bce_softc *, u32, u32);
290static void	bce_reg_wr16			(struct bce_softc *, u32, u16);
291static u32  bce_ctx_rd				(struct bce_softc *, u32, u32);
292static void bce_dump_enet           (struct bce_softc *, struct mbuf *);
293static void bce_dump_mbuf 			(struct bce_softc *, struct mbuf *);
294static void bce_dump_tx_mbuf_chain	(struct bce_softc *, u16, int);
295static void bce_dump_rx_mbuf_chain	(struct bce_softc *, u16, int);
296#ifdef BCE_JUMBO_HDRSPLIT
297static void bce_dump_pg_mbuf_chain	(struct bce_softc *, u16, int);
298#endif
299static void bce_dump_txbd			(struct bce_softc *, int, struct tx_bd *);
300static void bce_dump_rxbd			(struct bce_softc *, int, struct rx_bd *);
301#ifdef BCE_JUMBO_HDRSPLIT
302static void bce_dump_pgbd			(struct bce_softc *, int, struct rx_bd *);
303#endif
304static void bce_dump_l2fhdr			(struct bce_softc *, int, struct l2_fhdr *);
305static void bce_dump_ctx			(struct bce_softc *, u16);
306static void bce_dump_ftqs			(struct bce_softc *);
307static void bce_dump_tx_chain		(struct bce_softc *, u16, int);
308static void bce_dump_rx_chain		(struct bce_softc *, u16, int);
309#ifdef BCE_JUMBO_HDRSPLIT
310static void bce_dump_pg_chain		(struct bce_softc *, u16, int);
311#endif
312static void bce_dump_status_block	(struct bce_softc *);
313static void bce_dump_stats_block	(struct bce_softc *);
314static void bce_dump_driver_state	(struct bce_softc *);
315static void bce_dump_hw_state		(struct bce_softc *);
316static void bce_dump_mq_regs        (struct bce_softc *);
317static void bce_dump_bc_state		(struct bce_softc *);
318static void bce_dump_txp_state		(struct bce_softc *, int);
319static void bce_dump_rxp_state		(struct bce_softc *, int);
320static void bce_dump_tpat_state		(struct bce_softc *, int);
321static void bce_dump_cp_state		(struct bce_softc *, int);
322static void bce_dump_com_state		(struct bce_softc *, int);
323static void bce_breakpoint			(struct bce_softc *);
324#endif
325
326
327/****************************************************************************/
328/* BCE Register/Memory Access Routines                                      */
329/****************************************************************************/
330static u32  bce_reg_rd_ind			(struct bce_softc *, u32);
331static void bce_reg_wr_ind			(struct bce_softc *, u32, u32);
332static void bce_shmem_wr            (struct bce_softc *, u32, u32);
333static u32  bce_shmem_rd            (struct bce_softc *, u32);
334static void bce_ctx_wr				(struct bce_softc *, u32, u32, u32);
335static int  bce_miibus_read_reg		(device_t, int, int);
336static int  bce_miibus_write_reg	(device_t, int, int, int);
337static void bce_miibus_statchg		(device_t);
338
339
340/****************************************************************************/
341/* BCE NVRAM Access Routines                                                */
342/****************************************************************************/
343static int  bce_acquire_nvram_lock	(struct bce_softc *);
344static int  bce_release_nvram_lock	(struct bce_softc *);
345static void bce_enable_nvram_access	(struct bce_softc *);
346static void	bce_disable_nvram_access(struct bce_softc *);
347static int  bce_nvram_read_dword	(struct bce_softc *, u32, u8 *, u32);
348static int  bce_init_nvram			(struct bce_softc *);
349static int  bce_nvram_read			(struct bce_softc *, u32, u8 *, int);
350static int  bce_nvram_test			(struct bce_softc *);
351#ifdef BCE_NVRAM_WRITE_SUPPORT
352static int  bce_enable_nvram_write	(struct bce_softc *);
353static void bce_disable_nvram_write	(struct bce_softc *);
354static int  bce_nvram_erase_page	(struct bce_softc *, u32);
355static int  bce_nvram_write_dword	(struct bce_softc *, u32, u8 *, u32);
356static int  bce_nvram_write			(struct bce_softc *, u32, u8 *, int);
357#endif
358
359/****************************************************************************/
360/*                                                                          */
361/****************************************************************************/
362static void bce_get_media			(struct bce_softc *);
363static void bce_dma_map_addr		(void *, bus_dma_segment_t *, int, int);
364static int  bce_dma_alloc			(device_t);
365static void bce_dma_free			(struct bce_softc *);
366static void bce_release_resources	(struct bce_softc *);
367
368/****************************************************************************/
369/* BCE Firmware Synchronization and Load                                    */
370/****************************************************************************/
371static int  bce_fw_sync				(struct bce_softc *, u32);
372static void bce_load_rv2p_fw		(struct bce_softc *, u32 *, u32, u32);
373static void bce_load_cpu_fw			(struct bce_softc *, struct cpu_reg *, struct fw_info *);
374static void bce_start_cpu           (struct bce_softc *, struct cpu_reg *);
375static void bce_halt_cpu            (struct bce_softc *, struct cpu_reg *);
376static void bce_start_rxp_cpu       (struct bce_softc *);
377static void bce_init_rxp_cpu		(struct bce_softc *);
378static void bce_init_txp_cpu 		(struct bce_softc *);
379static void bce_init_tpat_cpu		(struct bce_softc *);
380static void bce_init_cp_cpu		  	(struct bce_softc *);
381static void bce_init_com_cpu	  	(struct bce_softc *);
382static void bce_init_cpus			(struct bce_softc *);
383
384static void	bce_print_adapter_info	(struct bce_softc *);
385static void bce_probe_pci_caps		(device_t, struct bce_softc *);
386static void bce_stop				(struct bce_softc *);
387static int  bce_reset				(struct bce_softc *, u32);
388static int  bce_chipinit 			(struct bce_softc *);
389static int  bce_blockinit 			(struct bce_softc *);
390
391static int  bce_init_tx_chain		(struct bce_softc *);
392static void bce_free_tx_chain		(struct bce_softc *);
393
394static int  bce_get_rx_buf			(struct bce_softc *, struct mbuf *, u16 *, u16 *, u32 *);
395static int  bce_init_rx_chain		(struct bce_softc *);
396static void bce_fill_rx_chain		(struct bce_softc *);
397static void bce_free_rx_chain		(struct bce_softc *);
398
399#ifdef BCE_JUMBO_HDRSPLIT
400static int  bce_get_pg_buf			(struct bce_softc *, struct mbuf *, u16 *, u16 *);
401static int  bce_init_pg_chain		(struct bce_softc *);
402static void bce_fill_pg_chain		(struct bce_softc *);
403static void bce_free_pg_chain		(struct bce_softc *);
404#endif
405
406static int  bce_tx_encap			(struct bce_softc *, struct mbuf **);
407static void bce_start_locked		(struct ifnet *);
408static void bce_start				(struct ifnet *);
409static int  bce_ioctl				(struct ifnet *, u_long, caddr_t);
410static void bce_watchdog			(struct bce_softc *);
411static int  bce_ifmedia_upd			(struct ifnet *);
412static void bce_ifmedia_upd_locked	(struct ifnet *);
413static void bce_ifmedia_sts			(struct ifnet *, struct ifmediareq *);
414static void bce_init_locked			(struct bce_softc *);
415static void bce_init				(void *);
416static void bce_mgmt_init_locked	(struct bce_softc *sc);
417
418static void bce_init_ctx			(struct bce_softc *);
419static void bce_get_mac_addr		(struct bce_softc *);
420static void bce_set_mac_addr		(struct bce_softc *);
421static void bce_phy_intr			(struct bce_softc *);
422static inline u16 bce_get_hw_rx_cons(struct bce_softc *);
423static void bce_rx_intr				(struct bce_softc *);
424static void bce_tx_intr				(struct bce_softc *);
425static void bce_disable_intr		(struct bce_softc *);
426static void bce_enable_intr			(struct bce_softc *, int);
427
428static void bce_intr				(void *);
429static void bce_set_rx_mode			(struct bce_softc *);
430static void bce_stats_update		(struct bce_softc *);
431static void bce_tick				(void *);
432static void bce_pulse				(void *);
433static void bce_add_sysctls			(struct bce_softc *);
434
435
436/****************************************************************************/
437/* FreeBSD device dispatch table.                                           */
438/****************************************************************************/
439static device_method_t bce_methods[] = {
440	/* Device interface (device_if.h) */
441	DEVMETHOD(device_probe,		bce_probe),
442	DEVMETHOD(device_attach,	bce_attach),
443	DEVMETHOD(device_detach,	bce_detach),
444	DEVMETHOD(device_shutdown,	bce_shutdown),
445/* Supported by device interface but not used here. */
446/*	DEVMETHOD(device_identify,	bce_identify),      */
447/*	DEVMETHOD(device_suspend,	bce_suspend),       */
448/*	DEVMETHOD(device_resume,	bce_resume),        */
449/*	DEVMETHOD(device_quiesce,	bce_quiesce),       */
450
451	/* Bus interface (bus_if.h) */
452	DEVMETHOD(bus_print_child,	bus_generic_print_child),
453	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
454
455	/* MII interface (miibus_if.h) */
456	DEVMETHOD(miibus_readreg,	bce_miibus_read_reg),
457	DEVMETHOD(miibus_writereg,	bce_miibus_write_reg),
458	DEVMETHOD(miibus_statchg,	bce_miibus_statchg),
459/* Supported by MII interface but not used here.       */
460/*	DEVMETHOD(miibus_linkchg,	bce_miibus_linkchg),   */
461/*	DEVMETHOD(miibus_mediainit,	bce_miibus_mediainit), */
462
463	{ 0, 0 }
464};
465
466static driver_t bce_driver = {
467	"bce",
468	bce_methods,
469	sizeof(struct bce_softc)
470};
471
472static devclass_t bce_devclass;
473
474MODULE_DEPEND(bce, pci, 1, 1, 1);
475MODULE_DEPEND(bce, ether, 1, 1, 1);
476MODULE_DEPEND(bce, miibus, 1, 1, 1);
477
478DRIVER_MODULE(bce, pci, bce_driver, bce_devclass, 0, 0);
479DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, 0, 0);
480
481
482/****************************************************************************/
483/* Tunable device values                                                    */
484/****************************************************************************/
485SYSCTL_NODE(_hw, OID_AUTO, bce, CTLFLAG_RD, 0, "bce driver parameters");
486
487/* Allowable values are TRUE or FALSE */
488static int bce_tso_enable = TRUE;
489TUNABLE_INT("hw.bce.tso_enable", &bce_tso_enable);
490SYSCTL_UINT(_hw_bce, OID_AUTO, tso_enable, CTLFLAG_RDTUN, &bce_tso_enable, 0,
491"TSO Enable/Disable");
492
493/* Allowable values are 0 (IRQ), 1 (MSI/IRQ), and 2 (MSI-X/MSI/IRQ) */
494/* ToDo: Add MSI-X support. */
495static int bce_msi_enable = 1;
496TUNABLE_INT("hw.bce.msi_enable", &bce_msi_enable);
497SYSCTL_UINT(_hw_bce, OID_AUTO, msi_enable, CTLFLAG_RDTUN, &bce_msi_enable, 0,
498"MSI-X|MSI|INTx selector");
499
500/* ToDo: Add tunable to enable/disable strict MTU handling. */
501/* Currently allows "loose" RX MTU checking (i.e. sets the  */
502/* H/W RX MTU to the size of the largest receive buffer, or */
503/* 2048 bytes). This will cause a UNH failure but is more   */
504/* desireable from a functional perspective.                */
505
506
507/****************************************************************************/
508/* Device probe function.                                                   */
509/*                                                                          */
510/* Compares the device to the driver's list of supported devices and        */
511/* reports back to the OS whether this is the right driver for the device.  */
512/*                                                                          */
513/* Returns:                                                                 */
514/*   BUS_PROBE_DEFAULT on success, positive value on failure.               */
515/****************************************************************************/
516static int
517bce_probe(device_t dev)
518{
519	struct bce_type *t;
520	struct bce_softc *sc;
521	char *descbuf;
522	u16 vid = 0, did = 0, svid = 0, sdid = 0;
523
524	t = bce_devs;
525
526	sc = device_get_softc(dev);
527	bzero(sc, sizeof(struct bce_softc));
528	sc->bce_unit = device_get_unit(dev);
529	sc->bce_dev = dev;
530
531	/* Get the data for the device to be probed. */
532	vid  = pci_get_vendor(dev);
533	did  = pci_get_device(dev);
534	svid = pci_get_subvendor(dev);
535	sdid = pci_get_subdevice(dev);
536
537	DBPRINT(sc, BCE_EXTREME_LOAD,
538		"%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
539		"SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
540
541	/* Look through the list of known devices for a match. */
542	while(t->bce_name != NULL) {
543
544		if ((vid == t->bce_vid) && (did == t->bce_did) &&
545			((svid == t->bce_svid) || (t->bce_svid == PCI_ANY_ID)) &&
546			((sdid == t->bce_sdid) || (t->bce_sdid == PCI_ANY_ID))) {
547
548			descbuf = malloc(BCE_DEVDESC_MAX, M_TEMP, M_NOWAIT);
549
550			if (descbuf == NULL)
551				return(ENOMEM);
552
553			/* Print out the device identity. */
554			snprintf(descbuf, BCE_DEVDESC_MAX, "%s (%c%d)",
555				t->bce_name,
556			    (((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
557			    (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
558
559			device_set_desc_copy(dev, descbuf);
560			free(descbuf, M_TEMP);
561			return(BUS_PROBE_DEFAULT);
562		}
563		t++;
564	}
565
566	return(ENXIO);
567}
568
569
570/****************************************************************************/
571/* PCI Capabilities Probe Function.                                         */
572/*                                                                          */
573/* Walks the PCI capabiites list for the device to find what features are   */
574/* supported.                                                               */
575/*                                                                          */
576/* Returns:                                                                 */
577/*   None.                                                                  */
578/****************************************************************************/
579static void
580bce_print_adapter_info(struct bce_softc *sc)
581{
582    int i = 0;
583
584	DBENTER(BCE_VERBOSE_LOAD);
585
586	BCE_PRINTF("ASIC (0x%08X); ", sc->bce_chipid);
587	printf("Rev (%c%d); ", ((BCE_CHIP_ID(sc) & 0xf000) >> 12) + 'A',
588		((BCE_CHIP_ID(sc) & 0x0ff0) >> 4));
589
590	/* Bus info. */
591	if (sc->bce_flags & BCE_PCIE_FLAG) {
592		printf("Bus (PCIe x%d, ", sc->link_width);
593		switch (sc->link_speed) {
594			case 1: printf("2.5Gbps); "); break;
595			case 2:	printf("5Gbps); "); break;
596			default: printf("Unknown link speed); ");
597		}
598	} else {
599		printf("Bus (PCI%s, %s, %dMHz); ",
600			((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""),
601			((sc->bce_flags & BCE_PCI_32BIT_FLAG) ? "32-bit" : "64-bit"),
602			sc->bus_speed_mhz);
603	}
604
605	/* Firmware version and device features. */
606	printf("B/C (%s); Flags (", sc->bce_bc_ver);
607
608#ifdef BCE_JUMBO_HDRSPLIT
609	printf("SPLT");
610    i++;
611#endif
612
613    if (sc->bce_flags & BCE_USING_MSI_FLAG) {
614        if (i > 0) printf("|");
615		printf("MSI"); i++;
616    }
617
618    if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
619        if (i > 0) printf("|");
620		printf("MSI-X"); i++;
621    }
622
623    if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
624        if (i > 0) printf("|");
625		printf("2.5G"); i++;
626    }
627
628    if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
629        if (i > 0) printf("|");
630        printf("MFW); MFW (%s)\n", sc->bce_mfw_ver);
631    } else {
632        printf(")\n");
633    }
634
635	DBEXIT(BCE_VERBOSE_LOAD);
636}
637
638
639/****************************************************************************/
640/* PCI Capabilities Probe Function.                                         */
641/*                                                                          */
642/* Walks the PCI capabiites list for the device to find what features are   */
643/* supported.                                                               */
644/*                                                                          */
645/* Returns:                                                                 */
646/*   None.                                                                  */
647/****************************************************************************/
648static void
649bce_probe_pci_caps(device_t dev, struct bce_softc *sc)
650{
651	u32 reg;
652
653	DBENTER(BCE_VERBOSE_LOAD);
654
655	/* Check if PCI-X capability is enabled. */
656	if (pci_find_extcap(dev, PCIY_PCIX, &reg) == 0) {
657		if (reg != 0)
658			sc->bce_cap_flags |= BCE_PCIX_CAPABLE_FLAG;
659	}
660
661	/* Check if PCIe capability is enabled. */
662	if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
663		if (reg != 0) {
664			u16 link_status = pci_read_config(dev, reg + 0x12, 2);
665			DBPRINT(sc, BCE_INFO_LOAD, "PCIe link_status = 0x%08X\n",
666				link_status);
667			sc->link_speed = link_status & 0xf;
668			sc->link_width = (link_status >> 4) & 0x3f;
669			sc->bce_cap_flags |= BCE_PCIE_CAPABLE_FLAG;
670			sc->bce_flags |= BCE_PCIE_FLAG;
671		}
672	}
673
674	/* Check if MSI capability is enabled. */
675	if (pci_find_extcap(dev, PCIY_MSI, &reg) == 0) {
676		if (reg != 0)
677			sc->bce_cap_flags |= BCE_MSI_CAPABLE_FLAG;
678	}
679
680	/* Check if MSI-X capability is enabled. */
681	if (pci_find_extcap(dev, PCIY_MSIX, &reg) == 0) {
682		if (reg != 0)
683			sc->bce_cap_flags |= BCE_MSIX_CAPABLE_FLAG;
684	}
685
686	DBEXIT(BCE_VERBOSE_LOAD);
687}
688
689
690/****************************************************************************/
691/* Device attach function.                                                  */
692/*                                                                          */
693/* Allocates device resources, performs secondary chip identification,      */
694/* resets and initializes the hardware, and initializes driver instance     */
695/* variables.                                                               */
696/*                                                                          */
697/* Returns:                                                                 */
698/*   0 on success, positive value on failure.                               */
699/****************************************************************************/
700static int
701bce_attach(device_t dev)
702{
703	struct bce_softc *sc;
704	struct ifnet *ifp;
705	u32 val;
706	int error, rid, rc = 0;
707
708	sc = device_get_softc(dev);
709	sc->bce_dev = dev;
710
711	DBENTER(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
712
713	sc->bce_unit = device_get_unit(dev);
714
715	/* Set initial device and PHY flags */
716	sc->bce_flags = 0;
717	sc->bce_phy_flags = 0;
718
719	pci_enable_busmaster(dev);
720
721	/* Allocate PCI memory resources. */
722	rid = PCIR_BAR(0);
723	sc->bce_res_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
724		&rid, RF_ACTIVE);
725
726	if (sc->bce_res_mem == NULL) {
727		BCE_PRINTF("%s(%d): PCI memory allocation failed\n",
728			__FILE__, __LINE__);
729		rc = ENXIO;
730		goto bce_attach_fail;
731	}
732
733	/* Get various resource handles. */
734	sc->bce_btag    = rman_get_bustag(sc->bce_res_mem);
735	sc->bce_bhandle = rman_get_bushandle(sc->bce_res_mem);
736	sc->bce_vhandle = (vm_offset_t) rman_get_virtual(sc->bce_res_mem);
737
738	bce_probe_pci_caps(dev, sc);
739
740	rid = 1;
741#if 0
742	/* Try allocating MSI-X interrupts. */
743	if ((sc->bce_cap_flags & BCE_MSIX_CAPABLE_FLAG) &&
744		(bce_msi_enable >= 2) &&
745		((sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
746		&rid, RF_ACTIVE)) != NULL)) {
747
748		msi_needed = sc->bce_msi_count = 1;
749
750		if (((error = pci_alloc_msix(dev, &sc->bce_msi_count)) != 0) ||
751			(sc->bce_msi_count != msi_needed)) {
752			BCE_PRINTF("%s(%d): MSI-X allocation failed! Requested = %d,"
753				"Received = %d, error = %d\n", __FILE__, __LINE__,
754				msi_needed, sc->bce_msi_count, error);
755			sc->bce_msi_count = 0;
756			pci_release_msi(dev);
757			bus_release_resource(dev, SYS_RES_MEMORY, rid,
758				sc->bce_res_irq);
759			sc->bce_res_irq = NULL;
760		} else {
761			DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI-X interrupt.\n",
762				__FUNCTION__);
763			sc->bce_flags |= BCE_USING_MSIX_FLAG;
764			sc->bce_intr = bce_intr;
765		}
766	}
767#endif
768
769	/* Try allocating a MSI interrupt. */
770	if ((sc->bce_cap_flags & BCE_MSI_CAPABLE_FLAG) &&
771		(bce_msi_enable >= 1) && (sc->bce_msi_count == 0)) {
772		sc->bce_msi_count = 1;
773		if ((error = pci_alloc_msi(dev, &sc->bce_msi_count)) != 0) {
774			BCE_PRINTF("%s(%d): MSI allocation failed! error = %d\n",
775				__FILE__, __LINE__, error);
776			sc->bce_msi_count = 0;
777			pci_release_msi(dev);
778		} else {
779			DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI interrupt.\n",
780				__FUNCTION__);
781			sc->bce_flags |= BCE_USING_MSI_FLAG;
782			if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
783				(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
784				sc->bce_flags |= BCE_ONE_SHOT_MSI_FLAG;
785			sc->bce_irq_rid = 1;
786			sc->bce_intr = bce_intr;
787		}
788	}
789
790	/* Try allocating a legacy interrupt. */
791	if (sc->bce_msi_count == 0) {
792		DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using INTx interrupt.\n",
793			__FUNCTION__);
794		rid = 0;
795		sc->bce_intr = bce_intr;
796	}
797
798	sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
799		&rid, RF_SHAREABLE | RF_ACTIVE);
800
801	sc->bce_irq_rid = rid;
802
803	/* Report any IRQ allocation errors. */
804	if (sc->bce_res_irq == NULL) {
805		BCE_PRINTF("%s(%d): PCI map interrupt failed!\n",
806			__FILE__, __LINE__);
807		rc = ENXIO;
808		goto bce_attach_fail;
809	}
810
811	/* Initialize mutex for the current device instance. */
812	BCE_LOCK_INIT(sc, device_get_nameunit(dev));
813
814	/*
815	 * Configure byte swap and enable indirect register access.
816	 * Rely on CPU to do target byte swapping on big endian systems.
817	 * Access to registers outside of PCI configurtion space are not
818	 * valid until this is done.
819	 */
820	pci_write_config(dev, BCE_PCICFG_MISC_CONFIG,
821			       BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
822			       BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4);
823
824	/* Save ASIC revsion info. */
825	sc->bce_chipid =  REG_RD(sc, BCE_MISC_ID);
826
827	/* Weed out any non-production controller revisions. */
828	switch(BCE_CHIP_ID(sc)) {
829		case BCE_CHIP_ID_5706_A0:
830		case BCE_CHIP_ID_5706_A1:
831		case BCE_CHIP_ID_5708_A0:
832		case BCE_CHIP_ID_5708_B0:
833		case BCE_CHIP_ID_5709_A0:
834		case BCE_CHIP_ID_5709_B0:
835		case BCE_CHIP_ID_5709_B1:
836		case BCE_CHIP_ID_5709_B2:
837			BCE_PRINTF("%s(%d): Unsupported controller revision (%c%d)!\n",
838				__FILE__, __LINE__,
839				(((pci_read_config(dev, PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
840			    (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
841			rc = ENODEV;
842			goto bce_attach_fail;
843	}
844
845	/*
846	 * The embedded PCIe to PCI-X bridge (EPB)
847	 * in the 5708 cannot address memory above
848	 * 40 bits (E7_5708CB1_23043 & E6_5708SB1_23043).
849	 */
850	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708)
851		sc->max_bus_addr = BCE_BUS_SPACE_MAXADDR;
852	else
853		sc->max_bus_addr = BUS_SPACE_MAXADDR;
854
855	/*
856	 * Find the base address for shared memory access.
857	 * Newer versions of bootcode use a signature and offset
858	 * while older versions use a fixed address.
859	 */
860	val = REG_RD_IND(sc, BCE_SHM_HDR_SIGNATURE);
861	if ((val & BCE_SHM_HDR_SIGNATURE_SIG_MASK) == BCE_SHM_HDR_SIGNATURE_SIG)
862		/* Multi-port devices use different offsets in shared memory. */
863		sc->bce_shmem_base = REG_RD_IND(sc, BCE_SHM_HDR_ADDR_0 +
864			(pci_get_function(sc->bce_dev) << 2));
865	else
866		sc->bce_shmem_base = HOST_VIEW_SHMEM_BASE;
867
868	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): bce_shmem_base = 0x%08X\n",
869		__FUNCTION__, sc->bce_shmem_base);
870
871	/* Fetch the bootcode revision. */
872    val = bce_shmem_rd(sc, BCE_DEV_INFO_BC_REV);
873    for (int i = 0, j = 0; i < 3; i++) {
874        u8 num;
875
876        num = (u8) (val >> (24 - (i * 8)));
877        for (int k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
878            if (num >= k || !skip0 || k == 1) {
879                sc->bce_bc_ver[j++] = (num / k) + '0';
880                skip0 = 0;
881            }
882        }
883        if (i != 2)
884            sc->bce_bc_ver[j++] = '.';
885    }
886
887    /* Check if any management firwmare is running. */
888    val = bce_shmem_rd(sc, BCE_PORT_FEATURE);
889    if (val & BCE_PORT_FEATURE_ASF_ENABLED) {
890        sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
891
892        /* Allow time for firmware to enter the running state. */
893        for (int i = 0; i < 30; i++) {
894            val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
895            if (val & BCE_CONDITION_MFW_RUN_MASK)
896                break;
897            DELAY(10000);
898        }
899    }
900
901    /* Check the current bootcode state. */
902    val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
903    val &= BCE_CONDITION_MFW_RUN_MASK;
904    if (val != BCE_CONDITION_MFW_RUN_UNKNOWN &&
905        val != BCE_CONDITION_MFW_RUN_NONE) {
906        u32 addr = bce_shmem_rd(sc, BCE_MFW_VER_PTR);
907        int i = 0;
908
909        for (int j = 0; j < 3; j++) {
910            val = bce_reg_rd_ind(sc, addr + j * 4);
911            val = bswap32(val);
912            memcpy(&sc->bce_mfw_ver[i], &val, 4);
913            i += 4;
914        }
915    }
916
917	/* Get PCI bus information (speed and type). */
918	val = REG_RD(sc, BCE_PCICFG_MISC_STATUS);
919	if (val & BCE_PCICFG_MISC_STATUS_PCIX_DET) {
920		u32 clkreg;
921
922		sc->bce_flags |= BCE_PCIX_FLAG;
923
924		clkreg = REG_RD(sc, BCE_PCICFG_PCI_CLOCK_CONTROL_BITS);
925
926		clkreg &= BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
927		switch (clkreg) {
928		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
929			sc->bus_speed_mhz = 133;
930			break;
931
932		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
933			sc->bus_speed_mhz = 100;
934			break;
935
936		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
937		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
938			sc->bus_speed_mhz = 66;
939			break;
940
941		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
942		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
943			sc->bus_speed_mhz = 50;
944			break;
945
946		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
947		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
948		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
949			sc->bus_speed_mhz = 33;
950			break;
951		}
952	} else {
953		if (val & BCE_PCICFG_MISC_STATUS_M66EN)
954			sc->bus_speed_mhz = 66;
955		else
956			sc->bus_speed_mhz = 33;
957	}
958
959	if (val & BCE_PCICFG_MISC_STATUS_32BIT_DET)
960		sc->bce_flags |= BCE_PCI_32BIT_FLAG;
961
962	/* Reset the controller and announce to bootcode that driver is present. */
963	if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
964		BCE_PRINTF("%s(%d): Controller reset failed!\n",
965			__FILE__, __LINE__);
966		rc = ENXIO;
967		goto bce_attach_fail;
968	}
969
970	/* Initialize the controller. */
971	if (bce_chipinit(sc)) {
972		BCE_PRINTF("%s(%d): Controller initialization failed!\n",
973			__FILE__, __LINE__);
974		rc = ENXIO;
975		goto bce_attach_fail;
976	}
977
978	/* Perform NVRAM test. */
979	if (bce_nvram_test(sc)) {
980		BCE_PRINTF("%s(%d): NVRAM test failed!\n",
981			__FILE__, __LINE__);
982		rc = ENXIO;
983		goto bce_attach_fail;
984	}
985
986	/* Fetch the permanent Ethernet MAC address. */
987	bce_get_mac_addr(sc);
988
989	/*
990	 * Trip points control how many BDs
991	 * should be ready before generating an
992	 * interrupt while ticks control how long
993	 * a BD can sit in the chain before
994	 * generating an interrupt.  Set the default
995	 * values for the RX and TX chains.
996	 */
997
998#ifdef BCE_DEBUG
999	/* Force more frequent interrupts. */
1000	sc->bce_tx_quick_cons_trip_int = 1;
1001	sc->bce_tx_quick_cons_trip     = 1;
1002	sc->bce_tx_ticks_int           = 0;
1003	sc->bce_tx_ticks               = 0;
1004
1005	sc->bce_rx_quick_cons_trip_int = 1;
1006	sc->bce_rx_quick_cons_trip     = 1;
1007	sc->bce_rx_ticks_int           = 0;
1008	sc->bce_rx_ticks               = 0;
1009#else
1010	/* Improve throughput at the expense of increased latency. */
1011	sc->bce_tx_quick_cons_trip_int = 20;
1012	sc->bce_tx_quick_cons_trip     = 20;
1013	sc->bce_tx_ticks_int           = 80;
1014	sc->bce_tx_ticks               = 80;
1015
1016	sc->bce_rx_quick_cons_trip_int = 6;
1017	sc->bce_rx_quick_cons_trip     = 6;
1018	sc->bce_rx_ticks_int           = 18;
1019	sc->bce_rx_ticks               = 18;
1020#endif
1021
1022	/* Update statistics once every second. */
1023	sc->bce_stats_ticks = 1000000 & 0xffff00;
1024
1025	/* Find the media type for the adapter. */
1026	bce_get_media(sc);
1027
1028	/* Store data needed by PHY driver for backplane applications */
1029	sc->bce_shared_hw_cfg = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
1030	sc->bce_port_hw_cfg   = bce_shmem_rd(sc, BCE_PORT_HW_CFG_CONFIG);
1031
1032	/* Allocate DMA memory resources. */
1033	if (bce_dma_alloc(dev)) {
1034		BCE_PRINTF("%s(%d): DMA resource allocation failed!\n",
1035		    __FILE__, __LINE__);
1036		rc = ENXIO;
1037		goto bce_attach_fail;
1038	}
1039
1040	/* Allocate an ifnet structure. */
1041	ifp = sc->bce_ifp = if_alloc(IFT_ETHER);
1042	if (ifp == NULL) {
1043		BCE_PRINTF("%s(%d): Interface allocation failed!\n",
1044			__FILE__, __LINE__);
1045		rc = ENXIO;
1046		goto bce_attach_fail;
1047	}
1048
1049	/* Initialize the ifnet interface. */
1050	ifp->if_softc        = sc;
1051	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
1052	ifp->if_flags        = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1053	ifp->if_ioctl        = bce_ioctl;
1054	ifp->if_start        = bce_start;
1055	ifp->if_init         = bce_init;
1056	ifp->if_mtu          = ETHERMTU;
1057
1058	if (bce_tso_enable) {
1059		ifp->if_hwassist = BCE_IF_HWASSIST | CSUM_TSO;
1060		ifp->if_capabilities = BCE_IF_CAPABILITIES | IFCAP_TSO4;
1061	} else {
1062		ifp->if_hwassist = BCE_IF_HWASSIST;
1063		ifp->if_capabilities = BCE_IF_CAPABILITIES;
1064	}
1065
1066	ifp->if_capenable    = ifp->if_capabilities;
1067
1068	/*
1069	 * Assume standard mbuf sizes for buffer allocation.
1070	 * This may change later if the MTU size is set to
1071	 * something other than 1500.
1072	 */
1073#ifdef BCE_JUMBO_HDRSPLIT
1074	sc->rx_bd_mbuf_alloc_size = MHLEN;
1075	/* Make sure offset is 16 byte aligned for hardware. */
1076	sc->rx_bd_mbuf_align_pad  = roundup2((MSIZE - MHLEN), 16) -
1077		(MSIZE - MHLEN);
1078	sc->rx_bd_mbuf_data_len   = sc->rx_bd_mbuf_alloc_size -
1079		sc->rx_bd_mbuf_align_pad;
1080	sc->pg_bd_mbuf_alloc_size = MCLBYTES;
1081#else
1082	sc->rx_bd_mbuf_alloc_size = MCLBYTES;
1083	sc->rx_bd_mbuf_align_pad  = roundup2(MCLBYTES, 16) - MCLBYTES;
1084	sc->rx_bd_mbuf_data_len   = sc->rx_bd_mbuf_alloc_size -
1085		sc->rx_bd_mbuf_align_pad;
1086#endif
1087
1088	ifp->if_snd.ifq_drv_maxlen = USABLE_TX_BD;
1089	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
1090	IFQ_SET_READY(&ifp->if_snd);
1091
1092	if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
1093		ifp->if_baudrate = IF_Mbps(2500ULL);
1094	else
1095		ifp->if_baudrate = IF_Mbps(1000);
1096
1097	/* Check for an MII child bus by probing the PHY. */
1098	if (mii_phy_probe(dev, &sc->bce_miibus, bce_ifmedia_upd,
1099		bce_ifmedia_sts)) {
1100		BCE_PRINTF("%s(%d): No PHY found on child MII bus!\n",
1101			__FILE__, __LINE__);
1102		rc = ENXIO;
1103		goto bce_attach_fail;
1104	}
1105
1106	/* Attach to the Ethernet interface list. */
1107	ether_ifattach(ifp, sc->eaddr);
1108
1109#if __FreeBSD_version < 500000
1110	callout_init(&sc->bce_tick_callout);
1111	callout_init(&sc->bce_pulse_callout);
1112#else
1113	callout_init_mtx(&sc->bce_tick_callout, &sc->bce_mtx, 0);
1114	callout_init_mtx(&sc->bce_pulse_callout, &sc->bce_mtx, 0);
1115#endif
1116
1117	/* Hookup IRQ last. */
1118	rc = bus_setup_intr(dev, sc->bce_res_irq, INTR_TYPE_NET | INTR_MPSAFE,
1119		NULL, bce_intr, sc, &sc->bce_intrhand);
1120
1121	if (rc) {
1122		BCE_PRINTF("%s(%d): Failed to setup IRQ!\n",
1123			__FILE__, __LINE__);
1124		bce_detach(dev);
1125		goto bce_attach_exit;
1126	}
1127
1128	/*
1129	 * At this point we've acquired all the resources
1130	 * we need to run so there's no turning back, we're
1131	 * cleared for launch.
1132	 */
1133
1134	/* Print some important debugging info. */
1135	DBRUNMSG(BCE_INFO, bce_dump_driver_state(sc));
1136
1137	/* Add the supported sysctls to the kernel. */
1138	bce_add_sysctls(sc);
1139
1140	BCE_LOCK(sc);
1141
1142	/*
1143	 * The chip reset earlier notified the bootcode that
1144	 * a driver is present.  We now need to start our pulse
1145	 * routine so that the bootcode is reminded that we're
1146	 * still running.
1147	 */
1148	bce_pulse(sc);
1149
1150	bce_mgmt_init_locked(sc);
1151	BCE_UNLOCK(sc);
1152
1153	/* Finally, print some useful adapter info */
1154	bce_print_adapter_info(sc);
1155	DBPRINT(sc, BCE_FATAL, "%s(): sc = %p\n",
1156		__FUNCTION__, sc);
1157
1158	goto bce_attach_exit;
1159
1160bce_attach_fail:
1161	bce_release_resources(sc);
1162
1163bce_attach_exit:
1164
1165	DBEXIT(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
1166
1167	return(rc);
1168}
1169
1170
1171/****************************************************************************/
1172/* Device detach function.                                                  */
1173/*                                                                          */
1174/* Stops the controller, resets the controller, and releases resources.     */
1175/*                                                                          */
1176/* Returns:                                                                 */
1177/*   0 on success, positive value on failure.                               */
1178/****************************************************************************/
1179static int
1180bce_detach(device_t dev)
1181{
1182	struct bce_softc *sc = device_get_softc(dev);
1183	struct ifnet *ifp;
1184	u32 msg;
1185
1186	DBENTER(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
1187
1188	ifp = sc->bce_ifp;
1189
1190	/* Stop and reset the controller. */
1191	BCE_LOCK(sc);
1192
1193	/* Stop the pulse so the bootcode can go to driver absent state. */
1194	callout_stop(&sc->bce_pulse_callout);
1195
1196	bce_stop(sc);
1197	if (sc->bce_flags & BCE_NO_WOL_FLAG)
1198		msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
1199	else
1200		msg = BCE_DRV_MSG_CODE_UNLOAD;
1201	bce_reset(sc, msg);
1202
1203	BCE_UNLOCK(sc);
1204
1205	ether_ifdetach(ifp);
1206
1207	/* If we have a child device on the MII bus remove it too. */
1208	bus_generic_detach(dev);
1209	device_delete_child(dev, sc->bce_miibus);
1210
1211	/* Release all remaining resources. */
1212	bce_release_resources(sc);
1213
1214	DBEXIT(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
1215
1216	return(0);
1217}
1218
1219
1220/****************************************************************************/
1221/* Device shutdown function.                                                */
1222/*                                                                          */
1223/* Stops and resets the controller.                                         */
1224/*                                                                          */
1225/* Returns:                                                                 */
1226/*   0 on success, positive value on failure.                               */
1227/****************************************************************************/
1228static int
1229bce_shutdown(device_t dev)
1230{
1231	struct bce_softc *sc = device_get_softc(dev);
1232	u32 msg;
1233
1234	DBENTER(BCE_VERBOSE);
1235
1236	BCE_LOCK(sc);
1237	bce_stop(sc);
1238	if (sc->bce_flags & BCE_NO_WOL_FLAG)
1239		msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
1240	else
1241		msg = BCE_DRV_MSG_CODE_UNLOAD;
1242	bce_reset(sc, msg);
1243	BCE_UNLOCK(sc);
1244
1245	DBEXIT(BCE_VERBOSE);
1246
1247	return (0);
1248}
1249
1250
1251#ifdef BCE_DEBUG
1252/****************************************************************************/
1253/* Register read.                                                           */
1254/*                                                                          */
1255/* Returns:                                                                 */
1256/*   The value of the register.                                             */
1257/****************************************************************************/
1258static u32
1259bce_reg_rd(struct bce_softc *sc, u32 offset)
1260{
1261	u32 val = bus_space_read_4(sc->bce_btag, sc->bce_bhandle, offset);
1262	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1263		__FUNCTION__, offset, val);
1264	return val;
1265}
1266
1267
1268/****************************************************************************/
1269/* Register write (16 bit).                                                 */
1270/*                                                                          */
1271/* Returns:                                                                 */
1272/*   Nothing.                                                               */
1273/****************************************************************************/
1274static void
1275bce_reg_wr16(struct bce_softc *sc, u32 offset, u16 val)
1276{
1277	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%04X\n",
1278		__FUNCTION__, offset, val);
1279	bus_space_write_2(sc->bce_btag, sc->bce_bhandle, offset, val);
1280}
1281
1282
1283/****************************************************************************/
1284/* Register write.                                                          */
1285/*                                                                          */
1286/* Returns:                                                                 */
1287/*   Nothing.                                                               */
1288/****************************************************************************/
1289static void
1290bce_reg_wr(struct bce_softc *sc, u32 offset, u32 val)
1291{
1292	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1293		__FUNCTION__, offset, val);
1294	bus_space_write_4(sc->bce_btag, sc->bce_bhandle, offset, val);
1295}
1296#endif
1297
1298/****************************************************************************/
1299/* Indirect register read.                                                  */
1300/*                                                                          */
1301/* Reads NetXtreme II registers using an index/data register pair in PCI    */
1302/* configuration space.  Using this mechanism avoids issues with posted     */
1303/* reads but is much slower than memory-mapped I/O.                         */
1304/*                                                                          */
1305/* Returns:                                                                 */
1306/*   The value of the register.                                             */
1307/****************************************************************************/
1308static u32
1309bce_reg_rd_ind(struct bce_softc *sc, u32 offset)
1310{
1311	device_t dev;
1312	dev = sc->bce_dev;
1313
1314	pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
1315#ifdef BCE_DEBUG
1316	{
1317		u32 val;
1318		val = pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
1319		DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1320			__FUNCTION__, offset, val);
1321		return val;
1322	}
1323#else
1324	return pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
1325#endif
1326}
1327
1328
1329/****************************************************************************/
1330/* Indirect register write.                                                 */
1331/*                                                                          */
1332/* Writes NetXtreme II registers using an index/data register pair in PCI   */
1333/* configuration space.  Using this mechanism avoids issues with posted     */
1334/* writes but is muchh slower than memory-mapped I/O.                       */
1335/*                                                                          */
1336/* Returns:                                                                 */
1337/*   Nothing.                                                               */
1338/****************************************************************************/
1339static void
1340bce_reg_wr_ind(struct bce_softc *sc, u32 offset, u32 val)
1341{
1342	device_t dev;
1343	dev = sc->bce_dev;
1344
1345	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1346		__FUNCTION__, offset, val);
1347
1348	pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
1349	pci_write_config(dev, BCE_PCICFG_REG_WINDOW, val, 4);
1350}
1351
1352
1353/****************************************************************************/
1354/* Shared memory write.                                                     */
1355/*                                                                          */
1356/* Writes NetXtreme II shared memory region.                                */
1357/*                                                                          */
1358/* Returns:                                                                 */
1359/*   Nothing.                                                               */
1360/****************************************************************************/
1361static void
1362bce_shmem_wr(struct bce_softc *sc, u32 offset, u32 val)
1363{
1364	bce_reg_wr_ind(sc, sc->bce_shmem_base + offset, val);
1365}
1366
1367
1368/****************************************************************************/
1369/* Shared memory read.                                                      */
1370/*                                                                          */
1371/* Reads NetXtreme II shared memory region.                                 */
1372/*                                                                          */
1373/* Returns:                                                                 */
1374/*   The 32 bit value read.                                                 */
1375/****************************************************************************/
1376static u32
1377bce_shmem_rd(struct bce_softc *sc, u32 offset)
1378{
1379	return (bce_reg_rd_ind(sc, sc->bce_shmem_base + offset));
1380}
1381
1382
1383#ifdef BCE_DEBUG
1384/****************************************************************************/
1385/* Context memory read.                                                     */
1386/*                                                                          */
1387/* The NetXtreme II controller uses context memory to track connection      */
1388/* information for L2 and higher network protocols.                         */
1389/*                                                                          */
1390/* Returns:                                                                 */
1391/*   The requested 32 bit value of context memory.                          */
1392/****************************************************************************/
1393static u32
1394bce_ctx_rd(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset)
1395{
1396	u32 idx, offset, retry_cnt = 5, val;
1397
1398	DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 || cid_addr & CTX_MASK),
1399		BCE_PRINTF("%s(): Invalid CID address: 0x%08X.\n",
1400			__FUNCTION__, cid_addr));
1401
1402	offset = ctx_offset + cid_addr;
1403
1404	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
1405		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
1406
1407		REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_READ_REQ));
1408
1409		for (idx = 0; idx < retry_cnt; idx++) {
1410			val = REG_RD(sc, BCE_CTX_CTX_CTRL);
1411			if ((val & BCE_CTX_CTX_CTRL_READ_REQ) == 0)
1412				break;
1413			DELAY(5);
1414		}
1415
1416		if (val & BCE_CTX_CTX_CTRL_READ_REQ)
1417			BCE_PRINTF("%s(%d); Unable to read CTX memory: "
1418				"cid_addr = 0x%08X, offset = 0x%08X!\n",
1419				__FILE__, __LINE__, cid_addr, ctx_offset);
1420
1421		val = REG_RD(sc, BCE_CTX_CTX_DATA);
1422	} else {
1423		REG_WR(sc, BCE_CTX_DATA_ADR, offset);
1424		val = REG_RD(sc, BCE_CTX_DATA);
1425	}
1426
1427	DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
1428		"val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, val);
1429
1430	return(val);
1431}
1432#endif
1433
1434
1435/****************************************************************************/
1436/* Context memory write.                                                    */
1437/*                                                                          */
1438/* The NetXtreme II controller uses context memory to track connection      */
1439/* information for L2 and higher network protocols.                         */
1440/*                                                                          */
1441/* Returns:                                                                 */
1442/*   Nothing.                                                               */
1443/****************************************************************************/
1444static void
1445bce_ctx_wr(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset, u32 ctx_val)
1446{
1447	u32 idx, offset = ctx_offset + cid_addr;
1448	u32 val, retry_cnt = 5;
1449
1450	DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
1451		"val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, ctx_val);
1452
1453	DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 || cid_addr & CTX_MASK),
1454		BCE_PRINTF("%s(): Invalid CID address: 0x%08X.\n",
1455			__FUNCTION__, cid_addr));
1456
1457	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
1458		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
1459
1460		REG_WR(sc, BCE_CTX_CTX_DATA, ctx_val);
1461		REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_WRITE_REQ));
1462
1463		for (idx = 0; idx < retry_cnt; idx++) {
1464			val = REG_RD(sc, BCE_CTX_CTX_CTRL);
1465			if ((val & BCE_CTX_CTX_CTRL_WRITE_REQ) == 0)
1466				break;
1467			DELAY(5);
1468		}
1469
1470		if (val & BCE_CTX_CTX_CTRL_WRITE_REQ)
1471			BCE_PRINTF("%s(%d); Unable to write CTX memory: "
1472				"cid_addr = 0x%08X, offset = 0x%08X!\n",
1473				__FILE__, __LINE__, cid_addr, ctx_offset);
1474
1475	} else {
1476		REG_WR(sc, BCE_CTX_DATA_ADR, offset);
1477		REG_WR(sc, BCE_CTX_DATA, ctx_val);
1478	}
1479}
1480
1481
1482/****************************************************************************/
1483/* PHY register read.                                                       */
1484/*                                                                          */
1485/* Implements register reads on the MII bus.                                */
1486/*                                                                          */
1487/* Returns:                                                                 */
1488/*   The value of the register.                                             */
1489/****************************************************************************/
1490static int
1491bce_miibus_read_reg(device_t dev, int phy, int reg)
1492{
1493	struct bce_softc *sc;
1494	u32 val;
1495	int i;
1496
1497	sc = device_get_softc(dev);
1498
1499	/* Make sure we are accessing the correct PHY address. */
1500	if (phy != sc->bce_phy_addr) {
1501		DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d for PHY read!\n", phy);
1502		return(0);
1503	}
1504
1505	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1506		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1507		val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1508
1509		REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1510		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1511
1512		DELAY(40);
1513	}
1514
1515
1516	val = BCE_MIPHY(phy) | BCE_MIREG(reg) |
1517		BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT |
1518		BCE_EMAC_MDIO_COMM_START_BUSY;
1519	REG_WR(sc, BCE_EMAC_MDIO_COMM, val);
1520
1521	for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1522		DELAY(10);
1523
1524		val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1525		if (!(val & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1526			DELAY(5);
1527
1528			val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1529			val &= BCE_EMAC_MDIO_COMM_DATA;
1530
1531			break;
1532		}
1533	}
1534
1535	if (val & BCE_EMAC_MDIO_COMM_START_BUSY) {
1536		BCE_PRINTF("%s(%d): Error: PHY read timeout! phy = %d, reg = 0x%04X\n",
1537			__FILE__, __LINE__, phy, reg);
1538		val = 0x0;
1539	} else {
1540		val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1541	}
1542
1543
1544	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1545		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1546		val |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1547
1548		REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1549		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1550
1551		DELAY(40);
1552	}
1553
1554	DB_PRINT_PHY_REG(reg, val);
1555	return (val & 0xffff);
1556
1557}
1558
1559
1560/****************************************************************************/
1561/* PHY register write.                                                      */
1562/*                                                                          */
1563/* Implements register writes on the MII bus.                               */
1564/*                                                                          */
1565/* Returns:                                                                 */
1566/*   The value of the register.                                             */
1567/****************************************************************************/
1568static int
1569bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
1570{
1571	struct bce_softc *sc;
1572	u32 val1;
1573	int i;
1574
1575	sc = device_get_softc(dev);
1576
1577	/* Make sure we are accessing the correct PHY address. */
1578	if (phy != sc->bce_phy_addr) {
1579		DBPRINT(sc, BCE_INSANE_PHY, "Invalid PHY address %d for PHY write!\n", phy);
1580		return(0);
1581	}
1582
1583	DB_PRINT_PHY_REG(reg, val);
1584
1585	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1586		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1587		val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1588
1589		REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1590		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1591
1592		DELAY(40);
1593	}
1594
1595	val1 = BCE_MIPHY(phy) | BCE_MIREG(reg) | val |
1596		BCE_EMAC_MDIO_COMM_COMMAND_WRITE |
1597		BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT;
1598	REG_WR(sc, BCE_EMAC_MDIO_COMM, val1);
1599
1600	for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1601		DELAY(10);
1602
1603		val1 = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1604		if (!(val1 & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1605			DELAY(5);
1606			break;
1607		}
1608	}
1609
1610	if (val1 & BCE_EMAC_MDIO_COMM_START_BUSY)
1611		BCE_PRINTF("%s(%d): PHY write timeout!\n",
1612			__FILE__, __LINE__);
1613
1614	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1615		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1616		val1 |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1617
1618		REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1619		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1620
1621		DELAY(40);
1622	}
1623
1624	return 0;
1625}
1626
1627
1628/****************************************************************************/
1629/* MII bus status change.                                                   */
1630/*                                                                          */
1631/* Called by the MII bus driver when the PHY establishes link to set the    */
1632/* MAC interface registers.                                                 */
1633/*                                                                          */
1634/* Returns:                                                                 */
1635/*   Nothing.                                                               */
1636/****************************************************************************/
1637static void
1638bce_miibus_statchg(device_t dev)
1639{
1640	struct bce_softc *sc;
1641	struct mii_data *mii;
1642	int val;
1643
1644	sc = device_get_softc(dev);
1645
1646	DBENTER(BCE_VERBOSE_PHY);
1647
1648	mii = device_get_softc(sc->bce_miibus);
1649
1650	val = REG_RD(sc, BCE_EMAC_MODE);
1651	val &= ~(BCE_EMAC_MODE_PORT | BCE_EMAC_MODE_HALF_DUPLEX |
1652		BCE_EMAC_MODE_MAC_LOOP | BCE_EMAC_MODE_FORCE_LINK |
1653		BCE_EMAC_MODE_25G);
1654
1655	/* Set MII or GMII interface based on the speed negotiated by the PHY. */
1656	switch (IFM_SUBTYPE(mii->mii_media_active)) {
1657	case IFM_10_T:
1658		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
1659			DBPRINT(sc, BCE_INFO, "Enabling 10Mb interface.\n");
1660			val |= BCE_EMAC_MODE_PORT_MII_10;
1661			break;
1662		}
1663		/* fall-through */
1664	case IFM_100_TX:
1665		DBPRINT(sc, BCE_INFO, "Enabling MII interface.\n");
1666		val |= BCE_EMAC_MODE_PORT_MII;
1667		break;
1668	case IFM_2500_SX:
1669		DBPRINT(sc, BCE_INFO, "Enabling 2.5G MAC mode.\n");
1670		val |= BCE_EMAC_MODE_25G;
1671		/* fall-through */
1672	case IFM_1000_T:
1673	case IFM_1000_SX:
1674		DBPRINT(sc, BCE_INFO, "Enabling GMII interface.\n");
1675		val |= BCE_EMAC_MODE_PORT_GMII;
1676		break;
1677	default:
1678		DBPRINT(sc, BCE_INFO, "Unknown speed, enabling default GMII "
1679			"interface.\n");
1680		val |= BCE_EMAC_MODE_PORT_GMII;
1681	}
1682
1683	/* Set half or full duplex based on the duplicity negotiated by the PHY. */
1684	if ((mii->mii_media_active & IFM_GMASK) == IFM_HDX) {
1685		DBPRINT(sc, BCE_INFO, "Setting Half-Duplex interface.\n");
1686		val |= BCE_EMAC_MODE_HALF_DUPLEX;
1687	} else
1688		DBPRINT(sc, BCE_INFO, "Setting Full-Duplex interface.\n");
1689
1690	REG_WR(sc, BCE_EMAC_MODE, val);
1691
1692#if 0
1693	/* ToDo: Enable flow control support in brgphy and bge. */
1694	/* FLAG0 is set if RX is enabled and FLAG1 if TX is enabled */
1695	if (mii->mii_media_active & IFM_FLAG0)
1696		BCE_SETBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
1697	if (mii->mii_media_active & IFM_FLAG1)
1698		BCE_SETBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_TX_MODE_FLOW_EN);
1699#endif
1700
1701	DBEXIT(BCE_VERBOSE_PHY);
1702}
1703
1704
1705/****************************************************************************/
1706/* Acquire NVRAM lock.                                                      */
1707/*                                                                          */
1708/* Before the NVRAM can be accessed the caller must acquire an NVRAM lock.  */
1709/* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1710/* for use by the driver.                                                   */
1711/*                                                                          */
1712/* Returns:                                                                 */
1713/*   0 on success, positive value on failure.                               */
1714/****************************************************************************/
1715static int
1716bce_acquire_nvram_lock(struct bce_softc *sc)
1717{
1718	u32 val;
1719	int j, rc = 0;
1720
1721	DBENTER(BCE_VERBOSE_NVRAM);
1722
1723	/* Request access to the flash interface. */
1724	REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_SET2);
1725	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1726		val = REG_RD(sc, BCE_NVM_SW_ARB);
1727		if (val & BCE_NVM_SW_ARB_ARB_ARB2)
1728			break;
1729
1730		DELAY(5);
1731	}
1732
1733	if (j >= NVRAM_TIMEOUT_COUNT) {
1734		DBPRINT(sc, BCE_WARN, "Timeout acquiring NVRAM lock!\n");
1735		rc = EBUSY;
1736	}
1737
1738	DBEXIT(BCE_VERBOSE_NVRAM);
1739	return (rc);
1740}
1741
1742
1743/****************************************************************************/
1744/* Release NVRAM lock.                                                      */
1745/*                                                                          */
1746/* When the caller is finished accessing NVRAM the lock must be released.   */
1747/* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
1748/* for use by the driver.                                                   */
1749/*                                                                          */
1750/* Returns:                                                                 */
1751/*   0 on success, positive value on failure.                               */
1752/****************************************************************************/
1753static int
1754bce_release_nvram_lock(struct bce_softc *sc)
1755{
1756	u32 val;
1757	int j, rc = 0;
1758
1759	DBENTER(BCE_VERBOSE_NVRAM);
1760
1761	/*
1762	 * Relinquish nvram interface.
1763	 */
1764	REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_CLR2);
1765
1766	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1767		val = REG_RD(sc, BCE_NVM_SW_ARB);
1768		if (!(val & BCE_NVM_SW_ARB_ARB_ARB2))
1769			break;
1770
1771		DELAY(5);
1772	}
1773
1774	if (j >= NVRAM_TIMEOUT_COUNT) {
1775		DBPRINT(sc, BCE_WARN, "Timeout releasing NVRAM lock!\n");
1776		rc = EBUSY;
1777	}
1778
1779	DBEXIT(BCE_VERBOSE_NVRAM);
1780	return (rc);
1781}
1782
1783
1784#ifdef BCE_NVRAM_WRITE_SUPPORT
1785/****************************************************************************/
1786/* Enable NVRAM write access.                                               */
1787/*                                                                          */
1788/* Before writing to NVRAM the caller must enable NVRAM writes.             */
1789/*                                                                          */
1790/* Returns:                                                                 */
1791/*   0 on success, positive value on failure.                               */
1792/****************************************************************************/
1793static int
1794bce_enable_nvram_write(struct bce_softc *sc)
1795{
1796	u32 val;
1797	int rc = 0;
1798
1799	DBENTER(BCE_VERBOSE_NVRAM);
1800
1801	val = REG_RD(sc, BCE_MISC_CFG);
1802	REG_WR(sc, BCE_MISC_CFG, val | BCE_MISC_CFG_NVM_WR_EN_PCI);
1803
1804	if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
1805		int j;
1806
1807		REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1808		REG_WR(sc, BCE_NVM_COMMAND,	BCE_NVM_COMMAND_WREN | BCE_NVM_COMMAND_DOIT);
1809
1810		for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1811			DELAY(5);
1812
1813			val = REG_RD(sc, BCE_NVM_COMMAND);
1814			if (val & BCE_NVM_COMMAND_DONE)
1815				break;
1816		}
1817
1818		if (j >= NVRAM_TIMEOUT_COUNT) {
1819			DBPRINT(sc, BCE_WARN, "Timeout writing NVRAM!\n");
1820			rc = EBUSY;
1821		}
1822	}
1823
1824	DBENTER(BCE_VERBOSE_NVRAM);
1825	return (rc);
1826}
1827
1828
1829/****************************************************************************/
1830/* Disable NVRAM write access.                                              */
1831/*                                                                          */
1832/* When the caller is finished writing to NVRAM write access must be        */
1833/* disabled.                                                                */
1834/*                                                                          */
1835/* Returns:                                                                 */
1836/*   Nothing.                                                               */
1837/****************************************************************************/
1838static void
1839bce_disable_nvram_write(struct bce_softc *sc)
1840{
1841	u32 val;
1842
1843	DBENTER(BCE_VERBOSE_NVRAM);
1844
1845	val = REG_RD(sc, BCE_MISC_CFG);
1846	REG_WR(sc, BCE_MISC_CFG, val & ~BCE_MISC_CFG_NVM_WR_EN);
1847
1848	DBEXIT(BCE_VERBOSE_NVRAM);
1849
1850}
1851#endif
1852
1853
1854/****************************************************************************/
1855/* Enable NVRAM access.                                                     */
1856/*                                                                          */
1857/* Before accessing NVRAM for read or write operations the caller must      */
1858/* enabled NVRAM access.                                                    */
1859/*                                                                          */
1860/* Returns:                                                                 */
1861/*   Nothing.                                                               */
1862/****************************************************************************/
1863static void
1864bce_enable_nvram_access(struct bce_softc *sc)
1865{
1866	u32 val;
1867
1868	DBENTER(BCE_VERBOSE_NVRAM);
1869
1870	val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
1871	/* Enable both bits, even on read. */
1872	REG_WR(sc, BCE_NVM_ACCESS_ENABLE,
1873	       val | BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN);
1874
1875	DBEXIT(BCE_VERBOSE_NVRAM);
1876}
1877
1878
1879/****************************************************************************/
1880/* Disable NVRAM access.                                                    */
1881/*                                                                          */
1882/* When the caller is finished accessing NVRAM access must be disabled.     */
1883/*                                                                          */
1884/* Returns:                                                                 */
1885/*   Nothing.                                                               */
1886/****************************************************************************/
1887static void
1888bce_disable_nvram_access(struct bce_softc *sc)
1889{
1890	u32 val;
1891
1892	DBENTER(BCE_VERBOSE_NVRAM);
1893
1894	val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
1895
1896	/* Disable both bits, even after read. */
1897	REG_WR(sc, BCE_NVM_ACCESS_ENABLE,
1898		val & ~(BCE_NVM_ACCESS_ENABLE_EN |
1899			BCE_NVM_ACCESS_ENABLE_WR_EN));
1900
1901	DBEXIT(BCE_VERBOSE_NVRAM);
1902}
1903
1904
1905#ifdef BCE_NVRAM_WRITE_SUPPORT
1906/****************************************************************************/
1907/* Erase NVRAM page before writing.                                         */
1908/*                                                                          */
1909/* Non-buffered flash parts require that a page be erased before it is      */
1910/* written.                                                                 */
1911/*                                                                          */
1912/* Returns:                                                                 */
1913/*   0 on success, positive value on failure.                               */
1914/****************************************************************************/
1915static int
1916bce_nvram_erase_page(struct bce_softc *sc, u32 offset)
1917{
1918	u32 cmd;
1919	int j, rc = 0;
1920
1921	DBENTER(BCE_VERBOSE_NVRAM);
1922
1923	/* Buffered flash doesn't require an erase. */
1924	if (sc->bce_flash_info->flags & BCE_NV_BUFFERED)
1925		goto bce_nvram_erase_page_exit;
1926
1927	/* Build an erase command. */
1928	cmd = BCE_NVM_COMMAND_ERASE | BCE_NVM_COMMAND_WR |
1929	      BCE_NVM_COMMAND_DOIT;
1930
1931	/*
1932	 * Clear the DONE bit separately, set the NVRAM adress to erase,
1933	 * and issue the erase command.
1934	 */
1935	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1936	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1937	REG_WR(sc, BCE_NVM_COMMAND, cmd);
1938
1939	/* Wait for completion. */
1940	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
1941		u32 val;
1942
1943		DELAY(5);
1944
1945		val = REG_RD(sc, BCE_NVM_COMMAND);
1946		if (val & BCE_NVM_COMMAND_DONE)
1947			break;
1948	}
1949
1950	if (j >= NVRAM_TIMEOUT_COUNT) {
1951		DBPRINT(sc, BCE_WARN, "Timeout erasing NVRAM.\n");
1952		rc = EBUSY;
1953	}
1954
1955bce_nvram_erase_page_exit:
1956	DBEXIT(BCE_VERBOSE_NVRAM);
1957	return (rc);
1958}
1959#endif /* BCE_NVRAM_WRITE_SUPPORT */
1960
1961
1962/****************************************************************************/
1963/* Read a dword (32 bits) from NVRAM.                                       */
1964/*                                                                          */
1965/* Read a 32 bit word from NVRAM.  The caller is assumed to have already    */
1966/* obtained the NVRAM lock and enabled the controller for NVRAM access.     */
1967/*                                                                          */
1968/* Returns:                                                                 */
1969/*   0 on success and the 32 bit value read, positive value on failure.     */
1970/****************************************************************************/
1971static int
1972bce_nvram_read_dword(struct bce_softc *sc, u32 offset, u8 *ret_val,
1973							u32 cmd_flags)
1974{
1975	u32 cmd;
1976	int i, rc = 0;
1977
1978	DBENTER(BCE_EXTREME_NVRAM);
1979
1980	/* Build the command word. */
1981	cmd = BCE_NVM_COMMAND_DOIT | cmd_flags;
1982
1983	/* Calculate the offset for buffered flash if translation is used. */
1984	if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
1985		offset = ((offset / sc->bce_flash_info->page_size) <<
1986			   sc->bce_flash_info->page_bits) +
1987			  (offset % sc->bce_flash_info->page_size);
1988	}
1989
1990	/*
1991	 * Clear the DONE bit separately, set the address to read,
1992	 * and issue the read.
1993	 */
1994	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
1995	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
1996	REG_WR(sc, BCE_NVM_COMMAND, cmd);
1997
1998	/* Wait for completion. */
1999	for (i = 0; i < NVRAM_TIMEOUT_COUNT; i++) {
2000		u32 val;
2001
2002		DELAY(5);
2003
2004		val = REG_RD(sc, BCE_NVM_COMMAND);
2005		if (val & BCE_NVM_COMMAND_DONE) {
2006			val = REG_RD(sc, BCE_NVM_READ);
2007
2008			val = bce_be32toh(val);
2009			memcpy(ret_val, &val, 4);
2010			break;
2011		}
2012	}
2013
2014	/* Check for errors. */
2015	if (i >= NVRAM_TIMEOUT_COUNT) {
2016		BCE_PRINTF("%s(%d): Timeout error reading NVRAM at offset 0x%08X!\n",
2017			__FILE__, __LINE__, offset);
2018		rc = EBUSY;
2019	}
2020
2021	DBEXIT(BCE_EXTREME_NVRAM);
2022	return(rc);
2023}
2024
2025
2026#ifdef BCE_NVRAM_WRITE_SUPPORT
2027/****************************************************************************/
2028/* Write a dword (32 bits) to NVRAM.                                        */
2029/*                                                                          */
2030/* Write a 32 bit word to NVRAM.  The caller is assumed to have already     */
2031/* obtained the NVRAM lock, enabled the controller for NVRAM access, and    */
2032/* enabled NVRAM write access.                                              */
2033/*                                                                          */
2034/* Returns:                                                                 */
2035/*   0 on success, positive value on failure.                               */
2036/****************************************************************************/
2037static int
2038bce_nvram_write_dword(struct bce_softc *sc, u32 offset, u8 *val,
2039	u32 cmd_flags)
2040{
2041	u32 cmd, val32;
2042	int j, rc = 0;
2043
2044	DBENTER(BCE_VERBOSE_NVRAM);
2045
2046	/* Build the command word. */
2047	cmd = BCE_NVM_COMMAND_DOIT | BCE_NVM_COMMAND_WR | cmd_flags;
2048
2049	/* Calculate the offset for buffered flash if translation is used. */
2050	if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
2051		offset = ((offset / sc->bce_flash_info->page_size) <<
2052			  sc->bce_flash_info->page_bits) +
2053			 (offset % sc->bce_flash_info->page_size);
2054	}
2055
2056	/*
2057	 * Clear the DONE bit separately, convert NVRAM data to big-endian,
2058	 * set the NVRAM address to write, and issue the write command
2059	 */
2060	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2061	memcpy(&val32, val, 4);
2062	val32 = htobe32(val32);
2063	REG_WR(sc, BCE_NVM_WRITE, val32);
2064	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
2065	REG_WR(sc, BCE_NVM_COMMAND, cmd);
2066
2067	/* Wait for completion. */
2068	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2069		DELAY(5);
2070
2071		if (REG_RD(sc, BCE_NVM_COMMAND) & BCE_NVM_COMMAND_DONE)
2072			break;
2073	}
2074	if (j >= NVRAM_TIMEOUT_COUNT) {
2075		BCE_PRINTF("%s(%d): Timeout error writing NVRAM at offset 0x%08X\n",
2076			__FILE__, __LINE__, offset);
2077		rc = EBUSY;
2078	}
2079
2080	DBEXIT(BCE_VERBOSE_NVRAM);
2081	return (rc);
2082}
2083#endif /* BCE_NVRAM_WRITE_SUPPORT */
2084
2085
2086/****************************************************************************/
2087/* Initialize NVRAM access.                                                 */
2088/*                                                                          */
2089/* Identify the NVRAM device in use and prepare the NVRAM interface to      */
2090/* access that device.                                                      */
2091/*                                                                          */
2092/* Returns:                                                                 */
2093/*   0 on success, positive value on failure.                               */
2094/****************************************************************************/
2095static int
2096bce_init_nvram(struct bce_softc *sc)
2097{
2098	u32 val;
2099	int j, entry_count, rc = 0;
2100	struct flash_spec *flash;
2101
2102	DBENTER(BCE_VERBOSE_NVRAM);
2103
2104	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
2105		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
2106		sc->bce_flash_info = &flash_5709;
2107		goto bce_init_nvram_get_flash_size;
2108	}
2109
2110	/* Determine the selected interface. */
2111	val = REG_RD(sc, BCE_NVM_CFG1);
2112
2113	entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
2114
2115	/*
2116	 * Flash reconfiguration is required to support additional
2117	 * NVRAM devices not directly supported in hardware.
2118	 * Check if the flash interface was reconfigured
2119	 * by the bootcode.
2120	 */
2121
2122	if (val & 0x40000000) {
2123		/* Flash interface reconfigured by bootcode. */
2124
2125		DBPRINT(sc,BCE_INFO_LOAD,
2126			"bce_init_nvram(): Flash WAS reconfigured.\n");
2127
2128		for (j = 0, flash = &flash_table[0]; j < entry_count;
2129		     j++, flash++) {
2130			if ((val & FLASH_BACKUP_STRAP_MASK) ==
2131			    (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
2132				sc->bce_flash_info = flash;
2133				break;
2134			}
2135		}
2136	} else {
2137		/* Flash interface not yet reconfigured. */
2138		u32 mask;
2139
2140		DBPRINT(sc, BCE_INFO_LOAD, "%s(): Flash was NOT reconfigured.\n",
2141			__FUNCTION__);
2142
2143		if (val & (1 << 23))
2144			mask = FLASH_BACKUP_STRAP_MASK;
2145		else
2146			mask = FLASH_STRAP_MASK;
2147
2148		/* Look for the matching NVRAM device configuration data. */
2149		for (j = 0, flash = &flash_table[0]; j < entry_count; j++, flash++) {
2150
2151			/* Check if the device matches any of the known devices. */
2152			if ((val & mask) == (flash->strapping & mask)) {
2153				/* Found a device match. */
2154				sc->bce_flash_info = flash;
2155
2156				/* Request access to the flash interface. */
2157				if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2158					return rc;
2159
2160				/* Reconfigure the flash interface. */
2161				bce_enable_nvram_access(sc);
2162				REG_WR(sc, BCE_NVM_CFG1, flash->config1);
2163				REG_WR(sc, BCE_NVM_CFG2, flash->config2);
2164				REG_WR(sc, BCE_NVM_CFG3, flash->config3);
2165				REG_WR(sc, BCE_NVM_WRITE1, flash->write1);
2166				bce_disable_nvram_access(sc);
2167				bce_release_nvram_lock(sc);
2168
2169				break;
2170			}
2171		}
2172	}
2173
2174	/* Check if a matching device was found. */
2175	if (j == entry_count) {
2176		sc->bce_flash_info = NULL;
2177		BCE_PRINTF("%s(%d): Unknown Flash NVRAM found!\n",
2178			__FILE__, __LINE__);
2179		rc = ENODEV;
2180	}
2181
2182bce_init_nvram_get_flash_size:
2183	/* Write the flash config data to the shared memory interface. */
2184	val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG2);
2185	val &= BCE_SHARED_HW_CFG2_NVM_SIZE_MASK;
2186	if (val)
2187		sc->bce_flash_size = val;
2188	else
2189		sc->bce_flash_size = sc->bce_flash_info->total_size;
2190
2191	DBPRINT(sc, BCE_INFO_LOAD, "%s(): Found %s, size = 0x%08X\n",
2192		__FUNCTION__, sc->bce_flash_info->name,
2193		sc->bce_flash_info->total_size);
2194
2195	DBEXIT(BCE_VERBOSE_NVRAM);
2196	return rc;
2197}
2198
2199
2200/****************************************************************************/
2201/* Read an arbitrary range of data from NVRAM.                              */
2202/*                                                                          */
2203/* Prepares the NVRAM interface for access and reads the requested data     */
2204/* into the supplied buffer.                                                */
2205/*                                                                          */
2206/* Returns:                                                                 */
2207/*   0 on success and the data read, positive value on failure.             */
2208/****************************************************************************/
2209static int
2210bce_nvram_read(struct bce_softc *sc, u32 offset, u8 *ret_buf,
2211	int buf_size)
2212{
2213	int rc = 0;
2214	u32 cmd_flags, offset32, len32, extra;
2215
2216	DBENTER(BCE_VERBOSE_NVRAM);
2217
2218	if (buf_size == 0)
2219		goto bce_nvram_read_exit;
2220
2221	/* Request access to the flash interface. */
2222	if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2223		goto bce_nvram_read_exit;
2224
2225	/* Enable access to flash interface */
2226	bce_enable_nvram_access(sc);
2227
2228	len32 = buf_size;
2229	offset32 = offset;
2230	extra = 0;
2231
2232	cmd_flags = 0;
2233
2234	if (offset32 & 3) {
2235		u8 buf[4];
2236		u32 pre_len;
2237
2238		offset32 &= ~3;
2239		pre_len = 4 - (offset & 3);
2240
2241		if (pre_len >= len32) {
2242			pre_len = len32;
2243			cmd_flags = BCE_NVM_COMMAND_FIRST | BCE_NVM_COMMAND_LAST;
2244		}
2245		else {
2246			cmd_flags = BCE_NVM_COMMAND_FIRST;
2247		}
2248
2249		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2250
2251		if (rc)
2252			return rc;
2253
2254		memcpy(ret_buf, buf + (offset & 3), pre_len);
2255
2256		offset32 += 4;
2257		ret_buf += pre_len;
2258		len32 -= pre_len;
2259	}
2260
2261	if (len32 & 3) {
2262		extra = 4 - (len32 & 3);
2263		len32 = (len32 + 4) & ~3;
2264	}
2265
2266	if (len32 == 4) {
2267		u8 buf[4];
2268
2269		if (cmd_flags)
2270			cmd_flags = BCE_NVM_COMMAND_LAST;
2271		else
2272			cmd_flags = BCE_NVM_COMMAND_FIRST |
2273				    BCE_NVM_COMMAND_LAST;
2274
2275		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2276
2277		memcpy(ret_buf, buf, 4 - extra);
2278	}
2279	else if (len32 > 0) {
2280		u8 buf[4];
2281
2282		/* Read the first word. */
2283		if (cmd_flags)
2284			cmd_flags = 0;
2285		else
2286			cmd_flags = BCE_NVM_COMMAND_FIRST;
2287
2288		rc = bce_nvram_read_dword(sc, offset32, ret_buf, cmd_flags);
2289
2290		/* Advance to the next dword. */
2291		offset32 += 4;
2292		ret_buf += 4;
2293		len32 -= 4;
2294
2295		while (len32 > 4 && rc == 0) {
2296			rc = bce_nvram_read_dword(sc, offset32, ret_buf, 0);
2297
2298			/* Advance to the next dword. */
2299			offset32 += 4;
2300			ret_buf += 4;
2301			len32 -= 4;
2302		}
2303
2304		if (rc)
2305			goto bce_nvram_read_locked_exit;
2306
2307		cmd_flags = BCE_NVM_COMMAND_LAST;
2308		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2309
2310		memcpy(ret_buf, buf, 4 - extra);
2311	}
2312
2313bce_nvram_read_locked_exit:
2314	/* Disable access to flash interface and release the lock. */
2315	bce_disable_nvram_access(sc);
2316	bce_release_nvram_lock(sc);
2317
2318bce_nvram_read_exit:
2319	DBEXIT(BCE_VERBOSE_NVRAM);
2320	return rc;
2321}
2322
2323
2324#ifdef BCE_NVRAM_WRITE_SUPPORT
2325/****************************************************************************/
2326/* Write an arbitrary range of data from NVRAM.                             */
2327/*                                                                          */
2328/* Prepares the NVRAM interface for write access and writes the requested   */
2329/* data from the supplied buffer.  The caller is responsible for            */
2330/* calculating any appropriate CRCs.                                        */
2331/*                                                                          */
2332/* Returns:                                                                 */
2333/*   0 on success, positive value on failure.                               */
2334/****************************************************************************/
2335static int
2336bce_nvram_write(struct bce_softc *sc, u32 offset, u8 *data_buf,
2337	int buf_size)
2338{
2339	u32 written, offset32, len32;
2340	u8 *buf, start[4], end[4];
2341	int rc = 0;
2342	int align_start, align_end;
2343
2344	DBENTER(BCE_VERBOSE_NVRAM);
2345
2346	buf = data_buf;
2347	offset32 = offset;
2348	len32 = buf_size;
2349	align_start = align_end = 0;
2350
2351	if ((align_start = (offset32 & 3))) {
2352		offset32 &= ~3;
2353		len32 += align_start;
2354		if ((rc = bce_nvram_read(sc, offset32, start, 4)))
2355			goto bce_nvram_write_exit;
2356	}
2357
2358	if (len32 & 3) {
2359	       	if ((len32 > 4) || !align_start) {
2360			align_end = 4 - (len32 & 3);
2361			len32 += align_end;
2362			if ((rc = bce_nvram_read(sc, offset32 + len32 - 4,
2363				end, 4))) {
2364				goto bce_nvram_write_exit;
2365			}
2366		}
2367	}
2368
2369	if (align_start || align_end) {
2370		buf = malloc(len32, M_DEVBUF, M_NOWAIT);
2371		if (buf == 0) {
2372			rc = ENOMEM;
2373			goto bce_nvram_write_exit;
2374		}
2375
2376		if (align_start) {
2377			memcpy(buf, start, 4);
2378		}
2379
2380		if (align_end) {
2381			memcpy(buf + len32 - 4, end, 4);
2382		}
2383		memcpy(buf + align_start, data_buf, buf_size);
2384	}
2385
2386	written = 0;
2387	while ((written < len32) && (rc == 0)) {
2388		u32 page_start, page_end, data_start, data_end;
2389		u32 addr, cmd_flags;
2390		int i;
2391		u8 flash_buffer[264];
2392
2393	    /* Find the page_start addr */
2394		page_start = offset32 + written;
2395		page_start -= (page_start % sc->bce_flash_info->page_size);
2396		/* Find the page_end addr */
2397		page_end = page_start + sc->bce_flash_info->page_size;
2398		/* Find the data_start addr */
2399		data_start = (written == 0) ? offset32 : page_start;
2400		/* Find the data_end addr */
2401		data_end = (page_end > offset32 + len32) ?
2402			(offset32 + len32) : page_end;
2403
2404		/* Request access to the flash interface. */
2405		if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2406			goto bce_nvram_write_exit;
2407
2408		/* Enable access to flash interface */
2409		bce_enable_nvram_access(sc);
2410
2411		cmd_flags = BCE_NVM_COMMAND_FIRST;
2412		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2413			int j;
2414
2415			/* Read the whole page into the buffer
2416			 * (non-buffer flash only) */
2417			for (j = 0; j < sc->bce_flash_info->page_size; j += 4) {
2418				if (j == (sc->bce_flash_info->page_size - 4)) {
2419					cmd_flags |= BCE_NVM_COMMAND_LAST;
2420				}
2421				rc = bce_nvram_read_dword(sc,
2422					page_start + j,
2423					&flash_buffer[j],
2424					cmd_flags);
2425
2426				if (rc)
2427					goto bce_nvram_write_locked_exit;
2428
2429				cmd_flags = 0;
2430			}
2431		}
2432
2433		/* Enable writes to flash interface (unlock write-protect) */
2434		if ((rc = bce_enable_nvram_write(sc)) != 0)
2435			goto bce_nvram_write_locked_exit;
2436
2437		/* Erase the page */
2438		if ((rc = bce_nvram_erase_page(sc, page_start)) != 0)
2439			goto bce_nvram_write_locked_exit;
2440
2441		/* Re-enable the write again for the actual write */
2442		bce_enable_nvram_write(sc);
2443
2444		/* Loop to write back the buffer data from page_start to
2445		 * data_start */
2446		i = 0;
2447		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2448			for (addr = page_start; addr < data_start;
2449				addr += 4, i += 4) {
2450
2451				rc = bce_nvram_write_dword(sc, addr,
2452					&flash_buffer[i], cmd_flags);
2453
2454				if (rc != 0)
2455					goto bce_nvram_write_locked_exit;
2456
2457				cmd_flags = 0;
2458			}
2459		}
2460
2461		/* Loop to write the new data from data_start to data_end */
2462		for (addr = data_start; addr < data_end; addr += 4, i++) {
2463			if ((addr == page_end - 4) ||
2464				((sc->bce_flash_info->flags & BCE_NV_BUFFERED) &&
2465				(addr == data_end - 4))) {
2466
2467				cmd_flags |= BCE_NVM_COMMAND_LAST;
2468			}
2469			rc = bce_nvram_write_dword(sc, addr, buf,
2470				cmd_flags);
2471
2472			if (rc != 0)
2473				goto bce_nvram_write_locked_exit;
2474
2475			cmd_flags = 0;
2476			buf += 4;
2477		}
2478
2479		/* Loop to write back the buffer data from data_end
2480		 * to page_end */
2481		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2482			for (addr = data_end; addr < page_end;
2483				addr += 4, i += 4) {
2484
2485				if (addr == page_end-4) {
2486					cmd_flags = BCE_NVM_COMMAND_LAST;
2487                		}
2488				rc = bce_nvram_write_dword(sc, addr,
2489					&flash_buffer[i], cmd_flags);
2490
2491				if (rc != 0)
2492					goto bce_nvram_write_locked_exit;
2493
2494				cmd_flags = 0;
2495			}
2496		}
2497
2498		/* Disable writes to flash interface (lock write-protect) */
2499		bce_disable_nvram_write(sc);
2500
2501		/* Disable access to flash interface */
2502		bce_disable_nvram_access(sc);
2503		bce_release_nvram_lock(sc);
2504
2505		/* Increment written */
2506		written += data_end - data_start;
2507	}
2508
2509	goto bce_nvram_write_exit;
2510
2511bce_nvram_write_locked_exit:
2512		bce_disable_nvram_write(sc);
2513		bce_disable_nvram_access(sc);
2514		bce_release_nvram_lock(sc);
2515
2516bce_nvram_write_exit:
2517	if (align_start || align_end)
2518		free(buf, M_DEVBUF);
2519
2520	DBEXIT(BCE_VERBOSE_NVRAM);
2521	return (rc);
2522}
2523#endif /* BCE_NVRAM_WRITE_SUPPORT */
2524
2525
2526/****************************************************************************/
2527/* Verifies that NVRAM is accessible and contains valid data.               */
2528/*                                                                          */
2529/* Reads the configuration data from NVRAM and verifies that the CRC is     */
2530/* correct.                                                                 */
2531/*                                                                          */
2532/* Returns:                                                                 */
2533/*   0 on success, positive value on failure.                               */
2534/****************************************************************************/
2535static int
2536bce_nvram_test(struct bce_softc *sc)
2537{
2538	u32 buf[BCE_NVRAM_SIZE / 4];
2539	u8 *data = (u8 *) buf;
2540	int rc = 0;
2541	u32 magic, csum;
2542
2543	DBENTER(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
2544
2545	/*
2546	 * Check that the device NVRAM is valid by reading
2547	 * the magic value at offset 0.
2548	 */
2549	if ((rc = bce_nvram_read(sc, 0, data, 4)) != 0) {
2550		BCE_PRINTF("%s(%d): Unable to read NVRAM!\n", __FILE__, __LINE__);
2551		goto bce_nvram_test_exit;
2552	}
2553
2554	/*
2555	 * Verify that offset 0 of the NVRAM contains
2556	 * a valid magic number.
2557	 */
2558    magic = bce_be32toh(buf[0]);
2559	if (magic != BCE_NVRAM_MAGIC) {
2560		rc = ENODEV;
2561		BCE_PRINTF("%s(%d): Invalid NVRAM magic value! Expected: 0x%08X, "
2562			"Found: 0x%08X\n",
2563			__FILE__, __LINE__, BCE_NVRAM_MAGIC, magic);
2564		goto bce_nvram_test_exit;
2565	}
2566
2567	/*
2568	 * Verify that the device NVRAM includes valid
2569	 * configuration data.
2570	 */
2571	if ((rc = bce_nvram_read(sc, 0x100, data, BCE_NVRAM_SIZE)) != 0) {
2572		BCE_PRINTF("%s(%d): Unable to read Manufacturing Information from "
2573			"NVRAM!\n", __FILE__, __LINE__);
2574		goto bce_nvram_test_exit;
2575	}
2576
2577	csum = ether_crc32_le(data, 0x100);
2578	if (csum != BCE_CRC32_RESIDUAL) {
2579		rc = ENODEV;
2580		BCE_PRINTF("%s(%d): Invalid Manufacturing Information NVRAM CRC! "
2581			"Expected: 0x%08X, Found: 0x%08X\n",
2582			__FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
2583		goto bce_nvram_test_exit;
2584	}
2585
2586	csum = ether_crc32_le(data + 0x100, 0x100);
2587	if (csum != BCE_CRC32_RESIDUAL) {
2588		rc = ENODEV;
2589		BCE_PRINTF("%s(%d): Invalid Feature Configuration Information "
2590			"NVRAM CRC! Expected: 0x%08X, Found: 08%08X\n",
2591			__FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
2592	}
2593
2594bce_nvram_test_exit:
2595	DBEXIT(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
2596	return rc;
2597}
2598
2599
2600/****************************************************************************/
2601/* Identifies the current media type of the controller and sets the PHY     */
2602/* address.                                                                 */
2603/*                                                                          */
2604/* Returns:                                                                 */
2605/*   Nothing.                                                               */
2606/****************************************************************************/
2607static void
2608bce_get_media(struct bce_softc *sc)
2609{
2610	u32 val;
2611
2612	DBENTER(BCE_VERBOSE);
2613
2614	/* Assume PHY address for copper controllers. */
2615	sc->bce_phy_addr = 1;
2616
2617	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
2618 		u32 val = REG_RD(sc, BCE_MISC_DUAL_MEDIA_CTRL);
2619		u32 bond_id = val & BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID;
2620		u32 strap;
2621
2622		/*
2623		 * The BCM5709S is software configurable
2624		 * for Copper or SerDes operation.
2625		 */
2626		if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_C) {
2627			DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded for copper.\n");
2628			goto bce_get_media_exit;
2629		} else if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_S) {
2630			DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded for dual media.\n");
2631			sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2632			goto bce_get_media_exit;
2633		}
2634
2635		if (val & BCE_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE)
2636			strap = (val & BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21;
2637		else
2638			strap = (val & BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8;
2639
2640		if (pci_get_function(sc->bce_dev) == 0) {
2641			switch (strap) {
2642			case 0x4:
2643			case 0x5:
2644			case 0x6:
2645				DBPRINT(sc, BCE_INFO_LOAD,
2646					"BCM5709 s/w configured for SerDes.\n");
2647				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2648			default:
2649				DBPRINT(sc, BCE_INFO_LOAD,
2650					"BCM5709 s/w configured for Copper.\n");
2651			}
2652		} else {
2653			switch (strap) {
2654			case 0x1:
2655			case 0x2:
2656			case 0x4:
2657				DBPRINT(sc, BCE_INFO_LOAD,
2658					"BCM5709 s/w configured for SerDes.\n");
2659				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2660			default:
2661				DBPRINT(sc, BCE_INFO_LOAD,
2662					"BCM5709 s/w configured for Copper.\n");
2663			}
2664		}
2665
2666	} else if (BCE_CHIP_BOND_ID(sc) & BCE_CHIP_BOND_ID_SERDES_BIT)
2667		sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
2668
2669	if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) {
2670		sc->bce_flags |= BCE_NO_WOL_FLAG;
2671		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
2672			sc->bce_phy_addr = 2;
2673			val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
2674			if (val & BCE_SHARED_HW_CFG_PHY_2_5G) {
2675				sc->bce_phy_flags |= BCE_PHY_2_5G_CAPABLE_FLAG;
2676				DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb capable adapter\n");
2677			}
2678		}
2679	} else if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) ||
2680		   (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708))
2681		sc->bce_phy_flags |= BCE_PHY_CRC_FIX_FLAG;
2682
2683bce_get_media_exit:
2684	DBPRINT(sc, (BCE_INFO_LOAD | BCE_INFO_PHY),
2685		"Using PHY address %d.\n", sc->bce_phy_addr);
2686
2687	DBEXIT(BCE_VERBOSE);
2688}
2689
2690
2691/****************************************************************************/
2692/* Free any DMA memory owned by the driver.                                 */
2693/*                                                                          */
2694/* Scans through each data structre that requires DMA memory and frees      */
2695/* the memory if allocated.                                                 */
2696/*                                                                          */
2697/* Returns:                                                                 */
2698/*   Nothing.                                                               */
2699/****************************************************************************/
2700static void
2701bce_dma_free(struct bce_softc *sc)
2702{
2703	int i;
2704
2705	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
2706
2707	/* Free, unmap, and destroy the status block. */
2708	if (sc->status_block != NULL) {
2709		bus_dmamem_free(
2710			sc->status_tag,
2711		    sc->status_block,
2712		    sc->status_map);
2713		sc->status_block = NULL;
2714	}
2715
2716	if (sc->status_map != NULL) {
2717		bus_dmamap_unload(
2718			sc->status_tag,
2719		    sc->status_map);
2720		bus_dmamap_destroy(sc->status_tag,
2721		    sc->status_map);
2722		sc->status_map = NULL;
2723	}
2724
2725	if (sc->status_tag != NULL) {
2726		bus_dma_tag_destroy(sc->status_tag);
2727		sc->status_tag = NULL;
2728	}
2729
2730
2731	/* Free, unmap, and destroy the statistics block. */
2732	if (sc->stats_block != NULL) {
2733		bus_dmamem_free(
2734			sc->stats_tag,
2735		    sc->stats_block,
2736		    sc->stats_map);
2737		sc->stats_block = NULL;
2738	}
2739
2740	if (sc->stats_map != NULL) {
2741		bus_dmamap_unload(
2742			sc->stats_tag,
2743		    sc->stats_map);
2744		bus_dmamap_destroy(sc->stats_tag,
2745		    sc->stats_map);
2746		sc->stats_map = NULL;
2747	}
2748
2749	if (sc->stats_tag != NULL) {
2750		bus_dma_tag_destroy(sc->stats_tag);
2751		sc->stats_tag = NULL;
2752	}
2753
2754
2755	/* Free, unmap and destroy all context memory pages. */
2756	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
2757		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
2758		for (i = 0; i < sc->ctx_pages; i++ ) {
2759			if (sc->ctx_block[i] != NULL) {
2760				bus_dmamem_free(
2761					sc->ctx_tag,
2762				    sc->ctx_block[i],
2763				    sc->ctx_map[i]);
2764				sc->ctx_block[i] = NULL;
2765			}
2766
2767			if (sc->ctx_map[i] != NULL) {
2768				bus_dmamap_unload(
2769					sc->ctx_tag,
2770		    		sc->ctx_map[i]);
2771				bus_dmamap_destroy(
2772					sc->ctx_tag,
2773				    sc->ctx_map[i]);
2774				sc->ctx_map[i] = NULL;
2775			}
2776		}
2777
2778		/* Destroy the context memory tag. */
2779		if (sc->ctx_tag != NULL) {
2780			bus_dma_tag_destroy(sc->ctx_tag);
2781			sc->ctx_tag = NULL;
2782		}
2783	}
2784
2785
2786	/* Free, unmap and destroy all TX buffer descriptor chain pages. */
2787	for (i = 0; i < TX_PAGES; i++ ) {
2788		if (sc->tx_bd_chain[i] != NULL) {
2789			bus_dmamem_free(
2790				sc->tx_bd_chain_tag,
2791			    sc->tx_bd_chain[i],
2792			    sc->tx_bd_chain_map[i]);
2793			sc->tx_bd_chain[i] = NULL;
2794		}
2795
2796		if (sc->tx_bd_chain_map[i] != NULL) {
2797			bus_dmamap_unload(
2798				sc->tx_bd_chain_tag,
2799		    	sc->tx_bd_chain_map[i]);
2800			bus_dmamap_destroy(
2801				sc->tx_bd_chain_tag,
2802			    sc->tx_bd_chain_map[i]);
2803			sc->tx_bd_chain_map[i] = NULL;
2804		}
2805	}
2806
2807	/* Destroy the TX buffer descriptor tag. */
2808	if (sc->tx_bd_chain_tag != NULL) {
2809		bus_dma_tag_destroy(sc->tx_bd_chain_tag);
2810		sc->tx_bd_chain_tag = NULL;
2811	}
2812
2813
2814	/* Free, unmap and destroy all RX buffer descriptor chain pages. */
2815	for (i = 0; i < RX_PAGES; i++ ) {
2816		if (sc->rx_bd_chain[i] != NULL) {
2817			bus_dmamem_free(
2818				sc->rx_bd_chain_tag,
2819			    sc->rx_bd_chain[i],
2820			    sc->rx_bd_chain_map[i]);
2821			sc->rx_bd_chain[i] = NULL;
2822		}
2823
2824		if (sc->rx_bd_chain_map[i] != NULL) {
2825			bus_dmamap_unload(
2826				sc->rx_bd_chain_tag,
2827		    	sc->rx_bd_chain_map[i]);
2828			bus_dmamap_destroy(
2829				sc->rx_bd_chain_tag,
2830			    sc->rx_bd_chain_map[i]);
2831			sc->rx_bd_chain_map[i] = NULL;
2832		}
2833	}
2834
2835	/* Destroy the RX buffer descriptor tag. */
2836	if (sc->rx_bd_chain_tag != NULL) {
2837		bus_dma_tag_destroy(sc->rx_bd_chain_tag);
2838		sc->rx_bd_chain_tag = NULL;
2839	}
2840
2841
2842#ifdef BCE_JUMBO_HDRSPLIT
2843	/* Free, unmap and destroy all page buffer descriptor chain pages. */
2844	for (i = 0; i < PG_PAGES; i++ ) {
2845		if (sc->pg_bd_chain[i] != NULL) {
2846			bus_dmamem_free(
2847				sc->pg_bd_chain_tag,
2848			    sc->pg_bd_chain[i],
2849			    sc->pg_bd_chain_map[i]);
2850			sc->pg_bd_chain[i] = NULL;
2851		}
2852
2853		if (sc->pg_bd_chain_map[i] != NULL) {
2854			bus_dmamap_unload(
2855				sc->pg_bd_chain_tag,
2856		    	sc->pg_bd_chain_map[i]);
2857			bus_dmamap_destroy(
2858				sc->pg_bd_chain_tag,
2859			    sc->pg_bd_chain_map[i]);
2860			sc->pg_bd_chain_map[i] = NULL;
2861		}
2862	}
2863
2864	/* Destroy the page buffer descriptor tag. */
2865	if (sc->pg_bd_chain_tag != NULL) {
2866		bus_dma_tag_destroy(sc->pg_bd_chain_tag);
2867		sc->pg_bd_chain_tag = NULL;
2868	}
2869#endif
2870
2871
2872	/* Unload and destroy the TX mbuf maps. */
2873	for (i = 0; i < TOTAL_TX_BD; i++) {
2874		if (sc->tx_mbuf_map[i] != NULL) {
2875			bus_dmamap_unload(sc->tx_mbuf_tag,
2876				sc->tx_mbuf_map[i]);
2877			bus_dmamap_destroy(sc->tx_mbuf_tag,
2878	 			sc->tx_mbuf_map[i]);
2879			sc->tx_mbuf_map[i] = NULL;
2880		}
2881	}
2882
2883	/* Destroy the TX mbuf tag. */
2884	if (sc->tx_mbuf_tag != NULL) {
2885		bus_dma_tag_destroy(sc->tx_mbuf_tag);
2886		sc->tx_mbuf_tag = NULL;
2887	}
2888
2889	/* Unload and destroy the RX mbuf maps. */
2890	for (i = 0; i < TOTAL_RX_BD; i++) {
2891		if (sc->rx_mbuf_map[i] != NULL) {
2892			bus_dmamap_unload(sc->rx_mbuf_tag,
2893				sc->rx_mbuf_map[i]);
2894			bus_dmamap_destroy(sc->rx_mbuf_tag,
2895	 			sc->rx_mbuf_map[i]);
2896			sc->rx_mbuf_map[i] = NULL;
2897		}
2898	}
2899
2900	/* Destroy the RX mbuf tag. */
2901	if (sc->rx_mbuf_tag != NULL) {
2902		bus_dma_tag_destroy(sc->rx_mbuf_tag);
2903		sc->rx_mbuf_tag = NULL;
2904	}
2905
2906#ifdef BCE_JUMBO_HDRSPLIT
2907	/* Unload and destroy the page mbuf maps. */
2908	for (i = 0; i < TOTAL_PG_BD; i++) {
2909		if (sc->pg_mbuf_map[i] != NULL) {
2910			bus_dmamap_unload(sc->pg_mbuf_tag,
2911				sc->pg_mbuf_map[i]);
2912			bus_dmamap_destroy(sc->pg_mbuf_tag,
2913	 			sc->pg_mbuf_map[i]);
2914			sc->pg_mbuf_map[i] = NULL;
2915		}
2916	}
2917
2918	/* Destroy the page mbuf tag. */
2919	if (sc->pg_mbuf_tag != NULL) {
2920		bus_dma_tag_destroy(sc->pg_mbuf_tag);
2921		sc->pg_mbuf_tag = NULL;
2922	}
2923#endif
2924
2925	/* Destroy the parent tag */
2926	if (sc->parent_tag != NULL) {
2927		bus_dma_tag_destroy(sc->parent_tag);
2928		sc->parent_tag = NULL;
2929	}
2930
2931	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
2932}
2933
2934
2935/****************************************************************************/
2936/* Get DMA memory from the OS.                                              */
2937/*                                                                          */
2938/* Validates that the OS has provided DMA buffers in response to a          */
2939/* bus_dmamap_load() call and saves the physical address of those buffers.  */
2940/* When the callback is used the OS will return 0 for the mapping function  */
2941/* (bus_dmamap_load()) so we use the value of map_arg->maxsegs to pass any  */
2942/* failures back to the caller.                                             */
2943/*                                                                          */
2944/* Returns:                                                                 */
2945/*   Nothing.                                                               */
2946/****************************************************************************/
2947static void
2948bce_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
2949{
2950	bus_addr_t *busaddr = arg;
2951
2952	/* Simulate a mapping failure. */
2953	DBRUNIF(DB_RANDOMTRUE(dma_map_addr_failed_sim_control),
2954		error = ENOMEM);
2955
2956	/* Check for an error and signal the caller that an error occurred. */
2957	if (error) {
2958		*busaddr = 0;
2959	} else {
2960		*busaddr = segs->ds_addr;
2961	}
2962
2963	return;
2964}
2965
2966
2967/****************************************************************************/
2968/* Allocate any DMA memory needed by the driver.                            */
2969/*                                                                          */
2970/* Allocates DMA memory needed for the various global structures needed by  */
2971/* hardware.                                                                */
2972/*                                                                          */
2973/* Memory alignment requirements:                                           */
2974/* +-----------------+----------+----------+----------+----------+          */
2975/* |                 |   5706   |   5708   |   5709   |   5716   |          */
2976/* +-----------------+----------+----------+----------+----------+          */
2977/* |Status Block     | 8 bytes  | 8 bytes  | 16 bytes | 16 bytes |          */
2978/* |Statistics Block | 8 bytes  | 8 bytes  | 16 bytes | 16 bytes |          */
2979/* |RX Buffers       | 16 bytes | 16 bytes | 16 bytes | 16 bytes |          */
2980/* |PG Buffers       |   none   |   none   |   none   |   none   |          */
2981/* |TX Buffers       |   none   |   none   |   none   |   none   |          */
2982/* |Chain Pages(1)   |   4KiB   |   4KiB   |   4KiB   |   4KiB   |          */
2983/* |Context Memory   |          |          |          |          |          */
2984/* +-----------------+----------+----------+----------+----------+          */
2985/*                                                                          */
2986/* (1) Must align with CPU page size (BCM_PAGE_SZIE).                       */
2987/*                                                                          */
2988/* Returns:                                                                 */
2989/*   0 for success, positive value for failure.                             */
2990/****************************************************************************/
2991static int
2992bce_dma_alloc(device_t dev)
2993{
2994	struct bce_softc *sc;
2995	int i, error, rc = 0;
2996	bus_size_t max_size, max_seg_size;
2997	int max_segments;
2998
2999	sc = device_get_softc(dev);
3000
3001	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
3002
3003	/*
3004	 * Allocate the parent bus DMA tag appropriate for PCI.
3005	 */
3006	if (bus_dma_tag_create(NULL,
3007			1,
3008			BCE_DMA_BOUNDARY,
3009			sc->max_bus_addr,
3010			BUS_SPACE_MAXADDR,
3011			NULL, NULL,
3012			MAXBSIZE,
3013			BUS_SPACE_UNRESTRICTED,
3014			BUS_SPACE_MAXSIZE_32BIT,
3015			0,
3016			NULL, NULL,
3017			&sc->parent_tag)) {
3018		BCE_PRINTF("%s(%d): Could not allocate parent DMA tag!\n",
3019			__FILE__, __LINE__);
3020		rc = ENOMEM;
3021		goto bce_dma_alloc_exit;
3022	}
3023
3024	/*
3025	 * Create a DMA tag for the status block, allocate and clear the
3026	 * memory, map the memory into DMA space, and fetch the physical
3027	 * address of the block.
3028	 */
3029	if (bus_dma_tag_create(sc->parent_tag,
3030	    	BCE_DMA_ALIGN,
3031	    	BCE_DMA_BOUNDARY,
3032	    	sc->max_bus_addr,
3033	    	BUS_SPACE_MAXADDR,
3034	    	NULL, NULL,
3035	    	BCE_STATUS_BLK_SZ,
3036	    	1,
3037	    	BCE_STATUS_BLK_SZ,
3038	    	0,
3039	    	NULL, NULL,
3040	    	&sc->status_tag)) {
3041		BCE_PRINTF("%s(%d): Could not allocate status block DMA tag!\n",
3042			__FILE__, __LINE__);
3043		rc = ENOMEM;
3044		goto bce_dma_alloc_exit;
3045	}
3046
3047	if(bus_dmamem_alloc(sc->status_tag,
3048	    	(void **)&sc->status_block,
3049	    	BUS_DMA_NOWAIT,
3050	    	&sc->status_map)) {
3051		BCE_PRINTF("%s(%d): Could not allocate status block DMA memory!\n",
3052			__FILE__, __LINE__);
3053		rc = ENOMEM;
3054		goto bce_dma_alloc_exit;
3055	}
3056
3057	bzero((char *)sc->status_block, BCE_STATUS_BLK_SZ);
3058
3059	error = bus_dmamap_load(sc->status_tag,
3060	    	sc->status_map,
3061	    	sc->status_block,
3062	    	BCE_STATUS_BLK_SZ,
3063	    	bce_dma_map_addr,
3064	    	&sc->status_block_paddr,
3065	    	BUS_DMA_NOWAIT);
3066
3067	if (error) {
3068		BCE_PRINTF("%s(%d): Could not map status block DMA memory!\n",
3069			__FILE__, __LINE__);
3070		rc = ENOMEM;
3071		goto bce_dma_alloc_exit;
3072	}
3073
3074	DBPRINT(sc, BCE_INFO, "%s(): status_block_paddr = 0x%jX\n",
3075		__FUNCTION__, (uintmax_t) sc->status_block_paddr);
3076
3077	/*
3078	 * Create a DMA tag for the statistics block, allocate and clear the
3079	 * memory, map the memory into DMA space, and fetch the physical
3080	 * address of the block.
3081	 */
3082	if (bus_dma_tag_create(sc->parent_tag,
3083	    	BCE_DMA_ALIGN,
3084	    	BCE_DMA_BOUNDARY,
3085	    	sc->max_bus_addr,
3086	    	BUS_SPACE_MAXADDR,
3087	    	NULL, NULL,
3088	    	BCE_STATS_BLK_SZ,
3089	    	1,
3090	    	BCE_STATS_BLK_SZ,
3091	    	0,
3092	    	NULL, NULL,
3093	    	&sc->stats_tag)) {
3094		BCE_PRINTF("%s(%d): Could not allocate statistics block DMA tag!\n",
3095			__FILE__, __LINE__);
3096		rc = ENOMEM;
3097		goto bce_dma_alloc_exit;
3098	}
3099
3100	if (bus_dmamem_alloc(sc->stats_tag,
3101	    	(void **)&sc->stats_block,
3102	    	BUS_DMA_NOWAIT,
3103	    	&sc->stats_map)) {
3104		BCE_PRINTF("%s(%d): Could not allocate statistics block DMA memory!\n",
3105			__FILE__, __LINE__);
3106		rc = ENOMEM;
3107		goto bce_dma_alloc_exit;
3108	}
3109
3110	bzero((char *)sc->stats_block, BCE_STATS_BLK_SZ);
3111
3112	error = bus_dmamap_load(sc->stats_tag,
3113	    	sc->stats_map,
3114	    	sc->stats_block,
3115	    	BCE_STATS_BLK_SZ,
3116	    	bce_dma_map_addr,
3117	    	&sc->stats_block_paddr,
3118	    	BUS_DMA_NOWAIT);
3119
3120	if(error) {
3121		BCE_PRINTF("%s(%d): Could not map statistics block DMA memory!\n",
3122			__FILE__, __LINE__);
3123		rc = ENOMEM;
3124		goto bce_dma_alloc_exit;
3125	}
3126
3127	DBPRINT(sc, BCE_INFO, "%s(): stats_block_paddr = 0x%jX\n",
3128		__FUNCTION__, (uintmax_t) sc->stats_block_paddr);
3129
3130	/* BCM5709 uses host memory as cache for context memory. */
3131	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3132		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3133		sc->ctx_pages = 0x2000 / BCM_PAGE_SIZE;
3134		if (sc->ctx_pages == 0)
3135			sc->ctx_pages = 1;
3136
3137		DBRUNIF((sc->ctx_pages > 512),
3138			BCE_PRINTF("%s(%d): Too many CTX pages! %d > 512\n",
3139				__FILE__, __LINE__, sc->ctx_pages));
3140
3141		/*
3142		 * Create a DMA tag for the context pages,
3143		 * allocate and clear the memory, map the
3144		 * memory into DMA space, and fetch the
3145		 * physical address of the block.
3146		 */
3147		if(bus_dma_tag_create(sc->parent_tag,
3148			BCM_PAGE_SIZE,
3149		    BCE_DMA_BOUNDARY,
3150			sc->max_bus_addr,
3151			BUS_SPACE_MAXADDR,
3152			NULL, NULL,
3153			BCM_PAGE_SIZE,
3154			1,
3155			BCM_PAGE_SIZE,
3156			0,
3157			NULL, NULL,
3158			&sc->ctx_tag)) {
3159			BCE_PRINTF("%s(%d): Could not allocate CTX DMA tag!\n",
3160				__FILE__, __LINE__);
3161			rc = ENOMEM;
3162			goto bce_dma_alloc_exit;
3163		}
3164
3165		for (i = 0; i < sc->ctx_pages; i++) {
3166
3167			if(bus_dmamem_alloc(sc->ctx_tag,
3168		    		(void **)&sc->ctx_block[i],
3169	    		BUS_DMA_NOWAIT,
3170		    	&sc->ctx_map[i])) {
3171				BCE_PRINTF("%s(%d): Could not allocate CTX "
3172					"DMA memory!\n", __FILE__, __LINE__);
3173				rc = ENOMEM;
3174				goto bce_dma_alloc_exit;
3175			}
3176
3177			bzero((char *)sc->ctx_block[i], BCM_PAGE_SIZE);
3178
3179			error = bus_dmamap_load(sc->ctx_tag,
3180	    		sc->ctx_map[i],
3181	    		sc->ctx_block[i],
3182		    	BCM_PAGE_SIZE,
3183		    	bce_dma_map_addr,
3184	    		&sc->ctx_paddr[i],
3185	    		BUS_DMA_NOWAIT);
3186
3187			if (error) {
3188				BCE_PRINTF("%s(%d): Could not map CTX DMA memory!\n",
3189					__FILE__, __LINE__);
3190				rc = ENOMEM;
3191				goto bce_dma_alloc_exit;
3192			}
3193
3194			DBPRINT(sc, BCE_INFO, "%s(): ctx_paddr[%d] = 0x%jX\n",
3195				__FUNCTION__, i, (uintmax_t) sc->ctx_paddr[i]);
3196		}
3197	}
3198
3199	/*
3200	 * Create a DMA tag for the TX buffer descriptor chain,
3201	 * allocate and clear the  memory, and fetch the
3202	 * physical address of the block.
3203	 */
3204	if(bus_dma_tag_create(sc->parent_tag,
3205			BCM_PAGE_SIZE,
3206		    BCE_DMA_BOUNDARY,
3207			sc->max_bus_addr,
3208			BUS_SPACE_MAXADDR,
3209			NULL, NULL,
3210			BCE_TX_CHAIN_PAGE_SZ,
3211			1,
3212			BCE_TX_CHAIN_PAGE_SZ,
3213			0,
3214			NULL, NULL,
3215			&sc->tx_bd_chain_tag)) {
3216		BCE_PRINTF("%s(%d): Could not allocate TX descriptor chain DMA tag!\n",
3217			__FILE__, __LINE__);
3218		rc = ENOMEM;
3219		goto bce_dma_alloc_exit;
3220	}
3221
3222	for (i = 0; i < TX_PAGES; i++) {
3223
3224		if(bus_dmamem_alloc(sc->tx_bd_chain_tag,
3225	    		(void **)&sc->tx_bd_chain[i],
3226	    		BUS_DMA_NOWAIT,
3227		    	&sc->tx_bd_chain_map[i])) {
3228			BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
3229				"chain DMA memory!\n", __FILE__, __LINE__);
3230			rc = ENOMEM;
3231			goto bce_dma_alloc_exit;
3232		}
3233
3234		error = bus_dmamap_load(sc->tx_bd_chain_tag,
3235	    		sc->tx_bd_chain_map[i],
3236	    		sc->tx_bd_chain[i],
3237		    	BCE_TX_CHAIN_PAGE_SZ,
3238		    	bce_dma_map_addr,
3239	    		&sc->tx_bd_chain_paddr[i],
3240	    		BUS_DMA_NOWAIT);
3241
3242		if (error) {
3243			BCE_PRINTF("%s(%d): Could not map TX descriptor chain DMA memory!\n",
3244				__FILE__, __LINE__);
3245			rc = ENOMEM;
3246			goto bce_dma_alloc_exit;
3247		}
3248
3249		DBPRINT(sc, BCE_INFO, "%s(): tx_bd_chain_paddr[%d] = 0x%jX\n",
3250			__FUNCTION__, i, (uintmax_t) sc->tx_bd_chain_paddr[i]);
3251	}
3252
3253	/* Check the required size before mapping to conserve resources. */
3254	if (bce_tso_enable) {
3255		max_size     = BCE_TSO_MAX_SIZE;
3256		max_segments = BCE_MAX_SEGMENTS;
3257		max_seg_size = BCE_TSO_MAX_SEG_SIZE;
3258	} else {
3259		max_size     = MCLBYTES * BCE_MAX_SEGMENTS;
3260		max_segments = BCE_MAX_SEGMENTS;
3261		max_seg_size = MCLBYTES;
3262	}
3263
3264	/* Create a DMA tag for TX mbufs. */
3265	if (bus_dma_tag_create(sc->parent_tag,
3266			1,
3267			BCE_DMA_BOUNDARY,
3268			sc->max_bus_addr,
3269			BUS_SPACE_MAXADDR,
3270			NULL, NULL,
3271			max_size,
3272			max_segments,
3273			max_seg_size,
3274			0,
3275			NULL, NULL,
3276			&sc->tx_mbuf_tag)) {
3277		BCE_PRINTF("%s(%d): Could not allocate TX mbuf DMA tag!\n",
3278			__FILE__, __LINE__);
3279		rc = ENOMEM;
3280		goto bce_dma_alloc_exit;
3281	}
3282
3283	/* Create DMA maps for the TX mbufs clusters. */
3284	for (i = 0; i < TOTAL_TX_BD; i++) {
3285		if (bus_dmamap_create(sc->tx_mbuf_tag, BUS_DMA_NOWAIT,
3286			&sc->tx_mbuf_map[i])) {
3287			BCE_PRINTF("%s(%d): Unable to create TX mbuf DMA map!\n",
3288				__FILE__, __LINE__);
3289			rc = ENOMEM;
3290			goto bce_dma_alloc_exit;
3291		}
3292	}
3293
3294	/*
3295	 * Create a DMA tag for the RX buffer descriptor chain,
3296	 * allocate and clear the memory, and fetch the physical
3297	 * address of the blocks.
3298	 */
3299	if (bus_dma_tag_create(sc->parent_tag,
3300			BCM_PAGE_SIZE,
3301			BCE_DMA_BOUNDARY,
3302			BUS_SPACE_MAXADDR,
3303			sc->max_bus_addr,
3304			NULL, NULL,
3305			BCE_RX_CHAIN_PAGE_SZ,
3306			1,
3307			BCE_RX_CHAIN_PAGE_SZ,
3308			0,
3309			NULL, NULL,
3310			&sc->rx_bd_chain_tag)) {
3311		BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain DMA tag!\n",
3312			__FILE__, __LINE__);
3313		rc = ENOMEM;
3314		goto bce_dma_alloc_exit;
3315	}
3316
3317	for (i = 0; i < RX_PAGES; i++) {
3318
3319		if (bus_dmamem_alloc(sc->rx_bd_chain_tag,
3320	    		(void **)&sc->rx_bd_chain[i],
3321	    		BUS_DMA_NOWAIT,
3322		    	&sc->rx_bd_chain_map[i])) {
3323			BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain "
3324				"DMA memory!\n", __FILE__, __LINE__);
3325			rc = ENOMEM;
3326			goto bce_dma_alloc_exit;
3327		}
3328
3329		bzero((char *)sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ);
3330
3331		error = bus_dmamap_load(sc->rx_bd_chain_tag,
3332	    		sc->rx_bd_chain_map[i],
3333	    		sc->rx_bd_chain[i],
3334		    	BCE_RX_CHAIN_PAGE_SZ,
3335		    	bce_dma_map_addr,
3336	    		&sc->rx_bd_chain_paddr[i],
3337	    		BUS_DMA_NOWAIT);
3338
3339		if (error) {
3340			BCE_PRINTF("%s(%d): Could not map RX descriptor chain DMA memory!\n",
3341				__FILE__, __LINE__);
3342			rc = ENOMEM;
3343			goto bce_dma_alloc_exit;
3344		}
3345
3346		DBPRINT(sc, BCE_INFO, "%s(): rx_bd_chain_paddr[%d] = 0x%jX\n",
3347			__FUNCTION__, i, (uintmax_t) sc->rx_bd_chain_paddr[i]);
3348	}
3349
3350	/*
3351	 * Create a DMA tag for RX mbufs.
3352	 */
3353#ifdef BCE_JUMBO_HDRSPLIT
3354	max_size = max_seg_size = ((sc->rx_bd_mbuf_alloc_size < MCLBYTES) ?
3355		MCLBYTES : sc->rx_bd_mbuf_alloc_size);
3356#else
3357	max_size = max_seg_size = MJUM9BYTES;
3358#endif
3359	max_segments = 1;
3360
3361	DBPRINT(sc, BCE_INFO, "%s(): Creating rx_mbuf_tag (max size = 0x%jX "
3362		"max segments = %d, max segment size = 0x%jX)\n", __FUNCTION__,
3363		(uintmax_t) max_size, max_segments, (uintmax_t) max_seg_size);
3364
3365	if (bus_dma_tag_create(sc->parent_tag,
3366			1,
3367			BCE_DMA_BOUNDARY,
3368			sc->max_bus_addr,
3369			BUS_SPACE_MAXADDR,
3370			NULL, NULL,
3371			max_size,
3372			max_segments,
3373			max_seg_size,
3374			0,
3375			NULL, NULL,
3376	    	&sc->rx_mbuf_tag)) {
3377		BCE_PRINTF("%s(%d): Could not allocate RX mbuf DMA tag!\n",
3378			__FILE__, __LINE__);
3379		rc = ENOMEM;
3380		goto bce_dma_alloc_exit;
3381	}
3382
3383	/* Create DMA maps for the RX mbuf clusters. */
3384	for (i = 0; i < TOTAL_RX_BD; i++) {
3385		if (bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_NOWAIT,
3386				&sc->rx_mbuf_map[i])) {
3387			BCE_PRINTF("%s(%d): Unable to create RX mbuf DMA map!\n",
3388				__FILE__, __LINE__);
3389			rc = ENOMEM;
3390			goto bce_dma_alloc_exit;
3391		}
3392	}
3393
3394#ifdef BCE_JUMBO_HDRSPLIT
3395	/*
3396	 * Create a DMA tag for the page buffer descriptor chain,
3397	 * allocate and clear the memory, and fetch the physical
3398	 * address of the blocks.
3399	 */
3400	if (bus_dma_tag_create(sc->parent_tag,
3401			BCM_PAGE_SIZE,
3402			BCE_DMA_BOUNDARY,
3403			BUS_SPACE_MAXADDR,
3404			sc->max_bus_addr,
3405			NULL, NULL,
3406			BCE_PG_CHAIN_PAGE_SZ,
3407			1,
3408			BCE_PG_CHAIN_PAGE_SZ,
3409			0,
3410			NULL, NULL,
3411			&sc->pg_bd_chain_tag)) {
3412		BCE_PRINTF("%s(%d): Could not allocate page descriptor chain DMA tag!\n",
3413			__FILE__, __LINE__);
3414		rc = ENOMEM;
3415		goto bce_dma_alloc_exit;
3416	}
3417
3418	for (i = 0; i < PG_PAGES; i++) {
3419
3420		if (bus_dmamem_alloc(sc->pg_bd_chain_tag,
3421	    		(void **)&sc->pg_bd_chain[i],
3422	    		BUS_DMA_NOWAIT,
3423		    	&sc->pg_bd_chain_map[i])) {
3424			BCE_PRINTF("%s(%d): Could not allocate page descriptor chain "
3425				"DMA memory!\n", __FILE__, __LINE__);
3426			rc = ENOMEM;
3427			goto bce_dma_alloc_exit;
3428		}
3429
3430		bzero((char *)sc->pg_bd_chain[i], BCE_PG_CHAIN_PAGE_SZ);
3431
3432		error = bus_dmamap_load(sc->pg_bd_chain_tag,
3433	    		sc->pg_bd_chain_map[i],
3434	    		sc->pg_bd_chain[i],
3435		    	BCE_PG_CHAIN_PAGE_SZ,
3436		    	bce_dma_map_addr,
3437	    		&sc->pg_bd_chain_paddr[i],
3438	    		BUS_DMA_NOWAIT);
3439
3440		if (error) {
3441			BCE_PRINTF("%s(%d): Could not map page descriptor chain DMA memory!\n",
3442				__FILE__, __LINE__);
3443			rc = ENOMEM;
3444			goto bce_dma_alloc_exit;
3445		}
3446
3447		DBPRINT(sc, BCE_INFO, "%s(): pg_bd_chain_paddr[%d] = 0x%jX\n",
3448			__FUNCTION__, i, (uintmax_t) sc->pg_bd_chain_paddr[i]);
3449	}
3450
3451	/*
3452	 * Create a DMA tag for page mbufs.
3453	 */
3454	max_size = max_seg_size = ((sc->pg_bd_mbuf_alloc_size < MCLBYTES) ?
3455		MCLBYTES : sc->pg_bd_mbuf_alloc_size);
3456
3457	if (bus_dma_tag_create(sc->parent_tag,
3458			1,
3459			BCE_DMA_BOUNDARY,
3460			sc->max_bus_addr,
3461			BUS_SPACE_MAXADDR,
3462			NULL, NULL,
3463			max_size,
3464			1,
3465			max_seg_size,
3466			0,
3467			NULL, NULL,
3468	    	&sc->pg_mbuf_tag)) {
3469		BCE_PRINTF("%s(%d): Could not allocate page mbuf DMA tag!\n",
3470			__FILE__, __LINE__);
3471		rc = ENOMEM;
3472		goto bce_dma_alloc_exit;
3473	}
3474
3475	/* Create DMA maps for the page mbuf clusters. */
3476	for (i = 0; i < TOTAL_PG_BD; i++) {
3477		if (bus_dmamap_create(sc->pg_mbuf_tag, BUS_DMA_NOWAIT,
3478				&sc->pg_mbuf_map[i])) {
3479			BCE_PRINTF("%s(%d): Unable to create page mbuf DMA map!\n",
3480				__FILE__, __LINE__);
3481			rc = ENOMEM;
3482			goto bce_dma_alloc_exit;
3483		}
3484	}
3485#endif
3486
3487bce_dma_alloc_exit:
3488	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
3489	return(rc);
3490}
3491
3492
3493/****************************************************************************/
3494/* Release all resources used by the driver.                                */
3495/*                                                                          */
3496/* Releases all resources acquired by the driver including interrupts,      */
3497/* interrupt handler, interfaces, mutexes, and DMA memory.                  */
3498/*                                                                          */
3499/* Returns:                                                                 */
3500/*   Nothing.                                                               */
3501/****************************************************************************/
3502static void
3503bce_release_resources(struct bce_softc *sc)
3504{
3505	device_t dev;
3506
3507	DBENTER(BCE_VERBOSE_RESET);
3508
3509	dev = sc->bce_dev;
3510
3511	bce_dma_free(sc);
3512
3513	if (sc->bce_intrhand != NULL) {
3514		DBPRINT(sc, BCE_INFO_RESET, "Removing interrupt handler.\n");
3515		bus_teardown_intr(dev, sc->bce_res_irq, sc->bce_intrhand);
3516	}
3517
3518	if (sc->bce_res_irq != NULL) {
3519		DBPRINT(sc, BCE_INFO_RESET, "Releasing IRQ.\n");
3520		bus_release_resource(dev, SYS_RES_IRQ, sc->bce_irq_rid,
3521			sc->bce_res_irq);
3522	}
3523
3524	if (sc->bce_flags & (BCE_USING_MSI_FLAG | BCE_USING_MSIX_FLAG)) {
3525		DBPRINT(sc, BCE_INFO_RESET, "Releasing MSI/MSI-X vector.\n");
3526		pci_release_msi(dev);
3527	}
3528
3529	if (sc->bce_res_mem != NULL) {
3530		DBPRINT(sc, BCE_INFO_RESET, "Releasing PCI memory.\n");
3531		bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), sc->bce_res_mem);
3532	}
3533
3534	if (sc->bce_ifp != NULL) {
3535		DBPRINT(sc, BCE_INFO_RESET, "Releasing IF.\n");
3536		if_free(sc->bce_ifp);
3537	}
3538
3539	if (mtx_initialized(&sc->bce_mtx))
3540		BCE_LOCK_DESTROY(sc);
3541
3542	DBEXIT(BCE_VERBOSE_RESET);
3543}
3544
3545
3546/****************************************************************************/
3547/* Firmware synchronization.                                                */
3548/*                                                                          */
3549/* Before performing certain events such as a chip reset, synchronize with  */
3550/* the firmware first.                                                      */
3551/*                                                                          */
3552/* Returns:                                                                 */
3553/*   0 for success, positive value for failure.                             */
3554/****************************************************************************/
3555static int
3556bce_fw_sync(struct bce_softc *sc, u32 msg_data)
3557{
3558	int i, rc = 0;
3559	u32 val;
3560
3561	DBENTER(BCE_VERBOSE_RESET);
3562
3563	/* Don't waste any time if we've timed out before. */
3564	if (sc->bce_fw_timed_out) {
3565		rc = EBUSY;
3566		goto bce_fw_sync_exit;
3567	}
3568
3569	/* Increment the message sequence number. */
3570	sc->bce_fw_wr_seq++;
3571	msg_data |= sc->bce_fw_wr_seq;
3572
3573 	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "bce_fw_sync(): msg_data = 0x%08X\n",
3574 		msg_data);
3575
3576	/* Send the message to the bootcode driver mailbox. */
3577	bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
3578
3579	/* Wait for the bootcode to acknowledge the message. */
3580	for (i = 0; i < FW_ACK_TIME_OUT_MS; i++) {
3581		/* Check for a response in the bootcode firmware mailbox. */
3582		val = bce_shmem_rd(sc, BCE_FW_MB);
3583		if ((val & BCE_FW_MSG_ACK) == (msg_data & BCE_DRV_MSG_SEQ))
3584			break;
3585		DELAY(1000);
3586	}
3587
3588	/* If we've timed out, tell the bootcode that we've stopped waiting. */
3589	if (((val & BCE_FW_MSG_ACK) != (msg_data & BCE_DRV_MSG_SEQ)) &&
3590		((msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0)) {
3591
3592		BCE_PRINTF("%s(%d): Firmware synchronization timeout! "
3593			"msg_data = 0x%08X\n",
3594			__FILE__, __LINE__, msg_data);
3595
3596		msg_data &= ~BCE_DRV_MSG_CODE;
3597		msg_data |= BCE_DRV_MSG_CODE_FW_TIMEOUT;
3598
3599		bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
3600
3601		sc->bce_fw_timed_out = 1;
3602		rc = EBUSY;
3603	}
3604
3605bce_fw_sync_exit:
3606	DBEXIT(BCE_VERBOSE_RESET);
3607	return (rc);
3608}
3609
3610
3611/****************************************************************************/
3612/* Load Receive Virtual 2 Physical (RV2P) processor firmware.               */
3613/*                                                                          */
3614/* Returns:                                                                 */
3615/*   Nothing.                                                               */
3616/****************************************************************************/
3617static void
3618bce_load_rv2p_fw(struct bce_softc *sc, u32 *rv2p_code,
3619	u32 rv2p_code_len, u32 rv2p_proc)
3620{
3621	int i;
3622	u32 val;
3623
3624	DBENTER(BCE_VERBOSE_RESET);
3625
3626	/* Set the page size used by RV2P. */
3627	if (rv2p_proc == RV2P_PROC2) {
3628		BCE_RV2P_PROC2_CHG_MAX_BD_PAGE(USABLE_RX_BD_PER_PAGE);
3629	}
3630
3631	for (i = 0; i < rv2p_code_len; i += 8) {
3632		REG_WR(sc, BCE_RV2P_INSTR_HIGH, *rv2p_code);
3633		rv2p_code++;
3634		REG_WR(sc, BCE_RV2P_INSTR_LOW, *rv2p_code);
3635		rv2p_code++;
3636
3637		if (rv2p_proc == RV2P_PROC1) {
3638			val = (i / 8) | BCE_RV2P_PROC1_ADDR_CMD_RDWR;
3639			REG_WR(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
3640		}
3641		else {
3642			val = (i / 8) | BCE_RV2P_PROC2_ADDR_CMD_RDWR;
3643			REG_WR(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
3644		}
3645	}
3646
3647	/* Reset the processor, un-stall is done later. */
3648	if (rv2p_proc == RV2P_PROC1) {
3649		REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC1_RESET);
3650	}
3651	else {
3652		REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC2_RESET);
3653	}
3654
3655	DBEXIT(BCE_VERBOSE_RESET);
3656}
3657
3658
3659/****************************************************************************/
3660/* Load RISC processor firmware.                                            */
3661/*                                                                          */
3662/* Loads firmware from the file if_bcefw.h into the scratchpad memory       */
3663/* associated with a particular processor.                                  */
3664/*                                                                          */
3665/* Returns:                                                                 */
3666/*   Nothing.                                                               */
3667/****************************************************************************/
3668static void
3669bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
3670	struct fw_info *fw)
3671{
3672	u32 offset;
3673
3674	DBENTER(BCE_VERBOSE_RESET);
3675
3676    bce_halt_cpu(sc, cpu_reg);
3677
3678	/* Load the Text area. */
3679	offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
3680	if (fw->text) {
3681		int j;
3682
3683		for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
3684			REG_WR_IND(sc, offset, fw->text[j]);
3685	        }
3686	}
3687
3688	/* Load the Data area. */
3689	offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
3690	if (fw->data) {
3691		int j;
3692
3693		for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
3694			REG_WR_IND(sc, offset, fw->data[j]);
3695		}
3696	}
3697
3698	/* Load the SBSS area. */
3699	offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
3700	if (fw->sbss) {
3701		int j;
3702
3703		for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
3704			REG_WR_IND(sc, offset, fw->sbss[j]);
3705		}
3706	}
3707
3708	/* Load the BSS area. */
3709	offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
3710	if (fw->bss) {
3711		int j;
3712
3713		for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
3714			REG_WR_IND(sc, offset, fw->bss[j]);
3715		}
3716	}
3717
3718	/* Load the Read-Only area. */
3719	offset = cpu_reg->spad_base +
3720		(fw->rodata_addr - cpu_reg->mips_view_base);
3721	if (fw->rodata) {
3722		int j;
3723
3724		for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
3725			REG_WR_IND(sc, offset, fw->rodata[j]);
3726		}
3727	}
3728
3729    /* Clear the pre-fetch instruction and set the FW start address. */
3730    REG_WR_IND(sc, cpu_reg->inst, 0);
3731    REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
3732
3733	DBEXIT(BCE_VERBOSE_RESET);
3734}
3735
3736
3737/****************************************************************************/
3738/* Starts the RISC processor.                                               */
3739/*                                                                          */
3740/* Assumes the CPU starting address has already been set.                   */
3741/*                                                                          */
3742/* Returns:                                                                 */
3743/*   Nothing.                                                               */
3744/****************************************************************************/
3745static void
3746bce_start_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
3747{
3748	u32 val;
3749
3750	DBENTER(BCE_VERBOSE_RESET);
3751
3752	/* Start the CPU. */
3753	val = REG_RD_IND(sc, cpu_reg->mode);
3754	val &= ~cpu_reg->mode_value_halt;
3755	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
3756	REG_WR_IND(sc, cpu_reg->mode, val);
3757
3758	DBEXIT(BCE_VERBOSE_RESET);
3759}
3760
3761
3762/****************************************************************************/
3763/* Halts the RISC processor.                                                */
3764/*                                                                          */
3765/* Returns:                                                                 */
3766/*   Nothing.                                                               */
3767/****************************************************************************/
3768static void
3769bce_halt_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
3770{
3771	u32 val;
3772
3773	DBENTER(BCE_VERBOSE_RESET);
3774
3775    /* Halt the CPU. */
3776    val = REG_RD_IND(sc, cpu_reg->mode);
3777    val |= cpu_reg->mode_value_halt;
3778    REG_WR_IND(sc, cpu_reg->mode, val);
3779    REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
3780
3781	DBEXIT(BCE_VERBOSE_RESET);
3782}
3783
3784
3785/****************************************************************************/
3786/* Initialize the RX CPU.                                                   */
3787/*                                                                          */
3788/* Returns:                                                                 */
3789/*   Nothing.                                                               */
3790/****************************************************************************/
3791static void
3792bce_start_rxp_cpu(struct bce_softc *sc)
3793{
3794	struct cpu_reg cpu_reg;
3795
3796	DBENTER(BCE_VERBOSE_RESET);
3797
3798	cpu_reg.mode = BCE_RXP_CPU_MODE;
3799	cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
3800	cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
3801	cpu_reg.state = BCE_RXP_CPU_STATE;
3802	cpu_reg.state_value_clear = 0xffffff;
3803	cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
3804	cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
3805	cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
3806	cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
3807	cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
3808	cpu_reg.spad_base = BCE_RXP_SCRATCH;
3809	cpu_reg.mips_view_base = 0x8000000;
3810
3811	DBPRINT(sc, BCE_INFO_RESET, "Starting RX firmware.\n");
3812	bce_start_cpu(sc, &cpu_reg);
3813
3814	DBEXIT(BCE_VERBOSE_RESET);
3815}
3816
3817
3818/****************************************************************************/
3819/* Initialize the RX CPU.                                                   */
3820/*                                                                          */
3821/* Returns:                                                                 */
3822/*   Nothing.                                                               */
3823/****************************************************************************/
3824static void
3825bce_init_rxp_cpu(struct bce_softc *sc)
3826{
3827	struct cpu_reg cpu_reg;
3828	struct fw_info fw;
3829
3830	DBENTER(BCE_VERBOSE_RESET);
3831
3832	cpu_reg.mode = BCE_RXP_CPU_MODE;
3833	cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
3834	cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
3835	cpu_reg.state = BCE_RXP_CPU_STATE;
3836	cpu_reg.state_value_clear = 0xffffff;
3837	cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
3838	cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
3839	cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
3840	cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
3841	cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
3842	cpu_reg.spad_base = BCE_RXP_SCRATCH;
3843	cpu_reg.mips_view_base = 0x8000000;
3844
3845	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3846		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3847 		fw.ver_major = bce_RXP_b09FwReleaseMajor;
3848		fw.ver_minor = bce_RXP_b09FwReleaseMinor;
3849		fw.ver_fix = bce_RXP_b09FwReleaseFix;
3850		fw.start_addr = bce_RXP_b09FwStartAddr;
3851
3852		fw.text_addr = bce_RXP_b09FwTextAddr;
3853		fw.text_len = bce_RXP_b09FwTextLen;
3854		fw.text_index = 0;
3855		fw.text = bce_RXP_b09FwText;
3856
3857		fw.data_addr = bce_RXP_b09FwDataAddr;
3858		fw.data_len = bce_RXP_b09FwDataLen;
3859		fw.data_index = 0;
3860		fw.data = bce_RXP_b09FwData;
3861
3862		fw.sbss_addr = bce_RXP_b09FwSbssAddr;
3863		fw.sbss_len = bce_RXP_b09FwSbssLen;
3864		fw.sbss_index = 0;
3865		fw.sbss = bce_RXP_b09FwSbss;
3866
3867		fw.bss_addr = bce_RXP_b09FwBssAddr;
3868		fw.bss_len = bce_RXP_b09FwBssLen;
3869		fw.bss_index = 0;
3870		fw.bss = bce_RXP_b09FwBss;
3871
3872		fw.rodata_addr = bce_RXP_b09FwRodataAddr;
3873		fw.rodata_len = bce_RXP_b09FwRodataLen;
3874		fw.rodata_index = 0;
3875		fw.rodata = bce_RXP_b09FwRodata;
3876	} else {
3877		fw.ver_major = bce_RXP_b06FwReleaseMajor;
3878		fw.ver_minor = bce_RXP_b06FwReleaseMinor;
3879		fw.ver_fix = bce_RXP_b06FwReleaseFix;
3880		fw.start_addr = bce_RXP_b06FwStartAddr;
3881
3882		fw.text_addr = bce_RXP_b06FwTextAddr;
3883		fw.text_len = bce_RXP_b06FwTextLen;
3884		fw.text_index = 0;
3885		fw.text = bce_RXP_b06FwText;
3886
3887		fw.data_addr = bce_RXP_b06FwDataAddr;
3888		fw.data_len = bce_RXP_b06FwDataLen;
3889		fw.data_index = 0;
3890		fw.data = bce_RXP_b06FwData;
3891
3892		fw.sbss_addr = bce_RXP_b06FwSbssAddr;
3893		fw.sbss_len = bce_RXP_b06FwSbssLen;
3894		fw.sbss_index = 0;
3895		fw.sbss = bce_RXP_b06FwSbss;
3896
3897		fw.bss_addr = bce_RXP_b06FwBssAddr;
3898		fw.bss_len = bce_RXP_b06FwBssLen;
3899		fw.bss_index = 0;
3900		fw.bss = bce_RXP_b06FwBss;
3901
3902		fw.rodata_addr = bce_RXP_b06FwRodataAddr;
3903		fw.rodata_len = bce_RXP_b06FwRodataLen;
3904		fw.rodata_index = 0;
3905		fw.rodata = bce_RXP_b06FwRodata;
3906	}
3907
3908	DBPRINT(sc, BCE_INFO_RESET, "Loading RX firmware.\n");
3909	bce_load_cpu_fw(sc, &cpu_reg, &fw);
3910
3911    /* Delay RXP start until initialization is complete. */
3912
3913	DBEXIT(BCE_VERBOSE_RESET);
3914}
3915
3916
3917/****************************************************************************/
3918/* Initialize the TX CPU.                                                   */
3919/*                                                                          */
3920/* Returns:                                                                 */
3921/*   Nothing.                                                               */
3922/****************************************************************************/
3923static void
3924bce_init_txp_cpu(struct bce_softc *sc)
3925{
3926	struct cpu_reg cpu_reg;
3927	struct fw_info fw;
3928
3929	DBENTER(BCE_VERBOSE_RESET);
3930
3931	cpu_reg.mode = BCE_TXP_CPU_MODE;
3932	cpu_reg.mode_value_halt = BCE_TXP_CPU_MODE_SOFT_HALT;
3933	cpu_reg.mode_value_sstep = BCE_TXP_CPU_MODE_STEP_ENA;
3934	cpu_reg.state = BCE_TXP_CPU_STATE;
3935	cpu_reg.state_value_clear = 0xffffff;
3936	cpu_reg.gpr0 = BCE_TXP_CPU_REG_FILE;
3937	cpu_reg.evmask = BCE_TXP_CPU_EVENT_MASK;
3938	cpu_reg.pc = BCE_TXP_CPU_PROGRAM_COUNTER;
3939	cpu_reg.inst = BCE_TXP_CPU_INSTRUCTION;
3940	cpu_reg.bp = BCE_TXP_CPU_HW_BREAKPOINT;
3941	cpu_reg.spad_base = BCE_TXP_SCRATCH;
3942	cpu_reg.mips_view_base = 0x8000000;
3943
3944	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
3945		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
3946		fw.ver_major = bce_TXP_b09FwReleaseMajor;
3947		fw.ver_minor = bce_TXP_b09FwReleaseMinor;
3948		fw.ver_fix = bce_TXP_b09FwReleaseFix;
3949		fw.start_addr = bce_TXP_b09FwStartAddr;
3950
3951		fw.text_addr = bce_TXP_b09FwTextAddr;
3952		fw.text_len = bce_TXP_b09FwTextLen;
3953		fw.text_index = 0;
3954		fw.text = bce_TXP_b09FwText;
3955
3956		fw.data_addr = bce_TXP_b09FwDataAddr;
3957		fw.data_len = bce_TXP_b09FwDataLen;
3958		fw.data_index = 0;
3959		fw.data = bce_TXP_b09FwData;
3960
3961		fw.sbss_addr = bce_TXP_b09FwSbssAddr;
3962		fw.sbss_len = bce_TXP_b09FwSbssLen;
3963		fw.sbss_index = 0;
3964		fw.sbss = bce_TXP_b09FwSbss;
3965
3966		fw.bss_addr = bce_TXP_b09FwBssAddr;
3967		fw.bss_len = bce_TXP_b09FwBssLen;
3968		fw.bss_index = 0;
3969		fw.bss = bce_TXP_b09FwBss;
3970
3971		fw.rodata_addr = bce_TXP_b09FwRodataAddr;
3972		fw.rodata_len = bce_TXP_b09FwRodataLen;
3973		fw.rodata_index = 0;
3974		fw.rodata = bce_TXP_b09FwRodata;
3975	} else {
3976		fw.ver_major = bce_TXP_b06FwReleaseMajor;
3977		fw.ver_minor = bce_TXP_b06FwReleaseMinor;
3978		fw.ver_fix = bce_TXP_b06FwReleaseFix;
3979		fw.start_addr = bce_TXP_b06FwStartAddr;
3980
3981		fw.text_addr = bce_TXP_b06FwTextAddr;
3982		fw.text_len = bce_TXP_b06FwTextLen;
3983		fw.text_index = 0;
3984		fw.text = bce_TXP_b06FwText;
3985
3986		fw.data_addr = bce_TXP_b06FwDataAddr;
3987		fw.data_len = bce_TXP_b06FwDataLen;
3988		fw.data_index = 0;
3989		fw.data = bce_TXP_b06FwData;
3990
3991		fw.sbss_addr = bce_TXP_b06FwSbssAddr;
3992		fw.sbss_len = bce_TXP_b06FwSbssLen;
3993		fw.sbss_index = 0;
3994		fw.sbss = bce_TXP_b06FwSbss;
3995
3996		fw.bss_addr = bce_TXP_b06FwBssAddr;
3997		fw.bss_len = bce_TXP_b06FwBssLen;
3998		fw.bss_index = 0;
3999		fw.bss = bce_TXP_b06FwBss;
4000
4001		fw.rodata_addr = bce_TXP_b06FwRodataAddr;
4002		fw.rodata_len = bce_TXP_b06FwRodataLen;
4003		fw.rodata_index = 0;
4004		fw.rodata = bce_TXP_b06FwRodata;
4005	}
4006
4007	DBPRINT(sc, BCE_INFO_RESET, "Loading TX firmware.\n");
4008	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4009    bce_start_cpu(sc, &cpu_reg);
4010
4011	DBEXIT(BCE_VERBOSE_RESET);
4012}
4013
4014
4015/****************************************************************************/
4016/* Initialize the TPAT CPU.                                                 */
4017/*                                                                          */
4018/* Returns:                                                                 */
4019/*   Nothing.                                                               */
4020/****************************************************************************/
4021static void
4022bce_init_tpat_cpu(struct bce_softc *sc)
4023{
4024	struct cpu_reg cpu_reg;
4025	struct fw_info fw;
4026
4027	DBENTER(BCE_VERBOSE_RESET);
4028
4029	cpu_reg.mode = BCE_TPAT_CPU_MODE;
4030	cpu_reg.mode_value_halt = BCE_TPAT_CPU_MODE_SOFT_HALT;
4031	cpu_reg.mode_value_sstep = BCE_TPAT_CPU_MODE_STEP_ENA;
4032	cpu_reg.state = BCE_TPAT_CPU_STATE;
4033	cpu_reg.state_value_clear = 0xffffff;
4034	cpu_reg.gpr0 = BCE_TPAT_CPU_REG_FILE;
4035	cpu_reg.evmask = BCE_TPAT_CPU_EVENT_MASK;
4036	cpu_reg.pc = BCE_TPAT_CPU_PROGRAM_COUNTER;
4037	cpu_reg.inst = BCE_TPAT_CPU_INSTRUCTION;
4038	cpu_reg.bp = BCE_TPAT_CPU_HW_BREAKPOINT;
4039	cpu_reg.spad_base = BCE_TPAT_SCRATCH;
4040	cpu_reg.mips_view_base = 0x8000000;
4041
4042	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4043		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4044		fw.ver_major = bce_TPAT_b09FwReleaseMajor;
4045		fw.ver_minor = bce_TPAT_b09FwReleaseMinor;
4046		fw.ver_fix = bce_TPAT_b09FwReleaseFix;
4047		fw.start_addr = bce_TPAT_b09FwStartAddr;
4048
4049		fw.text_addr = bce_TPAT_b09FwTextAddr;
4050		fw.text_len = bce_TPAT_b09FwTextLen;
4051		fw.text_index = 0;
4052		fw.text = bce_TPAT_b09FwText;
4053
4054		fw.data_addr = bce_TPAT_b09FwDataAddr;
4055		fw.data_len = bce_TPAT_b09FwDataLen;
4056		fw.data_index = 0;
4057		fw.data = bce_TPAT_b09FwData;
4058
4059		fw.sbss_addr = bce_TPAT_b09FwSbssAddr;
4060		fw.sbss_len = bce_TPAT_b09FwSbssLen;
4061		fw.sbss_index = 0;
4062		fw.sbss = bce_TPAT_b09FwSbss;
4063
4064		fw.bss_addr = bce_TPAT_b09FwBssAddr;
4065		fw.bss_len = bce_TPAT_b09FwBssLen;
4066		fw.bss_index = 0;
4067		fw.bss = bce_TPAT_b09FwBss;
4068
4069		fw.rodata_addr = bce_TPAT_b09FwRodataAddr;
4070		fw.rodata_len = bce_TPAT_b09FwRodataLen;
4071		fw.rodata_index = 0;
4072		fw.rodata = bce_TPAT_b09FwRodata;
4073	} else {
4074		fw.ver_major = bce_TPAT_b06FwReleaseMajor;
4075		fw.ver_minor = bce_TPAT_b06FwReleaseMinor;
4076		fw.ver_fix = bce_TPAT_b06FwReleaseFix;
4077		fw.start_addr = bce_TPAT_b06FwStartAddr;
4078
4079		fw.text_addr = bce_TPAT_b06FwTextAddr;
4080		fw.text_len = bce_TPAT_b06FwTextLen;
4081		fw.text_index = 0;
4082		fw.text = bce_TPAT_b06FwText;
4083
4084		fw.data_addr = bce_TPAT_b06FwDataAddr;
4085		fw.data_len = bce_TPAT_b06FwDataLen;
4086		fw.data_index = 0;
4087		fw.data = bce_TPAT_b06FwData;
4088
4089		fw.sbss_addr = bce_TPAT_b06FwSbssAddr;
4090		fw.sbss_len = bce_TPAT_b06FwSbssLen;
4091		fw.sbss_index = 0;
4092		fw.sbss = bce_TPAT_b06FwSbss;
4093
4094		fw.bss_addr = bce_TPAT_b06FwBssAddr;
4095		fw.bss_len = bce_TPAT_b06FwBssLen;
4096		fw.bss_index = 0;
4097		fw.bss = bce_TPAT_b06FwBss;
4098
4099		fw.rodata_addr = bce_TPAT_b06FwRodataAddr;
4100		fw.rodata_len = bce_TPAT_b06FwRodataLen;
4101		fw.rodata_index = 0;
4102		fw.rodata = bce_TPAT_b06FwRodata;
4103	}
4104
4105	DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n");
4106	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4107    bce_start_cpu(sc, &cpu_reg);
4108
4109	DBEXIT(BCE_VERBOSE_RESET);
4110}
4111
4112
4113/****************************************************************************/
4114/* Initialize the CP CPU.                                                   */
4115/*                                                                          */
4116/* Returns:                                                                 */
4117/*   Nothing.                                                               */
4118/****************************************************************************/
4119static void
4120bce_init_cp_cpu(struct bce_softc *sc)
4121{
4122	struct cpu_reg cpu_reg;
4123	struct fw_info fw;
4124
4125	DBENTER(BCE_VERBOSE_RESET);
4126
4127	cpu_reg.mode = BCE_CP_CPU_MODE;
4128	cpu_reg.mode_value_halt = BCE_CP_CPU_MODE_SOFT_HALT;
4129	cpu_reg.mode_value_sstep = BCE_CP_CPU_MODE_STEP_ENA;
4130	cpu_reg.state = BCE_CP_CPU_STATE;
4131	cpu_reg.state_value_clear = 0xffffff;
4132	cpu_reg.gpr0 = BCE_CP_CPU_REG_FILE;
4133	cpu_reg.evmask = BCE_CP_CPU_EVENT_MASK;
4134	cpu_reg.pc = BCE_CP_CPU_PROGRAM_COUNTER;
4135	cpu_reg.inst = BCE_CP_CPU_INSTRUCTION;
4136	cpu_reg.bp = BCE_CP_CPU_HW_BREAKPOINT;
4137	cpu_reg.spad_base = BCE_CP_SCRATCH;
4138	cpu_reg.mips_view_base = 0x8000000;
4139
4140	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4141		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4142		fw.ver_major = bce_CP_b09FwReleaseMajor;
4143		fw.ver_minor = bce_CP_b09FwReleaseMinor;
4144		fw.ver_fix = bce_CP_b09FwReleaseFix;
4145		fw.start_addr = bce_CP_b09FwStartAddr;
4146
4147		fw.text_addr = bce_CP_b09FwTextAddr;
4148		fw.text_len = bce_CP_b09FwTextLen;
4149		fw.text_index = 0;
4150		fw.text = bce_CP_b09FwText;
4151
4152		fw.data_addr = bce_CP_b09FwDataAddr;
4153		fw.data_len = bce_CP_b09FwDataLen;
4154		fw.data_index = 0;
4155		fw.data = bce_CP_b09FwData;
4156
4157		fw.sbss_addr = bce_CP_b09FwSbssAddr;
4158		fw.sbss_len = bce_CP_b09FwSbssLen;
4159		fw.sbss_index = 0;
4160		fw.sbss = bce_CP_b09FwSbss;
4161
4162		fw.bss_addr = bce_CP_b09FwBssAddr;
4163		fw.bss_len = bce_CP_b09FwBssLen;
4164		fw.bss_index = 0;
4165		fw.bss = bce_CP_b09FwBss;
4166
4167		fw.rodata_addr = bce_CP_b09FwRodataAddr;
4168		fw.rodata_len = bce_CP_b09FwRodataLen;
4169		fw.rodata_index = 0;
4170		fw.rodata = bce_CP_b09FwRodata;
4171	} else {
4172		fw.ver_major = bce_CP_b06FwReleaseMajor;
4173		fw.ver_minor = bce_CP_b06FwReleaseMinor;
4174		fw.ver_fix = bce_CP_b06FwReleaseFix;
4175		fw.start_addr = bce_CP_b06FwStartAddr;
4176
4177		fw.text_addr = bce_CP_b06FwTextAddr;
4178		fw.text_len = bce_CP_b06FwTextLen;
4179		fw.text_index = 0;
4180		fw.text = bce_CP_b06FwText;
4181
4182		fw.data_addr = bce_CP_b06FwDataAddr;
4183		fw.data_len = bce_CP_b06FwDataLen;
4184		fw.data_index = 0;
4185		fw.data = bce_CP_b06FwData;
4186
4187		fw.sbss_addr = bce_CP_b06FwSbssAddr;
4188		fw.sbss_len = bce_CP_b06FwSbssLen;
4189		fw.sbss_index = 0;
4190		fw.sbss = bce_CP_b06FwSbss;
4191
4192		fw.bss_addr = bce_CP_b06FwBssAddr;
4193		fw.bss_len = bce_CP_b06FwBssLen;
4194		fw.bss_index = 0;
4195		fw.bss = bce_CP_b06FwBss;
4196
4197		fw.rodata_addr = bce_CP_b06FwRodataAddr;
4198		fw.rodata_len = bce_CP_b06FwRodataLen;
4199		fw.rodata_index = 0;
4200		fw.rodata = bce_CP_b06FwRodata;
4201	}
4202
4203	DBPRINT(sc, BCE_INFO_RESET, "Loading CP firmware.\n");
4204	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4205    bce_start_cpu(sc, &cpu_reg);
4206
4207	DBEXIT(BCE_VERBOSE_RESET);
4208}
4209
4210
4211/****************************************************************************/
4212/* Initialize the COM CPU.                                                 */
4213/*                                                                          */
4214/* Returns:                                                                 */
4215/*   Nothing.                                                               */
4216/****************************************************************************/
4217static void
4218bce_init_com_cpu(struct bce_softc *sc)
4219{
4220	struct cpu_reg cpu_reg;
4221	struct fw_info fw;
4222
4223	DBENTER(BCE_VERBOSE_RESET);
4224
4225	cpu_reg.mode = BCE_COM_CPU_MODE;
4226	cpu_reg.mode_value_halt = BCE_COM_CPU_MODE_SOFT_HALT;
4227	cpu_reg.mode_value_sstep = BCE_COM_CPU_MODE_STEP_ENA;
4228	cpu_reg.state = BCE_COM_CPU_STATE;
4229	cpu_reg.state_value_clear = 0xffffff;
4230	cpu_reg.gpr0 = BCE_COM_CPU_REG_FILE;
4231	cpu_reg.evmask = BCE_COM_CPU_EVENT_MASK;
4232	cpu_reg.pc = BCE_COM_CPU_PROGRAM_COUNTER;
4233	cpu_reg.inst = BCE_COM_CPU_INSTRUCTION;
4234	cpu_reg.bp = BCE_COM_CPU_HW_BREAKPOINT;
4235	cpu_reg.spad_base = BCE_COM_SCRATCH;
4236	cpu_reg.mips_view_base = 0x8000000;
4237
4238	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4239		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4240		fw.ver_major = bce_COM_b09FwReleaseMajor;
4241		fw.ver_minor = bce_COM_b09FwReleaseMinor;
4242		fw.ver_fix = bce_COM_b09FwReleaseFix;
4243		fw.start_addr = bce_COM_b09FwStartAddr;
4244
4245		fw.text_addr = bce_COM_b09FwTextAddr;
4246		fw.text_len = bce_COM_b09FwTextLen;
4247		fw.text_index = 0;
4248		fw.text = bce_COM_b09FwText;
4249
4250		fw.data_addr = bce_COM_b09FwDataAddr;
4251		fw.data_len = bce_COM_b09FwDataLen;
4252		fw.data_index = 0;
4253		fw.data = bce_COM_b09FwData;
4254
4255		fw.sbss_addr = bce_COM_b09FwSbssAddr;
4256		fw.sbss_len = bce_COM_b09FwSbssLen;
4257		fw.sbss_index = 0;
4258		fw.sbss = bce_COM_b09FwSbss;
4259
4260		fw.bss_addr = bce_COM_b09FwBssAddr;
4261		fw.bss_len = bce_COM_b09FwBssLen;
4262		fw.bss_index = 0;
4263		fw.bss = bce_COM_b09FwBss;
4264
4265		fw.rodata_addr = bce_COM_b09FwRodataAddr;
4266		fw.rodata_len = bce_COM_b09FwRodataLen;
4267		fw.rodata_index = 0;
4268		fw.rodata = bce_COM_b09FwRodata;
4269	} else {
4270		fw.ver_major = bce_COM_b06FwReleaseMajor;
4271		fw.ver_minor = bce_COM_b06FwReleaseMinor;
4272		fw.ver_fix = bce_COM_b06FwReleaseFix;
4273		fw.start_addr = bce_COM_b06FwStartAddr;
4274
4275		fw.text_addr = bce_COM_b06FwTextAddr;
4276		fw.text_len = bce_COM_b06FwTextLen;
4277		fw.text_index = 0;
4278		fw.text = bce_COM_b06FwText;
4279
4280		fw.data_addr = bce_COM_b06FwDataAddr;
4281		fw.data_len = bce_COM_b06FwDataLen;
4282		fw.data_index = 0;
4283		fw.data = bce_COM_b06FwData;
4284
4285		fw.sbss_addr = bce_COM_b06FwSbssAddr;
4286		fw.sbss_len = bce_COM_b06FwSbssLen;
4287		fw.sbss_index = 0;
4288		fw.sbss = bce_COM_b06FwSbss;
4289
4290		fw.bss_addr = bce_COM_b06FwBssAddr;
4291		fw.bss_len = bce_COM_b06FwBssLen;
4292		fw.bss_index = 0;
4293		fw.bss = bce_COM_b06FwBss;
4294
4295		fw.rodata_addr = bce_COM_b06FwRodataAddr;
4296		fw.rodata_len = bce_COM_b06FwRodataLen;
4297		fw.rodata_index = 0;
4298		fw.rodata = bce_COM_b06FwRodata;
4299	}
4300
4301	DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n");
4302	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4303    bce_start_cpu(sc, &cpu_reg);
4304
4305	DBEXIT(BCE_VERBOSE_RESET);
4306}
4307
4308
4309/****************************************************************************/
4310/* Initialize the RV2P, RX, TX, TPAT, COM, and CP CPUs.                     */
4311/*                                                                          */
4312/* Loads the firmware for each CPU and starts the CPU.                      */
4313/*                                                                          */
4314/* Returns:                                                                 */
4315/*   Nothing.                                                               */
4316/****************************************************************************/
4317static void
4318bce_init_cpus(struct bce_softc *sc)
4319{
4320	DBENTER(BCE_VERBOSE_RESET);
4321
4322	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4323		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4324
4325		if ((BCE_CHIP_REV(sc) == BCE_CHIP_REV_Ax)) {
4326			bce_load_rv2p_fw(sc, bce_xi90_rv2p_proc1,
4327				sizeof(bce_xi90_rv2p_proc1), RV2P_PROC1);
4328			bce_load_rv2p_fw(sc, bce_xi90_rv2p_proc2,
4329				sizeof(bce_xi90_rv2p_proc2), RV2P_PROC2);
4330		} else {
4331			bce_load_rv2p_fw(sc, bce_xi_rv2p_proc1,
4332				sizeof(bce_xi_rv2p_proc1), RV2P_PROC1);
4333			bce_load_rv2p_fw(sc, bce_xi_rv2p_proc2,
4334				sizeof(bce_xi_rv2p_proc2), RV2P_PROC2);
4335		}
4336
4337	} else {
4338		bce_load_rv2p_fw(sc, bce_rv2p_proc1,
4339			sizeof(bce_rv2p_proc1),	RV2P_PROC1);
4340		bce_load_rv2p_fw(sc, bce_rv2p_proc2,
4341			sizeof(bce_rv2p_proc2),	RV2P_PROC2);
4342	}
4343
4344	bce_init_rxp_cpu(sc);
4345	bce_init_txp_cpu(sc);
4346	bce_init_tpat_cpu(sc);
4347	bce_init_com_cpu(sc);
4348	bce_init_cp_cpu(sc);
4349
4350	DBEXIT(BCE_VERBOSE_RESET);
4351}
4352
4353
4354/****************************************************************************/
4355/* Initialize context memory.                                               */
4356/*                                                                          */
4357/* Clears the memory associated with each Context ID (CID).                 */
4358/*                                                                          */
4359/* Returns:                                                                 */
4360/*   Nothing.                                                               */
4361/****************************************************************************/
4362static void
4363bce_init_ctx(struct bce_softc *sc)
4364{
4365
4366	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
4367
4368	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4369		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4370		int i, retry_cnt = CTX_INIT_RETRY_COUNT;
4371		u32 val;
4372
4373		DBPRINT(sc, BCE_INFO_CTX, "Initializing 5709 context.\n");
4374
4375		/*
4376		 * BCM5709 context memory may be cached
4377		 * in host memory so prepare the host memory
4378		 * for access.
4379		 */
4380		val = BCE_CTX_COMMAND_ENABLED | BCE_CTX_COMMAND_MEM_INIT | (1 << 12);
4381		val |= (BCM_PAGE_BITS - 8) << 16;
4382		REG_WR(sc, BCE_CTX_COMMAND, val);
4383
4384		/* Wait for mem init command to complete. */
4385		for (i = 0; i < retry_cnt; i++) {
4386			val = REG_RD(sc, BCE_CTX_COMMAND);
4387			if (!(val & BCE_CTX_COMMAND_MEM_INIT))
4388				break;
4389			DELAY(2);
4390		}
4391
4392		/* ToDo: Consider returning an error here. */
4393		DBRUNIF((val & BCE_CTX_COMMAND_MEM_INIT),
4394			BCE_PRINTF("%s(): Context memory initialization failed!\n",
4395			__FUNCTION__));
4396
4397		for (i = 0; i < sc->ctx_pages; i++) {
4398			int j;
4399
4400			/* Set the physical address of the context memory cache. */
4401			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA0,
4402				BCE_ADDR_LO(sc->ctx_paddr[i] & 0xfffffff0) |
4403				BCE_CTX_HOST_PAGE_TBL_DATA0_VALID);
4404			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA1,
4405				BCE_ADDR_HI(sc->ctx_paddr[i]));
4406			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_CTRL, i |
4407				BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
4408
4409			/* Verify that the context memory write was successful. */
4410			for (j = 0; j < retry_cnt; j++) {
4411				val = REG_RD(sc, BCE_CTX_HOST_PAGE_TBL_CTRL);
4412				if ((val & BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) == 0)
4413					break;
4414				DELAY(5);
4415			}
4416
4417			/* ToDo: Consider returning an error here. */
4418			DBRUNIF((val & BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ),
4419				BCE_PRINTF("%s(): Failed to initialize context page %d!\n",
4420				__FUNCTION__, i));
4421		}
4422	} else {
4423		u32 vcid_addr, offset;
4424
4425		DBPRINT(sc, BCE_INFO, "Initializing 5706/5708 context.\n");
4426
4427		/*
4428		 * For the 5706/5708, context memory is local to
4429		 * the controller, so initialize the controller
4430		 * context memory.
4431		 */
4432
4433		vcid_addr = GET_CID_ADDR(96);
4434		while (vcid_addr) {
4435
4436			vcid_addr -= PHY_CTX_SIZE;
4437
4438			REG_WR(sc, BCE_CTX_VIRT_ADDR, 0);
4439			REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
4440
4441            for(offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
4442                CTX_WR(sc, 0x00, offset, 0);
4443            }
4444
4445			REG_WR(sc, BCE_CTX_VIRT_ADDR, vcid_addr);
4446			REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
4447		}
4448
4449	}
4450	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
4451}
4452
4453
4454/****************************************************************************/
4455/* Fetch the permanent MAC address of the controller.                       */
4456/*                                                                          */
4457/* Returns:                                                                 */
4458/*   Nothing.                                                               */
4459/****************************************************************************/
4460static void
4461bce_get_mac_addr(struct bce_softc *sc)
4462{
4463	u32 mac_lo = 0, mac_hi = 0;
4464
4465	DBENTER(BCE_VERBOSE_RESET);
4466	/*
4467	 * The NetXtreme II bootcode populates various NIC
4468	 * power-on and runtime configuration items in a
4469	 * shared memory area.  The factory configured MAC
4470	 * address is available from both NVRAM and the
4471	 * shared memory area so we'll read the value from
4472	 * shared memory for speed.
4473	 */
4474
4475	mac_hi = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_UPPER);
4476	mac_lo = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_LOWER);
4477
4478	if ((mac_lo == 0) && (mac_hi == 0)) {
4479		BCE_PRINTF("%s(%d): Invalid Ethernet address!\n",
4480			__FILE__, __LINE__);
4481	} else {
4482		sc->eaddr[0] = (u_char)(mac_hi >> 8);
4483		sc->eaddr[1] = (u_char)(mac_hi >> 0);
4484		sc->eaddr[2] = (u_char)(mac_lo >> 24);
4485		sc->eaddr[3] = (u_char)(mac_lo >> 16);
4486		sc->eaddr[4] = (u_char)(mac_lo >> 8);
4487		sc->eaddr[5] = (u_char)(mac_lo >> 0);
4488	}
4489
4490	DBPRINT(sc, BCE_INFO_MISC, "Permanent Ethernet address = %6D\n", sc->eaddr, ":");
4491	DBEXIT(BCE_VERBOSE_RESET);
4492}
4493
4494
4495/****************************************************************************/
4496/* Program the MAC address.                                                 */
4497/*                                                                          */
4498/* Returns:                                                                 */
4499/*   Nothing.                                                               */
4500/****************************************************************************/
4501static void
4502bce_set_mac_addr(struct bce_softc *sc)
4503{
4504	u32 val;
4505	u8 *mac_addr = sc->eaddr;
4506
4507	/* ToDo: Add support for setting multiple MAC addresses. */
4508
4509	DBENTER(BCE_VERBOSE_RESET);
4510	DBPRINT(sc, BCE_INFO_MISC, "Setting Ethernet address = %6D\n", sc->eaddr, ":");
4511
4512	val = (mac_addr[0] << 8) | mac_addr[1];
4513
4514	REG_WR(sc, BCE_EMAC_MAC_MATCH0, val);
4515
4516	val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
4517		(mac_addr[4] << 8) | mac_addr[5];
4518
4519	REG_WR(sc, BCE_EMAC_MAC_MATCH1, val);
4520
4521	DBEXIT(BCE_VERBOSE_RESET);
4522}
4523
4524
4525/****************************************************************************/
4526/* Stop the controller.                                                     */
4527/*                                                                          */
4528/* Returns:                                                                 */
4529/*   Nothing.                                                               */
4530/****************************************************************************/
4531static void
4532bce_stop(struct bce_softc *sc)
4533{
4534	struct ifnet *ifp;
4535	struct ifmedia_entry *ifm;
4536	struct mii_data *mii = NULL;
4537	int mtmp, itmp;
4538
4539	DBENTER(BCE_VERBOSE_RESET);
4540
4541	BCE_LOCK_ASSERT(sc);
4542
4543	ifp = sc->bce_ifp;
4544
4545	mii = device_get_softc(sc->bce_miibus);
4546
4547	callout_stop(&sc->bce_tick_callout);
4548
4549	/* Disable the transmit/receive blocks. */
4550	REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS, BCE_MISC_ENABLE_CLR_DEFAULT);
4551	REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
4552	DELAY(20);
4553
4554	bce_disable_intr(sc);
4555
4556	/* Free RX buffers. */
4557#ifdef BCE_JUMBO_HDRSPLIT
4558	bce_free_pg_chain(sc);
4559#endif
4560	bce_free_rx_chain(sc);
4561
4562	/* Free TX buffers. */
4563	bce_free_tx_chain(sc);
4564
4565	/*
4566	 * Isolate/power down the PHY, but leave the media selection
4567	 * unchanged so that things will be put back to normal when
4568	 * we bring the interface back up.
4569	 */
4570
4571	itmp = ifp->if_flags;
4572	ifp->if_flags |= IFF_UP;
4573
4574	/* If we are called from bce_detach(), mii is already NULL. */
4575	if (mii != NULL) {
4576		ifm = mii->mii_media.ifm_cur;
4577		mtmp = ifm->ifm_media;
4578		ifm->ifm_media = IFM_ETHER | IFM_NONE;
4579		mii_mediachg(mii);
4580		ifm->ifm_media = mtmp;
4581	}
4582
4583	ifp->if_flags = itmp;
4584	sc->watchdog_timer = 0;
4585
4586	sc->bce_link = 0;
4587
4588	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
4589
4590	DBEXIT(BCE_VERBOSE_RESET);
4591}
4592
4593
4594static int
4595bce_reset(struct bce_softc *sc, u32 reset_code)
4596{
4597	u32 val;
4598	int i, rc = 0;
4599
4600	DBENTER(BCE_VERBOSE_RESET);
4601
4602	DBPRINT(sc, BCE_VERBOSE_RESET, "%s(): reset_code = 0x%08X\n",
4603		__FUNCTION__, reset_code);
4604
4605	/* Wait for pending PCI transactions to complete. */
4606	REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS,
4607	       BCE_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
4608	       BCE_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
4609	       BCE_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
4610	       BCE_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
4611	val = REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
4612	DELAY(5);
4613
4614	/* Disable DMA */
4615	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4616		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4617		val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
4618		val &= ~BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
4619		REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
4620	}
4621
4622	/* Assume bootcode is running. */
4623	sc->bce_fw_timed_out = 0;
4624
4625	/* Give the firmware a chance to prepare for the reset. */
4626	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT0 | reset_code);
4627	if (rc)
4628		goto bce_reset_exit;
4629
4630	/* Set a firmware reminder that this is a soft reset. */
4631	bce_shmem_wr(sc, BCE_DRV_RESET_SIGNATURE, BCE_DRV_RESET_SIGNATURE_MAGIC);
4632
4633	/* Dummy read to force the chip to complete all current transactions. */
4634	val = REG_RD(sc, BCE_MISC_ID);
4635
4636	/* Chip reset. */
4637	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4638		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4639		REG_WR(sc, BCE_MISC_COMMAND, BCE_MISC_COMMAND_SW_RESET);
4640		REG_RD(sc, BCE_MISC_COMMAND);
4641		DELAY(5);
4642
4643		val = BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
4644		      BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
4645
4646		pci_write_config(sc->bce_dev, BCE_PCICFG_MISC_CONFIG, val, 4);
4647	} else {
4648		val = BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4649			BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
4650			BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
4651		REG_WR(sc, BCE_PCICFG_MISC_CONFIG, val);
4652
4653		/* Allow up to 30us for reset to complete. */
4654		for (i = 0; i < 10; i++) {
4655			val = REG_RD(sc, BCE_PCICFG_MISC_CONFIG);
4656			if ((val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4657				BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
4658				break;
4659			}
4660			DELAY(10);
4661		}
4662
4663		/* Check that reset completed successfully. */
4664		if (val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4665			BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
4666			BCE_PRINTF("%s(%d): Reset failed!\n",
4667				__FILE__, __LINE__);
4668			rc = EBUSY;
4669			goto bce_reset_exit;
4670		}
4671	}
4672
4673	/* Make sure byte swapping is properly configured. */
4674	val = REG_RD(sc, BCE_PCI_SWAP_DIAG0);
4675	if (val != 0x01020304) {
4676		BCE_PRINTF("%s(%d): Byte swap is incorrect!\n",
4677			__FILE__, __LINE__);
4678		rc = ENODEV;
4679		goto bce_reset_exit;
4680	}
4681
4682	/* Just completed a reset, assume that firmware is running again. */
4683	sc->bce_fw_timed_out = 0;
4684
4685	/* Wait for the firmware to finish its initialization. */
4686	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT1 | reset_code);
4687	if (rc)
4688		BCE_PRINTF("%s(%d): Firmware did not complete initialization!\n",
4689			__FILE__, __LINE__);
4690
4691bce_reset_exit:
4692	DBEXIT(BCE_VERBOSE_RESET);
4693	return (rc);
4694}
4695
4696
4697static int
4698bce_chipinit(struct bce_softc *sc)
4699{
4700	u32 val;
4701	int rc = 0;
4702
4703	DBENTER(BCE_VERBOSE_RESET);
4704
4705	bce_disable_intr(sc);
4706
4707	/*
4708	 * Initialize DMA byte/word swapping, configure the number of DMA
4709	 * channels and PCI clock compensation delay.
4710	 */
4711	val = BCE_DMA_CONFIG_DATA_BYTE_SWAP |
4712	      BCE_DMA_CONFIG_DATA_WORD_SWAP |
4713#if BYTE_ORDER == BIG_ENDIAN
4714	      BCE_DMA_CONFIG_CNTL_BYTE_SWAP |
4715#endif
4716	      BCE_DMA_CONFIG_CNTL_WORD_SWAP |
4717	      DMA_READ_CHANS << 12 |
4718	      DMA_WRITE_CHANS << 16;
4719
4720	val |= (0x2 << 20) | BCE_DMA_CONFIG_CNTL_PCI_COMP_DLY;
4721
4722	if ((sc->bce_flags & BCE_PCIX_FLAG) && (sc->bus_speed_mhz == 133))
4723		val |= BCE_DMA_CONFIG_PCI_FAST_CLK_CMP;
4724
4725	/*
4726	 * This setting resolves a problem observed on certain Intel PCI
4727	 * chipsets that cannot handle multiple outstanding DMA operations.
4728	 * See errata E9_5706A1_65.
4729	 */
4730	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
4731	    (BCE_CHIP_ID(sc) != BCE_CHIP_ID_5706_A0) &&
4732	    !(sc->bce_flags & BCE_PCIX_FLAG))
4733		val |= BCE_DMA_CONFIG_CNTL_PING_PONG_DMA;
4734
4735	REG_WR(sc, BCE_DMA_CONFIG, val);
4736
4737	/* Enable the RX_V2P and Context state machines before access. */
4738	REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
4739	       BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
4740	       BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
4741	       BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
4742
4743	/* Initialize context mapping and zero out the quick contexts. */
4744	bce_init_ctx(sc);
4745
4746	/* Initialize the on-boards CPUs */
4747	bce_init_cpus(sc);
4748
4749    /* Enable management frames (NC-SI) to flow to the MCP. */
4750    if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
4751        val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) | BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
4752        REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
4753    }
4754
4755	/* Prepare NVRAM for access. */
4756	if (bce_init_nvram(sc)) {
4757		rc = ENODEV;
4758		goto bce_chipinit_exit;
4759	}
4760
4761	/* Set the kernel bypass block size */
4762	val = REG_RD(sc, BCE_MQ_CONFIG);
4763	val &= ~BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE;
4764	val |= BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
4765
4766	/* Enable bins used on the 5709. */
4767	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4768		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4769		val |= BCE_MQ_CONFIG_BIN_MQ_MODE;
4770		if (BCE_CHIP_ID(sc) == BCE_CHIP_ID_5709_A1)
4771			val |= BCE_MQ_CONFIG_HALT_DIS;
4772	}
4773
4774	REG_WR(sc, BCE_MQ_CONFIG, val);
4775
4776	val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
4777	REG_WR(sc, BCE_MQ_KNL_BYP_WIND_START, val);
4778	REG_WR(sc, BCE_MQ_KNL_WIND_END, val);
4779
4780	/* Set the page size and clear the RV2P processor stall bits. */
4781	val = (BCM_PAGE_BITS - 8) << 24;
4782	REG_WR(sc, BCE_RV2P_CONFIG, val);
4783
4784	/* Configure page size. */
4785	val = REG_RD(sc, BCE_TBDR_CONFIG);
4786	val &= ~BCE_TBDR_CONFIG_PAGE_SIZE;
4787	val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
4788	REG_WR(sc, BCE_TBDR_CONFIG, val);
4789
4790	/* Set the perfect match control register to default. */
4791	REG_WR_IND(sc, BCE_RXP_PM_CTRL, 0);
4792
4793bce_chipinit_exit:
4794	DBEXIT(BCE_VERBOSE_RESET);
4795
4796	return(rc);
4797}
4798
4799
4800/****************************************************************************/
4801/* Initialize the controller in preparation to send/receive traffic.        */
4802/*                                                                          */
4803/* Returns:                                                                 */
4804/*   0 for success, positive value for failure.                             */
4805/****************************************************************************/
4806static int
4807bce_blockinit(struct bce_softc *sc)
4808{
4809	u32 reg, val;
4810	int rc = 0;
4811
4812	DBENTER(BCE_VERBOSE_RESET);
4813
4814	/* Load the hardware default MAC address. */
4815	bce_set_mac_addr(sc);
4816
4817	/* Set the Ethernet backoff seed value */
4818	val = sc->eaddr[0]         + (sc->eaddr[1] << 8) +
4819	      (sc->eaddr[2] << 16) + (sc->eaddr[3]     ) +
4820	      (sc->eaddr[4] << 8)  + (sc->eaddr[5] << 16);
4821	REG_WR(sc, BCE_EMAC_BACKOFF_SEED, val);
4822
4823	sc->last_status_idx = 0;
4824	sc->rx_mode = BCE_EMAC_RX_MODE_SORT_MODE;
4825
4826	/* Set up link change interrupt generation. */
4827	REG_WR(sc, BCE_EMAC_ATTENTION_ENA, BCE_EMAC_ATTENTION_ENA_LINK);
4828
4829	/* Program the physical address of the status block. */
4830	REG_WR(sc, BCE_HC_STATUS_ADDR_L,
4831		BCE_ADDR_LO(sc->status_block_paddr));
4832	REG_WR(sc, BCE_HC_STATUS_ADDR_H,
4833		BCE_ADDR_HI(sc->status_block_paddr));
4834
4835	/* Program the physical address of the statistics block. */
4836	REG_WR(sc, BCE_HC_STATISTICS_ADDR_L,
4837		BCE_ADDR_LO(sc->stats_block_paddr));
4838	REG_WR(sc, BCE_HC_STATISTICS_ADDR_H,
4839		BCE_ADDR_HI(sc->stats_block_paddr));
4840
4841	/* Program various host coalescing parameters. */
4842	REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
4843		(sc->bce_tx_quick_cons_trip_int << 16) | sc->bce_tx_quick_cons_trip);
4844	REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
4845		(sc->bce_rx_quick_cons_trip_int << 16) | sc->bce_rx_quick_cons_trip);
4846	REG_WR(sc, BCE_HC_COMP_PROD_TRIP,
4847		(sc->bce_comp_prod_trip_int << 16) | sc->bce_comp_prod_trip);
4848	REG_WR(sc, BCE_HC_TX_TICKS,
4849		(sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
4850	REG_WR(sc, BCE_HC_RX_TICKS,
4851		(sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
4852	REG_WR(sc, BCE_HC_COM_TICKS,
4853		(sc->bce_com_ticks_int << 16) | sc->bce_com_ticks);
4854	REG_WR(sc, BCE_HC_CMD_TICKS,
4855		(sc->bce_cmd_ticks_int << 16) | sc->bce_cmd_ticks);
4856	REG_WR(sc, BCE_HC_STATS_TICKS,
4857		(sc->bce_stats_ticks & 0xffff00));
4858	REG_WR(sc, BCE_HC_STAT_COLLECT_TICKS, 0xbb8);  /* 3ms */
4859
4860	/* Configure the Host Coalescing block. */
4861	val = BCE_HC_CONFIG_RX_TMR_MODE | BCE_HC_CONFIG_TX_TMR_MODE |
4862		      BCE_HC_CONFIG_COLLECT_STATS;
4863
4864#if 0
4865	/* ToDo: Add MSI-X support. */
4866	if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
4867		u32 base = ((BCE_TX_VEC - 1) * BCE_HC_SB_CONFIG_SIZE) +
4868			   BCE_HC_SB_CONFIG_1;
4869
4870		REG_WR(sc, BCE_HC_MSIX_BIT_VECTOR, BCE_HC_MSIX_BIT_VECTOR_VAL);
4871
4872		REG_WR(sc, base, BCE_HC_SB_CONFIG_1_TX_TMR_MODE |
4873			BCE_HC_SB_CONFIG_1_ONE_SHOT);
4874
4875		REG_WR(sc, base + BCE_HC_TX_QUICK_CONS_TRIP_OFF,
4876			(sc->tx_quick_cons_trip_int << 16) |
4877			 sc->tx_quick_cons_trip);
4878
4879		REG_WR(sc, base + BCE_HC_TX_TICKS_OFF,
4880			(sc->tx_ticks_int << 16) | sc->tx_ticks);
4881
4882		val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
4883	}
4884
4885	/*
4886	 * Tell the HC block to automatically set the
4887	 * INT_MASK bit after an MSI/MSI-X interrupt
4888	 * is generated so the driver doesn't have to.
4889	 */
4890	if (sc->bce_flags & BCE_ONE_SHOT_MSI_FLAG)
4891		val |= BCE_HC_CONFIG_ONE_SHOT;
4892
4893	/* Set the MSI-X status blocks to 128 byte boundaries. */
4894	if (sc->bce_flags & BCE_USING_MSIX_FLAG)
4895		val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
4896#endif
4897
4898	REG_WR(sc, BCE_HC_CONFIG, val);
4899
4900	/* Clear the internal statistics counters. */
4901	REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
4902
4903	/* Verify that bootcode is running. */
4904	reg = bce_shmem_rd(sc, BCE_DEV_INFO_SIGNATURE);
4905
4906	DBRUNIF(DB_RANDOMTRUE(bootcode_running_failure_sim_control),
4907		BCE_PRINTF("%s(%d): Simulating bootcode failure.\n",
4908			__FILE__, __LINE__);
4909		reg = 0);
4910
4911	if ((reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
4912	    BCE_DEV_INFO_SIGNATURE_MAGIC) {
4913		BCE_PRINTF("%s(%d): Bootcode not running! Found: 0x%08X, "
4914			"Expected: 08%08X\n", __FILE__, __LINE__,
4915			(reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK),
4916			BCE_DEV_INFO_SIGNATURE_MAGIC);
4917		rc = ENODEV;
4918		goto bce_blockinit_exit;
4919	}
4920
4921	/* Enable DMA */
4922	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
4923		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
4924		val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
4925		val |= BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
4926		REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
4927	}
4928
4929	/* Allow bootcode to apply any additional fixes before enabling MAC. */
4930	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 | BCE_DRV_MSG_CODE_RESET);
4931
4932	/* Enable link state change interrupt generation. */
4933	REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
4934
4935    /* Enable the RXP. */
4936    bce_start_rxp_cpu(sc);
4937
4938    /* Disable management frames (NC-SI) from flowing to the MCP. */
4939    if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
4940        val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) & ~BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
4941        REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
4942    }
4943
4944	/* Enable all remaining blocks in the MAC. */
4945	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)	||
4946		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
4947		REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT_XI);
4948	else
4949		REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT);
4950
4951	REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
4952	DELAY(20);
4953
4954	/* Save the current host coalescing block settings. */
4955	sc->hc_command = REG_RD(sc, BCE_HC_COMMAND);
4956
4957bce_blockinit_exit:
4958	DBEXIT(BCE_VERBOSE_RESET);
4959
4960	return (rc);
4961}
4962
4963
4964/****************************************************************************/
4965/* Encapsulate an mbuf into the rx_bd chain.                                */
4966/*                                                                          */
4967/* Returns:                                                                 */
4968/*   0 for success, positive value for failure.                             */
4969/****************************************************************************/
4970static int
4971bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
4972	u16 *chain_prod, u32 *prod_bseq)
4973{
4974	bus_dmamap_t map;
4975	bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
4976	struct mbuf *m_new = NULL;
4977	struct rx_bd *rxbd;
4978	int nsegs, error, rc = 0;
4979#ifdef BCE_DEBUG
4980	u16 debug_chain_prod = *chain_prod;
4981#endif
4982
4983	DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
4984
4985	/* Make sure the inputs are valid. */
4986	DBRUNIF((*chain_prod > MAX_RX_BD),
4987		BCE_PRINTF("%s(%d): RX producer out of range: 0x%04X > 0x%04X\n",
4988		__FILE__, __LINE__, *chain_prod, (u16) MAX_RX_BD));
4989
4990	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, chain_prod = 0x%04X, "
4991		"prod_bseq = 0x%08X\n", __FUNCTION__, *prod, *chain_prod, *prod_bseq);
4992
4993	/* Update some debug statistic counters */
4994	DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
4995		sc->rx_low_watermark = sc->free_rx_bd);
4996	DBRUNIF((sc->free_rx_bd == sc->max_rx_bd), sc->rx_empty_count++);
4997
4998	/* Check whether this is a new mbuf allocation. */
4999	if (m == NULL) {
5000
5001		/* Simulate an mbuf allocation failure. */
5002		DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
5003			sc->mbuf_alloc_failed_count++;
5004			sc->mbuf_alloc_failed_sim_count++;
5005			rc = ENOBUFS;
5006			goto bce_get_rx_buf_exit);
5007
5008		/* This is a new mbuf allocation. */
5009#ifdef BCE_JUMBO_HDRSPLIT
5010		MGETHDR(m_new, M_DONTWAIT, MT_DATA);
5011#else
5012		if (sc->rx_bd_mbuf_alloc_size <= MCLBYTES)
5013			m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
5014		else
5015			m_new = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, sc->rx_bd_mbuf_alloc_size);
5016#endif
5017
5018		if (m_new == NULL) {
5019			sc->mbuf_alloc_failed_count++;
5020			rc = ENOBUFS;
5021			goto bce_get_rx_buf_exit;
5022		}
5023
5024		DBRUN(sc->debug_rx_mbuf_alloc++);
5025	} else {
5026		/* Reuse an existing mbuf. */
5027		m_new = m;
5028	}
5029
5030	/* Make sure we have a valid packet header. */
5031	M_ASSERTPKTHDR(m_new);
5032
5033	/* Initialize the mbuf size and pad if necessary for alignment. */
5034	m_new->m_pkthdr.len = m_new->m_len = sc->rx_bd_mbuf_alloc_size;
5035	m_adj(m_new, sc->rx_bd_mbuf_align_pad);
5036
5037	/* ToDo: Consider calling m_fragment() to test error handling. */
5038
5039	/* Map the mbuf cluster into device memory. */
5040	map = sc->rx_mbuf_map[*chain_prod];
5041	error = bus_dmamap_load_mbuf_sg(sc->rx_mbuf_tag, map, m_new,
5042	    segs, &nsegs, BUS_DMA_NOWAIT);
5043
5044	/* Handle any mapping errors. */
5045	if (error) {
5046		BCE_PRINTF("%s(%d): Error mapping mbuf into RX chain (%d)!\n",
5047			__FILE__, __LINE__, error);
5048
5049		sc->dma_map_addr_rx_failed_count++;
5050		m_freem(m_new);
5051
5052		DBRUN(sc->debug_rx_mbuf_alloc--);
5053
5054		rc = ENOBUFS;
5055		goto bce_get_rx_buf_exit;
5056	}
5057
5058	/* All mbufs must map to a single segment. */
5059	KASSERT(nsegs == 1, ("%s(): Too many segments returned (%d)!",
5060		 __FUNCTION__, nsegs));
5061
5062	/* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREREAD) here? */
5063
5064	/* Setup the rx_bd for the segment. */
5065	rxbd = &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
5066
5067	rxbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(segs[0].ds_addr));
5068	rxbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(segs[0].ds_addr));
5069	rxbd->rx_bd_len       = htole32(segs[0].ds_len);
5070	rxbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
5071	*prod_bseq += segs[0].ds_len;
5072
5073	/* Save the mbuf and update our counter. */
5074	sc->rx_mbuf_ptr[*chain_prod] = m_new;
5075	sc->free_rx_bd -= nsegs;
5076
5077	DBRUNMSG(BCE_INSANE_RECV, bce_dump_rx_mbuf_chain(sc, debug_chain_prod,
5078		nsegs));
5079
5080	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, chain_prod = 0x%04X, "
5081		"prod_bseq = 0x%08X\n", __FUNCTION__, *prod, *chain_prod, *prod_bseq);
5082
5083bce_get_rx_buf_exit:
5084	DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5085
5086	return(rc);
5087}
5088
5089
5090#ifdef BCE_JUMBO_HDRSPLIT
5091/****************************************************************************/
5092/* Encapsulate an mbuf cluster into the page chain.                        */
5093/*                                                                          */
5094/* Returns:                                                                 */
5095/*   0 for success, positive value for failure.                             */
5096/****************************************************************************/
5097static int
5098bce_get_pg_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod,
5099	u16 *prod_idx)
5100{
5101	bus_dmamap_t map;
5102	bus_addr_t busaddr;
5103	struct mbuf *m_new = NULL;
5104	struct rx_bd *pgbd;
5105	int error, rc = 0;
5106#ifdef BCE_DEBUG
5107	u16 debug_prod_idx = *prod_idx;
5108#endif
5109
5110	DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5111
5112	/* Make sure the inputs are valid. */
5113	DBRUNIF((*prod_idx > MAX_PG_BD),
5114		BCE_PRINTF("%s(%d): page producer out of range: 0x%04X > 0x%04X\n",
5115		__FILE__, __LINE__, *prod_idx, (u16) MAX_PG_BD));
5116
5117	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
5118		"chain_prod = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
5119
5120	/* Update counters if we've hit a new low or run out of pages. */
5121	DBRUNIF((sc->free_pg_bd < sc->pg_low_watermark),
5122		sc->pg_low_watermark = sc->free_pg_bd);
5123	DBRUNIF((sc->free_pg_bd == sc->max_pg_bd), sc->pg_empty_count++);
5124
5125	/* Check whether this is a new mbuf allocation. */
5126	if (m == NULL) {
5127
5128		/* Simulate an mbuf allocation failure. */
5129		DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
5130			sc->mbuf_alloc_failed_count++;
5131			sc->mbuf_alloc_failed_sim_count++;
5132			rc = ENOBUFS;
5133			goto bce_get_pg_buf_exit);
5134
5135		/* This is a new mbuf allocation. */
5136		m_new = m_getcl(M_DONTWAIT, MT_DATA, 0);
5137		if (m_new == NULL) {
5138			sc->mbuf_alloc_failed_count++;
5139			rc = ENOBUFS;
5140			goto bce_get_pg_buf_exit;
5141		}
5142
5143		DBRUN(sc->debug_pg_mbuf_alloc++);
5144	} else {
5145		/* Reuse an existing mbuf. */
5146		m_new = m;
5147		m_new->m_data = m_new->m_ext.ext_buf;
5148	}
5149
5150	m_new->m_len = sc->pg_bd_mbuf_alloc_size;
5151
5152	/* ToDo: Consider calling m_fragment() to test error handling. */
5153
5154	/* Map the mbuf cluster into device memory. */
5155	map = sc->pg_mbuf_map[*prod_idx];
5156	error = bus_dmamap_load(sc->pg_mbuf_tag, map, mtod(m_new, void *),
5157	    sc->pg_bd_mbuf_alloc_size, bce_dma_map_addr, &busaddr, BUS_DMA_NOWAIT);
5158
5159	/* Handle any mapping errors. */
5160	if (error) {
5161		BCE_PRINTF("%s(%d): Error mapping mbuf into page chain!\n",
5162			__FILE__, __LINE__);
5163
5164		m_freem(m_new);
5165		DBRUN(sc->debug_pg_mbuf_alloc--);
5166
5167		rc = ENOBUFS;
5168		goto bce_get_pg_buf_exit;
5169	}
5170
5171	/* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREREAD) here? */
5172
5173	/*
5174	 * The page chain uses the same rx_bd data structure
5175	 * as the receive chain but doesn't require a byte sequence (bseq).
5176	 */
5177	pgbd = &sc->pg_bd_chain[PG_PAGE(*prod_idx)][PG_IDX(*prod_idx)];
5178
5179	pgbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(busaddr));
5180	pgbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(busaddr));
5181	pgbd->rx_bd_len       = htole32(sc->pg_bd_mbuf_alloc_size);
5182	pgbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
5183
5184	/* Save the mbuf and update our counter. */
5185	sc->pg_mbuf_ptr[*prod_idx] = m_new;
5186	sc->free_pg_bd--;
5187
5188	DBRUNMSG(BCE_INSANE_RECV, bce_dump_pg_mbuf_chain(sc, debug_prod_idx,
5189		1));
5190
5191	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
5192		"prod_idx = 0x%04X\n", __FUNCTION__, *prod, *prod_idx);
5193
5194bce_get_pg_buf_exit:
5195	DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5196
5197	return(rc);
5198}
5199#endif /* BCE_JUMBO_HDRSPLIT */
5200
5201/****************************************************************************/
5202/* Initialize the TX context memory.                                        */
5203/*                                                                          */
5204/* Returns:                                                                 */
5205/*   Nothing                                                                */
5206/****************************************************************************/
5207static void
5208bce_init_tx_context(struct bce_softc *sc)
5209{
5210	u32 val;
5211
5212	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
5213
5214	/* Initialize the context ID for an L2 TX chain. */
5215	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
5216		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
5217		/* Set the CID type to support an L2 connection. */
5218		val = BCE_L2CTX_TX_TYPE_TYPE_L2_XI | BCE_L2CTX_TX_TYPE_SIZE_L2_XI;
5219		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE_XI, val);
5220		val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2_XI | (8 << 16);
5221		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_CMD_TYPE_XI, val);
5222
5223		/* Point the hardware to the first page in the chain. */
5224		val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
5225		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_HI_XI, val);
5226		val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
5227		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_LO_XI, val);
5228	} else {
5229		/* Set the CID type to support an L2 connection. */
5230		val = BCE_L2CTX_TX_TYPE_TYPE_L2 | BCE_L2CTX_TX_TYPE_SIZE_L2;
5231		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE, val);
5232		val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2 | (8 << 16);
5233		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_CMD_TYPE, val);
5234
5235		/* Point the hardware to the first page in the chain. */
5236		val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
5237		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_HI, val);
5238		val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
5239		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TBDR_BHADDR_LO, val);
5240	}
5241
5242	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
5243}
5244
5245
5246/****************************************************************************/
5247/* Allocate memory and initialize the TX data structures.                   */
5248/*                                                                          */
5249/* Returns:                                                                 */
5250/*   0 for success, positive value for failure.                             */
5251/****************************************************************************/
5252static int
5253bce_init_tx_chain(struct bce_softc *sc)
5254{
5255	struct tx_bd *txbd;
5256	int i, rc = 0;
5257
5258	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
5259
5260	/* Set the initial TX producer/consumer indices. */
5261	sc->tx_prod        = 0;
5262	sc->tx_cons        = 0;
5263	sc->tx_prod_bseq   = 0;
5264	sc->used_tx_bd     = 0;
5265	sc->max_tx_bd      = USABLE_TX_BD;
5266	DBRUN(sc->tx_hi_watermark = USABLE_TX_BD);
5267	DBRUN(sc->tx_full_count = 0);
5268
5269	/*
5270	 * The NetXtreme II supports a linked-list structre called
5271	 * a Buffer Descriptor Chain (or BD chain).  A BD chain
5272	 * consists of a series of 1 or more chain pages, each of which
5273	 * consists of a fixed number of BD entries.
5274	 * The last BD entry on each page is a pointer to the next page
5275	 * in the chain, and the last pointer in the BD chain
5276	 * points back to the beginning of the chain.
5277	 */
5278
5279	/* Set the TX next pointer chain entries. */
5280	for (i = 0; i < TX_PAGES; i++) {
5281		int j;
5282
5283		txbd = &sc->tx_bd_chain[i][USABLE_TX_BD_PER_PAGE];
5284
5285		/* Check if we've reached the last page. */
5286		if (i == (TX_PAGES - 1))
5287			j = 0;
5288		else
5289			j = i + 1;
5290
5291		txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->tx_bd_chain_paddr[j]));
5292		txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->tx_bd_chain_paddr[j]));
5293	}
5294
5295	bce_init_tx_context(sc);
5296
5297	DBRUNMSG(BCE_INSANE_SEND, bce_dump_tx_chain(sc, 0, TOTAL_TX_BD));
5298	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
5299
5300	return(rc);
5301}
5302
5303
5304/****************************************************************************/
5305/* Free memory and clear the TX data structures.                            */
5306/*                                                                          */
5307/* Returns:                                                                 */
5308/*   Nothing.                                                               */
5309/****************************************************************************/
5310static void
5311bce_free_tx_chain(struct bce_softc *sc)
5312{
5313	int i;
5314
5315	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
5316
5317	/* Unmap, unload, and free any mbufs still in the TX mbuf chain. */
5318	for (i = 0; i < TOTAL_TX_BD; i++) {
5319		if (sc->tx_mbuf_ptr[i] != NULL) {
5320			if (sc->tx_mbuf_map[i] != NULL)
5321				bus_dmamap_sync(sc->tx_mbuf_tag, sc->tx_mbuf_map[i],
5322					BUS_DMASYNC_POSTWRITE);
5323			m_freem(sc->tx_mbuf_ptr[i]);
5324			sc->tx_mbuf_ptr[i] = NULL;
5325			DBRUN(sc->debug_tx_mbuf_alloc--);
5326		}
5327	}
5328
5329	/* Clear each TX chain page. */
5330	for (i = 0; i < TX_PAGES; i++)
5331		bzero((char *)sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ);
5332
5333	sc->used_tx_bd     = 0;
5334
5335	/* Check if we lost any mbufs in the process. */
5336	DBRUNIF((sc->debug_tx_mbuf_alloc),
5337		BCE_PRINTF("%s(%d): Memory leak! Lost %d mbufs "
5338			"from tx chain!\n",
5339			__FILE__, __LINE__, sc->debug_tx_mbuf_alloc));
5340
5341	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
5342}
5343
5344
5345/****************************************************************************/
5346/* Initialize the RX context memory.                                        */
5347/*                                                                          */
5348/* Returns:                                                                 */
5349/*   Nothing                                                                */
5350/****************************************************************************/
5351static void
5352bce_init_rx_context(struct bce_softc *sc)
5353{
5354	u32 val;
5355
5356	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
5357
5358	/* Initialize the type, size, and BD cache levels for the RX context. */
5359	val = BCE_L2CTX_RX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE |
5360		BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 |
5361		(0x02 << BCE_L2CTX_RX_BD_PRE_READ_SHIFT);
5362
5363	/*
5364	 * Set the level for generating pause frames
5365	 * when the number of available rx_bd's gets
5366	 * too low (the low watermark) and the level
5367	 * when pause frames can be stopped (the high
5368	 * watermark).
5369	 */
5370	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
5371		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
5372		u32 lo_water, hi_water;
5373
5374		lo_water = BCE_L2CTX_RX_LO_WATER_MARK_DEFAULT;
5375		hi_water = USABLE_RX_BD / 4;
5376
5377		lo_water /= BCE_L2CTX_RX_LO_WATER_MARK_SCALE;
5378		hi_water /= BCE_L2CTX_RX_HI_WATER_MARK_SCALE;
5379
5380		if (hi_water > 0xf)
5381			hi_water = 0xf;
5382		else if (hi_water == 0)
5383			lo_water = 0;
5384		val |= (lo_water << BCE_L2CTX_RX_LO_WATER_MARK_SHIFT) |
5385			(hi_water << BCE_L2CTX_RX_HI_WATER_MARK_SHIFT);
5386	}
5387
5388 	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_CTX_TYPE, val);
5389
5390	/* Setup the MQ BIN mapping for l2_ctx_host_bseq. */
5391	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
5392		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
5393		val = REG_RD(sc, BCE_MQ_MAP_L2_5);
5394		REG_WR(sc, BCE_MQ_MAP_L2_5, val | BCE_MQ_MAP_L2_5_ARM);
5395	}
5396
5397	/* Point the hardware to the first page in the chain. */
5398	val = BCE_ADDR_HI(sc->rx_bd_chain_paddr[0]);
5399	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_HI, val);
5400	val = BCE_ADDR_LO(sc->rx_bd_chain_paddr[0]);
5401	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_LO, val);
5402
5403	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
5404}
5405
5406
5407/****************************************************************************/
5408/* Allocate memory and initialize the RX data structures.                   */
5409/*                                                                          */
5410/* Returns:                                                                 */
5411/*   0 for success, positive value for failure.                             */
5412/****************************************************************************/
5413static int
5414bce_init_rx_chain(struct bce_softc *sc)
5415{
5416	struct rx_bd *rxbd;
5417	int i, rc = 0;
5418
5419	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5420		BCE_VERBOSE_CTX);
5421
5422	/* Initialize the RX producer and consumer indices. */
5423	sc->rx_prod        = 0;
5424	sc->rx_cons        = 0;
5425	sc->rx_prod_bseq   = 0;
5426	sc->free_rx_bd     = USABLE_RX_BD;
5427	sc->max_rx_bd      = USABLE_RX_BD;
5428	DBRUN(sc->rx_low_watermark = sc->max_rx_bd);
5429	DBRUN(sc->rx_empty_count = 0);
5430
5431	/* Initialize the RX next pointer chain entries. */
5432	for (i = 0; i < RX_PAGES; i++) {
5433		int j;
5434
5435		rxbd = &sc->rx_bd_chain[i][USABLE_RX_BD_PER_PAGE];
5436
5437		/* Check if we've reached the last page. */
5438		if (i == (RX_PAGES - 1))
5439			j = 0;
5440		else
5441			j = i + 1;
5442
5443		/* Setup the chain page pointers. */
5444		rxbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j]));
5445		rxbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j]));
5446	}
5447
5448	/* Fill up the RX chain. */
5449	bce_fill_rx_chain(sc);
5450
5451	for (i = 0; i < RX_PAGES; i++) {
5452		bus_dmamap_sync(sc->rx_bd_chain_tag, sc->rx_bd_chain_map[i],
5453		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
5454	}
5455
5456	bce_init_rx_context(sc);
5457
5458	DBRUNMSG(BCE_EXTREME_RECV, bce_dump_rx_chain(sc, 0, TOTAL_RX_BD));
5459	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5460		BCE_VERBOSE_CTX);
5461	/* ToDo: Are there possible failure modes here? */
5462	return(rc);
5463}
5464
5465
5466/****************************************************************************/
5467/* Add mbufs to the RX chain until its full or an mbuf allocation error     */
5468/* occurs.                                                                  */
5469/*                                                                          */
5470/* Returns:                                                                 */
5471/*   Nothing                                                                */
5472/****************************************************************************/
5473static void
5474bce_fill_rx_chain(struct bce_softc *sc)
5475{
5476	u16 prod, prod_idx;
5477	u32 prod_bseq;
5478
5479	DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5480		BCE_VERBOSE_CTX);
5481
5482	/* Get the RX chain producer indices. */
5483	prod      = sc->rx_prod;
5484	prod_bseq = sc->rx_prod_bseq;
5485
5486	/* Keep filling the RX chain until it's full. */
5487	while (sc->free_rx_bd > 0) {
5488		prod_idx = RX_CHAIN_IDX(prod);
5489		if (bce_get_rx_buf(sc, NULL, &prod, &prod_idx, &prod_bseq)) {
5490			/* Bail out if we can't add an mbuf to the chain. */
5491			break;
5492		}
5493		prod = NEXT_RX_BD(prod);
5494	}
5495
5496	/* Save the RX chain producer indices. */
5497	sc->rx_prod      = prod;
5498	sc->rx_prod_bseq = prod_bseq;
5499
5500	DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
5501		BCE_PRINTF("%s(): Invalid rx_prod value: 0x%04X\n",
5502		__FUNCTION__, sc->rx_prod));
5503
5504	/* Write the mailbox and tell the chip about the waiting rx_bd's. */
5505	REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BDIDX,
5506		sc->rx_prod);
5507	REG_WR(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BSEQ,
5508		sc->rx_prod_bseq);
5509
5510	DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5511		BCE_VERBOSE_CTX);
5512}
5513
5514
5515/****************************************************************************/
5516/* Free memory and clear the RX data structures.                            */
5517/*                                                                          */
5518/* Returns:                                                                 */
5519/*   Nothing.                                                               */
5520/****************************************************************************/
5521static void
5522bce_free_rx_chain(struct bce_softc *sc)
5523{
5524	int i;
5525
5526	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5527
5528	/* Free any mbufs still in the RX mbuf chain. */
5529	for (i = 0; i < TOTAL_RX_BD; i++) {
5530		if (sc->rx_mbuf_ptr[i] != NULL) {
5531			if (sc->rx_mbuf_map[i] != NULL)
5532				bus_dmamap_sync(sc->rx_mbuf_tag, sc->rx_mbuf_map[i],
5533					BUS_DMASYNC_POSTREAD);
5534			m_freem(sc->rx_mbuf_ptr[i]);
5535			sc->rx_mbuf_ptr[i] = NULL;
5536			DBRUN(sc->debug_rx_mbuf_alloc--);
5537		}
5538	}
5539
5540	/* Clear each RX chain page. */
5541	for (i = 0; i < RX_PAGES; i++)
5542		bzero((char *)sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ);
5543
5544	sc->free_rx_bd = sc->max_rx_bd;
5545
5546	/* Check if we lost any mbufs in the process. */
5547	DBRUNIF((sc->debug_rx_mbuf_alloc),
5548		BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from rx chain!\n",
5549			__FUNCTION__, sc->debug_rx_mbuf_alloc));
5550
5551	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5552}
5553
5554
5555#ifdef BCE_JUMBO_HDRSPLIT
5556/****************************************************************************/
5557/* Allocate memory and initialize the page data structures.                 */
5558/* Assumes that bce_init_rx_chain() has not already been called.            */
5559/*                                                                          */
5560/* Returns:                                                                 */
5561/*   0 for success, positive value for failure.                             */
5562/****************************************************************************/
5563static int
5564bce_init_pg_chain(struct bce_softc *sc)
5565{
5566	struct rx_bd *pgbd;
5567	int i, rc = 0;
5568	u32 val;
5569
5570	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5571		BCE_VERBOSE_CTX);
5572
5573	/* Initialize the page producer and consumer indices. */
5574	sc->pg_prod        = 0;
5575	sc->pg_cons        = 0;
5576	sc->free_pg_bd     = USABLE_PG_BD;
5577	sc->max_pg_bd      = USABLE_PG_BD;
5578	DBRUN(sc->pg_low_watermark = sc->max_pg_bd);
5579	DBRUN(sc->pg_empty_count = 0);
5580
5581	/* Initialize the page next pointer chain entries. */
5582	for (i = 0; i < PG_PAGES; i++) {
5583		int j;
5584
5585		pgbd = &sc->pg_bd_chain[i][USABLE_PG_BD_PER_PAGE];
5586
5587		/* Check if we've reached the last page. */
5588		if (i == (PG_PAGES - 1))
5589			j = 0;
5590		else
5591			j = i + 1;
5592
5593		/* Setup the chain page pointers. */
5594		pgbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->pg_bd_chain_paddr[j]));
5595		pgbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->pg_bd_chain_paddr[j]));
5596	}
5597
5598	/* Setup the MQ BIN mapping for host_pg_bidx. */
5599	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)	||
5600		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
5601		REG_WR(sc, BCE_MQ_MAP_L2_3, BCE_MQ_MAP_L2_3_DEFAULT);
5602
5603	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, 0);
5604
5605	/* Configure the rx_bd and page chain mbuf cluster size. */
5606	val = (sc->rx_bd_mbuf_data_len << 16) | sc->pg_bd_mbuf_alloc_size;
5607	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, val);
5608
5609	/* Configure the context reserved for jumbo support. */
5610	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_RBDC_KEY,
5611		BCE_L2CTX_RX_RBDC_JUMBO_KEY);
5612
5613	/* Point the hardware to the first page in the page chain. */
5614	val = BCE_ADDR_HI(sc->pg_bd_chain_paddr[0]);
5615	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_HI, val);
5616	val = BCE_ADDR_LO(sc->pg_bd_chain_paddr[0]);
5617	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_LO, val);
5618
5619	/* Fill up the page chain. */
5620	bce_fill_pg_chain(sc);
5621
5622	for (i = 0; i < PG_PAGES; i++) {
5623		bus_dmamap_sync(sc->pg_bd_chain_tag, sc->pg_bd_chain_map[i],
5624		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
5625	}
5626
5627	DBRUNMSG(BCE_EXTREME_RECV, bce_dump_pg_chain(sc, 0, TOTAL_PG_BD));
5628	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5629		BCE_VERBOSE_CTX);
5630	return(rc);
5631}
5632
5633
5634/****************************************************************************/
5635/* Add mbufs to the page chain until its full or an mbuf allocation error   */
5636/* occurs.                                                                  */
5637/*                                                                          */
5638/* Returns:                                                                 */
5639/*   Nothing                                                                */
5640/****************************************************************************/
5641static void
5642bce_fill_pg_chain(struct bce_softc *sc)
5643{
5644	u16 prod, prod_idx;
5645
5646	DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5647		BCE_VERBOSE_CTX);
5648
5649	/* Get the page chain prodcuer index. */
5650	prod = sc->pg_prod;
5651
5652	/* Keep filling the page chain until it's full. */
5653	while (sc->free_pg_bd > 0) {
5654		prod_idx = PG_CHAIN_IDX(prod);
5655		if (bce_get_pg_buf(sc, NULL, &prod, &prod_idx)) {
5656			/* Bail out if we can't add an mbuf to the chain. */
5657			break;
5658		}
5659		prod = NEXT_PG_BD(prod);
5660	}
5661
5662	/* Save the page chain producer index. */
5663	sc->pg_prod = prod;
5664
5665	DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
5666		BCE_PRINTF("%s(): Invalid pg_prod value: 0x%04X\n",
5667		__FUNCTION__, sc->pg_prod));
5668
5669	/*
5670	 * Write the mailbox and tell the chip about
5671	 * the new rx_bd's in the page chain.
5672	 */
5673	REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_PG_BDIDX,
5674		sc->pg_prod);
5675
5676	DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5677		BCE_VERBOSE_CTX);
5678}
5679
5680
5681/****************************************************************************/
5682/* Free memory and clear the RX data structures.                            */
5683/*                                                                          */
5684/* Returns:                                                                 */
5685/*   Nothing.                                                               */
5686/****************************************************************************/
5687static void
5688bce_free_pg_chain(struct bce_softc *sc)
5689{
5690	int i;
5691
5692	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5693
5694	/* Free any mbufs still in the mbuf page chain. */
5695	for (i = 0; i < TOTAL_PG_BD; i++) {
5696		if (sc->pg_mbuf_ptr[i] != NULL) {
5697			if (sc->pg_mbuf_map[i] != NULL)
5698				bus_dmamap_sync(sc->pg_mbuf_tag, sc->pg_mbuf_map[i],
5699					BUS_DMASYNC_POSTREAD);
5700			m_freem(sc->pg_mbuf_ptr[i]);
5701			sc->pg_mbuf_ptr[i] = NULL;
5702			DBRUN(sc->debug_pg_mbuf_alloc--);
5703		}
5704	}
5705
5706	/* Clear each page chain pages. */
5707	for (i = 0; i < PG_PAGES; i++)
5708		bzero((char *)sc->pg_bd_chain[i], BCE_PG_CHAIN_PAGE_SZ);
5709
5710	sc->free_pg_bd = sc->max_pg_bd;
5711
5712	/* Check if we lost any mbufs in the process. */
5713	DBRUNIF((sc->debug_pg_mbuf_alloc),
5714		BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from page chain!\n",
5715			__FUNCTION__, sc->debug_pg_mbuf_alloc));
5716
5717	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5718}
5719#endif /* BCE_JUMBO_HDRSPLIT */
5720
5721
5722/****************************************************************************/
5723/* Set media options.                                                       */
5724/*                                                                          */
5725/* Returns:                                                                 */
5726/*   0 for success, positive value for failure.                             */
5727/****************************************************************************/
5728static int
5729bce_ifmedia_upd(struct ifnet *ifp)
5730{
5731	struct bce_softc *sc = ifp->if_softc;
5732
5733	DBENTER(BCE_VERBOSE);
5734
5735	BCE_LOCK(sc);
5736	bce_ifmedia_upd_locked(ifp);
5737	BCE_UNLOCK(sc);
5738
5739	DBEXIT(BCE_VERBOSE);
5740	return (0);
5741}
5742
5743
5744/****************************************************************************/
5745/* Set media options.                                                       */
5746/*                                                                          */
5747/* Returns:                                                                 */
5748/*   Nothing.                                                               */
5749/****************************************************************************/
5750static void
5751bce_ifmedia_upd_locked(struct ifnet *ifp)
5752{
5753	struct bce_softc *sc = ifp->if_softc;
5754	struct mii_data *mii;
5755
5756	DBENTER(BCE_VERBOSE);
5757
5758	BCE_LOCK_ASSERT(sc);
5759
5760	mii = device_get_softc(sc->bce_miibus);
5761
5762	/* Make sure the MII bus has been enumerated. */
5763	if (mii) {
5764		sc->bce_link = 0;
5765		if (mii->mii_instance) {
5766			struct mii_softc *miisc;
5767
5768			LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
5769				mii_phy_reset(miisc);
5770		}
5771		mii_mediachg(mii);
5772	}
5773
5774	DBEXIT(BCE_VERBOSE);
5775}
5776
5777
5778/****************************************************************************/
5779/* Reports current media status.                                            */
5780/*                                                                          */
5781/* Returns:                                                                 */
5782/*   Nothing.                                                               */
5783/****************************************************************************/
5784static void
5785bce_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
5786{
5787	struct bce_softc *sc = ifp->if_softc;
5788	struct mii_data *mii;
5789
5790	DBENTER(BCE_VERBOSE);
5791
5792	BCE_LOCK(sc);
5793
5794	mii = device_get_softc(sc->bce_miibus);
5795
5796	mii_pollstat(mii);
5797	ifmr->ifm_active = mii->mii_media_active;
5798	ifmr->ifm_status = mii->mii_media_status;
5799
5800	BCE_UNLOCK(sc);
5801
5802	DBEXIT(BCE_VERBOSE);
5803}
5804
5805
5806/****************************************************************************/
5807/* Handles PHY generated interrupt events.                                  */
5808/*                                                                          */
5809/* Returns:                                                                 */
5810/*   Nothing.                                                               */
5811/****************************************************************************/
5812static void
5813bce_phy_intr(struct bce_softc *sc)
5814{
5815	u32 new_link_state, old_link_state;
5816
5817	DBENTER(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
5818
5819	new_link_state = sc->status_block->status_attn_bits &
5820		STATUS_ATTN_BITS_LINK_STATE;
5821	old_link_state = sc->status_block->status_attn_bits_ack &
5822		STATUS_ATTN_BITS_LINK_STATE;
5823
5824	/* Handle any changes if the link state has changed. */
5825	if (new_link_state != old_link_state) {
5826
5827		/* Update the status_attn_bits_ack field in the status block. */
5828		if (new_link_state) {
5829			REG_WR(sc, BCE_PCICFG_STATUS_BIT_SET_CMD,
5830				STATUS_ATTN_BITS_LINK_STATE);
5831			DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now UP.\n",
5832				__FUNCTION__);
5833		}
5834		else {
5835			REG_WR(sc, BCE_PCICFG_STATUS_BIT_CLEAR_CMD,
5836				STATUS_ATTN_BITS_LINK_STATE);
5837			DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now DOWN.\n",
5838				__FUNCTION__);
5839		}
5840
5841		/*
5842		 * Assume link is down and allow
5843		 * tick routine to update the state
5844		 * based on the actual media state.
5845		 */
5846		sc->bce_link = 0;
5847		callout_stop(&sc->bce_tick_callout);
5848		bce_tick(sc);
5849	}
5850
5851	/* Acknowledge the link change interrupt. */
5852	REG_WR(sc, BCE_EMAC_STATUS, BCE_EMAC_STATUS_LINK_CHANGE);
5853
5854	DBEXIT(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
5855}
5856
5857
5858/****************************************************************************/
5859/* Reads the receive consumer value from the status block (skipping over    */
5860/* chain page pointer if necessary).                                        */
5861/*                                                                          */
5862/* Returns:                                                                 */
5863/*   hw_cons                                                                */
5864/****************************************************************************/
5865static inline u16
5866bce_get_hw_rx_cons(struct bce_softc *sc)
5867{
5868	u16 hw_cons;
5869
5870	rmb();
5871	hw_cons = sc->status_block->status_rx_quick_consumer_index0;
5872	if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
5873		hw_cons++;
5874
5875	return hw_cons;
5876}
5877
5878/****************************************************************************/
5879/* Handles received frame interrupt events.                                 */
5880/*                                                                          */
5881/* Returns:                                                                 */
5882/*   Nothing.                                                               */
5883/****************************************************************************/
5884static void
5885bce_rx_intr(struct bce_softc *sc)
5886{
5887	struct ifnet *ifp = sc->bce_ifp;
5888	struct l2_fhdr *l2fhdr;
5889	struct ether_vlan_header *vh;
5890	unsigned int pkt_len;
5891	u16 sw_rx_cons, sw_rx_cons_idx, hw_rx_cons;
5892	u32 status;
5893#ifdef BCE_JUMBO_HDRSPLIT
5894	unsigned int rem_len;
5895	u16 sw_pg_cons, sw_pg_cons_idx;
5896#endif
5897
5898	DBENTER(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
5899	DBRUN(sc->rx_interrupts++);
5900	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): rx_prod = 0x%04X, "
5901		"rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
5902		__FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
5903
5904	/* Prepare the RX chain pages to be accessed by the host CPU. */
5905	for (int i = 0; i < RX_PAGES; i++)
5906		bus_dmamap_sync(sc->rx_bd_chain_tag,
5907		    sc->rx_bd_chain_map[i], BUS_DMASYNC_POSTREAD);
5908
5909#ifdef BCE_JUMBO_HDRSPLIT
5910	/* Prepare the page chain pages to be accessed by the host CPU. */
5911	for (int i = 0; i < PG_PAGES; i++)
5912		bus_dmamap_sync(sc->pg_bd_chain_tag,
5913		    sc->pg_bd_chain_map[i], BUS_DMASYNC_POSTREAD);
5914#endif
5915
5916	/* Get the hardware's view of the RX consumer index. */
5917	hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
5918
5919	/* Get working copies of the driver's view of the consumer indices. */
5920	sw_rx_cons = sc->rx_cons;
5921#ifdef BCE_JUMBO_HDRSPLIT
5922	sw_pg_cons = sc->pg_cons;
5923#endif
5924
5925	/* Update some debug statistics counters */
5926	DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
5927		sc->rx_low_watermark = sc->free_rx_bd);
5928	DBRUNIF((sc->free_rx_bd == sc->max_rx_bd), sc->rx_empty_count++);
5929
5930	/* Scan through the receive chain as long as there is work to do */
5931	/* ToDo: Consider setting a limit on the number of packets processed. */
5932	rmb();
5933	while (sw_rx_cons != hw_rx_cons) {
5934		struct mbuf *m0;
5935
5936		/* Convert the producer/consumer indices to an actual rx_bd index. */
5937		sw_rx_cons_idx = RX_CHAIN_IDX(sw_rx_cons);
5938
5939		/* Unmap the mbuf from DMA space. */
5940		bus_dmamap_sync(sc->rx_mbuf_tag, sc->rx_mbuf_map[sw_rx_cons_idx],
5941		    BUS_DMASYNC_POSTREAD);
5942		bus_dmamap_unload(sc->rx_mbuf_tag,
5943		    sc->rx_mbuf_map[sw_rx_cons_idx]);
5944
5945		/* Remove the mbuf from the RX chain. */
5946		m0 = sc->rx_mbuf_ptr[sw_rx_cons_idx];
5947		sc->rx_mbuf_ptr[sw_rx_cons_idx] = NULL;
5948		DBRUN(sc->debug_rx_mbuf_alloc--);
5949		sc->free_rx_bd++;
5950
5951        if(m0 == NULL) {
5952            DBPRINT(sc, BCE_EXTREME_RECV, "%s(): Oops! Empty mbuf pointer "
5953                "found in sc->rx_mbuf_ptr[0x%04X]!\n",
5954                __FUNCTION__, sw_rx_cons_idx);
5955            goto bce_rx_int_next_rx;
5956        }
5957
5958        /*
5959         * Frames received on the NetXteme II are prepended	with an
5960         * l2_fhdr structure which provides status information about
5961         * the received frame (including VLAN tags and checksum info).
5962         * The frames are also automatically adjusted to align the IP
5963         * header (i.e. two null bytes are inserted before the Ethernet
5964         * header).  As a result the data DMA'd by the controller into
5965         * the mbuf is as follows:
5966         *
5967         * +---------+-----+---------------------+-----+
5968         * | l2_fhdr | pad | packet data         | FCS |
5969         * +---------+-----+---------------------+-----+
5970         *
5971         * The l2_fhdr needs to be checked and skipped and the FCS needs
5972         * to be stripped before sending the packet up the stack.
5973         */
5974		l2fhdr  = mtod(m0, struct l2_fhdr *);
5975
5976		/* Get the packet data + FCS length and the status. */
5977		pkt_len = l2fhdr->l2_fhdr_pkt_len;
5978		status  = l2fhdr->l2_fhdr_status;
5979
5980		/*
5981		 * Skip over the l2_fhdr and pad, resulting in the
5982		 * following data in the mbuf:
5983		 * +---------------------+-----+
5984		 * | packet data         | FCS |
5985		 * +---------------------+-----+
5986		 */
5987		m_adj(m0, sizeof(struct l2_fhdr) + ETHER_ALIGN);
5988
5989#ifdef BCE_JUMBO_HDRSPLIT
5990		/*
5991		 * Check whether the received frame fits in a single
5992		 * mbuf or not (i.e. packet data + FCS <=
5993		 * sc->rx_bd_mbuf_data_len bytes).
5994		 */
5995		if (pkt_len > m0->m_len) {
5996			/*
5997			 * The received frame is larger than a single mbuf.
5998			 * If the frame was a TCP frame then only the TCP
5999			 * header is placed in the mbuf, the remaining
6000			 * payload (including FCS) is placed in the page
6001			 * chain, the SPLIT flag is set, and the header
6002			 * length is placed in the IP checksum field.
6003			 * If the frame is not a TCP frame then the mbuf
6004			 * is filled and the remaining bytes are placed
6005			 * in the page chain.
6006			 */
6007
6008			DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a large packet.\n",
6009				__FUNCTION__);
6010
6011			/*
6012			 * When the page chain is enabled and the TCP
6013			 * header has been split from the TCP payload,
6014			 * the ip_xsum structure will reflect the length
6015			 * of the TCP header, not the IP checksum.  Set
6016			 * the packet length of the mbuf accordingly.
6017			 */
6018		 	if (status & L2_FHDR_STATUS_SPLIT)
6019				m0->m_len = l2fhdr->l2_fhdr_ip_xsum;
6020
6021			rem_len = pkt_len - m0->m_len;
6022
6023			/* Pull mbufs off the page chain for the remaining data. */
6024			while (rem_len > 0) {
6025				struct mbuf *m_pg;
6026
6027				sw_pg_cons_idx = PG_CHAIN_IDX(sw_pg_cons);
6028
6029				/* Remove the mbuf from the page chain. */
6030				m_pg = sc->pg_mbuf_ptr[sw_pg_cons_idx];
6031				sc->pg_mbuf_ptr[sw_pg_cons_idx] = NULL;
6032				DBRUN(sc->debug_pg_mbuf_alloc--);
6033				sc->free_pg_bd++;
6034
6035				/* Unmap the page chain mbuf from DMA space. */
6036				bus_dmamap_sync(sc->pg_mbuf_tag,
6037					sc->pg_mbuf_map[sw_pg_cons_idx],
6038					BUS_DMASYNC_POSTREAD);
6039				bus_dmamap_unload(sc->pg_mbuf_tag,
6040					sc->pg_mbuf_map[sw_pg_cons_idx]);
6041
6042				/* Adjust the mbuf length. */
6043				if (rem_len < m_pg->m_len) {
6044					/* The mbuf chain is complete. */
6045					m_pg->m_len = rem_len;
6046					rem_len = 0;
6047				} else {
6048					/* More packet data is waiting. */
6049					rem_len -= m_pg->m_len;
6050				}
6051
6052				/* Concatenate the mbuf cluster to the mbuf. */
6053				m_cat(m0, m_pg);
6054
6055				sw_pg_cons = NEXT_PG_BD(sw_pg_cons);
6056			}
6057
6058			/* Set the total packet length. */
6059			m0->m_pkthdr.len = pkt_len;
6060
6061		} else {
6062			/*
6063			 * The received packet is small and fits in a
6064			 * single mbuf (i.e. the l2_fhdr + pad + packet +
6065			 * FCS <= MHLEN).  In other words, the packet is
6066			 * 154 bytes or less in size.
6067			 */
6068
6069			DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a small packet.\n",
6070				__FUNCTION__);
6071
6072			/* Set the total packet length. */
6073			m0->m_pkthdr.len = m0->m_len = pkt_len;
6074		}
6075#else
6076        /* Set the total packet length. */
6077		m0->m_pkthdr.len = m0->m_len = pkt_len;
6078#endif
6079
6080		/* Remove the trailing Ethernet FCS. */
6081		m_adj(m0, -ETHER_CRC_LEN);
6082
6083		/* Check that the resulting mbuf chain is valid. */
6084		DBRUN(m_sanity(m0, FALSE));
6085		DBRUNIF(((m0->m_len < ETHER_HDR_LEN) |
6086			(m0->m_pkthdr.len > BCE_MAX_JUMBO_ETHER_MTU_VLAN)),
6087			BCE_PRINTF("Invalid Ethernet frame size!\n");
6088			m_print(m0, 128));
6089
6090		DBRUNIF(DB_RANDOMTRUE(l2fhdr_error_sim_control),
6091			BCE_PRINTF("Simulating l2_fhdr status error.\n");
6092			sc->l2fhdr_error_sim_count++;
6093			status = status | L2_FHDR_ERRORS_PHY_DECODE);
6094
6095		/* Check the received frame for errors. */
6096		if (status & (L2_FHDR_ERRORS_BAD_CRC |
6097			L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT |
6098			L2_FHDR_ERRORS_TOO_SHORT  | L2_FHDR_ERRORS_GIANT_FRAME)) {
6099
6100			/* Log the error and release the mbuf. */
6101			ifp->if_ierrors++;
6102			sc->l2fhdr_error_count++;
6103
6104			m_freem(m0);
6105			m0 = NULL;
6106			goto bce_rx_int_next_rx;
6107		}
6108
6109		/* Send the packet to the appropriate interface. */
6110		m0->m_pkthdr.rcvif = ifp;
6111
6112		/* Assume no hardware checksum. */
6113		m0->m_pkthdr.csum_flags = 0;
6114
6115		/* Validate the checksum if offload enabled. */
6116		if (ifp->if_capenable & IFCAP_RXCSUM) {
6117
6118			/* Check for an IP datagram. */
6119		 	if (!(status & L2_FHDR_STATUS_SPLIT) &&
6120				(status & L2_FHDR_STATUS_IP_DATAGRAM)) {
6121				m0->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
6122
6123				/* Check if the IP checksum is valid. */
6124				if ((l2fhdr->l2_fhdr_ip_xsum ^ 0xffff) == 0)
6125					m0->m_pkthdr.csum_flags |= CSUM_IP_VALID;
6126			}
6127
6128			/* Check for a valid TCP/UDP frame. */
6129			if (status & (L2_FHDR_STATUS_TCP_SEGMENT |
6130				L2_FHDR_STATUS_UDP_DATAGRAM)) {
6131
6132				/* Check for a good TCP/UDP checksum. */
6133				if ((status & (L2_FHDR_ERRORS_TCP_XSUM |
6134					      L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
6135					m0->m_pkthdr.csum_data =
6136					    l2fhdr->l2_fhdr_tcp_udp_xsum;
6137					m0->m_pkthdr.csum_flags |= (CSUM_DATA_VALID
6138						| CSUM_PSEUDO_HDR);
6139				}
6140			}
6141		}
6142
6143		/* Attach the VLAN tag.	*/
6144		if (status & L2_FHDR_STATUS_L2_VLAN_TAG) {
6145			if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
6146#if __FreeBSD_version < 700000
6147				VLAN_INPUT_TAG(ifp, m0,
6148				    l2fhdr->l2_fhdr_vlan_tag, continue);
6149#else
6150				m0->m_pkthdr.ether_vtag =
6151				    l2fhdr->l2_fhdr_vlan_tag;
6152				m0->m_flags |= M_VLANTAG;
6153#endif
6154			} else {
6155				/*
6156				 * bce(4) controllers can't disable VLAN
6157				 * tag stripping if management firmware
6158				 * (ASF/IPMI/UMP) is running. So we always
6159				 * strip VLAN tag and manually reconstruct
6160				 * the VLAN frame by appending stripped
6161				 * VLAN tag in driver if VLAN tag stripping
6162				 * was disabled.
6163				 *
6164				 * TODO: LLC SNAP handling.
6165				 */
6166				bcopy(mtod(m0, uint8_t *),
6167				    mtod(m0, uint8_t *) - ETHER_VLAN_ENCAP_LEN,
6168				    ETHER_ADDR_LEN * 2);
6169				m0->m_data -= ETHER_VLAN_ENCAP_LEN;
6170				vh = mtod(m0, struct ether_vlan_header *);
6171				vh->evl_encap_proto = htons(ETHERTYPE_VLAN);
6172				vh->evl_tag = htons(l2fhdr->l2_fhdr_vlan_tag);
6173				m0->m_pkthdr.len += ETHER_VLAN_ENCAP_LEN;
6174				m0->m_len += ETHER_VLAN_ENCAP_LEN;
6175			}
6176		}
6177
6178		/* Increment received packet statistics. */
6179		ifp->if_ipackets++;
6180
6181bce_rx_int_next_rx:
6182		sw_rx_cons = NEXT_RX_BD(sw_rx_cons);
6183
6184		/* If we have a packet, pass it up the stack */
6185		if (m0) {
6186			/* Make sure we don't lose our place when we release the lock. */
6187			sc->rx_cons = sw_rx_cons;
6188#ifdef BCE_JUMBO_HDRSPLIT
6189			sc->pg_cons = sw_pg_cons;
6190#endif
6191
6192			BCE_UNLOCK(sc);
6193			(*ifp->if_input)(ifp, m0);
6194			BCE_LOCK(sc);
6195
6196			/* Recover our place. */
6197			sw_rx_cons = sc->rx_cons;
6198#ifdef BCE_JUMBO_HDRSPLIT
6199			sw_pg_cons = sc->pg_cons;
6200#endif
6201		}
6202
6203		/* Refresh hw_cons to see if there's new work */
6204		if (sw_rx_cons == hw_rx_cons)
6205			hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
6206	}
6207
6208	/* No new packets to process.  Refill the RX and page chains and exit. */
6209#ifdef BCE_JUMBO_HDRSPLIT
6210	sc->pg_cons = sw_pg_cons;
6211	bce_fill_pg_chain(sc);
6212#endif
6213
6214	sc->rx_cons = sw_rx_cons;
6215	bce_fill_rx_chain(sc);
6216
6217	/* Prepare the page chain pages to be accessed by the NIC. */
6218	for (int i = 0; i < RX_PAGES; i++)
6219		bus_dmamap_sync(sc->rx_bd_chain_tag,
6220		    sc->rx_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
6221
6222#ifdef BCE_JUMBO_HDRSPLIT
6223	for (int i = 0; i < PG_PAGES; i++)
6224		bus_dmamap_sync(sc->pg_bd_chain_tag,
6225		    sc->pg_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
6226#endif
6227
6228	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): rx_prod = 0x%04X, "
6229		"rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
6230		__FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
6231	DBEXIT(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
6232}
6233
6234
6235/****************************************************************************/
6236/* Reads the transmit consumer value from the status block (skipping over   */
6237/* chain page pointer if necessary).                                        */
6238/*                                                                          */
6239/* Returns:                                                                 */
6240/*   hw_cons                                                                */
6241/****************************************************************************/
6242static inline u16
6243bce_get_hw_tx_cons(struct bce_softc *sc)
6244{
6245	u16 hw_cons;
6246
6247	mb();
6248	hw_cons = sc->status_block->status_tx_quick_consumer_index0;
6249	if ((hw_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
6250		hw_cons++;
6251
6252	return hw_cons;
6253}
6254
6255
6256/****************************************************************************/
6257/* Handles transmit completion interrupt events.                            */
6258/*                                                                          */
6259/* Returns:                                                                 */
6260/*   Nothing.                                                               */
6261/****************************************************************************/
6262static void
6263bce_tx_intr(struct bce_softc *sc)
6264{
6265	struct ifnet *ifp = sc->bce_ifp;
6266	u16 hw_tx_cons, sw_tx_cons, sw_tx_chain_cons;
6267
6268	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
6269	DBRUN(sc->tx_interrupts++);
6270	DBPRINT(sc, BCE_EXTREME_SEND, "%s(enter): tx_prod = 0x%04X, "
6271		"tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
6272		__FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
6273
6274	BCE_LOCK_ASSERT(sc);
6275
6276	/* Get the hardware's view of the TX consumer index. */
6277	hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
6278	sw_tx_cons = sc->tx_cons;
6279
6280	/* Prevent speculative reads from getting ahead of the status block. */
6281	bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
6282		BUS_SPACE_BARRIER_READ);
6283
6284	/* Cycle through any completed TX chain page entries. */
6285	while (sw_tx_cons != hw_tx_cons) {
6286#ifdef BCE_DEBUG
6287		struct tx_bd *txbd = NULL;
6288#endif
6289		sw_tx_chain_cons = TX_CHAIN_IDX(sw_tx_cons);
6290
6291		DBPRINT(sc, BCE_INFO_SEND,
6292			"%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, "
6293			"sw_tx_chain_cons = 0x%04X\n",
6294			__FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
6295
6296		DBRUNIF((sw_tx_chain_cons > MAX_TX_BD),
6297			BCE_PRINTF("%s(%d): TX chain consumer out of range! "
6298				" 0x%04X > 0x%04X\n", __FILE__, __LINE__, sw_tx_chain_cons,
6299				(int) MAX_TX_BD);
6300			bce_breakpoint(sc));
6301
6302		DBRUN(txbd = &sc->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)]
6303				[TX_IDX(sw_tx_chain_cons)]);
6304
6305		DBRUNIF((txbd == NULL),
6306			BCE_PRINTF("%s(%d): Unexpected NULL tx_bd[0x%04X]!\n",
6307				__FILE__, __LINE__, sw_tx_chain_cons);
6308			bce_breakpoint(sc));
6309
6310		DBRUNMSG(BCE_INFO_SEND, BCE_PRINTF("%s(): ", __FUNCTION__);
6311			bce_dump_txbd(sc, sw_tx_chain_cons, txbd));
6312
6313		/*
6314		 * Free the associated mbuf. Remember
6315		 * that only the last tx_bd of a packet
6316		 * has an mbuf pointer and DMA map.
6317		 */
6318		if (sc->tx_mbuf_ptr[sw_tx_chain_cons] != NULL) {
6319
6320			/* Validate that this is the last tx_bd. */
6321			DBRUNIF((!(txbd->tx_bd_flags & TX_BD_FLAGS_END)),
6322				BCE_PRINTF("%s(%d): tx_bd END flag not set but "
6323				"txmbuf == NULL!\n", __FILE__, __LINE__);
6324				bce_breakpoint(sc));
6325
6326			DBRUNMSG(BCE_INFO_SEND,
6327				BCE_PRINTF("%s(): Unloading map/freeing mbuf "
6328					"from tx_bd[0x%04X]\n", __FUNCTION__, sw_tx_chain_cons));
6329
6330			/* Unmap the mbuf. */
6331			bus_dmamap_unload(sc->tx_mbuf_tag,
6332			    sc->tx_mbuf_map[sw_tx_chain_cons]);
6333
6334			/* Free the mbuf. */
6335			m_freem(sc->tx_mbuf_ptr[sw_tx_chain_cons]);
6336			sc->tx_mbuf_ptr[sw_tx_chain_cons] = NULL;
6337			DBRUN(sc->debug_tx_mbuf_alloc--);
6338
6339			ifp->if_opackets++;
6340		}
6341
6342		sc->used_tx_bd--;
6343		sw_tx_cons = NEXT_TX_BD(sw_tx_cons);
6344
6345		/* Refresh hw_cons to see if there's new work. */
6346		hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
6347
6348		/* Prevent speculative reads from getting ahead of the status block. */
6349		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
6350			BUS_SPACE_BARRIER_READ);
6351	}
6352
6353	/* Clear the TX timeout timer. */
6354	sc->watchdog_timer = 0;
6355
6356	/* Clear the tx hardware queue full flag. */
6357	if (sc->used_tx_bd < sc->max_tx_bd) {
6358		DBRUNIF((ifp->if_drv_flags & IFF_DRV_OACTIVE),
6359			DBPRINT(sc, BCE_INFO_SEND,
6360				"%s(): Open TX chain! %d/%d (used/total)\n",
6361				__FUNCTION__, sc->used_tx_bd, sc->max_tx_bd));
6362		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
6363	}
6364
6365	sc->tx_cons = sw_tx_cons;
6366
6367	DBPRINT(sc, BCE_EXTREME_SEND, "%s(exit): tx_prod = 0x%04X, "
6368		"tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
6369		__FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
6370	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
6371}
6372
6373
6374/****************************************************************************/
6375/* Disables interrupt generation.                                           */
6376/*                                                                          */
6377/* Returns:                                                                 */
6378/*   Nothing.                                                               */
6379/****************************************************************************/
6380static void
6381bce_disable_intr(struct bce_softc *sc)
6382{
6383	DBENTER(BCE_VERBOSE_INTR);
6384
6385	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_MASK_INT);
6386	REG_RD(sc, BCE_PCICFG_INT_ACK_CMD);
6387
6388	DBEXIT(BCE_VERBOSE_INTR);
6389}
6390
6391
6392/****************************************************************************/
6393/* Enables interrupt generation.                                            */
6394/*                                                                          */
6395/* Returns:                                                                 */
6396/*   Nothing.                                                               */
6397/****************************************************************************/
6398static void
6399bce_enable_intr(struct bce_softc *sc, int coal_now)
6400{
6401	DBENTER(BCE_VERBOSE_INTR);
6402
6403	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
6404	       BCE_PCICFG_INT_ACK_CMD_INDEX_VALID |
6405	       BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
6406
6407	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
6408	       BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
6409
6410	/* Force an immediate interrupt (whether there is new data or not). */
6411	if (coal_now)
6412		REG_WR(sc, BCE_HC_COMMAND, sc->hc_command | BCE_HC_COMMAND_COAL_NOW);
6413
6414	DBEXIT(BCE_VERBOSE_INTR);
6415}
6416
6417
6418/****************************************************************************/
6419/* Handles controller initialization.                                       */
6420/*                                                                          */
6421/* Returns:                                                                 */
6422/*   Nothing.                                                               */
6423/****************************************************************************/
6424static void
6425bce_init_locked(struct bce_softc *sc)
6426{
6427	struct ifnet *ifp;
6428	u32 ether_mtu = 0;
6429
6430	DBENTER(BCE_VERBOSE_RESET);
6431
6432	BCE_LOCK_ASSERT(sc);
6433
6434	ifp = sc->bce_ifp;
6435
6436	/* Check if the driver is still running and bail out if it is. */
6437	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
6438		goto bce_init_locked_exit;
6439
6440	bce_stop(sc);
6441
6442	if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
6443		BCE_PRINTF("%s(%d): Controller reset failed!\n",
6444			__FILE__, __LINE__);
6445		goto bce_init_locked_exit;
6446	}
6447
6448	if (bce_chipinit(sc)) {
6449		BCE_PRINTF("%s(%d): Controller initialization failed!\n",
6450			__FILE__, __LINE__);
6451		goto bce_init_locked_exit;
6452	}
6453
6454	if (bce_blockinit(sc)) {
6455		BCE_PRINTF("%s(%d): Block initialization failed!\n",
6456			__FILE__, __LINE__);
6457		goto bce_init_locked_exit;
6458	}
6459
6460	/* Load our MAC address. */
6461	bcopy(IF_LLADDR(sc->bce_ifp), sc->eaddr, ETHER_ADDR_LEN);
6462	bce_set_mac_addr(sc);
6463
6464	/*
6465	 * Calculate and program the hardware Ethernet MTU
6466	 * size. Be generous on the receive if we have room.
6467	 */
6468#ifdef BCE_JUMBO_HDRSPLIT
6469	if (ifp->if_mtu <= (sc->rx_bd_mbuf_data_len + sc->pg_bd_mbuf_alloc_size))
6470		ether_mtu = sc->rx_bd_mbuf_data_len + sc->pg_bd_mbuf_alloc_size;
6471#else
6472	if (ifp->if_mtu <= sc->rx_bd_mbuf_data_len)
6473		ether_mtu = sc->rx_bd_mbuf_data_len;
6474#endif
6475	else
6476		ether_mtu = ifp->if_mtu;
6477
6478	ether_mtu += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN;
6479
6480	DBPRINT(sc, BCE_INFO_MISC, "%s(): setting h/w mtu = %d\n", __FUNCTION__,
6481		ether_mtu);
6482
6483	/* Program the mtu, enabling jumbo frame support if necessary. */
6484	if (ether_mtu > (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN))
6485		REG_WR(sc, BCE_EMAC_RX_MTU_SIZE,
6486			min(ether_mtu, BCE_MAX_JUMBO_ETHER_MTU) |
6487			BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA);
6488	else
6489		REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu);
6490
6491	DBPRINT(sc, BCE_INFO_LOAD,
6492		"%s(): rx_bd_mbuf_alloc_size = %d, rx_bce_mbuf_data_len = %d, "
6493		"rx_bd_mbuf_align_pad = %d\n", __FUNCTION__,
6494		sc->rx_bd_mbuf_alloc_size, sc->rx_bd_mbuf_data_len,
6495		sc->rx_bd_mbuf_align_pad);
6496
6497	/* Program appropriate promiscuous/multicast filtering. */
6498	bce_set_rx_mode(sc);
6499
6500#ifdef BCE_JUMBO_HDRSPLIT
6501	DBPRINT(sc, BCE_INFO_LOAD, "%s(): pg_bd_mbuf_alloc_size = %d\n",
6502		__FUNCTION__, sc->pg_bd_mbuf_alloc_size);
6503
6504	/* Init page buffer descriptor chain. */
6505	bce_init_pg_chain(sc);
6506#endif
6507
6508	/* Init RX buffer descriptor chain. */
6509	bce_init_rx_chain(sc);
6510
6511	/* Init TX buffer descriptor chain. */
6512	bce_init_tx_chain(sc);
6513
6514	/* Enable host interrupts. */
6515	bce_enable_intr(sc, 1);
6516
6517	bce_ifmedia_upd_locked(ifp);
6518
6519	/* Let the OS know the driver is up and running. */
6520	ifp->if_drv_flags |= IFF_DRV_RUNNING;
6521	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
6522
6523	callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
6524
6525bce_init_locked_exit:
6526	DBEXIT(BCE_VERBOSE_RESET);
6527}
6528
6529
6530/****************************************************************************/
6531/* Initialize the controller just enough so that any management firmware    */
6532/* running on the device will continue to operate correctly.                */
6533/*                                                                          */
6534/* Returns:                                                                 */
6535/*   Nothing.                                                               */
6536/****************************************************************************/
6537static void
6538bce_mgmt_init_locked(struct bce_softc *sc)
6539{
6540	struct ifnet *ifp;
6541
6542	DBENTER(BCE_VERBOSE_RESET);
6543
6544	BCE_LOCK_ASSERT(sc);
6545
6546	/* Bail out if management firmware is not running. */
6547	if (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)) {
6548		DBPRINT(sc, BCE_VERBOSE_SPECIAL,
6549			"No management firmware running...\n");
6550		goto bce_mgmt_init_locked_exit;
6551	}
6552
6553	ifp = sc->bce_ifp;
6554
6555	/* Enable all critical blocks in the MAC. */
6556	REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT);
6557	REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
6558	DELAY(20);
6559
6560	bce_ifmedia_upd_locked(ifp);
6561
6562bce_mgmt_init_locked_exit:
6563	DBEXIT(BCE_VERBOSE_RESET);
6564}
6565
6566
6567/****************************************************************************/
6568/* Handles controller initialization when called from an unlocked routine.  */
6569/*                                                                          */
6570/* Returns:                                                                 */
6571/*   Nothing.                                                               */
6572/****************************************************************************/
6573static void
6574bce_init(void *xsc)
6575{
6576	struct bce_softc *sc = xsc;
6577
6578	DBENTER(BCE_VERBOSE_RESET);
6579
6580	BCE_LOCK(sc);
6581	bce_init_locked(sc);
6582	BCE_UNLOCK(sc);
6583
6584	DBEXIT(BCE_VERBOSE_RESET);
6585}
6586
6587
6588/****************************************************************************/
6589/* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
6590/* memory visible to the controller.                                        */
6591/*                                                                          */
6592/* Returns:                                                                 */
6593/*   0 for success, positive value for failure.                             */
6594/* Modified:                                                                */
6595/*   m_head: May be set to NULL if MBUF is excessively fragmented.          */
6596/****************************************************************************/
6597static int
6598bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
6599{
6600	bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
6601	bus_dmamap_t map;
6602	struct tx_bd *txbd = NULL;
6603	struct mbuf *m0;
6604	struct ether_vlan_header *eh;
6605	struct ip *ip;
6606	struct tcphdr *th;
6607	u16 prod, chain_prod, etype, mss = 0, vlan_tag = 0, flags = 0;
6608	u32 prod_bseq;
6609	int hdr_len = 0, e_hlen = 0, ip_hlen = 0, tcp_hlen = 0, ip_len = 0;
6610
6611#ifdef BCE_DEBUG
6612	u16 debug_prod;
6613#endif
6614	int i, error, nsegs, rc = 0;
6615
6616	DBENTER(BCE_VERBOSE_SEND);
6617	DBPRINT(sc, BCE_INFO_SEND,
6618		"%s(enter): tx_prod = 0x%04X, tx_chain_prod = %04X, "
6619		"tx_prod_bseq = 0x%08X\n",
6620		__FUNCTION__, sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod),
6621		sc->tx_prod_bseq);
6622
6623	/* Transfer any checksum offload flags to the bd. */
6624	m0 = *m_head;
6625	if (m0->m_pkthdr.csum_flags) {
6626		if (m0->m_pkthdr.csum_flags & CSUM_IP)
6627			flags |= TX_BD_FLAGS_IP_CKSUM;
6628		if (m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
6629			flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
6630		if (m0->m_pkthdr.csum_flags & CSUM_TSO) {
6631			/* For TSO the controller needs two pieces of info, */
6632			/* the MSS and the IP+TCP options length.           */
6633			mss = htole16(m0->m_pkthdr.tso_segsz);
6634
6635			/* Map the header and find the Ethernet type & header length */
6636			eh = mtod(m0, struct ether_vlan_header *);
6637			if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
6638				etype = ntohs(eh->evl_proto);
6639				e_hlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
6640			} else {
6641				etype = ntohs(eh->evl_encap_proto);
6642				e_hlen = ETHER_HDR_LEN;
6643			}
6644
6645			/* Check for supported TSO Ethernet types (only IPv4 for now) */
6646			switch (etype) {
6647				case ETHERTYPE_IP:
6648					ip = (struct ip *)(m0->m_data + e_hlen);
6649
6650					/* TSO only supported for TCP protocol */
6651					if (ip->ip_p != IPPROTO_TCP) {
6652						BCE_PRINTF("%s(%d): TSO enabled for non-TCP frame!.\n",
6653							__FILE__, __LINE__);
6654						goto bce_tx_encap_skip_tso;
6655					}
6656
6657					/* Get IP header length in bytes (min 20) */
6658					ip_hlen = ip->ip_hl << 2;
6659
6660					/* Get the TCP header length in bytes (min 20) */
6661					th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
6662					tcp_hlen = (th->th_off << 2);
6663
6664					/* IP header length and checksum will be calc'd by hardware */
6665					ip_len = ip->ip_len;
6666					ip->ip_len = 0;
6667					ip->ip_sum = 0;
6668					break;
6669				case ETHERTYPE_IPV6:
6670					BCE_PRINTF("%s(%d): TSO over IPv6 not supported!.\n",
6671						__FILE__, __LINE__);
6672					goto bce_tx_encap_skip_tso;
6673				default:
6674					BCE_PRINTF("%s(%d): TSO enabled for unsupported protocol!.\n",
6675						__FILE__, __LINE__);
6676					goto bce_tx_encap_skip_tso;
6677			}
6678
6679			hdr_len = e_hlen + ip_hlen + tcp_hlen;
6680
6681			DBPRINT(sc, BCE_EXTREME_SEND,
6682				"%s(): hdr_len = %d, e_hlen = %d, ip_hlen = %d, tcp_hlen = %d, ip_len = %d\n",
6683				 __FUNCTION__, hdr_len, e_hlen, ip_hlen, tcp_hlen, ip_len);
6684
6685			/* Set the LSO flag in the TX BD */
6686			flags |= TX_BD_FLAGS_SW_LSO;
6687			/* Set the length of IP + TCP options (in 32 bit words) */
6688			flags |= (((ip_hlen + tcp_hlen - 40) >> 2) << 8);
6689
6690bce_tx_encap_skip_tso:
6691			DBRUN(sc->requested_tso_frames++);
6692		}
6693	}
6694
6695	/* Transfer any VLAN tags to the bd. */
6696	if (m0->m_flags & M_VLANTAG) {
6697		flags |= TX_BD_FLAGS_VLAN_TAG;
6698		vlan_tag = m0->m_pkthdr.ether_vtag;
6699	}
6700
6701	/* Map the mbuf into DMAable memory. */
6702	prod = sc->tx_prod;
6703	chain_prod = TX_CHAIN_IDX(prod);
6704	map = sc->tx_mbuf_map[chain_prod];
6705
6706	/* Map the mbuf into our DMA address space. */
6707	error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag, map, m0,
6708	    segs, &nsegs, BUS_DMA_NOWAIT);
6709
6710	/* Check if the DMA mapping was successful */
6711	if (error == EFBIG) {
6712
6713		sc->fragmented_mbuf_count++;
6714
6715		/* Try to defrag the mbuf. */
6716		m0 = m_collapse(*m_head, M_DONTWAIT, BCE_MAX_SEGMENTS);
6717		if (m0 == NULL) {
6718			/* Defrag was unsuccessful */
6719			m_freem(*m_head);
6720			*m_head = NULL;
6721			sc->mbuf_alloc_failed_count++;
6722			rc = ENOBUFS;
6723			goto bce_tx_encap_exit;
6724		}
6725
6726		/* Defrag was successful, try mapping again */
6727		*m_head = m0;
6728		error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag, map, m0,
6729		    segs, &nsegs, BUS_DMA_NOWAIT);
6730
6731		/* Still getting an error after a defrag. */
6732		if (error == ENOMEM) {
6733			/* Insufficient DMA buffers available. */
6734			sc->dma_map_addr_tx_failed_count++;
6735			rc = error;
6736			goto bce_tx_encap_exit;
6737		} else if (error != 0) {
6738			/* Still can't map the mbuf, release it and return an error. */
6739			BCE_PRINTF(
6740			    "%s(%d): Unknown error mapping mbuf into TX chain!\n",
6741			    __FILE__, __LINE__);
6742			m_freem(m0);
6743			*m_head = NULL;
6744			sc->dma_map_addr_tx_failed_count++;
6745			rc = ENOBUFS;
6746			goto bce_tx_encap_exit;
6747		}
6748	} else if (error == ENOMEM) {
6749		/* Insufficient DMA buffers available. */
6750		sc->dma_map_addr_tx_failed_count++;
6751		rc = error;
6752		goto bce_tx_encap_exit;
6753	} else if (error != 0) {
6754		m_freem(m0);
6755		*m_head = NULL;
6756		sc->dma_map_addr_tx_failed_count++;
6757		rc = error;
6758		goto bce_tx_encap_exit;
6759	}
6760
6761	/* Make sure there's room in the chain */
6762	if (nsegs > (sc->max_tx_bd - sc->used_tx_bd)) {
6763		bus_dmamap_unload(sc->tx_mbuf_tag, map);
6764		rc = ENOBUFS;
6765		goto bce_tx_encap_exit;
6766	}
6767
6768	/* prod points to an empty tx_bd at this point. */
6769	prod_bseq  = sc->tx_prod_bseq;
6770
6771#ifdef BCE_DEBUG
6772	debug_prod = chain_prod;
6773#endif
6774
6775	DBPRINT(sc, BCE_INFO_SEND,
6776		"%s(start): prod = 0x%04X, chain_prod = 0x%04X, "
6777		"prod_bseq = 0x%08X\n",
6778		__FUNCTION__, prod, chain_prod, prod_bseq);
6779
6780	/*
6781	 * Cycle through each mbuf segment that makes up
6782	 * the outgoing frame, gathering the mapping info
6783	 * for that segment and creating a tx_bd for
6784	 * the mbuf.
6785	 */
6786	for (i = 0; i < nsegs ; i++) {
6787
6788		chain_prod = TX_CHAIN_IDX(prod);
6789		txbd= &sc->tx_bd_chain[TX_PAGE(chain_prod)][TX_IDX(chain_prod)];
6790
6791		txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(segs[i].ds_addr));
6792		txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(segs[i].ds_addr));
6793		txbd->tx_bd_mss_nbytes = htole32(mss << 16) | htole16(segs[i].ds_len);
6794		txbd->tx_bd_vlan_tag = htole16(vlan_tag);
6795		txbd->tx_bd_flags = htole16(flags);
6796		prod_bseq += segs[i].ds_len;
6797		if (i == 0)
6798			txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_START);
6799		prod = NEXT_TX_BD(prod);
6800	}
6801
6802	/* Set the END flag on the last TX buffer descriptor. */
6803	txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_END);
6804
6805	DBRUNMSG(BCE_EXTREME_SEND, bce_dump_tx_chain(sc, debug_prod, nsegs));
6806
6807	DBPRINT(sc, BCE_INFO_SEND,
6808		"%s( end ): prod = 0x%04X, chain_prod = 0x%04X, "
6809		"prod_bseq = 0x%08X\n",
6810		__FUNCTION__, prod, chain_prod, prod_bseq);
6811
6812	/*
6813	 * Ensure that the mbuf pointer for this transmission
6814	 * is placed at the array index of the last
6815	 * descriptor in this chain.  This is done
6816	 * because a single map is used for all
6817	 * segments of the mbuf and we don't want to
6818	 * unload the map before all of the segments
6819	 * have been freed.
6820	 */
6821	sc->tx_mbuf_ptr[chain_prod] = m0;
6822	sc->used_tx_bd += nsegs;
6823
6824	/* Update some debug statistic counters */
6825	DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
6826		sc->tx_hi_watermark = sc->used_tx_bd);
6827	DBRUNIF((sc->used_tx_bd == sc->max_tx_bd), sc->tx_full_count++);
6828	DBRUNIF(sc->debug_tx_mbuf_alloc++);
6829
6830	DBRUNMSG(BCE_EXTREME_SEND, bce_dump_tx_mbuf_chain(sc, chain_prod, 1));
6831
6832	/* prod points to the next free tx_bd at this point. */
6833	sc->tx_prod = prod;
6834	sc->tx_prod_bseq = prod_bseq;
6835
6836	DBPRINT(sc, BCE_INFO_SEND,
6837		"%s(exit): prod = 0x%04X, chain_prod = %04X, "
6838		"prod_bseq = 0x%08X\n",
6839		__FUNCTION__, sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod),
6840		sc->tx_prod_bseq);
6841
6842bce_tx_encap_exit:
6843	DBEXIT(BCE_VERBOSE_SEND);
6844	return(rc);
6845}
6846
6847
6848/****************************************************************************/
6849/* Main transmit routine when called from another routine with a lock.      */
6850/*                                                                          */
6851/* Returns:                                                                 */
6852/*   Nothing.                                                               */
6853/****************************************************************************/
6854static void
6855bce_start_locked(struct ifnet *ifp)
6856{
6857	struct bce_softc *sc = ifp->if_softc;
6858	struct mbuf *m_head = NULL;
6859	int count = 0;
6860	u16 tx_prod, tx_chain_prod;
6861
6862	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
6863
6864	BCE_LOCK_ASSERT(sc);
6865
6866	/* prod points to the next free tx_bd. */
6867	tx_prod = sc->tx_prod;
6868	tx_chain_prod = TX_CHAIN_IDX(tx_prod);
6869
6870	DBPRINT(sc, BCE_INFO_SEND,
6871		"%s(enter): tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
6872		"tx_prod_bseq = 0x%08X\n",
6873		__FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
6874
6875	/* If there's no link or the transmit queue is empty then just exit. */
6876	if (!sc->bce_link) {
6877		DBPRINT(sc, BCE_INFO_SEND, "%s(): No link.\n",
6878			__FUNCTION__);
6879		goto bce_start_locked_exit;
6880	}
6881
6882	if (IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
6883		DBPRINT(sc, BCE_INFO_SEND, "%s(): Transmit queue empty.\n",
6884			__FUNCTION__);
6885		goto bce_start_locked_exit;
6886	}
6887
6888	/*
6889	 * Keep adding entries while there is space in the ring.
6890	 */
6891	while (sc->used_tx_bd < sc->max_tx_bd) {
6892
6893		/* Check for any frames to send. */
6894		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
6895
6896		/* Stop when the transmit queue is empty. */
6897		if (m_head == NULL)
6898			break;
6899
6900		/*
6901		 * Pack the data into the transmit ring. If we
6902		 * don't have room, place the mbuf back at the
6903		 * head of the queue and set the OACTIVE flag
6904		 * to wait for the NIC to drain the chain.
6905		 */
6906		if (bce_tx_encap(sc, &m_head)) {
6907			/* No room, put the frame back on the transmit queue. */
6908			if (m_head != NULL)
6909				IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
6910			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
6911			DBPRINT(sc, BCE_INFO_SEND,
6912				"TX chain is closed for business! Total tx_bd used = %d\n",
6913				sc->used_tx_bd);
6914			break;
6915		}
6916
6917		count++;
6918
6919		/* Send a copy of the frame to any BPF listeners. */
6920		ETHER_BPF_MTAP(ifp, m_head);
6921	}
6922
6923	/* Exit if no packets were dequeued. */
6924	if (count == 0) {
6925		DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were dequeued\n",
6926			__FUNCTION__);
6927		goto bce_start_locked_exit;
6928	}
6929
6930	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): Inserted %d frames into send queue.\n",
6931		__FUNCTION__, count);
6932
6933	REG_WR(sc, BCE_MQ_COMMAND, REG_RD(sc, BCE_MQ_COMMAND) | BCE_MQ_COMMAND_NO_MAP_ERROR);
6934
6935	/* Write the mailbox and tell the chip about the waiting tx_bd's. */
6936	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): MB_GET_CID_ADDR(TX_CID) = 0x%08X; "
6937		"BCE_L2MQ_TX_HOST_BIDX = 0x%08X, sc->tx_prod = 0x%04X\n",
6938		__FUNCTION__,
6939		MB_GET_CID_ADDR(TX_CID), BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
6940	REG_WR16(sc, MB_GET_CID_ADDR(TX_CID) + BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
6941	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): MB_GET_CID_ADDR(TX_CID) = 0x%08X; "
6942		"BCE_L2MQ_TX_HOST_BSEQ = 0x%08X, sc->tx_prod_bseq = 0x%04X\n",
6943		__FUNCTION__,
6944		MB_GET_CID_ADDR(TX_CID), BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
6945	REG_WR(sc, MB_GET_CID_ADDR(TX_CID) + BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
6946
6947	/* Set the tx timeout. */
6948	sc->watchdog_timer = BCE_TX_TIMEOUT;
6949
6950	DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_ctx(sc, TX_CID));
6951	DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_mq_regs(sc));
6952
6953bce_start_locked_exit:
6954	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
6955	return;
6956}
6957
6958
6959/****************************************************************************/
6960/* Main transmit routine when called from another routine without a lock.   */
6961/*                                                                          */
6962/* Returns:                                                                 */
6963/*   Nothing.                                                               */
6964/****************************************************************************/
6965static void
6966bce_start(struct ifnet *ifp)
6967{
6968	struct bce_softc *sc = ifp->if_softc;
6969
6970	DBENTER(BCE_VERBOSE_SEND);
6971
6972	BCE_LOCK(sc);
6973	bce_start_locked(ifp);
6974	BCE_UNLOCK(sc);
6975
6976	DBEXIT(BCE_VERBOSE_SEND);
6977}
6978
6979
6980/****************************************************************************/
6981/* Handles any IOCTL calls from the operating system.                       */
6982/*                                                                          */
6983/* Returns:                                                                 */
6984/*   0 for success, positive value for failure.                             */
6985/****************************************************************************/
6986static int
6987bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
6988{
6989	struct bce_softc *sc = ifp->if_softc;
6990	struct ifreq *ifr = (struct ifreq *) data;
6991	struct mii_data *mii;
6992	int mask, error = 0, reinit;
6993
6994	DBENTER(BCE_VERBOSE_MISC);
6995
6996	switch(command) {
6997
6998		/* Set the interface MTU. */
6999		case SIOCSIFMTU:
7000			/* Check that the MTU setting is supported. */
7001			if ((ifr->ifr_mtu < BCE_MIN_MTU) ||
7002				(ifr->ifr_mtu > BCE_MAX_JUMBO_MTU)) {
7003				error = EINVAL;
7004				break;
7005			}
7006
7007			DBPRINT(sc, BCE_INFO_MISC,
7008				"SIOCSIFMTU: Changing MTU from %d to %d\n",
7009				(int) ifp->if_mtu, (int) ifr->ifr_mtu);
7010
7011			BCE_LOCK(sc);
7012			ifp->if_mtu = ifr->ifr_mtu;
7013			reinit = 0;
7014			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
7015				/*
7016				 * Because allocation size is used in RX
7017				 * buffer allocation, stop controller if
7018				 * it is already running.
7019				 */
7020				bce_stop(sc);
7021				reinit = 1;
7022			}
7023#ifdef BCE_JUMBO_HDRSPLIT
7024			/* No buffer allocation size changes are necessary. */
7025#else
7026			/* Recalculate our buffer allocation sizes. */
7027			if ((ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN) > MCLBYTES) {
7028				sc->rx_bd_mbuf_alloc_size = MJUM9BYTES;
7029				sc->rx_bd_mbuf_align_pad  = roundup2(MJUM9BYTES, 16) - MJUM9BYTES;
7030				sc->rx_bd_mbuf_data_len   = sc->rx_bd_mbuf_alloc_size -
7031					sc->rx_bd_mbuf_align_pad;
7032			} else {
7033				sc->rx_bd_mbuf_alloc_size = MCLBYTES;
7034				sc->rx_bd_mbuf_align_pad  = roundup2(MCLBYTES, 16) - MCLBYTES;
7035				sc->rx_bd_mbuf_data_len   = sc->rx_bd_mbuf_alloc_size -
7036					sc->rx_bd_mbuf_align_pad;
7037			}
7038#endif
7039
7040			if (reinit != 0)
7041				bce_init_locked(sc);
7042			BCE_UNLOCK(sc);
7043			break;
7044
7045		/* Set interface flags. */
7046		case SIOCSIFFLAGS:
7047			DBPRINT(sc, BCE_VERBOSE_SPECIAL, "Received SIOCSIFFLAGS\n");
7048
7049			BCE_LOCK(sc);
7050
7051			/* Check if the interface is up. */
7052			if (ifp->if_flags & IFF_UP) {
7053				if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
7054					/* Change promiscuous/multicast flags as necessary. */
7055					bce_set_rx_mode(sc);
7056				} else {
7057					/* Start the HW */
7058					bce_init_locked(sc);
7059				}
7060			} else {
7061				/* The interface is down, check if driver is running. */
7062				if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
7063					bce_stop(sc);
7064
7065					/* If MFW is running, restart the controller a bit. */
7066					if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
7067						bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
7068						bce_chipinit(sc);
7069						bce_mgmt_init_locked(sc);
7070					}
7071				}
7072			}
7073
7074			BCE_UNLOCK(sc);
7075
7076			break;
7077
7078		/* Add/Delete multicast address */
7079		case SIOCADDMULTI:
7080		case SIOCDELMULTI:
7081			DBPRINT(sc, BCE_VERBOSE_MISC, "Received SIOCADDMULTI/SIOCDELMULTI\n");
7082
7083			BCE_LOCK(sc);
7084			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
7085				bce_set_rx_mode(sc);
7086			BCE_UNLOCK(sc);
7087
7088			break;
7089
7090		/* Set/Get Interface media */
7091		case SIOCSIFMEDIA:
7092		case SIOCGIFMEDIA:
7093			DBPRINT(sc, BCE_VERBOSE_MISC, "Received SIOCSIFMEDIA/SIOCGIFMEDIA\n");
7094
7095			mii = device_get_softc(sc->bce_miibus);
7096			error = ifmedia_ioctl(ifp, ifr,
7097			    &mii->mii_media, command);
7098			break;
7099
7100		/* Set interface capability */
7101		case SIOCSIFCAP:
7102			mask = ifr->ifr_reqcap ^ ifp->if_capenable;
7103			DBPRINT(sc, BCE_INFO_MISC, "Received SIOCSIFCAP = 0x%08X\n", (u32) mask);
7104
7105			/* Toggle the TX checksum capabilities enable flag. */
7106			if (mask & IFCAP_TXCSUM &&
7107			    ifp->if_capabilities & IFCAP_TXCSUM) {
7108				ifp->if_capenable ^= IFCAP_TXCSUM;
7109				if (IFCAP_TXCSUM & ifp->if_capenable)
7110					ifp->if_hwassist |= BCE_IF_HWASSIST;
7111				else
7112					ifp->if_hwassist &= ~BCE_IF_HWASSIST;
7113			}
7114
7115			/* Toggle the RX checksum capabilities enable flag. */
7116			if (mask & IFCAP_RXCSUM &&
7117			    ifp->if_capabilities & IFCAP_RXCSUM)
7118				ifp->if_capenable ^= IFCAP_RXCSUM;
7119
7120			/* Toggle the TSO capabilities enable flag. */
7121			if (bce_tso_enable && (mask & IFCAP_TSO4) &&
7122			    ifp->if_capabilities & IFCAP_TSO4) {
7123				ifp->if_capenable ^= IFCAP_TSO4;
7124				if (IFCAP_TSO4 & ifp->if_capenable)
7125					ifp->if_hwassist |= CSUM_TSO;
7126				else
7127					ifp->if_hwassist &= ~CSUM_TSO;
7128			}
7129
7130			if (mask & IFCAP_VLAN_HWCSUM &&
7131			    ifp->if_capabilities & IFCAP_VLAN_HWCSUM)
7132				ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
7133
7134			/*
7135			 * Don't actually disable VLAN tag stripping as
7136			 * management firmware (ASF/IPMI/UMP) requires the
7137			 * feature. If VLAN tag stripping is disabled driver
7138			 * will manually reconstruct the VLAN frame by
7139			 * appending stripped VLAN tag.
7140			 */
7141			if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
7142			    (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING))
7143				ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
7144			VLAN_CAPABILITIES(ifp);
7145			break;
7146		default:
7147			/* We don't know how to handle the IOCTL, pass it on. */
7148			error = ether_ioctl(ifp, command, data);
7149			break;
7150	}
7151
7152	DBEXIT(BCE_VERBOSE_MISC);
7153	return(error);
7154}
7155
7156
7157/****************************************************************************/
7158/* Transmit timeout handler.                                                */
7159/*                                                                          */
7160/* Returns:                                                                 */
7161/*   Nothing.                                                               */
7162/****************************************************************************/
7163static void
7164bce_watchdog(struct bce_softc *sc)
7165{
7166	DBENTER(BCE_EXTREME_SEND);
7167
7168	BCE_LOCK_ASSERT(sc);
7169
7170	/* If the watchdog timer hasn't expired then just exit. */
7171	if (sc->watchdog_timer == 0 || --sc->watchdog_timer)
7172		goto bce_watchdog_exit;
7173
7174	/* If pause frames are active then don't reset the hardware. */
7175	/* ToDo: Should we reset the timer here? */
7176	if (REG_RD(sc, BCE_EMAC_TX_STATUS) & BCE_EMAC_TX_STATUS_XOFFED)
7177		goto bce_watchdog_exit;
7178
7179	BCE_PRINTF("%s(%d): Watchdog timeout occurred, resetting!\n",
7180		__FILE__, __LINE__);
7181
7182	DBRUNMSG(BCE_INFO,
7183		bce_dump_driver_state(sc);
7184		bce_dump_status_block(sc);
7185		bce_dump_stats_block(sc);
7186		bce_dump_ftqs(sc);
7187		bce_dump_txp_state(sc, 0);
7188		bce_dump_rxp_state(sc, 0);
7189		bce_dump_tpat_state(sc, 0);
7190		bce_dump_cp_state(sc, 0);
7191		bce_dump_com_state(sc, 0));
7192
7193	DBRUN(bce_breakpoint(sc));
7194
7195	sc->bce_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
7196
7197	bce_init_locked(sc);
7198	sc->bce_ifp->if_oerrors++;
7199
7200bce_watchdog_exit:
7201	DBEXIT(BCE_EXTREME_SEND);
7202}
7203
7204
7205/*
7206 * Interrupt handler.
7207 */
7208/****************************************************************************/
7209/* Main interrupt entry point.  Verifies that the controller generated the  */
7210/* interrupt and then calls a separate routine for handle the various       */
7211/* interrupt causes (PHY, TX, RX).                                          */
7212/*                                                                          */
7213/* Returns:                                                                 */
7214/*   0 for success, positive value for failure.                             */
7215/****************************************************************************/
7216static void
7217bce_intr(void *xsc)
7218{
7219	struct bce_softc *sc;
7220	struct ifnet *ifp;
7221	u32 status_attn_bits;
7222	u16 hw_rx_cons, hw_tx_cons;
7223
7224	sc = xsc;
7225	ifp = sc->bce_ifp;
7226
7227	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
7228	DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_status_block(sc));
7229
7230	BCE_LOCK(sc);
7231
7232	DBRUN(sc->interrupts_generated++);
7233
7234	/* Synchnorize before we read from interface's status block */
7235	bus_dmamap_sync(sc->status_tag, sc->status_map,
7236	    BUS_DMASYNC_POSTREAD);
7237
7238	/*
7239	 * If the hardware status block index
7240	 * matches the last value read by the
7241	 * driver and we haven't asserted our
7242	 * interrupt then there's nothing to do.
7243	 */
7244	if ((sc->status_block->status_idx == sc->last_status_idx) &&
7245		(REG_RD(sc, BCE_PCICFG_MISC_STATUS) & BCE_PCICFG_MISC_STATUS_INTA_VALUE)) {
7246			DBPRINT(sc, BCE_VERBOSE_INTR, "%s(): Spurious interrupt.\n",
7247				__FUNCTION__);
7248			goto bce_intr_exit;
7249	}
7250
7251	/* Ack the interrupt and stop others from occuring. */
7252	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
7253		BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
7254		BCE_PCICFG_INT_ACK_CMD_MASK_INT);
7255
7256	/* Check if the hardware has finished any work. */
7257	hw_rx_cons = bce_get_hw_rx_cons(sc);
7258	hw_tx_cons = bce_get_hw_tx_cons(sc);
7259
7260	/* Keep processing data as long as there is work to do. */
7261	for (;;) {
7262
7263		status_attn_bits = sc->status_block->status_attn_bits;
7264
7265	DBRUNIF(DB_RANDOMTRUE(unexpected_attention_sim_control),
7266		BCE_PRINTF("Simulating unexpected status attention bit set.");
7267		sc->unexpected_attention_sim_count++;
7268		status_attn_bits = status_attn_bits | STATUS_ATTN_BITS_PARITY_ERROR);
7269
7270		/* Was it a link change interrupt? */
7271		if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
7272			(sc->status_block->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE)) {
7273			bce_phy_intr(sc);
7274
7275			/* Clear any transient status updates during link state change. */
7276			REG_WR(sc, BCE_HC_COMMAND,
7277				sc->hc_command | BCE_HC_COMMAND_COAL_NOW_WO_INT);
7278			REG_RD(sc, BCE_HC_COMMAND);
7279		}
7280
7281		/* If any other attention is asserted then the chip is toast. */
7282		if (((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
7283			(sc->status_block->status_attn_bits_ack &
7284			~STATUS_ATTN_BITS_LINK_STATE))) {
7285
7286		sc->unexpected_attention_count++;
7287
7288			BCE_PRINTF("%s(%d): Fatal attention detected: 0x%08X\n",
7289				__FILE__, __LINE__, sc->status_block->status_attn_bits);
7290
7291			DBRUNMSG(BCE_FATAL,
7292				if (unexpected_attention_sim_control == 0)
7293					bce_breakpoint(sc));
7294
7295			bce_init_locked(sc);
7296			goto bce_intr_exit;
7297		}
7298
7299		/* Check for any completed RX frames. */
7300		if (hw_rx_cons != sc->hw_rx_cons)
7301			bce_rx_intr(sc);
7302
7303		/* Check for any completed TX frames. */
7304		if (hw_tx_cons != sc->hw_tx_cons)
7305			bce_tx_intr(sc);
7306
7307		/* Save the status block index value for use during the next interrupt. */
7308		sc->last_status_idx = sc->status_block->status_idx;
7309
7310		/* Prevent speculative reads from getting ahead of the status block. */
7311		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
7312			BUS_SPACE_BARRIER_READ);
7313
7314		/* If there's no work left then exit the interrupt service routine. */
7315		hw_rx_cons = bce_get_hw_rx_cons(sc);
7316		hw_tx_cons = bce_get_hw_tx_cons(sc);
7317
7318		if ((hw_rx_cons == sc->hw_rx_cons) && (hw_tx_cons == sc->hw_tx_cons))
7319			break;
7320
7321	}
7322
7323	bus_dmamap_sync(sc->status_tag,	sc->status_map,
7324	    BUS_DMASYNC_PREREAD);
7325
7326	/* Re-enable interrupts. */
7327	bce_enable_intr(sc, 0);
7328
7329	/* Handle any frames that arrived while handling the interrupt. */
7330	if (ifp->if_drv_flags & IFF_DRV_RUNNING && !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
7331		bce_start_locked(ifp);
7332
7333bce_intr_exit:
7334	BCE_UNLOCK(sc);
7335
7336	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
7337}
7338
7339
7340/****************************************************************************/
7341/* Programs the various packet receive modes (broadcast and multicast).     */
7342/*                                                                          */
7343/* Returns:                                                                 */
7344/*   Nothing.                                                               */
7345/****************************************************************************/
7346static void
7347bce_set_rx_mode(struct bce_softc *sc)
7348{
7349	struct ifnet *ifp;
7350	struct ifmultiaddr *ifma;
7351	u32 hashes[NUM_MC_HASH_REGISTERS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
7352	u32 rx_mode, sort_mode;
7353	int h, i;
7354
7355	DBENTER(BCE_VERBOSE_MISC);
7356
7357	BCE_LOCK_ASSERT(sc);
7358
7359	ifp = sc->bce_ifp;
7360
7361	/* Initialize receive mode default settings. */
7362	rx_mode   = sc->rx_mode & ~(BCE_EMAC_RX_MODE_PROMISCUOUS |
7363			    BCE_EMAC_RX_MODE_KEEP_VLAN_TAG);
7364	sort_mode = 1 | BCE_RPM_SORT_USER0_BC_EN;
7365
7366	/*
7367	 * ASF/IPMI/UMP firmware requires that VLAN tag stripping
7368	 * be enbled.
7369	 */
7370	if (!(BCE_IF_CAPABILITIES & IFCAP_VLAN_HWTAGGING) &&
7371		(!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)))
7372		rx_mode |= BCE_EMAC_RX_MODE_KEEP_VLAN_TAG;
7373
7374	/*
7375	 * Check for promiscuous, all multicast, or selected
7376	 * multicast address filtering.
7377	 */
7378	if (ifp->if_flags & IFF_PROMISC) {
7379		DBPRINT(sc, BCE_INFO_MISC, "Enabling promiscuous mode.\n");
7380
7381		/* Enable promiscuous mode. */
7382		rx_mode |= BCE_EMAC_RX_MODE_PROMISCUOUS;
7383		sort_mode |= BCE_RPM_SORT_USER0_PROM_EN;
7384	} else if (ifp->if_flags & IFF_ALLMULTI) {
7385		DBPRINT(sc, BCE_INFO_MISC, "Enabling all multicast mode.\n");
7386
7387		/* Enable all multicast addresses. */
7388		for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
7389			REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), 0xffffffff);
7390       	}
7391		sort_mode |= BCE_RPM_SORT_USER0_MC_EN;
7392	} else {
7393		/* Accept one or more multicast(s). */
7394		DBPRINT(sc, BCE_INFO_MISC, "Enabling selective multicast mode.\n");
7395
7396		if_maddr_rlock(ifp);
7397		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
7398			if (ifma->ifma_addr->sa_family != AF_LINK)
7399				continue;
7400			h = ether_crc32_le(LLADDR((struct sockaddr_dl *)
7401			    ifma->ifma_addr), ETHER_ADDR_LEN) & 0xFF;
7402			    hashes[(h & 0xE0) >> 5] |= 1 << (h & 0x1F);
7403		}
7404		if_maddr_runlock(ifp);
7405
7406		for (i = 0; i < NUM_MC_HASH_REGISTERS; i++)
7407			REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), hashes[i]);
7408
7409		sort_mode |= BCE_RPM_SORT_USER0_MC_HSH_EN;
7410	}
7411
7412	/* Only make changes if the recive mode has actually changed. */
7413	if (rx_mode != sc->rx_mode) {
7414		DBPRINT(sc, BCE_VERBOSE_MISC, "Enabling new receive mode: 0x%08X\n",
7415			rx_mode);
7416
7417		sc->rx_mode = rx_mode;
7418		REG_WR(sc, BCE_EMAC_RX_MODE, rx_mode);
7419	}
7420
7421	/* Disable and clear the exisitng sort before enabling a new sort. */
7422	REG_WR(sc, BCE_RPM_SORT_USER0, 0x0);
7423	REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode);
7424	REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode | BCE_RPM_SORT_USER0_ENA);
7425
7426	DBEXIT(BCE_VERBOSE_MISC);
7427}
7428
7429
7430/****************************************************************************/
7431/* Called periodically to updates statistics from the controllers           */
7432/* statistics block.                                                        */
7433/*                                                                          */
7434/* Returns:                                                                 */
7435/*   Nothing.                                                               */
7436/****************************************************************************/
7437static void
7438bce_stats_update(struct bce_softc *sc)
7439{
7440	struct ifnet *ifp;
7441	struct statistics_block *stats;
7442
7443	DBENTER(BCE_EXTREME_MISC);
7444
7445	ifp = sc->bce_ifp;
7446
7447	stats = (struct statistics_block *) sc->stats_block;
7448
7449	/*
7450	 * Certain controllers don't report
7451	 * carrier sense errors correctly.
7452	 * See errata E11_5708CA0_1165.
7453	 */
7454	if (!(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
7455	    !(BCE_CHIP_ID(sc) == BCE_CHIP_ID_5708_A0))
7456		ifp->if_oerrors += (u_long) stats->stat_Dot3StatsCarrierSenseErrors;
7457
7458	/*
7459	 * Update the sysctl statistics from the
7460	 * hardware statistics.
7461	 */
7462	sc->stat_IfHCInOctets =
7463		((u64) stats->stat_IfHCInOctets_hi << 32) +
7464		 (u64) stats->stat_IfHCInOctets_lo;
7465
7466	sc->stat_IfHCInBadOctets =
7467		((u64) stats->stat_IfHCInBadOctets_hi << 32) +
7468		 (u64) stats->stat_IfHCInBadOctets_lo;
7469
7470	sc->stat_IfHCOutOctets =
7471		((u64) stats->stat_IfHCOutOctets_hi << 32) +
7472		 (u64) stats->stat_IfHCOutOctets_lo;
7473
7474	sc->stat_IfHCOutBadOctets =
7475		((u64) stats->stat_IfHCOutBadOctets_hi << 32) +
7476		 (u64) stats->stat_IfHCOutBadOctets_lo;
7477
7478	sc->stat_IfHCInUcastPkts =
7479		((u64) stats->stat_IfHCInUcastPkts_hi << 32) +
7480		 (u64) stats->stat_IfHCInUcastPkts_lo;
7481
7482	sc->stat_IfHCInMulticastPkts =
7483		((u64) stats->stat_IfHCInMulticastPkts_hi << 32) +
7484		 (u64) stats->stat_IfHCInMulticastPkts_lo;
7485
7486	sc->stat_IfHCInBroadcastPkts =
7487		((u64) stats->stat_IfHCInBroadcastPkts_hi << 32) +
7488		 (u64) stats->stat_IfHCInBroadcastPkts_lo;
7489
7490	sc->stat_IfHCOutUcastPkts =
7491		((u64) stats->stat_IfHCOutUcastPkts_hi << 32) +
7492		 (u64) stats->stat_IfHCOutUcastPkts_lo;
7493
7494	sc->stat_IfHCOutMulticastPkts =
7495		((u64) stats->stat_IfHCOutMulticastPkts_hi << 32) +
7496		 (u64) stats->stat_IfHCOutMulticastPkts_lo;
7497
7498	sc->stat_IfHCOutBroadcastPkts =
7499		((u64) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
7500		 (u64) stats->stat_IfHCOutBroadcastPkts_lo;
7501
7502	sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors =
7503		stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
7504
7505	sc->stat_Dot3StatsCarrierSenseErrors =
7506		stats->stat_Dot3StatsCarrierSenseErrors;
7507
7508	sc->stat_Dot3StatsFCSErrors =
7509		stats->stat_Dot3StatsFCSErrors;
7510
7511	sc->stat_Dot3StatsAlignmentErrors =
7512		stats->stat_Dot3StatsAlignmentErrors;
7513
7514	sc->stat_Dot3StatsSingleCollisionFrames =
7515		stats->stat_Dot3StatsSingleCollisionFrames;
7516
7517	sc->stat_Dot3StatsMultipleCollisionFrames =
7518		stats->stat_Dot3StatsMultipleCollisionFrames;
7519
7520	sc->stat_Dot3StatsDeferredTransmissions =
7521		stats->stat_Dot3StatsDeferredTransmissions;
7522
7523	sc->stat_Dot3StatsExcessiveCollisions =
7524		stats->stat_Dot3StatsExcessiveCollisions;
7525
7526	sc->stat_Dot3StatsLateCollisions =
7527		stats->stat_Dot3StatsLateCollisions;
7528
7529	sc->stat_EtherStatsCollisions =
7530		stats->stat_EtherStatsCollisions;
7531
7532	sc->stat_EtherStatsFragments =
7533		stats->stat_EtherStatsFragments;
7534
7535	sc->stat_EtherStatsJabbers =
7536		stats->stat_EtherStatsJabbers;
7537
7538	sc->stat_EtherStatsUndersizePkts =
7539		stats->stat_EtherStatsUndersizePkts;
7540
7541	sc->stat_EtherStatsOversizePkts =
7542		stats->stat_EtherStatsOversizePkts;
7543
7544	sc->stat_EtherStatsPktsRx64Octets =
7545		stats->stat_EtherStatsPktsRx64Octets;
7546
7547	sc->stat_EtherStatsPktsRx65Octetsto127Octets =
7548		stats->stat_EtherStatsPktsRx65Octetsto127Octets;
7549
7550	sc->stat_EtherStatsPktsRx128Octetsto255Octets =
7551		stats->stat_EtherStatsPktsRx128Octetsto255Octets;
7552
7553	sc->stat_EtherStatsPktsRx256Octetsto511Octets =
7554		stats->stat_EtherStatsPktsRx256Octetsto511Octets;
7555
7556	sc->stat_EtherStatsPktsRx512Octetsto1023Octets =
7557		stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
7558
7559	sc->stat_EtherStatsPktsRx1024Octetsto1522Octets =
7560		stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
7561
7562	sc->stat_EtherStatsPktsRx1523Octetsto9022Octets =
7563		stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
7564
7565	sc->stat_EtherStatsPktsTx64Octets =
7566		stats->stat_EtherStatsPktsTx64Octets;
7567
7568	sc->stat_EtherStatsPktsTx65Octetsto127Octets =
7569		stats->stat_EtherStatsPktsTx65Octetsto127Octets;
7570
7571	sc->stat_EtherStatsPktsTx128Octetsto255Octets =
7572		stats->stat_EtherStatsPktsTx128Octetsto255Octets;
7573
7574	sc->stat_EtherStatsPktsTx256Octetsto511Octets =
7575		stats->stat_EtherStatsPktsTx256Octetsto511Octets;
7576
7577	sc->stat_EtherStatsPktsTx512Octetsto1023Octets =
7578		stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
7579
7580	sc->stat_EtherStatsPktsTx1024Octetsto1522Octets =
7581		stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
7582
7583	sc->stat_EtherStatsPktsTx1523Octetsto9022Octets =
7584		stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
7585
7586	sc->stat_XonPauseFramesReceived =
7587		stats->stat_XonPauseFramesReceived;
7588
7589	sc->stat_XoffPauseFramesReceived =
7590		stats->stat_XoffPauseFramesReceived;
7591
7592	sc->stat_OutXonSent =
7593		stats->stat_OutXonSent;
7594
7595	sc->stat_OutXoffSent =
7596		stats->stat_OutXoffSent;
7597
7598	sc->stat_FlowControlDone =
7599		stats->stat_FlowControlDone;
7600
7601	sc->stat_MacControlFramesReceived =
7602		stats->stat_MacControlFramesReceived;
7603
7604	sc->stat_XoffStateEntered =
7605		stats->stat_XoffStateEntered;
7606
7607	sc->stat_IfInFramesL2FilterDiscards =
7608		stats->stat_IfInFramesL2FilterDiscards;
7609
7610	sc->stat_IfInRuleCheckerDiscards =
7611		stats->stat_IfInRuleCheckerDiscards;
7612
7613	sc->stat_IfInFTQDiscards =
7614		stats->stat_IfInFTQDiscards;
7615
7616	sc->stat_IfInMBUFDiscards =
7617		stats->stat_IfInMBUFDiscards;
7618
7619	sc->stat_IfInRuleCheckerP4Hit =
7620		stats->stat_IfInRuleCheckerP4Hit;
7621
7622	sc->stat_CatchupInRuleCheckerDiscards =
7623		stats->stat_CatchupInRuleCheckerDiscards;
7624
7625	sc->stat_CatchupInFTQDiscards =
7626		stats->stat_CatchupInFTQDiscards;
7627
7628	sc->stat_CatchupInMBUFDiscards =
7629		stats->stat_CatchupInMBUFDiscards;
7630
7631	sc->stat_CatchupInRuleCheckerP4Hit =
7632		stats->stat_CatchupInRuleCheckerP4Hit;
7633
7634	sc->com_no_buffers = REG_RD_IND(sc, 0x120084);
7635
7636	/*
7637	 * Update the interface statistics from the
7638	 * hardware statistics.
7639	 */
7640	ifp->if_collisions =
7641		(u_long) sc->stat_EtherStatsCollisions;
7642
7643	/* ToDo: This method loses soft errors. */
7644	ifp->if_ierrors =
7645		(u_long) sc->stat_EtherStatsUndersizePkts +
7646		(u_long) sc->stat_EtherStatsOversizePkts +
7647		(u_long) sc->stat_IfInMBUFDiscards +
7648		(u_long) sc->stat_Dot3StatsAlignmentErrors +
7649		(u_long) sc->stat_Dot3StatsFCSErrors +
7650		(u_long) sc->stat_IfInRuleCheckerDiscards +
7651		(u_long) sc->stat_IfInFTQDiscards +
7652		(u_long) sc->com_no_buffers;
7653
7654	/* ToDo: This method loses soft errors. */
7655	ifp->if_oerrors =
7656		(u_long) sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
7657		(u_long) sc->stat_Dot3StatsExcessiveCollisions +
7658		(u_long) sc->stat_Dot3StatsLateCollisions;
7659
7660	/* ToDo: Add additional statistics. */
7661
7662	DBEXIT(BCE_EXTREME_MISC);
7663}
7664
7665
7666/****************************************************************************/
7667/* Periodic function to notify the bootcode that the driver is still        */
7668/* present.                                                                 */
7669/*                                                                          */
7670/* Returns:                                                                 */
7671/*   Nothing.                                                               */
7672/****************************************************************************/
7673static void
7674bce_pulse(void *xsc)
7675{
7676	struct bce_softc *sc = xsc;
7677	u32 msg;
7678
7679	DBENTER(BCE_EXTREME_MISC);
7680
7681	BCE_LOCK_ASSERT(sc);
7682
7683	/* Tell the firmware that the driver is still running. */
7684	msg = (u32) ++sc->bce_fw_drv_pulse_wr_seq;
7685	bce_shmem_wr(sc, BCE_DRV_PULSE_MB, msg);
7686
7687	/* Schedule the next pulse. */
7688	callout_reset(&sc->bce_pulse_callout, hz, bce_pulse, sc);
7689
7690	DBEXIT(BCE_EXTREME_MISC);
7691}
7692
7693
7694/****************************************************************************/
7695/* Periodic function to perform maintenance tasks.                          */
7696/*                                                                          */
7697/* Returns:                                                                 */
7698/*   Nothing.                                                               */
7699/****************************************************************************/
7700static void
7701bce_tick(void *xsc)
7702{
7703	struct bce_softc *sc = xsc;
7704	struct mii_data *mii;
7705	struct ifnet *ifp;
7706
7707	ifp = sc->bce_ifp;
7708
7709	DBENTER(BCE_EXTREME_MISC);
7710
7711	BCE_LOCK_ASSERT(sc);
7712
7713	/* Schedule the next tick. */
7714	callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
7715
7716	/* Update the statistics from the hardware statistics block. */
7717	bce_stats_update(sc);
7718
7719	/* Top off the receive and page chains. */
7720#ifdef BCE_JUMBO_HDRSPLIT
7721	bce_fill_pg_chain(sc);
7722#endif
7723	bce_fill_rx_chain(sc);
7724
7725	/* Check that chip hasn't hung. */
7726	bce_watchdog(sc);
7727
7728	/* If link is up already up then we're done. */
7729	if (sc->bce_link)
7730		goto bce_tick_exit;
7731
7732	/* Link is down.  Check what the PHY's doing. */
7733	mii = device_get_softc(sc->bce_miibus);
7734	mii_tick(mii);
7735
7736	/* Check if the link has come up. */
7737	if ((mii->mii_media_status & IFM_ACTIVE) &&
7738	    (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)) {
7739		DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Link up!\n", __FUNCTION__);
7740		sc->bce_link++;
7741		if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
7742		    IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX) &&
7743		    bootverbose)
7744			BCE_PRINTF("Gigabit link up!\n");
7745		/* Now that link is up, handle any outstanding TX traffic. */
7746		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
7747			DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Found pending TX traffic.\n",
7748				 __FUNCTION__);
7749			bce_start_locked(ifp);
7750		}
7751	}
7752
7753bce_tick_exit:
7754	DBEXIT(BCE_EXTREME_MISC);
7755	return;
7756}
7757
7758
7759#ifdef BCE_DEBUG
7760/****************************************************************************/
7761/* Allows the driver state to be dumped through the sysctl interface.       */
7762/*                                                                          */
7763/* Returns:                                                                 */
7764/*   0 for success, positive value for failure.                             */
7765/****************************************************************************/
7766static int
7767bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS)
7768{
7769        int error;
7770        int result;
7771        struct bce_softc *sc;
7772
7773        result = -1;
7774        error = sysctl_handle_int(oidp, &result, 0, req);
7775
7776        if (error || !req->newptr)
7777                return (error);
7778
7779        if (result == 1) {
7780                sc = (struct bce_softc *)arg1;
7781                bce_dump_driver_state(sc);
7782        }
7783
7784        return error;
7785}
7786
7787
7788/****************************************************************************/
7789/* Allows the hardware state to be dumped through the sysctl interface.     */
7790/*                                                                          */
7791/* Returns:                                                                 */
7792/*   0 for success, positive value for failure.                             */
7793/****************************************************************************/
7794static int
7795bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS)
7796{
7797        int error;
7798        int result;
7799        struct bce_softc *sc;
7800
7801        result = -1;
7802        error = sysctl_handle_int(oidp, &result, 0, req);
7803
7804        if (error || !req->newptr)
7805                return (error);
7806
7807        if (result == 1) {
7808                sc = (struct bce_softc *)arg1;
7809                bce_dump_hw_state(sc);
7810        }
7811
7812        return error;
7813}
7814
7815
7816/****************************************************************************/
7817/* Allows the bootcode state to be dumped through the sysctl interface.     */
7818/*                                                                          */
7819/* Returns:                                                                 */
7820/*   0 for success, positive value for failure.                             */
7821/****************************************************************************/
7822static int
7823bce_sysctl_bc_state(SYSCTL_HANDLER_ARGS)
7824{
7825        int error;
7826        int result;
7827        struct bce_softc *sc;
7828
7829        result = -1;
7830        error = sysctl_handle_int(oidp, &result, 0, req);
7831
7832        if (error || !req->newptr)
7833                return (error);
7834
7835        if (result == 1) {
7836                sc = (struct bce_softc *)arg1;
7837                bce_dump_bc_state(sc);
7838        }
7839
7840        return error;
7841}
7842
7843
7844/****************************************************************************/
7845/* Provides a sysctl interface to allow dumping the RX chain.               */
7846/*                                                                          */
7847/* Returns:                                                                 */
7848/*   0 for success, positive value for failure.                             */
7849/****************************************************************************/
7850static int
7851bce_sysctl_dump_rx_chain(SYSCTL_HANDLER_ARGS)
7852{
7853        int error;
7854        int result;
7855        struct bce_softc *sc;
7856
7857        result = -1;
7858        error = sysctl_handle_int(oidp, &result, 0, req);
7859
7860        if (error || !req->newptr)
7861                return (error);
7862
7863        if (result == 1) {
7864                sc = (struct bce_softc *)arg1;
7865                bce_dump_rx_chain(sc, 0, TOTAL_RX_BD);
7866        }
7867
7868        return error;
7869}
7870
7871
7872/****************************************************************************/
7873/* Provides a sysctl interface to allow dumping the TX chain.               */
7874/*                                                                          */
7875/* Returns:                                                                 */
7876/*   0 for success, positive value for failure.                             */
7877/****************************************************************************/
7878static int
7879bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
7880{
7881        int error;
7882        int result;
7883        struct bce_softc *sc;
7884
7885        result = -1;
7886        error = sysctl_handle_int(oidp, &result, 0, req);
7887
7888        if (error || !req->newptr)
7889                return (error);
7890
7891        if (result == 1) {
7892                sc = (struct bce_softc *)arg1;
7893                bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
7894        }
7895
7896        return error;
7897}
7898
7899
7900#ifdef BCE_JUMBO_HDRSPLIT
7901/****************************************************************************/
7902/* Provides a sysctl interface to allow dumping the page chain.             */
7903/*                                                                          */
7904/* Returns:                                                                 */
7905/*   0 for success, positive value for failure.                             */
7906/****************************************************************************/
7907static int
7908bce_sysctl_dump_pg_chain(SYSCTL_HANDLER_ARGS)
7909{
7910        int error;
7911        int result;
7912        struct bce_softc *sc;
7913
7914        result = -1;
7915        error = sysctl_handle_int(oidp, &result, 0, req);
7916
7917        if (error || !req->newptr)
7918                return (error);
7919
7920        if (result == 1) {
7921                sc = (struct bce_softc *)arg1;
7922                bce_dump_pg_chain(sc, 0, TOTAL_PG_BD);
7923        }
7924
7925        return error;
7926}
7927#endif
7928
7929/****************************************************************************/
7930/* Provides a sysctl interface to allow reading arbitrary NVRAM offsets in  */
7931/* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
7932/*                                                                          */
7933/* Returns:                                                                 */
7934/*   0 for success, positive value for failure.                             */
7935/****************************************************************************/
7936static int
7937bce_sysctl_nvram_read(SYSCTL_HANDLER_ARGS)
7938{
7939	struct bce_softc *sc = (struct bce_softc *)arg1;
7940	int error;
7941	u32 result;
7942	u32 val[1];
7943	u8 *data = (u8 *) val;
7944
7945	result = -1;
7946	error = sysctl_handle_int(oidp, &result, 0, req);
7947	if (error || (req->newptr == NULL))
7948		return (error);
7949
7950	bce_nvram_read(sc, result, data, 4);
7951	BCE_PRINTF("offset 0x%08X = 0x%08X\n", result, bce_be32toh(val[0]));
7952
7953	return (error);
7954}
7955
7956
7957/****************************************************************************/
7958/* Provides a sysctl interface to allow reading arbitrary registers in the  */
7959/* device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                            */
7960/*                                                                          */
7961/* Returns:                                                                 */
7962/*   0 for success, positive value for failure.                             */
7963/****************************************************************************/
7964static int
7965bce_sysctl_reg_read(SYSCTL_HANDLER_ARGS)
7966{
7967	struct bce_softc *sc = (struct bce_softc *)arg1;
7968	int error;
7969	u32 val, result;
7970
7971	result = -1;
7972	error = sysctl_handle_int(oidp, &result, 0, req);
7973	if (error || (req->newptr == NULL))
7974		return (error);
7975
7976	/* Make sure the register is accessible. */
7977	if (result < 0x8000) {
7978		val = REG_RD(sc, result);
7979		BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
7980	} else if (result < 0x0280000) {
7981		val = REG_RD_IND(sc, result);
7982		BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
7983	}
7984
7985	return (error);
7986}
7987
7988
7989/****************************************************************************/
7990/* Provides a sysctl interface to allow reading arbitrary PHY registers in  */
7991/* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
7992/*                                                                          */
7993/* Returns:                                                                 */
7994/*   0 for success, positive value for failure.                             */
7995/****************************************************************************/
7996static int
7997bce_sysctl_phy_read(SYSCTL_HANDLER_ARGS)
7998{
7999	struct bce_softc *sc;
8000	device_t dev;
8001	int error, result;
8002	u16 val;
8003
8004	result = -1;
8005	error = sysctl_handle_int(oidp, &result, 0, req);
8006	if (error || (req->newptr == NULL))
8007		return (error);
8008
8009	/* Make sure the register is accessible. */
8010	if (result < 0x20) {
8011		sc = (struct bce_softc *)arg1;
8012		dev = sc->bce_dev;
8013		val = bce_miibus_read_reg(dev, sc->bce_phy_addr, result);
8014		BCE_PRINTF("phy 0x%02X = 0x%04X\n", result, val);
8015	}
8016	return (error);
8017}
8018
8019
8020/****************************************************************************/
8021/* Provides a sysctl interface to allow reading a CID.                      */
8022/*                                                                          */
8023/* Returns:                                                                 */
8024/*   0 for success, positive value for failure.                             */
8025/****************************************************************************/
8026static int
8027bce_sysctl_dump_ctx(SYSCTL_HANDLER_ARGS)
8028{
8029	struct bce_softc *sc;
8030	int error;
8031	u16 result;
8032
8033	result = -1;
8034	error = sysctl_handle_int(oidp, &result, 0, req);
8035	if (error || (req->newptr == NULL))
8036		return (error);
8037
8038	/* Make sure the register is accessible. */
8039	if (result <= TX_CID) {
8040		sc = (struct bce_softc *)arg1;
8041		bce_dump_ctx(sc, result);
8042	}
8043
8044	return (error);
8045}
8046
8047
8048 /****************************************************************************/
8049/* Provides a sysctl interface to forcing the driver to dump state and      */
8050/* enter the debugger.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                */
8051/*                                                                          */
8052/* Returns:                                                                 */
8053/*   0 for success, positive value for failure.                             */
8054/****************************************************************************/
8055static int
8056bce_sysctl_breakpoint(SYSCTL_HANDLER_ARGS)
8057{
8058        int error;
8059        int result;
8060        struct bce_softc *sc;
8061
8062        result = -1;
8063        error = sysctl_handle_int(oidp, &result, 0, req);
8064
8065        if (error || !req->newptr)
8066                return (error);
8067
8068        if (result == 1) {
8069                sc = (struct bce_softc *)arg1;
8070                bce_breakpoint(sc);
8071        }
8072
8073        return error;
8074}
8075#endif
8076
8077
8078/****************************************************************************/
8079/* Adds any sysctl parameters for tuning or debugging purposes.             */
8080/*                                                                          */
8081/* Returns:                                                                 */
8082/*   0 for success, positive value for failure.                             */
8083/****************************************************************************/
8084static void
8085bce_add_sysctls(struct bce_softc *sc)
8086{
8087	struct sysctl_ctx_list *ctx;
8088	struct sysctl_oid_list *children;
8089
8090	DBENTER(BCE_VERBOSE_MISC);
8091
8092	ctx = device_get_sysctl_ctx(sc->bce_dev);
8093	children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->bce_dev));
8094
8095#ifdef BCE_DEBUG
8096	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8097		"l2fhdr_error_sim_control",
8098		CTLFLAG_RW, &l2fhdr_error_sim_control,
8099		0, "Debug control to force l2fhdr errors");
8100
8101	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8102		"l2fhdr_error_sim_count",
8103		CTLFLAG_RD, &sc->l2fhdr_error_sim_count,
8104		0, "Number of simulated l2_fhdr errors");
8105#endif
8106
8107	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8108		"l2fhdr_error_count",
8109		CTLFLAG_RD, &sc->l2fhdr_error_count,
8110		0, "Number of l2_fhdr errors");
8111
8112#ifdef BCE_DEBUG
8113	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8114		"mbuf_alloc_failed_sim_control",
8115		CTLFLAG_RW, &mbuf_alloc_failed_sim_control,
8116		0, "Debug control to force mbuf allocation failures");
8117
8118	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8119		"mbuf_alloc_failed_sim_count",
8120		CTLFLAG_RD, &sc->mbuf_alloc_failed_sim_count,
8121		0, "Number of simulated mbuf cluster allocation failures");
8122#endif
8123
8124	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8125		"mbuf_alloc_failed_count",
8126		CTLFLAG_RD, &sc->mbuf_alloc_failed_count,
8127		0, "Number of mbuf allocation failures");
8128
8129	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8130		"fragmented_mbuf_count",
8131		CTLFLAG_RD, &sc->fragmented_mbuf_count,
8132		0, "Number of fragmented mbufs");
8133
8134#ifdef BCE_DEBUG
8135	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8136		"dma_map_addr_failed_sim_control",
8137		CTLFLAG_RW, &dma_map_addr_failed_sim_control,
8138		0, "Debug control to force DMA mapping failures");
8139
8140	/* ToDo: Figure out how to update this value in bce_dma_map_addr(). */
8141	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8142		"dma_map_addr_failed_sim_count",
8143		CTLFLAG_RD, &sc->dma_map_addr_failed_sim_count,
8144		0, "Number of simulated DMA mapping failures");
8145
8146#endif
8147
8148	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8149		"dma_map_addr_rx_failed_count",
8150		CTLFLAG_RD, &sc->dma_map_addr_rx_failed_count,
8151		0, "Number of RX DMA mapping failures");
8152
8153	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8154		"dma_map_addr_tx_failed_count",
8155		CTLFLAG_RD, &sc->dma_map_addr_tx_failed_count,
8156		0, "Number of TX DMA mapping failures");
8157
8158#ifdef BCE_DEBUG
8159	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8160		"unexpected_attention_sim_control",
8161		CTLFLAG_RW, &unexpected_attention_sim_control,
8162		0, "Debug control to simulate unexpected attentions");
8163
8164	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8165		"unexpected_attention_sim_count",
8166		CTLFLAG_RW, &sc->unexpected_attention_sim_count,
8167		0, "Number of simulated unexpected attentions");
8168#endif
8169
8170	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8171		"unexpected_attention_count",
8172		CTLFLAG_RW, &sc->unexpected_attention_count,
8173		0, "Number of unexpected attentions");
8174
8175#ifdef BCE_DEBUG
8176	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8177		"debug_bootcode_running_failure",
8178		CTLFLAG_RW, &bootcode_running_failure_sim_control,
8179		0, "Debug control to force bootcode running failures");
8180
8181	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8182		"rx_low_watermark",
8183		CTLFLAG_RD, &sc->rx_low_watermark,
8184		0, "Lowest level of free rx_bd's");
8185
8186	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8187		"rx_empty_count",
8188		CTLFLAG_RD, &sc->rx_empty_count,
8189		0, "Number of times the RX chain was empty");
8190
8191	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8192		"tx_hi_watermark",
8193		CTLFLAG_RD, &sc->tx_hi_watermark,
8194		0, "Highest level of used tx_bd's");
8195
8196	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8197		"tx_full_count",
8198		CTLFLAG_RD, &sc->tx_full_count,
8199		0, "Number of times the TX chain was full");
8200
8201	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8202		"requested_tso_frames",
8203		CTLFLAG_RD, &sc->requested_tso_frames,
8204		0, "Number of TSO frames received");
8205
8206	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8207		"rx_interrupts",
8208		CTLFLAG_RD, &sc->rx_interrupts,
8209		0, "Number of RX interrupts");
8210
8211	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8212		"tx_interrupts",
8213		CTLFLAG_RD, &sc->tx_interrupts,
8214		0, "Number of TX interrupts");
8215
8216	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8217		"rx_intr_time",
8218		CTLFLAG_RD, &sc->rx_intr_time,
8219		"RX interrupt time");
8220
8221	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8222		"tx_intr_time",
8223		CTLFLAG_RD, &sc->tx_intr_time,
8224		"TX interrupt time");
8225#endif
8226
8227	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8228		"stat_IfHcInOctets",
8229		CTLFLAG_RD, &sc->stat_IfHCInOctets,
8230		"Bytes received");
8231
8232	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8233		"stat_IfHCInBadOctets",
8234		CTLFLAG_RD, &sc->stat_IfHCInBadOctets,
8235		"Bad bytes received");
8236
8237	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8238		"stat_IfHCOutOctets",
8239		CTLFLAG_RD, &sc->stat_IfHCOutOctets,
8240		"Bytes sent");
8241
8242	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8243		"stat_IfHCOutBadOctets",
8244		CTLFLAG_RD, &sc->stat_IfHCOutBadOctets,
8245		"Bad bytes sent");
8246
8247	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8248		"stat_IfHCInUcastPkts",
8249		CTLFLAG_RD, &sc->stat_IfHCInUcastPkts,
8250		"Unicast packets received");
8251
8252	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8253		"stat_IfHCInMulticastPkts",
8254		CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts,
8255		"Multicast packets received");
8256
8257	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8258		"stat_IfHCInBroadcastPkts",
8259		CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts,
8260		"Broadcast packets received");
8261
8262	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8263		"stat_IfHCOutUcastPkts",
8264		CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts,
8265		"Unicast packets sent");
8266
8267	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8268		"stat_IfHCOutMulticastPkts",
8269		CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts,
8270		"Multicast packets sent");
8271
8272	SYSCTL_ADD_ULONG(ctx, children, OID_AUTO,
8273		"stat_IfHCOutBroadcastPkts",
8274		CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts,
8275		"Broadcast packets sent");
8276
8277	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8278		"stat_emac_tx_stat_dot3statsinternalmactransmiterrors",
8279		CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors,
8280		0, "Internal MAC transmit errors");
8281
8282	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8283		"stat_Dot3StatsCarrierSenseErrors",
8284		CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors,
8285		0, "Carrier sense errors");
8286
8287	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8288		"stat_Dot3StatsFCSErrors",
8289		CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors,
8290		0, "Frame check sequence errors");
8291
8292	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8293		"stat_Dot3StatsAlignmentErrors",
8294		CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors,
8295		0, "Alignment errors");
8296
8297	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8298		"stat_Dot3StatsSingleCollisionFrames",
8299		CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames,
8300		0, "Single Collision Frames");
8301
8302	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8303		"stat_Dot3StatsMultipleCollisionFrames",
8304		CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames,
8305		0, "Multiple Collision Frames");
8306
8307	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8308		"stat_Dot3StatsDeferredTransmissions",
8309		CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions,
8310		0, "Deferred Transmissions");
8311
8312	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8313		"stat_Dot3StatsExcessiveCollisions",
8314		CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions,
8315		0, "Excessive Collisions");
8316
8317	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8318		"stat_Dot3StatsLateCollisions",
8319		CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions,
8320		0, "Late Collisions");
8321
8322	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8323		"stat_EtherStatsCollisions",
8324		CTLFLAG_RD, &sc->stat_EtherStatsCollisions,
8325		0, "Collisions");
8326
8327	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8328		"stat_EtherStatsFragments",
8329		CTLFLAG_RD, &sc->stat_EtherStatsFragments,
8330		0, "Fragments");
8331
8332	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8333		"stat_EtherStatsJabbers",
8334		CTLFLAG_RD, &sc->stat_EtherStatsJabbers,
8335		0, "Jabbers");
8336
8337	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8338		"stat_EtherStatsUndersizePkts",
8339		CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts,
8340		0, "Undersize packets");
8341
8342	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8343		"stat_EtherStatsOversizePkts",
8344		CTLFLAG_RD, &sc->stat_EtherStatsOversizePkts,
8345		0, "stat_EtherStatsOversizePkts");
8346
8347	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8348		"stat_EtherStatsPktsRx64Octets",
8349		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets,
8350		0, "Bytes received in 64 byte packets");
8351
8352	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8353		"stat_EtherStatsPktsRx65Octetsto127Octets",
8354		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets,
8355		0, "Bytes received in 65 to 127 byte packets");
8356
8357	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8358		"stat_EtherStatsPktsRx128Octetsto255Octets",
8359		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets,
8360		0, "Bytes received in 128 to 255 byte packets");
8361
8362	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8363		"stat_EtherStatsPktsRx256Octetsto511Octets",
8364		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets,
8365		0, "Bytes received in 256 to 511 byte packets");
8366
8367	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8368		"stat_EtherStatsPktsRx512Octetsto1023Octets",
8369		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets,
8370		0, "Bytes received in 512 to 1023 byte packets");
8371
8372	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8373		"stat_EtherStatsPktsRx1024Octetsto1522Octets",
8374		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets,
8375		0, "Bytes received in 1024 t0 1522 byte packets");
8376
8377	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8378		"stat_EtherStatsPktsRx1523Octetsto9022Octets",
8379		CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets,
8380		0, "Bytes received in 1523 to 9022 byte packets");
8381
8382	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8383		"stat_EtherStatsPktsTx64Octets",
8384		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets,
8385		0, "Bytes sent in 64 byte packets");
8386
8387	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8388		"stat_EtherStatsPktsTx65Octetsto127Octets",
8389		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets,
8390		0, "Bytes sent in 65 to 127 byte packets");
8391
8392	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8393		"stat_EtherStatsPktsTx128Octetsto255Octets",
8394		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets,
8395		0, "Bytes sent in 128 to 255 byte packets");
8396
8397	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8398		"stat_EtherStatsPktsTx256Octetsto511Octets",
8399		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets,
8400		0, "Bytes sent in 256 to 511 byte packets");
8401
8402	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8403		"stat_EtherStatsPktsTx512Octetsto1023Octets",
8404		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets,
8405		0, "Bytes sent in 512 to 1023 byte packets");
8406
8407	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8408		"stat_EtherStatsPktsTx1024Octetsto1522Octets",
8409		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets,
8410		0, "Bytes sent in 1024 to 1522 byte packets");
8411
8412	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8413		"stat_EtherStatsPktsTx1523Octetsto9022Octets",
8414		CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets,
8415		0, "Bytes sent in 1523 to 9022 byte packets");
8416
8417	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8418		"stat_XonPauseFramesReceived",
8419		CTLFLAG_RD, &sc->stat_XonPauseFramesReceived,
8420		0, "XON pause frames receved");
8421
8422	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8423		"stat_XoffPauseFramesReceived",
8424		CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived,
8425		0, "XOFF pause frames received");
8426
8427	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8428		"stat_OutXonSent",
8429		CTLFLAG_RD, &sc->stat_OutXonSent,
8430		0, "XON pause frames sent");
8431
8432	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8433		"stat_OutXoffSent",
8434		CTLFLAG_RD, &sc->stat_OutXoffSent,
8435		0, "XOFF pause frames sent");
8436
8437	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8438		"stat_FlowControlDone",
8439		CTLFLAG_RD, &sc->stat_FlowControlDone,
8440		0, "Flow control done");
8441
8442	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8443		"stat_MacControlFramesReceived",
8444		CTLFLAG_RD, &sc->stat_MacControlFramesReceived,
8445		0, "MAC control frames received");
8446
8447	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8448		"stat_XoffStateEntered",
8449		CTLFLAG_RD, &sc->stat_XoffStateEntered,
8450		0, "XOFF state entered");
8451
8452	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8453		"stat_IfInFramesL2FilterDiscards",
8454		CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards,
8455		0, "Received L2 packets discarded");
8456
8457	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8458		"stat_IfInRuleCheckerDiscards",
8459		CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards,
8460		0, "Received packets discarded by rule");
8461
8462	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8463		"stat_IfInFTQDiscards",
8464		CTLFLAG_RD, &sc->stat_IfInFTQDiscards,
8465		0, "Received packet FTQ discards");
8466
8467	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8468		"stat_IfInMBUFDiscards",
8469		CTLFLAG_RD, &sc->stat_IfInMBUFDiscards,
8470		0, "Received packets discarded due to lack of controller buffer memory");
8471
8472	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8473		"stat_IfInRuleCheckerP4Hit",
8474		CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit,
8475		0, "Received packets rule checker hits");
8476
8477	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8478		"stat_CatchupInRuleCheckerDiscards",
8479		CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards,
8480		0, "Received packets discarded in Catchup path");
8481
8482	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8483		"stat_CatchupInFTQDiscards",
8484		CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards,
8485		0, "Received packets discarded in FTQ in Catchup path");
8486
8487	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8488		"stat_CatchupInMBUFDiscards",
8489		CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards,
8490		0, "Received packets discarded in controller buffer memory in Catchup path");
8491
8492	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8493		"stat_CatchupInRuleCheckerP4Hit",
8494		CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit,
8495		0, "Received packets rule checker hits in Catchup path");
8496
8497	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8498		"com_no_buffers",
8499		CTLFLAG_RD, &sc->com_no_buffers,
8500		0, "Valid packets received but no RX buffers available");
8501
8502#ifdef BCE_DEBUG
8503	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8504		"driver_state", CTLTYPE_INT | CTLFLAG_RW,
8505		(void *)sc, 0,
8506		bce_sysctl_driver_state, "I", "Drive state information");
8507
8508	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8509		"hw_state", CTLTYPE_INT | CTLFLAG_RW,
8510		(void *)sc, 0,
8511		bce_sysctl_hw_state, "I", "Hardware state information");
8512
8513	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8514		"bc_state", CTLTYPE_INT | CTLFLAG_RW,
8515		(void *)sc, 0,
8516		bce_sysctl_bc_state, "I", "Bootcode state information");
8517
8518	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8519		"dump_rx_chain", CTLTYPE_INT | CTLFLAG_RW,
8520		(void *)sc, 0,
8521		bce_sysctl_dump_rx_chain, "I", "Dump rx_bd chain");
8522
8523	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8524		"dump_tx_chain", CTLTYPE_INT | CTLFLAG_RW,
8525		(void *)sc, 0,
8526		bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
8527
8528#ifdef BCE_JUMBO_HDRSPLIT
8529	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8530		"dump_pg_chain", CTLTYPE_INT | CTLFLAG_RW,
8531		(void *)sc, 0,
8532		bce_sysctl_dump_pg_chain, "I", "Dump page chain");
8533#endif
8534	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8535		"dump_ctx", CTLTYPE_INT | CTLFLAG_RW,
8536		(void *)sc, 0,
8537		bce_sysctl_dump_ctx, "I", "Dump context memory");
8538
8539	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8540		"breakpoint", CTLTYPE_INT | CTLFLAG_RW,
8541		(void *)sc, 0,
8542		bce_sysctl_breakpoint, "I", "Driver breakpoint");
8543
8544	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8545		"reg_read", CTLTYPE_INT | CTLFLAG_RW,
8546		(void *)sc, 0,
8547		bce_sysctl_reg_read, "I", "Register read");
8548
8549	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8550		"nvram_read", CTLTYPE_INT | CTLFLAG_RW,
8551		(void *)sc, 0,
8552		bce_sysctl_nvram_read, "I", "NVRAM read");
8553
8554	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
8555		"phy_read", CTLTYPE_INT | CTLFLAG_RW,
8556		(void *)sc, 0,
8557		bce_sysctl_phy_read, "I", "PHY register read");
8558
8559#endif
8560
8561	DBEXIT(BCE_VERBOSE_MISC);
8562}
8563
8564
8565/****************************************************************************/
8566/* BCE Debug Routines                                                       */
8567/****************************************************************************/
8568#ifdef BCE_DEBUG
8569
8570/****************************************************************************/
8571/* Freezes the controller to allow for a cohesive state dump.               */
8572/*                                                                          */
8573/* Returns:                                                                 */
8574/*   Nothing.                                                               */
8575/****************************************************************************/
8576static void
8577bce_freeze_controller(struct bce_softc *sc)
8578{
8579	u32 val;
8580	val = REG_RD(sc, BCE_MISC_COMMAND);
8581	val |= BCE_MISC_COMMAND_DISABLE_ALL;
8582	REG_WR(sc, BCE_MISC_COMMAND, val);
8583}
8584
8585
8586/****************************************************************************/
8587/* Unfreezes the controller after a freeze operation.  This may not always  */
8588/* work and the controller will require a reset!                            */
8589/*                                                                          */
8590/* Returns:                                                                 */
8591/*   Nothing.                                                               */
8592/****************************************************************************/
8593static void
8594bce_unfreeze_controller(struct bce_softc *sc)
8595{
8596	u32 val;
8597	val = REG_RD(sc, BCE_MISC_COMMAND);
8598	val |= BCE_MISC_COMMAND_ENABLE_ALL;
8599	REG_WR(sc, BCE_MISC_COMMAND, val);
8600}
8601
8602
8603/****************************************************************************/
8604/* Prints out Ethernet frame information from an mbuf.                      */
8605/*                                                                          */
8606/* Partially decode an Ethernet frame to look at some important headers.    */
8607/*                                                                          */
8608/* Returns:                                                                 */
8609/*   Nothing.                                                               */
8610/****************************************************************************/
8611static void
8612bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
8613{
8614	struct ether_vlan_header *eh;
8615	u16 etype;
8616	int ehlen;
8617	struct ip *ip;
8618	struct tcphdr *th;
8619	struct udphdr *uh;
8620	struct arphdr *ah;
8621
8622		BCE_PRINTF(
8623			"-----------------------------"
8624			" Frame Decode "
8625			"-----------------------------\n");
8626
8627	eh = mtod(m, struct ether_vlan_header *);
8628
8629	/* Handle VLAN encapsulation if present. */
8630	if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
8631		etype = ntohs(eh->evl_proto);
8632		ehlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
8633	} else {
8634		etype = ntohs(eh->evl_encap_proto);
8635		ehlen = ETHER_HDR_LEN;
8636	}
8637
8638	/* ToDo: Add VLAN output. */
8639	BCE_PRINTF("enet: dest = %6D, src = %6D, type = 0x%04X, hlen = %d\n",
8640		eh->evl_dhost, ":", eh->evl_shost, ":", etype, ehlen);
8641
8642	switch (etype) {
8643		case ETHERTYPE_IP:
8644			ip = (struct ip *)(m->m_data + ehlen);
8645			BCE_PRINTF("--ip: dest = 0x%08X , src = 0x%08X, len = %d bytes, "
8646				"protocol = 0x%02X, xsum = 0x%04X\n",
8647				ntohl(ip->ip_dst.s_addr), ntohl(ip->ip_src.s_addr),
8648				ntohs(ip->ip_len), ip->ip_p, ntohs(ip->ip_sum));
8649
8650			switch (ip->ip_p) {
8651				case IPPROTO_TCP:
8652					th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
8653					BCE_PRINTF("-tcp: dest = %d, src = %d, hlen = %d bytes, "
8654						"flags = 0x%b, csum = 0x%04X\n",
8655						ntohs(th->th_dport), ntohs(th->th_sport), (th->th_off << 2),
8656						th->th_flags, "\20\10CWR\07ECE\06URG\05ACK\04PSH\03RST\02SYN\01FIN",
8657						ntohs(th->th_sum));
8658					break;
8659				case IPPROTO_UDP:
8660        		    uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
8661					BCE_PRINTF("-udp: dest = %d, src = %d, len = %d bytes, "
8662						"csum = 0x%04X\n", ntohs(uh->uh_dport), ntohs(uh->uh_sport),
8663						ntohs(uh->uh_ulen), ntohs(uh->uh_sum));
8664					break;
8665				case IPPROTO_ICMP:
8666					BCE_PRINTF("icmp:\n");
8667					break;
8668				default:
8669					BCE_PRINTF("----: Other IP protocol.\n");
8670			}
8671			break;
8672		case ETHERTYPE_IPV6:
8673			BCE_PRINTF("ipv6: No decode supported.\n");
8674			break;
8675		case ETHERTYPE_ARP:
8676			BCE_PRINTF("-arp: ");
8677			ah = (struct arphdr *) (m->m_data + ehlen);
8678			switch (ntohs(ah->ar_op)) {
8679				case ARPOP_REVREQUEST:
8680					printf("reverse ARP request\n");
8681					break;
8682				case ARPOP_REVREPLY:
8683					printf("reverse ARP reply\n");
8684					break;
8685				case ARPOP_REQUEST:
8686					printf("ARP request\n");
8687					break;
8688				case ARPOP_REPLY:
8689					printf("ARP reply\n");
8690					break;
8691				default:
8692					printf("other ARP operation\n");
8693			}
8694			break;
8695		default:
8696			BCE_PRINTF("----: Other protocol.\n");
8697	}
8698
8699	BCE_PRINTF(
8700		"-----------------------------"
8701		"--------------"
8702		"-----------------------------\n");
8703}
8704
8705
8706/****************************************************************************/
8707/* Prints out information about an mbuf.                                    */
8708/*                                                                          */
8709/* Returns:                                                                 */
8710/*   Nothing.                                                               */
8711/****************************************************************************/
8712static __attribute__ ((noinline)) void
8713bce_dump_mbuf(struct bce_softc *sc, struct mbuf *m)
8714{
8715	struct mbuf *mp = m;
8716
8717	if (m == NULL) {
8718		BCE_PRINTF("mbuf: null pointer\n");
8719		return;
8720	}
8721
8722	while (mp) {
8723		BCE_PRINTF("mbuf: %p, m_len = %d, m_flags = 0x%b, m_data = %p\n",
8724			mp, mp->m_len, mp->m_flags,
8725			"\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY",
8726			mp->m_data);
8727
8728		if (mp->m_flags & M_PKTHDR) {
8729			BCE_PRINTF("- m_pkthdr: len = %d, flags = 0x%b, csum_flags = %b\n",
8730				mp->m_pkthdr.len, mp->m_flags,
8731				"\20\12M_BCAST\13M_MCAST\14M_FRAG\15M_FIRSTFRAG"
8732				"\16M_LASTFRAG\21M_VLANTAG\22M_PROMISC\23M_NOFREE",
8733				mp->m_pkthdr.csum_flags,
8734				"\20\1CSUM_IP\2CSUM_TCP\3CSUM_UDP\4CSUM_IP_FRAGS"
8735				"\5CSUM_FRAGMENT\6CSUM_TSO\11CSUM_IP_CHECKED"
8736				"\12CSUM_IP_VALID\13CSUM_DATA_VALID\14CSUM_PSEUDO_HDR");
8737		}
8738
8739		if (mp->m_flags & M_EXT) {
8740			BCE_PRINTF("- m_ext: %p, ext_size = %d, type = ",
8741				mp->m_ext.ext_buf, mp->m_ext.ext_size);
8742			switch (mp->m_ext.ext_type) {
8743				case EXT_CLUSTER:    printf("EXT_CLUSTER\n"); break;
8744				case EXT_SFBUF:      printf("EXT_SFBUF\n"); break;
8745				case EXT_JUMBO9:     printf("EXT_JUMBO9\n"); break;
8746				case EXT_JUMBO16:    printf("EXT_JUMBO16\n"); break;
8747				case EXT_PACKET:     printf("EXT_PACKET\n"); break;
8748				case EXT_MBUF:       printf("EXT_MBUF\n"); break;
8749				case EXT_NET_DRV:    printf("EXT_NET_DRV\n"); break;
8750				case EXT_MOD_TYPE:   printf("EXT_MDD_TYPE\n"); break;
8751				case EXT_DISPOSABLE: printf("EXT_DISPOSABLE\n"); break;
8752				case EXT_EXTREF:     printf("EXT_EXTREF\n"); break;
8753				default:             printf("UNKNOWN\n");
8754			}
8755		}
8756
8757		mp = mp->m_next;
8758	}
8759}
8760
8761
8762/****************************************************************************/
8763/* Prints out the mbufs in the TX mbuf chain.                               */
8764/*                                                                          */
8765/* Returns:                                                                 */
8766/*   Nothing.                                                               */
8767/****************************************************************************/
8768static __attribute__ ((noinline)) void
8769bce_dump_tx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
8770{
8771	struct mbuf *m;
8772
8773	BCE_PRINTF(
8774		"----------------------------"
8775		"  tx mbuf data  "
8776		"----------------------------\n");
8777
8778	for (int i = 0; i < count; i++) {
8779	 	m = sc->tx_mbuf_ptr[chain_prod];
8780		BCE_PRINTF("txmbuf[0x%04X]\n", chain_prod);
8781		bce_dump_mbuf(sc, m);
8782		chain_prod = TX_CHAIN_IDX(NEXT_TX_BD(chain_prod));
8783	}
8784
8785	BCE_PRINTF(
8786		"----------------------------"
8787		"----------------"
8788		"----------------------------\n");
8789}
8790
8791
8792/****************************************************************************/
8793/* Prints out the mbufs in the RX mbuf chain.                               */
8794/*                                                                          */
8795/* Returns:                                                                 */
8796/*   Nothing.                                                               */
8797/****************************************************************************/
8798static __attribute__ ((noinline)) void
8799bce_dump_rx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
8800{
8801	struct mbuf *m;
8802
8803	BCE_PRINTF(
8804		"----------------------------"
8805		"  rx mbuf data  "
8806		"----------------------------\n");
8807
8808	for (int i = 0; i < count; i++) {
8809	 	m = sc->rx_mbuf_ptr[chain_prod];
8810		BCE_PRINTF("rxmbuf[0x%04X]\n", chain_prod);
8811		bce_dump_mbuf(sc, m);
8812		chain_prod = RX_CHAIN_IDX(NEXT_RX_BD(chain_prod));
8813	}
8814
8815
8816	BCE_PRINTF(
8817		"----------------------------"
8818		"----------------"
8819		"----------------------------\n");
8820}
8821
8822
8823#ifdef BCE_JUMBO_HDRSPLIT
8824/****************************************************************************/
8825/* Prints out the mbufs in the mbuf page chain.                             */
8826/*                                                                          */
8827/* Returns:                                                                 */
8828/*   Nothing.                                                               */
8829/****************************************************************************/
8830static __attribute__ ((noinline)) void
8831bce_dump_pg_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
8832{
8833	struct mbuf *m;
8834
8835	BCE_PRINTF(
8836		"----------------------------"
8837		"  pg mbuf data  "
8838		"----------------------------\n");
8839
8840	for (int i = 0; i < count; i++) {
8841	 	m = sc->pg_mbuf_ptr[chain_prod];
8842		BCE_PRINTF("pgmbuf[0x%04X]\n", chain_prod);
8843		bce_dump_mbuf(sc, m);
8844		chain_prod = PG_CHAIN_IDX(NEXT_PG_BD(chain_prod));
8845	}
8846
8847
8848	BCE_PRINTF(
8849		"----------------------------"
8850		"----------------"
8851		"----------------------------\n");
8852}
8853#endif
8854
8855
8856/****************************************************************************/
8857/* Prints out a tx_bd structure.                                            */
8858/*                                                                          */
8859/* Returns:                                                                 */
8860/*   Nothing.                                                               */
8861/****************************************************************************/
8862static __attribute__ ((noinline)) void
8863bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
8864{
8865	if (idx > MAX_TX_BD)
8866		/* Index out of range. */
8867		BCE_PRINTF("tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
8868	else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
8869		/* TX Chain page pointer. */
8870		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
8871			idx, txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo);
8872	else {
8873			/* Normal tx_bd entry. */
8874			BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
8875				"vlan tag= 0x%04X, flags = 0x%04X (", idx,
8876				txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
8877				txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag,
8878				txbd->tx_bd_flags);
8879
8880			if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT)
8881				printf(" CONN_FAULT");
8882
8883			if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM)
8884				printf(" TCP_UDP_CKSUM");
8885
8886			if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM)
8887				printf(" IP_CKSUM");
8888
8889			if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG)
8890				printf("  VLAN");
8891
8892			if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW)
8893				printf(" COAL_NOW");
8894
8895			if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC)
8896				printf(" DONT_GEN_CRC");
8897
8898			if (txbd->tx_bd_flags & TX_BD_FLAGS_START)
8899				printf(" START");
8900
8901			if (txbd->tx_bd_flags & TX_BD_FLAGS_END)
8902				printf(" END");
8903
8904			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO)
8905				printf(" LSO");
8906
8907			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD)
8908				printf(" OPTION_WORD");
8909
8910			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS)
8911				printf(" FLAGS");
8912
8913			if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP)
8914				printf(" SNAP");
8915
8916			printf(" )\n");
8917		}
8918
8919}
8920
8921
8922/****************************************************************************/
8923/* Prints out a rx_bd structure.                                            */
8924/*                                                                          */
8925/* Returns:                                                                 */
8926/*   Nothing.                                                               */
8927/****************************************************************************/
8928static __attribute__ ((noinline)) void
8929bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd)
8930{
8931	if (idx > MAX_RX_BD)
8932		/* Index out of range. */
8933		BCE_PRINTF("rx_bd[0x%04X]: Invalid rx_bd index!\n", idx);
8934	else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
8935		/* RX Chain page pointer. */
8936		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
8937			idx, rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo);
8938	else
8939		/* Normal rx_bd entry. */
8940		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
8941			"flags = 0x%08X\n", idx,
8942			rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo,
8943			rxbd->rx_bd_len, rxbd->rx_bd_flags);
8944}
8945
8946
8947#ifdef BCE_JUMBO_HDRSPLIT
8948/****************************************************************************/
8949/* Prints out a rx_bd structure in the page chain.                          */
8950/*                                                                          */
8951/* Returns:                                                                 */
8952/*   Nothing.                                                               */
8953/****************************************************************************/
8954static __attribute__ ((noinline)) void
8955bce_dump_pgbd(struct bce_softc *sc, int idx, struct rx_bd *pgbd)
8956{
8957	if (idx > MAX_PG_BD)
8958		/* Index out of range. */
8959		BCE_PRINTF("pg_bd[0x%04X]: Invalid pg_bd index!\n", idx);
8960	else if ((idx & USABLE_PG_BD_PER_PAGE) == USABLE_PG_BD_PER_PAGE)
8961		/* Page Chain page pointer. */
8962		BCE_PRINTF("px_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
8963			idx, pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo);
8964	else
8965		/* Normal rx_bd entry. */
8966		BCE_PRINTF("pg_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
8967			"flags = 0x%08X\n", idx,
8968			pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo,
8969			pgbd->rx_bd_len, pgbd->rx_bd_flags);
8970}
8971#endif
8972
8973
8974/****************************************************************************/
8975/* Prints out a l2_fhdr structure.                                          */
8976/*                                                                          */
8977/* Returns:                                                                 */
8978/*   Nothing.                                                               */
8979/****************************************************************************/
8980static __attribute__ ((noinline)) void
8981bce_dump_l2fhdr(struct bce_softc *sc, int idx, struct l2_fhdr *l2fhdr)
8982{
8983	BCE_PRINTF("l2_fhdr[0x%04X]: status = 0x%b, "
8984		"pkt_len = %d, vlan = 0x%04x, ip_xsum/hdr_len = 0x%04X, "
8985		"tcp_udp_xsum = 0x%04X\n", idx,
8986		l2fhdr->l2_fhdr_status, BCE_L2FHDR_PRINTFB,
8987		l2fhdr->l2_fhdr_pkt_len, l2fhdr->l2_fhdr_vlan_tag,
8988		l2fhdr->l2_fhdr_ip_xsum, l2fhdr->l2_fhdr_tcp_udp_xsum);
8989}
8990
8991
8992/****************************************************************************/
8993/* Prints out context memory info.  (Only useful for CID 0 to 16.)          */
8994/*                                                                          */
8995/* Returns:                                                                 */
8996/*   Nothing.                                                               */
8997/****************************************************************************/
8998static __attribute__ ((noinline)) void
8999bce_dump_ctx(struct bce_softc *sc, u16 cid)
9000{
9001	if (cid <= TX_CID) {
9002		BCE_PRINTF(
9003			"----------------------------"
9004			"    CTX Data    "
9005			"----------------------------\n");
9006
9007		BCE_PRINTF("     0x%04X - (CID) Context ID\n", cid);
9008
9009		if (cid == RX_CID) {
9010			BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BDIDX) host rx "
9011				"producer index\n",
9012				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BDIDX));
9013			BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BSEQ) host byte sequence\n",
9014				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BSEQ));
9015			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BSEQ) h/w byte sequence\n",
9016				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BSEQ));
9017			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_HI) h/w buffer "
9018				"descriptor address\n",
9019 				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_HI));
9020			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_LO) h/w buffer "
9021				"descriptor address\n",
9022				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_LO));
9023			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDIDX) h/w rx consumer index\n",
9024				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDIDX));
9025			BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_PG_BDIDX) host page "
9026				"producer index\n",
9027				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_PG_BDIDX));
9028			BCE_PRINTF(" 0x%08X - (L2CTX_RX_PG_BUF_SIZE) host rx_bd/page "
9029				"buffer size\n",
9030				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_PG_BUF_SIZE));
9031			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_HI) h/w page "
9032				"chain address\n",
9033				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_PG_BDHADDR_HI));
9034			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_LO) h/w page "
9035				"chain address\n",
9036				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_PG_BDHADDR_LO));
9037			BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDIDX) h/w page "
9038				"consumer index\n",
9039				CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_PG_BDIDX));
9040		} else if (cid == TX_CID) {
9041			if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
9042				(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
9043				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE_XI) ctx type\n",
9044					CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE_XI));
9045				BCE_PRINTF(" 0x%08X - (L2CTX_CMD_TX_TYPE_XI) ctx cmd\n",
9046					CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_CMD_TYPE_XI));
9047				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI_XI) h/w buffer "
9048					"descriptor address\n",	CTX_RD(sc,
9049					GET_CID_ADDR(cid), BCE_L2CTX_TX_TBDR_BHADDR_HI_XI));
9050				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO_XI) h/w buffer "
9051					"descriptor address\n", CTX_RD(sc,
9052					GET_CID_ADDR(cid), BCE_L2CTX_TX_TBDR_BHADDR_LO_XI));
9053				BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX_XI) host producer "
9054					"index\n", CTX_RD(sc, GET_CID_ADDR(cid),
9055					BCE_L2CTX_TX_HOST_BIDX_XI));
9056				BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ_XI) host byte "
9057					"sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
9058					BCE_L2CTX_TX_HOST_BSEQ_XI));
9059			} else {
9060				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE) ctx type\n",
9061					CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE));
9062				BCE_PRINTF(" 0x%08X - (L2CTX_TX_CMD_TYPE) ctx cmd\n",
9063					CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_CMD_TYPE));
9064				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI) h/w buffer "
9065					"descriptor address\n", CTX_RD(sc, GET_CID_ADDR(cid),
9066					BCE_L2CTX_TX_TBDR_BHADDR_HI));
9067				BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO) h/w buffer "
9068					"descriptor address\n", CTX_RD(sc, GET_CID_ADDR(cid),
9069					BCE_L2CTX_TX_TBDR_BHADDR_LO));
9070				BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX) host producer "
9071					"index\n", CTX_RD(sc, GET_CID_ADDR(cid),
9072					BCE_L2CTX_TX_HOST_BIDX));
9073				BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ) host byte "
9074					"sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
9075					BCE_L2CTX_TX_HOST_BSEQ));
9076			}
9077		} else
9078			BCE_PRINTF(" Unknown CID\n");
9079
9080		BCE_PRINTF(
9081			"----------------------------"
9082			"    Raw CTX     "
9083			"----------------------------\n");
9084
9085		for (int i = 0x0; i < 0x300; i += 0x10) {
9086			BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n", i,
9087				CTX_RD(sc, GET_CID_ADDR(cid), i),
9088				CTX_RD(sc, GET_CID_ADDR(cid), i + 0x4),
9089				CTX_RD(sc, GET_CID_ADDR(cid), i + 0x8),
9090				CTX_RD(sc, GET_CID_ADDR(cid), i + 0xc));
9091		}
9092
9093
9094		BCE_PRINTF(
9095			"----------------------------"
9096			"----------------"
9097			"----------------------------\n");
9098	}
9099}
9100
9101
9102/****************************************************************************/
9103/* Prints out the FTQ data.                                                 */
9104/*                                                                          */
9105/* Returns:                                                                */
9106/*   Nothing.                                                               */
9107/****************************************************************************/
9108static __attribute__ ((noinline)) void
9109bce_dump_ftqs(struct bce_softc *sc)
9110{
9111	u32 cmd, ctl, cur_depth, max_depth, valid_cnt, val;
9112
9113	BCE_PRINTF(
9114		"----------------------------"
9115		"    FTQ Data    "
9116		"----------------------------\n");
9117
9118	BCE_PRINTF("   FTQ    Command    Control   Depth_Now  Max_Depth  Valid_Cnt \n");
9119	BCE_PRINTF(" ------- ---------- ---------- ---------- ---------- ----------\n");
9120
9121	/* Setup the generic statistic counters for the FTQ valid count. */
9122	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PPQ_VALID_CNT << 24) |
9123		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT  << 16) |
9124		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT   <<  8) |
9125		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT);
9126	REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
9127
9128	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCHQ_VALID_CNT  << 24) |
9129		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT  << 16) |
9130		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT <<  8) |
9131		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT);
9132	REG_WR(sc, BCE_HC_STAT_GEN_SEL_1, val);
9133
9134	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPATQ_VALID_CNT  << 24) |
9135		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT  << 16) |
9136		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT   <<  8) |
9137		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT);
9138	REG_WR(sc, BCE_HC_STAT_GEN_SEL_2, val);
9139
9140	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMQ_VALID_CNT   << 24) |
9141		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT  << 16) |
9142		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT  <<  8) |
9143		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT);
9144	REG_WR(sc, BCE_HC_STAT_GEN_SEL_3, val);
9145
9146	/* Input queue to the Receive Lookup state machine */
9147	cmd = REG_RD(sc, BCE_RLUP_FTQ_CMD);
9148	ctl = REG_RD(sc, BCE_RLUP_FTQ_CTL);
9149	cur_depth = (ctl & BCE_RLUP_FTQ_CTL_CUR_DEPTH) >> 22;
9150	max_depth = (ctl & BCE_RLUP_FTQ_CTL_MAX_DEPTH) >> 12;
9151	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
9152	BCE_PRINTF(" RLUP    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9153		cmd, ctl, cur_depth, max_depth, valid_cnt);
9154
9155	/* Input queue to the Receive Processor */
9156	cmd = REG_RD_IND(sc, BCE_RXP_FTQ_CMD);
9157	ctl = REG_RD_IND(sc, BCE_RXP_FTQ_CTL);
9158	cur_depth = (ctl & BCE_RXP_FTQ_CTL_CUR_DEPTH) >> 22;
9159	max_depth = (ctl & BCE_RXP_FTQ_CTL_MAX_DEPTH) >> 12;
9160	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
9161	BCE_PRINTF(" RXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9162		cmd, ctl, cur_depth, max_depth, valid_cnt);
9163
9164	/* Input queue to the Recevie Processor */
9165	cmd = REG_RD_IND(sc, BCE_RXP_CFTQ_CMD);
9166	ctl = REG_RD_IND(sc, BCE_RXP_CFTQ_CTL);
9167	cur_depth = (ctl & BCE_RXP_CFTQ_CTL_CUR_DEPTH) >> 22;
9168	max_depth = (ctl & BCE_RXP_CFTQ_CTL_MAX_DEPTH) >> 12;
9169	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
9170	BCE_PRINTF(" RXPC    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9171		cmd, ctl, cur_depth, max_depth, valid_cnt);
9172
9173	/* Input queue to the Receive Virtual to Physical state machine */
9174	cmd = REG_RD(sc, BCE_RV2P_PFTQ_CMD);
9175	ctl = REG_RD(sc, BCE_RV2P_PFTQ_CTL);
9176	cur_depth = (ctl & BCE_RV2P_PFTQ_CTL_CUR_DEPTH) >> 22;
9177	max_depth = (ctl & BCE_RV2P_PFTQ_CTL_MAX_DEPTH) >> 12;
9178	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
9179	BCE_PRINTF(" RV2PP   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9180		cmd, ctl, cur_depth, max_depth, valid_cnt);
9181
9182	/* Input queue to the Recevie Virtual to Physical state machine */
9183	cmd = REG_RD(sc, BCE_RV2P_MFTQ_CMD);
9184	ctl = REG_RD(sc, BCE_RV2P_MFTQ_CTL);
9185	cur_depth = (ctl & BCE_RV2P_MFTQ_CTL_CUR_DEPTH) >> 22;
9186	max_depth = (ctl & BCE_RV2P_MFTQ_CTL_MAX_DEPTH) >> 12;
9187	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT4);
9188	BCE_PRINTF(" RV2PM   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9189		cmd, ctl, cur_depth, max_depth, valid_cnt);
9190
9191	/* Input queue to the Receive Virtual to Physical state machine */
9192	cmd = REG_RD(sc, BCE_RV2P_TFTQ_CMD);
9193	ctl = REG_RD(sc, BCE_RV2P_TFTQ_CTL);
9194	cur_depth = (ctl & BCE_RV2P_TFTQ_CTL_CUR_DEPTH) >> 22;
9195	max_depth = (ctl & BCE_RV2P_TFTQ_CTL_MAX_DEPTH) >> 12;
9196	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT5);
9197	BCE_PRINTF(" RV2PT   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9198		cmd, ctl, cur_depth, max_depth, valid_cnt);
9199
9200	/* Input queue to the Receive DMA state machine */
9201	cmd = REG_RD(sc, BCE_RDMA_FTQ_CMD);
9202	ctl = REG_RD(sc, BCE_RDMA_FTQ_CTL);
9203	cur_depth = (ctl & BCE_RDMA_FTQ_CTL_CUR_DEPTH) >> 22;
9204	max_depth = (ctl & BCE_RDMA_FTQ_CTL_MAX_DEPTH) >> 12;
9205	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT6);
9206	BCE_PRINTF(" RDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9207		cmd, ctl, cur_depth, max_depth, valid_cnt);
9208
9209	/* Input queue to the Transmit Scheduler state machine */
9210	cmd = REG_RD(sc, BCE_TSCH_FTQ_CMD);
9211	ctl = REG_RD(sc, BCE_TSCH_FTQ_CTL);
9212	cur_depth = (ctl & BCE_TSCH_FTQ_CTL_CUR_DEPTH) >> 22;
9213	max_depth = (ctl & BCE_TSCH_FTQ_CTL_MAX_DEPTH) >> 12;
9214	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT7);
9215	BCE_PRINTF(" TSCH    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9216		cmd, ctl, cur_depth, max_depth, valid_cnt);
9217
9218	/* Input queue to the Transmit Buffer Descriptor state machine */
9219	cmd = REG_RD(sc, BCE_TBDR_FTQ_CMD);
9220	ctl = REG_RD(sc, BCE_TBDR_FTQ_CTL);
9221	cur_depth = (ctl & BCE_TBDR_FTQ_CTL_CUR_DEPTH) >> 22;
9222	max_depth = (ctl & BCE_TBDR_FTQ_CTL_MAX_DEPTH) >> 12;
9223	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT8);
9224	BCE_PRINTF(" TBDR    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9225		cmd, ctl, cur_depth, max_depth, valid_cnt);
9226
9227	/* Input queue to the Transmit Processor */
9228	cmd = REG_RD_IND(sc, BCE_TXP_FTQ_CMD);
9229	ctl = REG_RD_IND(sc, BCE_TXP_FTQ_CTL);
9230	cur_depth = (ctl & BCE_TXP_FTQ_CTL_CUR_DEPTH) >> 22;
9231	max_depth = (ctl & BCE_TXP_FTQ_CTL_MAX_DEPTH) >> 12;
9232	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT9);
9233	BCE_PRINTF(" TXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9234		cmd, ctl, cur_depth, max_depth, valid_cnt);
9235
9236	/* Input queue to the Transmit DMA state machine */
9237	cmd = REG_RD(sc, BCE_TDMA_FTQ_CMD);
9238	ctl = REG_RD(sc, BCE_TDMA_FTQ_CTL);
9239	cur_depth = (ctl & BCE_TDMA_FTQ_CTL_CUR_DEPTH) >> 22;
9240	max_depth = (ctl & BCE_TDMA_FTQ_CTL_MAX_DEPTH) >> 12;
9241	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT10);
9242	BCE_PRINTF(" TDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9243		cmd, ctl, cur_depth, max_depth, valid_cnt);
9244
9245	/* Input queue to the Transmit Patch-Up Processor */
9246	cmd = REG_RD_IND(sc, BCE_TPAT_FTQ_CMD);
9247	ctl = REG_RD_IND(sc, BCE_TPAT_FTQ_CTL);
9248	cur_depth = (ctl & BCE_TPAT_FTQ_CTL_CUR_DEPTH) >> 22;
9249	max_depth = (ctl & BCE_TPAT_FTQ_CTL_MAX_DEPTH) >> 12;
9250	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT11);
9251	BCE_PRINTF(" TPAT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9252		cmd, ctl, cur_depth, max_depth, valid_cnt);
9253
9254	/* Input queue to the Transmit Assembler state machine */
9255	cmd = REG_RD_IND(sc, BCE_TAS_FTQ_CMD);
9256	ctl = REG_RD_IND(sc, BCE_TAS_FTQ_CTL);
9257	cur_depth = (ctl & BCE_TAS_FTQ_CTL_CUR_DEPTH) >> 22;
9258	max_depth = (ctl & BCE_TAS_FTQ_CTL_MAX_DEPTH) >> 12;
9259	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT12);
9260	BCE_PRINTF(" TAS     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9261		cmd, ctl, cur_depth, max_depth, valid_cnt);
9262
9263	/* Input queue to the Completion Processor */
9264	cmd = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CMD);
9265	ctl = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CTL);
9266	cur_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_CUR_DEPTH) >> 22;
9267	max_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_MAX_DEPTH) >> 12;
9268	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT13);
9269	BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9270		cmd, ctl, cur_depth, max_depth, valid_cnt);
9271
9272	/* Input queue to the Completion Processor */
9273	cmd = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CMD);
9274	ctl = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CTL);
9275	cur_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_CUR_DEPTH) >> 22;
9276	max_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_MAX_DEPTH) >> 12;
9277	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT14);
9278	BCE_PRINTF(" COMT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9279		cmd, ctl, cur_depth, max_depth, valid_cnt);
9280
9281	/* Input queue to the Completion Processor */
9282	cmd = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CMD);
9283	ctl = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CTL);
9284	cur_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_CUR_DEPTH) >> 22;
9285	max_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_MAX_DEPTH) >> 12;
9286	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT15);
9287	BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9288		cmd, ctl, cur_depth, max_depth, valid_cnt);
9289
9290	/* Setup the generic statistic counters for the FTQ valid count. */
9291	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSQ_VALID_CNT  << 16) |
9292		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT  <<  8) |
9293		(BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT);
9294
9295	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)	||
9296		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716))
9297		val = val | (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCSQ_VALID_CNT_XI << 24);
9298		REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
9299
9300	/* Input queue to the Management Control Processor */
9301	cmd = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CMD);
9302	ctl = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CTL);
9303	cur_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_CUR_DEPTH) >> 22;
9304	max_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_MAX_DEPTH) >> 12;
9305	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
9306	BCE_PRINTF(" MCP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9307		cmd, ctl, cur_depth, max_depth, valid_cnt);
9308
9309	/* Input queue to the Command Processor */
9310	cmd = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CMD);
9311	ctl = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CTL);
9312	cur_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_CUR_DEPTH) >> 22;
9313	max_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_MAX_DEPTH) >> 12;
9314	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
9315	BCE_PRINTF(" CP      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9316		cmd, ctl, cur_depth, max_depth, valid_cnt);
9317
9318	/* Input queue to the Completion Scheduler state machine */
9319	cmd = REG_RD(sc, BCE_CSCH_CH_FTQ_CMD);
9320	ctl = REG_RD(sc, BCE_CSCH_CH_FTQ_CTL);
9321	cur_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_CUR_DEPTH) >> 22;
9322	max_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_MAX_DEPTH) >> 12;
9323	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
9324	BCE_PRINTF(" CS      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9325		cmd, ctl, cur_depth, max_depth, valid_cnt);
9326
9327	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) ||
9328		(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) {
9329		/* Input queue to the Receive Virtual to Physical Command Scheduler */
9330		cmd = REG_RD(sc, BCE_RV2PCSR_FTQ_CMD);
9331		ctl = REG_RD(sc, BCE_RV2PCSR_FTQ_CTL);
9332		cur_depth = (ctl & 0xFFC00000) >> 22;
9333		max_depth = (ctl & 0x003FF000) >> 12;
9334		valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
9335		BCE_PRINTF(" RV2PCSR 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
9336			cmd, ctl, cur_depth, max_depth, valid_cnt);
9337	}
9338
9339	BCE_PRINTF(
9340		"----------------------------"
9341		"----------------"
9342		"----------------------------\n");
9343}
9344
9345
9346/****************************************************************************/
9347/* Prints out the TX chain.                                                 */
9348/*                                                                          */
9349/* Returns:                                                                 */
9350/*   Nothing.                                                               */
9351/****************************************************************************/
9352static __attribute__ ((noinline)) void
9353bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count)
9354{
9355	struct tx_bd *txbd;
9356
9357	/* First some info about the tx_bd chain structure. */
9358	BCE_PRINTF(
9359		"----------------------------"
9360		"  tx_bd  chain  "
9361		"----------------------------\n");
9362
9363	BCE_PRINTF("page size      = 0x%08X, tx chain pages        = 0x%08X\n",
9364		(u32) BCM_PAGE_SIZE, (u32) TX_PAGES);
9365
9366	BCE_PRINTF("tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
9367		(u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
9368
9369	BCE_PRINTF("total tx_bd    = 0x%08X\n", (u32) TOTAL_TX_BD);
9370
9371	BCE_PRINTF(
9372		"----------------------------"
9373		"   tx_bd data   "
9374		"----------------------------\n");
9375
9376	/* Now print out the tx_bd's themselves. */
9377	for (int i = 0; i < count; i++) {
9378	 	txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
9379		bce_dump_txbd(sc, tx_prod, txbd);
9380		tx_prod = NEXT_TX_BD(tx_prod);
9381	}
9382
9383	BCE_PRINTF(
9384		"----------------------------"
9385		"----------------"
9386		"----------------------------\n");
9387}
9388
9389
9390/****************************************************************************/
9391/* Prints out the RX chain.                                                 */
9392/*                                                                          */
9393/* Returns:                                                                 */
9394/*   Nothing.                                                               */
9395/****************************************************************************/
9396static __attribute__ ((noinline)) void
9397bce_dump_rx_chain(struct bce_softc *sc, u16 rx_prod, int count)
9398{
9399	struct rx_bd *rxbd;
9400
9401	/* First some info about the rx_bd chain structure. */
9402	BCE_PRINTF(
9403		"----------------------------"
9404		"  rx_bd  chain  "
9405		"----------------------------\n");
9406
9407	BCE_PRINTF("page size      = 0x%08X, rx chain pages        = 0x%08X\n",
9408		(u32) BCM_PAGE_SIZE, (u32) RX_PAGES);
9409
9410	BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
9411		(u32) TOTAL_RX_BD_PER_PAGE, (u32) USABLE_RX_BD_PER_PAGE);
9412
9413	BCE_PRINTF("total rx_bd    = 0x%08X\n", (u32) TOTAL_RX_BD);
9414
9415	BCE_PRINTF(
9416		"----------------------------"
9417		"   rx_bd data   "
9418		"----------------------------\n");
9419
9420	/* Now print out the rx_bd's themselves. */
9421	for (int i = 0; i < count; i++) {
9422		rxbd = &sc->rx_bd_chain[RX_PAGE(rx_prod)][RX_IDX(rx_prod)];
9423		bce_dump_rxbd(sc, rx_prod, rxbd);
9424		rx_prod = RX_CHAIN_IDX(rx_prod + 1);
9425	}
9426
9427	BCE_PRINTF(
9428		"----------------------------"
9429		"----------------"
9430		"----------------------------\n");
9431}
9432
9433
9434#ifdef BCE_JUMBO_HDRSPLIT
9435/****************************************************************************/
9436/* Prints out the page chain.                                               */
9437/*                                                                          */
9438/* Returns:                                                                 */
9439/*   Nothing.                                                               */
9440/****************************************************************************/
9441static __attribute__ ((noinline)) void
9442bce_dump_pg_chain(struct bce_softc *sc, u16 pg_prod, int count)
9443{
9444	struct rx_bd *pgbd;
9445
9446	/* First some info about the page chain structure. */
9447	BCE_PRINTF(
9448		"----------------------------"
9449		"   page chain   "
9450		"----------------------------\n");
9451
9452	BCE_PRINTF("page size      = 0x%08X, pg chain pages        = 0x%08X\n",
9453		(u32) BCM_PAGE_SIZE, (u32) PG_PAGES);
9454
9455	BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
9456		(u32) TOTAL_PG_BD_PER_PAGE, (u32) USABLE_PG_BD_PER_PAGE);
9457
9458	BCE_PRINTF("total rx_bd    = 0x%08X, max_pg_bd             = 0x%08X\n",
9459		(u32) TOTAL_PG_BD, (u32) MAX_PG_BD);
9460
9461	BCE_PRINTF(
9462		"----------------------------"
9463		"   page data    "
9464		"----------------------------\n");
9465
9466	/* Now print out the rx_bd's themselves. */
9467	for (int i = 0; i < count; i++) {
9468		pgbd = &sc->pg_bd_chain[PG_PAGE(pg_prod)][PG_IDX(pg_prod)];
9469		bce_dump_pgbd(sc, pg_prod, pgbd);
9470		pg_prod = PG_CHAIN_IDX(pg_prod + 1);
9471	}
9472
9473	BCE_PRINTF(
9474		"----------------------------"
9475		"----------------"
9476		"----------------------------\n");
9477}
9478#endif
9479
9480
9481/****************************************************************************/
9482/* Prints out the status block from host memory.                            */
9483/*                                                                          */
9484/* Returns:                                                                 */
9485/*   Nothing.                                                               */
9486/****************************************************************************/
9487static __attribute__ ((noinline)) void
9488bce_dump_status_block(struct bce_softc *sc)
9489{
9490	struct status_block *sblk;
9491
9492	sblk = sc->status_block;
9493
9494   	BCE_PRINTF(
9495		"----------------------------"
9496		"  Status Block  "
9497		"----------------------------\n");
9498
9499	BCE_PRINTF("    0x%08X - attn_bits\n",
9500		sblk->status_attn_bits);
9501
9502	BCE_PRINTF("    0x%08X - attn_bits_ack\n",
9503		sblk->status_attn_bits_ack);
9504
9505	BCE_PRINTF("0x%04X(0x%04X) - rx_cons0\n",
9506		sblk->status_rx_quick_consumer_index0,
9507		(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index0));
9508
9509	BCE_PRINTF("0x%04X(0x%04X) - tx_cons0\n",
9510		sblk->status_tx_quick_consumer_index0,
9511		(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index0));
9512
9513	BCE_PRINTF("        0x%04X - status_idx\n", sblk->status_idx);
9514
9515	/* Theses indices are not used for normal L2 drivers. */
9516	if (sblk->status_rx_quick_consumer_index1)
9517		BCE_PRINTF("0x%04X(0x%04X) - rx_cons1\n",
9518			sblk->status_rx_quick_consumer_index1,
9519			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index1));
9520
9521	if (sblk->status_tx_quick_consumer_index1)
9522		BCE_PRINTF("0x%04X(0x%04X) - tx_cons1\n",
9523			sblk->status_tx_quick_consumer_index1,
9524			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index1));
9525
9526	if (sblk->status_rx_quick_consumer_index2)
9527		BCE_PRINTF("0x%04X(0x%04X)- rx_cons2\n",
9528			sblk->status_rx_quick_consumer_index2,
9529			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index2));
9530
9531	if (sblk->status_tx_quick_consumer_index2)
9532		BCE_PRINTF("0x%04X(0x%04X) - tx_cons2\n",
9533			sblk->status_tx_quick_consumer_index2,
9534			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index2));
9535
9536	if (sblk->status_rx_quick_consumer_index3)
9537		BCE_PRINTF("0x%04X(0x%04X) - rx_cons3\n",
9538			sblk->status_rx_quick_consumer_index3,
9539			(u16) RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index3));
9540
9541	if (sblk->status_tx_quick_consumer_index3)
9542		BCE_PRINTF("0x%04X(0x%04X) - tx_cons3\n",
9543			sblk->status_tx_quick_consumer_index3,
9544			(u16) TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index3));
9545
9546	if (sblk->status_rx_quick_consumer_index4 ||
9547		sblk->status_rx_quick_consumer_index5)
9548		BCE_PRINTF("rx_cons4  = 0x%08X, rx_cons5      = 0x%08X\n",
9549			sblk->status_rx_quick_consumer_index4,
9550			sblk->status_rx_quick_consumer_index5);
9551
9552	if (sblk->status_rx_quick_consumer_index6 ||
9553		sblk->status_rx_quick_consumer_index7)
9554		BCE_PRINTF("rx_cons6  = 0x%08X, rx_cons7      = 0x%08X\n",
9555			sblk->status_rx_quick_consumer_index6,
9556			sblk->status_rx_quick_consumer_index7);
9557
9558	if (sblk->status_rx_quick_consumer_index8 ||
9559		sblk->status_rx_quick_consumer_index9)
9560		BCE_PRINTF("rx_cons8  = 0x%08X, rx_cons9      = 0x%08X\n",
9561			sblk->status_rx_quick_consumer_index8,
9562			sblk->status_rx_quick_consumer_index9);
9563
9564	if (sblk->status_rx_quick_consumer_index10 ||
9565		sblk->status_rx_quick_consumer_index11)
9566		BCE_PRINTF("rx_cons10 = 0x%08X, rx_cons11     = 0x%08X\n",
9567			sblk->status_rx_quick_consumer_index10,
9568			sblk->status_rx_quick_consumer_index11);
9569
9570	if (sblk->status_rx_quick_consumer_index12 ||
9571		sblk->status_rx_quick_consumer_index13)
9572		BCE_PRINTF("rx_cons12 = 0x%08X, rx_cons13     = 0x%08X\n",
9573			sblk->status_rx_quick_consumer_index12,
9574			sblk->status_rx_quick_consumer_index13);
9575
9576	if (sblk->status_rx_quick_consumer_index14 ||
9577		sblk->status_rx_quick_consumer_index15)
9578		BCE_PRINTF("rx_cons14 = 0x%08X, rx_cons15     = 0x%08X\n",
9579			sblk->status_rx_quick_consumer_index14,
9580			sblk->status_rx_quick_consumer_index15);
9581
9582	if (sblk->status_completion_producer_index ||
9583		sblk->status_cmd_consumer_index)
9584		BCE_PRINTF("com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
9585			sblk->status_completion_producer_index,
9586			sblk->status_cmd_consumer_index);
9587
9588	BCE_PRINTF(
9589		"----------------------------"
9590		"----------------"
9591		"----------------------------\n");
9592}
9593
9594
9595/****************************************************************************/
9596/* Prints out the statistics block from host memory.                        */
9597/*                                                                          */
9598/* Returns:                                                                 */
9599/*   Nothing.                                                               */
9600/****************************************************************************/
9601static __attribute__ ((noinline)) void
9602bce_dump_stats_block(struct bce_softc *sc)
9603{
9604	struct statistics_block *sblk;
9605
9606	sblk = sc->stats_block;
9607
9608	BCE_PRINTF(
9609		"---------------"
9610		" Stats Block  (All Stats Not Shown Are 0) "
9611		"---------------\n");
9612
9613	if (sblk->stat_IfHCInOctets_hi
9614		|| sblk->stat_IfHCInOctets_lo)
9615		BCE_PRINTF("0x%08X:%08X : "
9616			"IfHcInOctets\n",
9617			sblk->stat_IfHCInOctets_hi,
9618			sblk->stat_IfHCInOctets_lo);
9619
9620	if (sblk->stat_IfHCInBadOctets_hi
9621		|| sblk->stat_IfHCInBadOctets_lo)
9622		BCE_PRINTF("0x%08X:%08X : "
9623			"IfHcInBadOctets\n",
9624			sblk->stat_IfHCInBadOctets_hi,
9625			sblk->stat_IfHCInBadOctets_lo);
9626
9627	if (sblk->stat_IfHCOutOctets_hi
9628		|| sblk->stat_IfHCOutOctets_lo)
9629		BCE_PRINTF("0x%08X:%08X : "
9630			"IfHcOutOctets\n",
9631			sblk->stat_IfHCOutOctets_hi,
9632			sblk->stat_IfHCOutOctets_lo);
9633
9634	if (sblk->stat_IfHCOutBadOctets_hi
9635		|| sblk->stat_IfHCOutBadOctets_lo)
9636		BCE_PRINTF("0x%08X:%08X : "
9637			"IfHcOutBadOctets\n",
9638			sblk->stat_IfHCOutBadOctets_hi,
9639			sblk->stat_IfHCOutBadOctets_lo);
9640
9641	if (sblk->stat_IfHCInUcastPkts_hi
9642		|| sblk->stat_IfHCInUcastPkts_lo)
9643		BCE_PRINTF("0x%08X:%08X : "
9644			"IfHcInUcastPkts\n",
9645			sblk->stat_IfHCInUcastPkts_hi,
9646			sblk->stat_IfHCInUcastPkts_lo);
9647
9648	if (sblk->stat_IfHCInBroadcastPkts_hi
9649		|| sblk->stat_IfHCInBroadcastPkts_lo)
9650		BCE_PRINTF("0x%08X:%08X : "
9651			"IfHcInBroadcastPkts\n",
9652			sblk->stat_IfHCInBroadcastPkts_hi,
9653			sblk->stat_IfHCInBroadcastPkts_lo);
9654
9655	if (sblk->stat_IfHCInMulticastPkts_hi
9656		|| sblk->stat_IfHCInMulticastPkts_lo)
9657		BCE_PRINTF("0x%08X:%08X : "
9658			"IfHcInMulticastPkts\n",
9659			sblk->stat_IfHCInMulticastPkts_hi,
9660			sblk->stat_IfHCInMulticastPkts_lo);
9661
9662	if (sblk->stat_IfHCOutUcastPkts_hi
9663		|| sblk->stat_IfHCOutUcastPkts_lo)
9664		BCE_PRINTF("0x%08X:%08X : "
9665			"IfHcOutUcastPkts\n",
9666			sblk->stat_IfHCOutUcastPkts_hi,
9667			sblk->stat_IfHCOutUcastPkts_lo);
9668
9669	if (sblk->stat_IfHCOutBroadcastPkts_hi
9670		|| sblk->stat_IfHCOutBroadcastPkts_lo)
9671		BCE_PRINTF("0x%08X:%08X : "
9672			"IfHcOutBroadcastPkts\n",
9673			sblk->stat_IfHCOutBroadcastPkts_hi,
9674			sblk->stat_IfHCOutBroadcastPkts_lo);
9675
9676	if (sblk->stat_IfHCOutMulticastPkts_hi
9677		|| sblk->stat_IfHCOutMulticastPkts_lo)
9678		BCE_PRINTF("0x%08X:%08X : "
9679			"IfHcOutMulticastPkts\n",
9680			sblk->stat_IfHCOutMulticastPkts_hi,
9681			sblk->stat_IfHCOutMulticastPkts_lo);
9682
9683	if (sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors)
9684		BCE_PRINTF("         0x%08X : "
9685			"emac_tx_stat_dot3statsinternalmactransmiterrors\n",
9686			sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
9687
9688	if (sblk->stat_Dot3StatsCarrierSenseErrors)
9689		BCE_PRINTF("         0x%08X : Dot3StatsCarrierSenseErrors\n",
9690			sblk->stat_Dot3StatsCarrierSenseErrors);
9691
9692	if (sblk->stat_Dot3StatsFCSErrors)
9693		BCE_PRINTF("         0x%08X : Dot3StatsFCSErrors\n",
9694			sblk->stat_Dot3StatsFCSErrors);
9695
9696	if (sblk->stat_Dot3StatsAlignmentErrors)
9697		BCE_PRINTF("         0x%08X : Dot3StatsAlignmentErrors\n",
9698			sblk->stat_Dot3StatsAlignmentErrors);
9699
9700	if (sblk->stat_Dot3StatsSingleCollisionFrames)
9701		BCE_PRINTF("         0x%08X : Dot3StatsSingleCollisionFrames\n",
9702			sblk->stat_Dot3StatsSingleCollisionFrames);
9703
9704	if (sblk->stat_Dot3StatsMultipleCollisionFrames)
9705		BCE_PRINTF("         0x%08X : Dot3StatsMultipleCollisionFrames\n",
9706			sblk->stat_Dot3StatsMultipleCollisionFrames);
9707
9708	if (sblk->stat_Dot3StatsDeferredTransmissions)
9709		BCE_PRINTF("         0x%08X : Dot3StatsDeferredTransmissions\n",
9710			sblk->stat_Dot3StatsDeferredTransmissions);
9711
9712	if (sblk->stat_Dot3StatsExcessiveCollisions)
9713		BCE_PRINTF("         0x%08X : Dot3StatsExcessiveCollisions\n",
9714			sblk->stat_Dot3StatsExcessiveCollisions);
9715
9716	if (sblk->stat_Dot3StatsLateCollisions)
9717		BCE_PRINTF("         0x%08X : Dot3StatsLateCollisions\n",
9718			sblk->stat_Dot3StatsLateCollisions);
9719
9720	if (sblk->stat_EtherStatsCollisions)
9721		BCE_PRINTF("         0x%08X : EtherStatsCollisions\n",
9722			sblk->stat_EtherStatsCollisions);
9723
9724	if (sblk->stat_EtherStatsFragments)
9725		BCE_PRINTF("         0x%08X : EtherStatsFragments\n",
9726			sblk->stat_EtherStatsFragments);
9727
9728	if (sblk->stat_EtherStatsJabbers)
9729		BCE_PRINTF("         0x%08X : EtherStatsJabbers\n",
9730			sblk->stat_EtherStatsJabbers);
9731
9732	if (sblk->stat_EtherStatsUndersizePkts)
9733		BCE_PRINTF("         0x%08X : EtherStatsUndersizePkts\n",
9734			sblk->stat_EtherStatsUndersizePkts);
9735
9736	if (sblk->stat_EtherStatsOversizePkts)
9737		BCE_PRINTF("         0x%08X : EtherStatsOverrsizePkts\n",
9738			sblk->stat_EtherStatsOversizePkts);
9739
9740	if (sblk->stat_EtherStatsPktsRx64Octets)
9741		BCE_PRINTF("         0x%08X : EtherStatsPktsRx64Octets\n",
9742			sblk->stat_EtherStatsPktsRx64Octets);
9743
9744	if (sblk->stat_EtherStatsPktsRx65Octetsto127Octets)
9745		BCE_PRINTF("         0x%08X : EtherStatsPktsRx65Octetsto127Octets\n",
9746			sblk->stat_EtherStatsPktsRx65Octetsto127Octets);
9747
9748	if (sblk->stat_EtherStatsPktsRx128Octetsto255Octets)
9749		BCE_PRINTF("         0x%08X : EtherStatsPktsRx128Octetsto255Octets\n",
9750			sblk->stat_EtherStatsPktsRx128Octetsto255Octets);
9751
9752	if (sblk->stat_EtherStatsPktsRx256Octetsto511Octets)
9753		BCE_PRINTF("         0x%08X : EtherStatsPktsRx256Octetsto511Octets\n",
9754			sblk->stat_EtherStatsPktsRx256Octetsto511Octets);
9755
9756	if (sblk->stat_EtherStatsPktsRx512Octetsto1023Octets)
9757		BCE_PRINTF("         0x%08X : EtherStatsPktsRx512Octetsto1023Octets\n",
9758			sblk->stat_EtherStatsPktsRx512Octetsto1023Octets);
9759
9760	if (sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets)
9761		BCE_PRINTF("         0x%08X : EtherStatsPktsRx1024Octetsto1522Octets\n",
9762			sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets);
9763
9764	if (sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets)
9765		BCE_PRINTF("         0x%08X : EtherStatsPktsRx1523Octetsto9022Octets\n",
9766			sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets);
9767
9768	if (sblk->stat_EtherStatsPktsTx64Octets)
9769		BCE_PRINTF("         0x%08X : EtherStatsPktsTx64Octets\n",
9770			sblk->stat_EtherStatsPktsTx64Octets);
9771
9772	if (sblk->stat_EtherStatsPktsTx65Octetsto127Octets)
9773		BCE_PRINTF("         0x%08X : EtherStatsPktsTx65Octetsto127Octets\n",
9774			sblk->stat_EtherStatsPktsTx65Octetsto127Octets);
9775
9776	if (sblk->stat_EtherStatsPktsTx128Octetsto255Octets)
9777		BCE_PRINTF("         0x%08X : EtherStatsPktsTx128Octetsto255Octets\n",
9778			sblk->stat_EtherStatsPktsTx128Octetsto255Octets);
9779
9780	if (sblk->stat_EtherStatsPktsTx256Octetsto511Octets)
9781		BCE_PRINTF("         0x%08X : EtherStatsPktsTx256Octetsto511Octets\n",
9782			sblk->stat_EtherStatsPktsTx256Octetsto511Octets);
9783
9784	if (sblk->stat_EtherStatsPktsTx512Octetsto1023Octets)
9785		BCE_PRINTF("         0x%08X : EtherStatsPktsTx512Octetsto1023Octets\n",
9786			sblk->stat_EtherStatsPktsTx512Octetsto1023Octets);
9787
9788	if (sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets)
9789		BCE_PRINTF("         0x%08X : EtherStatsPktsTx1024Octetsto1522Octets\n",
9790			sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets);
9791
9792	if (sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets)
9793		BCE_PRINTF("         0x%08X : EtherStatsPktsTx1523Octetsto9022Octets\n",
9794			sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets);
9795
9796	if (sblk->stat_XonPauseFramesReceived)
9797		BCE_PRINTF("         0x%08X : XonPauseFramesReceived\n",
9798			sblk->stat_XonPauseFramesReceived);
9799
9800	if (sblk->stat_XoffPauseFramesReceived)
9801	   BCE_PRINTF("          0x%08X : XoffPauseFramesReceived\n",
9802			sblk->stat_XoffPauseFramesReceived);
9803
9804	if (sblk->stat_OutXonSent)
9805		BCE_PRINTF("         0x%08X : OutXonSent\n",
9806			sblk->stat_OutXonSent);
9807
9808	if (sblk->stat_OutXoffSent)
9809		BCE_PRINTF("         0x%08X : OutXoffSent\n",
9810			sblk->stat_OutXoffSent);
9811
9812	if (sblk->stat_FlowControlDone)
9813		BCE_PRINTF("         0x%08X : FlowControlDone\n",
9814			sblk->stat_FlowControlDone);
9815
9816	if (sblk->stat_MacControlFramesReceived)
9817		BCE_PRINTF("         0x%08X : MacControlFramesReceived\n",
9818			sblk->stat_MacControlFramesReceived);
9819
9820	if (sblk->stat_XoffStateEntered)
9821		BCE_PRINTF("         0x%08X : XoffStateEntered\n",
9822			sblk->stat_XoffStateEntered);
9823
9824	if (sblk->stat_IfInFramesL2FilterDiscards)
9825		BCE_PRINTF("         0x%08X : IfInFramesL2FilterDiscards\n",
9826			sblk->stat_IfInFramesL2FilterDiscards);
9827
9828	if (sblk->stat_IfInRuleCheckerDiscards)
9829		BCE_PRINTF("         0x%08X : IfInRuleCheckerDiscards\n",
9830			sblk->stat_IfInRuleCheckerDiscards);
9831
9832	if (sblk->stat_IfInFTQDiscards)
9833		BCE_PRINTF("         0x%08X : IfInFTQDiscards\n",
9834			sblk->stat_IfInFTQDiscards);
9835
9836	if (sblk->stat_IfInMBUFDiscards)
9837		BCE_PRINTF("         0x%08X : IfInMBUFDiscards\n",
9838			sblk->stat_IfInMBUFDiscards);
9839
9840	if (sblk->stat_IfInRuleCheckerP4Hit)
9841		BCE_PRINTF("         0x%08X : IfInRuleCheckerP4Hit\n",
9842			sblk->stat_IfInRuleCheckerP4Hit);
9843
9844	if (sblk->stat_CatchupInRuleCheckerDiscards)
9845		BCE_PRINTF("         0x%08X : CatchupInRuleCheckerDiscards\n",
9846			sblk->stat_CatchupInRuleCheckerDiscards);
9847
9848	if (sblk->stat_CatchupInFTQDiscards)
9849		BCE_PRINTF("         0x%08X : CatchupInFTQDiscards\n",
9850			sblk->stat_CatchupInFTQDiscards);
9851
9852	if (sblk->stat_CatchupInMBUFDiscards)
9853		BCE_PRINTF("         0x%08X : CatchupInMBUFDiscards\n",
9854			sblk->stat_CatchupInMBUFDiscards);
9855
9856	if (sblk->stat_CatchupInRuleCheckerP4Hit)
9857		BCE_PRINTF("         0x%08X : CatchupInRuleCheckerP4Hit\n",
9858			sblk->stat_CatchupInRuleCheckerP4Hit);
9859
9860	BCE_PRINTF(
9861		"----------------------------"
9862		"----------------"
9863		"----------------------------\n");
9864}
9865
9866
9867/****************************************************************************/
9868/* Prints out a summary of the driver state.                                */
9869/*                                                                          */
9870/* Returns:                                                                 */
9871/*   Nothing.                                                               */
9872/****************************************************************************/
9873static __attribute__ ((noinline)) void
9874bce_dump_driver_state(struct bce_softc *sc)
9875{
9876	u32 val_hi, val_lo;
9877
9878	BCE_PRINTF(
9879		"-----------------------------"
9880		" Driver State "
9881		"-----------------------------\n");
9882
9883	val_hi = BCE_ADDR_HI(sc);
9884	val_lo = BCE_ADDR_LO(sc);
9885	BCE_PRINTF("0x%08X:%08X - (sc) driver softc structure virtual address\n",
9886		val_hi, val_lo);
9887
9888	val_hi = BCE_ADDR_HI(sc->bce_vhandle);
9889	val_lo = BCE_ADDR_LO(sc->bce_vhandle);
9890	BCE_PRINTF("0x%08X:%08X - (sc->bce_vhandle) PCI BAR virtual address\n",
9891		val_hi, val_lo);
9892
9893	val_hi = BCE_ADDR_HI(sc->status_block);
9894	val_lo = BCE_ADDR_LO(sc->status_block);
9895	BCE_PRINTF("0x%08X:%08X - (sc->status_block) status block virtual address\n",
9896		val_hi, val_lo);
9897
9898	val_hi = BCE_ADDR_HI(sc->stats_block);
9899	val_lo = BCE_ADDR_LO(sc->stats_block);
9900	BCE_PRINTF("0x%08X:%08X - (sc->stats_block) statistics block virtual address\n",
9901		val_hi, val_lo);
9902
9903	val_hi = BCE_ADDR_HI(sc->tx_bd_chain);
9904	val_lo = BCE_ADDR_LO(sc->tx_bd_chain);
9905	BCE_PRINTF(
9906		"0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain virtual adddress\n",
9907		val_hi, val_lo);
9908
9909	val_hi = BCE_ADDR_HI(sc->rx_bd_chain);
9910	val_lo = BCE_ADDR_LO(sc->rx_bd_chain);
9911	BCE_PRINTF(
9912		"0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain virtual address\n",
9913		val_hi, val_lo);
9914
9915#ifdef BCE_JUMBO_HDRSPLIT
9916	val_hi = BCE_ADDR_HI(sc->pg_bd_chain);
9917	val_lo = BCE_ADDR_LO(sc->pg_bd_chain);
9918	BCE_PRINTF(
9919		"0x%08X:%08X - (sc->pg_bd_chain) page chain virtual address\n",
9920		val_hi, val_lo);
9921#endif
9922
9923	val_hi = BCE_ADDR_HI(sc->tx_mbuf_ptr);
9924	val_lo = BCE_ADDR_LO(sc->tx_mbuf_ptr);
9925	BCE_PRINTF(
9926		"0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain virtual address\n",
9927		val_hi, val_lo);
9928
9929	val_hi = BCE_ADDR_HI(sc->rx_mbuf_ptr);
9930	val_lo = BCE_ADDR_LO(sc->rx_mbuf_ptr);
9931	BCE_PRINTF(
9932		"0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain virtual address\n",
9933		val_hi, val_lo);
9934
9935#ifdef BCE_JUMBO_HDRSPLIT
9936	val_hi = BCE_ADDR_HI(sc->pg_mbuf_ptr);
9937	val_lo = BCE_ADDR_LO(sc->pg_mbuf_ptr);
9938	BCE_PRINTF(
9939		"0x%08X:%08X - (sc->pg_mbuf_ptr) page mbuf chain virtual address\n",
9940		val_hi, val_lo);
9941#endif
9942
9943	BCE_PRINTF("         0x%08X - (sc->interrupts_generated) h/w intrs\n",
9944		sc->interrupts_generated);
9945
9946	BCE_PRINTF("         0x%08X - (sc->rx_interrupts) rx interrupts handled\n",
9947		sc->rx_interrupts);
9948
9949	BCE_PRINTF("         0x%08X - (sc->tx_interrupts) tx interrupts handled\n",
9950		sc->tx_interrupts);
9951
9952	BCE_PRINTF("         0x%08X - (sc->last_status_idx) status block index\n",
9953		sc->last_status_idx);
9954
9955	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_prod) tx producer index\n",
9956		sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod));
9957
9958	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_cons) tx consumer index\n",
9959		sc->tx_cons, (u16) TX_CHAIN_IDX(sc->tx_cons));
9960
9961	BCE_PRINTF("         0x%08X - (sc->tx_prod_bseq) tx producer bseq index\n",
9962		sc->tx_prod_bseq);
9963
9964	BCE_PRINTF("         0x%08X - (sc->debug_tx_mbuf_alloc) tx mbufs allocated\n",
9965		sc->debug_tx_mbuf_alloc);
9966
9967	BCE_PRINTF("         0x%08X - (sc->used_tx_bd) used tx_bd's\n",
9968		sc->used_tx_bd);
9969
9970	BCE_PRINTF("0x%08X/%08X - (sc->tx_hi_watermark) tx hi watermark\n",
9971		sc->tx_hi_watermark, sc->max_tx_bd);
9972
9973	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_prod) rx producer index\n",
9974		sc->rx_prod, (u16) RX_CHAIN_IDX(sc->rx_prod));
9975
9976	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_cons) rx consumer index\n",
9977		sc->rx_cons, (u16) RX_CHAIN_IDX(sc->rx_cons));
9978
9979	BCE_PRINTF("         0x%08X - (sc->rx_prod_bseq) rx producer bseq index\n",
9980		sc->rx_prod_bseq);
9981
9982	BCE_PRINTF("         0x%08X - (sc->debug_rx_mbuf_alloc) rx mbufs allocated\n",
9983		sc->debug_rx_mbuf_alloc);
9984
9985	BCE_PRINTF("         0x%08X - (sc->free_rx_bd) free rx_bd's\n",
9986		sc->free_rx_bd);
9987
9988#ifdef BCE_JUMBO_HDRSPLIT
9989	BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_prod) page producer index\n",
9990		sc->pg_prod, (u16) PG_CHAIN_IDX(sc->pg_prod));
9991
9992	BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_cons) page consumer index\n",
9993		sc->pg_cons, (u16) PG_CHAIN_IDX(sc->pg_cons));
9994
9995	BCE_PRINTF("         0x%08X - (sc->debug_pg_mbuf_alloc) page mbufs allocated\n",
9996		sc->debug_pg_mbuf_alloc);
9997
9998	BCE_PRINTF("         0x%08X - (sc->free_pg_bd) free page rx_bd's\n",
9999		sc->free_pg_bd);
10000
10001	BCE_PRINTF("0x%08X/%08X - (sc->pg_low_watermark) page low watermark\n",
10002		sc->pg_low_watermark, sc->max_pg_bd);
10003#endif
10004
10005	BCE_PRINTF("         0x%08X - (sc->mbuf_alloc_failed_count) "
10006		"mbuf alloc failures\n",
10007		sc->mbuf_alloc_failed_count);
10008
10009	BCE_PRINTF("         0x%08X - (sc->bce_flags) bce mac flags\n",
10010		sc->bce_flags);
10011
10012	BCE_PRINTF("         0x%08X - (sc->bce_phy_flags) bce phy flags\n",
10013		sc->bce_phy_flags);
10014
10015	BCE_PRINTF(
10016		"----------------------------"
10017		"----------------"
10018		"----------------------------\n");
10019}
10020
10021
10022/****************************************************************************/
10023/* Prints out the hardware state through a summary of important register,   */
10024/* followed by a complete register dump.                                    */
10025/*                                                                          */
10026/* Returns:                                                                 */
10027/*   Nothing.                                                               */
10028/****************************************************************************/
10029static __attribute__ ((noinline)) void
10030bce_dump_hw_state(struct bce_softc *sc)
10031{
10032	u32 val;
10033
10034	BCE_PRINTF(
10035		"----------------------------"
10036		" Hardware State "
10037		"----------------------------\n");
10038
10039	BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
10040
10041	val = REG_RD(sc, BCE_MISC_ENABLE_STATUS_BITS);
10042	BCE_PRINTF("0x%08X - (0x%06X) misc_enable_status_bits\n",
10043		val, BCE_MISC_ENABLE_STATUS_BITS);
10044
10045	val = REG_RD(sc, BCE_DMA_STATUS);
10046	BCE_PRINTF("0x%08X - (0x%06X) dma_status\n", val, BCE_DMA_STATUS);
10047
10048	val = REG_RD(sc, BCE_CTX_STATUS);
10049	BCE_PRINTF("0x%08X - (0x%06X) ctx_status\n", val, BCE_CTX_STATUS);
10050
10051	val = REG_RD(sc, BCE_EMAC_STATUS);
10052	BCE_PRINTF("0x%08X - (0x%06X) emac_status\n", val, BCE_EMAC_STATUS);
10053
10054	val = REG_RD(sc, BCE_RPM_STATUS);
10055	BCE_PRINTF("0x%08X - (0x%06X) rpm_status\n", val, BCE_RPM_STATUS);
10056
10057	val = REG_RD(sc, 0x2004);
10058	BCE_PRINTF("0x%08X - (0x%06X) rlup_status\n", val, 0x2004);
10059
10060	val = REG_RD(sc, BCE_RV2P_STATUS);
10061	BCE_PRINTF("0x%08X - (0x%06X) rv2p_status\n", val, BCE_RV2P_STATUS);
10062
10063	val = REG_RD(sc, 0x2c04);
10064	BCE_PRINTF("0x%08X - (0x%06X) rdma_status\n", val, 0x2c04);
10065
10066	val = REG_RD(sc, BCE_TBDR_STATUS);
10067	BCE_PRINTF("0x%08X - (0x%06X) tbdr_status\n", val, BCE_TBDR_STATUS);
10068
10069	val = REG_RD(sc, BCE_TDMA_STATUS);
10070	BCE_PRINTF("0x%08X - (0x%06X) tdma_status\n", val, BCE_TDMA_STATUS);
10071
10072	val = REG_RD(sc, BCE_HC_STATUS);
10073	BCE_PRINTF("0x%08X - (0x%06X) hc_status\n", val, BCE_HC_STATUS);
10074
10075	val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
10076	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n", val, BCE_TXP_CPU_STATE);
10077
10078	val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
10079	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n", val, BCE_TPAT_CPU_STATE);
10080
10081	val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
10082	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n", val, BCE_RXP_CPU_STATE);
10083
10084	val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
10085	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n", val, BCE_COM_CPU_STATE);
10086
10087	val = REG_RD_IND(sc, BCE_MCP_CPU_STATE);
10088	BCE_PRINTF("0x%08X - (0x%06X) mcp_cpu_state\n", val, BCE_MCP_CPU_STATE);
10089
10090	val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
10091	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n", val, BCE_CP_CPU_STATE);
10092
10093	BCE_PRINTF(
10094		"----------------------------"
10095		"----------------"
10096		"----------------------------\n");
10097
10098	BCE_PRINTF(
10099		"----------------------------"
10100		" Register  Dump "
10101		"----------------------------\n");
10102
10103	for (int i = 0x400; i < 0x8000; i += 0x10) {
10104		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10105			i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
10106			REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
10107	}
10108
10109	BCE_PRINTF(
10110		"----------------------------"
10111		"----------------"
10112		"----------------------------\n");
10113}
10114
10115
10116/****************************************************************************/
10117/* Prints out the mailbox queue registers.                                  */
10118/*                                                                          */
10119/* Returns:                                                                 */
10120/*   Nothing.                                                               */
10121/****************************************************************************/
10122static __attribute__ ((noinline)) void
10123bce_dump_mq_regs(struct bce_softc *sc)
10124{
10125	BCE_PRINTF(
10126		"----------------------------"
10127		"    MQ Regs     "
10128		"----------------------------\n");
10129
10130	BCE_PRINTF(
10131		"----------------------------"
10132		"----------------"
10133		"----------------------------\n");
10134
10135	for (int i = 0x3c00; i < 0x4000; i += 0x10) {
10136		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10137			i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
10138			REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
10139	}
10140
10141	BCE_PRINTF(
10142		"----------------------------"
10143		"----------------"
10144		"----------------------------\n");
10145}
10146
10147
10148/****************************************************************************/
10149/* Prints out the bootcode state.                                           */
10150/*                                                                          */
10151/* Returns:                                                                 */
10152/*   Nothing.                                                               */
10153/****************************************************************************/
10154static __attribute__ ((noinline)) void
10155bce_dump_bc_state(struct bce_softc *sc)
10156{
10157	u32 val;
10158
10159	BCE_PRINTF(
10160		"----------------------------"
10161		" Bootcode State "
10162		"----------------------------\n");
10163
10164	BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
10165
10166	val = bce_shmem_rd(sc, BCE_BC_RESET_TYPE);
10167	BCE_PRINTF("0x%08X - (0x%06X) reset_type\n",
10168		val, BCE_BC_RESET_TYPE);
10169
10170	val = bce_shmem_rd(sc, BCE_BC_STATE);
10171	BCE_PRINTF("0x%08X - (0x%06X) state\n",
10172		val, BCE_BC_STATE);
10173
10174	val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
10175	BCE_PRINTF("0x%08X - (0x%06X) condition\n",
10176		val, BCE_BC_STATE_CONDITION);
10177
10178	val = bce_shmem_rd(sc, BCE_BC_STATE_DEBUG_CMD);
10179	BCE_PRINTF("0x%08X - (0x%06X) debug_cmd\n",
10180		val, BCE_BC_STATE_DEBUG_CMD);
10181
10182	BCE_PRINTF(
10183		"----------------------------"
10184		"----------------"
10185		"----------------------------\n");
10186}
10187
10188
10189/****************************************************************************/
10190/* Prints out the TXP processor state.                                      */
10191/*                                                                          */
10192/* Returns:                                                                 */
10193/*   Nothing.                                                               */
10194/****************************************************************************/
10195static __attribute__ ((noinline)) void
10196bce_dump_txp_state(struct bce_softc *sc, int regs)
10197{
10198	u32 val;
10199	u32 fw_version[3];
10200
10201	BCE_PRINTF(
10202		"----------------------------"
10203		"   TXP  State   "
10204		"----------------------------\n");
10205
10206	for (int i = 0; i < 3; i++)
10207		fw_version[i] = htonl(REG_RD_IND(sc,
10208			(BCE_TXP_SCRATCH + 0x10 + i * 4)));
10209	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10210
10211	val = REG_RD_IND(sc, BCE_TXP_CPU_MODE);
10212	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_mode\n", val, BCE_TXP_CPU_MODE);
10213
10214	val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
10215	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n", val, BCE_TXP_CPU_STATE);
10216
10217	val = REG_RD_IND(sc, BCE_TXP_CPU_EVENT_MASK);
10218	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_event_mask\n", val,
10219		BCE_TXP_CPU_EVENT_MASK);
10220
10221	if (regs) {
10222		BCE_PRINTF(
10223			"----------------------------"
10224			" Register  Dump "
10225			"----------------------------\n");
10226
10227		for (int i = BCE_TXP_CPU_MODE; i < 0x68000; i += 0x10) {
10228			/* Skip the big blank spaces */
10229			if (i < 0x454000 && i > 0x5ffff)
10230				BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10231					i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
10232					REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
10233		}
10234	}
10235
10236	BCE_PRINTF(
10237		"----------------------------"
10238		"----------------"
10239		"----------------------------\n");
10240}
10241
10242
10243/****************************************************************************/
10244/* Prints out the RXP processor state.                                      */
10245/*                                                                          */
10246/* Returns:                                                                 */
10247/*   Nothing.                                                               */
10248/****************************************************************************/
10249static __attribute__ ((noinline)) void
10250bce_dump_rxp_state(struct bce_softc *sc, int regs)
10251{
10252	u32 val;
10253	u32 fw_version[3];
10254
10255	BCE_PRINTF(
10256		"----------------------------"
10257		"   RXP  State   "
10258		"----------------------------\n");
10259
10260	for (int i = 0; i < 3; i++)
10261		fw_version[i] = htonl(REG_RD_IND(sc,
10262			(BCE_RXP_SCRATCH + 0x10 + i * 4)));
10263	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10264
10265	val = REG_RD_IND(sc, BCE_RXP_CPU_MODE);
10266	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_mode\n", val, BCE_RXP_CPU_MODE);
10267
10268	val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
10269	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n", val, BCE_RXP_CPU_STATE);
10270
10271	val = REG_RD_IND(sc, BCE_RXP_CPU_EVENT_MASK);
10272	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_event_mask\n", val,
10273		BCE_RXP_CPU_EVENT_MASK);
10274
10275	if (regs) {
10276		BCE_PRINTF(
10277			"----------------------------"
10278			" Register  Dump "
10279			"----------------------------\n");
10280
10281		for (int i = BCE_RXP_CPU_MODE; i < 0xe8fff; i += 0x10) {
10282			/* Skip the big blank sapces */
10283			if (i < 0xc5400 && i > 0xdffff)
10284				BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10285	 				i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
10286					REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
10287		}
10288	}
10289
10290	BCE_PRINTF(
10291		"----------------------------"
10292		"----------------"
10293		"----------------------------\n");
10294}
10295
10296
10297/****************************************************************************/
10298/* Prints out the TPAT processor state.                                     */
10299/*                                                                          */
10300/* Returns:                                                                 */
10301/*   Nothing.                                                               */
10302/****************************************************************************/
10303static __attribute__ ((noinline)) void
10304bce_dump_tpat_state(struct bce_softc *sc, int regs)
10305{
10306	u32 val;
10307	u32 fw_version[3];
10308
10309	BCE_PRINTF(
10310		"----------------------------"
10311		"   TPAT State   "
10312		"----------------------------\n");
10313
10314	for (int i = 0; i < 3; i++)
10315		fw_version[i] = htonl(REG_RD_IND(sc,
10316			(BCE_TPAT_SCRATCH + 0x410 + i * 4)));
10317	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10318
10319	val = REG_RD_IND(sc, BCE_TPAT_CPU_MODE);
10320	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_mode\n", val, BCE_TPAT_CPU_MODE);
10321
10322	val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
10323	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n", val, BCE_TPAT_CPU_STATE);
10324
10325	val = REG_RD_IND(sc, BCE_TPAT_CPU_EVENT_MASK);
10326	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_event_mask\n", val,
10327		BCE_TPAT_CPU_EVENT_MASK);
10328
10329	if (regs) {
10330		BCE_PRINTF(
10331			"----------------------------"
10332			" Register  Dump "
10333			"----------------------------\n");
10334
10335		for (int i = BCE_TPAT_CPU_MODE; i < 0xa3fff; i += 0x10) {
10336			/* Skip the big blank spaces */
10337			if (i < 0x854000 && i > 0x9ffff)
10338				BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10339					i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
10340					REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
10341		}
10342	}
10343
10344	BCE_PRINTF(
10345		"----------------------------"
10346		"----------------"
10347		"----------------------------\n");
10348}
10349
10350
10351/****************************************************************************/
10352/* Prints out the Command Procesor (CP) state.                              */
10353/*                                                                          */
10354/* Returns:                                                                 */
10355/*   Nothing.                                                               */
10356/****************************************************************************/
10357static __attribute__ ((noinline)) void
10358bce_dump_cp_state(struct bce_softc *sc, int regs)
10359{
10360	u32 val;
10361	u32 fw_version[3];
10362
10363	BCE_PRINTF(
10364		"----------------------------"
10365		"    CP State    "
10366		"----------------------------\n");
10367
10368	for (int i = 0; i < 3; i++)
10369		fw_version[i] = htonl(REG_RD_IND(sc,
10370			(BCE_CP_SCRATCH + 0x10 + i * 4)));
10371	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10372
10373	val = REG_RD_IND(sc, BCE_CP_CPU_MODE);
10374	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_mode\n", val, BCE_CP_CPU_MODE);
10375
10376	val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
10377	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n", val, BCE_CP_CPU_STATE);
10378
10379	val = REG_RD_IND(sc, BCE_CP_CPU_EVENT_MASK);
10380	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_event_mask\n", val,
10381		BCE_CP_CPU_EVENT_MASK);
10382
10383	if (regs) {
10384		BCE_PRINTF(
10385			"----------------------------"
10386			" Register  Dump "
10387			"----------------------------\n");
10388
10389		for (int i = BCE_CP_CPU_MODE; i < 0x1aa000; i += 0x10) {
10390			/* Skip the big blank spaces */
10391			if (i < 0x185400 && i > 0x19ffff)
10392				BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10393					i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
10394					REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
10395		}
10396	}
10397
10398	BCE_PRINTF(
10399		"----------------------------"
10400		"----------------"
10401		"----------------------------\n");
10402}
10403
10404
10405/****************************************************************************/
10406/* Prints out the Completion Procesor (COM) state.                          */
10407/*                                                                          */
10408/* Returns:                                                                 */
10409/*   Nothing.                                                               */
10410/****************************************************************************/
10411static __attribute__ ((noinline)) void
10412bce_dump_com_state(struct bce_softc *sc, int regs)
10413{
10414	u32 val;
10415	u32 fw_version[3];
10416
10417	BCE_PRINTF(
10418		"----------------------------"
10419		"   COM State    "
10420		"----------------------------\n");
10421
10422	for (int i = 0; i < 3; i++)
10423		fw_version[i] = htonl(REG_RD_IND(sc,
10424			(BCE_COM_SCRATCH + 0x10 + i * 4)));
10425	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
10426
10427	val = REG_RD_IND(sc, BCE_COM_CPU_MODE);
10428	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_mode\n", val, BCE_COM_CPU_MODE);
10429
10430	val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
10431	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n", val, BCE_COM_CPU_STATE);
10432
10433	val = REG_RD_IND(sc, BCE_COM_CPU_EVENT_MASK);
10434	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_event_mask\n", val,
10435		BCE_COM_CPU_EVENT_MASK);
10436
10437	if (regs) {
10438		BCE_PRINTF(
10439			"----------------------------"
10440			" Register  Dump "
10441			"----------------------------\n");
10442
10443		for (int i = BCE_COM_CPU_MODE; i < 0x1053e8; i += 0x10) {
10444			BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10445				i, REG_RD_IND(sc, i), REG_RD_IND(sc, i + 0x4),
10446				REG_RD_IND(sc, i + 0x8), REG_RD_IND(sc, i + 0xC));
10447		}
10448	}
10449
10450	BCE_PRINTF(
10451		"----------------------------"
10452		"----------------"
10453		"----------------------------\n");
10454}
10455
10456
10457/****************************************************************************/
10458/* Prints out the driver state and then enters the debugger.                */
10459/*                                                                          */
10460/* Returns:                                                                 */
10461/*   Nothing.                                                               */
10462/****************************************************************************/
10463static void
10464bce_breakpoint(struct bce_softc *sc)
10465{
10466
10467	/*
10468	 * Unreachable code to silence compiler warnings
10469	 * about unused functions.
10470	 */
10471	if (0) {
10472		bce_freeze_controller(sc);
10473		bce_unfreeze_controller(sc);
10474		bce_dump_enet(sc, NULL);
10475   		bce_dump_txbd(sc, 0, NULL);
10476		bce_dump_rxbd(sc, 0, NULL);
10477		bce_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD);
10478		bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD);
10479		bce_dump_l2fhdr(sc, 0, NULL);
10480		bce_dump_ctx(sc, RX_CID);
10481		bce_dump_ftqs(sc);
10482		bce_dump_tx_chain(sc, 0, USABLE_TX_BD);
10483		bce_dump_rx_chain(sc, 0, USABLE_RX_BD);
10484		bce_dump_status_block(sc);
10485		bce_dump_stats_block(sc);
10486		bce_dump_driver_state(sc);
10487		bce_dump_hw_state(sc);
10488		bce_dump_bc_state(sc);
10489		bce_dump_txp_state(sc, 0);
10490		bce_dump_rxp_state(sc, 0);
10491		bce_dump_tpat_state(sc, 0);
10492		bce_dump_cp_state(sc, 0);
10493		bce_dump_com_state(sc, 0);
10494#ifdef BCE_JUMBO_HDRSPLIT
10495		bce_dump_pgbd(sc, 0, NULL);
10496		bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD);
10497		bce_dump_pg_chain(sc, 0, USABLE_PG_BD);
10498#endif
10499	}
10500
10501	bce_dump_status_block(sc);
10502	bce_dump_driver_state(sc);
10503
10504	/* Call the debugger. */
10505	breakpoint();
10506
10507	return;
10508}
10509#endif
10510
10511