1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2006-2014 QLogic Corporation
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26 * THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <sys/cdefs.h>
30/*
31 * The following controllers are supported by this driver:
32 *   BCM5706C A2, A3
33 *   BCM5706S A2, A3
34 *   BCM5708C B1, B2
35 *   BCM5708S B1, B2
36 *   BCM5709C A1, C0
37 *   BCM5709S A1, C0
38 *   BCM5716C C0
39 *   BCM5716S C0
40 *
41 * The following controllers are not supported by this driver:
42 *   BCM5706C A0, A1 (pre-production)
43 *   BCM5706S A0, A1 (pre-production)
44 *   BCM5708C A0, B0 (pre-production)
45 *   BCM5708S A0, B0 (pre-production)
46 *   BCM5709C A0  B0, B1, B2 (pre-production)
47 *   BCM5709S A0, B0, B1, B2 (pre-production)
48 */
49
50#include "opt_bce.h"
51
52#include <sys/param.h>
53#include <sys/endian.h>
54#include <sys/systm.h>
55#include <sys/sockio.h>
56#include <sys/lock.h>
57#include <sys/mbuf.h>
58#include <sys/malloc.h>
59#include <sys/mutex.h>
60#include <sys/kernel.h>
61#include <sys/module.h>
62#include <sys/socket.h>
63#include <sys/sysctl.h>
64#include <sys/queue.h>
65
66#include <net/bpf.h>
67#include <net/ethernet.h>
68#include <net/if.h>
69#include <net/if_var.h>
70#include <net/if_arp.h>
71#include <net/if_dl.h>
72#include <net/if_media.h>
73
74#include <net/if_types.h>
75#include <net/if_vlan_var.h>
76
77#include <netinet/in_systm.h>
78#include <netinet/in.h>
79#include <netinet/if_ether.h>
80#include <netinet/ip.h>
81#include <netinet/ip6.h>
82#include <netinet/tcp.h>
83#include <netinet/udp.h>
84
85#include <machine/bus.h>
86#include <machine/resource.h>
87#include <sys/bus.h>
88#include <sys/rman.h>
89
90#include <dev/mii/mii.h>
91#include <dev/mii/miivar.h>
92#include "miidevs.h"
93#include <dev/mii/brgphyreg.h>
94
95#include <dev/pci/pcireg.h>
96#include <dev/pci/pcivar.h>
97
98#include "miibus_if.h"
99
100#include <dev/bce/if_bcereg.h>
101#include <dev/bce/if_bcefw.h>
102
103/****************************************************************************/
104/* BCE Debug Options                                                        */
105/****************************************************************************/
106#ifdef BCE_DEBUG
107	u32 bce_debug = BCE_WARN;
108
109	/*          0 = Never              */
110	/*          1 = 1 in 2,147,483,648 */
111	/*        256 = 1 in     8,388,608 */
112	/*       2048 = 1 in     1,048,576 */
113	/*      65536 = 1 in        32,768 */
114	/*    1048576 = 1 in         2,048 */
115	/*  268435456 =	1 in             8 */
116	/*  536870912 = 1 in             4 */
117	/* 1073741824 = 1 in             2 */
118
119	/* Controls how often the l2_fhdr frame error check will fail. */
120	int l2fhdr_error_sim_control = 0;
121
122	/* Controls how often the unexpected attention check will fail. */
123	int unexpected_attention_sim_control = 0;
124
125	/* Controls how often to simulate an mbuf allocation failure. */
126	int mbuf_alloc_failed_sim_control = 0;
127
128	/* Controls how often to simulate a DMA mapping failure. */
129	int dma_map_addr_failed_sim_control = 0;
130
131	/* Controls how often to simulate a bootcode failure. */
132	int bootcode_running_failure_sim_control = 0;
133#endif
134
135/****************************************************************************/
136/* PCI Device ID Table                                                      */
137/*                                                                          */
138/* Used by bce_probe() to identify the devices supported by this driver.    */
139/****************************************************************************/
140#define BCE_DEVDESC_MAX		64
141
142static const struct bce_type bce_devs[] = {
143	/* BCM5706C Controllers and OEM boards. */
144	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3101,
145		"HP NC370T Multifunction Gigabit Server Adapter" },
146	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3106,
147		"HP NC370i Multifunction Gigabit Server Adapter" },
148	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3070,
149		"HP NC380T PCIe DP Multifunc Gig Server Adapter" },
150	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x1709,
151		"HP NC371i Multifunction Gigabit Server Adapter" },
152	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  PCI_ANY_ID,  PCI_ANY_ID,
153		"QLogic NetXtreme II BCM5706 1000Base-T" },
154
155	/* BCM5706S controllers and OEM boards. */
156	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, HP_VENDORID, 0x3102,
157		"HP NC370F Multifunction Gigabit Server Adapter" },
158	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, PCI_ANY_ID,  PCI_ANY_ID,
159		"QLogic NetXtreme II BCM5706 1000Base-SX" },
160
161	/* BCM5708C controllers and OEM boards. */
162	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7037,
163		"HP NC373T PCIe Multifunction Gig Server Adapter" },
164	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7038,
165		"HP NC373i Multifunction Gigabit Server Adapter" },
166	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7045,
167		"HP NC374m PCIe Multifunction Adapter" },
168	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  PCI_ANY_ID,  PCI_ANY_ID,
169		"QLogic NetXtreme II BCM5708 1000Base-T" },
170
171	/* BCM5708S controllers and OEM boards. */
172	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x1706,
173		"HP NC373m Multifunction Gigabit Server Adapter" },
174	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703b,
175		"HP NC373i Multifunction Gigabit Server Adapter" },
176	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703d,
177		"HP NC373F PCIe Multifunc Giga Server Adapter" },
178	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  PCI_ANY_ID,  PCI_ANY_ID,
179		"QLogic NetXtreme II BCM5708 1000Base-SX" },
180
181	/* BCM5709C controllers and OEM boards. */
182	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7055,
183		"HP NC382i DP Multifunction Gigabit Server Adapter" },
184	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7059,
185		"HP NC382T PCIe DP Multifunction Gigabit Server Adapter" },
186	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  PCI_ANY_ID,  PCI_ANY_ID,
187		"QLogic NetXtreme II BCM5709 1000Base-T" },
188
189	/* BCM5709S controllers and OEM boards. */
190	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x171d,
191		"HP NC382m DP 1GbE Multifunction BL-c Adapter" },
192	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x7056,
193		"HP NC382i DP Multifunction Gigabit Server Adapter" },
194	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  PCI_ANY_ID,  PCI_ANY_ID,
195		"QLogic NetXtreme II BCM5709 1000Base-SX" },
196
197	/* BCM5716 controllers and OEM boards. */
198	{ BRCM_VENDORID, BRCM_DEVICEID_BCM5716,  PCI_ANY_ID,  PCI_ANY_ID,
199		"QLogic NetXtreme II BCM5716 1000Base-T" },
200	{ 0, 0, 0, 0, NULL }
201};
202
203/****************************************************************************/
204/* Supported Flash NVRAM device data.                                       */
205/****************************************************************************/
206static const struct flash_spec flash_table[] =
207{
208#define BUFFERED_FLAGS		(BCE_NV_BUFFERED | BCE_NV_TRANSLATE)
209#define NONBUFFERED_FLAGS	(BCE_NV_WREN)
210
211	/* Slow EEPROM */
212	{0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
213	 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
214	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
215	 "EEPROM - slow"},
216	/* Expansion entry 0001 */
217	{0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
218	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
219	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
220	 "Entry 0001"},
221	/* Saifun SA25F010 (non-buffered flash) */
222	/* strap, cfg1, & write1 need updates */
223	{0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
224	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
225	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
226	 "Non-buffered flash (128kB)"},
227	/* Saifun SA25F020 (non-buffered flash) */
228	/* strap, cfg1, & write1 need updates */
229	{0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
230	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
231	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
232	 "Non-buffered flash (256kB)"},
233	/* Expansion entry 0100 */
234	{0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
235	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
236	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
237	 "Entry 0100"},
238	/* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
239	{0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
240	 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
241	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
242	 "Entry 0101: ST M45PE10 (128kB non-buffered)"},
243	/* Entry 0110: ST M45PE20 (non-buffered flash)*/
244	{0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
245	 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
246	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
247	 "Entry 0110: ST M45PE20 (256kB non-buffered)"},
248	/* Saifun SA25F005 (non-buffered flash) */
249	/* strap, cfg1, & write1 need updates */
250	{0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
251	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
252	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
253	 "Non-buffered flash (64kB)"},
254	/* Fast EEPROM */
255	{0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
256	 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
257	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
258	 "EEPROM - fast"},
259	/* Expansion entry 1001 */
260	{0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
261	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
262	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
263	 "Entry 1001"},
264	/* Expansion entry 1010 */
265	{0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
266	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
267	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
268	 "Entry 1010"},
269	/* ATMEL AT45DB011B (buffered flash) */
270	{0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
271	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
272	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
273	 "Buffered flash (128kB)"},
274	/* Expansion entry 1100 */
275	{0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
276	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
277	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
278	 "Entry 1100"},
279	/* Expansion entry 1101 */
280	{0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
281	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
282	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
283	 "Entry 1101"},
284	/* Ateml Expansion entry 1110 */
285	{0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
286	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
287	 BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
288	 "Entry 1110 (Atmel)"},
289	/* ATMEL AT45DB021B (buffered flash) */
290	{0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
291	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
292	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
293	 "Buffered flash (256kB)"},
294};
295
296/*
297 * The BCM5709 controllers transparently handle the
298 * differences between Atmel 264 byte pages and all
299 * flash devices which use 256 byte pages, so no
300 * logical-to-physical mapping is required in the
301 * driver.
302 */
303static const struct flash_spec flash_5709 = {
304	.flags		= BCE_NV_BUFFERED,
305	.page_bits	= BCM5709_FLASH_PAGE_BITS,
306	.page_size	= BCM5709_FLASH_PAGE_SIZE,
307	.addr_mask	= BCM5709_FLASH_BYTE_ADDR_MASK,
308	.total_size	= BUFFERED_FLASH_TOTAL_SIZE * 2,
309	.name		= "5709/5716 buffered flash (256kB)",
310};
311
312/****************************************************************************/
313/* FreeBSD device entry points.                                             */
314/****************************************************************************/
315static int  bce_probe			(device_t);
316static int  bce_attach			(device_t);
317static int  bce_detach			(device_t);
318static int  bce_shutdown		(device_t);
319
320/****************************************************************************/
321/* BCE Debug Data Structure Dump Routines                                   */
322/****************************************************************************/
323#ifdef BCE_DEBUG
324static u32  bce_reg_rd				(struct bce_softc *, u32);
325static void bce_reg_wr				(struct bce_softc *, u32, u32);
326static void bce_reg_wr16			(struct bce_softc *, u32, u16);
327static u32  bce_ctx_rd				(struct bce_softc *, u32, u32);
328static void bce_dump_enet			(struct bce_softc *, struct mbuf *);
329static void bce_dump_mbuf			(struct bce_softc *, struct mbuf *);
330static void bce_dump_tx_mbuf_chain	(struct bce_softc *, u16, int);
331static void bce_dump_rx_mbuf_chain	(struct bce_softc *, u16, int);
332static void bce_dump_pg_mbuf_chain	(struct bce_softc *, u16, int);
333static void bce_dump_txbd			(struct bce_softc *,
334    int, struct tx_bd *);
335static void bce_dump_rxbd			(struct bce_softc *,
336    int, struct rx_bd *);
337static void bce_dump_pgbd			(struct bce_softc *,
338    int, struct rx_bd *);
339static void bce_dump_l2fhdr		(struct bce_softc *,
340    int, struct l2_fhdr *);
341static void bce_dump_ctx			(struct bce_softc *, u16);
342static void bce_dump_ftqs			(struct bce_softc *);
343static void bce_dump_tx_chain		(struct bce_softc *, u16, int);
344static void bce_dump_rx_bd_chain	(struct bce_softc *, u16, int);
345static void bce_dump_pg_chain		(struct bce_softc *, u16, int);
346static void bce_dump_status_block	(struct bce_softc *);
347static void bce_dump_stats_block	(struct bce_softc *);
348static void bce_dump_driver_state	(struct bce_softc *);
349static void bce_dump_hw_state		(struct bce_softc *);
350static void bce_dump_shmem_state	(struct bce_softc *);
351static void bce_dump_mq_regs		(struct bce_softc *);
352static void bce_dump_bc_state		(struct bce_softc *);
353static void bce_dump_txp_state		(struct bce_softc *, int);
354static void bce_dump_rxp_state		(struct bce_softc *, int);
355static void bce_dump_tpat_state	(struct bce_softc *, int);
356static void bce_dump_cp_state		(struct bce_softc *, int);
357static void bce_dump_com_state		(struct bce_softc *, int);
358static void bce_dump_rv2p_state	(struct bce_softc *);
359static void bce_breakpoint			(struct bce_softc *);
360#endif /*BCE_DEBUG */
361
362/****************************************************************************/
363/* BCE Register/Memory Access Routines                                      */
364/****************************************************************************/
365static u32  bce_reg_rd_ind		(struct bce_softc *, u32);
366static void bce_reg_wr_ind		(struct bce_softc *, u32, u32);
367static void bce_shmem_wr		(struct bce_softc *, u32, u32);
368static u32  bce_shmem_rd		(struct bce_softc *, u32);
369static void bce_ctx_wr			(struct bce_softc *, u32, u32, u32);
370static int  bce_miibus_read_reg		(device_t, int, int);
371static int  bce_miibus_write_reg	(device_t, int, int, int);
372static void bce_miibus_statchg		(device_t);
373
374#ifdef BCE_DEBUG
375static int bce_sysctl_nvram_dump(SYSCTL_HANDLER_ARGS);
376#ifdef BCE_NVRAM_WRITE_SUPPORT
377static int bce_sysctl_nvram_write(SYSCTL_HANDLER_ARGS);
378#endif
379#endif
380
381/****************************************************************************/
382/* BCE NVRAM Access Routines                                                */
383/****************************************************************************/
384static int  bce_acquire_nvram_lock	(struct bce_softc *);
385static int  bce_release_nvram_lock	(struct bce_softc *);
386static void bce_enable_nvram_access(struct bce_softc *);
387static void bce_disable_nvram_access(struct bce_softc *);
388static int  bce_nvram_read_dword	(struct bce_softc *, u32, u8 *, u32);
389static int  bce_init_nvram			(struct bce_softc *);
390static int  bce_nvram_read			(struct bce_softc *, u32, u8 *, int);
391static int  bce_nvram_test			(struct bce_softc *);
392#ifdef BCE_NVRAM_WRITE_SUPPORT
393static int  bce_enable_nvram_write	(struct bce_softc *);
394static void bce_disable_nvram_write(struct bce_softc *);
395static int  bce_nvram_erase_page	(struct bce_softc *, u32);
396static int  bce_nvram_write_dword	(struct bce_softc *, u32, u8 *, u32);
397static int  bce_nvram_write		(struct bce_softc *, u32, u8 *, int);
398#endif
399
400/****************************************************************************/
401/*                                                                          */
402/****************************************************************************/
403static void bce_get_rx_buffer_sizes(struct bce_softc *, int);
404static void bce_get_media			(struct bce_softc *);
405static void bce_init_media			(struct bce_softc *);
406static u32 bce_get_rphy_link		(struct bce_softc *);
407static void bce_dma_map_addr		(void *, bus_dma_segment_t *, int, int);
408static int  bce_dma_alloc			(device_t);
409static void bce_dma_free			(struct bce_softc *);
410static void bce_release_resources	(struct bce_softc *);
411
412/****************************************************************************/
413/* BCE Firmware Synchronization and Load                                    */
414/****************************************************************************/
415static void bce_fw_cap_init			(struct bce_softc *);
416static int  bce_fw_sync			(struct bce_softc *, u32);
417static void bce_load_rv2p_fw		(struct bce_softc *, const u32 *, u32,
418    u32);
419static void bce_load_cpu_fw		(struct bce_softc *,
420    struct cpu_reg *, struct fw_info *);
421static void bce_start_cpu			(struct bce_softc *, struct cpu_reg *);
422static void bce_halt_cpu			(struct bce_softc *, struct cpu_reg *);
423static void bce_start_rxp_cpu		(struct bce_softc *);
424static void bce_init_rxp_cpu		(struct bce_softc *);
425static void bce_init_txp_cpu 		(struct bce_softc *);
426static void bce_init_tpat_cpu		(struct bce_softc *);
427static void bce_init_cp_cpu	  	(struct bce_softc *);
428static void bce_init_com_cpu	  	(struct bce_softc *);
429static void bce_init_cpus			(struct bce_softc *);
430
431static void bce_print_adapter_info	(struct bce_softc *);
432static void bce_probe_pci_caps		(device_t, struct bce_softc *);
433static void bce_stop				(struct bce_softc *);
434static int  bce_reset				(struct bce_softc *, u32);
435static int  bce_chipinit 			(struct bce_softc *);
436static int  bce_blockinit 			(struct bce_softc *);
437
438static int  bce_init_tx_chain		(struct bce_softc *);
439static void bce_free_tx_chain		(struct bce_softc *);
440
441static int  bce_get_rx_buf		(struct bce_softc *, u16, u16, u32 *);
442static int  bce_init_rx_chain		(struct bce_softc *);
443static void bce_fill_rx_chain		(struct bce_softc *);
444static void bce_free_rx_chain		(struct bce_softc *);
445
446static int  bce_get_pg_buf		(struct bce_softc *, u16, u16);
447static int  bce_init_pg_chain		(struct bce_softc *);
448static void bce_fill_pg_chain		(struct bce_softc *);
449static void bce_free_pg_chain		(struct bce_softc *);
450
451static struct mbuf *bce_tso_setup	(struct bce_softc *,
452    struct mbuf **, u16 *);
453static int  bce_tx_encap			(struct bce_softc *, struct mbuf **);
454static void bce_start_locked		(if_t);
455static void bce_start			(if_t);
456static int  bce_ioctl			(if_t, u_long, caddr_t);
457static uint64_t bce_get_counter		(if_t, ift_counter);
458static void bce_watchdog		(struct bce_softc *);
459static int  bce_ifmedia_upd		(if_t);
460static int  bce_ifmedia_upd_locked	(if_t);
461static void bce_ifmedia_sts		(if_t, struct ifmediareq *);
462static void bce_ifmedia_sts_rphy	(struct bce_softc *, struct ifmediareq *);
463static void bce_init_locked		(struct bce_softc *);
464static void bce_init				(void *);
465static void bce_mgmt_init_locked	(struct bce_softc *sc);
466
467static int  bce_init_ctx			(struct bce_softc *);
468static void bce_get_mac_addr		(struct bce_softc *);
469static void bce_set_mac_addr		(struct bce_softc *);
470static void bce_phy_intr			(struct bce_softc *);
471static inline u16 bce_get_hw_rx_cons	(struct bce_softc *);
472static void bce_rx_intr			(struct bce_softc *);
473static void bce_tx_intr			(struct bce_softc *);
474static void bce_disable_intr		(struct bce_softc *);
475static void bce_enable_intr		(struct bce_softc *, int);
476
477static void bce_intr				(void *);
478static void bce_set_rx_mode		(struct bce_softc *);
479static void bce_stats_update		(struct bce_softc *);
480static void bce_tick				(void *);
481static void bce_pulse				(void *);
482static void bce_add_sysctls		(struct bce_softc *);
483
484/****************************************************************************/
485/* FreeBSD device dispatch table.                                           */
486/****************************************************************************/
487static device_method_t bce_methods[] = {
488	/* Device interface (device_if.h) */
489	DEVMETHOD(device_probe,		bce_probe),
490	DEVMETHOD(device_attach,	bce_attach),
491	DEVMETHOD(device_detach,	bce_detach),
492	DEVMETHOD(device_shutdown,	bce_shutdown),
493/* Supported by device interface but not used here. */
494/*	DEVMETHOD(device_identify,	bce_identify),      */
495/*	DEVMETHOD(device_suspend,	bce_suspend),       */
496/*	DEVMETHOD(device_resume,	bce_resume),        */
497/*	DEVMETHOD(device_quiesce,	bce_quiesce),       */
498
499	/* MII interface (miibus_if.h) */
500	DEVMETHOD(miibus_readreg,	bce_miibus_read_reg),
501	DEVMETHOD(miibus_writereg,	bce_miibus_write_reg),
502	DEVMETHOD(miibus_statchg,	bce_miibus_statchg),
503/* Supported by MII interface but not used here.       */
504/*	DEVMETHOD(miibus_linkchg,	bce_miibus_linkchg),   */
505/*	DEVMETHOD(miibus_mediainit,	bce_miibus_mediainit), */
506
507	DEVMETHOD_END
508};
509
510static driver_t bce_driver = {
511	"bce",
512	bce_methods,
513	sizeof(struct bce_softc)
514};
515
516MODULE_DEPEND(bce, pci, 1, 1, 1);
517MODULE_DEPEND(bce, ether, 1, 1, 1);
518MODULE_DEPEND(bce, miibus, 1, 1, 1);
519
520DRIVER_MODULE(bce, pci, bce_driver, NULL, NULL);
521DRIVER_MODULE(miibus, bce, miibus_driver, NULL, NULL);
522MODULE_PNP_INFO("U16:vendor;U16:device;U16:#;U16:#;D:#", pci, bce,
523    bce_devs, nitems(bce_devs) - 1);
524
525/****************************************************************************/
526/* Tunable device values                                                    */
527/****************************************************************************/
528static SYSCTL_NODE(_hw, OID_AUTO, bce, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
529    "bce driver parameters");
530
531/* Allowable values are TRUE or FALSE */
532static int bce_verbose = TRUE;
533SYSCTL_INT(_hw_bce, OID_AUTO, verbose, CTLFLAG_RDTUN, &bce_verbose, 0,
534    "Verbose output enable/disable");
535
536/* Allowable values are TRUE or FALSE */
537static int bce_tso_enable = TRUE;
538SYSCTL_INT(_hw_bce, OID_AUTO, tso_enable, CTLFLAG_RDTUN, &bce_tso_enable, 0,
539    "TSO Enable/Disable");
540
541/* Allowable values are 0 (IRQ), 1 (MSI/IRQ), and 2 (MSI-X/MSI/IRQ) */
542/* ToDo: Add MSI-X support. */
543static int bce_msi_enable = 1;
544SYSCTL_INT(_hw_bce, OID_AUTO, msi_enable, CTLFLAG_RDTUN, &bce_msi_enable, 0,
545    "MSI-X|MSI|INTx selector");
546
547/* Allowable values are 1, 2, 4, 8. */
548static int bce_rx_pages = DEFAULT_RX_PAGES;
549SYSCTL_UINT(_hw_bce, OID_AUTO, rx_pages, CTLFLAG_RDTUN, &bce_rx_pages, 0,
550    "Receive buffer descriptor pages (1 page = 255 buffer descriptors)");
551
552/* Allowable values are 1, 2, 4, 8. */
553static int bce_tx_pages = DEFAULT_TX_PAGES;
554SYSCTL_UINT(_hw_bce, OID_AUTO, tx_pages, CTLFLAG_RDTUN, &bce_tx_pages, 0,
555    "Transmit buffer descriptor pages (1 page = 255 buffer descriptors)");
556
557/* Allowable values are TRUE or FALSE. */
558static int bce_hdr_split = TRUE;
559SYSCTL_UINT(_hw_bce, OID_AUTO, hdr_split, CTLFLAG_RDTUN, &bce_hdr_split, 0,
560    "Frame header/payload splitting Enable/Disable");
561
562/* Allowable values are TRUE or FALSE. */
563static int bce_strict_rx_mtu = FALSE;
564SYSCTL_UINT(_hw_bce, OID_AUTO, strict_rx_mtu, CTLFLAG_RDTUN,
565    &bce_strict_rx_mtu, 0,
566    "Enable/Disable strict RX frame size checking");
567
568/* Allowable values are 0 ... 100 */
569#ifdef BCE_DEBUG
570/* Generate 1 interrupt for every transmit completion. */
571static int bce_tx_quick_cons_trip_int = 1;
572#else
573/* Generate 1 interrupt for every 20 transmit completions. */
574static int bce_tx_quick_cons_trip_int = DEFAULT_TX_QUICK_CONS_TRIP_INT;
575#endif
576SYSCTL_UINT(_hw_bce, OID_AUTO, tx_quick_cons_trip_int, CTLFLAG_RDTUN,
577    &bce_tx_quick_cons_trip_int, 0,
578    "Transmit BD trip point during interrupts");
579
580/* Allowable values are 0 ... 100 */
581/* Generate 1 interrupt for every transmit completion. */
582#ifdef BCE_DEBUG
583static int bce_tx_quick_cons_trip = 1;
584#else
585/* Generate 1 interrupt for every 20 transmit completions. */
586static int bce_tx_quick_cons_trip = DEFAULT_TX_QUICK_CONS_TRIP;
587#endif
588SYSCTL_UINT(_hw_bce, OID_AUTO, tx_quick_cons_trip, CTLFLAG_RDTUN,
589    &bce_tx_quick_cons_trip, 0,
590    "Transmit BD trip point");
591
592/* Allowable values are 0 ... 100 */
593#ifdef BCE_DEBUG
594/* Generate an interrupt if 0us have elapsed since the last TX completion. */
595static int bce_tx_ticks_int = 0;
596#else
597/* Generate an interrupt if 80us have elapsed since the last TX completion. */
598static int bce_tx_ticks_int = DEFAULT_TX_TICKS_INT;
599#endif
600SYSCTL_UINT(_hw_bce, OID_AUTO, tx_ticks_int, CTLFLAG_RDTUN,
601    &bce_tx_ticks_int, 0, "Transmit ticks count during interrupt");
602
603/* Allowable values are 0 ... 100 */
604#ifdef BCE_DEBUG
605/* Generate an interrupt if 0us have elapsed since the last TX completion. */
606static int bce_tx_ticks = 0;
607#else
608/* Generate an interrupt if 80us have elapsed since the last TX completion. */
609static int bce_tx_ticks = DEFAULT_TX_TICKS;
610#endif
611SYSCTL_UINT(_hw_bce, OID_AUTO, tx_ticks, CTLFLAG_RDTUN,
612    &bce_tx_ticks, 0, "Transmit ticks count");
613
614/* Allowable values are 1 ... 100 */
615#ifdef BCE_DEBUG
616/* Generate 1 interrupt for every received frame. */
617static int bce_rx_quick_cons_trip_int = 1;
618#else
619/* Generate 1 interrupt for every 6 received frames. */
620static int bce_rx_quick_cons_trip_int = DEFAULT_RX_QUICK_CONS_TRIP_INT;
621#endif
622SYSCTL_UINT(_hw_bce, OID_AUTO, rx_quick_cons_trip_int, CTLFLAG_RDTUN,
623    &bce_rx_quick_cons_trip_int, 0,
624    "Receive BD trip point during interrupts");
625
626/* Allowable values are 1 ... 100 */
627#ifdef BCE_DEBUG
628/* Generate 1 interrupt for every received frame. */
629static int bce_rx_quick_cons_trip = 1;
630#else
631/* Generate 1 interrupt for every 6 received frames. */
632static int bce_rx_quick_cons_trip = DEFAULT_RX_QUICK_CONS_TRIP;
633#endif
634SYSCTL_UINT(_hw_bce, OID_AUTO, rx_quick_cons_trip, CTLFLAG_RDTUN,
635    &bce_rx_quick_cons_trip, 0,
636    "Receive BD trip point");
637
638/* Allowable values are 0 ... 100 */
639#ifdef BCE_DEBUG
640/* Generate an int. if 0us have elapsed since the last received frame. */
641static int bce_rx_ticks_int = 0;
642#else
643/* Generate an int. if 18us have elapsed since the last received frame. */
644static int bce_rx_ticks_int = DEFAULT_RX_TICKS_INT;
645#endif
646SYSCTL_UINT(_hw_bce, OID_AUTO, rx_ticks_int, CTLFLAG_RDTUN,
647    &bce_rx_ticks_int, 0, "Receive ticks count during interrupt");
648
649/* Allowable values are 0 ... 100 */
650#ifdef BCE_DEBUG
651/* Generate an int. if 0us have elapsed since the last received frame. */
652static int bce_rx_ticks = 0;
653#else
654/* Generate an int. if 18us have elapsed since the last received frame. */
655static int bce_rx_ticks = DEFAULT_RX_TICKS;
656#endif
657SYSCTL_UINT(_hw_bce, OID_AUTO, rx_ticks, CTLFLAG_RDTUN,
658    &bce_rx_ticks, 0, "Receive ticks count");
659
660/****************************************************************************/
661/* Device probe function.                                                   */
662/*                                                                          */
663/* Compares the device to the driver's list of supported devices and        */
664/* reports back to the OS whether this is the right driver for the device.  */
665/*                                                                          */
666/* Returns:                                                                 */
667/*   BUS_PROBE_DEFAULT on success, positive value on failure.               */
668/****************************************************************************/
669static int
670bce_probe(device_t dev)
671{
672	const struct bce_type *t;
673	struct bce_softc *sc;
674	char *descbuf;
675	u16 vid = 0, did = 0, svid = 0, sdid = 0;
676
677	t = bce_devs;
678
679	sc = device_get_softc(dev);
680	sc->bce_unit = device_get_unit(dev);
681	sc->bce_dev = dev;
682
683	/* Get the data for the device to be probed. */
684	vid  = pci_get_vendor(dev);
685	did  = pci_get_device(dev);
686	svid = pci_get_subvendor(dev);
687	sdid = pci_get_subdevice(dev);
688
689	DBPRINT(sc, BCE_EXTREME_LOAD,
690	    "%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
691	    "SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
692
693	/* Look through the list of known devices for a match. */
694	while(t->bce_name != NULL) {
695		if ((vid == t->bce_vid) && (did == t->bce_did) &&
696		    ((svid == t->bce_svid) || (t->bce_svid == PCI_ANY_ID)) &&
697		    ((sdid == t->bce_sdid) || (t->bce_sdid == PCI_ANY_ID))) {
698			descbuf = malloc(BCE_DEVDESC_MAX, M_TEMP, M_NOWAIT);
699
700			if (descbuf == NULL)
701				return(ENOMEM);
702
703			/* Print out the device identity. */
704			snprintf(descbuf, BCE_DEVDESC_MAX, "%s (%c%d)",
705			    t->bce_name, (((pci_read_config(dev,
706			    PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
707			    (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
708
709			device_set_desc_copy(dev, descbuf);
710			free(descbuf, M_TEMP);
711			return(BUS_PROBE_DEFAULT);
712		}
713		t++;
714	}
715
716	return(ENXIO);
717}
718
719/****************************************************************************/
720/* PCI Capabilities Probe Function.                                         */
721/*                                                                          */
722/* Walks the PCI capabiites list for the device to find what features are   */
723/* supported.                                                               */
724/*                                                                          */
725/* Returns:                                                                 */
726/*   None.                                                                  */
727/****************************************************************************/
728static void
729bce_print_adapter_info(struct bce_softc *sc)
730{
731	int i = 0;
732
733	DBENTER(BCE_VERBOSE_LOAD);
734
735	if (bce_verbose || bootverbose) {
736		BCE_PRINTF("ASIC (0x%08X); ", sc->bce_chipid);
737		printf("Rev (%c%d); ", ((BCE_CHIP_ID(sc) & 0xf000) >>
738		    12) + 'A', ((BCE_CHIP_ID(sc) & 0x0ff0) >> 4));
739
740		/* Bus info. */
741		if (sc->bce_flags & BCE_PCIE_FLAG) {
742			printf("Bus (PCIe x%d, ", sc->link_width);
743			switch (sc->link_speed) {
744			case 1: printf("2.5Gbps); "); break;
745			case 2:	printf("5Gbps); "); break;
746			default: printf("Unknown link speed); ");
747			}
748		} else {
749			printf("Bus (PCI%s, %s, %dMHz); ",
750			    ((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""),
751			    ((sc->bce_flags & BCE_PCI_32BIT_FLAG) ?
752			    "32-bit" : "64-bit"), sc->bus_speed_mhz);
753		}
754
755		/* Firmware version and device features. */
756		printf("B/C (%s); Bufs (RX:%d;TX:%d;PG:%d); Flags (",
757		    sc->bce_bc_ver,	sc->rx_pages, sc->tx_pages,
758		    (bce_hdr_split == TRUE ? sc->pg_pages: 0));
759
760		if (bce_hdr_split == TRUE) {
761			printf("SPLT");
762			i++;
763		}
764
765		if (sc->bce_flags & BCE_USING_MSI_FLAG) {
766			if (i > 0) printf("|");
767			printf("MSI"); i++;
768		}
769
770		if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
771			if (i > 0) printf("|");
772			printf("MSI-X"); i++;
773		}
774
775		if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
776			if (i > 0) printf("|");
777			printf("2.5G"); i++;
778		}
779
780		if (sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) {
781			if (i > 0) printf("|");
782			printf("Remote PHY(%s)",
783			    sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG ?
784			    "FIBER" : "TP"); i++;
785		}
786
787		if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
788			if (i > 0) printf("|");
789			printf("MFW); MFW (%s)\n", sc->bce_mfw_ver);
790		} else {
791			printf(")\n");
792		}
793
794		printf("Coal (RX:%d,%d,%d,%d; TX:%d,%d,%d,%d)\n",
795		    sc->bce_rx_quick_cons_trip_int,
796		    sc->bce_rx_quick_cons_trip,
797		    sc->bce_rx_ticks_int,
798		    sc->bce_rx_ticks,
799		    sc->bce_tx_quick_cons_trip_int,
800		    sc->bce_tx_quick_cons_trip,
801		    sc->bce_tx_ticks_int,
802		    sc->bce_tx_ticks);
803	}
804
805	DBEXIT(BCE_VERBOSE_LOAD);
806}
807
808/****************************************************************************/
809/* PCI Capabilities Probe Function.                                         */
810/*                                                                          */
811/* Walks the PCI capabiites list for the device to find what features are   */
812/* supported.                                                               */
813/*                                                                          */
814/* Returns:                                                                 */
815/*   None.                                                                  */
816/****************************************************************************/
817static void
818bce_probe_pci_caps(device_t dev, struct bce_softc *sc)
819{
820	u32 reg;
821
822	DBENTER(BCE_VERBOSE_LOAD);
823
824	/* Check if PCI-X capability is enabled. */
825	if (pci_find_cap(dev, PCIY_PCIX, &reg) == 0) {
826		if (reg != 0)
827			sc->bce_cap_flags |= BCE_PCIX_CAPABLE_FLAG;
828	}
829
830	/* Check if PCIe capability is enabled. */
831	if (pci_find_cap(dev, PCIY_EXPRESS, &reg) == 0) {
832		if (reg != 0) {
833			u16 link_status = pci_read_config(dev, reg + 0x12, 2);
834			DBPRINT(sc, BCE_INFO_LOAD, "PCIe link_status = "
835			    "0x%08X\n",	link_status);
836			sc->link_speed = link_status & 0xf;
837			sc->link_width = (link_status >> 4) & 0x3f;
838			sc->bce_cap_flags |= BCE_PCIE_CAPABLE_FLAG;
839			sc->bce_flags |= BCE_PCIE_FLAG;
840		}
841	}
842
843	/* Check if MSI capability is enabled. */
844	if (pci_find_cap(dev, PCIY_MSI, &reg) == 0) {
845		if (reg != 0)
846			sc->bce_cap_flags |= BCE_MSI_CAPABLE_FLAG;
847	}
848
849	/* Check if MSI-X capability is enabled. */
850	if (pci_find_cap(dev, PCIY_MSIX, &reg) == 0) {
851		if (reg != 0)
852			sc->bce_cap_flags |= BCE_MSIX_CAPABLE_FLAG;
853	}
854
855	DBEXIT(BCE_VERBOSE_LOAD);
856}
857
858/****************************************************************************/
859/* Load and validate user tunable settings.                                 */
860/*                                                                          */
861/* Returns:                                                                 */
862/*   Nothing.                                                               */
863/****************************************************************************/
864static void
865bce_set_tunables(struct bce_softc *sc)
866{
867	/* Set sysctl values for RX page count. */
868	switch (bce_rx_pages) {
869	case 1:
870		/* fall-through */
871	case 2:
872		/* fall-through */
873	case 4:
874		/* fall-through */
875	case 8:
876		sc->rx_pages = bce_rx_pages;
877		break;
878	default:
879		sc->rx_pages = DEFAULT_RX_PAGES;
880		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
881		    "hw.bce.rx_pages!  Setting default of %d.\n",
882		    __FILE__, __LINE__, bce_rx_pages, DEFAULT_RX_PAGES);
883	}
884
885	/* ToDo: Consider allowing user setting for pg_pages. */
886	sc->pg_pages = min((sc->rx_pages * 4), MAX_PG_PAGES);
887
888	/* Set sysctl values for TX page count. */
889	switch (bce_tx_pages) {
890	case 1:
891		/* fall-through */
892	case 2:
893		/* fall-through */
894	case 4:
895		/* fall-through */
896	case 8:
897		sc->tx_pages = bce_tx_pages;
898		break;
899	default:
900		sc->tx_pages = DEFAULT_TX_PAGES;
901		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
902		    "hw.bce.tx_pages!  Setting default of %d.\n",
903		    __FILE__, __LINE__, bce_tx_pages, DEFAULT_TX_PAGES);
904	}
905
906	/*
907	 * Validate the TX trip point (i.e. the number of
908	 * TX completions before a status block update is
909	 * generated and an interrupt is asserted.
910	 */
911	if (bce_tx_quick_cons_trip_int <= 100) {
912		sc->bce_tx_quick_cons_trip_int =
913		    bce_tx_quick_cons_trip_int;
914	} else {
915		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
916		    "hw.bce.tx_quick_cons_trip_int!  Setting default of %d.\n",
917		    __FILE__, __LINE__, bce_tx_quick_cons_trip_int,
918		    DEFAULT_TX_QUICK_CONS_TRIP_INT);
919		sc->bce_tx_quick_cons_trip_int =
920		    DEFAULT_TX_QUICK_CONS_TRIP_INT;
921	}
922
923	if (bce_tx_quick_cons_trip <= 100) {
924		sc->bce_tx_quick_cons_trip =
925		    bce_tx_quick_cons_trip;
926	} else {
927		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
928		    "hw.bce.tx_quick_cons_trip!  Setting default of %d.\n",
929		    __FILE__, __LINE__, bce_tx_quick_cons_trip,
930		    DEFAULT_TX_QUICK_CONS_TRIP);
931		sc->bce_tx_quick_cons_trip =
932		    DEFAULT_TX_QUICK_CONS_TRIP;
933	}
934
935	/*
936	 * Validate the TX ticks count (i.e. the maximum amount
937	 * of time to wait after the last TX completion has
938	 * occurred before a status block update is generated
939	 * and an interrupt is asserted.
940	 */
941	if (bce_tx_ticks_int <= 100) {
942		sc->bce_tx_ticks_int =
943		    bce_tx_ticks_int;
944	} else {
945		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
946		    "hw.bce.tx_ticks_int!  Setting default of %d.\n",
947		    __FILE__, __LINE__, bce_tx_ticks_int,
948		    DEFAULT_TX_TICKS_INT);
949		sc->bce_tx_ticks_int =
950		    DEFAULT_TX_TICKS_INT;
951	   }
952
953	if (bce_tx_ticks <= 100) {
954		sc->bce_tx_ticks =
955		    bce_tx_ticks;
956	} else {
957		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
958		    "hw.bce.tx_ticks!  Setting default of %d.\n",
959		    __FILE__, __LINE__, bce_tx_ticks,
960		    DEFAULT_TX_TICKS);
961		sc->bce_tx_ticks =
962		    DEFAULT_TX_TICKS;
963	}
964
965	/*
966	 * Validate the RX trip point (i.e. the number of
967	 * RX frames received before a status block update is
968	 * generated and an interrupt is asserted.
969	 */
970	if (bce_rx_quick_cons_trip_int <= 100) {
971		sc->bce_rx_quick_cons_trip_int =
972		    bce_rx_quick_cons_trip_int;
973	} else {
974		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
975		    "hw.bce.rx_quick_cons_trip_int!  Setting default of %d.\n",
976		    __FILE__, __LINE__, bce_rx_quick_cons_trip_int,
977		    DEFAULT_RX_QUICK_CONS_TRIP_INT);
978		sc->bce_rx_quick_cons_trip_int =
979		    DEFAULT_RX_QUICK_CONS_TRIP_INT;
980	}
981
982	if (bce_rx_quick_cons_trip <= 100) {
983		sc->bce_rx_quick_cons_trip =
984		    bce_rx_quick_cons_trip;
985	} else {
986		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
987		    "hw.bce.rx_quick_cons_trip!  Setting default of %d.\n",
988		    __FILE__, __LINE__, bce_rx_quick_cons_trip,
989		    DEFAULT_RX_QUICK_CONS_TRIP);
990		sc->bce_rx_quick_cons_trip =
991		    DEFAULT_RX_QUICK_CONS_TRIP;
992	}
993
994	/*
995	 * Validate the RX ticks count (i.e. the maximum amount
996	 * of time to wait after the last RX frame has been
997	 * received before a status block update is generated
998	 * and an interrupt is asserted.
999	 */
1000	if (bce_rx_ticks_int <= 100) {
1001		sc->bce_rx_ticks_int = bce_rx_ticks_int;
1002	} else {
1003		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
1004		    "hw.bce.rx_ticks_int!  Setting default of %d.\n",
1005		    __FILE__, __LINE__, bce_rx_ticks_int,
1006		    DEFAULT_RX_TICKS_INT);
1007		sc->bce_rx_ticks_int = DEFAULT_RX_TICKS_INT;
1008	}
1009
1010	if (bce_rx_ticks <= 100) {
1011		sc->bce_rx_ticks = bce_rx_ticks;
1012	} else {
1013		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
1014		    "hw.bce.rx_ticks!  Setting default of %d.\n",
1015		    __FILE__, __LINE__, bce_rx_ticks,
1016		    DEFAULT_RX_TICKS);
1017		sc->bce_rx_ticks = DEFAULT_RX_TICKS;
1018	}
1019
1020	/* Disabling both RX ticks and RX trips will prevent interrupts. */
1021	if ((bce_rx_quick_cons_trip == 0) && (bce_rx_ticks == 0)) {
1022		BCE_PRINTF("%s(%d): Cannot set both hw.bce.rx_ticks and "
1023		    "hw.bce.rx_quick_cons_trip to 0. Setting default values.\n",
1024		   __FILE__, __LINE__);
1025		sc->bce_rx_ticks = DEFAULT_RX_TICKS;
1026		sc->bce_rx_quick_cons_trip = DEFAULT_RX_QUICK_CONS_TRIP;
1027	}
1028
1029	/* Disabling both TX ticks and TX trips will prevent interrupts. */
1030	if ((bce_tx_quick_cons_trip == 0) && (bce_tx_ticks == 0)) {
1031		BCE_PRINTF("%s(%d): Cannot set both hw.bce.tx_ticks and "
1032		    "hw.bce.tx_quick_cons_trip to 0. Setting default values.\n",
1033		   __FILE__, __LINE__);
1034		sc->bce_tx_ticks = DEFAULT_TX_TICKS;
1035		sc->bce_tx_quick_cons_trip = DEFAULT_TX_QUICK_CONS_TRIP;
1036	}
1037}
1038
1039/****************************************************************************/
1040/* Device attach function.                                                  */
1041/*                                                                          */
1042/* Allocates device resources, performs secondary chip identification,      */
1043/* resets and initializes the hardware, and initializes driver instance     */
1044/* variables.                                                               */
1045/*                                                                          */
1046/* Returns:                                                                 */
1047/*   0 on success, positive value on failure.                               */
1048/****************************************************************************/
1049static int
1050bce_attach(device_t dev)
1051{
1052	struct bce_softc *sc;
1053	if_t ifp;
1054	u32 val;
1055	int count, error, rc = 0, rid;
1056
1057	sc = device_get_softc(dev);
1058	sc->bce_dev = dev;
1059
1060	DBENTER(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
1061
1062	sc->bce_unit = device_get_unit(dev);
1063
1064	/* Set initial device and PHY flags */
1065	sc->bce_flags = 0;
1066	sc->bce_phy_flags = 0;
1067
1068	bce_set_tunables(sc);
1069
1070	pci_enable_busmaster(dev);
1071
1072	/* Allocate PCI memory resources. */
1073	rid = PCIR_BAR(0);
1074	sc->bce_res_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
1075		&rid, RF_ACTIVE);
1076
1077	if (sc->bce_res_mem == NULL) {
1078		BCE_PRINTF("%s(%d): PCI memory allocation failed\n",
1079		    __FILE__, __LINE__);
1080		rc = ENXIO;
1081		goto bce_attach_fail;
1082	}
1083
1084	/* Get various resource handles. */
1085	sc->bce_btag    = rman_get_bustag(sc->bce_res_mem);
1086	sc->bce_bhandle = rman_get_bushandle(sc->bce_res_mem);
1087	sc->bce_vhandle = (vm_offset_t) rman_get_virtual(sc->bce_res_mem);
1088
1089	bce_probe_pci_caps(dev, sc);
1090
1091	rid = 1;
1092	count = 0;
1093#if 0
1094	/* Try allocating MSI-X interrupts. */
1095	if ((sc->bce_cap_flags & BCE_MSIX_CAPABLE_FLAG) &&
1096		(bce_msi_enable >= 2) &&
1097		((sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
1098		&rid, RF_ACTIVE)) != NULL)) {
1099		msi_needed = count = 1;
1100
1101		if (((error = pci_alloc_msix(dev, &count)) != 0) ||
1102			(count != msi_needed)) {
1103			BCE_PRINTF("%s(%d): MSI-X allocation failed! Requested = %d,"
1104				"Received = %d, error = %d\n", __FILE__, __LINE__,
1105				msi_needed, count, error);
1106			count = 0;
1107			pci_release_msi(dev);
1108			bus_release_resource(dev, SYS_RES_MEMORY, rid,
1109				sc->bce_res_irq);
1110			sc->bce_res_irq = NULL;
1111		} else {
1112			DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI-X interrupt.\n",
1113				__FUNCTION__);
1114			sc->bce_flags |= BCE_USING_MSIX_FLAG;
1115		}
1116	}
1117#endif
1118
1119	/* Try allocating a MSI interrupt. */
1120	if ((sc->bce_cap_flags & BCE_MSI_CAPABLE_FLAG) &&
1121		(bce_msi_enable >= 1) && (count == 0)) {
1122		count = 1;
1123		if ((error = pci_alloc_msi(dev, &count)) != 0) {
1124			BCE_PRINTF("%s(%d): MSI allocation failed! "
1125			    "error = %d\n", __FILE__, __LINE__, error);
1126			count = 0;
1127			pci_release_msi(dev);
1128		} else {
1129			DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI "
1130			    "interrupt.\n", __FUNCTION__);
1131			sc->bce_flags |= BCE_USING_MSI_FLAG;
1132			if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
1133				sc->bce_flags |= BCE_ONE_SHOT_MSI_FLAG;
1134			rid = 1;
1135		}
1136	}
1137
1138	/* Try allocating a legacy interrupt. */
1139	if (count == 0) {
1140		DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using INTx interrupt.\n",
1141			__FUNCTION__);
1142		rid = 0;
1143	}
1144
1145	sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
1146	    &rid, RF_ACTIVE | (count != 0 ? 0 : RF_SHAREABLE));
1147
1148	/* Report any IRQ allocation errors. */
1149	if (sc->bce_res_irq == NULL) {
1150		BCE_PRINTF("%s(%d): PCI map interrupt failed!\n",
1151		    __FILE__, __LINE__);
1152		rc = ENXIO;
1153		goto bce_attach_fail;
1154	}
1155
1156	/* Initialize mutex for the current device instance. */
1157	BCE_LOCK_INIT(sc, device_get_nameunit(dev));
1158
1159	/*
1160	 * Configure byte swap and enable indirect register access.
1161	 * Rely on CPU to do target byte swapping on big endian systems.
1162	 * Access to registers outside of PCI configurtion space are not
1163	 * valid until this is done.
1164	 */
1165	pci_write_config(dev, BCE_PCICFG_MISC_CONFIG,
1166	    BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
1167	    BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4);
1168
1169	/* Save ASIC revsion info. */
1170	sc->bce_chipid =  REG_RD(sc, BCE_MISC_ID);
1171
1172	/* Weed out any non-production controller revisions. */
1173	switch(BCE_CHIP_ID(sc)) {
1174	case BCE_CHIP_ID_5706_A0:
1175	case BCE_CHIP_ID_5706_A1:
1176	case BCE_CHIP_ID_5708_A0:
1177	case BCE_CHIP_ID_5708_B0:
1178	case BCE_CHIP_ID_5709_A0:
1179	case BCE_CHIP_ID_5709_B0:
1180	case BCE_CHIP_ID_5709_B1:
1181	case BCE_CHIP_ID_5709_B2:
1182		BCE_PRINTF("%s(%d): Unsupported controller "
1183		    "revision (%c%d)!\n", __FILE__, __LINE__,
1184		    (((pci_read_config(dev, PCIR_REVID, 4) &
1185		    0xf0) >> 4) + 'A'), (pci_read_config(dev,
1186		    PCIR_REVID, 4) & 0xf));
1187		rc = ENODEV;
1188		goto bce_attach_fail;
1189	}
1190
1191	/*
1192	 * The embedded PCIe to PCI-X bridge (EPB)
1193	 * in the 5708 cannot address memory above
1194	 * 40 bits (E7_5708CB1_23043 & E6_5708SB1_23043).
1195	 */
1196	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708)
1197		sc->max_bus_addr = BCE_BUS_SPACE_MAXADDR;
1198	else
1199		sc->max_bus_addr = BUS_SPACE_MAXADDR;
1200
1201	/*
1202	 * Find the base address for shared memory access.
1203	 * Newer versions of bootcode use a signature and offset
1204	 * while older versions use a fixed address.
1205	 */
1206	val = REG_RD_IND(sc, BCE_SHM_HDR_SIGNATURE);
1207	if ((val & BCE_SHM_HDR_SIGNATURE_SIG_MASK) == BCE_SHM_HDR_SIGNATURE_SIG)
1208		/* Multi-port devices use different offsets in shared memory. */
1209		sc->bce_shmem_base = REG_RD_IND(sc, BCE_SHM_HDR_ADDR_0 +
1210		    (pci_get_function(sc->bce_dev) << 2));
1211	else
1212		sc->bce_shmem_base = HOST_VIEW_SHMEM_BASE;
1213
1214	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): bce_shmem_base = 0x%08X\n",
1215	    __FUNCTION__, sc->bce_shmem_base);
1216
1217	/* Fetch the bootcode revision. */
1218	val = bce_shmem_rd(sc, BCE_DEV_INFO_BC_REV);
1219	for (int i = 0, j = 0; i < 3; i++) {
1220		u8 num;
1221
1222		num = (u8) (val >> (24 - (i * 8)));
1223		for (int k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
1224			if (num >= k || !skip0 || k == 1) {
1225				sc->bce_bc_ver[j++] = (num / k) + '0';
1226				skip0 = 0;
1227			}
1228		}
1229
1230		if (i != 2)
1231			sc->bce_bc_ver[j++] = '.';
1232	}
1233
1234	/* Check if any management firwmare is enabled. */
1235	val = bce_shmem_rd(sc, BCE_PORT_FEATURE);
1236	if (val & BCE_PORT_FEATURE_ASF_ENABLED) {
1237		sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
1238
1239		/* Allow time for firmware to enter the running state. */
1240		for (int i = 0; i < 30; i++) {
1241			val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
1242			if (val & BCE_CONDITION_MFW_RUN_MASK)
1243				break;
1244			DELAY(10000);
1245		}
1246
1247		/* Check if management firmware is running. */
1248		val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
1249		val &= BCE_CONDITION_MFW_RUN_MASK;
1250		if ((val != BCE_CONDITION_MFW_RUN_UNKNOWN) &&
1251		    (val != BCE_CONDITION_MFW_RUN_NONE)) {
1252			u32 addr = bce_shmem_rd(sc, BCE_MFW_VER_PTR);
1253			int i = 0;
1254
1255			/* Read the management firmware version string. */
1256			for (int j = 0; j < 3; j++) {
1257				val = bce_reg_rd_ind(sc, addr + j * 4);
1258				val = bswap32(val);
1259				memcpy(&sc->bce_mfw_ver[i], &val, 4);
1260				i += 4;
1261			}
1262		} else {
1263			/* May cause firmware synchronization timeouts. */
1264			BCE_PRINTF("%s(%d): Management firmware enabled "
1265			    "but not running!\n", __FILE__, __LINE__);
1266			strcpy(sc->bce_mfw_ver, "NOT RUNNING!");
1267
1268			/* ToDo: Any action the driver should take? */
1269		}
1270	}
1271
1272	/* Get PCI bus information (speed and type). */
1273	val = REG_RD(sc, BCE_PCICFG_MISC_STATUS);
1274	if (val & BCE_PCICFG_MISC_STATUS_PCIX_DET) {
1275		u32 clkreg;
1276
1277		sc->bce_flags |= BCE_PCIX_FLAG;
1278
1279		clkreg = REG_RD(sc, BCE_PCICFG_PCI_CLOCK_CONTROL_BITS);
1280
1281		clkreg &= BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
1282		switch (clkreg) {
1283		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
1284			sc->bus_speed_mhz = 133;
1285			break;
1286
1287		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
1288			sc->bus_speed_mhz = 100;
1289			break;
1290
1291		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
1292		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
1293			sc->bus_speed_mhz = 66;
1294			break;
1295
1296		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
1297		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
1298			sc->bus_speed_mhz = 50;
1299			break;
1300
1301		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
1302		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
1303		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
1304			sc->bus_speed_mhz = 33;
1305			break;
1306		}
1307	} else {
1308		if (val & BCE_PCICFG_MISC_STATUS_M66EN)
1309			sc->bus_speed_mhz = 66;
1310		else
1311			sc->bus_speed_mhz = 33;
1312	}
1313
1314	if (val & BCE_PCICFG_MISC_STATUS_32BIT_DET)
1315		sc->bce_flags |= BCE_PCI_32BIT_FLAG;
1316
1317	/* Find the media type for the adapter. */
1318	bce_get_media(sc);
1319
1320	/* Reset controller and announce to bootcode that driver is present. */
1321	if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
1322		BCE_PRINTF("%s(%d): Controller reset failed!\n",
1323		    __FILE__, __LINE__);
1324		rc = ENXIO;
1325		goto bce_attach_fail;
1326	}
1327
1328	/* Initialize the controller. */
1329	if (bce_chipinit(sc)) {
1330		BCE_PRINTF("%s(%d): Controller initialization failed!\n",
1331		    __FILE__, __LINE__);
1332		rc = ENXIO;
1333		goto bce_attach_fail;
1334	}
1335
1336	/* Perform NVRAM test. */
1337	if (bce_nvram_test(sc)) {
1338		BCE_PRINTF("%s(%d): NVRAM test failed!\n",
1339		    __FILE__, __LINE__);
1340		rc = ENXIO;
1341		goto bce_attach_fail;
1342	}
1343
1344	/* Fetch the permanent Ethernet MAC address. */
1345	bce_get_mac_addr(sc);
1346
1347	/* Update statistics once every second. */
1348	sc->bce_stats_ticks = 1000000 & 0xffff00;
1349
1350	/* Store data needed by PHY driver for backplane applications */
1351	sc->bce_shared_hw_cfg = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
1352	sc->bce_port_hw_cfg   = bce_shmem_rd(sc, BCE_PORT_HW_CFG_CONFIG);
1353
1354	/* Allocate DMA memory resources. */
1355	if (bce_dma_alloc(dev)) {
1356		BCE_PRINTF("%s(%d): DMA resource allocation failed!\n",
1357		    __FILE__, __LINE__);
1358		rc = ENXIO;
1359		goto bce_attach_fail;
1360	}
1361
1362	/* Allocate an ifnet structure. */
1363	ifp = sc->bce_ifp = if_alloc(IFT_ETHER);
1364	if (ifp == NULL) {
1365		BCE_PRINTF("%s(%d): Interface allocation failed!\n",
1366		    __FILE__, __LINE__);
1367		rc = ENXIO;
1368		goto bce_attach_fail;
1369	}
1370
1371	/* Initialize the ifnet interface. */
1372	if_setsoftc(ifp, sc);
1373	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
1374	if_setflags(ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
1375	if_setioctlfn(ifp, bce_ioctl);
1376	if_setstartfn(ifp, bce_start);
1377	if_setgetcounterfn(ifp, bce_get_counter);
1378	if_setinitfn(ifp, bce_init);
1379	if_setmtu(ifp, ETHERMTU);
1380
1381	if (bce_tso_enable) {
1382		if_sethwassist(ifp, BCE_IF_HWASSIST | CSUM_TSO);
1383		if_setcapabilities(ifp, BCE_IF_CAPABILITIES | IFCAP_TSO4 |
1384		    IFCAP_VLAN_HWTSO);
1385	} else {
1386		if_sethwassist(ifp, BCE_IF_HWASSIST);
1387		if_setcapabilities(ifp, BCE_IF_CAPABILITIES);
1388	}
1389
1390	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
1391		if_setcapabilitiesbit(ifp, IFCAP_LINKSTATE, 0);
1392
1393	if_setcapenable(ifp, if_getcapabilities(ifp));
1394
1395	/*
1396	 * Assume standard mbuf sizes for buffer allocation.
1397	 * This may change later if the MTU size is set to
1398	 * something other than 1500.
1399	 */
1400	bce_get_rx_buffer_sizes(sc,
1401	    (ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN));
1402
1403	/* Recalculate our buffer allocation sizes. */
1404	if_setsendqlen(ifp, USABLE_TX_BD_ALLOC);
1405	if_setsendqready(ifp);
1406
1407	if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
1408		if_setbaudrate(ifp, IF_Mbps(2500ULL));
1409	else
1410		if_setbaudrate(ifp, IF_Mbps(1000));
1411
1412	/* Handle any special PHY initialization for SerDes PHYs. */
1413	bce_init_media(sc);
1414
1415	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
1416		ifmedia_init(&sc->bce_ifmedia, IFM_IMASK, bce_ifmedia_upd,
1417		    bce_ifmedia_sts);
1418		/*
1419		 * We can't manually override remote PHY's link and assume
1420		 * PHY port configuration(Fiber or TP) is not changed after
1421		 * device attach.  This may not be correct though.
1422		 */
1423		if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) != 0) {
1424			if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
1425				ifmedia_add(&sc->bce_ifmedia,
1426				    IFM_ETHER | IFM_2500_SX, 0, NULL);
1427				ifmedia_add(&sc->bce_ifmedia,
1428				    IFM_ETHER | IFM_2500_SX | IFM_FDX, 0, NULL);
1429			}
1430			ifmedia_add(&sc->bce_ifmedia,
1431			    IFM_ETHER | IFM_1000_SX, 0, NULL);
1432			ifmedia_add(&sc->bce_ifmedia,
1433			    IFM_ETHER | IFM_1000_SX | IFM_FDX, 0, NULL);
1434		} else {
1435			ifmedia_add(&sc->bce_ifmedia,
1436			    IFM_ETHER | IFM_10_T, 0, NULL);
1437			ifmedia_add(&sc->bce_ifmedia,
1438			    IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL);
1439			ifmedia_add(&sc->bce_ifmedia,
1440			    IFM_ETHER | IFM_100_TX, 0, NULL);
1441			ifmedia_add(&sc->bce_ifmedia,
1442			    IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL);
1443			ifmedia_add(&sc->bce_ifmedia,
1444			    IFM_ETHER | IFM_1000_T, 0, NULL);
1445			ifmedia_add(&sc->bce_ifmedia,
1446			    IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL);
1447		}
1448		ifmedia_add(&sc->bce_ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL);
1449		ifmedia_set(&sc->bce_ifmedia, IFM_ETHER | IFM_AUTO);
1450		sc->bce_ifmedia.ifm_media = sc->bce_ifmedia.ifm_cur->ifm_media;
1451	} else {
1452		/* MII child bus by attaching the PHY. */
1453		rc = mii_attach(dev, &sc->bce_miibus, ifp, bce_ifmedia_upd,
1454		    bce_ifmedia_sts, BMSR_DEFCAPMASK, sc->bce_phy_addr,
1455		    MII_OFFSET_ANY, MIIF_DOPAUSE);
1456		if (rc != 0) {
1457			BCE_PRINTF("%s(%d): attaching PHYs failed\n", __FILE__,
1458			    __LINE__);
1459			goto bce_attach_fail;
1460		}
1461	}
1462
1463	/* Attach to the Ethernet interface list. */
1464	ether_ifattach(ifp, sc->eaddr);
1465
1466	callout_init_mtx(&sc->bce_tick_callout, &sc->bce_mtx, 0);
1467	callout_init_mtx(&sc->bce_pulse_callout, &sc->bce_mtx, 0);
1468
1469	/* Hookup IRQ last. */
1470	rc = bus_setup_intr(dev, sc->bce_res_irq, INTR_TYPE_NET | INTR_MPSAFE,
1471		NULL, bce_intr, sc, &sc->bce_intrhand);
1472
1473	if (rc) {
1474		BCE_PRINTF("%s(%d): Failed to setup IRQ!\n",
1475		    __FILE__, __LINE__);
1476		bce_detach(dev);
1477		goto bce_attach_exit;
1478	}
1479
1480	/*
1481	 * At this point we've acquired all the resources
1482	 * we need to run so there's no turning back, we're
1483	 * cleared for launch.
1484	 */
1485
1486	/* Print some important debugging info. */
1487	DBRUNMSG(BCE_INFO, bce_dump_driver_state(sc));
1488
1489	/* Add the supported sysctls to the kernel. */
1490	bce_add_sysctls(sc);
1491
1492	BCE_LOCK(sc);
1493
1494	/*
1495	 * The chip reset earlier notified the bootcode that
1496	 * a driver is present.  We now need to start our pulse
1497	 * routine so that the bootcode is reminded that we're
1498	 * still running.
1499	 */
1500	bce_pulse(sc);
1501
1502	bce_mgmt_init_locked(sc);
1503	BCE_UNLOCK(sc);
1504
1505	/* Finally, print some useful adapter info */
1506	bce_print_adapter_info(sc);
1507	DBPRINT(sc, BCE_FATAL, "%s(): sc = %p\n",
1508		__FUNCTION__, sc);
1509
1510	goto bce_attach_exit;
1511
1512bce_attach_fail:
1513	bce_release_resources(sc);
1514
1515bce_attach_exit:
1516
1517	DBEXIT(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
1518
1519	return(rc);
1520}
1521
1522/****************************************************************************/
1523/* Device detach function.                                                  */
1524/*                                                                          */
1525/* Stops the controller, resets the controller, and releases resources.     */
1526/*                                                                          */
1527/* Returns:                                                                 */
1528/*   0 on success, positive value on failure.                               */
1529/****************************************************************************/
1530static int
1531bce_detach(device_t dev)
1532{
1533	struct bce_softc *sc = device_get_softc(dev);
1534	if_t ifp;
1535	u32 msg;
1536
1537	DBENTER(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
1538
1539	ifp = sc->bce_ifp;
1540
1541	/* Stop and reset the controller. */
1542	BCE_LOCK(sc);
1543
1544	/* Stop the pulse so the bootcode can go to driver absent state. */
1545	callout_stop(&sc->bce_pulse_callout);
1546
1547	bce_stop(sc);
1548	if (sc->bce_flags & BCE_NO_WOL_FLAG)
1549		msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
1550	else
1551		msg = BCE_DRV_MSG_CODE_UNLOAD;
1552	bce_reset(sc, msg);
1553
1554	BCE_UNLOCK(sc);
1555
1556	ether_ifdetach(ifp);
1557
1558	/* If we have a child device on the MII bus remove it too. */
1559	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
1560		ifmedia_removeall(&sc->bce_ifmedia);
1561	else {
1562		bus_generic_detach(dev);
1563		device_delete_child(dev, sc->bce_miibus);
1564	}
1565
1566	/* Release all remaining resources. */
1567	bce_release_resources(sc);
1568
1569	DBEXIT(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
1570
1571	return(0);
1572}
1573
1574/****************************************************************************/
1575/* Device shutdown function.                                                */
1576/*                                                                          */
1577/* Stops and resets the controller.                                         */
1578/*                                                                          */
1579/* Returns:                                                                 */
1580/*   0 on success, positive value on failure.                               */
1581/****************************************************************************/
1582static int
1583bce_shutdown(device_t dev)
1584{
1585	struct bce_softc *sc = device_get_softc(dev);
1586	u32 msg;
1587
1588	DBENTER(BCE_VERBOSE);
1589
1590	BCE_LOCK(sc);
1591	bce_stop(sc);
1592	if (sc->bce_flags & BCE_NO_WOL_FLAG)
1593		msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
1594	else
1595		msg = BCE_DRV_MSG_CODE_UNLOAD;
1596	bce_reset(sc, msg);
1597	BCE_UNLOCK(sc);
1598
1599	DBEXIT(BCE_VERBOSE);
1600
1601	return (0);
1602}
1603
1604#ifdef BCE_DEBUG
1605/****************************************************************************/
1606/* Register read.                                                           */
1607/*                                                                          */
1608/* Returns:                                                                 */
1609/*   The value of the register.                                             */
1610/****************************************************************************/
1611static u32
1612bce_reg_rd(struct bce_softc *sc, u32 offset)
1613{
1614	u32 val = REG_RD(sc, offset);
1615	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1616		__FUNCTION__, offset, val);
1617	return val;
1618}
1619
1620/****************************************************************************/
1621/* Register write (16 bit).                                                 */
1622/*                                                                          */
1623/* Returns:                                                                 */
1624/*   Nothing.                                                               */
1625/****************************************************************************/
1626static void
1627bce_reg_wr16(struct bce_softc *sc, u32 offset, u16 val)
1628{
1629	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%04X\n",
1630		__FUNCTION__, offset, val);
1631	REG_WR16(sc, offset, val);
1632}
1633
1634/****************************************************************************/
1635/* Register write.                                                          */
1636/*                                                                          */
1637/* Returns:                                                                 */
1638/*   Nothing.                                                               */
1639/****************************************************************************/
1640static void
1641bce_reg_wr(struct bce_softc *sc, u32 offset, u32 val)
1642{
1643	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1644		__FUNCTION__, offset, val);
1645	REG_WR(sc, offset, val);
1646}
1647#endif
1648
1649/****************************************************************************/
1650/* Indirect register read.                                                  */
1651/*                                                                          */
1652/* Reads NetXtreme II registers using an index/data register pair in PCI    */
1653/* configuration space.  Using this mechanism avoids issues with posted     */
1654/* reads but is much slower than memory-mapped I/O.                         */
1655/*                                                                          */
1656/* Returns:                                                                 */
1657/*   The value of the register.                                             */
1658/****************************************************************************/
1659static u32
1660bce_reg_rd_ind(struct bce_softc *sc, u32 offset)
1661{
1662	device_t dev;
1663	dev = sc->bce_dev;
1664
1665	pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
1666#ifdef BCE_DEBUG
1667	{
1668		u32 val;
1669		val = pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
1670		DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1671			__FUNCTION__, offset, val);
1672		return val;
1673	}
1674#else
1675	return pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
1676#endif
1677}
1678
1679/****************************************************************************/
1680/* Indirect register write.                                                 */
1681/*                                                                          */
1682/* Writes NetXtreme II registers using an index/data register pair in PCI   */
1683/* configuration space.  Using this mechanism avoids issues with posted     */
1684/* writes but is muchh slower than memory-mapped I/O.                       */
1685/*                                                                          */
1686/* Returns:                                                                 */
1687/*   Nothing.                                                               */
1688/****************************************************************************/
1689static void
1690bce_reg_wr_ind(struct bce_softc *sc, u32 offset, u32 val)
1691{
1692	device_t dev;
1693	dev = sc->bce_dev;
1694
1695	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1696		__FUNCTION__, offset, val);
1697
1698	pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
1699	pci_write_config(dev, BCE_PCICFG_REG_WINDOW, val, 4);
1700}
1701
1702/****************************************************************************/
1703/* Shared memory write.                                                     */
1704/*                                                                          */
1705/* Writes NetXtreme II shared memory region.                                */
1706/*                                                                          */
1707/* Returns:                                                                 */
1708/*   Nothing.                                                               */
1709/****************************************************************************/
1710static void
1711bce_shmem_wr(struct bce_softc *sc, u32 offset, u32 val)
1712{
1713	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): Writing 0x%08X  to  "
1714	    "0x%08X\n",	__FUNCTION__, val, offset);
1715
1716	bce_reg_wr_ind(sc, sc->bce_shmem_base + offset, val);
1717}
1718
1719/****************************************************************************/
1720/* Shared memory read.                                                      */
1721/*                                                                          */
1722/* Reads NetXtreme II shared memory region.                                 */
1723/*                                                                          */
1724/* Returns:                                                                 */
1725/*   The 32 bit value read.                                                 */
1726/****************************************************************************/
1727static u32
1728bce_shmem_rd(struct bce_softc *sc, u32 offset)
1729{
1730	u32 val = bce_reg_rd_ind(sc, sc->bce_shmem_base + offset);
1731
1732	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): Reading 0x%08X from "
1733	    "0x%08X\n",	__FUNCTION__, val, offset);
1734
1735	return val;
1736}
1737
1738#ifdef BCE_DEBUG
1739/****************************************************************************/
1740/* Context memory read.                                                     */
1741/*                                                                          */
1742/* The NetXtreme II controller uses context memory to track connection      */
1743/* information for L2 and higher network protocols.                         */
1744/*                                                                          */
1745/* Returns:                                                                 */
1746/*   The requested 32 bit value of context memory.                          */
1747/****************************************************************************/
1748static u32
1749bce_ctx_rd(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset)
1750{
1751	u32 idx, offset, retry_cnt = 5, val;
1752
1753	DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 ||
1754	    cid_addr & CTX_MASK), BCE_PRINTF("%s(): Invalid CID "
1755	    "address: 0x%08X.\n", __FUNCTION__, cid_addr));
1756
1757	offset = ctx_offset + cid_addr;
1758
1759	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
1760		REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_READ_REQ));
1761
1762		for (idx = 0; idx < retry_cnt; idx++) {
1763			val = REG_RD(sc, BCE_CTX_CTX_CTRL);
1764			if ((val & BCE_CTX_CTX_CTRL_READ_REQ) == 0)
1765				break;
1766			DELAY(5);
1767		}
1768
1769		if (val & BCE_CTX_CTX_CTRL_READ_REQ)
1770			BCE_PRINTF("%s(%d); Unable to read CTX memory: "
1771			    "cid_addr = 0x%08X, offset = 0x%08X!\n",
1772			    __FILE__, __LINE__, cid_addr, ctx_offset);
1773
1774		val = REG_RD(sc, BCE_CTX_CTX_DATA);
1775	} else {
1776		REG_WR(sc, BCE_CTX_DATA_ADR, offset);
1777		val = REG_RD(sc, BCE_CTX_DATA);
1778	}
1779
1780	DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
1781		"val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, val);
1782
1783	return(val);
1784}
1785#endif
1786
1787/****************************************************************************/
1788/* Context memory write.                                                    */
1789/*                                                                          */
1790/* The NetXtreme II controller uses context memory to track connection      */
1791/* information for L2 and higher network protocols.                         */
1792/*                                                                          */
1793/* Returns:                                                                 */
1794/*   Nothing.                                                               */
1795/****************************************************************************/
1796static void
1797bce_ctx_wr(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset, u32 ctx_val)
1798{
1799	u32 idx, offset = ctx_offset + cid_addr;
1800	u32 val, retry_cnt = 5;
1801
1802	DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
1803		"val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, ctx_val);
1804
1805	DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 || cid_addr & CTX_MASK),
1806		BCE_PRINTF("%s(): Invalid CID address: 0x%08X.\n",
1807		    __FUNCTION__, cid_addr));
1808
1809	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
1810		REG_WR(sc, BCE_CTX_CTX_DATA, ctx_val);
1811		REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_WRITE_REQ));
1812
1813		for (idx = 0; idx < retry_cnt; idx++) {
1814			val = REG_RD(sc, BCE_CTX_CTX_CTRL);
1815			if ((val & BCE_CTX_CTX_CTRL_WRITE_REQ) == 0)
1816				break;
1817			DELAY(5);
1818		}
1819
1820		if (val & BCE_CTX_CTX_CTRL_WRITE_REQ)
1821			BCE_PRINTF("%s(%d); Unable to write CTX memory: "
1822			    "cid_addr = 0x%08X, offset = 0x%08X!\n",
1823			    __FILE__, __LINE__, cid_addr, ctx_offset);
1824
1825	} else {
1826		REG_WR(sc, BCE_CTX_DATA_ADR, offset);
1827		REG_WR(sc, BCE_CTX_DATA, ctx_val);
1828	}
1829}
1830
1831/****************************************************************************/
1832/* PHY register read.                                                       */
1833/*                                                                          */
1834/* Implements register reads on the MII bus.                                */
1835/*                                                                          */
1836/* Returns:                                                                 */
1837/*   The value of the register.                                             */
1838/****************************************************************************/
1839static int
1840bce_miibus_read_reg(device_t dev, int phy, int reg)
1841{
1842	struct bce_softc *sc;
1843	u32 val;
1844	int i;
1845
1846	sc = device_get_softc(dev);
1847
1848    /*
1849     * The 5709S PHY is an IEEE Clause 45 PHY
1850     * with special mappings to work with IEEE
1851     * Clause 22 register accesses.
1852     */
1853	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
1854		if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
1855			reg += 0x10;
1856	}
1857
1858    if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1859		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1860		val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1861
1862		REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1863		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1864
1865		DELAY(40);
1866	}
1867
1868	val = BCE_MIPHY(phy) | BCE_MIREG(reg) |
1869	    BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT |
1870	    BCE_EMAC_MDIO_COMM_START_BUSY;
1871	REG_WR(sc, BCE_EMAC_MDIO_COMM, val);
1872
1873	for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1874		DELAY(10);
1875
1876		val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1877		if (!(val & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1878			DELAY(5);
1879
1880			val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1881			val &= BCE_EMAC_MDIO_COMM_DATA;
1882
1883			break;
1884		}
1885	}
1886
1887	if (val & BCE_EMAC_MDIO_COMM_START_BUSY) {
1888		BCE_PRINTF("%s(%d): Error: PHY read timeout! phy = %d, "
1889		    "reg = 0x%04X\n", __FILE__, __LINE__, phy, reg);
1890		val = 0x0;
1891	} else {
1892		val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1893	}
1894
1895	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1896		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1897		val |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1898
1899		REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1900		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1901
1902		DELAY(40);
1903	}
1904
1905	DB_PRINT_PHY_REG(reg, val);
1906	return (val & 0xffff);
1907}
1908
1909/****************************************************************************/
1910/* PHY register write.                                                      */
1911/*                                                                          */
1912/* Implements register writes on the MII bus.                               */
1913/*                                                                          */
1914/* Returns:                                                                 */
1915/*   The value of the register.                                             */
1916/****************************************************************************/
1917static int
1918bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
1919{
1920	struct bce_softc *sc;
1921	u32 val1;
1922	int i;
1923
1924	sc = device_get_softc(dev);
1925
1926	DB_PRINT_PHY_REG(reg, val);
1927
1928	/*
1929	 * The 5709S PHY is an IEEE Clause 45 PHY
1930	 * with special mappings to work with IEEE
1931	 * Clause 22 register accesses.
1932	 */
1933	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
1934		if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
1935			reg += 0x10;
1936	}
1937
1938	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1939		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1940		val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1941
1942		REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1943		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1944
1945		DELAY(40);
1946	}
1947
1948	val1 = BCE_MIPHY(phy) | BCE_MIREG(reg) | val |
1949	    BCE_EMAC_MDIO_COMM_COMMAND_WRITE |
1950	    BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT;
1951	REG_WR(sc, BCE_EMAC_MDIO_COMM, val1);
1952
1953	for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1954		DELAY(10);
1955
1956		val1 = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1957		if (!(val1 & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1958			DELAY(5);
1959			break;
1960		}
1961	}
1962
1963	if (val1 & BCE_EMAC_MDIO_COMM_START_BUSY)
1964		BCE_PRINTF("%s(%d): PHY write timeout!\n",
1965		    __FILE__, __LINE__);
1966
1967	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1968		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1969		val1 |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1970
1971		REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1972		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1973
1974		DELAY(40);
1975	}
1976
1977	return 0;
1978}
1979
1980/****************************************************************************/
1981/* MII bus status change.                                                   */
1982/*                                                                          */
1983/* Called by the MII bus driver when the PHY establishes link to set the    */
1984/* MAC interface registers.                                                 */
1985/*                                                                          */
1986/* Returns:                                                                 */
1987/*   Nothing.                                                               */
1988/****************************************************************************/
1989static void
1990bce_miibus_statchg(device_t dev)
1991{
1992	struct bce_softc *sc;
1993	struct mii_data *mii;
1994	struct ifmediareq ifmr;
1995	int media_active, media_status, val;
1996
1997	sc = device_get_softc(dev);
1998
1999	DBENTER(BCE_VERBOSE_PHY);
2000
2001	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
2002		bzero(&ifmr, sizeof(ifmr));
2003		bce_ifmedia_sts_rphy(sc, &ifmr);
2004		media_active = ifmr.ifm_active;
2005		media_status = ifmr.ifm_status;
2006	} else {
2007		mii = device_get_softc(sc->bce_miibus);
2008		media_active = mii->mii_media_active;
2009		media_status = mii->mii_media_status;
2010	}
2011
2012	/* Ignore invalid media status. */
2013	if ((media_status & (IFM_ACTIVE | IFM_AVALID)) !=
2014	    (IFM_ACTIVE | IFM_AVALID))
2015		goto bce_miibus_statchg_exit;
2016
2017	val = REG_RD(sc, BCE_EMAC_MODE);
2018	val &= ~(BCE_EMAC_MODE_PORT | BCE_EMAC_MODE_HALF_DUPLEX |
2019	    BCE_EMAC_MODE_MAC_LOOP | BCE_EMAC_MODE_FORCE_LINK |
2020	    BCE_EMAC_MODE_25G);
2021
2022	/* Set MII or GMII interface based on the PHY speed. */
2023	switch (IFM_SUBTYPE(media_active)) {
2024	case IFM_10_T:
2025		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
2026			DBPRINT(sc, BCE_INFO_PHY,
2027			    "Enabling 10Mb interface.\n");
2028			val |= BCE_EMAC_MODE_PORT_MII_10;
2029			break;
2030		}
2031		/* fall-through */
2032	case IFM_100_TX:
2033		DBPRINT(sc, BCE_INFO_PHY, "Enabling MII interface.\n");
2034		val |= BCE_EMAC_MODE_PORT_MII;
2035		break;
2036	case IFM_2500_SX:
2037		DBPRINT(sc, BCE_INFO_PHY, "Enabling 2.5G MAC mode.\n");
2038		val |= BCE_EMAC_MODE_25G;
2039		/* fall-through */
2040	case IFM_1000_T:
2041	case IFM_1000_SX:
2042		DBPRINT(sc, BCE_INFO_PHY, "Enabling GMII interface.\n");
2043		val |= BCE_EMAC_MODE_PORT_GMII;
2044		break;
2045	default:
2046		DBPRINT(sc, BCE_INFO_PHY, "Unknown link speed, enabling "
2047		    "default GMII interface.\n");
2048		val |= BCE_EMAC_MODE_PORT_GMII;
2049	}
2050
2051	/* Set half or full duplex based on PHY settings. */
2052	if ((IFM_OPTIONS(media_active) & IFM_FDX) == 0) {
2053		DBPRINT(sc, BCE_INFO_PHY,
2054		    "Setting Half-Duplex interface.\n");
2055		val |= BCE_EMAC_MODE_HALF_DUPLEX;
2056	} else
2057		DBPRINT(sc, BCE_INFO_PHY,
2058		    "Setting Full-Duplex interface.\n");
2059
2060	REG_WR(sc, BCE_EMAC_MODE, val);
2061
2062	if ((IFM_OPTIONS(media_active) & IFM_ETH_RXPAUSE) != 0) {
2063		DBPRINT(sc, BCE_INFO_PHY,
2064		    "%s(): Enabling RX flow control.\n", __FUNCTION__);
2065		BCE_SETBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
2066		sc->bce_flags |= BCE_USING_RX_FLOW_CONTROL;
2067	} else {
2068		DBPRINT(sc, BCE_INFO_PHY,
2069		    "%s(): Disabling RX flow control.\n", __FUNCTION__);
2070		BCE_CLRBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
2071		sc->bce_flags &= ~BCE_USING_RX_FLOW_CONTROL;
2072	}
2073
2074	if ((IFM_OPTIONS(media_active) & IFM_ETH_TXPAUSE) != 0) {
2075		DBPRINT(sc, BCE_INFO_PHY,
2076		    "%s(): Enabling TX flow control.\n", __FUNCTION__);
2077		BCE_SETBIT(sc, BCE_EMAC_TX_MODE, BCE_EMAC_TX_MODE_FLOW_EN);
2078		sc->bce_flags |= BCE_USING_TX_FLOW_CONTROL;
2079	} else {
2080		DBPRINT(sc, BCE_INFO_PHY,
2081		    "%s(): Disabling TX flow control.\n", __FUNCTION__);
2082		BCE_CLRBIT(sc, BCE_EMAC_TX_MODE, BCE_EMAC_TX_MODE_FLOW_EN);
2083		sc->bce_flags &= ~BCE_USING_TX_FLOW_CONTROL;
2084	}
2085
2086	/* ToDo: Update watermarks in bce_init_rx_context(). */
2087
2088bce_miibus_statchg_exit:
2089	DBEXIT(BCE_VERBOSE_PHY);
2090}
2091
2092/****************************************************************************/
2093/* Acquire NVRAM lock.                                                      */
2094/*                                                                          */
2095/* Before the NVRAM can be accessed the caller must acquire an NVRAM lock.  */
2096/* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
2097/* for use by the driver.                                                   */
2098/*                                                                          */
2099/* Returns:                                                                 */
2100/*   0 on success, positive value on failure.                               */
2101/****************************************************************************/
2102static int
2103bce_acquire_nvram_lock(struct bce_softc *sc)
2104{
2105	u32 val;
2106	int j, rc = 0;
2107
2108	DBENTER(BCE_VERBOSE_NVRAM);
2109
2110	/* Request access to the flash interface. */
2111	REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_SET2);
2112	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2113		val = REG_RD(sc, BCE_NVM_SW_ARB);
2114		if (val & BCE_NVM_SW_ARB_ARB_ARB2)
2115			break;
2116
2117		DELAY(5);
2118	}
2119
2120	if (j >= NVRAM_TIMEOUT_COUNT) {
2121		DBPRINT(sc, BCE_WARN, "Timeout acquiring NVRAM lock!\n");
2122		rc = EBUSY;
2123	}
2124
2125	DBEXIT(BCE_VERBOSE_NVRAM);
2126	return (rc);
2127}
2128
2129/****************************************************************************/
2130/* Release NVRAM lock.                                                      */
2131/*                                                                          */
2132/* When the caller is finished accessing NVRAM the lock must be released.   */
2133/* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
2134/* for use by the driver.                                                   */
2135/*                                                                          */
2136/* Returns:                                                                 */
2137/*   0 on success, positive value on failure.                               */
2138/****************************************************************************/
2139static int
2140bce_release_nvram_lock(struct bce_softc *sc)
2141{
2142	u32 val;
2143	int j, rc = 0;
2144
2145	DBENTER(BCE_VERBOSE_NVRAM);
2146
2147	/*
2148	 * Relinquish nvram interface.
2149	 */
2150	REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_CLR2);
2151
2152	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2153		val = REG_RD(sc, BCE_NVM_SW_ARB);
2154		if (!(val & BCE_NVM_SW_ARB_ARB_ARB2))
2155			break;
2156
2157		DELAY(5);
2158	}
2159
2160	if (j >= NVRAM_TIMEOUT_COUNT) {
2161		DBPRINT(sc, BCE_WARN, "Timeout releasing NVRAM lock!\n");
2162		rc = EBUSY;
2163	}
2164
2165	DBEXIT(BCE_VERBOSE_NVRAM);
2166	return (rc);
2167}
2168
2169#ifdef BCE_NVRAM_WRITE_SUPPORT
2170/****************************************************************************/
2171/* Enable NVRAM write access.                                               */
2172/*                                                                          */
2173/* Before writing to NVRAM the caller must enable NVRAM writes.             */
2174/*                                                                          */
2175/* Returns:                                                                 */
2176/*   0 on success, positive value on failure.                               */
2177/****************************************************************************/
2178static int
2179bce_enable_nvram_write(struct bce_softc *sc)
2180{
2181	u32 val;
2182	int rc = 0;
2183
2184	DBENTER(BCE_VERBOSE_NVRAM);
2185
2186	val = REG_RD(sc, BCE_MISC_CFG);
2187	REG_WR(sc, BCE_MISC_CFG, val | BCE_MISC_CFG_NVM_WR_EN_PCI);
2188
2189	if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2190		int j;
2191
2192		REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2193		REG_WR(sc, BCE_NVM_COMMAND,	BCE_NVM_COMMAND_WREN | BCE_NVM_COMMAND_DOIT);
2194
2195		for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2196			DELAY(5);
2197
2198			val = REG_RD(sc, BCE_NVM_COMMAND);
2199			if (val & BCE_NVM_COMMAND_DONE)
2200				break;
2201		}
2202
2203		if (j >= NVRAM_TIMEOUT_COUNT) {
2204			DBPRINT(sc, BCE_WARN, "Timeout writing NVRAM!\n");
2205			rc = EBUSY;
2206		}
2207	}
2208
2209	DBENTER(BCE_VERBOSE_NVRAM);
2210	return (rc);
2211}
2212
2213/****************************************************************************/
2214/* Disable NVRAM write access.                                              */
2215/*                                                                          */
2216/* When the caller is finished writing to NVRAM write access must be        */
2217/* disabled.                                                                */
2218/*                                                                          */
2219/* Returns:                                                                 */
2220/*   Nothing.                                                               */
2221/****************************************************************************/
2222static void
2223bce_disable_nvram_write(struct bce_softc *sc)
2224{
2225	u32 val;
2226
2227	DBENTER(BCE_VERBOSE_NVRAM);
2228
2229	val = REG_RD(sc, BCE_MISC_CFG);
2230	REG_WR(sc, BCE_MISC_CFG, val & ~BCE_MISC_CFG_NVM_WR_EN);
2231
2232	DBEXIT(BCE_VERBOSE_NVRAM);
2233
2234}
2235#endif
2236
2237/****************************************************************************/
2238/* Enable NVRAM access.                                                     */
2239/*                                                                          */
2240/* Before accessing NVRAM for read or write operations the caller must      */
2241/* enabled NVRAM access.                                                    */
2242/*                                                                          */
2243/* Returns:                                                                 */
2244/*   Nothing.                                                               */
2245/****************************************************************************/
2246static void
2247bce_enable_nvram_access(struct bce_softc *sc)
2248{
2249	u32 val;
2250
2251	DBENTER(BCE_VERBOSE_NVRAM);
2252
2253	val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
2254	/* Enable both bits, even on read. */
2255	REG_WR(sc, BCE_NVM_ACCESS_ENABLE, val |
2256	    BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN);
2257
2258	DBEXIT(BCE_VERBOSE_NVRAM);
2259}
2260
2261/****************************************************************************/
2262/* Disable NVRAM access.                                                    */
2263/*                                                                          */
2264/* When the caller is finished accessing NVRAM access must be disabled.     */
2265/*                                                                          */
2266/* Returns:                                                                 */
2267/*   Nothing.                                                               */
2268/****************************************************************************/
2269static void
2270bce_disable_nvram_access(struct bce_softc *sc)
2271{
2272	u32 val;
2273
2274	DBENTER(BCE_VERBOSE_NVRAM);
2275
2276	val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
2277
2278	/* Disable both bits, even after read. */
2279	REG_WR(sc, BCE_NVM_ACCESS_ENABLE, val &
2280	    ~(BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN));
2281
2282	DBEXIT(BCE_VERBOSE_NVRAM);
2283}
2284
2285#ifdef BCE_NVRAM_WRITE_SUPPORT
2286/****************************************************************************/
2287/* Erase NVRAM page before writing.                                         */
2288/*                                                                          */
2289/* Non-buffered flash parts require that a page be erased before it is      */
2290/* written.                                                                 */
2291/*                                                                          */
2292/* Returns:                                                                 */
2293/*   0 on success, positive value on failure.                               */
2294/****************************************************************************/
2295static int
2296bce_nvram_erase_page(struct bce_softc *sc, u32 offset)
2297{
2298	u32 cmd;
2299	int j, rc = 0;
2300
2301	DBENTER(BCE_VERBOSE_NVRAM);
2302
2303	/* Buffered flash doesn't require an erase. */
2304	if (sc->bce_flash_info->flags & BCE_NV_BUFFERED)
2305		goto bce_nvram_erase_page_exit;
2306
2307	/* Build an erase command. */
2308	cmd = BCE_NVM_COMMAND_ERASE | BCE_NVM_COMMAND_WR |
2309	    BCE_NVM_COMMAND_DOIT;
2310
2311	/*
2312	 * Clear the DONE bit separately, set the NVRAM address to erase,
2313	 * and issue the erase command.
2314	 */
2315	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2316	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
2317	REG_WR(sc, BCE_NVM_COMMAND, cmd);
2318
2319	/* Wait for completion. */
2320	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2321		u32 val;
2322
2323		DELAY(5);
2324
2325		val = REG_RD(sc, BCE_NVM_COMMAND);
2326		if (val & BCE_NVM_COMMAND_DONE)
2327			break;
2328	}
2329
2330	if (j >= NVRAM_TIMEOUT_COUNT) {
2331		DBPRINT(sc, BCE_WARN, "Timeout erasing NVRAM.\n");
2332		rc = EBUSY;
2333	}
2334
2335bce_nvram_erase_page_exit:
2336	DBEXIT(BCE_VERBOSE_NVRAM);
2337	return (rc);
2338}
2339#endif /* BCE_NVRAM_WRITE_SUPPORT */
2340
2341/****************************************************************************/
2342/* Read a dword (32 bits) from NVRAM.                                       */
2343/*                                                                          */
2344/* Read a 32 bit word from NVRAM.  The caller is assumed to have already    */
2345/* obtained the NVRAM lock and enabled the controller for NVRAM access.     */
2346/*                                                                          */
2347/* Returns:                                                                 */
2348/*   0 on success and the 32 bit value read, positive value on failure.     */
2349/****************************************************************************/
2350static int
2351bce_nvram_read_dword(struct bce_softc *sc,
2352    u32 offset, u8 *ret_val, u32 cmd_flags)
2353{
2354	u32 cmd;
2355	int i, rc = 0;
2356
2357	DBENTER(BCE_EXTREME_NVRAM);
2358
2359	/* Build the command word. */
2360	cmd = BCE_NVM_COMMAND_DOIT | cmd_flags;
2361
2362	/* Calculate the offset for buffered flash if translation is used. */
2363	if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
2364		offset = ((offset / sc->bce_flash_info->page_size) <<
2365		    sc->bce_flash_info->page_bits) +
2366		    (offset % sc->bce_flash_info->page_size);
2367	}
2368
2369	/*
2370	 * Clear the DONE bit separately, set the address to read,
2371	 * and issue the read.
2372	 */
2373	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2374	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
2375	REG_WR(sc, BCE_NVM_COMMAND, cmd);
2376
2377	/* Wait for completion. */
2378	for (i = 0; i < NVRAM_TIMEOUT_COUNT; i++) {
2379		u32 val;
2380
2381		DELAY(5);
2382
2383		val = REG_RD(sc, BCE_NVM_COMMAND);
2384		if (val & BCE_NVM_COMMAND_DONE) {
2385			val = REG_RD(sc, BCE_NVM_READ);
2386
2387			val = bce_be32toh(val);
2388			memcpy(ret_val, &val, 4);
2389			break;
2390		}
2391	}
2392
2393	/* Check for errors. */
2394	if (i >= NVRAM_TIMEOUT_COUNT) {
2395		BCE_PRINTF("%s(%d): Timeout error reading NVRAM at "
2396		    "offset 0x%08X!\n",	__FILE__, __LINE__, offset);
2397		rc = EBUSY;
2398	}
2399
2400	DBEXIT(BCE_EXTREME_NVRAM);
2401	return(rc);
2402}
2403
2404#ifdef BCE_NVRAM_WRITE_SUPPORT
2405/****************************************************************************/
2406/* Write a dword (32 bits) to NVRAM.                                        */
2407/*                                                                          */
2408/* Write a 32 bit word to NVRAM.  The caller is assumed to have already     */
2409/* obtained the NVRAM lock, enabled the controller for NVRAM access, and    */
2410/* enabled NVRAM write access.                                              */
2411/*                                                                          */
2412/* Returns:                                                                 */
2413/*   0 on success, positive value on failure.                               */
2414/****************************************************************************/
2415static int
2416bce_nvram_write_dword(struct bce_softc *sc, u32 offset, u8 *val,
2417	u32 cmd_flags)
2418{
2419	u32 cmd, val32;
2420	int j, rc = 0;
2421
2422	DBENTER(BCE_VERBOSE_NVRAM);
2423
2424	/* Build the command word. */
2425	cmd = BCE_NVM_COMMAND_DOIT | BCE_NVM_COMMAND_WR | cmd_flags;
2426
2427	/* Calculate the offset for buffered flash if translation is used. */
2428	if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
2429		offset = ((offset / sc->bce_flash_info->page_size) <<
2430		    sc->bce_flash_info->page_bits) +
2431		    (offset % sc->bce_flash_info->page_size);
2432	}
2433
2434	/*
2435	 * Clear the DONE bit separately, convert NVRAM data to big-endian,
2436	 * set the NVRAM address to write, and issue the write command
2437	 */
2438	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2439	memcpy(&val32, val, 4);
2440	val32 = htobe32(val32);
2441	REG_WR(sc, BCE_NVM_WRITE, val32);
2442	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
2443	REG_WR(sc, BCE_NVM_COMMAND, cmd);
2444
2445	/* Wait for completion. */
2446	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2447		DELAY(5);
2448
2449		if (REG_RD(sc, BCE_NVM_COMMAND) & BCE_NVM_COMMAND_DONE)
2450			break;
2451	}
2452	if (j >= NVRAM_TIMEOUT_COUNT) {
2453		BCE_PRINTF("%s(%d): Timeout error writing NVRAM at "
2454		    "offset 0x%08X\n", __FILE__, __LINE__, offset);
2455		rc = EBUSY;
2456	}
2457
2458	DBEXIT(BCE_VERBOSE_NVRAM);
2459	return (rc);
2460}
2461#endif /* BCE_NVRAM_WRITE_SUPPORT */
2462
2463/****************************************************************************/
2464/* Initialize NVRAM access.                                                 */
2465/*                                                                          */
2466/* Identify the NVRAM device in use and prepare the NVRAM interface to      */
2467/* access that device.                                                      */
2468/*                                                                          */
2469/* Returns:                                                                 */
2470/*   0 on success, positive value on failure.                               */
2471/****************************************************************************/
2472static int
2473bce_init_nvram(struct bce_softc *sc)
2474{
2475	u32 val;
2476	int j, entry_count, rc = 0;
2477	const struct flash_spec *flash;
2478
2479	DBENTER(BCE_VERBOSE_NVRAM);
2480
2481	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
2482		sc->bce_flash_info = &flash_5709;
2483		goto bce_init_nvram_get_flash_size;
2484	}
2485
2486	/* Determine the selected interface. */
2487	val = REG_RD(sc, BCE_NVM_CFG1);
2488
2489	entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
2490
2491	/*
2492	 * Flash reconfiguration is required to support additional
2493	 * NVRAM devices not directly supported in hardware.
2494	 * Check if the flash interface was reconfigured
2495	 * by the bootcode.
2496	 */
2497
2498	if (val & 0x40000000) {
2499		/* Flash interface reconfigured by bootcode. */
2500
2501		DBPRINT(sc,BCE_INFO_LOAD,
2502			"bce_init_nvram(): Flash WAS reconfigured.\n");
2503
2504		for (j = 0, flash = &flash_table[0]; j < entry_count;
2505		     j++, flash++) {
2506			if ((val & FLASH_BACKUP_STRAP_MASK) ==
2507			    (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
2508				sc->bce_flash_info = flash;
2509				break;
2510			}
2511		}
2512	} else {
2513		/* Flash interface not yet reconfigured. */
2514		u32 mask;
2515
2516		DBPRINT(sc, BCE_INFO_LOAD, "%s(): Flash was NOT reconfigured.\n",
2517			__FUNCTION__);
2518
2519		if (val & (1 << 23))
2520			mask = FLASH_BACKUP_STRAP_MASK;
2521		else
2522			mask = FLASH_STRAP_MASK;
2523
2524		/* Look for the matching NVRAM device configuration data. */
2525		for (j = 0, flash = &flash_table[0]; j < entry_count; j++, flash++) {
2526			/* Check if the device matches any of the known devices. */
2527			if ((val & mask) == (flash->strapping & mask)) {
2528				/* Found a device match. */
2529				sc->bce_flash_info = flash;
2530
2531				/* Request access to the flash interface. */
2532				if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2533					return rc;
2534
2535				/* Reconfigure the flash interface. */
2536				bce_enable_nvram_access(sc);
2537				REG_WR(sc, BCE_NVM_CFG1, flash->config1);
2538				REG_WR(sc, BCE_NVM_CFG2, flash->config2);
2539				REG_WR(sc, BCE_NVM_CFG3, flash->config3);
2540				REG_WR(sc, BCE_NVM_WRITE1, flash->write1);
2541				bce_disable_nvram_access(sc);
2542				bce_release_nvram_lock(sc);
2543
2544				break;
2545			}
2546		}
2547	}
2548
2549	/* Check if a matching device was found. */
2550	if (j == entry_count) {
2551		sc->bce_flash_info = NULL;
2552		BCE_PRINTF("%s(%d): Unknown Flash NVRAM found!\n",
2553		    __FILE__, __LINE__);
2554		DBEXIT(BCE_VERBOSE_NVRAM);
2555		return (ENODEV);
2556	}
2557
2558bce_init_nvram_get_flash_size:
2559	/* Write the flash config data to the shared memory interface. */
2560	val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG2);
2561	val &= BCE_SHARED_HW_CFG2_NVM_SIZE_MASK;
2562	if (val)
2563		sc->bce_flash_size = val;
2564	else
2565		sc->bce_flash_size = sc->bce_flash_info->total_size;
2566
2567	DBPRINT(sc, BCE_INFO_LOAD, "%s(): Found %s, size = 0x%08X\n",
2568	    __FUNCTION__, sc->bce_flash_info->name,
2569	    sc->bce_flash_info->total_size);
2570
2571	DBEXIT(BCE_VERBOSE_NVRAM);
2572	return rc;
2573}
2574
2575/****************************************************************************/
2576/* Read an arbitrary range of data from NVRAM.                              */
2577/*                                                                          */
2578/* Prepares the NVRAM interface for access and reads the requested data     */
2579/* into the supplied buffer.                                                */
2580/*                                                                          */
2581/* Returns:                                                                 */
2582/*   0 on success and the data read, positive value on failure.             */
2583/****************************************************************************/
2584static int
2585bce_nvram_read(struct bce_softc *sc, u32 offset, u8 *ret_buf,
2586	int buf_size)
2587{
2588	int rc = 0;
2589	u32 cmd_flags, offset32, len32, extra;
2590
2591	DBENTER(BCE_VERBOSE_NVRAM);
2592
2593	if (buf_size == 0)
2594		goto bce_nvram_read_exit;
2595
2596	/* Request access to the flash interface. */
2597	if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2598		goto bce_nvram_read_exit;
2599
2600	/* Enable access to flash interface */
2601	bce_enable_nvram_access(sc);
2602
2603	len32 = buf_size;
2604	offset32 = offset;
2605	extra = 0;
2606
2607	cmd_flags = 0;
2608
2609	if (offset32 & 3) {
2610		u8 buf[4];
2611		u32 pre_len;
2612
2613		offset32 &= ~3;
2614		pre_len = 4 - (offset & 3);
2615
2616		if (pre_len >= len32) {
2617			pre_len = len32;
2618			cmd_flags = BCE_NVM_COMMAND_FIRST | BCE_NVM_COMMAND_LAST;
2619		}
2620		else {
2621			cmd_flags = BCE_NVM_COMMAND_FIRST;
2622		}
2623
2624		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2625
2626		if (rc)
2627			return rc;
2628
2629		memcpy(ret_buf, buf + (offset & 3), pre_len);
2630
2631		offset32 += 4;
2632		ret_buf += pre_len;
2633		len32 -= pre_len;
2634	}
2635
2636	if (len32 & 3) {
2637		extra = 4 - (len32 & 3);
2638		len32 = (len32 + 4) & ~3;
2639	}
2640
2641	if (len32 == 4) {
2642		u8 buf[4];
2643
2644		if (cmd_flags)
2645			cmd_flags = BCE_NVM_COMMAND_LAST;
2646		else
2647			cmd_flags = BCE_NVM_COMMAND_FIRST |
2648				    BCE_NVM_COMMAND_LAST;
2649
2650		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2651
2652		memcpy(ret_buf, buf, 4 - extra);
2653	}
2654	else if (len32 > 0) {
2655		u8 buf[4];
2656
2657		/* Read the first word. */
2658		if (cmd_flags)
2659			cmd_flags = 0;
2660		else
2661			cmd_flags = BCE_NVM_COMMAND_FIRST;
2662
2663		rc = bce_nvram_read_dword(sc, offset32, ret_buf, cmd_flags);
2664
2665		/* Advance to the next dword. */
2666		offset32 += 4;
2667		ret_buf += 4;
2668		len32 -= 4;
2669
2670		while (len32 > 4 && rc == 0) {
2671			rc = bce_nvram_read_dword(sc, offset32, ret_buf, 0);
2672
2673			/* Advance to the next dword. */
2674			offset32 += 4;
2675			ret_buf += 4;
2676			len32 -= 4;
2677		}
2678
2679		if (rc)
2680			goto bce_nvram_read_locked_exit;
2681
2682		cmd_flags = BCE_NVM_COMMAND_LAST;
2683		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2684
2685		memcpy(ret_buf, buf, 4 - extra);
2686	}
2687
2688bce_nvram_read_locked_exit:
2689	/* Disable access to flash interface and release the lock. */
2690	bce_disable_nvram_access(sc);
2691	bce_release_nvram_lock(sc);
2692
2693bce_nvram_read_exit:
2694	DBEXIT(BCE_VERBOSE_NVRAM);
2695	return rc;
2696}
2697
2698#ifdef BCE_NVRAM_WRITE_SUPPORT
2699/****************************************************************************/
2700/* Write an arbitrary range of data from NVRAM.                             */
2701/*                                                                          */
2702/* Prepares the NVRAM interface for write access and writes the requested   */
2703/* data from the supplied buffer.  The caller is responsible for            */
2704/* calculating any appropriate CRCs.                                        */
2705/*                                                                          */
2706/* Returns:                                                                 */
2707/*   0 on success, positive value on failure.                               */
2708/****************************************************************************/
2709static int
2710bce_nvram_write(struct bce_softc *sc, u32 offset, u8 *data_buf,
2711	int buf_size)
2712{
2713	u32 written, offset32, len32;
2714	u8 *buf, start[4], end[4];
2715	int rc = 0;
2716	int align_start, align_end;
2717
2718	DBENTER(BCE_VERBOSE_NVRAM);
2719
2720	buf = data_buf;
2721	offset32 = offset;
2722	len32 = buf_size;
2723	align_start = align_end = 0;
2724
2725	if ((align_start = (offset32 & 3))) {
2726		offset32 &= ~3;
2727		len32 += align_start;
2728		if ((rc = bce_nvram_read(sc, offset32, start, 4)))
2729			goto bce_nvram_write_exit;
2730	}
2731
2732	if (len32 & 3) {
2733	       	if ((len32 > 4) || !align_start) {
2734			align_end = 4 - (len32 & 3);
2735			len32 += align_end;
2736			if ((rc = bce_nvram_read(sc, offset32 + len32 - 4,
2737				end, 4))) {
2738				goto bce_nvram_write_exit;
2739			}
2740		}
2741	}
2742
2743	if (align_start || align_end) {
2744		buf = malloc(len32, M_DEVBUF, M_NOWAIT);
2745		if (buf == NULL) {
2746			rc = ENOMEM;
2747			goto bce_nvram_write_exit;
2748		}
2749
2750		if (align_start) {
2751			memcpy(buf, start, 4);
2752		}
2753
2754		if (align_end) {
2755			memcpy(buf + len32 - 4, end, 4);
2756		}
2757		memcpy(buf + align_start, data_buf, buf_size);
2758	}
2759
2760	written = 0;
2761	while ((written < len32) && (rc == 0)) {
2762		u32 page_start, page_end, data_start, data_end;
2763		u32 addr, cmd_flags;
2764		int i;
2765		u8 flash_buffer[264];
2766
2767	    /* Find the page_start addr */
2768		page_start = offset32 + written;
2769		page_start -= (page_start % sc->bce_flash_info->page_size);
2770		/* Find the page_end addr */
2771		page_end = page_start + sc->bce_flash_info->page_size;
2772		/* Find the data_start addr */
2773		data_start = (written == 0) ? offset32 : page_start;
2774		/* Find the data_end addr */
2775		data_end = (page_end > offset32 + len32) ?
2776			(offset32 + len32) : page_end;
2777
2778		/* Request access to the flash interface. */
2779		if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2780			goto bce_nvram_write_exit;
2781
2782		/* Enable access to flash interface */
2783		bce_enable_nvram_access(sc);
2784
2785		cmd_flags = BCE_NVM_COMMAND_FIRST;
2786		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2787			int j;
2788
2789			/* Read the whole page into the buffer
2790			 * (non-buffer flash only) */
2791			for (j = 0; j < sc->bce_flash_info->page_size; j += 4) {
2792				if (j == (sc->bce_flash_info->page_size - 4)) {
2793					cmd_flags |= BCE_NVM_COMMAND_LAST;
2794				}
2795				rc = bce_nvram_read_dword(sc,
2796					page_start + j,
2797					&flash_buffer[j],
2798					cmd_flags);
2799
2800				if (rc)
2801					goto bce_nvram_write_locked_exit;
2802
2803				cmd_flags = 0;
2804			}
2805		}
2806
2807		/* Enable writes to flash interface (unlock write-protect) */
2808		if ((rc = bce_enable_nvram_write(sc)) != 0)
2809			goto bce_nvram_write_locked_exit;
2810
2811		/* Erase the page */
2812		if ((rc = bce_nvram_erase_page(sc, page_start)) != 0)
2813			goto bce_nvram_write_locked_exit;
2814
2815		/* Re-enable the write again for the actual write */
2816		bce_enable_nvram_write(sc);
2817
2818		/* Loop to write back the buffer data from page_start to
2819		 * data_start */
2820		i = 0;
2821		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2822			for (addr = page_start; addr < data_start;
2823				addr += 4, i += 4) {
2824				rc = bce_nvram_write_dword(sc, addr,
2825					&flash_buffer[i], cmd_flags);
2826
2827				if (rc != 0)
2828					goto bce_nvram_write_locked_exit;
2829
2830				cmd_flags = 0;
2831			}
2832		}
2833
2834		/* Loop to write the new data from data_start to data_end */
2835		for (addr = data_start; addr < data_end; addr += 4, i++) {
2836			if ((addr == page_end - 4) ||
2837				((sc->bce_flash_info->flags & BCE_NV_BUFFERED) &&
2838				(addr == data_end - 4))) {
2839				cmd_flags |= BCE_NVM_COMMAND_LAST;
2840			}
2841			rc = bce_nvram_write_dword(sc, addr, buf,
2842				cmd_flags);
2843
2844			if (rc != 0)
2845				goto bce_nvram_write_locked_exit;
2846
2847			cmd_flags = 0;
2848			buf += 4;
2849		}
2850
2851		/* Loop to write back the buffer data from data_end
2852		 * to page_end */
2853		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2854			for (addr = data_end; addr < page_end;
2855				addr += 4, i += 4) {
2856				if (addr == page_end-4) {
2857					cmd_flags = BCE_NVM_COMMAND_LAST;
2858                		}
2859				rc = bce_nvram_write_dword(sc, addr,
2860					&flash_buffer[i], cmd_flags);
2861
2862				if (rc != 0)
2863					goto bce_nvram_write_locked_exit;
2864
2865				cmd_flags = 0;
2866			}
2867		}
2868
2869		/* Disable writes to flash interface (lock write-protect) */
2870		bce_disable_nvram_write(sc);
2871
2872		/* Disable access to flash interface */
2873		bce_disable_nvram_access(sc);
2874		bce_release_nvram_lock(sc);
2875
2876		/* Increment written */
2877		written += data_end - data_start;
2878	}
2879
2880	goto bce_nvram_write_exit;
2881
2882bce_nvram_write_locked_exit:
2883	bce_disable_nvram_write(sc);
2884	bce_disable_nvram_access(sc);
2885	bce_release_nvram_lock(sc);
2886
2887bce_nvram_write_exit:
2888	if (align_start || align_end)
2889		free(buf, M_DEVBUF);
2890
2891	DBEXIT(BCE_VERBOSE_NVRAM);
2892	return (rc);
2893}
2894#endif /* BCE_NVRAM_WRITE_SUPPORT */
2895
2896/****************************************************************************/
2897/* Verifies that NVRAM is accessible and contains valid data.               */
2898/*                                                                          */
2899/* Reads the configuration data from NVRAM and verifies that the CRC is     */
2900/* correct.                                                                 */
2901/*                                                                          */
2902/* Returns:                                                                 */
2903/*   0 on success, positive value on failure.                               */
2904/****************************************************************************/
2905static int
2906bce_nvram_test(struct bce_softc *sc)
2907{
2908	u32 buf[BCE_NVRAM_SIZE / 4];
2909	u8 *data = (u8 *) buf;
2910	int rc = 0;
2911	u32 magic, csum;
2912
2913	DBENTER(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
2914
2915	/*
2916	 * Check that the device NVRAM is valid by reading
2917	 * the magic value at offset 0.
2918	 */
2919	if ((rc = bce_nvram_read(sc, 0, data, 4)) != 0) {
2920		BCE_PRINTF("%s(%d): Unable to read NVRAM!\n",
2921		    __FILE__, __LINE__);
2922		goto bce_nvram_test_exit;
2923	}
2924
2925	/*
2926	 * Verify that offset 0 of the NVRAM contains
2927	 * a valid magic number.
2928	 */
2929	magic = bce_be32toh(buf[0]);
2930	if (magic != BCE_NVRAM_MAGIC) {
2931		rc = ENODEV;
2932		BCE_PRINTF("%s(%d): Invalid NVRAM magic value! "
2933		    "Expected: 0x%08X, Found: 0x%08X\n",
2934		    __FILE__, __LINE__, BCE_NVRAM_MAGIC, magic);
2935		goto bce_nvram_test_exit;
2936	}
2937
2938	/*
2939	 * Verify that the device NVRAM includes valid
2940	 * configuration data.
2941	 */
2942	if ((rc = bce_nvram_read(sc, 0x100, data, BCE_NVRAM_SIZE)) != 0) {
2943		BCE_PRINTF("%s(%d): Unable to read manufacturing "
2944		    "Information from  NVRAM!\n", __FILE__, __LINE__);
2945		goto bce_nvram_test_exit;
2946	}
2947
2948	csum = ether_crc32_le(data, 0x100);
2949	if (csum != BCE_CRC32_RESIDUAL) {
2950		rc = ENODEV;
2951		BCE_PRINTF("%s(%d): Invalid manufacturing information "
2952		    "NVRAM CRC!	Expected: 0x%08X, Found: 0x%08X\n",
2953		    __FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
2954		goto bce_nvram_test_exit;
2955	}
2956
2957	csum = ether_crc32_le(data + 0x100, 0x100);
2958	if (csum != BCE_CRC32_RESIDUAL) {
2959		rc = ENODEV;
2960		BCE_PRINTF("%s(%d): Invalid feature configuration "
2961		    "information NVRAM CRC! Expected: 0x%08X, "
2962		    "Found: 08%08X\n", __FILE__, __LINE__,
2963		    BCE_CRC32_RESIDUAL, csum);
2964	}
2965
2966bce_nvram_test_exit:
2967	DBEXIT(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
2968	return rc;
2969}
2970
2971/****************************************************************************/
2972/* Calculates the size of the buffers to allocate based on the MTU.         */
2973/*                                                                          */
2974/* Returns:                                                                 */
2975/*   Nothing.                                                               */
2976/****************************************************************************/
2977static void
2978bce_get_rx_buffer_sizes(struct bce_softc *sc, int mtu)
2979{
2980	DBENTER(BCE_VERBOSE_LOAD);
2981
2982	/* Use a single allocation type when header splitting enabled. */
2983	if (bce_hdr_split == TRUE) {
2984		sc->rx_bd_mbuf_alloc_size = MHLEN;
2985		/* Make sure offset is 16 byte aligned for hardware. */
2986		sc->rx_bd_mbuf_align_pad =
2987			roundup2(MSIZE - MHLEN, 16) - (MSIZE - MHLEN);
2988		sc->rx_bd_mbuf_data_len = sc->rx_bd_mbuf_alloc_size -
2989			sc->rx_bd_mbuf_align_pad;
2990	} else {
2991		if ((mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN +
2992		    ETHER_CRC_LEN) > MCLBYTES) {
2993			/* Setup for jumbo RX buffer allocations. */
2994			sc->rx_bd_mbuf_alloc_size = MJUM9BYTES;
2995			sc->rx_bd_mbuf_align_pad  =
2996				roundup2(MJUM9BYTES, 16) - MJUM9BYTES;
2997			sc->rx_bd_mbuf_data_len =
2998			    sc->rx_bd_mbuf_alloc_size -
2999			    sc->rx_bd_mbuf_align_pad;
3000		} else {
3001			/* Setup for standard RX buffer allocations. */
3002			sc->rx_bd_mbuf_alloc_size = MCLBYTES;
3003			sc->rx_bd_mbuf_align_pad  =
3004			    roundup2(MCLBYTES, 16) - MCLBYTES;
3005			sc->rx_bd_mbuf_data_len =
3006			    sc->rx_bd_mbuf_alloc_size -
3007			    sc->rx_bd_mbuf_align_pad;
3008		}
3009	}
3010
3011//	DBPRINT(sc, BCE_INFO_LOAD,
3012	DBPRINT(sc, BCE_WARN,
3013	   "%s(): rx_bd_mbuf_alloc_size = %d, rx_bd_mbuf_data_len = %d, "
3014	   "rx_bd_mbuf_align_pad = %d\n", __FUNCTION__,
3015	   sc->rx_bd_mbuf_alloc_size, sc->rx_bd_mbuf_data_len,
3016	   sc->rx_bd_mbuf_align_pad);
3017
3018	DBEXIT(BCE_VERBOSE_LOAD);
3019}
3020
3021/****************************************************************************/
3022/* Identifies the current media type of the controller and sets the PHY     */
3023/* address.                                                                 */
3024/*                                                                          */
3025/* Returns:                                                                 */
3026/*   Nothing.                                                               */
3027/****************************************************************************/
3028static void
3029bce_get_media(struct bce_softc *sc)
3030{
3031	u32 val;
3032
3033	DBENTER(BCE_VERBOSE_PHY);
3034
3035	/* Assume PHY address for copper controllers. */
3036	sc->bce_phy_addr = 1;
3037
3038	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
3039 		u32 val = REG_RD(sc, BCE_MISC_DUAL_MEDIA_CTRL);
3040		u32 bond_id = val & BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID;
3041		u32 strap;
3042
3043		/*
3044		 * The BCM5709S is software configurable
3045		 * for Copper or SerDes operation.
3046		 */
3047		if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_C) {
3048			DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded "
3049			    "for copper.\n");
3050			goto bce_get_media_exit;
3051		} else if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_S) {
3052			DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded "
3053			    "for dual media.\n");
3054			sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
3055			goto bce_get_media_exit;
3056		}
3057
3058		if (val & BCE_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE)
3059			strap = (val &
3060			    BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21;
3061		else
3062			strap = (val &
3063			    BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8;
3064
3065		if (pci_get_function(sc->bce_dev) == 0) {
3066			switch (strap) {
3067			case 0x4:
3068			case 0x5:
3069			case 0x6:
3070				DBPRINT(sc, BCE_INFO_LOAD,
3071				    "BCM5709 s/w configured for SerDes.\n");
3072				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
3073				break;
3074			default:
3075				DBPRINT(sc, BCE_INFO_LOAD,
3076				    "BCM5709 s/w configured for Copper.\n");
3077				break;
3078			}
3079		} else {
3080			switch (strap) {
3081			case 0x1:
3082			case 0x2:
3083			case 0x4:
3084				DBPRINT(sc, BCE_INFO_LOAD,
3085				    "BCM5709 s/w configured for SerDes.\n");
3086				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
3087				break;
3088			default:
3089				DBPRINT(sc, BCE_INFO_LOAD,
3090				    "BCM5709 s/w configured for Copper.\n");
3091				break;
3092			}
3093		}
3094
3095	} else if (BCE_CHIP_BOND_ID(sc) & BCE_CHIP_BOND_ID_SERDES_BIT)
3096		sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
3097
3098	if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) {
3099		sc->bce_flags |= BCE_NO_WOL_FLAG;
3100
3101		if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
3102			sc->bce_phy_flags |= BCE_PHY_IEEE_CLAUSE_45_FLAG;
3103
3104		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
3105			/* 5708S/09S/16S use a separate PHY for SerDes. */
3106			sc->bce_phy_addr = 2;
3107
3108			val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
3109			if (val & BCE_SHARED_HW_CFG_PHY_2_5G) {
3110				sc->bce_phy_flags |=
3111				    BCE_PHY_2_5G_CAPABLE_FLAG;
3112				DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb "
3113				    "capable adapter\n");
3114			}
3115		}
3116	} else if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) ||
3117	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708))
3118		sc->bce_phy_flags |= BCE_PHY_CRC_FIX_FLAG;
3119
3120bce_get_media_exit:
3121	DBPRINT(sc, (BCE_INFO_LOAD | BCE_INFO_PHY),
3122		"Using PHY address %d.\n", sc->bce_phy_addr);
3123
3124	DBEXIT(BCE_VERBOSE_PHY);
3125}
3126
3127/****************************************************************************/
3128/* Performs PHY initialization required before MII drivers access the       */
3129/* device.                                                                  */
3130/*                                                                          */
3131/* Returns:                                                                 */
3132/*   Nothing.                                                               */
3133/****************************************************************************/
3134static void
3135bce_init_media(struct bce_softc *sc)
3136{
3137	if ((sc->bce_phy_flags & (BCE_PHY_IEEE_CLAUSE_45_FLAG |
3138	    BCE_PHY_REMOTE_CAP_FLAG)) == BCE_PHY_IEEE_CLAUSE_45_FLAG) {
3139		/*
3140		 * Configure 5709S/5716S PHYs to use traditional IEEE
3141		 * Clause 22 method. Otherwise we have no way to attach
3142		 * the PHY in mii(4) layer. PHY specific configuration
3143		 * is done in mii layer.
3144		 */
3145
3146		/* Select auto-negotiation MMD of the PHY. */
3147		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
3148		    BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_ADDR_EXT);
3149		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
3150		    BRGPHY_ADDR_EXT, BRGPHY_ADDR_EXT_AN_MMD);
3151
3152		/* Set IEEE0 block of AN MMD (assumed in brgphy(4) code). */
3153		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
3154		    BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
3155	}
3156}
3157
3158/****************************************************************************/
3159/* Free any DMA memory owned by the driver.                                 */
3160/*                                                                          */
3161/* Scans through each data structure that requires DMA memory and frees     */
3162/* the memory if allocated.                                                 */
3163/*                                                                          */
3164/* Returns:                                                                 */
3165/*   Nothing.                                                               */
3166/****************************************************************************/
3167static void
3168bce_dma_free(struct bce_softc *sc)
3169{
3170	int i;
3171
3172	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
3173
3174	/* Free, unmap, and destroy the status block. */
3175	if (sc->status_block_paddr != 0) {
3176		bus_dmamap_unload(
3177		    sc->status_tag,
3178		    sc->status_map);
3179		sc->status_block_paddr = 0;
3180	}
3181
3182	if (sc->status_block != NULL) {
3183		bus_dmamem_free(
3184		   sc->status_tag,
3185		    sc->status_block,
3186		    sc->status_map);
3187		sc->status_block = NULL;
3188	}
3189
3190	if (sc->status_tag != NULL) {
3191		bus_dma_tag_destroy(sc->status_tag);
3192		sc->status_tag = NULL;
3193	}
3194
3195	/* Free, unmap, and destroy the statistics block. */
3196	if (sc->stats_block_paddr != 0) {
3197		bus_dmamap_unload(
3198		    sc->stats_tag,
3199		    sc->stats_map);
3200		sc->stats_block_paddr = 0;
3201	}
3202
3203	if (sc->stats_block != NULL) {
3204		bus_dmamem_free(
3205		    sc->stats_tag,
3206		    sc->stats_block,
3207		    sc->stats_map);
3208		sc->stats_block = NULL;
3209	}
3210
3211	if (sc->stats_tag != NULL) {
3212		bus_dma_tag_destroy(sc->stats_tag);
3213		sc->stats_tag = NULL;
3214	}
3215
3216	/* Free, unmap and destroy all context memory pages. */
3217	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
3218		for (i = 0; i < sc->ctx_pages; i++ ) {
3219			if (sc->ctx_paddr[i] != 0) {
3220				bus_dmamap_unload(
3221				    sc->ctx_tag,
3222				    sc->ctx_map[i]);
3223				sc->ctx_paddr[i] = 0;
3224			}
3225
3226			if (sc->ctx_block[i] != NULL) {
3227				bus_dmamem_free(
3228				    sc->ctx_tag,
3229				    sc->ctx_block[i],
3230				    sc->ctx_map[i]);
3231				sc->ctx_block[i] = NULL;
3232			}
3233		}
3234
3235		/* Destroy the context memory tag. */
3236		if (sc->ctx_tag != NULL) {
3237			bus_dma_tag_destroy(sc->ctx_tag);
3238			sc->ctx_tag = NULL;
3239		}
3240	}
3241
3242	/* Free, unmap and destroy all TX buffer descriptor chain pages. */
3243	for (i = 0; i < sc->tx_pages; i++ ) {
3244		if (sc->tx_bd_chain_paddr[i] != 0) {
3245			bus_dmamap_unload(
3246			    sc->tx_bd_chain_tag,
3247			    sc->tx_bd_chain_map[i]);
3248			sc->tx_bd_chain_paddr[i] = 0;
3249		}
3250
3251		if (sc->tx_bd_chain[i] != NULL) {
3252			bus_dmamem_free(
3253			    sc->tx_bd_chain_tag,
3254			    sc->tx_bd_chain[i],
3255			    sc->tx_bd_chain_map[i]);
3256			sc->tx_bd_chain[i] = NULL;
3257		}
3258	}
3259
3260	/* Destroy the TX buffer descriptor tag. */
3261	if (sc->tx_bd_chain_tag != NULL) {
3262		bus_dma_tag_destroy(sc->tx_bd_chain_tag);
3263		sc->tx_bd_chain_tag = NULL;
3264	}
3265
3266	/* Free, unmap and destroy all RX buffer descriptor chain pages. */
3267	for (i = 0; i < sc->rx_pages; i++ ) {
3268		if (sc->rx_bd_chain_paddr[i] != 0) {
3269			bus_dmamap_unload(
3270			    sc->rx_bd_chain_tag,
3271			    sc->rx_bd_chain_map[i]);
3272			sc->rx_bd_chain_paddr[i] = 0;
3273		}
3274
3275		if (sc->rx_bd_chain[i] != NULL) {
3276			bus_dmamem_free(
3277			    sc->rx_bd_chain_tag,
3278			    sc->rx_bd_chain[i],
3279			    sc->rx_bd_chain_map[i]);
3280			sc->rx_bd_chain[i] = NULL;
3281		}
3282	}
3283
3284	/* Destroy the RX buffer descriptor tag. */
3285	if (sc->rx_bd_chain_tag != NULL) {
3286		bus_dma_tag_destroy(sc->rx_bd_chain_tag);
3287		sc->rx_bd_chain_tag = NULL;
3288	}
3289
3290	/* Free, unmap and destroy all page buffer descriptor chain pages. */
3291	if (bce_hdr_split == TRUE) {
3292		for (i = 0; i < sc->pg_pages; i++ ) {
3293			if (sc->pg_bd_chain_paddr[i] != 0) {
3294				bus_dmamap_unload(
3295				    sc->pg_bd_chain_tag,
3296				    sc->pg_bd_chain_map[i]);
3297				sc->pg_bd_chain_paddr[i] = 0;
3298			}
3299
3300			if (sc->pg_bd_chain[i] != NULL) {
3301				bus_dmamem_free(
3302				    sc->pg_bd_chain_tag,
3303				    sc->pg_bd_chain[i],
3304				    sc->pg_bd_chain_map[i]);
3305				sc->pg_bd_chain[i] = NULL;
3306			}
3307		}
3308
3309		/* Destroy the page buffer descriptor tag. */
3310		if (sc->pg_bd_chain_tag != NULL) {
3311			bus_dma_tag_destroy(sc->pg_bd_chain_tag);
3312			sc->pg_bd_chain_tag = NULL;
3313		}
3314	}
3315
3316	/* Unload and destroy the TX mbuf maps. */
3317	for (i = 0; i < MAX_TX_BD_AVAIL; i++) {
3318		if (sc->tx_mbuf_map[i] != NULL) {
3319			bus_dmamap_unload(sc->tx_mbuf_tag,
3320			    sc->tx_mbuf_map[i]);
3321			bus_dmamap_destroy(sc->tx_mbuf_tag,
3322	 		    sc->tx_mbuf_map[i]);
3323			sc->tx_mbuf_map[i] = NULL;
3324		}
3325	}
3326
3327	/* Destroy the TX mbuf tag. */
3328	if (sc->tx_mbuf_tag != NULL) {
3329		bus_dma_tag_destroy(sc->tx_mbuf_tag);
3330		sc->tx_mbuf_tag = NULL;
3331	}
3332
3333	/* Unload and destroy the RX mbuf maps. */
3334	for (i = 0; i < MAX_RX_BD_AVAIL; i++) {
3335		if (sc->rx_mbuf_map[i] != NULL) {
3336			bus_dmamap_unload(sc->rx_mbuf_tag,
3337			    sc->rx_mbuf_map[i]);
3338			bus_dmamap_destroy(sc->rx_mbuf_tag,
3339	 		    sc->rx_mbuf_map[i]);
3340			sc->rx_mbuf_map[i] = NULL;
3341		}
3342	}
3343
3344	/* Destroy the RX mbuf tag. */
3345	if (sc->rx_mbuf_tag != NULL) {
3346		bus_dma_tag_destroy(sc->rx_mbuf_tag);
3347		sc->rx_mbuf_tag = NULL;
3348	}
3349
3350	/* Unload and destroy the page mbuf maps. */
3351	if (bce_hdr_split == TRUE) {
3352		for (i = 0; i < MAX_PG_BD_AVAIL; i++) {
3353			if (sc->pg_mbuf_map[i] != NULL) {
3354				bus_dmamap_unload(sc->pg_mbuf_tag,
3355				    sc->pg_mbuf_map[i]);
3356				bus_dmamap_destroy(sc->pg_mbuf_tag,
3357				    sc->pg_mbuf_map[i]);
3358				sc->pg_mbuf_map[i] = NULL;
3359			}
3360		}
3361
3362		/* Destroy the page mbuf tag. */
3363		if (sc->pg_mbuf_tag != NULL) {
3364			bus_dma_tag_destroy(sc->pg_mbuf_tag);
3365			sc->pg_mbuf_tag = NULL;
3366		}
3367	}
3368
3369	/* Destroy the parent tag */
3370	if (sc->parent_tag != NULL) {
3371		bus_dma_tag_destroy(sc->parent_tag);
3372		sc->parent_tag = NULL;
3373	}
3374
3375	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
3376}
3377
3378/****************************************************************************/
3379/* Get DMA memory from the OS.                                              */
3380/*                                                                          */
3381/* Validates that the OS has provided DMA buffers in response to a          */
3382/* bus_dmamap_load() call and saves the physical address of those buffers.  */
3383/* When the callback is used the OS will return 0 for the mapping function  */
3384/* (bus_dmamap_load()) so we use the value of map_arg->maxsegs to pass any  */
3385/* failures back to the caller.                                             */
3386/*                                                                          */
3387/* Returns:                                                                 */
3388/*   Nothing.                                                               */
3389/****************************************************************************/
3390static void
3391bce_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
3392{
3393	bus_addr_t *busaddr = arg;
3394
3395	KASSERT(nseg == 1, ("%s(): Too many segments returned (%d)!",
3396	    __FUNCTION__, nseg));
3397	/* Simulate a mapping failure. */
3398	DBRUNIF(DB_RANDOMTRUE(dma_map_addr_failed_sim_control),
3399	    error = ENOMEM);
3400
3401	/* ToDo: How to increment debug sim_count variable here? */
3402
3403	/* Check for an error and signal the caller that an error occurred. */
3404	if (error) {
3405		*busaddr = 0;
3406	} else {
3407		*busaddr = segs->ds_addr;
3408	}
3409}
3410
3411/****************************************************************************/
3412/* Allocate any DMA memory needed by the driver.                            */
3413/*                                                                          */
3414/* Allocates DMA memory needed for the various global structures needed by  */
3415/* hardware.                                                                */
3416/*                                                                          */
3417/* Memory alignment requirements:                                           */
3418/* +-----------------+----------+----------+----------+----------+          */
3419/* |                 |   5706   |   5708   |   5709   |   5716   |          */
3420/* +-----------------+----------+----------+----------+----------+          */
3421/* |Status Block     | 8 bytes  | 8 bytes  | 16 bytes | 16 bytes |          */
3422/* |Statistics Block | 8 bytes  | 8 bytes  | 16 bytes | 16 bytes |          */
3423/* |RX Buffers       | 16 bytes | 16 bytes | 16 bytes | 16 bytes |          */
3424/* |PG Buffers       |   none   |   none   |   none   |   none   |          */
3425/* |TX Buffers       |   none   |   none   |   none   |   none   |          */
3426/* |Chain Pages(1)   |   4KiB   |   4KiB   |   4KiB   |   4KiB   |          */
3427/* |Context Memory   |          |          |          |          |          */
3428/* +-----------------+----------+----------+----------+----------+          */
3429/*                                                                          */
3430/* (1) Must align with CPU page size (BCM_PAGE_SZIE).                       */
3431/*                                                                          */
3432/* Returns:                                                                 */
3433/*   0 for success, positive value for failure.                             */
3434/****************************************************************************/
3435static int
3436bce_dma_alloc(device_t dev)
3437{
3438	struct bce_softc *sc;
3439	int i, error, rc = 0;
3440	bus_size_t max_size, max_seg_size;
3441	int max_segments;
3442
3443	sc = device_get_softc(dev);
3444
3445	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
3446
3447	/*
3448	 * Allocate the parent bus DMA tag appropriate for PCI.
3449	 */
3450	if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, BCE_DMA_BOUNDARY,
3451	    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
3452	    BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL,
3453	    &sc->parent_tag)) {
3454		BCE_PRINTF("%s(%d): Could not allocate parent DMA tag!\n",
3455		    __FILE__, __LINE__);
3456		rc = ENOMEM;
3457		goto bce_dma_alloc_exit;
3458	}
3459
3460	/*
3461	 * Create a DMA tag for the status block, allocate and clear the
3462	 * memory, map the memory into DMA space, and fetch the physical
3463	 * address of the block.
3464	 */
3465	if (bus_dma_tag_create(sc->parent_tag, BCE_DMA_ALIGN,
3466	    BCE_DMA_BOUNDARY, sc->max_bus_addr,	BUS_SPACE_MAXADDR,
3467	    NULL, NULL,	BCE_STATUS_BLK_SZ, 1, BCE_STATUS_BLK_SZ,
3468	    0, NULL, NULL, &sc->status_tag)) {
3469		BCE_PRINTF("%s(%d): Could not allocate status block "
3470		    "DMA tag!\n", __FILE__, __LINE__);
3471		rc = ENOMEM;
3472		goto bce_dma_alloc_exit;
3473	}
3474
3475	if(bus_dmamem_alloc(sc->status_tag, (void **)&sc->status_block,
3476	    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3477	    &sc->status_map)) {
3478		BCE_PRINTF("%s(%d): Could not allocate status block "
3479		    "DMA memory!\n", __FILE__, __LINE__);
3480		rc = ENOMEM;
3481		goto bce_dma_alloc_exit;
3482	}
3483
3484	error = bus_dmamap_load(sc->status_tag,	sc->status_map,
3485	    sc->status_block, BCE_STATUS_BLK_SZ, bce_dma_map_addr,
3486	    &sc->status_block_paddr, BUS_DMA_NOWAIT);
3487
3488	if (error || sc->status_block_paddr == 0) {
3489		BCE_PRINTF("%s(%d): Could not map status block "
3490		    "DMA memory!\n", __FILE__, __LINE__);
3491		rc = ENOMEM;
3492		goto bce_dma_alloc_exit;
3493	}
3494
3495	DBPRINT(sc, BCE_INFO_LOAD, "%s(): status_block_paddr = 0x%jX\n",
3496	    __FUNCTION__, (uintmax_t) sc->status_block_paddr);
3497
3498	/*
3499	 * Create a DMA tag for the statistics block, allocate and clear the
3500	 * memory, map the memory into DMA space, and fetch the physical
3501	 * address of the block.
3502	 */
3503	if (bus_dma_tag_create(sc->parent_tag, BCE_DMA_ALIGN,
3504	    BCE_DMA_BOUNDARY, sc->max_bus_addr,	BUS_SPACE_MAXADDR,
3505	    NULL, NULL,	BCE_STATS_BLK_SZ, 1, BCE_STATS_BLK_SZ,
3506	    0, NULL, NULL, &sc->stats_tag)) {
3507		BCE_PRINTF("%s(%d): Could not allocate statistics block "
3508		    "DMA tag!\n", __FILE__, __LINE__);
3509		rc = ENOMEM;
3510		goto bce_dma_alloc_exit;
3511	}
3512
3513	if (bus_dmamem_alloc(sc->stats_tag, (void **)&sc->stats_block,
3514	    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &sc->stats_map)) {
3515		BCE_PRINTF("%s(%d): Could not allocate statistics block "
3516		    "DMA memory!\n", __FILE__, __LINE__);
3517		rc = ENOMEM;
3518		goto bce_dma_alloc_exit;
3519	}
3520
3521	error = bus_dmamap_load(sc->stats_tag, sc->stats_map,
3522	    sc->stats_block, BCE_STATS_BLK_SZ, bce_dma_map_addr,
3523	    &sc->stats_block_paddr, BUS_DMA_NOWAIT);
3524
3525	if (error || sc->stats_block_paddr == 0) {
3526		BCE_PRINTF("%s(%d): Could not map statistics block "
3527		    "DMA memory!\n", __FILE__, __LINE__);
3528		rc = ENOMEM;
3529		goto bce_dma_alloc_exit;
3530	}
3531
3532	DBPRINT(sc, BCE_INFO_LOAD, "%s(): stats_block_paddr = 0x%jX\n",
3533	    __FUNCTION__, (uintmax_t) sc->stats_block_paddr);
3534
3535	/* BCM5709 uses host memory as cache for context memory. */
3536	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
3537		sc->ctx_pages = 0x2000 / BCM_PAGE_SIZE;
3538		if (sc->ctx_pages == 0)
3539			sc->ctx_pages = 1;
3540
3541		DBRUNIF((sc->ctx_pages > 512),
3542		    BCE_PRINTF("%s(%d): Too many CTX pages! %d > 512\n",
3543		    __FILE__, __LINE__, sc->ctx_pages));
3544
3545		/*
3546		 * Create a DMA tag for the context pages,
3547		 * allocate and clear the memory, map the
3548		 * memory into DMA space, and fetch the
3549		 * physical address of the block.
3550		 */
3551		if(bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
3552		    BCE_DMA_BOUNDARY, sc->max_bus_addr,	BUS_SPACE_MAXADDR,
3553		    NULL, NULL,	BCM_PAGE_SIZE, 1, BCM_PAGE_SIZE,
3554		    0, NULL, NULL, &sc->ctx_tag)) {
3555			BCE_PRINTF("%s(%d): Could not allocate CTX "
3556			    "DMA tag!\n", __FILE__, __LINE__);
3557			rc = ENOMEM;
3558			goto bce_dma_alloc_exit;
3559		}
3560
3561		for (i = 0; i < sc->ctx_pages; i++) {
3562			if(bus_dmamem_alloc(sc->ctx_tag,
3563			    (void **)&sc->ctx_block[i],
3564			    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3565			    &sc->ctx_map[i])) {
3566				BCE_PRINTF("%s(%d): Could not allocate CTX "
3567				    "DMA memory!\n", __FILE__, __LINE__);
3568				rc = ENOMEM;
3569				goto bce_dma_alloc_exit;
3570			}
3571
3572			error = bus_dmamap_load(sc->ctx_tag, sc->ctx_map[i],
3573			    sc->ctx_block[i], BCM_PAGE_SIZE, bce_dma_map_addr,
3574			    &sc->ctx_paddr[i], BUS_DMA_NOWAIT);
3575
3576			if (error || sc->ctx_paddr[i] == 0) {
3577				BCE_PRINTF("%s(%d): Could not map CTX "
3578				    "DMA memory!\n", __FILE__, __LINE__);
3579				rc = ENOMEM;
3580				goto bce_dma_alloc_exit;
3581			}
3582
3583			DBPRINT(sc, BCE_INFO_LOAD, "%s(): ctx_paddr[%d] "
3584			    "= 0x%jX\n", __FUNCTION__, i,
3585			    (uintmax_t) sc->ctx_paddr[i]);
3586		}
3587	}
3588
3589	/*
3590	 * Create a DMA tag for the TX buffer descriptor chain,
3591	 * allocate and clear the  memory, and fetch the
3592	 * physical address of the block.
3593	 */
3594	if(bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE, BCE_DMA_BOUNDARY,
3595	    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
3596	    BCE_TX_CHAIN_PAGE_SZ, 1, BCE_TX_CHAIN_PAGE_SZ, 0,
3597	    NULL, NULL,	&sc->tx_bd_chain_tag)) {
3598		BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
3599		    "chain DMA tag!\n", __FILE__, __LINE__);
3600		rc = ENOMEM;
3601		goto bce_dma_alloc_exit;
3602	}
3603
3604	for (i = 0; i < sc->tx_pages; i++) {
3605		if(bus_dmamem_alloc(sc->tx_bd_chain_tag,
3606		    (void **)&sc->tx_bd_chain[i],
3607		    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3608		    &sc->tx_bd_chain_map[i])) {
3609			BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
3610			    "chain DMA memory!\n", __FILE__, __LINE__);
3611			rc = ENOMEM;
3612			goto bce_dma_alloc_exit;
3613		}
3614
3615		error = bus_dmamap_load(sc->tx_bd_chain_tag,
3616		    sc->tx_bd_chain_map[i], sc->tx_bd_chain[i],
3617		    BCE_TX_CHAIN_PAGE_SZ, bce_dma_map_addr,
3618		    &sc->tx_bd_chain_paddr[i], BUS_DMA_NOWAIT);
3619
3620		if (error || sc->tx_bd_chain_paddr[i] == 0) {
3621			BCE_PRINTF("%s(%d): Could not map TX descriptor "
3622			    "chain DMA memory!\n", __FILE__, __LINE__);
3623			rc = ENOMEM;
3624			goto bce_dma_alloc_exit;
3625		}
3626
3627		DBPRINT(sc, BCE_INFO_LOAD, "%s(): tx_bd_chain_paddr[%d] = "
3628		    "0x%jX\n", __FUNCTION__, i,
3629		    (uintmax_t) sc->tx_bd_chain_paddr[i]);
3630	}
3631
3632	/* Check the required size before mapping to conserve resources. */
3633	if (bce_tso_enable) {
3634		max_size     = BCE_TSO_MAX_SIZE;
3635		max_segments = BCE_MAX_SEGMENTS;
3636		max_seg_size = BCE_TSO_MAX_SEG_SIZE;
3637	} else {
3638		max_size     = MCLBYTES * BCE_MAX_SEGMENTS;
3639		max_segments = BCE_MAX_SEGMENTS;
3640		max_seg_size = MCLBYTES;
3641	}
3642
3643	/* Create a DMA tag for TX mbufs. */
3644	if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
3645	    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, max_size,
3646	    max_segments, max_seg_size,	0, NULL, NULL, &sc->tx_mbuf_tag)) {
3647		BCE_PRINTF("%s(%d): Could not allocate TX mbuf DMA tag!\n",
3648		    __FILE__, __LINE__);
3649		rc = ENOMEM;
3650		goto bce_dma_alloc_exit;
3651	}
3652
3653	/* Create DMA maps for the TX mbufs clusters. */
3654	for (i = 0; i < TOTAL_TX_BD_ALLOC; i++) {
3655		if (bus_dmamap_create(sc->tx_mbuf_tag, BUS_DMA_NOWAIT,
3656			&sc->tx_mbuf_map[i])) {
3657			BCE_PRINTF("%s(%d): Unable to create TX mbuf DMA "
3658			    "map!\n", __FILE__, __LINE__);
3659			rc = ENOMEM;
3660			goto bce_dma_alloc_exit;
3661		}
3662	}
3663
3664	/*
3665	 * Create a DMA tag for the RX buffer descriptor chain,
3666	 * allocate and clear the memory, and fetch the physical
3667	 * address of the blocks.
3668	 */
3669	if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
3670			BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR,
3671			sc->max_bus_addr, NULL, NULL,
3672			BCE_RX_CHAIN_PAGE_SZ, 1, BCE_RX_CHAIN_PAGE_SZ,
3673			0, NULL, NULL, &sc->rx_bd_chain_tag)) {
3674		BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain "
3675		    "DMA tag!\n", __FILE__, __LINE__);
3676		rc = ENOMEM;
3677		goto bce_dma_alloc_exit;
3678	}
3679
3680	for (i = 0; i < sc->rx_pages; i++) {
3681		if (bus_dmamem_alloc(sc->rx_bd_chain_tag,
3682		    (void **)&sc->rx_bd_chain[i],
3683		    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3684		    &sc->rx_bd_chain_map[i])) {
3685			BCE_PRINTF("%s(%d): Could not allocate RX descriptor "
3686			    "chain DMA memory!\n", __FILE__, __LINE__);
3687			rc = ENOMEM;
3688			goto bce_dma_alloc_exit;
3689		}
3690
3691		error = bus_dmamap_load(sc->rx_bd_chain_tag,
3692		    sc->rx_bd_chain_map[i], sc->rx_bd_chain[i],
3693		    BCE_RX_CHAIN_PAGE_SZ, bce_dma_map_addr,
3694		    &sc->rx_bd_chain_paddr[i], BUS_DMA_NOWAIT);
3695
3696		if (error || sc->rx_bd_chain_paddr[i] == 0) {
3697			BCE_PRINTF("%s(%d): Could not map RX descriptor "
3698			    "chain DMA memory!\n", __FILE__, __LINE__);
3699			rc = ENOMEM;
3700			goto bce_dma_alloc_exit;
3701		}
3702
3703		DBPRINT(sc, BCE_INFO_LOAD, "%s(): rx_bd_chain_paddr[%d] = "
3704		    "0x%jX\n", __FUNCTION__, i,
3705		    (uintmax_t) sc->rx_bd_chain_paddr[i]);
3706	}
3707
3708	/*
3709	 * Create a DMA tag for RX mbufs.
3710	 */
3711	if (bce_hdr_split == TRUE)
3712		max_size = ((sc->rx_bd_mbuf_alloc_size < MCLBYTES) ?
3713		    MCLBYTES : sc->rx_bd_mbuf_alloc_size);
3714	else
3715		max_size = MJUM9BYTES;
3716
3717	DBPRINT(sc, BCE_INFO_LOAD, "%s(): Creating rx_mbuf_tag "
3718	    "(max size = 0x%jX)\n", __FUNCTION__, (uintmax_t)max_size);
3719
3720	if (bus_dma_tag_create(sc->parent_tag, BCE_RX_BUF_ALIGN,
3721	    BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
3722	    max_size, 1, max_size, 0, NULL, NULL, &sc->rx_mbuf_tag)) {
3723		BCE_PRINTF("%s(%d): Could not allocate RX mbuf DMA tag!\n",
3724		    __FILE__, __LINE__);
3725		rc = ENOMEM;
3726		goto bce_dma_alloc_exit;
3727	}
3728
3729	/* Create DMA maps for the RX mbuf clusters. */
3730	for (i = 0; i < TOTAL_RX_BD_ALLOC; i++) {
3731		if (bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_NOWAIT,
3732		    &sc->rx_mbuf_map[i])) {
3733			BCE_PRINTF("%s(%d): Unable to create RX mbuf "
3734			    "DMA map!\n", __FILE__, __LINE__);
3735			rc = ENOMEM;
3736			goto bce_dma_alloc_exit;
3737		}
3738	}
3739
3740	if (bce_hdr_split == TRUE) {
3741		/*
3742		 * Create a DMA tag for the page buffer descriptor chain,
3743		 * allocate and clear the memory, and fetch the physical
3744		 * address of the blocks.
3745		 */
3746		if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
3747			    BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR, sc->max_bus_addr,
3748			    NULL, NULL,	BCE_PG_CHAIN_PAGE_SZ, 1, BCE_PG_CHAIN_PAGE_SZ,
3749			    0, NULL, NULL, &sc->pg_bd_chain_tag)) {
3750			BCE_PRINTF("%s(%d): Could not allocate page descriptor "
3751			    "chain DMA tag!\n",	__FILE__, __LINE__);
3752			rc = ENOMEM;
3753			goto bce_dma_alloc_exit;
3754		}
3755
3756		for (i = 0; i < sc->pg_pages; i++) {
3757			if (bus_dmamem_alloc(sc->pg_bd_chain_tag,
3758			    (void **)&sc->pg_bd_chain[i],
3759			    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3760			    &sc->pg_bd_chain_map[i])) {
3761				BCE_PRINTF("%s(%d): Could not allocate page "
3762				    "descriptor chain DMA memory!\n",
3763				    __FILE__, __LINE__);
3764				rc = ENOMEM;
3765				goto bce_dma_alloc_exit;
3766			}
3767
3768			error = bus_dmamap_load(sc->pg_bd_chain_tag,
3769			    sc->pg_bd_chain_map[i], sc->pg_bd_chain[i],
3770			    BCE_PG_CHAIN_PAGE_SZ, bce_dma_map_addr,
3771			    &sc->pg_bd_chain_paddr[i], BUS_DMA_NOWAIT);
3772
3773			if (error || sc->pg_bd_chain_paddr[i] == 0) {
3774				BCE_PRINTF("%s(%d): Could not map page descriptor "
3775					"chain DMA memory!\n", __FILE__, __LINE__);
3776				rc = ENOMEM;
3777				goto bce_dma_alloc_exit;
3778			}
3779
3780			DBPRINT(sc, BCE_INFO_LOAD, "%s(): pg_bd_chain_paddr[%d] = "
3781				"0x%jX\n", __FUNCTION__, i,
3782				(uintmax_t) sc->pg_bd_chain_paddr[i]);
3783		}
3784
3785		/*
3786		 * Create a DMA tag for page mbufs.
3787		 */
3788		if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
3789		    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
3790		    1, MCLBYTES, 0, NULL, NULL, &sc->pg_mbuf_tag)) {
3791			BCE_PRINTF("%s(%d): Could not allocate page mbuf "
3792				"DMA tag!\n", __FILE__, __LINE__);
3793			rc = ENOMEM;
3794			goto bce_dma_alloc_exit;
3795		}
3796
3797		/* Create DMA maps for the page mbuf clusters. */
3798		for (i = 0; i < TOTAL_PG_BD_ALLOC; i++) {
3799			if (bus_dmamap_create(sc->pg_mbuf_tag, BUS_DMA_NOWAIT,
3800				&sc->pg_mbuf_map[i])) {
3801				BCE_PRINTF("%s(%d): Unable to create page mbuf "
3802					"DMA map!\n", __FILE__, __LINE__);
3803				rc = ENOMEM;
3804				goto bce_dma_alloc_exit;
3805			}
3806		}
3807	}
3808
3809bce_dma_alloc_exit:
3810	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
3811	return(rc);
3812}
3813
3814/****************************************************************************/
3815/* Release all resources used by the driver.                                */
3816/*                                                                          */
3817/* Releases all resources acquired by the driver including interrupts,      */
3818/* interrupt handler, interfaces, mutexes, and DMA memory.                  */
3819/*                                                                          */
3820/* Returns:                                                                 */
3821/*   Nothing.                                                               */
3822/****************************************************************************/
3823static void
3824bce_release_resources(struct bce_softc *sc)
3825{
3826	device_t dev;
3827
3828	DBENTER(BCE_VERBOSE_RESET);
3829
3830	dev = sc->bce_dev;
3831
3832	bce_dma_free(sc);
3833
3834	if (sc->bce_intrhand != NULL) {
3835		DBPRINT(sc, BCE_INFO_RESET, "Removing interrupt handler.\n");
3836		bus_teardown_intr(dev, sc->bce_res_irq, sc->bce_intrhand);
3837	}
3838
3839	if (sc->bce_res_irq != NULL) {
3840		DBPRINT(sc, BCE_INFO_RESET, "Releasing IRQ.\n");
3841		bus_release_resource(dev, SYS_RES_IRQ,
3842		    rman_get_rid(sc->bce_res_irq), sc->bce_res_irq);
3843	}
3844
3845	if (sc->bce_flags & (BCE_USING_MSI_FLAG | BCE_USING_MSIX_FLAG)) {
3846		DBPRINT(sc, BCE_INFO_RESET, "Releasing MSI/MSI-X vector.\n");
3847		pci_release_msi(dev);
3848	}
3849
3850	if (sc->bce_res_mem != NULL) {
3851		DBPRINT(sc, BCE_INFO_RESET, "Releasing PCI memory.\n");
3852		    bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0),
3853		    sc->bce_res_mem);
3854	}
3855
3856	if (sc->bce_ifp != NULL) {
3857		DBPRINT(sc, BCE_INFO_RESET, "Releasing IF.\n");
3858		if_free(sc->bce_ifp);
3859	}
3860
3861	if (mtx_initialized(&sc->bce_mtx))
3862		BCE_LOCK_DESTROY(sc);
3863
3864	DBEXIT(BCE_VERBOSE_RESET);
3865}
3866
3867/****************************************************************************/
3868/* Firmware synchronization.                                                */
3869/*                                                                          */
3870/* Before performing certain events such as a chip reset, synchronize with  */
3871/* the firmware first.                                                      */
3872/*                                                                          */
3873/* Returns:                                                                 */
3874/*   0 for success, positive value for failure.                             */
3875/****************************************************************************/
3876static int
3877bce_fw_sync(struct bce_softc *sc, u32 msg_data)
3878{
3879	int i, rc = 0;
3880	u32 val;
3881
3882	DBENTER(BCE_VERBOSE_RESET);
3883
3884	/* Don't waste any time if we've timed out before. */
3885	if (sc->bce_fw_timed_out == TRUE) {
3886		rc = EBUSY;
3887		goto bce_fw_sync_exit;
3888	}
3889
3890	/* Increment the message sequence number. */
3891	sc->bce_fw_wr_seq++;
3892	msg_data |= sc->bce_fw_wr_seq;
3893
3894 	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "bce_fw_sync(): msg_data = "
3895	    "0x%08X\n",	msg_data);
3896
3897	/* Send the message to the bootcode driver mailbox. */
3898	bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
3899
3900	/* Wait for the bootcode to acknowledge the message. */
3901	for (i = 0; i < FW_ACK_TIME_OUT_MS; i++) {
3902		/* Check for a response in the bootcode firmware mailbox. */
3903		val = bce_shmem_rd(sc, BCE_FW_MB);
3904		if ((val & BCE_FW_MSG_ACK) == (msg_data & BCE_DRV_MSG_SEQ))
3905			break;
3906		DELAY(1000);
3907	}
3908
3909	/* If we've timed out, tell bootcode that we've stopped waiting. */
3910	if (((val & BCE_FW_MSG_ACK) != (msg_data & BCE_DRV_MSG_SEQ)) &&
3911	    ((msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0)) {
3912		BCE_PRINTF("%s(%d): Firmware synchronization timeout! "
3913		    "msg_data = 0x%08X\n", __FILE__, __LINE__, msg_data);
3914
3915		msg_data &= ~BCE_DRV_MSG_CODE;
3916		msg_data |= BCE_DRV_MSG_CODE_FW_TIMEOUT;
3917
3918		bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
3919
3920		sc->bce_fw_timed_out = TRUE;
3921		rc = EBUSY;
3922	}
3923
3924bce_fw_sync_exit:
3925	DBEXIT(BCE_VERBOSE_RESET);
3926	return (rc);
3927}
3928
3929/****************************************************************************/
3930/* Load Receive Virtual 2 Physical (RV2P) processor firmware.               */
3931/*                                                                          */
3932/* Returns:                                                                 */
3933/*   Nothing.                                                               */
3934/****************************************************************************/
3935static void
3936bce_load_rv2p_fw(struct bce_softc *sc, const u32 *rv2p_code,
3937	u32 rv2p_code_len, u32 rv2p_proc)
3938{
3939	int i;
3940	u32 val;
3941
3942	DBENTER(BCE_VERBOSE_RESET);
3943
3944	/* Set the page size used by RV2P. */
3945	if (rv2p_proc == RV2P_PROC2) {
3946		BCE_RV2P_PROC2_CHG_MAX_BD_PAGE(USABLE_RX_BD_PER_PAGE);
3947	}
3948
3949	for (i = 0; i < rv2p_code_len; i += 8) {
3950		REG_WR(sc, BCE_RV2P_INSTR_HIGH, *rv2p_code);
3951		rv2p_code++;
3952		REG_WR(sc, BCE_RV2P_INSTR_LOW, *rv2p_code);
3953		rv2p_code++;
3954
3955		if (rv2p_proc == RV2P_PROC1) {
3956			val = (i / 8) | BCE_RV2P_PROC1_ADDR_CMD_RDWR;
3957			REG_WR(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
3958		}
3959		else {
3960			val = (i / 8) | BCE_RV2P_PROC2_ADDR_CMD_RDWR;
3961			REG_WR(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
3962		}
3963	}
3964
3965	/* Reset the processor, un-stall is done later. */
3966	if (rv2p_proc == RV2P_PROC1) {
3967		REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC1_RESET);
3968	}
3969	else {
3970		REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC2_RESET);
3971	}
3972
3973	DBEXIT(BCE_VERBOSE_RESET);
3974}
3975
3976/****************************************************************************/
3977/* Load RISC processor firmware.                                            */
3978/*                                                                          */
3979/* Loads firmware from the file if_bcefw.h into the scratchpad memory       */
3980/* associated with a particular processor.                                  */
3981/*                                                                          */
3982/* Returns:                                                                 */
3983/*   Nothing.                                                               */
3984/****************************************************************************/
3985static void
3986bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
3987	struct fw_info *fw)
3988{
3989	u32 offset;
3990
3991	DBENTER(BCE_VERBOSE_RESET);
3992
3993    bce_halt_cpu(sc, cpu_reg);
3994
3995	/* Load the Text area. */
3996	offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
3997	if (fw->text) {
3998		int j;
3999
4000		for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
4001			REG_WR_IND(sc, offset, fw->text[j]);
4002	        }
4003	}
4004
4005	/* Load the Data area. */
4006	offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
4007	if (fw->data) {
4008		int j;
4009
4010		for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
4011			REG_WR_IND(sc, offset, fw->data[j]);
4012		}
4013	}
4014
4015	/* Load the SBSS area. */
4016	offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
4017	if (fw->sbss) {
4018		int j;
4019
4020		for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
4021			REG_WR_IND(sc, offset, fw->sbss[j]);
4022		}
4023	}
4024
4025	/* Load the BSS area. */
4026	offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
4027	if (fw->bss) {
4028		int j;
4029
4030		for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
4031			REG_WR_IND(sc, offset, fw->bss[j]);
4032		}
4033	}
4034
4035	/* Load the Read-Only area. */
4036	offset = cpu_reg->spad_base +
4037		(fw->rodata_addr - cpu_reg->mips_view_base);
4038	if (fw->rodata) {
4039		int j;
4040
4041		for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
4042			REG_WR_IND(sc, offset, fw->rodata[j]);
4043		}
4044	}
4045
4046	/* Clear the pre-fetch instruction and set the FW start address. */
4047	REG_WR_IND(sc, cpu_reg->inst, 0);
4048	REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
4049
4050	DBEXIT(BCE_VERBOSE_RESET);
4051}
4052
4053/****************************************************************************/
4054/* Starts the RISC processor.                                               */
4055/*                                                                          */
4056/* Assumes the CPU starting address has already been set.                   */
4057/*                                                                          */
4058/* Returns:                                                                 */
4059/*   Nothing.                                                               */
4060/****************************************************************************/
4061static void
4062bce_start_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
4063{
4064	u32 val;
4065
4066	DBENTER(BCE_VERBOSE_RESET);
4067
4068	/* Start the CPU. */
4069	val = REG_RD_IND(sc, cpu_reg->mode);
4070	val &= ~cpu_reg->mode_value_halt;
4071	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
4072	REG_WR_IND(sc, cpu_reg->mode, val);
4073
4074	DBEXIT(BCE_VERBOSE_RESET);
4075}
4076
4077/****************************************************************************/
4078/* Halts the RISC processor.                                                */
4079/*                                                                          */
4080/* Returns:                                                                 */
4081/*   Nothing.                                                               */
4082/****************************************************************************/
4083static void
4084bce_halt_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
4085{
4086	u32 val;
4087
4088	DBENTER(BCE_VERBOSE_RESET);
4089
4090	/* Halt the CPU. */
4091	val = REG_RD_IND(sc, cpu_reg->mode);
4092	val |= cpu_reg->mode_value_halt;
4093	REG_WR_IND(sc, cpu_reg->mode, val);
4094	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
4095
4096	DBEXIT(BCE_VERBOSE_RESET);
4097}
4098
4099/****************************************************************************/
4100/* Initialize the RX CPU.                                                   */
4101/*                                                                          */
4102/* Returns:                                                                 */
4103/*   Nothing.                                                               */
4104/****************************************************************************/
4105static void
4106bce_start_rxp_cpu(struct bce_softc *sc)
4107{
4108	struct cpu_reg cpu_reg;
4109
4110	DBENTER(BCE_VERBOSE_RESET);
4111
4112	cpu_reg.mode = BCE_RXP_CPU_MODE;
4113	cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
4114	cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
4115	cpu_reg.state = BCE_RXP_CPU_STATE;
4116	cpu_reg.state_value_clear = 0xffffff;
4117	cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
4118	cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
4119	cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
4120	cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
4121	cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
4122	cpu_reg.spad_base = BCE_RXP_SCRATCH;
4123	cpu_reg.mips_view_base = 0x8000000;
4124
4125	DBPRINT(sc, BCE_INFO_RESET, "Starting RX firmware.\n");
4126	bce_start_cpu(sc, &cpu_reg);
4127
4128	DBEXIT(BCE_VERBOSE_RESET);
4129}
4130
4131/****************************************************************************/
4132/* Initialize the RX CPU.                                                   */
4133/*                                                                          */
4134/* Returns:                                                                 */
4135/*   Nothing.                                                               */
4136/****************************************************************************/
4137static void
4138bce_init_rxp_cpu(struct bce_softc *sc)
4139{
4140	struct cpu_reg cpu_reg;
4141	struct fw_info fw;
4142
4143	DBENTER(BCE_VERBOSE_RESET);
4144
4145	cpu_reg.mode = BCE_RXP_CPU_MODE;
4146	cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
4147	cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
4148	cpu_reg.state = BCE_RXP_CPU_STATE;
4149	cpu_reg.state_value_clear = 0xffffff;
4150	cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
4151	cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
4152	cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
4153	cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
4154	cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
4155	cpu_reg.spad_base = BCE_RXP_SCRATCH;
4156	cpu_reg.mips_view_base = 0x8000000;
4157
4158	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4159 		fw.ver_major = bce_RXP_b09FwReleaseMajor;
4160		fw.ver_minor = bce_RXP_b09FwReleaseMinor;
4161		fw.ver_fix = bce_RXP_b09FwReleaseFix;
4162		fw.start_addr = bce_RXP_b09FwStartAddr;
4163
4164		fw.text_addr = bce_RXP_b09FwTextAddr;
4165		fw.text_len = bce_RXP_b09FwTextLen;
4166		fw.text_index = 0;
4167		fw.text = bce_RXP_b09FwText;
4168
4169		fw.data_addr = bce_RXP_b09FwDataAddr;
4170		fw.data_len = bce_RXP_b09FwDataLen;
4171		fw.data_index = 0;
4172		fw.data = bce_RXP_b09FwData;
4173
4174		fw.sbss_addr = bce_RXP_b09FwSbssAddr;
4175		fw.sbss_len = bce_RXP_b09FwSbssLen;
4176		fw.sbss_index = 0;
4177		fw.sbss = bce_RXP_b09FwSbss;
4178
4179		fw.bss_addr = bce_RXP_b09FwBssAddr;
4180		fw.bss_len = bce_RXP_b09FwBssLen;
4181		fw.bss_index = 0;
4182		fw.bss = bce_RXP_b09FwBss;
4183
4184		fw.rodata_addr = bce_RXP_b09FwRodataAddr;
4185		fw.rodata_len = bce_RXP_b09FwRodataLen;
4186		fw.rodata_index = 0;
4187		fw.rodata = bce_RXP_b09FwRodata;
4188	} else {
4189		fw.ver_major = bce_RXP_b06FwReleaseMajor;
4190		fw.ver_minor = bce_RXP_b06FwReleaseMinor;
4191		fw.ver_fix = bce_RXP_b06FwReleaseFix;
4192		fw.start_addr = bce_RXP_b06FwStartAddr;
4193
4194		fw.text_addr = bce_RXP_b06FwTextAddr;
4195		fw.text_len = bce_RXP_b06FwTextLen;
4196		fw.text_index = 0;
4197		fw.text = bce_RXP_b06FwText;
4198
4199		fw.data_addr = bce_RXP_b06FwDataAddr;
4200		fw.data_len = bce_RXP_b06FwDataLen;
4201		fw.data_index = 0;
4202		fw.data = bce_RXP_b06FwData;
4203
4204		fw.sbss_addr = bce_RXP_b06FwSbssAddr;
4205		fw.sbss_len = bce_RXP_b06FwSbssLen;
4206		fw.sbss_index = 0;
4207		fw.sbss = bce_RXP_b06FwSbss;
4208
4209		fw.bss_addr = bce_RXP_b06FwBssAddr;
4210		fw.bss_len = bce_RXP_b06FwBssLen;
4211		fw.bss_index = 0;
4212		fw.bss = bce_RXP_b06FwBss;
4213
4214		fw.rodata_addr = bce_RXP_b06FwRodataAddr;
4215		fw.rodata_len = bce_RXP_b06FwRodataLen;
4216		fw.rodata_index = 0;
4217		fw.rodata = bce_RXP_b06FwRodata;
4218	}
4219
4220	DBPRINT(sc, BCE_INFO_RESET, "Loading RX firmware.\n");
4221	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4222
4223    /* Delay RXP start until initialization is complete. */
4224
4225	DBEXIT(BCE_VERBOSE_RESET);
4226}
4227
4228/****************************************************************************/
4229/* Initialize the TX CPU.                                                   */
4230/*                                                                          */
4231/* Returns:                                                                 */
4232/*   Nothing.                                                               */
4233/****************************************************************************/
4234static void
4235bce_init_txp_cpu(struct bce_softc *sc)
4236{
4237	struct cpu_reg cpu_reg;
4238	struct fw_info fw;
4239
4240	DBENTER(BCE_VERBOSE_RESET);
4241
4242	cpu_reg.mode = BCE_TXP_CPU_MODE;
4243	cpu_reg.mode_value_halt = BCE_TXP_CPU_MODE_SOFT_HALT;
4244	cpu_reg.mode_value_sstep = BCE_TXP_CPU_MODE_STEP_ENA;
4245	cpu_reg.state = BCE_TXP_CPU_STATE;
4246	cpu_reg.state_value_clear = 0xffffff;
4247	cpu_reg.gpr0 = BCE_TXP_CPU_REG_FILE;
4248	cpu_reg.evmask = BCE_TXP_CPU_EVENT_MASK;
4249	cpu_reg.pc = BCE_TXP_CPU_PROGRAM_COUNTER;
4250	cpu_reg.inst = BCE_TXP_CPU_INSTRUCTION;
4251	cpu_reg.bp = BCE_TXP_CPU_HW_BREAKPOINT;
4252	cpu_reg.spad_base = BCE_TXP_SCRATCH;
4253	cpu_reg.mips_view_base = 0x8000000;
4254
4255	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4256		fw.ver_major = bce_TXP_b09FwReleaseMajor;
4257		fw.ver_minor = bce_TXP_b09FwReleaseMinor;
4258		fw.ver_fix = bce_TXP_b09FwReleaseFix;
4259		fw.start_addr = bce_TXP_b09FwStartAddr;
4260
4261		fw.text_addr = bce_TXP_b09FwTextAddr;
4262		fw.text_len = bce_TXP_b09FwTextLen;
4263		fw.text_index = 0;
4264		fw.text = bce_TXP_b09FwText;
4265
4266		fw.data_addr = bce_TXP_b09FwDataAddr;
4267		fw.data_len = bce_TXP_b09FwDataLen;
4268		fw.data_index = 0;
4269		fw.data = bce_TXP_b09FwData;
4270
4271		fw.sbss_addr = bce_TXP_b09FwSbssAddr;
4272		fw.sbss_len = bce_TXP_b09FwSbssLen;
4273		fw.sbss_index = 0;
4274		fw.sbss = bce_TXP_b09FwSbss;
4275
4276		fw.bss_addr = bce_TXP_b09FwBssAddr;
4277		fw.bss_len = bce_TXP_b09FwBssLen;
4278		fw.bss_index = 0;
4279		fw.bss = bce_TXP_b09FwBss;
4280
4281		fw.rodata_addr = bce_TXP_b09FwRodataAddr;
4282		fw.rodata_len = bce_TXP_b09FwRodataLen;
4283		fw.rodata_index = 0;
4284		fw.rodata = bce_TXP_b09FwRodata;
4285	} else {
4286		fw.ver_major = bce_TXP_b06FwReleaseMajor;
4287		fw.ver_minor = bce_TXP_b06FwReleaseMinor;
4288		fw.ver_fix = bce_TXP_b06FwReleaseFix;
4289		fw.start_addr = bce_TXP_b06FwStartAddr;
4290
4291		fw.text_addr = bce_TXP_b06FwTextAddr;
4292		fw.text_len = bce_TXP_b06FwTextLen;
4293		fw.text_index = 0;
4294		fw.text = bce_TXP_b06FwText;
4295
4296		fw.data_addr = bce_TXP_b06FwDataAddr;
4297		fw.data_len = bce_TXP_b06FwDataLen;
4298		fw.data_index = 0;
4299		fw.data = bce_TXP_b06FwData;
4300
4301		fw.sbss_addr = bce_TXP_b06FwSbssAddr;
4302		fw.sbss_len = bce_TXP_b06FwSbssLen;
4303		fw.sbss_index = 0;
4304		fw.sbss = bce_TXP_b06FwSbss;
4305
4306		fw.bss_addr = bce_TXP_b06FwBssAddr;
4307		fw.bss_len = bce_TXP_b06FwBssLen;
4308		fw.bss_index = 0;
4309		fw.bss = bce_TXP_b06FwBss;
4310
4311		fw.rodata_addr = bce_TXP_b06FwRodataAddr;
4312		fw.rodata_len = bce_TXP_b06FwRodataLen;
4313		fw.rodata_index = 0;
4314		fw.rodata = bce_TXP_b06FwRodata;
4315	}
4316
4317	DBPRINT(sc, BCE_INFO_RESET, "Loading TX firmware.\n");
4318	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4319    bce_start_cpu(sc, &cpu_reg);
4320
4321	DBEXIT(BCE_VERBOSE_RESET);
4322}
4323
4324/****************************************************************************/
4325/* Initialize the TPAT CPU.                                                 */
4326/*                                                                          */
4327/* Returns:                                                                 */
4328/*   Nothing.                                                               */
4329/****************************************************************************/
4330static void
4331bce_init_tpat_cpu(struct bce_softc *sc)
4332{
4333	struct cpu_reg cpu_reg;
4334	struct fw_info fw;
4335
4336	DBENTER(BCE_VERBOSE_RESET);
4337
4338	cpu_reg.mode = BCE_TPAT_CPU_MODE;
4339	cpu_reg.mode_value_halt = BCE_TPAT_CPU_MODE_SOFT_HALT;
4340	cpu_reg.mode_value_sstep = BCE_TPAT_CPU_MODE_STEP_ENA;
4341	cpu_reg.state = BCE_TPAT_CPU_STATE;
4342	cpu_reg.state_value_clear = 0xffffff;
4343	cpu_reg.gpr0 = BCE_TPAT_CPU_REG_FILE;
4344	cpu_reg.evmask = BCE_TPAT_CPU_EVENT_MASK;
4345	cpu_reg.pc = BCE_TPAT_CPU_PROGRAM_COUNTER;
4346	cpu_reg.inst = BCE_TPAT_CPU_INSTRUCTION;
4347	cpu_reg.bp = BCE_TPAT_CPU_HW_BREAKPOINT;
4348	cpu_reg.spad_base = BCE_TPAT_SCRATCH;
4349	cpu_reg.mips_view_base = 0x8000000;
4350
4351	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4352		fw.ver_major = bce_TPAT_b09FwReleaseMajor;
4353		fw.ver_minor = bce_TPAT_b09FwReleaseMinor;
4354		fw.ver_fix = bce_TPAT_b09FwReleaseFix;
4355		fw.start_addr = bce_TPAT_b09FwStartAddr;
4356
4357		fw.text_addr = bce_TPAT_b09FwTextAddr;
4358		fw.text_len = bce_TPAT_b09FwTextLen;
4359		fw.text_index = 0;
4360		fw.text = bce_TPAT_b09FwText;
4361
4362		fw.data_addr = bce_TPAT_b09FwDataAddr;
4363		fw.data_len = bce_TPAT_b09FwDataLen;
4364		fw.data_index = 0;
4365		fw.data = bce_TPAT_b09FwData;
4366
4367		fw.sbss_addr = bce_TPAT_b09FwSbssAddr;
4368		fw.sbss_len = bce_TPAT_b09FwSbssLen;
4369		fw.sbss_index = 0;
4370		fw.sbss = bce_TPAT_b09FwSbss;
4371
4372		fw.bss_addr = bce_TPAT_b09FwBssAddr;
4373		fw.bss_len = bce_TPAT_b09FwBssLen;
4374		fw.bss_index = 0;
4375		fw.bss = bce_TPAT_b09FwBss;
4376
4377		fw.rodata_addr = bce_TPAT_b09FwRodataAddr;
4378		fw.rodata_len = bce_TPAT_b09FwRodataLen;
4379		fw.rodata_index = 0;
4380		fw.rodata = bce_TPAT_b09FwRodata;
4381	} else {
4382		fw.ver_major = bce_TPAT_b06FwReleaseMajor;
4383		fw.ver_minor = bce_TPAT_b06FwReleaseMinor;
4384		fw.ver_fix = bce_TPAT_b06FwReleaseFix;
4385		fw.start_addr = bce_TPAT_b06FwStartAddr;
4386
4387		fw.text_addr = bce_TPAT_b06FwTextAddr;
4388		fw.text_len = bce_TPAT_b06FwTextLen;
4389		fw.text_index = 0;
4390		fw.text = bce_TPAT_b06FwText;
4391
4392		fw.data_addr = bce_TPAT_b06FwDataAddr;
4393		fw.data_len = bce_TPAT_b06FwDataLen;
4394		fw.data_index = 0;
4395		fw.data = bce_TPAT_b06FwData;
4396
4397		fw.sbss_addr = bce_TPAT_b06FwSbssAddr;
4398		fw.sbss_len = bce_TPAT_b06FwSbssLen;
4399		fw.sbss_index = 0;
4400		fw.sbss = bce_TPAT_b06FwSbss;
4401
4402		fw.bss_addr = bce_TPAT_b06FwBssAddr;
4403		fw.bss_len = bce_TPAT_b06FwBssLen;
4404		fw.bss_index = 0;
4405		fw.bss = bce_TPAT_b06FwBss;
4406
4407		fw.rodata_addr = bce_TPAT_b06FwRodataAddr;
4408		fw.rodata_len = bce_TPAT_b06FwRodataLen;
4409		fw.rodata_index = 0;
4410		fw.rodata = bce_TPAT_b06FwRodata;
4411	}
4412
4413	DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n");
4414	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4415	bce_start_cpu(sc, &cpu_reg);
4416
4417	DBEXIT(BCE_VERBOSE_RESET);
4418}
4419
4420/****************************************************************************/
4421/* Initialize the CP CPU.                                                   */
4422/*                                                                          */
4423/* Returns:                                                                 */
4424/*   Nothing.                                                               */
4425/****************************************************************************/
4426static void
4427bce_init_cp_cpu(struct bce_softc *sc)
4428{
4429	struct cpu_reg cpu_reg;
4430	struct fw_info fw;
4431
4432	DBENTER(BCE_VERBOSE_RESET);
4433
4434	cpu_reg.mode = BCE_CP_CPU_MODE;
4435	cpu_reg.mode_value_halt = BCE_CP_CPU_MODE_SOFT_HALT;
4436	cpu_reg.mode_value_sstep = BCE_CP_CPU_MODE_STEP_ENA;
4437	cpu_reg.state = BCE_CP_CPU_STATE;
4438	cpu_reg.state_value_clear = 0xffffff;
4439	cpu_reg.gpr0 = BCE_CP_CPU_REG_FILE;
4440	cpu_reg.evmask = BCE_CP_CPU_EVENT_MASK;
4441	cpu_reg.pc = BCE_CP_CPU_PROGRAM_COUNTER;
4442	cpu_reg.inst = BCE_CP_CPU_INSTRUCTION;
4443	cpu_reg.bp = BCE_CP_CPU_HW_BREAKPOINT;
4444	cpu_reg.spad_base = BCE_CP_SCRATCH;
4445	cpu_reg.mips_view_base = 0x8000000;
4446
4447	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4448		fw.ver_major = bce_CP_b09FwReleaseMajor;
4449		fw.ver_minor = bce_CP_b09FwReleaseMinor;
4450		fw.ver_fix = bce_CP_b09FwReleaseFix;
4451		fw.start_addr = bce_CP_b09FwStartAddr;
4452
4453		fw.text_addr = bce_CP_b09FwTextAddr;
4454		fw.text_len = bce_CP_b09FwTextLen;
4455		fw.text_index = 0;
4456		fw.text = bce_CP_b09FwText;
4457
4458		fw.data_addr = bce_CP_b09FwDataAddr;
4459		fw.data_len = bce_CP_b09FwDataLen;
4460		fw.data_index = 0;
4461		fw.data = bce_CP_b09FwData;
4462
4463		fw.sbss_addr = bce_CP_b09FwSbssAddr;
4464		fw.sbss_len = bce_CP_b09FwSbssLen;
4465		fw.sbss_index = 0;
4466		fw.sbss = bce_CP_b09FwSbss;
4467
4468		fw.bss_addr = bce_CP_b09FwBssAddr;
4469		fw.bss_len = bce_CP_b09FwBssLen;
4470		fw.bss_index = 0;
4471		fw.bss = bce_CP_b09FwBss;
4472
4473		fw.rodata_addr = bce_CP_b09FwRodataAddr;
4474		fw.rodata_len = bce_CP_b09FwRodataLen;
4475		fw.rodata_index = 0;
4476		fw.rodata = bce_CP_b09FwRodata;
4477	} else {
4478		fw.ver_major = bce_CP_b06FwReleaseMajor;
4479		fw.ver_minor = bce_CP_b06FwReleaseMinor;
4480		fw.ver_fix = bce_CP_b06FwReleaseFix;
4481		fw.start_addr = bce_CP_b06FwStartAddr;
4482
4483		fw.text_addr = bce_CP_b06FwTextAddr;
4484		fw.text_len = bce_CP_b06FwTextLen;
4485		fw.text_index = 0;
4486		fw.text = bce_CP_b06FwText;
4487
4488		fw.data_addr = bce_CP_b06FwDataAddr;
4489		fw.data_len = bce_CP_b06FwDataLen;
4490		fw.data_index = 0;
4491		fw.data = bce_CP_b06FwData;
4492
4493		fw.sbss_addr = bce_CP_b06FwSbssAddr;
4494		fw.sbss_len = bce_CP_b06FwSbssLen;
4495		fw.sbss_index = 0;
4496		fw.sbss = bce_CP_b06FwSbss;
4497
4498		fw.bss_addr = bce_CP_b06FwBssAddr;
4499		fw.bss_len = bce_CP_b06FwBssLen;
4500		fw.bss_index = 0;
4501		fw.bss = bce_CP_b06FwBss;
4502
4503		fw.rodata_addr = bce_CP_b06FwRodataAddr;
4504		fw.rodata_len = bce_CP_b06FwRodataLen;
4505		fw.rodata_index = 0;
4506		fw.rodata = bce_CP_b06FwRodata;
4507	}
4508
4509	DBPRINT(sc, BCE_INFO_RESET, "Loading CP firmware.\n");
4510	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4511	bce_start_cpu(sc, &cpu_reg);
4512
4513	DBEXIT(BCE_VERBOSE_RESET);
4514}
4515
4516/****************************************************************************/
4517/* Initialize the COM CPU.                                                 */
4518/*                                                                          */
4519/* Returns:                                                                 */
4520/*   Nothing.                                                               */
4521/****************************************************************************/
4522static void
4523bce_init_com_cpu(struct bce_softc *sc)
4524{
4525	struct cpu_reg cpu_reg;
4526	struct fw_info fw;
4527
4528	DBENTER(BCE_VERBOSE_RESET);
4529
4530	cpu_reg.mode = BCE_COM_CPU_MODE;
4531	cpu_reg.mode_value_halt = BCE_COM_CPU_MODE_SOFT_HALT;
4532	cpu_reg.mode_value_sstep = BCE_COM_CPU_MODE_STEP_ENA;
4533	cpu_reg.state = BCE_COM_CPU_STATE;
4534	cpu_reg.state_value_clear = 0xffffff;
4535	cpu_reg.gpr0 = BCE_COM_CPU_REG_FILE;
4536	cpu_reg.evmask = BCE_COM_CPU_EVENT_MASK;
4537	cpu_reg.pc = BCE_COM_CPU_PROGRAM_COUNTER;
4538	cpu_reg.inst = BCE_COM_CPU_INSTRUCTION;
4539	cpu_reg.bp = BCE_COM_CPU_HW_BREAKPOINT;
4540	cpu_reg.spad_base = BCE_COM_SCRATCH;
4541	cpu_reg.mips_view_base = 0x8000000;
4542
4543	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4544		fw.ver_major = bce_COM_b09FwReleaseMajor;
4545		fw.ver_minor = bce_COM_b09FwReleaseMinor;
4546		fw.ver_fix = bce_COM_b09FwReleaseFix;
4547		fw.start_addr = bce_COM_b09FwStartAddr;
4548
4549		fw.text_addr = bce_COM_b09FwTextAddr;
4550		fw.text_len = bce_COM_b09FwTextLen;
4551		fw.text_index = 0;
4552		fw.text = bce_COM_b09FwText;
4553
4554		fw.data_addr = bce_COM_b09FwDataAddr;
4555		fw.data_len = bce_COM_b09FwDataLen;
4556		fw.data_index = 0;
4557		fw.data = bce_COM_b09FwData;
4558
4559		fw.sbss_addr = bce_COM_b09FwSbssAddr;
4560		fw.sbss_len = bce_COM_b09FwSbssLen;
4561		fw.sbss_index = 0;
4562		fw.sbss = bce_COM_b09FwSbss;
4563
4564		fw.bss_addr = bce_COM_b09FwBssAddr;
4565		fw.bss_len = bce_COM_b09FwBssLen;
4566		fw.bss_index = 0;
4567		fw.bss = bce_COM_b09FwBss;
4568
4569		fw.rodata_addr = bce_COM_b09FwRodataAddr;
4570		fw.rodata_len = bce_COM_b09FwRodataLen;
4571		fw.rodata_index = 0;
4572		fw.rodata = bce_COM_b09FwRodata;
4573	} else {
4574		fw.ver_major = bce_COM_b06FwReleaseMajor;
4575		fw.ver_minor = bce_COM_b06FwReleaseMinor;
4576		fw.ver_fix = bce_COM_b06FwReleaseFix;
4577		fw.start_addr = bce_COM_b06FwStartAddr;
4578
4579		fw.text_addr = bce_COM_b06FwTextAddr;
4580		fw.text_len = bce_COM_b06FwTextLen;
4581		fw.text_index = 0;
4582		fw.text = bce_COM_b06FwText;
4583
4584		fw.data_addr = bce_COM_b06FwDataAddr;
4585		fw.data_len = bce_COM_b06FwDataLen;
4586		fw.data_index = 0;
4587		fw.data = bce_COM_b06FwData;
4588
4589		fw.sbss_addr = bce_COM_b06FwSbssAddr;
4590		fw.sbss_len = bce_COM_b06FwSbssLen;
4591		fw.sbss_index = 0;
4592		fw.sbss = bce_COM_b06FwSbss;
4593
4594		fw.bss_addr = bce_COM_b06FwBssAddr;
4595		fw.bss_len = bce_COM_b06FwBssLen;
4596		fw.bss_index = 0;
4597		fw.bss = bce_COM_b06FwBss;
4598
4599		fw.rodata_addr = bce_COM_b06FwRodataAddr;
4600		fw.rodata_len = bce_COM_b06FwRodataLen;
4601		fw.rodata_index = 0;
4602		fw.rodata = bce_COM_b06FwRodata;
4603	}
4604
4605	DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n");
4606	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4607	bce_start_cpu(sc, &cpu_reg);
4608
4609	DBEXIT(BCE_VERBOSE_RESET);
4610}
4611
4612/****************************************************************************/
4613/* Initialize the RV2P, RX, TX, TPAT, COM, and CP CPUs.                     */
4614/*                                                                          */
4615/* Loads the firmware for each CPU and starts the CPU.                      */
4616/*                                                                          */
4617/* Returns:                                                                 */
4618/*   Nothing.                                                               */
4619/****************************************************************************/
4620static void
4621bce_init_cpus(struct bce_softc *sc)
4622{
4623	DBENTER(BCE_VERBOSE_RESET);
4624
4625	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4626		if ((BCE_CHIP_REV(sc) == BCE_CHIP_REV_Ax)) {
4627			bce_load_rv2p_fw(sc, bce_xi90_rv2p_proc1,
4628			    sizeof(bce_xi90_rv2p_proc1), RV2P_PROC1);
4629			bce_load_rv2p_fw(sc, bce_xi90_rv2p_proc2,
4630			    sizeof(bce_xi90_rv2p_proc2), RV2P_PROC2);
4631		} else {
4632			bce_load_rv2p_fw(sc, bce_xi_rv2p_proc1,
4633			    sizeof(bce_xi_rv2p_proc1), RV2P_PROC1);
4634			bce_load_rv2p_fw(sc, bce_xi_rv2p_proc2,
4635			    sizeof(bce_xi_rv2p_proc2), RV2P_PROC2);
4636		}
4637
4638	} else {
4639		bce_load_rv2p_fw(sc, bce_rv2p_proc1,
4640		    sizeof(bce_rv2p_proc1), RV2P_PROC1);
4641		bce_load_rv2p_fw(sc, bce_rv2p_proc2,
4642		    sizeof(bce_rv2p_proc2), RV2P_PROC2);
4643	}
4644
4645	bce_init_rxp_cpu(sc);
4646	bce_init_txp_cpu(sc);
4647	bce_init_tpat_cpu(sc);
4648	bce_init_com_cpu(sc);
4649	bce_init_cp_cpu(sc);
4650
4651	DBEXIT(BCE_VERBOSE_RESET);
4652}
4653
4654/****************************************************************************/
4655/* Initialize context memory.                                               */
4656/*                                                                          */
4657/* Clears the memory associated with each Context ID (CID).                 */
4658/*                                                                          */
4659/* Returns:                                                                 */
4660/*   Nothing.                                                               */
4661/****************************************************************************/
4662static int
4663bce_init_ctx(struct bce_softc *sc)
4664{
4665	u32 offset, val, vcid_addr;
4666	int i, j, rc, retry_cnt;
4667
4668	rc = 0;
4669	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
4670
4671	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4672		retry_cnt = CTX_INIT_RETRY_COUNT;
4673
4674		DBPRINT(sc, BCE_INFO_CTX, "Initializing 5709 context.\n");
4675
4676		/*
4677		 * BCM5709 context memory may be cached
4678		 * in host memory so prepare the host memory
4679		 * for access.
4680		 */
4681		val = BCE_CTX_COMMAND_ENABLED |
4682		    BCE_CTX_COMMAND_MEM_INIT | (1 << 12);
4683		val |= (BCM_PAGE_BITS - 8) << 16;
4684		REG_WR(sc, BCE_CTX_COMMAND, val);
4685
4686		/* Wait for mem init command to complete. */
4687		for (i = 0; i < retry_cnt; i++) {
4688			val = REG_RD(sc, BCE_CTX_COMMAND);
4689			if (!(val & BCE_CTX_COMMAND_MEM_INIT))
4690				break;
4691			DELAY(2);
4692		}
4693		if ((val & BCE_CTX_COMMAND_MEM_INIT) != 0) {
4694			BCE_PRINTF("%s(): Context memory initialization failed!\n",
4695			    __FUNCTION__);
4696			rc = EBUSY;
4697			goto init_ctx_fail;
4698		}
4699
4700		for (i = 0; i < sc->ctx_pages; i++) {
4701			/* Set the physical address of the context memory. */
4702			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA0,
4703			    BCE_ADDR_LO(sc->ctx_paddr[i] & 0xfffffff0) |
4704			    BCE_CTX_HOST_PAGE_TBL_DATA0_VALID);
4705			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA1,
4706			    BCE_ADDR_HI(sc->ctx_paddr[i]));
4707			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_CTRL, i |
4708			    BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
4709
4710			/* Verify the context memory write was successful. */
4711			for (j = 0; j < retry_cnt; j++) {
4712				val = REG_RD(sc, BCE_CTX_HOST_PAGE_TBL_CTRL);
4713				if ((val &
4714				    BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) == 0)
4715					break;
4716				DELAY(5);
4717			}
4718			if ((val & BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) != 0) {
4719				BCE_PRINTF("%s(): Failed to initialize "
4720				    "context page %d!\n", __FUNCTION__, i);
4721				rc = EBUSY;
4722				goto init_ctx_fail;
4723			}
4724		}
4725	} else {
4726		DBPRINT(sc, BCE_INFO, "Initializing 5706/5708 context.\n");
4727
4728		/*
4729		 * For the 5706/5708, context memory is local to
4730		 * the controller, so initialize the controller
4731		 * context memory.
4732		 */
4733
4734		vcid_addr = GET_CID_ADDR(96);
4735		while (vcid_addr) {
4736			vcid_addr -= PHY_CTX_SIZE;
4737
4738			REG_WR(sc, BCE_CTX_VIRT_ADDR, 0);
4739			REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
4740
4741			for(offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
4742				CTX_WR(sc, 0x00, offset, 0);
4743			}
4744
4745			REG_WR(sc, BCE_CTX_VIRT_ADDR, vcid_addr);
4746			REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
4747		}
4748	}
4749init_ctx_fail:
4750	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
4751	return (rc);
4752}
4753
4754/****************************************************************************/
4755/* Fetch the permanent MAC address of the controller.                       */
4756/*                                                                          */
4757/* Returns:                                                                 */
4758/*   Nothing.                                                               */
4759/****************************************************************************/
4760static void
4761bce_get_mac_addr(struct bce_softc *sc)
4762{
4763	u32 mac_lo = 0, mac_hi = 0;
4764
4765	DBENTER(BCE_VERBOSE_RESET);
4766
4767	/*
4768	 * The NetXtreme II bootcode populates various NIC
4769	 * power-on and runtime configuration items in a
4770	 * shared memory area.  The factory configured MAC
4771	 * address is available from both NVRAM and the
4772	 * shared memory area so we'll read the value from
4773	 * shared memory for speed.
4774	 */
4775
4776	mac_hi = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_UPPER);
4777	mac_lo = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_LOWER);
4778
4779	if ((mac_lo == 0) && (mac_hi == 0)) {
4780		BCE_PRINTF("%s(%d): Invalid Ethernet address!\n",
4781		    __FILE__, __LINE__);
4782	} else {
4783		sc->eaddr[0] = (u_char)(mac_hi >> 8);
4784		sc->eaddr[1] = (u_char)(mac_hi >> 0);
4785		sc->eaddr[2] = (u_char)(mac_lo >> 24);
4786		sc->eaddr[3] = (u_char)(mac_lo >> 16);
4787		sc->eaddr[4] = (u_char)(mac_lo >> 8);
4788		sc->eaddr[5] = (u_char)(mac_lo >> 0);
4789	}
4790
4791	DBPRINT(sc, BCE_INFO_MISC, "Permanent Ethernet "
4792	    "address = %6D\n", sc->eaddr, ":");
4793	DBEXIT(BCE_VERBOSE_RESET);
4794}
4795
4796/****************************************************************************/
4797/* Program the MAC address.                                                 */
4798/*                                                                          */
4799/* Returns:                                                                 */
4800/*   Nothing.                                                               */
4801/****************************************************************************/
4802static void
4803bce_set_mac_addr(struct bce_softc *sc)
4804{
4805	u32 val;
4806	u8 *mac_addr = sc->eaddr;
4807
4808	/* ToDo: Add support for setting multiple MAC addresses. */
4809
4810	DBENTER(BCE_VERBOSE_RESET);
4811	DBPRINT(sc, BCE_INFO_MISC, "Setting Ethernet address = "
4812	    "%6D\n", sc->eaddr, ":");
4813
4814	val = (mac_addr[0] << 8) | mac_addr[1];
4815
4816	REG_WR(sc, BCE_EMAC_MAC_MATCH0, val);
4817
4818	val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
4819	    (mac_addr[4] << 8) | mac_addr[5];
4820
4821	REG_WR(sc, BCE_EMAC_MAC_MATCH1, val);
4822
4823	DBEXIT(BCE_VERBOSE_RESET);
4824}
4825
4826/****************************************************************************/
4827/* Stop the controller.                                                     */
4828/*                                                                          */
4829/* Returns:                                                                 */
4830/*   Nothing.                                                               */
4831/****************************************************************************/
4832static void
4833bce_stop(struct bce_softc *sc)
4834{
4835	if_t ifp;
4836
4837	DBENTER(BCE_VERBOSE_RESET);
4838
4839	BCE_LOCK_ASSERT(sc);
4840
4841	ifp = sc->bce_ifp;
4842
4843	callout_stop(&sc->bce_tick_callout);
4844
4845	/* Disable the transmit/receive blocks. */
4846	REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS, BCE_MISC_ENABLE_CLR_DEFAULT);
4847	REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
4848	DELAY(20);
4849
4850	bce_disable_intr(sc);
4851
4852	/* Free RX buffers. */
4853	if (bce_hdr_split == TRUE) {
4854		bce_free_pg_chain(sc);
4855	}
4856	bce_free_rx_chain(sc);
4857
4858	/* Free TX buffers. */
4859	bce_free_tx_chain(sc);
4860
4861	sc->watchdog_timer = 0;
4862
4863	sc->bce_link_up = FALSE;
4864
4865	if_setdrvflagbits(ifp, 0, (IFF_DRV_RUNNING | IFF_DRV_OACTIVE));
4866
4867	DBEXIT(BCE_VERBOSE_RESET);
4868}
4869
4870static int
4871bce_reset(struct bce_softc *sc, u32 reset_code)
4872{
4873	u32 emac_mode_save, val;
4874	int i, rc = 0;
4875	static const u32 emac_mode_mask = BCE_EMAC_MODE_PORT |
4876	    BCE_EMAC_MODE_HALF_DUPLEX | BCE_EMAC_MODE_25G;
4877
4878	DBENTER(BCE_VERBOSE_RESET);
4879
4880	DBPRINT(sc, BCE_VERBOSE_RESET, "%s(): reset_code = 0x%08X\n",
4881	    __FUNCTION__, reset_code);
4882
4883	/*
4884	 * If ASF/IPMI is operational, then the EMAC Mode register already
4885	 * contains appropriate values for the link settings that have
4886	 * been auto-negotiated.  Resetting the chip will clobber those
4887	 * values.  Save the important bits so we can restore them after
4888	 * the reset.
4889	 */
4890	emac_mode_save = REG_RD(sc, BCE_EMAC_MODE) & emac_mode_mask;
4891
4892	/* Wait for pending PCI transactions to complete. */
4893	REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS,
4894	    BCE_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
4895	    BCE_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
4896	    BCE_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
4897	    BCE_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
4898	val = REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
4899	DELAY(5);
4900
4901	/* Disable DMA */
4902	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4903		val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
4904		val &= ~BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
4905		REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
4906	}
4907
4908	/* Assume bootcode is running. */
4909	sc->bce_fw_timed_out = FALSE;
4910	sc->bce_drv_cardiac_arrest = FALSE;
4911
4912	/* Give the firmware a chance to prepare for the reset. */
4913	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT0 | reset_code);
4914	if (rc)
4915		goto bce_reset_exit;
4916
4917	/* Set a firmware reminder that this is a soft reset. */
4918	bce_shmem_wr(sc, BCE_DRV_RESET_SIGNATURE, BCE_DRV_RESET_SIGNATURE_MAGIC);
4919
4920	/* Dummy read to force the chip to complete all current transactions. */
4921	val = REG_RD(sc, BCE_MISC_ID);
4922
4923	/* Chip reset. */
4924	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4925		REG_WR(sc, BCE_MISC_COMMAND, BCE_MISC_COMMAND_SW_RESET);
4926		REG_RD(sc, BCE_MISC_COMMAND);
4927		DELAY(5);
4928
4929		val = BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
4930		    BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
4931
4932		pci_write_config(sc->bce_dev, BCE_PCICFG_MISC_CONFIG, val, 4);
4933	} else {
4934		val = BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4935		    BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
4936		    BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
4937		REG_WR(sc, BCE_PCICFG_MISC_CONFIG, val);
4938
4939		/* Allow up to 30us for reset to complete. */
4940		for (i = 0; i < 10; i++) {
4941			val = REG_RD(sc, BCE_PCICFG_MISC_CONFIG);
4942			if ((val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4943			    BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
4944				break;
4945			}
4946			DELAY(10);
4947		}
4948
4949		/* Check that reset completed successfully. */
4950		if (val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
4951		    BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
4952			BCE_PRINTF("%s(%d): Reset failed!\n",
4953			    __FILE__, __LINE__);
4954			rc = EBUSY;
4955			goto bce_reset_exit;
4956		}
4957	}
4958
4959	/* Make sure byte swapping is properly configured. */
4960	val = REG_RD(sc, BCE_PCI_SWAP_DIAG0);
4961	if (val != 0x01020304) {
4962		BCE_PRINTF("%s(%d): Byte swap is incorrect!\n",
4963		    __FILE__, __LINE__);
4964		rc = ENODEV;
4965		goto bce_reset_exit;
4966	}
4967
4968	/* Just completed a reset, assume that firmware is running again. */
4969	sc->bce_fw_timed_out = FALSE;
4970	sc->bce_drv_cardiac_arrest = FALSE;
4971
4972	/* Wait for the firmware to finish its initialization. */
4973	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT1 | reset_code);
4974	if (rc)
4975		BCE_PRINTF("%s(%d): Firmware did not complete "
4976		    "initialization!\n", __FILE__, __LINE__);
4977	/* Get firmware capabilities. */
4978	bce_fw_cap_init(sc);
4979
4980bce_reset_exit:
4981	/* Restore EMAC Mode bits needed to keep ASF/IPMI running. */
4982	if (reset_code == BCE_DRV_MSG_CODE_RESET) {
4983		val = REG_RD(sc, BCE_EMAC_MODE);
4984		val = (val & ~emac_mode_mask) | emac_mode_save;
4985		REG_WR(sc, BCE_EMAC_MODE, val);
4986	}
4987
4988	DBEXIT(BCE_VERBOSE_RESET);
4989	return (rc);
4990}
4991
4992static int
4993bce_chipinit(struct bce_softc *sc)
4994{
4995	u32 val;
4996	int rc = 0;
4997
4998	DBENTER(BCE_VERBOSE_RESET);
4999
5000	bce_disable_intr(sc);
5001
5002	/*
5003	 * Initialize DMA byte/word swapping, configure the number of DMA
5004	 * channels and PCI clock compensation delay.
5005	 */
5006	val = BCE_DMA_CONFIG_DATA_BYTE_SWAP |
5007	    BCE_DMA_CONFIG_DATA_WORD_SWAP |
5008#if BYTE_ORDER == BIG_ENDIAN
5009	    BCE_DMA_CONFIG_CNTL_BYTE_SWAP |
5010#endif
5011	    BCE_DMA_CONFIG_CNTL_WORD_SWAP |
5012	    DMA_READ_CHANS << 12 |
5013	    DMA_WRITE_CHANS << 16;
5014
5015	val |= (0x2 << 20) | BCE_DMA_CONFIG_CNTL_PCI_COMP_DLY;
5016
5017	if ((sc->bce_flags & BCE_PCIX_FLAG) && (sc->bus_speed_mhz == 133))
5018		val |= BCE_DMA_CONFIG_PCI_FAST_CLK_CMP;
5019
5020	/*
5021	 * This setting resolves a problem observed on certain Intel PCI
5022	 * chipsets that cannot handle multiple outstanding DMA operations.
5023	 * See errata E9_5706A1_65.
5024	 */
5025	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
5026	    (BCE_CHIP_ID(sc) != BCE_CHIP_ID_5706_A0) &&
5027	    !(sc->bce_flags & BCE_PCIX_FLAG))
5028		val |= BCE_DMA_CONFIG_CNTL_PING_PONG_DMA;
5029
5030	REG_WR(sc, BCE_DMA_CONFIG, val);
5031
5032	/* Enable the RX_V2P and Context state machines before access. */
5033	REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
5034	    BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
5035	    BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
5036	    BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
5037
5038	/* Initialize context mapping and zero out the quick contexts. */
5039	if ((rc = bce_init_ctx(sc)) != 0)
5040		goto bce_chipinit_exit;
5041
5042	/* Initialize the on-boards CPUs */
5043	bce_init_cpus(sc);
5044
5045	/* Enable management frames (NC-SI) to flow to the MCP. */
5046	if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
5047		val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) | BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
5048		REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
5049	}
5050
5051	/* Prepare NVRAM for access. */
5052	if ((rc = bce_init_nvram(sc)) != 0)
5053		goto bce_chipinit_exit;
5054
5055	/* Set the kernel bypass block size */
5056	val = REG_RD(sc, BCE_MQ_CONFIG);
5057	val &= ~BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE;
5058	val |= BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
5059
5060	/* Enable bins used on the 5709. */
5061	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5062		val |= BCE_MQ_CONFIG_BIN_MQ_MODE;
5063		if (BCE_CHIP_ID(sc) == BCE_CHIP_ID_5709_A1)
5064			val |= BCE_MQ_CONFIG_HALT_DIS;
5065	}
5066
5067	REG_WR(sc, BCE_MQ_CONFIG, val);
5068
5069	val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
5070	REG_WR(sc, BCE_MQ_KNL_BYP_WIND_START, val);
5071	REG_WR(sc, BCE_MQ_KNL_WIND_END, val);
5072
5073	/* Set the page size and clear the RV2P processor stall bits. */
5074	val = (BCM_PAGE_BITS - 8) << 24;
5075	REG_WR(sc, BCE_RV2P_CONFIG, val);
5076
5077	/* Configure page size. */
5078	val = REG_RD(sc, BCE_TBDR_CONFIG);
5079	val &= ~BCE_TBDR_CONFIG_PAGE_SIZE;
5080	val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
5081	REG_WR(sc, BCE_TBDR_CONFIG, val);
5082
5083	/* Set the perfect match control register to default. */
5084	REG_WR_IND(sc, BCE_RXP_PM_CTRL, 0);
5085
5086bce_chipinit_exit:
5087	DBEXIT(BCE_VERBOSE_RESET);
5088
5089	return(rc);
5090}
5091
5092/****************************************************************************/
5093/* Initialize the controller in preparation to send/receive traffic.        */
5094/*                                                                          */
5095/* Returns:                                                                 */
5096/*   0 for success, positive value for failure.                             */
5097/****************************************************************************/
5098static int
5099bce_blockinit(struct bce_softc *sc)
5100{
5101	u32 reg, val;
5102	int rc = 0;
5103
5104	DBENTER(BCE_VERBOSE_RESET);
5105
5106	/* Load the hardware default MAC address. */
5107	bce_set_mac_addr(sc);
5108
5109	/* Set the Ethernet backoff seed value */
5110	val = sc->eaddr[0]         + (sc->eaddr[1] << 8) +
5111	      (sc->eaddr[2] << 16) + (sc->eaddr[3]     ) +
5112	      (sc->eaddr[4] << 8)  + (sc->eaddr[5] << 16);
5113	REG_WR(sc, BCE_EMAC_BACKOFF_SEED, val);
5114
5115	sc->last_status_idx = 0;
5116	sc->rx_mode = BCE_EMAC_RX_MODE_SORT_MODE;
5117
5118	/* Set up link change interrupt generation. */
5119	REG_WR(sc, BCE_EMAC_ATTENTION_ENA, BCE_EMAC_ATTENTION_ENA_LINK);
5120
5121	/* Program the physical address of the status block. */
5122	REG_WR(sc, BCE_HC_STATUS_ADDR_L,
5123	    BCE_ADDR_LO(sc->status_block_paddr));
5124	REG_WR(sc, BCE_HC_STATUS_ADDR_H,
5125	    BCE_ADDR_HI(sc->status_block_paddr));
5126
5127	/* Program the physical address of the statistics block. */
5128	REG_WR(sc, BCE_HC_STATISTICS_ADDR_L,
5129	    BCE_ADDR_LO(sc->stats_block_paddr));
5130	REG_WR(sc, BCE_HC_STATISTICS_ADDR_H,
5131	    BCE_ADDR_HI(sc->stats_block_paddr));
5132
5133	/*
5134	 * Program various host coalescing parameters.
5135	 * Trip points control how many BDs should be ready before generating
5136	 * an interrupt while ticks control how long a BD can sit in the chain
5137	 * before generating an interrupt.
5138	 */
5139	REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
5140	    (sc->bce_tx_quick_cons_trip_int << 16) |
5141	    sc->bce_tx_quick_cons_trip);
5142	REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
5143	    (sc->bce_rx_quick_cons_trip_int << 16) |
5144	    sc->bce_rx_quick_cons_trip);
5145	REG_WR(sc, BCE_HC_TX_TICKS,
5146	    (sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
5147	REG_WR(sc, BCE_HC_RX_TICKS,
5148	    (sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
5149	REG_WR(sc, BCE_HC_STATS_TICKS, sc->bce_stats_ticks & 0xffff00);
5150	REG_WR(sc, BCE_HC_STAT_COLLECT_TICKS, 0xbb8);  /* 3ms */
5151	/* Not used for L2. */
5152	REG_WR(sc, BCE_HC_COMP_PROD_TRIP, 0);
5153	REG_WR(sc, BCE_HC_COM_TICKS, 0);
5154	REG_WR(sc, BCE_HC_CMD_TICKS, 0);
5155
5156	/* Configure the Host Coalescing block. */
5157	val = BCE_HC_CONFIG_RX_TMR_MODE | BCE_HC_CONFIG_TX_TMR_MODE |
5158	    BCE_HC_CONFIG_COLLECT_STATS;
5159
5160#if 0
5161	/* ToDo: Add MSI-X support. */
5162	if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
5163		u32 base = ((BCE_TX_VEC - 1) * BCE_HC_SB_CONFIG_SIZE) +
5164		    BCE_HC_SB_CONFIG_1;
5165
5166		REG_WR(sc, BCE_HC_MSIX_BIT_VECTOR, BCE_HC_MSIX_BIT_VECTOR_VAL);
5167
5168		REG_WR(sc, base, BCE_HC_SB_CONFIG_1_TX_TMR_MODE |
5169		    BCE_HC_SB_CONFIG_1_ONE_SHOT);
5170
5171		REG_WR(sc, base + BCE_HC_TX_QUICK_CONS_TRIP_OFF,
5172		    (sc->tx_quick_cons_trip_int << 16) |
5173		     sc->tx_quick_cons_trip);
5174
5175		REG_WR(sc, base + BCE_HC_TX_TICKS_OFF,
5176		    (sc->tx_ticks_int << 16) | sc->tx_ticks);
5177
5178		val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
5179	}
5180
5181	/*
5182	 * Tell the HC block to automatically set the
5183	 * INT_MASK bit after an MSI/MSI-X interrupt
5184	 * is generated so the driver doesn't have to.
5185	 */
5186	if (sc->bce_flags & BCE_ONE_SHOT_MSI_FLAG)
5187		val |= BCE_HC_CONFIG_ONE_SHOT;
5188
5189	/* Set the MSI-X status blocks to 128 byte boundaries. */
5190	if (sc->bce_flags & BCE_USING_MSIX_FLAG)
5191		val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
5192#endif
5193
5194	REG_WR(sc, BCE_HC_CONFIG, val);
5195
5196	/* Clear the internal statistics counters. */
5197	REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
5198
5199	/* Verify that bootcode is running. */
5200	reg = bce_shmem_rd(sc, BCE_DEV_INFO_SIGNATURE);
5201
5202	DBRUNIF(DB_RANDOMTRUE(bootcode_running_failure_sim_control),
5203	    BCE_PRINTF("%s(%d): Simulating bootcode failure.\n",
5204	    __FILE__, __LINE__);
5205	    reg = 0);
5206
5207	if ((reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
5208	    BCE_DEV_INFO_SIGNATURE_MAGIC) {
5209		BCE_PRINTF("%s(%d): Bootcode not running! Found: 0x%08X, "
5210		    "Expected: 08%08X\n", __FILE__, __LINE__,
5211		    (reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK),
5212		    BCE_DEV_INFO_SIGNATURE_MAGIC);
5213		rc = ENODEV;
5214		goto bce_blockinit_exit;
5215	}
5216
5217	/* Enable DMA */
5218	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5219		val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
5220		val |= BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
5221		REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
5222	}
5223
5224	/* Allow bootcode to apply additional fixes before enabling MAC. */
5225	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 |
5226	    BCE_DRV_MSG_CODE_RESET);
5227
5228	/* Enable link state change interrupt generation. */
5229	REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
5230
5231	/* Enable the RXP. */
5232	bce_start_rxp_cpu(sc);
5233
5234	/* Disable management frames (NC-SI) from flowing to the MCP. */
5235	if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
5236		val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) &
5237		    ~BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
5238		REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
5239	}
5240
5241	/* Enable all remaining blocks in the MAC. */
5242	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
5243		REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
5244		    BCE_MISC_ENABLE_DEFAULT_XI);
5245	else
5246		REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
5247		    BCE_MISC_ENABLE_DEFAULT);
5248
5249	REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
5250	DELAY(20);
5251
5252	/* Save the current host coalescing block settings. */
5253	sc->hc_command = REG_RD(sc, BCE_HC_COMMAND);
5254
5255bce_blockinit_exit:
5256	DBEXIT(BCE_VERBOSE_RESET);
5257
5258	return (rc);
5259}
5260
5261/****************************************************************************/
5262/* Encapsulate an mbuf into the rx_bd chain.                                */
5263/*                                                                          */
5264/* Returns:                                                                 */
5265/*   0 for success, positive value for failure.                             */
5266/****************************************************************************/
5267static int
5268bce_get_rx_buf(struct bce_softc *sc, u16 prod, u16 chain_prod, u32 *prod_bseq)
5269{
5270	bus_dma_segment_t segs[1];
5271	struct mbuf *m_new = NULL;
5272	struct rx_bd *rxbd;
5273	int nsegs, error, rc = 0;
5274#ifdef BCE_DEBUG
5275	u16 debug_chain_prod = chain_prod;
5276#endif
5277
5278	DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5279
5280	/* Make sure the inputs are valid. */
5281	DBRUNIF((chain_prod > MAX_RX_BD_ALLOC),
5282	    BCE_PRINTF("%s(%d): RX producer out of range: "
5283	    "0x%04X > 0x%04X\n", __FILE__, __LINE__,
5284	    chain_prod, (u16)MAX_RX_BD_ALLOC));
5285
5286	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
5287	    "chain_prod = 0x%04X, prod_bseq = 0x%08X\n", __FUNCTION__,
5288	    prod, chain_prod, *prod_bseq);
5289
5290	/* Update some debug statistic counters */
5291	DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
5292	    sc->rx_low_watermark = sc->free_rx_bd);
5293	DBRUNIF((sc->free_rx_bd == sc->max_rx_bd),
5294	    sc->rx_empty_count++);
5295
5296	/* Simulate an mbuf allocation failure. */
5297	DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
5298	    sc->mbuf_alloc_failed_count++;
5299	    sc->mbuf_alloc_failed_sim_count++;
5300	    rc = ENOBUFS;
5301	    goto bce_get_rx_buf_exit);
5302
5303	/* This is a new mbuf allocation. */
5304	if (bce_hdr_split == TRUE)
5305		MGETHDR(m_new, M_NOWAIT, MT_DATA);
5306	else
5307		m_new = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR,
5308		    sc->rx_bd_mbuf_alloc_size);
5309
5310	if (m_new == NULL) {
5311		sc->mbuf_alloc_failed_count++;
5312		rc = ENOBUFS;
5313		goto bce_get_rx_buf_exit;
5314	}
5315
5316	DBRUN(sc->debug_rx_mbuf_alloc++);
5317
5318	/* Make sure we have a valid packet header. */
5319	M_ASSERTPKTHDR(m_new);
5320
5321	/* Initialize the mbuf size and pad if necessary for alignment. */
5322	m_new->m_pkthdr.len = m_new->m_len = sc->rx_bd_mbuf_alloc_size;
5323	m_adj(m_new, sc->rx_bd_mbuf_align_pad);
5324
5325	/* ToDo: Consider calling m_fragment() to test error handling. */
5326
5327	/* Map the mbuf cluster into device memory. */
5328	error = bus_dmamap_load_mbuf_sg(sc->rx_mbuf_tag,
5329	    sc->rx_mbuf_map[chain_prod], m_new, segs, &nsegs, BUS_DMA_NOWAIT);
5330
5331	/* Handle any mapping errors. */
5332	if (error) {
5333		BCE_PRINTF("%s(%d): Error mapping mbuf into RX "
5334		    "chain (%d)!\n", __FILE__, __LINE__, error);
5335
5336		sc->dma_map_addr_rx_failed_count++;
5337		m_freem(m_new);
5338
5339		DBRUN(sc->debug_rx_mbuf_alloc--);
5340
5341		rc = ENOBUFS;
5342		goto bce_get_rx_buf_exit;
5343	}
5344
5345	/* All mbufs must map to a single segment. */
5346	KASSERT(nsegs == 1, ("%s(): Too many segments returned (%d)!",
5347	    __FUNCTION__, nsegs));
5348
5349	/* Setup the rx_bd for the segment. */
5350	rxbd = &sc->rx_bd_chain[RX_PAGE(chain_prod)][RX_IDX(chain_prod)];
5351
5352	rxbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(segs[0].ds_addr));
5353	rxbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(segs[0].ds_addr));
5354	rxbd->rx_bd_len       = htole32(segs[0].ds_len);
5355	rxbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
5356	*prod_bseq += segs[0].ds_len;
5357
5358	/* Save the mbuf and update our counter. */
5359	sc->rx_mbuf_ptr[chain_prod] = m_new;
5360	sc->free_rx_bd -= nsegs;
5361
5362	DBRUNMSG(BCE_INSANE_RECV,
5363	    bce_dump_rx_mbuf_chain(sc, debug_chain_prod, nsegs));
5364
5365	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
5366	    "chain_prod = 0x%04X, prod_bseq = 0x%08X\n", __FUNCTION__, prod,
5367	    chain_prod, *prod_bseq);
5368
5369bce_get_rx_buf_exit:
5370	DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5371
5372	return(rc);
5373}
5374
5375/****************************************************************************/
5376/* Encapsulate an mbuf cluster into the page chain.                         */
5377/*                                                                          */
5378/* Returns:                                                                 */
5379/*   0 for success, positive value for failure.                             */
5380/****************************************************************************/
5381static int
5382bce_get_pg_buf(struct bce_softc *sc, u16 prod, u16 prod_idx)
5383{
5384	bus_dma_segment_t segs[1];
5385	struct mbuf *m_new = NULL;
5386	struct rx_bd *pgbd;
5387	int error, nsegs, rc = 0;
5388#ifdef BCE_DEBUG
5389	u16 debug_prod_idx = prod_idx;
5390#endif
5391
5392	DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5393
5394	/* Make sure the inputs are valid. */
5395	DBRUNIF((prod_idx > MAX_PG_BD_ALLOC),
5396	    BCE_PRINTF("%s(%d): page producer out of range: "
5397	    "0x%04X > 0x%04X\n", __FILE__, __LINE__,
5398	    prod_idx, (u16)MAX_PG_BD_ALLOC));
5399
5400	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
5401	    "chain_prod = 0x%04X\n", __FUNCTION__, prod, prod_idx);
5402
5403	/* Update counters if we've hit a new low or run out of pages. */
5404	DBRUNIF((sc->free_pg_bd < sc->pg_low_watermark),
5405	    sc->pg_low_watermark = sc->free_pg_bd);
5406	DBRUNIF((sc->free_pg_bd == sc->max_pg_bd), sc->pg_empty_count++);
5407
5408	/* Simulate an mbuf allocation failure. */
5409	DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
5410	    sc->mbuf_alloc_failed_count++;
5411	    sc->mbuf_alloc_failed_sim_count++;
5412	    rc = ENOBUFS;
5413	    goto bce_get_pg_buf_exit);
5414
5415	/* This is a new mbuf allocation. */
5416	m_new = m_getcl(M_NOWAIT, MT_DATA, 0);
5417	if (m_new == NULL) {
5418		sc->mbuf_alloc_failed_count++;
5419		rc = ENOBUFS;
5420		goto bce_get_pg_buf_exit;
5421	}
5422
5423	DBRUN(sc->debug_pg_mbuf_alloc++);
5424
5425	m_new->m_len = MCLBYTES;
5426
5427	/* ToDo: Consider calling m_fragment() to test error handling. */
5428
5429	/* Map the mbuf cluster into device memory. */
5430	error = bus_dmamap_load_mbuf_sg(sc->pg_mbuf_tag,
5431	    sc->pg_mbuf_map[prod_idx], m_new, segs, &nsegs, BUS_DMA_NOWAIT);
5432
5433	/* Handle any mapping errors. */
5434	if (error) {
5435		BCE_PRINTF("%s(%d): Error mapping mbuf into page chain!\n",
5436		    __FILE__, __LINE__);
5437
5438		m_freem(m_new);
5439		DBRUN(sc->debug_pg_mbuf_alloc--);
5440
5441		rc = ENOBUFS;
5442		goto bce_get_pg_buf_exit;
5443	}
5444
5445	/* All mbufs must map to a single segment. */
5446	KASSERT(nsegs == 1, ("%s(): Too many segments returned (%d)!",
5447	    __FUNCTION__, nsegs));
5448
5449	/* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREREAD) here? */
5450
5451	/*
5452	 * The page chain uses the same rx_bd data structure
5453	 * as the receive chain but doesn't require a byte sequence (bseq).
5454	 */
5455	pgbd = &sc->pg_bd_chain[PG_PAGE(prod_idx)][PG_IDX(prod_idx)];
5456
5457	pgbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(segs[0].ds_addr));
5458	pgbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(segs[0].ds_addr));
5459	pgbd->rx_bd_len       = htole32(MCLBYTES);
5460	pgbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
5461
5462	/* Save the mbuf and update our counter. */
5463	sc->pg_mbuf_ptr[prod_idx] = m_new;
5464	sc->free_pg_bd--;
5465
5466	DBRUNMSG(BCE_INSANE_RECV,
5467	    bce_dump_pg_mbuf_chain(sc, debug_prod_idx, 1));
5468
5469	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
5470	    "prod_idx = 0x%04X\n", __FUNCTION__, prod, prod_idx);
5471
5472bce_get_pg_buf_exit:
5473	DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5474
5475	return(rc);
5476}
5477
5478/****************************************************************************/
5479/* Initialize the TX context memory.                                        */
5480/*                                                                          */
5481/* Returns:                                                                 */
5482/*   Nothing                                                                */
5483/****************************************************************************/
5484static void
5485bce_init_tx_context(struct bce_softc *sc)
5486{
5487	u32 val;
5488
5489	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
5490
5491	/* Initialize the context ID for an L2 TX chain. */
5492	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5493		/* Set the CID type to support an L2 connection. */
5494		val = BCE_L2CTX_TX_TYPE_TYPE_L2_XI |
5495		    BCE_L2CTX_TX_TYPE_SIZE_L2_XI;
5496		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE_XI, val);
5497		val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2_XI | (8 << 16);
5498		CTX_WR(sc, GET_CID_ADDR(TX_CID),
5499		    BCE_L2CTX_TX_CMD_TYPE_XI, val);
5500
5501		/* Point the hardware to the first page in the chain. */
5502		val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
5503		CTX_WR(sc, GET_CID_ADDR(TX_CID),
5504		    BCE_L2CTX_TX_TBDR_BHADDR_HI_XI, val);
5505		val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
5506		CTX_WR(sc, GET_CID_ADDR(TX_CID),
5507		    BCE_L2CTX_TX_TBDR_BHADDR_LO_XI, val);
5508	} else {
5509		/* Set the CID type to support an L2 connection. */
5510		val = BCE_L2CTX_TX_TYPE_TYPE_L2 | BCE_L2CTX_TX_TYPE_SIZE_L2;
5511		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE, val);
5512		val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2 | (8 << 16);
5513		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_CMD_TYPE, val);
5514
5515		/* Point the hardware to the first page in the chain. */
5516		val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
5517		CTX_WR(sc, GET_CID_ADDR(TX_CID),
5518		    BCE_L2CTX_TX_TBDR_BHADDR_HI, val);
5519		val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
5520		CTX_WR(sc, GET_CID_ADDR(TX_CID),
5521		    BCE_L2CTX_TX_TBDR_BHADDR_LO, val);
5522	}
5523
5524	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
5525}
5526
5527/****************************************************************************/
5528/* Allocate memory and initialize the TX data structures.                   */
5529/*                                                                          */
5530/* Returns:                                                                 */
5531/*   0 for success, positive value for failure.                             */
5532/****************************************************************************/
5533static int
5534bce_init_tx_chain(struct bce_softc *sc)
5535{
5536	struct tx_bd *txbd;
5537	int i, rc = 0;
5538
5539	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
5540
5541	/* Set the initial TX producer/consumer indices. */
5542	sc->tx_prod        = 0;
5543	sc->tx_cons        = 0;
5544	sc->tx_prod_bseq   = 0;
5545	sc->used_tx_bd     = 0;
5546	sc->max_tx_bd      = USABLE_TX_BD_ALLOC;
5547	DBRUN(sc->tx_hi_watermark = 0);
5548	DBRUN(sc->tx_full_count = 0);
5549
5550	/*
5551	 * The NetXtreme II supports a linked-list structure called
5552	 * a Buffer Descriptor Chain (or BD chain).  A BD chain
5553	 * consists of a series of 1 or more chain pages, each of which
5554	 * consists of a fixed number of BD entries.
5555	 * The last BD entry on each page is a pointer to the next page
5556	 * in the chain, and the last pointer in the BD chain
5557	 * points back to the beginning of the chain.
5558	 */
5559
5560	/* Set the TX next pointer chain entries. */
5561	for (i = 0; i < sc->tx_pages; i++) {
5562		int j;
5563
5564		txbd = &sc->tx_bd_chain[i][USABLE_TX_BD_PER_PAGE];
5565
5566		/* Check if we've reached the last page. */
5567		if (i == (sc->tx_pages - 1))
5568			j = 0;
5569		else
5570			j = i + 1;
5571
5572		txbd->tx_bd_haddr_hi =
5573		    htole32(BCE_ADDR_HI(sc->tx_bd_chain_paddr[j]));
5574		txbd->tx_bd_haddr_lo =
5575		    htole32(BCE_ADDR_LO(sc->tx_bd_chain_paddr[j]));
5576	}
5577
5578	bce_init_tx_context(sc);
5579
5580	DBRUNMSG(BCE_INSANE_SEND, bce_dump_tx_chain(sc, 0, TOTAL_TX_BD_ALLOC));
5581	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
5582
5583	return(rc);
5584}
5585
5586/****************************************************************************/
5587/* Free memory and clear the TX data structures.                            */
5588/*                                                                          */
5589/* Returns:                                                                 */
5590/*   Nothing.                                                               */
5591/****************************************************************************/
5592static void
5593bce_free_tx_chain(struct bce_softc *sc)
5594{
5595	int i;
5596
5597	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
5598
5599	/* Unmap, unload, and free any mbufs still in the TX mbuf chain. */
5600	for (i = 0; i < MAX_TX_BD_AVAIL; i++) {
5601		if (sc->tx_mbuf_ptr[i] != NULL) {
5602			if (sc->tx_mbuf_map[i] != NULL)
5603				bus_dmamap_sync(sc->tx_mbuf_tag,
5604				    sc->tx_mbuf_map[i],
5605				    BUS_DMASYNC_POSTWRITE);
5606			m_freem(sc->tx_mbuf_ptr[i]);
5607			sc->tx_mbuf_ptr[i] = NULL;
5608			DBRUN(sc->debug_tx_mbuf_alloc--);
5609		}
5610	}
5611
5612	/* Clear each TX chain page. */
5613	for (i = 0; i < sc->tx_pages; i++)
5614		bzero((char *)sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ);
5615
5616	sc->used_tx_bd = 0;
5617
5618	/* Check if we lost any mbufs in the process. */
5619	DBRUNIF((sc->debug_tx_mbuf_alloc),
5620	    BCE_PRINTF("%s(%d): Memory leak! Lost %d mbufs "
5621	    "from tx chain!\n",	__FILE__, __LINE__,
5622	    sc->debug_tx_mbuf_alloc));
5623
5624	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
5625}
5626
5627/****************************************************************************/
5628/* Initialize the RX context memory.                                        */
5629/*                                                                          */
5630/* Returns:                                                                 */
5631/*   Nothing                                                                */
5632/****************************************************************************/
5633static void
5634bce_init_rx_context(struct bce_softc *sc)
5635{
5636	u32 val;
5637
5638	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
5639
5640	/* Init the type, size, and BD cache levels for the RX context. */
5641	val = BCE_L2CTX_RX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE |
5642	    BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 |
5643	    (0x02 << BCE_L2CTX_RX_BD_PRE_READ_SHIFT);
5644
5645	/*
5646	 * Set the level for generating pause frames
5647	 * when the number of available rx_bd's gets
5648	 * too low (the low watermark) and the level
5649	 * when pause frames can be stopped (the high
5650	 * watermark).
5651	 */
5652	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5653		u32 lo_water, hi_water;
5654
5655		if (sc->bce_flags & BCE_USING_TX_FLOW_CONTROL) {
5656			lo_water = BCE_L2CTX_RX_LO_WATER_MARK_DEFAULT;
5657		} else {
5658			lo_water = 0;
5659		}
5660
5661		if (lo_water >= USABLE_RX_BD_ALLOC) {
5662			lo_water = 0;
5663		}
5664
5665		hi_water = USABLE_RX_BD_ALLOC / 4;
5666
5667		if (hi_water <= lo_water) {
5668			lo_water = 0;
5669		}
5670
5671		lo_water /= BCE_L2CTX_RX_LO_WATER_MARK_SCALE;
5672		hi_water /= BCE_L2CTX_RX_HI_WATER_MARK_SCALE;
5673
5674		if (hi_water > 0xf)
5675			hi_water = 0xf;
5676		else if (hi_water == 0)
5677			lo_water = 0;
5678
5679		val |= (lo_water << BCE_L2CTX_RX_LO_WATER_MARK_SHIFT) |
5680		    (hi_water << BCE_L2CTX_RX_HI_WATER_MARK_SHIFT);
5681	}
5682
5683	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_CTX_TYPE, val);
5684
5685	/* Setup the MQ BIN mapping for l2_ctx_host_bseq. */
5686	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5687		val = REG_RD(sc, BCE_MQ_MAP_L2_5);
5688		REG_WR(sc, BCE_MQ_MAP_L2_5, val | BCE_MQ_MAP_L2_5_ARM);
5689	}
5690
5691	/* Point the hardware to the first page in the chain. */
5692	val = BCE_ADDR_HI(sc->rx_bd_chain_paddr[0]);
5693	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_HI, val);
5694	val = BCE_ADDR_LO(sc->rx_bd_chain_paddr[0]);
5695	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_LO, val);
5696
5697	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
5698}
5699
5700/****************************************************************************/
5701/* Allocate memory and initialize the RX data structures.                   */
5702/*                                                                          */
5703/* Returns:                                                                 */
5704/*   0 for success, positive value for failure.                             */
5705/****************************************************************************/
5706static int
5707bce_init_rx_chain(struct bce_softc *sc)
5708{
5709	struct rx_bd *rxbd;
5710	int i, rc = 0;
5711
5712	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5713	    BCE_VERBOSE_CTX);
5714
5715	/* Initialize the RX producer and consumer indices. */
5716	sc->rx_prod        = 0;
5717	sc->rx_cons        = 0;
5718	sc->rx_prod_bseq   = 0;
5719	sc->free_rx_bd     = USABLE_RX_BD_ALLOC;
5720	sc->max_rx_bd      = USABLE_RX_BD_ALLOC;
5721
5722	/* Initialize the RX next pointer chain entries. */
5723	for (i = 0; i < sc->rx_pages; i++) {
5724		int j;
5725
5726		rxbd = &sc->rx_bd_chain[i][USABLE_RX_BD_PER_PAGE];
5727
5728		/* Check if we've reached the last page. */
5729		if (i == (sc->rx_pages - 1))
5730			j = 0;
5731		else
5732			j = i + 1;
5733
5734		/* Setup the chain page pointers. */
5735		rxbd->rx_bd_haddr_hi =
5736		    htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j]));
5737		rxbd->rx_bd_haddr_lo =
5738		    htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j]));
5739	}
5740
5741	/* Fill up the RX chain. */
5742	bce_fill_rx_chain(sc);
5743
5744	DBRUN(sc->rx_low_watermark = USABLE_RX_BD_ALLOC);
5745	DBRUN(sc->rx_empty_count = 0);
5746	for (i = 0; i < sc->rx_pages; i++) {
5747		bus_dmamap_sync(sc->rx_bd_chain_tag, sc->rx_bd_chain_map[i],
5748		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
5749	}
5750
5751	bce_init_rx_context(sc);
5752
5753	DBRUNMSG(BCE_EXTREME_RECV,
5754	    bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD_ALLOC));
5755	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5756	    BCE_VERBOSE_CTX);
5757
5758	/* ToDo: Are there possible failure modes here? */
5759
5760	return(rc);
5761}
5762
5763/****************************************************************************/
5764/* Add mbufs to the RX chain until its full or an mbuf allocation error     */
5765/* occurs.                                                                  */
5766/*                                                                          */
5767/* Returns:                                                                 */
5768/*   Nothing                                                                */
5769/****************************************************************************/
5770static void
5771bce_fill_rx_chain(struct bce_softc *sc)
5772{
5773	u16 prod, prod_idx;
5774	u32 prod_bseq;
5775
5776	DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5777	    BCE_VERBOSE_CTX);
5778
5779	/* Get the RX chain producer indices. */
5780	prod      = sc->rx_prod;
5781	prod_bseq = sc->rx_prod_bseq;
5782
5783	/* Keep filling the RX chain until it's full. */
5784	while (sc->free_rx_bd > 0) {
5785		prod_idx = RX_CHAIN_IDX(prod);
5786		if (bce_get_rx_buf(sc, prod, prod_idx, &prod_bseq)) {
5787			/* Bail out if we can't add an mbuf to the chain. */
5788			break;
5789		}
5790		prod = NEXT_RX_BD(prod);
5791	}
5792
5793	/* Save the RX chain producer indices. */
5794	sc->rx_prod      = prod;
5795	sc->rx_prod_bseq = prod_bseq;
5796
5797	/* We should never end up pointing to a next page pointer. */
5798	DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
5799	    BCE_PRINTF("%s(): Invalid rx_prod value: 0x%04X\n",
5800	    __FUNCTION__, rx_prod));
5801
5802	/* Write the mailbox and tell the chip about the waiting rx_bd's. */
5803	REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BDIDX, prod);
5804	REG_WR(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BSEQ, prod_bseq);
5805
5806	DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5807	    BCE_VERBOSE_CTX);
5808}
5809
5810/****************************************************************************/
5811/* Free memory and clear the RX data structures.                            */
5812/*                                                                          */
5813/* Returns:                                                                 */
5814/*   Nothing.                                                               */
5815/****************************************************************************/
5816static void
5817bce_free_rx_chain(struct bce_softc *sc)
5818{
5819	int i;
5820
5821	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5822
5823	/* Free any mbufs still in the RX mbuf chain. */
5824	for (i = 0; i < MAX_RX_BD_AVAIL; i++) {
5825		if (sc->rx_mbuf_ptr[i] != NULL) {
5826			if (sc->rx_mbuf_map[i] != NULL)
5827				bus_dmamap_sync(sc->rx_mbuf_tag,
5828				    sc->rx_mbuf_map[i],
5829				    BUS_DMASYNC_POSTREAD);
5830			m_freem(sc->rx_mbuf_ptr[i]);
5831			sc->rx_mbuf_ptr[i] = NULL;
5832			DBRUN(sc->debug_rx_mbuf_alloc--);
5833		}
5834	}
5835
5836	/* Clear each RX chain page. */
5837	for (i = 0; i < sc->rx_pages; i++)
5838		if (sc->rx_bd_chain[i] != NULL)
5839			bzero((char *)sc->rx_bd_chain[i],
5840			    BCE_RX_CHAIN_PAGE_SZ);
5841
5842	sc->free_rx_bd = sc->max_rx_bd;
5843
5844	/* Check if we lost any mbufs in the process. */
5845	DBRUNIF((sc->debug_rx_mbuf_alloc),
5846	    BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from rx chain!\n",
5847	    __FUNCTION__, sc->debug_rx_mbuf_alloc));
5848
5849	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5850}
5851
5852/****************************************************************************/
5853/* Allocate memory and initialize the page data structures.                 */
5854/* Assumes that bce_init_rx_chain() has not already been called.            */
5855/*                                                                          */
5856/* Returns:                                                                 */
5857/*   0 for success, positive value for failure.                             */
5858/****************************************************************************/
5859static int
5860bce_init_pg_chain(struct bce_softc *sc)
5861{
5862	struct rx_bd *pgbd;
5863	int i, rc = 0;
5864	u32 val;
5865
5866	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5867		BCE_VERBOSE_CTX);
5868
5869	/* Initialize the page producer and consumer indices. */
5870	sc->pg_prod        = 0;
5871	sc->pg_cons        = 0;
5872	sc->free_pg_bd     = USABLE_PG_BD_ALLOC;
5873	sc->max_pg_bd      = USABLE_PG_BD_ALLOC;
5874	DBRUN(sc->pg_low_watermark = sc->max_pg_bd);
5875	DBRUN(sc->pg_empty_count = 0);
5876
5877	/* Initialize the page next pointer chain entries. */
5878	for (i = 0; i < sc->pg_pages; i++) {
5879		int j;
5880
5881		pgbd = &sc->pg_bd_chain[i][USABLE_PG_BD_PER_PAGE];
5882
5883		/* Check if we've reached the last page. */
5884		if (i == (sc->pg_pages - 1))
5885			j = 0;
5886		else
5887			j = i + 1;
5888
5889		/* Setup the chain page pointers. */
5890		pgbd->rx_bd_haddr_hi =
5891		    htole32(BCE_ADDR_HI(sc->pg_bd_chain_paddr[j]));
5892		pgbd->rx_bd_haddr_lo =
5893		    htole32(BCE_ADDR_LO(sc->pg_bd_chain_paddr[j]));
5894	}
5895
5896	/* Setup the MQ BIN mapping for host_pg_bidx. */
5897	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
5898		REG_WR(sc, BCE_MQ_MAP_L2_3, BCE_MQ_MAP_L2_3_DEFAULT);
5899
5900	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, 0);
5901
5902	/* Configure the rx_bd and page chain mbuf cluster size. */
5903	val = (sc->rx_bd_mbuf_data_len << 16) | MCLBYTES;
5904	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, val);
5905
5906	/* Configure the context reserved for jumbo support. */
5907	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_RBDC_KEY,
5908		BCE_L2CTX_RX_RBDC_JUMBO_KEY);
5909
5910	/* Point the hardware to the first page in the page chain. */
5911	val = BCE_ADDR_HI(sc->pg_bd_chain_paddr[0]);
5912	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_HI, val);
5913	val = BCE_ADDR_LO(sc->pg_bd_chain_paddr[0]);
5914	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_LO, val);
5915
5916	/* Fill up the page chain. */
5917	bce_fill_pg_chain(sc);
5918
5919	for (i = 0; i < sc->pg_pages; i++) {
5920		bus_dmamap_sync(sc->pg_bd_chain_tag, sc->pg_bd_chain_map[i],
5921		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
5922	}
5923
5924	DBRUNMSG(BCE_EXTREME_RECV,
5925	    bce_dump_pg_chain(sc, 0, TOTAL_PG_BD_ALLOC));
5926	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5927		BCE_VERBOSE_CTX);
5928	return(rc);
5929}
5930
5931/****************************************************************************/
5932/* Add mbufs to the page chain until its full or an mbuf allocation error   */
5933/* occurs.                                                                  */
5934/*                                                                          */
5935/* Returns:                                                                 */
5936/*   Nothing                                                                */
5937/****************************************************************************/
5938static void
5939bce_fill_pg_chain(struct bce_softc *sc)
5940{
5941	u16 prod, prod_idx;
5942
5943	DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5944	    BCE_VERBOSE_CTX);
5945
5946	/* Get the page chain prodcuer index. */
5947	prod = sc->pg_prod;
5948
5949	/* Keep filling the page chain until it's full. */
5950	while (sc->free_pg_bd > 0) {
5951		prod_idx = PG_CHAIN_IDX(prod);
5952		if (bce_get_pg_buf(sc, prod, prod_idx)) {
5953			/* Bail out if we can't add an mbuf to the chain. */
5954			break;
5955		}
5956		prod = NEXT_PG_BD(prod);
5957	}
5958
5959	/* Save the page chain producer index. */
5960	sc->pg_prod = prod;
5961
5962	DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
5963	    BCE_PRINTF("%s(): Invalid pg_prod value: 0x%04X\n",
5964	    __FUNCTION__, pg_prod));
5965
5966	/*
5967	 * Write the mailbox and tell the chip about
5968	 * the new rx_bd's in the page chain.
5969	 */
5970	REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_PG_BDIDX,
5971	    prod);
5972
5973	DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5974	    BCE_VERBOSE_CTX);
5975}
5976
5977/****************************************************************************/
5978/* Free memory and clear the RX data structures.                            */
5979/*                                                                          */
5980/* Returns:                                                                 */
5981/*   Nothing.                                                               */
5982/****************************************************************************/
5983static void
5984bce_free_pg_chain(struct bce_softc *sc)
5985{
5986	int i;
5987
5988	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5989
5990	/* Free any mbufs still in the mbuf page chain. */
5991	for (i = 0; i < MAX_PG_BD_AVAIL; i++) {
5992		if (sc->pg_mbuf_ptr[i] != NULL) {
5993			if (sc->pg_mbuf_map[i] != NULL)
5994				bus_dmamap_sync(sc->pg_mbuf_tag,
5995				    sc->pg_mbuf_map[i],
5996				    BUS_DMASYNC_POSTREAD);
5997			m_freem(sc->pg_mbuf_ptr[i]);
5998			sc->pg_mbuf_ptr[i] = NULL;
5999			DBRUN(sc->debug_pg_mbuf_alloc--);
6000		}
6001	}
6002
6003	/* Clear each page chain pages. */
6004	for (i = 0; i < sc->pg_pages; i++)
6005		bzero((char *)sc->pg_bd_chain[i], BCE_PG_CHAIN_PAGE_SZ);
6006
6007	sc->free_pg_bd = sc->max_pg_bd;
6008
6009	/* Check if we lost any mbufs in the process. */
6010	DBRUNIF((sc->debug_pg_mbuf_alloc),
6011	    BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from page chain!\n",
6012	    __FUNCTION__, sc->debug_pg_mbuf_alloc));
6013
6014	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
6015}
6016
6017static u32
6018bce_get_rphy_link(struct bce_softc *sc)
6019{
6020	u32 advertise, link;
6021	int fdpx;
6022
6023	advertise = 0;
6024	fdpx = 0;
6025	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) != 0)
6026		link = bce_shmem_rd(sc, BCE_RPHY_SERDES_LINK);
6027	else
6028		link = bce_shmem_rd(sc, BCE_RPHY_COPPER_LINK);
6029	if (link & BCE_NETLINK_ANEG_ENB)
6030		advertise |= BCE_NETLINK_ANEG_ENB;
6031	if (link & BCE_NETLINK_SPEED_10HALF)
6032		advertise |= BCE_NETLINK_SPEED_10HALF;
6033	if (link & BCE_NETLINK_SPEED_10FULL) {
6034		advertise |= BCE_NETLINK_SPEED_10FULL;
6035		fdpx++;
6036	}
6037	if (link & BCE_NETLINK_SPEED_100HALF)
6038		advertise |= BCE_NETLINK_SPEED_100HALF;
6039	if (link & BCE_NETLINK_SPEED_100FULL) {
6040		advertise |= BCE_NETLINK_SPEED_100FULL;
6041		fdpx++;
6042	}
6043	if (link & BCE_NETLINK_SPEED_1000HALF)
6044		advertise |= BCE_NETLINK_SPEED_1000HALF;
6045	if (link & BCE_NETLINK_SPEED_1000FULL) {
6046		advertise |= BCE_NETLINK_SPEED_1000FULL;
6047		fdpx++;
6048	}
6049	if (link & BCE_NETLINK_SPEED_2500HALF)
6050		advertise |= BCE_NETLINK_SPEED_2500HALF;
6051	if (link & BCE_NETLINK_SPEED_2500FULL) {
6052		advertise |= BCE_NETLINK_SPEED_2500FULL;
6053		fdpx++;
6054	}
6055	if (fdpx)
6056		advertise |= BCE_NETLINK_FC_PAUSE_SYM |
6057		    BCE_NETLINK_FC_PAUSE_ASYM;
6058	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
6059		advertise |= BCE_NETLINK_PHY_APP_REMOTE |
6060		    BCE_NETLINK_ETH_AT_WIRESPEED;
6061
6062	return (advertise);
6063}
6064
6065/****************************************************************************/
6066/* Set media options.                                                       */
6067/*                                                                          */
6068/* Returns:                                                                 */
6069/*   0 for success, positive value for failure.                             */
6070/****************************************************************************/
6071static int
6072bce_ifmedia_upd(if_t ifp)
6073{
6074	struct bce_softc *sc = if_getsoftc(ifp);
6075	int error;
6076
6077	DBENTER(BCE_VERBOSE);
6078
6079	BCE_LOCK(sc);
6080	error = bce_ifmedia_upd_locked(ifp);
6081	BCE_UNLOCK(sc);
6082
6083	DBEXIT(BCE_VERBOSE);
6084	return (error);
6085}
6086
6087/****************************************************************************/
6088/* Set media options.                                                       */
6089/*                                                                          */
6090/* Returns:                                                                 */
6091/*   Nothing.                                                               */
6092/****************************************************************************/
6093static int
6094bce_ifmedia_upd_locked(if_t ifp)
6095{
6096	struct bce_softc *sc = if_getsoftc(ifp);
6097	struct mii_data *mii;
6098	struct mii_softc *miisc;
6099	struct ifmedia *ifm;
6100	u32 link;
6101	int error, fdx;
6102
6103	DBENTER(BCE_VERBOSE_PHY);
6104
6105	error = 0;
6106	BCE_LOCK_ASSERT(sc);
6107
6108	sc->bce_link_up = FALSE;
6109	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
6110		ifm = &sc->bce_ifmedia;
6111		if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
6112			return (EINVAL);
6113		link = 0;
6114		fdx = IFM_OPTIONS(ifm->ifm_media) & IFM_FDX;
6115		switch(IFM_SUBTYPE(ifm->ifm_media)) {
6116		case IFM_AUTO:
6117			/*
6118			 * Check advertised link of remote PHY by reading
6119			 * BCE_RPHY_SERDES_LINK or BCE_RPHY_COPPER_LINK.
6120			 * Always use the same link type of remote PHY.
6121			 */
6122			link = bce_get_rphy_link(sc);
6123			break;
6124		case IFM_2500_SX:
6125			if ((sc->bce_phy_flags &
6126			    (BCE_PHY_REMOTE_PORT_FIBER_FLAG |
6127			    BCE_PHY_2_5G_CAPABLE_FLAG)) == 0)
6128				return (EINVAL);
6129			/*
6130			 * XXX
6131			 * Have to enable forced 2.5Gbps configuration.
6132			 */
6133			if (fdx != 0)
6134				link |= BCE_NETLINK_SPEED_2500FULL;
6135			else
6136				link |= BCE_NETLINK_SPEED_2500HALF;
6137			break;
6138		case IFM_1000_SX:
6139			if ((sc->bce_phy_flags &
6140			    BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
6141				return (EINVAL);
6142			/*
6143			 * XXX
6144			 * Have to disable 2.5Gbps configuration.
6145			 */
6146			if (fdx != 0)
6147				link = BCE_NETLINK_SPEED_1000FULL;
6148			else
6149				link = BCE_NETLINK_SPEED_1000HALF;
6150			break;
6151		case IFM_1000_T:
6152			if (sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG)
6153				return (EINVAL);
6154			if (fdx != 0)
6155				link = BCE_NETLINK_SPEED_1000FULL;
6156			else
6157				link = BCE_NETLINK_SPEED_1000HALF;
6158			break;
6159		case IFM_100_TX:
6160			if (sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG)
6161				return (EINVAL);
6162			if (fdx != 0)
6163				link = BCE_NETLINK_SPEED_100FULL;
6164			else
6165				link = BCE_NETLINK_SPEED_100HALF;
6166			break;
6167		case IFM_10_T:
6168			if (sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG)
6169				return (EINVAL);
6170			if (fdx != 0)
6171				link = BCE_NETLINK_SPEED_10FULL;
6172			else
6173				link = BCE_NETLINK_SPEED_10HALF;
6174			break;
6175		default:
6176			return (EINVAL);
6177		}
6178		if (IFM_SUBTYPE(ifm->ifm_media) != IFM_AUTO) {
6179			/*
6180			 * XXX
6181			 * Advertise pause capability for full-duplex media.
6182			 */
6183			if (fdx != 0)
6184				link |= BCE_NETLINK_FC_PAUSE_SYM |
6185				    BCE_NETLINK_FC_PAUSE_ASYM;
6186			if ((sc->bce_phy_flags &
6187			    BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
6188				link |= BCE_NETLINK_PHY_APP_REMOTE |
6189				    BCE_NETLINK_ETH_AT_WIRESPEED;
6190		}
6191
6192		bce_shmem_wr(sc, BCE_MB_ARGS_0, link);
6193		error = bce_fw_sync(sc, BCE_DRV_MSG_CODE_CMD_SET_LINK);
6194	} else {
6195		mii = device_get_softc(sc->bce_miibus);
6196
6197		/* Make sure the MII bus has been enumerated. */
6198		if (mii) {
6199			LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
6200				PHY_RESET(miisc);
6201			error = mii_mediachg(mii);
6202		}
6203	}
6204
6205	DBEXIT(BCE_VERBOSE_PHY);
6206	return (error);
6207}
6208
6209static void
6210bce_ifmedia_sts_rphy(struct bce_softc *sc, struct ifmediareq *ifmr)
6211{
6212	if_t ifp;
6213	u32 link;
6214
6215	ifp = sc->bce_ifp;
6216	BCE_LOCK_ASSERT(sc);
6217
6218	ifmr->ifm_status = IFM_AVALID;
6219	ifmr->ifm_active = IFM_ETHER;
6220	link = bce_shmem_rd(sc, BCE_LINK_STATUS);
6221	/* XXX Handle heart beat status? */
6222	if ((link & BCE_LINK_STATUS_LINK_UP) != 0)
6223		ifmr->ifm_status |= IFM_ACTIVE;
6224	else {
6225		ifmr->ifm_active |= IFM_NONE;
6226		if_setbaudrate(ifp, 0);
6227		return;
6228	}
6229	switch (link & BCE_LINK_STATUS_SPEED_MASK) {
6230	case BCE_LINK_STATUS_10HALF:
6231		ifmr->ifm_active |= IFM_10_T | IFM_HDX;
6232		if_setbaudrate(ifp, IF_Mbps(10UL));
6233		break;
6234	case BCE_LINK_STATUS_10FULL:
6235		ifmr->ifm_active |= IFM_10_T | IFM_FDX;
6236		if_setbaudrate(ifp, IF_Mbps(10UL));
6237		break;
6238	case BCE_LINK_STATUS_100HALF:
6239		ifmr->ifm_active |= IFM_100_TX | IFM_HDX;
6240		if_setbaudrate(ifp, IF_Mbps(100UL));
6241		break;
6242	case BCE_LINK_STATUS_100FULL:
6243		ifmr->ifm_active |= IFM_100_TX | IFM_FDX;
6244		if_setbaudrate(ifp, IF_Mbps(100UL));
6245		break;
6246	case BCE_LINK_STATUS_1000HALF:
6247		if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
6248			ifmr->ifm_active |= IFM_1000_T | IFM_HDX;
6249		else
6250			ifmr->ifm_active |= IFM_1000_SX | IFM_HDX;
6251		if_setbaudrate(ifp, IF_Mbps(1000UL));
6252		break;
6253	case BCE_LINK_STATUS_1000FULL:
6254		if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
6255			ifmr->ifm_active |= IFM_1000_T | IFM_FDX;
6256		else
6257			ifmr->ifm_active |= IFM_1000_SX | IFM_FDX;
6258		if_setbaudrate(ifp, IF_Mbps(1000UL));
6259		break;
6260	case BCE_LINK_STATUS_2500HALF:
6261		if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0) {
6262			ifmr->ifm_active |= IFM_NONE;
6263			return;
6264		} else
6265			ifmr->ifm_active |= IFM_2500_SX | IFM_HDX;
6266		if_setbaudrate(ifp, IF_Mbps(2500UL));
6267		break;
6268	case BCE_LINK_STATUS_2500FULL:
6269		if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0) {
6270			ifmr->ifm_active |= IFM_NONE;
6271			return;
6272		} else
6273			ifmr->ifm_active |= IFM_2500_SX | IFM_FDX;
6274		if_setbaudrate(ifp, IF_Mbps(2500UL));
6275		break;
6276	default:
6277		ifmr->ifm_active |= IFM_NONE;
6278		return;
6279	}
6280
6281	if ((link & BCE_LINK_STATUS_RX_FC_ENABLED) != 0)
6282		ifmr->ifm_active |= IFM_ETH_RXPAUSE;
6283	if ((link & BCE_LINK_STATUS_TX_FC_ENABLED) != 0)
6284		ifmr->ifm_active |= IFM_ETH_TXPAUSE;
6285}
6286
6287/****************************************************************************/
6288/* Reports current media status.                                            */
6289/*                                                                          */
6290/* Returns:                                                                 */
6291/*   Nothing.                                                               */
6292/****************************************************************************/
6293static void
6294bce_ifmedia_sts(if_t ifp, struct ifmediareq *ifmr)
6295{
6296	struct bce_softc *sc = if_getsoftc(ifp);
6297	struct mii_data *mii;
6298
6299	DBENTER(BCE_VERBOSE_PHY);
6300
6301	BCE_LOCK(sc);
6302
6303	if ((if_getflags(ifp) & IFF_UP) == 0) {
6304		BCE_UNLOCK(sc);
6305		return;
6306	}
6307
6308	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
6309		bce_ifmedia_sts_rphy(sc, ifmr);
6310	else {
6311		mii = device_get_softc(sc->bce_miibus);
6312		mii_pollstat(mii);
6313		ifmr->ifm_active = mii->mii_media_active;
6314		ifmr->ifm_status = mii->mii_media_status;
6315	}
6316
6317	BCE_UNLOCK(sc);
6318
6319	DBEXIT(BCE_VERBOSE_PHY);
6320}
6321
6322/****************************************************************************/
6323/* Handles PHY generated interrupt events.                                  */
6324/*                                                                          */
6325/* Returns:                                                                 */
6326/*   Nothing.                                                               */
6327/****************************************************************************/
6328static void
6329bce_phy_intr(struct bce_softc *sc)
6330{
6331	u32 new_link_state, old_link_state;
6332
6333	DBENTER(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
6334
6335	DBRUN(sc->phy_interrupts++);
6336
6337	new_link_state = sc->status_block->status_attn_bits &
6338	    STATUS_ATTN_BITS_LINK_STATE;
6339	old_link_state = sc->status_block->status_attn_bits_ack &
6340	    STATUS_ATTN_BITS_LINK_STATE;
6341
6342	/* Handle any changes if the link state has changed. */
6343	if (new_link_state != old_link_state) {
6344		/* Update the status_attn_bits_ack field. */
6345		if (new_link_state) {
6346			REG_WR(sc, BCE_PCICFG_STATUS_BIT_SET_CMD,
6347			    STATUS_ATTN_BITS_LINK_STATE);
6348			DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now UP.\n",
6349			    __FUNCTION__);
6350		} else {
6351			REG_WR(sc, BCE_PCICFG_STATUS_BIT_CLEAR_CMD,
6352			    STATUS_ATTN_BITS_LINK_STATE);
6353			DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now DOWN.\n",
6354			    __FUNCTION__);
6355		}
6356
6357		if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
6358			if (new_link_state) {
6359				if (bootverbose)
6360					if_printf(sc->bce_ifp, "link UP\n");
6361				if_link_state_change(sc->bce_ifp,
6362				    LINK_STATE_UP);
6363			} else {
6364				if (bootverbose)
6365					if_printf(sc->bce_ifp, "link DOWN\n");
6366				if_link_state_change(sc->bce_ifp,
6367				    LINK_STATE_DOWN);
6368			}
6369		}
6370		/*
6371		 * Assume link is down and allow
6372		 * tick routine to update the state
6373		 * based on the actual media state.
6374		 */
6375		sc->bce_link_up = FALSE;
6376		callout_stop(&sc->bce_tick_callout);
6377		bce_tick(sc);
6378	}
6379
6380	/* Acknowledge the link change interrupt. */
6381	REG_WR(sc, BCE_EMAC_STATUS, BCE_EMAC_STATUS_LINK_CHANGE);
6382
6383	DBEXIT(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
6384}
6385
6386/****************************************************************************/
6387/* Reads the receive consumer value from the status block (skipping over    */
6388/* chain page pointer if necessary).                                        */
6389/*                                                                          */
6390/* Returns:                                                                 */
6391/*   hw_cons                                                                */
6392/****************************************************************************/
6393static inline u16
6394bce_get_hw_rx_cons(struct bce_softc *sc)
6395{
6396	u16 hw_cons;
6397
6398	rmb();
6399	hw_cons = sc->status_block->status_rx_quick_consumer_index0;
6400	if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
6401		hw_cons++;
6402
6403	return hw_cons;
6404}
6405
6406/****************************************************************************/
6407/* Handles received frame interrupt events.                                 */
6408/*                                                                          */
6409/* Returns:                                                                 */
6410/*   Nothing.                                                               */
6411/****************************************************************************/
6412static void
6413bce_rx_intr(struct bce_softc *sc)
6414{
6415	if_t ifp = sc->bce_ifp;
6416	struct l2_fhdr *l2fhdr;
6417	struct ether_vlan_header *vh;
6418	unsigned int pkt_len;
6419	u16 sw_rx_cons, sw_rx_cons_idx, hw_rx_cons;
6420	u32 status;
6421	unsigned int rem_len;
6422	u16 sw_pg_cons, sw_pg_cons_idx;
6423
6424	DBENTER(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
6425	DBRUN(sc->interrupts_rx++);
6426	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): rx_prod = 0x%04X, "
6427	    "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
6428	    __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
6429
6430	/* Prepare the RX chain pages to be accessed by the host CPU. */
6431	for (int i = 0; i < sc->rx_pages; i++)
6432		bus_dmamap_sync(sc->rx_bd_chain_tag,
6433		    sc->rx_bd_chain_map[i], BUS_DMASYNC_POSTREAD);
6434
6435	/* Prepare the page chain pages to be accessed by the host CPU. */
6436	if (bce_hdr_split == TRUE) {
6437		for (int i = 0; i < sc->pg_pages; i++)
6438			bus_dmamap_sync(sc->pg_bd_chain_tag,
6439			    sc->pg_bd_chain_map[i], BUS_DMASYNC_POSTREAD);
6440	}
6441
6442	/* Get the hardware's view of the RX consumer index. */
6443	hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
6444
6445	/* Get working copies of the driver's view of the consumer indices. */
6446	sw_rx_cons = sc->rx_cons;
6447	sw_pg_cons = sc->pg_cons;
6448
6449	/* Update some debug statistics counters */
6450	DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
6451	    sc->rx_low_watermark = sc->free_rx_bd);
6452	DBRUNIF((sc->free_rx_bd == sc->max_rx_bd),
6453	    sc->rx_empty_count++);
6454
6455	/* Scan through the receive chain as long as there is work to do */
6456	/* ToDo: Consider setting a limit on the number of packets processed. */
6457	rmb();
6458	while (sw_rx_cons != hw_rx_cons) {
6459		struct mbuf *m0;
6460
6461		/* Convert the producer/consumer indices to an actual rx_bd index. */
6462		sw_rx_cons_idx = RX_CHAIN_IDX(sw_rx_cons);
6463
6464		/* Unmap the mbuf from DMA space. */
6465		bus_dmamap_sync(sc->rx_mbuf_tag,
6466		    sc->rx_mbuf_map[sw_rx_cons_idx],
6467		    BUS_DMASYNC_POSTREAD);
6468		bus_dmamap_unload(sc->rx_mbuf_tag,
6469		    sc->rx_mbuf_map[sw_rx_cons_idx]);
6470
6471		/* Remove the mbuf from the RX chain. */
6472		m0 = sc->rx_mbuf_ptr[sw_rx_cons_idx];
6473		sc->rx_mbuf_ptr[sw_rx_cons_idx] = NULL;
6474		DBRUN(sc->debug_rx_mbuf_alloc--);
6475		sc->free_rx_bd++;
6476
6477		/*
6478 		 * Frames received on the NetXteme II are prepended
6479 		 * with an l2_fhdr structure which provides status
6480 		 * information about the received frame (including
6481 		 * VLAN tags and checksum info).  The frames are
6482		 * also automatically adjusted to word align the IP
6483 		 * header (i.e. two null bytes are inserted before
6484 		 * the Ethernet	header).  As a result the data
6485 		 * DMA'd by the controller into	the mbuf looks
6486		 * like this:
6487		 *
6488		 * +---------+-----+---------------------+-----+
6489		 * | l2_fhdr | pad | packet data         | FCS |
6490		 * +---------+-----+---------------------+-----+
6491		 *
6492 		 * The l2_fhdr needs to be checked and skipped and
6493 		 * the FCS needs to be stripped before sending the
6494		 * packet up the stack.
6495		 */
6496		l2fhdr  = mtod(m0, struct l2_fhdr *);
6497
6498		/* Get the packet data + FCS length and the status. */
6499		pkt_len = l2fhdr->l2_fhdr_pkt_len;
6500		status  = l2fhdr->l2_fhdr_status;
6501
6502		/*
6503		 * Skip over the l2_fhdr and pad, resulting in the
6504		 * following data in the mbuf:
6505		 * +---------------------+-----+
6506		 * | packet data         | FCS |
6507		 * +---------------------+-----+
6508		 */
6509		m_adj(m0, sizeof(struct l2_fhdr) + ETHER_ALIGN);
6510
6511		/*
6512 		 * When split header mode is used, an ethernet frame
6513 		 * may be split across the receive chain and the
6514 		 * page chain. If that occurs an mbuf cluster must be
6515 		 * reassembled from the individual mbuf pieces.
6516		 */
6517		if (bce_hdr_split == TRUE) {
6518			/*
6519			 * Check whether the received frame fits in a single
6520			 * mbuf or not (i.e. packet data + FCS <=
6521			 * sc->rx_bd_mbuf_data_len bytes).
6522			 */
6523			if (pkt_len > m0->m_len) {
6524				/*
6525				 * The received frame is larger than a single mbuf.
6526				 * If the frame was a TCP frame then only the TCP
6527				 * header is placed in the mbuf, the remaining
6528				 * payload (including FCS) is placed in the page
6529				 * chain, the SPLIT flag is set, and the header
6530				 * length is placed in the IP checksum field.
6531				 * If the frame is not a TCP frame then the mbuf
6532				 * is filled and the remaining bytes are placed
6533				 * in the page chain.
6534				 */
6535
6536				DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a large "
6537					"packet.\n", __FUNCTION__);
6538				DBRUN(sc->split_header_frames_rcvd++);
6539
6540				/*
6541				 * When the page chain is enabled and the TCP
6542				 * header has been split from the TCP payload,
6543				 * the ip_xsum structure will reflect the length
6544				 * of the TCP header, not the IP checksum.  Set
6545				 * the packet length of the mbuf accordingly.
6546				 */
6547				if (status & L2_FHDR_STATUS_SPLIT) {
6548					m0->m_len = l2fhdr->l2_fhdr_ip_xsum;
6549					DBRUN(sc->split_header_tcp_frames_rcvd++);
6550				}
6551
6552				rem_len = pkt_len - m0->m_len;
6553
6554				/* Pull mbufs off the page chain for any remaining data. */
6555				while (rem_len > 0) {
6556					struct mbuf *m_pg;
6557
6558					sw_pg_cons_idx = PG_CHAIN_IDX(sw_pg_cons);
6559
6560					/* Remove the mbuf from the page chain. */
6561					m_pg = sc->pg_mbuf_ptr[sw_pg_cons_idx];
6562					sc->pg_mbuf_ptr[sw_pg_cons_idx] = NULL;
6563					DBRUN(sc->debug_pg_mbuf_alloc--);
6564					sc->free_pg_bd++;
6565
6566					/* Unmap the page chain mbuf from DMA space. */
6567					bus_dmamap_sync(sc->pg_mbuf_tag,
6568						sc->pg_mbuf_map[sw_pg_cons_idx],
6569						BUS_DMASYNC_POSTREAD);
6570					bus_dmamap_unload(sc->pg_mbuf_tag,
6571						sc->pg_mbuf_map[sw_pg_cons_idx]);
6572
6573					/* Adjust the mbuf length. */
6574					if (rem_len < m_pg->m_len) {
6575						/* The mbuf chain is complete. */
6576						m_pg->m_len = rem_len;
6577						rem_len = 0;
6578					} else {
6579						/* More packet data is waiting. */
6580						rem_len -= m_pg->m_len;
6581					}
6582
6583					/* Concatenate the mbuf cluster to the mbuf. */
6584					m_cat(m0, m_pg);
6585
6586					sw_pg_cons = NEXT_PG_BD(sw_pg_cons);
6587				}
6588
6589				/* Set the total packet length. */
6590				m0->m_pkthdr.len = pkt_len;
6591
6592			} else {
6593				/*
6594				 * The received packet is small and fits in a
6595				 * single mbuf (i.e. the l2_fhdr + pad + packet +
6596				 * FCS <= MHLEN).  In other words, the packet is
6597				 * 154 bytes or less in size.
6598				 */
6599
6600				DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a small "
6601					"packet.\n", __FUNCTION__);
6602
6603				/* Set the total packet length. */
6604				m0->m_pkthdr.len = m0->m_len = pkt_len;
6605			}
6606		} else
6607			/* Set the total packet length. */
6608			m0->m_pkthdr.len = m0->m_len = pkt_len;
6609
6610		/* Remove the trailing Ethernet FCS. */
6611		m_adj(m0, -ETHER_CRC_LEN);
6612
6613		/* Check that the resulting mbuf chain is valid. */
6614		DBRUN(m_sanity(m0, FALSE));
6615		DBRUNIF(((m0->m_len < ETHER_HDR_LEN) |
6616		    (m0->m_pkthdr.len > BCE_MAX_JUMBO_ETHER_MTU_VLAN)),
6617		    BCE_PRINTF("Invalid Ethernet frame size!\n");
6618		    m_print(m0, 128));
6619
6620		DBRUNIF(DB_RANDOMTRUE(l2fhdr_error_sim_control),
6621		    sc->l2fhdr_error_sim_count++;
6622		    status = status | L2_FHDR_ERRORS_PHY_DECODE);
6623
6624		/* Check the received frame for errors. */
6625		if (status & (L2_FHDR_ERRORS_BAD_CRC |
6626		    L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT |
6627		    L2_FHDR_ERRORS_TOO_SHORT  | L2_FHDR_ERRORS_GIANT_FRAME)) {
6628			/* Log the error and release the mbuf. */
6629			sc->l2fhdr_error_count++;
6630			m_freem(m0);
6631			m0 = NULL;
6632			goto bce_rx_intr_next_rx;
6633		}
6634
6635		/* Send the packet to the appropriate interface. */
6636		m0->m_pkthdr.rcvif = ifp;
6637
6638		/* Assume no hardware checksum. */
6639		m0->m_pkthdr.csum_flags = 0;
6640
6641		/* Validate the checksum if offload enabled. */
6642		if (if_getcapenable(ifp) & IFCAP_RXCSUM) {
6643			/* Check for an IP datagram. */
6644		 	if (!(status & L2_FHDR_STATUS_SPLIT) &&
6645			    (status & L2_FHDR_STATUS_IP_DATAGRAM)) {
6646				m0->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
6647				DBRUN(sc->csum_offload_ip++);
6648				/* Check if the IP checksum is valid. */
6649				if ((l2fhdr->l2_fhdr_ip_xsum ^ 0xffff) == 0)
6650					m0->m_pkthdr.csum_flags |=
6651					    CSUM_IP_VALID;
6652			}
6653
6654			/* Check for a valid TCP/UDP frame. */
6655			if (status & (L2_FHDR_STATUS_TCP_SEGMENT |
6656			    L2_FHDR_STATUS_UDP_DATAGRAM)) {
6657				/* Check for a good TCP/UDP checksum. */
6658				if ((status & (L2_FHDR_ERRORS_TCP_XSUM |
6659				    L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
6660					DBRUN(sc->csum_offload_tcp_udp++);
6661					m0->m_pkthdr.csum_data =
6662					    l2fhdr->l2_fhdr_tcp_udp_xsum;
6663					m0->m_pkthdr.csum_flags |=
6664					    (CSUM_DATA_VALID
6665					    | CSUM_PSEUDO_HDR);
6666				}
6667			}
6668		}
6669
6670		/* Attach the VLAN tag.	*/
6671		if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) &&
6672		    !(sc->rx_mode & BCE_EMAC_RX_MODE_KEEP_VLAN_TAG)) {
6673			DBRUN(sc->vlan_tagged_frames_rcvd++);
6674			if (if_getcapenable(ifp) & IFCAP_VLAN_HWTAGGING) {
6675				DBRUN(sc->vlan_tagged_frames_stripped++);
6676				m0->m_pkthdr.ether_vtag =
6677				    l2fhdr->l2_fhdr_vlan_tag;
6678				m0->m_flags |= M_VLANTAG;
6679			} else {
6680				/*
6681				 * bce(4) controllers can't disable VLAN
6682				 * tag stripping if management firmware
6683				 * (ASF/IPMI/UMP) is running. So we always
6684				 * strip VLAN tag and manually reconstruct
6685				 * the VLAN frame by appending stripped
6686				 * VLAN tag in driver if VLAN tag stripping
6687				 * was disabled.
6688				 *
6689				 * TODO: LLC SNAP handling.
6690				 */
6691				bcopy(mtod(m0, uint8_t *),
6692				    mtod(m0, uint8_t *) - ETHER_VLAN_ENCAP_LEN,
6693				    ETHER_ADDR_LEN * 2);
6694				m0->m_data -= ETHER_VLAN_ENCAP_LEN;
6695				vh = mtod(m0, struct ether_vlan_header *);
6696				vh->evl_encap_proto = htons(ETHERTYPE_VLAN);
6697				vh->evl_tag = htons(l2fhdr->l2_fhdr_vlan_tag);
6698				m0->m_pkthdr.len += ETHER_VLAN_ENCAP_LEN;
6699				m0->m_len += ETHER_VLAN_ENCAP_LEN;
6700			}
6701		}
6702
6703		/* Increment received packet statistics. */
6704		if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
6705
6706bce_rx_intr_next_rx:
6707		sw_rx_cons = NEXT_RX_BD(sw_rx_cons);
6708
6709		/* If we have a packet, pass it up the stack */
6710		if (m0) {
6711			/* Make sure we don't lose our place when we release the lock. */
6712			sc->rx_cons = sw_rx_cons;
6713			sc->pg_cons = sw_pg_cons;
6714
6715			BCE_UNLOCK(sc);
6716			if_input(ifp, m0);
6717			BCE_LOCK(sc);
6718
6719			/* Recover our place. */
6720			sw_rx_cons = sc->rx_cons;
6721			sw_pg_cons = sc->pg_cons;
6722		}
6723
6724		/* Refresh hw_cons to see if there's new work */
6725		if (sw_rx_cons == hw_rx_cons)
6726			hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
6727	}
6728
6729	/* No new packets.  Refill the page chain. */
6730	if (bce_hdr_split == TRUE) {
6731		sc->pg_cons = sw_pg_cons;
6732		bce_fill_pg_chain(sc);
6733	}
6734
6735	/* No new packets.  Refill the RX chain. */
6736	sc->rx_cons = sw_rx_cons;
6737	bce_fill_rx_chain(sc);
6738
6739	/* Prepare the page chain pages to be accessed by the NIC. */
6740	for (int i = 0; i < sc->rx_pages; i++)
6741		bus_dmamap_sync(sc->rx_bd_chain_tag,
6742		    sc->rx_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
6743
6744	if (bce_hdr_split == TRUE) {
6745		for (int i = 0; i < sc->pg_pages; i++)
6746			bus_dmamap_sync(sc->pg_bd_chain_tag,
6747			    sc->pg_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
6748	}
6749
6750	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): rx_prod = 0x%04X, "
6751	    "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
6752	    __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
6753	DBEXIT(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
6754}
6755
6756/****************************************************************************/
6757/* Reads the transmit consumer value from the status block (skipping over   */
6758/* chain page pointer if necessary).                                        */
6759/*                                                                          */
6760/* Returns:                                                                 */
6761/*   hw_cons                                                                */
6762/****************************************************************************/
6763static inline u16
6764bce_get_hw_tx_cons(struct bce_softc *sc)
6765{
6766	u16 hw_cons;
6767
6768	mb();
6769	hw_cons = sc->status_block->status_tx_quick_consumer_index0;
6770	if ((hw_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
6771		hw_cons++;
6772
6773	return hw_cons;
6774}
6775
6776/****************************************************************************/
6777/* Handles transmit completion interrupt events.                            */
6778/*                                                                          */
6779/* Returns:                                                                 */
6780/*   Nothing.                                                               */
6781/****************************************************************************/
6782static void
6783bce_tx_intr(struct bce_softc *sc)
6784{
6785	if_t ifp = sc->bce_ifp;
6786	u16 hw_tx_cons, sw_tx_cons, sw_tx_chain_cons;
6787
6788	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
6789	DBRUN(sc->interrupts_tx++);
6790	DBPRINT(sc, BCE_EXTREME_SEND, "%s(enter): tx_prod = 0x%04X, "
6791	    "tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
6792	    __FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
6793
6794	BCE_LOCK_ASSERT(sc);
6795
6796	/* Get the hardware's view of the TX consumer index. */
6797	hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
6798	sw_tx_cons = sc->tx_cons;
6799
6800	/* Prevent speculative reads of the status block. */
6801	bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
6802	    BUS_SPACE_BARRIER_READ);
6803
6804	/* Cycle through any completed TX chain page entries. */
6805	while (sw_tx_cons != hw_tx_cons) {
6806#ifdef BCE_DEBUG
6807		struct tx_bd *txbd = NULL;
6808#endif
6809		sw_tx_chain_cons = TX_CHAIN_IDX(sw_tx_cons);
6810
6811		DBPRINT(sc, BCE_INFO_SEND,
6812		    "%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, "
6813		    "sw_tx_chain_cons = 0x%04X\n",
6814		    __FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
6815
6816		DBRUNIF((sw_tx_chain_cons > MAX_TX_BD_ALLOC),
6817		    BCE_PRINTF("%s(%d): TX chain consumer out of range! "
6818		    " 0x%04X > 0x%04X\n", __FILE__, __LINE__, sw_tx_chain_cons,
6819		    (int) MAX_TX_BD_ALLOC);
6820		    bce_breakpoint(sc));
6821
6822		DBRUN(txbd = &sc->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)]
6823		    [TX_IDX(sw_tx_chain_cons)]);
6824
6825		DBRUNIF((txbd == NULL),
6826		    BCE_PRINTF("%s(%d): Unexpected NULL tx_bd[0x%04X]!\n",
6827		    __FILE__, __LINE__, sw_tx_chain_cons);
6828		    bce_breakpoint(sc));
6829
6830		DBRUNMSG(BCE_INFO_SEND, BCE_PRINTF("%s(): ", __FUNCTION__);
6831		    bce_dump_txbd(sc, sw_tx_chain_cons, txbd));
6832
6833		/*
6834		 * Free the associated mbuf. Remember
6835		 * that only the last tx_bd of a packet
6836		 * has an mbuf pointer and DMA map.
6837		 */
6838		if (sc->tx_mbuf_ptr[sw_tx_chain_cons] != NULL) {
6839			/* Validate that this is the last tx_bd. */
6840			DBRUNIF((!(txbd->tx_bd_flags & TX_BD_FLAGS_END)),
6841			    BCE_PRINTF("%s(%d): tx_bd END flag not set but "
6842			    "txmbuf == NULL!\n", __FILE__, __LINE__);
6843			    bce_breakpoint(sc));
6844
6845			DBRUNMSG(BCE_INFO_SEND,
6846			    BCE_PRINTF("%s(): Unloading map/freeing mbuf "
6847			    "from tx_bd[0x%04X]\n", __FUNCTION__,
6848			    sw_tx_chain_cons));
6849
6850			/* Unmap the mbuf. */
6851			bus_dmamap_unload(sc->tx_mbuf_tag,
6852			    sc->tx_mbuf_map[sw_tx_chain_cons]);
6853
6854			/* Free the mbuf. */
6855			m_freem(sc->tx_mbuf_ptr[sw_tx_chain_cons]);
6856			sc->tx_mbuf_ptr[sw_tx_chain_cons] = NULL;
6857			DBRUN(sc->debug_tx_mbuf_alloc--);
6858
6859			if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
6860		}
6861
6862		sc->used_tx_bd--;
6863		sw_tx_cons = NEXT_TX_BD(sw_tx_cons);
6864
6865		/* Refresh hw_cons to see if there's new work. */
6866		hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
6867
6868		/* Prevent speculative reads of the status block. */
6869		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
6870		    BUS_SPACE_BARRIER_READ);
6871	}
6872
6873	/* Clear the TX timeout timer. */
6874	sc->watchdog_timer = 0;
6875
6876	/* Clear the tx hardware queue full flag. */
6877	if (sc->used_tx_bd < sc->max_tx_bd) {
6878		DBRUNIF((if_getdrvflags(ifp) & IFF_DRV_OACTIVE),
6879		    DBPRINT(sc, BCE_INFO_SEND,
6880		    "%s(): Open TX chain! %d/%d (used/total)\n",
6881		    __FUNCTION__, sc->used_tx_bd, sc->max_tx_bd));
6882		if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE);
6883	}
6884
6885	sc->tx_cons = sw_tx_cons;
6886
6887	DBPRINT(sc, BCE_EXTREME_SEND, "%s(exit): tx_prod = 0x%04X, "
6888	    "tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
6889	    __FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
6890	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
6891}
6892
6893/****************************************************************************/
6894/* Disables interrupt generation.                                           */
6895/*                                                                          */
6896/* Returns:                                                                 */
6897/*   Nothing.                                                               */
6898/****************************************************************************/
6899static void
6900bce_disable_intr(struct bce_softc *sc)
6901{
6902	DBENTER(BCE_VERBOSE_INTR);
6903
6904	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_MASK_INT);
6905	REG_RD(sc, BCE_PCICFG_INT_ACK_CMD);
6906
6907	DBEXIT(BCE_VERBOSE_INTR);
6908}
6909
6910/****************************************************************************/
6911/* Enables interrupt generation.                                            */
6912/*                                                                          */
6913/* Returns:                                                                 */
6914/*   Nothing.                                                               */
6915/****************************************************************************/
6916static void
6917bce_enable_intr(struct bce_softc *sc, int coal_now)
6918{
6919	DBENTER(BCE_VERBOSE_INTR);
6920
6921	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
6922	    BCE_PCICFG_INT_ACK_CMD_INDEX_VALID |
6923	    BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
6924
6925	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
6926	    BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
6927
6928	/* Force an immediate interrupt (whether there is new data or not). */
6929	if (coal_now)
6930		REG_WR(sc, BCE_HC_COMMAND, sc->hc_command | BCE_HC_COMMAND_COAL_NOW);
6931
6932	DBEXIT(BCE_VERBOSE_INTR);
6933}
6934
6935/****************************************************************************/
6936/* Handles controller initialization.                                       */
6937/*                                                                          */
6938/* Returns:                                                                 */
6939/*   Nothing.                                                               */
6940/****************************************************************************/
6941static void
6942bce_init_locked(struct bce_softc *sc)
6943{
6944	if_t ifp;
6945	u32 ether_mtu = 0;
6946
6947	DBENTER(BCE_VERBOSE_RESET);
6948
6949	BCE_LOCK_ASSERT(sc);
6950
6951	ifp = sc->bce_ifp;
6952
6953	/* Check if the driver is still running and bail out if it is. */
6954	if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
6955		goto bce_init_locked_exit;
6956
6957	bce_stop(sc);
6958
6959	if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
6960		BCE_PRINTF("%s(%d): Controller reset failed!\n",
6961		    __FILE__, __LINE__);
6962		goto bce_init_locked_exit;
6963	}
6964
6965	if (bce_chipinit(sc)) {
6966		BCE_PRINTF("%s(%d): Controller initialization failed!\n",
6967		    __FILE__, __LINE__);
6968		goto bce_init_locked_exit;
6969	}
6970
6971	if (bce_blockinit(sc)) {
6972		BCE_PRINTF("%s(%d): Block initialization failed!\n",
6973		    __FILE__, __LINE__);
6974		goto bce_init_locked_exit;
6975	}
6976
6977	/* Load our MAC address. */
6978	bcopy(if_getlladdr(sc->bce_ifp), sc->eaddr, ETHER_ADDR_LEN);
6979	bce_set_mac_addr(sc);
6980
6981	if (bce_hdr_split == FALSE)
6982		bce_get_rx_buffer_sizes(sc, if_getmtu(ifp));
6983	/*
6984	 * Calculate and program the hardware Ethernet MTU
6985 	 * size. Be generous on the receive if we have room
6986 	 * and allowed by the user.
6987	 */
6988	if (bce_strict_rx_mtu == TRUE)
6989		ether_mtu = if_getmtu(ifp);
6990	else {
6991		if (bce_hdr_split == TRUE) {
6992			if (if_getmtu(ifp) <= sc->rx_bd_mbuf_data_len + MCLBYTES)
6993				ether_mtu = sc->rx_bd_mbuf_data_len +
6994				    MCLBYTES;
6995			else
6996				ether_mtu = if_getmtu(ifp);
6997		} else {
6998			if (if_getmtu(ifp) <= sc->rx_bd_mbuf_data_len)
6999				ether_mtu = sc->rx_bd_mbuf_data_len;
7000			else
7001				ether_mtu = if_getmtu(ifp);
7002		}
7003	}
7004
7005	ether_mtu += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN;
7006
7007	DBPRINT(sc, BCE_INFO_MISC, "%s(): setting h/w mtu = %d\n",
7008	    __FUNCTION__, ether_mtu);
7009
7010	/* Program the mtu, enabling jumbo frame support if necessary. */
7011	if (ether_mtu > (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN))
7012		REG_WR(sc, BCE_EMAC_RX_MTU_SIZE,
7013		    min(ether_mtu, BCE_MAX_JUMBO_ETHER_MTU) |
7014		    BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA);
7015	else
7016		REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu);
7017
7018	/* Program appropriate promiscuous/multicast filtering. */
7019	bce_set_rx_mode(sc);
7020
7021	if (bce_hdr_split == TRUE) {
7022		/* Init page buffer descriptor chain. */
7023		bce_init_pg_chain(sc);
7024	}
7025
7026	/* Init RX buffer descriptor chain. */
7027	bce_init_rx_chain(sc);
7028
7029	/* Init TX buffer descriptor chain. */
7030	bce_init_tx_chain(sc);
7031
7032	/* Enable host interrupts. */
7033	bce_enable_intr(sc, 1);
7034
7035	bce_ifmedia_upd_locked(ifp);
7036
7037	/* Let the OS know the driver is up and running. */
7038	if_setdrvflagbits(ifp, IFF_DRV_RUNNING, 0);
7039	if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE);
7040
7041	callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
7042
7043bce_init_locked_exit:
7044	DBEXIT(BCE_VERBOSE_RESET);
7045}
7046
7047/****************************************************************************/
7048/* Initialize the controller just enough so that any management firmware    */
7049/* running on the device will continue to operate correctly.                */
7050/*                                                                          */
7051/* Returns:                                                                 */
7052/*   Nothing.                                                               */
7053/****************************************************************************/
7054static void
7055bce_mgmt_init_locked(struct bce_softc *sc)
7056{
7057	if_t ifp;
7058
7059	DBENTER(BCE_VERBOSE_RESET);
7060
7061	BCE_LOCK_ASSERT(sc);
7062
7063	/* Bail out if management firmware is not running. */
7064	if (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)) {
7065		DBPRINT(sc, BCE_VERBOSE_SPECIAL,
7066		    "No management firmware running...\n");
7067		goto bce_mgmt_init_locked_exit;
7068	}
7069
7070	ifp = sc->bce_ifp;
7071
7072	/* Enable all critical blocks in the MAC. */
7073	REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT);
7074	REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
7075	DELAY(20);
7076
7077	bce_ifmedia_upd_locked(ifp);
7078
7079bce_mgmt_init_locked_exit:
7080	DBEXIT(BCE_VERBOSE_RESET);
7081}
7082
7083/****************************************************************************/
7084/* Handles controller initialization when called from an unlocked routine.  */
7085/*                                                                          */
7086/* Returns:                                                                 */
7087/*   Nothing.                                                               */
7088/****************************************************************************/
7089static void
7090bce_init(void *xsc)
7091{
7092	struct bce_softc *sc = xsc;
7093
7094	DBENTER(BCE_VERBOSE_RESET);
7095
7096	BCE_LOCK(sc);
7097	bce_init_locked(sc);
7098	BCE_UNLOCK(sc);
7099
7100	DBEXIT(BCE_VERBOSE_RESET);
7101}
7102
7103/****************************************************************************/
7104/* Modifies an mbuf for TSO on the hardware.                                */
7105/*                                                                          */
7106/* Returns:                                                                 */
7107/*   Pointer to a modified mbuf.                                            */
7108/****************************************************************************/
7109static struct mbuf *
7110bce_tso_setup(struct bce_softc *sc, struct mbuf **m_head, u16 *flags)
7111{
7112	struct mbuf *m;
7113	struct ether_header *eh;
7114	struct ip *ip;
7115	struct tcphdr *th;
7116	u16 etype;
7117	int hdr_len __unused, ip_len __unused, ip_hlen = 0, tcp_hlen = 0;
7118
7119	DBRUN(sc->tso_frames_requested++);
7120
7121	ip_len = 0;
7122	/* Controller may modify mbuf chains. */
7123	if (M_WRITABLE(*m_head) == 0) {
7124		m = m_dup(*m_head, M_NOWAIT);
7125		m_freem(*m_head);
7126		if (m == NULL) {
7127			sc->mbuf_alloc_failed_count++;
7128			*m_head = NULL;
7129			return (NULL);
7130		}
7131		*m_head = m;
7132	}
7133
7134	/*
7135	 * For TSO the controller needs two pieces of info,
7136	 * the MSS and the IP+TCP options length.
7137	 */
7138	m = m_pullup(*m_head, sizeof(struct ether_header) + sizeof(struct ip));
7139	if (m == NULL) {
7140		*m_head = NULL;
7141		return (NULL);
7142	}
7143	eh = mtod(m, struct ether_header *);
7144	etype = ntohs(eh->ether_type);
7145
7146	/* Check for supported TSO Ethernet types (only IPv4 for now) */
7147	switch (etype) {
7148	case ETHERTYPE_IP:
7149		ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
7150		/* TSO only supported for TCP protocol. */
7151		if (ip->ip_p != IPPROTO_TCP) {
7152			BCE_PRINTF("%s(%d): TSO enabled for non-TCP frame!.\n",
7153			    __FILE__, __LINE__);
7154			m_freem(*m_head);
7155			*m_head = NULL;
7156			return (NULL);
7157		}
7158
7159		/* Get IP header length in bytes (min 20) */
7160		ip_hlen = ip->ip_hl << 2;
7161		m = m_pullup(*m_head, sizeof(struct ether_header) + ip_hlen +
7162		    sizeof(struct tcphdr));
7163		if (m == NULL) {
7164			*m_head = NULL;
7165			return (NULL);
7166		}
7167
7168		/* Get the TCP header length in bytes (min 20) */
7169		ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
7170		th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
7171		tcp_hlen = (th->th_off << 2);
7172
7173		/* Make sure all IP/TCP options live in the same buffer. */
7174		m = m_pullup(*m_head,  sizeof(struct ether_header)+ ip_hlen +
7175		    tcp_hlen);
7176		if (m == NULL) {
7177			*m_head = NULL;
7178			return (NULL);
7179		}
7180
7181		/* Clear IP header length and checksum, will be calc'd by h/w. */
7182		ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
7183		ip_len = ip->ip_len;
7184		ip->ip_len = 0;
7185		ip->ip_sum = 0;
7186		break;
7187	case ETHERTYPE_IPV6:
7188		BCE_PRINTF("%s(%d): TSO over IPv6 not supported!.\n",
7189		    __FILE__, __LINE__);
7190		m_freem(*m_head);
7191		*m_head = NULL;
7192		return (NULL);
7193		/* NOT REACHED */
7194	default:
7195		BCE_PRINTF("%s(%d): TSO enabled for unsupported protocol!.\n",
7196		    __FILE__, __LINE__);
7197		m_freem(*m_head);
7198		*m_head = NULL;
7199		return (NULL);
7200	}
7201
7202	hdr_len = sizeof(struct ether_header) + ip_hlen + tcp_hlen;
7203
7204	DBPRINT(sc, BCE_EXTREME_SEND, "%s(): hdr_len = %d, e_hlen = %d, "
7205	    "ip_hlen = %d, tcp_hlen = %d, ip_len = %d\n",
7206	    __FUNCTION__, hdr_len, (int) sizeof(struct ether_header), ip_hlen,
7207	    tcp_hlen, ip_len);
7208
7209	/* Set the LSO flag in the TX BD */
7210	*flags |= TX_BD_FLAGS_SW_LSO;
7211
7212	/* Set the length of IP + TCP options (in 32 bit words) */
7213	*flags |= (((ip_hlen + tcp_hlen - sizeof(struct ip) -
7214	    sizeof(struct tcphdr)) >> 2) << 8);
7215
7216	DBRUN(sc->tso_frames_completed++);
7217	return (*m_head);
7218}
7219
7220/****************************************************************************/
7221/* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
7222/* memory visible to the controller.                                        */
7223/*                                                                          */
7224/* Returns:                                                                 */
7225/*   0 for success, positive value for failure.                             */
7226/* Modified:                                                                */
7227/*   m_head: May be set to NULL if MBUF is excessively fragmented.          */
7228/****************************************************************************/
7229static int
7230bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
7231{
7232	bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
7233	bus_dmamap_t map;
7234	struct tx_bd *txbd = NULL;
7235	struct mbuf *m0;
7236	u16 prod, chain_prod, mss = 0, vlan_tag = 0, flags = 0;
7237	u32 prod_bseq;
7238
7239#ifdef BCE_DEBUG
7240	u16 debug_prod;
7241#endif
7242
7243	int i, error, nsegs, rc = 0;
7244
7245	DBENTER(BCE_VERBOSE_SEND);
7246
7247	/* Make sure we have room in the TX chain. */
7248	if (sc->used_tx_bd >= sc->max_tx_bd)
7249		goto bce_tx_encap_exit;
7250
7251	/* Transfer any checksum offload flags to the bd. */
7252	m0 = *m_head;
7253	if (m0->m_pkthdr.csum_flags) {
7254		if (m0->m_pkthdr.csum_flags & CSUM_TSO) {
7255			m0 = bce_tso_setup(sc, m_head, &flags);
7256			if (m0 == NULL) {
7257				DBRUN(sc->tso_frames_failed++);
7258				goto bce_tx_encap_exit;
7259			}
7260			mss = htole16(m0->m_pkthdr.tso_segsz);
7261		} else {
7262			if (m0->m_pkthdr.csum_flags & CSUM_IP)
7263				flags |= TX_BD_FLAGS_IP_CKSUM;
7264			if (m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
7265				flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
7266		}
7267	}
7268
7269	/* Transfer any VLAN tags to the bd. */
7270	if (m0->m_flags & M_VLANTAG) {
7271		flags |= TX_BD_FLAGS_VLAN_TAG;
7272		vlan_tag = m0->m_pkthdr.ether_vtag;
7273	}
7274
7275	/* Map the mbuf into DMAable memory. */
7276	prod = sc->tx_prod;
7277	chain_prod = TX_CHAIN_IDX(prod);
7278	map = sc->tx_mbuf_map[chain_prod];
7279
7280	/* Map the mbuf into our DMA address space. */
7281	error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag, map, m0,
7282	    segs, &nsegs, BUS_DMA_NOWAIT);
7283
7284	/* Check if the DMA mapping was successful */
7285	if (error == EFBIG) {
7286		sc->mbuf_frag_count++;
7287
7288		/* Try to defrag the mbuf. */
7289		m0 = m_collapse(*m_head, M_NOWAIT, BCE_MAX_SEGMENTS);
7290		if (m0 == NULL) {
7291			/* Defrag was unsuccessful */
7292			m_freem(*m_head);
7293			*m_head = NULL;
7294			sc->mbuf_alloc_failed_count++;
7295			rc = ENOBUFS;
7296			goto bce_tx_encap_exit;
7297		}
7298
7299		/* Defrag was successful, try mapping again */
7300		*m_head = m0;
7301		error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag,
7302		    map, m0, segs, &nsegs, BUS_DMA_NOWAIT);
7303
7304		/* Still getting an error after a defrag. */
7305		if (error == ENOMEM) {
7306			/* Insufficient DMA buffers available. */
7307			sc->dma_map_addr_tx_failed_count++;
7308			rc = error;
7309			goto bce_tx_encap_exit;
7310		} else if (error != 0) {
7311			/* Release it and return an error. */
7312			BCE_PRINTF("%s(%d): Unknown error mapping mbuf into "
7313			    "TX chain!\n", __FILE__, __LINE__);
7314			m_freem(m0);
7315			*m_head = NULL;
7316			sc->dma_map_addr_tx_failed_count++;
7317			rc = ENOBUFS;
7318			goto bce_tx_encap_exit;
7319		}
7320	} else if (error == ENOMEM) {
7321		/* Insufficient DMA buffers available. */
7322		sc->dma_map_addr_tx_failed_count++;
7323		rc = error;
7324		goto bce_tx_encap_exit;
7325	} else if (error != 0) {
7326		m_freem(m0);
7327		*m_head = NULL;
7328		sc->dma_map_addr_tx_failed_count++;
7329		rc = error;
7330		goto bce_tx_encap_exit;
7331	}
7332
7333	/* Make sure there's room in the chain */
7334	if (nsegs > (sc->max_tx_bd - sc->used_tx_bd)) {
7335		bus_dmamap_unload(sc->tx_mbuf_tag, map);
7336		rc = ENOBUFS;
7337		goto bce_tx_encap_exit;
7338	}
7339
7340	/* prod points to an empty tx_bd at this point. */
7341	prod_bseq  = sc->tx_prod_bseq;
7342
7343#ifdef BCE_DEBUG
7344	debug_prod = chain_prod;
7345#endif
7346
7347	DBPRINT(sc, BCE_INFO_SEND,
7348	    "%s(start): prod = 0x%04X, chain_prod = 0x%04X, "
7349	    "prod_bseq = 0x%08X\n",
7350	    __FUNCTION__, prod, chain_prod, prod_bseq);
7351
7352	/*
7353	 * Cycle through each mbuf segment that makes up
7354	 * the outgoing frame, gathering the mapping info
7355	 * for that segment and creating a tx_bd for
7356	 * the mbuf.
7357	 */
7358	for (i = 0; i < nsegs ; i++) {
7359		chain_prod = TX_CHAIN_IDX(prod);
7360		txbd= &sc->tx_bd_chain[TX_PAGE(chain_prod)]
7361		    [TX_IDX(chain_prod)];
7362
7363		txbd->tx_bd_haddr_lo =
7364		    htole32(BCE_ADDR_LO(segs[i].ds_addr));
7365		txbd->tx_bd_haddr_hi =
7366		    htole32(BCE_ADDR_HI(segs[i].ds_addr));
7367		txbd->tx_bd_mss_nbytes = htole32(mss << 16) |
7368		    htole16(segs[i].ds_len);
7369		txbd->tx_bd_vlan_tag = htole16(vlan_tag);
7370		txbd->tx_bd_flags = htole16(flags);
7371		prod_bseq += segs[i].ds_len;
7372		if (i == 0)
7373			txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_START);
7374		prod = NEXT_TX_BD(prod);
7375	}
7376
7377	/* Set the END flag on the last TX buffer descriptor. */
7378	txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_END);
7379
7380	DBRUNMSG(BCE_EXTREME_SEND,
7381	    bce_dump_tx_chain(sc, debug_prod, nsegs));
7382
7383	/*
7384	 * Ensure that the mbuf pointer for this transmission
7385	 * is placed at the array index of the last
7386	 * descriptor in this chain.  This is done
7387	 * because a single map is used for all
7388	 * segments of the mbuf and we don't want to
7389	 * unload the map before all of the segments
7390	 * have been freed.
7391	 */
7392	sc->tx_mbuf_ptr[chain_prod] = m0;
7393	sc->used_tx_bd += nsegs;
7394
7395	/* Update some debug statistic counters */
7396	DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
7397	    sc->tx_hi_watermark = sc->used_tx_bd);
7398	DBRUNIF((sc->used_tx_bd == sc->max_tx_bd), sc->tx_full_count++);
7399	DBRUNIF(sc->debug_tx_mbuf_alloc++);
7400
7401	DBRUNMSG(BCE_EXTREME_SEND, bce_dump_tx_mbuf_chain(sc, chain_prod, 1));
7402
7403	/* prod points to the next free tx_bd at this point. */
7404	sc->tx_prod = prod;
7405	sc->tx_prod_bseq = prod_bseq;
7406
7407	/* Tell the chip about the waiting TX frames. */
7408	REG_WR16(sc, MB_GET_CID_ADDR(TX_CID) +
7409	    BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
7410	REG_WR(sc, MB_GET_CID_ADDR(TX_CID) +
7411	    BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
7412
7413bce_tx_encap_exit:
7414	DBEXIT(BCE_VERBOSE_SEND);
7415	return(rc);
7416}
7417
7418/****************************************************************************/
7419/* Main transmit routine when called from another routine with a lock.      */
7420/*                                                                          */
7421/* Returns:                                                                 */
7422/*   Nothing.                                                               */
7423/****************************************************************************/
7424static void
7425bce_start_locked(if_t ifp)
7426{
7427	struct bce_softc *sc = if_getsoftc(ifp);
7428	struct mbuf *m_head = NULL;
7429	int count = 0;
7430	u16 tx_prod, tx_chain_prod __unused;
7431
7432	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
7433
7434	BCE_LOCK_ASSERT(sc);
7435
7436	/* prod points to the next free tx_bd. */
7437	tx_prod = sc->tx_prod;
7438	tx_chain_prod = TX_CHAIN_IDX(tx_prod);
7439
7440	DBPRINT(sc, BCE_INFO_SEND,
7441	    "%s(enter): tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
7442	    "tx_prod_bseq = 0x%08X\n",
7443	    __FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
7444
7445	/* If there's no link or the transmit queue is empty then just exit. */
7446	if (sc->bce_link_up == FALSE) {
7447		DBPRINT(sc, BCE_INFO_SEND, "%s(): No link.\n",
7448		    __FUNCTION__);
7449		goto bce_start_locked_exit;
7450	}
7451
7452	if (if_sendq_empty(ifp)) {
7453		DBPRINT(sc, BCE_INFO_SEND, "%s(): Transmit queue empty.\n",
7454		    __FUNCTION__);
7455		goto bce_start_locked_exit;
7456	}
7457
7458	/*
7459	 * Keep adding entries while there is space in the ring.
7460	 */
7461	while (sc->used_tx_bd < sc->max_tx_bd) {
7462		/* Check for any frames to send. */
7463		m_head = if_dequeue(ifp);
7464
7465		/* Stop when the transmit queue is empty. */
7466		if (m_head == NULL)
7467			break;
7468
7469		/*
7470		 * Pack the data into the transmit ring. If we
7471		 * don't have room, place the mbuf back at the
7472		 * head of the queue and set the OACTIVE flag
7473		 * to wait for the NIC to drain the chain.
7474		 */
7475		if (bce_tx_encap(sc, &m_head)) {
7476			if (m_head != NULL)
7477				if_sendq_prepend(ifp, m_head);
7478			if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0);
7479			DBPRINT(sc, BCE_INFO_SEND,
7480			    "TX chain is closed for business! Total "
7481			    "tx_bd used = %d\n", sc->used_tx_bd);
7482			break;
7483		}
7484
7485		count++;
7486
7487		/* Send a copy of the frame to any BPF listeners. */
7488		ETHER_BPF_MTAP(ifp, m_head);
7489	}
7490
7491	/* Exit if no packets were dequeued. */
7492	if (count == 0) {
7493		DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were "
7494		    "dequeued\n", __FUNCTION__);
7495		goto bce_start_locked_exit;
7496	}
7497
7498	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): Inserted %d frames into "
7499	    "send queue.\n", __FUNCTION__, count);
7500
7501	/* Set the tx timeout. */
7502	sc->watchdog_timer = BCE_TX_TIMEOUT;
7503
7504	DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_ctx(sc, TX_CID));
7505	DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_mq_regs(sc));
7506
7507bce_start_locked_exit:
7508	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
7509}
7510
7511/****************************************************************************/
7512/* Main transmit routine when called from another routine without a lock.   */
7513/*                                                                          */
7514/* Returns:                                                                 */
7515/*   Nothing.                                                               */
7516/****************************************************************************/
7517static void
7518bce_start(if_t ifp)
7519{
7520	struct bce_softc *sc = if_getsoftc(ifp);
7521
7522	DBENTER(BCE_VERBOSE_SEND);
7523
7524	BCE_LOCK(sc);
7525	bce_start_locked(ifp);
7526	BCE_UNLOCK(sc);
7527
7528	DBEXIT(BCE_VERBOSE_SEND);
7529}
7530
7531/****************************************************************************/
7532/* Handles any IOCTL calls from the operating system.                       */
7533/*                                                                          */
7534/* Returns:                                                                 */
7535/*   0 for success, positive value for failure.                             */
7536/****************************************************************************/
7537static int
7538bce_ioctl(if_t ifp, u_long command, caddr_t data)
7539{
7540	struct bce_softc *sc = if_getsoftc(ifp);
7541	struct ifreq *ifr = (struct ifreq *) data;
7542	struct mii_data *mii;
7543	int mask, error = 0;
7544
7545	DBENTER(BCE_VERBOSE_MISC);
7546
7547	switch(command) {
7548	/* Set the interface MTU. */
7549	case SIOCSIFMTU:
7550		/* Check that the MTU setting is supported. */
7551		if ((ifr->ifr_mtu < BCE_MIN_MTU) ||
7552			(ifr->ifr_mtu > BCE_MAX_JUMBO_MTU)) {
7553			error = EINVAL;
7554			break;
7555		}
7556
7557		DBPRINT(sc, BCE_INFO_MISC,
7558		    "SIOCSIFMTU: Changing MTU from %d to %d\n",
7559		    (int) if_getmtu(ifp), (int) ifr->ifr_mtu);
7560
7561		BCE_LOCK(sc);
7562		if_setmtu(ifp, ifr->ifr_mtu);
7563		if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
7564			if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING);
7565			bce_init_locked(sc);
7566		}
7567		BCE_UNLOCK(sc);
7568		break;
7569
7570	/* Set interface flags. */
7571	case SIOCSIFFLAGS:
7572		DBPRINT(sc, BCE_VERBOSE_SPECIAL, "Received SIOCSIFFLAGS\n");
7573
7574		BCE_LOCK(sc);
7575
7576		/* Check if the interface is up. */
7577		if (if_getflags(ifp) & IFF_UP) {
7578			if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
7579				/* Change promiscuous/multicast flags as necessary. */
7580				bce_set_rx_mode(sc);
7581			} else {
7582				/* Start the HW */
7583				bce_init_locked(sc);
7584			}
7585		} else {
7586			/* The interface is down, check if driver is running. */
7587			if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
7588				bce_stop(sc);
7589
7590				/* If MFW is running, restart the controller a bit. */
7591				if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
7592					bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
7593					bce_chipinit(sc);
7594					bce_mgmt_init_locked(sc);
7595				}
7596			}
7597		}
7598
7599		BCE_UNLOCK(sc);
7600		break;
7601
7602	/* Add/Delete multicast address */
7603	case SIOCADDMULTI:
7604	case SIOCDELMULTI:
7605		DBPRINT(sc, BCE_VERBOSE_MISC,
7606		    "Received SIOCADDMULTI/SIOCDELMULTI\n");
7607
7608		BCE_LOCK(sc);
7609		if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
7610			bce_set_rx_mode(sc);
7611		BCE_UNLOCK(sc);
7612
7613		break;
7614
7615	/* Set/Get Interface media */
7616	case SIOCSIFMEDIA:
7617	case SIOCGIFMEDIA:
7618		DBPRINT(sc, BCE_VERBOSE_MISC,
7619		    "Received SIOCSIFMEDIA/SIOCGIFMEDIA\n");
7620		if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
7621			error = ifmedia_ioctl(ifp, ifr, &sc->bce_ifmedia,
7622			    command);
7623		else {
7624			mii = device_get_softc(sc->bce_miibus);
7625			error = ifmedia_ioctl(ifp, ifr, &mii->mii_media,
7626			    command);
7627		}
7628		break;
7629
7630	/* Set interface capability */
7631	case SIOCSIFCAP:
7632		mask = ifr->ifr_reqcap ^ if_getcapenable(ifp);
7633		DBPRINT(sc, BCE_INFO_MISC,
7634		    "Received SIOCSIFCAP = 0x%08X\n", (u32) mask);
7635
7636		/* Toggle the TX checksum capabilities enable flag. */
7637		if (mask & IFCAP_TXCSUM &&
7638		    if_getcapabilities(ifp) & IFCAP_TXCSUM) {
7639			if_togglecapenable(ifp, IFCAP_TXCSUM);
7640			if (IFCAP_TXCSUM & if_getcapenable(ifp))
7641				if_sethwassistbits(ifp, BCE_IF_HWASSIST, 0);
7642			else
7643				if_sethwassistbits(ifp, 0, BCE_IF_HWASSIST);
7644		}
7645
7646		/* Toggle the RX checksum capabilities enable flag. */
7647		if (mask & IFCAP_RXCSUM &&
7648		    if_getcapabilities(ifp) & IFCAP_RXCSUM)
7649			if_togglecapenable(ifp, IFCAP_RXCSUM);
7650
7651		/* Toggle the TSO capabilities enable flag. */
7652		if (bce_tso_enable && (mask & IFCAP_TSO4) &&
7653		    if_getcapabilities(ifp) & IFCAP_TSO4) {
7654			if_togglecapenable(ifp, IFCAP_TSO4);
7655			if (IFCAP_TSO4 & if_getcapenable(ifp))
7656				if_sethwassistbits(ifp, CSUM_TSO, 0);
7657			else
7658				if_sethwassistbits(ifp, 0, CSUM_TSO);
7659		}
7660
7661		if (mask & IFCAP_VLAN_HWCSUM &&
7662		    if_getcapabilities(ifp) & IFCAP_VLAN_HWCSUM)
7663			if_togglecapenable(ifp, IFCAP_VLAN_HWCSUM);
7664
7665		if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
7666		    (if_getcapabilities(ifp) & IFCAP_VLAN_HWTSO) != 0)
7667			if_togglecapenable(ifp, IFCAP_VLAN_HWTSO);
7668		/*
7669		 * Don't actually disable VLAN tag stripping as
7670		 * management firmware (ASF/IPMI/UMP) requires the
7671		 * feature. If VLAN tag stripping is disabled driver
7672		 * will manually reconstruct the VLAN frame by
7673		 * appending stripped VLAN tag.
7674		 */
7675		if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
7676		    (if_getcapabilities(ifp) & IFCAP_VLAN_HWTAGGING)) {
7677			if_togglecapenable(ifp, IFCAP_VLAN_HWTAGGING);
7678			if ((if_getcapenable(ifp) & IFCAP_VLAN_HWTAGGING)
7679			    == 0)
7680				if_setcapenablebit(ifp, 0, IFCAP_VLAN_HWTSO);
7681		}
7682		VLAN_CAPABILITIES(ifp);
7683		break;
7684	default:
7685		/* We don't know how to handle the IOCTL, pass it on. */
7686		error = ether_ioctl(ifp, command, data);
7687		break;
7688	}
7689
7690	DBEXIT(BCE_VERBOSE_MISC);
7691	return(error);
7692}
7693
7694/****************************************************************************/
7695/* Transmit timeout handler.                                                */
7696/*                                                                          */
7697/* Returns:                                                                 */
7698/*   Nothing.                                                               */
7699/****************************************************************************/
7700static void
7701bce_watchdog(struct bce_softc *sc)
7702{
7703	uint32_t status;
7704
7705	DBENTER(BCE_EXTREME_SEND);
7706
7707	BCE_LOCK_ASSERT(sc);
7708
7709	status = 0;
7710	/* If the watchdog timer hasn't expired then just exit. */
7711	if (sc->watchdog_timer == 0 || --sc->watchdog_timer)
7712		goto bce_watchdog_exit;
7713
7714	status = REG_RD(sc, BCE_EMAC_RX_STATUS);
7715	/* If pause frames are active then don't reset the hardware. */
7716	if ((sc->bce_flags & BCE_USING_RX_FLOW_CONTROL) != 0) {
7717		if ((status & BCE_EMAC_RX_STATUS_FFED) != 0) {
7718			/*
7719			 * If link partner has us in XOFF state then wait for
7720			 * the condition to clear.
7721			 */
7722			sc->watchdog_timer = BCE_TX_TIMEOUT;
7723			goto bce_watchdog_exit;
7724		} else if ((status & BCE_EMAC_RX_STATUS_FF_RECEIVED) != 0 &&
7725			(status & BCE_EMAC_RX_STATUS_N_RECEIVED) != 0) {
7726			/*
7727			 * If we're not currently XOFF'ed but have recently
7728			 * been XOFF'd/XON'd then assume that's delaying TX
7729			 * this time around.
7730			 */
7731			sc->watchdog_timer = BCE_TX_TIMEOUT;
7732			goto bce_watchdog_exit;
7733		}
7734		/*
7735		 * Any other condition is unexpected and the controller
7736		 * should be reset.
7737		 */
7738	}
7739
7740	BCE_PRINTF("%s(%d): Watchdog timeout occurred, resetting!\n",
7741	    __FILE__, __LINE__);
7742
7743	DBRUNMSG(BCE_INFO,
7744	    bce_dump_driver_state(sc);
7745	    bce_dump_status_block(sc);
7746	    bce_dump_stats_block(sc);
7747	    bce_dump_ftqs(sc);
7748	    bce_dump_txp_state(sc, 0);
7749	    bce_dump_rxp_state(sc, 0);
7750	    bce_dump_tpat_state(sc, 0);
7751	    bce_dump_cp_state(sc, 0);
7752	    bce_dump_com_state(sc, 0));
7753
7754	DBRUN(bce_breakpoint(sc));
7755
7756	if_setdrvflagbits(sc->bce_ifp, 0, IFF_DRV_RUNNING);
7757
7758	bce_init_locked(sc);
7759	sc->watchdog_timeouts++;
7760
7761bce_watchdog_exit:
7762	REG_WR(sc, BCE_EMAC_RX_STATUS, status);
7763	DBEXIT(BCE_EXTREME_SEND);
7764}
7765
7766/*
7767 * Interrupt handler.
7768 */
7769/****************************************************************************/
7770/* Main interrupt entry point.  Verifies that the controller generated the  */
7771/* interrupt and then calls a separate routine for handle the various       */
7772/* interrupt causes (PHY, TX, RX).                                          */
7773/*                                                                          */
7774/* Returns:                                                                 */
7775/*   Nothing.                                                               */
7776/****************************************************************************/
7777static void
7778bce_intr(void *xsc)
7779{
7780	struct bce_softc *sc;
7781	if_t ifp;
7782	u32 status_attn_bits;
7783	u16 hw_rx_cons, hw_tx_cons;
7784
7785	sc = xsc;
7786	ifp = sc->bce_ifp;
7787
7788	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
7789	DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_status_block(sc));
7790	DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_stats_block(sc));
7791
7792	BCE_LOCK(sc);
7793
7794	DBRUN(sc->interrupts_generated++);
7795
7796	/* Synchnorize before we read from interface's status block */
7797	bus_dmamap_sync(sc->status_tag, sc->status_map, BUS_DMASYNC_POSTREAD);
7798
7799	/*
7800	 * If the hardware status block index matches the last value read
7801	 * by the driver and we haven't asserted our interrupt then there's
7802	 * nothing to do.  This may only happen in case of INTx due to the
7803	 * interrupt arriving at the CPU before the status block is updated.
7804	 */
7805	if ((sc->bce_flags & (BCE_USING_MSI_FLAG | BCE_USING_MSIX_FLAG)) == 0 &&
7806	    sc->status_block->status_idx == sc->last_status_idx &&
7807	    (REG_RD(sc, BCE_PCICFG_MISC_STATUS) &
7808	     BCE_PCICFG_MISC_STATUS_INTA_VALUE)) {
7809		DBPRINT(sc, BCE_VERBOSE_INTR, "%s(): Spurious interrupt.\n",
7810		    __FUNCTION__);
7811		goto bce_intr_exit;
7812	}
7813
7814	/* Ack the interrupt and stop others from occurring. */
7815	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
7816	    BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
7817	    BCE_PCICFG_INT_ACK_CMD_MASK_INT);
7818
7819	/* Check if the hardware has finished any work. */
7820	hw_rx_cons = bce_get_hw_rx_cons(sc);
7821	hw_tx_cons = bce_get_hw_tx_cons(sc);
7822
7823	/* Keep processing data as long as there is work to do. */
7824	for (;;) {
7825		status_attn_bits = sc->status_block->status_attn_bits;
7826
7827		DBRUNIF(DB_RANDOMTRUE(unexpected_attention_sim_control),
7828		    BCE_PRINTF("Simulating unexpected status attention "
7829		    "bit set.");
7830		    sc->unexpected_attention_sim_count++;
7831		    status_attn_bits = status_attn_bits |
7832		    STATUS_ATTN_BITS_PARITY_ERROR);
7833
7834		/* Was it a link change interrupt? */
7835		if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
7836		    (sc->status_block->status_attn_bits_ack &
7837		     STATUS_ATTN_BITS_LINK_STATE)) {
7838			bce_phy_intr(sc);
7839
7840			/* Clear transient updates during link state change. */
7841			REG_WR(sc, BCE_HC_COMMAND, sc->hc_command |
7842			    BCE_HC_COMMAND_COAL_NOW_WO_INT);
7843			REG_RD(sc, BCE_HC_COMMAND);
7844		}
7845
7846		/* If any other attention is asserted, the chip is toast. */
7847		if (((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
7848		    (sc->status_block->status_attn_bits_ack &
7849		    ~STATUS_ATTN_BITS_LINK_STATE))) {
7850			sc->unexpected_attention_count++;
7851
7852			BCE_PRINTF("%s(%d): Fatal attention detected: "
7853			    "0x%08X\n",	__FILE__, __LINE__,
7854			    sc->status_block->status_attn_bits);
7855
7856			DBRUNMSG(BCE_FATAL,
7857			    if (unexpected_attention_sim_control == 0)
7858				bce_breakpoint(sc));
7859
7860			bce_init_locked(sc);
7861			goto bce_intr_exit;
7862		}
7863
7864		/* Check for any completed RX frames. */
7865		if (hw_rx_cons != sc->hw_rx_cons)
7866			bce_rx_intr(sc);
7867
7868		/* Check for any completed TX frames. */
7869		if (hw_tx_cons != sc->hw_tx_cons)
7870			bce_tx_intr(sc);
7871
7872		/* Save status block index value for the next interrupt. */
7873		sc->last_status_idx = sc->status_block->status_idx;
7874
7875 		/*
7876 		 * Prevent speculative reads from getting
7877 		 * ahead of the status block.
7878		 */
7879		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
7880		    BUS_SPACE_BARRIER_READ);
7881
7882 		/*
7883 		 * If there's no work left then exit the
7884 		 * interrupt service routine.
7885		 */
7886		hw_rx_cons = bce_get_hw_rx_cons(sc);
7887		hw_tx_cons = bce_get_hw_tx_cons(sc);
7888
7889		if ((hw_rx_cons == sc->hw_rx_cons) &&
7890		    (hw_tx_cons == sc->hw_tx_cons))
7891			break;
7892	}
7893
7894	bus_dmamap_sync(sc->status_tag,	sc->status_map, BUS_DMASYNC_PREREAD);
7895
7896	/* Re-enable interrupts. */
7897	bce_enable_intr(sc, 0);
7898
7899	/* Handle any frames that arrived while handling the interrupt. */
7900	if (if_getdrvflags(ifp) & IFF_DRV_RUNNING &&
7901	    !if_sendq_empty(ifp))
7902		bce_start_locked(ifp);
7903
7904bce_intr_exit:
7905	BCE_UNLOCK(sc);
7906
7907	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
7908}
7909
7910/****************************************************************************/
7911/* Programs the various packet receive modes (broadcast and multicast).     */
7912/*                                                                          */
7913/* Returns:                                                                 */
7914/*   Nothing.                                                               */
7915/****************************************************************************/
7916static u_int
7917bce_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
7918{
7919	u32 *hashes = arg;
7920	int h;
7921
7922	h = ether_crc32_le(LLADDR(sdl), ETHER_ADDR_LEN) & 0xFF;
7923	hashes[(h & 0xE0) >> 5] |= 1 << (h & 0x1F);
7924
7925	return (1);
7926}
7927
7928static void
7929bce_set_rx_mode(struct bce_softc *sc)
7930{
7931	if_t ifp;
7932	u32 hashes[NUM_MC_HASH_REGISTERS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
7933	u32 rx_mode, sort_mode;
7934	int i;
7935
7936	DBENTER(BCE_VERBOSE_MISC);
7937
7938	BCE_LOCK_ASSERT(sc);
7939
7940	ifp = sc->bce_ifp;
7941
7942	/* Initialize receive mode default settings. */
7943	rx_mode   = sc->rx_mode & ~(BCE_EMAC_RX_MODE_PROMISCUOUS |
7944	    BCE_EMAC_RX_MODE_KEEP_VLAN_TAG);
7945	sort_mode = 1 | BCE_RPM_SORT_USER0_BC_EN;
7946
7947	/*
7948	 * ASF/IPMI/UMP firmware requires that VLAN tag stripping
7949	 * be enbled.
7950	 */
7951	if (!(BCE_IF_CAPABILITIES & IFCAP_VLAN_HWTAGGING) &&
7952	    (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)))
7953		rx_mode |= BCE_EMAC_RX_MODE_KEEP_VLAN_TAG;
7954
7955	/*
7956	 * Check for promiscuous, all multicast, or selected
7957	 * multicast address filtering.
7958	 */
7959	if (if_getflags(ifp) & IFF_PROMISC) {
7960		DBPRINT(sc, BCE_INFO_MISC, "Enabling promiscuous mode.\n");
7961
7962		/* Enable promiscuous mode. */
7963		rx_mode |= BCE_EMAC_RX_MODE_PROMISCUOUS;
7964		sort_mode |= BCE_RPM_SORT_USER0_PROM_EN;
7965	} else if (if_getflags(ifp) & IFF_ALLMULTI) {
7966		DBPRINT(sc, BCE_INFO_MISC, "Enabling all multicast mode.\n");
7967
7968		/* Enable all multicast addresses. */
7969		for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
7970			REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4),
7971			    0xffffffff);
7972		}
7973		sort_mode |= BCE_RPM_SORT_USER0_MC_EN;
7974	} else {
7975		/* Accept one or more multicast(s). */
7976		DBPRINT(sc, BCE_INFO_MISC, "Enabling selective multicast mode.\n");
7977		if_foreach_llmaddr(ifp, bce_hash_maddr, hashes);
7978
7979		for (i = 0; i < NUM_MC_HASH_REGISTERS; i++)
7980			REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), hashes[i]);
7981
7982		sort_mode |= BCE_RPM_SORT_USER0_MC_HSH_EN;
7983	}
7984
7985	/* Only make changes if the recive mode has actually changed. */
7986	if (rx_mode != sc->rx_mode) {
7987		DBPRINT(sc, BCE_VERBOSE_MISC, "Enabling new receive mode: "
7988		    "0x%08X\n", rx_mode);
7989
7990		sc->rx_mode = rx_mode;
7991		REG_WR(sc, BCE_EMAC_RX_MODE, rx_mode);
7992	}
7993
7994	/* Disable and clear the existing sort before enabling a new sort. */
7995	REG_WR(sc, BCE_RPM_SORT_USER0, 0x0);
7996	REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode);
7997	REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode | BCE_RPM_SORT_USER0_ENA);
7998
7999	DBEXIT(BCE_VERBOSE_MISC);
8000}
8001
8002/****************************************************************************/
8003/* Called periodically to updates statistics from the controllers           */
8004/* statistics block.                                                        */
8005/*                                                                          */
8006/* Returns:                                                                 */
8007/*   Nothing.                                                               */
8008/****************************************************************************/
8009static void
8010bce_stats_update(struct bce_softc *sc)
8011{
8012	struct statistics_block *stats;
8013
8014	DBENTER(BCE_EXTREME_MISC);
8015
8016	bus_dmamap_sync(sc->stats_tag, sc->stats_map, BUS_DMASYNC_POSTREAD);
8017
8018	stats = (struct statistics_block *) sc->stats_block;
8019
8020	/*
8021	 * Update the sysctl statistics from the
8022	 * hardware statistics.
8023	 */
8024	sc->stat_IfHCInOctets =
8025	    ((u64) stats->stat_IfHCInOctets_hi << 32) +
8026	     (u64) stats->stat_IfHCInOctets_lo;
8027
8028	sc->stat_IfHCInBadOctets =
8029	    ((u64) stats->stat_IfHCInBadOctets_hi << 32) +
8030	     (u64) stats->stat_IfHCInBadOctets_lo;
8031
8032	sc->stat_IfHCOutOctets =
8033	    ((u64) stats->stat_IfHCOutOctets_hi << 32) +
8034	     (u64) stats->stat_IfHCOutOctets_lo;
8035
8036	sc->stat_IfHCOutBadOctets =
8037	    ((u64) stats->stat_IfHCOutBadOctets_hi << 32) +
8038	     (u64) stats->stat_IfHCOutBadOctets_lo;
8039
8040	sc->stat_IfHCInUcastPkts =
8041	    ((u64) stats->stat_IfHCInUcastPkts_hi << 32) +
8042	     (u64) stats->stat_IfHCInUcastPkts_lo;
8043
8044	sc->stat_IfHCInMulticastPkts =
8045	    ((u64) stats->stat_IfHCInMulticastPkts_hi << 32) +
8046	     (u64) stats->stat_IfHCInMulticastPkts_lo;
8047
8048	sc->stat_IfHCInBroadcastPkts =
8049	    ((u64) stats->stat_IfHCInBroadcastPkts_hi << 32) +
8050	     (u64) stats->stat_IfHCInBroadcastPkts_lo;
8051
8052	sc->stat_IfHCOutUcastPkts =
8053	    ((u64) stats->stat_IfHCOutUcastPkts_hi << 32) +
8054	     (u64) stats->stat_IfHCOutUcastPkts_lo;
8055
8056	sc->stat_IfHCOutMulticastPkts =
8057	    ((u64) stats->stat_IfHCOutMulticastPkts_hi << 32) +
8058	     (u64) stats->stat_IfHCOutMulticastPkts_lo;
8059
8060	sc->stat_IfHCOutBroadcastPkts =
8061	    ((u64) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
8062	     (u64) stats->stat_IfHCOutBroadcastPkts_lo;
8063
8064	/* ToDo: Preserve counters beyond 32 bits? */
8065	/* ToDo: Read the statistics from auto-clear regs? */
8066
8067	sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors =
8068	    stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
8069
8070	sc->stat_Dot3StatsCarrierSenseErrors =
8071	    stats->stat_Dot3StatsCarrierSenseErrors;
8072
8073	sc->stat_Dot3StatsFCSErrors =
8074	    stats->stat_Dot3StatsFCSErrors;
8075
8076	sc->stat_Dot3StatsAlignmentErrors =
8077	    stats->stat_Dot3StatsAlignmentErrors;
8078
8079	sc->stat_Dot3StatsSingleCollisionFrames =
8080	    stats->stat_Dot3StatsSingleCollisionFrames;
8081
8082	sc->stat_Dot3StatsMultipleCollisionFrames =
8083	    stats->stat_Dot3StatsMultipleCollisionFrames;
8084
8085	sc->stat_Dot3StatsDeferredTransmissions =
8086	    stats->stat_Dot3StatsDeferredTransmissions;
8087
8088	sc->stat_Dot3StatsExcessiveCollisions =
8089	    stats->stat_Dot3StatsExcessiveCollisions;
8090
8091	sc->stat_Dot3StatsLateCollisions =
8092	    stats->stat_Dot3StatsLateCollisions;
8093
8094	sc->stat_EtherStatsCollisions =
8095	    stats->stat_EtherStatsCollisions;
8096
8097	sc->stat_EtherStatsFragments =
8098	    stats->stat_EtherStatsFragments;
8099
8100	sc->stat_EtherStatsJabbers =
8101	    stats->stat_EtherStatsJabbers;
8102
8103	sc->stat_EtherStatsUndersizePkts =
8104	    stats->stat_EtherStatsUndersizePkts;
8105
8106	sc->stat_EtherStatsOversizePkts =
8107	     stats->stat_EtherStatsOversizePkts;
8108
8109	sc->stat_EtherStatsPktsRx64Octets =
8110	    stats->stat_EtherStatsPktsRx64Octets;
8111
8112	sc->stat_EtherStatsPktsRx65Octetsto127Octets =
8113	    stats->stat_EtherStatsPktsRx65Octetsto127Octets;
8114
8115	sc->stat_EtherStatsPktsRx128Octetsto255Octets =
8116	    stats->stat_EtherStatsPktsRx128Octetsto255Octets;
8117
8118	sc->stat_EtherStatsPktsRx256Octetsto511Octets =
8119	    stats->stat_EtherStatsPktsRx256Octetsto511Octets;
8120
8121	sc->stat_EtherStatsPktsRx512Octetsto1023Octets =
8122	    stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
8123
8124	sc->stat_EtherStatsPktsRx1024Octetsto1522Octets =
8125	    stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
8126
8127	sc->stat_EtherStatsPktsRx1523Octetsto9022Octets =
8128	    stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
8129
8130	sc->stat_EtherStatsPktsTx64Octets =
8131	    stats->stat_EtherStatsPktsTx64Octets;
8132
8133	sc->stat_EtherStatsPktsTx65Octetsto127Octets =
8134	    stats->stat_EtherStatsPktsTx65Octetsto127Octets;
8135
8136	sc->stat_EtherStatsPktsTx128Octetsto255Octets =
8137	    stats->stat_EtherStatsPktsTx128Octetsto255Octets;
8138
8139	sc->stat_EtherStatsPktsTx256Octetsto511Octets =
8140	    stats->stat_EtherStatsPktsTx256Octetsto511Octets;
8141
8142	sc->stat_EtherStatsPktsTx512Octetsto1023Octets =
8143	    stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
8144
8145	sc->stat_EtherStatsPktsTx1024Octetsto1522Octets =
8146	    stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
8147
8148	sc->stat_EtherStatsPktsTx1523Octetsto9022Octets =
8149	    stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
8150
8151	sc->stat_XonPauseFramesReceived =
8152	    stats->stat_XonPauseFramesReceived;
8153
8154	sc->stat_XoffPauseFramesReceived =
8155	    stats->stat_XoffPauseFramesReceived;
8156
8157	sc->stat_OutXonSent =
8158	    stats->stat_OutXonSent;
8159
8160	sc->stat_OutXoffSent =
8161	    stats->stat_OutXoffSent;
8162
8163	sc->stat_FlowControlDone =
8164	    stats->stat_FlowControlDone;
8165
8166	sc->stat_MacControlFramesReceived =
8167	    stats->stat_MacControlFramesReceived;
8168
8169	sc->stat_XoffStateEntered =
8170	    stats->stat_XoffStateEntered;
8171
8172	sc->stat_IfInFramesL2FilterDiscards =
8173	    stats->stat_IfInFramesL2FilterDiscards;
8174
8175	sc->stat_IfInRuleCheckerDiscards =
8176	    stats->stat_IfInRuleCheckerDiscards;
8177
8178	sc->stat_IfInFTQDiscards =
8179	    stats->stat_IfInFTQDiscards;
8180
8181	sc->stat_IfInMBUFDiscards =
8182	    stats->stat_IfInMBUFDiscards;
8183
8184	sc->stat_IfInRuleCheckerP4Hit =
8185	    stats->stat_IfInRuleCheckerP4Hit;
8186
8187	sc->stat_CatchupInRuleCheckerDiscards =
8188	    stats->stat_CatchupInRuleCheckerDiscards;
8189
8190	sc->stat_CatchupInFTQDiscards =
8191	    stats->stat_CatchupInFTQDiscards;
8192
8193	sc->stat_CatchupInMBUFDiscards =
8194	    stats->stat_CatchupInMBUFDiscards;
8195
8196	sc->stat_CatchupInRuleCheckerP4Hit =
8197	    stats->stat_CatchupInRuleCheckerP4Hit;
8198
8199	sc->com_no_buffers = REG_RD_IND(sc, 0x120084);
8200
8201	/* ToDo: Add additional statistics? */
8202
8203	DBEXIT(BCE_EXTREME_MISC);
8204}
8205
8206static uint64_t
8207bce_get_counter(if_t ifp, ift_counter cnt)
8208{
8209	struct bce_softc *sc;
8210	uint64_t rv;
8211
8212	sc = if_getsoftc(ifp);
8213
8214	switch (cnt) {
8215	case IFCOUNTER_COLLISIONS:
8216		return (sc->stat_EtherStatsCollisions);
8217	case IFCOUNTER_IERRORS:
8218		return (sc->stat_EtherStatsUndersizePkts +
8219		    sc->stat_EtherStatsOversizePkts +
8220		    sc->stat_IfInMBUFDiscards +
8221		    sc->stat_Dot3StatsAlignmentErrors +
8222		    sc->stat_Dot3StatsFCSErrors +
8223		    sc->stat_IfInRuleCheckerDiscards +
8224		    sc->stat_IfInFTQDiscards +
8225		    sc->l2fhdr_error_count +
8226		    sc->com_no_buffers);
8227	case IFCOUNTER_OERRORS:
8228		rv = sc->stat_Dot3StatsExcessiveCollisions +
8229		    sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
8230		    sc->stat_Dot3StatsLateCollisions +
8231		    sc->watchdog_timeouts;
8232		/*
8233		 * Certain controllers don't report
8234		 * carrier sense errors correctly.
8235		 * See errata E11_5708CA0_1165.
8236		 */
8237		if (!(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
8238		    !(BCE_CHIP_ID(sc) == BCE_CHIP_ID_5708_A0))
8239			rv += sc->stat_Dot3StatsCarrierSenseErrors;
8240		return (rv);
8241	default:
8242		return (if_get_counter_default(ifp, cnt));
8243	}
8244}
8245
8246/****************************************************************************/
8247/* Periodic function to notify the bootcode that the driver is still        */
8248/* present.                                                                 */
8249/*                                                                          */
8250/* Returns:                                                                 */
8251/*   Nothing.                                                               */
8252/****************************************************************************/
8253static void
8254bce_pulse(void *xsc)
8255{
8256	struct bce_softc *sc = xsc;
8257	u32 msg;
8258
8259	DBENTER(BCE_EXTREME_MISC);
8260
8261	BCE_LOCK_ASSERT(sc);
8262
8263	/* Tell the firmware that the driver is still running. */
8264	msg = (u32) ++sc->bce_fw_drv_pulse_wr_seq;
8265	bce_shmem_wr(sc, BCE_DRV_PULSE_MB, msg);
8266
8267	/* Update the bootcode condition. */
8268	sc->bc_state = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
8269
8270	/* Report whether the bootcode still knows the driver is running. */
8271	if (bce_verbose || bootverbose) {
8272		if (sc->bce_drv_cardiac_arrest == FALSE) {
8273			if (!(sc->bc_state & BCE_CONDITION_DRV_PRESENT)) {
8274				sc->bce_drv_cardiac_arrest = TRUE;
8275				BCE_PRINTF("%s(): Warning: bootcode "
8276				    "thinks driver is absent! "
8277				    "(bc_state = 0x%08X)\n",
8278				    __FUNCTION__, sc->bc_state);
8279			}
8280		} else {
8281			/*
8282			 * Not supported by all bootcode versions.
8283			 * (v5.0.11+ and v5.2.1+)  Older bootcode
8284			 * will require the driver to reset the
8285			 * controller to clear this condition.
8286			 */
8287			if (sc->bc_state & BCE_CONDITION_DRV_PRESENT) {
8288				sc->bce_drv_cardiac_arrest = FALSE;
8289				BCE_PRINTF("%s(): Bootcode found the "
8290				    "driver pulse! (bc_state = 0x%08X)\n",
8291				    __FUNCTION__, sc->bc_state);
8292			}
8293		}
8294	}
8295
8296	/* Schedule the next pulse. */
8297	callout_reset(&sc->bce_pulse_callout, hz, bce_pulse, sc);
8298
8299	DBEXIT(BCE_EXTREME_MISC);
8300}
8301
8302/****************************************************************************/
8303/* Periodic function to perform maintenance tasks.                          */
8304/*                                                                          */
8305/* Returns:                                                                 */
8306/*   Nothing.                                                               */
8307/****************************************************************************/
8308static void
8309bce_tick(void *xsc)
8310{
8311	struct bce_softc *sc = xsc;
8312	struct mii_data *mii;
8313	if_t ifp;
8314	struct ifmediareq ifmr;
8315
8316	ifp = sc->bce_ifp;
8317
8318	DBENTER(BCE_EXTREME_MISC);
8319
8320	BCE_LOCK_ASSERT(sc);
8321
8322	/* Schedule the next tick. */
8323	callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
8324
8325	/* Update the statistics from the hardware statistics block. */
8326	bce_stats_update(sc);
8327
8328 	/* Ensure page and RX chains get refilled in low-memory situations. */
8329	if (bce_hdr_split == TRUE)
8330		bce_fill_pg_chain(sc);
8331	bce_fill_rx_chain(sc);
8332
8333	/* Check that chip hasn't hung. */
8334	bce_watchdog(sc);
8335
8336	/* If link is up already up then we're done. */
8337	if (sc->bce_link_up == TRUE)
8338		goto bce_tick_exit;
8339
8340	/* Link is down.  Check what the PHY's doing. */
8341	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
8342		bzero(&ifmr, sizeof(ifmr));
8343		bce_ifmedia_sts_rphy(sc, &ifmr);
8344		if ((ifmr.ifm_status & (IFM_ACTIVE | IFM_AVALID)) ==
8345		    (IFM_ACTIVE | IFM_AVALID)) {
8346			sc->bce_link_up = TRUE;
8347			bce_miibus_statchg(sc->bce_dev);
8348		}
8349	} else {
8350		mii = device_get_softc(sc->bce_miibus);
8351		mii_tick(mii);
8352		/* Check if the link has come up. */
8353		if ((mii->mii_media_status & IFM_ACTIVE) &&
8354		    (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)) {
8355			DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Link up!\n",
8356			    __FUNCTION__);
8357			sc->bce_link_up = TRUE;
8358			if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
8359			    IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX ||
8360			    IFM_SUBTYPE(mii->mii_media_active) == IFM_2500_SX) &&
8361			    (bce_verbose || bootverbose))
8362				BCE_PRINTF("Gigabit link up!\n");
8363		}
8364	}
8365	if (sc->bce_link_up == TRUE) {
8366		/* Now that link is up, handle any outstanding TX traffic. */
8367		if (!if_sendq_empty(ifp)) {
8368			DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Found "
8369			    "pending TX traffic.\n", __FUNCTION__);
8370			bce_start_locked(ifp);
8371		}
8372	}
8373
8374bce_tick_exit:
8375	DBEXIT(BCE_EXTREME_MISC);
8376}
8377
8378static void
8379bce_fw_cap_init(struct bce_softc *sc)
8380{
8381	u32 ack, cap, link;
8382
8383	ack = 0;
8384	cap = bce_shmem_rd(sc, BCE_FW_CAP_MB);
8385	if ((cap & BCE_FW_CAP_SIGNATURE_MAGIC_MASK) !=
8386	    BCE_FW_CAP_SIGNATURE_MAGIC)
8387		return;
8388	if ((cap & (BCE_FW_CAP_MFW_KEEP_VLAN | BCE_FW_CAP_BC_KEEP_VLAN)) ==
8389	    (BCE_FW_CAP_MFW_KEEP_VLAN | BCE_FW_CAP_BC_KEEP_VLAN))
8390		ack |= BCE_DRV_ACK_CAP_SIGNATURE_MAGIC |
8391		    BCE_FW_CAP_MFW_KEEP_VLAN | BCE_FW_CAP_BC_KEEP_VLAN;
8392	if ((sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) != 0 &&
8393	    (cap & BCE_FW_CAP_REMOTE_PHY_CAP) != 0) {
8394		sc->bce_phy_flags &= ~BCE_PHY_REMOTE_PORT_FIBER_FLAG;
8395		sc->bce_phy_flags |= BCE_PHY_REMOTE_CAP_FLAG;
8396		link = bce_shmem_rd(sc, BCE_LINK_STATUS);
8397		if ((link & BCE_LINK_STATUS_SERDES_LINK) != 0)
8398			sc->bce_phy_flags |= BCE_PHY_REMOTE_PORT_FIBER_FLAG;
8399		ack |= BCE_DRV_ACK_CAP_SIGNATURE_MAGIC |
8400		    BCE_FW_CAP_REMOTE_PHY_CAP;
8401	}
8402
8403	if (ack != 0)
8404		bce_shmem_wr(sc, BCE_DRV_ACK_CAP_MB, ack);
8405}
8406
8407#ifdef BCE_DEBUG
8408/****************************************************************************/
8409/* Allows the driver state to be dumped through the sysctl interface.       */
8410/*                                                                          */
8411/* Returns:                                                                 */
8412/*   0 for success, positive value for failure.                             */
8413/****************************************************************************/
8414static int
8415bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS)
8416{
8417	int error;
8418	int result;
8419	struct bce_softc *sc;
8420
8421	result = -1;
8422	error = sysctl_handle_int(oidp, &result, 0, req);
8423
8424	if (error || !req->newptr)
8425		return (error);
8426
8427	if (result == 1) {
8428		sc = (struct bce_softc *)arg1;
8429		bce_dump_driver_state(sc);
8430	}
8431
8432	return error;
8433}
8434
8435/****************************************************************************/
8436/* Allows the hardware state to be dumped through the sysctl interface.     */
8437/*                                                                          */
8438/* Returns:                                                                 */
8439/*   0 for success, positive value for failure.                             */
8440/****************************************************************************/
8441static int
8442bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS)
8443{
8444	int error;
8445	int result;
8446	struct bce_softc *sc;
8447
8448	result = -1;
8449	error = sysctl_handle_int(oidp, &result, 0, req);
8450
8451	if (error || !req->newptr)
8452		return (error);
8453
8454	if (result == 1) {
8455		sc = (struct bce_softc *)arg1;
8456		bce_dump_hw_state(sc);
8457	}
8458
8459	return error;
8460}
8461
8462/****************************************************************************/
8463/* Allows the status block to be dumped through the sysctl interface.       */
8464/*                                                                          */
8465/* Returns:                                                                 */
8466/*   0 for success, positive value for failure.                             */
8467/****************************************************************************/
8468static int
8469bce_sysctl_status_block(SYSCTL_HANDLER_ARGS)
8470{
8471	int error;
8472	int result;
8473	struct bce_softc *sc;
8474
8475	result = -1;
8476	error = sysctl_handle_int(oidp, &result, 0, req);
8477
8478	if (error || !req->newptr)
8479		return (error);
8480
8481	if (result == 1) {
8482		sc = (struct bce_softc *)arg1;
8483		bce_dump_status_block(sc);
8484	}
8485
8486	return error;
8487}
8488
8489/****************************************************************************/
8490/* Allows the stats block to be dumped through the sysctl interface.        */
8491/*                                                                          */
8492/* Returns:                                                                 */
8493/*   0 for success, positive value for failure.                             */
8494/****************************************************************************/
8495static int
8496bce_sysctl_stats_block(SYSCTL_HANDLER_ARGS)
8497{
8498	int error;
8499	int result;
8500	struct bce_softc *sc;
8501
8502	result = -1;
8503	error = sysctl_handle_int(oidp, &result, 0, req);
8504
8505	if (error || !req->newptr)
8506		return (error);
8507
8508	if (result == 1) {
8509		sc = (struct bce_softc *)arg1;
8510		bce_dump_stats_block(sc);
8511	}
8512
8513	return error;
8514}
8515
8516/****************************************************************************/
8517/* Allows the stat counters to be cleared without unloading/reloading the   */
8518/* driver.                                                                  */
8519/*                                                                          */
8520/* Returns:                                                                 */
8521/*   0 for success, positive value for failure.                             */
8522/****************************************************************************/
8523static int
8524bce_sysctl_stats_clear(SYSCTL_HANDLER_ARGS)
8525{
8526	int error;
8527	int result;
8528	struct bce_softc *sc;
8529
8530	result = -1;
8531	error = sysctl_handle_int(oidp, &result, 0, req);
8532
8533	if (error || !req->newptr)
8534		return (error);
8535
8536	if (result == 1) {
8537		sc = (struct bce_softc *)arg1;
8538		struct statistics_block *stats;
8539
8540		stats = (struct statistics_block *) sc->stats_block;
8541		bzero(stats, sizeof(struct statistics_block));
8542		bus_dmamap_sync(sc->stats_tag, sc->stats_map,
8543		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
8544
8545		/* Clear the internal H/W statistics counters. */
8546		REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
8547
8548		/* Reset the driver maintained statistics. */
8549		sc->interrupts_rx =
8550		    sc->interrupts_tx = 0;
8551		sc->tso_frames_requested =
8552		    sc->tso_frames_completed =
8553		    sc->tso_frames_failed = 0;
8554		sc->rx_empty_count =
8555		    sc->tx_full_count = 0;
8556		sc->rx_low_watermark = USABLE_RX_BD_ALLOC;
8557		sc->tx_hi_watermark = 0;
8558		sc->l2fhdr_error_count =
8559		    sc->l2fhdr_error_sim_count = 0;
8560		sc->mbuf_alloc_failed_count =
8561		    sc->mbuf_alloc_failed_sim_count = 0;
8562		sc->dma_map_addr_rx_failed_count =
8563		    sc->dma_map_addr_tx_failed_count = 0;
8564		sc->mbuf_frag_count = 0;
8565		sc->csum_offload_tcp_udp =
8566		    sc->csum_offload_ip = 0;
8567		sc->vlan_tagged_frames_rcvd =
8568		    sc->vlan_tagged_frames_stripped = 0;
8569		sc->split_header_frames_rcvd =
8570		    sc->split_header_tcp_frames_rcvd = 0;
8571
8572		/* Clear firmware maintained statistics. */
8573		REG_WR_IND(sc, 0x120084, 0);
8574	}
8575
8576	return error;
8577}
8578
8579/****************************************************************************/
8580/* Allows the shared memory contents to be dumped through the sysctl  .     */
8581/* interface.                                                               */
8582/*                                                                          */
8583/* Returns:                                                                 */
8584/*   0 for success, positive value for failure.                             */
8585/****************************************************************************/
8586static int
8587bce_sysctl_shmem_state(SYSCTL_HANDLER_ARGS)
8588{
8589	int error;
8590	int result;
8591	struct bce_softc *sc;
8592
8593	result = -1;
8594	error = sysctl_handle_int(oidp, &result, 0, req);
8595
8596	if (error || !req->newptr)
8597		return (error);
8598
8599	if (result == 1) {
8600		sc = (struct bce_softc *)arg1;
8601		bce_dump_shmem_state(sc);
8602	}
8603
8604	return error;
8605}
8606
8607/****************************************************************************/
8608/* Allows the bootcode state to be dumped through the sysctl interface.     */
8609/*                                                                          */
8610/* Returns:                                                                 */
8611/*   0 for success, positive value for failure.                             */
8612/****************************************************************************/
8613static int
8614bce_sysctl_bc_state(SYSCTL_HANDLER_ARGS)
8615{
8616	int error;
8617	int result;
8618	struct bce_softc *sc;
8619
8620	result = -1;
8621	error = sysctl_handle_int(oidp, &result, 0, req);
8622
8623	if (error || !req->newptr)
8624		return (error);
8625
8626	if (result == 1) {
8627		sc = (struct bce_softc *)arg1;
8628		bce_dump_bc_state(sc);
8629	}
8630
8631	return error;
8632}
8633
8634/****************************************************************************/
8635/* Provides a sysctl interface to allow dumping the RX BD chain.            */
8636/*                                                                          */
8637/* Returns:                                                                 */
8638/*   0 for success, positive value for failure.                             */
8639/****************************************************************************/
8640static int
8641bce_sysctl_dump_rx_bd_chain(SYSCTL_HANDLER_ARGS)
8642{
8643	int error;
8644	int result;
8645	struct bce_softc *sc;
8646
8647	result = -1;
8648	error = sysctl_handle_int(oidp, &result, 0, req);
8649
8650	if (error || !req->newptr)
8651		return (error);
8652
8653	if (result == 1) {
8654		sc = (struct bce_softc *)arg1;
8655		bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD_ALLOC);
8656	}
8657
8658	return error;
8659}
8660
8661/****************************************************************************/
8662/* Provides a sysctl interface to allow dumping the RX MBUF chain.          */
8663/*                                                                          */
8664/* Returns:                                                                 */
8665/*   0 for success, positive value for failure.                             */
8666/****************************************************************************/
8667static int
8668bce_sysctl_dump_rx_mbuf_chain(SYSCTL_HANDLER_ARGS)
8669{
8670	int error;
8671	int result;
8672	struct bce_softc *sc;
8673
8674	result = -1;
8675	error = sysctl_handle_int(oidp, &result, 0, req);
8676
8677	if (error || !req->newptr)
8678		return (error);
8679
8680	if (result == 1) {
8681		sc = (struct bce_softc *)arg1;
8682		bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD_ALLOC);
8683	}
8684
8685	return error;
8686}
8687
8688/****************************************************************************/
8689/* Provides a sysctl interface to allow dumping the TX chain.               */
8690/*                                                                          */
8691/* Returns:                                                                 */
8692/*   0 for success, positive value for failure.                             */
8693/****************************************************************************/
8694static int
8695bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
8696{
8697	int error;
8698	int result;
8699	struct bce_softc *sc;
8700
8701	result = -1;
8702	error = sysctl_handle_int(oidp, &result, 0, req);
8703
8704	if (error || !req->newptr)
8705		return (error);
8706
8707	if (result == 1) {
8708		sc = (struct bce_softc *)arg1;
8709		bce_dump_tx_chain(sc, 0, TOTAL_TX_BD_ALLOC);
8710	}
8711
8712	return error;
8713}
8714
8715/****************************************************************************/
8716/* Provides a sysctl interface to allow dumping the page chain.             */
8717/*                                                                          */
8718/* Returns:                                                                 */
8719/*   0 for success, positive value for failure.                             */
8720/****************************************************************************/
8721static int
8722bce_sysctl_dump_pg_chain(SYSCTL_HANDLER_ARGS)
8723{
8724	int error;
8725	int result;
8726	struct bce_softc *sc;
8727
8728	result = -1;
8729	error = sysctl_handle_int(oidp, &result, 0, req);
8730
8731	if (error || !req->newptr)
8732		return (error);
8733
8734	if (result == 1) {
8735		sc = (struct bce_softc *)arg1;
8736		bce_dump_pg_chain(sc, 0, TOTAL_PG_BD_ALLOC);
8737	}
8738
8739	return error;
8740}
8741
8742/****************************************************************************/
8743/* Provides a sysctl interface to allow reading arbitrary NVRAM offsets in  */
8744/* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
8745/*                                                                          */
8746/* Returns:                                                                 */
8747/*   0 for success, positive value for failure.                             */
8748/****************************************************************************/
8749static int
8750bce_sysctl_nvram_read(SYSCTL_HANDLER_ARGS)
8751{
8752	struct bce_softc *sc = (struct bce_softc *)arg1;
8753	int error;
8754	u32 result;
8755	u32 val[1];
8756	u8 *data = (u8 *) val;
8757
8758	result = -1;
8759	error = sysctl_handle_int(oidp, &result, 0, req);
8760	if (error || (req->newptr == NULL))
8761		return (error);
8762
8763	error = bce_nvram_read(sc, result, data, 4);
8764
8765	BCE_PRINTF("offset 0x%08X = 0x%08X\n", result, bce_be32toh(val[0]));
8766
8767	return (error);
8768}
8769
8770/****************************************************************************/
8771/* Provides a sysctl interface to allow reading arbitrary registers in the  */
8772/* device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                            */
8773/*                                                                          */
8774/* Returns:                                                                 */
8775/*   0 for success, positive value for failure.                             */
8776/****************************************************************************/
8777static int
8778bce_sysctl_reg_read(SYSCTL_HANDLER_ARGS)
8779{
8780	struct bce_softc *sc = (struct bce_softc *)arg1;
8781	int error;
8782	u32 val, result;
8783
8784	result = -1;
8785	error = sysctl_handle_int(oidp, &result, 0, req);
8786	if (error || (req->newptr == NULL))
8787		return (error);
8788
8789	/* Make sure the register is accessible. */
8790	if (result < 0x8000) {
8791		val = REG_RD(sc, result);
8792		BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
8793	} else if (result < 0x0280000) {
8794		val = REG_RD_IND(sc, result);
8795		BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
8796	}
8797
8798	return (error);
8799}
8800
8801/****************************************************************************/
8802/* Provides a sysctl interface to allow reading arbitrary PHY registers in  */
8803/* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
8804/*                                                                          */
8805/* Returns:                                                                 */
8806/*   0 for success, positive value for failure.                             */
8807/****************************************************************************/
8808static int
8809bce_sysctl_phy_read(SYSCTL_HANDLER_ARGS)
8810{
8811	struct bce_softc *sc;
8812	device_t dev;
8813	int error, result;
8814	u16 val;
8815
8816	result = -1;
8817	error = sysctl_handle_int(oidp, &result, 0, req);
8818	if (error || (req->newptr == NULL))
8819		return (error);
8820
8821	/* Make sure the register is accessible. */
8822	if (result < 0x20) {
8823		sc = (struct bce_softc *)arg1;
8824		dev = sc->bce_dev;
8825		val = bce_miibus_read_reg(dev, sc->bce_phy_addr, result);
8826		BCE_PRINTF("phy 0x%02X = 0x%04X\n", result, val);
8827	}
8828	return (error);
8829}
8830
8831/****************************************************************************/
8832/* Provides a sysctl interface for dumping the nvram contents.              */
8833/* DO NOT ENABLE ON PRODUCTION SYSTEMS!					    */
8834/*									    */
8835/* Returns:								    */
8836/*   0 for success, positive errno for failure.				    */
8837/****************************************************************************/
8838static int
8839bce_sysctl_nvram_dump(SYSCTL_HANDLER_ARGS)
8840{
8841	struct bce_softc *sc = (struct bce_softc *)arg1;
8842	int error, i;
8843
8844	if (sc->nvram_buf == NULL)
8845		sc->nvram_buf = malloc(sc->bce_flash_size,
8846				    M_TEMP, M_ZERO | M_WAITOK);
8847
8848	error = 0;
8849	if (req->oldlen == sc->bce_flash_size) {
8850		for (i = 0; i < sc->bce_flash_size && error == 0; i++)
8851			error = bce_nvram_read(sc, i, &sc->nvram_buf[i], 1);
8852	}
8853
8854	if (error == 0)
8855		error = SYSCTL_OUT(req, sc->nvram_buf, sc->bce_flash_size);
8856
8857	return error;
8858}
8859
8860#ifdef BCE_NVRAM_WRITE_SUPPORT
8861/****************************************************************************/
8862/* Provides a sysctl interface for writing to nvram.                        */
8863/* DO NOT ENABLE ON PRODUCTION SYSTEMS!					    */
8864/*									    */
8865/* Returns:								    */
8866/*   0 for success, positive errno for failure.				    */
8867/****************************************************************************/
8868static int
8869bce_sysctl_nvram_write(SYSCTL_HANDLER_ARGS)
8870{
8871	struct bce_softc *sc = (struct bce_softc *)arg1;
8872	int error;
8873
8874	if (sc->nvram_buf == NULL)
8875		sc->nvram_buf = malloc(sc->bce_flash_size,
8876				    M_TEMP, M_ZERO | M_WAITOK);
8877	else
8878		bzero(sc->nvram_buf, sc->bce_flash_size);
8879
8880	error = SYSCTL_IN(req, sc->nvram_buf, sc->bce_flash_size);
8881	if (error == 0)
8882		return (error);
8883
8884	if (req->newlen == sc->bce_flash_size)
8885		error = bce_nvram_write(sc, 0, sc->nvram_buf,
8886			    sc->bce_flash_size);
8887
8888	return error;
8889}
8890#endif
8891
8892/****************************************************************************/
8893/* Provides a sysctl interface to allow reading a CID.                      */
8894/*                                                                          */
8895/* Returns:                                                                 */
8896/*   0 for success, positive value for failure.                             */
8897/****************************************************************************/
8898static int
8899bce_sysctl_dump_ctx(SYSCTL_HANDLER_ARGS)
8900{
8901	struct bce_softc *sc;
8902	int error, result;
8903
8904	result = -1;
8905	error = sysctl_handle_int(oidp, &result, 0, req);
8906	if (error || (req->newptr == NULL))
8907		return (error);
8908
8909	/* Make sure the register is accessible. */
8910	if (result <= TX_CID) {
8911		sc = (struct bce_softc *)arg1;
8912		bce_dump_ctx(sc, result);
8913	}
8914
8915	return (error);
8916}
8917
8918/****************************************************************************/
8919/* Provides a sysctl interface to forcing the driver to dump state and      */
8920/* enter the debugger.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                */
8921/*                                                                          */
8922/* Returns:                                                                 */
8923/*   0 for success, positive value for failure.                             */
8924/****************************************************************************/
8925static int
8926bce_sysctl_breakpoint(SYSCTL_HANDLER_ARGS)
8927{
8928	int error;
8929	int result;
8930	struct bce_softc *sc;
8931
8932	result = -1;
8933	error = sysctl_handle_int(oidp, &result, 0, req);
8934
8935	if (error || !req->newptr)
8936		return (error);
8937
8938	if (result == 1) {
8939		sc = (struct bce_softc *)arg1;
8940		bce_breakpoint(sc);
8941	}
8942
8943	return error;
8944}
8945#endif
8946
8947/****************************************************************************/
8948/* Adds any sysctl parameters for tuning or debugging purposes.             */
8949/*                                                                          */
8950/* Returns:                                                                 */
8951/*   0 for success, positive value for failure.                             */
8952/****************************************************************************/
8953static void
8954bce_add_sysctls(struct bce_softc *sc)
8955{
8956	struct sysctl_ctx_list *ctx;
8957	struct sysctl_oid_list *children;
8958
8959	DBENTER(BCE_VERBOSE_MISC);
8960
8961	ctx = device_get_sysctl_ctx(sc->bce_dev);
8962	children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->bce_dev));
8963
8964#ifdef BCE_DEBUG
8965	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8966	    "l2fhdr_error_sim_control",
8967	    CTLFLAG_RW, &l2fhdr_error_sim_control,
8968	    0, "Debug control to force l2fhdr errors");
8969
8970	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8971	    "l2fhdr_error_sim_count",
8972	    CTLFLAG_RD, &sc->l2fhdr_error_sim_count,
8973	    0, "Number of simulated l2_fhdr errors");
8974#endif
8975
8976	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8977	    "l2fhdr_error_count",
8978	    CTLFLAG_RD, &sc->l2fhdr_error_count,
8979	    0, "Number of l2_fhdr errors");
8980
8981#ifdef BCE_DEBUG
8982	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
8983	    "mbuf_alloc_failed_sim_control",
8984	    CTLFLAG_RW, &mbuf_alloc_failed_sim_control,
8985	    0, "Debug control to force mbuf allocation failures");
8986
8987	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8988	    "mbuf_alloc_failed_sim_count",
8989	    CTLFLAG_RD, &sc->mbuf_alloc_failed_sim_count,
8990	    0, "Number of simulated mbuf cluster allocation failures");
8991#endif
8992
8993	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8994	    "mbuf_alloc_failed_count",
8995	    CTLFLAG_RD, &sc->mbuf_alloc_failed_count,
8996	    0, "Number of mbuf allocation failures");
8997
8998	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
8999	    "mbuf_frag_count",
9000	    CTLFLAG_RD, &sc->mbuf_frag_count,
9001	    0, "Number of fragmented mbufs");
9002
9003#ifdef BCE_DEBUG
9004	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
9005	    "dma_map_addr_failed_sim_control",
9006	    CTLFLAG_RW, &dma_map_addr_failed_sim_control,
9007	    0, "Debug control to force DMA mapping failures");
9008
9009	/* ToDo: Figure out how to update this value in bce_dma_map_addr(). */
9010	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9011	    "dma_map_addr_failed_sim_count",
9012	    CTLFLAG_RD, &sc->dma_map_addr_failed_sim_count,
9013	    0, "Number of simulated DMA mapping failures");
9014
9015#endif
9016
9017	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9018	    "dma_map_addr_rx_failed_count",
9019	    CTLFLAG_RD, &sc->dma_map_addr_rx_failed_count,
9020	    0, "Number of RX DMA mapping failures");
9021
9022	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9023	    "dma_map_addr_tx_failed_count",
9024	    CTLFLAG_RD, &sc->dma_map_addr_tx_failed_count,
9025	    0, "Number of TX DMA mapping failures");
9026
9027#ifdef BCE_DEBUG
9028	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
9029	    "unexpected_attention_sim_control",
9030	    CTLFLAG_RW, &unexpected_attention_sim_control,
9031	    0, "Debug control to simulate unexpected attentions");
9032
9033	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9034	    "unexpected_attention_sim_count",
9035	    CTLFLAG_RW, &sc->unexpected_attention_sim_count,
9036	    0, "Number of simulated unexpected attentions");
9037#endif
9038
9039	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9040	    "unexpected_attention_count",
9041	    CTLFLAG_RW, &sc->unexpected_attention_count,
9042	    0, "Number of unexpected attentions");
9043
9044#ifdef BCE_DEBUG
9045	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
9046	    "debug_bootcode_running_failure",
9047	    CTLFLAG_RW, &bootcode_running_failure_sim_control,
9048	    0, "Debug control to force bootcode running failures");
9049
9050	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
9051	    "rx_low_watermark",
9052	    CTLFLAG_RD, &sc->rx_low_watermark,
9053	    0, "Lowest level of free rx_bd's");
9054
9055	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9056	    "rx_empty_count",
9057	    CTLFLAG_RD, &sc->rx_empty_count,
9058	    "Number of times the RX chain was empty");
9059
9060	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
9061	    "tx_hi_watermark",
9062	    CTLFLAG_RD, &sc->tx_hi_watermark,
9063	    0, "Highest level of used tx_bd's");
9064
9065	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9066	    "tx_full_count",
9067	    CTLFLAG_RD, &sc->tx_full_count,
9068	    "Number of times the TX chain was full");
9069
9070	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9071	    "tso_frames_requested",
9072	    CTLFLAG_RD, &sc->tso_frames_requested,
9073	    "Number of TSO frames requested");
9074
9075	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9076	    "tso_frames_completed",
9077	    CTLFLAG_RD, &sc->tso_frames_completed,
9078	    "Number of TSO frames completed");
9079
9080	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9081	    "tso_frames_failed",
9082	    CTLFLAG_RD, &sc->tso_frames_failed,
9083	    "Number of TSO frames failed");
9084
9085	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9086	    "csum_offload_ip",
9087	    CTLFLAG_RD, &sc->csum_offload_ip,
9088	    "Number of IP checksum offload frames");
9089
9090	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9091	    "csum_offload_tcp_udp",
9092	    CTLFLAG_RD, &sc->csum_offload_tcp_udp,
9093	    "Number of TCP/UDP checksum offload frames");
9094
9095	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9096	    "vlan_tagged_frames_rcvd",
9097	    CTLFLAG_RD, &sc->vlan_tagged_frames_rcvd,
9098	    "Number of VLAN tagged frames received");
9099
9100	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9101	    "vlan_tagged_frames_stripped",
9102	    CTLFLAG_RD, &sc->vlan_tagged_frames_stripped,
9103	    "Number of VLAN tagged frames stripped");
9104
9105	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9106	    "interrupts_rx",
9107	    CTLFLAG_RD, &sc->interrupts_rx,
9108	    "Number of RX interrupts");
9109
9110	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9111	    "interrupts_tx",
9112	    CTLFLAG_RD, &sc->interrupts_tx,
9113	    "Number of TX interrupts");
9114
9115	if (bce_hdr_split == TRUE) {
9116		SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9117		    "split_header_frames_rcvd",
9118		    CTLFLAG_RD, &sc->split_header_frames_rcvd,
9119		    "Number of split header frames received");
9120
9121		SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9122		    "split_header_tcp_frames_rcvd",
9123		    CTLFLAG_RD, &sc->split_header_tcp_frames_rcvd,
9124		    "Number of split header TCP frames received");
9125	}
9126
9127	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9128	    "nvram_dump", CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
9129	    (void *)sc, 0,
9130	    bce_sysctl_nvram_dump, "S", "");
9131
9132#ifdef BCE_NVRAM_WRITE_SUPPORT
9133	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9134	    "nvram_write", CTLTYPE_OPAQUE | CTLFLAG_WR | CTLFLAG_NEEDGIANT,
9135	    (void *)sc, 0,
9136	    bce_sysctl_nvram_write, "S", "");
9137#endif
9138#endif /* BCE_DEBUG */
9139
9140	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9141	    "stat_IfHcInOctets",
9142	    CTLFLAG_RD, &sc->stat_IfHCInOctets,
9143	    "Bytes received");
9144
9145	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9146	    "stat_IfHCInBadOctets",
9147	    CTLFLAG_RD, &sc->stat_IfHCInBadOctets,
9148	    "Bad bytes received");
9149
9150	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9151	    "stat_IfHCOutOctets",
9152	    CTLFLAG_RD, &sc->stat_IfHCOutOctets,
9153	    "Bytes sent");
9154
9155	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9156	    "stat_IfHCOutBadOctets",
9157	    CTLFLAG_RD, &sc->stat_IfHCOutBadOctets,
9158	    "Bad bytes sent");
9159
9160	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9161	    "stat_IfHCInUcastPkts",
9162	    CTLFLAG_RD, &sc->stat_IfHCInUcastPkts,
9163	    "Unicast packets received");
9164
9165	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9166	    "stat_IfHCInMulticastPkts",
9167	    CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts,
9168	    "Multicast packets received");
9169
9170	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9171	    "stat_IfHCInBroadcastPkts",
9172	    CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts,
9173	    "Broadcast packets received");
9174
9175	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9176	    "stat_IfHCOutUcastPkts",
9177	    CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts,
9178	    "Unicast packets sent");
9179
9180	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9181	    "stat_IfHCOutMulticastPkts",
9182	    CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts,
9183	    "Multicast packets sent");
9184
9185	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9186	    "stat_IfHCOutBroadcastPkts",
9187	    CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts,
9188	    "Broadcast packets sent");
9189
9190	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9191	    "stat_emac_tx_stat_dot3statsinternalmactransmiterrors",
9192	    CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors,
9193	    0, "Internal MAC transmit errors");
9194
9195	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9196	    "stat_Dot3StatsCarrierSenseErrors",
9197	    CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors,
9198	    0, "Carrier sense errors");
9199
9200	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9201	    "stat_Dot3StatsFCSErrors",
9202	    CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors,
9203	    0, "Frame check sequence errors");
9204
9205	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9206	    "stat_Dot3StatsAlignmentErrors",
9207	    CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors,
9208	    0, "Alignment errors");
9209
9210	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9211	    "stat_Dot3StatsSingleCollisionFrames",
9212	    CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames,
9213	    0, "Single Collision Frames");
9214
9215	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9216	    "stat_Dot3StatsMultipleCollisionFrames",
9217	    CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames,
9218	    0, "Multiple Collision Frames");
9219
9220	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9221	    "stat_Dot3StatsDeferredTransmissions",
9222	    CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions,
9223	    0, "Deferred Transmissions");
9224
9225	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9226	    "stat_Dot3StatsExcessiveCollisions",
9227	    CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions,
9228	    0, "Excessive Collisions");
9229
9230	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9231	    "stat_Dot3StatsLateCollisions",
9232	    CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions,
9233	    0, "Late Collisions");
9234
9235	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9236	    "stat_EtherStatsCollisions",
9237	    CTLFLAG_RD, &sc->stat_EtherStatsCollisions,
9238	    0, "Collisions");
9239
9240	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9241	    "stat_EtherStatsFragments",
9242	    CTLFLAG_RD, &sc->stat_EtherStatsFragments,
9243	    0, "Fragments");
9244
9245	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9246	    "stat_EtherStatsJabbers",
9247	    CTLFLAG_RD, &sc->stat_EtherStatsJabbers,
9248	    0, "Jabbers");
9249
9250	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9251	    "stat_EtherStatsUndersizePkts",
9252	    CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts,
9253	    0, "Undersize packets");
9254
9255	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9256	    "stat_EtherStatsOversizePkts",
9257	    CTLFLAG_RD, &sc->stat_EtherStatsOversizePkts,
9258	    0, "stat_EtherStatsOversizePkts");
9259
9260	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9261	    "stat_EtherStatsPktsRx64Octets",
9262	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets,
9263	    0, "Bytes received in 64 byte packets");
9264
9265	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9266	    "stat_EtherStatsPktsRx65Octetsto127Octets",
9267	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets,
9268	    0, "Bytes received in 65 to 127 byte packets");
9269
9270	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9271	    "stat_EtherStatsPktsRx128Octetsto255Octets",
9272	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets,
9273	    0, "Bytes received in 128 to 255 byte packets");
9274
9275	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9276	    "stat_EtherStatsPktsRx256Octetsto511Octets",
9277	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets,
9278	    0, "Bytes received in 256 to 511 byte packets");
9279
9280	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9281	    "stat_EtherStatsPktsRx512Octetsto1023Octets",
9282	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets,
9283	    0, "Bytes received in 512 to 1023 byte packets");
9284
9285	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9286	    "stat_EtherStatsPktsRx1024Octetsto1522Octets",
9287	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets,
9288	    0, "Bytes received in 1024 t0 1522 byte packets");
9289
9290	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9291	    "stat_EtherStatsPktsRx1523Octetsto9022Octets",
9292	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets,
9293	    0, "Bytes received in 1523 to 9022 byte packets");
9294
9295	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9296	    "stat_EtherStatsPktsTx64Octets",
9297	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets,
9298	    0, "Bytes sent in 64 byte packets");
9299
9300	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9301	    "stat_EtherStatsPktsTx65Octetsto127Octets",
9302	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets,
9303	    0, "Bytes sent in 65 to 127 byte packets");
9304
9305	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9306	    "stat_EtherStatsPktsTx128Octetsto255Octets",
9307	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets,
9308	    0, "Bytes sent in 128 to 255 byte packets");
9309
9310	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9311	    "stat_EtherStatsPktsTx256Octetsto511Octets",
9312	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets,
9313	    0, "Bytes sent in 256 to 511 byte packets");
9314
9315	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9316	    "stat_EtherStatsPktsTx512Octetsto1023Octets",
9317	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets,
9318	    0, "Bytes sent in 512 to 1023 byte packets");
9319
9320	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9321	    "stat_EtherStatsPktsTx1024Octetsto1522Octets",
9322	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets,
9323	    0, "Bytes sent in 1024 to 1522 byte packets");
9324
9325	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9326	    "stat_EtherStatsPktsTx1523Octetsto9022Octets",
9327	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets,
9328	    0, "Bytes sent in 1523 to 9022 byte packets");
9329
9330	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9331	    "stat_XonPauseFramesReceived",
9332	    CTLFLAG_RD, &sc->stat_XonPauseFramesReceived,
9333	    0, "XON pause frames receved");
9334
9335	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9336	    "stat_XoffPauseFramesReceived",
9337	    CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived,
9338	    0, "XOFF pause frames received");
9339
9340	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9341	    "stat_OutXonSent",
9342	    CTLFLAG_RD, &sc->stat_OutXonSent,
9343	    0, "XON pause frames sent");
9344
9345	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9346	    "stat_OutXoffSent",
9347	    CTLFLAG_RD, &sc->stat_OutXoffSent,
9348	    0, "XOFF pause frames sent");
9349
9350	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9351	    "stat_FlowControlDone",
9352	    CTLFLAG_RD, &sc->stat_FlowControlDone,
9353	    0, "Flow control done");
9354
9355	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9356	    "stat_MacControlFramesReceived",
9357	    CTLFLAG_RD, &sc->stat_MacControlFramesReceived,
9358	    0, "MAC control frames received");
9359
9360	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9361	    "stat_XoffStateEntered",
9362	    CTLFLAG_RD, &sc->stat_XoffStateEntered,
9363	    0, "XOFF state entered");
9364
9365	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9366	    "stat_IfInFramesL2FilterDiscards",
9367	    CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards,
9368	    0, "Received L2 packets discarded");
9369
9370	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9371	    "stat_IfInRuleCheckerDiscards",
9372	    CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards,
9373	    0, "Received packets discarded by rule");
9374
9375	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9376	    "stat_IfInFTQDiscards",
9377	    CTLFLAG_RD, &sc->stat_IfInFTQDiscards,
9378	    0, "Received packet FTQ discards");
9379
9380	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9381	    "stat_IfInMBUFDiscards",
9382	    CTLFLAG_RD, &sc->stat_IfInMBUFDiscards,
9383	    0, "Received packets discarded due to lack "
9384	    "of controller buffer memory");
9385
9386	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9387	    "stat_IfInRuleCheckerP4Hit",
9388	    CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit,
9389	    0, "Received packets rule checker hits");
9390
9391	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9392	    "stat_CatchupInRuleCheckerDiscards",
9393	    CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards,
9394	    0, "Received packets discarded in Catchup path");
9395
9396	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9397	    "stat_CatchupInFTQDiscards",
9398	    CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards,
9399	    0, "Received packets discarded in FTQ in Catchup path");
9400
9401	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9402	    "stat_CatchupInMBUFDiscards",
9403	    CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards,
9404	    0, "Received packets discarded in controller "
9405	    "buffer memory in Catchup path");
9406
9407	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9408	    "stat_CatchupInRuleCheckerP4Hit",
9409	    CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit,
9410	    0, "Received packets rule checker hits in Catchup path");
9411
9412	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9413	    "com_no_buffers",
9414	    CTLFLAG_RD, &sc->com_no_buffers,
9415	    0, "Valid packets received but no RX buffers available");
9416
9417#ifdef BCE_DEBUG
9418	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9419	    "driver_state", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9420	    (void *)sc, 0,
9421	    bce_sysctl_driver_state, "I", "Drive state information");
9422
9423	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9424	    "hw_state", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9425	    (void *)sc, 0,
9426	    bce_sysctl_hw_state, "I", "Hardware state information");
9427
9428	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9429	    "status_block", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9430	    (void *)sc, 0,
9431	    bce_sysctl_status_block, "I", "Dump status block");
9432
9433	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9434	    "stats_block", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9435	    (void *)sc, 0,
9436	    bce_sysctl_stats_block, "I", "Dump statistics block");
9437
9438	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9439	    "stats_clear", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9440	    (void *)sc, 0,
9441	    bce_sysctl_stats_clear, "I", "Clear statistics block");
9442
9443	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9444	    "shmem_state", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9445	    (void *)sc, 0,
9446	    bce_sysctl_shmem_state, "I", "Shared memory state information");
9447
9448	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9449	    "bc_state", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9450	    (void *)sc, 0,
9451	    bce_sysctl_bc_state, "I", "Bootcode state information");
9452
9453	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9454	    "dump_rx_bd_chain", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9455	    (void *)sc, 0,
9456	    bce_sysctl_dump_rx_bd_chain, "I", "Dump RX BD chain");
9457
9458	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9459	    "dump_rx_mbuf_chain", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9460	    (void *)sc, 0,
9461	    bce_sysctl_dump_rx_mbuf_chain, "I", "Dump RX MBUF chain");
9462
9463	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9464	    "dump_tx_chain", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9465	    (void *)sc, 0,
9466	    bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
9467
9468	if (bce_hdr_split == TRUE) {
9469		SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9470		    "dump_pg_chain",
9471		    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9472		    (void *)sc, 0,
9473		    bce_sysctl_dump_pg_chain, "I", "Dump page chain");
9474	}
9475
9476	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9477	    "dump_ctx", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9478	    (void *)sc, 0,
9479	    bce_sysctl_dump_ctx, "I", "Dump context memory");
9480
9481	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9482	    "breakpoint", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9483	    (void *)sc, 0,
9484	    bce_sysctl_breakpoint, "I", "Driver breakpoint");
9485
9486	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9487	    "reg_read", CTLTYPE_INT | CTLFLAG_RW| CTLFLAG_NEEDGIANT,
9488	    (void *)sc, 0,
9489	    bce_sysctl_reg_read, "I", "Register read");
9490
9491	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9492	    "nvram_read", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9493	    (void *)sc, 0,
9494	    bce_sysctl_nvram_read, "I", "NVRAM read");
9495
9496	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9497	    "phy_read", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
9498	    (void *)sc, 0,
9499	    bce_sysctl_phy_read, "I", "PHY register read");
9500
9501#endif
9502
9503	DBEXIT(BCE_VERBOSE_MISC);
9504}
9505
9506/****************************************************************************/
9507/* BCE Debug Routines                                                       */
9508/****************************************************************************/
9509#ifdef BCE_DEBUG
9510
9511/****************************************************************************/
9512/* Freezes the controller to allow for a cohesive state dump.               */
9513/*                                                                          */
9514/* Returns:                                                                 */
9515/*   Nothing.                                                               */
9516/****************************************************************************/
9517static __attribute__ ((noinline)) void
9518bce_freeze_controller(struct bce_softc *sc)
9519{
9520	u32 val;
9521	val = REG_RD(sc, BCE_MISC_COMMAND);
9522	val |= BCE_MISC_COMMAND_DISABLE_ALL;
9523	REG_WR(sc, BCE_MISC_COMMAND, val);
9524}
9525
9526/****************************************************************************/
9527/* Unfreezes the controller after a freeze operation.  This may not always  */
9528/* work and the controller will require a reset!                            */
9529/*                                                                          */
9530/* Returns:                                                                 */
9531/*   Nothing.                                                               */
9532/****************************************************************************/
9533static __attribute__ ((noinline)) void
9534bce_unfreeze_controller(struct bce_softc *sc)
9535{
9536	u32 val;
9537	val = REG_RD(sc, BCE_MISC_COMMAND);
9538	val |= BCE_MISC_COMMAND_ENABLE_ALL;
9539	REG_WR(sc, BCE_MISC_COMMAND, val);
9540}
9541
9542/****************************************************************************/
9543/* Prints out Ethernet frame information from an mbuf.                      */
9544/*                                                                          */
9545/* Partially decode an Ethernet frame to look at some important headers.    */
9546/*                                                                          */
9547/* Returns:                                                                 */
9548/*   Nothing.                                                               */
9549/****************************************************************************/
9550static __attribute__ ((noinline)) void
9551bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
9552{
9553	struct ether_vlan_header *eh;
9554	u16 etype;
9555	int ehlen;
9556	struct ip *ip;
9557	struct tcphdr *th;
9558	struct udphdr *uh;
9559	struct arphdr *ah;
9560
9561	BCE_PRINTF(
9562	    "-----------------------------"
9563	    " Frame Decode "
9564	    "-----------------------------\n");
9565
9566	eh = mtod(m, struct ether_vlan_header *);
9567
9568	/* Handle VLAN encapsulation if present. */
9569	if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
9570		etype = ntohs(eh->evl_proto);
9571		ehlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
9572	} else {
9573		etype = ntohs(eh->evl_encap_proto);
9574		ehlen = ETHER_HDR_LEN;
9575	}
9576
9577	/* ToDo: Add VLAN output. */
9578	BCE_PRINTF("enet: dest = %6D, src = %6D, type = 0x%04X, hlen = %d\n",
9579	    eh->evl_dhost, ":", eh->evl_shost, ":", etype, ehlen);
9580
9581	switch (etype) {
9582	case ETHERTYPE_IP:
9583		ip = (struct ip *)(m->m_data + ehlen);
9584		BCE_PRINTF("--ip: dest = 0x%08X , src = 0x%08X, "
9585		    "len = %d bytes, protocol = 0x%02X, xsum = 0x%04X\n",
9586		    ntohl(ip->ip_dst.s_addr), ntohl(ip->ip_src.s_addr),
9587		    ntohs(ip->ip_len), ip->ip_p, ntohs(ip->ip_sum));
9588
9589		switch (ip->ip_p) {
9590		case IPPROTO_TCP:
9591			th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
9592			BCE_PRINTF("-tcp: dest = %d, src = %d, hlen = "
9593			    "%d bytes, flags = 0x%b, csum = 0x%04X\n",
9594			    ntohs(th->th_dport), ntohs(th->th_sport),
9595			    (th->th_off << 2), th->th_flags,
9596			    "\20\10CWR\07ECE\06URG\05ACK\04PSH\03RST"
9597			    "\02SYN\01FIN", ntohs(th->th_sum));
9598			break;
9599		case IPPROTO_UDP:
9600			uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
9601			BCE_PRINTF("-udp: dest = %d, src = %d, len = %d "
9602			    "bytes, csum = 0x%04X\n", ntohs(uh->uh_dport),
9603			    ntohs(uh->uh_sport), ntohs(uh->uh_ulen),
9604			    ntohs(uh->uh_sum));
9605			break;
9606		case IPPROTO_ICMP:
9607			BCE_PRINTF("icmp:\n");
9608			break;
9609		default:
9610			BCE_PRINTF("----: Other IP protocol.\n");
9611			}
9612		break;
9613	case ETHERTYPE_IPV6:
9614		BCE_PRINTF("ipv6: No decode supported.\n");
9615		break;
9616	case ETHERTYPE_ARP:
9617		BCE_PRINTF("-arp: ");
9618		ah = (struct arphdr *) (m->m_data + ehlen);
9619		switch (ntohs(ah->ar_op)) {
9620		case ARPOP_REVREQUEST:
9621			printf("reverse ARP request\n");
9622			break;
9623		case ARPOP_REVREPLY:
9624			printf("reverse ARP reply\n");
9625			break;
9626		case ARPOP_REQUEST:
9627			printf("ARP request\n");
9628			break;
9629		case ARPOP_REPLY:
9630			printf("ARP reply\n");
9631			break;
9632		default:
9633			printf("other ARP operation\n");
9634		}
9635		break;
9636	default:
9637		BCE_PRINTF("----: Other protocol.\n");
9638	}
9639
9640	BCE_PRINTF(
9641		"-----------------------------"
9642		"--------------"
9643		"-----------------------------\n");
9644}
9645
9646/****************************************************************************/
9647/* Prints out information about an mbuf.                                    */
9648/*                                                                          */
9649/* Returns:                                                                 */
9650/*   Nothing.                                                               */
9651/****************************************************************************/
9652static __attribute__ ((noinline)) void
9653bce_dump_mbuf(struct bce_softc *sc, struct mbuf *m)
9654{
9655	struct mbuf *mp = m;
9656
9657	if (m == NULL) {
9658		BCE_PRINTF("mbuf: null pointer\n");
9659		return;
9660	}
9661
9662	while (mp) {
9663		BCE_PRINTF("mbuf: %p, m_len = %d, m_flags = 0x%b, "
9664		    "m_data = %p\n", mp, mp->m_len, mp->m_flags,
9665		    "\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY", mp->m_data);
9666
9667		if (mp->m_flags & M_PKTHDR) {
9668			BCE_PRINTF("- m_pkthdr: len = %d, flags = 0x%b, "
9669			    "csum_flags = %b\n", mp->m_pkthdr.len,
9670			    mp->m_flags, M_FLAG_PRINTF,
9671			    mp->m_pkthdr.csum_flags, CSUM_BITS);
9672		}
9673
9674		if (mp->m_flags & M_EXT) {
9675			BCE_PRINTF("- m_ext: %p, ext_size = %d, type = ",
9676			    mp->m_ext.ext_buf, mp->m_ext.ext_size);
9677			switch (mp->m_ext.ext_type) {
9678			case EXT_CLUSTER:
9679				printf("EXT_CLUSTER\n"); break;
9680			case EXT_SFBUF:
9681				printf("EXT_SFBUF\n"); break;
9682			case EXT_JUMBO9:
9683				printf("EXT_JUMBO9\n"); break;
9684			case EXT_JUMBO16:
9685				printf("EXT_JUMBO16\n"); break;
9686			case EXT_PACKET:
9687				printf("EXT_PACKET\n"); break;
9688			case EXT_MBUF:
9689				printf("EXT_MBUF\n"); break;
9690			case EXT_NET_DRV:
9691				printf("EXT_NET_DRV\n"); break;
9692			case EXT_MOD_TYPE:
9693				printf("EXT_MDD_TYPE\n"); break;
9694			case EXT_DISPOSABLE:
9695				printf("EXT_DISPOSABLE\n"); break;
9696			case EXT_EXTREF:
9697				printf("EXT_EXTREF\n"); break;
9698			default:
9699				printf("UNKNOWN\n");
9700			}
9701		}
9702
9703		mp = mp->m_next;
9704	}
9705}
9706
9707/****************************************************************************/
9708/* Prints out the mbufs in the TX mbuf chain.                               */
9709/*                                                                          */
9710/* Returns:                                                                 */
9711/*   Nothing.                                                               */
9712/****************************************************************************/
9713static __attribute__ ((noinline)) void
9714bce_dump_tx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
9715{
9716	struct mbuf *m;
9717
9718	BCE_PRINTF(
9719		"----------------------------"
9720		"  tx mbuf data  "
9721		"----------------------------\n");
9722
9723	for (int i = 0; i < count; i++) {
9724	 	m = sc->tx_mbuf_ptr[chain_prod];
9725		BCE_PRINTF("txmbuf[0x%04X]\n", chain_prod);
9726		bce_dump_mbuf(sc, m);
9727		chain_prod = TX_CHAIN_IDX(NEXT_TX_BD(chain_prod));
9728	}
9729
9730	BCE_PRINTF(
9731		"----------------------------"
9732		"----------------"
9733		"----------------------------\n");
9734}
9735
9736/****************************************************************************/
9737/* Prints out the mbufs in the RX mbuf chain.                               */
9738/*                                                                          */
9739/* Returns:                                                                 */
9740/*   Nothing.                                                               */
9741/****************************************************************************/
9742static __attribute__ ((noinline)) void
9743bce_dump_rx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
9744{
9745	struct mbuf *m;
9746
9747	BCE_PRINTF(
9748		"----------------------------"
9749		"  rx mbuf data  "
9750		"----------------------------\n");
9751
9752	for (int i = 0; i < count; i++) {
9753	 	m = sc->rx_mbuf_ptr[chain_prod];
9754		BCE_PRINTF("rxmbuf[0x%04X]\n", chain_prod);
9755		bce_dump_mbuf(sc, m);
9756		chain_prod = RX_CHAIN_IDX(NEXT_RX_BD(chain_prod));
9757	}
9758
9759	BCE_PRINTF(
9760		"----------------------------"
9761		"----------------"
9762		"----------------------------\n");
9763}
9764
9765/****************************************************************************/
9766/* Prints out the mbufs in the mbuf page chain.                             */
9767/*                                                                          */
9768/* Returns:                                                                 */
9769/*   Nothing.                                                               */
9770/****************************************************************************/
9771static __attribute__ ((noinline)) void
9772bce_dump_pg_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
9773{
9774	struct mbuf *m;
9775
9776	BCE_PRINTF(
9777		"----------------------------"
9778		"  pg mbuf data  "
9779		"----------------------------\n");
9780
9781	for (int i = 0; i < count; i++) {
9782	 	m = sc->pg_mbuf_ptr[chain_prod];
9783		BCE_PRINTF("pgmbuf[0x%04X]\n", chain_prod);
9784		bce_dump_mbuf(sc, m);
9785		chain_prod = PG_CHAIN_IDX(NEXT_PG_BD(chain_prod));
9786	}
9787
9788	BCE_PRINTF(
9789		"----------------------------"
9790		"----------------"
9791		"----------------------------\n");
9792}
9793
9794/****************************************************************************/
9795/* Prints out a tx_bd structure.                                            */
9796/*                                                                          */
9797/* Returns:                                                                 */
9798/*   Nothing.                                                               */
9799/****************************************************************************/
9800static __attribute__ ((noinline)) void
9801bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
9802{
9803	int i = 0;
9804
9805	if (idx > MAX_TX_BD_ALLOC)
9806		/* Index out of range. */
9807		BCE_PRINTF("tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
9808	else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
9809		/* TX Chain page pointer. */
9810		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
9811		    "pointer\n", idx, txbd->tx_bd_haddr_hi,
9812		    txbd->tx_bd_haddr_lo);
9813	else {
9814		/* Normal tx_bd entry. */
9815		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, "
9816		    "mss_nbytes = 0x%08X, vlan tag = 0x%04X, flags = "
9817		    "0x%04X (", idx, txbd->tx_bd_haddr_hi,
9818		    txbd->tx_bd_haddr_lo, txbd->tx_bd_mss_nbytes,
9819		    txbd->tx_bd_vlan_tag, txbd->tx_bd_flags);
9820
9821		if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT) {
9822			if (i>0)
9823				printf("|");
9824			printf("CONN_FAULT");
9825			i++;
9826		}
9827
9828		if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM) {
9829			if (i>0)
9830				printf("|");
9831			printf("TCP_UDP_CKSUM");
9832			i++;
9833		}
9834
9835		if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM) {
9836			if (i>0)
9837				printf("|");
9838			printf("IP_CKSUM");
9839			i++;
9840		}
9841
9842		if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG) {
9843			if (i>0)
9844				printf("|");
9845			printf("VLAN");
9846			i++;
9847		}
9848
9849		if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW) {
9850			if (i>0)
9851				printf("|");
9852			printf("COAL_NOW");
9853			i++;
9854		}
9855
9856		if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC) {
9857			if (i>0)
9858				printf("|");
9859			printf("DONT_GEN_CRC");
9860			i++;
9861		}
9862
9863		if (txbd->tx_bd_flags & TX_BD_FLAGS_START) {
9864			if (i>0)
9865				printf("|");
9866			printf("START");
9867			i++;
9868		}
9869
9870		if (txbd->tx_bd_flags & TX_BD_FLAGS_END) {
9871			if (i>0)
9872				printf("|");
9873			printf("END");
9874			i++;
9875		}
9876
9877		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO) {
9878			if (i>0)
9879				printf("|");
9880			printf("LSO");
9881			i++;
9882		}
9883
9884		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD) {
9885			if (i>0)
9886				printf("|");
9887			printf("SW_OPTION=%d", ((txbd->tx_bd_flags &
9888			    TX_BD_FLAGS_SW_OPTION_WORD) >> 8)); i++;
9889		}
9890
9891		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS) {
9892			if (i>0)
9893				printf("|");
9894			printf("SW_FLAGS");
9895			i++;
9896		}
9897
9898		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP) {
9899			if (i>0)
9900				printf("|");
9901			printf("SNAP)");
9902		} else {
9903			printf(")\n");
9904		}
9905	}
9906}
9907
9908/****************************************************************************/
9909/* Prints out a rx_bd structure.                                            */
9910/*                                                                          */
9911/* Returns:                                                                 */
9912/*   Nothing.                                                               */
9913/****************************************************************************/
9914static __attribute__ ((noinline)) void
9915bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd)
9916{
9917	if (idx > MAX_RX_BD_ALLOC)
9918		/* Index out of range. */
9919		BCE_PRINTF("rx_bd[0x%04X]: Invalid rx_bd index!\n", idx);
9920	else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
9921		/* RX Chain page pointer. */
9922		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
9923		    "pointer\n", idx, rxbd->rx_bd_haddr_hi,
9924		    rxbd->rx_bd_haddr_lo);
9925	else
9926		/* Normal rx_bd entry. */
9927		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = "
9928		    "0x%08X, flags = 0x%08X\n", idx, rxbd->rx_bd_haddr_hi,
9929		    rxbd->rx_bd_haddr_lo, rxbd->rx_bd_len,
9930		    rxbd->rx_bd_flags);
9931}
9932
9933/****************************************************************************/
9934/* Prints out a rx_bd structure in the page chain.                          */
9935/*                                                                          */
9936/* Returns:                                                                 */
9937/*   Nothing.                                                               */
9938/****************************************************************************/
9939static __attribute__ ((noinline)) void
9940bce_dump_pgbd(struct bce_softc *sc, int idx, struct rx_bd *pgbd)
9941{
9942	if (idx > MAX_PG_BD_ALLOC)
9943		/* Index out of range. */
9944		BCE_PRINTF("pg_bd[0x%04X]: Invalid pg_bd index!\n", idx);
9945	else if ((idx & USABLE_PG_BD_PER_PAGE) == USABLE_PG_BD_PER_PAGE)
9946		/* Page Chain page pointer. */
9947		BCE_PRINTF("px_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
9948			idx, pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo);
9949	else
9950		/* Normal rx_bd entry. */
9951		BCE_PRINTF("pg_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
9952			"flags = 0x%08X\n", idx,
9953			pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo,
9954			pgbd->rx_bd_len, pgbd->rx_bd_flags);
9955}
9956
9957/****************************************************************************/
9958/* Prints out a l2_fhdr structure.                                          */
9959/*                                                                          */
9960/* Returns:                                                                 */
9961/*   Nothing.                                                               */
9962/****************************************************************************/
9963static __attribute__ ((noinline)) void
9964bce_dump_l2fhdr(struct bce_softc *sc, int idx, struct l2_fhdr *l2fhdr)
9965{
9966	BCE_PRINTF("l2_fhdr[0x%04X]: status = 0x%b, "
9967		"pkt_len = %d, vlan = 0x%04x, ip_xsum/hdr_len = 0x%04X, "
9968		"tcp_udp_xsum = 0x%04X\n", idx,
9969		l2fhdr->l2_fhdr_status, BCE_L2FHDR_PRINTFB,
9970		l2fhdr->l2_fhdr_pkt_len, l2fhdr->l2_fhdr_vlan_tag,
9971		l2fhdr->l2_fhdr_ip_xsum, l2fhdr->l2_fhdr_tcp_udp_xsum);
9972}
9973
9974/****************************************************************************/
9975/* Prints out context memory info.  (Only useful for CID 0 to 16.)          */
9976/*                                                                          */
9977/* Returns:                                                                 */
9978/*   Nothing.                                                               */
9979/****************************************************************************/
9980static __attribute__ ((noinline)) void
9981bce_dump_ctx(struct bce_softc *sc, u16 cid)
9982{
9983	if (cid > TX_CID) {
9984		BCE_PRINTF(" Unknown CID\n");
9985		return;
9986	}
9987
9988	BCE_PRINTF(
9989	    "----------------------------"
9990	    "    CTX Data    "
9991	    "----------------------------\n");
9992
9993	BCE_PRINTF("     0x%04X - (CID) Context ID\n", cid);
9994
9995	if (cid == RX_CID) {
9996		BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BDIDX) host rx "
9997		   "producer index\n",
9998		    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BDIDX));
9999		BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BSEQ) host "
10000		    "byte sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
10001		    BCE_L2CTX_RX_HOST_BSEQ));
10002		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BSEQ) h/w byte sequence\n",
10003		    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BSEQ));
10004		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_HI) h/w buffer "
10005		    "descriptor address\n",
10006 		    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_HI));
10007		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_LO) h/w buffer "
10008		    "descriptor address\n",
10009		    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_LO));
10010		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDIDX) h/w rx consumer "
10011		    "index\n", CTX_RD(sc, GET_CID_ADDR(cid),
10012		    BCE_L2CTX_RX_NX_BDIDX));
10013		BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_PG_BDIDX) host page "
10014		    "producer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
10015		    BCE_L2CTX_RX_HOST_PG_BDIDX));
10016		BCE_PRINTF(" 0x%08X - (L2CTX_RX_PG_BUF_SIZE) host rx_bd/page "
10017		    "buffer size\n", CTX_RD(sc, GET_CID_ADDR(cid),
10018		    BCE_L2CTX_RX_PG_BUF_SIZE));
10019		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_HI) h/w page "
10020		    "chain address\n", CTX_RD(sc, GET_CID_ADDR(cid),
10021		    BCE_L2CTX_RX_NX_PG_BDHADDR_HI));
10022		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_LO) h/w page "
10023		    "chain address\n", CTX_RD(sc, GET_CID_ADDR(cid),
10024		    BCE_L2CTX_RX_NX_PG_BDHADDR_LO));
10025		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDIDX) h/w page "
10026		    "consumer index\n",	CTX_RD(sc, GET_CID_ADDR(cid),
10027		    BCE_L2CTX_RX_NX_PG_BDIDX));
10028	} else if (cid == TX_CID) {
10029		if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
10030			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE_XI) ctx type\n",
10031			    CTX_RD(sc, GET_CID_ADDR(cid),
10032			    BCE_L2CTX_TX_TYPE_XI));
10033			BCE_PRINTF(" 0x%08X - (L2CTX_CMD_TX_TYPE_XI) ctx "
10034			    "cmd\n", CTX_RD(sc, GET_CID_ADDR(cid),
10035			    BCE_L2CTX_TX_CMD_TYPE_XI));
10036			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI_XI) "
10037			    "h/w buffer descriptor address\n",
10038			    CTX_RD(sc, GET_CID_ADDR(cid),
10039			    BCE_L2CTX_TX_TBDR_BHADDR_HI_XI));
10040			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO_XI) "
10041			    "h/w buffer	descriptor address\n",
10042			    CTX_RD(sc, GET_CID_ADDR(cid),
10043			    BCE_L2CTX_TX_TBDR_BHADDR_LO_XI));
10044			BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX_XI) "
10045			    "host producer index\n",
10046			    CTX_RD(sc, GET_CID_ADDR(cid),
10047			    BCE_L2CTX_TX_HOST_BIDX_XI));
10048			BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ_XI) "
10049			    "host byte sequence\n",
10050			    CTX_RD(sc, GET_CID_ADDR(cid),
10051			    BCE_L2CTX_TX_HOST_BSEQ_XI));
10052		} else {
10053			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE) ctx type\n",
10054			    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE));
10055			BCE_PRINTF(" 0x%08X - (L2CTX_TX_CMD_TYPE) ctx cmd\n",
10056			    CTX_RD(sc, GET_CID_ADDR(cid),
10057			    BCE_L2CTX_TX_CMD_TYPE));
10058			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI) "
10059			    "h/w buffer	descriptor address\n",
10060			    CTX_RD(sc, GET_CID_ADDR(cid),
10061			    BCE_L2CTX_TX_TBDR_BHADDR_HI));
10062			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO) "
10063			    "h/w buffer	descriptor address\n",
10064			    CTX_RD(sc, GET_CID_ADDR(cid),
10065			    BCE_L2CTX_TX_TBDR_BHADDR_LO));
10066			BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX) host "
10067			    "producer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
10068			    BCE_L2CTX_TX_HOST_BIDX));
10069			BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ) host byte "
10070			    "sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
10071			    BCE_L2CTX_TX_HOST_BSEQ));
10072		}
10073	}
10074
10075	BCE_PRINTF(
10076	   "----------------------------"
10077	   "    Raw CTX     "
10078	   "----------------------------\n");
10079
10080	for (int i = 0x0; i < 0x300; i += 0x10) {
10081		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n", i,
10082		   CTX_RD(sc, GET_CID_ADDR(cid), i),
10083		   CTX_RD(sc, GET_CID_ADDR(cid), i + 0x4),
10084		   CTX_RD(sc, GET_CID_ADDR(cid), i + 0x8),
10085		   CTX_RD(sc, GET_CID_ADDR(cid), i + 0xc));
10086	}
10087
10088	BCE_PRINTF(
10089	   "----------------------------"
10090	   "----------------"
10091	   "----------------------------\n");
10092}
10093
10094/****************************************************************************/
10095/* Prints out the FTQ data.                                                 */
10096/*                                                                          */
10097/* Returns:                                                                */
10098/*   Nothing.                                                               */
10099/****************************************************************************/
10100static __attribute__ ((noinline)) void
10101bce_dump_ftqs(struct bce_softc *sc)
10102{
10103	u32 cmd, ctl, cur_depth, max_depth, valid_cnt, val;
10104
10105	BCE_PRINTF(
10106	    "----------------------------"
10107	    "    FTQ Data    "
10108	    "----------------------------\n");
10109
10110	BCE_PRINTF("   FTQ    Command    Control   Depth_Now  "
10111	    "Max_Depth  Valid_Cnt \n");
10112	BCE_PRINTF(" ------- ---------- ---------- ---------- "
10113	    "---------- ----------\n");
10114
10115	/* Setup the generic statistic counters for the FTQ valid count. */
10116	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PPQ_VALID_CNT << 24) |
10117	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT  << 16) |
10118	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT   <<  8) |
10119	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT);
10120	REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
10121
10122	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCHQ_VALID_CNT  << 24) |
10123	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT  << 16) |
10124	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT <<  8) |
10125	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT);
10126	REG_WR(sc, BCE_HC_STAT_GEN_SEL_1, val);
10127
10128	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPATQ_VALID_CNT  << 24) |
10129	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT  << 16) |
10130	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT   <<  8) |
10131	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT);
10132	REG_WR(sc, BCE_HC_STAT_GEN_SEL_2, val);
10133
10134	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMQ_VALID_CNT   << 24) |
10135	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT  << 16) |
10136	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT  <<  8) |
10137	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT);
10138	REG_WR(sc, BCE_HC_STAT_GEN_SEL_3, val);
10139
10140	/* Input queue to the Receive Lookup state machine */
10141	cmd = REG_RD(sc, BCE_RLUP_FTQ_CMD);
10142	ctl = REG_RD(sc, BCE_RLUP_FTQ_CTL);
10143	cur_depth = (ctl & BCE_RLUP_FTQ_CTL_CUR_DEPTH) >> 22;
10144	max_depth = (ctl & BCE_RLUP_FTQ_CTL_MAX_DEPTH) >> 12;
10145	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
10146	BCE_PRINTF(" RLUP    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10147	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10148
10149	/* Input queue to the Receive Processor */
10150	cmd = REG_RD_IND(sc, BCE_RXP_FTQ_CMD);
10151	ctl = REG_RD_IND(sc, BCE_RXP_FTQ_CTL);
10152	cur_depth = (ctl & BCE_RXP_FTQ_CTL_CUR_DEPTH) >> 22;
10153	max_depth = (ctl & BCE_RXP_FTQ_CTL_MAX_DEPTH) >> 12;
10154	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
10155	BCE_PRINTF(" RXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10156	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10157
10158	/* Input queue to the Recevie Processor */
10159	cmd = REG_RD_IND(sc, BCE_RXP_CFTQ_CMD);
10160	ctl = REG_RD_IND(sc, BCE_RXP_CFTQ_CTL);
10161	cur_depth = (ctl & BCE_RXP_CFTQ_CTL_CUR_DEPTH) >> 22;
10162	max_depth = (ctl & BCE_RXP_CFTQ_CTL_MAX_DEPTH) >> 12;
10163	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
10164	BCE_PRINTF(" RXPC    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10165	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10166
10167	/* Input queue to the Receive Virtual to Physical state machine */
10168	cmd = REG_RD(sc, BCE_RV2P_PFTQ_CMD);
10169	ctl = REG_RD(sc, BCE_RV2P_PFTQ_CTL);
10170	cur_depth = (ctl & BCE_RV2P_PFTQ_CTL_CUR_DEPTH) >> 22;
10171	max_depth = (ctl & BCE_RV2P_PFTQ_CTL_MAX_DEPTH) >> 12;
10172	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
10173	BCE_PRINTF(" RV2PP   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10174	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10175
10176	/* Input queue to the Recevie Virtual to Physical state machine */
10177	cmd = REG_RD(sc, BCE_RV2P_MFTQ_CMD);
10178	ctl = REG_RD(sc, BCE_RV2P_MFTQ_CTL);
10179	cur_depth = (ctl & BCE_RV2P_MFTQ_CTL_CUR_DEPTH) >> 22;
10180	max_depth = (ctl & BCE_RV2P_MFTQ_CTL_MAX_DEPTH) >> 12;
10181	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT4);
10182	BCE_PRINTF(" RV2PM   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10183	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10184
10185	/* Input queue to the Receive Virtual to Physical state machine */
10186	cmd = REG_RD(sc, BCE_RV2P_TFTQ_CMD);
10187	ctl = REG_RD(sc, BCE_RV2P_TFTQ_CTL);
10188	cur_depth = (ctl & BCE_RV2P_TFTQ_CTL_CUR_DEPTH) >> 22;
10189	max_depth = (ctl & BCE_RV2P_TFTQ_CTL_MAX_DEPTH) >> 12;
10190	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT5);
10191	BCE_PRINTF(" RV2PT   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10192	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10193
10194	/* Input queue to the Receive DMA state machine */
10195	cmd = REG_RD(sc, BCE_RDMA_FTQ_CMD);
10196	ctl = REG_RD(sc, BCE_RDMA_FTQ_CTL);
10197	cur_depth = (ctl & BCE_RDMA_FTQ_CTL_CUR_DEPTH) >> 22;
10198	max_depth = (ctl & BCE_RDMA_FTQ_CTL_MAX_DEPTH) >> 12;
10199	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT6);
10200	BCE_PRINTF(" RDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10201	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10202
10203	/* Input queue to the Transmit Scheduler state machine */
10204	cmd = REG_RD(sc, BCE_TSCH_FTQ_CMD);
10205	ctl = REG_RD(sc, BCE_TSCH_FTQ_CTL);
10206	cur_depth = (ctl & BCE_TSCH_FTQ_CTL_CUR_DEPTH) >> 22;
10207	max_depth = (ctl & BCE_TSCH_FTQ_CTL_MAX_DEPTH) >> 12;
10208	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT7);
10209	BCE_PRINTF(" TSCH    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10210	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10211
10212	/* Input queue to the Transmit Buffer Descriptor state machine */
10213	cmd = REG_RD(sc, BCE_TBDR_FTQ_CMD);
10214	ctl = REG_RD(sc, BCE_TBDR_FTQ_CTL);
10215	cur_depth = (ctl & BCE_TBDR_FTQ_CTL_CUR_DEPTH) >> 22;
10216	max_depth = (ctl & BCE_TBDR_FTQ_CTL_MAX_DEPTH) >> 12;
10217	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT8);
10218	BCE_PRINTF(" TBDR    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10219	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10220
10221	/* Input queue to the Transmit Processor */
10222	cmd = REG_RD_IND(sc, BCE_TXP_FTQ_CMD);
10223	ctl = REG_RD_IND(sc, BCE_TXP_FTQ_CTL);
10224	cur_depth = (ctl & BCE_TXP_FTQ_CTL_CUR_DEPTH) >> 22;
10225	max_depth = (ctl & BCE_TXP_FTQ_CTL_MAX_DEPTH) >> 12;
10226	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT9);
10227	BCE_PRINTF(" TXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10228	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10229
10230	/* Input queue to the Transmit DMA state machine */
10231	cmd = REG_RD(sc, BCE_TDMA_FTQ_CMD);
10232	ctl = REG_RD(sc, BCE_TDMA_FTQ_CTL);
10233	cur_depth = (ctl & BCE_TDMA_FTQ_CTL_CUR_DEPTH) >> 22;
10234	max_depth = (ctl & BCE_TDMA_FTQ_CTL_MAX_DEPTH) >> 12;
10235	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT10);
10236	BCE_PRINTF(" TDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10237	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10238
10239	/* Input queue to the Transmit Patch-Up Processor */
10240	cmd = REG_RD_IND(sc, BCE_TPAT_FTQ_CMD);
10241	ctl = REG_RD_IND(sc, BCE_TPAT_FTQ_CTL);
10242	cur_depth = (ctl & BCE_TPAT_FTQ_CTL_CUR_DEPTH) >> 22;
10243	max_depth = (ctl & BCE_TPAT_FTQ_CTL_MAX_DEPTH) >> 12;
10244	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT11);
10245	BCE_PRINTF(" TPAT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10246	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10247
10248	/* Input queue to the Transmit Assembler state machine */
10249	cmd = REG_RD_IND(sc, BCE_TAS_FTQ_CMD);
10250	ctl = REG_RD_IND(sc, BCE_TAS_FTQ_CTL);
10251	cur_depth = (ctl & BCE_TAS_FTQ_CTL_CUR_DEPTH) >> 22;
10252	max_depth = (ctl & BCE_TAS_FTQ_CTL_MAX_DEPTH) >> 12;
10253	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT12);
10254	BCE_PRINTF(" TAS     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10255	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10256
10257	/* Input queue to the Completion Processor */
10258	cmd = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CMD);
10259	ctl = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CTL);
10260	cur_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_CUR_DEPTH) >> 22;
10261	max_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_MAX_DEPTH) >> 12;
10262	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT13);
10263	BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10264	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10265
10266	/* Input queue to the Completion Processor */
10267	cmd = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CMD);
10268	ctl = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CTL);
10269	cur_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_CUR_DEPTH) >> 22;
10270	max_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_MAX_DEPTH) >> 12;
10271	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT14);
10272	BCE_PRINTF(" COMT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10273	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10274
10275	/* Input queue to the Completion Processor */
10276	cmd = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CMD);
10277	ctl = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CTL);
10278	cur_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_CUR_DEPTH) >> 22;
10279	max_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_MAX_DEPTH) >> 12;
10280	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT15);
10281	BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10282	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10283
10284	/* Setup the generic statistic counters for the FTQ valid count. */
10285	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSQ_VALID_CNT  << 16) |
10286	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT  <<  8) |
10287	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT);
10288
10289	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
10290		val = val |
10291		    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCSQ_VALID_CNT_XI <<
10292		     24);
10293	REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
10294
10295	/* Input queue to the Management Control Processor */
10296	cmd = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CMD);
10297	ctl = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CTL);
10298	cur_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_CUR_DEPTH) >> 22;
10299	max_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_MAX_DEPTH) >> 12;
10300	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
10301	BCE_PRINTF(" MCP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10302	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10303
10304	/* Input queue to the Command Processor */
10305	cmd = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CMD);
10306	ctl = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CTL);
10307	cur_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_CUR_DEPTH) >> 22;
10308	max_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_MAX_DEPTH) >> 12;
10309	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
10310	BCE_PRINTF(" CP      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10311	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10312
10313	/* Input queue to the Completion Scheduler state machine */
10314	cmd = REG_RD(sc, BCE_CSCH_CH_FTQ_CMD);
10315	ctl = REG_RD(sc, BCE_CSCH_CH_FTQ_CTL);
10316	cur_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_CUR_DEPTH) >> 22;
10317	max_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_MAX_DEPTH) >> 12;
10318	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
10319	BCE_PRINTF(" CS      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10320	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10321
10322	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
10323		/* Input queue to the RV2P Command Scheduler */
10324		cmd = REG_RD(sc, BCE_RV2PCSR_FTQ_CMD);
10325		ctl = REG_RD(sc, BCE_RV2PCSR_FTQ_CTL);
10326		cur_depth = (ctl & 0xFFC00000) >> 22;
10327		max_depth = (ctl & 0x003FF000) >> 12;
10328		valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
10329		BCE_PRINTF(" RV2PCSR 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10330		    cmd, ctl, cur_depth, max_depth, valid_cnt);
10331	}
10332
10333	BCE_PRINTF(
10334	    "----------------------------"
10335	    "----------------"
10336	    "----------------------------\n");
10337}
10338
10339/****************************************************************************/
10340/* Prints out the TX chain.                                                 */
10341/*                                                                          */
10342/* Returns:                                                                 */
10343/*   Nothing.                                                               */
10344/****************************************************************************/
10345static __attribute__ ((noinline)) void
10346bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count)
10347{
10348	struct tx_bd *txbd;
10349
10350	/* First some info about the tx_bd chain structure. */
10351	BCE_PRINTF(
10352	    "----------------------------"
10353	    "  tx_bd  chain  "
10354	    "----------------------------\n");
10355
10356	BCE_PRINTF("page size      = 0x%08X, tx chain pages        = 0x%08X\n",
10357	    (u32) BCM_PAGE_SIZE, (u32) sc->tx_pages);
10358	BCE_PRINTF("tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
10359	    (u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
10360	BCE_PRINTF("total tx_bd    = 0x%08X\n", (u32) TOTAL_TX_BD_ALLOC);
10361
10362	BCE_PRINTF(
10363	    "----------------------------"
10364	    "   tx_bd data   "
10365	    "----------------------------\n");
10366
10367	/* Now print out a decoded list of TX buffer descriptors. */
10368	for (int i = 0; i < count; i++) {
10369	 	txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
10370		bce_dump_txbd(sc, tx_prod, txbd);
10371		tx_prod++;
10372	}
10373
10374	BCE_PRINTF(
10375	    "----------------------------"
10376	    "----------------"
10377	    "----------------------------\n");
10378}
10379
10380/****************************************************************************/
10381/* Prints out the RX chain.                                                 */
10382/*                                                                          */
10383/* Returns:                                                                 */
10384/*   Nothing.                                                               */
10385/****************************************************************************/
10386static __attribute__ ((noinline)) void
10387bce_dump_rx_bd_chain(struct bce_softc *sc, u16 rx_prod, int count)
10388{
10389	struct rx_bd *rxbd;
10390
10391	/* First some info about the rx_bd chain structure. */
10392	BCE_PRINTF(
10393	    "----------------------------"
10394	    "  rx_bd  chain  "
10395	    "----------------------------\n");
10396
10397	BCE_PRINTF("page size      = 0x%08X, rx chain pages        = 0x%08X\n",
10398	    (u32) BCM_PAGE_SIZE, (u32) sc->rx_pages);
10399
10400	BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
10401	    (u32) TOTAL_RX_BD_PER_PAGE, (u32) USABLE_RX_BD_PER_PAGE);
10402
10403	BCE_PRINTF("total rx_bd    = 0x%08X\n", (u32) TOTAL_RX_BD_ALLOC);
10404
10405	BCE_PRINTF(
10406	    "----------------------------"
10407	    "   rx_bd data   "
10408	    "----------------------------\n");
10409
10410	/* Now print out the rx_bd's themselves. */
10411	for (int i = 0; i < count; i++) {
10412		rxbd = &sc->rx_bd_chain[RX_PAGE(rx_prod)][RX_IDX(rx_prod)];
10413		bce_dump_rxbd(sc, rx_prod, rxbd);
10414		rx_prod = RX_CHAIN_IDX(rx_prod + 1);
10415	}
10416
10417	BCE_PRINTF(
10418	    "----------------------------"
10419	    "----------------"
10420	    "----------------------------\n");
10421}
10422
10423/****************************************************************************/
10424/* Prints out the page chain.                                               */
10425/*                                                                          */
10426/* Returns:                                                                 */
10427/*   Nothing.                                                               */
10428/****************************************************************************/
10429static __attribute__ ((noinline)) void
10430bce_dump_pg_chain(struct bce_softc *sc, u16 pg_prod, int count)
10431{
10432	struct rx_bd *pgbd;
10433
10434	/* First some info about the page chain structure. */
10435	BCE_PRINTF(
10436	    "----------------------------"
10437	    "   page chain   "
10438	    "----------------------------\n");
10439
10440	BCE_PRINTF("page size      = 0x%08X, pg chain pages        = 0x%08X\n",
10441	    (u32) BCM_PAGE_SIZE, (u32) sc->pg_pages);
10442
10443	BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
10444	    (u32) TOTAL_PG_BD_PER_PAGE, (u32) USABLE_PG_BD_PER_PAGE);
10445
10446	BCE_PRINTF("total pg_bd             = 0x%08X\n", (u32) TOTAL_PG_BD_ALLOC);
10447
10448	BCE_PRINTF(
10449	    "----------------------------"
10450	    "   page data    "
10451	    "----------------------------\n");
10452
10453	/* Now print out the rx_bd's themselves. */
10454	for (int i = 0; i < count; i++) {
10455		pgbd = &sc->pg_bd_chain[PG_PAGE(pg_prod)][PG_IDX(pg_prod)];
10456		bce_dump_pgbd(sc, pg_prod, pgbd);
10457		pg_prod = PG_CHAIN_IDX(pg_prod + 1);
10458	}
10459
10460	BCE_PRINTF(
10461	    "----------------------------"
10462	    "----------------"
10463	    "----------------------------\n");
10464}
10465
10466#define BCE_PRINT_RX_CONS(arg)						\
10467if (sblk->status_rx_quick_consumer_index##arg)				\
10468	BCE_PRINTF("0x%04X(0x%04X) - rx_quick_consumer_index%d\n",	\
10469	    sblk->status_rx_quick_consumer_index##arg, (u16)		\
10470	    RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index##arg),	\
10471	    arg);
10472
10473#define BCE_PRINT_TX_CONS(arg)						\
10474if (sblk->status_tx_quick_consumer_index##arg)				\
10475	BCE_PRINTF("0x%04X(0x%04X) - tx_quick_consumer_index%d\n",	\
10476	    sblk->status_tx_quick_consumer_index##arg, (u16)		\
10477	    TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index##arg),	\
10478	    arg);
10479
10480/****************************************************************************/
10481/* Prints out the status block from host memory.                            */
10482/*                                                                          */
10483/* Returns:                                                                 */
10484/*   Nothing.                                                               */
10485/****************************************************************************/
10486static __attribute__ ((noinline)) void
10487bce_dump_status_block(struct bce_softc *sc)
10488{
10489	struct status_block *sblk;
10490
10491	bus_dmamap_sync(sc->status_tag, sc->status_map, BUS_DMASYNC_POSTREAD);
10492
10493	sblk = sc->status_block;
10494
10495	BCE_PRINTF(
10496	    "----------------------------"
10497	    "  Status Block  "
10498	    "----------------------------\n");
10499
10500	/* Theses indices are used for normal L2 drivers. */
10501	BCE_PRINTF("    0x%08X - attn_bits\n",
10502	    sblk->status_attn_bits);
10503
10504	BCE_PRINTF("    0x%08X - attn_bits_ack\n",
10505	    sblk->status_attn_bits_ack);
10506
10507	BCE_PRINT_RX_CONS(0);
10508	BCE_PRINT_TX_CONS(0)
10509
10510	BCE_PRINTF("        0x%04X - status_idx\n", sblk->status_idx);
10511
10512	/* Theses indices are not used for normal L2 drivers. */
10513	BCE_PRINT_RX_CONS(1);   BCE_PRINT_RX_CONS(2);   BCE_PRINT_RX_CONS(3);
10514	BCE_PRINT_RX_CONS(4);   BCE_PRINT_RX_CONS(5);   BCE_PRINT_RX_CONS(6);
10515	BCE_PRINT_RX_CONS(7);   BCE_PRINT_RX_CONS(8);   BCE_PRINT_RX_CONS(9);
10516	BCE_PRINT_RX_CONS(10);  BCE_PRINT_RX_CONS(11);  BCE_PRINT_RX_CONS(12);
10517	BCE_PRINT_RX_CONS(13);  BCE_PRINT_RX_CONS(14);  BCE_PRINT_RX_CONS(15);
10518
10519	BCE_PRINT_TX_CONS(1);   BCE_PRINT_TX_CONS(2);   BCE_PRINT_TX_CONS(3);
10520
10521	if (sblk->status_completion_producer_index ||
10522	    sblk->status_cmd_consumer_index)
10523		BCE_PRINTF("com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
10524		    sblk->status_completion_producer_index,
10525		    sblk->status_cmd_consumer_index);
10526
10527	BCE_PRINTF(
10528	    "----------------------------"
10529	    "----------------"
10530	    "----------------------------\n");
10531}
10532
10533#define BCE_PRINT_64BIT_STAT(arg) 				\
10534if (sblk->arg##_lo || sblk->arg##_hi)				\
10535	BCE_PRINTF("0x%08X:%08X : %s\n", sblk->arg##_hi,	\
10536	    sblk->arg##_lo, #arg);
10537
10538#define BCE_PRINT_32BIT_STAT(arg)				\
10539if (sblk->arg)							\
10540	BCE_PRINTF("         0x%08X : %s\n", 			\
10541	    sblk->arg, #arg);
10542
10543/****************************************************************************/
10544/* Prints out the statistics block from host memory.                        */
10545/*                                                                          */
10546/* Returns:                                                                 */
10547/*   Nothing.                                                               */
10548/****************************************************************************/
10549static __attribute__ ((noinline)) void
10550bce_dump_stats_block(struct bce_softc *sc)
10551{
10552	struct statistics_block *sblk;
10553
10554	bus_dmamap_sync(sc->stats_tag, sc->stats_map, BUS_DMASYNC_POSTREAD);
10555
10556	sblk = sc->stats_block;
10557
10558	BCE_PRINTF(
10559	    "---------------"
10560	    " Stats Block  (All Stats Not Shown Are 0) "
10561	    "---------------\n");
10562
10563	BCE_PRINT_64BIT_STAT(stat_IfHCInOctets);
10564	BCE_PRINT_64BIT_STAT(stat_IfHCInBadOctets);
10565	BCE_PRINT_64BIT_STAT(stat_IfHCOutOctets);
10566	BCE_PRINT_64BIT_STAT(stat_IfHCOutBadOctets);
10567	BCE_PRINT_64BIT_STAT(stat_IfHCInUcastPkts);
10568	BCE_PRINT_64BIT_STAT(stat_IfHCInBroadcastPkts);
10569	BCE_PRINT_64BIT_STAT(stat_IfHCInMulticastPkts);
10570	BCE_PRINT_64BIT_STAT(stat_IfHCOutUcastPkts);
10571	BCE_PRINT_64BIT_STAT(stat_IfHCOutBroadcastPkts);
10572	BCE_PRINT_64BIT_STAT(stat_IfHCOutMulticastPkts);
10573	BCE_PRINT_32BIT_STAT(
10574	    stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
10575	BCE_PRINT_32BIT_STAT(stat_Dot3StatsCarrierSenseErrors);
10576	BCE_PRINT_32BIT_STAT(stat_Dot3StatsFCSErrors);
10577	BCE_PRINT_32BIT_STAT(stat_Dot3StatsAlignmentErrors);
10578	BCE_PRINT_32BIT_STAT(stat_Dot3StatsSingleCollisionFrames);
10579	BCE_PRINT_32BIT_STAT(stat_Dot3StatsMultipleCollisionFrames);
10580	BCE_PRINT_32BIT_STAT(stat_Dot3StatsDeferredTransmissions);
10581	BCE_PRINT_32BIT_STAT(stat_Dot3StatsExcessiveCollisions);
10582	BCE_PRINT_32BIT_STAT(stat_Dot3StatsLateCollisions);
10583	BCE_PRINT_32BIT_STAT(stat_EtherStatsCollisions);
10584	BCE_PRINT_32BIT_STAT(stat_EtherStatsFragments);
10585	BCE_PRINT_32BIT_STAT(stat_EtherStatsJabbers);
10586	BCE_PRINT_32BIT_STAT(stat_EtherStatsUndersizePkts);
10587	BCE_PRINT_32BIT_STAT(stat_EtherStatsOversizePkts);
10588	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx64Octets);
10589	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx65Octetsto127Octets);
10590	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx128Octetsto255Octets);
10591	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx256Octetsto511Octets);
10592	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx512Octetsto1023Octets);
10593	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1024Octetsto1522Octets);
10594	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1523Octetsto9022Octets);
10595	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx64Octets);
10596	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx65Octetsto127Octets);
10597	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx128Octetsto255Octets);
10598	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx256Octetsto511Octets);
10599	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx512Octetsto1023Octets);
10600	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1024Octetsto1522Octets);
10601	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1523Octetsto9022Octets);
10602	BCE_PRINT_32BIT_STAT(stat_XonPauseFramesReceived);
10603	BCE_PRINT_32BIT_STAT(stat_XoffPauseFramesReceived);
10604	BCE_PRINT_32BIT_STAT(stat_OutXonSent);
10605	BCE_PRINT_32BIT_STAT(stat_OutXoffSent);
10606	BCE_PRINT_32BIT_STAT(stat_FlowControlDone);
10607	BCE_PRINT_32BIT_STAT(stat_MacControlFramesReceived);
10608	BCE_PRINT_32BIT_STAT(stat_XoffStateEntered);
10609	BCE_PRINT_32BIT_STAT(stat_IfInFramesL2FilterDiscards);
10610	BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerDiscards);
10611	BCE_PRINT_32BIT_STAT(stat_IfInFTQDiscards);
10612	BCE_PRINT_32BIT_STAT(stat_IfInMBUFDiscards);
10613	BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerP4Hit);
10614	BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerDiscards);
10615	BCE_PRINT_32BIT_STAT(stat_CatchupInFTQDiscards);
10616	BCE_PRINT_32BIT_STAT(stat_CatchupInMBUFDiscards);
10617	BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerP4Hit);
10618
10619	BCE_PRINTF(
10620	    "----------------------------"
10621	    "----------------"
10622	    "----------------------------\n");
10623}
10624
10625/****************************************************************************/
10626/* Prints out a summary of the driver state.                                */
10627/*                                                                          */
10628/* Returns:                                                                 */
10629/*   Nothing.                                                               */
10630/****************************************************************************/
10631static __attribute__ ((noinline)) void
10632bce_dump_driver_state(struct bce_softc *sc)
10633{
10634	u32 val_hi, val_lo;
10635
10636	BCE_PRINTF(
10637	    "-----------------------------"
10638	    " Driver State "
10639	    "-----------------------------\n");
10640
10641	val_hi = BCE_ADDR_HI(sc);
10642	val_lo = BCE_ADDR_LO(sc);
10643	BCE_PRINTF("0x%08X:%08X - (sc) driver softc structure virtual "
10644	    "address\n", val_hi, val_lo);
10645
10646	val_hi = BCE_ADDR_HI(sc->bce_vhandle);
10647	val_lo = BCE_ADDR_LO(sc->bce_vhandle);
10648	BCE_PRINTF("0x%08X:%08X - (sc->bce_vhandle) PCI BAR virtual "
10649	    "address\n", val_hi, val_lo);
10650
10651	val_hi = BCE_ADDR_HI(sc->status_block);
10652	val_lo = BCE_ADDR_LO(sc->status_block);
10653	BCE_PRINTF("0x%08X:%08X - (sc->status_block) status block "
10654	    "virtual address\n",	val_hi, val_lo);
10655
10656	val_hi = BCE_ADDR_HI(sc->stats_block);
10657	val_lo = BCE_ADDR_LO(sc->stats_block);
10658	BCE_PRINTF("0x%08X:%08X - (sc->stats_block) statistics block "
10659	    "virtual address\n", val_hi, val_lo);
10660
10661	val_hi = BCE_ADDR_HI(sc->tx_bd_chain);
10662	val_lo = BCE_ADDR_LO(sc->tx_bd_chain);
10663	BCE_PRINTF("0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain "
10664	    "virtual address\n", val_hi, val_lo);
10665
10666	val_hi = BCE_ADDR_HI(sc->rx_bd_chain);
10667	val_lo = BCE_ADDR_LO(sc->rx_bd_chain);
10668	BCE_PRINTF("0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain "
10669	    "virtual address\n", val_hi, val_lo);
10670
10671	if (bce_hdr_split == TRUE) {
10672		val_hi = BCE_ADDR_HI(sc->pg_bd_chain);
10673		val_lo = BCE_ADDR_LO(sc->pg_bd_chain);
10674		BCE_PRINTF("0x%08X:%08X - (sc->pg_bd_chain) page chain "
10675		    "virtual address\n", val_hi, val_lo);
10676	}
10677
10678	val_hi = BCE_ADDR_HI(sc->tx_mbuf_ptr);
10679	val_lo = BCE_ADDR_LO(sc->tx_mbuf_ptr);
10680	BCE_PRINTF("0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain "
10681	    "virtual address\n",	val_hi, val_lo);
10682
10683	val_hi = BCE_ADDR_HI(sc->rx_mbuf_ptr);
10684	val_lo = BCE_ADDR_LO(sc->rx_mbuf_ptr);
10685	BCE_PRINTF("0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain "
10686	    "virtual address\n", val_hi, val_lo);
10687
10688	if (bce_hdr_split == TRUE) {
10689		val_hi = BCE_ADDR_HI(sc->pg_mbuf_ptr);
10690		val_lo = BCE_ADDR_LO(sc->pg_mbuf_ptr);
10691		BCE_PRINTF("0x%08X:%08X - (sc->pg_mbuf_ptr) page mbuf chain "
10692		    "virtual address\n", val_hi, val_lo);
10693	}
10694
10695	BCE_PRINTF(" 0x%016llX - (sc->interrupts_generated) "
10696	    "h/w intrs\n",
10697	    (long long unsigned int) sc->interrupts_generated);
10698
10699	BCE_PRINTF(" 0x%016llX - (sc->interrupts_rx) "
10700	    "rx interrupts handled\n",
10701	    (long long unsigned int) sc->interrupts_rx);
10702
10703	BCE_PRINTF(" 0x%016llX - (sc->interrupts_tx) "
10704	    "tx interrupts handled\n",
10705	    (long long unsigned int) sc->interrupts_tx);
10706
10707	BCE_PRINTF(" 0x%016llX - (sc->phy_interrupts) "
10708	    "phy interrupts handled\n",
10709	    (long long unsigned int) sc->phy_interrupts);
10710
10711	BCE_PRINTF("         0x%08X - (sc->last_status_idx) "
10712	    "status block index\n", sc->last_status_idx);
10713
10714	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_prod) tx producer "
10715	    "index\n", sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod));
10716
10717	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_cons) tx consumer "
10718	    "index\n", sc->tx_cons, (u16) TX_CHAIN_IDX(sc->tx_cons));
10719
10720	BCE_PRINTF("         0x%08X - (sc->tx_prod_bseq) tx producer "
10721	    "byte seq index\n",	sc->tx_prod_bseq);
10722
10723	BCE_PRINTF("         0x%08X - (sc->debug_tx_mbuf_alloc) tx "
10724	    "mbufs allocated\n", sc->debug_tx_mbuf_alloc);
10725
10726	BCE_PRINTF("         0x%08X - (sc->used_tx_bd) used "
10727	    "tx_bd's\n", sc->used_tx_bd);
10728
10729	BCE_PRINTF("      0x%04X/0x%04X - (sc->tx_hi_watermark)/"
10730	    "(sc->max_tx_bd)\n", sc->tx_hi_watermark, sc->max_tx_bd);
10731
10732	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_prod) rx producer "
10733	    "index\n", sc->rx_prod, (u16) RX_CHAIN_IDX(sc->rx_prod));
10734
10735	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_cons) rx consumer "
10736	    "index\n", sc->rx_cons, (u16) RX_CHAIN_IDX(sc->rx_cons));
10737
10738	BCE_PRINTF("         0x%08X - (sc->rx_prod_bseq) rx producer "
10739	    "byte seq index\n",	sc->rx_prod_bseq);
10740
10741	BCE_PRINTF("      0x%04X/0x%04X - (sc->rx_low_watermark)/"
10742		   "(sc->max_rx_bd)\n", sc->rx_low_watermark, sc->max_rx_bd);
10743
10744	BCE_PRINTF("         0x%08X - (sc->debug_rx_mbuf_alloc) rx "
10745	    "mbufs allocated\n", sc->debug_rx_mbuf_alloc);
10746
10747	BCE_PRINTF("         0x%08X - (sc->free_rx_bd) free "
10748	    "rx_bd's\n", sc->free_rx_bd);
10749
10750	if (bce_hdr_split == TRUE) {
10751		BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_prod) page producer "
10752		    "index\n", sc->pg_prod, (u16) PG_CHAIN_IDX(sc->pg_prod));
10753
10754		BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_cons) page consumer "
10755		    "index\n", sc->pg_cons, (u16) PG_CHAIN_IDX(sc->pg_cons));
10756
10757		BCE_PRINTF("         0x%08X - (sc->debug_pg_mbuf_alloc) page "
10758		    "mbufs allocated\n", sc->debug_pg_mbuf_alloc);
10759	}
10760
10761	BCE_PRINTF("         0x%08X - (sc->free_pg_bd) free page "
10762	    "rx_bd's\n", sc->free_pg_bd);
10763
10764	BCE_PRINTF("      0x%04X/0x%04X - (sc->pg_low_watermark)/"
10765	    "(sc->max_pg_bd)\n", sc->pg_low_watermark, sc->max_pg_bd);
10766
10767	BCE_PRINTF("         0x%08X - (sc->mbuf_alloc_failed_count) "
10768	    "mbuf alloc failures\n", sc->mbuf_alloc_failed_count);
10769
10770	BCE_PRINTF("         0x%08X - (sc->bce_flags) "
10771	    "bce mac flags\n", sc->bce_flags);
10772
10773	BCE_PRINTF("         0x%08X - (sc->bce_phy_flags) "
10774	    "bce phy flags\n", sc->bce_phy_flags);
10775
10776	BCE_PRINTF(
10777	    "----------------------------"
10778	    "----------------"
10779	    "----------------------------\n");
10780}
10781
10782/****************************************************************************/
10783/* Prints out the hardware state through a summary of important register,   */
10784/* followed by a complete register dump.                                    */
10785/*                                                                          */
10786/* Returns:                                                                 */
10787/*   Nothing.                                                               */
10788/****************************************************************************/
10789static __attribute__ ((noinline)) void
10790bce_dump_hw_state(struct bce_softc *sc)
10791{
10792	u32 val;
10793
10794	BCE_PRINTF(
10795	    "----------------------------"
10796	    " Hardware State "
10797	    "----------------------------\n");
10798
10799	BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
10800
10801	val = REG_RD(sc, BCE_MISC_ENABLE_STATUS_BITS);
10802	BCE_PRINTF("0x%08X - (0x%06X) misc_enable_status_bits\n",
10803	    val, BCE_MISC_ENABLE_STATUS_BITS);
10804
10805	val = REG_RD(sc, BCE_DMA_STATUS);
10806	BCE_PRINTF("0x%08X - (0x%06X) dma_status\n",
10807	    val, BCE_DMA_STATUS);
10808
10809	val = REG_RD(sc, BCE_CTX_STATUS);
10810	BCE_PRINTF("0x%08X - (0x%06X) ctx_status\n",
10811	    val, BCE_CTX_STATUS);
10812
10813	val = REG_RD(sc, BCE_EMAC_STATUS);
10814	BCE_PRINTF("0x%08X - (0x%06X) emac_status\n",
10815	    val, BCE_EMAC_STATUS);
10816
10817	val = REG_RD(sc, BCE_RPM_STATUS);
10818	BCE_PRINTF("0x%08X - (0x%06X) rpm_status\n",
10819	    val, BCE_RPM_STATUS);
10820
10821	/* ToDo: Create a #define for this constant. */
10822	val = REG_RD(sc, 0x2004);
10823	BCE_PRINTF("0x%08X - (0x%06X) rlup_status\n",
10824	    val, 0x2004);
10825
10826	val = REG_RD(sc, BCE_RV2P_STATUS);
10827	BCE_PRINTF("0x%08X - (0x%06X) rv2p_status\n",
10828	    val, BCE_RV2P_STATUS);
10829
10830	/* ToDo: Create a #define for this constant. */
10831	val = REG_RD(sc, 0x2c04);
10832	BCE_PRINTF("0x%08X - (0x%06X) rdma_status\n",
10833	    val, 0x2c04);
10834
10835	val = REG_RD(sc, BCE_TBDR_STATUS);
10836	BCE_PRINTF("0x%08X - (0x%06X) tbdr_status\n",
10837	    val, BCE_TBDR_STATUS);
10838
10839	val = REG_RD(sc, BCE_TDMA_STATUS);
10840	BCE_PRINTF("0x%08X - (0x%06X) tdma_status\n",
10841	    val, BCE_TDMA_STATUS);
10842
10843	val = REG_RD(sc, BCE_HC_STATUS);
10844	BCE_PRINTF("0x%08X - (0x%06X) hc_status\n",
10845	    val, BCE_HC_STATUS);
10846
10847	val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
10848	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n",
10849	    val, BCE_TXP_CPU_STATE);
10850
10851	val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
10852	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n",
10853	    val, BCE_TPAT_CPU_STATE);
10854
10855	val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
10856	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n",
10857	    val, BCE_RXP_CPU_STATE);
10858
10859	val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
10860	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n",
10861	    val, BCE_COM_CPU_STATE);
10862
10863	val = REG_RD_IND(sc, BCE_MCP_CPU_STATE);
10864	BCE_PRINTF("0x%08X - (0x%06X) mcp_cpu_state\n",
10865	    val, BCE_MCP_CPU_STATE);
10866
10867	val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
10868	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n",
10869	    val, BCE_CP_CPU_STATE);
10870
10871	BCE_PRINTF(
10872	    "----------------------------"
10873	    "----------------"
10874	    "----------------------------\n");
10875
10876	BCE_PRINTF(
10877	    "----------------------------"
10878	    " Register  Dump "
10879	    "----------------------------\n");
10880
10881	for (int i = 0x400; i < 0x8000; i += 0x10) {
10882		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10883		    i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
10884		    REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
10885	}
10886
10887	BCE_PRINTF(
10888	    "----------------------------"
10889	    "----------------"
10890	    "----------------------------\n");
10891}
10892
10893/****************************************************************************/
10894/* Prints out the contentst of shared memory which is used for host driver  */
10895/* to bootcode firmware communication.                                      */
10896/*                                                                          */
10897/* Returns:                                                                 */
10898/*   Nothing.                                                               */
10899/****************************************************************************/
10900static __attribute__ ((noinline)) void
10901bce_dump_shmem_state(struct bce_softc *sc)
10902{
10903	BCE_PRINTF(
10904	    "----------------------------"
10905	    " Hardware State "
10906	    "----------------------------\n");
10907
10908	BCE_PRINTF("0x%08X - Shared memory base address\n",
10909	    sc->bce_shmem_base);
10910	BCE_PRINTF("%s - bootcode version\n",
10911	    sc->bce_bc_ver);
10912
10913	BCE_PRINTF(
10914	    "----------------------------"
10915	    "   Shared Mem   "
10916	    "----------------------------\n");
10917
10918	for (int i = 0x0; i < 0x200; i += 0x10) {
10919		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10920		    i, bce_shmem_rd(sc, i), bce_shmem_rd(sc, i + 0x4),
10921		    bce_shmem_rd(sc, i + 0x8), bce_shmem_rd(sc, i + 0xC));
10922	}
10923
10924	BCE_PRINTF(
10925	    "----------------------------"
10926	    "----------------"
10927	    "----------------------------\n");
10928}
10929
10930/****************************************************************************/
10931/* Prints out the mailbox queue registers.                                  */
10932/*                                                                          */
10933/* Returns:                                                                 */
10934/*   Nothing.                                                               */
10935/****************************************************************************/
10936static __attribute__ ((noinline)) void
10937bce_dump_mq_regs(struct bce_softc *sc)
10938{
10939	BCE_PRINTF(
10940	    "----------------------------"
10941	    "    MQ Regs     "
10942	    "----------------------------\n");
10943
10944	BCE_PRINTF(
10945	    "----------------------------"
10946	    "----------------"
10947	    "----------------------------\n");
10948
10949	for (int i = 0x3c00; i < 0x4000; i += 0x10) {
10950		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
10951		    i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
10952		    REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
10953	}
10954
10955	BCE_PRINTF(
10956	    "----------------------------"
10957	    "----------------"
10958	    "----------------------------\n");
10959}
10960
10961/****************************************************************************/
10962/* Prints out the bootcode state.                                           */
10963/*                                                                          */
10964/* Returns:                                                                 */
10965/*   Nothing.                                                               */
10966/****************************************************************************/
10967static __attribute__ ((noinline)) void
10968bce_dump_bc_state(struct bce_softc *sc)
10969{
10970	u32 val;
10971
10972	BCE_PRINTF(
10973	    "----------------------------"
10974	    " Bootcode State "
10975	    "----------------------------\n");
10976
10977	BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
10978
10979	val = bce_shmem_rd(sc, BCE_BC_RESET_TYPE);
10980	BCE_PRINTF("0x%08X - (0x%06X) reset_type\n",
10981	    val, BCE_BC_RESET_TYPE);
10982
10983	val = bce_shmem_rd(sc, BCE_BC_STATE);
10984	BCE_PRINTF("0x%08X - (0x%06X) state\n",
10985	    val, BCE_BC_STATE);
10986
10987	val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
10988	BCE_PRINTF("0x%08X - (0x%06X) condition\n",
10989	    val, BCE_BC_STATE_CONDITION);
10990
10991	val = bce_shmem_rd(sc, BCE_BC_STATE_DEBUG_CMD);
10992	BCE_PRINTF("0x%08X - (0x%06X) debug_cmd\n",
10993	    val, BCE_BC_STATE_DEBUG_CMD);
10994
10995	BCE_PRINTF(
10996	    "----------------------------"
10997	    "----------------"
10998	    "----------------------------\n");
10999}
11000
11001/****************************************************************************/
11002/* Prints out the TXP processor state.                                      */
11003/*                                                                          */
11004/* Returns:                                                                 */
11005/*   Nothing.                                                               */
11006/****************************************************************************/
11007static __attribute__ ((noinline)) void
11008bce_dump_txp_state(struct bce_softc *sc, int regs)
11009{
11010	u32 val;
11011	u32 fw_version[3];
11012
11013	BCE_PRINTF(
11014	    "----------------------------"
11015	    "   TXP  State   "
11016	    "----------------------------\n");
11017
11018	for (int i = 0; i < 3; i++)
11019		fw_version[i] = htonl(REG_RD_IND(sc,
11020		    (BCE_TXP_SCRATCH + 0x10 + i * 4)));
11021	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11022
11023	val = REG_RD_IND(sc, BCE_TXP_CPU_MODE);
11024	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_mode\n",
11025	    val, BCE_TXP_CPU_MODE);
11026
11027	val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
11028	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n",
11029	    val, BCE_TXP_CPU_STATE);
11030
11031	val = REG_RD_IND(sc, BCE_TXP_CPU_EVENT_MASK);
11032	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_event_mask\n",
11033	    val, BCE_TXP_CPU_EVENT_MASK);
11034
11035	if (regs) {
11036		BCE_PRINTF(
11037		    "----------------------------"
11038		    " Register  Dump "
11039		    "----------------------------\n");
11040
11041		for (int i = BCE_TXP_CPU_MODE; i < 0x68000; i += 0x10) {
11042			/* Skip the big blank spaces */
11043			if (i < 0x454000 && i > 0x5ffff)
11044				BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11045				    "0x%08X 0x%08X\n", i,
11046				    REG_RD_IND(sc, i),
11047				    REG_RD_IND(sc, i + 0x4),
11048				    REG_RD_IND(sc, i + 0x8),
11049				    REG_RD_IND(sc, i + 0xC));
11050		}
11051	}
11052
11053	BCE_PRINTF(
11054	    "----------------------------"
11055	    "----------------"
11056	    "----------------------------\n");
11057}
11058
11059/****************************************************************************/
11060/* Prints out the RXP processor state.                                      */
11061/*                                                                          */
11062/* Returns:                                                                 */
11063/*   Nothing.                                                               */
11064/****************************************************************************/
11065static __attribute__ ((noinline)) void
11066bce_dump_rxp_state(struct bce_softc *sc, int regs)
11067{
11068	u32 val;
11069	u32 fw_version[3];
11070
11071	BCE_PRINTF(
11072	    "----------------------------"
11073	    "   RXP  State   "
11074	    "----------------------------\n");
11075
11076	for (int i = 0; i < 3; i++)
11077		fw_version[i] = htonl(REG_RD_IND(sc,
11078		    (BCE_RXP_SCRATCH + 0x10 + i * 4)));
11079
11080	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11081
11082	val = REG_RD_IND(sc, BCE_RXP_CPU_MODE);
11083	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_mode\n",
11084	    val, BCE_RXP_CPU_MODE);
11085
11086	val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
11087	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n",
11088	    val, BCE_RXP_CPU_STATE);
11089
11090	val = REG_RD_IND(sc, BCE_RXP_CPU_EVENT_MASK);
11091	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_event_mask\n",
11092	    val, BCE_RXP_CPU_EVENT_MASK);
11093
11094	if (regs) {
11095		BCE_PRINTF(
11096		    "----------------------------"
11097		    " Register  Dump "
11098		    "----------------------------\n");
11099
11100		for (int i = BCE_RXP_CPU_MODE; i < 0xe8fff; i += 0x10) {
11101			/* Skip the big blank sapces */
11102			if (i < 0xc5400 && i > 0xdffff)
11103				BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11104				    "0x%08X 0x%08X\n", i,
11105				    REG_RD_IND(sc, i),
11106				    REG_RD_IND(sc, i + 0x4),
11107				    REG_RD_IND(sc, i + 0x8),
11108				    REG_RD_IND(sc, i + 0xC));
11109		}
11110	}
11111
11112	BCE_PRINTF(
11113	    "----------------------------"
11114	    "----------------"
11115	    "----------------------------\n");
11116}
11117
11118/****************************************************************************/
11119/* Prints out the TPAT processor state.                                     */
11120/*                                                                          */
11121/* Returns:                                                                 */
11122/*   Nothing.                                                               */
11123/****************************************************************************/
11124static __attribute__ ((noinline)) void
11125bce_dump_tpat_state(struct bce_softc *sc, int regs)
11126{
11127	u32 val;
11128	u32 fw_version[3];
11129
11130	BCE_PRINTF(
11131	    "----------------------------"
11132	    "   TPAT State   "
11133	    "----------------------------\n");
11134
11135	for (int i = 0; i < 3; i++)
11136		fw_version[i] = htonl(REG_RD_IND(sc,
11137		    (BCE_TPAT_SCRATCH + 0x410 + i * 4)));
11138
11139	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11140
11141	val = REG_RD_IND(sc, BCE_TPAT_CPU_MODE);
11142	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_mode\n",
11143	    val, BCE_TPAT_CPU_MODE);
11144
11145	val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
11146	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n",
11147	    val, BCE_TPAT_CPU_STATE);
11148
11149	val = REG_RD_IND(sc, BCE_TPAT_CPU_EVENT_MASK);
11150	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_event_mask\n",
11151	    val, BCE_TPAT_CPU_EVENT_MASK);
11152
11153	if (regs) {
11154		BCE_PRINTF(
11155		    "----------------------------"
11156		    " Register  Dump "
11157		    "----------------------------\n");
11158
11159		for (int i = BCE_TPAT_CPU_MODE; i < 0xa3fff; i += 0x10) {
11160			/* Skip the big blank spaces */
11161			if (i < 0x854000 && i > 0x9ffff)
11162				BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11163				    "0x%08X 0x%08X\n", i,
11164				    REG_RD_IND(sc, i),
11165				    REG_RD_IND(sc, i + 0x4),
11166				    REG_RD_IND(sc, i + 0x8),
11167				    REG_RD_IND(sc, i + 0xC));
11168		}
11169	}
11170
11171	BCE_PRINTF(
11172		"----------------------------"
11173		"----------------"
11174		"----------------------------\n");
11175}
11176
11177/****************************************************************************/
11178/* Prints out the Command Procesor (CP) state.                              */
11179/*                                                                          */
11180/* Returns:                                                                 */
11181/*   Nothing.                                                               */
11182/****************************************************************************/
11183static __attribute__ ((noinline)) void
11184bce_dump_cp_state(struct bce_softc *sc, int regs)
11185{
11186	u32 val;
11187	u32 fw_version[3];
11188
11189	BCE_PRINTF(
11190	    "----------------------------"
11191	    "    CP State    "
11192	    "----------------------------\n");
11193
11194	for (int i = 0; i < 3; i++)
11195		fw_version[i] = htonl(REG_RD_IND(sc,
11196		    (BCE_CP_SCRATCH + 0x10 + i * 4)));
11197
11198	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11199
11200	val = REG_RD_IND(sc, BCE_CP_CPU_MODE);
11201	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_mode\n",
11202	    val, BCE_CP_CPU_MODE);
11203
11204	val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
11205	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n",
11206	    val, BCE_CP_CPU_STATE);
11207
11208	val = REG_RD_IND(sc, BCE_CP_CPU_EVENT_MASK);
11209	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_event_mask\n", val,
11210	    BCE_CP_CPU_EVENT_MASK);
11211
11212	if (regs) {
11213		BCE_PRINTF(
11214		    "----------------------------"
11215		    " Register  Dump "
11216		    "----------------------------\n");
11217
11218		for (int i = BCE_CP_CPU_MODE; i < 0x1aa000; i += 0x10) {
11219			/* Skip the big blank spaces */
11220			if (i < 0x185400 && i > 0x19ffff)
11221				BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11222				    "0x%08X 0x%08X\n", i,
11223				    REG_RD_IND(sc, i),
11224				    REG_RD_IND(sc, i + 0x4),
11225				    REG_RD_IND(sc, i + 0x8),
11226				    REG_RD_IND(sc, i + 0xC));
11227		}
11228	}
11229
11230	BCE_PRINTF(
11231	    "----------------------------"
11232	    "----------------"
11233	    "----------------------------\n");
11234}
11235
11236/****************************************************************************/
11237/* Prints out the Completion Procesor (COM) state.                          */
11238/*                                                                          */
11239/* Returns:                                                                 */
11240/*   Nothing.                                                               */
11241/****************************************************************************/
11242static __attribute__ ((noinline)) void
11243bce_dump_com_state(struct bce_softc *sc, int regs)
11244{
11245	u32 val;
11246	u32 fw_version[4];
11247
11248	BCE_PRINTF(
11249	    "----------------------------"
11250	    "   COM State    "
11251	    "----------------------------\n");
11252
11253	for (int i = 0; i < 3; i++)
11254		fw_version[i] = htonl(REG_RD_IND(sc,
11255		    (BCE_COM_SCRATCH + 0x10 + i * 4)));
11256
11257	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11258
11259	val = REG_RD_IND(sc, BCE_COM_CPU_MODE);
11260	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_mode\n",
11261	    val, BCE_COM_CPU_MODE);
11262
11263	val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
11264	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n",
11265	    val, BCE_COM_CPU_STATE);
11266
11267	val = REG_RD_IND(sc, BCE_COM_CPU_EVENT_MASK);
11268	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_event_mask\n", val,
11269	    BCE_COM_CPU_EVENT_MASK);
11270
11271	if (regs) {
11272		BCE_PRINTF(
11273		    "----------------------------"
11274		    " Register  Dump "
11275		    "----------------------------\n");
11276
11277		for (int i = BCE_COM_CPU_MODE; i < 0x1053e8; i += 0x10) {
11278			BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11279			    "0x%08X 0x%08X\n", i,
11280			    REG_RD_IND(sc, i),
11281			    REG_RD_IND(sc, i + 0x4),
11282			    REG_RD_IND(sc, i + 0x8),
11283			    REG_RD_IND(sc, i + 0xC));
11284		}
11285	}
11286
11287	BCE_PRINTF(
11288		"----------------------------"
11289		"----------------"
11290		"----------------------------\n");
11291}
11292
11293/****************************************************************************/
11294/* Prints out the Receive Virtual 2 Physical (RV2P) state.                  */
11295/*                                                                          */
11296/* Returns:                                                                 */
11297/*   Nothing.                                                               */
11298/****************************************************************************/
11299static __attribute__ ((noinline)) void
11300bce_dump_rv2p_state(struct bce_softc *sc)
11301{
11302	u32 val, pc1, pc2, fw_ver_high, fw_ver_low;
11303
11304	BCE_PRINTF(
11305	    "----------------------------"
11306	    "   RV2P State   "
11307	    "----------------------------\n");
11308
11309	/* Stall the RV2P processors. */
11310	val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
11311	val |= BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2;
11312	REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
11313
11314	/* Read the firmware version. */
11315	val = 0x00000001;
11316	REG_WR_IND(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
11317	fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
11318	fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) &
11319	    BCE_RV2P_INSTR_HIGH_HIGH;
11320	BCE_PRINTF("RV2P1 Firmware version - 0x%08X:0x%08X\n",
11321	    fw_ver_high, fw_ver_low);
11322
11323	val = 0x00000001;
11324	REG_WR_IND(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
11325	fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
11326	fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) &
11327	    BCE_RV2P_INSTR_HIGH_HIGH;
11328	BCE_PRINTF("RV2P2 Firmware version - 0x%08X:0x%08X\n",
11329	    fw_ver_high, fw_ver_low);
11330
11331	/* Resume the RV2P processors. */
11332	val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
11333	val &= ~(BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2);
11334	REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
11335
11336	/* Fetch the program counter value. */
11337	val = 0x68007800;
11338	REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
11339	val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
11340	pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
11341	pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
11342	BCE_PRINTF("0x%08X - RV2P1 program counter (1st read)\n", pc1);
11343	BCE_PRINTF("0x%08X - RV2P2 program counter (1st read)\n", pc2);
11344
11345	/* Fetch the program counter value again to see if it is advancing. */
11346	val = 0x68007800;
11347	REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
11348	val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
11349	pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
11350	pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
11351	BCE_PRINTF("0x%08X - RV2P1 program counter (2nd read)\n", pc1);
11352	BCE_PRINTF("0x%08X - RV2P2 program counter (2nd read)\n", pc2);
11353
11354	BCE_PRINTF(
11355	    "----------------------------"
11356	    "----------------"
11357	    "----------------------------\n");
11358}
11359
11360/****************************************************************************/
11361/* Prints out the driver state and then enters the debugger.                */
11362/*                                                                          */
11363/* Returns:                                                                 */
11364/*   Nothing.                                                               */
11365/****************************************************************************/
11366static __attribute__ ((noinline)) void
11367bce_breakpoint(struct bce_softc *sc)
11368{
11369
11370	/*
11371	 * Unreachable code to silence compiler warnings
11372	 * about unused functions.
11373	 */
11374	if (0) {
11375		bce_freeze_controller(sc);
11376		bce_unfreeze_controller(sc);
11377		bce_dump_enet(sc, NULL);
11378		bce_dump_txbd(sc, 0, NULL);
11379		bce_dump_rxbd(sc, 0, NULL);
11380		bce_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD_ALLOC);
11381		bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD_ALLOC);
11382		bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD_ALLOC);
11383		bce_dump_l2fhdr(sc, 0, NULL);
11384		bce_dump_ctx(sc, RX_CID);
11385		bce_dump_ftqs(sc);
11386		bce_dump_tx_chain(sc, 0, USABLE_TX_BD_ALLOC);
11387		bce_dump_rx_bd_chain(sc, 0, USABLE_RX_BD_ALLOC);
11388		bce_dump_pg_chain(sc, 0, USABLE_PG_BD_ALLOC);
11389		bce_dump_status_block(sc);
11390		bce_dump_stats_block(sc);
11391		bce_dump_driver_state(sc);
11392		bce_dump_hw_state(sc);
11393		bce_dump_bc_state(sc);
11394		bce_dump_txp_state(sc, 0);
11395		bce_dump_rxp_state(sc, 0);
11396		bce_dump_tpat_state(sc, 0);
11397		bce_dump_cp_state(sc, 0);
11398		bce_dump_com_state(sc, 0);
11399		bce_dump_rv2p_state(sc);
11400		bce_dump_pgbd(sc, 0, NULL);
11401	}
11402
11403	bce_dump_status_block(sc);
11404	bce_dump_driver_state(sc);
11405
11406	/* Call the debugger. */
11407	breakpoint();
11408}
11409#endif
11410