if_bce.c revision 267961
1/*-
2 * Copyright (c) 2006-2014 QLogic Corporation
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/dev/bce/if_bce.c 267961 2014-06-27 16:33:43Z hselasky $");
29
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
201	{ 0, 0, 0, 0, NULL }
202};
203
204
205/****************************************************************************/
206/* Supported Flash NVRAM device data.                                       */
207/****************************************************************************/
208static const struct flash_spec flash_table[] =
209{
210#define BUFFERED_FLAGS		(BCE_NV_BUFFERED | BCE_NV_TRANSLATE)
211#define NONBUFFERED_FLAGS	(BCE_NV_WREN)
212
213	/* Slow EEPROM */
214	{0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
215	 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
216	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
217	 "EEPROM - slow"},
218	/* Expansion entry 0001 */
219	{0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
220	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
221	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
222	 "Entry 0001"},
223	/* Saifun SA25F010 (non-buffered flash) */
224	/* strap, cfg1, & write1 need updates */
225	{0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
226	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
227	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
228	 "Non-buffered flash (128kB)"},
229	/* Saifun SA25F020 (non-buffered flash) */
230	/* strap, cfg1, & write1 need updates */
231	{0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
232	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
233	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
234	 "Non-buffered flash (256kB)"},
235	/* Expansion entry 0100 */
236	{0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
237	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
238	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
239	 "Entry 0100"},
240	/* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
241	{0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
242	 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
243	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
244	 "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
245	/* Entry 0110: ST M45PE20 (non-buffered flash)*/
246	{0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
247	 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
248	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
249	 "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
250	/* Saifun SA25F005 (non-buffered flash) */
251	/* strap, cfg1, & write1 need updates */
252	{0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
253	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
254	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
255	 "Non-buffered flash (64kB)"},
256	/* Fast EEPROM */
257	{0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
258	 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
259	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
260	 "EEPROM - fast"},
261	/* Expansion entry 1001 */
262	{0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
263	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
264	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
265	 "Entry 1001"},
266	/* Expansion entry 1010 */
267	{0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
268	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
269	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
270	 "Entry 1010"},
271	/* ATMEL AT45DB011B (buffered flash) */
272	{0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
273	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
274	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
275	 "Buffered flash (128kB)"},
276	/* Expansion entry 1100 */
277	{0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
278	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
279	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
280	 "Entry 1100"},
281	/* Expansion entry 1101 */
282	{0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
283	 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
284	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
285	 "Entry 1101"},
286	/* Ateml Expansion entry 1110 */
287	{0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
288	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
289	 BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
290	 "Entry 1110 (Atmel)"},
291	/* ATMEL AT45DB021B (buffered flash) */
292	{0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
293	 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
294	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
295	 "Buffered flash (256kB)"},
296};
297
298/*
299 * The BCM5709 controllers transparently handle the
300 * differences between Atmel 264 byte pages and all
301 * flash devices which use 256 byte pages, so no
302 * logical-to-physical mapping is required in the
303 * driver.
304 */
305static const struct flash_spec flash_5709 = {
306	.flags		= BCE_NV_BUFFERED,
307	.page_bits	= BCM5709_FLASH_PAGE_BITS,
308	.page_size	= BCM5709_FLASH_PAGE_SIZE,
309	.addr_mask	= BCM5709_FLASH_BYTE_ADDR_MASK,
310	.total_size	= BUFFERED_FLASH_TOTAL_SIZE * 2,
311	.name		= "5709/5716 buffered flash (256kB)",
312};
313
314
315/****************************************************************************/
316/* FreeBSD device entry points.                                             */
317/****************************************************************************/
318static int  bce_probe			(device_t);
319static int  bce_attach			(device_t);
320static int  bce_detach			(device_t);
321static int  bce_shutdown		(device_t);
322
323
324/****************************************************************************/
325/* BCE Debug Data Structure Dump Routines                                   */
326/****************************************************************************/
327#ifdef BCE_DEBUG
328static u32  bce_reg_rd				(struct bce_softc *, u32);
329static void bce_reg_wr				(struct bce_softc *, u32, u32);
330static void bce_reg_wr16			(struct bce_softc *, u32, u16);
331static u32  bce_ctx_rd				(struct bce_softc *, u32, u32);
332static void bce_dump_enet			(struct bce_softc *, struct mbuf *);
333static void bce_dump_mbuf			(struct bce_softc *, struct mbuf *);
334static void bce_dump_tx_mbuf_chain	(struct bce_softc *, u16, int);
335static void bce_dump_rx_mbuf_chain	(struct bce_softc *, u16, int);
336static void bce_dump_pg_mbuf_chain	(struct bce_softc *, u16, int);
337static void bce_dump_txbd			(struct bce_softc *,
338    int, struct tx_bd *);
339static void bce_dump_rxbd			(struct bce_softc *,
340    int, struct rx_bd *);
341static void bce_dump_pgbd			(struct bce_softc *,
342    int, struct rx_bd *);
343static void bce_dump_l2fhdr		(struct bce_softc *,
344    int, struct l2_fhdr *);
345static void bce_dump_ctx			(struct bce_softc *, u16);
346static void bce_dump_ftqs			(struct bce_softc *);
347static void bce_dump_tx_chain		(struct bce_softc *, u16, int);
348static void bce_dump_rx_bd_chain	(struct bce_softc *, u16, int);
349static void bce_dump_pg_chain		(struct bce_softc *, u16, int);
350static void bce_dump_status_block	(struct bce_softc *);
351static void bce_dump_stats_block	(struct bce_softc *);
352static void bce_dump_driver_state	(struct bce_softc *);
353static void bce_dump_hw_state		(struct bce_softc *);
354static void bce_dump_shmem_state	(struct bce_softc *);
355static void bce_dump_mq_regs		(struct bce_softc *);
356static void bce_dump_bc_state		(struct bce_softc *);
357static void bce_dump_txp_state		(struct bce_softc *, int);
358static void bce_dump_rxp_state		(struct bce_softc *, int);
359static void bce_dump_tpat_state	(struct bce_softc *, int);
360static void bce_dump_cp_state		(struct bce_softc *, int);
361static void bce_dump_com_state		(struct bce_softc *, int);
362static void bce_dump_rv2p_state	(struct bce_softc *);
363static void bce_breakpoint			(struct bce_softc *);
364#endif /*BCE_DEBUG */
365
366
367/****************************************************************************/
368/* BCE Register/Memory Access Routines                                      */
369/****************************************************************************/
370static u32  bce_reg_rd_ind		(struct bce_softc *, u32);
371static void bce_reg_wr_ind		(struct bce_softc *, u32, u32);
372static void bce_shmem_wr		(struct bce_softc *, u32, u32);
373static u32  bce_shmem_rd		(struct bce_softc *, u32);
374static void bce_ctx_wr			(struct bce_softc *, u32, u32, u32);
375static int  bce_miibus_read_reg		(device_t, int, int);
376static int  bce_miibus_write_reg	(device_t, int, int, int);
377static void bce_miibus_statchg		(device_t);
378
379#ifdef BCE_DEBUG
380static int bce_sysctl_nvram_dump(SYSCTL_HANDLER_ARGS);
381#ifdef BCE_NVRAM_WRITE_SUPPORT
382static int bce_sysctl_nvram_write(SYSCTL_HANDLER_ARGS);
383#endif
384#endif
385
386/****************************************************************************/
387/* BCE NVRAM Access Routines                                                */
388/****************************************************************************/
389static int  bce_acquire_nvram_lock	(struct bce_softc *);
390static int  bce_release_nvram_lock	(struct bce_softc *);
391static void bce_enable_nvram_access(struct bce_softc *);
392static void bce_disable_nvram_access(struct bce_softc *);
393static int  bce_nvram_read_dword	(struct bce_softc *, u32, u8 *, u32);
394static int  bce_init_nvram			(struct bce_softc *);
395static int  bce_nvram_read			(struct bce_softc *, u32, u8 *, int);
396static int  bce_nvram_test			(struct bce_softc *);
397#ifdef BCE_NVRAM_WRITE_SUPPORT
398static int  bce_enable_nvram_write	(struct bce_softc *);
399static void bce_disable_nvram_write(struct bce_softc *);
400static int  bce_nvram_erase_page	(struct bce_softc *, u32);
401static int  bce_nvram_write_dword	(struct bce_softc *, u32, u8 *, u32);
402static int  bce_nvram_write		(struct bce_softc *, u32, u8 *, int);
403#endif
404
405/****************************************************************************/
406/*                                                                          */
407/****************************************************************************/
408static void bce_get_rx_buffer_sizes(struct bce_softc *, int);
409static void bce_get_media			(struct bce_softc *);
410static void bce_init_media			(struct bce_softc *);
411static u32 bce_get_rphy_link		(struct bce_softc *);
412static void bce_dma_map_addr		(void *, bus_dma_segment_t *, int, int);
413static int  bce_dma_alloc			(device_t);
414static void bce_dma_free			(struct bce_softc *);
415static void bce_release_resources	(struct bce_softc *);
416
417/****************************************************************************/
418/* BCE Firmware Synchronization and Load                                    */
419/****************************************************************************/
420static void bce_fw_cap_init			(struct bce_softc *);
421static int  bce_fw_sync			(struct bce_softc *, u32);
422static void bce_load_rv2p_fw		(struct bce_softc *, const u32 *, u32,
423    u32);
424static void bce_load_cpu_fw		(struct bce_softc *,
425    struct cpu_reg *, struct fw_info *);
426static void bce_start_cpu			(struct bce_softc *, struct cpu_reg *);
427static void bce_halt_cpu			(struct bce_softc *, struct cpu_reg *);
428static void bce_start_rxp_cpu		(struct bce_softc *);
429static void bce_init_rxp_cpu		(struct bce_softc *);
430static void bce_init_txp_cpu 		(struct bce_softc *);
431static void bce_init_tpat_cpu		(struct bce_softc *);
432static void bce_init_cp_cpu	  	(struct bce_softc *);
433static void bce_init_com_cpu	  	(struct bce_softc *);
434static void bce_init_cpus			(struct bce_softc *);
435
436static void bce_print_adapter_info	(struct bce_softc *);
437static void bce_probe_pci_caps		(device_t, struct bce_softc *);
438static void bce_stop				(struct bce_softc *);
439static int  bce_reset				(struct bce_softc *, u32);
440static int  bce_chipinit 			(struct bce_softc *);
441static int  bce_blockinit 			(struct bce_softc *);
442
443static int  bce_init_tx_chain		(struct bce_softc *);
444static void bce_free_tx_chain		(struct bce_softc *);
445
446static int  bce_get_rx_buf		(struct bce_softc *, u16, u16, u32 *);
447static int  bce_init_rx_chain		(struct bce_softc *);
448static void bce_fill_rx_chain		(struct bce_softc *);
449static void bce_free_rx_chain		(struct bce_softc *);
450
451static int  bce_get_pg_buf		(struct bce_softc *, u16, u16);
452static int  bce_init_pg_chain		(struct bce_softc *);
453static void bce_fill_pg_chain		(struct bce_softc *);
454static void bce_free_pg_chain		(struct bce_softc *);
455
456static struct mbuf *bce_tso_setup	(struct bce_softc *,
457    struct mbuf **, u16 *);
458static int  bce_tx_encap			(struct bce_softc *, struct mbuf **);
459static void bce_start_locked		(struct ifnet *);
460static void bce_start				(struct ifnet *);
461static int  bce_ioctl				(struct ifnet *, u_long, caddr_t);
462static void bce_watchdog			(struct bce_softc *);
463static int  bce_ifmedia_upd		(struct ifnet *);
464static int  bce_ifmedia_upd_locked	(struct ifnet *);
465static void bce_ifmedia_sts		(struct ifnet *, struct ifmediareq *);
466static void bce_ifmedia_sts_rphy	(struct bce_softc *, struct ifmediareq *);
467static void bce_init_locked		(struct bce_softc *);
468static void bce_init				(void *);
469static void bce_mgmt_init_locked	(struct bce_softc *sc);
470
471static int  bce_init_ctx			(struct bce_softc *);
472static void bce_get_mac_addr		(struct bce_softc *);
473static void bce_set_mac_addr		(struct bce_softc *);
474static void bce_phy_intr			(struct bce_softc *);
475static inline u16 bce_get_hw_rx_cons	(struct bce_softc *);
476static void bce_rx_intr			(struct bce_softc *);
477static void bce_tx_intr			(struct bce_softc *);
478static void bce_disable_intr		(struct bce_softc *);
479static void bce_enable_intr		(struct bce_softc *, int);
480
481static void bce_intr				(void *);
482static void bce_set_rx_mode		(struct bce_softc *);
483static void bce_stats_update		(struct bce_softc *);
484static void bce_tick				(void *);
485static void bce_pulse				(void *);
486static void bce_add_sysctls		(struct bce_softc *);
487
488
489/****************************************************************************/
490/* FreeBSD device dispatch table.                                           */
491/****************************************************************************/
492static device_method_t bce_methods[] = {
493	/* Device interface (device_if.h) */
494	DEVMETHOD(device_probe,		bce_probe),
495	DEVMETHOD(device_attach,	bce_attach),
496	DEVMETHOD(device_detach,	bce_detach),
497	DEVMETHOD(device_shutdown,	bce_shutdown),
498/* Supported by device interface but not used here. */
499/*	DEVMETHOD(device_identify,	bce_identify),      */
500/*	DEVMETHOD(device_suspend,	bce_suspend),       */
501/*	DEVMETHOD(device_resume,	bce_resume),        */
502/*	DEVMETHOD(device_quiesce,	bce_quiesce),       */
503
504	/* MII interface (miibus_if.h) */
505	DEVMETHOD(miibus_readreg,	bce_miibus_read_reg),
506	DEVMETHOD(miibus_writereg,	bce_miibus_write_reg),
507	DEVMETHOD(miibus_statchg,	bce_miibus_statchg),
508/* Supported by MII interface but not used here.       */
509/*	DEVMETHOD(miibus_linkchg,	bce_miibus_linkchg),   */
510/*	DEVMETHOD(miibus_mediainit,	bce_miibus_mediainit), */
511
512	DEVMETHOD_END
513};
514
515static driver_t bce_driver = {
516	"bce",
517	bce_methods,
518	sizeof(struct bce_softc)
519};
520
521static devclass_t bce_devclass;
522
523MODULE_DEPEND(bce, pci, 1, 1, 1);
524MODULE_DEPEND(bce, ether, 1, 1, 1);
525MODULE_DEPEND(bce, miibus, 1, 1, 1);
526
527DRIVER_MODULE(bce, pci, bce_driver, bce_devclass, NULL, NULL);
528DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, NULL, NULL);
529
530
531/****************************************************************************/
532/* Tunable device values                                                    */
533/****************************************************************************/
534static SYSCTL_NODE(_hw, OID_AUTO, bce, CTLFLAG_RD, 0, "bce driver parameters");
535
536/* Allowable values are TRUE or FALSE */
537static int bce_verbose = TRUE;
538SYSCTL_INT(_hw_bce, OID_AUTO, verbose, CTLFLAG_RDTUN, &bce_verbose, 0,
539    "Verbose output enable/disable");
540
541/* Allowable values are TRUE or FALSE */
542static int bce_tso_enable = TRUE;
543SYSCTL_INT(_hw_bce, OID_AUTO, tso_enable, CTLFLAG_RDTUN, &bce_tso_enable, 0,
544    "TSO Enable/Disable");
545
546/* Allowable values are 0 (IRQ), 1 (MSI/IRQ), and 2 (MSI-X/MSI/IRQ) */
547/* ToDo: Add MSI-X support. */
548static int bce_msi_enable = 1;
549SYSCTL_INT(_hw_bce, OID_AUTO, msi_enable, CTLFLAG_RDTUN, &bce_msi_enable, 0,
550    "MSI-X|MSI|INTx selector");
551
552/* Allowable values are 1, 2, 4, 8. */
553static int bce_rx_pages = DEFAULT_RX_PAGES;
554SYSCTL_UINT(_hw_bce, OID_AUTO, rx_pages, CTLFLAG_RDTUN, &bce_rx_pages, 0,
555    "Receive buffer descriptor pages (1 page = 255 buffer descriptors)");
556
557/* Allowable values are 1, 2, 4, 8. */
558static int bce_tx_pages = DEFAULT_TX_PAGES;
559SYSCTL_UINT(_hw_bce, OID_AUTO, tx_pages, CTLFLAG_RDTUN, &bce_tx_pages, 0,
560    "Transmit buffer descriptor pages (1 page = 255 buffer descriptors)");
561
562/* Allowable values are TRUE or FALSE. */
563static int bce_hdr_split = TRUE;
564SYSCTL_UINT(_hw_bce, OID_AUTO, hdr_split, CTLFLAG_RDTUN, &bce_hdr_split, 0,
565    "Frame header/payload splitting Enable/Disable");
566
567/* Allowable values are TRUE or FALSE. */
568static int bce_strict_rx_mtu = FALSE;
569SYSCTL_UINT(_hw_bce, OID_AUTO, strict_rx_mtu, CTLFLAG_RDTUN,
570    &bce_strict_rx_mtu, 0,
571    "Enable/Disable strict RX frame size checking");
572
573/* Allowable values are 0 ... 100 */
574#ifdef BCE_DEBUG
575/* Generate 1 interrupt for every transmit completion. */
576static int bce_tx_quick_cons_trip_int = 1;
577#else
578/* Generate 1 interrupt for every 20 transmit completions. */
579static int bce_tx_quick_cons_trip_int = DEFAULT_TX_QUICK_CONS_TRIP_INT;
580#endif
581SYSCTL_UINT(_hw_bce, OID_AUTO, tx_quick_cons_trip_int, CTLFLAG_RDTUN,
582    &bce_tx_quick_cons_trip_int, 0,
583    "Transmit BD trip point during interrupts");
584
585/* Allowable values are 0 ... 100 */
586/* Generate 1 interrupt for every transmit completion. */
587#ifdef BCE_DEBUG
588static int bce_tx_quick_cons_trip = 1;
589#else
590/* Generate 1 interrupt for every 20 transmit completions. */
591static int bce_tx_quick_cons_trip = DEFAULT_TX_QUICK_CONS_TRIP;
592#endif
593SYSCTL_UINT(_hw_bce, OID_AUTO, tx_quick_cons_trip, CTLFLAG_RDTUN,
594    &bce_tx_quick_cons_trip, 0,
595    "Transmit BD trip point");
596
597/* Allowable values are 0 ... 100 */
598#ifdef BCE_DEBUG
599/* Generate an interrupt if 0us have elapsed since the last TX completion. */
600static int bce_tx_ticks_int = 0;
601#else
602/* Generate an interrupt if 80us have elapsed since the last TX completion. */
603static int bce_tx_ticks_int = DEFAULT_TX_TICKS_INT;
604#endif
605SYSCTL_UINT(_hw_bce, OID_AUTO, tx_ticks_int, CTLFLAG_RDTUN,
606    &bce_tx_ticks_int, 0, "Transmit ticks count during interrupt");
607
608/* Allowable values are 0 ... 100 */
609#ifdef BCE_DEBUG
610/* Generate an interrupt if 0us have elapsed since the last TX completion. */
611static int bce_tx_ticks = 0;
612#else
613/* Generate an interrupt if 80us have elapsed since the last TX completion. */
614static int bce_tx_ticks = DEFAULT_TX_TICKS;
615#endif
616SYSCTL_UINT(_hw_bce, OID_AUTO, tx_ticks, CTLFLAG_RDTUN,
617    &bce_tx_ticks, 0, "Transmit ticks count");
618
619/* Allowable values are 1 ... 100 */
620#ifdef BCE_DEBUG
621/* Generate 1 interrupt for every received frame. */
622static int bce_rx_quick_cons_trip_int = 1;
623#else
624/* Generate 1 interrupt for every 6 received frames. */
625static int bce_rx_quick_cons_trip_int = DEFAULT_RX_QUICK_CONS_TRIP_INT;
626#endif
627SYSCTL_UINT(_hw_bce, OID_AUTO, rx_quick_cons_trip_int, CTLFLAG_RDTUN,
628    &bce_rx_quick_cons_trip_int, 0,
629    "Receive BD trip point duirng interrupts");
630
631/* Allowable values are 1 ... 100 */
632#ifdef BCE_DEBUG
633/* Generate 1 interrupt for every received frame. */
634static int bce_rx_quick_cons_trip = 1;
635#else
636/* Generate 1 interrupt for every 6 received frames. */
637static int bce_rx_quick_cons_trip = DEFAULT_RX_QUICK_CONS_TRIP;
638#endif
639SYSCTL_UINT(_hw_bce, OID_AUTO, rx_quick_cons_trip, CTLFLAG_RDTUN,
640    &bce_rx_quick_cons_trip, 0,
641    "Receive BD trip point");
642
643/* Allowable values are 0 ... 100 */
644#ifdef BCE_DEBUG
645/* Generate an int. if 0us have elapsed since the last received frame. */
646static int bce_rx_ticks_int = 0;
647#else
648/* Generate an int. if 18us have elapsed since the last received frame. */
649static int bce_rx_ticks_int = DEFAULT_RX_TICKS_INT;
650#endif
651SYSCTL_UINT(_hw_bce, OID_AUTO, rx_ticks_int, CTLFLAG_RDTUN,
652    &bce_rx_ticks_int, 0, "Receive ticks count during interrupt");
653
654/* Allowable values are 0 ... 100 */
655#ifdef BCE_DEBUG
656/* Generate an int. if 0us have elapsed since the last received frame. */
657static int bce_rx_ticks = 0;
658#else
659/* Generate an int. if 18us have elapsed since the last received frame. */
660static int bce_rx_ticks = DEFAULT_RX_TICKS;
661#endif
662SYSCTL_UINT(_hw_bce, OID_AUTO, rx_ticks, CTLFLAG_RDTUN,
663    &bce_rx_ticks, 0, "Receive ticks count");
664
665
666/****************************************************************************/
667/* Device probe function.                                                   */
668/*                                                                          */
669/* Compares the device to the driver's list of supported devices and        */
670/* reports back to the OS whether this is the right driver for the device.  */
671/*                                                                          */
672/* Returns:                                                                 */
673/*   BUS_PROBE_DEFAULT on success, positive value on failure.               */
674/****************************************************************************/
675static int
676bce_probe(device_t dev)
677{
678	const struct bce_type *t;
679	struct bce_softc *sc;
680	char *descbuf;
681	u16 vid = 0, did = 0, svid = 0, sdid = 0;
682
683	t = bce_devs;
684
685	sc = device_get_softc(dev);
686	sc->bce_unit = device_get_unit(dev);
687	sc->bce_dev = dev;
688
689	/* Get the data for the device to be probed. */
690	vid  = pci_get_vendor(dev);
691	did  = pci_get_device(dev);
692	svid = pci_get_subvendor(dev);
693	sdid = pci_get_subdevice(dev);
694
695	DBPRINT(sc, BCE_EXTREME_LOAD,
696	    "%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
697	    "SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
698
699	/* Look through the list of known devices for a match. */
700	while(t->bce_name != NULL) {
701
702		if ((vid == t->bce_vid) && (did == t->bce_did) &&
703		    ((svid == t->bce_svid) || (t->bce_svid == PCI_ANY_ID)) &&
704		    ((sdid == t->bce_sdid) || (t->bce_sdid == PCI_ANY_ID))) {
705
706			descbuf = malloc(BCE_DEVDESC_MAX, M_TEMP, M_NOWAIT);
707
708			if (descbuf == NULL)
709				return(ENOMEM);
710
711			/* Print out the device identity. */
712			snprintf(descbuf, BCE_DEVDESC_MAX, "%s (%c%d)",
713			    t->bce_name, (((pci_read_config(dev,
714			    PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
715			    (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
716
717			device_set_desc_copy(dev, descbuf);
718			free(descbuf, M_TEMP);
719			return(BUS_PROBE_DEFAULT);
720		}
721		t++;
722	}
723
724	return(ENXIO);
725}
726
727
728/****************************************************************************/
729/* PCI Capabilities Probe Function.                                         */
730/*                                                                          */
731/* Walks the PCI capabiites list for the device to find what features are   */
732/* supported.                                                               */
733/*                                                                          */
734/* Returns:                                                                 */
735/*   None.                                                                  */
736/****************************************************************************/
737static void
738bce_print_adapter_info(struct bce_softc *sc)
739{
740	int i = 0;
741
742	DBENTER(BCE_VERBOSE_LOAD);
743
744	if (bce_verbose || bootverbose) {
745		BCE_PRINTF("ASIC (0x%08X); ", sc->bce_chipid);
746		printf("Rev (%c%d); ", ((BCE_CHIP_ID(sc) & 0xf000) >>
747		    12) + 'A', ((BCE_CHIP_ID(sc) & 0x0ff0) >> 4));
748
749
750		/* Bus info. */
751		if (sc->bce_flags & BCE_PCIE_FLAG) {
752			printf("Bus (PCIe x%d, ", sc->link_width);
753			switch (sc->link_speed) {
754			case 1: printf("2.5Gbps); "); break;
755			case 2:	printf("5Gbps); "); break;
756			default: printf("Unknown link speed); ");
757			}
758		} else {
759			printf("Bus (PCI%s, %s, %dMHz); ",
760			    ((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""),
761			    ((sc->bce_flags & BCE_PCI_32BIT_FLAG) ?
762			    "32-bit" : "64-bit"), sc->bus_speed_mhz);
763		}
764
765		/* Firmware version and device features. */
766		printf("B/C (%s); Bufs (RX:%d;TX:%d;PG:%d); Flags (",
767		    sc->bce_bc_ver,	sc->rx_pages, sc->tx_pages,
768		    (bce_hdr_split == TRUE ? sc->pg_pages: 0));
769
770		if (bce_hdr_split == TRUE) {
771			printf("SPLT");
772			i++;
773		}
774
775		if (sc->bce_flags & BCE_USING_MSI_FLAG) {
776			if (i > 0) printf("|");
777			printf("MSI"); i++;
778		}
779
780		if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
781			if (i > 0) printf("|");
782			printf("MSI-X"); i++;
783		}
784
785		if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
786			if (i > 0) printf("|");
787			printf("2.5G"); i++;
788		}
789
790		if (sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) {
791			if (i > 0) printf("|");
792			printf("Remote PHY(%s)",
793			    sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG ?
794			    "FIBER" : "TP"); i++;
795		}
796
797		if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
798			if (i > 0) printf("|");
799			printf("MFW); MFW (%s)\n", sc->bce_mfw_ver);
800		} else {
801			printf(")\n");
802		}
803
804		printf("Coal (RX:%d,%d,%d,%d; TX:%d,%d,%d,%d)\n",
805		    sc->bce_rx_quick_cons_trip_int,
806		    sc->bce_rx_quick_cons_trip,
807		    sc->bce_rx_ticks_int,
808		    sc->bce_rx_ticks,
809		    sc->bce_tx_quick_cons_trip_int,
810		    sc->bce_tx_quick_cons_trip,
811		    sc->bce_tx_ticks_int,
812		    sc->bce_tx_ticks);
813
814	}
815
816	DBEXIT(BCE_VERBOSE_LOAD);
817}
818
819
820/****************************************************************************/
821/* PCI Capabilities Probe Function.                                         */
822/*                                                                          */
823/* Walks the PCI capabiites list for the device to find what features are   */
824/* supported.                                                               */
825/*                                                                          */
826/* Returns:                                                                 */
827/*   None.                                                                  */
828/****************************************************************************/
829static void
830bce_probe_pci_caps(device_t dev, struct bce_softc *sc)
831{
832	u32 reg;
833
834	DBENTER(BCE_VERBOSE_LOAD);
835
836	/* Check if PCI-X capability is enabled. */
837	if (pci_find_cap(dev, PCIY_PCIX, &reg) == 0) {
838		if (reg != 0)
839			sc->bce_cap_flags |= BCE_PCIX_CAPABLE_FLAG;
840	}
841
842	/* Check if PCIe capability is enabled. */
843	if (pci_find_cap(dev, PCIY_EXPRESS, &reg) == 0) {
844		if (reg != 0) {
845			u16 link_status = pci_read_config(dev, reg + 0x12, 2);
846			DBPRINT(sc, BCE_INFO_LOAD, "PCIe link_status = "
847			    "0x%08X\n",	link_status);
848			sc->link_speed = link_status & 0xf;
849			sc->link_width = (link_status >> 4) & 0x3f;
850			sc->bce_cap_flags |= BCE_PCIE_CAPABLE_FLAG;
851			sc->bce_flags |= BCE_PCIE_FLAG;
852		}
853	}
854
855	/* Check if MSI capability is enabled. */
856	if (pci_find_cap(dev, PCIY_MSI, &reg) == 0) {
857		if (reg != 0)
858			sc->bce_cap_flags |= BCE_MSI_CAPABLE_FLAG;
859	}
860
861	/* Check if MSI-X capability is enabled. */
862	if (pci_find_cap(dev, PCIY_MSIX, &reg) == 0) {
863		if (reg != 0)
864			sc->bce_cap_flags |= BCE_MSIX_CAPABLE_FLAG;
865	}
866
867	DBEXIT(BCE_VERBOSE_LOAD);
868}
869
870
871/****************************************************************************/
872/* Load and validate user tunable settings.                                 */
873/*                                                                          */
874/* Returns:                                                                 */
875/*   Nothing.                                                               */
876/****************************************************************************/
877static void
878bce_set_tunables(struct bce_softc *sc)
879{
880	/* Set sysctl values for RX page count. */
881	switch (bce_rx_pages) {
882	case 1:
883		/* fall-through */
884	case 2:
885		/* fall-through */
886	case 4:
887		/* fall-through */
888	case 8:
889		sc->rx_pages = bce_rx_pages;
890		break;
891	default:
892		sc->rx_pages = DEFAULT_RX_PAGES;
893		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
894		    "hw.bce.rx_pages!  Setting default of %d.\n",
895		    __FILE__, __LINE__, bce_rx_pages, DEFAULT_RX_PAGES);
896	}
897
898	/* ToDo: Consider allowing user setting for pg_pages. */
899	sc->pg_pages = min((sc->rx_pages * 4), MAX_PG_PAGES);
900
901	/* Set sysctl values for TX page count. */
902	switch (bce_tx_pages) {
903	case 1:
904		/* fall-through */
905	case 2:
906		/* fall-through */
907	case 4:
908		/* fall-through */
909	case 8:
910		sc->tx_pages = bce_tx_pages;
911		break;
912	default:
913		sc->tx_pages = DEFAULT_TX_PAGES;
914		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
915		    "hw.bce.tx_pages!  Setting default of %d.\n",
916		    __FILE__, __LINE__, bce_tx_pages, DEFAULT_TX_PAGES);
917	}
918
919	/*
920	 * Validate the TX trip point (i.e. the number of
921	 * TX completions before a status block update is
922	 * generated and an interrupt is asserted.
923	 */
924	if (bce_tx_quick_cons_trip_int <= 100) {
925		sc->bce_tx_quick_cons_trip_int =
926		    bce_tx_quick_cons_trip_int;
927	} else {
928		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
929		    "hw.bce.tx_quick_cons_trip_int!  Setting default of %d.\n",
930		    __FILE__, __LINE__, bce_tx_quick_cons_trip_int,
931		    DEFAULT_TX_QUICK_CONS_TRIP_INT);
932		sc->bce_tx_quick_cons_trip_int =
933		    DEFAULT_TX_QUICK_CONS_TRIP_INT;
934	}
935
936	if (bce_tx_quick_cons_trip <= 100) {
937		sc->bce_tx_quick_cons_trip =
938		    bce_tx_quick_cons_trip;
939	} else {
940		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
941		    "hw.bce.tx_quick_cons_trip!  Setting default of %d.\n",
942		    __FILE__, __LINE__, bce_tx_quick_cons_trip,
943		    DEFAULT_TX_QUICK_CONS_TRIP);
944		sc->bce_tx_quick_cons_trip =
945		    DEFAULT_TX_QUICK_CONS_TRIP;
946	}
947
948	/*
949	 * Validate the TX ticks count (i.e. the maximum amount
950	 * of time to wait after the last TX completion has
951	 * occurred before a status block update is generated
952	 * and an interrupt is asserted.
953	 */
954	if (bce_tx_ticks_int <= 100) {
955		sc->bce_tx_ticks_int =
956		    bce_tx_ticks_int;
957	} else {
958		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
959		    "hw.bce.tx_ticks_int!  Setting default of %d.\n",
960		    __FILE__, __LINE__, bce_tx_ticks_int,
961		    DEFAULT_TX_TICKS_INT);
962		sc->bce_tx_ticks_int =
963		    DEFAULT_TX_TICKS_INT;
964	   }
965
966	if (bce_tx_ticks <= 100) {
967		sc->bce_tx_ticks =
968		    bce_tx_ticks;
969	} else {
970		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
971		    "hw.bce.tx_ticks!  Setting default of %d.\n",
972		    __FILE__, __LINE__, bce_tx_ticks,
973		    DEFAULT_TX_TICKS);
974		sc->bce_tx_ticks =
975		    DEFAULT_TX_TICKS;
976	}
977
978	/*
979	 * Validate the RX trip point (i.e. the number of
980	 * RX frames received before a status block update is
981	 * generated and an interrupt is asserted.
982	 */
983	if (bce_rx_quick_cons_trip_int <= 100) {
984		sc->bce_rx_quick_cons_trip_int =
985		    bce_rx_quick_cons_trip_int;
986	} else {
987		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
988		    "hw.bce.rx_quick_cons_trip_int!  Setting default of %d.\n",
989		    __FILE__, __LINE__, bce_rx_quick_cons_trip_int,
990		    DEFAULT_RX_QUICK_CONS_TRIP_INT);
991		sc->bce_rx_quick_cons_trip_int =
992		    DEFAULT_RX_QUICK_CONS_TRIP_INT;
993	}
994
995	if (bce_rx_quick_cons_trip <= 100) {
996		sc->bce_rx_quick_cons_trip =
997		    bce_rx_quick_cons_trip;
998	} else {
999		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
1000		    "hw.bce.rx_quick_cons_trip!  Setting default of %d.\n",
1001		    __FILE__, __LINE__, bce_rx_quick_cons_trip,
1002		    DEFAULT_RX_QUICK_CONS_TRIP);
1003		sc->bce_rx_quick_cons_trip =
1004		    DEFAULT_RX_QUICK_CONS_TRIP;
1005	}
1006
1007	/*
1008	 * Validate the RX ticks count (i.e. the maximum amount
1009	 * of time to wait after the last RX frame has been
1010	 * received before a status block update is generated
1011	 * and an interrupt is asserted.
1012	 */
1013	if (bce_rx_ticks_int <= 100) {
1014		sc->bce_rx_ticks_int = bce_rx_ticks_int;
1015	} else {
1016		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
1017		    "hw.bce.rx_ticks_int!  Setting default of %d.\n",
1018		    __FILE__, __LINE__, bce_rx_ticks_int,
1019		    DEFAULT_RX_TICKS_INT);
1020		sc->bce_rx_ticks_int = DEFAULT_RX_TICKS_INT;
1021	}
1022
1023	if (bce_rx_ticks <= 100) {
1024		sc->bce_rx_ticks = bce_rx_ticks;
1025	} else {
1026		BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
1027		    "hw.bce.rx_ticks!  Setting default of %d.\n",
1028		    __FILE__, __LINE__, bce_rx_ticks,
1029		    DEFAULT_RX_TICKS);
1030		sc->bce_rx_ticks = DEFAULT_RX_TICKS;
1031	}
1032
1033	/* Disabling both RX ticks and RX trips will prevent interrupts. */
1034	if ((bce_rx_quick_cons_trip == 0) && (bce_rx_ticks == 0)) {
1035		BCE_PRINTF("%s(%d): Cannot set both hw.bce.rx_ticks and "
1036		    "hw.bce.rx_quick_cons_trip to 0. Setting default values.\n",
1037		   __FILE__, __LINE__);
1038		sc->bce_rx_ticks = DEFAULT_RX_TICKS;
1039		sc->bce_rx_quick_cons_trip = DEFAULT_RX_QUICK_CONS_TRIP;
1040	}
1041
1042	/* Disabling both TX ticks and TX trips will prevent interrupts. */
1043	if ((bce_tx_quick_cons_trip == 0) && (bce_tx_ticks == 0)) {
1044		BCE_PRINTF("%s(%d): Cannot set both hw.bce.tx_ticks and "
1045		    "hw.bce.tx_quick_cons_trip to 0. Setting default values.\n",
1046		   __FILE__, __LINE__);
1047		sc->bce_tx_ticks = DEFAULT_TX_TICKS;
1048		sc->bce_tx_quick_cons_trip = DEFAULT_TX_QUICK_CONS_TRIP;
1049	}
1050}
1051
1052
1053/****************************************************************************/
1054/* Device attach function.                                                  */
1055/*                                                                          */
1056/* Allocates device resources, performs secondary chip identification,      */
1057/* resets and initializes the hardware, and initializes driver instance     */
1058/* variables.                                                               */
1059/*                                                                          */
1060/* Returns:                                                                 */
1061/*   0 on success, positive value on failure.                               */
1062/****************************************************************************/
1063static int
1064bce_attach(device_t dev)
1065{
1066	struct bce_softc *sc;
1067	struct ifnet *ifp;
1068	u32 val;
1069	int count, error, rc = 0, rid;
1070
1071	sc = device_get_softc(dev);
1072	sc->bce_dev = dev;
1073
1074	DBENTER(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
1075
1076	sc->bce_unit = device_get_unit(dev);
1077
1078	/* Set initial device and PHY flags */
1079	sc->bce_flags = 0;
1080	sc->bce_phy_flags = 0;
1081
1082	bce_set_tunables(sc);
1083
1084	pci_enable_busmaster(dev);
1085
1086	/* Allocate PCI memory resources. */
1087	rid = PCIR_BAR(0);
1088	sc->bce_res_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
1089		&rid, RF_ACTIVE);
1090
1091	if (sc->bce_res_mem == NULL) {
1092		BCE_PRINTF("%s(%d): PCI memory allocation failed\n",
1093		    __FILE__, __LINE__);
1094		rc = ENXIO;
1095		goto bce_attach_fail;
1096	}
1097
1098	/* Get various resource handles. */
1099	sc->bce_btag    = rman_get_bustag(sc->bce_res_mem);
1100	sc->bce_bhandle = rman_get_bushandle(sc->bce_res_mem);
1101	sc->bce_vhandle = (vm_offset_t) rman_get_virtual(sc->bce_res_mem);
1102
1103	bce_probe_pci_caps(dev, sc);
1104
1105	rid = 1;
1106	count = 0;
1107#if 0
1108	/* Try allocating MSI-X interrupts. */
1109	if ((sc->bce_cap_flags & BCE_MSIX_CAPABLE_FLAG) &&
1110		(bce_msi_enable >= 2) &&
1111		((sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
1112		&rid, RF_ACTIVE)) != NULL)) {
1113
1114		msi_needed = count = 1;
1115
1116		if (((error = pci_alloc_msix(dev, &count)) != 0) ||
1117			(count != msi_needed)) {
1118			BCE_PRINTF("%s(%d): MSI-X allocation failed! Requested = %d,"
1119				"Received = %d, error = %d\n", __FILE__, __LINE__,
1120				msi_needed, count, error);
1121			count = 0;
1122			pci_release_msi(dev);
1123			bus_release_resource(dev, SYS_RES_MEMORY, rid,
1124				sc->bce_res_irq);
1125			sc->bce_res_irq = NULL;
1126		} else {
1127			DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI-X interrupt.\n",
1128				__FUNCTION__);
1129			sc->bce_flags |= BCE_USING_MSIX_FLAG;
1130		}
1131	}
1132#endif
1133
1134	/* Try allocating a MSI interrupt. */
1135	if ((sc->bce_cap_flags & BCE_MSI_CAPABLE_FLAG) &&
1136		(bce_msi_enable >= 1) && (count == 0)) {
1137		count = 1;
1138		if ((error = pci_alloc_msi(dev, &count)) != 0) {
1139			BCE_PRINTF("%s(%d): MSI allocation failed! "
1140			    "error = %d\n", __FILE__, __LINE__, error);
1141			count = 0;
1142			pci_release_msi(dev);
1143		} else {
1144			DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI "
1145			    "interrupt.\n", __FUNCTION__);
1146			sc->bce_flags |= BCE_USING_MSI_FLAG;
1147			if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
1148				sc->bce_flags |= BCE_ONE_SHOT_MSI_FLAG;
1149			rid = 1;
1150		}
1151	}
1152
1153	/* Try allocating a legacy interrupt. */
1154	if (count == 0) {
1155		DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using INTx interrupt.\n",
1156			__FUNCTION__);
1157		rid = 0;
1158	}
1159
1160	sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
1161	    &rid, RF_ACTIVE | (count != 0 ? 0 : RF_SHAREABLE));
1162
1163	/* Report any IRQ allocation errors. */
1164	if (sc->bce_res_irq == NULL) {
1165		BCE_PRINTF("%s(%d): PCI map interrupt failed!\n",
1166		    __FILE__, __LINE__);
1167		rc = ENXIO;
1168		goto bce_attach_fail;
1169	}
1170
1171	/* Initialize mutex for the current device instance. */
1172	BCE_LOCK_INIT(sc, device_get_nameunit(dev));
1173
1174	/*
1175	 * Configure byte swap and enable indirect register access.
1176	 * Rely on CPU to do target byte swapping on big endian systems.
1177	 * Access to registers outside of PCI configurtion space are not
1178	 * valid until this is done.
1179	 */
1180	pci_write_config(dev, BCE_PCICFG_MISC_CONFIG,
1181	    BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
1182	    BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4);
1183
1184	/* Save ASIC revsion info. */
1185	sc->bce_chipid =  REG_RD(sc, BCE_MISC_ID);
1186
1187	/* Weed out any non-production controller revisions. */
1188	switch(BCE_CHIP_ID(sc)) {
1189	case BCE_CHIP_ID_5706_A0:
1190	case BCE_CHIP_ID_5706_A1:
1191	case BCE_CHIP_ID_5708_A0:
1192	case BCE_CHIP_ID_5708_B0:
1193	case BCE_CHIP_ID_5709_A0:
1194	case BCE_CHIP_ID_5709_B0:
1195	case BCE_CHIP_ID_5709_B1:
1196	case BCE_CHIP_ID_5709_B2:
1197		BCE_PRINTF("%s(%d): Unsupported controller "
1198		    "revision (%c%d)!\n", __FILE__, __LINE__,
1199		    (((pci_read_config(dev, PCIR_REVID, 4) &
1200		    0xf0) >> 4) + 'A'), (pci_read_config(dev,
1201		    PCIR_REVID, 4) & 0xf));
1202		rc = ENODEV;
1203		goto bce_attach_fail;
1204	}
1205
1206	/*
1207	 * The embedded PCIe to PCI-X bridge (EPB)
1208	 * in the 5708 cannot address memory above
1209	 * 40 bits (E7_5708CB1_23043 & E6_5708SB1_23043).
1210	 */
1211	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708)
1212		sc->max_bus_addr = BCE_BUS_SPACE_MAXADDR;
1213	else
1214		sc->max_bus_addr = BUS_SPACE_MAXADDR;
1215
1216	/*
1217	 * Find the base address for shared memory access.
1218	 * Newer versions of bootcode use a signature and offset
1219	 * while older versions use a fixed address.
1220	 */
1221	val = REG_RD_IND(sc, BCE_SHM_HDR_SIGNATURE);
1222	if ((val & BCE_SHM_HDR_SIGNATURE_SIG_MASK) == BCE_SHM_HDR_SIGNATURE_SIG)
1223		/* Multi-port devices use different offsets in shared memory. */
1224		sc->bce_shmem_base = REG_RD_IND(sc, BCE_SHM_HDR_ADDR_0 +
1225		    (pci_get_function(sc->bce_dev) << 2));
1226	else
1227		sc->bce_shmem_base = HOST_VIEW_SHMEM_BASE;
1228
1229	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): bce_shmem_base = 0x%08X\n",
1230	    __FUNCTION__, sc->bce_shmem_base);
1231
1232	/* Fetch the bootcode revision. */
1233	val = bce_shmem_rd(sc, BCE_DEV_INFO_BC_REV);
1234	for (int i = 0, j = 0; i < 3; i++) {
1235		u8 num;
1236
1237		num = (u8) (val >> (24 - (i * 8)));
1238		for (int k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
1239			if (num >= k || !skip0 || k == 1) {
1240				sc->bce_bc_ver[j++] = (num / k) + '0';
1241				skip0 = 0;
1242			}
1243		}
1244
1245		if (i != 2)
1246			sc->bce_bc_ver[j++] = '.';
1247	}
1248
1249	/* Check if any management firwmare is enabled. */
1250	val = bce_shmem_rd(sc, BCE_PORT_FEATURE);
1251	if (val & BCE_PORT_FEATURE_ASF_ENABLED) {
1252		sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
1253
1254		/* Allow time for firmware to enter the running state. */
1255		for (int i = 0; i < 30; i++) {
1256			val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
1257			if (val & BCE_CONDITION_MFW_RUN_MASK)
1258				break;
1259			DELAY(10000);
1260		}
1261
1262		/* Check if management firmware is running. */
1263		val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
1264		val &= BCE_CONDITION_MFW_RUN_MASK;
1265		if ((val != BCE_CONDITION_MFW_RUN_UNKNOWN) &&
1266		    (val != BCE_CONDITION_MFW_RUN_NONE)) {
1267			u32 addr = bce_shmem_rd(sc, BCE_MFW_VER_PTR);
1268			int i = 0;
1269
1270			/* Read the management firmware version string. */
1271			for (int j = 0; j < 3; j++) {
1272				val = bce_reg_rd_ind(sc, addr + j * 4);
1273				val = bswap32(val);
1274				memcpy(&sc->bce_mfw_ver[i], &val, 4);
1275				i += 4;
1276			}
1277		} else {
1278			/* May cause firmware synchronization timeouts. */
1279			BCE_PRINTF("%s(%d): Management firmware enabled "
1280			    "but not running!\n", __FILE__, __LINE__);
1281			strcpy(sc->bce_mfw_ver, "NOT RUNNING!");
1282
1283			/* ToDo: Any action the driver should take? */
1284		}
1285	}
1286
1287	/* Get PCI bus information (speed and type). */
1288	val = REG_RD(sc, BCE_PCICFG_MISC_STATUS);
1289	if (val & BCE_PCICFG_MISC_STATUS_PCIX_DET) {
1290		u32 clkreg;
1291
1292		sc->bce_flags |= BCE_PCIX_FLAG;
1293
1294		clkreg = REG_RD(sc, BCE_PCICFG_PCI_CLOCK_CONTROL_BITS);
1295
1296		clkreg &= BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
1297		switch (clkreg) {
1298		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
1299			sc->bus_speed_mhz = 133;
1300			break;
1301
1302		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
1303			sc->bus_speed_mhz = 100;
1304			break;
1305
1306		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
1307		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
1308			sc->bus_speed_mhz = 66;
1309			break;
1310
1311		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
1312		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
1313			sc->bus_speed_mhz = 50;
1314			break;
1315
1316		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
1317		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
1318		case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
1319			sc->bus_speed_mhz = 33;
1320			break;
1321		}
1322	} else {
1323		if (val & BCE_PCICFG_MISC_STATUS_M66EN)
1324			sc->bus_speed_mhz = 66;
1325		else
1326			sc->bus_speed_mhz = 33;
1327	}
1328
1329	if (val & BCE_PCICFG_MISC_STATUS_32BIT_DET)
1330		sc->bce_flags |= BCE_PCI_32BIT_FLAG;
1331
1332	/* Find the media type for the adapter. */
1333	bce_get_media(sc);
1334
1335	/* Reset controller and announce to bootcode that driver is present. */
1336	if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
1337		BCE_PRINTF("%s(%d): Controller reset failed!\n",
1338		    __FILE__, __LINE__);
1339		rc = ENXIO;
1340		goto bce_attach_fail;
1341	}
1342
1343	/* Initialize the controller. */
1344	if (bce_chipinit(sc)) {
1345		BCE_PRINTF("%s(%d): Controller initialization failed!\n",
1346		    __FILE__, __LINE__);
1347		rc = ENXIO;
1348		goto bce_attach_fail;
1349	}
1350
1351	/* Perform NVRAM test. */
1352	if (bce_nvram_test(sc)) {
1353		BCE_PRINTF("%s(%d): NVRAM test failed!\n",
1354		    __FILE__, __LINE__);
1355		rc = ENXIO;
1356		goto bce_attach_fail;
1357	}
1358
1359	/* Fetch the permanent Ethernet MAC address. */
1360	bce_get_mac_addr(sc);
1361
1362	/* Update statistics once every second. */
1363	sc->bce_stats_ticks = 1000000 & 0xffff00;
1364
1365	/* Store data needed by PHY driver for backplane applications */
1366	sc->bce_shared_hw_cfg = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
1367	sc->bce_port_hw_cfg   = bce_shmem_rd(sc, BCE_PORT_HW_CFG_CONFIG);
1368
1369	/* Allocate DMA memory resources. */
1370	if (bce_dma_alloc(dev)) {
1371		BCE_PRINTF("%s(%d): DMA resource allocation failed!\n",
1372		    __FILE__, __LINE__);
1373		rc = ENXIO;
1374		goto bce_attach_fail;
1375	}
1376
1377	/* Allocate an ifnet structure. */
1378	ifp = sc->bce_ifp = if_alloc(IFT_ETHER);
1379	if (ifp == NULL) {
1380		BCE_PRINTF("%s(%d): Interface allocation failed!\n",
1381		    __FILE__, __LINE__);
1382		rc = ENXIO;
1383		goto bce_attach_fail;
1384	}
1385
1386	/* Initialize the ifnet interface. */
1387	ifp->if_softc	= sc;
1388	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
1389	ifp->if_flags	= IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1390	ifp->if_ioctl	= bce_ioctl;
1391	ifp->if_start	= bce_start;
1392	ifp->if_init	= bce_init;
1393	ifp->if_mtu	= ETHERMTU;
1394
1395	if (bce_tso_enable) {
1396		ifp->if_hwassist = BCE_IF_HWASSIST | CSUM_TSO;
1397		ifp->if_capabilities = BCE_IF_CAPABILITIES | IFCAP_TSO4 |
1398		    IFCAP_VLAN_HWTSO;
1399	} else {
1400		ifp->if_hwassist = BCE_IF_HWASSIST;
1401		ifp->if_capabilities = BCE_IF_CAPABILITIES;
1402	}
1403
1404#if __FreeBSD_version >= 800505
1405	/*
1406	 * Introducing IFCAP_LINKSTATE didn't bump __FreeBSD_version
1407	 * so it's approximate value.
1408	 */
1409	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
1410		ifp->if_capabilities |= IFCAP_LINKSTATE;
1411#endif
1412
1413	ifp->if_capenable = ifp->if_capabilities;
1414
1415	/*
1416	 * Assume standard mbuf sizes for buffer allocation.
1417	 * This may change later if the MTU size is set to
1418	 * something other than 1500.
1419	 */
1420	bce_get_rx_buffer_sizes(sc,
1421	    (ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN));
1422
1423	/* Recalculate our buffer allocation sizes. */
1424	ifp->if_snd.ifq_drv_maxlen = USABLE_TX_BD_ALLOC;
1425	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
1426	IFQ_SET_READY(&ifp->if_snd);
1427
1428	if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
1429		ifp->if_baudrate = IF_Mbps(2500ULL);
1430	else
1431		ifp->if_baudrate = IF_Mbps(1000);
1432
1433	/* Handle any special PHY initialization for SerDes PHYs. */
1434	bce_init_media(sc);
1435
1436	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
1437		ifmedia_init(&sc->bce_ifmedia, IFM_IMASK, bce_ifmedia_upd,
1438		    bce_ifmedia_sts);
1439		/*
1440		 * We can't manually override remote PHY's link and assume
1441		 * PHY port configuration(Fiber or TP) is not changed after
1442		 * device attach.  This may not be correct though.
1443		 */
1444		if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) != 0) {
1445			if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
1446				ifmedia_add(&sc->bce_ifmedia,
1447				    IFM_ETHER | IFM_2500_SX, 0, NULL);
1448				ifmedia_add(&sc->bce_ifmedia,
1449				    IFM_ETHER | IFM_2500_SX | IFM_FDX, 0, NULL);
1450			}
1451			ifmedia_add(&sc->bce_ifmedia,
1452			    IFM_ETHER | IFM_1000_SX, 0, NULL);
1453			ifmedia_add(&sc->bce_ifmedia,
1454			    IFM_ETHER | IFM_1000_SX | IFM_FDX, 0, NULL);
1455		} else {
1456			ifmedia_add(&sc->bce_ifmedia,
1457			    IFM_ETHER | IFM_10_T, 0, NULL);
1458			ifmedia_add(&sc->bce_ifmedia,
1459			    IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL);
1460			ifmedia_add(&sc->bce_ifmedia,
1461			    IFM_ETHER | IFM_100_TX, 0, NULL);
1462			ifmedia_add(&sc->bce_ifmedia,
1463			    IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL);
1464			ifmedia_add(&sc->bce_ifmedia,
1465			    IFM_ETHER | IFM_1000_T, 0, NULL);
1466			ifmedia_add(&sc->bce_ifmedia,
1467			    IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL);
1468		}
1469		ifmedia_add(&sc->bce_ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL);
1470		ifmedia_set(&sc->bce_ifmedia, IFM_ETHER | IFM_AUTO);
1471		sc->bce_ifmedia.ifm_media = sc->bce_ifmedia.ifm_cur->ifm_media;
1472	} else {
1473		/* MII child bus by attaching the PHY. */
1474		rc = mii_attach(dev, &sc->bce_miibus, ifp, bce_ifmedia_upd,
1475		    bce_ifmedia_sts, BMSR_DEFCAPMASK, sc->bce_phy_addr,
1476		    MII_OFFSET_ANY, MIIF_DOPAUSE);
1477		if (rc != 0) {
1478			BCE_PRINTF("%s(%d): attaching PHYs failed\n", __FILE__,
1479			    __LINE__);
1480			goto bce_attach_fail;
1481		}
1482	}
1483
1484	/* Attach to the Ethernet interface list. */
1485	ether_ifattach(ifp, sc->eaddr);
1486
1487#if __FreeBSD_version < 500000
1488	callout_init(&sc->bce_tick_callout);
1489	callout_init(&sc->bce_pulse_callout);
1490#else
1491	callout_init_mtx(&sc->bce_tick_callout, &sc->bce_mtx, 0);
1492	callout_init_mtx(&sc->bce_pulse_callout, &sc->bce_mtx, 0);
1493#endif
1494
1495	/* Hookup IRQ last. */
1496	rc = bus_setup_intr(dev, sc->bce_res_irq, INTR_TYPE_NET | INTR_MPSAFE,
1497		NULL, bce_intr, sc, &sc->bce_intrhand);
1498
1499	if (rc) {
1500		BCE_PRINTF("%s(%d): Failed to setup IRQ!\n",
1501		    __FILE__, __LINE__);
1502		bce_detach(dev);
1503		goto bce_attach_exit;
1504	}
1505
1506	/*
1507	 * At this point we've acquired all the resources
1508	 * we need to run so there's no turning back, we're
1509	 * cleared for launch.
1510	 */
1511
1512	/* Print some important debugging info. */
1513	DBRUNMSG(BCE_INFO, bce_dump_driver_state(sc));
1514
1515	/* Add the supported sysctls to the kernel. */
1516	bce_add_sysctls(sc);
1517
1518	BCE_LOCK(sc);
1519
1520	/*
1521	 * The chip reset earlier notified the bootcode that
1522	 * a driver is present.  We now need to start our pulse
1523	 * routine so that the bootcode is reminded that we're
1524	 * still running.
1525	 */
1526	bce_pulse(sc);
1527
1528	bce_mgmt_init_locked(sc);
1529	BCE_UNLOCK(sc);
1530
1531	/* Finally, print some useful adapter info */
1532	bce_print_adapter_info(sc);
1533	DBPRINT(sc, BCE_FATAL, "%s(): sc = %p\n",
1534		__FUNCTION__, sc);
1535
1536	goto bce_attach_exit;
1537
1538bce_attach_fail:
1539	bce_release_resources(sc);
1540
1541bce_attach_exit:
1542
1543	DBEXIT(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
1544
1545	return(rc);
1546}
1547
1548
1549/****************************************************************************/
1550/* Device detach function.                                                  */
1551/*                                                                          */
1552/* Stops the controller, resets the controller, and releases resources.     */
1553/*                                                                          */
1554/* Returns:                                                                 */
1555/*   0 on success, positive value on failure.                               */
1556/****************************************************************************/
1557static int
1558bce_detach(device_t dev)
1559{
1560	struct bce_softc *sc = device_get_softc(dev);
1561	struct ifnet *ifp;
1562	u32 msg;
1563
1564	DBENTER(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
1565
1566	ifp = sc->bce_ifp;
1567
1568	/* Stop and reset the controller. */
1569	BCE_LOCK(sc);
1570
1571	/* Stop the pulse so the bootcode can go to driver absent state. */
1572	callout_stop(&sc->bce_pulse_callout);
1573
1574	bce_stop(sc);
1575	if (sc->bce_flags & BCE_NO_WOL_FLAG)
1576		msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
1577	else
1578		msg = BCE_DRV_MSG_CODE_UNLOAD;
1579	bce_reset(sc, msg);
1580
1581	BCE_UNLOCK(sc);
1582
1583	ether_ifdetach(ifp);
1584
1585	/* If we have a child device on the MII bus remove it too. */
1586	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
1587		ifmedia_removeall(&sc->bce_ifmedia);
1588	else {
1589		bus_generic_detach(dev);
1590		device_delete_child(dev, sc->bce_miibus);
1591	}
1592
1593	/* Release all remaining resources. */
1594	bce_release_resources(sc);
1595
1596	DBEXIT(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
1597
1598	return(0);
1599}
1600
1601
1602/****************************************************************************/
1603/* Device shutdown function.                                                */
1604/*                                                                          */
1605/* Stops and resets the controller.                                         */
1606/*                                                                          */
1607/* Returns:                                                                 */
1608/*   0 on success, positive value on failure.                               */
1609/****************************************************************************/
1610static int
1611bce_shutdown(device_t dev)
1612{
1613	struct bce_softc *sc = device_get_softc(dev);
1614	u32 msg;
1615
1616	DBENTER(BCE_VERBOSE);
1617
1618	BCE_LOCK(sc);
1619	bce_stop(sc);
1620	if (sc->bce_flags & BCE_NO_WOL_FLAG)
1621		msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
1622	else
1623		msg = BCE_DRV_MSG_CODE_UNLOAD;
1624	bce_reset(sc, msg);
1625	BCE_UNLOCK(sc);
1626
1627	DBEXIT(BCE_VERBOSE);
1628
1629	return (0);
1630}
1631
1632
1633#ifdef BCE_DEBUG
1634/****************************************************************************/
1635/* Register read.                                                           */
1636/*                                                                          */
1637/* Returns:                                                                 */
1638/*   The value of the register.                                             */
1639/****************************************************************************/
1640static u32
1641bce_reg_rd(struct bce_softc *sc, u32 offset)
1642{
1643	u32 val = REG_RD(sc, offset);
1644	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1645		__FUNCTION__, offset, val);
1646	return val;
1647}
1648
1649
1650/****************************************************************************/
1651/* Register write (16 bit).                                                 */
1652/*                                                                          */
1653/* Returns:                                                                 */
1654/*   Nothing.                                                               */
1655/****************************************************************************/
1656static void
1657bce_reg_wr16(struct bce_softc *sc, u32 offset, u16 val)
1658{
1659	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%04X\n",
1660		__FUNCTION__, offset, val);
1661	REG_WR16(sc, offset, val);
1662}
1663
1664
1665/****************************************************************************/
1666/* Register write.                                                          */
1667/*                                                                          */
1668/* Returns:                                                                 */
1669/*   Nothing.                                                               */
1670/****************************************************************************/
1671static void
1672bce_reg_wr(struct bce_softc *sc, u32 offset, u32 val)
1673{
1674	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1675		__FUNCTION__, offset, val);
1676	REG_WR(sc, offset, val);
1677}
1678#endif
1679
1680/****************************************************************************/
1681/* Indirect register read.                                                  */
1682/*                                                                          */
1683/* Reads NetXtreme II registers using an index/data register pair in PCI    */
1684/* configuration space.  Using this mechanism avoids issues with posted     */
1685/* reads but is much slower than memory-mapped I/O.                         */
1686/*                                                                          */
1687/* Returns:                                                                 */
1688/*   The value of the register.                                             */
1689/****************************************************************************/
1690static u32
1691bce_reg_rd_ind(struct bce_softc *sc, u32 offset)
1692{
1693	device_t dev;
1694	dev = sc->bce_dev;
1695
1696	pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
1697#ifdef BCE_DEBUG
1698	{
1699		u32 val;
1700		val = pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
1701		DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1702			__FUNCTION__, offset, val);
1703		return val;
1704	}
1705#else
1706	return pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
1707#endif
1708}
1709
1710
1711/****************************************************************************/
1712/* Indirect register write.                                                 */
1713/*                                                                          */
1714/* Writes NetXtreme II registers using an index/data register pair in PCI   */
1715/* configuration space.  Using this mechanism avoids issues with posted     */
1716/* writes but is muchh slower than memory-mapped I/O.                       */
1717/*                                                                          */
1718/* Returns:                                                                 */
1719/*   Nothing.                                                               */
1720/****************************************************************************/
1721static void
1722bce_reg_wr_ind(struct bce_softc *sc, u32 offset, u32 val)
1723{
1724	device_t dev;
1725	dev = sc->bce_dev;
1726
1727	DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
1728		__FUNCTION__, offset, val);
1729
1730	pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
1731	pci_write_config(dev, BCE_PCICFG_REG_WINDOW, val, 4);
1732}
1733
1734
1735/****************************************************************************/
1736/* Shared memory write.                                                     */
1737/*                                                                          */
1738/* Writes NetXtreme II shared memory region.                                */
1739/*                                                                          */
1740/* Returns:                                                                 */
1741/*   Nothing.                                                               */
1742/****************************************************************************/
1743static void
1744bce_shmem_wr(struct bce_softc *sc, u32 offset, u32 val)
1745{
1746	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): Writing 0x%08X  to  "
1747	    "0x%08X\n",	__FUNCTION__, val, offset);
1748
1749	bce_reg_wr_ind(sc, sc->bce_shmem_base + offset, val);
1750}
1751
1752
1753/****************************************************************************/
1754/* Shared memory read.                                                      */
1755/*                                                                          */
1756/* Reads NetXtreme II shared memory region.                                 */
1757/*                                                                          */
1758/* Returns:                                                                 */
1759/*   The 32 bit value read.                                                 */
1760/****************************************************************************/
1761static u32
1762bce_shmem_rd(struct bce_softc *sc, u32 offset)
1763{
1764	u32 val = bce_reg_rd_ind(sc, sc->bce_shmem_base + offset);
1765
1766	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): Reading 0x%08X from "
1767	    "0x%08X\n",	__FUNCTION__, val, offset);
1768
1769	return val;
1770}
1771
1772
1773#ifdef BCE_DEBUG
1774/****************************************************************************/
1775/* Context memory read.                                                     */
1776/*                                                                          */
1777/* The NetXtreme II controller uses context memory to track connection      */
1778/* information for L2 and higher network protocols.                         */
1779/*                                                                          */
1780/* Returns:                                                                 */
1781/*   The requested 32 bit value of context memory.                          */
1782/****************************************************************************/
1783static u32
1784bce_ctx_rd(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset)
1785{
1786	u32 idx, offset, retry_cnt = 5, val;
1787
1788	DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 ||
1789	    cid_addr & CTX_MASK), BCE_PRINTF("%s(): Invalid CID "
1790	    "address: 0x%08X.\n", __FUNCTION__, cid_addr));
1791
1792	offset = ctx_offset + cid_addr;
1793
1794	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
1795
1796		REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_READ_REQ));
1797
1798		for (idx = 0; idx < retry_cnt; idx++) {
1799			val = REG_RD(sc, BCE_CTX_CTX_CTRL);
1800			if ((val & BCE_CTX_CTX_CTRL_READ_REQ) == 0)
1801				break;
1802			DELAY(5);
1803		}
1804
1805		if (val & BCE_CTX_CTX_CTRL_READ_REQ)
1806			BCE_PRINTF("%s(%d); Unable to read CTX memory: "
1807			    "cid_addr = 0x%08X, offset = 0x%08X!\n",
1808			    __FILE__, __LINE__, cid_addr, ctx_offset);
1809
1810		val = REG_RD(sc, BCE_CTX_CTX_DATA);
1811	} else {
1812		REG_WR(sc, BCE_CTX_DATA_ADR, offset);
1813		val = REG_RD(sc, BCE_CTX_DATA);
1814	}
1815
1816	DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
1817		"val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, val);
1818
1819	return(val);
1820}
1821#endif
1822
1823
1824/****************************************************************************/
1825/* Context memory write.                                                    */
1826/*                                                                          */
1827/* The NetXtreme II controller uses context memory to track connection      */
1828/* information for L2 and higher network protocols.                         */
1829/*                                                                          */
1830/* Returns:                                                                 */
1831/*   Nothing.                                                               */
1832/****************************************************************************/
1833static void
1834bce_ctx_wr(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset, u32 ctx_val)
1835{
1836	u32 idx, offset = ctx_offset + cid_addr;
1837	u32 val, retry_cnt = 5;
1838
1839	DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
1840		"val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, ctx_val);
1841
1842	DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 || cid_addr & CTX_MASK),
1843		BCE_PRINTF("%s(): Invalid CID address: 0x%08X.\n",
1844		    __FUNCTION__, cid_addr));
1845
1846	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
1847
1848		REG_WR(sc, BCE_CTX_CTX_DATA, ctx_val);
1849		REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_WRITE_REQ));
1850
1851		for (idx = 0; idx < retry_cnt; idx++) {
1852			val = REG_RD(sc, BCE_CTX_CTX_CTRL);
1853			if ((val & BCE_CTX_CTX_CTRL_WRITE_REQ) == 0)
1854				break;
1855			DELAY(5);
1856		}
1857
1858		if (val & BCE_CTX_CTX_CTRL_WRITE_REQ)
1859			BCE_PRINTF("%s(%d); Unable to write CTX memory: "
1860			    "cid_addr = 0x%08X, offset = 0x%08X!\n",
1861			    __FILE__, __LINE__, cid_addr, ctx_offset);
1862
1863	} else {
1864		REG_WR(sc, BCE_CTX_DATA_ADR, offset);
1865		REG_WR(sc, BCE_CTX_DATA, ctx_val);
1866	}
1867}
1868
1869
1870/****************************************************************************/
1871/* PHY register read.                                                       */
1872/*                                                                          */
1873/* Implements register reads on the MII bus.                                */
1874/*                                                                          */
1875/* Returns:                                                                 */
1876/*   The value of the register.                                             */
1877/****************************************************************************/
1878static int
1879bce_miibus_read_reg(device_t dev, int phy, int reg)
1880{
1881	struct bce_softc *sc;
1882	u32 val;
1883	int i;
1884
1885	sc = device_get_softc(dev);
1886
1887    /*
1888     * The 5709S PHY is an IEEE Clause 45 PHY
1889     * with special mappings to work with IEEE
1890     * Clause 22 register accesses.
1891     */
1892	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
1893		if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
1894			reg += 0x10;
1895	}
1896
1897    if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1898		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1899		val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1900
1901		REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1902		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1903
1904		DELAY(40);
1905	}
1906
1907
1908	val = BCE_MIPHY(phy) | BCE_MIREG(reg) |
1909	    BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT |
1910	    BCE_EMAC_MDIO_COMM_START_BUSY;
1911	REG_WR(sc, BCE_EMAC_MDIO_COMM, val);
1912
1913	for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1914		DELAY(10);
1915
1916		val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1917		if (!(val & BCE_EMAC_MDIO_COMM_START_BUSY)) {
1918			DELAY(5);
1919
1920			val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1921			val &= BCE_EMAC_MDIO_COMM_DATA;
1922
1923			break;
1924		}
1925	}
1926
1927	if (val & BCE_EMAC_MDIO_COMM_START_BUSY) {
1928		BCE_PRINTF("%s(%d): Error: PHY read timeout! phy = %d, "
1929		    "reg = 0x%04X\n", __FILE__, __LINE__, phy, reg);
1930		val = 0x0;
1931	} else {
1932		val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1933	}
1934
1935
1936	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1937		val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1938		val |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
1939
1940		REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
1941		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1942
1943		DELAY(40);
1944	}
1945
1946	DB_PRINT_PHY_REG(reg, val);
1947	return (val & 0xffff);
1948}
1949
1950
1951/****************************************************************************/
1952/* PHY register write.                                                      */
1953/*                                                                          */
1954/* Implements register writes on the MII bus.                               */
1955/*                                                                          */
1956/* Returns:                                                                 */
1957/*   The value of the register.                                             */
1958/****************************************************************************/
1959static int
1960bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
1961{
1962	struct bce_softc *sc;
1963	u32 val1;
1964	int i;
1965
1966	sc = device_get_softc(dev);
1967
1968	DB_PRINT_PHY_REG(reg, val);
1969
1970	/*
1971	 * The 5709S PHY is an IEEE Clause 45 PHY
1972	 * with special mappings to work with IEEE
1973	 * Clause 22 register accesses.
1974	 */
1975	if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
1976		if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
1977			reg += 0x10;
1978	}
1979
1980	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
1981		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
1982		val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
1983
1984		REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
1985		REG_RD(sc, BCE_EMAC_MDIO_MODE);
1986
1987		DELAY(40);
1988	}
1989
1990	val1 = BCE_MIPHY(phy) | BCE_MIREG(reg) | val |
1991	    BCE_EMAC_MDIO_COMM_COMMAND_WRITE |
1992	    BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT;
1993	REG_WR(sc, BCE_EMAC_MDIO_COMM, val1);
1994
1995	for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
1996		DELAY(10);
1997
1998		val1 = REG_RD(sc, BCE_EMAC_MDIO_COMM);
1999		if (!(val1 & BCE_EMAC_MDIO_COMM_START_BUSY)) {
2000			DELAY(5);
2001			break;
2002		}
2003	}
2004
2005	if (val1 & BCE_EMAC_MDIO_COMM_START_BUSY)
2006		BCE_PRINTF("%s(%d): PHY write timeout!\n",
2007		    __FILE__, __LINE__);
2008
2009	if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
2010		val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
2011		val1 |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
2012
2013		REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
2014		REG_RD(sc, BCE_EMAC_MDIO_MODE);
2015
2016		DELAY(40);
2017	}
2018
2019	return 0;
2020}
2021
2022
2023/****************************************************************************/
2024/* MII bus status change.                                                   */
2025/*                                                                          */
2026/* Called by the MII bus driver when the PHY establishes link to set the    */
2027/* MAC interface registers.                                                 */
2028/*                                                                          */
2029/* Returns:                                                                 */
2030/*   Nothing.                                                               */
2031/****************************************************************************/
2032static void
2033bce_miibus_statchg(device_t dev)
2034{
2035	struct bce_softc *sc;
2036	struct mii_data *mii;
2037	struct ifmediareq ifmr;
2038	int media_active, media_status, val;
2039
2040	sc = device_get_softc(dev);
2041
2042	DBENTER(BCE_VERBOSE_PHY);
2043
2044	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
2045		bzero(&ifmr, sizeof(ifmr));
2046		bce_ifmedia_sts_rphy(sc, &ifmr);
2047		media_active = ifmr.ifm_active;
2048		media_status = ifmr.ifm_status;
2049	} else {
2050		mii = device_get_softc(sc->bce_miibus);
2051		media_active = mii->mii_media_active;
2052		media_status = mii->mii_media_status;
2053	}
2054
2055	/* Ignore invalid media status. */
2056	if ((media_status & (IFM_ACTIVE | IFM_AVALID)) !=
2057	    (IFM_ACTIVE | IFM_AVALID))
2058		goto bce_miibus_statchg_exit;
2059
2060	val = REG_RD(sc, BCE_EMAC_MODE);
2061	val &= ~(BCE_EMAC_MODE_PORT | BCE_EMAC_MODE_HALF_DUPLEX |
2062	    BCE_EMAC_MODE_MAC_LOOP | BCE_EMAC_MODE_FORCE_LINK |
2063	    BCE_EMAC_MODE_25G);
2064
2065	/* Set MII or GMII interface based on the PHY speed. */
2066	switch (IFM_SUBTYPE(media_active)) {
2067	case IFM_10_T:
2068		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
2069			DBPRINT(sc, BCE_INFO_PHY,
2070			    "Enabling 10Mb interface.\n");
2071			val |= BCE_EMAC_MODE_PORT_MII_10;
2072			break;
2073		}
2074		/* fall-through */
2075	case IFM_100_TX:
2076		DBPRINT(sc, BCE_INFO_PHY, "Enabling MII interface.\n");
2077		val |= BCE_EMAC_MODE_PORT_MII;
2078		break;
2079	case IFM_2500_SX:
2080		DBPRINT(sc, BCE_INFO_PHY, "Enabling 2.5G MAC mode.\n");
2081		val |= BCE_EMAC_MODE_25G;
2082		/* fall-through */
2083	case IFM_1000_T:
2084	case IFM_1000_SX:
2085		DBPRINT(sc, BCE_INFO_PHY, "Enabling GMII interface.\n");
2086		val |= BCE_EMAC_MODE_PORT_GMII;
2087		break;
2088	default:
2089		DBPRINT(sc, BCE_INFO_PHY, "Unknown link speed, enabling "
2090		    "default GMII interface.\n");
2091		val |= BCE_EMAC_MODE_PORT_GMII;
2092	}
2093
2094	/* Set half or full duplex based on PHY settings. */
2095	if ((IFM_OPTIONS(media_active) & IFM_FDX) == 0) {
2096		DBPRINT(sc, BCE_INFO_PHY,
2097		    "Setting Half-Duplex interface.\n");
2098		val |= BCE_EMAC_MODE_HALF_DUPLEX;
2099	} else
2100		DBPRINT(sc, BCE_INFO_PHY,
2101		    "Setting Full-Duplex interface.\n");
2102
2103	REG_WR(sc, BCE_EMAC_MODE, val);
2104
2105	if ((IFM_OPTIONS(media_active) & IFM_ETH_RXPAUSE) != 0) {
2106		DBPRINT(sc, BCE_INFO_PHY,
2107		    "%s(): Enabling RX flow control.\n", __FUNCTION__);
2108		BCE_SETBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
2109		sc->bce_flags |= BCE_USING_RX_FLOW_CONTROL;
2110	} else {
2111		DBPRINT(sc, BCE_INFO_PHY,
2112		    "%s(): Disabling RX flow control.\n", __FUNCTION__);
2113		BCE_CLRBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
2114		sc->bce_flags &= ~BCE_USING_RX_FLOW_CONTROL;
2115	}
2116
2117	if ((IFM_OPTIONS(media_active) & IFM_ETH_TXPAUSE) != 0) {
2118		DBPRINT(sc, BCE_INFO_PHY,
2119		    "%s(): Enabling TX flow control.\n", __FUNCTION__);
2120		BCE_SETBIT(sc, BCE_EMAC_TX_MODE, BCE_EMAC_TX_MODE_FLOW_EN);
2121		sc->bce_flags |= BCE_USING_TX_FLOW_CONTROL;
2122	} else {
2123		DBPRINT(sc, BCE_INFO_PHY,
2124		    "%s(): Disabling TX flow control.\n", __FUNCTION__);
2125		BCE_CLRBIT(sc, BCE_EMAC_TX_MODE, BCE_EMAC_TX_MODE_FLOW_EN);
2126		sc->bce_flags &= ~BCE_USING_TX_FLOW_CONTROL;
2127	}
2128
2129	/* ToDo: Update watermarks in bce_init_rx_context(). */
2130
2131bce_miibus_statchg_exit:
2132	DBEXIT(BCE_VERBOSE_PHY);
2133}
2134
2135
2136/****************************************************************************/
2137/* Acquire NVRAM lock.                                                      */
2138/*                                                                          */
2139/* Before the NVRAM can be accessed the caller must acquire an NVRAM lock.  */
2140/* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
2141/* for use by the driver.                                                   */
2142/*                                                                          */
2143/* Returns:                                                                 */
2144/*   0 on success, positive value on failure.                               */
2145/****************************************************************************/
2146static int
2147bce_acquire_nvram_lock(struct bce_softc *sc)
2148{
2149	u32 val;
2150	int j, rc = 0;
2151
2152	DBENTER(BCE_VERBOSE_NVRAM);
2153
2154	/* Request access to the flash interface. */
2155	REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_SET2);
2156	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2157		val = REG_RD(sc, BCE_NVM_SW_ARB);
2158		if (val & BCE_NVM_SW_ARB_ARB_ARB2)
2159			break;
2160
2161		DELAY(5);
2162	}
2163
2164	if (j >= NVRAM_TIMEOUT_COUNT) {
2165		DBPRINT(sc, BCE_WARN, "Timeout acquiring NVRAM lock!\n");
2166		rc = EBUSY;
2167	}
2168
2169	DBEXIT(BCE_VERBOSE_NVRAM);
2170	return (rc);
2171}
2172
2173
2174/****************************************************************************/
2175/* Release NVRAM lock.                                                      */
2176/*                                                                          */
2177/* When the caller is finished accessing NVRAM the lock must be released.   */
2178/* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
2179/* for use by the driver.                                                   */
2180/*                                                                          */
2181/* Returns:                                                                 */
2182/*   0 on success, positive value on failure.                               */
2183/****************************************************************************/
2184static int
2185bce_release_nvram_lock(struct bce_softc *sc)
2186{
2187	u32 val;
2188	int j, rc = 0;
2189
2190	DBENTER(BCE_VERBOSE_NVRAM);
2191
2192	/*
2193	 * Relinquish nvram interface.
2194	 */
2195	REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_CLR2);
2196
2197	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2198		val = REG_RD(sc, BCE_NVM_SW_ARB);
2199		if (!(val & BCE_NVM_SW_ARB_ARB_ARB2))
2200			break;
2201
2202		DELAY(5);
2203	}
2204
2205	if (j >= NVRAM_TIMEOUT_COUNT) {
2206		DBPRINT(sc, BCE_WARN, "Timeout releasing NVRAM lock!\n");
2207		rc = EBUSY;
2208	}
2209
2210	DBEXIT(BCE_VERBOSE_NVRAM);
2211	return (rc);
2212}
2213
2214
2215#ifdef BCE_NVRAM_WRITE_SUPPORT
2216/****************************************************************************/
2217/* Enable NVRAM write access.                                               */
2218/*                                                                          */
2219/* Before writing to NVRAM the caller must enable NVRAM writes.             */
2220/*                                                                          */
2221/* Returns:                                                                 */
2222/*   0 on success, positive value on failure.                               */
2223/****************************************************************************/
2224static int
2225bce_enable_nvram_write(struct bce_softc *sc)
2226{
2227	u32 val;
2228	int rc = 0;
2229
2230	DBENTER(BCE_VERBOSE_NVRAM);
2231
2232	val = REG_RD(sc, BCE_MISC_CFG);
2233	REG_WR(sc, BCE_MISC_CFG, val | BCE_MISC_CFG_NVM_WR_EN_PCI);
2234
2235	if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2236		int j;
2237
2238		REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2239		REG_WR(sc, BCE_NVM_COMMAND,	BCE_NVM_COMMAND_WREN | BCE_NVM_COMMAND_DOIT);
2240
2241		for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2242			DELAY(5);
2243
2244			val = REG_RD(sc, BCE_NVM_COMMAND);
2245			if (val & BCE_NVM_COMMAND_DONE)
2246				break;
2247		}
2248
2249		if (j >= NVRAM_TIMEOUT_COUNT) {
2250			DBPRINT(sc, BCE_WARN, "Timeout writing NVRAM!\n");
2251			rc = EBUSY;
2252		}
2253	}
2254
2255	DBENTER(BCE_VERBOSE_NVRAM);
2256	return (rc);
2257}
2258
2259
2260/****************************************************************************/
2261/* Disable NVRAM write access.                                              */
2262/*                                                                          */
2263/* When the caller is finished writing to NVRAM write access must be        */
2264/* disabled.                                                                */
2265/*                                                                          */
2266/* Returns:                                                                 */
2267/*   Nothing.                                                               */
2268/****************************************************************************/
2269static void
2270bce_disable_nvram_write(struct bce_softc *sc)
2271{
2272	u32 val;
2273
2274	DBENTER(BCE_VERBOSE_NVRAM);
2275
2276	val = REG_RD(sc, BCE_MISC_CFG);
2277	REG_WR(sc, BCE_MISC_CFG, val & ~BCE_MISC_CFG_NVM_WR_EN);
2278
2279	DBEXIT(BCE_VERBOSE_NVRAM);
2280
2281}
2282#endif
2283
2284
2285/****************************************************************************/
2286/* Enable NVRAM access.                                                     */
2287/*                                                                          */
2288/* Before accessing NVRAM for read or write operations the caller must      */
2289/* enabled NVRAM access.                                                    */
2290/*                                                                          */
2291/* Returns:                                                                 */
2292/*   Nothing.                                                               */
2293/****************************************************************************/
2294static void
2295bce_enable_nvram_access(struct bce_softc *sc)
2296{
2297	u32 val;
2298
2299	DBENTER(BCE_VERBOSE_NVRAM);
2300
2301	val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
2302	/* Enable both bits, even on read. */
2303	REG_WR(sc, BCE_NVM_ACCESS_ENABLE, val |
2304	    BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN);
2305
2306	DBEXIT(BCE_VERBOSE_NVRAM);
2307}
2308
2309
2310/****************************************************************************/
2311/* Disable NVRAM access.                                                    */
2312/*                                                                          */
2313/* When the caller is finished accessing NVRAM access must be disabled.     */
2314/*                                                                          */
2315/* Returns:                                                                 */
2316/*   Nothing.                                                               */
2317/****************************************************************************/
2318static void
2319bce_disable_nvram_access(struct bce_softc *sc)
2320{
2321	u32 val;
2322
2323	DBENTER(BCE_VERBOSE_NVRAM);
2324
2325	val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
2326
2327	/* Disable both bits, even after read. */
2328	REG_WR(sc, BCE_NVM_ACCESS_ENABLE, val &
2329	    ~(BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN));
2330
2331	DBEXIT(BCE_VERBOSE_NVRAM);
2332}
2333
2334
2335#ifdef BCE_NVRAM_WRITE_SUPPORT
2336/****************************************************************************/
2337/* Erase NVRAM page before writing.                                         */
2338/*                                                                          */
2339/* Non-buffered flash parts require that a page be erased before it is      */
2340/* written.                                                                 */
2341/*                                                                          */
2342/* Returns:                                                                 */
2343/*   0 on success, positive value on failure.                               */
2344/****************************************************************************/
2345static int
2346bce_nvram_erase_page(struct bce_softc *sc, u32 offset)
2347{
2348	u32 cmd;
2349	int j, rc = 0;
2350
2351	DBENTER(BCE_VERBOSE_NVRAM);
2352
2353	/* Buffered flash doesn't require an erase. */
2354	if (sc->bce_flash_info->flags & BCE_NV_BUFFERED)
2355		goto bce_nvram_erase_page_exit;
2356
2357	/* Build an erase command. */
2358	cmd = BCE_NVM_COMMAND_ERASE | BCE_NVM_COMMAND_WR |
2359	    BCE_NVM_COMMAND_DOIT;
2360
2361	/*
2362	 * Clear the DONE bit separately, set the NVRAM adress to erase,
2363	 * and issue the erase command.
2364	 */
2365	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2366	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
2367	REG_WR(sc, BCE_NVM_COMMAND, cmd);
2368
2369	/* Wait for completion. */
2370	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2371		u32 val;
2372
2373		DELAY(5);
2374
2375		val = REG_RD(sc, BCE_NVM_COMMAND);
2376		if (val & BCE_NVM_COMMAND_DONE)
2377			break;
2378	}
2379
2380	if (j >= NVRAM_TIMEOUT_COUNT) {
2381		DBPRINT(sc, BCE_WARN, "Timeout erasing NVRAM.\n");
2382		rc = EBUSY;
2383	}
2384
2385bce_nvram_erase_page_exit:
2386	DBEXIT(BCE_VERBOSE_NVRAM);
2387	return (rc);
2388}
2389#endif /* BCE_NVRAM_WRITE_SUPPORT */
2390
2391
2392/****************************************************************************/
2393/* Read a dword (32 bits) from NVRAM.                                       */
2394/*                                                                          */
2395/* Read a 32 bit word from NVRAM.  The caller is assumed to have already    */
2396/* obtained the NVRAM lock and enabled the controller for NVRAM access.     */
2397/*                                                                          */
2398/* Returns:                                                                 */
2399/*   0 on success and the 32 bit value read, positive value on failure.     */
2400/****************************************************************************/
2401static int
2402bce_nvram_read_dword(struct bce_softc *sc,
2403    u32 offset, u8 *ret_val, u32 cmd_flags)
2404{
2405	u32 cmd;
2406	int i, rc = 0;
2407
2408	DBENTER(BCE_EXTREME_NVRAM);
2409
2410	/* Build the command word. */
2411	cmd = BCE_NVM_COMMAND_DOIT | cmd_flags;
2412
2413	/* Calculate the offset for buffered flash if translation is used. */
2414	if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
2415		offset = ((offset / sc->bce_flash_info->page_size) <<
2416		    sc->bce_flash_info->page_bits) +
2417		    (offset % sc->bce_flash_info->page_size);
2418	}
2419
2420	/*
2421	 * Clear the DONE bit separately, set the address to read,
2422	 * and issue the read.
2423	 */
2424	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2425	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
2426	REG_WR(sc, BCE_NVM_COMMAND, cmd);
2427
2428	/* Wait for completion. */
2429	for (i = 0; i < NVRAM_TIMEOUT_COUNT; i++) {
2430		u32 val;
2431
2432		DELAY(5);
2433
2434		val = REG_RD(sc, BCE_NVM_COMMAND);
2435		if (val & BCE_NVM_COMMAND_DONE) {
2436			val = REG_RD(sc, BCE_NVM_READ);
2437
2438			val = bce_be32toh(val);
2439			memcpy(ret_val, &val, 4);
2440			break;
2441		}
2442	}
2443
2444	/* Check for errors. */
2445	if (i >= NVRAM_TIMEOUT_COUNT) {
2446		BCE_PRINTF("%s(%d): Timeout error reading NVRAM at "
2447		    "offset 0x%08X!\n",	__FILE__, __LINE__, offset);
2448		rc = EBUSY;
2449	}
2450
2451	DBEXIT(BCE_EXTREME_NVRAM);
2452	return(rc);
2453}
2454
2455
2456#ifdef BCE_NVRAM_WRITE_SUPPORT
2457/****************************************************************************/
2458/* Write a dword (32 bits) to NVRAM.                                        */
2459/*                                                                          */
2460/* Write a 32 bit word to NVRAM.  The caller is assumed to have already     */
2461/* obtained the NVRAM lock, enabled the controller for NVRAM access, and    */
2462/* enabled NVRAM write access.                                              */
2463/*                                                                          */
2464/* Returns:                                                                 */
2465/*   0 on success, positive value on failure.                               */
2466/****************************************************************************/
2467static int
2468bce_nvram_write_dword(struct bce_softc *sc, u32 offset, u8 *val,
2469	u32 cmd_flags)
2470{
2471	u32 cmd, val32;
2472	int j, rc = 0;
2473
2474	DBENTER(BCE_VERBOSE_NVRAM);
2475
2476	/* Build the command word. */
2477	cmd = BCE_NVM_COMMAND_DOIT | BCE_NVM_COMMAND_WR | cmd_flags;
2478
2479	/* Calculate the offset for buffered flash if translation is used. */
2480	if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
2481		offset = ((offset / sc->bce_flash_info->page_size) <<
2482		    sc->bce_flash_info->page_bits) +
2483		    (offset % sc->bce_flash_info->page_size);
2484	}
2485
2486	/*
2487	 * Clear the DONE bit separately, convert NVRAM data to big-endian,
2488	 * set the NVRAM address to write, and issue the write command
2489	 */
2490	REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
2491	memcpy(&val32, val, 4);
2492	val32 = htobe32(val32);
2493	REG_WR(sc, BCE_NVM_WRITE, val32);
2494	REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
2495	REG_WR(sc, BCE_NVM_COMMAND, cmd);
2496
2497	/* Wait for completion. */
2498	for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
2499		DELAY(5);
2500
2501		if (REG_RD(sc, BCE_NVM_COMMAND) & BCE_NVM_COMMAND_DONE)
2502			break;
2503	}
2504	if (j >= NVRAM_TIMEOUT_COUNT) {
2505		BCE_PRINTF("%s(%d): Timeout error writing NVRAM at "
2506		    "offset 0x%08X\n", __FILE__, __LINE__, offset);
2507		rc = EBUSY;
2508	}
2509
2510	DBEXIT(BCE_VERBOSE_NVRAM);
2511	return (rc);
2512}
2513#endif /* BCE_NVRAM_WRITE_SUPPORT */
2514
2515
2516/****************************************************************************/
2517/* Initialize NVRAM access.                                                 */
2518/*                                                                          */
2519/* Identify the NVRAM device in use and prepare the NVRAM interface to      */
2520/* access that device.                                                      */
2521/*                                                                          */
2522/* Returns:                                                                 */
2523/*   0 on success, positive value on failure.                               */
2524/****************************************************************************/
2525static int
2526bce_init_nvram(struct bce_softc *sc)
2527{
2528	u32 val;
2529	int j, entry_count, rc = 0;
2530	const struct flash_spec *flash;
2531
2532	DBENTER(BCE_VERBOSE_NVRAM);
2533
2534	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
2535		sc->bce_flash_info = &flash_5709;
2536		goto bce_init_nvram_get_flash_size;
2537	}
2538
2539	/* Determine the selected interface. */
2540	val = REG_RD(sc, BCE_NVM_CFG1);
2541
2542	entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
2543
2544	/*
2545	 * Flash reconfiguration is required to support additional
2546	 * NVRAM devices not directly supported in hardware.
2547	 * Check if the flash interface was reconfigured
2548	 * by the bootcode.
2549	 */
2550
2551	if (val & 0x40000000) {
2552		/* Flash interface reconfigured by bootcode. */
2553
2554		DBPRINT(sc,BCE_INFO_LOAD,
2555			"bce_init_nvram(): Flash WAS reconfigured.\n");
2556
2557		for (j = 0, flash = &flash_table[0]; j < entry_count;
2558		     j++, flash++) {
2559			if ((val & FLASH_BACKUP_STRAP_MASK) ==
2560			    (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
2561				sc->bce_flash_info = flash;
2562				break;
2563			}
2564		}
2565	} else {
2566		/* Flash interface not yet reconfigured. */
2567		u32 mask;
2568
2569		DBPRINT(sc, BCE_INFO_LOAD, "%s(): Flash was NOT reconfigured.\n",
2570			__FUNCTION__);
2571
2572		if (val & (1 << 23))
2573			mask = FLASH_BACKUP_STRAP_MASK;
2574		else
2575			mask = FLASH_STRAP_MASK;
2576
2577		/* Look for the matching NVRAM device configuration data. */
2578		for (j = 0, flash = &flash_table[0]; j < entry_count; j++, flash++) {
2579
2580			/* Check if the device matches any of the known devices. */
2581			if ((val & mask) == (flash->strapping & mask)) {
2582				/* Found a device match. */
2583				sc->bce_flash_info = flash;
2584
2585				/* Request access to the flash interface. */
2586				if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2587					return rc;
2588
2589				/* Reconfigure the flash interface. */
2590				bce_enable_nvram_access(sc);
2591				REG_WR(sc, BCE_NVM_CFG1, flash->config1);
2592				REG_WR(sc, BCE_NVM_CFG2, flash->config2);
2593				REG_WR(sc, BCE_NVM_CFG3, flash->config3);
2594				REG_WR(sc, BCE_NVM_WRITE1, flash->write1);
2595				bce_disable_nvram_access(sc);
2596				bce_release_nvram_lock(sc);
2597
2598				break;
2599			}
2600		}
2601	}
2602
2603	/* Check if a matching device was found. */
2604	if (j == entry_count) {
2605		sc->bce_flash_info = NULL;
2606		BCE_PRINTF("%s(%d): Unknown Flash NVRAM found!\n",
2607		    __FILE__, __LINE__);
2608		DBEXIT(BCE_VERBOSE_NVRAM);
2609		return (ENODEV);
2610	}
2611
2612bce_init_nvram_get_flash_size:
2613	/* Write the flash config data to the shared memory interface. */
2614	val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG2);
2615	val &= BCE_SHARED_HW_CFG2_NVM_SIZE_MASK;
2616	if (val)
2617		sc->bce_flash_size = val;
2618	else
2619		sc->bce_flash_size = sc->bce_flash_info->total_size;
2620
2621	DBPRINT(sc, BCE_INFO_LOAD, "%s(): Found %s, size = 0x%08X\n",
2622	    __FUNCTION__, sc->bce_flash_info->name,
2623	    sc->bce_flash_info->total_size);
2624
2625	DBEXIT(BCE_VERBOSE_NVRAM);
2626	return rc;
2627}
2628
2629
2630/****************************************************************************/
2631/* Read an arbitrary range of data from NVRAM.                              */
2632/*                                                                          */
2633/* Prepares the NVRAM interface for access and reads the requested data     */
2634/* into the supplied buffer.                                                */
2635/*                                                                          */
2636/* Returns:                                                                 */
2637/*   0 on success and the data read, positive value on failure.             */
2638/****************************************************************************/
2639static int
2640bce_nvram_read(struct bce_softc *sc, u32 offset, u8 *ret_buf,
2641	int buf_size)
2642{
2643	int rc = 0;
2644	u32 cmd_flags, offset32, len32, extra;
2645
2646	DBENTER(BCE_VERBOSE_NVRAM);
2647
2648	if (buf_size == 0)
2649		goto bce_nvram_read_exit;
2650
2651	/* Request access to the flash interface. */
2652	if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2653		goto bce_nvram_read_exit;
2654
2655	/* Enable access to flash interface */
2656	bce_enable_nvram_access(sc);
2657
2658	len32 = buf_size;
2659	offset32 = offset;
2660	extra = 0;
2661
2662	cmd_flags = 0;
2663
2664	if (offset32 & 3) {
2665		u8 buf[4];
2666		u32 pre_len;
2667
2668		offset32 &= ~3;
2669		pre_len = 4 - (offset & 3);
2670
2671		if (pre_len >= len32) {
2672			pre_len = len32;
2673			cmd_flags = BCE_NVM_COMMAND_FIRST | BCE_NVM_COMMAND_LAST;
2674		}
2675		else {
2676			cmd_flags = BCE_NVM_COMMAND_FIRST;
2677		}
2678
2679		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2680
2681		if (rc)
2682			return rc;
2683
2684		memcpy(ret_buf, buf + (offset & 3), pre_len);
2685
2686		offset32 += 4;
2687		ret_buf += pre_len;
2688		len32 -= pre_len;
2689	}
2690
2691	if (len32 & 3) {
2692		extra = 4 - (len32 & 3);
2693		len32 = (len32 + 4) & ~3;
2694	}
2695
2696	if (len32 == 4) {
2697		u8 buf[4];
2698
2699		if (cmd_flags)
2700			cmd_flags = BCE_NVM_COMMAND_LAST;
2701		else
2702			cmd_flags = BCE_NVM_COMMAND_FIRST |
2703				    BCE_NVM_COMMAND_LAST;
2704
2705		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2706
2707		memcpy(ret_buf, buf, 4 - extra);
2708	}
2709	else if (len32 > 0) {
2710		u8 buf[4];
2711
2712		/* Read the first word. */
2713		if (cmd_flags)
2714			cmd_flags = 0;
2715		else
2716			cmd_flags = BCE_NVM_COMMAND_FIRST;
2717
2718		rc = bce_nvram_read_dword(sc, offset32, ret_buf, cmd_flags);
2719
2720		/* Advance to the next dword. */
2721		offset32 += 4;
2722		ret_buf += 4;
2723		len32 -= 4;
2724
2725		while (len32 > 4 && rc == 0) {
2726			rc = bce_nvram_read_dword(sc, offset32, ret_buf, 0);
2727
2728			/* Advance to the next dword. */
2729			offset32 += 4;
2730			ret_buf += 4;
2731			len32 -= 4;
2732		}
2733
2734		if (rc)
2735			goto bce_nvram_read_locked_exit;
2736
2737		cmd_flags = BCE_NVM_COMMAND_LAST;
2738		rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
2739
2740		memcpy(ret_buf, buf, 4 - extra);
2741	}
2742
2743bce_nvram_read_locked_exit:
2744	/* Disable access to flash interface and release the lock. */
2745	bce_disable_nvram_access(sc);
2746	bce_release_nvram_lock(sc);
2747
2748bce_nvram_read_exit:
2749	DBEXIT(BCE_VERBOSE_NVRAM);
2750	return rc;
2751}
2752
2753
2754#ifdef BCE_NVRAM_WRITE_SUPPORT
2755/****************************************************************************/
2756/* Write an arbitrary range of data from NVRAM.                             */
2757/*                                                                          */
2758/* Prepares the NVRAM interface for write access and writes the requested   */
2759/* data from the supplied buffer.  The caller is responsible for            */
2760/* calculating any appropriate CRCs.                                        */
2761/*                                                                          */
2762/* Returns:                                                                 */
2763/*   0 on success, positive value on failure.                               */
2764/****************************************************************************/
2765static int
2766bce_nvram_write(struct bce_softc *sc, u32 offset, u8 *data_buf,
2767	int buf_size)
2768{
2769	u32 written, offset32, len32;
2770	u8 *buf, start[4], end[4];
2771	int rc = 0;
2772	int align_start, align_end;
2773
2774	DBENTER(BCE_VERBOSE_NVRAM);
2775
2776	buf = data_buf;
2777	offset32 = offset;
2778	len32 = buf_size;
2779	align_start = align_end = 0;
2780
2781	if ((align_start = (offset32 & 3))) {
2782		offset32 &= ~3;
2783		len32 += align_start;
2784		if ((rc = bce_nvram_read(sc, offset32, start, 4)))
2785			goto bce_nvram_write_exit;
2786	}
2787
2788	if (len32 & 3) {
2789	       	if ((len32 > 4) || !align_start) {
2790			align_end = 4 - (len32 & 3);
2791			len32 += align_end;
2792			if ((rc = bce_nvram_read(sc, offset32 + len32 - 4,
2793				end, 4))) {
2794				goto bce_nvram_write_exit;
2795			}
2796		}
2797	}
2798
2799	if (align_start || align_end) {
2800		buf = malloc(len32, M_DEVBUF, M_NOWAIT);
2801		if (buf == 0) {
2802			rc = ENOMEM;
2803			goto bce_nvram_write_exit;
2804		}
2805
2806		if (align_start) {
2807			memcpy(buf, start, 4);
2808		}
2809
2810		if (align_end) {
2811			memcpy(buf + len32 - 4, end, 4);
2812		}
2813		memcpy(buf + align_start, data_buf, buf_size);
2814	}
2815
2816	written = 0;
2817	while ((written < len32) && (rc == 0)) {
2818		u32 page_start, page_end, data_start, data_end;
2819		u32 addr, cmd_flags;
2820		int i;
2821		u8 flash_buffer[264];
2822
2823	    /* Find the page_start addr */
2824		page_start = offset32 + written;
2825		page_start -= (page_start % sc->bce_flash_info->page_size);
2826		/* Find the page_end addr */
2827		page_end = page_start + sc->bce_flash_info->page_size;
2828		/* Find the data_start addr */
2829		data_start = (written == 0) ? offset32 : page_start;
2830		/* Find the data_end addr */
2831		data_end = (page_end > offset32 + len32) ?
2832			(offset32 + len32) : page_end;
2833
2834		/* Request access to the flash interface. */
2835		if ((rc = bce_acquire_nvram_lock(sc)) != 0)
2836			goto bce_nvram_write_exit;
2837
2838		/* Enable access to flash interface */
2839		bce_enable_nvram_access(sc);
2840
2841		cmd_flags = BCE_NVM_COMMAND_FIRST;
2842		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2843			int j;
2844
2845			/* Read the whole page into the buffer
2846			 * (non-buffer flash only) */
2847			for (j = 0; j < sc->bce_flash_info->page_size; j += 4) {
2848				if (j == (sc->bce_flash_info->page_size - 4)) {
2849					cmd_flags |= BCE_NVM_COMMAND_LAST;
2850				}
2851				rc = bce_nvram_read_dword(sc,
2852					page_start + j,
2853					&flash_buffer[j],
2854					cmd_flags);
2855
2856				if (rc)
2857					goto bce_nvram_write_locked_exit;
2858
2859				cmd_flags = 0;
2860			}
2861		}
2862
2863		/* Enable writes to flash interface (unlock write-protect) */
2864		if ((rc = bce_enable_nvram_write(sc)) != 0)
2865			goto bce_nvram_write_locked_exit;
2866
2867		/* Erase the page */
2868		if ((rc = bce_nvram_erase_page(sc, page_start)) != 0)
2869			goto bce_nvram_write_locked_exit;
2870
2871		/* Re-enable the write again for the actual write */
2872		bce_enable_nvram_write(sc);
2873
2874		/* Loop to write back the buffer data from page_start to
2875		 * data_start */
2876		i = 0;
2877		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2878			for (addr = page_start; addr < data_start;
2879				addr += 4, i += 4) {
2880
2881				rc = bce_nvram_write_dword(sc, addr,
2882					&flash_buffer[i], cmd_flags);
2883
2884				if (rc != 0)
2885					goto bce_nvram_write_locked_exit;
2886
2887				cmd_flags = 0;
2888			}
2889		}
2890
2891		/* Loop to write the new data from data_start to data_end */
2892		for (addr = data_start; addr < data_end; addr += 4, i++) {
2893			if ((addr == page_end - 4) ||
2894				((sc->bce_flash_info->flags & BCE_NV_BUFFERED) &&
2895				(addr == data_end - 4))) {
2896
2897				cmd_flags |= BCE_NVM_COMMAND_LAST;
2898			}
2899			rc = bce_nvram_write_dword(sc, addr, buf,
2900				cmd_flags);
2901
2902			if (rc != 0)
2903				goto bce_nvram_write_locked_exit;
2904
2905			cmd_flags = 0;
2906			buf += 4;
2907		}
2908
2909		/* Loop to write back the buffer data from data_end
2910		 * to page_end */
2911		if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
2912			for (addr = data_end; addr < page_end;
2913				addr += 4, i += 4) {
2914
2915				if (addr == page_end-4) {
2916					cmd_flags = BCE_NVM_COMMAND_LAST;
2917                		}
2918				rc = bce_nvram_write_dword(sc, addr,
2919					&flash_buffer[i], cmd_flags);
2920
2921				if (rc != 0)
2922					goto bce_nvram_write_locked_exit;
2923
2924				cmd_flags = 0;
2925			}
2926		}
2927
2928		/* Disable writes to flash interface (lock write-protect) */
2929		bce_disable_nvram_write(sc);
2930
2931		/* Disable access to flash interface */
2932		bce_disable_nvram_access(sc);
2933		bce_release_nvram_lock(sc);
2934
2935		/* Increment written */
2936		written += data_end - data_start;
2937	}
2938
2939	goto bce_nvram_write_exit;
2940
2941bce_nvram_write_locked_exit:
2942	bce_disable_nvram_write(sc);
2943	bce_disable_nvram_access(sc);
2944	bce_release_nvram_lock(sc);
2945
2946bce_nvram_write_exit:
2947	if (align_start || align_end)
2948		free(buf, M_DEVBUF);
2949
2950	DBEXIT(BCE_VERBOSE_NVRAM);
2951	return (rc);
2952}
2953#endif /* BCE_NVRAM_WRITE_SUPPORT */
2954
2955
2956/****************************************************************************/
2957/* Verifies that NVRAM is accessible and contains valid data.               */
2958/*                                                                          */
2959/* Reads the configuration data from NVRAM and verifies that the CRC is     */
2960/* correct.                                                                 */
2961/*                                                                          */
2962/* Returns:                                                                 */
2963/*   0 on success, positive value on failure.                               */
2964/****************************************************************************/
2965static int
2966bce_nvram_test(struct bce_softc *sc)
2967{
2968	u32 buf[BCE_NVRAM_SIZE / 4];
2969	u8 *data = (u8 *) buf;
2970	int rc = 0;
2971	u32 magic, csum;
2972
2973	DBENTER(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
2974
2975	/*
2976	 * Check that the device NVRAM is valid by reading
2977	 * the magic value at offset 0.
2978	 */
2979	if ((rc = bce_nvram_read(sc, 0, data, 4)) != 0) {
2980		BCE_PRINTF("%s(%d): Unable to read NVRAM!\n",
2981		    __FILE__, __LINE__);
2982		goto bce_nvram_test_exit;
2983	}
2984
2985	/*
2986	 * Verify that offset 0 of the NVRAM contains
2987	 * a valid magic number.
2988	 */
2989	magic = bce_be32toh(buf[0]);
2990	if (magic != BCE_NVRAM_MAGIC) {
2991		rc = ENODEV;
2992		BCE_PRINTF("%s(%d): Invalid NVRAM magic value! "
2993		    "Expected: 0x%08X, Found: 0x%08X\n",
2994		    __FILE__, __LINE__, BCE_NVRAM_MAGIC, magic);
2995		goto bce_nvram_test_exit;
2996	}
2997
2998	/*
2999	 * Verify that the device NVRAM includes valid
3000	 * configuration data.
3001	 */
3002	if ((rc = bce_nvram_read(sc, 0x100, data, BCE_NVRAM_SIZE)) != 0) {
3003		BCE_PRINTF("%s(%d): Unable to read manufacturing "
3004		    "Information from  NVRAM!\n", __FILE__, __LINE__);
3005		goto bce_nvram_test_exit;
3006	}
3007
3008	csum = ether_crc32_le(data, 0x100);
3009	if (csum != BCE_CRC32_RESIDUAL) {
3010		rc = ENODEV;
3011		BCE_PRINTF("%s(%d): Invalid manufacturing information "
3012		    "NVRAM CRC!	Expected: 0x%08X, Found: 0x%08X\n",
3013		    __FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
3014		goto bce_nvram_test_exit;
3015	}
3016
3017	csum = ether_crc32_le(data + 0x100, 0x100);
3018	if (csum != BCE_CRC32_RESIDUAL) {
3019		rc = ENODEV;
3020		BCE_PRINTF("%s(%d): Invalid feature configuration "
3021		    "information NVRAM CRC! Expected: 0x%08X, "
3022		    "Found: 08%08X\n", __FILE__, __LINE__,
3023		    BCE_CRC32_RESIDUAL, csum);
3024	}
3025
3026bce_nvram_test_exit:
3027	DBEXIT(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
3028	return rc;
3029}
3030
3031
3032/****************************************************************************/
3033/* Calculates the size of the buffers to allocate based on the MTU.         */
3034/*                                                                          */
3035/* Returns:                                                                 */
3036/*   Nothing.                                                               */
3037/****************************************************************************/
3038static void
3039bce_get_rx_buffer_sizes(struct bce_softc *sc, int mtu)
3040{
3041	DBENTER(BCE_VERBOSE_LOAD);
3042
3043	/* Use a single allocation type when header splitting enabled. */
3044	if (bce_hdr_split == TRUE) {
3045		sc->rx_bd_mbuf_alloc_size = MHLEN;
3046		/* Make sure offset is 16 byte aligned for hardware. */
3047		sc->rx_bd_mbuf_align_pad =
3048			roundup2((MSIZE - MHLEN), 16) - (MSIZE - MHLEN);
3049		sc->rx_bd_mbuf_data_len = sc->rx_bd_mbuf_alloc_size -
3050			sc->rx_bd_mbuf_align_pad;
3051	} else {
3052		if ((mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN +
3053		    ETHER_CRC_LEN) > MCLBYTES) {
3054			/* Setup for jumbo RX buffer allocations. */
3055			sc->rx_bd_mbuf_alloc_size = MJUM9BYTES;
3056			sc->rx_bd_mbuf_align_pad  =
3057				roundup2(MJUM9BYTES, 16) - MJUM9BYTES;
3058			sc->rx_bd_mbuf_data_len =
3059			    sc->rx_bd_mbuf_alloc_size -
3060			    sc->rx_bd_mbuf_align_pad;
3061		} else {
3062			/* Setup for standard RX buffer allocations. */
3063			sc->rx_bd_mbuf_alloc_size = MCLBYTES;
3064			sc->rx_bd_mbuf_align_pad  =
3065			    roundup2(MCLBYTES, 16) - MCLBYTES;
3066			sc->rx_bd_mbuf_data_len =
3067			    sc->rx_bd_mbuf_alloc_size -
3068			    sc->rx_bd_mbuf_align_pad;
3069		}
3070	}
3071
3072//	DBPRINT(sc, BCE_INFO_LOAD,
3073	DBPRINT(sc, BCE_WARN,
3074	   "%s(): rx_bd_mbuf_alloc_size = %d, rx_bd_mbuf_data_len = %d, "
3075	   "rx_bd_mbuf_align_pad = %d\n", __FUNCTION__,
3076	   sc->rx_bd_mbuf_alloc_size, sc->rx_bd_mbuf_data_len,
3077	   sc->rx_bd_mbuf_align_pad);
3078
3079	DBEXIT(BCE_VERBOSE_LOAD);
3080}
3081
3082/****************************************************************************/
3083/* Identifies the current media type of the controller and sets the PHY     */
3084/* address.                                                                 */
3085/*                                                                          */
3086/* Returns:                                                                 */
3087/*   Nothing.                                                               */
3088/****************************************************************************/
3089static void
3090bce_get_media(struct bce_softc *sc)
3091{
3092	u32 val;
3093
3094	DBENTER(BCE_VERBOSE_PHY);
3095
3096	/* Assume PHY address for copper controllers. */
3097	sc->bce_phy_addr = 1;
3098
3099	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
3100 		u32 val = REG_RD(sc, BCE_MISC_DUAL_MEDIA_CTRL);
3101		u32 bond_id = val & BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID;
3102		u32 strap;
3103
3104		/*
3105		 * The BCM5709S is software configurable
3106		 * for Copper or SerDes operation.
3107		 */
3108		if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_C) {
3109			DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded "
3110			    "for copper.\n");
3111			goto bce_get_media_exit;
3112		} else if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_S) {
3113			DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded "
3114			    "for dual media.\n");
3115			sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
3116			goto bce_get_media_exit;
3117		}
3118
3119		if (val & BCE_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE)
3120			strap = (val &
3121			    BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21;
3122		else
3123			strap = (val &
3124			    BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8;
3125
3126		if (pci_get_function(sc->bce_dev) == 0) {
3127			switch (strap) {
3128			case 0x4:
3129			case 0x5:
3130			case 0x6:
3131				DBPRINT(sc, BCE_INFO_LOAD,
3132				    "BCM5709 s/w configured for SerDes.\n");
3133				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
3134				break;
3135			default:
3136				DBPRINT(sc, BCE_INFO_LOAD,
3137				    "BCM5709 s/w configured for Copper.\n");
3138				break;
3139			}
3140		} else {
3141			switch (strap) {
3142			case 0x1:
3143			case 0x2:
3144			case 0x4:
3145				DBPRINT(sc, BCE_INFO_LOAD,
3146				    "BCM5709 s/w configured for SerDes.\n");
3147				sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
3148				break;
3149			default:
3150				DBPRINT(sc, BCE_INFO_LOAD,
3151				    "BCM5709 s/w configured for Copper.\n");
3152				break;
3153			}
3154		}
3155
3156	} else if (BCE_CHIP_BOND_ID(sc) & BCE_CHIP_BOND_ID_SERDES_BIT)
3157		sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
3158
3159	if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) {
3160
3161		sc->bce_flags |= BCE_NO_WOL_FLAG;
3162
3163		if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
3164			sc->bce_phy_flags |= BCE_PHY_IEEE_CLAUSE_45_FLAG;
3165
3166		if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
3167			/* 5708S/09S/16S use a separate PHY for SerDes. */
3168			sc->bce_phy_addr = 2;
3169
3170			val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
3171			if (val & BCE_SHARED_HW_CFG_PHY_2_5G) {
3172				sc->bce_phy_flags |=
3173				    BCE_PHY_2_5G_CAPABLE_FLAG;
3174				DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb "
3175				    "capable adapter\n");
3176			}
3177		}
3178	} else if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) ||
3179	    (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708))
3180		sc->bce_phy_flags |= BCE_PHY_CRC_FIX_FLAG;
3181
3182bce_get_media_exit:
3183	DBPRINT(sc, (BCE_INFO_LOAD | BCE_INFO_PHY),
3184		"Using PHY address %d.\n", sc->bce_phy_addr);
3185
3186	DBEXIT(BCE_VERBOSE_PHY);
3187}
3188
3189
3190/****************************************************************************/
3191/* Performs PHY initialization required before MII drivers access the       */
3192/* device.                                                                  */
3193/*                                                                          */
3194/* Returns:                                                                 */
3195/*   Nothing.                                                               */
3196/****************************************************************************/
3197static void
3198bce_init_media(struct bce_softc *sc)
3199{
3200	if ((sc->bce_phy_flags & (BCE_PHY_IEEE_CLAUSE_45_FLAG |
3201	    BCE_PHY_REMOTE_CAP_FLAG)) == BCE_PHY_IEEE_CLAUSE_45_FLAG) {
3202		/*
3203		 * Configure 5709S/5716S PHYs to use traditional IEEE
3204		 * Clause 22 method. Otherwise we have no way to attach
3205		 * the PHY in mii(4) layer. PHY specific configuration
3206		 * is done in mii layer.
3207		 */
3208
3209		/* Select auto-negotiation MMD of the PHY. */
3210		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
3211		    BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_ADDR_EXT);
3212		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
3213		    BRGPHY_ADDR_EXT, BRGPHY_ADDR_EXT_AN_MMD);
3214
3215		/* Set IEEE0 block of AN MMD (assumed in brgphy(4) code). */
3216		bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
3217		    BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
3218	}
3219}
3220
3221
3222/****************************************************************************/
3223/* Free any DMA memory owned by the driver.                                 */
3224/*                                                                          */
3225/* Scans through each data structre that requires DMA memory and frees      */
3226/* the memory if allocated.                                                 */
3227/*                                                                          */
3228/* Returns:                                                                 */
3229/*   Nothing.                                                               */
3230/****************************************************************************/
3231static void
3232bce_dma_free(struct bce_softc *sc)
3233{
3234	int i;
3235
3236	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
3237
3238	/* Free, unmap, and destroy the status block. */
3239	if (sc->status_block_paddr != 0) {
3240		bus_dmamap_unload(
3241		    sc->status_tag,
3242		    sc->status_map);
3243		sc->status_block_paddr = 0;
3244	}
3245
3246	if (sc->status_block != NULL) {
3247		bus_dmamem_free(
3248		   sc->status_tag,
3249		    sc->status_block,
3250		    sc->status_map);
3251		sc->status_block = NULL;
3252	}
3253
3254	if (sc->status_tag != NULL) {
3255		bus_dma_tag_destroy(sc->status_tag);
3256		sc->status_tag = NULL;
3257	}
3258
3259
3260	/* Free, unmap, and destroy the statistics block. */
3261	if (sc->stats_block_paddr != 0) {
3262		bus_dmamap_unload(
3263		    sc->stats_tag,
3264		    sc->stats_map);
3265		sc->stats_block_paddr = 0;
3266	}
3267
3268	if (sc->stats_block != NULL) {
3269		bus_dmamem_free(
3270		    sc->stats_tag,
3271		    sc->stats_block,
3272		    sc->stats_map);
3273		sc->stats_block = NULL;
3274	}
3275
3276	if (sc->stats_tag != NULL) {
3277		bus_dma_tag_destroy(sc->stats_tag);
3278		sc->stats_tag = NULL;
3279	}
3280
3281
3282	/* Free, unmap and destroy all context memory pages. */
3283	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
3284		for (i = 0; i < sc->ctx_pages; i++ ) {
3285			if (sc->ctx_paddr[i] != 0) {
3286				bus_dmamap_unload(
3287				    sc->ctx_tag,
3288				    sc->ctx_map[i]);
3289				sc->ctx_paddr[i] = 0;
3290			}
3291
3292			if (sc->ctx_block[i] != NULL) {
3293				bus_dmamem_free(
3294				    sc->ctx_tag,
3295				    sc->ctx_block[i],
3296				    sc->ctx_map[i]);
3297				sc->ctx_block[i] = NULL;
3298			}
3299		}
3300
3301		/* Destroy the context memory tag. */
3302		if (sc->ctx_tag != NULL) {
3303			bus_dma_tag_destroy(sc->ctx_tag);
3304			sc->ctx_tag = NULL;
3305		}
3306	}
3307
3308
3309	/* Free, unmap and destroy all TX buffer descriptor chain pages. */
3310	for (i = 0; i < sc->tx_pages; i++ ) {
3311		if (sc->tx_bd_chain_paddr[i] != 0) {
3312			bus_dmamap_unload(
3313			    sc->tx_bd_chain_tag,
3314			    sc->tx_bd_chain_map[i]);
3315			sc->tx_bd_chain_paddr[i] = 0;
3316		}
3317
3318		if (sc->tx_bd_chain[i] != NULL) {
3319			bus_dmamem_free(
3320			    sc->tx_bd_chain_tag,
3321			    sc->tx_bd_chain[i],
3322			    sc->tx_bd_chain_map[i]);
3323			sc->tx_bd_chain[i] = NULL;
3324		}
3325	}
3326
3327	/* Destroy the TX buffer descriptor tag. */
3328	if (sc->tx_bd_chain_tag != NULL) {
3329		bus_dma_tag_destroy(sc->tx_bd_chain_tag);
3330		sc->tx_bd_chain_tag = NULL;
3331	}
3332
3333
3334	/* Free, unmap and destroy all RX buffer descriptor chain pages. */
3335	for (i = 0; i < sc->rx_pages; i++ ) {
3336		if (sc->rx_bd_chain_paddr[i] != 0) {
3337			bus_dmamap_unload(
3338			    sc->rx_bd_chain_tag,
3339			    sc->rx_bd_chain_map[i]);
3340			sc->rx_bd_chain_paddr[i] = 0;
3341		}
3342
3343		if (sc->rx_bd_chain[i] != NULL) {
3344			bus_dmamem_free(
3345			    sc->rx_bd_chain_tag,
3346			    sc->rx_bd_chain[i],
3347			    sc->rx_bd_chain_map[i]);
3348			sc->rx_bd_chain[i] = NULL;
3349		}
3350	}
3351
3352	/* Destroy the RX buffer descriptor tag. */
3353	if (sc->rx_bd_chain_tag != NULL) {
3354		bus_dma_tag_destroy(sc->rx_bd_chain_tag);
3355		sc->rx_bd_chain_tag = NULL;
3356	}
3357
3358
3359	/* Free, unmap and destroy all page buffer descriptor chain pages. */
3360	if (bce_hdr_split == TRUE) {
3361		for (i = 0; i < sc->pg_pages; i++ ) {
3362			if (sc->pg_bd_chain_paddr[i] != 0) {
3363				bus_dmamap_unload(
3364				    sc->pg_bd_chain_tag,
3365				    sc->pg_bd_chain_map[i]);
3366				sc->pg_bd_chain_paddr[i] = 0;
3367			}
3368
3369			if (sc->pg_bd_chain[i] != NULL) {
3370				bus_dmamem_free(
3371				    sc->pg_bd_chain_tag,
3372				    sc->pg_bd_chain[i],
3373				    sc->pg_bd_chain_map[i]);
3374				sc->pg_bd_chain[i] = NULL;
3375			}
3376		}
3377
3378		/* Destroy the page buffer descriptor tag. */
3379		if (sc->pg_bd_chain_tag != NULL) {
3380			bus_dma_tag_destroy(sc->pg_bd_chain_tag);
3381			sc->pg_bd_chain_tag = NULL;
3382		}
3383	}
3384
3385
3386	/* Unload and destroy the TX mbuf maps. */
3387	for (i = 0; i < MAX_TX_BD_AVAIL; i++) {
3388		if (sc->tx_mbuf_map[i] != NULL) {
3389			bus_dmamap_unload(sc->tx_mbuf_tag,
3390			    sc->tx_mbuf_map[i]);
3391			bus_dmamap_destroy(sc->tx_mbuf_tag,
3392	 		    sc->tx_mbuf_map[i]);
3393			sc->tx_mbuf_map[i] = NULL;
3394		}
3395	}
3396
3397	/* Destroy the TX mbuf tag. */
3398	if (sc->tx_mbuf_tag != NULL) {
3399		bus_dma_tag_destroy(sc->tx_mbuf_tag);
3400		sc->tx_mbuf_tag = NULL;
3401	}
3402
3403	/* Unload and destroy the RX mbuf maps. */
3404	for (i = 0; i < MAX_RX_BD_AVAIL; i++) {
3405		if (sc->rx_mbuf_map[i] != NULL) {
3406			bus_dmamap_unload(sc->rx_mbuf_tag,
3407			    sc->rx_mbuf_map[i]);
3408			bus_dmamap_destroy(sc->rx_mbuf_tag,
3409	 		    sc->rx_mbuf_map[i]);
3410			sc->rx_mbuf_map[i] = NULL;
3411		}
3412	}
3413
3414	/* Destroy the RX mbuf tag. */
3415	if (sc->rx_mbuf_tag != NULL) {
3416		bus_dma_tag_destroy(sc->rx_mbuf_tag);
3417		sc->rx_mbuf_tag = NULL;
3418	}
3419
3420	/* Unload and destroy the page mbuf maps. */
3421	if (bce_hdr_split == TRUE) {
3422		for (i = 0; i < MAX_PG_BD_AVAIL; i++) {
3423			if (sc->pg_mbuf_map[i] != NULL) {
3424				bus_dmamap_unload(sc->pg_mbuf_tag,
3425				    sc->pg_mbuf_map[i]);
3426				bus_dmamap_destroy(sc->pg_mbuf_tag,
3427				    sc->pg_mbuf_map[i]);
3428				sc->pg_mbuf_map[i] = NULL;
3429			}
3430		}
3431
3432		/* Destroy the page mbuf tag. */
3433		if (sc->pg_mbuf_tag != NULL) {
3434			bus_dma_tag_destroy(sc->pg_mbuf_tag);
3435			sc->pg_mbuf_tag = NULL;
3436		}
3437	}
3438
3439	/* Destroy the parent tag */
3440	if (sc->parent_tag != NULL) {
3441		bus_dma_tag_destroy(sc->parent_tag);
3442		sc->parent_tag = NULL;
3443	}
3444
3445	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
3446}
3447
3448
3449/****************************************************************************/
3450/* Get DMA memory from the OS.                                              */
3451/*                                                                          */
3452/* Validates that the OS has provided DMA buffers in response to a          */
3453/* bus_dmamap_load() call and saves the physical address of those buffers.  */
3454/* When the callback is used the OS will return 0 for the mapping function  */
3455/* (bus_dmamap_load()) so we use the value of map_arg->maxsegs to pass any  */
3456/* failures back to the caller.                                             */
3457/*                                                                          */
3458/* Returns:                                                                 */
3459/*   Nothing.                                                               */
3460/****************************************************************************/
3461static void
3462bce_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
3463{
3464	bus_addr_t *busaddr = arg;
3465
3466	KASSERT(nseg == 1, ("%s(): Too many segments returned (%d)!",
3467	    __FUNCTION__, nseg));
3468	/* Simulate a mapping failure. */
3469	DBRUNIF(DB_RANDOMTRUE(dma_map_addr_failed_sim_control),
3470	    error = ENOMEM);
3471
3472	/* ToDo: How to increment debug sim_count variable here? */
3473
3474	/* Check for an error and signal the caller that an error occurred. */
3475	if (error) {
3476		*busaddr = 0;
3477	} else {
3478		*busaddr = segs->ds_addr;
3479	}
3480}
3481
3482
3483/****************************************************************************/
3484/* Allocate any DMA memory needed by the driver.                            */
3485/*                                                                          */
3486/* Allocates DMA memory needed for the various global structures needed by  */
3487/* hardware.                                                                */
3488/*                                                                          */
3489/* Memory alignment requirements:                                           */
3490/* +-----------------+----------+----------+----------+----------+          */
3491/* |                 |   5706   |   5708   |   5709   |   5716   |          */
3492/* +-----------------+----------+----------+----------+----------+          */
3493/* |Status Block     | 8 bytes  | 8 bytes  | 16 bytes | 16 bytes |          */
3494/* |Statistics Block | 8 bytes  | 8 bytes  | 16 bytes | 16 bytes |          */
3495/* |RX Buffers       | 16 bytes | 16 bytes | 16 bytes | 16 bytes |          */
3496/* |PG Buffers       |   none   |   none   |   none   |   none   |          */
3497/* |TX Buffers       |   none   |   none   |   none   |   none   |          */
3498/* |Chain Pages(1)   |   4KiB   |   4KiB   |   4KiB   |   4KiB   |          */
3499/* |Context Memory   |          |          |          |          |          */
3500/* +-----------------+----------+----------+----------+----------+          */
3501/*                                                                          */
3502/* (1) Must align with CPU page size (BCM_PAGE_SZIE).                       */
3503/*                                                                          */
3504/* Returns:                                                                 */
3505/*   0 for success, positive value for failure.                             */
3506/****************************************************************************/
3507static int
3508bce_dma_alloc(device_t dev)
3509{
3510	struct bce_softc *sc;
3511	int i, error, rc = 0;
3512	bus_size_t max_size, max_seg_size;
3513	int max_segments;
3514
3515	sc = device_get_softc(dev);
3516
3517	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
3518
3519	/*
3520	 * Allocate the parent bus DMA tag appropriate for PCI.
3521	 */
3522	if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, BCE_DMA_BOUNDARY,
3523	    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
3524	    BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL,
3525	    &sc->parent_tag)) {
3526		BCE_PRINTF("%s(%d): Could not allocate parent DMA tag!\n",
3527		    __FILE__, __LINE__);
3528		rc = ENOMEM;
3529		goto bce_dma_alloc_exit;
3530	}
3531
3532	/*
3533	 * Create a DMA tag for the status block, allocate and clear the
3534	 * memory, map the memory into DMA space, and fetch the physical
3535	 * address of the block.
3536	 */
3537	if (bus_dma_tag_create(sc->parent_tag, BCE_DMA_ALIGN,
3538	    BCE_DMA_BOUNDARY, sc->max_bus_addr,	BUS_SPACE_MAXADDR,
3539	    NULL, NULL,	BCE_STATUS_BLK_SZ, 1, BCE_STATUS_BLK_SZ,
3540	    0, NULL, NULL, &sc->status_tag)) {
3541		BCE_PRINTF("%s(%d): Could not allocate status block "
3542		    "DMA tag!\n", __FILE__, __LINE__);
3543		rc = ENOMEM;
3544		goto bce_dma_alloc_exit;
3545	}
3546
3547	if(bus_dmamem_alloc(sc->status_tag, (void **)&sc->status_block,
3548	    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3549	    &sc->status_map)) {
3550		BCE_PRINTF("%s(%d): Could not allocate status block "
3551		    "DMA memory!\n", __FILE__, __LINE__);
3552		rc = ENOMEM;
3553		goto bce_dma_alloc_exit;
3554	}
3555
3556	error = bus_dmamap_load(sc->status_tag,	sc->status_map,
3557	    sc->status_block, BCE_STATUS_BLK_SZ, bce_dma_map_addr,
3558	    &sc->status_block_paddr, BUS_DMA_NOWAIT);
3559
3560	if (error || sc->status_block_paddr == 0) {
3561		BCE_PRINTF("%s(%d): Could not map status block "
3562		    "DMA memory!\n", __FILE__, __LINE__);
3563		rc = ENOMEM;
3564		goto bce_dma_alloc_exit;
3565	}
3566
3567	DBPRINT(sc, BCE_INFO_LOAD, "%s(): status_block_paddr = 0x%jX\n",
3568	    __FUNCTION__, (uintmax_t) sc->status_block_paddr);
3569
3570	/*
3571	 * Create a DMA tag for the statistics block, allocate and clear the
3572	 * memory, map the memory into DMA space, and fetch the physical
3573	 * address of the block.
3574	 */
3575	if (bus_dma_tag_create(sc->parent_tag, BCE_DMA_ALIGN,
3576	    BCE_DMA_BOUNDARY, sc->max_bus_addr,	BUS_SPACE_MAXADDR,
3577	    NULL, NULL,	BCE_STATS_BLK_SZ, 1, BCE_STATS_BLK_SZ,
3578	    0, NULL, NULL, &sc->stats_tag)) {
3579		BCE_PRINTF("%s(%d): Could not allocate statistics block "
3580		    "DMA tag!\n", __FILE__, __LINE__);
3581		rc = ENOMEM;
3582		goto bce_dma_alloc_exit;
3583	}
3584
3585	if (bus_dmamem_alloc(sc->stats_tag, (void **)&sc->stats_block,
3586	    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &sc->stats_map)) {
3587		BCE_PRINTF("%s(%d): Could not allocate statistics block "
3588		    "DMA memory!\n", __FILE__, __LINE__);
3589		rc = ENOMEM;
3590		goto bce_dma_alloc_exit;
3591	}
3592
3593	error = bus_dmamap_load(sc->stats_tag, sc->stats_map,
3594	    sc->stats_block, BCE_STATS_BLK_SZ, bce_dma_map_addr,
3595	    &sc->stats_block_paddr, BUS_DMA_NOWAIT);
3596
3597	if (error || sc->stats_block_paddr == 0) {
3598		BCE_PRINTF("%s(%d): Could not map statistics block "
3599		    "DMA memory!\n", __FILE__, __LINE__);
3600		rc = ENOMEM;
3601		goto bce_dma_alloc_exit;
3602	}
3603
3604	DBPRINT(sc, BCE_INFO_LOAD, "%s(): stats_block_paddr = 0x%jX\n",
3605	    __FUNCTION__, (uintmax_t) sc->stats_block_paddr);
3606
3607	/* BCM5709 uses host memory as cache for context memory. */
3608	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
3609		sc->ctx_pages = 0x2000 / BCM_PAGE_SIZE;
3610		if (sc->ctx_pages == 0)
3611			sc->ctx_pages = 1;
3612
3613		DBRUNIF((sc->ctx_pages > 512),
3614		    BCE_PRINTF("%s(%d): Too many CTX pages! %d > 512\n",
3615		    __FILE__, __LINE__, sc->ctx_pages));
3616
3617		/*
3618		 * Create a DMA tag for the context pages,
3619		 * allocate and clear the memory, map the
3620		 * memory into DMA space, and fetch the
3621		 * physical address of the block.
3622		 */
3623		if(bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
3624		    BCE_DMA_BOUNDARY, sc->max_bus_addr,	BUS_SPACE_MAXADDR,
3625		    NULL, NULL,	BCM_PAGE_SIZE, 1, BCM_PAGE_SIZE,
3626		    0, NULL, NULL, &sc->ctx_tag)) {
3627			BCE_PRINTF("%s(%d): Could not allocate CTX "
3628			    "DMA tag!\n", __FILE__, __LINE__);
3629			rc = ENOMEM;
3630			goto bce_dma_alloc_exit;
3631		}
3632
3633		for (i = 0; i < sc->ctx_pages; i++) {
3634
3635			if(bus_dmamem_alloc(sc->ctx_tag,
3636			    (void **)&sc->ctx_block[i],
3637			    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3638			    &sc->ctx_map[i])) {
3639				BCE_PRINTF("%s(%d): Could not allocate CTX "
3640				    "DMA memory!\n", __FILE__, __LINE__);
3641				rc = ENOMEM;
3642				goto bce_dma_alloc_exit;
3643			}
3644
3645			error = bus_dmamap_load(sc->ctx_tag, sc->ctx_map[i],
3646			    sc->ctx_block[i], BCM_PAGE_SIZE, bce_dma_map_addr,
3647			    &sc->ctx_paddr[i], BUS_DMA_NOWAIT);
3648
3649			if (error || sc->ctx_paddr[i] == 0) {
3650				BCE_PRINTF("%s(%d): Could not map CTX "
3651				    "DMA memory!\n", __FILE__, __LINE__);
3652				rc = ENOMEM;
3653				goto bce_dma_alloc_exit;
3654			}
3655
3656			DBPRINT(sc, BCE_INFO_LOAD, "%s(): ctx_paddr[%d] "
3657			    "= 0x%jX\n", __FUNCTION__, i,
3658			    (uintmax_t) sc->ctx_paddr[i]);
3659		}
3660	}
3661
3662	/*
3663	 * Create a DMA tag for the TX buffer descriptor chain,
3664	 * allocate and clear the  memory, and fetch the
3665	 * physical address of the block.
3666	 */
3667	if(bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE, BCE_DMA_BOUNDARY,
3668	    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
3669	    BCE_TX_CHAIN_PAGE_SZ, 1, BCE_TX_CHAIN_PAGE_SZ, 0,
3670	    NULL, NULL,	&sc->tx_bd_chain_tag)) {
3671		BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
3672		    "chain DMA tag!\n", __FILE__, __LINE__);
3673		rc = ENOMEM;
3674		goto bce_dma_alloc_exit;
3675	}
3676
3677	for (i = 0; i < sc->tx_pages; i++) {
3678
3679		if(bus_dmamem_alloc(sc->tx_bd_chain_tag,
3680		    (void **)&sc->tx_bd_chain[i],
3681		    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3682		    &sc->tx_bd_chain_map[i])) {
3683			BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
3684			    "chain DMA memory!\n", __FILE__, __LINE__);
3685			rc = ENOMEM;
3686			goto bce_dma_alloc_exit;
3687		}
3688
3689		error = bus_dmamap_load(sc->tx_bd_chain_tag,
3690		    sc->tx_bd_chain_map[i], sc->tx_bd_chain[i],
3691		    BCE_TX_CHAIN_PAGE_SZ, bce_dma_map_addr,
3692		    &sc->tx_bd_chain_paddr[i], BUS_DMA_NOWAIT);
3693
3694		if (error || sc->tx_bd_chain_paddr[i] == 0) {
3695			BCE_PRINTF("%s(%d): Could not map TX descriptor "
3696			    "chain DMA memory!\n", __FILE__, __LINE__);
3697			rc = ENOMEM;
3698			goto bce_dma_alloc_exit;
3699		}
3700
3701		DBPRINT(sc, BCE_INFO_LOAD, "%s(): tx_bd_chain_paddr[%d] = "
3702		    "0x%jX\n", __FUNCTION__, i,
3703		    (uintmax_t) sc->tx_bd_chain_paddr[i]);
3704	}
3705
3706	/* Check the required size before mapping to conserve resources. */
3707	if (bce_tso_enable) {
3708		max_size     = BCE_TSO_MAX_SIZE;
3709		max_segments = BCE_MAX_SEGMENTS;
3710		max_seg_size = BCE_TSO_MAX_SEG_SIZE;
3711	} else {
3712		max_size     = MCLBYTES * BCE_MAX_SEGMENTS;
3713		max_segments = BCE_MAX_SEGMENTS;
3714		max_seg_size = MCLBYTES;
3715	}
3716
3717	/* Create a DMA tag for TX mbufs. */
3718	if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
3719	    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, max_size,
3720	    max_segments, max_seg_size,	0, NULL, NULL, &sc->tx_mbuf_tag)) {
3721		BCE_PRINTF("%s(%d): Could not allocate TX mbuf DMA tag!\n",
3722		    __FILE__, __LINE__);
3723		rc = ENOMEM;
3724		goto bce_dma_alloc_exit;
3725	}
3726
3727	/* Create DMA maps for the TX mbufs clusters. */
3728	for (i = 0; i < TOTAL_TX_BD_ALLOC; i++) {
3729		if (bus_dmamap_create(sc->tx_mbuf_tag, BUS_DMA_NOWAIT,
3730			&sc->tx_mbuf_map[i])) {
3731			BCE_PRINTF("%s(%d): Unable to create TX mbuf DMA "
3732			    "map!\n", __FILE__, __LINE__);
3733			rc = ENOMEM;
3734			goto bce_dma_alloc_exit;
3735		}
3736	}
3737
3738	/*
3739	 * Create a DMA tag for the RX buffer descriptor chain,
3740	 * allocate and clear the memory, and fetch the physical
3741	 * address of the blocks.
3742	 */
3743	if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
3744			BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR,
3745			sc->max_bus_addr, NULL, NULL,
3746			BCE_RX_CHAIN_PAGE_SZ, 1, BCE_RX_CHAIN_PAGE_SZ,
3747			0, NULL, NULL, &sc->rx_bd_chain_tag)) {
3748		BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain "
3749		    "DMA tag!\n", __FILE__, __LINE__);
3750		rc = ENOMEM;
3751		goto bce_dma_alloc_exit;
3752	}
3753
3754	for (i = 0; i < sc->rx_pages; i++) {
3755
3756		if (bus_dmamem_alloc(sc->rx_bd_chain_tag,
3757		    (void **)&sc->rx_bd_chain[i],
3758		    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3759		    &sc->rx_bd_chain_map[i])) {
3760			BCE_PRINTF("%s(%d): Could not allocate RX descriptor "
3761			    "chain DMA memory!\n", __FILE__, __LINE__);
3762			rc = ENOMEM;
3763			goto bce_dma_alloc_exit;
3764		}
3765
3766		error = bus_dmamap_load(sc->rx_bd_chain_tag,
3767		    sc->rx_bd_chain_map[i], sc->rx_bd_chain[i],
3768		    BCE_RX_CHAIN_PAGE_SZ, bce_dma_map_addr,
3769		    &sc->rx_bd_chain_paddr[i], BUS_DMA_NOWAIT);
3770
3771		if (error || sc->rx_bd_chain_paddr[i] == 0) {
3772			BCE_PRINTF("%s(%d): Could not map RX descriptor "
3773			    "chain DMA memory!\n", __FILE__, __LINE__);
3774			rc = ENOMEM;
3775			goto bce_dma_alloc_exit;
3776		}
3777
3778		DBPRINT(sc, BCE_INFO_LOAD, "%s(): rx_bd_chain_paddr[%d] = "
3779		    "0x%jX\n", __FUNCTION__, i,
3780		    (uintmax_t) sc->rx_bd_chain_paddr[i]);
3781	}
3782
3783	/*
3784	 * Create a DMA tag for RX mbufs.
3785	 */
3786	if (bce_hdr_split == TRUE)
3787		max_size = ((sc->rx_bd_mbuf_alloc_size < MCLBYTES) ?
3788		    MCLBYTES : sc->rx_bd_mbuf_alloc_size);
3789	else
3790		max_size = MJUM9BYTES;
3791
3792	DBPRINT(sc, BCE_INFO_LOAD, "%s(): Creating rx_mbuf_tag "
3793	    "(max size = 0x%jX)\n", __FUNCTION__, (uintmax_t)max_size);
3794
3795	if (bus_dma_tag_create(sc->parent_tag, BCE_RX_BUF_ALIGN,
3796	    BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
3797	    max_size, 1, max_size, 0, NULL, NULL, &sc->rx_mbuf_tag)) {
3798		BCE_PRINTF("%s(%d): Could not allocate RX mbuf DMA tag!\n",
3799		    __FILE__, __LINE__);
3800		rc = ENOMEM;
3801		goto bce_dma_alloc_exit;
3802	}
3803
3804	/* Create DMA maps for the RX mbuf clusters. */
3805	for (i = 0; i < TOTAL_RX_BD_ALLOC; i++) {
3806		if (bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_NOWAIT,
3807		    &sc->rx_mbuf_map[i])) {
3808			BCE_PRINTF("%s(%d): Unable to create RX mbuf "
3809			    "DMA map!\n", __FILE__, __LINE__);
3810			rc = ENOMEM;
3811			goto bce_dma_alloc_exit;
3812		}
3813	}
3814
3815	if (bce_hdr_split == TRUE) {
3816		/*
3817		 * Create a DMA tag for the page buffer descriptor chain,
3818		 * allocate and clear the memory, and fetch the physical
3819		 * address of the blocks.
3820		 */
3821		if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
3822			    BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR, sc->max_bus_addr,
3823			    NULL, NULL,	BCE_PG_CHAIN_PAGE_SZ, 1, BCE_PG_CHAIN_PAGE_SZ,
3824			    0, NULL, NULL, &sc->pg_bd_chain_tag)) {
3825			BCE_PRINTF("%s(%d): Could not allocate page descriptor "
3826			    "chain DMA tag!\n",	__FILE__, __LINE__);
3827			rc = ENOMEM;
3828			goto bce_dma_alloc_exit;
3829		}
3830
3831		for (i = 0; i < sc->pg_pages; i++) {
3832			if (bus_dmamem_alloc(sc->pg_bd_chain_tag,
3833			    (void **)&sc->pg_bd_chain[i],
3834			    BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
3835			    &sc->pg_bd_chain_map[i])) {
3836				BCE_PRINTF("%s(%d): Could not allocate page "
3837				    "descriptor chain DMA memory!\n",
3838				    __FILE__, __LINE__);
3839				rc = ENOMEM;
3840				goto bce_dma_alloc_exit;
3841			}
3842
3843			error = bus_dmamap_load(sc->pg_bd_chain_tag,
3844			    sc->pg_bd_chain_map[i], sc->pg_bd_chain[i],
3845			    BCE_PG_CHAIN_PAGE_SZ, bce_dma_map_addr,
3846			    &sc->pg_bd_chain_paddr[i], BUS_DMA_NOWAIT);
3847
3848			if (error || sc->pg_bd_chain_paddr[i] == 0) {
3849				BCE_PRINTF("%s(%d): Could not map page descriptor "
3850					"chain DMA memory!\n", __FILE__, __LINE__);
3851				rc = ENOMEM;
3852				goto bce_dma_alloc_exit;
3853			}
3854
3855			DBPRINT(sc, BCE_INFO_LOAD, "%s(): pg_bd_chain_paddr[%d] = "
3856				"0x%jX\n", __FUNCTION__, i,
3857				(uintmax_t) sc->pg_bd_chain_paddr[i]);
3858		}
3859
3860		/*
3861		 * Create a DMA tag for page mbufs.
3862		 */
3863		if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
3864		    sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
3865		    1, MCLBYTES, 0, NULL, NULL, &sc->pg_mbuf_tag)) {
3866			BCE_PRINTF("%s(%d): Could not allocate page mbuf "
3867				"DMA tag!\n", __FILE__, __LINE__);
3868			rc = ENOMEM;
3869			goto bce_dma_alloc_exit;
3870		}
3871
3872		/* Create DMA maps for the page mbuf clusters. */
3873		for (i = 0; i < TOTAL_PG_BD_ALLOC; i++) {
3874			if (bus_dmamap_create(sc->pg_mbuf_tag, BUS_DMA_NOWAIT,
3875				&sc->pg_mbuf_map[i])) {
3876				BCE_PRINTF("%s(%d): Unable to create page mbuf "
3877					"DMA map!\n", __FILE__, __LINE__);
3878				rc = ENOMEM;
3879				goto bce_dma_alloc_exit;
3880			}
3881		}
3882	}
3883
3884bce_dma_alloc_exit:
3885	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
3886	return(rc);
3887}
3888
3889
3890/****************************************************************************/
3891/* Release all resources used by the driver.                                */
3892/*                                                                          */
3893/* Releases all resources acquired by the driver including interrupts,      */
3894/* interrupt handler, interfaces, mutexes, and DMA memory.                  */
3895/*                                                                          */
3896/* Returns:                                                                 */
3897/*   Nothing.                                                               */
3898/****************************************************************************/
3899static void
3900bce_release_resources(struct bce_softc *sc)
3901{
3902	device_t dev;
3903
3904	DBENTER(BCE_VERBOSE_RESET);
3905
3906	dev = sc->bce_dev;
3907
3908	bce_dma_free(sc);
3909
3910	if (sc->bce_intrhand != NULL) {
3911		DBPRINT(sc, BCE_INFO_RESET, "Removing interrupt handler.\n");
3912		bus_teardown_intr(dev, sc->bce_res_irq, sc->bce_intrhand);
3913	}
3914
3915	if (sc->bce_res_irq != NULL) {
3916		DBPRINT(sc, BCE_INFO_RESET, "Releasing IRQ.\n");
3917		bus_release_resource(dev, SYS_RES_IRQ,
3918		    rman_get_rid(sc->bce_res_irq), sc->bce_res_irq);
3919	}
3920
3921	if (sc->bce_flags & (BCE_USING_MSI_FLAG | BCE_USING_MSIX_FLAG)) {
3922		DBPRINT(sc, BCE_INFO_RESET, "Releasing MSI/MSI-X vector.\n");
3923		pci_release_msi(dev);
3924	}
3925
3926	if (sc->bce_res_mem != NULL) {
3927		DBPRINT(sc, BCE_INFO_RESET, "Releasing PCI memory.\n");
3928		    bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0),
3929		    sc->bce_res_mem);
3930	}
3931
3932	if (sc->bce_ifp != NULL) {
3933		DBPRINT(sc, BCE_INFO_RESET, "Releasing IF.\n");
3934		if_free(sc->bce_ifp);
3935	}
3936
3937	if (mtx_initialized(&sc->bce_mtx))
3938		BCE_LOCK_DESTROY(sc);
3939
3940	DBEXIT(BCE_VERBOSE_RESET);
3941}
3942
3943
3944/****************************************************************************/
3945/* Firmware synchronization.                                                */
3946/*                                                                          */
3947/* Before performing certain events such as a chip reset, synchronize with  */
3948/* the firmware first.                                                      */
3949/*                                                                          */
3950/* Returns:                                                                 */
3951/*   0 for success, positive value for failure.                             */
3952/****************************************************************************/
3953static int
3954bce_fw_sync(struct bce_softc *sc, u32 msg_data)
3955{
3956	int i, rc = 0;
3957	u32 val;
3958
3959	DBENTER(BCE_VERBOSE_RESET);
3960
3961	/* Don't waste any time if we've timed out before. */
3962	if (sc->bce_fw_timed_out == TRUE) {
3963		rc = EBUSY;
3964		goto bce_fw_sync_exit;
3965	}
3966
3967	/* Increment the message sequence number. */
3968	sc->bce_fw_wr_seq++;
3969	msg_data |= sc->bce_fw_wr_seq;
3970
3971 	DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "bce_fw_sync(): msg_data = "
3972	    "0x%08X\n",	msg_data);
3973
3974	/* Send the message to the bootcode driver mailbox. */
3975	bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
3976
3977	/* Wait for the bootcode to acknowledge the message. */
3978	for (i = 0; i < FW_ACK_TIME_OUT_MS; i++) {
3979		/* Check for a response in the bootcode firmware mailbox. */
3980		val = bce_shmem_rd(sc, BCE_FW_MB);
3981		if ((val & BCE_FW_MSG_ACK) == (msg_data & BCE_DRV_MSG_SEQ))
3982			break;
3983		DELAY(1000);
3984	}
3985
3986	/* If we've timed out, tell bootcode that we've stopped waiting. */
3987	if (((val & BCE_FW_MSG_ACK) != (msg_data & BCE_DRV_MSG_SEQ)) &&
3988	    ((msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0)) {
3989
3990		BCE_PRINTF("%s(%d): Firmware synchronization timeout! "
3991		    "msg_data = 0x%08X\n", __FILE__, __LINE__, msg_data);
3992
3993		msg_data &= ~BCE_DRV_MSG_CODE;
3994		msg_data |= BCE_DRV_MSG_CODE_FW_TIMEOUT;
3995
3996		bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
3997
3998		sc->bce_fw_timed_out = TRUE;
3999		rc = EBUSY;
4000	}
4001
4002bce_fw_sync_exit:
4003	DBEXIT(BCE_VERBOSE_RESET);
4004	return (rc);
4005}
4006
4007
4008/****************************************************************************/
4009/* Load Receive Virtual 2 Physical (RV2P) processor firmware.               */
4010/*                                                                          */
4011/* Returns:                                                                 */
4012/*   Nothing.                                                               */
4013/****************************************************************************/
4014static void
4015bce_load_rv2p_fw(struct bce_softc *sc, const u32 *rv2p_code,
4016	u32 rv2p_code_len, u32 rv2p_proc)
4017{
4018	int i;
4019	u32 val;
4020
4021	DBENTER(BCE_VERBOSE_RESET);
4022
4023	/* Set the page size used by RV2P. */
4024	if (rv2p_proc == RV2P_PROC2) {
4025		BCE_RV2P_PROC2_CHG_MAX_BD_PAGE(USABLE_RX_BD_PER_PAGE);
4026	}
4027
4028	for (i = 0; i < rv2p_code_len; i += 8) {
4029		REG_WR(sc, BCE_RV2P_INSTR_HIGH, *rv2p_code);
4030		rv2p_code++;
4031		REG_WR(sc, BCE_RV2P_INSTR_LOW, *rv2p_code);
4032		rv2p_code++;
4033
4034		if (rv2p_proc == RV2P_PROC1) {
4035			val = (i / 8) | BCE_RV2P_PROC1_ADDR_CMD_RDWR;
4036			REG_WR(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
4037		}
4038		else {
4039			val = (i / 8) | BCE_RV2P_PROC2_ADDR_CMD_RDWR;
4040			REG_WR(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
4041		}
4042	}
4043
4044	/* Reset the processor, un-stall is done later. */
4045	if (rv2p_proc == RV2P_PROC1) {
4046		REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC1_RESET);
4047	}
4048	else {
4049		REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC2_RESET);
4050	}
4051
4052	DBEXIT(BCE_VERBOSE_RESET);
4053}
4054
4055
4056/****************************************************************************/
4057/* Load RISC processor firmware.                                            */
4058/*                                                                          */
4059/* Loads firmware from the file if_bcefw.h into the scratchpad memory       */
4060/* associated with a particular processor.                                  */
4061/*                                                                          */
4062/* Returns:                                                                 */
4063/*   Nothing.                                                               */
4064/****************************************************************************/
4065static void
4066bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
4067	struct fw_info *fw)
4068{
4069	u32 offset;
4070
4071	DBENTER(BCE_VERBOSE_RESET);
4072
4073    bce_halt_cpu(sc, cpu_reg);
4074
4075	/* Load the Text area. */
4076	offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
4077	if (fw->text) {
4078		int j;
4079
4080		for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
4081			REG_WR_IND(sc, offset, fw->text[j]);
4082	        }
4083	}
4084
4085	/* Load the Data area. */
4086	offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
4087	if (fw->data) {
4088		int j;
4089
4090		for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
4091			REG_WR_IND(sc, offset, fw->data[j]);
4092		}
4093	}
4094
4095	/* Load the SBSS area. */
4096	offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
4097	if (fw->sbss) {
4098		int j;
4099
4100		for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
4101			REG_WR_IND(sc, offset, fw->sbss[j]);
4102		}
4103	}
4104
4105	/* Load the BSS area. */
4106	offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
4107	if (fw->bss) {
4108		int j;
4109
4110		for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
4111			REG_WR_IND(sc, offset, fw->bss[j]);
4112		}
4113	}
4114
4115	/* Load the Read-Only area. */
4116	offset = cpu_reg->spad_base +
4117		(fw->rodata_addr - cpu_reg->mips_view_base);
4118	if (fw->rodata) {
4119		int j;
4120
4121		for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
4122			REG_WR_IND(sc, offset, fw->rodata[j]);
4123		}
4124	}
4125
4126	/* Clear the pre-fetch instruction and set the FW start address. */
4127	REG_WR_IND(sc, cpu_reg->inst, 0);
4128	REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
4129
4130	DBEXIT(BCE_VERBOSE_RESET);
4131}
4132
4133
4134/****************************************************************************/
4135/* Starts the RISC processor.                                               */
4136/*                                                                          */
4137/* Assumes the CPU starting address has already been set.                   */
4138/*                                                                          */
4139/* Returns:                                                                 */
4140/*   Nothing.                                                               */
4141/****************************************************************************/
4142static void
4143bce_start_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
4144{
4145	u32 val;
4146
4147	DBENTER(BCE_VERBOSE_RESET);
4148
4149	/* Start the CPU. */
4150	val = REG_RD_IND(sc, cpu_reg->mode);
4151	val &= ~cpu_reg->mode_value_halt;
4152	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
4153	REG_WR_IND(sc, cpu_reg->mode, val);
4154
4155	DBEXIT(BCE_VERBOSE_RESET);
4156}
4157
4158
4159/****************************************************************************/
4160/* Halts the RISC processor.                                                */
4161/*                                                                          */
4162/* Returns:                                                                 */
4163/*   Nothing.                                                               */
4164/****************************************************************************/
4165static void
4166bce_halt_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
4167{
4168	u32 val;
4169
4170	DBENTER(BCE_VERBOSE_RESET);
4171
4172	/* Halt the CPU. */
4173	val = REG_RD_IND(sc, cpu_reg->mode);
4174	val |= cpu_reg->mode_value_halt;
4175	REG_WR_IND(sc, cpu_reg->mode, val);
4176	REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
4177
4178	DBEXIT(BCE_VERBOSE_RESET);
4179}
4180
4181
4182/****************************************************************************/
4183/* Initialize the RX CPU.                                                   */
4184/*                                                                          */
4185/* Returns:                                                                 */
4186/*   Nothing.                                                               */
4187/****************************************************************************/
4188static void
4189bce_start_rxp_cpu(struct bce_softc *sc)
4190{
4191	struct cpu_reg cpu_reg;
4192
4193	DBENTER(BCE_VERBOSE_RESET);
4194
4195	cpu_reg.mode = BCE_RXP_CPU_MODE;
4196	cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
4197	cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
4198	cpu_reg.state = BCE_RXP_CPU_STATE;
4199	cpu_reg.state_value_clear = 0xffffff;
4200	cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
4201	cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
4202	cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
4203	cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
4204	cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
4205	cpu_reg.spad_base = BCE_RXP_SCRATCH;
4206	cpu_reg.mips_view_base = 0x8000000;
4207
4208	DBPRINT(sc, BCE_INFO_RESET, "Starting RX firmware.\n");
4209	bce_start_cpu(sc, &cpu_reg);
4210
4211	DBEXIT(BCE_VERBOSE_RESET);
4212}
4213
4214
4215/****************************************************************************/
4216/* Initialize the RX CPU.                                                   */
4217/*                                                                          */
4218/* Returns:                                                                 */
4219/*   Nothing.                                                               */
4220/****************************************************************************/
4221static void
4222bce_init_rxp_cpu(struct bce_softc *sc)
4223{
4224	struct cpu_reg cpu_reg;
4225	struct fw_info fw;
4226
4227	DBENTER(BCE_VERBOSE_RESET);
4228
4229	cpu_reg.mode = BCE_RXP_CPU_MODE;
4230	cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
4231	cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
4232	cpu_reg.state = BCE_RXP_CPU_STATE;
4233	cpu_reg.state_value_clear = 0xffffff;
4234	cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
4235	cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
4236	cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
4237	cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
4238	cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
4239	cpu_reg.spad_base = BCE_RXP_SCRATCH;
4240	cpu_reg.mips_view_base = 0x8000000;
4241
4242	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4243 		fw.ver_major = bce_RXP_b09FwReleaseMajor;
4244		fw.ver_minor = bce_RXP_b09FwReleaseMinor;
4245		fw.ver_fix = bce_RXP_b09FwReleaseFix;
4246		fw.start_addr = bce_RXP_b09FwStartAddr;
4247
4248		fw.text_addr = bce_RXP_b09FwTextAddr;
4249		fw.text_len = bce_RXP_b09FwTextLen;
4250		fw.text_index = 0;
4251		fw.text = bce_RXP_b09FwText;
4252
4253		fw.data_addr = bce_RXP_b09FwDataAddr;
4254		fw.data_len = bce_RXP_b09FwDataLen;
4255		fw.data_index = 0;
4256		fw.data = bce_RXP_b09FwData;
4257
4258		fw.sbss_addr = bce_RXP_b09FwSbssAddr;
4259		fw.sbss_len = bce_RXP_b09FwSbssLen;
4260		fw.sbss_index = 0;
4261		fw.sbss = bce_RXP_b09FwSbss;
4262
4263		fw.bss_addr = bce_RXP_b09FwBssAddr;
4264		fw.bss_len = bce_RXP_b09FwBssLen;
4265		fw.bss_index = 0;
4266		fw.bss = bce_RXP_b09FwBss;
4267
4268		fw.rodata_addr = bce_RXP_b09FwRodataAddr;
4269		fw.rodata_len = bce_RXP_b09FwRodataLen;
4270		fw.rodata_index = 0;
4271		fw.rodata = bce_RXP_b09FwRodata;
4272	} else {
4273		fw.ver_major = bce_RXP_b06FwReleaseMajor;
4274		fw.ver_minor = bce_RXP_b06FwReleaseMinor;
4275		fw.ver_fix = bce_RXP_b06FwReleaseFix;
4276		fw.start_addr = bce_RXP_b06FwStartAddr;
4277
4278		fw.text_addr = bce_RXP_b06FwTextAddr;
4279		fw.text_len = bce_RXP_b06FwTextLen;
4280		fw.text_index = 0;
4281		fw.text = bce_RXP_b06FwText;
4282
4283		fw.data_addr = bce_RXP_b06FwDataAddr;
4284		fw.data_len = bce_RXP_b06FwDataLen;
4285		fw.data_index = 0;
4286		fw.data = bce_RXP_b06FwData;
4287
4288		fw.sbss_addr = bce_RXP_b06FwSbssAddr;
4289		fw.sbss_len = bce_RXP_b06FwSbssLen;
4290		fw.sbss_index = 0;
4291		fw.sbss = bce_RXP_b06FwSbss;
4292
4293		fw.bss_addr = bce_RXP_b06FwBssAddr;
4294		fw.bss_len = bce_RXP_b06FwBssLen;
4295		fw.bss_index = 0;
4296		fw.bss = bce_RXP_b06FwBss;
4297
4298		fw.rodata_addr = bce_RXP_b06FwRodataAddr;
4299		fw.rodata_len = bce_RXP_b06FwRodataLen;
4300		fw.rodata_index = 0;
4301		fw.rodata = bce_RXP_b06FwRodata;
4302	}
4303
4304	DBPRINT(sc, BCE_INFO_RESET, "Loading RX firmware.\n");
4305	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4306
4307    /* Delay RXP start until initialization is complete. */
4308
4309	DBEXIT(BCE_VERBOSE_RESET);
4310}
4311
4312
4313/****************************************************************************/
4314/* Initialize the TX CPU.                                                   */
4315/*                                                                          */
4316/* Returns:                                                                 */
4317/*   Nothing.                                                               */
4318/****************************************************************************/
4319static void
4320bce_init_txp_cpu(struct bce_softc *sc)
4321{
4322	struct cpu_reg cpu_reg;
4323	struct fw_info fw;
4324
4325	DBENTER(BCE_VERBOSE_RESET);
4326
4327	cpu_reg.mode = BCE_TXP_CPU_MODE;
4328	cpu_reg.mode_value_halt = BCE_TXP_CPU_MODE_SOFT_HALT;
4329	cpu_reg.mode_value_sstep = BCE_TXP_CPU_MODE_STEP_ENA;
4330	cpu_reg.state = BCE_TXP_CPU_STATE;
4331	cpu_reg.state_value_clear = 0xffffff;
4332	cpu_reg.gpr0 = BCE_TXP_CPU_REG_FILE;
4333	cpu_reg.evmask = BCE_TXP_CPU_EVENT_MASK;
4334	cpu_reg.pc = BCE_TXP_CPU_PROGRAM_COUNTER;
4335	cpu_reg.inst = BCE_TXP_CPU_INSTRUCTION;
4336	cpu_reg.bp = BCE_TXP_CPU_HW_BREAKPOINT;
4337	cpu_reg.spad_base = BCE_TXP_SCRATCH;
4338	cpu_reg.mips_view_base = 0x8000000;
4339
4340	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4341		fw.ver_major = bce_TXP_b09FwReleaseMajor;
4342		fw.ver_minor = bce_TXP_b09FwReleaseMinor;
4343		fw.ver_fix = bce_TXP_b09FwReleaseFix;
4344		fw.start_addr = bce_TXP_b09FwStartAddr;
4345
4346		fw.text_addr = bce_TXP_b09FwTextAddr;
4347		fw.text_len = bce_TXP_b09FwTextLen;
4348		fw.text_index = 0;
4349		fw.text = bce_TXP_b09FwText;
4350
4351		fw.data_addr = bce_TXP_b09FwDataAddr;
4352		fw.data_len = bce_TXP_b09FwDataLen;
4353		fw.data_index = 0;
4354		fw.data = bce_TXP_b09FwData;
4355
4356		fw.sbss_addr = bce_TXP_b09FwSbssAddr;
4357		fw.sbss_len = bce_TXP_b09FwSbssLen;
4358		fw.sbss_index = 0;
4359		fw.sbss = bce_TXP_b09FwSbss;
4360
4361		fw.bss_addr = bce_TXP_b09FwBssAddr;
4362		fw.bss_len = bce_TXP_b09FwBssLen;
4363		fw.bss_index = 0;
4364		fw.bss = bce_TXP_b09FwBss;
4365
4366		fw.rodata_addr = bce_TXP_b09FwRodataAddr;
4367		fw.rodata_len = bce_TXP_b09FwRodataLen;
4368		fw.rodata_index = 0;
4369		fw.rodata = bce_TXP_b09FwRodata;
4370	} else {
4371		fw.ver_major = bce_TXP_b06FwReleaseMajor;
4372		fw.ver_minor = bce_TXP_b06FwReleaseMinor;
4373		fw.ver_fix = bce_TXP_b06FwReleaseFix;
4374		fw.start_addr = bce_TXP_b06FwStartAddr;
4375
4376		fw.text_addr = bce_TXP_b06FwTextAddr;
4377		fw.text_len = bce_TXP_b06FwTextLen;
4378		fw.text_index = 0;
4379		fw.text = bce_TXP_b06FwText;
4380
4381		fw.data_addr = bce_TXP_b06FwDataAddr;
4382		fw.data_len = bce_TXP_b06FwDataLen;
4383		fw.data_index = 0;
4384		fw.data = bce_TXP_b06FwData;
4385
4386		fw.sbss_addr = bce_TXP_b06FwSbssAddr;
4387		fw.sbss_len = bce_TXP_b06FwSbssLen;
4388		fw.sbss_index = 0;
4389		fw.sbss = bce_TXP_b06FwSbss;
4390
4391		fw.bss_addr = bce_TXP_b06FwBssAddr;
4392		fw.bss_len = bce_TXP_b06FwBssLen;
4393		fw.bss_index = 0;
4394		fw.bss = bce_TXP_b06FwBss;
4395
4396		fw.rodata_addr = bce_TXP_b06FwRodataAddr;
4397		fw.rodata_len = bce_TXP_b06FwRodataLen;
4398		fw.rodata_index = 0;
4399		fw.rodata = bce_TXP_b06FwRodata;
4400	}
4401
4402	DBPRINT(sc, BCE_INFO_RESET, "Loading TX firmware.\n");
4403	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4404    bce_start_cpu(sc, &cpu_reg);
4405
4406	DBEXIT(BCE_VERBOSE_RESET);
4407}
4408
4409
4410/****************************************************************************/
4411/* Initialize the TPAT CPU.                                                 */
4412/*                                                                          */
4413/* Returns:                                                                 */
4414/*   Nothing.                                                               */
4415/****************************************************************************/
4416static void
4417bce_init_tpat_cpu(struct bce_softc *sc)
4418{
4419	struct cpu_reg cpu_reg;
4420	struct fw_info fw;
4421
4422	DBENTER(BCE_VERBOSE_RESET);
4423
4424	cpu_reg.mode = BCE_TPAT_CPU_MODE;
4425	cpu_reg.mode_value_halt = BCE_TPAT_CPU_MODE_SOFT_HALT;
4426	cpu_reg.mode_value_sstep = BCE_TPAT_CPU_MODE_STEP_ENA;
4427	cpu_reg.state = BCE_TPAT_CPU_STATE;
4428	cpu_reg.state_value_clear = 0xffffff;
4429	cpu_reg.gpr0 = BCE_TPAT_CPU_REG_FILE;
4430	cpu_reg.evmask = BCE_TPAT_CPU_EVENT_MASK;
4431	cpu_reg.pc = BCE_TPAT_CPU_PROGRAM_COUNTER;
4432	cpu_reg.inst = BCE_TPAT_CPU_INSTRUCTION;
4433	cpu_reg.bp = BCE_TPAT_CPU_HW_BREAKPOINT;
4434	cpu_reg.spad_base = BCE_TPAT_SCRATCH;
4435	cpu_reg.mips_view_base = 0x8000000;
4436
4437	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4438		fw.ver_major = bce_TPAT_b09FwReleaseMajor;
4439		fw.ver_minor = bce_TPAT_b09FwReleaseMinor;
4440		fw.ver_fix = bce_TPAT_b09FwReleaseFix;
4441		fw.start_addr = bce_TPAT_b09FwStartAddr;
4442
4443		fw.text_addr = bce_TPAT_b09FwTextAddr;
4444		fw.text_len = bce_TPAT_b09FwTextLen;
4445		fw.text_index = 0;
4446		fw.text = bce_TPAT_b09FwText;
4447
4448		fw.data_addr = bce_TPAT_b09FwDataAddr;
4449		fw.data_len = bce_TPAT_b09FwDataLen;
4450		fw.data_index = 0;
4451		fw.data = bce_TPAT_b09FwData;
4452
4453		fw.sbss_addr = bce_TPAT_b09FwSbssAddr;
4454		fw.sbss_len = bce_TPAT_b09FwSbssLen;
4455		fw.sbss_index = 0;
4456		fw.sbss = bce_TPAT_b09FwSbss;
4457
4458		fw.bss_addr = bce_TPAT_b09FwBssAddr;
4459		fw.bss_len = bce_TPAT_b09FwBssLen;
4460		fw.bss_index = 0;
4461		fw.bss = bce_TPAT_b09FwBss;
4462
4463		fw.rodata_addr = bce_TPAT_b09FwRodataAddr;
4464		fw.rodata_len = bce_TPAT_b09FwRodataLen;
4465		fw.rodata_index = 0;
4466		fw.rodata = bce_TPAT_b09FwRodata;
4467	} else {
4468		fw.ver_major = bce_TPAT_b06FwReleaseMajor;
4469		fw.ver_minor = bce_TPAT_b06FwReleaseMinor;
4470		fw.ver_fix = bce_TPAT_b06FwReleaseFix;
4471		fw.start_addr = bce_TPAT_b06FwStartAddr;
4472
4473		fw.text_addr = bce_TPAT_b06FwTextAddr;
4474		fw.text_len = bce_TPAT_b06FwTextLen;
4475		fw.text_index = 0;
4476		fw.text = bce_TPAT_b06FwText;
4477
4478		fw.data_addr = bce_TPAT_b06FwDataAddr;
4479		fw.data_len = bce_TPAT_b06FwDataLen;
4480		fw.data_index = 0;
4481		fw.data = bce_TPAT_b06FwData;
4482
4483		fw.sbss_addr = bce_TPAT_b06FwSbssAddr;
4484		fw.sbss_len = bce_TPAT_b06FwSbssLen;
4485		fw.sbss_index = 0;
4486		fw.sbss = bce_TPAT_b06FwSbss;
4487
4488		fw.bss_addr = bce_TPAT_b06FwBssAddr;
4489		fw.bss_len = bce_TPAT_b06FwBssLen;
4490		fw.bss_index = 0;
4491		fw.bss = bce_TPAT_b06FwBss;
4492
4493		fw.rodata_addr = bce_TPAT_b06FwRodataAddr;
4494		fw.rodata_len = bce_TPAT_b06FwRodataLen;
4495		fw.rodata_index = 0;
4496		fw.rodata = bce_TPAT_b06FwRodata;
4497	}
4498
4499	DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n");
4500	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4501	bce_start_cpu(sc, &cpu_reg);
4502
4503	DBEXIT(BCE_VERBOSE_RESET);
4504}
4505
4506
4507/****************************************************************************/
4508/* Initialize the CP CPU.                                                   */
4509/*                                                                          */
4510/* Returns:                                                                 */
4511/*   Nothing.                                                               */
4512/****************************************************************************/
4513static void
4514bce_init_cp_cpu(struct bce_softc *sc)
4515{
4516	struct cpu_reg cpu_reg;
4517	struct fw_info fw;
4518
4519	DBENTER(BCE_VERBOSE_RESET);
4520
4521	cpu_reg.mode = BCE_CP_CPU_MODE;
4522	cpu_reg.mode_value_halt = BCE_CP_CPU_MODE_SOFT_HALT;
4523	cpu_reg.mode_value_sstep = BCE_CP_CPU_MODE_STEP_ENA;
4524	cpu_reg.state = BCE_CP_CPU_STATE;
4525	cpu_reg.state_value_clear = 0xffffff;
4526	cpu_reg.gpr0 = BCE_CP_CPU_REG_FILE;
4527	cpu_reg.evmask = BCE_CP_CPU_EVENT_MASK;
4528	cpu_reg.pc = BCE_CP_CPU_PROGRAM_COUNTER;
4529	cpu_reg.inst = BCE_CP_CPU_INSTRUCTION;
4530	cpu_reg.bp = BCE_CP_CPU_HW_BREAKPOINT;
4531	cpu_reg.spad_base = BCE_CP_SCRATCH;
4532	cpu_reg.mips_view_base = 0x8000000;
4533
4534	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4535		fw.ver_major = bce_CP_b09FwReleaseMajor;
4536		fw.ver_minor = bce_CP_b09FwReleaseMinor;
4537		fw.ver_fix = bce_CP_b09FwReleaseFix;
4538		fw.start_addr = bce_CP_b09FwStartAddr;
4539
4540		fw.text_addr = bce_CP_b09FwTextAddr;
4541		fw.text_len = bce_CP_b09FwTextLen;
4542		fw.text_index = 0;
4543		fw.text = bce_CP_b09FwText;
4544
4545		fw.data_addr = bce_CP_b09FwDataAddr;
4546		fw.data_len = bce_CP_b09FwDataLen;
4547		fw.data_index = 0;
4548		fw.data = bce_CP_b09FwData;
4549
4550		fw.sbss_addr = bce_CP_b09FwSbssAddr;
4551		fw.sbss_len = bce_CP_b09FwSbssLen;
4552		fw.sbss_index = 0;
4553		fw.sbss = bce_CP_b09FwSbss;
4554
4555		fw.bss_addr = bce_CP_b09FwBssAddr;
4556		fw.bss_len = bce_CP_b09FwBssLen;
4557		fw.bss_index = 0;
4558		fw.bss = bce_CP_b09FwBss;
4559
4560		fw.rodata_addr = bce_CP_b09FwRodataAddr;
4561		fw.rodata_len = bce_CP_b09FwRodataLen;
4562		fw.rodata_index = 0;
4563		fw.rodata = bce_CP_b09FwRodata;
4564	} else {
4565		fw.ver_major = bce_CP_b06FwReleaseMajor;
4566		fw.ver_minor = bce_CP_b06FwReleaseMinor;
4567		fw.ver_fix = bce_CP_b06FwReleaseFix;
4568		fw.start_addr = bce_CP_b06FwStartAddr;
4569
4570		fw.text_addr = bce_CP_b06FwTextAddr;
4571		fw.text_len = bce_CP_b06FwTextLen;
4572		fw.text_index = 0;
4573		fw.text = bce_CP_b06FwText;
4574
4575		fw.data_addr = bce_CP_b06FwDataAddr;
4576		fw.data_len = bce_CP_b06FwDataLen;
4577		fw.data_index = 0;
4578		fw.data = bce_CP_b06FwData;
4579
4580		fw.sbss_addr = bce_CP_b06FwSbssAddr;
4581		fw.sbss_len = bce_CP_b06FwSbssLen;
4582		fw.sbss_index = 0;
4583		fw.sbss = bce_CP_b06FwSbss;
4584
4585		fw.bss_addr = bce_CP_b06FwBssAddr;
4586		fw.bss_len = bce_CP_b06FwBssLen;
4587		fw.bss_index = 0;
4588		fw.bss = bce_CP_b06FwBss;
4589
4590		fw.rodata_addr = bce_CP_b06FwRodataAddr;
4591		fw.rodata_len = bce_CP_b06FwRodataLen;
4592		fw.rodata_index = 0;
4593		fw.rodata = bce_CP_b06FwRodata;
4594	}
4595
4596	DBPRINT(sc, BCE_INFO_RESET, "Loading CP firmware.\n");
4597	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4598	bce_start_cpu(sc, &cpu_reg);
4599
4600	DBEXIT(BCE_VERBOSE_RESET);
4601}
4602
4603
4604/****************************************************************************/
4605/* Initialize the COM CPU.                                                 */
4606/*                                                                          */
4607/* Returns:                                                                 */
4608/*   Nothing.                                                               */
4609/****************************************************************************/
4610static void
4611bce_init_com_cpu(struct bce_softc *sc)
4612{
4613	struct cpu_reg cpu_reg;
4614	struct fw_info fw;
4615
4616	DBENTER(BCE_VERBOSE_RESET);
4617
4618	cpu_reg.mode = BCE_COM_CPU_MODE;
4619	cpu_reg.mode_value_halt = BCE_COM_CPU_MODE_SOFT_HALT;
4620	cpu_reg.mode_value_sstep = BCE_COM_CPU_MODE_STEP_ENA;
4621	cpu_reg.state = BCE_COM_CPU_STATE;
4622	cpu_reg.state_value_clear = 0xffffff;
4623	cpu_reg.gpr0 = BCE_COM_CPU_REG_FILE;
4624	cpu_reg.evmask = BCE_COM_CPU_EVENT_MASK;
4625	cpu_reg.pc = BCE_COM_CPU_PROGRAM_COUNTER;
4626	cpu_reg.inst = BCE_COM_CPU_INSTRUCTION;
4627	cpu_reg.bp = BCE_COM_CPU_HW_BREAKPOINT;
4628	cpu_reg.spad_base = BCE_COM_SCRATCH;
4629	cpu_reg.mips_view_base = 0x8000000;
4630
4631	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4632		fw.ver_major = bce_COM_b09FwReleaseMajor;
4633		fw.ver_minor = bce_COM_b09FwReleaseMinor;
4634		fw.ver_fix = bce_COM_b09FwReleaseFix;
4635		fw.start_addr = bce_COM_b09FwStartAddr;
4636
4637		fw.text_addr = bce_COM_b09FwTextAddr;
4638		fw.text_len = bce_COM_b09FwTextLen;
4639		fw.text_index = 0;
4640		fw.text = bce_COM_b09FwText;
4641
4642		fw.data_addr = bce_COM_b09FwDataAddr;
4643		fw.data_len = bce_COM_b09FwDataLen;
4644		fw.data_index = 0;
4645		fw.data = bce_COM_b09FwData;
4646
4647		fw.sbss_addr = bce_COM_b09FwSbssAddr;
4648		fw.sbss_len = bce_COM_b09FwSbssLen;
4649		fw.sbss_index = 0;
4650		fw.sbss = bce_COM_b09FwSbss;
4651
4652		fw.bss_addr = bce_COM_b09FwBssAddr;
4653		fw.bss_len = bce_COM_b09FwBssLen;
4654		fw.bss_index = 0;
4655		fw.bss = bce_COM_b09FwBss;
4656
4657		fw.rodata_addr = bce_COM_b09FwRodataAddr;
4658		fw.rodata_len = bce_COM_b09FwRodataLen;
4659		fw.rodata_index = 0;
4660		fw.rodata = bce_COM_b09FwRodata;
4661	} else {
4662		fw.ver_major = bce_COM_b06FwReleaseMajor;
4663		fw.ver_minor = bce_COM_b06FwReleaseMinor;
4664		fw.ver_fix = bce_COM_b06FwReleaseFix;
4665		fw.start_addr = bce_COM_b06FwStartAddr;
4666
4667		fw.text_addr = bce_COM_b06FwTextAddr;
4668		fw.text_len = bce_COM_b06FwTextLen;
4669		fw.text_index = 0;
4670		fw.text = bce_COM_b06FwText;
4671
4672		fw.data_addr = bce_COM_b06FwDataAddr;
4673		fw.data_len = bce_COM_b06FwDataLen;
4674		fw.data_index = 0;
4675		fw.data = bce_COM_b06FwData;
4676
4677		fw.sbss_addr = bce_COM_b06FwSbssAddr;
4678		fw.sbss_len = bce_COM_b06FwSbssLen;
4679		fw.sbss_index = 0;
4680		fw.sbss = bce_COM_b06FwSbss;
4681
4682		fw.bss_addr = bce_COM_b06FwBssAddr;
4683		fw.bss_len = bce_COM_b06FwBssLen;
4684		fw.bss_index = 0;
4685		fw.bss = bce_COM_b06FwBss;
4686
4687		fw.rodata_addr = bce_COM_b06FwRodataAddr;
4688		fw.rodata_len = bce_COM_b06FwRodataLen;
4689		fw.rodata_index = 0;
4690		fw.rodata = bce_COM_b06FwRodata;
4691	}
4692
4693	DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n");
4694	bce_load_cpu_fw(sc, &cpu_reg, &fw);
4695	bce_start_cpu(sc, &cpu_reg);
4696
4697	DBEXIT(BCE_VERBOSE_RESET);
4698}
4699
4700
4701/****************************************************************************/
4702/* Initialize the RV2P, RX, TX, TPAT, COM, and CP CPUs.                     */
4703/*                                                                          */
4704/* Loads the firmware for each CPU and starts the CPU.                      */
4705/*                                                                          */
4706/* Returns:                                                                 */
4707/*   Nothing.                                                               */
4708/****************************************************************************/
4709static void
4710bce_init_cpus(struct bce_softc *sc)
4711{
4712	DBENTER(BCE_VERBOSE_RESET);
4713
4714	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4715
4716		if ((BCE_CHIP_REV(sc) == BCE_CHIP_REV_Ax)) {
4717			bce_load_rv2p_fw(sc, bce_xi90_rv2p_proc1,
4718			    sizeof(bce_xi90_rv2p_proc1), RV2P_PROC1);
4719			bce_load_rv2p_fw(sc, bce_xi90_rv2p_proc2,
4720			    sizeof(bce_xi90_rv2p_proc2), RV2P_PROC2);
4721		} else {
4722			bce_load_rv2p_fw(sc, bce_xi_rv2p_proc1,
4723			    sizeof(bce_xi_rv2p_proc1), RV2P_PROC1);
4724			bce_load_rv2p_fw(sc, bce_xi_rv2p_proc2,
4725			    sizeof(bce_xi_rv2p_proc2), RV2P_PROC2);
4726		}
4727
4728	} else {
4729		bce_load_rv2p_fw(sc, bce_rv2p_proc1,
4730		    sizeof(bce_rv2p_proc1), RV2P_PROC1);
4731		bce_load_rv2p_fw(sc, bce_rv2p_proc2,
4732		    sizeof(bce_rv2p_proc2), RV2P_PROC2);
4733	}
4734
4735	bce_init_rxp_cpu(sc);
4736	bce_init_txp_cpu(sc);
4737	bce_init_tpat_cpu(sc);
4738	bce_init_com_cpu(sc);
4739	bce_init_cp_cpu(sc);
4740
4741	DBEXIT(BCE_VERBOSE_RESET);
4742}
4743
4744
4745/****************************************************************************/
4746/* Initialize context memory.                                               */
4747/*                                                                          */
4748/* Clears the memory associated with each Context ID (CID).                 */
4749/*                                                                          */
4750/* Returns:                                                                 */
4751/*   Nothing.                                                               */
4752/****************************************************************************/
4753static int
4754bce_init_ctx(struct bce_softc *sc)
4755{
4756	u32 offset, val, vcid_addr;
4757	int i, j, rc, retry_cnt;
4758
4759	rc = 0;
4760	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
4761
4762	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
4763		retry_cnt = CTX_INIT_RETRY_COUNT;
4764
4765		DBPRINT(sc, BCE_INFO_CTX, "Initializing 5709 context.\n");
4766
4767		/*
4768		 * BCM5709 context memory may be cached
4769		 * in host memory so prepare the host memory
4770		 * for access.
4771		 */
4772		val = BCE_CTX_COMMAND_ENABLED |
4773		    BCE_CTX_COMMAND_MEM_INIT | (1 << 12);
4774		val |= (BCM_PAGE_BITS - 8) << 16;
4775		REG_WR(sc, BCE_CTX_COMMAND, val);
4776
4777		/* Wait for mem init command to complete. */
4778		for (i = 0; i < retry_cnt; i++) {
4779			val = REG_RD(sc, BCE_CTX_COMMAND);
4780			if (!(val & BCE_CTX_COMMAND_MEM_INIT))
4781				break;
4782			DELAY(2);
4783		}
4784		if ((val & BCE_CTX_COMMAND_MEM_INIT) != 0) {
4785			BCE_PRINTF("%s(): Context memory initialization failed!\n",
4786			    __FUNCTION__);
4787			rc = EBUSY;
4788			goto init_ctx_fail;
4789		}
4790
4791		for (i = 0; i < sc->ctx_pages; i++) {
4792			/* Set the physical address of the context memory. */
4793			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA0,
4794			    BCE_ADDR_LO(sc->ctx_paddr[i] & 0xfffffff0) |
4795			    BCE_CTX_HOST_PAGE_TBL_DATA0_VALID);
4796			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA1,
4797			    BCE_ADDR_HI(sc->ctx_paddr[i]));
4798			REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_CTRL, i |
4799			    BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
4800
4801			/* Verify the context memory write was successful. */
4802			for (j = 0; j < retry_cnt; j++) {
4803				val = REG_RD(sc, BCE_CTX_HOST_PAGE_TBL_CTRL);
4804				if ((val &
4805				    BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) == 0)
4806					break;
4807				DELAY(5);
4808			}
4809			if ((val & BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) != 0) {
4810				BCE_PRINTF("%s(): Failed to initialize "
4811				    "context page %d!\n", __FUNCTION__, i);
4812				rc = EBUSY;
4813				goto init_ctx_fail;
4814			}
4815		}
4816	} else {
4817
4818		DBPRINT(sc, BCE_INFO, "Initializing 5706/5708 context.\n");
4819
4820		/*
4821		 * For the 5706/5708, context memory is local to
4822		 * the controller, so initialize the controller
4823		 * context memory.
4824		 */
4825
4826		vcid_addr = GET_CID_ADDR(96);
4827		while (vcid_addr) {
4828
4829			vcid_addr -= PHY_CTX_SIZE;
4830
4831			REG_WR(sc, BCE_CTX_VIRT_ADDR, 0);
4832			REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
4833
4834			for(offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
4835				CTX_WR(sc, 0x00, offset, 0);
4836			}
4837
4838			REG_WR(sc, BCE_CTX_VIRT_ADDR, vcid_addr);
4839			REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
4840		}
4841
4842	}
4843init_ctx_fail:
4844	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
4845	return (rc);
4846}
4847
4848
4849/****************************************************************************/
4850/* Fetch the permanent MAC address of the controller.                       */
4851/*                                                                          */
4852/* Returns:                                                                 */
4853/*   Nothing.                                                               */
4854/****************************************************************************/
4855static void
4856bce_get_mac_addr(struct bce_softc *sc)
4857{
4858	u32 mac_lo = 0, mac_hi = 0;
4859
4860	DBENTER(BCE_VERBOSE_RESET);
4861
4862	/*
4863	 * The NetXtreme II bootcode populates various NIC
4864	 * power-on and runtime configuration items in a
4865	 * shared memory area.  The factory configured MAC
4866	 * address is available from both NVRAM and the
4867	 * shared memory area so we'll read the value from
4868	 * shared memory for speed.
4869	 */
4870
4871	mac_hi = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_UPPER);
4872	mac_lo = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_LOWER);
4873
4874	if ((mac_lo == 0) && (mac_hi == 0)) {
4875		BCE_PRINTF("%s(%d): Invalid Ethernet address!\n",
4876		    __FILE__, __LINE__);
4877	} else {
4878		sc->eaddr[0] = (u_char)(mac_hi >> 8);
4879		sc->eaddr[1] = (u_char)(mac_hi >> 0);
4880		sc->eaddr[2] = (u_char)(mac_lo >> 24);
4881		sc->eaddr[3] = (u_char)(mac_lo >> 16);
4882		sc->eaddr[4] = (u_char)(mac_lo >> 8);
4883		sc->eaddr[5] = (u_char)(mac_lo >> 0);
4884	}
4885
4886	DBPRINT(sc, BCE_INFO_MISC, "Permanent Ethernet "
4887	    "address = %6D\n", sc->eaddr, ":");
4888	DBEXIT(BCE_VERBOSE_RESET);
4889}
4890
4891
4892/****************************************************************************/
4893/* Program the MAC address.                                                 */
4894/*                                                                          */
4895/* Returns:                                                                 */
4896/*   Nothing.                                                               */
4897/****************************************************************************/
4898static void
4899bce_set_mac_addr(struct bce_softc *sc)
4900{
4901	u32 val;
4902	u8 *mac_addr = sc->eaddr;
4903
4904	/* ToDo: Add support for setting multiple MAC addresses. */
4905
4906	DBENTER(BCE_VERBOSE_RESET);
4907	DBPRINT(sc, BCE_INFO_MISC, "Setting Ethernet address = "
4908	    "%6D\n", sc->eaddr, ":");
4909
4910	val = (mac_addr[0] << 8) | mac_addr[1];
4911
4912	REG_WR(sc, BCE_EMAC_MAC_MATCH0, val);
4913
4914	val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
4915	    (mac_addr[4] << 8) | mac_addr[5];
4916
4917	REG_WR(sc, BCE_EMAC_MAC_MATCH1, val);
4918
4919	DBEXIT(BCE_VERBOSE_RESET);
4920}
4921
4922
4923/****************************************************************************/
4924/* Stop the controller.                                                     */
4925/*                                                                          */
4926/* Returns:                                                                 */
4927/*   Nothing.                                                               */
4928/****************************************************************************/
4929static void
4930bce_stop(struct bce_softc *sc)
4931{
4932	struct ifnet *ifp;
4933
4934	DBENTER(BCE_VERBOSE_RESET);
4935
4936	BCE_LOCK_ASSERT(sc);
4937
4938	ifp = sc->bce_ifp;
4939
4940	callout_stop(&sc->bce_tick_callout);
4941
4942	/* Disable the transmit/receive blocks. */
4943	REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS, BCE_MISC_ENABLE_CLR_DEFAULT);
4944	REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
4945	DELAY(20);
4946
4947	bce_disable_intr(sc);
4948
4949	/* Free RX buffers. */
4950	if (bce_hdr_split == TRUE) {
4951		bce_free_pg_chain(sc);
4952	}
4953	bce_free_rx_chain(sc);
4954
4955	/* Free TX buffers. */
4956	bce_free_tx_chain(sc);
4957
4958	sc->watchdog_timer = 0;
4959
4960	sc->bce_link_up = FALSE;
4961
4962	ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
4963
4964	DBEXIT(BCE_VERBOSE_RESET);
4965}
4966
4967
4968static int
4969bce_reset(struct bce_softc *sc, u32 reset_code)
4970{
4971	u32 emac_mode_save, val;
4972	int i, rc = 0;
4973	static const u32 emac_mode_mask = BCE_EMAC_MODE_PORT |
4974	    BCE_EMAC_MODE_HALF_DUPLEX | BCE_EMAC_MODE_25G;
4975
4976	DBENTER(BCE_VERBOSE_RESET);
4977
4978	DBPRINT(sc, BCE_VERBOSE_RESET, "%s(): reset_code = 0x%08X\n",
4979	    __FUNCTION__, reset_code);
4980
4981	/*
4982	 * If ASF/IPMI is operational, then the EMAC Mode register already
4983	 * contains appropriate values for the link settings that have
4984	 * been auto-negotiated.  Resetting the chip will clobber those
4985	 * values.  Save the important bits so we can restore them after
4986	 * the reset.
4987	 */
4988	emac_mode_save = REG_RD(sc, BCE_EMAC_MODE) & emac_mode_mask;
4989
4990	/* Wait for pending PCI transactions to complete. */
4991	REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS,
4992	    BCE_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
4993	    BCE_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
4994	    BCE_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
4995	    BCE_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
4996	val = REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
4997	DELAY(5);
4998
4999	/* Disable DMA */
5000	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5001		val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
5002		val &= ~BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
5003		REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
5004	}
5005
5006	/* Assume bootcode is running. */
5007	sc->bce_fw_timed_out = FALSE;
5008	sc->bce_drv_cardiac_arrest = FALSE;
5009
5010	/* Give the firmware a chance to prepare for the reset. */
5011	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT0 | reset_code);
5012	if (rc)
5013		goto bce_reset_exit;
5014
5015	/* Set a firmware reminder that this is a soft reset. */
5016	bce_shmem_wr(sc, BCE_DRV_RESET_SIGNATURE, BCE_DRV_RESET_SIGNATURE_MAGIC);
5017
5018	/* Dummy read to force the chip to complete all current transactions. */
5019	val = REG_RD(sc, BCE_MISC_ID);
5020
5021	/* Chip reset. */
5022	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5023		REG_WR(sc, BCE_MISC_COMMAND, BCE_MISC_COMMAND_SW_RESET);
5024		REG_RD(sc, BCE_MISC_COMMAND);
5025		DELAY(5);
5026
5027		val = BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
5028		    BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
5029
5030		pci_write_config(sc->bce_dev, BCE_PCICFG_MISC_CONFIG, val, 4);
5031	} else {
5032		val = BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
5033		    BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
5034		    BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
5035		REG_WR(sc, BCE_PCICFG_MISC_CONFIG, val);
5036
5037		/* Allow up to 30us for reset to complete. */
5038		for (i = 0; i < 10; i++) {
5039			val = REG_RD(sc, BCE_PCICFG_MISC_CONFIG);
5040			if ((val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
5041			    BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
5042				break;
5043			}
5044			DELAY(10);
5045		}
5046
5047		/* Check that reset completed successfully. */
5048		if (val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
5049		    BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
5050			BCE_PRINTF("%s(%d): Reset failed!\n",
5051			    __FILE__, __LINE__);
5052			rc = EBUSY;
5053			goto bce_reset_exit;
5054		}
5055	}
5056
5057	/* Make sure byte swapping is properly configured. */
5058	val = REG_RD(sc, BCE_PCI_SWAP_DIAG0);
5059	if (val != 0x01020304) {
5060		BCE_PRINTF("%s(%d): Byte swap is incorrect!\n",
5061		    __FILE__, __LINE__);
5062		rc = ENODEV;
5063		goto bce_reset_exit;
5064	}
5065
5066	/* Just completed a reset, assume that firmware is running again. */
5067	sc->bce_fw_timed_out = FALSE;
5068	sc->bce_drv_cardiac_arrest = FALSE;
5069
5070	/* Wait for the firmware to finish its initialization. */
5071	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT1 | reset_code);
5072	if (rc)
5073		BCE_PRINTF("%s(%d): Firmware did not complete "
5074		    "initialization!\n", __FILE__, __LINE__);
5075	/* Get firmware capabilities. */
5076	bce_fw_cap_init(sc);
5077
5078bce_reset_exit:
5079	/* Restore EMAC Mode bits needed to keep ASF/IPMI running. */
5080	if (reset_code == BCE_DRV_MSG_CODE_RESET) {
5081		val = REG_RD(sc, BCE_EMAC_MODE);
5082		val = (val & ~emac_mode_mask) | emac_mode_save;
5083		REG_WR(sc, BCE_EMAC_MODE, val);
5084	}
5085
5086	DBEXIT(BCE_VERBOSE_RESET);
5087	return (rc);
5088}
5089
5090
5091static int
5092bce_chipinit(struct bce_softc *sc)
5093{
5094	u32 val;
5095	int rc = 0;
5096
5097	DBENTER(BCE_VERBOSE_RESET);
5098
5099	bce_disable_intr(sc);
5100
5101	/*
5102	 * Initialize DMA byte/word swapping, configure the number of DMA
5103	 * channels and PCI clock compensation delay.
5104	 */
5105	val = BCE_DMA_CONFIG_DATA_BYTE_SWAP |
5106	    BCE_DMA_CONFIG_DATA_WORD_SWAP |
5107#if BYTE_ORDER == BIG_ENDIAN
5108	    BCE_DMA_CONFIG_CNTL_BYTE_SWAP |
5109#endif
5110	    BCE_DMA_CONFIG_CNTL_WORD_SWAP |
5111	    DMA_READ_CHANS << 12 |
5112	    DMA_WRITE_CHANS << 16;
5113
5114	val |= (0x2 << 20) | BCE_DMA_CONFIG_CNTL_PCI_COMP_DLY;
5115
5116	if ((sc->bce_flags & BCE_PCIX_FLAG) && (sc->bus_speed_mhz == 133))
5117		val |= BCE_DMA_CONFIG_PCI_FAST_CLK_CMP;
5118
5119	/*
5120	 * This setting resolves a problem observed on certain Intel PCI
5121	 * chipsets that cannot handle multiple outstanding DMA operations.
5122	 * See errata E9_5706A1_65.
5123	 */
5124	if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
5125	    (BCE_CHIP_ID(sc) != BCE_CHIP_ID_5706_A0) &&
5126	    !(sc->bce_flags & BCE_PCIX_FLAG))
5127		val |= BCE_DMA_CONFIG_CNTL_PING_PONG_DMA;
5128
5129	REG_WR(sc, BCE_DMA_CONFIG, val);
5130
5131	/* Enable the RX_V2P and Context state machines before access. */
5132	REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
5133	    BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
5134	    BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
5135	    BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
5136
5137	/* Initialize context mapping and zero out the quick contexts. */
5138	if ((rc = bce_init_ctx(sc)) != 0)
5139		goto bce_chipinit_exit;
5140
5141	/* Initialize the on-boards CPUs */
5142	bce_init_cpus(sc);
5143
5144	/* Enable management frames (NC-SI) to flow to the MCP. */
5145	if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
5146		val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) | BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
5147		REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
5148	}
5149
5150	/* Prepare NVRAM for access. */
5151	if ((rc = bce_init_nvram(sc)) != 0)
5152		goto bce_chipinit_exit;
5153
5154	/* Set the kernel bypass block size */
5155	val = REG_RD(sc, BCE_MQ_CONFIG);
5156	val &= ~BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE;
5157	val |= BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
5158
5159	/* Enable bins used on the 5709. */
5160	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5161		val |= BCE_MQ_CONFIG_BIN_MQ_MODE;
5162		if (BCE_CHIP_ID(sc) == BCE_CHIP_ID_5709_A1)
5163			val |= BCE_MQ_CONFIG_HALT_DIS;
5164	}
5165
5166	REG_WR(sc, BCE_MQ_CONFIG, val);
5167
5168	val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
5169	REG_WR(sc, BCE_MQ_KNL_BYP_WIND_START, val);
5170	REG_WR(sc, BCE_MQ_KNL_WIND_END, val);
5171
5172	/* Set the page size and clear the RV2P processor stall bits. */
5173	val = (BCM_PAGE_BITS - 8) << 24;
5174	REG_WR(sc, BCE_RV2P_CONFIG, val);
5175
5176	/* Configure page size. */
5177	val = REG_RD(sc, BCE_TBDR_CONFIG);
5178	val &= ~BCE_TBDR_CONFIG_PAGE_SIZE;
5179	val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
5180	REG_WR(sc, BCE_TBDR_CONFIG, val);
5181
5182	/* Set the perfect match control register to default. */
5183	REG_WR_IND(sc, BCE_RXP_PM_CTRL, 0);
5184
5185bce_chipinit_exit:
5186	DBEXIT(BCE_VERBOSE_RESET);
5187
5188	return(rc);
5189}
5190
5191
5192/****************************************************************************/
5193/* Initialize the controller in preparation to send/receive traffic.        */
5194/*                                                                          */
5195/* Returns:                                                                 */
5196/*   0 for success, positive value for failure.                             */
5197/****************************************************************************/
5198static int
5199bce_blockinit(struct bce_softc *sc)
5200{
5201	u32 reg, val;
5202	int rc = 0;
5203
5204	DBENTER(BCE_VERBOSE_RESET);
5205
5206	/* Load the hardware default MAC address. */
5207	bce_set_mac_addr(sc);
5208
5209	/* Set the Ethernet backoff seed value */
5210	val = sc->eaddr[0]         + (sc->eaddr[1] << 8) +
5211	      (sc->eaddr[2] << 16) + (sc->eaddr[3]     ) +
5212	      (sc->eaddr[4] << 8)  + (sc->eaddr[5] << 16);
5213	REG_WR(sc, BCE_EMAC_BACKOFF_SEED, val);
5214
5215	sc->last_status_idx = 0;
5216	sc->rx_mode = BCE_EMAC_RX_MODE_SORT_MODE;
5217
5218	/* Set up link change interrupt generation. */
5219	REG_WR(sc, BCE_EMAC_ATTENTION_ENA, BCE_EMAC_ATTENTION_ENA_LINK);
5220
5221	/* Program the physical address of the status block. */
5222	REG_WR(sc, BCE_HC_STATUS_ADDR_L,
5223	    BCE_ADDR_LO(sc->status_block_paddr));
5224	REG_WR(sc, BCE_HC_STATUS_ADDR_H,
5225	    BCE_ADDR_HI(sc->status_block_paddr));
5226
5227	/* Program the physical address of the statistics block. */
5228	REG_WR(sc, BCE_HC_STATISTICS_ADDR_L,
5229	    BCE_ADDR_LO(sc->stats_block_paddr));
5230	REG_WR(sc, BCE_HC_STATISTICS_ADDR_H,
5231	    BCE_ADDR_HI(sc->stats_block_paddr));
5232
5233	/*
5234	 * Program various host coalescing parameters.
5235	 * Trip points control how many BDs should be ready before generating
5236	 * an interrupt while ticks control how long a BD can sit in the chain
5237	 * before generating an interrupt.
5238	 */
5239	REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
5240	    (sc->bce_tx_quick_cons_trip_int << 16) |
5241	    sc->bce_tx_quick_cons_trip);
5242	REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
5243	    (sc->bce_rx_quick_cons_trip_int << 16) |
5244	    sc->bce_rx_quick_cons_trip);
5245	REG_WR(sc, BCE_HC_TX_TICKS,
5246	    (sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
5247	REG_WR(sc, BCE_HC_RX_TICKS,
5248	    (sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
5249	REG_WR(sc, BCE_HC_STATS_TICKS, sc->bce_stats_ticks & 0xffff00);
5250	REG_WR(sc, BCE_HC_STAT_COLLECT_TICKS, 0xbb8);  /* 3ms */
5251	/* Not used for L2. */
5252	REG_WR(sc, BCE_HC_COMP_PROD_TRIP, 0);
5253	REG_WR(sc, BCE_HC_COM_TICKS, 0);
5254	REG_WR(sc, BCE_HC_CMD_TICKS, 0);
5255
5256	/* Configure the Host Coalescing block. */
5257	val = BCE_HC_CONFIG_RX_TMR_MODE | BCE_HC_CONFIG_TX_TMR_MODE |
5258	    BCE_HC_CONFIG_COLLECT_STATS;
5259
5260#if 0
5261	/* ToDo: Add MSI-X support. */
5262	if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
5263		u32 base = ((BCE_TX_VEC - 1) * BCE_HC_SB_CONFIG_SIZE) +
5264		    BCE_HC_SB_CONFIG_1;
5265
5266		REG_WR(sc, BCE_HC_MSIX_BIT_VECTOR, BCE_HC_MSIX_BIT_VECTOR_VAL);
5267
5268		REG_WR(sc, base, BCE_HC_SB_CONFIG_1_TX_TMR_MODE |
5269		    BCE_HC_SB_CONFIG_1_ONE_SHOT);
5270
5271		REG_WR(sc, base + BCE_HC_TX_QUICK_CONS_TRIP_OFF,
5272		    (sc->tx_quick_cons_trip_int << 16) |
5273		     sc->tx_quick_cons_trip);
5274
5275		REG_WR(sc, base + BCE_HC_TX_TICKS_OFF,
5276		    (sc->tx_ticks_int << 16) | sc->tx_ticks);
5277
5278		val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
5279	}
5280
5281	/*
5282	 * Tell the HC block to automatically set the
5283	 * INT_MASK bit after an MSI/MSI-X interrupt
5284	 * is generated so the driver doesn't have to.
5285	 */
5286	if (sc->bce_flags & BCE_ONE_SHOT_MSI_FLAG)
5287		val |= BCE_HC_CONFIG_ONE_SHOT;
5288
5289	/* Set the MSI-X status blocks to 128 byte boundaries. */
5290	if (sc->bce_flags & BCE_USING_MSIX_FLAG)
5291		val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
5292#endif
5293
5294	REG_WR(sc, BCE_HC_CONFIG, val);
5295
5296	/* Clear the internal statistics counters. */
5297	REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
5298
5299	/* Verify that bootcode is running. */
5300	reg = bce_shmem_rd(sc, BCE_DEV_INFO_SIGNATURE);
5301
5302	DBRUNIF(DB_RANDOMTRUE(bootcode_running_failure_sim_control),
5303	    BCE_PRINTF("%s(%d): Simulating bootcode failure.\n",
5304	    __FILE__, __LINE__);
5305	    reg = 0);
5306
5307	if ((reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
5308	    BCE_DEV_INFO_SIGNATURE_MAGIC) {
5309		BCE_PRINTF("%s(%d): Bootcode not running! Found: 0x%08X, "
5310		    "Expected: 08%08X\n", __FILE__, __LINE__,
5311		    (reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK),
5312		    BCE_DEV_INFO_SIGNATURE_MAGIC);
5313		rc = ENODEV;
5314		goto bce_blockinit_exit;
5315	}
5316
5317	/* Enable DMA */
5318	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5319		val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
5320		val |= BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
5321		REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
5322	}
5323
5324	/* Allow bootcode to apply additional fixes before enabling MAC. */
5325	rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 |
5326	    BCE_DRV_MSG_CODE_RESET);
5327
5328	/* Enable link state change interrupt generation. */
5329	REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
5330
5331	/* Enable the RXP. */
5332	bce_start_rxp_cpu(sc);
5333
5334	/* Disable management frames (NC-SI) from flowing to the MCP. */
5335	if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
5336		val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) &
5337		    ~BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
5338		REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
5339	}
5340
5341	/* Enable all remaining blocks in the MAC. */
5342	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
5343		REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
5344		    BCE_MISC_ENABLE_DEFAULT_XI);
5345	else
5346		REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
5347		    BCE_MISC_ENABLE_DEFAULT);
5348
5349	REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
5350	DELAY(20);
5351
5352	/* Save the current host coalescing block settings. */
5353	sc->hc_command = REG_RD(sc, BCE_HC_COMMAND);
5354
5355bce_blockinit_exit:
5356	DBEXIT(BCE_VERBOSE_RESET);
5357
5358	return (rc);
5359}
5360
5361
5362/****************************************************************************/
5363/* Encapsulate an mbuf into the rx_bd chain.                                */
5364/*                                                                          */
5365/* Returns:                                                                 */
5366/*   0 for success, positive value for failure.                             */
5367/****************************************************************************/
5368static int
5369bce_get_rx_buf(struct bce_softc *sc, u16 prod, u16 chain_prod, u32 *prod_bseq)
5370{
5371	bus_dma_segment_t segs[1];
5372	struct mbuf *m_new = NULL;
5373	struct rx_bd *rxbd;
5374	int nsegs, error, rc = 0;
5375#ifdef BCE_DEBUG
5376	u16 debug_chain_prod = chain_prod;
5377#endif
5378
5379	DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5380
5381	/* Make sure the inputs are valid. */
5382	DBRUNIF((chain_prod > MAX_RX_BD_ALLOC),
5383	    BCE_PRINTF("%s(%d): RX producer out of range: "
5384	    "0x%04X > 0x%04X\n", __FILE__, __LINE__,
5385	    chain_prod, (u16)MAX_RX_BD_ALLOC));
5386
5387	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
5388	    "chain_prod = 0x%04X, prod_bseq = 0x%08X\n", __FUNCTION__,
5389	    prod, chain_prod, *prod_bseq);
5390
5391	/* Update some debug statistic counters */
5392	DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
5393	    sc->rx_low_watermark = sc->free_rx_bd);
5394	DBRUNIF((sc->free_rx_bd == sc->max_rx_bd),
5395	    sc->rx_empty_count++);
5396
5397	/* Simulate an mbuf allocation failure. */
5398	DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
5399	    sc->mbuf_alloc_failed_count++;
5400	    sc->mbuf_alloc_failed_sim_count++;
5401	    rc = ENOBUFS;
5402	    goto bce_get_rx_buf_exit);
5403
5404	/* This is a new mbuf allocation. */
5405	if (bce_hdr_split == TRUE)
5406		MGETHDR(m_new, M_NOWAIT, MT_DATA);
5407	else
5408		m_new = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR,
5409		    sc->rx_bd_mbuf_alloc_size);
5410
5411	if (m_new == NULL) {
5412		sc->mbuf_alloc_failed_count++;
5413		rc = ENOBUFS;
5414		goto bce_get_rx_buf_exit;
5415	}
5416
5417	DBRUN(sc->debug_rx_mbuf_alloc++);
5418
5419	/* Make sure we have a valid packet header. */
5420	M_ASSERTPKTHDR(m_new);
5421
5422	/* Initialize the mbuf size and pad if necessary for alignment. */
5423	m_new->m_pkthdr.len = m_new->m_len = sc->rx_bd_mbuf_alloc_size;
5424	m_adj(m_new, sc->rx_bd_mbuf_align_pad);
5425
5426	/* ToDo: Consider calling m_fragment() to test error handling. */
5427
5428	/* Map the mbuf cluster into device memory. */
5429	error = bus_dmamap_load_mbuf_sg(sc->rx_mbuf_tag,
5430	    sc->rx_mbuf_map[chain_prod], m_new, segs, &nsegs, BUS_DMA_NOWAIT);
5431
5432	/* Handle any mapping errors. */
5433	if (error) {
5434		BCE_PRINTF("%s(%d): Error mapping mbuf into RX "
5435		    "chain (%d)!\n", __FILE__, __LINE__, error);
5436
5437		sc->dma_map_addr_rx_failed_count++;
5438		m_freem(m_new);
5439
5440		DBRUN(sc->debug_rx_mbuf_alloc--);
5441
5442		rc = ENOBUFS;
5443		goto bce_get_rx_buf_exit;
5444	}
5445
5446	/* All mbufs must map to a single segment. */
5447	KASSERT(nsegs == 1, ("%s(): Too many segments returned (%d)!",
5448	    __FUNCTION__, nsegs));
5449
5450	/* Setup the rx_bd for the segment. */
5451	rxbd = &sc->rx_bd_chain[RX_PAGE(chain_prod)][RX_IDX(chain_prod)];
5452
5453	rxbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(segs[0].ds_addr));
5454	rxbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(segs[0].ds_addr));
5455	rxbd->rx_bd_len       = htole32(segs[0].ds_len);
5456	rxbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
5457	*prod_bseq += segs[0].ds_len;
5458
5459	/* Save the mbuf and update our counter. */
5460	sc->rx_mbuf_ptr[chain_prod] = m_new;
5461	sc->free_rx_bd -= nsegs;
5462
5463	DBRUNMSG(BCE_INSANE_RECV,
5464	    bce_dump_rx_mbuf_chain(sc, debug_chain_prod, nsegs));
5465
5466	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
5467	    "chain_prod = 0x%04X, prod_bseq = 0x%08X\n", __FUNCTION__, prod,
5468	    chain_prod, *prod_bseq);
5469
5470bce_get_rx_buf_exit:
5471	DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5472
5473	return(rc);
5474}
5475
5476
5477/****************************************************************************/
5478/* Encapsulate an mbuf cluster into the page chain.                         */
5479/*                                                                          */
5480/* Returns:                                                                 */
5481/*   0 for success, positive value for failure.                             */
5482/****************************************************************************/
5483static int
5484bce_get_pg_buf(struct bce_softc *sc, u16 prod, u16 prod_idx)
5485{
5486	bus_dma_segment_t segs[1];
5487	struct mbuf *m_new = NULL;
5488	struct rx_bd *pgbd;
5489	int error, nsegs, rc = 0;
5490#ifdef BCE_DEBUG
5491	u16 debug_prod_idx = prod_idx;
5492#endif
5493
5494	DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5495
5496	/* Make sure the inputs are valid. */
5497	DBRUNIF((prod_idx > MAX_PG_BD_ALLOC),
5498	    BCE_PRINTF("%s(%d): page producer out of range: "
5499	    "0x%04X > 0x%04X\n", __FILE__, __LINE__,
5500	    prod_idx, (u16)MAX_PG_BD_ALLOC));
5501
5502	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
5503	    "chain_prod = 0x%04X\n", __FUNCTION__, prod, prod_idx);
5504
5505	/* Update counters if we've hit a new low or run out of pages. */
5506	DBRUNIF((sc->free_pg_bd < sc->pg_low_watermark),
5507	    sc->pg_low_watermark = sc->free_pg_bd);
5508	DBRUNIF((sc->free_pg_bd == sc->max_pg_bd), sc->pg_empty_count++);
5509
5510	/* Simulate an mbuf allocation failure. */
5511	DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
5512	    sc->mbuf_alloc_failed_count++;
5513	    sc->mbuf_alloc_failed_sim_count++;
5514	    rc = ENOBUFS;
5515	    goto bce_get_pg_buf_exit);
5516
5517	/* This is a new mbuf allocation. */
5518	m_new = m_getcl(M_NOWAIT, MT_DATA, 0);
5519	if (m_new == NULL) {
5520		sc->mbuf_alloc_failed_count++;
5521		rc = ENOBUFS;
5522		goto bce_get_pg_buf_exit;
5523	}
5524
5525	DBRUN(sc->debug_pg_mbuf_alloc++);
5526
5527	m_new->m_len = MCLBYTES;
5528
5529	/* ToDo: Consider calling m_fragment() to test error handling. */
5530
5531	/* Map the mbuf cluster into device memory. */
5532	error = bus_dmamap_load_mbuf_sg(sc->pg_mbuf_tag,
5533	    sc->pg_mbuf_map[prod_idx], m_new, segs, &nsegs, BUS_DMA_NOWAIT);
5534
5535	/* Handle any mapping errors. */
5536	if (error) {
5537		BCE_PRINTF("%s(%d): Error mapping mbuf into page chain!\n",
5538		    __FILE__, __LINE__);
5539
5540		m_freem(m_new);
5541		DBRUN(sc->debug_pg_mbuf_alloc--);
5542
5543		rc = ENOBUFS;
5544		goto bce_get_pg_buf_exit;
5545	}
5546
5547	/* All mbufs must map to a single segment. */
5548	KASSERT(nsegs == 1, ("%s(): Too many segments returned (%d)!",
5549	    __FUNCTION__, nsegs));
5550
5551	/* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREREAD) here? */
5552
5553	/*
5554	 * The page chain uses the same rx_bd data structure
5555	 * as the receive chain but doesn't require a byte sequence (bseq).
5556	 */
5557	pgbd = &sc->pg_bd_chain[PG_PAGE(prod_idx)][PG_IDX(prod_idx)];
5558
5559	pgbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(segs[0].ds_addr));
5560	pgbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(segs[0].ds_addr));
5561	pgbd->rx_bd_len       = htole32(MCLBYTES);
5562	pgbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
5563
5564	/* Save the mbuf and update our counter. */
5565	sc->pg_mbuf_ptr[prod_idx] = m_new;
5566	sc->free_pg_bd--;
5567
5568	DBRUNMSG(BCE_INSANE_RECV,
5569	    bce_dump_pg_mbuf_chain(sc, debug_prod_idx, 1));
5570
5571	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
5572	    "prod_idx = 0x%04X\n", __FUNCTION__, prod, prod_idx);
5573
5574bce_get_pg_buf_exit:
5575	DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
5576
5577	return(rc);
5578}
5579
5580
5581/****************************************************************************/
5582/* Initialize the TX context memory.                                        */
5583/*                                                                          */
5584/* Returns:                                                                 */
5585/*   Nothing                                                                */
5586/****************************************************************************/
5587static void
5588bce_init_tx_context(struct bce_softc *sc)
5589{
5590	u32 val;
5591
5592	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
5593
5594	/* Initialize the context ID for an L2 TX chain. */
5595	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5596		/* Set the CID type to support an L2 connection. */
5597		val = BCE_L2CTX_TX_TYPE_TYPE_L2_XI |
5598		    BCE_L2CTX_TX_TYPE_SIZE_L2_XI;
5599		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE_XI, val);
5600		val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2_XI | (8 << 16);
5601		CTX_WR(sc, GET_CID_ADDR(TX_CID),
5602		    BCE_L2CTX_TX_CMD_TYPE_XI, val);
5603
5604		/* Point the hardware to the first page in the chain. */
5605		val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
5606		CTX_WR(sc, GET_CID_ADDR(TX_CID),
5607		    BCE_L2CTX_TX_TBDR_BHADDR_HI_XI, val);
5608		val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
5609		CTX_WR(sc, GET_CID_ADDR(TX_CID),
5610		    BCE_L2CTX_TX_TBDR_BHADDR_LO_XI, val);
5611	} else {
5612		/* Set the CID type to support an L2 connection. */
5613		val = BCE_L2CTX_TX_TYPE_TYPE_L2 | BCE_L2CTX_TX_TYPE_SIZE_L2;
5614		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE, val);
5615		val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2 | (8 << 16);
5616		CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_CMD_TYPE, val);
5617
5618		/* Point the hardware to the first page in the chain. */
5619		val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
5620		CTX_WR(sc, GET_CID_ADDR(TX_CID),
5621		    BCE_L2CTX_TX_TBDR_BHADDR_HI, val);
5622		val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
5623		CTX_WR(sc, GET_CID_ADDR(TX_CID),
5624		    BCE_L2CTX_TX_TBDR_BHADDR_LO, val);
5625	}
5626
5627	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
5628}
5629
5630
5631/****************************************************************************/
5632/* Allocate memory and initialize the TX data structures.                   */
5633/*                                                                          */
5634/* Returns:                                                                 */
5635/*   0 for success, positive value for failure.                             */
5636/****************************************************************************/
5637static int
5638bce_init_tx_chain(struct bce_softc *sc)
5639{
5640	struct tx_bd *txbd;
5641	int i, rc = 0;
5642
5643	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
5644
5645	/* Set the initial TX producer/consumer indices. */
5646	sc->tx_prod        = 0;
5647	sc->tx_cons        = 0;
5648	sc->tx_prod_bseq   = 0;
5649	sc->used_tx_bd     = 0;
5650	sc->max_tx_bd      = USABLE_TX_BD_ALLOC;
5651	DBRUN(sc->tx_hi_watermark = 0);
5652	DBRUN(sc->tx_full_count = 0);
5653
5654	/*
5655	 * The NetXtreme II supports a linked-list structre called
5656	 * a Buffer Descriptor Chain (or BD chain).  A BD chain
5657	 * consists of a series of 1 or more chain pages, each of which
5658	 * consists of a fixed number of BD entries.
5659	 * The last BD entry on each page is a pointer to the next page
5660	 * in the chain, and the last pointer in the BD chain
5661	 * points back to the beginning of the chain.
5662	 */
5663
5664	/* Set the TX next pointer chain entries. */
5665	for (i = 0; i < sc->tx_pages; i++) {
5666		int j;
5667
5668		txbd = &sc->tx_bd_chain[i][USABLE_TX_BD_PER_PAGE];
5669
5670		/* Check if we've reached the last page. */
5671		if (i == (sc->tx_pages - 1))
5672			j = 0;
5673		else
5674			j = i + 1;
5675
5676		txbd->tx_bd_haddr_hi =
5677		    htole32(BCE_ADDR_HI(sc->tx_bd_chain_paddr[j]));
5678		txbd->tx_bd_haddr_lo =
5679		    htole32(BCE_ADDR_LO(sc->tx_bd_chain_paddr[j]));
5680	}
5681
5682	bce_init_tx_context(sc);
5683
5684	DBRUNMSG(BCE_INSANE_SEND, bce_dump_tx_chain(sc, 0, TOTAL_TX_BD_ALLOC));
5685	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
5686
5687	return(rc);
5688}
5689
5690
5691/****************************************************************************/
5692/* Free memory and clear the TX data structures.                            */
5693/*                                                                          */
5694/* Returns:                                                                 */
5695/*   Nothing.                                                               */
5696/****************************************************************************/
5697static void
5698bce_free_tx_chain(struct bce_softc *sc)
5699{
5700	int i;
5701
5702	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
5703
5704	/* Unmap, unload, and free any mbufs still in the TX mbuf chain. */
5705	for (i = 0; i < MAX_TX_BD_AVAIL; i++) {
5706		if (sc->tx_mbuf_ptr[i] != NULL) {
5707			if (sc->tx_mbuf_map[i] != NULL)
5708				bus_dmamap_sync(sc->tx_mbuf_tag,
5709				    sc->tx_mbuf_map[i],
5710				    BUS_DMASYNC_POSTWRITE);
5711			m_freem(sc->tx_mbuf_ptr[i]);
5712			sc->tx_mbuf_ptr[i] = NULL;
5713			DBRUN(sc->debug_tx_mbuf_alloc--);
5714		}
5715	}
5716
5717	/* Clear each TX chain page. */
5718	for (i = 0; i < sc->tx_pages; i++)
5719		bzero((char *)sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ);
5720
5721	sc->used_tx_bd = 0;
5722
5723	/* Check if we lost any mbufs in the process. */
5724	DBRUNIF((sc->debug_tx_mbuf_alloc),
5725	    BCE_PRINTF("%s(%d): Memory leak! Lost %d mbufs "
5726	    "from tx chain!\n",	__FILE__, __LINE__,
5727	    sc->debug_tx_mbuf_alloc));
5728
5729	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
5730}
5731
5732
5733/****************************************************************************/
5734/* Initialize the RX context memory.                                        */
5735/*                                                                          */
5736/* Returns:                                                                 */
5737/*   Nothing                                                                */
5738/****************************************************************************/
5739static void
5740bce_init_rx_context(struct bce_softc *sc)
5741{
5742	u32 val;
5743
5744	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
5745
5746	/* Init the type, size, and BD cache levels for the RX context. */
5747	val = BCE_L2CTX_RX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE |
5748	    BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 |
5749	    (0x02 << BCE_L2CTX_RX_BD_PRE_READ_SHIFT);
5750
5751	/*
5752	 * Set the level for generating pause frames
5753	 * when the number of available rx_bd's gets
5754	 * too low (the low watermark) and the level
5755	 * when pause frames can be stopped (the high
5756	 * watermark).
5757	 */
5758	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5759		u32 lo_water, hi_water;
5760
5761		if (sc->bce_flags & BCE_USING_TX_FLOW_CONTROL) {
5762			lo_water = BCE_L2CTX_RX_LO_WATER_MARK_DEFAULT;
5763		} else {
5764			lo_water = 0;
5765		}
5766
5767		if (lo_water >= USABLE_RX_BD_ALLOC) {
5768			lo_water = 0;
5769		}
5770
5771		hi_water = USABLE_RX_BD_ALLOC / 4;
5772
5773		if (hi_water <= lo_water) {
5774			lo_water = 0;
5775		}
5776
5777		lo_water /= BCE_L2CTX_RX_LO_WATER_MARK_SCALE;
5778		hi_water /= BCE_L2CTX_RX_HI_WATER_MARK_SCALE;
5779
5780		if (hi_water > 0xf)
5781			hi_water = 0xf;
5782		else if (hi_water == 0)
5783			lo_water = 0;
5784
5785		val |= (lo_water << BCE_L2CTX_RX_LO_WATER_MARK_SHIFT) |
5786		    (hi_water << BCE_L2CTX_RX_HI_WATER_MARK_SHIFT);
5787	}
5788
5789	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_CTX_TYPE, val);
5790
5791	/* Setup the MQ BIN mapping for l2_ctx_host_bseq. */
5792	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
5793		val = REG_RD(sc, BCE_MQ_MAP_L2_5);
5794		REG_WR(sc, BCE_MQ_MAP_L2_5, val | BCE_MQ_MAP_L2_5_ARM);
5795	}
5796
5797	/* Point the hardware to the first page in the chain. */
5798	val = BCE_ADDR_HI(sc->rx_bd_chain_paddr[0]);
5799	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_HI, val);
5800	val = BCE_ADDR_LO(sc->rx_bd_chain_paddr[0]);
5801	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_LO, val);
5802
5803	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
5804}
5805
5806
5807/****************************************************************************/
5808/* Allocate memory and initialize the RX data structures.                   */
5809/*                                                                          */
5810/* Returns:                                                                 */
5811/*   0 for success, positive value for failure.                             */
5812/****************************************************************************/
5813static int
5814bce_init_rx_chain(struct bce_softc *sc)
5815{
5816	struct rx_bd *rxbd;
5817	int i, rc = 0;
5818
5819	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5820	    BCE_VERBOSE_CTX);
5821
5822	/* Initialize the RX producer and consumer indices. */
5823	sc->rx_prod        = 0;
5824	sc->rx_cons        = 0;
5825	sc->rx_prod_bseq   = 0;
5826	sc->free_rx_bd     = USABLE_RX_BD_ALLOC;
5827	sc->max_rx_bd      = USABLE_RX_BD_ALLOC;
5828
5829	/* Initialize the RX next pointer chain entries. */
5830	for (i = 0; i < sc->rx_pages; i++) {
5831		int j;
5832
5833		rxbd = &sc->rx_bd_chain[i][USABLE_RX_BD_PER_PAGE];
5834
5835		/* Check if we've reached the last page. */
5836		if (i == (sc->rx_pages - 1))
5837			j = 0;
5838		else
5839			j = i + 1;
5840
5841		/* Setup the chain page pointers. */
5842		rxbd->rx_bd_haddr_hi =
5843		    htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j]));
5844		rxbd->rx_bd_haddr_lo =
5845		    htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j]));
5846	}
5847
5848	/* Fill up the RX chain. */
5849	bce_fill_rx_chain(sc);
5850
5851	DBRUN(sc->rx_low_watermark = USABLE_RX_BD_ALLOC);
5852	DBRUN(sc->rx_empty_count = 0);
5853	for (i = 0; i < sc->rx_pages; i++) {
5854		bus_dmamap_sync(sc->rx_bd_chain_tag, sc->rx_bd_chain_map[i],
5855		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
5856	}
5857
5858	bce_init_rx_context(sc);
5859
5860	DBRUNMSG(BCE_EXTREME_RECV,
5861	    bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD_ALLOC));
5862	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5863	    BCE_VERBOSE_CTX);
5864
5865	/* ToDo: Are there possible failure modes here? */
5866
5867	return(rc);
5868}
5869
5870
5871/****************************************************************************/
5872/* Add mbufs to the RX chain until its full or an mbuf allocation error     */
5873/* occurs.                                                                  */
5874/*                                                                          */
5875/* Returns:                                                                 */
5876/*   Nothing                                                                */
5877/****************************************************************************/
5878static void
5879bce_fill_rx_chain(struct bce_softc *sc)
5880{
5881	u16 prod, prod_idx;
5882	u32 prod_bseq;
5883
5884	DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5885	    BCE_VERBOSE_CTX);
5886
5887	/* Get the RX chain producer indices. */
5888	prod      = sc->rx_prod;
5889	prod_bseq = sc->rx_prod_bseq;
5890
5891	/* Keep filling the RX chain until it's full. */
5892	while (sc->free_rx_bd > 0) {
5893		prod_idx = RX_CHAIN_IDX(prod);
5894		if (bce_get_rx_buf(sc, prod, prod_idx, &prod_bseq)) {
5895			/* Bail out if we can't add an mbuf to the chain. */
5896			break;
5897		}
5898		prod = NEXT_RX_BD(prod);
5899	}
5900
5901	/* Save the RX chain producer indices. */
5902	sc->rx_prod      = prod;
5903	sc->rx_prod_bseq = prod_bseq;
5904
5905	/* We should never end up pointing to a next page pointer. */
5906	DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
5907	    BCE_PRINTF("%s(): Invalid rx_prod value: 0x%04X\n",
5908	    __FUNCTION__, rx_prod));
5909
5910	/* Write the mailbox and tell the chip about the waiting rx_bd's. */
5911	REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BDIDX, prod);
5912	REG_WR(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BSEQ, prod_bseq);
5913
5914	DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
5915	    BCE_VERBOSE_CTX);
5916}
5917
5918
5919/****************************************************************************/
5920/* Free memory and clear the RX data structures.                            */
5921/*                                                                          */
5922/* Returns:                                                                 */
5923/*   Nothing.                                                               */
5924/****************************************************************************/
5925static void
5926bce_free_rx_chain(struct bce_softc *sc)
5927{
5928	int i;
5929
5930	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5931
5932	/* Free any mbufs still in the RX mbuf chain. */
5933	for (i = 0; i < MAX_RX_BD_AVAIL; i++) {
5934		if (sc->rx_mbuf_ptr[i] != NULL) {
5935			if (sc->rx_mbuf_map[i] != NULL)
5936				bus_dmamap_sync(sc->rx_mbuf_tag,
5937				    sc->rx_mbuf_map[i],
5938				    BUS_DMASYNC_POSTREAD);
5939			m_freem(sc->rx_mbuf_ptr[i]);
5940			sc->rx_mbuf_ptr[i] = NULL;
5941			DBRUN(sc->debug_rx_mbuf_alloc--);
5942		}
5943	}
5944
5945	/* Clear each RX chain page. */
5946	for (i = 0; i < sc->rx_pages; i++)
5947		if (sc->rx_bd_chain[i] != NULL)
5948			bzero((char *)sc->rx_bd_chain[i],
5949			    BCE_RX_CHAIN_PAGE_SZ);
5950
5951	sc->free_rx_bd = sc->max_rx_bd;
5952
5953	/* Check if we lost any mbufs in the process. */
5954	DBRUNIF((sc->debug_rx_mbuf_alloc),
5955	    BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from rx chain!\n",
5956	    __FUNCTION__, sc->debug_rx_mbuf_alloc));
5957
5958	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
5959}
5960
5961
5962/****************************************************************************/
5963/* Allocate memory and initialize the page data structures.                 */
5964/* Assumes that bce_init_rx_chain() has not already been called.            */
5965/*                                                                          */
5966/* Returns:                                                                 */
5967/*   0 for success, positive value for failure.                             */
5968/****************************************************************************/
5969static int
5970bce_init_pg_chain(struct bce_softc *sc)
5971{
5972	struct rx_bd *pgbd;
5973	int i, rc = 0;
5974	u32 val;
5975
5976	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
5977		BCE_VERBOSE_CTX);
5978
5979	/* Initialize the page producer and consumer indices. */
5980	sc->pg_prod        = 0;
5981	sc->pg_cons        = 0;
5982	sc->free_pg_bd     = USABLE_PG_BD_ALLOC;
5983	sc->max_pg_bd      = USABLE_PG_BD_ALLOC;
5984	DBRUN(sc->pg_low_watermark = sc->max_pg_bd);
5985	DBRUN(sc->pg_empty_count = 0);
5986
5987	/* Initialize the page next pointer chain entries. */
5988	for (i = 0; i < sc->pg_pages; i++) {
5989		int j;
5990
5991		pgbd = &sc->pg_bd_chain[i][USABLE_PG_BD_PER_PAGE];
5992
5993		/* Check if we've reached the last page. */
5994		if (i == (sc->pg_pages - 1))
5995			j = 0;
5996		else
5997			j = i + 1;
5998
5999		/* Setup the chain page pointers. */
6000		pgbd->rx_bd_haddr_hi =
6001		    htole32(BCE_ADDR_HI(sc->pg_bd_chain_paddr[j]));
6002		pgbd->rx_bd_haddr_lo =
6003		    htole32(BCE_ADDR_LO(sc->pg_bd_chain_paddr[j]));
6004	}
6005
6006	/* Setup the MQ BIN mapping for host_pg_bidx. */
6007	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
6008		REG_WR(sc, BCE_MQ_MAP_L2_3, BCE_MQ_MAP_L2_3_DEFAULT);
6009
6010	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, 0);
6011
6012	/* Configure the rx_bd and page chain mbuf cluster size. */
6013	val = (sc->rx_bd_mbuf_data_len << 16) | MCLBYTES;
6014	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, val);
6015
6016	/* Configure the context reserved for jumbo support. */
6017	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_RBDC_KEY,
6018		BCE_L2CTX_RX_RBDC_JUMBO_KEY);
6019
6020	/* Point the hardware to the first page in the page chain. */
6021	val = BCE_ADDR_HI(sc->pg_bd_chain_paddr[0]);
6022	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_HI, val);
6023	val = BCE_ADDR_LO(sc->pg_bd_chain_paddr[0]);
6024	CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_LO, val);
6025
6026	/* Fill up the page chain. */
6027	bce_fill_pg_chain(sc);
6028
6029	for (i = 0; i < sc->pg_pages; i++) {
6030		bus_dmamap_sync(sc->pg_bd_chain_tag, sc->pg_bd_chain_map[i],
6031		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
6032	}
6033
6034	DBRUNMSG(BCE_EXTREME_RECV,
6035	    bce_dump_pg_chain(sc, 0, TOTAL_PG_BD_ALLOC));
6036	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
6037		BCE_VERBOSE_CTX);
6038	return(rc);
6039}
6040
6041
6042/****************************************************************************/
6043/* Add mbufs to the page chain until its full or an mbuf allocation error   */
6044/* occurs.                                                                  */
6045/*                                                                          */
6046/* Returns:                                                                 */
6047/*   Nothing                                                                */
6048/****************************************************************************/
6049static void
6050bce_fill_pg_chain(struct bce_softc *sc)
6051{
6052	u16 prod, prod_idx;
6053
6054	DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
6055	    BCE_VERBOSE_CTX);
6056
6057	/* Get the page chain prodcuer index. */
6058	prod = sc->pg_prod;
6059
6060	/* Keep filling the page chain until it's full. */
6061	while (sc->free_pg_bd > 0) {
6062		prod_idx = PG_CHAIN_IDX(prod);
6063		if (bce_get_pg_buf(sc, prod, prod_idx)) {
6064			/* Bail out if we can't add an mbuf to the chain. */
6065			break;
6066		}
6067		prod = NEXT_PG_BD(prod);
6068	}
6069
6070	/* Save the page chain producer index. */
6071	sc->pg_prod = prod;
6072
6073	DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
6074	    BCE_PRINTF("%s(): Invalid pg_prod value: 0x%04X\n",
6075	    __FUNCTION__, pg_prod));
6076
6077	/*
6078	 * Write the mailbox and tell the chip about
6079	 * the new rx_bd's in the page chain.
6080	 */
6081	REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_PG_BDIDX,
6082	    prod);
6083
6084	DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
6085	    BCE_VERBOSE_CTX);
6086}
6087
6088
6089/****************************************************************************/
6090/* Free memory and clear the RX data structures.                            */
6091/*                                                                          */
6092/* Returns:                                                                 */
6093/*   Nothing.                                                               */
6094/****************************************************************************/
6095static void
6096bce_free_pg_chain(struct bce_softc *sc)
6097{
6098	int i;
6099
6100	DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
6101
6102	/* Free any mbufs still in the mbuf page chain. */
6103	for (i = 0; i < MAX_PG_BD_AVAIL; i++) {
6104		if (sc->pg_mbuf_ptr[i] != NULL) {
6105			if (sc->pg_mbuf_map[i] != NULL)
6106				bus_dmamap_sync(sc->pg_mbuf_tag,
6107				    sc->pg_mbuf_map[i],
6108				    BUS_DMASYNC_POSTREAD);
6109			m_freem(sc->pg_mbuf_ptr[i]);
6110			sc->pg_mbuf_ptr[i] = NULL;
6111			DBRUN(sc->debug_pg_mbuf_alloc--);
6112		}
6113	}
6114
6115	/* Clear each page chain pages. */
6116	for (i = 0; i < sc->pg_pages; i++)
6117		bzero((char *)sc->pg_bd_chain[i], BCE_PG_CHAIN_PAGE_SZ);
6118
6119	sc->free_pg_bd = sc->max_pg_bd;
6120
6121	/* Check if we lost any mbufs in the process. */
6122	DBRUNIF((sc->debug_pg_mbuf_alloc),
6123	    BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from page chain!\n",
6124	    __FUNCTION__, sc->debug_pg_mbuf_alloc));
6125
6126	DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
6127}
6128
6129
6130static u32
6131bce_get_rphy_link(struct bce_softc *sc)
6132{
6133	u32 advertise, link;
6134	int fdpx;
6135
6136	advertise = 0;
6137	fdpx = 0;
6138	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) != 0)
6139		link = bce_shmem_rd(sc, BCE_RPHY_SERDES_LINK);
6140	else
6141		link = bce_shmem_rd(sc, BCE_RPHY_COPPER_LINK);
6142	if (link & BCE_NETLINK_ANEG_ENB)
6143		advertise |= BCE_NETLINK_ANEG_ENB;
6144	if (link & BCE_NETLINK_SPEED_10HALF)
6145		advertise |= BCE_NETLINK_SPEED_10HALF;
6146	if (link & BCE_NETLINK_SPEED_10FULL) {
6147		advertise |= BCE_NETLINK_SPEED_10FULL;
6148		fdpx++;
6149	}
6150	if (link & BCE_NETLINK_SPEED_100HALF)
6151		advertise |= BCE_NETLINK_SPEED_100HALF;
6152	if (link & BCE_NETLINK_SPEED_100FULL) {
6153		advertise |= BCE_NETLINK_SPEED_100FULL;
6154		fdpx++;
6155	}
6156	if (link & BCE_NETLINK_SPEED_1000HALF)
6157		advertise |= BCE_NETLINK_SPEED_1000HALF;
6158	if (link & BCE_NETLINK_SPEED_1000FULL) {
6159		advertise |= BCE_NETLINK_SPEED_1000FULL;
6160		fdpx++;
6161	}
6162	if (link & BCE_NETLINK_SPEED_2500HALF)
6163		advertise |= BCE_NETLINK_SPEED_2500HALF;
6164	if (link & BCE_NETLINK_SPEED_2500FULL) {
6165		advertise |= BCE_NETLINK_SPEED_2500FULL;
6166		fdpx++;
6167	}
6168	if (fdpx)
6169		advertise |= BCE_NETLINK_FC_PAUSE_SYM |
6170		    BCE_NETLINK_FC_PAUSE_ASYM;
6171	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
6172		advertise |= BCE_NETLINK_PHY_APP_REMOTE |
6173		    BCE_NETLINK_ETH_AT_WIRESPEED;
6174
6175	return (advertise);
6176}
6177
6178
6179/****************************************************************************/
6180/* Set media options.                                                       */
6181/*                                                                          */
6182/* Returns:                                                                 */
6183/*   0 for success, positive value for failure.                             */
6184/****************************************************************************/
6185static int
6186bce_ifmedia_upd(struct ifnet *ifp)
6187{
6188	struct bce_softc *sc = ifp->if_softc;
6189	int error;
6190
6191	DBENTER(BCE_VERBOSE);
6192
6193	BCE_LOCK(sc);
6194	error = bce_ifmedia_upd_locked(ifp);
6195	BCE_UNLOCK(sc);
6196
6197	DBEXIT(BCE_VERBOSE);
6198	return (error);
6199}
6200
6201
6202/****************************************************************************/
6203/* Set media options.                                                       */
6204/*                                                                          */
6205/* Returns:                                                                 */
6206/*   Nothing.                                                               */
6207/****************************************************************************/
6208static int
6209bce_ifmedia_upd_locked(struct ifnet *ifp)
6210{
6211	struct bce_softc *sc = ifp->if_softc;
6212	struct mii_data *mii;
6213	struct mii_softc *miisc;
6214	struct ifmedia *ifm;
6215	u32 link;
6216	int error, fdx;
6217
6218	DBENTER(BCE_VERBOSE_PHY);
6219
6220	error = 0;
6221	BCE_LOCK_ASSERT(sc);
6222
6223	sc->bce_link_up = FALSE;
6224	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
6225		ifm = &sc->bce_ifmedia;
6226		if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
6227			return (EINVAL);
6228		link = 0;
6229		fdx = IFM_OPTIONS(ifm->ifm_media) & IFM_FDX;
6230		switch(IFM_SUBTYPE(ifm->ifm_media)) {
6231		case IFM_AUTO:
6232			/*
6233			 * Check advertised link of remote PHY by reading
6234			 * BCE_RPHY_SERDES_LINK or BCE_RPHY_COPPER_LINK.
6235			 * Always use the same link type of remote PHY.
6236			 */
6237			link = bce_get_rphy_link(sc);
6238			break;
6239		case IFM_2500_SX:
6240			if ((sc->bce_phy_flags &
6241			    (BCE_PHY_REMOTE_PORT_FIBER_FLAG |
6242			    BCE_PHY_2_5G_CAPABLE_FLAG)) == 0)
6243				return (EINVAL);
6244			/*
6245			 * XXX
6246			 * Have to enable forced 2.5Gbps configuration.
6247			 */
6248			if (fdx != 0)
6249				link |= BCE_NETLINK_SPEED_2500FULL;
6250			else
6251				link |= BCE_NETLINK_SPEED_2500HALF;
6252			break;
6253		case IFM_1000_SX:
6254			if ((sc->bce_phy_flags &
6255			    BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
6256				return (EINVAL);
6257			/*
6258			 * XXX
6259			 * Have to disable 2.5Gbps configuration.
6260			 */
6261			if (fdx != 0)
6262				link = BCE_NETLINK_SPEED_1000FULL;
6263			else
6264				link = BCE_NETLINK_SPEED_1000HALF;
6265			break;
6266		case IFM_1000_T:
6267			if (sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG)
6268				return (EINVAL);
6269			if (fdx != 0)
6270				link = BCE_NETLINK_SPEED_1000FULL;
6271			else
6272				link = BCE_NETLINK_SPEED_1000HALF;
6273			break;
6274		case IFM_100_TX:
6275			if (sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG)
6276				return (EINVAL);
6277			if (fdx != 0)
6278				link = BCE_NETLINK_SPEED_100FULL;
6279			else
6280				link = BCE_NETLINK_SPEED_100HALF;
6281			break;
6282		case IFM_10_T:
6283			if (sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG)
6284				return (EINVAL);
6285			if (fdx != 0)
6286				link = BCE_NETLINK_SPEED_10FULL;
6287			else
6288				link = BCE_NETLINK_SPEED_10HALF;
6289			break;
6290		default:
6291			return (EINVAL);
6292		}
6293		if (IFM_SUBTYPE(ifm->ifm_media) != IFM_AUTO) {
6294			/*
6295			 * XXX
6296			 * Advertise pause capability for full-duplex media.
6297			 */
6298			if (fdx != 0)
6299				link |= BCE_NETLINK_FC_PAUSE_SYM |
6300				    BCE_NETLINK_FC_PAUSE_ASYM;
6301			if ((sc->bce_phy_flags &
6302			    BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
6303				link |= BCE_NETLINK_PHY_APP_REMOTE |
6304				    BCE_NETLINK_ETH_AT_WIRESPEED;
6305		}
6306
6307		bce_shmem_wr(sc, BCE_MB_ARGS_0, link);
6308		error = bce_fw_sync(sc, BCE_DRV_MSG_CODE_CMD_SET_LINK);
6309	} else {
6310		mii = device_get_softc(sc->bce_miibus);
6311
6312		/* Make sure the MII bus has been enumerated. */
6313		if (mii) {
6314			LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
6315				PHY_RESET(miisc);
6316			error = mii_mediachg(mii);
6317		}
6318	}
6319
6320	DBEXIT(BCE_VERBOSE_PHY);
6321	return (error);
6322}
6323
6324
6325static void
6326bce_ifmedia_sts_rphy(struct bce_softc *sc, struct ifmediareq *ifmr)
6327{
6328	struct ifnet *ifp;
6329	u32 link;
6330
6331	ifp = sc->bce_ifp;
6332	BCE_LOCK_ASSERT(sc);
6333
6334	ifmr->ifm_status = IFM_AVALID;
6335	ifmr->ifm_active = IFM_ETHER;
6336	link = bce_shmem_rd(sc, BCE_LINK_STATUS);
6337	/* XXX Handle heart beat status? */
6338	if ((link & BCE_LINK_STATUS_LINK_UP) != 0)
6339		ifmr->ifm_status |= IFM_ACTIVE;
6340	else {
6341		ifmr->ifm_active |= IFM_NONE;
6342		ifp->if_baudrate = 0;
6343		return;
6344	}
6345	switch (link & BCE_LINK_STATUS_SPEED_MASK) {
6346	case BCE_LINK_STATUS_10HALF:
6347		ifmr->ifm_active |= IFM_10_T | IFM_HDX;
6348		ifp->if_baudrate = IF_Mbps(10UL);
6349		break;
6350	case BCE_LINK_STATUS_10FULL:
6351		ifmr->ifm_active |= IFM_10_T | IFM_FDX;
6352		ifp->if_baudrate = IF_Mbps(10UL);
6353		break;
6354	case BCE_LINK_STATUS_100HALF:
6355		ifmr->ifm_active |= IFM_100_TX | IFM_HDX;
6356		ifp->if_baudrate = IF_Mbps(100UL);
6357		break;
6358	case BCE_LINK_STATUS_100FULL:
6359		ifmr->ifm_active |= IFM_100_TX | IFM_FDX;
6360		ifp->if_baudrate = IF_Mbps(100UL);
6361		break;
6362	case BCE_LINK_STATUS_1000HALF:
6363		if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
6364			ifmr->ifm_active |= IFM_1000_T | IFM_HDX;
6365		else
6366			ifmr->ifm_active |= IFM_1000_SX | IFM_HDX;
6367		ifp->if_baudrate = IF_Mbps(1000UL);
6368		break;
6369	case BCE_LINK_STATUS_1000FULL:
6370		if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
6371			ifmr->ifm_active |= IFM_1000_T | IFM_FDX;
6372		else
6373			ifmr->ifm_active |= IFM_1000_SX | IFM_FDX;
6374		ifp->if_baudrate = IF_Mbps(1000UL);
6375		break;
6376	case BCE_LINK_STATUS_2500HALF:
6377		if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0) {
6378			ifmr->ifm_active |= IFM_NONE;
6379			return;
6380		} else
6381			ifmr->ifm_active |= IFM_2500_SX | IFM_HDX;
6382		ifp->if_baudrate = IF_Mbps(2500UL);
6383		break;
6384	case BCE_LINK_STATUS_2500FULL:
6385		if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0) {
6386			ifmr->ifm_active |= IFM_NONE;
6387			return;
6388		} else
6389			ifmr->ifm_active |= IFM_2500_SX | IFM_FDX;
6390		ifp->if_baudrate = IF_Mbps(2500UL);
6391		break;
6392	default:
6393		ifmr->ifm_active |= IFM_NONE;
6394		return;
6395	}
6396
6397	if ((link & BCE_LINK_STATUS_RX_FC_ENABLED) != 0)
6398		ifmr->ifm_active |= IFM_ETH_RXPAUSE;
6399	if ((link & BCE_LINK_STATUS_TX_FC_ENABLED) != 0)
6400		ifmr->ifm_active |= IFM_ETH_TXPAUSE;
6401}
6402
6403
6404/****************************************************************************/
6405/* Reports current media status.                                            */
6406/*                                                                          */
6407/* Returns:                                                                 */
6408/*   Nothing.                                                               */
6409/****************************************************************************/
6410static void
6411bce_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
6412{
6413	struct bce_softc *sc = ifp->if_softc;
6414	struct mii_data *mii;
6415
6416	DBENTER(BCE_VERBOSE_PHY);
6417
6418	BCE_LOCK(sc);
6419
6420	if ((ifp->if_flags & IFF_UP) == 0) {
6421		BCE_UNLOCK(sc);
6422		return;
6423	}
6424
6425	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
6426		bce_ifmedia_sts_rphy(sc, ifmr);
6427	else {
6428		mii = device_get_softc(sc->bce_miibus);
6429		mii_pollstat(mii);
6430		ifmr->ifm_active = mii->mii_media_active;
6431		ifmr->ifm_status = mii->mii_media_status;
6432	}
6433
6434	BCE_UNLOCK(sc);
6435
6436	DBEXIT(BCE_VERBOSE_PHY);
6437}
6438
6439
6440/****************************************************************************/
6441/* Handles PHY generated interrupt events.                                  */
6442/*                                                                          */
6443/* Returns:                                                                 */
6444/*   Nothing.                                                               */
6445/****************************************************************************/
6446static void
6447bce_phy_intr(struct bce_softc *sc)
6448{
6449	u32 new_link_state, old_link_state;
6450
6451	DBENTER(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
6452
6453	DBRUN(sc->phy_interrupts++);
6454
6455	new_link_state = sc->status_block->status_attn_bits &
6456	    STATUS_ATTN_BITS_LINK_STATE;
6457	old_link_state = sc->status_block->status_attn_bits_ack &
6458	    STATUS_ATTN_BITS_LINK_STATE;
6459
6460	/* Handle any changes if the link state has changed. */
6461	if (new_link_state != old_link_state) {
6462
6463		/* Update the status_attn_bits_ack field. */
6464		if (new_link_state) {
6465			REG_WR(sc, BCE_PCICFG_STATUS_BIT_SET_CMD,
6466			    STATUS_ATTN_BITS_LINK_STATE);
6467			DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now UP.\n",
6468			    __FUNCTION__);
6469		} else {
6470			REG_WR(sc, BCE_PCICFG_STATUS_BIT_CLEAR_CMD,
6471			    STATUS_ATTN_BITS_LINK_STATE);
6472			DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now DOWN.\n",
6473			    __FUNCTION__);
6474		}
6475
6476		if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
6477			if (new_link_state) {
6478				if (bootverbose)
6479					if_printf(sc->bce_ifp, "link UP\n");
6480				if_link_state_change(sc->bce_ifp,
6481				    LINK_STATE_UP);
6482			} else {
6483				if (bootverbose)
6484					if_printf(sc->bce_ifp, "link DOWN\n");
6485				if_link_state_change(sc->bce_ifp,
6486				    LINK_STATE_DOWN);
6487			}
6488		}
6489		/*
6490		 * Assume link is down and allow
6491		 * tick routine to update the state
6492		 * based on the actual media state.
6493		 */
6494		sc->bce_link_up = FALSE;
6495		callout_stop(&sc->bce_tick_callout);
6496		bce_tick(sc);
6497	}
6498
6499	/* Acknowledge the link change interrupt. */
6500	REG_WR(sc, BCE_EMAC_STATUS, BCE_EMAC_STATUS_LINK_CHANGE);
6501
6502	DBEXIT(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
6503}
6504
6505
6506/****************************************************************************/
6507/* Reads the receive consumer value from the status block (skipping over    */
6508/* chain page pointer if necessary).                                        */
6509/*                                                                          */
6510/* Returns:                                                                 */
6511/*   hw_cons                                                                */
6512/****************************************************************************/
6513static inline u16
6514bce_get_hw_rx_cons(struct bce_softc *sc)
6515{
6516	u16 hw_cons;
6517
6518	rmb();
6519	hw_cons = sc->status_block->status_rx_quick_consumer_index0;
6520	if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
6521		hw_cons++;
6522
6523	return hw_cons;
6524}
6525
6526/****************************************************************************/
6527/* Handles received frame interrupt events.                                 */
6528/*                                                                          */
6529/* Returns:                                                                 */
6530/*   Nothing.                                                               */
6531/****************************************************************************/
6532static void
6533bce_rx_intr(struct bce_softc *sc)
6534{
6535	struct ifnet *ifp = sc->bce_ifp;
6536	struct l2_fhdr *l2fhdr;
6537	struct ether_vlan_header *vh;
6538	unsigned int pkt_len;
6539	u16 sw_rx_cons, sw_rx_cons_idx, hw_rx_cons;
6540	u32 status;
6541	unsigned int rem_len;
6542	u16 sw_pg_cons, sw_pg_cons_idx;
6543
6544	DBENTER(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
6545	DBRUN(sc->interrupts_rx++);
6546	DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): rx_prod = 0x%04X, "
6547	    "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
6548	    __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
6549
6550	/* Prepare the RX chain pages to be accessed by the host CPU. */
6551	for (int i = 0; i < sc->rx_pages; i++)
6552		bus_dmamap_sync(sc->rx_bd_chain_tag,
6553		    sc->rx_bd_chain_map[i], BUS_DMASYNC_POSTREAD);
6554
6555	/* Prepare the page chain pages to be accessed by the host CPU. */
6556	if (bce_hdr_split == TRUE) {
6557		for (int i = 0; i < sc->pg_pages; i++)
6558			bus_dmamap_sync(sc->pg_bd_chain_tag,
6559			    sc->pg_bd_chain_map[i], BUS_DMASYNC_POSTREAD);
6560	}
6561
6562	/* Get the hardware's view of the RX consumer index. */
6563	hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
6564
6565	/* Get working copies of the driver's view of the consumer indices. */
6566	sw_rx_cons = sc->rx_cons;
6567	sw_pg_cons = sc->pg_cons;
6568
6569	/* Update some debug statistics counters */
6570	DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
6571	    sc->rx_low_watermark = sc->free_rx_bd);
6572	DBRUNIF((sc->free_rx_bd == sc->max_rx_bd),
6573	    sc->rx_empty_count++);
6574
6575	/* Scan through the receive chain as long as there is work to do */
6576	/* ToDo: Consider setting a limit on the number of packets processed. */
6577	rmb();
6578	while (sw_rx_cons != hw_rx_cons) {
6579		struct mbuf *m0;
6580
6581		/* Convert the producer/consumer indices to an actual rx_bd index. */
6582		sw_rx_cons_idx = RX_CHAIN_IDX(sw_rx_cons);
6583
6584		/* Unmap the mbuf from DMA space. */
6585		bus_dmamap_sync(sc->rx_mbuf_tag,
6586		    sc->rx_mbuf_map[sw_rx_cons_idx],
6587		    BUS_DMASYNC_POSTREAD);
6588		bus_dmamap_unload(sc->rx_mbuf_tag,
6589		    sc->rx_mbuf_map[sw_rx_cons_idx]);
6590
6591		/* Remove the mbuf from the RX chain. */
6592		m0 = sc->rx_mbuf_ptr[sw_rx_cons_idx];
6593		sc->rx_mbuf_ptr[sw_rx_cons_idx] = NULL;
6594		DBRUN(sc->debug_rx_mbuf_alloc--);
6595		sc->free_rx_bd++;
6596
6597		/*
6598 		 * Frames received on the NetXteme II are prepended
6599 		 * with an l2_fhdr structure which provides status
6600 		 * information about the received frame (including
6601 		 * VLAN tags and checksum info).  The frames are
6602		 * also automatically adjusted to word align the IP
6603 		 * header (i.e. two null bytes are inserted before
6604 		 * the Ethernet	header).  As a result the data
6605 		 * DMA'd by the controller into	the mbuf looks
6606		 * like this:
6607		 *
6608		 * +---------+-----+---------------------+-----+
6609		 * | l2_fhdr | pad | packet data         | FCS |
6610		 * +---------+-----+---------------------+-----+
6611		 *
6612 		 * The l2_fhdr needs to be checked and skipped and
6613 		 * the FCS needs to be stripped before sending the
6614		 * packet up the stack.
6615		 */
6616		l2fhdr  = mtod(m0, struct l2_fhdr *);
6617
6618		/* Get the packet data + FCS length and the status. */
6619		pkt_len = l2fhdr->l2_fhdr_pkt_len;
6620		status  = l2fhdr->l2_fhdr_status;
6621
6622		/*
6623		 * Skip over the l2_fhdr and pad, resulting in the
6624		 * following data in the mbuf:
6625		 * +---------------------+-----+
6626		 * | packet data         | FCS |
6627		 * +---------------------+-----+
6628		 */
6629		m_adj(m0, sizeof(struct l2_fhdr) + ETHER_ALIGN);
6630
6631		/*
6632 		 * When split header mode is used, an ethernet frame
6633 		 * may be split across the receive chain and the
6634 		 * page chain. If that occurs an mbuf cluster must be
6635 		 * reassembled from the individual mbuf pieces.
6636		 */
6637		if (bce_hdr_split == TRUE) {
6638			/*
6639			 * Check whether the received frame fits in a single
6640			 * mbuf or not (i.e. packet data + FCS <=
6641			 * sc->rx_bd_mbuf_data_len bytes).
6642			 */
6643			if (pkt_len > m0->m_len) {
6644				/*
6645				 * The received frame is larger than a single mbuf.
6646				 * If the frame was a TCP frame then only the TCP
6647				 * header is placed in the mbuf, the remaining
6648				 * payload (including FCS) is placed in the page
6649				 * chain, the SPLIT flag is set, and the header
6650				 * length is placed in the IP checksum field.
6651				 * If the frame is not a TCP frame then the mbuf
6652				 * is filled and the remaining bytes are placed
6653				 * in the page chain.
6654				 */
6655
6656				DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a large "
6657					"packet.\n", __FUNCTION__);
6658				DBRUN(sc->split_header_frames_rcvd++);
6659
6660				/*
6661				 * When the page chain is enabled and the TCP
6662				 * header has been split from the TCP payload,
6663				 * the ip_xsum structure will reflect the length
6664				 * of the TCP header, not the IP checksum.  Set
6665				 * the packet length of the mbuf accordingly.
6666				 */
6667				if (status & L2_FHDR_STATUS_SPLIT) {
6668					m0->m_len = l2fhdr->l2_fhdr_ip_xsum;
6669					DBRUN(sc->split_header_tcp_frames_rcvd++);
6670				}
6671
6672				rem_len = pkt_len - m0->m_len;
6673
6674				/* Pull mbufs off the page chain for any remaining data. */
6675				while (rem_len > 0) {
6676					struct mbuf *m_pg;
6677
6678					sw_pg_cons_idx = PG_CHAIN_IDX(sw_pg_cons);
6679
6680					/* Remove the mbuf from the page chain. */
6681					m_pg = sc->pg_mbuf_ptr[sw_pg_cons_idx];
6682					sc->pg_mbuf_ptr[sw_pg_cons_idx] = NULL;
6683					DBRUN(sc->debug_pg_mbuf_alloc--);
6684					sc->free_pg_bd++;
6685
6686					/* Unmap the page chain mbuf from DMA space. */
6687					bus_dmamap_sync(sc->pg_mbuf_tag,
6688						sc->pg_mbuf_map[sw_pg_cons_idx],
6689						BUS_DMASYNC_POSTREAD);
6690					bus_dmamap_unload(sc->pg_mbuf_tag,
6691						sc->pg_mbuf_map[sw_pg_cons_idx]);
6692
6693					/* Adjust the mbuf length. */
6694					if (rem_len < m_pg->m_len) {
6695						/* The mbuf chain is complete. */
6696						m_pg->m_len = rem_len;
6697						rem_len = 0;
6698					} else {
6699						/* More packet data is waiting. */
6700						rem_len -= m_pg->m_len;
6701					}
6702
6703					/* Concatenate the mbuf cluster to the mbuf. */
6704					m_cat(m0, m_pg);
6705
6706					sw_pg_cons = NEXT_PG_BD(sw_pg_cons);
6707				}
6708
6709				/* Set the total packet length. */
6710				m0->m_pkthdr.len = pkt_len;
6711
6712			} else {
6713				/*
6714				 * The received packet is small and fits in a
6715				 * single mbuf (i.e. the l2_fhdr + pad + packet +
6716				 * FCS <= MHLEN).  In other words, the packet is
6717				 * 154 bytes or less in size.
6718				 */
6719
6720				DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a small "
6721					"packet.\n", __FUNCTION__);
6722
6723				/* Set the total packet length. */
6724				m0->m_pkthdr.len = m0->m_len = pkt_len;
6725			}
6726		} else
6727			/* Set the total packet length. */
6728			m0->m_pkthdr.len = m0->m_len = pkt_len;
6729
6730		/* Remove the trailing Ethernet FCS. */
6731		m_adj(m0, -ETHER_CRC_LEN);
6732
6733		/* Check that the resulting mbuf chain is valid. */
6734		DBRUN(m_sanity(m0, FALSE));
6735		DBRUNIF(((m0->m_len < ETHER_HDR_LEN) |
6736		    (m0->m_pkthdr.len > BCE_MAX_JUMBO_ETHER_MTU_VLAN)),
6737		    BCE_PRINTF("Invalid Ethernet frame size!\n");
6738		    m_print(m0, 128));
6739
6740		DBRUNIF(DB_RANDOMTRUE(l2fhdr_error_sim_control),
6741		    sc->l2fhdr_error_sim_count++;
6742		    status = status | L2_FHDR_ERRORS_PHY_DECODE);
6743
6744		/* Check the received frame for errors. */
6745		if (status & (L2_FHDR_ERRORS_BAD_CRC |
6746		    L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT |
6747		    L2_FHDR_ERRORS_TOO_SHORT  | L2_FHDR_ERRORS_GIANT_FRAME)) {
6748
6749			/* Log the error and release the mbuf. */
6750			ifp->if_ierrors++;
6751			sc->l2fhdr_error_count++;
6752
6753			m_freem(m0);
6754			m0 = NULL;
6755			goto bce_rx_intr_next_rx;
6756		}
6757
6758		/* Send the packet to the appropriate interface. */
6759		m0->m_pkthdr.rcvif = ifp;
6760
6761		/* Assume no hardware checksum. */
6762		m0->m_pkthdr.csum_flags = 0;
6763
6764		/* Validate the checksum if offload enabled. */
6765		if (ifp->if_capenable & IFCAP_RXCSUM) {
6766			/* Check for an IP datagram. */
6767		 	if (!(status & L2_FHDR_STATUS_SPLIT) &&
6768			    (status & L2_FHDR_STATUS_IP_DATAGRAM)) {
6769				m0->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
6770				DBRUN(sc->csum_offload_ip++);
6771				/* Check if the IP checksum is valid. */
6772				if ((l2fhdr->l2_fhdr_ip_xsum ^ 0xffff) == 0)
6773					m0->m_pkthdr.csum_flags |=
6774					    CSUM_IP_VALID;
6775			}
6776
6777			/* Check for a valid TCP/UDP frame. */
6778			if (status & (L2_FHDR_STATUS_TCP_SEGMENT |
6779			    L2_FHDR_STATUS_UDP_DATAGRAM)) {
6780
6781				/* Check for a good TCP/UDP checksum. */
6782				if ((status & (L2_FHDR_ERRORS_TCP_XSUM |
6783				    L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
6784					DBRUN(sc->csum_offload_tcp_udp++);
6785					m0->m_pkthdr.csum_data =
6786					    l2fhdr->l2_fhdr_tcp_udp_xsum;
6787					m0->m_pkthdr.csum_flags |=
6788					    (CSUM_DATA_VALID
6789					    | CSUM_PSEUDO_HDR);
6790				}
6791			}
6792		}
6793
6794		/* Attach the VLAN tag.	*/
6795		if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) &&
6796		    !(sc->rx_mode & BCE_EMAC_RX_MODE_KEEP_VLAN_TAG)) {
6797			DBRUN(sc->vlan_tagged_frames_rcvd++);
6798			if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
6799				DBRUN(sc->vlan_tagged_frames_stripped++);
6800#if __FreeBSD_version < 700000
6801				VLAN_INPUT_TAG(ifp, m0,
6802				    l2fhdr->l2_fhdr_vlan_tag, continue);
6803#else
6804				m0->m_pkthdr.ether_vtag =
6805				    l2fhdr->l2_fhdr_vlan_tag;
6806				m0->m_flags |= M_VLANTAG;
6807#endif
6808			} else {
6809				/*
6810				 * bce(4) controllers can't disable VLAN
6811				 * tag stripping if management firmware
6812				 * (ASF/IPMI/UMP) is running. So we always
6813				 * strip VLAN tag and manually reconstruct
6814				 * the VLAN frame by appending stripped
6815				 * VLAN tag in driver if VLAN tag stripping
6816				 * was disabled.
6817				 *
6818				 * TODO: LLC SNAP handling.
6819				 */
6820				bcopy(mtod(m0, uint8_t *),
6821				    mtod(m0, uint8_t *) - ETHER_VLAN_ENCAP_LEN,
6822				    ETHER_ADDR_LEN * 2);
6823				m0->m_data -= ETHER_VLAN_ENCAP_LEN;
6824				vh = mtod(m0, struct ether_vlan_header *);
6825				vh->evl_encap_proto = htons(ETHERTYPE_VLAN);
6826				vh->evl_tag = htons(l2fhdr->l2_fhdr_vlan_tag);
6827				m0->m_pkthdr.len += ETHER_VLAN_ENCAP_LEN;
6828				m0->m_len += ETHER_VLAN_ENCAP_LEN;
6829			}
6830		}
6831
6832		/* Increment received packet statistics. */
6833		ifp->if_ipackets++;
6834
6835bce_rx_intr_next_rx:
6836		sw_rx_cons = NEXT_RX_BD(sw_rx_cons);
6837
6838		/* If we have a packet, pass it up the stack */
6839		if (m0) {
6840			/* Make sure we don't lose our place when we release the lock. */
6841			sc->rx_cons = sw_rx_cons;
6842			sc->pg_cons = sw_pg_cons;
6843
6844			BCE_UNLOCK(sc);
6845			(*ifp->if_input)(ifp, m0);
6846			BCE_LOCK(sc);
6847
6848			/* Recover our place. */
6849			sw_rx_cons = sc->rx_cons;
6850			sw_pg_cons = sc->pg_cons;
6851		}
6852
6853		/* Refresh hw_cons to see if there's new work */
6854		if (sw_rx_cons == hw_rx_cons)
6855			hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
6856	}
6857
6858	/* No new packets.  Refill the page chain. */
6859	if (bce_hdr_split == TRUE) {
6860		sc->pg_cons = sw_pg_cons;
6861		bce_fill_pg_chain(sc);
6862	}
6863
6864	/* No new packets.  Refill the RX chain. */
6865	sc->rx_cons = sw_rx_cons;
6866	bce_fill_rx_chain(sc);
6867
6868	/* Prepare the page chain pages to be accessed by the NIC. */
6869	for (int i = 0; i < sc->rx_pages; i++)
6870		bus_dmamap_sync(sc->rx_bd_chain_tag,
6871		    sc->rx_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
6872
6873	if (bce_hdr_split == TRUE) {
6874		for (int i = 0; i < sc->pg_pages; i++)
6875			bus_dmamap_sync(sc->pg_bd_chain_tag,
6876			    sc->pg_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
6877	}
6878
6879	DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): rx_prod = 0x%04X, "
6880	    "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
6881	    __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
6882	DBEXIT(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
6883}
6884
6885
6886/****************************************************************************/
6887/* Reads the transmit consumer value from the status block (skipping over   */
6888/* chain page pointer if necessary).                                        */
6889/*                                                                          */
6890/* Returns:                                                                 */
6891/*   hw_cons                                                                */
6892/****************************************************************************/
6893static inline u16
6894bce_get_hw_tx_cons(struct bce_softc *sc)
6895{
6896	u16 hw_cons;
6897
6898	mb();
6899	hw_cons = sc->status_block->status_tx_quick_consumer_index0;
6900	if ((hw_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
6901		hw_cons++;
6902
6903	return hw_cons;
6904}
6905
6906
6907/****************************************************************************/
6908/* Handles transmit completion interrupt events.                            */
6909/*                                                                          */
6910/* Returns:                                                                 */
6911/*   Nothing.                                                               */
6912/****************************************************************************/
6913static void
6914bce_tx_intr(struct bce_softc *sc)
6915{
6916	struct ifnet *ifp = sc->bce_ifp;
6917	u16 hw_tx_cons, sw_tx_cons, sw_tx_chain_cons;
6918
6919	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
6920	DBRUN(sc->interrupts_tx++);
6921	DBPRINT(sc, BCE_EXTREME_SEND, "%s(enter): tx_prod = 0x%04X, "
6922	    "tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
6923	    __FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
6924
6925	BCE_LOCK_ASSERT(sc);
6926
6927	/* Get the hardware's view of the TX consumer index. */
6928	hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
6929	sw_tx_cons = sc->tx_cons;
6930
6931	/* Prevent speculative reads of the status block. */
6932	bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
6933	    BUS_SPACE_BARRIER_READ);
6934
6935	/* Cycle through any completed TX chain page entries. */
6936	while (sw_tx_cons != hw_tx_cons) {
6937#ifdef BCE_DEBUG
6938		struct tx_bd *txbd = NULL;
6939#endif
6940		sw_tx_chain_cons = TX_CHAIN_IDX(sw_tx_cons);
6941
6942		DBPRINT(sc, BCE_INFO_SEND,
6943		    "%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, "
6944		    "sw_tx_chain_cons = 0x%04X\n",
6945		    __FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
6946
6947		DBRUNIF((sw_tx_chain_cons > MAX_TX_BD_ALLOC),
6948		    BCE_PRINTF("%s(%d): TX chain consumer out of range! "
6949		    " 0x%04X > 0x%04X\n", __FILE__, __LINE__, sw_tx_chain_cons,
6950		    (int) MAX_TX_BD_ALLOC);
6951		    bce_breakpoint(sc));
6952
6953		DBRUN(txbd = &sc->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)]
6954		    [TX_IDX(sw_tx_chain_cons)]);
6955
6956		DBRUNIF((txbd == NULL),
6957		    BCE_PRINTF("%s(%d): Unexpected NULL tx_bd[0x%04X]!\n",
6958		    __FILE__, __LINE__, sw_tx_chain_cons);
6959		    bce_breakpoint(sc));
6960
6961		DBRUNMSG(BCE_INFO_SEND, BCE_PRINTF("%s(): ", __FUNCTION__);
6962		    bce_dump_txbd(sc, sw_tx_chain_cons, txbd));
6963
6964		/*
6965		 * Free the associated mbuf. Remember
6966		 * that only the last tx_bd of a packet
6967		 * has an mbuf pointer and DMA map.
6968		 */
6969		if (sc->tx_mbuf_ptr[sw_tx_chain_cons] != NULL) {
6970
6971			/* Validate that this is the last tx_bd. */
6972			DBRUNIF((!(txbd->tx_bd_flags & TX_BD_FLAGS_END)),
6973			    BCE_PRINTF("%s(%d): tx_bd END flag not set but "
6974			    "txmbuf == NULL!\n", __FILE__, __LINE__);
6975			    bce_breakpoint(sc));
6976
6977			DBRUNMSG(BCE_INFO_SEND,
6978			    BCE_PRINTF("%s(): Unloading map/freeing mbuf "
6979			    "from tx_bd[0x%04X]\n", __FUNCTION__,
6980			    sw_tx_chain_cons));
6981
6982			/* Unmap the mbuf. */
6983			bus_dmamap_unload(sc->tx_mbuf_tag,
6984			    sc->tx_mbuf_map[sw_tx_chain_cons]);
6985
6986			/* Free the mbuf. */
6987			m_freem(sc->tx_mbuf_ptr[sw_tx_chain_cons]);
6988			sc->tx_mbuf_ptr[sw_tx_chain_cons] = NULL;
6989			DBRUN(sc->debug_tx_mbuf_alloc--);
6990
6991			ifp->if_opackets++;
6992		}
6993
6994		sc->used_tx_bd--;
6995		sw_tx_cons = NEXT_TX_BD(sw_tx_cons);
6996
6997		/* Refresh hw_cons to see if there's new work. */
6998		hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
6999
7000		/* Prevent speculative reads of the status block. */
7001		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
7002		    BUS_SPACE_BARRIER_READ);
7003	}
7004
7005	/* Clear the TX timeout timer. */
7006	sc->watchdog_timer = 0;
7007
7008	/* Clear the tx hardware queue full flag. */
7009	if (sc->used_tx_bd < sc->max_tx_bd) {
7010		DBRUNIF((ifp->if_drv_flags & IFF_DRV_OACTIVE),
7011		    DBPRINT(sc, BCE_INFO_SEND,
7012		    "%s(): Open TX chain! %d/%d (used/total)\n",
7013		    __FUNCTION__, sc->used_tx_bd, sc->max_tx_bd));
7014		ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
7015	}
7016
7017	sc->tx_cons = sw_tx_cons;
7018
7019	DBPRINT(sc, BCE_EXTREME_SEND, "%s(exit): tx_prod = 0x%04X, "
7020	    "tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
7021	    __FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
7022	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
7023}
7024
7025
7026/****************************************************************************/
7027/* Disables interrupt generation.                                           */
7028/*                                                                          */
7029/* Returns:                                                                 */
7030/*   Nothing.                                                               */
7031/****************************************************************************/
7032static void
7033bce_disable_intr(struct bce_softc *sc)
7034{
7035	DBENTER(BCE_VERBOSE_INTR);
7036
7037	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_MASK_INT);
7038	REG_RD(sc, BCE_PCICFG_INT_ACK_CMD);
7039
7040	DBEXIT(BCE_VERBOSE_INTR);
7041}
7042
7043
7044/****************************************************************************/
7045/* Enables interrupt generation.                                            */
7046/*                                                                          */
7047/* Returns:                                                                 */
7048/*   Nothing.                                                               */
7049/****************************************************************************/
7050static void
7051bce_enable_intr(struct bce_softc *sc, int coal_now)
7052{
7053	DBENTER(BCE_VERBOSE_INTR);
7054
7055	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
7056	    BCE_PCICFG_INT_ACK_CMD_INDEX_VALID |
7057	    BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
7058
7059	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
7060	    BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
7061
7062	/* Force an immediate interrupt (whether there is new data or not). */
7063	if (coal_now)
7064		REG_WR(sc, BCE_HC_COMMAND, sc->hc_command | BCE_HC_COMMAND_COAL_NOW);
7065
7066	DBEXIT(BCE_VERBOSE_INTR);
7067}
7068
7069
7070/****************************************************************************/
7071/* Handles controller initialization.                                       */
7072/*                                                                          */
7073/* Returns:                                                                 */
7074/*   Nothing.                                                               */
7075/****************************************************************************/
7076static void
7077bce_init_locked(struct bce_softc *sc)
7078{
7079	struct ifnet *ifp;
7080	u32 ether_mtu = 0;
7081
7082	DBENTER(BCE_VERBOSE_RESET);
7083
7084	BCE_LOCK_ASSERT(sc);
7085
7086	ifp = sc->bce_ifp;
7087
7088	/* Check if the driver is still running and bail out if it is. */
7089	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
7090		goto bce_init_locked_exit;
7091
7092	bce_stop(sc);
7093
7094	if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
7095		BCE_PRINTF("%s(%d): Controller reset failed!\n",
7096		    __FILE__, __LINE__);
7097		goto bce_init_locked_exit;
7098	}
7099
7100	if (bce_chipinit(sc)) {
7101		BCE_PRINTF("%s(%d): Controller initialization failed!\n",
7102		    __FILE__, __LINE__);
7103		goto bce_init_locked_exit;
7104	}
7105
7106	if (bce_blockinit(sc)) {
7107		BCE_PRINTF("%s(%d): Block initialization failed!\n",
7108		    __FILE__, __LINE__);
7109		goto bce_init_locked_exit;
7110	}
7111
7112	/* Load our MAC address. */
7113	bcopy(IF_LLADDR(sc->bce_ifp), sc->eaddr, ETHER_ADDR_LEN);
7114	bce_set_mac_addr(sc);
7115
7116	if (bce_hdr_split == FALSE)
7117		bce_get_rx_buffer_sizes(sc, ifp->if_mtu);
7118	/*
7119	 * Calculate and program the hardware Ethernet MTU
7120 	 * size. Be generous on the receive if we have room
7121 	 * and allowed by the user.
7122	 */
7123	if (bce_strict_rx_mtu == TRUE)
7124		ether_mtu = ifp->if_mtu;
7125	else {
7126		if (bce_hdr_split == TRUE) {
7127			if (ifp->if_mtu <= sc->rx_bd_mbuf_data_len + MCLBYTES)
7128				ether_mtu = sc->rx_bd_mbuf_data_len +
7129				    MCLBYTES;
7130			else
7131				ether_mtu = ifp->if_mtu;
7132		} else {
7133			if (ifp->if_mtu <= sc->rx_bd_mbuf_data_len)
7134				ether_mtu = sc->rx_bd_mbuf_data_len;
7135			else
7136				ether_mtu = ifp->if_mtu;
7137		}
7138	}
7139
7140	ether_mtu += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN;
7141
7142	DBPRINT(sc, BCE_INFO_MISC, "%s(): setting h/w mtu = %d\n",
7143	    __FUNCTION__, ether_mtu);
7144
7145	/* Program the mtu, enabling jumbo frame support if necessary. */
7146	if (ether_mtu > (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN))
7147		REG_WR(sc, BCE_EMAC_RX_MTU_SIZE,
7148		    min(ether_mtu, BCE_MAX_JUMBO_ETHER_MTU) |
7149		    BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA);
7150	else
7151		REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu);
7152
7153	/* Program appropriate promiscuous/multicast filtering. */
7154	bce_set_rx_mode(sc);
7155
7156	if (bce_hdr_split == TRUE) {
7157		/* Init page buffer descriptor chain. */
7158		bce_init_pg_chain(sc);
7159	}
7160
7161	/* Init RX buffer descriptor chain. */
7162	bce_init_rx_chain(sc);
7163
7164	/* Init TX buffer descriptor chain. */
7165	bce_init_tx_chain(sc);
7166
7167	/* Enable host interrupts. */
7168	bce_enable_intr(sc, 1);
7169
7170	bce_ifmedia_upd_locked(ifp);
7171
7172	/* Let the OS know the driver is up and running. */
7173	ifp->if_drv_flags |= IFF_DRV_RUNNING;
7174	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
7175
7176	callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
7177
7178bce_init_locked_exit:
7179	DBEXIT(BCE_VERBOSE_RESET);
7180}
7181
7182
7183/****************************************************************************/
7184/* Initialize the controller just enough so that any management firmware    */
7185/* running on the device will continue to operate correctly.                */
7186/*                                                                          */
7187/* Returns:                                                                 */
7188/*   Nothing.                                                               */
7189/****************************************************************************/
7190static void
7191bce_mgmt_init_locked(struct bce_softc *sc)
7192{
7193	struct ifnet *ifp;
7194
7195	DBENTER(BCE_VERBOSE_RESET);
7196
7197	BCE_LOCK_ASSERT(sc);
7198
7199	/* Bail out if management firmware is not running. */
7200	if (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)) {
7201		DBPRINT(sc, BCE_VERBOSE_SPECIAL,
7202		    "No management firmware running...\n");
7203		goto bce_mgmt_init_locked_exit;
7204	}
7205
7206	ifp = sc->bce_ifp;
7207
7208	/* Enable all critical blocks in the MAC. */
7209	REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT);
7210	REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
7211	DELAY(20);
7212
7213	bce_ifmedia_upd_locked(ifp);
7214
7215bce_mgmt_init_locked_exit:
7216	DBEXIT(BCE_VERBOSE_RESET);
7217}
7218
7219
7220/****************************************************************************/
7221/* Handles controller initialization when called from an unlocked routine.  */
7222/*                                                                          */
7223/* Returns:                                                                 */
7224/*   Nothing.                                                               */
7225/****************************************************************************/
7226static void
7227bce_init(void *xsc)
7228{
7229	struct bce_softc *sc = xsc;
7230
7231	DBENTER(BCE_VERBOSE_RESET);
7232
7233	BCE_LOCK(sc);
7234	bce_init_locked(sc);
7235	BCE_UNLOCK(sc);
7236
7237	DBEXIT(BCE_VERBOSE_RESET);
7238}
7239
7240
7241/****************************************************************************/
7242/* Modifies an mbuf for TSO on the hardware.                                */
7243/*                                                                          */
7244/* Returns:                                                                 */
7245/*   Pointer to a modified mbuf.                                            */
7246/****************************************************************************/
7247static struct mbuf *
7248bce_tso_setup(struct bce_softc *sc, struct mbuf **m_head, u16 *flags)
7249{
7250	struct mbuf *m;
7251	struct ether_header *eh;
7252	struct ip *ip;
7253	struct tcphdr *th;
7254	u16 etype;
7255	int hdr_len, ip_hlen = 0, tcp_hlen = 0, ip_len = 0;
7256
7257	DBRUN(sc->tso_frames_requested++);
7258
7259	/* Controller may modify mbuf chains. */
7260	if (M_WRITABLE(*m_head) == 0) {
7261		m = m_dup(*m_head, M_NOWAIT);
7262		m_freem(*m_head);
7263		if (m == NULL) {
7264			sc->mbuf_alloc_failed_count++;
7265			*m_head = NULL;
7266			return (NULL);
7267		}
7268		*m_head = m;
7269	}
7270
7271	/*
7272	 * For TSO the controller needs two pieces of info,
7273	 * the MSS and the IP+TCP options length.
7274	 */
7275	m = m_pullup(*m_head, sizeof(struct ether_header) + sizeof(struct ip));
7276	if (m == NULL) {
7277		*m_head = NULL;
7278		return (NULL);
7279	}
7280	eh = mtod(m, struct ether_header *);
7281	etype = ntohs(eh->ether_type);
7282
7283	/* Check for supported TSO Ethernet types (only IPv4 for now) */
7284	switch (etype) {
7285	case ETHERTYPE_IP:
7286		ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
7287		/* TSO only supported for TCP protocol. */
7288		if (ip->ip_p != IPPROTO_TCP) {
7289			BCE_PRINTF("%s(%d): TSO enabled for non-TCP frame!.\n",
7290			    __FILE__, __LINE__);
7291			m_freem(*m_head);
7292			*m_head = NULL;
7293			return (NULL);
7294		}
7295
7296		/* Get IP header length in bytes (min 20) */
7297		ip_hlen = ip->ip_hl << 2;
7298		m = m_pullup(*m_head, sizeof(struct ether_header) + ip_hlen +
7299		    sizeof(struct tcphdr));
7300		if (m == NULL) {
7301			*m_head = NULL;
7302			return (NULL);
7303		}
7304
7305		/* Get the TCP header length in bytes (min 20) */
7306		ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
7307		th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
7308		tcp_hlen = (th->th_off << 2);
7309
7310		/* Make sure all IP/TCP options live in the same buffer. */
7311		m = m_pullup(*m_head,  sizeof(struct ether_header)+ ip_hlen +
7312		    tcp_hlen);
7313		if (m == NULL) {
7314			*m_head = NULL;
7315			return (NULL);
7316		}
7317
7318		/* Clear IP header length and checksum, will be calc'd by h/w. */
7319		ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
7320		ip_len = ip->ip_len;
7321		ip->ip_len = 0;
7322		ip->ip_sum = 0;
7323		break;
7324	case ETHERTYPE_IPV6:
7325		BCE_PRINTF("%s(%d): TSO over IPv6 not supported!.\n",
7326		    __FILE__, __LINE__);
7327		m_freem(*m_head);
7328		*m_head = NULL;
7329		return (NULL);
7330		/* NOT REACHED */
7331	default:
7332		BCE_PRINTF("%s(%d): TSO enabled for unsupported protocol!.\n",
7333		    __FILE__, __LINE__);
7334		m_freem(*m_head);
7335		*m_head = NULL;
7336		return (NULL);
7337	}
7338
7339	hdr_len = sizeof(struct ether_header) + ip_hlen + tcp_hlen;
7340
7341	DBPRINT(sc, BCE_EXTREME_SEND, "%s(): hdr_len = %d, e_hlen = %d, "
7342	    "ip_hlen = %d, tcp_hlen = %d, ip_len = %d\n",
7343	    __FUNCTION__, hdr_len, (int) sizeof(struct ether_header), ip_hlen,
7344	    tcp_hlen, ip_len);
7345
7346	/* Set the LSO flag in the TX BD */
7347	*flags |= TX_BD_FLAGS_SW_LSO;
7348
7349	/* Set the length of IP + TCP options (in 32 bit words) */
7350	*flags |= (((ip_hlen + tcp_hlen - sizeof(struct ip) -
7351	    sizeof(struct tcphdr)) >> 2) << 8);
7352
7353	DBRUN(sc->tso_frames_completed++);
7354	return (*m_head);
7355}
7356
7357
7358/****************************************************************************/
7359/* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
7360/* memory visible to the controller.                                        */
7361/*                                                                          */
7362/* Returns:                                                                 */
7363/*   0 for success, positive value for failure.                             */
7364/* Modified:                                                                */
7365/*   m_head: May be set to NULL if MBUF is excessively fragmented.          */
7366/****************************************************************************/
7367static int
7368bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
7369{
7370	bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
7371	bus_dmamap_t map;
7372	struct tx_bd *txbd = NULL;
7373	struct mbuf *m0;
7374	u16 prod, chain_prod, mss = 0, vlan_tag = 0, flags = 0;
7375	u32 prod_bseq;
7376
7377#ifdef BCE_DEBUG
7378	u16 debug_prod;
7379#endif
7380
7381	int i, error, nsegs, rc = 0;
7382
7383	DBENTER(BCE_VERBOSE_SEND);
7384
7385	/* Make sure we have room in the TX chain. */
7386	if (sc->used_tx_bd >= sc->max_tx_bd)
7387		goto bce_tx_encap_exit;
7388
7389	/* Transfer any checksum offload flags to the bd. */
7390	m0 = *m_head;
7391	if (m0->m_pkthdr.csum_flags) {
7392		if (m0->m_pkthdr.csum_flags & CSUM_TSO) {
7393			m0 = bce_tso_setup(sc, m_head, &flags);
7394			if (m0 == NULL) {
7395				DBRUN(sc->tso_frames_failed++);
7396				goto bce_tx_encap_exit;
7397			}
7398			mss = htole16(m0->m_pkthdr.tso_segsz);
7399		} else {
7400			if (m0->m_pkthdr.csum_flags & CSUM_IP)
7401				flags |= TX_BD_FLAGS_IP_CKSUM;
7402			if (m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
7403				flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
7404		}
7405	}
7406
7407	/* Transfer any VLAN tags to the bd. */
7408	if (m0->m_flags & M_VLANTAG) {
7409		flags |= TX_BD_FLAGS_VLAN_TAG;
7410		vlan_tag = m0->m_pkthdr.ether_vtag;
7411	}
7412
7413	/* Map the mbuf into DMAable memory. */
7414	prod = sc->tx_prod;
7415	chain_prod = TX_CHAIN_IDX(prod);
7416	map = sc->tx_mbuf_map[chain_prod];
7417
7418	/* Map the mbuf into our DMA address space. */
7419	error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag, map, m0,
7420	    segs, &nsegs, BUS_DMA_NOWAIT);
7421
7422	/* Check if the DMA mapping was successful */
7423	if (error == EFBIG) {
7424		sc->mbuf_frag_count++;
7425
7426		/* Try to defrag the mbuf. */
7427		m0 = m_collapse(*m_head, M_NOWAIT, BCE_MAX_SEGMENTS);
7428		if (m0 == NULL) {
7429			/* Defrag was unsuccessful */
7430			m_freem(*m_head);
7431			*m_head = NULL;
7432			sc->mbuf_alloc_failed_count++;
7433			rc = ENOBUFS;
7434			goto bce_tx_encap_exit;
7435		}
7436
7437		/* Defrag was successful, try mapping again */
7438		*m_head = m0;
7439		error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag,
7440		    map, m0, segs, &nsegs, BUS_DMA_NOWAIT);
7441
7442		/* Still getting an error after a defrag. */
7443		if (error == ENOMEM) {
7444			/* Insufficient DMA buffers available. */
7445			sc->dma_map_addr_tx_failed_count++;
7446			rc = error;
7447			goto bce_tx_encap_exit;
7448		} else if (error != 0) {
7449			/* Release it and return an error. */
7450			BCE_PRINTF("%s(%d): Unknown error mapping mbuf into "
7451			    "TX chain!\n", __FILE__, __LINE__);
7452			m_freem(m0);
7453			*m_head = NULL;
7454			sc->dma_map_addr_tx_failed_count++;
7455			rc = ENOBUFS;
7456			goto bce_tx_encap_exit;
7457		}
7458	} else if (error == ENOMEM) {
7459		/* Insufficient DMA buffers available. */
7460		sc->dma_map_addr_tx_failed_count++;
7461		rc = error;
7462		goto bce_tx_encap_exit;
7463	} else if (error != 0) {
7464		m_freem(m0);
7465		*m_head = NULL;
7466		sc->dma_map_addr_tx_failed_count++;
7467		rc = error;
7468		goto bce_tx_encap_exit;
7469	}
7470
7471	/* Make sure there's room in the chain */
7472	if (nsegs > (sc->max_tx_bd - sc->used_tx_bd)) {
7473		bus_dmamap_unload(sc->tx_mbuf_tag, map);
7474		rc = ENOBUFS;
7475		goto bce_tx_encap_exit;
7476	}
7477
7478	/* prod points to an empty tx_bd at this point. */
7479	prod_bseq  = sc->tx_prod_bseq;
7480
7481#ifdef BCE_DEBUG
7482	debug_prod = chain_prod;
7483#endif
7484
7485	DBPRINT(sc, BCE_INFO_SEND,
7486	    "%s(start): prod = 0x%04X, chain_prod = 0x%04X, "
7487	    "prod_bseq = 0x%08X\n",
7488	    __FUNCTION__, prod, chain_prod, prod_bseq);
7489
7490	/*
7491	 * Cycle through each mbuf segment that makes up
7492	 * the outgoing frame, gathering the mapping info
7493	 * for that segment and creating a tx_bd for
7494	 * the mbuf.
7495	 */
7496	for (i = 0; i < nsegs ; i++) {
7497
7498		chain_prod = TX_CHAIN_IDX(prod);
7499		txbd= &sc->tx_bd_chain[TX_PAGE(chain_prod)]
7500		    [TX_IDX(chain_prod)];
7501
7502		txbd->tx_bd_haddr_lo =
7503		    htole32(BCE_ADDR_LO(segs[i].ds_addr));
7504		txbd->tx_bd_haddr_hi =
7505		    htole32(BCE_ADDR_HI(segs[i].ds_addr));
7506		txbd->tx_bd_mss_nbytes = htole32(mss << 16) |
7507		    htole16(segs[i].ds_len);
7508		txbd->tx_bd_vlan_tag = htole16(vlan_tag);
7509		txbd->tx_bd_flags = htole16(flags);
7510		prod_bseq += segs[i].ds_len;
7511		if (i == 0)
7512			txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_START);
7513		prod = NEXT_TX_BD(prod);
7514	}
7515
7516	/* Set the END flag on the last TX buffer descriptor. */
7517	txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_END);
7518
7519	DBRUNMSG(BCE_EXTREME_SEND,
7520	    bce_dump_tx_chain(sc, debug_prod, nsegs));
7521
7522	/*
7523	 * Ensure that the mbuf pointer for this transmission
7524	 * is placed at the array index of the last
7525	 * descriptor in this chain.  This is done
7526	 * because a single map is used for all
7527	 * segments of the mbuf and we don't want to
7528	 * unload the map before all of the segments
7529	 * have been freed.
7530	 */
7531	sc->tx_mbuf_ptr[chain_prod] = m0;
7532	sc->used_tx_bd += nsegs;
7533
7534	/* Update some debug statistic counters */
7535	DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
7536	    sc->tx_hi_watermark = sc->used_tx_bd);
7537	DBRUNIF((sc->used_tx_bd == sc->max_tx_bd), sc->tx_full_count++);
7538	DBRUNIF(sc->debug_tx_mbuf_alloc++);
7539
7540	DBRUNMSG(BCE_EXTREME_SEND, bce_dump_tx_mbuf_chain(sc, chain_prod, 1));
7541
7542	/* prod points to the next free tx_bd at this point. */
7543	sc->tx_prod = prod;
7544	sc->tx_prod_bseq = prod_bseq;
7545
7546	/* Tell the chip about the waiting TX frames. */
7547	REG_WR16(sc, MB_GET_CID_ADDR(TX_CID) +
7548	    BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
7549	REG_WR(sc, MB_GET_CID_ADDR(TX_CID) +
7550	    BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
7551
7552bce_tx_encap_exit:
7553	DBEXIT(BCE_VERBOSE_SEND);
7554	return(rc);
7555}
7556
7557
7558/****************************************************************************/
7559/* Main transmit routine when called from another routine with a lock.      */
7560/*                                                                          */
7561/* Returns:                                                                 */
7562/*   Nothing.                                                               */
7563/****************************************************************************/
7564static void
7565bce_start_locked(struct ifnet *ifp)
7566{
7567	struct bce_softc *sc = ifp->if_softc;
7568	struct mbuf *m_head = NULL;
7569	int count = 0;
7570	u16 tx_prod, tx_chain_prod;
7571
7572	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
7573
7574	BCE_LOCK_ASSERT(sc);
7575
7576	/* prod points to the next free tx_bd. */
7577	tx_prod = sc->tx_prod;
7578	tx_chain_prod = TX_CHAIN_IDX(tx_prod);
7579
7580	DBPRINT(sc, BCE_INFO_SEND,
7581	    "%s(enter): tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
7582	    "tx_prod_bseq = 0x%08X\n",
7583	    __FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
7584
7585	/* If there's no link or the transmit queue is empty then just exit. */
7586	if (sc->bce_link_up == FALSE) {
7587		DBPRINT(sc, BCE_INFO_SEND, "%s(): No link.\n",
7588		    __FUNCTION__);
7589		goto bce_start_locked_exit;
7590	}
7591
7592	if (IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
7593		DBPRINT(sc, BCE_INFO_SEND, "%s(): Transmit queue empty.\n",
7594		    __FUNCTION__);
7595		goto bce_start_locked_exit;
7596	}
7597
7598	/*
7599	 * Keep adding entries while there is space in the ring.
7600	 */
7601	while (sc->used_tx_bd < sc->max_tx_bd) {
7602
7603		/* Check for any frames to send. */
7604		IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
7605
7606		/* Stop when the transmit queue is empty. */
7607		if (m_head == NULL)
7608			break;
7609
7610		/*
7611		 * Pack the data into the transmit ring. If we
7612		 * don't have room, place the mbuf back at the
7613		 * head of the queue and set the OACTIVE flag
7614		 * to wait for the NIC to drain the chain.
7615		 */
7616		if (bce_tx_encap(sc, &m_head)) {
7617			if (m_head != NULL)
7618				IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
7619			ifp->if_drv_flags |= IFF_DRV_OACTIVE;
7620			DBPRINT(sc, BCE_INFO_SEND,
7621			    "TX chain is closed for business! Total "
7622			    "tx_bd used = %d\n", sc->used_tx_bd);
7623			break;
7624		}
7625
7626		count++;
7627
7628		/* Send a copy of the frame to any BPF listeners. */
7629		ETHER_BPF_MTAP(ifp, m_head);
7630	}
7631
7632	/* Exit if no packets were dequeued. */
7633	if (count == 0) {
7634		DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were "
7635		    "dequeued\n", __FUNCTION__);
7636		goto bce_start_locked_exit;
7637	}
7638
7639	DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): Inserted %d frames into "
7640	    "send queue.\n", __FUNCTION__, count);
7641
7642	/* Set the tx timeout. */
7643	sc->watchdog_timer = BCE_TX_TIMEOUT;
7644
7645	DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_ctx(sc, TX_CID));
7646	DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_mq_regs(sc));
7647
7648bce_start_locked_exit:
7649	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
7650}
7651
7652
7653/****************************************************************************/
7654/* Main transmit routine when called from another routine without a lock.   */
7655/*                                                                          */
7656/* Returns:                                                                 */
7657/*   Nothing.                                                               */
7658/****************************************************************************/
7659static void
7660bce_start(struct ifnet *ifp)
7661{
7662	struct bce_softc *sc = ifp->if_softc;
7663
7664	DBENTER(BCE_VERBOSE_SEND);
7665
7666	BCE_LOCK(sc);
7667	bce_start_locked(ifp);
7668	BCE_UNLOCK(sc);
7669
7670	DBEXIT(BCE_VERBOSE_SEND);
7671}
7672
7673
7674/****************************************************************************/
7675/* Handles any IOCTL calls from the operating system.                       */
7676/*                                                                          */
7677/* Returns:                                                                 */
7678/*   0 for success, positive value for failure.                             */
7679/****************************************************************************/
7680static int
7681bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
7682{
7683	struct bce_softc *sc = ifp->if_softc;
7684	struct ifreq *ifr = (struct ifreq *) data;
7685	struct mii_data *mii;
7686	int mask, error = 0;
7687
7688	DBENTER(BCE_VERBOSE_MISC);
7689
7690	switch(command) {
7691
7692	/* Set the interface MTU. */
7693	case SIOCSIFMTU:
7694		/* Check that the MTU setting is supported. */
7695		if ((ifr->ifr_mtu < BCE_MIN_MTU) ||
7696			(ifr->ifr_mtu > BCE_MAX_JUMBO_MTU)) {
7697			error = EINVAL;
7698			break;
7699		}
7700
7701		DBPRINT(sc, BCE_INFO_MISC,
7702		    "SIOCSIFMTU: Changing MTU from %d to %d\n",
7703		    (int) ifp->if_mtu, (int) ifr->ifr_mtu);
7704
7705		BCE_LOCK(sc);
7706		ifp->if_mtu = ifr->ifr_mtu;
7707		if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
7708			ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
7709			bce_init_locked(sc);
7710		}
7711		BCE_UNLOCK(sc);
7712		break;
7713
7714	/* Set interface flags. */
7715	case SIOCSIFFLAGS:
7716		DBPRINT(sc, BCE_VERBOSE_SPECIAL, "Received SIOCSIFFLAGS\n");
7717
7718		BCE_LOCK(sc);
7719
7720		/* Check if the interface is up. */
7721		if (ifp->if_flags & IFF_UP) {
7722			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
7723				/* Change promiscuous/multicast flags as necessary. */
7724				bce_set_rx_mode(sc);
7725			} else {
7726				/* Start the HW */
7727				bce_init_locked(sc);
7728			}
7729		} else {
7730			/* The interface is down, check if driver is running. */
7731			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
7732				bce_stop(sc);
7733
7734				/* If MFW is running, restart the controller a bit. */
7735				if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
7736					bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
7737					bce_chipinit(sc);
7738					bce_mgmt_init_locked(sc);
7739				}
7740			}
7741		}
7742
7743		BCE_UNLOCK(sc);
7744		break;
7745
7746	/* Add/Delete multicast address */
7747	case SIOCADDMULTI:
7748	case SIOCDELMULTI:
7749		DBPRINT(sc, BCE_VERBOSE_MISC,
7750		    "Received SIOCADDMULTI/SIOCDELMULTI\n");
7751
7752		BCE_LOCK(sc);
7753		if (ifp->if_drv_flags & IFF_DRV_RUNNING)
7754			bce_set_rx_mode(sc);
7755		BCE_UNLOCK(sc);
7756
7757		break;
7758
7759	/* Set/Get Interface media */
7760	case SIOCSIFMEDIA:
7761	case SIOCGIFMEDIA:
7762		DBPRINT(sc, BCE_VERBOSE_MISC,
7763		    "Received SIOCSIFMEDIA/SIOCGIFMEDIA\n");
7764		if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
7765			error = ifmedia_ioctl(ifp, ifr, &sc->bce_ifmedia,
7766			    command);
7767		else {
7768			mii = device_get_softc(sc->bce_miibus);
7769			error = ifmedia_ioctl(ifp, ifr, &mii->mii_media,
7770			    command);
7771		}
7772		break;
7773
7774	/* Set interface capability */
7775	case SIOCSIFCAP:
7776		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
7777		DBPRINT(sc, BCE_INFO_MISC,
7778		    "Received SIOCSIFCAP = 0x%08X\n", (u32) mask);
7779
7780		/* Toggle the TX checksum capabilities enable flag. */
7781		if (mask & IFCAP_TXCSUM &&
7782		    ifp->if_capabilities & IFCAP_TXCSUM) {
7783			ifp->if_capenable ^= IFCAP_TXCSUM;
7784			if (IFCAP_TXCSUM & ifp->if_capenable)
7785				ifp->if_hwassist |= BCE_IF_HWASSIST;
7786			else
7787				ifp->if_hwassist &= ~BCE_IF_HWASSIST;
7788		}
7789
7790		/* Toggle the RX checksum capabilities enable flag. */
7791		if (mask & IFCAP_RXCSUM &&
7792		    ifp->if_capabilities & IFCAP_RXCSUM)
7793			ifp->if_capenable ^= IFCAP_RXCSUM;
7794
7795		/* Toggle the TSO capabilities enable flag. */
7796		if (bce_tso_enable && (mask & IFCAP_TSO4) &&
7797		    ifp->if_capabilities & IFCAP_TSO4) {
7798			ifp->if_capenable ^= IFCAP_TSO4;
7799			if (IFCAP_TSO4 & ifp->if_capenable)
7800				ifp->if_hwassist |= CSUM_TSO;
7801			else
7802				ifp->if_hwassist &= ~CSUM_TSO;
7803		}
7804
7805		if (mask & IFCAP_VLAN_HWCSUM &&
7806		    ifp->if_capabilities & IFCAP_VLAN_HWCSUM)
7807			ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
7808
7809		if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
7810		    (ifp->if_capabilities & IFCAP_VLAN_HWTSO) != 0)
7811			ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
7812		/*
7813		 * Don't actually disable VLAN tag stripping as
7814		 * management firmware (ASF/IPMI/UMP) requires the
7815		 * feature. If VLAN tag stripping is disabled driver
7816		 * will manually reconstruct the VLAN frame by
7817		 * appending stripped VLAN tag.
7818		 */
7819		if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
7820		    (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)) {
7821			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
7822			if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING)
7823			    == 0)
7824				ifp->if_capenable &= ~IFCAP_VLAN_HWTSO;
7825		}
7826		VLAN_CAPABILITIES(ifp);
7827		break;
7828	default:
7829		/* We don't know how to handle the IOCTL, pass it on. */
7830		error = ether_ioctl(ifp, command, data);
7831		break;
7832	}
7833
7834	DBEXIT(BCE_VERBOSE_MISC);
7835	return(error);
7836}
7837
7838
7839/****************************************************************************/
7840/* Transmit timeout handler.                                                */
7841/*                                                                          */
7842/* Returns:                                                                 */
7843/*   Nothing.                                                               */
7844/****************************************************************************/
7845static void
7846bce_watchdog(struct bce_softc *sc)
7847{
7848	uint32_t status;
7849
7850	DBENTER(BCE_EXTREME_SEND);
7851
7852	BCE_LOCK_ASSERT(sc);
7853
7854	status = 0;
7855	/* If the watchdog timer hasn't expired then just exit. */
7856	if (sc->watchdog_timer == 0 || --sc->watchdog_timer)
7857		goto bce_watchdog_exit;
7858
7859	status = REG_RD(sc, BCE_EMAC_RX_STATUS);
7860	/* If pause frames are active then don't reset the hardware. */
7861	if ((sc->bce_flags & BCE_USING_RX_FLOW_CONTROL) != 0) {
7862		if ((status & BCE_EMAC_RX_STATUS_FFED) != 0) {
7863			/*
7864			 * If link partner has us in XOFF state then wait for
7865			 * the condition to clear.
7866			 */
7867			sc->watchdog_timer = BCE_TX_TIMEOUT;
7868			goto bce_watchdog_exit;
7869		} else if ((status & BCE_EMAC_RX_STATUS_FF_RECEIVED) != 0 &&
7870			(status & BCE_EMAC_RX_STATUS_N_RECEIVED) != 0) {
7871			/*
7872			 * If we're not currently XOFF'ed but have recently
7873			 * been XOFF'd/XON'd then assume that's delaying TX
7874			 * this time around.
7875			 */
7876			sc->watchdog_timer = BCE_TX_TIMEOUT;
7877			goto bce_watchdog_exit;
7878		}
7879		/*
7880		 * Any other condition is unexpected and the controller
7881		 * should be reset.
7882		 */
7883	}
7884
7885	BCE_PRINTF("%s(%d): Watchdog timeout occurred, resetting!\n",
7886	    __FILE__, __LINE__);
7887
7888	DBRUNMSG(BCE_INFO,
7889	    bce_dump_driver_state(sc);
7890	    bce_dump_status_block(sc);
7891	    bce_dump_stats_block(sc);
7892	    bce_dump_ftqs(sc);
7893	    bce_dump_txp_state(sc, 0);
7894	    bce_dump_rxp_state(sc, 0);
7895	    bce_dump_tpat_state(sc, 0);
7896	    bce_dump_cp_state(sc, 0);
7897	    bce_dump_com_state(sc, 0));
7898
7899	DBRUN(bce_breakpoint(sc));
7900
7901	sc->bce_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
7902
7903	bce_init_locked(sc);
7904	sc->bce_ifp->if_oerrors++;
7905
7906bce_watchdog_exit:
7907	REG_WR(sc, BCE_EMAC_RX_STATUS, status);
7908	DBEXIT(BCE_EXTREME_SEND);
7909}
7910
7911
7912/*
7913 * Interrupt handler.
7914 */
7915/****************************************************************************/
7916/* Main interrupt entry point.  Verifies that the controller generated the  */
7917/* interrupt and then calls a separate routine for handle the various       */
7918/* interrupt causes (PHY, TX, RX).                                          */
7919/*                                                                          */
7920/* Returns:                                                                 */
7921/*   Nothing.                                                               */
7922/****************************************************************************/
7923static void
7924bce_intr(void *xsc)
7925{
7926	struct bce_softc *sc;
7927	struct ifnet *ifp;
7928	u32 status_attn_bits;
7929	u16 hw_rx_cons, hw_tx_cons;
7930
7931	sc = xsc;
7932	ifp = sc->bce_ifp;
7933
7934	DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
7935	DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_status_block(sc));
7936	DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_stats_block(sc));
7937
7938	BCE_LOCK(sc);
7939
7940	DBRUN(sc->interrupts_generated++);
7941
7942	/* Synchnorize before we read from interface's status block */
7943	bus_dmamap_sync(sc->status_tag, sc->status_map, BUS_DMASYNC_POSTREAD);
7944
7945	/*
7946	 * If the hardware status block index matches the last value read
7947	 * by the driver and we haven't asserted our interrupt then there's
7948	 * nothing to do.  This may only happen in case of INTx due to the
7949	 * interrupt arriving at the CPU before the status block is updated.
7950	 */
7951	if ((sc->bce_flags & (BCE_USING_MSI_FLAG | BCE_USING_MSIX_FLAG)) == 0 &&
7952	    sc->status_block->status_idx == sc->last_status_idx &&
7953	    (REG_RD(sc, BCE_PCICFG_MISC_STATUS) &
7954	     BCE_PCICFG_MISC_STATUS_INTA_VALUE)) {
7955		DBPRINT(sc, BCE_VERBOSE_INTR, "%s(): Spurious interrupt.\n",
7956		    __FUNCTION__);
7957		goto bce_intr_exit;
7958	}
7959
7960	/* Ack the interrupt and stop others from occuring. */
7961	REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
7962	    BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
7963	    BCE_PCICFG_INT_ACK_CMD_MASK_INT);
7964
7965	/* Check if the hardware has finished any work. */
7966	hw_rx_cons = bce_get_hw_rx_cons(sc);
7967	hw_tx_cons = bce_get_hw_tx_cons(sc);
7968
7969	/* Keep processing data as long as there is work to do. */
7970	for (;;) {
7971
7972		status_attn_bits = sc->status_block->status_attn_bits;
7973
7974		DBRUNIF(DB_RANDOMTRUE(unexpected_attention_sim_control),
7975		    BCE_PRINTF("Simulating unexpected status attention "
7976		    "bit set.");
7977		    sc->unexpected_attention_sim_count++;
7978		    status_attn_bits = status_attn_bits |
7979		    STATUS_ATTN_BITS_PARITY_ERROR);
7980
7981		/* Was it a link change interrupt? */
7982		if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
7983		    (sc->status_block->status_attn_bits_ack &
7984		     STATUS_ATTN_BITS_LINK_STATE)) {
7985			bce_phy_intr(sc);
7986
7987			/* Clear transient updates during link state change. */
7988			REG_WR(sc, BCE_HC_COMMAND, sc->hc_command |
7989			    BCE_HC_COMMAND_COAL_NOW_WO_INT);
7990			REG_RD(sc, BCE_HC_COMMAND);
7991		}
7992
7993		/* If any other attention is asserted, the chip is toast. */
7994		if (((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
7995		    (sc->status_block->status_attn_bits_ack &
7996		    ~STATUS_ATTN_BITS_LINK_STATE))) {
7997
7998			sc->unexpected_attention_count++;
7999
8000			BCE_PRINTF("%s(%d): Fatal attention detected: "
8001			    "0x%08X\n",	__FILE__, __LINE__,
8002			    sc->status_block->status_attn_bits);
8003
8004			DBRUNMSG(BCE_FATAL,
8005			    if (unexpected_attention_sim_control == 0)
8006				bce_breakpoint(sc));
8007
8008			bce_init_locked(sc);
8009			goto bce_intr_exit;
8010		}
8011
8012		/* Check for any completed RX frames. */
8013		if (hw_rx_cons != sc->hw_rx_cons)
8014			bce_rx_intr(sc);
8015
8016		/* Check for any completed TX frames. */
8017		if (hw_tx_cons != sc->hw_tx_cons)
8018			bce_tx_intr(sc);
8019
8020		/* Save status block index value for the next interrupt. */
8021		sc->last_status_idx = sc->status_block->status_idx;
8022
8023 		/*
8024 		 * Prevent speculative reads from getting
8025 		 * ahead of the status block.
8026		 */
8027		bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
8028		    BUS_SPACE_BARRIER_READ);
8029
8030 		/*
8031 		 * If there's no work left then exit the
8032 		 * interrupt service routine.
8033		 */
8034		hw_rx_cons = bce_get_hw_rx_cons(sc);
8035		hw_tx_cons = bce_get_hw_tx_cons(sc);
8036
8037		if ((hw_rx_cons == sc->hw_rx_cons) &&
8038		    (hw_tx_cons == sc->hw_tx_cons))
8039			break;
8040	}
8041
8042	bus_dmamap_sync(sc->status_tag,	sc->status_map, BUS_DMASYNC_PREREAD);
8043
8044	/* Re-enable interrupts. */
8045	bce_enable_intr(sc, 0);
8046
8047	/* Handle any frames that arrived while handling the interrupt. */
8048	if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
8049	    !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
8050		bce_start_locked(ifp);
8051
8052bce_intr_exit:
8053	BCE_UNLOCK(sc);
8054
8055	DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
8056}
8057
8058
8059/****************************************************************************/
8060/* Programs the various packet receive modes (broadcast and multicast).     */
8061/*                                                                          */
8062/* Returns:                                                                 */
8063/*   Nothing.                                                               */
8064/****************************************************************************/
8065static void
8066bce_set_rx_mode(struct bce_softc *sc)
8067{
8068	struct ifnet *ifp;
8069	struct ifmultiaddr *ifma;
8070	u32 hashes[NUM_MC_HASH_REGISTERS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
8071	u32 rx_mode, sort_mode;
8072	int h, i;
8073
8074	DBENTER(BCE_VERBOSE_MISC);
8075
8076	BCE_LOCK_ASSERT(sc);
8077
8078	ifp = sc->bce_ifp;
8079
8080	/* Initialize receive mode default settings. */
8081	rx_mode   = sc->rx_mode & ~(BCE_EMAC_RX_MODE_PROMISCUOUS |
8082	    BCE_EMAC_RX_MODE_KEEP_VLAN_TAG);
8083	sort_mode = 1 | BCE_RPM_SORT_USER0_BC_EN;
8084
8085	/*
8086	 * ASF/IPMI/UMP firmware requires that VLAN tag stripping
8087	 * be enbled.
8088	 */
8089	if (!(BCE_IF_CAPABILITIES & IFCAP_VLAN_HWTAGGING) &&
8090	    (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)))
8091		rx_mode |= BCE_EMAC_RX_MODE_KEEP_VLAN_TAG;
8092
8093	/*
8094	 * Check for promiscuous, all multicast, or selected
8095	 * multicast address filtering.
8096	 */
8097	if (ifp->if_flags & IFF_PROMISC) {
8098		DBPRINT(sc, BCE_INFO_MISC, "Enabling promiscuous mode.\n");
8099
8100		/* Enable promiscuous mode. */
8101		rx_mode |= BCE_EMAC_RX_MODE_PROMISCUOUS;
8102		sort_mode |= BCE_RPM_SORT_USER0_PROM_EN;
8103	} else if (ifp->if_flags & IFF_ALLMULTI) {
8104		DBPRINT(sc, BCE_INFO_MISC, "Enabling all multicast mode.\n");
8105
8106		/* Enable all multicast addresses. */
8107		for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
8108			REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4),
8109			    0xffffffff);
8110		}
8111		sort_mode |= BCE_RPM_SORT_USER0_MC_EN;
8112	} else {
8113		/* Accept one or more multicast(s). */
8114		DBPRINT(sc, BCE_INFO_MISC, "Enabling selective multicast mode.\n");
8115
8116		if_maddr_rlock(ifp);
8117		TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
8118			if (ifma->ifma_addr->sa_family != AF_LINK)
8119				continue;
8120			h = ether_crc32_le(LLADDR((struct sockaddr_dl *)
8121			    ifma->ifma_addr), ETHER_ADDR_LEN) & 0xFF;
8122			    hashes[(h & 0xE0) >> 5] |= 1 << (h & 0x1F);
8123		}
8124		if_maddr_runlock(ifp);
8125
8126		for (i = 0; i < NUM_MC_HASH_REGISTERS; i++)
8127			REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), hashes[i]);
8128
8129		sort_mode |= BCE_RPM_SORT_USER0_MC_HSH_EN;
8130	}
8131
8132	/* Only make changes if the recive mode has actually changed. */
8133	if (rx_mode != sc->rx_mode) {
8134		DBPRINT(sc, BCE_VERBOSE_MISC, "Enabling new receive mode: "
8135		    "0x%08X\n", rx_mode);
8136
8137		sc->rx_mode = rx_mode;
8138		REG_WR(sc, BCE_EMAC_RX_MODE, rx_mode);
8139	}
8140
8141	/* Disable and clear the exisitng sort before enabling a new sort. */
8142	REG_WR(sc, BCE_RPM_SORT_USER0, 0x0);
8143	REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode);
8144	REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode | BCE_RPM_SORT_USER0_ENA);
8145
8146	DBEXIT(BCE_VERBOSE_MISC);
8147}
8148
8149
8150/****************************************************************************/
8151/* Called periodically to updates statistics from the controllers           */
8152/* statistics block.                                                        */
8153/*                                                                          */
8154/* Returns:                                                                 */
8155/*   Nothing.                                                               */
8156/****************************************************************************/
8157static void
8158bce_stats_update(struct bce_softc *sc)
8159{
8160	struct ifnet *ifp;
8161	struct statistics_block *stats;
8162
8163	DBENTER(BCE_EXTREME_MISC);
8164
8165	ifp = sc->bce_ifp;
8166
8167	bus_dmamap_sync(sc->stats_tag, sc->stats_map, BUS_DMASYNC_POSTREAD);
8168
8169	stats = (struct statistics_block *) sc->stats_block;
8170
8171	/*
8172	 * Certain controllers don't report
8173	 * carrier sense errors correctly.
8174	 * See errata E11_5708CA0_1165.
8175	 */
8176	if (!(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
8177	    !(BCE_CHIP_ID(sc) == BCE_CHIP_ID_5708_A0))
8178		ifp->if_oerrors +=
8179		    (u_long) stats->stat_Dot3StatsCarrierSenseErrors;
8180
8181	/*
8182	 * Update the sysctl statistics from the
8183	 * hardware statistics.
8184	 */
8185	sc->stat_IfHCInOctets =
8186	    ((u64) stats->stat_IfHCInOctets_hi << 32) +
8187	     (u64) stats->stat_IfHCInOctets_lo;
8188
8189	sc->stat_IfHCInBadOctets =
8190	    ((u64) stats->stat_IfHCInBadOctets_hi << 32) +
8191	     (u64) stats->stat_IfHCInBadOctets_lo;
8192
8193	sc->stat_IfHCOutOctets =
8194	    ((u64) stats->stat_IfHCOutOctets_hi << 32) +
8195	     (u64) stats->stat_IfHCOutOctets_lo;
8196
8197	sc->stat_IfHCOutBadOctets =
8198	    ((u64) stats->stat_IfHCOutBadOctets_hi << 32) +
8199	     (u64) stats->stat_IfHCOutBadOctets_lo;
8200
8201	sc->stat_IfHCInUcastPkts =
8202	    ((u64) stats->stat_IfHCInUcastPkts_hi << 32) +
8203	     (u64) stats->stat_IfHCInUcastPkts_lo;
8204
8205	sc->stat_IfHCInMulticastPkts =
8206	    ((u64) stats->stat_IfHCInMulticastPkts_hi << 32) +
8207	     (u64) stats->stat_IfHCInMulticastPkts_lo;
8208
8209	sc->stat_IfHCInBroadcastPkts =
8210	    ((u64) stats->stat_IfHCInBroadcastPkts_hi << 32) +
8211	     (u64) stats->stat_IfHCInBroadcastPkts_lo;
8212
8213	sc->stat_IfHCOutUcastPkts =
8214	    ((u64) stats->stat_IfHCOutUcastPkts_hi << 32) +
8215	     (u64) stats->stat_IfHCOutUcastPkts_lo;
8216
8217	sc->stat_IfHCOutMulticastPkts =
8218	    ((u64) stats->stat_IfHCOutMulticastPkts_hi << 32) +
8219	     (u64) stats->stat_IfHCOutMulticastPkts_lo;
8220
8221	sc->stat_IfHCOutBroadcastPkts =
8222	    ((u64) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
8223	     (u64) stats->stat_IfHCOutBroadcastPkts_lo;
8224
8225	/* ToDo: Preserve counters beyond 32 bits? */
8226	/* ToDo: Read the statistics from auto-clear regs? */
8227
8228	sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors =
8229	    stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
8230
8231	sc->stat_Dot3StatsCarrierSenseErrors =
8232	    stats->stat_Dot3StatsCarrierSenseErrors;
8233
8234	sc->stat_Dot3StatsFCSErrors =
8235	    stats->stat_Dot3StatsFCSErrors;
8236
8237	sc->stat_Dot3StatsAlignmentErrors =
8238	    stats->stat_Dot3StatsAlignmentErrors;
8239
8240	sc->stat_Dot3StatsSingleCollisionFrames =
8241	    stats->stat_Dot3StatsSingleCollisionFrames;
8242
8243	sc->stat_Dot3StatsMultipleCollisionFrames =
8244	    stats->stat_Dot3StatsMultipleCollisionFrames;
8245
8246	sc->stat_Dot3StatsDeferredTransmissions =
8247	    stats->stat_Dot3StatsDeferredTransmissions;
8248
8249	sc->stat_Dot3StatsExcessiveCollisions =
8250	    stats->stat_Dot3StatsExcessiveCollisions;
8251
8252	sc->stat_Dot3StatsLateCollisions =
8253	    stats->stat_Dot3StatsLateCollisions;
8254
8255	sc->stat_EtherStatsCollisions =
8256	    stats->stat_EtherStatsCollisions;
8257
8258	sc->stat_EtherStatsFragments =
8259	    stats->stat_EtherStatsFragments;
8260
8261	sc->stat_EtherStatsJabbers =
8262	    stats->stat_EtherStatsJabbers;
8263
8264	sc->stat_EtherStatsUndersizePkts =
8265	    stats->stat_EtherStatsUndersizePkts;
8266
8267	sc->stat_EtherStatsOversizePkts =
8268	     stats->stat_EtherStatsOversizePkts;
8269
8270	sc->stat_EtherStatsPktsRx64Octets =
8271	    stats->stat_EtherStatsPktsRx64Octets;
8272
8273	sc->stat_EtherStatsPktsRx65Octetsto127Octets =
8274	    stats->stat_EtherStatsPktsRx65Octetsto127Octets;
8275
8276	sc->stat_EtherStatsPktsRx128Octetsto255Octets =
8277	    stats->stat_EtherStatsPktsRx128Octetsto255Octets;
8278
8279	sc->stat_EtherStatsPktsRx256Octetsto511Octets =
8280	    stats->stat_EtherStatsPktsRx256Octetsto511Octets;
8281
8282	sc->stat_EtherStatsPktsRx512Octetsto1023Octets =
8283	    stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
8284
8285	sc->stat_EtherStatsPktsRx1024Octetsto1522Octets =
8286	    stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
8287
8288	sc->stat_EtherStatsPktsRx1523Octetsto9022Octets =
8289	    stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
8290
8291	sc->stat_EtherStatsPktsTx64Octets =
8292	    stats->stat_EtherStatsPktsTx64Octets;
8293
8294	sc->stat_EtherStatsPktsTx65Octetsto127Octets =
8295	    stats->stat_EtherStatsPktsTx65Octetsto127Octets;
8296
8297	sc->stat_EtherStatsPktsTx128Octetsto255Octets =
8298	    stats->stat_EtherStatsPktsTx128Octetsto255Octets;
8299
8300	sc->stat_EtherStatsPktsTx256Octetsto511Octets =
8301	    stats->stat_EtherStatsPktsTx256Octetsto511Octets;
8302
8303	sc->stat_EtherStatsPktsTx512Octetsto1023Octets =
8304	    stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
8305
8306	sc->stat_EtherStatsPktsTx1024Octetsto1522Octets =
8307	    stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
8308
8309	sc->stat_EtherStatsPktsTx1523Octetsto9022Octets =
8310	    stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
8311
8312	sc->stat_XonPauseFramesReceived =
8313	    stats->stat_XonPauseFramesReceived;
8314
8315	sc->stat_XoffPauseFramesReceived =
8316	    stats->stat_XoffPauseFramesReceived;
8317
8318	sc->stat_OutXonSent =
8319	    stats->stat_OutXonSent;
8320
8321	sc->stat_OutXoffSent =
8322	    stats->stat_OutXoffSent;
8323
8324	sc->stat_FlowControlDone =
8325	    stats->stat_FlowControlDone;
8326
8327	sc->stat_MacControlFramesReceived =
8328	    stats->stat_MacControlFramesReceived;
8329
8330	sc->stat_XoffStateEntered =
8331	    stats->stat_XoffStateEntered;
8332
8333	sc->stat_IfInFramesL2FilterDiscards =
8334	    stats->stat_IfInFramesL2FilterDiscards;
8335
8336	sc->stat_IfInRuleCheckerDiscards =
8337	    stats->stat_IfInRuleCheckerDiscards;
8338
8339	sc->stat_IfInFTQDiscards =
8340	    stats->stat_IfInFTQDiscards;
8341
8342	sc->stat_IfInMBUFDiscards =
8343	    stats->stat_IfInMBUFDiscards;
8344
8345	sc->stat_IfInRuleCheckerP4Hit =
8346	    stats->stat_IfInRuleCheckerP4Hit;
8347
8348	sc->stat_CatchupInRuleCheckerDiscards =
8349	    stats->stat_CatchupInRuleCheckerDiscards;
8350
8351	sc->stat_CatchupInFTQDiscards =
8352	    stats->stat_CatchupInFTQDiscards;
8353
8354	sc->stat_CatchupInMBUFDiscards =
8355	    stats->stat_CatchupInMBUFDiscards;
8356
8357	sc->stat_CatchupInRuleCheckerP4Hit =
8358	    stats->stat_CatchupInRuleCheckerP4Hit;
8359
8360	sc->com_no_buffers = REG_RD_IND(sc, 0x120084);
8361
8362	/*
8363	 * Update the interface statistics from the
8364	 * hardware statistics.
8365	 */
8366	ifp->if_collisions =
8367	    (u_long) sc->stat_EtherStatsCollisions;
8368
8369	/* ToDo: This method loses soft errors. */
8370	ifp->if_ierrors =
8371	    (u_long) sc->stat_EtherStatsUndersizePkts +
8372	    (u_long) sc->stat_EtherStatsOversizePkts +
8373	    (u_long) sc->stat_IfInMBUFDiscards +
8374	    (u_long) sc->stat_Dot3StatsAlignmentErrors +
8375	    (u_long) sc->stat_Dot3StatsFCSErrors +
8376	    (u_long) sc->stat_IfInRuleCheckerDiscards +
8377	    (u_long) sc->stat_IfInFTQDiscards +
8378	    (u_long) sc->com_no_buffers;
8379
8380	/* ToDo: This method loses soft errors. */
8381	ifp->if_oerrors =
8382	    (u_long) sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
8383	    (u_long) sc->stat_Dot3StatsExcessiveCollisions +
8384	    (u_long) sc->stat_Dot3StatsLateCollisions;
8385
8386	/* ToDo: Add additional statistics? */
8387
8388	DBEXIT(BCE_EXTREME_MISC);
8389}
8390
8391
8392/****************************************************************************/
8393/* Periodic function to notify the bootcode that the driver is still        */
8394/* present.                                                                 */
8395/*                                                                          */
8396/* Returns:                                                                 */
8397/*   Nothing.                                                               */
8398/****************************************************************************/
8399static void
8400bce_pulse(void *xsc)
8401{
8402	struct bce_softc *sc = xsc;
8403	u32 msg;
8404
8405	DBENTER(BCE_EXTREME_MISC);
8406
8407	BCE_LOCK_ASSERT(sc);
8408
8409	/* Tell the firmware that the driver is still running. */
8410	msg = (u32) ++sc->bce_fw_drv_pulse_wr_seq;
8411	bce_shmem_wr(sc, BCE_DRV_PULSE_MB, msg);
8412
8413	/* Update the bootcode condition. */
8414	sc->bc_state = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
8415
8416	/* Report whether the bootcode still knows the driver is running. */
8417	if (bce_verbose || bootverbose) {
8418		if (sc->bce_drv_cardiac_arrest == FALSE) {
8419			if (!(sc->bc_state & BCE_CONDITION_DRV_PRESENT)) {
8420				sc->bce_drv_cardiac_arrest = TRUE;
8421				BCE_PRINTF("%s(): Warning: bootcode "
8422				    "thinks driver is absent! "
8423				    "(bc_state = 0x%08X)\n",
8424				    __FUNCTION__, sc->bc_state);
8425			}
8426		} else {
8427			/*
8428			 * Not supported by all bootcode versions.
8429			 * (v5.0.11+ and v5.2.1+)  Older bootcode
8430			 * will require the driver to reset the
8431			 * controller to clear this condition.
8432			 */
8433			if (sc->bc_state & BCE_CONDITION_DRV_PRESENT) {
8434				sc->bce_drv_cardiac_arrest = FALSE;
8435				BCE_PRINTF("%s(): Bootcode found the "
8436				    "driver pulse! (bc_state = 0x%08X)\n",
8437				    __FUNCTION__, sc->bc_state);
8438			}
8439		}
8440	}
8441
8442
8443	/* Schedule the next pulse. */
8444	callout_reset(&sc->bce_pulse_callout, hz, bce_pulse, sc);
8445
8446	DBEXIT(BCE_EXTREME_MISC);
8447}
8448
8449
8450/****************************************************************************/
8451/* Periodic function to perform maintenance tasks.                          */
8452/*                                                                          */
8453/* Returns:                                                                 */
8454/*   Nothing.                                                               */
8455/****************************************************************************/
8456static void
8457bce_tick(void *xsc)
8458{
8459	struct bce_softc *sc = xsc;
8460	struct mii_data *mii;
8461	struct ifnet *ifp;
8462	struct ifmediareq ifmr;
8463
8464	ifp = sc->bce_ifp;
8465
8466	DBENTER(BCE_EXTREME_MISC);
8467
8468	BCE_LOCK_ASSERT(sc);
8469
8470	/* Schedule the next tick. */
8471	callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
8472
8473	/* Update the statistics from the hardware statistics block. */
8474	bce_stats_update(sc);
8475
8476 	/* Ensure page and RX chains get refilled in low-memory situations. */
8477	if (bce_hdr_split == TRUE)
8478		bce_fill_pg_chain(sc);
8479	bce_fill_rx_chain(sc);
8480
8481	/* Check that chip hasn't hung. */
8482	bce_watchdog(sc);
8483
8484	/* If link is up already up then we're done. */
8485	if (sc->bce_link_up == TRUE)
8486		goto bce_tick_exit;
8487
8488	/* Link is down.  Check what the PHY's doing. */
8489	if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
8490		bzero(&ifmr, sizeof(ifmr));
8491		bce_ifmedia_sts_rphy(sc, &ifmr);
8492		if ((ifmr.ifm_status & (IFM_ACTIVE | IFM_AVALID)) ==
8493		    (IFM_ACTIVE | IFM_AVALID)) {
8494			sc->bce_link_up = TRUE;
8495			bce_miibus_statchg(sc->bce_dev);
8496		}
8497	} else {
8498		mii = device_get_softc(sc->bce_miibus);
8499		mii_tick(mii);
8500		/* Check if the link has come up. */
8501		if ((mii->mii_media_status & IFM_ACTIVE) &&
8502		    (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)) {
8503			DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Link up!\n",
8504			    __FUNCTION__);
8505			sc->bce_link_up = TRUE;
8506			if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
8507			    IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX ||
8508			    IFM_SUBTYPE(mii->mii_media_active) == IFM_2500_SX) &&
8509			    (bce_verbose || bootverbose))
8510				BCE_PRINTF("Gigabit link up!\n");
8511		}
8512
8513	}
8514	if (sc->bce_link_up == TRUE) {
8515		/* Now that link is up, handle any outstanding TX traffic. */
8516		if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
8517			DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Found "
8518			    "pending TX traffic.\n", __FUNCTION__);
8519			bce_start_locked(ifp);
8520		}
8521	}
8522
8523bce_tick_exit:
8524	DBEXIT(BCE_EXTREME_MISC);
8525}
8526
8527static void
8528bce_fw_cap_init(struct bce_softc *sc)
8529{
8530	u32 ack, cap, link;
8531
8532	ack = 0;
8533	cap = bce_shmem_rd(sc, BCE_FW_CAP_MB);
8534	if ((cap & BCE_FW_CAP_SIGNATURE_MAGIC_MASK) !=
8535	    BCE_FW_CAP_SIGNATURE_MAGIC)
8536		return;
8537	if ((cap & (BCE_FW_CAP_MFW_KEEP_VLAN | BCE_FW_CAP_BC_KEEP_VLAN)) ==
8538	    (BCE_FW_CAP_MFW_KEEP_VLAN | BCE_FW_CAP_BC_KEEP_VLAN))
8539		ack |= BCE_DRV_ACK_CAP_SIGNATURE_MAGIC |
8540		    BCE_FW_CAP_MFW_KEEP_VLAN | BCE_FW_CAP_BC_KEEP_VLAN;
8541	if ((sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) != 0 &&
8542	    (cap & BCE_FW_CAP_REMOTE_PHY_CAP) != 0) {
8543		sc->bce_phy_flags &= ~BCE_PHY_REMOTE_PORT_FIBER_FLAG;
8544		sc->bce_phy_flags |= BCE_PHY_REMOTE_CAP_FLAG;
8545		link = bce_shmem_rd(sc, BCE_LINK_STATUS);
8546		if ((link & BCE_LINK_STATUS_SERDES_LINK) != 0)
8547			sc->bce_phy_flags |= BCE_PHY_REMOTE_PORT_FIBER_FLAG;
8548		ack |= BCE_DRV_ACK_CAP_SIGNATURE_MAGIC |
8549		    BCE_FW_CAP_REMOTE_PHY_CAP;
8550	}
8551
8552	if (ack != 0)
8553		bce_shmem_wr(sc, BCE_DRV_ACK_CAP_MB, ack);
8554}
8555
8556
8557#ifdef BCE_DEBUG
8558/****************************************************************************/
8559/* Allows the driver state to be dumped through the sysctl interface.       */
8560/*                                                                          */
8561/* Returns:                                                                 */
8562/*   0 for success, positive value for failure.                             */
8563/****************************************************************************/
8564static int
8565bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS)
8566{
8567	int error;
8568	int result;
8569	struct bce_softc *sc;
8570
8571	result = -1;
8572	error = sysctl_handle_int(oidp, &result, 0, req);
8573
8574	if (error || !req->newptr)
8575		return (error);
8576
8577	if (result == 1) {
8578		sc = (struct bce_softc *)arg1;
8579		bce_dump_driver_state(sc);
8580	}
8581
8582	return error;
8583}
8584
8585
8586/****************************************************************************/
8587/* Allows the hardware state to be dumped through the sysctl interface.     */
8588/*                                                                          */
8589/* Returns:                                                                 */
8590/*   0 for success, positive value for failure.                             */
8591/****************************************************************************/
8592static int
8593bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS)
8594{
8595	int error;
8596	int result;
8597	struct bce_softc *sc;
8598
8599	result = -1;
8600	error = sysctl_handle_int(oidp, &result, 0, req);
8601
8602	if (error || !req->newptr)
8603		return (error);
8604
8605	if (result == 1) {
8606		sc = (struct bce_softc *)arg1;
8607		bce_dump_hw_state(sc);
8608	}
8609
8610	return error;
8611}
8612
8613
8614/****************************************************************************/
8615/* Allows the status block to be dumped through the sysctl interface.       */
8616/*                                                                          */
8617/* Returns:                                                                 */
8618/*   0 for success, positive value for failure.                             */
8619/****************************************************************************/
8620static int
8621bce_sysctl_status_block(SYSCTL_HANDLER_ARGS)
8622{
8623	int error;
8624	int result;
8625	struct bce_softc *sc;
8626
8627	result = -1;
8628	error = sysctl_handle_int(oidp, &result, 0, req);
8629
8630	if (error || !req->newptr)
8631		return (error);
8632
8633	if (result == 1) {
8634		sc = (struct bce_softc *)arg1;
8635		bce_dump_status_block(sc);
8636	}
8637
8638	return error;
8639}
8640
8641
8642/****************************************************************************/
8643/* Allows the stats block to be dumped through the sysctl interface.        */
8644/*                                                                          */
8645/* Returns:                                                                 */
8646/*   0 for success, positive value for failure.                             */
8647/****************************************************************************/
8648static int
8649bce_sysctl_stats_block(SYSCTL_HANDLER_ARGS)
8650{
8651	int error;
8652	int result;
8653	struct bce_softc *sc;
8654
8655	result = -1;
8656	error = sysctl_handle_int(oidp, &result, 0, req);
8657
8658	if (error || !req->newptr)
8659		return (error);
8660
8661	if (result == 1) {
8662		sc = (struct bce_softc *)arg1;
8663		bce_dump_stats_block(sc);
8664	}
8665
8666	return error;
8667}
8668
8669
8670/****************************************************************************/
8671/* Allows the stat counters to be cleared without unloading/reloading the   */
8672/* driver.                                                                  */
8673/*                                                                          */
8674/* Returns:                                                                 */
8675/*   0 for success, positive value for failure.                             */
8676/****************************************************************************/
8677static int
8678bce_sysctl_stats_clear(SYSCTL_HANDLER_ARGS)
8679{
8680	int error;
8681	int result;
8682	struct bce_softc *sc;
8683
8684	result = -1;
8685	error = sysctl_handle_int(oidp, &result, 0, req);
8686
8687	if (error || !req->newptr)
8688		return (error);
8689
8690	if (result == 1) {
8691		sc = (struct bce_softc *)arg1;
8692		struct statistics_block *stats;
8693
8694		stats = (struct statistics_block *) sc->stats_block;
8695		bzero(stats, sizeof(struct statistics_block));
8696		bus_dmamap_sync(sc->stats_tag, sc->stats_map,
8697		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
8698
8699		/* Clear the internal H/W statistics counters. */
8700		REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
8701
8702		/* Reset the driver maintained statistics. */
8703		sc->interrupts_rx =
8704		    sc->interrupts_tx = 0;
8705		sc->tso_frames_requested =
8706		    sc->tso_frames_completed =
8707		    sc->tso_frames_failed = 0;
8708		sc->rx_empty_count =
8709		    sc->tx_full_count = 0;
8710		sc->rx_low_watermark = USABLE_RX_BD_ALLOC;
8711		sc->tx_hi_watermark = 0;
8712		sc->l2fhdr_error_count =
8713		    sc->l2fhdr_error_sim_count = 0;
8714		sc->mbuf_alloc_failed_count =
8715		    sc->mbuf_alloc_failed_sim_count = 0;
8716		sc->dma_map_addr_rx_failed_count =
8717		    sc->dma_map_addr_tx_failed_count = 0;
8718		sc->mbuf_frag_count = 0;
8719		sc->csum_offload_tcp_udp =
8720		    sc->csum_offload_ip = 0;
8721		sc->vlan_tagged_frames_rcvd =
8722		    sc->vlan_tagged_frames_stripped = 0;
8723		sc->split_header_frames_rcvd =
8724		    sc->split_header_tcp_frames_rcvd = 0;
8725
8726		/* Clear firmware maintained statistics. */
8727		REG_WR_IND(sc, 0x120084, 0);
8728	}
8729
8730	return error;
8731}
8732
8733
8734/****************************************************************************/
8735/* Allows the shared memory contents to be dumped through the sysctl  .     */
8736/* interface.                                                               */
8737/*                                                                          */
8738/* Returns:                                                                 */
8739/*   0 for success, positive value for failure.                             */
8740/****************************************************************************/
8741static int
8742bce_sysctl_shmem_state(SYSCTL_HANDLER_ARGS)
8743{
8744	int error;
8745	int result;
8746	struct bce_softc *sc;
8747
8748	result = -1;
8749	error = sysctl_handle_int(oidp, &result, 0, req);
8750
8751	if (error || !req->newptr)
8752		return (error);
8753
8754	if (result == 1) {
8755		sc = (struct bce_softc *)arg1;
8756		bce_dump_shmem_state(sc);
8757	}
8758
8759	return error;
8760}
8761
8762
8763/****************************************************************************/
8764/* Allows the bootcode state to be dumped through the sysctl interface.     */
8765/*                                                                          */
8766/* Returns:                                                                 */
8767/*   0 for success, positive value for failure.                             */
8768/****************************************************************************/
8769static int
8770bce_sysctl_bc_state(SYSCTL_HANDLER_ARGS)
8771{
8772	int error;
8773	int result;
8774	struct bce_softc *sc;
8775
8776	result = -1;
8777	error = sysctl_handle_int(oidp, &result, 0, req);
8778
8779	if (error || !req->newptr)
8780		return (error);
8781
8782	if (result == 1) {
8783		sc = (struct bce_softc *)arg1;
8784		bce_dump_bc_state(sc);
8785	}
8786
8787	return error;
8788}
8789
8790
8791/****************************************************************************/
8792/* Provides a sysctl interface to allow dumping the RX BD chain.            */
8793/*                                                                          */
8794/* Returns:                                                                 */
8795/*   0 for success, positive value for failure.                             */
8796/****************************************************************************/
8797static int
8798bce_sysctl_dump_rx_bd_chain(SYSCTL_HANDLER_ARGS)
8799{
8800	int error;
8801	int result;
8802	struct bce_softc *sc;
8803
8804	result = -1;
8805	error = sysctl_handle_int(oidp, &result, 0, req);
8806
8807	if (error || !req->newptr)
8808		return (error);
8809
8810	if (result == 1) {
8811		sc = (struct bce_softc *)arg1;
8812		bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD_ALLOC);
8813	}
8814
8815	return error;
8816}
8817
8818
8819/****************************************************************************/
8820/* Provides a sysctl interface to allow dumping the RX MBUF chain.          */
8821/*                                                                          */
8822/* Returns:                                                                 */
8823/*   0 for success, positive value for failure.                             */
8824/****************************************************************************/
8825static int
8826bce_sysctl_dump_rx_mbuf_chain(SYSCTL_HANDLER_ARGS)
8827{
8828	int error;
8829	int result;
8830	struct bce_softc *sc;
8831
8832	result = -1;
8833	error = sysctl_handle_int(oidp, &result, 0, req);
8834
8835	if (error || !req->newptr)
8836		return (error);
8837
8838	if (result == 1) {
8839		sc = (struct bce_softc *)arg1;
8840		bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD_ALLOC);
8841	}
8842
8843	return error;
8844}
8845
8846
8847/****************************************************************************/
8848/* Provides a sysctl interface to allow dumping the TX chain.               */
8849/*                                                                          */
8850/* Returns:                                                                 */
8851/*   0 for success, positive value for failure.                             */
8852/****************************************************************************/
8853static int
8854bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
8855{
8856	int error;
8857	int result;
8858	struct bce_softc *sc;
8859
8860	result = -1;
8861	error = sysctl_handle_int(oidp, &result, 0, req);
8862
8863	if (error || !req->newptr)
8864		return (error);
8865
8866	if (result == 1) {
8867		sc = (struct bce_softc *)arg1;
8868		bce_dump_tx_chain(sc, 0, TOTAL_TX_BD_ALLOC);
8869	}
8870
8871	return error;
8872}
8873
8874
8875/****************************************************************************/
8876/* Provides a sysctl interface to allow dumping the page chain.             */
8877/*                                                                          */
8878/* Returns:                                                                 */
8879/*   0 for success, positive value for failure.                             */
8880/****************************************************************************/
8881static int
8882bce_sysctl_dump_pg_chain(SYSCTL_HANDLER_ARGS)
8883{
8884	int error;
8885	int result;
8886	struct bce_softc *sc;
8887
8888	result = -1;
8889	error = sysctl_handle_int(oidp, &result, 0, req);
8890
8891	if (error || !req->newptr)
8892		return (error);
8893
8894	if (result == 1) {
8895		sc = (struct bce_softc *)arg1;
8896		bce_dump_pg_chain(sc, 0, TOTAL_PG_BD_ALLOC);
8897	}
8898
8899	return error;
8900}
8901
8902/****************************************************************************/
8903/* Provides a sysctl interface to allow reading arbitrary NVRAM offsets in  */
8904/* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
8905/*                                                                          */
8906/* Returns:                                                                 */
8907/*   0 for success, positive value for failure.                             */
8908/****************************************************************************/
8909static int
8910bce_sysctl_nvram_read(SYSCTL_HANDLER_ARGS)
8911{
8912	struct bce_softc *sc = (struct bce_softc *)arg1;
8913	int error;
8914	u32 result;
8915	u32 val[1];
8916	u8 *data = (u8 *) val;
8917
8918	result = -1;
8919	error = sysctl_handle_int(oidp, &result, 0, req);
8920	if (error || (req->newptr == NULL))
8921		return (error);
8922
8923	error = bce_nvram_read(sc, result, data, 4);
8924
8925	BCE_PRINTF("offset 0x%08X = 0x%08X\n", result, bce_be32toh(val[0]));
8926
8927	return (error);
8928}
8929
8930
8931/****************************************************************************/
8932/* Provides a sysctl interface to allow reading arbitrary registers in the  */
8933/* device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                            */
8934/*                                                                          */
8935/* Returns:                                                                 */
8936/*   0 for success, positive value for failure.                             */
8937/****************************************************************************/
8938static int
8939bce_sysctl_reg_read(SYSCTL_HANDLER_ARGS)
8940{
8941	struct bce_softc *sc = (struct bce_softc *)arg1;
8942	int error;
8943	u32 val, result;
8944
8945	result = -1;
8946	error = sysctl_handle_int(oidp, &result, 0, req);
8947	if (error || (req->newptr == NULL))
8948		return (error);
8949
8950	/* Make sure the register is accessible. */
8951	if (result < 0x8000) {
8952		val = REG_RD(sc, result);
8953		BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
8954	} else if (result < 0x0280000) {
8955		val = REG_RD_IND(sc, result);
8956		BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
8957	}
8958
8959	return (error);
8960}
8961
8962
8963/****************************************************************************/
8964/* Provides a sysctl interface to allow reading arbitrary PHY registers in  */
8965/* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
8966/*                                                                          */
8967/* Returns:                                                                 */
8968/*   0 for success, positive value for failure.                             */
8969/****************************************************************************/
8970static int
8971bce_sysctl_phy_read(SYSCTL_HANDLER_ARGS)
8972{
8973	struct bce_softc *sc;
8974	device_t dev;
8975	int error, result;
8976	u16 val;
8977
8978	result = -1;
8979	error = sysctl_handle_int(oidp, &result, 0, req);
8980	if (error || (req->newptr == NULL))
8981		return (error);
8982
8983	/* Make sure the register is accessible. */
8984	if (result < 0x20) {
8985		sc = (struct bce_softc *)arg1;
8986		dev = sc->bce_dev;
8987		val = bce_miibus_read_reg(dev, sc->bce_phy_addr, result);
8988		BCE_PRINTF("phy 0x%02X = 0x%04X\n", result, val);
8989	}
8990	return (error);
8991}
8992
8993
8994/****************************************************************************/
8995/* Provides a sysctl interface for dumping the nvram contents.              */
8996/* DO NOT ENABLE ON PRODUCTION SYSTEMS!					    */
8997/*									    */
8998/* Returns:								    */
8999/*   0 for success, positive errno for failure.				    */
9000/****************************************************************************/
9001static int
9002bce_sysctl_nvram_dump(SYSCTL_HANDLER_ARGS)
9003{
9004	struct bce_softc *sc = (struct bce_softc *)arg1;
9005	int error, i;
9006
9007	if (sc->nvram_buf == NULL)
9008		sc->nvram_buf = malloc(sc->bce_flash_size,
9009				    M_TEMP, M_ZERO | M_WAITOK);
9010
9011	error = 0;
9012	if (req->oldlen == sc->bce_flash_size) {
9013		for (i = 0; i < sc->bce_flash_size && error == 0; i++)
9014			error = bce_nvram_read(sc, i, &sc->nvram_buf[i], 1);
9015	}
9016
9017	if (error == 0)
9018		error = SYSCTL_OUT(req, sc->nvram_buf, sc->bce_flash_size);
9019
9020	return error;
9021}
9022
9023#ifdef BCE_NVRAM_WRITE_SUPPORT
9024/****************************************************************************/
9025/* Provides a sysctl interface for writing to nvram.                        */
9026/* DO NOT ENABLE ON PRODUCTION SYSTEMS!					    */
9027/*									    */
9028/* Returns:								    */
9029/*   0 for success, positive errno for failure.				    */
9030/****************************************************************************/
9031static int
9032bce_sysctl_nvram_write(SYSCTL_HANDLER_ARGS)
9033{
9034	struct bce_softc *sc = (struct bce_softc *)arg1;
9035	int error;
9036
9037	if (sc->nvram_buf == NULL)
9038		sc->nvram_buf = malloc(sc->bce_flash_size,
9039				    M_TEMP, M_ZERO | M_WAITOK);
9040	else
9041		bzero(sc->nvram_buf, sc->bce_flash_size);
9042
9043	error = SYSCTL_IN(req, sc->nvram_buf, sc->bce_flash_size);
9044	if (error == 0)
9045		return (error);
9046
9047	if (req->newlen == sc->bce_flash_size)
9048		error = bce_nvram_write(sc, 0, sc->nvram_buf,
9049			    sc->bce_flash_size);
9050
9051
9052	return error;
9053}
9054#endif
9055
9056
9057/****************************************************************************/
9058/* Provides a sysctl interface to allow reading a CID.                      */
9059/*                                                                          */
9060/* Returns:                                                                 */
9061/*   0 for success, positive value for failure.                             */
9062/****************************************************************************/
9063static int
9064bce_sysctl_dump_ctx(SYSCTL_HANDLER_ARGS)
9065{
9066	struct bce_softc *sc;
9067	int error, result;
9068
9069	result = -1;
9070	error = sysctl_handle_int(oidp, &result, 0, req);
9071	if (error || (req->newptr == NULL))
9072		return (error);
9073
9074	/* Make sure the register is accessible. */
9075	if (result <= TX_CID) {
9076		sc = (struct bce_softc *)arg1;
9077		bce_dump_ctx(sc, result);
9078	}
9079
9080	return (error);
9081}
9082
9083
9084/****************************************************************************/
9085/* Provides a sysctl interface to forcing the driver to dump state and      */
9086/* enter the debugger.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                */
9087/*                                                                          */
9088/* Returns:                                                                 */
9089/*   0 for success, positive value for failure.                             */
9090/****************************************************************************/
9091static int
9092bce_sysctl_breakpoint(SYSCTL_HANDLER_ARGS)
9093{
9094	int error;
9095	int result;
9096	struct bce_softc *sc;
9097
9098	result = -1;
9099	error = sysctl_handle_int(oidp, &result, 0, req);
9100
9101	if (error || !req->newptr)
9102		return (error);
9103
9104	if (result == 1) {
9105		sc = (struct bce_softc *)arg1;
9106		bce_breakpoint(sc);
9107	}
9108
9109	return error;
9110}
9111#endif
9112
9113/****************************************************************************/
9114/* Adds any sysctl parameters for tuning or debugging purposes.             */
9115/*                                                                          */
9116/* Returns:                                                                 */
9117/*   0 for success, positive value for failure.                             */
9118/****************************************************************************/
9119static void
9120bce_add_sysctls(struct bce_softc *sc)
9121{
9122	struct sysctl_ctx_list *ctx;
9123	struct sysctl_oid_list *children;
9124
9125	DBENTER(BCE_VERBOSE_MISC);
9126
9127	ctx = device_get_sysctl_ctx(sc->bce_dev);
9128	children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->bce_dev));
9129
9130#ifdef BCE_DEBUG
9131	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
9132	    "l2fhdr_error_sim_control",
9133	    CTLFLAG_RW, &l2fhdr_error_sim_control,
9134	    0, "Debug control to force l2fhdr errors");
9135
9136	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
9137	    "l2fhdr_error_sim_count",
9138	    CTLFLAG_RD, &sc->l2fhdr_error_sim_count,
9139	    0, "Number of simulated l2_fhdr errors");
9140#endif
9141
9142	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9143	    "l2fhdr_error_count",
9144	    CTLFLAG_RD, &sc->l2fhdr_error_count,
9145	    0, "Number of l2_fhdr errors");
9146
9147#ifdef BCE_DEBUG
9148	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
9149	    "mbuf_alloc_failed_sim_control",
9150	    CTLFLAG_RW, &mbuf_alloc_failed_sim_control,
9151	    0, "Debug control to force mbuf allocation failures");
9152
9153	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9154	    "mbuf_alloc_failed_sim_count",
9155	    CTLFLAG_RD, &sc->mbuf_alloc_failed_sim_count,
9156	    0, "Number of simulated mbuf cluster allocation failures");
9157#endif
9158
9159	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9160	    "mbuf_alloc_failed_count",
9161	    CTLFLAG_RD, &sc->mbuf_alloc_failed_count,
9162	    0, "Number of mbuf allocation failures");
9163
9164	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9165	    "mbuf_frag_count",
9166	    CTLFLAG_RD, &sc->mbuf_frag_count,
9167	    0, "Number of fragmented mbufs");
9168
9169#ifdef BCE_DEBUG
9170	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
9171	    "dma_map_addr_failed_sim_control",
9172	    CTLFLAG_RW, &dma_map_addr_failed_sim_control,
9173	    0, "Debug control to force DMA mapping failures");
9174
9175	/* ToDo: Figure out how to update this value in bce_dma_map_addr(). */
9176	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9177	    "dma_map_addr_failed_sim_count",
9178	    CTLFLAG_RD, &sc->dma_map_addr_failed_sim_count,
9179	    0, "Number of simulated DMA mapping failures");
9180
9181#endif
9182
9183	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9184	    "dma_map_addr_rx_failed_count",
9185	    CTLFLAG_RD, &sc->dma_map_addr_rx_failed_count,
9186	    0, "Number of RX DMA mapping failures");
9187
9188	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9189	    "dma_map_addr_tx_failed_count",
9190	    CTLFLAG_RD, &sc->dma_map_addr_tx_failed_count,
9191	    0, "Number of TX DMA mapping failures");
9192
9193#ifdef BCE_DEBUG
9194	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
9195	    "unexpected_attention_sim_control",
9196	    CTLFLAG_RW, &unexpected_attention_sim_control,
9197	    0, "Debug control to simulate unexpected attentions");
9198
9199	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9200	    "unexpected_attention_sim_count",
9201	    CTLFLAG_RW, &sc->unexpected_attention_sim_count,
9202	    0, "Number of simulated unexpected attentions");
9203#endif
9204
9205	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9206	    "unexpected_attention_count",
9207	    CTLFLAG_RW, &sc->unexpected_attention_count,
9208	    0, "Number of unexpected attentions");
9209
9210#ifdef BCE_DEBUG
9211	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
9212	    "debug_bootcode_running_failure",
9213	    CTLFLAG_RW, &bootcode_running_failure_sim_control,
9214	    0, "Debug control to force bootcode running failures");
9215
9216	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
9217	    "rx_low_watermark",
9218	    CTLFLAG_RD, &sc->rx_low_watermark,
9219	    0, "Lowest level of free rx_bd's");
9220
9221	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9222	    "rx_empty_count",
9223	    CTLFLAG_RD, &sc->rx_empty_count,
9224	    "Number of times the RX chain was empty");
9225
9226	SYSCTL_ADD_INT(ctx, children, OID_AUTO,
9227	    "tx_hi_watermark",
9228	    CTLFLAG_RD, &sc->tx_hi_watermark,
9229	    0, "Highest level of used tx_bd's");
9230
9231	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9232	    "tx_full_count",
9233	    CTLFLAG_RD, &sc->tx_full_count,
9234	    "Number of times the TX chain was full");
9235
9236	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9237	    "tso_frames_requested",
9238	    CTLFLAG_RD, &sc->tso_frames_requested,
9239	    "Number of TSO frames requested");
9240
9241	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9242	    "tso_frames_completed",
9243	    CTLFLAG_RD, &sc->tso_frames_completed,
9244	    "Number of TSO frames completed");
9245
9246	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9247	    "tso_frames_failed",
9248	    CTLFLAG_RD, &sc->tso_frames_failed,
9249	    "Number of TSO frames failed");
9250
9251	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9252	    "csum_offload_ip",
9253	    CTLFLAG_RD, &sc->csum_offload_ip,
9254	    "Number of IP checksum offload frames");
9255
9256	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9257	    "csum_offload_tcp_udp",
9258	    CTLFLAG_RD, &sc->csum_offload_tcp_udp,
9259	    "Number of TCP/UDP checksum offload frames");
9260
9261	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9262	    "vlan_tagged_frames_rcvd",
9263	    CTLFLAG_RD, &sc->vlan_tagged_frames_rcvd,
9264	    "Number of VLAN tagged frames received");
9265
9266	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9267	    "vlan_tagged_frames_stripped",
9268	    CTLFLAG_RD, &sc->vlan_tagged_frames_stripped,
9269	    "Number of VLAN tagged frames stripped");
9270
9271	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9272	    "interrupts_rx",
9273	    CTLFLAG_RD, &sc->interrupts_rx,
9274	    "Number of RX interrupts");
9275
9276	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9277	    "interrupts_tx",
9278	    CTLFLAG_RD, &sc->interrupts_tx,
9279	    "Number of TX interrupts");
9280
9281	if (bce_hdr_split == TRUE) {
9282		SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9283		    "split_header_frames_rcvd",
9284		    CTLFLAG_RD, &sc->split_header_frames_rcvd,
9285		    "Number of split header frames received");
9286
9287		SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9288		    "split_header_tcp_frames_rcvd",
9289		    CTLFLAG_RD, &sc->split_header_tcp_frames_rcvd,
9290		    "Number of split header TCP frames received");
9291	}
9292
9293	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9294	    "nvram_dump", CTLTYPE_OPAQUE | CTLFLAG_RD,
9295	    (void *)sc, 0,
9296	    bce_sysctl_nvram_dump, "S", "");
9297
9298#ifdef BCE_NVRAM_WRITE_SUPPORT
9299	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9300	    "nvram_write", CTLTYPE_OPAQUE | CTLFLAG_WR,
9301	    (void *)sc, 0,
9302	    bce_sysctl_nvram_write, "S", "");
9303#endif
9304#endif /* BCE_DEBUG */
9305
9306	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9307	    "stat_IfHcInOctets",
9308	    CTLFLAG_RD, &sc->stat_IfHCInOctets,
9309	    "Bytes received");
9310
9311	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9312	    "stat_IfHCInBadOctets",
9313	    CTLFLAG_RD, &sc->stat_IfHCInBadOctets,
9314	    "Bad bytes received");
9315
9316	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9317	    "stat_IfHCOutOctets",
9318	    CTLFLAG_RD, &sc->stat_IfHCOutOctets,
9319	    "Bytes sent");
9320
9321	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9322	    "stat_IfHCOutBadOctets",
9323	    CTLFLAG_RD, &sc->stat_IfHCOutBadOctets,
9324	    "Bad bytes sent");
9325
9326	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9327	    "stat_IfHCInUcastPkts",
9328	    CTLFLAG_RD, &sc->stat_IfHCInUcastPkts,
9329	    "Unicast packets received");
9330
9331	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9332	    "stat_IfHCInMulticastPkts",
9333	    CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts,
9334	    "Multicast packets received");
9335
9336	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9337	    "stat_IfHCInBroadcastPkts",
9338	    CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts,
9339	    "Broadcast packets received");
9340
9341	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9342	    "stat_IfHCOutUcastPkts",
9343	    CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts,
9344	    "Unicast packets sent");
9345
9346	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9347	    "stat_IfHCOutMulticastPkts",
9348	    CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts,
9349	    "Multicast packets sent");
9350
9351	SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
9352	    "stat_IfHCOutBroadcastPkts",
9353	    CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts,
9354	    "Broadcast packets sent");
9355
9356	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9357	    "stat_emac_tx_stat_dot3statsinternalmactransmiterrors",
9358	    CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors,
9359	    0, "Internal MAC transmit errors");
9360
9361	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9362	    "stat_Dot3StatsCarrierSenseErrors",
9363	    CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors,
9364	    0, "Carrier sense errors");
9365
9366	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9367	    "stat_Dot3StatsFCSErrors",
9368	    CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors,
9369	    0, "Frame check sequence errors");
9370
9371	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9372	    "stat_Dot3StatsAlignmentErrors",
9373	    CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors,
9374	    0, "Alignment errors");
9375
9376	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9377	    "stat_Dot3StatsSingleCollisionFrames",
9378	    CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames,
9379	    0, "Single Collision Frames");
9380
9381	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9382	    "stat_Dot3StatsMultipleCollisionFrames",
9383	    CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames,
9384	    0, "Multiple Collision Frames");
9385
9386	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9387	    "stat_Dot3StatsDeferredTransmissions",
9388	    CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions,
9389	    0, "Deferred Transmissions");
9390
9391	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9392	    "stat_Dot3StatsExcessiveCollisions",
9393	    CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions,
9394	    0, "Excessive Collisions");
9395
9396	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9397	    "stat_Dot3StatsLateCollisions",
9398	    CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions,
9399	    0, "Late Collisions");
9400
9401	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9402	    "stat_EtherStatsCollisions",
9403	    CTLFLAG_RD, &sc->stat_EtherStatsCollisions,
9404	    0, "Collisions");
9405
9406	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9407	    "stat_EtherStatsFragments",
9408	    CTLFLAG_RD, &sc->stat_EtherStatsFragments,
9409	    0, "Fragments");
9410
9411	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9412	    "stat_EtherStatsJabbers",
9413	    CTLFLAG_RD, &sc->stat_EtherStatsJabbers,
9414	    0, "Jabbers");
9415
9416	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9417	    "stat_EtherStatsUndersizePkts",
9418	    CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts,
9419	    0, "Undersize packets");
9420
9421	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9422	    "stat_EtherStatsOversizePkts",
9423	    CTLFLAG_RD, &sc->stat_EtherStatsOversizePkts,
9424	    0, "stat_EtherStatsOversizePkts");
9425
9426	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9427	    "stat_EtherStatsPktsRx64Octets",
9428	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets,
9429	    0, "Bytes received in 64 byte packets");
9430
9431	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9432	    "stat_EtherStatsPktsRx65Octetsto127Octets",
9433	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets,
9434	    0, "Bytes received in 65 to 127 byte packets");
9435
9436	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9437	    "stat_EtherStatsPktsRx128Octetsto255Octets",
9438	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets,
9439	    0, "Bytes received in 128 to 255 byte packets");
9440
9441	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9442	    "stat_EtherStatsPktsRx256Octetsto511Octets",
9443	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets,
9444	    0, "Bytes received in 256 to 511 byte packets");
9445
9446	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9447	    "stat_EtherStatsPktsRx512Octetsto1023Octets",
9448	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets,
9449	    0, "Bytes received in 512 to 1023 byte packets");
9450
9451	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9452	    "stat_EtherStatsPktsRx1024Octetsto1522Octets",
9453	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets,
9454	    0, "Bytes received in 1024 t0 1522 byte packets");
9455
9456	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9457	    "stat_EtherStatsPktsRx1523Octetsto9022Octets",
9458	    CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets,
9459	    0, "Bytes received in 1523 to 9022 byte packets");
9460
9461	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9462	    "stat_EtherStatsPktsTx64Octets",
9463	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets,
9464	    0, "Bytes sent in 64 byte packets");
9465
9466	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9467	    "stat_EtherStatsPktsTx65Octetsto127Octets",
9468	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets,
9469	    0, "Bytes sent in 65 to 127 byte packets");
9470
9471	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9472	    "stat_EtherStatsPktsTx128Octetsto255Octets",
9473	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets,
9474	    0, "Bytes sent in 128 to 255 byte packets");
9475
9476	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9477	    "stat_EtherStatsPktsTx256Octetsto511Octets",
9478	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets,
9479	    0, "Bytes sent in 256 to 511 byte packets");
9480
9481	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9482	    "stat_EtherStatsPktsTx512Octetsto1023Octets",
9483	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets,
9484	    0, "Bytes sent in 512 to 1023 byte packets");
9485
9486	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9487	    "stat_EtherStatsPktsTx1024Octetsto1522Octets",
9488	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets,
9489	    0, "Bytes sent in 1024 to 1522 byte packets");
9490
9491	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9492	    "stat_EtherStatsPktsTx1523Octetsto9022Octets",
9493	    CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets,
9494	    0, "Bytes sent in 1523 to 9022 byte packets");
9495
9496	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9497	    "stat_XonPauseFramesReceived",
9498	    CTLFLAG_RD, &sc->stat_XonPauseFramesReceived,
9499	    0, "XON pause frames receved");
9500
9501	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9502	    "stat_XoffPauseFramesReceived",
9503	    CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived,
9504	    0, "XOFF pause frames received");
9505
9506	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9507	    "stat_OutXonSent",
9508	    CTLFLAG_RD, &sc->stat_OutXonSent,
9509	    0, "XON pause frames sent");
9510
9511	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9512	    "stat_OutXoffSent",
9513	    CTLFLAG_RD, &sc->stat_OutXoffSent,
9514	    0, "XOFF pause frames sent");
9515
9516	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9517	    "stat_FlowControlDone",
9518	    CTLFLAG_RD, &sc->stat_FlowControlDone,
9519	    0, "Flow control done");
9520
9521	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9522	    "stat_MacControlFramesReceived",
9523	    CTLFLAG_RD, &sc->stat_MacControlFramesReceived,
9524	    0, "MAC control frames received");
9525
9526	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9527	    "stat_XoffStateEntered",
9528	    CTLFLAG_RD, &sc->stat_XoffStateEntered,
9529	    0, "XOFF state entered");
9530
9531	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9532	    "stat_IfInFramesL2FilterDiscards",
9533	    CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards,
9534	    0, "Received L2 packets discarded");
9535
9536	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9537	    "stat_IfInRuleCheckerDiscards",
9538	    CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards,
9539	    0, "Received packets discarded by rule");
9540
9541	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9542	    "stat_IfInFTQDiscards",
9543	    CTLFLAG_RD, &sc->stat_IfInFTQDiscards,
9544	    0, "Received packet FTQ discards");
9545
9546	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9547	    "stat_IfInMBUFDiscards",
9548	    CTLFLAG_RD, &sc->stat_IfInMBUFDiscards,
9549	    0, "Received packets discarded due to lack "
9550	    "of controller buffer memory");
9551
9552	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9553	    "stat_IfInRuleCheckerP4Hit",
9554	    CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit,
9555	    0, "Received packets rule checker hits");
9556
9557	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9558	    "stat_CatchupInRuleCheckerDiscards",
9559	    CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards,
9560	    0, "Received packets discarded in Catchup path");
9561
9562	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9563	    "stat_CatchupInFTQDiscards",
9564	    CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards,
9565	    0, "Received packets discarded in FTQ in Catchup path");
9566
9567	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9568	    "stat_CatchupInMBUFDiscards",
9569	    CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards,
9570	    0, "Received packets discarded in controller "
9571	    "buffer memory in Catchup path");
9572
9573	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9574	    "stat_CatchupInRuleCheckerP4Hit",
9575	    CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit,
9576	    0, "Received packets rule checker hits in Catchup path");
9577
9578	SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
9579	    "com_no_buffers",
9580	    CTLFLAG_RD, &sc->com_no_buffers,
9581	    0, "Valid packets received but no RX buffers available");
9582
9583#ifdef BCE_DEBUG
9584	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9585	    "driver_state", CTLTYPE_INT | CTLFLAG_RW,
9586	    (void *)sc, 0,
9587	    bce_sysctl_driver_state, "I", "Drive state information");
9588
9589	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9590	    "hw_state", CTLTYPE_INT | CTLFLAG_RW,
9591	    (void *)sc, 0,
9592	    bce_sysctl_hw_state, "I", "Hardware state information");
9593
9594	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9595	    "status_block", CTLTYPE_INT | CTLFLAG_RW,
9596	    (void *)sc, 0,
9597	    bce_sysctl_status_block, "I", "Dump status block");
9598
9599	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9600	    "stats_block", CTLTYPE_INT | CTLFLAG_RW,
9601	    (void *)sc, 0,
9602	    bce_sysctl_stats_block, "I", "Dump statistics block");
9603
9604	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9605	    "stats_clear", CTLTYPE_INT | CTLFLAG_RW,
9606	    (void *)sc, 0,
9607	    bce_sysctl_stats_clear, "I", "Clear statistics block");
9608
9609	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9610	    "shmem_state", CTLTYPE_INT | CTLFLAG_RW,
9611	    (void *)sc, 0,
9612	    bce_sysctl_shmem_state, "I", "Shared memory state information");
9613
9614	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9615	    "bc_state", CTLTYPE_INT | CTLFLAG_RW,
9616	    (void *)sc, 0,
9617	    bce_sysctl_bc_state, "I", "Bootcode state information");
9618
9619	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9620	    "dump_rx_bd_chain", CTLTYPE_INT | CTLFLAG_RW,
9621	    (void *)sc, 0,
9622	    bce_sysctl_dump_rx_bd_chain, "I", "Dump RX BD chain");
9623
9624	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9625	    "dump_rx_mbuf_chain", CTLTYPE_INT | CTLFLAG_RW,
9626	    (void *)sc, 0,
9627	    bce_sysctl_dump_rx_mbuf_chain, "I", "Dump RX MBUF chain");
9628
9629	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9630	    "dump_tx_chain", CTLTYPE_INT | CTLFLAG_RW,
9631	    (void *)sc, 0,
9632	    bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
9633
9634	if (bce_hdr_split == TRUE) {
9635		SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9636		    "dump_pg_chain", CTLTYPE_INT | CTLFLAG_RW,
9637		    (void *)sc, 0,
9638		    bce_sysctl_dump_pg_chain, "I", "Dump page chain");
9639	}
9640
9641	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9642	    "dump_ctx", CTLTYPE_INT | CTLFLAG_RW,
9643	    (void *)sc, 0,
9644	    bce_sysctl_dump_ctx, "I", "Dump context memory");
9645
9646	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9647	    "breakpoint", CTLTYPE_INT | CTLFLAG_RW,
9648	    (void *)sc, 0,
9649	    bce_sysctl_breakpoint, "I", "Driver breakpoint");
9650
9651	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9652	    "reg_read", CTLTYPE_INT | CTLFLAG_RW,
9653	    (void *)sc, 0,
9654	    bce_sysctl_reg_read, "I", "Register read");
9655
9656	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9657	    "nvram_read", CTLTYPE_INT | CTLFLAG_RW,
9658	    (void *)sc, 0,
9659	    bce_sysctl_nvram_read, "I", "NVRAM read");
9660
9661	SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
9662	    "phy_read", CTLTYPE_INT | CTLFLAG_RW,
9663	    (void *)sc, 0,
9664	    bce_sysctl_phy_read, "I", "PHY register read");
9665
9666#endif
9667
9668	DBEXIT(BCE_VERBOSE_MISC);
9669}
9670
9671
9672/****************************************************************************/
9673/* BCE Debug Routines                                                       */
9674/****************************************************************************/
9675#ifdef BCE_DEBUG
9676
9677/****************************************************************************/
9678/* Freezes the controller to allow for a cohesive state dump.               */
9679/*                                                                          */
9680/* Returns:                                                                 */
9681/*   Nothing.                                                               */
9682/****************************************************************************/
9683static __attribute__ ((noinline)) void
9684bce_freeze_controller(struct bce_softc *sc)
9685{
9686	u32 val;
9687	val = REG_RD(sc, BCE_MISC_COMMAND);
9688	val |= BCE_MISC_COMMAND_DISABLE_ALL;
9689	REG_WR(sc, BCE_MISC_COMMAND, val);
9690}
9691
9692
9693/****************************************************************************/
9694/* Unfreezes the controller after a freeze operation.  This may not always  */
9695/* work and the controller will require a reset!                            */
9696/*                                                                          */
9697/* Returns:                                                                 */
9698/*   Nothing.                                                               */
9699/****************************************************************************/
9700static __attribute__ ((noinline)) void
9701bce_unfreeze_controller(struct bce_softc *sc)
9702{
9703	u32 val;
9704	val = REG_RD(sc, BCE_MISC_COMMAND);
9705	val |= BCE_MISC_COMMAND_ENABLE_ALL;
9706	REG_WR(sc, BCE_MISC_COMMAND, val);
9707}
9708
9709
9710/****************************************************************************/
9711/* Prints out Ethernet frame information from an mbuf.                      */
9712/*                                                                          */
9713/* Partially decode an Ethernet frame to look at some important headers.    */
9714/*                                                                          */
9715/* Returns:                                                                 */
9716/*   Nothing.                                                               */
9717/****************************************************************************/
9718static __attribute__ ((noinline)) void
9719bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
9720{
9721	struct ether_vlan_header *eh;
9722	u16 etype;
9723	int ehlen;
9724	struct ip *ip;
9725	struct tcphdr *th;
9726	struct udphdr *uh;
9727	struct arphdr *ah;
9728
9729	BCE_PRINTF(
9730	    "-----------------------------"
9731	    " Frame Decode "
9732	    "-----------------------------\n");
9733
9734	eh = mtod(m, struct ether_vlan_header *);
9735
9736	/* Handle VLAN encapsulation if present. */
9737	if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
9738		etype = ntohs(eh->evl_proto);
9739		ehlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
9740	} else {
9741		etype = ntohs(eh->evl_encap_proto);
9742		ehlen = ETHER_HDR_LEN;
9743	}
9744
9745	/* ToDo: Add VLAN output. */
9746	BCE_PRINTF("enet: dest = %6D, src = %6D, type = 0x%04X, hlen = %d\n",
9747	    eh->evl_dhost, ":", eh->evl_shost, ":", etype, ehlen);
9748
9749	switch (etype) {
9750	case ETHERTYPE_IP:
9751		ip = (struct ip *)(m->m_data + ehlen);
9752		BCE_PRINTF("--ip: dest = 0x%08X , src = 0x%08X, "
9753		    "len = %d bytes, protocol = 0x%02X, xsum = 0x%04X\n",
9754		    ntohl(ip->ip_dst.s_addr), ntohl(ip->ip_src.s_addr),
9755		    ntohs(ip->ip_len), ip->ip_p, ntohs(ip->ip_sum));
9756
9757		switch (ip->ip_p) {
9758		case IPPROTO_TCP:
9759			th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
9760			BCE_PRINTF("-tcp: dest = %d, src = %d, hlen = "
9761			    "%d bytes, flags = 0x%b, csum = 0x%04X\n",
9762			    ntohs(th->th_dport), ntohs(th->th_sport),
9763			    (th->th_off << 2), th->th_flags,
9764			    "\20\10CWR\07ECE\06URG\05ACK\04PSH\03RST"
9765			    "\02SYN\01FIN", ntohs(th->th_sum));
9766			break;
9767		case IPPROTO_UDP:
9768			uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
9769			BCE_PRINTF("-udp: dest = %d, src = %d, len = %d "
9770			    "bytes, csum = 0x%04X\n", ntohs(uh->uh_dport),
9771			    ntohs(uh->uh_sport), ntohs(uh->uh_ulen),
9772			    ntohs(uh->uh_sum));
9773			break;
9774		case IPPROTO_ICMP:
9775			BCE_PRINTF("icmp:\n");
9776			break;
9777		default:
9778			BCE_PRINTF("----: Other IP protocol.\n");
9779			}
9780		break;
9781	case ETHERTYPE_IPV6:
9782		BCE_PRINTF("ipv6: No decode supported.\n");
9783		break;
9784	case ETHERTYPE_ARP:
9785		BCE_PRINTF("-arp: ");
9786		ah = (struct arphdr *) (m->m_data + ehlen);
9787		switch (ntohs(ah->ar_op)) {
9788		case ARPOP_REVREQUEST:
9789			printf("reverse ARP request\n");
9790			break;
9791		case ARPOP_REVREPLY:
9792			printf("reverse ARP reply\n");
9793			break;
9794		case ARPOP_REQUEST:
9795			printf("ARP request\n");
9796			break;
9797		case ARPOP_REPLY:
9798			printf("ARP reply\n");
9799			break;
9800		default:
9801			printf("other ARP operation\n");
9802		}
9803		break;
9804	default:
9805		BCE_PRINTF("----: Other protocol.\n");
9806	}
9807
9808	BCE_PRINTF(
9809		"-----------------------------"
9810		"--------------"
9811		"-----------------------------\n");
9812}
9813
9814
9815/****************************************************************************/
9816/* Prints out information about an mbuf.                                    */
9817/*                                                                          */
9818/* Returns:                                                                 */
9819/*   Nothing.                                                               */
9820/****************************************************************************/
9821static __attribute__ ((noinline)) void
9822bce_dump_mbuf(struct bce_softc *sc, struct mbuf *m)
9823{
9824	struct mbuf *mp = m;
9825
9826	if (m == NULL) {
9827		BCE_PRINTF("mbuf: null pointer\n");
9828		return;
9829	}
9830
9831	while (mp) {
9832		BCE_PRINTF("mbuf: %p, m_len = %d, m_flags = 0x%b, "
9833		    "m_data = %p\n", mp, mp->m_len, mp->m_flags,
9834		    "\20\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY", mp->m_data);
9835
9836		if (mp->m_flags & M_PKTHDR) {
9837			BCE_PRINTF("- m_pkthdr: len = %d, flags = 0x%b, "
9838			    "csum_flags = %b\n", mp->m_pkthdr.len,
9839			    mp->m_flags, M_FLAG_PRINTF,
9840			    mp->m_pkthdr.csum_flags,
9841			    "\20\1CSUM_IP\2CSUM_TCP\3CSUM_UDP"
9842			    "\5CSUM_FRAGMENT\6CSUM_TSO\11CSUM_IP_CHECKED"
9843			    "\12CSUM_IP_VALID\13CSUM_DATA_VALID"
9844			    "\14CSUM_PSEUDO_HDR");
9845		}
9846
9847		if (mp->m_flags & M_EXT) {
9848			BCE_PRINTF("- m_ext: %p, ext_size = %d, type = ",
9849			    mp->m_ext.ext_buf, mp->m_ext.ext_size);
9850			switch (mp->m_ext.ext_type) {
9851			case EXT_CLUSTER:
9852				printf("EXT_CLUSTER\n"); break;
9853			case EXT_SFBUF:
9854				printf("EXT_SFBUF\n"); break;
9855			case EXT_JUMBO9:
9856				printf("EXT_JUMBO9\n"); break;
9857			case EXT_JUMBO16:
9858				printf("EXT_JUMBO16\n"); break;
9859			case EXT_PACKET:
9860				printf("EXT_PACKET\n"); break;
9861			case EXT_MBUF:
9862				printf("EXT_MBUF\n"); break;
9863			case EXT_NET_DRV:
9864				printf("EXT_NET_DRV\n"); break;
9865			case EXT_MOD_TYPE:
9866				printf("EXT_MDD_TYPE\n"); break;
9867			case EXT_DISPOSABLE:
9868				printf("EXT_DISPOSABLE\n"); break;
9869			case EXT_EXTREF:
9870				printf("EXT_EXTREF\n"); break;
9871			default:
9872				printf("UNKNOWN\n");
9873			}
9874		}
9875
9876		mp = mp->m_next;
9877	}
9878}
9879
9880
9881/****************************************************************************/
9882/* Prints out the mbufs in the TX mbuf chain.                               */
9883/*                                                                          */
9884/* Returns:                                                                 */
9885/*   Nothing.                                                               */
9886/****************************************************************************/
9887static __attribute__ ((noinline)) void
9888bce_dump_tx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
9889{
9890	struct mbuf *m;
9891
9892	BCE_PRINTF(
9893		"----------------------------"
9894		"  tx mbuf data  "
9895		"----------------------------\n");
9896
9897	for (int i = 0; i < count; i++) {
9898	 	m = sc->tx_mbuf_ptr[chain_prod];
9899		BCE_PRINTF("txmbuf[0x%04X]\n", chain_prod);
9900		bce_dump_mbuf(sc, m);
9901		chain_prod = TX_CHAIN_IDX(NEXT_TX_BD(chain_prod));
9902	}
9903
9904	BCE_PRINTF(
9905		"----------------------------"
9906		"----------------"
9907		"----------------------------\n");
9908}
9909
9910
9911/****************************************************************************/
9912/* Prints out the mbufs in the RX mbuf chain.                               */
9913/*                                                                          */
9914/* Returns:                                                                 */
9915/*   Nothing.                                                               */
9916/****************************************************************************/
9917static __attribute__ ((noinline)) void
9918bce_dump_rx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
9919{
9920	struct mbuf *m;
9921
9922	BCE_PRINTF(
9923		"----------------------------"
9924		"  rx mbuf data  "
9925		"----------------------------\n");
9926
9927	for (int i = 0; i < count; i++) {
9928	 	m = sc->rx_mbuf_ptr[chain_prod];
9929		BCE_PRINTF("rxmbuf[0x%04X]\n", chain_prod);
9930		bce_dump_mbuf(sc, m);
9931		chain_prod = RX_CHAIN_IDX(NEXT_RX_BD(chain_prod));
9932	}
9933
9934
9935	BCE_PRINTF(
9936		"----------------------------"
9937		"----------------"
9938		"----------------------------\n");
9939}
9940
9941
9942/****************************************************************************/
9943/* Prints out the mbufs in the mbuf page chain.                             */
9944/*                                                                          */
9945/* Returns:                                                                 */
9946/*   Nothing.                                                               */
9947/****************************************************************************/
9948static __attribute__ ((noinline)) void
9949bce_dump_pg_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
9950{
9951	struct mbuf *m;
9952
9953	BCE_PRINTF(
9954		"----------------------------"
9955		"  pg mbuf data  "
9956		"----------------------------\n");
9957
9958	for (int i = 0; i < count; i++) {
9959	 	m = sc->pg_mbuf_ptr[chain_prod];
9960		BCE_PRINTF("pgmbuf[0x%04X]\n", chain_prod);
9961		bce_dump_mbuf(sc, m);
9962		chain_prod = PG_CHAIN_IDX(NEXT_PG_BD(chain_prod));
9963	}
9964
9965
9966	BCE_PRINTF(
9967		"----------------------------"
9968		"----------------"
9969		"----------------------------\n");
9970}
9971
9972
9973/****************************************************************************/
9974/* Prints out a tx_bd structure.                                            */
9975/*                                                                          */
9976/* Returns:                                                                 */
9977/*   Nothing.                                                               */
9978/****************************************************************************/
9979static __attribute__ ((noinline)) void
9980bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
9981{
9982	int i = 0;
9983
9984	if (idx > MAX_TX_BD_ALLOC)
9985		/* Index out of range. */
9986		BCE_PRINTF("tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
9987	else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
9988		/* TX Chain page pointer. */
9989		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
9990		    "pointer\n", idx, txbd->tx_bd_haddr_hi,
9991		    txbd->tx_bd_haddr_lo);
9992	else {
9993		/* Normal tx_bd entry. */
9994		BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, "
9995		    "mss_nbytes = 0x%08X, vlan tag = 0x%04X, flags = "
9996		    "0x%04X (", idx, txbd->tx_bd_haddr_hi,
9997		    txbd->tx_bd_haddr_lo, txbd->tx_bd_mss_nbytes,
9998		    txbd->tx_bd_vlan_tag, txbd->tx_bd_flags);
9999
10000		if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT) {
10001			if (i>0)
10002				printf("|");
10003			printf("CONN_FAULT");
10004			i++;
10005		}
10006
10007		if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM) {
10008			if (i>0)
10009				printf("|");
10010			printf("TCP_UDP_CKSUM");
10011			i++;
10012		}
10013
10014		if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM) {
10015			if (i>0)
10016				printf("|");
10017			printf("IP_CKSUM");
10018			i++;
10019		}
10020
10021		if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG) {
10022			if (i>0)
10023				printf("|");
10024			printf("VLAN");
10025			i++;
10026		}
10027
10028		if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW) {
10029			if (i>0)
10030				printf("|");
10031			printf("COAL_NOW");
10032			i++;
10033		}
10034
10035		if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC) {
10036			if (i>0)
10037				printf("|");
10038			printf("DONT_GEN_CRC");
10039			i++;
10040		}
10041
10042		if (txbd->tx_bd_flags & TX_BD_FLAGS_START) {
10043			if (i>0)
10044				printf("|");
10045			printf("START");
10046			i++;
10047		}
10048
10049		if (txbd->tx_bd_flags & TX_BD_FLAGS_END) {
10050			if (i>0)
10051				printf("|");
10052			printf("END");
10053			i++;
10054		}
10055
10056		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO) {
10057			if (i>0)
10058				printf("|");
10059			printf("LSO");
10060			i++;
10061		}
10062
10063		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD) {
10064			if (i>0)
10065				printf("|");
10066			printf("SW_OPTION=%d", ((txbd->tx_bd_flags &
10067			    TX_BD_FLAGS_SW_OPTION_WORD) >> 8)); i++;
10068		}
10069
10070		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS) {
10071			if (i>0)
10072				printf("|");
10073			printf("SW_FLAGS");
10074			i++;
10075		}
10076
10077		if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP) {
10078			if (i>0)
10079				printf("|");
10080			printf("SNAP)");
10081		} else {
10082			printf(")\n");
10083		}
10084	}
10085}
10086
10087
10088/****************************************************************************/
10089/* Prints out a rx_bd structure.                                            */
10090/*                                                                          */
10091/* Returns:                                                                 */
10092/*   Nothing.                                                               */
10093/****************************************************************************/
10094static __attribute__ ((noinline)) void
10095bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd)
10096{
10097	if (idx > MAX_RX_BD_ALLOC)
10098		/* Index out of range. */
10099		BCE_PRINTF("rx_bd[0x%04X]: Invalid rx_bd index!\n", idx);
10100	else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
10101		/* RX Chain page pointer. */
10102		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
10103		    "pointer\n", idx, rxbd->rx_bd_haddr_hi,
10104		    rxbd->rx_bd_haddr_lo);
10105	else
10106		/* Normal rx_bd entry. */
10107		BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = "
10108		    "0x%08X, flags = 0x%08X\n", idx, rxbd->rx_bd_haddr_hi,
10109		    rxbd->rx_bd_haddr_lo, rxbd->rx_bd_len,
10110		    rxbd->rx_bd_flags);
10111}
10112
10113
10114/****************************************************************************/
10115/* Prints out a rx_bd structure in the page chain.                          */
10116/*                                                                          */
10117/* Returns:                                                                 */
10118/*   Nothing.                                                               */
10119/****************************************************************************/
10120static __attribute__ ((noinline)) void
10121bce_dump_pgbd(struct bce_softc *sc, int idx, struct rx_bd *pgbd)
10122{
10123	if (idx > MAX_PG_BD_ALLOC)
10124		/* Index out of range. */
10125		BCE_PRINTF("pg_bd[0x%04X]: Invalid pg_bd index!\n", idx);
10126	else if ((idx & USABLE_PG_BD_PER_PAGE) == USABLE_PG_BD_PER_PAGE)
10127		/* Page Chain page pointer. */
10128		BCE_PRINTF("px_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
10129			idx, pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo);
10130	else
10131		/* Normal rx_bd entry. */
10132		BCE_PRINTF("pg_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
10133			"flags = 0x%08X\n", idx,
10134			pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo,
10135			pgbd->rx_bd_len, pgbd->rx_bd_flags);
10136}
10137
10138
10139/****************************************************************************/
10140/* Prints out a l2_fhdr structure.                                          */
10141/*                                                                          */
10142/* Returns:                                                                 */
10143/*   Nothing.                                                               */
10144/****************************************************************************/
10145static __attribute__ ((noinline)) void
10146bce_dump_l2fhdr(struct bce_softc *sc, int idx, struct l2_fhdr *l2fhdr)
10147{
10148	BCE_PRINTF("l2_fhdr[0x%04X]: status = 0x%b, "
10149		"pkt_len = %d, vlan = 0x%04x, ip_xsum/hdr_len = 0x%04X, "
10150		"tcp_udp_xsum = 0x%04X\n", idx,
10151		l2fhdr->l2_fhdr_status, BCE_L2FHDR_PRINTFB,
10152		l2fhdr->l2_fhdr_pkt_len, l2fhdr->l2_fhdr_vlan_tag,
10153		l2fhdr->l2_fhdr_ip_xsum, l2fhdr->l2_fhdr_tcp_udp_xsum);
10154}
10155
10156
10157/****************************************************************************/
10158/* Prints out context memory info.  (Only useful for CID 0 to 16.)          */
10159/*                                                                          */
10160/* Returns:                                                                 */
10161/*   Nothing.                                                               */
10162/****************************************************************************/
10163static __attribute__ ((noinline)) void
10164bce_dump_ctx(struct bce_softc *sc, u16 cid)
10165{
10166	if (cid > TX_CID) {
10167		BCE_PRINTF(" Unknown CID\n");
10168		return;
10169	}
10170
10171	BCE_PRINTF(
10172	    "----------------------------"
10173	    "    CTX Data    "
10174	    "----------------------------\n");
10175
10176	BCE_PRINTF("     0x%04X - (CID) Context ID\n", cid);
10177
10178	if (cid == RX_CID) {
10179		BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BDIDX) host rx "
10180		   "producer index\n",
10181		    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BDIDX));
10182		BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BSEQ) host "
10183		    "byte sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
10184		    BCE_L2CTX_RX_HOST_BSEQ));
10185		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BSEQ) h/w byte sequence\n",
10186		    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BSEQ));
10187		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_HI) h/w buffer "
10188		    "descriptor address\n",
10189 		    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_HI));
10190		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_LO) h/w buffer "
10191		    "descriptor address\n",
10192		    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_LO));
10193		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDIDX) h/w rx consumer "
10194		    "index\n", CTX_RD(sc, GET_CID_ADDR(cid),
10195		    BCE_L2CTX_RX_NX_BDIDX));
10196		BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_PG_BDIDX) host page "
10197		    "producer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
10198		    BCE_L2CTX_RX_HOST_PG_BDIDX));
10199		BCE_PRINTF(" 0x%08X - (L2CTX_RX_PG_BUF_SIZE) host rx_bd/page "
10200		    "buffer size\n", CTX_RD(sc, GET_CID_ADDR(cid),
10201		    BCE_L2CTX_RX_PG_BUF_SIZE));
10202		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_HI) h/w page "
10203		    "chain address\n", CTX_RD(sc, GET_CID_ADDR(cid),
10204		    BCE_L2CTX_RX_NX_PG_BDHADDR_HI));
10205		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_LO) h/w page "
10206		    "chain address\n", CTX_RD(sc, GET_CID_ADDR(cid),
10207		    BCE_L2CTX_RX_NX_PG_BDHADDR_LO));
10208		BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDIDX) h/w page "
10209		    "consumer index\n",	CTX_RD(sc, GET_CID_ADDR(cid),
10210		    BCE_L2CTX_RX_NX_PG_BDIDX));
10211	} else if (cid == TX_CID) {
10212		if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
10213			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE_XI) ctx type\n",
10214			    CTX_RD(sc, GET_CID_ADDR(cid),
10215			    BCE_L2CTX_TX_TYPE_XI));
10216			BCE_PRINTF(" 0x%08X - (L2CTX_CMD_TX_TYPE_XI) ctx "
10217			    "cmd\n", CTX_RD(sc, GET_CID_ADDR(cid),
10218			    BCE_L2CTX_TX_CMD_TYPE_XI));
10219			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI_XI) "
10220			    "h/w buffer descriptor address\n",
10221			    CTX_RD(sc, GET_CID_ADDR(cid),
10222			    BCE_L2CTX_TX_TBDR_BHADDR_HI_XI));
10223			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO_XI) "
10224			    "h/w buffer	descriptor address\n",
10225			    CTX_RD(sc, GET_CID_ADDR(cid),
10226			    BCE_L2CTX_TX_TBDR_BHADDR_LO_XI));
10227			BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX_XI) "
10228			    "host producer index\n",
10229			    CTX_RD(sc, GET_CID_ADDR(cid),
10230			    BCE_L2CTX_TX_HOST_BIDX_XI));
10231			BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ_XI) "
10232			    "host byte sequence\n",
10233			    CTX_RD(sc, GET_CID_ADDR(cid),
10234			    BCE_L2CTX_TX_HOST_BSEQ_XI));
10235		} else {
10236			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE) ctx type\n",
10237			    CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE));
10238			BCE_PRINTF(" 0x%08X - (L2CTX_TX_CMD_TYPE) ctx cmd\n",
10239			    CTX_RD(sc, GET_CID_ADDR(cid),
10240			    BCE_L2CTX_TX_CMD_TYPE));
10241			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI) "
10242			    "h/w buffer	descriptor address\n",
10243			    CTX_RD(sc, GET_CID_ADDR(cid),
10244			    BCE_L2CTX_TX_TBDR_BHADDR_HI));
10245			BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO) "
10246			    "h/w buffer	descriptor address\n",
10247			    CTX_RD(sc, GET_CID_ADDR(cid),
10248			    BCE_L2CTX_TX_TBDR_BHADDR_LO));
10249			BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX) host "
10250			    "producer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
10251			    BCE_L2CTX_TX_HOST_BIDX));
10252			BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ) host byte "
10253			    "sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
10254			    BCE_L2CTX_TX_HOST_BSEQ));
10255		}
10256	}
10257
10258	BCE_PRINTF(
10259	   "----------------------------"
10260	   "    Raw CTX     "
10261	   "----------------------------\n");
10262
10263	for (int i = 0x0; i < 0x300; i += 0x10) {
10264		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n", i,
10265		   CTX_RD(sc, GET_CID_ADDR(cid), i),
10266		   CTX_RD(sc, GET_CID_ADDR(cid), i + 0x4),
10267		   CTX_RD(sc, GET_CID_ADDR(cid), i + 0x8),
10268		   CTX_RD(sc, GET_CID_ADDR(cid), i + 0xc));
10269	}
10270
10271
10272	BCE_PRINTF(
10273	   "----------------------------"
10274	   "----------------"
10275	   "----------------------------\n");
10276}
10277
10278
10279/****************************************************************************/
10280/* Prints out the FTQ data.                                                 */
10281/*                                                                          */
10282/* Returns:                                                                */
10283/*   Nothing.                                                               */
10284/****************************************************************************/
10285static __attribute__ ((noinline)) void
10286bce_dump_ftqs(struct bce_softc *sc)
10287{
10288	u32 cmd, ctl, cur_depth, max_depth, valid_cnt, val;
10289
10290	BCE_PRINTF(
10291	    "----------------------------"
10292	    "    FTQ Data    "
10293	    "----------------------------\n");
10294
10295	BCE_PRINTF("   FTQ    Command    Control   Depth_Now  "
10296	    "Max_Depth  Valid_Cnt \n");
10297	BCE_PRINTF(" ------- ---------- ---------- ---------- "
10298	    "---------- ----------\n");
10299
10300	/* Setup the generic statistic counters for the FTQ valid count. */
10301	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PPQ_VALID_CNT << 24) |
10302	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT  << 16) |
10303	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT   <<  8) |
10304	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT);
10305	REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
10306
10307	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCHQ_VALID_CNT  << 24) |
10308	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT  << 16) |
10309	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT <<  8) |
10310	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT);
10311	REG_WR(sc, BCE_HC_STAT_GEN_SEL_1, val);
10312
10313	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPATQ_VALID_CNT  << 24) |
10314	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT  << 16) |
10315	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT   <<  8) |
10316	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT);
10317	REG_WR(sc, BCE_HC_STAT_GEN_SEL_2, val);
10318
10319	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMQ_VALID_CNT   << 24) |
10320	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT  << 16) |
10321	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT  <<  8) |
10322	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT);
10323	REG_WR(sc, BCE_HC_STAT_GEN_SEL_3, val);
10324
10325	/* Input queue to the Receive Lookup state machine */
10326	cmd = REG_RD(sc, BCE_RLUP_FTQ_CMD);
10327	ctl = REG_RD(sc, BCE_RLUP_FTQ_CTL);
10328	cur_depth = (ctl & BCE_RLUP_FTQ_CTL_CUR_DEPTH) >> 22;
10329	max_depth = (ctl & BCE_RLUP_FTQ_CTL_MAX_DEPTH) >> 12;
10330	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
10331	BCE_PRINTF(" RLUP    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10332	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10333
10334	/* Input queue to the Receive Processor */
10335	cmd = REG_RD_IND(sc, BCE_RXP_FTQ_CMD);
10336	ctl = REG_RD_IND(sc, BCE_RXP_FTQ_CTL);
10337	cur_depth = (ctl & BCE_RXP_FTQ_CTL_CUR_DEPTH) >> 22;
10338	max_depth = (ctl & BCE_RXP_FTQ_CTL_MAX_DEPTH) >> 12;
10339	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
10340	BCE_PRINTF(" RXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10341	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10342
10343	/* Input queue to the Recevie Processor */
10344	cmd = REG_RD_IND(sc, BCE_RXP_CFTQ_CMD);
10345	ctl = REG_RD_IND(sc, BCE_RXP_CFTQ_CTL);
10346	cur_depth = (ctl & BCE_RXP_CFTQ_CTL_CUR_DEPTH) >> 22;
10347	max_depth = (ctl & BCE_RXP_CFTQ_CTL_MAX_DEPTH) >> 12;
10348	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
10349	BCE_PRINTF(" RXPC    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10350	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10351
10352	/* Input queue to the Receive Virtual to Physical state machine */
10353	cmd = REG_RD(sc, BCE_RV2P_PFTQ_CMD);
10354	ctl = REG_RD(sc, BCE_RV2P_PFTQ_CTL);
10355	cur_depth = (ctl & BCE_RV2P_PFTQ_CTL_CUR_DEPTH) >> 22;
10356	max_depth = (ctl & BCE_RV2P_PFTQ_CTL_MAX_DEPTH) >> 12;
10357	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
10358	BCE_PRINTF(" RV2PP   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10359	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10360
10361	/* Input queue to the Recevie Virtual to Physical state machine */
10362	cmd = REG_RD(sc, BCE_RV2P_MFTQ_CMD);
10363	ctl = REG_RD(sc, BCE_RV2P_MFTQ_CTL);
10364	cur_depth = (ctl & BCE_RV2P_MFTQ_CTL_CUR_DEPTH) >> 22;
10365	max_depth = (ctl & BCE_RV2P_MFTQ_CTL_MAX_DEPTH) >> 12;
10366	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT4);
10367	BCE_PRINTF(" RV2PM   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10368	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10369
10370	/* Input queue to the Receive Virtual to Physical state machine */
10371	cmd = REG_RD(sc, BCE_RV2P_TFTQ_CMD);
10372	ctl = REG_RD(sc, BCE_RV2P_TFTQ_CTL);
10373	cur_depth = (ctl & BCE_RV2P_TFTQ_CTL_CUR_DEPTH) >> 22;
10374	max_depth = (ctl & BCE_RV2P_TFTQ_CTL_MAX_DEPTH) >> 12;
10375	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT5);
10376	BCE_PRINTF(" RV2PT   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10377	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10378
10379	/* Input queue to the Receive DMA state machine */
10380	cmd = REG_RD(sc, BCE_RDMA_FTQ_CMD);
10381	ctl = REG_RD(sc, BCE_RDMA_FTQ_CTL);
10382	cur_depth = (ctl & BCE_RDMA_FTQ_CTL_CUR_DEPTH) >> 22;
10383	max_depth = (ctl & BCE_RDMA_FTQ_CTL_MAX_DEPTH) >> 12;
10384	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT6);
10385	BCE_PRINTF(" RDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10386	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10387
10388	/* Input queue to the Transmit Scheduler state machine */
10389	cmd = REG_RD(sc, BCE_TSCH_FTQ_CMD);
10390	ctl = REG_RD(sc, BCE_TSCH_FTQ_CTL);
10391	cur_depth = (ctl & BCE_TSCH_FTQ_CTL_CUR_DEPTH) >> 22;
10392	max_depth = (ctl & BCE_TSCH_FTQ_CTL_MAX_DEPTH) >> 12;
10393	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT7);
10394	BCE_PRINTF(" TSCH    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10395	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10396
10397	/* Input queue to the Transmit Buffer Descriptor state machine */
10398	cmd = REG_RD(sc, BCE_TBDR_FTQ_CMD);
10399	ctl = REG_RD(sc, BCE_TBDR_FTQ_CTL);
10400	cur_depth = (ctl & BCE_TBDR_FTQ_CTL_CUR_DEPTH) >> 22;
10401	max_depth = (ctl & BCE_TBDR_FTQ_CTL_MAX_DEPTH) >> 12;
10402	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT8);
10403	BCE_PRINTF(" TBDR    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10404	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10405
10406	/* Input queue to the Transmit Processor */
10407	cmd = REG_RD_IND(sc, BCE_TXP_FTQ_CMD);
10408	ctl = REG_RD_IND(sc, BCE_TXP_FTQ_CTL);
10409	cur_depth = (ctl & BCE_TXP_FTQ_CTL_CUR_DEPTH) >> 22;
10410	max_depth = (ctl & BCE_TXP_FTQ_CTL_MAX_DEPTH) >> 12;
10411	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT9);
10412	BCE_PRINTF(" TXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10413	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10414
10415	/* Input queue to the Transmit DMA state machine */
10416	cmd = REG_RD(sc, BCE_TDMA_FTQ_CMD);
10417	ctl = REG_RD(sc, BCE_TDMA_FTQ_CTL);
10418	cur_depth = (ctl & BCE_TDMA_FTQ_CTL_CUR_DEPTH) >> 22;
10419	max_depth = (ctl & BCE_TDMA_FTQ_CTL_MAX_DEPTH) >> 12;
10420	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT10);
10421	BCE_PRINTF(" TDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10422	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10423
10424	/* Input queue to the Transmit Patch-Up Processor */
10425	cmd = REG_RD_IND(sc, BCE_TPAT_FTQ_CMD);
10426	ctl = REG_RD_IND(sc, BCE_TPAT_FTQ_CTL);
10427	cur_depth = (ctl & BCE_TPAT_FTQ_CTL_CUR_DEPTH) >> 22;
10428	max_depth = (ctl & BCE_TPAT_FTQ_CTL_MAX_DEPTH) >> 12;
10429	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT11);
10430	BCE_PRINTF(" TPAT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10431	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10432
10433	/* Input queue to the Transmit Assembler state machine */
10434	cmd = REG_RD_IND(sc, BCE_TAS_FTQ_CMD);
10435	ctl = REG_RD_IND(sc, BCE_TAS_FTQ_CTL);
10436	cur_depth = (ctl & BCE_TAS_FTQ_CTL_CUR_DEPTH) >> 22;
10437	max_depth = (ctl & BCE_TAS_FTQ_CTL_MAX_DEPTH) >> 12;
10438	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT12);
10439	BCE_PRINTF(" TAS     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10440	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10441
10442	/* Input queue to the Completion Processor */
10443	cmd = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CMD);
10444	ctl = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CTL);
10445	cur_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_CUR_DEPTH) >> 22;
10446	max_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_MAX_DEPTH) >> 12;
10447	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT13);
10448	BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10449	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10450
10451	/* Input queue to the Completion Processor */
10452	cmd = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CMD);
10453	ctl = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CTL);
10454	cur_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_CUR_DEPTH) >> 22;
10455	max_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_MAX_DEPTH) >> 12;
10456	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT14);
10457	BCE_PRINTF(" COMT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10458	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10459
10460	/* Input queue to the Completion Processor */
10461	cmd = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CMD);
10462	ctl = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CTL);
10463	cur_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_CUR_DEPTH) >> 22;
10464	max_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_MAX_DEPTH) >> 12;
10465	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT15);
10466	BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10467	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10468
10469	/* Setup the generic statistic counters for the FTQ valid count. */
10470	val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSQ_VALID_CNT  << 16) |
10471	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT  <<  8) |
10472	    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT);
10473
10474	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
10475		val = val |
10476		    (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCSQ_VALID_CNT_XI <<
10477		     24);
10478	REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
10479
10480	/* Input queue to the Management Control Processor */
10481	cmd = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CMD);
10482	ctl = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CTL);
10483	cur_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_CUR_DEPTH) >> 22;
10484	max_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_MAX_DEPTH) >> 12;
10485	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
10486	BCE_PRINTF(" MCP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10487	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10488
10489	/* Input queue to the Command Processor */
10490	cmd = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CMD);
10491	ctl = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CTL);
10492	cur_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_CUR_DEPTH) >> 22;
10493	max_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_MAX_DEPTH) >> 12;
10494	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
10495	BCE_PRINTF(" CP      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10496	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10497
10498	/* Input queue to the Completion Scheduler state machine */
10499	cmd = REG_RD(sc, BCE_CSCH_CH_FTQ_CMD);
10500	ctl = REG_RD(sc, BCE_CSCH_CH_FTQ_CTL);
10501	cur_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_CUR_DEPTH) >> 22;
10502	max_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_MAX_DEPTH) >> 12;
10503	valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
10504	BCE_PRINTF(" CS      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10505	    cmd, ctl, cur_depth, max_depth, valid_cnt);
10506
10507	if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
10508		/* Input queue to the RV2P Command Scheduler */
10509		cmd = REG_RD(sc, BCE_RV2PCSR_FTQ_CMD);
10510		ctl = REG_RD(sc, BCE_RV2PCSR_FTQ_CTL);
10511		cur_depth = (ctl & 0xFFC00000) >> 22;
10512		max_depth = (ctl & 0x003FF000) >> 12;
10513		valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
10514		BCE_PRINTF(" RV2PCSR 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10515		    cmd, ctl, cur_depth, max_depth, valid_cnt);
10516	}
10517
10518	BCE_PRINTF(
10519	    "----------------------------"
10520	    "----------------"
10521	    "----------------------------\n");
10522}
10523
10524
10525/****************************************************************************/
10526/* Prints out the TX chain.                                                 */
10527/*                                                                          */
10528/* Returns:                                                                 */
10529/*   Nothing.                                                               */
10530/****************************************************************************/
10531static __attribute__ ((noinline)) void
10532bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count)
10533{
10534	struct tx_bd *txbd;
10535
10536	/* First some info about the tx_bd chain structure. */
10537	BCE_PRINTF(
10538	    "----------------------------"
10539	    "  tx_bd  chain  "
10540	    "----------------------------\n");
10541
10542	BCE_PRINTF("page size      = 0x%08X, tx chain pages        = 0x%08X\n",
10543	    (u32) BCM_PAGE_SIZE, (u32) sc->tx_pages);
10544	BCE_PRINTF("tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
10545	    (u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
10546	BCE_PRINTF("total tx_bd    = 0x%08X\n", (u32) TOTAL_TX_BD_ALLOC);
10547
10548	BCE_PRINTF(
10549	    "----------------------------"
10550	    "   tx_bd data   "
10551	    "----------------------------\n");
10552
10553	/* Now print out a decoded list of TX buffer descriptors. */
10554	for (int i = 0; i < count; i++) {
10555	 	txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
10556		bce_dump_txbd(sc, tx_prod, txbd);
10557		tx_prod++;
10558	}
10559
10560	BCE_PRINTF(
10561	    "----------------------------"
10562	    "----------------"
10563	    "----------------------------\n");
10564}
10565
10566
10567/****************************************************************************/
10568/* Prints out the RX chain.                                                 */
10569/*                                                                          */
10570/* Returns:                                                                 */
10571/*   Nothing.                                                               */
10572/****************************************************************************/
10573static __attribute__ ((noinline)) void
10574bce_dump_rx_bd_chain(struct bce_softc *sc, u16 rx_prod, int count)
10575{
10576	struct rx_bd *rxbd;
10577
10578	/* First some info about the rx_bd chain structure. */
10579	BCE_PRINTF(
10580	    "----------------------------"
10581	    "  rx_bd  chain  "
10582	    "----------------------------\n");
10583
10584	BCE_PRINTF("page size      = 0x%08X, rx chain pages        = 0x%08X\n",
10585	    (u32) BCM_PAGE_SIZE, (u32) sc->rx_pages);
10586
10587	BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
10588	    (u32) TOTAL_RX_BD_PER_PAGE, (u32) USABLE_RX_BD_PER_PAGE);
10589
10590	BCE_PRINTF("total rx_bd    = 0x%08X\n", (u32) TOTAL_RX_BD_ALLOC);
10591
10592	BCE_PRINTF(
10593	    "----------------------------"
10594	    "   rx_bd data   "
10595	    "----------------------------\n");
10596
10597	/* Now print out the rx_bd's themselves. */
10598	for (int i = 0; i < count; i++) {
10599		rxbd = &sc->rx_bd_chain[RX_PAGE(rx_prod)][RX_IDX(rx_prod)];
10600		bce_dump_rxbd(sc, rx_prod, rxbd);
10601		rx_prod = RX_CHAIN_IDX(rx_prod + 1);
10602	}
10603
10604	BCE_PRINTF(
10605	    "----------------------------"
10606	    "----------------"
10607	    "----------------------------\n");
10608}
10609
10610
10611/****************************************************************************/
10612/* Prints out the page chain.                                               */
10613/*                                                                          */
10614/* Returns:                                                                 */
10615/*   Nothing.                                                               */
10616/****************************************************************************/
10617static __attribute__ ((noinline)) void
10618bce_dump_pg_chain(struct bce_softc *sc, u16 pg_prod, int count)
10619{
10620	struct rx_bd *pgbd;
10621
10622	/* First some info about the page chain structure. */
10623	BCE_PRINTF(
10624	    "----------------------------"
10625	    "   page chain   "
10626	    "----------------------------\n");
10627
10628	BCE_PRINTF("page size      = 0x%08X, pg chain pages        = 0x%08X\n",
10629	    (u32) BCM_PAGE_SIZE, (u32) sc->pg_pages);
10630
10631	BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
10632	    (u32) TOTAL_PG_BD_PER_PAGE, (u32) USABLE_PG_BD_PER_PAGE);
10633
10634	BCE_PRINTF("total pg_bd             = 0x%08X\n", (u32) TOTAL_PG_BD_ALLOC);
10635
10636	BCE_PRINTF(
10637	    "----------------------------"
10638	    "   page data    "
10639	    "----------------------------\n");
10640
10641	/* Now print out the rx_bd's themselves. */
10642	for (int i = 0; i < count; i++) {
10643		pgbd = &sc->pg_bd_chain[PG_PAGE(pg_prod)][PG_IDX(pg_prod)];
10644		bce_dump_pgbd(sc, pg_prod, pgbd);
10645		pg_prod = PG_CHAIN_IDX(pg_prod + 1);
10646	}
10647
10648	BCE_PRINTF(
10649	    "----------------------------"
10650	    "----------------"
10651	    "----------------------------\n");
10652}
10653
10654
10655#define BCE_PRINT_RX_CONS(arg)						\
10656if (sblk->status_rx_quick_consumer_index##arg)				\
10657	BCE_PRINTF("0x%04X(0x%04X) - rx_quick_consumer_index%d\n",	\
10658	    sblk->status_rx_quick_consumer_index##arg, (u16)		\
10659	    RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index##arg),	\
10660	    arg);
10661
10662
10663#define BCE_PRINT_TX_CONS(arg)						\
10664if (sblk->status_tx_quick_consumer_index##arg)				\
10665	BCE_PRINTF("0x%04X(0x%04X) - tx_quick_consumer_index%d\n",	\
10666	    sblk->status_tx_quick_consumer_index##arg, (u16)		\
10667	    TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index##arg),	\
10668	    arg);
10669
10670/****************************************************************************/
10671/* Prints out the status block from host memory.                            */
10672/*                                                                          */
10673/* Returns:                                                                 */
10674/*   Nothing.                                                               */
10675/****************************************************************************/
10676static __attribute__ ((noinline)) void
10677bce_dump_status_block(struct bce_softc *sc)
10678{
10679	struct status_block *sblk;
10680
10681	bus_dmamap_sync(sc->status_tag, sc->status_map, BUS_DMASYNC_POSTREAD);
10682
10683	sblk = sc->status_block;
10684
10685	BCE_PRINTF(
10686	    "----------------------------"
10687	    "  Status Block  "
10688	    "----------------------------\n");
10689
10690	/* Theses indices are used for normal L2 drivers. */
10691	BCE_PRINTF("    0x%08X - attn_bits\n",
10692	    sblk->status_attn_bits);
10693
10694	BCE_PRINTF("    0x%08X - attn_bits_ack\n",
10695	    sblk->status_attn_bits_ack);
10696
10697	BCE_PRINT_RX_CONS(0);
10698	BCE_PRINT_TX_CONS(0)
10699
10700	BCE_PRINTF("        0x%04X - status_idx\n", sblk->status_idx);
10701
10702	/* Theses indices are not used for normal L2 drivers. */
10703	BCE_PRINT_RX_CONS(1);   BCE_PRINT_RX_CONS(2);   BCE_PRINT_RX_CONS(3);
10704	BCE_PRINT_RX_CONS(4);   BCE_PRINT_RX_CONS(5);   BCE_PRINT_RX_CONS(6);
10705	BCE_PRINT_RX_CONS(7);   BCE_PRINT_RX_CONS(8);   BCE_PRINT_RX_CONS(9);
10706	BCE_PRINT_RX_CONS(10);  BCE_PRINT_RX_CONS(11);  BCE_PRINT_RX_CONS(12);
10707	BCE_PRINT_RX_CONS(13);  BCE_PRINT_RX_CONS(14);  BCE_PRINT_RX_CONS(15);
10708
10709	BCE_PRINT_TX_CONS(1);   BCE_PRINT_TX_CONS(2);   BCE_PRINT_TX_CONS(3);
10710
10711	if (sblk->status_completion_producer_index ||
10712	    sblk->status_cmd_consumer_index)
10713		BCE_PRINTF("com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
10714		    sblk->status_completion_producer_index,
10715		    sblk->status_cmd_consumer_index);
10716
10717	BCE_PRINTF(
10718	    "----------------------------"
10719	    "----------------"
10720	    "----------------------------\n");
10721}
10722
10723
10724#define BCE_PRINT_64BIT_STAT(arg) 				\
10725if (sblk->arg##_lo || sblk->arg##_hi)				\
10726	BCE_PRINTF("0x%08X:%08X : %s\n", sblk->arg##_hi,	\
10727	    sblk->arg##_lo, #arg);
10728
10729#define BCE_PRINT_32BIT_STAT(arg)				\
10730if (sblk->arg)							\
10731	BCE_PRINTF("         0x%08X : %s\n", 			\
10732	    sblk->arg, #arg);
10733
10734/****************************************************************************/
10735/* Prints out the statistics block from host memory.                        */
10736/*                                                                          */
10737/* Returns:                                                                 */
10738/*   Nothing.                                                               */
10739/****************************************************************************/
10740static __attribute__ ((noinline)) void
10741bce_dump_stats_block(struct bce_softc *sc)
10742{
10743	struct statistics_block *sblk;
10744
10745	bus_dmamap_sync(sc->stats_tag, sc->stats_map, BUS_DMASYNC_POSTREAD);
10746
10747	sblk = sc->stats_block;
10748
10749	BCE_PRINTF(
10750	    "---------------"
10751	    " Stats Block  (All Stats Not Shown Are 0) "
10752	    "---------------\n");
10753
10754	BCE_PRINT_64BIT_STAT(stat_IfHCInOctets);
10755	BCE_PRINT_64BIT_STAT(stat_IfHCInBadOctets);
10756	BCE_PRINT_64BIT_STAT(stat_IfHCOutOctets);
10757	BCE_PRINT_64BIT_STAT(stat_IfHCOutBadOctets);
10758	BCE_PRINT_64BIT_STAT(stat_IfHCInUcastPkts);
10759	BCE_PRINT_64BIT_STAT(stat_IfHCInBroadcastPkts);
10760	BCE_PRINT_64BIT_STAT(stat_IfHCInMulticastPkts);
10761	BCE_PRINT_64BIT_STAT(stat_IfHCOutUcastPkts);
10762	BCE_PRINT_64BIT_STAT(stat_IfHCOutBroadcastPkts);
10763	BCE_PRINT_64BIT_STAT(stat_IfHCOutMulticastPkts);
10764	BCE_PRINT_32BIT_STAT(
10765	    stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
10766	BCE_PRINT_32BIT_STAT(stat_Dot3StatsCarrierSenseErrors);
10767	BCE_PRINT_32BIT_STAT(stat_Dot3StatsFCSErrors);
10768	BCE_PRINT_32BIT_STAT(stat_Dot3StatsAlignmentErrors);
10769	BCE_PRINT_32BIT_STAT(stat_Dot3StatsSingleCollisionFrames);
10770	BCE_PRINT_32BIT_STAT(stat_Dot3StatsMultipleCollisionFrames);
10771	BCE_PRINT_32BIT_STAT(stat_Dot3StatsDeferredTransmissions);
10772	BCE_PRINT_32BIT_STAT(stat_Dot3StatsExcessiveCollisions);
10773	BCE_PRINT_32BIT_STAT(stat_Dot3StatsLateCollisions);
10774	BCE_PRINT_32BIT_STAT(stat_EtherStatsCollisions);
10775	BCE_PRINT_32BIT_STAT(stat_EtherStatsFragments);
10776	BCE_PRINT_32BIT_STAT(stat_EtherStatsJabbers);
10777	BCE_PRINT_32BIT_STAT(stat_EtherStatsUndersizePkts);
10778	BCE_PRINT_32BIT_STAT(stat_EtherStatsOversizePkts);
10779	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx64Octets);
10780	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx65Octetsto127Octets);
10781	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx128Octetsto255Octets);
10782	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx256Octetsto511Octets);
10783	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx512Octetsto1023Octets);
10784	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1024Octetsto1522Octets);
10785	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1523Octetsto9022Octets);
10786	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx64Octets);
10787	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx65Octetsto127Octets);
10788	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx128Octetsto255Octets);
10789	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx256Octetsto511Octets);
10790	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx512Octetsto1023Octets);
10791	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1024Octetsto1522Octets);
10792	BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1523Octetsto9022Octets);
10793	BCE_PRINT_32BIT_STAT(stat_XonPauseFramesReceived);
10794	BCE_PRINT_32BIT_STAT(stat_XoffPauseFramesReceived);
10795	BCE_PRINT_32BIT_STAT(stat_OutXonSent);
10796	BCE_PRINT_32BIT_STAT(stat_OutXoffSent);
10797	BCE_PRINT_32BIT_STAT(stat_FlowControlDone);
10798	BCE_PRINT_32BIT_STAT(stat_MacControlFramesReceived);
10799	BCE_PRINT_32BIT_STAT(stat_XoffStateEntered);
10800	BCE_PRINT_32BIT_STAT(stat_IfInFramesL2FilterDiscards);
10801	BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerDiscards);
10802	BCE_PRINT_32BIT_STAT(stat_IfInFTQDiscards);
10803	BCE_PRINT_32BIT_STAT(stat_IfInMBUFDiscards);
10804	BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerP4Hit);
10805	BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerDiscards);
10806	BCE_PRINT_32BIT_STAT(stat_CatchupInFTQDiscards);
10807	BCE_PRINT_32BIT_STAT(stat_CatchupInMBUFDiscards);
10808	BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerP4Hit);
10809
10810	BCE_PRINTF(
10811	    "----------------------------"
10812	    "----------------"
10813	    "----------------------------\n");
10814}
10815
10816
10817/****************************************************************************/
10818/* Prints out a summary of the driver state.                                */
10819/*                                                                          */
10820/* Returns:                                                                 */
10821/*   Nothing.                                                               */
10822/****************************************************************************/
10823static __attribute__ ((noinline)) void
10824bce_dump_driver_state(struct bce_softc *sc)
10825{
10826	u32 val_hi, val_lo;
10827
10828	BCE_PRINTF(
10829	    "-----------------------------"
10830	    " Driver State "
10831	    "-----------------------------\n");
10832
10833	val_hi = BCE_ADDR_HI(sc);
10834	val_lo = BCE_ADDR_LO(sc);
10835	BCE_PRINTF("0x%08X:%08X - (sc) driver softc structure virtual "
10836	    "address\n", val_hi, val_lo);
10837
10838	val_hi = BCE_ADDR_HI(sc->bce_vhandle);
10839	val_lo = BCE_ADDR_LO(sc->bce_vhandle);
10840	BCE_PRINTF("0x%08X:%08X - (sc->bce_vhandle) PCI BAR virtual "
10841	    "address\n", val_hi, val_lo);
10842
10843	val_hi = BCE_ADDR_HI(sc->status_block);
10844	val_lo = BCE_ADDR_LO(sc->status_block);
10845	BCE_PRINTF("0x%08X:%08X - (sc->status_block) status block "
10846	    "virtual address\n",	val_hi, val_lo);
10847
10848	val_hi = BCE_ADDR_HI(sc->stats_block);
10849	val_lo = BCE_ADDR_LO(sc->stats_block);
10850	BCE_PRINTF("0x%08X:%08X - (sc->stats_block) statistics block "
10851	    "virtual address\n", val_hi, val_lo);
10852
10853	val_hi = BCE_ADDR_HI(sc->tx_bd_chain);
10854	val_lo = BCE_ADDR_LO(sc->tx_bd_chain);
10855	BCE_PRINTF("0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain "
10856	    "virtual adddress\n", val_hi, val_lo);
10857
10858	val_hi = BCE_ADDR_HI(sc->rx_bd_chain);
10859	val_lo = BCE_ADDR_LO(sc->rx_bd_chain);
10860	BCE_PRINTF("0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain "
10861	    "virtual address\n", val_hi, val_lo);
10862
10863	if (bce_hdr_split == TRUE) {
10864		val_hi = BCE_ADDR_HI(sc->pg_bd_chain);
10865		val_lo = BCE_ADDR_LO(sc->pg_bd_chain);
10866		BCE_PRINTF("0x%08X:%08X - (sc->pg_bd_chain) page chain "
10867		    "virtual address\n", val_hi, val_lo);
10868	}
10869
10870	val_hi = BCE_ADDR_HI(sc->tx_mbuf_ptr);
10871	val_lo = BCE_ADDR_LO(sc->tx_mbuf_ptr);
10872	BCE_PRINTF("0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain "
10873	    "virtual address\n",	val_hi, val_lo);
10874
10875	val_hi = BCE_ADDR_HI(sc->rx_mbuf_ptr);
10876	val_lo = BCE_ADDR_LO(sc->rx_mbuf_ptr);
10877	BCE_PRINTF("0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain "
10878	    "virtual address\n", val_hi, val_lo);
10879
10880	if (bce_hdr_split == TRUE) {
10881		val_hi = BCE_ADDR_HI(sc->pg_mbuf_ptr);
10882		val_lo = BCE_ADDR_LO(sc->pg_mbuf_ptr);
10883		BCE_PRINTF("0x%08X:%08X - (sc->pg_mbuf_ptr) page mbuf chain "
10884		    "virtual address\n", val_hi, val_lo);
10885	}
10886
10887	BCE_PRINTF(" 0x%016llX - (sc->interrupts_generated) "
10888	    "h/w intrs\n",
10889	    (long long unsigned int) sc->interrupts_generated);
10890
10891	BCE_PRINTF(" 0x%016llX - (sc->interrupts_rx) "
10892	    "rx interrupts handled\n",
10893	    (long long unsigned int) sc->interrupts_rx);
10894
10895	BCE_PRINTF(" 0x%016llX - (sc->interrupts_tx) "
10896	    "tx interrupts handled\n",
10897	    (long long unsigned int) sc->interrupts_tx);
10898
10899	BCE_PRINTF(" 0x%016llX - (sc->phy_interrupts) "
10900	    "phy interrupts handled\n",
10901	    (long long unsigned int) sc->phy_interrupts);
10902
10903	BCE_PRINTF("         0x%08X - (sc->last_status_idx) "
10904	    "status block index\n", sc->last_status_idx);
10905
10906	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_prod) tx producer "
10907	    "index\n", sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod));
10908
10909	BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_cons) tx consumer "
10910	    "index\n", sc->tx_cons, (u16) TX_CHAIN_IDX(sc->tx_cons));
10911
10912	BCE_PRINTF("         0x%08X - (sc->tx_prod_bseq) tx producer "
10913	    "byte seq index\n",	sc->tx_prod_bseq);
10914
10915	BCE_PRINTF("         0x%08X - (sc->debug_tx_mbuf_alloc) tx "
10916	    "mbufs allocated\n", sc->debug_tx_mbuf_alloc);
10917
10918	BCE_PRINTF("         0x%08X - (sc->used_tx_bd) used "
10919	    "tx_bd's\n", sc->used_tx_bd);
10920
10921	BCE_PRINTF("      0x%04X/0x%04X - (sc->tx_hi_watermark)/"
10922	    "(sc->max_tx_bd)\n", sc->tx_hi_watermark, sc->max_tx_bd);
10923
10924	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_prod) rx producer "
10925	    "index\n", sc->rx_prod, (u16) RX_CHAIN_IDX(sc->rx_prod));
10926
10927	BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_cons) rx consumer "
10928	    "index\n", sc->rx_cons, (u16) RX_CHAIN_IDX(sc->rx_cons));
10929
10930	BCE_PRINTF("         0x%08X - (sc->rx_prod_bseq) rx producer "
10931	    "byte seq index\n",	sc->rx_prod_bseq);
10932
10933	BCE_PRINTF("      0x%04X/0x%04X - (sc->rx_low_watermark)/"
10934		   "(sc->max_rx_bd)\n", sc->rx_low_watermark, sc->max_rx_bd);
10935
10936	BCE_PRINTF("         0x%08X - (sc->debug_rx_mbuf_alloc) rx "
10937	    "mbufs allocated\n", sc->debug_rx_mbuf_alloc);
10938
10939	BCE_PRINTF("         0x%08X - (sc->free_rx_bd) free "
10940	    "rx_bd's\n", sc->free_rx_bd);
10941
10942	if (bce_hdr_split == TRUE) {
10943		BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_prod) page producer "
10944		    "index\n", sc->pg_prod, (u16) PG_CHAIN_IDX(sc->pg_prod));
10945
10946		BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_cons) page consumer "
10947		    "index\n", sc->pg_cons, (u16) PG_CHAIN_IDX(sc->pg_cons));
10948
10949		BCE_PRINTF("         0x%08X - (sc->debug_pg_mbuf_alloc) page "
10950		    "mbufs allocated\n", sc->debug_pg_mbuf_alloc);
10951	}
10952
10953	BCE_PRINTF("         0x%08X - (sc->free_pg_bd) free page "
10954	    "rx_bd's\n", sc->free_pg_bd);
10955
10956	BCE_PRINTF("      0x%04X/0x%04X - (sc->pg_low_watermark)/"
10957	    "(sc->max_pg_bd)\n", sc->pg_low_watermark, sc->max_pg_bd);
10958
10959	BCE_PRINTF("         0x%08X - (sc->mbuf_alloc_failed_count) "
10960	    "mbuf alloc failures\n", sc->mbuf_alloc_failed_count);
10961
10962	BCE_PRINTF("         0x%08X - (sc->bce_flags) "
10963	    "bce mac flags\n", sc->bce_flags);
10964
10965	BCE_PRINTF("         0x%08X - (sc->bce_phy_flags) "
10966	    "bce phy flags\n", sc->bce_phy_flags);
10967
10968	BCE_PRINTF(
10969	    "----------------------------"
10970	    "----------------"
10971	    "----------------------------\n");
10972}
10973
10974
10975/****************************************************************************/
10976/* Prints out the hardware state through a summary of important register,   */
10977/* followed by a complete register dump.                                    */
10978/*                                                                          */
10979/* Returns:                                                                 */
10980/*   Nothing.                                                               */
10981/****************************************************************************/
10982static __attribute__ ((noinline)) void
10983bce_dump_hw_state(struct bce_softc *sc)
10984{
10985	u32 val;
10986
10987	BCE_PRINTF(
10988	    "----------------------------"
10989	    " Hardware State "
10990	    "----------------------------\n");
10991
10992	BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
10993
10994	val = REG_RD(sc, BCE_MISC_ENABLE_STATUS_BITS);
10995	BCE_PRINTF("0x%08X - (0x%06X) misc_enable_status_bits\n",
10996	    val, BCE_MISC_ENABLE_STATUS_BITS);
10997
10998	val = REG_RD(sc, BCE_DMA_STATUS);
10999	BCE_PRINTF("0x%08X - (0x%06X) dma_status\n",
11000	    val, BCE_DMA_STATUS);
11001
11002	val = REG_RD(sc, BCE_CTX_STATUS);
11003	BCE_PRINTF("0x%08X - (0x%06X) ctx_status\n",
11004	    val, BCE_CTX_STATUS);
11005
11006	val = REG_RD(sc, BCE_EMAC_STATUS);
11007	BCE_PRINTF("0x%08X - (0x%06X) emac_status\n",
11008	    val, BCE_EMAC_STATUS);
11009
11010	val = REG_RD(sc, BCE_RPM_STATUS);
11011	BCE_PRINTF("0x%08X - (0x%06X) rpm_status\n",
11012	    val, BCE_RPM_STATUS);
11013
11014	/* ToDo: Create a #define for this constant. */
11015	val = REG_RD(sc, 0x2004);
11016	BCE_PRINTF("0x%08X - (0x%06X) rlup_status\n",
11017	    val, 0x2004);
11018
11019	val = REG_RD(sc, BCE_RV2P_STATUS);
11020	BCE_PRINTF("0x%08X - (0x%06X) rv2p_status\n",
11021	    val, BCE_RV2P_STATUS);
11022
11023	/* ToDo: Create a #define for this constant. */
11024	val = REG_RD(sc, 0x2c04);
11025	BCE_PRINTF("0x%08X - (0x%06X) rdma_status\n",
11026	    val, 0x2c04);
11027
11028	val = REG_RD(sc, BCE_TBDR_STATUS);
11029	BCE_PRINTF("0x%08X - (0x%06X) tbdr_status\n",
11030	    val, BCE_TBDR_STATUS);
11031
11032	val = REG_RD(sc, BCE_TDMA_STATUS);
11033	BCE_PRINTF("0x%08X - (0x%06X) tdma_status\n",
11034	    val, BCE_TDMA_STATUS);
11035
11036	val = REG_RD(sc, BCE_HC_STATUS);
11037	BCE_PRINTF("0x%08X - (0x%06X) hc_status\n",
11038	    val, BCE_HC_STATUS);
11039
11040	val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
11041	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n",
11042	    val, BCE_TXP_CPU_STATE);
11043
11044	val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
11045	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n",
11046	    val, BCE_TPAT_CPU_STATE);
11047
11048	val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
11049	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n",
11050	    val, BCE_RXP_CPU_STATE);
11051
11052	val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
11053	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n",
11054	    val, BCE_COM_CPU_STATE);
11055
11056	val = REG_RD_IND(sc, BCE_MCP_CPU_STATE);
11057	BCE_PRINTF("0x%08X - (0x%06X) mcp_cpu_state\n",
11058	    val, BCE_MCP_CPU_STATE);
11059
11060	val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
11061	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n",
11062	    val, BCE_CP_CPU_STATE);
11063
11064	BCE_PRINTF(
11065	    "----------------------------"
11066	    "----------------"
11067	    "----------------------------\n");
11068
11069	BCE_PRINTF(
11070	    "----------------------------"
11071	    " Register  Dump "
11072	    "----------------------------\n");
11073
11074	for (int i = 0x400; i < 0x8000; i += 0x10) {
11075		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
11076		    i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
11077		    REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
11078	}
11079
11080	BCE_PRINTF(
11081	    "----------------------------"
11082	    "----------------"
11083	    "----------------------------\n");
11084}
11085
11086
11087/****************************************************************************/
11088/* Prints out the contentst of shared memory which is used for host driver  */
11089/* to bootcode firmware communication.                                      */
11090/*                                                                          */
11091/* Returns:                                                                 */
11092/*   Nothing.                                                               */
11093/****************************************************************************/
11094static __attribute__ ((noinline)) void
11095bce_dump_shmem_state(struct bce_softc *sc)
11096{
11097	BCE_PRINTF(
11098	    "----------------------------"
11099	    " Hardware State "
11100	    "----------------------------\n");
11101
11102	BCE_PRINTF("0x%08X - Shared memory base address\n",
11103	    sc->bce_shmem_base);
11104	BCE_PRINTF("%s - bootcode version\n",
11105	    sc->bce_bc_ver);
11106
11107	BCE_PRINTF(
11108	    "----------------------------"
11109	    "   Shared Mem   "
11110	    "----------------------------\n");
11111
11112	for (int i = 0x0; i < 0x200; i += 0x10) {
11113		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
11114		    i, bce_shmem_rd(sc, i), bce_shmem_rd(sc, i + 0x4),
11115		    bce_shmem_rd(sc, i + 0x8), bce_shmem_rd(sc, i + 0xC));
11116	}
11117
11118	BCE_PRINTF(
11119	    "----------------------------"
11120	    "----------------"
11121	    "----------------------------\n");
11122}
11123
11124
11125/****************************************************************************/
11126/* Prints out the mailbox queue registers.                                  */
11127/*                                                                          */
11128/* Returns:                                                                 */
11129/*   Nothing.                                                               */
11130/****************************************************************************/
11131static __attribute__ ((noinline)) void
11132bce_dump_mq_regs(struct bce_softc *sc)
11133{
11134	BCE_PRINTF(
11135	    "----------------------------"
11136	    "    MQ Regs     "
11137	    "----------------------------\n");
11138
11139	BCE_PRINTF(
11140	    "----------------------------"
11141	    "----------------"
11142	    "----------------------------\n");
11143
11144	for (int i = 0x3c00; i < 0x4000; i += 0x10) {
11145		BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
11146		    i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
11147		    REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
11148	}
11149
11150	BCE_PRINTF(
11151	    "----------------------------"
11152	    "----------------"
11153	    "----------------------------\n");
11154}
11155
11156
11157/****************************************************************************/
11158/* Prints out the bootcode state.                                           */
11159/*                                                                          */
11160/* Returns:                                                                 */
11161/*   Nothing.                                                               */
11162/****************************************************************************/
11163static __attribute__ ((noinline)) void
11164bce_dump_bc_state(struct bce_softc *sc)
11165{
11166	u32 val;
11167
11168	BCE_PRINTF(
11169	    "----------------------------"
11170	    " Bootcode State "
11171	    "----------------------------\n");
11172
11173	BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
11174
11175	val = bce_shmem_rd(sc, BCE_BC_RESET_TYPE);
11176	BCE_PRINTF("0x%08X - (0x%06X) reset_type\n",
11177	    val, BCE_BC_RESET_TYPE);
11178
11179	val = bce_shmem_rd(sc, BCE_BC_STATE);
11180	BCE_PRINTF("0x%08X - (0x%06X) state\n",
11181	    val, BCE_BC_STATE);
11182
11183	val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
11184	BCE_PRINTF("0x%08X - (0x%06X) condition\n",
11185	    val, BCE_BC_STATE_CONDITION);
11186
11187	val = bce_shmem_rd(sc, BCE_BC_STATE_DEBUG_CMD);
11188	BCE_PRINTF("0x%08X - (0x%06X) debug_cmd\n",
11189	    val, BCE_BC_STATE_DEBUG_CMD);
11190
11191	BCE_PRINTF(
11192	    "----------------------------"
11193	    "----------------"
11194	    "----------------------------\n");
11195}
11196
11197
11198/****************************************************************************/
11199/* Prints out the TXP processor state.                                      */
11200/*                                                                          */
11201/* Returns:                                                                 */
11202/*   Nothing.                                                               */
11203/****************************************************************************/
11204static __attribute__ ((noinline)) void
11205bce_dump_txp_state(struct bce_softc *sc, int regs)
11206{
11207	u32 val;
11208	u32 fw_version[3];
11209
11210	BCE_PRINTF(
11211	    "----------------------------"
11212	    "   TXP  State   "
11213	    "----------------------------\n");
11214
11215	for (int i = 0; i < 3; i++)
11216		fw_version[i] = htonl(REG_RD_IND(sc,
11217		    (BCE_TXP_SCRATCH + 0x10 + i * 4)));
11218	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11219
11220	val = REG_RD_IND(sc, BCE_TXP_CPU_MODE);
11221	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_mode\n",
11222	    val, BCE_TXP_CPU_MODE);
11223
11224	val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
11225	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n",
11226	    val, BCE_TXP_CPU_STATE);
11227
11228	val = REG_RD_IND(sc, BCE_TXP_CPU_EVENT_MASK);
11229	BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_event_mask\n",
11230	    val, BCE_TXP_CPU_EVENT_MASK);
11231
11232	if (regs) {
11233		BCE_PRINTF(
11234		    "----------------------------"
11235		    " Register  Dump "
11236		    "----------------------------\n");
11237
11238		for (int i = BCE_TXP_CPU_MODE; i < 0x68000; i += 0x10) {
11239			/* Skip the big blank spaces */
11240			if (i < 0x454000 && i > 0x5ffff)
11241				BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11242				    "0x%08X 0x%08X\n", i,
11243				    REG_RD_IND(sc, i),
11244				    REG_RD_IND(sc, i + 0x4),
11245				    REG_RD_IND(sc, i + 0x8),
11246				    REG_RD_IND(sc, i + 0xC));
11247		}
11248	}
11249
11250	BCE_PRINTF(
11251	    "----------------------------"
11252	    "----------------"
11253	    "----------------------------\n");
11254}
11255
11256
11257/****************************************************************************/
11258/* Prints out the RXP processor state.                                      */
11259/*                                                                          */
11260/* Returns:                                                                 */
11261/*   Nothing.                                                               */
11262/****************************************************************************/
11263static __attribute__ ((noinline)) void
11264bce_dump_rxp_state(struct bce_softc *sc, int regs)
11265{
11266	u32 val;
11267	u32 fw_version[3];
11268
11269	BCE_PRINTF(
11270	    "----------------------------"
11271	    "   RXP  State   "
11272	    "----------------------------\n");
11273
11274	for (int i = 0; i < 3; i++)
11275		fw_version[i] = htonl(REG_RD_IND(sc,
11276		    (BCE_RXP_SCRATCH + 0x10 + i * 4)));
11277
11278	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11279
11280	val = REG_RD_IND(sc, BCE_RXP_CPU_MODE);
11281	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_mode\n",
11282	    val, BCE_RXP_CPU_MODE);
11283
11284	val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
11285	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n",
11286	    val, BCE_RXP_CPU_STATE);
11287
11288	val = REG_RD_IND(sc, BCE_RXP_CPU_EVENT_MASK);
11289	BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_event_mask\n",
11290	    val, BCE_RXP_CPU_EVENT_MASK);
11291
11292	if (regs) {
11293		BCE_PRINTF(
11294		    "----------------------------"
11295		    " Register  Dump "
11296		    "----------------------------\n");
11297
11298		for (int i = BCE_RXP_CPU_MODE; i < 0xe8fff; i += 0x10) {
11299			/* Skip the big blank sapces */
11300			if (i < 0xc5400 && i > 0xdffff)
11301				BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11302				    "0x%08X 0x%08X\n", i,
11303				    REG_RD_IND(sc, i),
11304				    REG_RD_IND(sc, i + 0x4),
11305				    REG_RD_IND(sc, i + 0x8),
11306				    REG_RD_IND(sc, i + 0xC));
11307		}
11308	}
11309
11310	BCE_PRINTF(
11311	    "----------------------------"
11312	    "----------------"
11313	    "----------------------------\n");
11314}
11315
11316
11317/****************************************************************************/
11318/* Prints out the TPAT processor state.                                     */
11319/*                                                                          */
11320/* Returns:                                                                 */
11321/*   Nothing.                                                               */
11322/****************************************************************************/
11323static __attribute__ ((noinline)) void
11324bce_dump_tpat_state(struct bce_softc *sc, int regs)
11325{
11326	u32 val;
11327	u32 fw_version[3];
11328
11329	BCE_PRINTF(
11330	    "----------------------------"
11331	    "   TPAT State   "
11332	    "----------------------------\n");
11333
11334	for (int i = 0; i < 3; i++)
11335		fw_version[i] = htonl(REG_RD_IND(sc,
11336		    (BCE_TPAT_SCRATCH + 0x410 + i * 4)));
11337
11338	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11339
11340	val = REG_RD_IND(sc, BCE_TPAT_CPU_MODE);
11341	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_mode\n",
11342	    val, BCE_TPAT_CPU_MODE);
11343
11344	val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
11345	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n",
11346	    val, BCE_TPAT_CPU_STATE);
11347
11348	val = REG_RD_IND(sc, BCE_TPAT_CPU_EVENT_MASK);
11349	BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_event_mask\n",
11350	    val, BCE_TPAT_CPU_EVENT_MASK);
11351
11352	if (regs) {
11353		BCE_PRINTF(
11354		    "----------------------------"
11355		    " Register  Dump "
11356		    "----------------------------\n");
11357
11358		for (int i = BCE_TPAT_CPU_MODE; i < 0xa3fff; i += 0x10) {
11359			/* Skip the big blank spaces */
11360			if (i < 0x854000 && i > 0x9ffff)
11361				BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11362				    "0x%08X 0x%08X\n", i,
11363				    REG_RD_IND(sc, i),
11364				    REG_RD_IND(sc, i + 0x4),
11365				    REG_RD_IND(sc, i + 0x8),
11366				    REG_RD_IND(sc, i + 0xC));
11367		}
11368	}
11369
11370	BCE_PRINTF(
11371		"----------------------------"
11372		"----------------"
11373		"----------------------------\n");
11374}
11375
11376
11377/****************************************************************************/
11378/* Prints out the Command Procesor (CP) state.                              */
11379/*                                                                          */
11380/* Returns:                                                                 */
11381/*   Nothing.                                                               */
11382/****************************************************************************/
11383static __attribute__ ((noinline)) void
11384bce_dump_cp_state(struct bce_softc *sc, int regs)
11385{
11386	u32 val;
11387	u32 fw_version[3];
11388
11389	BCE_PRINTF(
11390	    "----------------------------"
11391	    "    CP State    "
11392	    "----------------------------\n");
11393
11394	for (int i = 0; i < 3; i++)
11395		fw_version[i] = htonl(REG_RD_IND(sc,
11396		    (BCE_CP_SCRATCH + 0x10 + i * 4)));
11397
11398	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11399
11400	val = REG_RD_IND(sc, BCE_CP_CPU_MODE);
11401	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_mode\n",
11402	    val, BCE_CP_CPU_MODE);
11403
11404	val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
11405	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n",
11406	    val, BCE_CP_CPU_STATE);
11407
11408	val = REG_RD_IND(sc, BCE_CP_CPU_EVENT_MASK);
11409	BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_event_mask\n", val,
11410	    BCE_CP_CPU_EVENT_MASK);
11411
11412	if (regs) {
11413		BCE_PRINTF(
11414		    "----------------------------"
11415		    " Register  Dump "
11416		    "----------------------------\n");
11417
11418		for (int i = BCE_CP_CPU_MODE; i < 0x1aa000; i += 0x10) {
11419			/* Skip the big blank spaces */
11420			if (i < 0x185400 && i > 0x19ffff)
11421				BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11422				    "0x%08X 0x%08X\n", i,
11423				    REG_RD_IND(sc, i),
11424				    REG_RD_IND(sc, i + 0x4),
11425				    REG_RD_IND(sc, i + 0x8),
11426				    REG_RD_IND(sc, i + 0xC));
11427		}
11428	}
11429
11430	BCE_PRINTF(
11431	    "----------------------------"
11432	    "----------------"
11433	    "----------------------------\n");
11434}
11435
11436
11437/****************************************************************************/
11438/* Prints out the Completion Procesor (COM) state.                          */
11439/*                                                                          */
11440/* Returns:                                                                 */
11441/*   Nothing.                                                               */
11442/****************************************************************************/
11443static __attribute__ ((noinline)) void
11444bce_dump_com_state(struct bce_softc *sc, int regs)
11445{
11446	u32 val;
11447	u32 fw_version[4];
11448
11449	BCE_PRINTF(
11450	    "----------------------------"
11451	    "   COM State    "
11452	    "----------------------------\n");
11453
11454	for (int i = 0; i < 3; i++)
11455		fw_version[i] = htonl(REG_RD_IND(sc,
11456		    (BCE_COM_SCRATCH + 0x10 + i * 4)));
11457
11458	BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11459
11460	val = REG_RD_IND(sc, BCE_COM_CPU_MODE);
11461	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_mode\n",
11462	    val, BCE_COM_CPU_MODE);
11463
11464	val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
11465	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n",
11466	    val, BCE_COM_CPU_STATE);
11467
11468	val = REG_RD_IND(sc, BCE_COM_CPU_EVENT_MASK);
11469	BCE_PRINTF("0x%08X - (0x%06X) com_cpu_event_mask\n", val,
11470	    BCE_COM_CPU_EVENT_MASK);
11471
11472	if (regs) {
11473		BCE_PRINTF(
11474		    "----------------------------"
11475		    " Register  Dump "
11476		    "----------------------------\n");
11477
11478		for (int i = BCE_COM_CPU_MODE; i < 0x1053e8; i += 0x10) {
11479			BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11480			    "0x%08X 0x%08X\n", i,
11481			    REG_RD_IND(sc, i),
11482			    REG_RD_IND(sc, i + 0x4),
11483			    REG_RD_IND(sc, i + 0x8),
11484			    REG_RD_IND(sc, i + 0xC));
11485		}
11486	}
11487
11488	BCE_PRINTF(
11489		"----------------------------"
11490		"----------------"
11491		"----------------------------\n");
11492}
11493
11494
11495/****************************************************************************/
11496/* Prints out the Receive Virtual 2 Physical (RV2P) state.                  */
11497/*                                                                          */
11498/* Returns:                                                                 */
11499/*   Nothing.                                                               */
11500/****************************************************************************/
11501static __attribute__ ((noinline)) void
11502bce_dump_rv2p_state(struct bce_softc *sc)
11503{
11504	u32 val, pc1, pc2, fw_ver_high, fw_ver_low;
11505
11506	BCE_PRINTF(
11507	    "----------------------------"
11508	    "   RV2P State   "
11509	    "----------------------------\n");
11510
11511	/* Stall the RV2P processors. */
11512	val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
11513	val |= BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2;
11514	REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
11515
11516	/* Read the firmware version. */
11517	val = 0x00000001;
11518	REG_WR_IND(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
11519	fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
11520	fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) &
11521	    BCE_RV2P_INSTR_HIGH_HIGH;
11522	BCE_PRINTF("RV2P1 Firmware version - 0x%08X:0x%08X\n",
11523	    fw_ver_high, fw_ver_low);
11524
11525	val = 0x00000001;
11526	REG_WR_IND(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
11527	fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
11528	fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) &
11529	    BCE_RV2P_INSTR_HIGH_HIGH;
11530	BCE_PRINTF("RV2P2 Firmware version - 0x%08X:0x%08X\n",
11531	    fw_ver_high, fw_ver_low);
11532
11533	/* Resume the RV2P processors. */
11534	val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
11535	val &= ~(BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2);
11536	REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
11537
11538	/* Fetch the program counter value. */
11539	val = 0x68007800;
11540	REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
11541	val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
11542	pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
11543	pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
11544	BCE_PRINTF("0x%08X - RV2P1 program counter (1st read)\n", pc1);
11545	BCE_PRINTF("0x%08X - RV2P2 program counter (1st read)\n", pc2);
11546
11547	/* Fetch the program counter value again to see if it is advancing. */
11548	val = 0x68007800;
11549	REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
11550	val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
11551	pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
11552	pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
11553	BCE_PRINTF("0x%08X - RV2P1 program counter (2nd read)\n", pc1);
11554	BCE_PRINTF("0x%08X - RV2P2 program counter (2nd read)\n", pc2);
11555
11556	BCE_PRINTF(
11557	    "----------------------------"
11558	    "----------------"
11559	    "----------------------------\n");
11560}
11561
11562
11563/****************************************************************************/
11564/* Prints out the driver state and then enters the debugger.                */
11565/*                                                                          */
11566/* Returns:                                                                 */
11567/*   Nothing.                                                               */
11568/****************************************************************************/
11569static __attribute__ ((noinline)) void
11570bce_breakpoint(struct bce_softc *sc)
11571{
11572
11573	/*
11574	 * Unreachable code to silence compiler warnings
11575	 * about unused functions.
11576	 */
11577	if (0) {
11578		bce_freeze_controller(sc);
11579		bce_unfreeze_controller(sc);
11580		bce_dump_enet(sc, NULL);
11581		bce_dump_txbd(sc, 0, NULL);
11582		bce_dump_rxbd(sc, 0, NULL);
11583		bce_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD_ALLOC);
11584		bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD_ALLOC);
11585		bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD_ALLOC);
11586		bce_dump_l2fhdr(sc, 0, NULL);
11587		bce_dump_ctx(sc, RX_CID);
11588		bce_dump_ftqs(sc);
11589		bce_dump_tx_chain(sc, 0, USABLE_TX_BD_ALLOC);
11590		bce_dump_rx_bd_chain(sc, 0, USABLE_RX_BD_ALLOC);
11591		bce_dump_pg_chain(sc, 0, USABLE_PG_BD_ALLOC);
11592		bce_dump_status_block(sc);
11593		bce_dump_stats_block(sc);
11594		bce_dump_driver_state(sc);
11595		bce_dump_hw_state(sc);
11596		bce_dump_bc_state(sc);
11597		bce_dump_txp_state(sc, 0);
11598		bce_dump_rxp_state(sc, 0);
11599		bce_dump_tpat_state(sc, 0);
11600		bce_dump_cp_state(sc, 0);
11601		bce_dump_com_state(sc, 0);
11602		bce_dump_rv2p_state(sc);
11603		bce_dump_pgbd(sc, 0, NULL);
11604	}
11605
11606	bce_dump_status_block(sc);
11607	bce_dump_driver_state(sc);
11608
11609	/* Call the debugger. */
11610	breakpoint();
11611}
11612#endif
11613