1 /* $NetBSD: if_bnx.c,v 1.29 2009/11/18 23:11:16 bouyer Exp $ */
2 /* $OpenBSD: if_bnx.c,v 1.85 2009/11/09 14:32:41 dlg Exp $ */
5 * Copyright (c) 2006 Broadcom Corporation
6 * David Christensen <davidch@broadcom.com>. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of Broadcom Corporation nor the name of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written consent.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD: src/sys/dev/bce/if_bce.c,v 1.3 2006/04/13 14:12:26 ru Exp $");
38 __KERNEL_RCSID(0, "$NetBSD: if_bnx.c,v 1.29 2009/11/18 23:11:16 bouyer Exp $");
41 * The following controllers are supported by this driver:
49 * The following controllers are not supported by this driver:
55 * BCM5709C A0 B0, B1, B2 (pre-production)
56 * BCM5709S A0, A1, B0, B1, B2, C0 (pre-production)
59 #include <sys/callout.h>
60 #include <sys/mutex.h>
62 #include <dev/pci/if_bnxreg.h>
63 #include <dev/microcode/bnx/bnxfw.h>
65 /****************************************************************************/
66 /* BNX Driver Version */
67 /****************************************************************************/
68 #define BNX_DRIVER_VERSION "v0.9.6"
70 /****************************************************************************/
71 /* BNX Debug Options */
72 /****************************************************************************/
74 u_int32_t bnx_debug
= /*BNX_WARN*/ BNX_VERBOSE_SEND
;
77 /* 1 = 1 in 2,147,483,648 */
78 /* 256 = 1 in 8,388,608 */
79 /* 2048 = 1 in 1,048,576 */
80 /* 65536 = 1 in 32,768 */
81 /* 1048576 = 1 in 2,048 */
82 /* 268435456 = 1 in 8 */
83 /* 536870912 = 1 in 4 */
84 /* 1073741824 = 1 in 2 */
86 /* Controls how often the l2_fhdr frame error check will fail. */
87 int bnx_debug_l2fhdr_status_check
= 0;
89 /* Controls how often the unexpected attention check will fail. */
90 int bnx_debug_unexpected_attention
= 0;
92 /* Controls how often to simulate an mbuf allocation failure. */
93 int bnx_debug_mbuf_allocation_failure
= 0;
95 /* Controls how often to simulate a DMA mapping failure. */
96 int bnx_debug_dma_map_addr_failure
= 0;
98 /* Controls how often to simulate a bootcode failure. */
99 int bnx_debug_bootcode_running_failure
= 0;
102 /****************************************************************************/
103 /* PCI Device ID Table */
105 /* Used by bnx_probe() to identify the devices supported by this driver. */
106 /****************************************************************************/
107 static const struct bnx_product
{
108 pci_vendor_id_t bp_vendor
;
109 pci_product_id_t bp_product
;
110 pci_vendor_id_t bp_subvendor
;
111 pci_product_id_t bp_subproduct
;
114 #ifdef PCI_SUBPRODUCT_HP_NC370T
116 PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM5706
,
117 PCI_VENDOR_HP
, PCI_SUBPRODUCT_HP_NC370T
,
118 "HP NC370T Multifunction Gigabit Server Adapter"
121 #ifdef PCI_SUBPRODUCT_HP_NC370i
123 PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM5706
,
124 PCI_VENDOR_HP
, PCI_SUBPRODUCT_HP_NC370i
,
125 "HP NC370i Multifunction Gigabit Server Adapter"
129 PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM5706
,
131 "Broadcom NetXtreme II BCM5706 1000Base-T"
133 #ifdef PCI_SUBPRODUCT_HP_NC370F
135 PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM5706S
,
136 PCI_VENDOR_HP
, PCI_SUBPRODUCT_HP_NC370F
,
137 "HP NC370F Multifunction Gigabit Server Adapter"
141 PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM5706S
,
143 "Broadcom NetXtreme II BCM5706 1000Base-SX"
146 PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM5708
,
148 "Broadcom NetXtreme II BCM5708 1000Base-T"
151 PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM5708S
,
153 "Broadcom NetXtreme II BCM5708 1000Base-SX"
156 PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM5709
,
158 "Broadcom NetXtreme II BCM5709 1000Base-T"
161 PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM5709S
,
163 "Broadcom NetXtreme II BCM5709 1000Base-SX"
166 PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM5716
,
168 "Broadcom NetXtreme II BCM5716 1000Base-T"
171 PCI_VENDOR_BROADCOM
, PCI_PRODUCT_BROADCOM_BCM5716S
,
173 "Broadcom NetXtreme II BCM5716 1000Base-SX"
177 /****************************************************************************/
178 /* Supported Flash NVRAM device data. */
179 /****************************************************************************/
180 static struct flash_spec flash_table
[] =
182 #define BUFFERED_FLAGS (BNX_NV_BUFFERED | BNX_NV_TRANSLATE)
183 #define NONBUFFERED_FLAGS (BNX_NV_WREN)
185 {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
186 BUFFERED_FLAGS
, SEEPROM_PAGE_BITS
, SEEPROM_PAGE_SIZE
,
187 SEEPROM_BYTE_ADDR_MASK
, SEEPROM_TOTAL_SIZE
,
189 /* Expansion entry 0001 */
190 {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
191 NONBUFFERED_FLAGS
, SAIFUN_FLASH_PAGE_BITS
, SAIFUN_FLASH_PAGE_SIZE
,
192 SAIFUN_FLASH_BYTE_ADDR_MASK
, 0,
194 /* Saifun SA25F010 (non-buffered flash) */
195 /* strap, cfg1, & write1 need updates */
196 {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
197 NONBUFFERED_FLAGS
, SAIFUN_FLASH_PAGE_BITS
, SAIFUN_FLASH_PAGE_SIZE
,
198 SAIFUN_FLASH_BYTE_ADDR_MASK
, SAIFUN_FLASH_BASE_TOTAL_SIZE
*2,
199 "Non-buffered flash (128kB)"},
200 /* Saifun SA25F020 (non-buffered flash) */
201 /* strap, cfg1, & write1 need updates */
202 {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
203 NONBUFFERED_FLAGS
, SAIFUN_FLASH_PAGE_BITS
, SAIFUN_FLASH_PAGE_SIZE
,
204 SAIFUN_FLASH_BYTE_ADDR_MASK
, SAIFUN_FLASH_BASE_TOTAL_SIZE
*4,
205 "Non-buffered flash (256kB)"},
206 /* Expansion entry 0100 */
207 {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
208 NONBUFFERED_FLAGS
, SAIFUN_FLASH_PAGE_BITS
, SAIFUN_FLASH_PAGE_SIZE
,
209 SAIFUN_FLASH_BYTE_ADDR_MASK
, 0,
211 /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
212 {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
213 NONBUFFERED_FLAGS
, ST_MICRO_FLASH_PAGE_BITS
, ST_MICRO_FLASH_PAGE_SIZE
,
214 ST_MICRO_FLASH_BYTE_ADDR_MASK
, ST_MICRO_FLASH_BASE_TOTAL_SIZE
*2,
215 "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
216 /* Entry 0110: ST M45PE20 (non-buffered flash)*/
217 {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
218 NONBUFFERED_FLAGS
, ST_MICRO_FLASH_PAGE_BITS
, ST_MICRO_FLASH_PAGE_SIZE
,
219 ST_MICRO_FLASH_BYTE_ADDR_MASK
, ST_MICRO_FLASH_BASE_TOTAL_SIZE
*4,
220 "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
221 /* Saifun SA25F005 (non-buffered flash) */
222 /* strap, cfg1, & write1 need updates */
223 {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
224 NONBUFFERED_FLAGS
, SAIFUN_FLASH_PAGE_BITS
, SAIFUN_FLASH_PAGE_SIZE
,
225 SAIFUN_FLASH_BYTE_ADDR_MASK
, SAIFUN_FLASH_BASE_TOTAL_SIZE
,
226 "Non-buffered flash (64kB)"},
228 {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
229 BUFFERED_FLAGS
, SEEPROM_PAGE_BITS
, SEEPROM_PAGE_SIZE
,
230 SEEPROM_BYTE_ADDR_MASK
, SEEPROM_TOTAL_SIZE
,
232 /* Expansion entry 1001 */
233 {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
234 NONBUFFERED_FLAGS
, SAIFUN_FLASH_PAGE_BITS
, SAIFUN_FLASH_PAGE_SIZE
,
235 SAIFUN_FLASH_BYTE_ADDR_MASK
, 0,
237 /* Expansion entry 1010 */
238 {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
239 NONBUFFERED_FLAGS
, SAIFUN_FLASH_PAGE_BITS
, SAIFUN_FLASH_PAGE_SIZE
,
240 SAIFUN_FLASH_BYTE_ADDR_MASK
, 0,
242 /* ATMEL AT45DB011B (buffered flash) */
243 {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
244 BUFFERED_FLAGS
, BUFFERED_FLASH_PAGE_BITS
, BUFFERED_FLASH_PAGE_SIZE
,
245 BUFFERED_FLASH_BYTE_ADDR_MASK
, BUFFERED_FLASH_TOTAL_SIZE
,
246 "Buffered flash (128kB)"},
247 /* Expansion entry 1100 */
248 {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
249 NONBUFFERED_FLAGS
, SAIFUN_FLASH_PAGE_BITS
, SAIFUN_FLASH_PAGE_SIZE
,
250 SAIFUN_FLASH_BYTE_ADDR_MASK
, 0,
252 /* Expansion entry 1101 */
253 {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
254 NONBUFFERED_FLAGS
, SAIFUN_FLASH_PAGE_BITS
, SAIFUN_FLASH_PAGE_SIZE
,
255 SAIFUN_FLASH_BYTE_ADDR_MASK
, 0,
257 /* Ateml Expansion entry 1110 */
258 {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
259 BUFFERED_FLAGS
, BUFFERED_FLASH_PAGE_BITS
, BUFFERED_FLASH_PAGE_SIZE
,
260 BUFFERED_FLASH_BYTE_ADDR_MASK
, 0,
261 "Entry 1110 (Atmel)"},
262 /* ATMEL AT45DB021B (buffered flash) */
263 {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
264 BUFFERED_FLAGS
, BUFFERED_FLASH_PAGE_BITS
, BUFFERED_FLASH_PAGE_SIZE
,
265 BUFFERED_FLASH_BYTE_ADDR_MASK
, BUFFERED_FLASH_TOTAL_SIZE
*2,
266 "Buffered flash (256kB)"},
270 * The BCM5709 controllers transparently handle the
271 * differences between Atmel 264 byte pages and all
272 * flash devices which use 256 byte pages, so no
273 * logical-to-physical mapping is required in the
276 static struct flash_spec flash_5709
= {
277 .flags
= BNX_NV_BUFFERED
,
278 .page_bits
= BCM5709_FLASH_PAGE_BITS
,
279 .page_size
= BCM5709_FLASH_PAGE_SIZE
,
280 .addr_mask
= BCM5709_FLASH_BYTE_ADDR_MASK
,
281 .total_size
= BUFFERED_FLASH_TOTAL_SIZE
* 2,
282 .name
= "5709 buffered flash (256kB)",
285 /****************************************************************************/
286 /* OpenBSD device entry points. */
287 /****************************************************************************/
288 static int bnx_probe(device_t
, cfdata_t
, void *);
289 void bnx_attach(device_t
, device_t
, void *);
290 int bnx_detach(device_t
, int);
292 /****************************************************************************/
293 /* BNX Debug Data Structure Dump Routines */
294 /****************************************************************************/
296 void bnx_dump_mbuf(struct bnx_softc
*, struct mbuf
*);
297 void bnx_dump_tx_mbuf_chain(struct bnx_softc
*, int, int);
298 void bnx_dump_rx_mbuf_chain(struct bnx_softc
*, int, int);
299 void bnx_dump_txbd(struct bnx_softc
*, int, struct tx_bd
*);
300 void bnx_dump_rxbd(struct bnx_softc
*, int, struct rx_bd
*);
301 void bnx_dump_l2fhdr(struct bnx_softc
*, int, struct l2_fhdr
*);
302 void bnx_dump_tx_chain(struct bnx_softc
*, int, int);
303 void bnx_dump_rx_chain(struct bnx_softc
*, int, int);
304 void bnx_dump_status_block(struct bnx_softc
*);
305 void bnx_dump_stats_block(struct bnx_softc
*);
306 void bnx_dump_driver_state(struct bnx_softc
*);
307 void bnx_dump_hw_state(struct bnx_softc
*);
308 void bnx_breakpoint(struct bnx_softc
*);
311 /****************************************************************************/
312 /* BNX Register/Memory Access Routines */
313 /****************************************************************************/
314 u_int32_t
bnx_reg_rd_ind(struct bnx_softc
*, u_int32_t
);
315 void bnx_reg_wr_ind(struct bnx_softc
*, u_int32_t
, u_int32_t
);
316 void bnx_ctx_wr(struct bnx_softc
*, u_int32_t
, u_int32_t
, u_int32_t
);
317 int bnx_miibus_read_reg(device_t
, int, int);
318 void bnx_miibus_write_reg(device_t
, int, int, int);
319 void bnx_miibus_statchg(device_t
);
321 /****************************************************************************/
322 /* BNX NVRAM Access Routines */
323 /****************************************************************************/
324 int bnx_acquire_nvram_lock(struct bnx_softc
*);
325 int bnx_release_nvram_lock(struct bnx_softc
*);
326 void bnx_enable_nvram_access(struct bnx_softc
*);
327 void bnx_disable_nvram_access(struct bnx_softc
*);
328 int bnx_nvram_read_dword(struct bnx_softc
*, u_int32_t
, u_int8_t
*,
330 int bnx_init_nvram(struct bnx_softc
*);
331 int bnx_nvram_read(struct bnx_softc
*, u_int32_t
, u_int8_t
*, int);
332 int bnx_nvram_test(struct bnx_softc
*);
333 #ifdef BNX_NVRAM_WRITE_SUPPORT
334 int bnx_enable_nvram_write(struct bnx_softc
*);
335 void bnx_disable_nvram_write(struct bnx_softc
*);
336 int bnx_nvram_erase_page(struct bnx_softc
*, u_int32_t
);
337 int bnx_nvram_write_dword(struct bnx_softc
*, u_int32_t
, u_int8_t
*,
339 int bnx_nvram_write(struct bnx_softc
*, u_int32_t
, u_int8_t
*, int);
342 /****************************************************************************/
344 /****************************************************************************/
345 void bnx_get_media(struct bnx_softc
*);
346 int bnx_dma_alloc(struct bnx_softc
*);
347 void bnx_dma_free(struct bnx_softc
*);
348 void bnx_release_resources(struct bnx_softc
*);
350 /****************************************************************************/
351 /* BNX Firmware Synchronization and Load */
352 /****************************************************************************/
353 int bnx_fw_sync(struct bnx_softc
*, u_int32_t
);
354 void bnx_load_rv2p_fw(struct bnx_softc
*, u_int32_t
*, u_int32_t
,
356 void bnx_load_cpu_fw(struct bnx_softc
*, struct cpu_reg
*,
358 void bnx_init_cpus(struct bnx_softc
*);
360 void bnx_stop(struct ifnet
*, int);
361 int bnx_reset(struct bnx_softc
*, u_int32_t
);
362 int bnx_chipinit(struct bnx_softc
*);
363 int bnx_blockinit(struct bnx_softc
*);
364 static int bnx_add_buf(struct bnx_softc
*, struct mbuf
*, u_int16_t
*,
365 u_int16_t
*, u_int32_t
*);
366 int bnx_get_buf(struct bnx_softc
*, u_int16_t
*, u_int16_t
*, u_int32_t
*);
368 int bnx_init_tx_chain(struct bnx_softc
*);
369 void bnx_init_tx_context(struct bnx_softc
*);
370 int bnx_init_rx_chain(struct bnx_softc
*);
371 void bnx_init_rx_context(struct bnx_softc
*);
372 void bnx_free_rx_chain(struct bnx_softc
*);
373 void bnx_free_tx_chain(struct bnx_softc
*);
375 int bnx_tx_encap(struct bnx_softc
*, struct mbuf
*);
376 void bnx_start(struct ifnet
*);
377 int bnx_ioctl(struct ifnet
*, u_long
, void *);
378 void bnx_watchdog(struct ifnet
*);
379 int bnx_init(struct ifnet
*);
381 void bnx_init_context(struct bnx_softc
*);
382 void bnx_get_mac_addr(struct bnx_softc
*);
383 void bnx_set_mac_addr(struct bnx_softc
*);
384 void bnx_phy_intr(struct bnx_softc
*);
385 void bnx_rx_intr(struct bnx_softc
*);
386 void bnx_tx_intr(struct bnx_softc
*);
387 void bnx_disable_intr(struct bnx_softc
*);
388 void bnx_enable_intr(struct bnx_softc
*);
390 int bnx_intr(void *);
391 void bnx_iff(struct bnx_softc
*);
392 void bnx_stats_update(struct bnx_softc
*);
393 void bnx_tick(void *);
395 struct pool
*bnx_tx_pool
= NULL
;
396 int bnx_alloc_pkts(struct bnx_softc
*);
398 /****************************************************************************/
399 /* OpenBSD device dispatch table. */
400 /****************************************************************************/
401 CFATTACH_DECL3_NEW(bnx
, sizeof(struct bnx_softc
),
402 bnx_probe
, bnx_attach
, bnx_detach
, NULL
, NULL
, NULL
, DVF_DETACH_SHUTDOWN
);
404 /****************************************************************************/
405 /* Device probe function. */
407 /* Compares the device to the driver's list of supported devices and */
408 /* reports back to the OS whether this is the right driver for the device. */
411 /* BUS_PROBE_DEFAULT on success, positive value on failure. */
412 /****************************************************************************/
413 static const struct bnx_product
*
414 bnx_lookup(const struct pci_attach_args
*pa
)
419 for (i
= 0; i
< __arraycount(bnx_devices
); i
++) {
420 if (PCI_VENDOR(pa
->pa_id
) != bnx_devices
[i
].bp_vendor
||
421 PCI_PRODUCT(pa
->pa_id
) != bnx_devices
[i
].bp_product
)
423 if (!bnx_devices
[i
].bp_subvendor
)
424 return &bnx_devices
[i
];
425 subid
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, PCI_SUBSYS_ID_REG
);
426 if (PCI_VENDOR(subid
) == bnx_devices
[i
].bp_subvendor
&&
427 PCI_PRODUCT(subid
) == bnx_devices
[i
].bp_subproduct
)
428 return &bnx_devices
[i
];
434 bnx_probe(device_t parent
, cfdata_t match
, void *aux
)
436 struct pci_attach_args
*pa
= (struct pci_attach_args
*)aux
;
438 if (bnx_lookup(pa
) != NULL
)
444 /****************************************************************************/
445 /* Device attach function. */
447 /* Allocates device resources, performs secondary chip identification, */
448 /* resets and initializes the hardware, and initializes driver instance */
452 /* 0 on success, positive value on failure. */
453 /****************************************************************************/
455 bnx_attach(device_t parent
, device_t self
, void *aux
)
457 const struct bnx_product
*bp
;
458 struct bnx_softc
*sc
= device_private(self
);
459 struct pci_attach_args
*pa
= aux
;
460 pci_chipset_tag_t pc
= pa
->pa_pc
;
461 pci_intr_handle_t ih
;
462 const char *intrstr
= NULL
;
466 int mii_flags
= MIIF_FORCEANEG
;
469 if (bnx_tx_pool
== NULL
) {
470 bnx_tx_pool
= malloc(sizeof(*bnx_tx_pool
), M_DEVBUF
, M_NOWAIT
);
471 if (bnx_tx_pool
!= NULL
) {
472 pool_init(bnx_tx_pool
, sizeof(struct bnx_pkt
),
473 0, 0, 0, "bnxpkts", NULL
, IPL_NET
);
475 aprint_error(": can't alloc bnx_tx_pool\n");
482 panic("unknown device");
487 aprint_normal(": %s\n", bp
->bp_name
);
492 * Map control/status registers.
494 command
= pci_conf_read(pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
);
495 command
|= PCI_COMMAND_MEM_ENABLE
| PCI_COMMAND_MASTER_ENABLE
;
496 pci_conf_write(pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
, command
);
497 command
= pci_conf_read(pc
, pa
->pa_tag
, PCI_COMMAND_STATUS_REG
);
499 if (!(command
& PCI_COMMAND_MEM_ENABLE
)) {
500 aprint_error_dev(sc
->bnx_dev
,
501 "failed to enable memory mapping!\n");
505 memtype
= pci_mapreg_type(pa
->pa_pc
, pa
->pa_tag
, BNX_PCI_BAR0
);
506 if (pci_mapreg_map(pa
, BNX_PCI_BAR0
, memtype
, 0, &sc
->bnx_btag
,
507 &sc
->bnx_bhandle
, NULL
, &sc
->bnx_size
)) {
508 aprint_error_dev(sc
->bnx_dev
, "can't find mem space\n");
512 if (pci_intr_map(pa
, &ih
)) {
513 aprint_error_dev(sc
->bnx_dev
, "couldn't map interrupt\n");
514 goto bnx_attach_fail
;
517 intrstr
= pci_intr_string(pc
, ih
);
520 * Configure byte swap and enable indirect register access.
521 * Rely on CPU to do target byte swapping on big endian systems.
522 * Access to registers outside of PCI configurtion space are not
523 * valid until this is done.
525 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
, BNX_PCICFG_MISC_CONFIG
,
526 BNX_PCICFG_MISC_CONFIG_REG_WINDOW_ENA
|
527 BNX_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP
);
529 /* Save ASIC revsion info. */
530 sc
->bnx_chipid
= REG_RD(sc
, BNX_MISC_ID
);
533 * Find the base address for shared memory access.
534 * Newer versions of bootcode use a signature and offset
535 * while older versions use a fixed address.
537 val
= REG_RD_IND(sc
, BNX_SHM_HDR_SIGNATURE
);
538 if ((val
& BNX_SHM_HDR_SIGNATURE_SIG_MASK
) == BNX_SHM_HDR_SIGNATURE_SIG
)
539 sc
->bnx_shmem_base
= REG_RD_IND(sc
, BNX_SHM_HDR_ADDR_0
+
540 (sc
->bnx_pa
.pa_function
<< 2));
542 sc
->bnx_shmem_base
= HOST_VIEW_SHMEM_BASE
;
544 DBPRINT(sc
, BNX_INFO
, "bnx_shmem_base = 0x%08X\n", sc
->bnx_shmem_base
);
546 /* Set initial device and PHY flags */
548 sc
->bnx_phy_flags
= 0;
550 /* Get PCI bus information (speed and type). */
551 val
= REG_RD(sc
, BNX_PCICFG_MISC_STATUS
);
552 if (val
& BNX_PCICFG_MISC_STATUS_PCIX_DET
) {
555 sc
->bnx_flags
|= BNX_PCIX_FLAG
;
557 clkreg
= REG_RD(sc
, BNX_PCICFG_PCI_CLOCK_CONTROL_BITS
);
559 clkreg
&= BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET
;
561 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ
:
562 sc
->bus_speed_mhz
= 133;
565 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ
:
566 sc
->bus_speed_mhz
= 100;
569 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ
:
570 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ
:
571 sc
->bus_speed_mhz
= 66;
574 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ
:
575 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ
:
576 sc
->bus_speed_mhz
= 50;
579 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW
:
580 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ
:
581 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ
:
582 sc
->bus_speed_mhz
= 33;
585 } else if (val
& BNX_PCICFG_MISC_STATUS_M66EN
)
586 sc
->bus_speed_mhz
= 66;
588 sc
->bus_speed_mhz
= 33;
590 if (val
& BNX_PCICFG_MISC_STATUS_32BIT_DET
)
591 sc
->bnx_flags
|= BNX_PCI_32BIT_FLAG
;
593 /* Reset the controller. */
594 if (bnx_reset(sc
, BNX_DRV_MSG_CODE_RESET
))
595 goto bnx_attach_fail
;
597 /* Initialize the controller. */
598 if (bnx_chipinit(sc
)) {
599 aprint_error_dev(sc
->bnx_dev
,
600 "Controller initialization failed!\n");
601 goto bnx_attach_fail
;
604 /* Perform NVRAM test. */
605 if (bnx_nvram_test(sc
)) {
606 aprint_error_dev(sc
->bnx_dev
, "NVRAM test failed!\n");
607 goto bnx_attach_fail
;
610 /* Fetch the permanent Ethernet MAC address. */
611 bnx_get_mac_addr(sc
);
612 aprint_normal_dev(sc
->bnx_dev
, "Ethernet address %s\n",
613 ether_sprintf(sc
->eaddr
));
616 * Trip points control how many BDs
617 * should be ready before generating an
618 * interrupt while ticks control how long
619 * a BD can sit in the chain before
620 * generating an interrupt. Set the default
621 * values for the RX and TX rings.
625 /* Force more frequent interrupts. */
626 sc
->bnx_tx_quick_cons_trip_int
= 1;
627 sc
->bnx_tx_quick_cons_trip
= 1;
628 sc
->bnx_tx_ticks_int
= 0;
629 sc
->bnx_tx_ticks
= 0;
631 sc
->bnx_rx_quick_cons_trip_int
= 1;
632 sc
->bnx_rx_quick_cons_trip
= 1;
633 sc
->bnx_rx_ticks_int
= 0;
634 sc
->bnx_rx_ticks
= 0;
636 sc
->bnx_tx_quick_cons_trip_int
= 20;
637 sc
->bnx_tx_quick_cons_trip
= 20;
638 sc
->bnx_tx_ticks_int
= 80;
639 sc
->bnx_tx_ticks
= 80;
641 sc
->bnx_rx_quick_cons_trip_int
= 6;
642 sc
->bnx_rx_quick_cons_trip
= 6;
643 sc
->bnx_rx_ticks_int
= 18;
644 sc
->bnx_rx_ticks
= 18;
647 /* Update statistics once every second. */
648 sc
->bnx_stats_ticks
= 1000000 & 0xffff00;
650 /* Find the media type for the adapter. */
654 * Store config data needed by the PHY driver for
655 * backplane applications
657 sc
->bnx_shared_hw_cfg
= REG_RD_IND(sc
, sc
->bnx_shmem_base
+
658 BNX_SHARED_HW_CFG_CONFIG
);
659 sc
->bnx_port_hw_cfg
= REG_RD_IND(sc
, sc
->bnx_shmem_base
+
660 BNX_PORT_HW_CFG_CONFIG
);
662 /* Allocate DMA memory resources. */
663 sc
->bnx_dmatag
= pa
->pa_dmat
;
664 if (bnx_dma_alloc(sc
)) {
665 aprint_error_dev(sc
->bnx_dev
,
666 "DMA resource allocation failed!\n");
667 goto bnx_attach_fail
;
670 /* Initialize the ifnet interface. */
671 ifp
= &sc
->bnx_ec
.ec_if
;
673 ifp
->if_flags
= IFF_BROADCAST
| IFF_SIMPLEX
| IFF_MULTICAST
;
674 ifp
->if_ioctl
= bnx_ioctl
;
675 ifp
->if_stop
= bnx_stop
;
676 ifp
->if_start
= bnx_start
;
677 ifp
->if_init
= bnx_init
;
679 ifp
->if_watchdog
= bnx_watchdog
;
680 IFQ_SET_MAXLEN(&ifp
->if_snd
, USABLE_TX_BD
- 1);
681 IFQ_SET_READY(&ifp
->if_snd
);
682 memcpy(ifp
->if_xname
, device_xname(self
), IFNAMSIZ
);
684 sc
->bnx_ec
.ec_capabilities
|= ETHERCAP_JUMBO_MTU
|
685 ETHERCAP_VLAN_MTU
| ETHERCAP_VLAN_HWTAGGING
;
687 ifp
->if_capabilities
|=
688 IFCAP_CSUM_IPv4_Tx
| IFCAP_CSUM_IPv4_Rx
|
689 IFCAP_CSUM_TCPv4_Tx
| IFCAP_CSUM_TCPv4_Rx
|
690 IFCAP_CSUM_UDPv4_Tx
| IFCAP_CSUM_UDPv4_Rx
;
692 /* Hookup IRQ last. */
693 sc
->bnx_intrhand
= pci_intr_establish(pc
, ih
, IPL_NET
, bnx_intr
, sc
);
694 if (sc
->bnx_intrhand
== NULL
) {
695 aprint_error_dev(self
, "couldn't establish interrupt");
697 aprint_error(" at %s", intrstr
);
699 goto bnx_attach_fail
;
701 aprint_normal_dev(sc
->bnx_dev
, "interrupting at %s\n", intrstr
);
703 sc
->bnx_mii
.mii_ifp
= ifp
;
704 sc
->bnx_mii
.mii_readreg
= bnx_miibus_read_reg
;
705 sc
->bnx_mii
.mii_writereg
= bnx_miibus_write_reg
;
706 sc
->bnx_mii
.mii_statchg
= bnx_miibus_statchg
;
708 sc
->bnx_ec
.ec_mii
= &sc
->bnx_mii
;
709 ifmedia_init(&sc
->bnx_mii
.mii_media
, 0, ether_mediachange
,
711 if (sc
->bnx_phy_flags
& BNX_PHY_SERDES_FLAG
)
712 mii_flags
|= MIIF_HAVEFIBER
;
713 mii_attach(self
, &sc
->bnx_mii
, 0xffffffff,
714 MII_PHY_ANY
, MII_OFFSET_ANY
, mii_flags
);
716 if (LIST_EMPTY(&sc
->bnx_mii
.mii_phys
)) {
717 aprint_error_dev(self
, "no PHY found!\n");
718 ifmedia_add(&sc
->bnx_mii
.mii_media
,
719 IFM_ETHER
|IFM_MANUAL
, 0, NULL
);
720 ifmedia_set(&sc
->bnx_mii
.mii_media
,
721 IFM_ETHER
|IFM_MANUAL
);
723 ifmedia_set(&sc
->bnx_mii
.mii_media
,
727 /* Attach to the Ethernet interface list. */
729 ether_ifattach(ifp
,sc
->eaddr
);
731 callout_init(&sc
->bnx_timeout
, 0);
733 if (pmf_device_register(self
, NULL
, NULL
))
734 pmf_class_network_register(self
, ifp
);
736 aprint_error_dev(self
, "couldn't establish power handler\n");
738 /* Print some important debugging info. */
739 DBRUN(BNX_INFO
, bnx_dump_driver_state(sc
));
741 goto bnx_attach_exit
;
744 bnx_release_resources(sc
);
747 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Exiting %s()\n", __func__
);
750 /****************************************************************************/
751 /* Device detach function. */
753 /* Stops the controller, resets the controller, and releases resources. */
756 /* 0 on success, positive value on failure. */
757 /****************************************************************************/
759 bnx_detach(device_t dev
, int flags
)
762 struct bnx_softc
*sc
;
765 sc
= device_private(dev
);
766 ifp
= &sc
->bnx_ec
.ec_if
;
768 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Entering %s()\n", __func__
);
770 /* Stop and reset the controller. */
772 if (ifp
->if_flags
& IFF_RUNNING
)
775 /* Disable the transmit/receive blocks. */
776 REG_WR(sc
, BNX_MISC_ENABLE_CLR_BITS
, 0x5ffffff);
777 REG_RD(sc
, BNX_MISC_ENABLE_CLR_BITS
);
779 bnx_disable_intr(sc
);
780 bnx_reset(sc
, BNX_DRV_MSG_CODE_RESET
);
785 pmf_device_deregister(dev
);
786 callout_destroy(&sc
->bnx_timeout
);
789 mii_detach(&sc
->bnx_mii
, MII_PHY_ANY
, MII_OFFSET_ANY
);
791 /* Release all remaining resources. */
792 bnx_release_resources(sc
);
794 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Exiting %s()\n", __func__
);
799 /****************************************************************************/
800 /* Indirect register read. */
802 /* Reads NetXtreme II registers using an index/data register pair in PCI */
803 /* configuration space. Using this mechanism avoids issues with posted */
804 /* reads but is much slower than memory-mapped I/O. */
807 /* The value of the register. */
808 /****************************************************************************/
810 bnx_reg_rd_ind(struct bnx_softc
*sc
, u_int32_t offset
)
812 struct pci_attach_args
*pa
= &(sc
->bnx_pa
);
814 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
, BNX_PCICFG_REG_WINDOW_ADDRESS
,
819 val
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
,
820 BNX_PCICFG_REG_WINDOW
);
821 DBPRINT(sc
, BNX_EXCESSIVE
, "%s(); offset = 0x%08X, "
822 "val = 0x%08X\n", __func__
, offset
, val
);
826 return pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, BNX_PCICFG_REG_WINDOW
);
830 /****************************************************************************/
831 /* Indirect register write. */
833 /* Writes NetXtreme II registers using an index/data register pair in PCI */
834 /* configuration space. Using this mechanism avoids issues with posted */
835 /* writes but is muchh slower than memory-mapped I/O. */
839 /****************************************************************************/
841 bnx_reg_wr_ind(struct bnx_softc
*sc
, u_int32_t offset
, u_int32_t val
)
843 struct pci_attach_args
*pa
= &(sc
->bnx_pa
);
845 DBPRINT(sc
, BNX_EXCESSIVE
, "%s(); offset = 0x%08X, val = 0x%08X\n",
846 __func__
, offset
, val
);
848 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
, BNX_PCICFG_REG_WINDOW_ADDRESS
,
850 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
, BNX_PCICFG_REG_WINDOW
, val
);
853 /****************************************************************************/
854 /* Context memory write. */
856 /* The NetXtreme II controller uses context memory to track connection */
857 /* information for L2 and higher network protocols. */
861 /****************************************************************************/
863 bnx_ctx_wr(struct bnx_softc
*sc
, u_int32_t cid_addr
, u_int32_t ctx_offset
,
866 u_int32_t idx
, offset
= ctx_offset
+ cid_addr
;
867 u_int32_t val
, retry_cnt
= 5;
869 if (BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5709
) {
870 REG_WR(sc
, BNX_CTX_CTX_DATA
, ctx_val
);
871 REG_WR(sc
, BNX_CTX_CTX_CTRL
,
872 (offset
| BNX_CTX_CTX_CTRL_WRITE_REQ
));
874 for (idx
= 0; idx
< retry_cnt
; idx
++) {
875 val
= REG_RD(sc
, BNX_CTX_CTX_CTRL
);
876 if ((val
& BNX_CTX_CTX_CTRL_WRITE_REQ
) == 0)
882 if (val
& BNX_CTX_CTX_CTRL_WRITE_REQ
)
883 BNX_PRINTF("%s(%d); Unable to write CTX memory: "
884 "cid_addr = 0x%08X, offset = 0x%08X!\n",
885 __FILE__
, __LINE__
, cid_addr
, ctx_offset
);
889 REG_WR(sc
, BNX_CTX_DATA_ADR
, offset
);
890 REG_WR(sc
, BNX_CTX_DATA
, ctx_val
);
894 /****************************************************************************/
895 /* PHY register read. */
897 /* Implements register reads on the MII bus. */
900 /* The value of the register. */
901 /****************************************************************************/
903 bnx_miibus_read_reg(device_t dev
, int phy
, int reg
)
905 struct bnx_softc
*sc
= device_private(dev
);
909 /* Make sure we are accessing the correct PHY address. */
910 if (phy
!= sc
->bnx_phy_addr
) {
911 DBPRINT(sc
, BNX_VERBOSE
,
912 "Invalid PHY address %d for PHY read!\n", phy
);
916 if (sc
->bnx_phy_flags
& BNX_PHY_INT_MODE_AUTO_POLLING_FLAG
) {
917 val
= REG_RD(sc
, BNX_EMAC_MDIO_MODE
);
918 val
&= ~BNX_EMAC_MDIO_MODE_AUTO_POLL
;
920 REG_WR(sc
, BNX_EMAC_MDIO_MODE
, val
);
921 REG_RD(sc
, BNX_EMAC_MDIO_MODE
);
926 val
= BNX_MIPHY(phy
) | BNX_MIREG(reg
) |
927 BNX_EMAC_MDIO_COMM_COMMAND_READ
| BNX_EMAC_MDIO_COMM_DISEXT
|
928 BNX_EMAC_MDIO_COMM_START_BUSY
;
929 REG_WR(sc
, BNX_EMAC_MDIO_COMM
, val
);
931 for (i
= 0; i
< BNX_PHY_TIMEOUT
; i
++) {
934 val
= REG_RD(sc
, BNX_EMAC_MDIO_COMM
);
935 if (!(val
& BNX_EMAC_MDIO_COMM_START_BUSY
)) {
938 val
= REG_RD(sc
, BNX_EMAC_MDIO_COMM
);
939 val
&= BNX_EMAC_MDIO_COMM_DATA
;
945 if (val
& BNX_EMAC_MDIO_COMM_START_BUSY
) {
946 BNX_PRINTF(sc
, "%s(%d): Error: PHY read timeout! phy = %d, "
947 "reg = 0x%04X\n", __FILE__
, __LINE__
, phy
, reg
);
950 val
= REG_RD(sc
, BNX_EMAC_MDIO_COMM
);
952 DBPRINT(sc
, BNX_EXCESSIVE
,
953 "%s(): phy = %d, reg = 0x%04X, val = 0x%04X\n", __func__
, phy
,
954 (u_int16_t
) reg
& 0xffff, (u_int16_t
) val
& 0xffff);
956 if (sc
->bnx_phy_flags
& BNX_PHY_INT_MODE_AUTO_POLLING_FLAG
) {
957 val
= REG_RD(sc
, BNX_EMAC_MDIO_MODE
);
958 val
|= BNX_EMAC_MDIO_MODE_AUTO_POLL
;
960 REG_WR(sc
, BNX_EMAC_MDIO_MODE
, val
);
961 REG_RD(sc
, BNX_EMAC_MDIO_MODE
);
966 return (val
& 0xffff);
969 /****************************************************************************/
970 /* PHY register write. */
972 /* Implements register writes on the MII bus. */
975 /* The value of the register. */
976 /****************************************************************************/
978 bnx_miibus_write_reg(device_t dev
, int phy
, int reg
, int val
)
980 struct bnx_softc
*sc
= device_private(dev
);
984 /* Make sure we are accessing the correct PHY address. */
985 if (phy
!= sc
->bnx_phy_addr
) {
986 DBPRINT(sc
, BNX_WARN
, "Invalid PHY address %d for PHY write!\n",
991 DBPRINT(sc
, BNX_EXCESSIVE
, "%s(): phy = %d, reg = 0x%04X, "
992 "val = 0x%04X\n", __func__
,
993 phy
, (u_int16_t
) reg
& 0xffff, (u_int16_t
) val
& 0xffff);
995 if (sc
->bnx_phy_flags
& BNX_PHY_INT_MODE_AUTO_POLLING_FLAG
) {
996 val1
= REG_RD(sc
, BNX_EMAC_MDIO_MODE
);
997 val1
&= ~BNX_EMAC_MDIO_MODE_AUTO_POLL
;
999 REG_WR(sc
, BNX_EMAC_MDIO_MODE
, val1
);
1000 REG_RD(sc
, BNX_EMAC_MDIO_MODE
);
1005 val1
= BNX_MIPHY(phy
) | BNX_MIREG(reg
) | val
|
1006 BNX_EMAC_MDIO_COMM_COMMAND_WRITE
|
1007 BNX_EMAC_MDIO_COMM_START_BUSY
| BNX_EMAC_MDIO_COMM_DISEXT
;
1008 REG_WR(sc
, BNX_EMAC_MDIO_COMM
, val1
);
1010 for (i
= 0; i
< BNX_PHY_TIMEOUT
; i
++) {
1013 val1
= REG_RD(sc
, BNX_EMAC_MDIO_COMM
);
1014 if (!(val1
& BNX_EMAC_MDIO_COMM_START_BUSY
)) {
1020 if (val1
& BNX_EMAC_MDIO_COMM_START_BUSY
) {
1021 BNX_PRINTF(sc
, "%s(%d): PHY write timeout!\n", __FILE__
,
1025 if (sc
->bnx_phy_flags
& BNX_PHY_INT_MODE_AUTO_POLLING_FLAG
) {
1026 val1
= REG_RD(sc
, BNX_EMAC_MDIO_MODE
);
1027 val1
|= BNX_EMAC_MDIO_MODE_AUTO_POLL
;
1029 REG_WR(sc
, BNX_EMAC_MDIO_MODE
, val1
);
1030 REG_RD(sc
, BNX_EMAC_MDIO_MODE
);
1036 /****************************************************************************/
1037 /* MII bus status change. */
1039 /* Called by the MII bus driver when the PHY establishes link to set the */
1040 /* MAC interface registers. */
1044 /****************************************************************************/
1046 bnx_miibus_statchg(device_t dev
)
1048 struct bnx_softc
*sc
= device_private(dev
);
1049 struct mii_data
*mii
= &sc
->bnx_mii
;
1052 val
= REG_RD(sc
, BNX_EMAC_MODE
);
1053 val
&= ~(BNX_EMAC_MODE_PORT
| BNX_EMAC_MODE_HALF_DUPLEX
|
1054 BNX_EMAC_MODE_MAC_LOOP
| BNX_EMAC_MODE_FORCE_LINK
|
1057 /* Set MII or GMII interface based on the speed
1058 * negotiated by the PHY.
1060 switch (IFM_SUBTYPE(mii
->mii_media_active
)) {
1062 if (BNX_CHIP_NUM(sc
) != BNX_CHIP_NUM_5706
) {
1063 DBPRINT(sc
, BNX_INFO
, "Enabling 10Mb interface.\n");
1064 val
|= BNX_EMAC_MODE_PORT_MII_10
;
1069 DBPRINT(sc
, BNX_INFO
, "Enabling MII interface.\n");
1070 val
|= BNX_EMAC_MODE_PORT_MII
;
1073 DBPRINT(sc
, BNX_INFO
, "Enabling 2.5G MAC mode.\n");
1074 val
|= BNX_EMAC_MODE_25G
;
1078 DBPRINT(sc
, BNX_INFO
, "Enabling GMII interface.\n");
1079 val
|= BNX_EMAC_MODE_PORT_GMII
;
1082 val
|= BNX_EMAC_MODE_PORT_GMII
;
1086 /* Set half or full duplex based on the duplicity
1087 * negotiated by the PHY.
1089 if ((mii
->mii_media_active
& IFM_GMASK
) == IFM_HDX
) {
1090 DBPRINT(sc
, BNX_INFO
, "Setting Half-Duplex interface.\n");
1091 val
|= BNX_EMAC_MODE_HALF_DUPLEX
;
1093 DBPRINT(sc
, BNX_INFO
, "Setting Full-Duplex interface.\n");
1096 REG_WR(sc
, BNX_EMAC_MODE
, val
);
1099 /****************************************************************************/
1100 /* Acquire NVRAM lock. */
1102 /* Before the NVRAM can be accessed the caller must acquire an NVRAM lock. */
1103 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is */
1104 /* for use by the driver. */
1107 /* 0 on success, positive value on failure. */
1108 /****************************************************************************/
1110 bnx_acquire_nvram_lock(struct bnx_softc
*sc
)
1115 DBPRINT(sc
, BNX_VERBOSE
, "Acquiring NVRAM lock.\n");
1117 /* Request access to the flash interface. */
1118 REG_WR(sc
, BNX_NVM_SW_ARB
, BNX_NVM_SW_ARB_ARB_REQ_SET2
);
1119 for (j
= 0; j
< NVRAM_TIMEOUT_COUNT
; j
++) {
1120 val
= REG_RD(sc
, BNX_NVM_SW_ARB
);
1121 if (val
& BNX_NVM_SW_ARB_ARB_ARB2
)
1127 if (j
>= NVRAM_TIMEOUT_COUNT
) {
1128 DBPRINT(sc
, BNX_WARN
, "Timeout acquiring NVRAM lock!\n");
1135 /****************************************************************************/
1136 /* Release NVRAM lock. */
1138 /* When the caller is finished accessing NVRAM the lock must be released. */
1139 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is */
1140 /* for use by the driver. */
1143 /* 0 on success, positive value on failure. */
1144 /****************************************************************************/
1146 bnx_release_nvram_lock(struct bnx_softc
*sc
)
1151 DBPRINT(sc
, BNX_VERBOSE
, "Releasing NVRAM lock.\n");
1153 /* Relinquish nvram interface. */
1154 REG_WR(sc
, BNX_NVM_SW_ARB
, BNX_NVM_SW_ARB_ARB_REQ_CLR2
);
1156 for (j
= 0; j
< NVRAM_TIMEOUT_COUNT
; j
++) {
1157 val
= REG_RD(sc
, BNX_NVM_SW_ARB
);
1158 if (!(val
& BNX_NVM_SW_ARB_ARB_ARB2
))
1164 if (j
>= NVRAM_TIMEOUT_COUNT
) {
1165 DBPRINT(sc
, BNX_WARN
, "Timeout reeasing NVRAM lock!\n");
1172 #ifdef BNX_NVRAM_WRITE_SUPPORT
1173 /****************************************************************************/
1174 /* Enable NVRAM write access. */
1176 /* Before writing to NVRAM the caller must enable NVRAM writes. */
1179 /* 0 on success, positive value on failure. */
1180 /****************************************************************************/
1182 bnx_enable_nvram_write(struct bnx_softc
*sc
)
1186 DBPRINT(sc
, BNX_VERBOSE
, "Enabling NVRAM write.\n");
1188 val
= REG_RD(sc
, BNX_MISC_CFG
);
1189 REG_WR(sc
, BNX_MISC_CFG
, val
| BNX_MISC_CFG_NVM_WR_EN_PCI
);
1191 if (!ISSET(sc
->bnx_flash_info
->flags
, BNX_NV_BUFFERED
)) {
1194 REG_WR(sc
, BNX_NVM_COMMAND
, BNX_NVM_COMMAND_DONE
);
1195 REG_WR(sc
, BNX_NVM_COMMAND
,
1196 BNX_NVM_COMMAND_WREN
| BNX_NVM_COMMAND_DOIT
);
1198 for (j
= 0; j
< NVRAM_TIMEOUT_COUNT
; j
++) {
1201 val
= REG_RD(sc
, BNX_NVM_COMMAND
);
1202 if (val
& BNX_NVM_COMMAND_DONE
)
1206 if (j
>= NVRAM_TIMEOUT_COUNT
) {
1207 DBPRINT(sc
, BNX_WARN
, "Timeout writing NVRAM!\n");
1215 /****************************************************************************/
1216 /* Disable NVRAM write access. */
1218 /* When the caller is finished writing to NVRAM write access must be */
1223 /****************************************************************************/
1225 bnx_disable_nvram_write(struct bnx_softc
*sc
)
1229 DBPRINT(sc
, BNX_VERBOSE
, "Disabling NVRAM write.\n");
1231 val
= REG_RD(sc
, BNX_MISC_CFG
);
1232 REG_WR(sc
, BNX_MISC_CFG
, val
& ~BNX_MISC_CFG_NVM_WR_EN
);
1236 /****************************************************************************/
1237 /* Enable NVRAM access. */
1239 /* Before accessing NVRAM for read or write operations the caller must */
1240 /* enabled NVRAM access. */
1244 /****************************************************************************/
1246 bnx_enable_nvram_access(struct bnx_softc
*sc
)
1250 DBPRINT(sc
, BNX_VERBOSE
, "Enabling NVRAM access.\n");
1252 val
= REG_RD(sc
, BNX_NVM_ACCESS_ENABLE
);
1253 /* Enable both bits, even on read. */
1254 REG_WR(sc
, BNX_NVM_ACCESS_ENABLE
,
1255 val
| BNX_NVM_ACCESS_ENABLE_EN
| BNX_NVM_ACCESS_ENABLE_WR_EN
);
1258 /****************************************************************************/
1259 /* Disable NVRAM access. */
1261 /* When the caller is finished accessing NVRAM access must be disabled. */
1265 /****************************************************************************/
1267 bnx_disable_nvram_access(struct bnx_softc
*sc
)
1271 DBPRINT(sc
, BNX_VERBOSE
, "Disabling NVRAM access.\n");
1273 val
= REG_RD(sc
, BNX_NVM_ACCESS_ENABLE
);
1275 /* Disable both bits, even after read. */
1276 REG_WR(sc
, BNX_NVM_ACCESS_ENABLE
,
1277 val
& ~(BNX_NVM_ACCESS_ENABLE_EN
| BNX_NVM_ACCESS_ENABLE_WR_EN
));
1280 #ifdef BNX_NVRAM_WRITE_SUPPORT
1281 /****************************************************************************/
1282 /* Erase NVRAM page before writing. */
1284 /* Non-buffered flash parts require that a page be erased before it is */
1288 /* 0 on success, positive value on failure. */
1289 /****************************************************************************/
1291 bnx_nvram_erase_page(struct bnx_softc
*sc
, u_int32_t offset
)
1296 /* Buffered flash doesn't require an erase. */
1297 if (ISSET(sc
->bnx_flash_info
->flags
, BNX_NV_BUFFERED
))
1300 DBPRINT(sc
, BNX_VERBOSE
, "Erasing NVRAM page.\n");
1302 /* Build an erase command. */
1303 cmd
= BNX_NVM_COMMAND_ERASE
| BNX_NVM_COMMAND_WR
|
1304 BNX_NVM_COMMAND_DOIT
;
1307 * Clear the DONE bit separately, set the NVRAM adress to erase,
1308 * and issue the erase command.
1310 REG_WR(sc
, BNX_NVM_COMMAND
, BNX_NVM_COMMAND_DONE
);
1311 REG_WR(sc
, BNX_NVM_ADDR
, offset
& BNX_NVM_ADDR_NVM_ADDR_VALUE
);
1312 REG_WR(sc
, BNX_NVM_COMMAND
, cmd
);
1314 /* Wait for completion. */
1315 for (j
= 0; j
< NVRAM_TIMEOUT_COUNT
; j
++) {
1320 val
= REG_RD(sc
, BNX_NVM_COMMAND
);
1321 if (val
& BNX_NVM_COMMAND_DONE
)
1325 if (j
>= NVRAM_TIMEOUT_COUNT
) {
1326 DBPRINT(sc
, BNX_WARN
, "Timeout erasing NVRAM.\n");
1332 #endif /* BNX_NVRAM_WRITE_SUPPORT */
1334 /****************************************************************************/
1335 /* Read a dword (32 bits) from NVRAM. */
1337 /* Read a 32 bit word from NVRAM. The caller is assumed to have already */
1338 /* obtained the NVRAM lock and enabled the controller for NVRAM access. */
1341 /* 0 on success and the 32 bit value read, positive value on failure. */
1342 /****************************************************************************/
1344 bnx_nvram_read_dword(struct bnx_softc
*sc
, u_int32_t offset
,
1345 u_int8_t
*ret_val
, u_int32_t cmd_flags
)
1350 /* Build the command word. */
1351 cmd
= BNX_NVM_COMMAND_DOIT
| cmd_flags
;
1353 /* Calculate the offset for buffered flash if translation is used. */
1354 if (ISSET(sc
->bnx_flash_info
->flags
, BNX_NV_TRANSLATE
)) {
1355 offset
= ((offset
/ sc
->bnx_flash_info
->page_size
) <<
1356 sc
->bnx_flash_info
->page_bits
) +
1357 (offset
% sc
->bnx_flash_info
->page_size
);
1361 * Clear the DONE bit separately, set the address to read,
1362 * and issue the read.
1364 REG_WR(sc
, BNX_NVM_COMMAND
, BNX_NVM_COMMAND_DONE
);
1365 REG_WR(sc
, BNX_NVM_ADDR
, offset
& BNX_NVM_ADDR_NVM_ADDR_VALUE
);
1366 REG_WR(sc
, BNX_NVM_COMMAND
, cmd
);
1368 /* Wait for completion. */
1369 for (i
= 0; i
< NVRAM_TIMEOUT_COUNT
; i
++) {
1374 val
= REG_RD(sc
, BNX_NVM_COMMAND
);
1375 if (val
& BNX_NVM_COMMAND_DONE
) {
1376 val
= REG_RD(sc
, BNX_NVM_READ
);
1378 val
= bnx_be32toh(val
);
1379 memcpy(ret_val
, &val
, 4);
1384 /* Check for errors. */
1385 if (i
>= NVRAM_TIMEOUT_COUNT
) {
1386 BNX_PRINTF(sc
, "%s(%d): Timeout error reading NVRAM at "
1387 "offset 0x%08X!\n", __FILE__
, __LINE__
, offset
);
1394 #ifdef BNX_NVRAM_WRITE_SUPPORT
1395 /****************************************************************************/
1396 /* Write a dword (32 bits) to NVRAM. */
1398 /* Write a 32 bit word to NVRAM. The caller is assumed to have already */
1399 /* obtained the NVRAM lock, enabled the controller for NVRAM access, and */
1400 /* enabled NVRAM write access. */
1403 /* 0 on success, positive value on failure. */
1404 /****************************************************************************/
1406 bnx_nvram_write_dword(struct bnx_softc
*sc
, u_int32_t offset
, u_int8_t
*val
,
1407 u_int32_t cmd_flags
)
1409 u_int32_t cmd
, val32
;
1412 /* Build the command word. */
1413 cmd
= BNX_NVM_COMMAND_DOIT
| BNX_NVM_COMMAND_WR
| cmd_flags
;
1415 /* Calculate the offset for buffered flash if translation is used. */
1416 if (ISSET(sc
->bnx_flash_info
->flags
, BNX_NV_TRANSLATE
)) {
1417 offset
= ((offset
/ sc
->bnx_flash_info
->page_size
) <<
1418 sc
->bnx_flash_info
->page_bits
) +
1419 (offset
% sc
->bnx_flash_info
->page_size
);
1423 * Clear the DONE bit separately, convert NVRAM data to big-endian,
1424 * set the NVRAM address to write, and issue the write command
1426 REG_WR(sc
, BNX_NVM_COMMAND
, BNX_NVM_COMMAND_DONE
);
1427 memcpy(&val32
, val
, 4);
1428 val32
= htobe32(val32
);
1429 REG_WR(sc
, BNX_NVM_WRITE
, val32
);
1430 REG_WR(sc
, BNX_NVM_ADDR
, offset
& BNX_NVM_ADDR_NVM_ADDR_VALUE
);
1431 REG_WR(sc
, BNX_NVM_COMMAND
, cmd
);
1433 /* Wait for completion. */
1434 for (j
= 0; j
< NVRAM_TIMEOUT_COUNT
; j
++) {
1437 if (REG_RD(sc
, BNX_NVM_COMMAND
) & BNX_NVM_COMMAND_DONE
)
1440 if (j
>= NVRAM_TIMEOUT_COUNT
) {
1441 BNX_PRINTF(sc
, "%s(%d): Timeout error writing NVRAM at "
1442 "offset 0x%08X\n", __FILE__
, __LINE__
, offset
);
1448 #endif /* BNX_NVRAM_WRITE_SUPPORT */
1450 /****************************************************************************/
1451 /* Initialize NVRAM access. */
1453 /* Identify the NVRAM device in use and prepare the NVRAM interface to */
1454 /* access that device. */
1457 /* 0 on success, positive value on failure. */
1458 /****************************************************************************/
1460 bnx_init_nvram(struct bnx_softc
*sc
)
1463 int j
, entry_count
, rc
= 0;
1464 struct flash_spec
*flash
;
1466 DBPRINT(sc
,BNX_VERBOSE_RESET
, "Entering %s()\n", __func__
);
1468 if (BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5709
) {
1469 sc
->bnx_flash_info
= &flash_5709
;
1470 goto bnx_init_nvram_get_flash_size
;
1473 /* Determine the selected interface. */
1474 val
= REG_RD(sc
, BNX_NVM_CFG1
);
1476 entry_count
= sizeof(flash_table
) / sizeof(struct flash_spec
);
1479 * Flash reconfiguration is required to support additional
1480 * NVRAM devices not directly supported in hardware.
1481 * Check if the flash interface was reconfigured
1485 if (val
& 0x40000000) {
1486 /* Flash interface reconfigured by bootcode. */
1488 DBPRINT(sc
,BNX_INFO_LOAD
,
1489 "bnx_init_nvram(): Flash WAS reconfigured.\n");
1491 for (j
= 0, flash
= &flash_table
[0]; j
< entry_count
;
1493 if ((val
& FLASH_BACKUP_STRAP_MASK
) ==
1494 (flash
->config1
& FLASH_BACKUP_STRAP_MASK
)) {
1495 sc
->bnx_flash_info
= flash
;
1500 /* Flash interface not yet reconfigured. */
1503 DBPRINT(sc
,BNX_INFO_LOAD
,
1504 "bnx_init_nvram(): Flash was NOT reconfigured.\n");
1506 if (val
& (1 << 23))
1507 mask
= FLASH_BACKUP_STRAP_MASK
;
1509 mask
= FLASH_STRAP_MASK
;
1511 /* Look for the matching NVRAM device configuration data. */
1512 for (j
= 0, flash
= &flash_table
[0]; j
< entry_count
;
1514 /* Check if the dev matches any of the known devices. */
1515 if ((val
& mask
) == (flash
->strapping
& mask
)) {
1516 /* Found a device match. */
1517 sc
->bnx_flash_info
= flash
;
1519 /* Request access to the flash interface. */
1520 if ((rc
= bnx_acquire_nvram_lock(sc
)) != 0)
1523 /* Reconfigure the flash interface. */
1524 bnx_enable_nvram_access(sc
);
1525 REG_WR(sc
, BNX_NVM_CFG1
, flash
->config1
);
1526 REG_WR(sc
, BNX_NVM_CFG2
, flash
->config2
);
1527 REG_WR(sc
, BNX_NVM_CFG3
, flash
->config3
);
1528 REG_WR(sc
, BNX_NVM_WRITE1
, flash
->write1
);
1529 bnx_disable_nvram_access(sc
);
1530 bnx_release_nvram_lock(sc
);
1537 /* Check if a matching device was found. */
1538 if (j
== entry_count
) {
1539 sc
->bnx_flash_info
= NULL
;
1540 BNX_PRINTF(sc
, "%s(%d): Unknown Flash NVRAM found!\n",
1541 __FILE__
, __LINE__
);
1545 bnx_init_nvram_get_flash_size
:
1546 /* Write the flash config data to the shared memory interface. */
1547 val
= REG_RD_IND(sc
, sc
->bnx_shmem_base
+ BNX_SHARED_HW_CFG_CONFIG2
);
1548 val
&= BNX_SHARED_HW_CFG2_NVM_SIZE_MASK
;
1550 sc
->bnx_flash_size
= val
;
1552 sc
->bnx_flash_size
= sc
->bnx_flash_info
->total_size
;
1554 DBPRINT(sc
, BNX_INFO_LOAD
, "bnx_init_nvram() flash->total_size = "
1555 "0x%08X\n", sc
->bnx_flash_info
->total_size
);
1557 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Exiting %s()\n", __func__
);
1562 /****************************************************************************/
1563 /* Read an arbitrary range of data from NVRAM. */
1565 /* Prepares the NVRAM interface for access and reads the requested data */
1566 /* into the supplied buffer. */
1569 /* 0 on success and the data read, positive value on failure. */
1570 /****************************************************************************/
1572 bnx_nvram_read(struct bnx_softc
*sc
, u_int32_t offset
, u_int8_t
*ret_buf
,
1576 u_int32_t cmd_flags
, offset32
, len32
, extra
;
1581 /* Request access to the flash interface. */
1582 if ((rc
= bnx_acquire_nvram_lock(sc
)) != 0)
1585 /* Enable access to flash interface */
1586 bnx_enable_nvram_access(sc
);
1599 pre_len
= 4 - (offset
& 3);
1601 if (pre_len
>= len32
) {
1604 BNX_NVM_COMMAND_FIRST
| BNX_NVM_COMMAND_LAST
;
1606 cmd_flags
= BNX_NVM_COMMAND_FIRST
;
1608 rc
= bnx_nvram_read_dword(sc
, offset32
, buf
, cmd_flags
);
1613 memcpy(ret_buf
, buf
+ (offset
& 3), pre_len
);
1621 extra
= 4 - (len32
& 3);
1622 len32
= (len32
+ 4) & ~3;
1629 cmd_flags
= BNX_NVM_COMMAND_LAST
;
1632 BNX_NVM_COMMAND_FIRST
| BNX_NVM_COMMAND_LAST
;
1634 rc
= bnx_nvram_read_dword(sc
, offset32
, buf
, cmd_flags
);
1636 memcpy(ret_buf
, buf
, 4 - extra
);
1637 } else if (len32
> 0) {
1640 /* Read the first word. */
1644 cmd_flags
= BNX_NVM_COMMAND_FIRST
;
1646 rc
= bnx_nvram_read_dword(sc
, offset32
, ret_buf
, cmd_flags
);
1648 /* Advance to the next dword. */
1653 while (len32
> 4 && rc
== 0) {
1654 rc
= bnx_nvram_read_dword(sc
, offset32
, ret_buf
, 0);
1656 /* Advance to the next dword. */
1665 cmd_flags
= BNX_NVM_COMMAND_LAST
;
1666 rc
= bnx_nvram_read_dword(sc
, offset32
, buf
, cmd_flags
);
1668 memcpy(ret_buf
, buf
, 4 - extra
);
1671 /* Disable access to flash interface and release the lock. */
1672 bnx_disable_nvram_access(sc
);
1673 bnx_release_nvram_lock(sc
);
1678 #ifdef BNX_NVRAM_WRITE_SUPPORT
1679 /****************************************************************************/
1680 /* Write an arbitrary range of data from NVRAM. */
1682 /* Prepares the NVRAM interface for write access and writes the requested */
1683 /* data from the supplied buffer. The caller is responsible for */
1684 /* calculating any appropriate CRCs. */
1687 /* 0 on success, positive value on failure. */
1688 /****************************************************************************/
1690 bnx_nvram_write(struct bnx_softc
*sc
, u_int32_t offset
, u_int8_t
*data_buf
,
1693 u_int32_t written
, offset32
, len32
;
1694 u_int8_t
*buf
, start
[4], end
[4];
1696 int align_start
, align_end
;
1701 align_start
= align_end
= 0;
1703 if ((align_start
= (offset32
& 3))) {
1705 len32
+= align_start
;
1706 if ((rc
= bnx_nvram_read(sc
, offset32
, start
, 4)))
1711 if ((len32
> 4) || !align_start
) {
1712 align_end
= 4 - (len32
& 3);
1714 if ((rc
= bnx_nvram_read(sc
, offset32
+ len32
- 4,
1721 if (align_start
|| align_end
) {
1722 buf
= malloc(len32
, M_DEVBUF
, M_NOWAIT
);
1727 memcpy(buf
, start
, 4);
1730 memcpy(buf
+ len32
- 4, end
, 4);
1732 memcpy(buf
+ align_start
, data_buf
, buf_size
);
1736 while ((written
< len32
) && (rc
== 0)) {
1737 u_int32_t page_start
, page_end
, data_start
, data_end
;
1738 u_int32_t addr
, cmd_flags
;
1740 u_int8_t flash_buffer
[264];
1742 /* Find the page_start addr */
1743 page_start
= offset32
+ written
;
1744 page_start
-= (page_start
% sc
->bnx_flash_info
->page_size
);
1745 /* Find the page_end addr */
1746 page_end
= page_start
+ sc
->bnx_flash_info
->page_size
;
1747 /* Find the data_start addr */
1748 data_start
= (written
== 0) ? offset32
: page_start
;
1749 /* Find the data_end addr */
1750 data_end
= (page_end
> offset32
+ len32
) ?
1751 (offset32
+ len32
) : page_end
;
1753 /* Request access to the flash interface. */
1754 if ((rc
= bnx_acquire_nvram_lock(sc
)) != 0)
1755 goto nvram_write_end
;
1757 /* Enable access to flash interface */
1758 bnx_enable_nvram_access(sc
);
1760 cmd_flags
= BNX_NVM_COMMAND_FIRST
;
1761 if (!ISSET(sc
->bnx_flash_info
->flags
, BNX_NV_BUFFERED
)) {
1764 /* Read the whole page into the buffer
1765 * (non-buffer flash only) */
1766 for (j
= 0; j
< sc
->bnx_flash_info
->page_size
; j
+= 4) {
1767 if (j
== (sc
->bnx_flash_info
->page_size
- 4))
1768 cmd_flags
|= BNX_NVM_COMMAND_LAST
;
1770 rc
= bnx_nvram_read_dword(sc
,
1776 goto nvram_write_end
;
1782 /* Enable writes to flash interface (unlock write-protect) */
1783 if ((rc
= bnx_enable_nvram_write(sc
)) != 0)
1784 goto nvram_write_end
;
1786 /* Erase the page */
1787 if ((rc
= bnx_nvram_erase_page(sc
, page_start
)) != 0)
1788 goto nvram_write_end
;
1790 /* Re-enable the write again for the actual write */
1791 bnx_enable_nvram_write(sc
);
1793 /* Loop to write back the buffer data from page_start to
1796 if (!ISSET(sc
->bnx_flash_info
->flags
, BNX_NV_BUFFERED
)) {
1797 for (addr
= page_start
; addr
< data_start
;
1798 addr
+= 4, i
+= 4) {
1800 rc
= bnx_nvram_write_dword(sc
, addr
,
1801 &flash_buffer
[i
], cmd_flags
);
1804 goto nvram_write_end
;
1810 /* Loop to write the new data from data_start to data_end */
1811 for (addr
= data_start
; addr
< data_end
; addr
+= 4, i
++) {
1812 if ((addr
== page_end
- 4) ||
1813 (ISSET(sc
->bnx_flash_info
->flags
, BNX_NV_BUFFERED
)
1814 && (addr
== data_end
- 4))) {
1816 cmd_flags
|= BNX_NVM_COMMAND_LAST
;
1819 rc
= bnx_nvram_write_dword(sc
, addr
, buf
, cmd_flags
);
1822 goto nvram_write_end
;
1828 /* Loop to write back the buffer data from data_end
1830 if (!ISSET(sc
->bnx_flash_info
->flags
, BNX_NV_BUFFERED
)) {
1831 for (addr
= data_end
; addr
< page_end
;
1832 addr
+= 4, i
+= 4) {
1834 if (addr
== page_end
-4)
1835 cmd_flags
= BNX_NVM_COMMAND_LAST
;
1837 rc
= bnx_nvram_write_dword(sc
, addr
,
1838 &flash_buffer
[i
], cmd_flags
);
1841 goto nvram_write_end
;
1847 /* Disable writes to flash interface (lock write-protect) */
1848 bnx_disable_nvram_write(sc
);
1850 /* Disable access to flash interface */
1851 bnx_disable_nvram_access(sc
);
1852 bnx_release_nvram_lock(sc
);
1854 /* Increment written */
1855 written
+= data_end
- data_start
;
1859 if (align_start
|| align_end
)
1860 free(buf
, M_DEVBUF
);
1864 #endif /* BNX_NVRAM_WRITE_SUPPORT */
1866 /****************************************************************************/
1867 /* Verifies that NVRAM is accessible and contains valid data. */
1869 /* Reads the configuration data from NVRAM and verifies that the CRC is */
1873 /* 0 on success, positive value on failure. */
1874 /****************************************************************************/
1876 bnx_nvram_test(struct bnx_softc
*sc
)
1878 u_int32_t buf
[BNX_NVRAM_SIZE
/ 4];
1879 u_int8_t
*data
= (u_int8_t
*) buf
;
1881 u_int32_t magic
, csum
;
1884 * Check that the device NVRAM is valid by reading
1885 * the magic value at offset 0.
1887 if ((rc
= bnx_nvram_read(sc
, 0, data
, 4)) != 0)
1888 goto bnx_nvram_test_done
;
1890 magic
= bnx_be32toh(buf
[0]);
1891 if (magic
!= BNX_NVRAM_MAGIC
) {
1893 BNX_PRINTF(sc
, "%s(%d): Invalid NVRAM magic value! "
1894 "Expected: 0x%08X, Found: 0x%08X\n",
1895 __FILE__
, __LINE__
, BNX_NVRAM_MAGIC
, magic
);
1896 goto bnx_nvram_test_done
;
1900 * Verify that the device NVRAM includes valid
1901 * configuration data.
1903 if ((rc
= bnx_nvram_read(sc
, 0x100, data
, BNX_NVRAM_SIZE
)) != 0)
1904 goto bnx_nvram_test_done
;
1906 csum
= ether_crc32_le(data
, 0x100);
1907 if (csum
!= BNX_CRC32_RESIDUAL
) {
1909 BNX_PRINTF(sc
, "%s(%d): Invalid Manufacturing Information "
1910 "NVRAM CRC! Expected: 0x%08X, Found: 0x%08X\n",
1911 __FILE__
, __LINE__
, BNX_CRC32_RESIDUAL
, csum
);
1912 goto bnx_nvram_test_done
;
1915 csum
= ether_crc32_le(data
+ 0x100, 0x100);
1916 if (csum
!= BNX_CRC32_RESIDUAL
) {
1917 BNX_PRINTF(sc
, "%s(%d): Invalid Feature Configuration "
1918 "Information NVRAM CRC! Expected: 0x%08X, Found: 08%08X\n",
1919 __FILE__
, __LINE__
, BNX_CRC32_RESIDUAL
, csum
);
1923 bnx_nvram_test_done
:
1927 /****************************************************************************/
1928 /* Identifies the current media type of the controller and sets the PHY */
1933 /****************************************************************************/
1935 bnx_get_media(struct bnx_softc
*sc
)
1937 sc
->bnx_phy_addr
= 1;
1939 if (BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5709
) {
1940 u_int32_t val
= REG_RD(sc
, BNX_MISC_DUAL_MEDIA_CTRL
);
1941 u_int32_t bond_id
= val
& BNX_MISC_DUAL_MEDIA_CTRL_BOND_ID
;
1945 * The BCM5709S is software configurable
1946 * for Copper or SerDes operation.
1948 if (bond_id
== BNX_MISC_DUAL_MEDIA_CTRL_BOND_ID_C
) {
1949 DBPRINT(sc
, BNX_INFO_LOAD
,
1950 "5709 bonded for copper.\n");
1951 goto bnx_get_media_exit
;
1952 } else if (bond_id
== BNX_MISC_DUAL_MEDIA_CTRL_BOND_ID_S
) {
1953 DBPRINT(sc
, BNX_INFO_LOAD
,
1954 "5709 bonded for dual media.\n");
1955 sc
->bnx_phy_flags
|= BNX_PHY_SERDES_FLAG
;
1956 goto bnx_get_media_exit
;
1959 if (val
& BNX_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE
)
1960 strap
= (val
& BNX_MISC_DUAL_MEDIA_CTRL_PHY_CTRL
) >> 21;
1962 strap
= (val
& BNX_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP
)
1966 if (sc
->bnx_pa
.pa_function
== 0) {
1971 DBPRINT(sc
, BNX_INFO_LOAD
,
1972 "BCM5709 s/w configured for SerDes.\n");
1973 sc
->bnx_phy_flags
|= BNX_PHY_SERDES_FLAG
;
1975 DBPRINT(sc
, BNX_INFO_LOAD
,
1976 "BCM5709 s/w configured for Copper.\n");
1983 DBPRINT(sc
, BNX_INFO_LOAD
,
1984 "BCM5709 s/w configured for SerDes.\n");
1985 sc
->bnx_phy_flags
|= BNX_PHY_SERDES_FLAG
;
1987 DBPRINT(sc
, BNX_INFO_LOAD
,
1988 "BCM5709 s/w configured for Copper.\n");
1992 } else if (BNX_CHIP_BOND_ID(sc
) & BNX_CHIP_BOND_ID_SERDES_BIT
)
1993 sc
->bnx_phy_flags
|= BNX_PHY_SERDES_FLAG
;
1995 if (sc
->bnx_phy_flags
&& BNX_PHY_SERDES_FLAG
) {
1998 sc
->bnx_flags
|= BNX_NO_WOL_FLAG
;
1999 if (BNX_CHIP_NUM(sc
) != BNX_CHIP_NUM_5706
) {
2000 sc
->bnx_phy_addr
= 2;
2001 val
= REG_RD_IND(sc
, sc
->bnx_shmem_base
+
2002 BNX_SHARED_HW_CFG_CONFIG
);
2003 if (val
& BNX_SHARED_HW_CFG_PHY_2_5G
) {
2004 sc
->bnx_phy_flags
|= BNX_PHY_2_5G_CAPABLE_FLAG
;
2005 DBPRINT(sc
, BNX_INFO_LOAD
,
2006 "Found 2.5Gb capable adapter\n");
2009 } else if ((BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5706
) ||
2010 (BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5708
))
2011 sc
->bnx_phy_flags
|= BNX_PHY_CRC_FIX_FLAG
;
2014 DBPRINT(sc
, (BNX_INFO_LOAD
),
2015 "Using PHY address %d.\n", sc
->bnx_phy_addr
);
2018 /****************************************************************************/
2019 /* Free any DMA memory owned by the driver. */
2021 /* Scans through each data structre that requires DMA memory and frees */
2022 /* the memory if allocated. */
2026 /****************************************************************************/
2028 bnx_dma_free(struct bnx_softc
*sc
)
2032 DBPRINT(sc
,BNX_VERBOSE_RESET
, "Entering %s()\n", __func__
);
2034 /* Destroy the status block. */
2035 if (sc
->status_block
!= NULL
&& sc
->status_map
!= NULL
) {
2036 bus_dmamap_unload(sc
->bnx_dmatag
, sc
->status_map
);
2037 bus_dmamem_unmap(sc
->bnx_dmatag
, (void *)sc
->status_block
,
2039 bus_dmamem_free(sc
->bnx_dmatag
, &sc
->status_seg
,
2041 bus_dmamap_destroy(sc
->bnx_dmatag
, sc
->status_map
);
2042 sc
->status_block
= NULL
;
2043 sc
->status_map
= NULL
;
2046 /* Destroy the statistics block. */
2047 if (sc
->stats_block
!= NULL
&& sc
->stats_map
!= NULL
) {
2048 bus_dmamap_unload(sc
->bnx_dmatag
, sc
->stats_map
);
2049 bus_dmamem_unmap(sc
->bnx_dmatag
, (void *)sc
->stats_block
,
2051 bus_dmamem_free(sc
->bnx_dmatag
, &sc
->stats_seg
,
2053 bus_dmamap_destroy(sc
->bnx_dmatag
, sc
->stats_map
);
2054 sc
->stats_block
= NULL
;
2055 sc
->stats_map
= NULL
;
2058 /* Free, unmap and destroy all context memory pages. */
2059 if (BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5709
) {
2060 for (i
= 0; i
< sc
->ctx_pages
; i
++) {
2061 if (sc
->ctx_block
[i
] != NULL
) {
2062 bus_dmamap_unload(sc
->bnx_dmatag
,
2064 bus_dmamem_unmap(sc
->bnx_dmatag
,
2065 (void *)sc
->ctx_block
[i
],
2067 bus_dmamem_free(sc
->bnx_dmatag
,
2068 &sc
->ctx_segs
[i
], sc
->ctx_rsegs
[i
]);
2069 bus_dmamap_destroy(sc
->bnx_dmatag
,
2071 sc
->ctx_block
[i
] = NULL
;
2076 /* Free, unmap and destroy all TX buffer descriptor chain pages. */
2077 for (i
= 0; i
< TX_PAGES
; i
++ ) {
2078 if (sc
->tx_bd_chain
[i
] != NULL
&&
2079 sc
->tx_bd_chain_map
[i
] != NULL
) {
2080 bus_dmamap_unload(sc
->bnx_dmatag
,
2081 sc
->tx_bd_chain_map
[i
]);
2082 bus_dmamem_unmap(sc
->bnx_dmatag
,
2083 (void *)sc
->tx_bd_chain
[i
], BNX_TX_CHAIN_PAGE_SZ
);
2084 bus_dmamem_free(sc
->bnx_dmatag
, &sc
->tx_bd_chain_seg
[i
],
2085 sc
->tx_bd_chain_rseg
[i
]);
2086 bus_dmamap_destroy(sc
->bnx_dmatag
,
2087 sc
->tx_bd_chain_map
[i
]);
2088 sc
->tx_bd_chain
[i
] = NULL
;
2089 sc
->tx_bd_chain_map
[i
] = NULL
;
2093 /* Destroy the TX dmamaps. */
2094 /* This isn't necessary since we dont allocate them up front */
2096 /* Free, unmap and destroy all RX buffer descriptor chain pages. */
2097 for (i
= 0; i
< RX_PAGES
; i
++ ) {
2098 if (sc
->rx_bd_chain
[i
] != NULL
&&
2099 sc
->rx_bd_chain_map
[i
] != NULL
) {
2100 bus_dmamap_unload(sc
->bnx_dmatag
,
2101 sc
->rx_bd_chain_map
[i
]);
2102 bus_dmamem_unmap(sc
->bnx_dmatag
,
2103 (void *)sc
->rx_bd_chain
[i
], BNX_RX_CHAIN_PAGE_SZ
);
2104 bus_dmamem_free(sc
->bnx_dmatag
, &sc
->rx_bd_chain_seg
[i
],
2105 sc
->rx_bd_chain_rseg
[i
]);
2107 bus_dmamap_destroy(sc
->bnx_dmatag
,
2108 sc
->rx_bd_chain_map
[i
]);
2109 sc
->rx_bd_chain
[i
] = NULL
;
2110 sc
->rx_bd_chain_map
[i
] = NULL
;
2114 /* Unload and destroy the RX mbuf maps. */
2115 for (i
= 0; i
< TOTAL_RX_BD
; i
++) {
2116 if (sc
->rx_mbuf_map
[i
] != NULL
) {
2117 bus_dmamap_unload(sc
->bnx_dmatag
, sc
->rx_mbuf_map
[i
]);
2118 bus_dmamap_destroy(sc
->bnx_dmatag
, sc
->rx_mbuf_map
[i
]);
2122 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Exiting %s()\n", __func__
);
2125 /****************************************************************************/
2126 /* Allocate any DMA memory needed by the driver. */
2128 /* Allocates DMA memory needed for the various global structures needed by */
2132 /* 0 for success, positive value for failure. */
2133 /****************************************************************************/
2135 bnx_dma_alloc(struct bnx_softc
*sc
)
2139 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Entering %s()\n", __func__
);
2142 * Allocate DMA memory for the status block, map the memory into DMA
2143 * space, and fetch the physical address of the block.
2145 if (bus_dmamap_create(sc
->bnx_dmatag
, BNX_STATUS_BLK_SZ
, 1,
2146 BNX_STATUS_BLK_SZ
, 0, BUS_DMA_NOWAIT
, &sc
->status_map
)) {
2147 aprint_error_dev(sc
->bnx_dev
,
2148 "Could not create status block DMA map!\n");
2150 goto bnx_dma_alloc_exit
;
2153 if (bus_dmamem_alloc(sc
->bnx_dmatag
, BNX_STATUS_BLK_SZ
,
2154 BNX_DMA_ALIGN
, BNX_DMA_BOUNDARY
, &sc
->status_seg
, 1,
2155 &sc
->status_rseg
, BUS_DMA_NOWAIT
)) {
2156 aprint_error_dev(sc
->bnx_dev
,
2157 "Could not allocate status block DMA memory!\n");
2159 goto bnx_dma_alloc_exit
;
2162 if (bus_dmamem_map(sc
->bnx_dmatag
, &sc
->status_seg
, sc
->status_rseg
,
2163 BNX_STATUS_BLK_SZ
, (void **)&sc
->status_block
, BUS_DMA_NOWAIT
)) {
2164 aprint_error_dev(sc
->bnx_dev
,
2165 "Could not map status block DMA memory!\n");
2167 goto bnx_dma_alloc_exit
;
2170 if (bus_dmamap_load(sc
->bnx_dmatag
, sc
->status_map
,
2171 sc
->status_block
, BNX_STATUS_BLK_SZ
, NULL
, BUS_DMA_NOWAIT
)) {
2172 aprint_error_dev(sc
->bnx_dev
,
2173 "Could not load status block DMA memory!\n");
2175 goto bnx_dma_alloc_exit
;
2178 sc
->status_block_paddr
= sc
->status_map
->dm_segs
[0].ds_addr
;
2179 memset(sc
->status_block
, 0, BNX_STATUS_BLK_SZ
);
2181 /* DRC - Fix for 64 bit addresses. */
2182 DBPRINT(sc
, BNX_INFO
, "status_block_paddr = 0x%08X\n",
2183 (u_int32_t
) sc
->status_block_paddr
);
2185 /* BCM5709 uses host memory as cache for context memory. */
2186 if (BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5709
) {
2187 sc
->ctx_pages
= 0x2000 / BCM_PAGE_SIZE
;
2188 if (sc
->ctx_pages
== 0)
2190 if (sc
->ctx_pages
> 4) /* XXX */
2193 DBRUNIF((sc
->ctx_pages
> 512),
2194 BNX_PRINTF(sc
, "%s(%d): Too many CTX pages! %d > 512\n",
2195 __FILE__
, __LINE__
, sc
->ctx_pages
));
2198 for (i
= 0; i
< sc
->ctx_pages
; i
++) {
2199 if (bus_dmamap_create(sc
->bnx_dmatag
, BCM_PAGE_SIZE
,
2200 1, BCM_PAGE_SIZE
, BNX_DMA_BOUNDARY
,
2201 BUS_DMA_NOWAIT
| BUS_DMA_ALLOCNOW
,
2202 &sc
->ctx_map
[i
]) != 0) {
2204 goto bnx_dma_alloc_exit
;
2207 if (bus_dmamem_alloc(sc
->bnx_dmatag
, BCM_PAGE_SIZE
,
2208 BCM_PAGE_SIZE
, BNX_DMA_BOUNDARY
, &sc
->ctx_segs
[i
],
2209 1, &sc
->ctx_rsegs
[i
], BUS_DMA_NOWAIT
) != 0) {
2211 goto bnx_dma_alloc_exit
;
2214 if (bus_dmamem_map(sc
->bnx_dmatag
, &sc
->ctx_segs
[i
],
2215 sc
->ctx_rsegs
[i
], BCM_PAGE_SIZE
,
2216 &sc
->ctx_block
[i
], BUS_DMA_NOWAIT
) != 0) {
2218 goto bnx_dma_alloc_exit
;
2221 if (bus_dmamap_load(sc
->bnx_dmatag
, sc
->ctx_map
[i
],
2222 sc
->ctx_block
[i
], BCM_PAGE_SIZE
, NULL
,
2223 BUS_DMA_NOWAIT
) != 0) {
2225 goto bnx_dma_alloc_exit
;
2228 bzero(sc
->ctx_block
[i
], BCM_PAGE_SIZE
);
2233 * Allocate DMA memory for the statistics block, map the memory into
2234 * DMA space, and fetch the physical address of the block.
2236 if (bus_dmamap_create(sc
->bnx_dmatag
, BNX_STATS_BLK_SZ
, 1,
2237 BNX_STATS_BLK_SZ
, 0, BUS_DMA_NOWAIT
, &sc
->stats_map
)) {
2238 aprint_error_dev(sc
->bnx_dev
,
2239 "Could not create stats block DMA map!\n");
2241 goto bnx_dma_alloc_exit
;
2244 if (bus_dmamem_alloc(sc
->bnx_dmatag
, BNX_STATS_BLK_SZ
,
2245 BNX_DMA_ALIGN
, BNX_DMA_BOUNDARY
, &sc
->stats_seg
, 1,
2246 &sc
->stats_rseg
, BUS_DMA_NOWAIT
)) {
2247 aprint_error_dev(sc
->bnx_dev
,
2248 "Could not allocate stats block DMA memory!\n");
2250 goto bnx_dma_alloc_exit
;
2253 if (bus_dmamem_map(sc
->bnx_dmatag
, &sc
->stats_seg
, sc
->stats_rseg
,
2254 BNX_STATS_BLK_SZ
, (void **)&sc
->stats_block
, BUS_DMA_NOWAIT
)) {
2255 aprint_error_dev(sc
->bnx_dev
,
2256 "Could not map stats block DMA memory!\n");
2258 goto bnx_dma_alloc_exit
;
2261 if (bus_dmamap_load(sc
->bnx_dmatag
, sc
->stats_map
,
2262 sc
->stats_block
, BNX_STATS_BLK_SZ
, NULL
, BUS_DMA_NOWAIT
)) {
2263 aprint_error_dev(sc
->bnx_dev
,
2264 "Could not load status block DMA memory!\n");
2266 goto bnx_dma_alloc_exit
;
2269 sc
->stats_block_paddr
= sc
->stats_map
->dm_segs
[0].ds_addr
;
2270 memset(sc
->stats_block
, 0, BNX_STATS_BLK_SZ
);
2272 /* DRC - Fix for 64 bit address. */
2273 DBPRINT(sc
,BNX_INFO
, "stats_block_paddr = 0x%08X\n",
2274 (u_int32_t
) sc
->stats_block_paddr
);
2277 * Allocate DMA memory for the TX buffer descriptor chain,
2278 * and fetch the physical address of the block.
2280 for (i
= 0; i
< TX_PAGES
; i
++) {
2281 if (bus_dmamap_create(sc
->bnx_dmatag
, BNX_TX_CHAIN_PAGE_SZ
, 1,
2282 BNX_TX_CHAIN_PAGE_SZ
, 0, BUS_DMA_NOWAIT
,
2283 &sc
->tx_bd_chain_map
[i
])) {
2284 aprint_error_dev(sc
->bnx_dev
,
2285 "Could not create Tx desc %d DMA map!\n", i
);
2287 goto bnx_dma_alloc_exit
;
2290 if (bus_dmamem_alloc(sc
->bnx_dmatag
, BNX_TX_CHAIN_PAGE_SZ
,
2291 BCM_PAGE_SIZE
, BNX_DMA_BOUNDARY
, &sc
->tx_bd_chain_seg
[i
], 1,
2292 &sc
->tx_bd_chain_rseg
[i
], BUS_DMA_NOWAIT
)) {
2293 aprint_error_dev(sc
->bnx_dev
,
2294 "Could not allocate TX desc %d DMA memory!\n",
2297 goto bnx_dma_alloc_exit
;
2300 if (bus_dmamem_map(sc
->bnx_dmatag
, &sc
->tx_bd_chain_seg
[i
],
2301 sc
->tx_bd_chain_rseg
[i
], BNX_TX_CHAIN_PAGE_SZ
,
2302 (void **)&sc
->tx_bd_chain
[i
], BUS_DMA_NOWAIT
)) {
2303 aprint_error_dev(sc
->bnx_dev
,
2304 "Could not map TX desc %d DMA memory!\n", i
);
2306 goto bnx_dma_alloc_exit
;
2309 if (bus_dmamap_load(sc
->bnx_dmatag
, sc
->tx_bd_chain_map
[i
],
2310 (void *)sc
->tx_bd_chain
[i
], BNX_TX_CHAIN_PAGE_SZ
, NULL
,
2312 aprint_error_dev(sc
->bnx_dev
,
2313 "Could not load TX desc %d DMA memory!\n", i
);
2315 goto bnx_dma_alloc_exit
;
2318 sc
->tx_bd_chain_paddr
[i
] =
2319 sc
->tx_bd_chain_map
[i
]->dm_segs
[0].ds_addr
;
2321 /* DRC - Fix for 64 bit systems. */
2322 DBPRINT(sc
, BNX_INFO
, "tx_bd_chain_paddr[%d] = 0x%08X\n",
2323 i
, (u_int32_t
) sc
->tx_bd_chain_paddr
[i
]);
2327 * Create lists to hold TX mbufs.
2329 TAILQ_INIT(&sc
->tx_free_pkts
);
2330 TAILQ_INIT(&sc
->tx_used_pkts
);
2331 sc
->tx_pkt_count
= 0;
2332 mutex_init(&sc
->tx_pkt_mtx
, MUTEX_DEFAULT
, IPL_NET
);
2335 * Allocate DMA memory for the Rx buffer descriptor chain,
2336 * and fetch the physical address of the block.
2338 for (i
= 0; i
< RX_PAGES
; i
++) {
2339 if (bus_dmamap_create(sc
->bnx_dmatag
, BNX_RX_CHAIN_PAGE_SZ
, 1,
2340 BNX_RX_CHAIN_PAGE_SZ
, 0, BUS_DMA_NOWAIT
,
2341 &sc
->rx_bd_chain_map
[i
])) {
2342 aprint_error_dev(sc
->bnx_dev
,
2343 "Could not create Rx desc %d DMA map!\n", i
);
2345 goto bnx_dma_alloc_exit
;
2348 if (bus_dmamem_alloc(sc
->bnx_dmatag
, BNX_RX_CHAIN_PAGE_SZ
,
2349 BCM_PAGE_SIZE
, BNX_DMA_BOUNDARY
, &sc
->rx_bd_chain_seg
[i
], 1,
2350 &sc
->rx_bd_chain_rseg
[i
], BUS_DMA_NOWAIT
)) {
2351 aprint_error_dev(sc
->bnx_dev
,
2352 "Could not allocate Rx desc %d DMA memory!\n", i
);
2354 goto bnx_dma_alloc_exit
;
2357 if (bus_dmamem_map(sc
->bnx_dmatag
, &sc
->rx_bd_chain_seg
[i
],
2358 sc
->rx_bd_chain_rseg
[i
], BNX_RX_CHAIN_PAGE_SZ
,
2359 (void **)&sc
->rx_bd_chain
[i
], BUS_DMA_NOWAIT
)) {
2360 aprint_error_dev(sc
->bnx_dev
,
2361 "Could not map Rx desc %d DMA memory!\n", i
);
2363 goto bnx_dma_alloc_exit
;
2366 if (bus_dmamap_load(sc
->bnx_dmatag
, sc
->rx_bd_chain_map
[i
],
2367 (void *)sc
->rx_bd_chain
[i
], BNX_RX_CHAIN_PAGE_SZ
, NULL
,
2369 aprint_error_dev(sc
->bnx_dev
,
2370 "Could not load Rx desc %d DMA memory!\n", i
);
2372 goto bnx_dma_alloc_exit
;
2375 memset(sc
->rx_bd_chain
[i
], 0, BNX_RX_CHAIN_PAGE_SZ
);
2376 sc
->rx_bd_chain_paddr
[i
] =
2377 sc
->rx_bd_chain_map
[i
]->dm_segs
[0].ds_addr
;
2379 /* DRC - Fix for 64 bit systems. */
2380 DBPRINT(sc
, BNX_INFO
, "rx_bd_chain_paddr[%d] = 0x%08X\n",
2381 i
, (u_int32_t
) sc
->rx_bd_chain_paddr
[i
]);
2382 bus_dmamap_sync(sc
->bnx_dmatag
, sc
->rx_bd_chain_map
[i
],
2383 0, BNX_RX_CHAIN_PAGE_SZ
,
2384 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
2388 * Create DMA maps for the Rx buffer mbufs.
2390 for (i
= 0; i
< TOTAL_RX_BD
; i
++) {
2391 if (bus_dmamap_create(sc
->bnx_dmatag
, BNX_MAX_JUMBO_MRU
,
2392 BNX_MAX_SEGMENTS
, BNX_MAX_JUMBO_MRU
, 0, BUS_DMA_NOWAIT
,
2393 &sc
->rx_mbuf_map
[i
])) {
2394 aprint_error_dev(sc
->bnx_dev
,
2395 "Could not create Rx mbuf %d DMA map!\n", i
);
2397 goto bnx_dma_alloc_exit
;
2402 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Exiting %s()\n", __func__
);
2407 /****************************************************************************/
2408 /* Release all resources used by the driver. */
2410 /* Releases all resources acquired by the driver including interrupts, */
2411 /* interrupt handler, interfaces, mutexes, and DMA memory. */
2415 /****************************************************************************/
2417 bnx_release_resources(struct bnx_softc
*sc
)
2419 struct pci_attach_args
*pa
= &(sc
->bnx_pa
);
2421 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Entering %s()\n", __func__
);
2425 if (sc
->bnx_intrhand
!= NULL
)
2426 pci_intr_disestablish(pa
->pa_pc
, sc
->bnx_intrhand
);
2429 bus_space_unmap(sc
->bnx_btag
, sc
->bnx_bhandle
, sc
->bnx_size
);
2431 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Exiting %s()\n", __func__
);
2434 /****************************************************************************/
2435 /* Firmware synchronization. */
2437 /* Before performing certain events such as a chip reset, synchronize with */
2438 /* the firmware first. */
2441 /* 0 for success, positive value for failure. */
2442 /****************************************************************************/
2444 bnx_fw_sync(struct bnx_softc
*sc
, u_int32_t msg_data
)
2449 /* Don't waste any time if we've timed out before. */
2450 if (sc
->bnx_fw_timed_out
) {
2452 goto bnx_fw_sync_exit
;
2455 /* Increment the message sequence number. */
2456 sc
->bnx_fw_wr_seq
++;
2457 msg_data
|= sc
->bnx_fw_wr_seq
;
2459 DBPRINT(sc
, BNX_VERBOSE
, "bnx_fw_sync(): msg_data = 0x%08X\n",
2462 /* Send the message to the bootcode driver mailbox. */
2463 REG_WR_IND(sc
, sc
->bnx_shmem_base
+ BNX_DRV_MB
, msg_data
);
2465 /* Wait for the bootcode to acknowledge the message. */
2466 for (i
= 0; i
< FW_ACK_TIME_OUT_MS
; i
++) {
2467 /* Check for a response in the bootcode firmware mailbox. */
2468 val
= REG_RD_IND(sc
, sc
->bnx_shmem_base
+ BNX_FW_MB
);
2469 if ((val
& BNX_FW_MSG_ACK
) == (msg_data
& BNX_DRV_MSG_SEQ
))
2474 /* If we've timed out, tell the bootcode that we've stopped waiting. */
2475 if (((val
& BNX_FW_MSG_ACK
) != (msg_data
& BNX_DRV_MSG_SEQ
)) &&
2476 ((msg_data
& BNX_DRV_MSG_DATA
) != BNX_DRV_MSG_DATA_WAIT0
)) {
2477 BNX_PRINTF(sc
, "%s(%d): Firmware synchronization timeout! "
2478 "msg_data = 0x%08X\n", __FILE__
, __LINE__
, msg_data
);
2480 msg_data
&= ~BNX_DRV_MSG_CODE
;
2481 msg_data
|= BNX_DRV_MSG_CODE_FW_TIMEOUT
;
2483 REG_WR_IND(sc
, sc
->bnx_shmem_base
+ BNX_DRV_MB
, msg_data
);
2485 sc
->bnx_fw_timed_out
= 1;
2493 /****************************************************************************/
2494 /* Load Receive Virtual 2 Physical (RV2P) processor firmware. */
2498 /****************************************************************************/
2500 bnx_load_rv2p_fw(struct bnx_softc
*sc
, u_int32_t
*rv2p_code
,
2501 u_int32_t rv2p_code_len
, u_int32_t rv2p_proc
)
2506 /* Set the page size used by RV2P. */
2507 if (rv2p_proc
== RV2P_PROC2
) {
2508 BNX_RV2P_PROC2_CHG_MAX_BD_PAGE(rv2p_code
,
2509 USABLE_RX_BD_PER_PAGE
);
2512 for (i
= 0; i
< rv2p_code_len
; i
+= 8) {
2513 REG_WR(sc
, BNX_RV2P_INSTR_HIGH
, *rv2p_code
);
2515 REG_WR(sc
, BNX_RV2P_INSTR_LOW
, *rv2p_code
);
2518 if (rv2p_proc
== RV2P_PROC1
) {
2519 val
= (i
/ 8) | BNX_RV2P_PROC1_ADDR_CMD_RDWR
;
2520 REG_WR(sc
, BNX_RV2P_PROC1_ADDR_CMD
, val
);
2522 val
= (i
/ 8) | BNX_RV2P_PROC2_ADDR_CMD_RDWR
;
2523 REG_WR(sc
, BNX_RV2P_PROC2_ADDR_CMD
, val
);
2527 /* Reset the processor, un-stall is done later. */
2528 if (rv2p_proc
== RV2P_PROC1
)
2529 REG_WR(sc
, BNX_RV2P_COMMAND
, BNX_RV2P_COMMAND_PROC1_RESET
);
2531 REG_WR(sc
, BNX_RV2P_COMMAND
, BNX_RV2P_COMMAND_PROC2_RESET
);
2534 /****************************************************************************/
2535 /* Load RISC processor firmware. */
2537 /* Loads firmware from the file if_bnxfw.h into the scratchpad memory */
2538 /* associated with a particular processor. */
2542 /****************************************************************************/
2544 bnx_load_cpu_fw(struct bnx_softc
*sc
, struct cpu_reg
*cpu_reg
,
2551 val
= REG_RD_IND(sc
, cpu_reg
->mode
);
2552 val
|= cpu_reg
->mode_value_halt
;
2553 REG_WR_IND(sc
, cpu_reg
->mode
, val
);
2554 REG_WR_IND(sc
, cpu_reg
->state
, cpu_reg
->state_value_clear
);
2556 /* Load the Text area. */
2557 offset
= cpu_reg
->spad_base
+ (fw
->text_addr
- cpu_reg
->mips_view_base
);
2561 for (j
= 0; j
< (fw
->text_len
/ 4); j
++, offset
+= 4)
2562 REG_WR_IND(sc
, offset
, fw
->text
[j
]);
2565 /* Load the Data area. */
2566 offset
= cpu_reg
->spad_base
+ (fw
->data_addr
- cpu_reg
->mips_view_base
);
2570 for (j
= 0; j
< (fw
->data_len
/ 4); j
++, offset
+= 4)
2571 REG_WR_IND(sc
, offset
, fw
->data
[j
]);
2574 /* Load the SBSS area. */
2575 offset
= cpu_reg
->spad_base
+ (fw
->sbss_addr
- cpu_reg
->mips_view_base
);
2579 for (j
= 0; j
< (fw
->sbss_len
/ 4); j
++, offset
+= 4)
2580 REG_WR_IND(sc
, offset
, fw
->sbss
[j
]);
2583 /* Load the BSS area. */
2584 offset
= cpu_reg
->spad_base
+ (fw
->bss_addr
- cpu_reg
->mips_view_base
);
2588 for (j
= 0; j
< (fw
->bss_len
/4); j
++, offset
+= 4)
2589 REG_WR_IND(sc
, offset
, fw
->bss
[j
]);
2592 /* Load the Read-Only area. */
2593 offset
= cpu_reg
->spad_base
+
2594 (fw
->rodata_addr
- cpu_reg
->mips_view_base
);
2598 for (j
= 0; j
< (fw
->rodata_len
/ 4); j
++, offset
+= 4)
2599 REG_WR_IND(sc
, offset
, fw
->rodata
[j
]);
2602 /* Clear the pre-fetch instruction. */
2603 REG_WR_IND(sc
, cpu_reg
->inst
, 0);
2604 REG_WR_IND(sc
, cpu_reg
->pc
, fw
->start_addr
);
2606 /* Start the CPU. */
2607 val
= REG_RD_IND(sc
, cpu_reg
->mode
);
2608 val
&= ~cpu_reg
->mode_value_halt
;
2609 REG_WR_IND(sc
, cpu_reg
->state
, cpu_reg
->state_value_clear
);
2610 REG_WR_IND(sc
, cpu_reg
->mode
, val
);
2613 /****************************************************************************/
2614 /* Initialize the RV2P, RX, TX, TPAT, and COM CPUs. */
2616 /* Loads the firmware for each CPU and starts the CPU. */
2620 /****************************************************************************/
2622 bnx_init_cpus(struct bnx_softc
*sc
)
2624 struct cpu_reg cpu_reg
;
2627 switch(BNX_CHIP_NUM(sc
)) {
2628 case BNX_CHIP_NUM_5709
:
2629 /* Initialize the RV2P processor. */
2630 if (BNX_CHIP_REV(sc
) == BNX_CHIP_REV_Ax
) {
2631 bnx_load_rv2p_fw(sc
, bnx_xi90_rv2p_proc1
,
2632 sizeof(bnx_xi90_rv2p_proc1
), RV2P_PROC1
);
2633 bnx_load_rv2p_fw(sc
, bnx_xi90_rv2p_proc2
,
2634 sizeof(bnx_xi90_rv2p_proc2
), RV2P_PROC2
);
2636 bnx_load_rv2p_fw(sc
, bnx_xi_rv2p_proc1
,
2637 sizeof(bnx_xi_rv2p_proc1
), RV2P_PROC1
);
2638 bnx_load_rv2p_fw(sc
, bnx_xi_rv2p_proc2
,
2639 sizeof(bnx_xi_rv2p_proc2
), RV2P_PROC2
);
2642 /* Initialize the RX Processor. */
2643 cpu_reg
.mode
= BNX_RXP_CPU_MODE
;
2644 cpu_reg
.mode_value_halt
= BNX_RXP_CPU_MODE_SOFT_HALT
;
2645 cpu_reg
.mode_value_sstep
= BNX_RXP_CPU_MODE_STEP_ENA
;
2646 cpu_reg
.state
= BNX_RXP_CPU_STATE
;
2647 cpu_reg
.state_value_clear
= 0xffffff;
2648 cpu_reg
.gpr0
= BNX_RXP_CPU_REG_FILE
;
2649 cpu_reg
.evmask
= BNX_RXP_CPU_EVENT_MASK
;
2650 cpu_reg
.pc
= BNX_RXP_CPU_PROGRAM_COUNTER
;
2651 cpu_reg
.inst
= BNX_RXP_CPU_INSTRUCTION
;
2652 cpu_reg
.bp
= BNX_RXP_CPU_HW_BREAKPOINT
;
2653 cpu_reg
.spad_base
= BNX_RXP_SCRATCH
;
2654 cpu_reg
.mips_view_base
= 0x8000000;
2656 fw
.ver_major
= bnx_RXP_b09FwReleaseMajor
;
2657 fw
.ver_minor
= bnx_RXP_b09FwReleaseMinor
;
2658 fw
.ver_fix
= bnx_RXP_b09FwReleaseFix
;
2659 fw
.start_addr
= bnx_RXP_b09FwStartAddr
;
2661 fw
.text_addr
= bnx_RXP_b09FwTextAddr
;
2662 fw
.text_len
= bnx_RXP_b09FwTextLen
;
2664 fw
.text
= bnx_RXP_b09FwText
;
2666 fw
.data_addr
= bnx_RXP_b09FwDataAddr
;
2667 fw
.data_len
= bnx_RXP_b09FwDataLen
;
2669 fw
.data
= bnx_RXP_b09FwData
;
2671 fw
.sbss_addr
= bnx_RXP_b09FwSbssAddr
;
2672 fw
.sbss_len
= bnx_RXP_b09FwSbssLen
;
2674 fw
.sbss
= bnx_RXP_b09FwSbss
;
2676 fw
.bss_addr
= bnx_RXP_b09FwBssAddr
;
2677 fw
.bss_len
= bnx_RXP_b09FwBssLen
;
2679 fw
.bss
= bnx_RXP_b09FwBss
;
2681 fw
.rodata_addr
= bnx_RXP_b09FwRodataAddr
;
2682 fw
.rodata_len
= bnx_RXP_b09FwRodataLen
;
2683 fw
.rodata_index
= 0;
2684 fw
.rodata
= bnx_RXP_b09FwRodata
;
2686 DBPRINT(sc
, BNX_INFO_RESET
, "Loading RX firmware.\n");
2687 bnx_load_cpu_fw(sc
, &cpu_reg
, &fw
);
2689 /* Initialize the TX Processor. */
2690 cpu_reg
.mode
= BNX_TXP_CPU_MODE
;
2691 cpu_reg
.mode_value_halt
= BNX_TXP_CPU_MODE_SOFT_HALT
;
2692 cpu_reg
.mode_value_sstep
= BNX_TXP_CPU_MODE_STEP_ENA
;
2693 cpu_reg
.state
= BNX_TXP_CPU_STATE
;
2694 cpu_reg
.state_value_clear
= 0xffffff;
2695 cpu_reg
.gpr0
= BNX_TXP_CPU_REG_FILE
;
2696 cpu_reg
.evmask
= BNX_TXP_CPU_EVENT_MASK
;
2697 cpu_reg
.pc
= BNX_TXP_CPU_PROGRAM_COUNTER
;
2698 cpu_reg
.inst
= BNX_TXP_CPU_INSTRUCTION
;
2699 cpu_reg
.bp
= BNX_TXP_CPU_HW_BREAKPOINT
;
2700 cpu_reg
.spad_base
= BNX_TXP_SCRATCH
;
2701 cpu_reg
.mips_view_base
= 0x8000000;
2703 fw
.ver_major
= bnx_TXP_b09FwReleaseMajor
;
2704 fw
.ver_minor
= bnx_TXP_b09FwReleaseMinor
;
2705 fw
.ver_fix
= bnx_TXP_b09FwReleaseFix
;
2706 fw
.start_addr
= bnx_TXP_b09FwStartAddr
;
2708 fw
.text_addr
= bnx_TXP_b09FwTextAddr
;
2709 fw
.text_len
= bnx_TXP_b09FwTextLen
;
2711 fw
.text
= bnx_TXP_b09FwText
;
2713 fw
.data_addr
= bnx_TXP_b09FwDataAddr
;
2714 fw
.data_len
= bnx_TXP_b09FwDataLen
;
2716 fw
.data
= bnx_TXP_b09FwData
;
2718 fw
.sbss_addr
= bnx_TXP_b09FwSbssAddr
;
2719 fw
.sbss_len
= bnx_TXP_b09FwSbssLen
;
2721 fw
.sbss
= bnx_TXP_b09FwSbss
;
2723 fw
.bss_addr
= bnx_TXP_b09FwBssAddr
;
2724 fw
.bss_len
= bnx_TXP_b09FwBssLen
;
2726 fw
.bss
= bnx_TXP_b09FwBss
;
2728 fw
.rodata_addr
= bnx_TXP_b09FwRodataAddr
;
2729 fw
.rodata_len
= bnx_TXP_b09FwRodataLen
;
2730 fw
.rodata_index
= 0;
2731 fw
.rodata
= bnx_TXP_b09FwRodata
;
2733 DBPRINT(sc
, BNX_INFO_RESET
, "Loading TX firmware.\n");
2734 bnx_load_cpu_fw(sc
, &cpu_reg
, &fw
);
2736 /* Initialize the TX Patch-up Processor. */
2737 cpu_reg
.mode
= BNX_TPAT_CPU_MODE
;
2738 cpu_reg
.mode_value_halt
= BNX_TPAT_CPU_MODE_SOFT_HALT
;
2739 cpu_reg
.mode_value_sstep
= BNX_TPAT_CPU_MODE_STEP_ENA
;
2740 cpu_reg
.state
= BNX_TPAT_CPU_STATE
;
2741 cpu_reg
.state_value_clear
= 0xffffff;
2742 cpu_reg
.gpr0
= BNX_TPAT_CPU_REG_FILE
;
2743 cpu_reg
.evmask
= BNX_TPAT_CPU_EVENT_MASK
;
2744 cpu_reg
.pc
= BNX_TPAT_CPU_PROGRAM_COUNTER
;
2745 cpu_reg
.inst
= BNX_TPAT_CPU_INSTRUCTION
;
2746 cpu_reg
.bp
= BNX_TPAT_CPU_HW_BREAKPOINT
;
2747 cpu_reg
.spad_base
= BNX_TPAT_SCRATCH
;
2748 cpu_reg
.mips_view_base
= 0x8000000;
2750 fw
.ver_major
= bnx_TPAT_b09FwReleaseMajor
;
2751 fw
.ver_minor
= bnx_TPAT_b09FwReleaseMinor
;
2752 fw
.ver_fix
= bnx_TPAT_b09FwReleaseFix
;
2753 fw
.start_addr
= bnx_TPAT_b09FwStartAddr
;
2755 fw
.text_addr
= bnx_TPAT_b09FwTextAddr
;
2756 fw
.text_len
= bnx_TPAT_b09FwTextLen
;
2758 fw
.text
= bnx_TPAT_b09FwText
;
2760 fw
.data_addr
= bnx_TPAT_b09FwDataAddr
;
2761 fw
.data_len
= bnx_TPAT_b09FwDataLen
;
2763 fw
.data
= bnx_TPAT_b09FwData
;
2765 fw
.sbss_addr
= bnx_TPAT_b09FwSbssAddr
;
2766 fw
.sbss_len
= bnx_TPAT_b09FwSbssLen
;
2768 fw
.sbss
= bnx_TPAT_b09FwSbss
;
2770 fw
.bss_addr
= bnx_TPAT_b09FwBssAddr
;
2771 fw
.bss_len
= bnx_TPAT_b09FwBssLen
;
2773 fw
.bss
= bnx_TPAT_b09FwBss
;
2775 fw
.rodata_addr
= bnx_TPAT_b09FwRodataAddr
;
2776 fw
.rodata_len
= bnx_TPAT_b09FwRodataLen
;
2777 fw
.rodata_index
= 0;
2778 fw
.rodata
= bnx_TPAT_b09FwRodata
;
2780 DBPRINT(sc
, BNX_INFO_RESET
, "Loading TPAT firmware.\n");
2781 bnx_load_cpu_fw(sc
, &cpu_reg
, &fw
);
2783 /* Initialize the Completion Processor. */
2784 cpu_reg
.mode
= BNX_COM_CPU_MODE
;
2785 cpu_reg
.mode_value_halt
= BNX_COM_CPU_MODE_SOFT_HALT
;
2786 cpu_reg
.mode_value_sstep
= BNX_COM_CPU_MODE_STEP_ENA
;
2787 cpu_reg
.state
= BNX_COM_CPU_STATE
;
2788 cpu_reg
.state_value_clear
= 0xffffff;
2789 cpu_reg
.gpr0
= BNX_COM_CPU_REG_FILE
;
2790 cpu_reg
.evmask
= BNX_COM_CPU_EVENT_MASK
;
2791 cpu_reg
.pc
= BNX_COM_CPU_PROGRAM_COUNTER
;
2792 cpu_reg
.inst
= BNX_COM_CPU_INSTRUCTION
;
2793 cpu_reg
.bp
= BNX_COM_CPU_HW_BREAKPOINT
;
2794 cpu_reg
.spad_base
= BNX_COM_SCRATCH
;
2795 cpu_reg
.mips_view_base
= 0x8000000;
2797 fw
.ver_major
= bnx_COM_b09FwReleaseMajor
;
2798 fw
.ver_minor
= bnx_COM_b09FwReleaseMinor
;
2799 fw
.ver_fix
= bnx_COM_b09FwReleaseFix
;
2800 fw
.start_addr
= bnx_COM_b09FwStartAddr
;
2802 fw
.text_addr
= bnx_COM_b09FwTextAddr
;
2803 fw
.text_len
= bnx_COM_b09FwTextLen
;
2805 fw
.text
= bnx_COM_b09FwText
;
2807 fw
.data_addr
= bnx_COM_b09FwDataAddr
;
2808 fw
.data_len
= bnx_COM_b09FwDataLen
;
2810 fw
.data
= bnx_COM_b09FwData
;
2812 fw
.sbss_addr
= bnx_COM_b09FwSbssAddr
;
2813 fw
.sbss_len
= bnx_COM_b09FwSbssLen
;
2815 fw
.sbss
= bnx_COM_b09FwSbss
;
2817 fw
.bss_addr
= bnx_COM_b09FwBssAddr
;
2818 fw
.bss_len
= bnx_COM_b09FwBssLen
;
2820 fw
.bss
= bnx_COM_b09FwBss
;
2822 fw
.rodata_addr
= bnx_COM_b09FwRodataAddr
;
2823 fw
.rodata_len
= bnx_COM_b09FwRodataLen
;
2824 fw
.rodata_index
= 0;
2825 fw
.rodata
= bnx_COM_b09FwRodata
;
2826 DBPRINT(sc
, BNX_INFO_RESET
, "Loading COM firmware.\n");
2827 bnx_load_cpu_fw(sc
, &cpu_reg
, &fw
);
2830 /* Initialize the RV2P processor. */
2831 bnx_load_rv2p_fw(sc
, bnx_rv2p_proc1
, sizeof(bnx_rv2p_proc1
),
2833 bnx_load_rv2p_fw(sc
, bnx_rv2p_proc2
, sizeof(bnx_rv2p_proc2
),
2836 /* Initialize the RX Processor. */
2837 cpu_reg
.mode
= BNX_RXP_CPU_MODE
;
2838 cpu_reg
.mode_value_halt
= BNX_RXP_CPU_MODE_SOFT_HALT
;
2839 cpu_reg
.mode_value_sstep
= BNX_RXP_CPU_MODE_STEP_ENA
;
2840 cpu_reg
.state
= BNX_RXP_CPU_STATE
;
2841 cpu_reg
.state_value_clear
= 0xffffff;
2842 cpu_reg
.gpr0
= BNX_RXP_CPU_REG_FILE
;
2843 cpu_reg
.evmask
= BNX_RXP_CPU_EVENT_MASK
;
2844 cpu_reg
.pc
= BNX_RXP_CPU_PROGRAM_COUNTER
;
2845 cpu_reg
.inst
= BNX_RXP_CPU_INSTRUCTION
;
2846 cpu_reg
.bp
= BNX_RXP_CPU_HW_BREAKPOINT
;
2847 cpu_reg
.spad_base
= BNX_RXP_SCRATCH
;
2848 cpu_reg
.mips_view_base
= 0x8000000;
2850 fw
.ver_major
= bnx_RXP_b06FwReleaseMajor
;
2851 fw
.ver_minor
= bnx_RXP_b06FwReleaseMinor
;
2852 fw
.ver_fix
= bnx_RXP_b06FwReleaseFix
;
2853 fw
.start_addr
= bnx_RXP_b06FwStartAddr
;
2855 fw
.text_addr
= bnx_RXP_b06FwTextAddr
;
2856 fw
.text_len
= bnx_RXP_b06FwTextLen
;
2858 fw
.text
= bnx_RXP_b06FwText
;
2860 fw
.data_addr
= bnx_RXP_b06FwDataAddr
;
2861 fw
.data_len
= bnx_RXP_b06FwDataLen
;
2863 fw
.data
= bnx_RXP_b06FwData
;
2865 fw
.sbss_addr
= bnx_RXP_b06FwSbssAddr
;
2866 fw
.sbss_len
= bnx_RXP_b06FwSbssLen
;
2868 fw
.sbss
= bnx_RXP_b06FwSbss
;
2870 fw
.bss_addr
= bnx_RXP_b06FwBssAddr
;
2871 fw
.bss_len
= bnx_RXP_b06FwBssLen
;
2873 fw
.bss
= bnx_RXP_b06FwBss
;
2875 fw
.rodata_addr
= bnx_RXP_b06FwRodataAddr
;
2876 fw
.rodata_len
= bnx_RXP_b06FwRodataLen
;
2877 fw
.rodata_index
= 0;
2878 fw
.rodata
= bnx_RXP_b06FwRodata
;
2880 DBPRINT(sc
, BNX_INFO_RESET
, "Loading RX firmware.\n");
2881 bnx_load_cpu_fw(sc
, &cpu_reg
, &fw
);
2883 /* Initialize the TX Processor. */
2884 cpu_reg
.mode
= BNX_TXP_CPU_MODE
;
2885 cpu_reg
.mode_value_halt
= BNX_TXP_CPU_MODE_SOFT_HALT
;
2886 cpu_reg
.mode_value_sstep
= BNX_TXP_CPU_MODE_STEP_ENA
;
2887 cpu_reg
.state
= BNX_TXP_CPU_STATE
;
2888 cpu_reg
.state_value_clear
= 0xffffff;
2889 cpu_reg
.gpr0
= BNX_TXP_CPU_REG_FILE
;
2890 cpu_reg
.evmask
= BNX_TXP_CPU_EVENT_MASK
;
2891 cpu_reg
.pc
= BNX_TXP_CPU_PROGRAM_COUNTER
;
2892 cpu_reg
.inst
= BNX_TXP_CPU_INSTRUCTION
;
2893 cpu_reg
.bp
= BNX_TXP_CPU_HW_BREAKPOINT
;
2894 cpu_reg
.spad_base
= BNX_TXP_SCRATCH
;
2895 cpu_reg
.mips_view_base
= 0x8000000;
2897 fw
.ver_major
= bnx_TXP_b06FwReleaseMajor
;
2898 fw
.ver_minor
= bnx_TXP_b06FwReleaseMinor
;
2899 fw
.ver_fix
= bnx_TXP_b06FwReleaseFix
;
2900 fw
.start_addr
= bnx_TXP_b06FwStartAddr
;
2902 fw
.text_addr
= bnx_TXP_b06FwTextAddr
;
2903 fw
.text_len
= bnx_TXP_b06FwTextLen
;
2905 fw
.text
= bnx_TXP_b06FwText
;
2907 fw
.data_addr
= bnx_TXP_b06FwDataAddr
;
2908 fw
.data_len
= bnx_TXP_b06FwDataLen
;
2910 fw
.data
= bnx_TXP_b06FwData
;
2912 fw
.sbss_addr
= bnx_TXP_b06FwSbssAddr
;
2913 fw
.sbss_len
= bnx_TXP_b06FwSbssLen
;
2915 fw
.sbss
= bnx_TXP_b06FwSbss
;
2917 fw
.bss_addr
= bnx_TXP_b06FwBssAddr
;
2918 fw
.bss_len
= bnx_TXP_b06FwBssLen
;
2920 fw
.bss
= bnx_TXP_b06FwBss
;
2922 fw
.rodata_addr
= bnx_TXP_b06FwRodataAddr
;
2923 fw
.rodata_len
= bnx_TXP_b06FwRodataLen
;
2924 fw
.rodata_index
= 0;
2925 fw
.rodata
= bnx_TXP_b06FwRodata
;
2927 DBPRINT(sc
, BNX_INFO_RESET
, "Loading TX firmware.\n");
2928 bnx_load_cpu_fw(sc
, &cpu_reg
, &fw
);
2930 /* Initialize the TX Patch-up Processor. */
2931 cpu_reg
.mode
= BNX_TPAT_CPU_MODE
;
2932 cpu_reg
.mode_value_halt
= BNX_TPAT_CPU_MODE_SOFT_HALT
;
2933 cpu_reg
.mode_value_sstep
= BNX_TPAT_CPU_MODE_STEP_ENA
;
2934 cpu_reg
.state
= BNX_TPAT_CPU_STATE
;
2935 cpu_reg
.state_value_clear
= 0xffffff;
2936 cpu_reg
.gpr0
= BNX_TPAT_CPU_REG_FILE
;
2937 cpu_reg
.evmask
= BNX_TPAT_CPU_EVENT_MASK
;
2938 cpu_reg
.pc
= BNX_TPAT_CPU_PROGRAM_COUNTER
;
2939 cpu_reg
.inst
= BNX_TPAT_CPU_INSTRUCTION
;
2940 cpu_reg
.bp
= BNX_TPAT_CPU_HW_BREAKPOINT
;
2941 cpu_reg
.spad_base
= BNX_TPAT_SCRATCH
;
2942 cpu_reg
.mips_view_base
= 0x8000000;
2944 fw
.ver_major
= bnx_TPAT_b06FwReleaseMajor
;
2945 fw
.ver_minor
= bnx_TPAT_b06FwReleaseMinor
;
2946 fw
.ver_fix
= bnx_TPAT_b06FwReleaseFix
;
2947 fw
.start_addr
= bnx_TPAT_b06FwStartAddr
;
2949 fw
.text_addr
= bnx_TPAT_b06FwTextAddr
;
2950 fw
.text_len
= bnx_TPAT_b06FwTextLen
;
2952 fw
.text
= bnx_TPAT_b06FwText
;
2954 fw
.data_addr
= bnx_TPAT_b06FwDataAddr
;
2955 fw
.data_len
= bnx_TPAT_b06FwDataLen
;
2957 fw
.data
= bnx_TPAT_b06FwData
;
2959 fw
.sbss_addr
= bnx_TPAT_b06FwSbssAddr
;
2960 fw
.sbss_len
= bnx_TPAT_b06FwSbssLen
;
2962 fw
.sbss
= bnx_TPAT_b06FwSbss
;
2964 fw
.bss_addr
= bnx_TPAT_b06FwBssAddr
;
2965 fw
.bss_len
= bnx_TPAT_b06FwBssLen
;
2967 fw
.bss
= bnx_TPAT_b06FwBss
;
2969 fw
.rodata_addr
= bnx_TPAT_b06FwRodataAddr
;
2970 fw
.rodata_len
= bnx_TPAT_b06FwRodataLen
;
2971 fw
.rodata_index
= 0;
2972 fw
.rodata
= bnx_TPAT_b06FwRodata
;
2974 DBPRINT(sc
, BNX_INFO_RESET
, "Loading TPAT firmware.\n");
2975 bnx_load_cpu_fw(sc
, &cpu_reg
, &fw
);
2977 /* Initialize the Completion Processor. */
2978 cpu_reg
.mode
= BNX_COM_CPU_MODE
;
2979 cpu_reg
.mode_value_halt
= BNX_COM_CPU_MODE_SOFT_HALT
;
2980 cpu_reg
.mode_value_sstep
= BNX_COM_CPU_MODE_STEP_ENA
;
2981 cpu_reg
.state
= BNX_COM_CPU_STATE
;
2982 cpu_reg
.state_value_clear
= 0xffffff;
2983 cpu_reg
.gpr0
= BNX_COM_CPU_REG_FILE
;
2984 cpu_reg
.evmask
= BNX_COM_CPU_EVENT_MASK
;
2985 cpu_reg
.pc
= BNX_COM_CPU_PROGRAM_COUNTER
;
2986 cpu_reg
.inst
= BNX_COM_CPU_INSTRUCTION
;
2987 cpu_reg
.bp
= BNX_COM_CPU_HW_BREAKPOINT
;
2988 cpu_reg
.spad_base
= BNX_COM_SCRATCH
;
2989 cpu_reg
.mips_view_base
= 0x8000000;
2991 fw
.ver_major
= bnx_COM_b06FwReleaseMajor
;
2992 fw
.ver_minor
= bnx_COM_b06FwReleaseMinor
;
2993 fw
.ver_fix
= bnx_COM_b06FwReleaseFix
;
2994 fw
.start_addr
= bnx_COM_b06FwStartAddr
;
2996 fw
.text_addr
= bnx_COM_b06FwTextAddr
;
2997 fw
.text_len
= bnx_COM_b06FwTextLen
;
2999 fw
.text
= bnx_COM_b06FwText
;
3001 fw
.data_addr
= bnx_COM_b06FwDataAddr
;
3002 fw
.data_len
= bnx_COM_b06FwDataLen
;
3004 fw
.data
= bnx_COM_b06FwData
;
3006 fw
.sbss_addr
= bnx_COM_b06FwSbssAddr
;
3007 fw
.sbss_len
= bnx_COM_b06FwSbssLen
;
3009 fw
.sbss
= bnx_COM_b06FwSbss
;
3011 fw
.bss_addr
= bnx_COM_b06FwBssAddr
;
3012 fw
.bss_len
= bnx_COM_b06FwBssLen
;
3014 fw
.bss
= bnx_COM_b06FwBss
;
3016 fw
.rodata_addr
= bnx_COM_b06FwRodataAddr
;
3017 fw
.rodata_len
= bnx_COM_b06FwRodataLen
;
3018 fw
.rodata_index
= 0;
3019 fw
.rodata
= bnx_COM_b06FwRodata
;
3020 DBPRINT(sc
, BNX_INFO_RESET
, "Loading COM firmware.\n");
3021 bnx_load_cpu_fw(sc
, &cpu_reg
, &fw
);
3026 /****************************************************************************/
3027 /* Initialize context memory. */
3029 /* Clears the memory associated with each Context ID (CID). */
3033 /****************************************************************************/
3035 bnx_init_context(struct bnx_softc
*sc
)
3037 if (BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5709
) {
3038 /* DRC: Replace this constant value with a #define. */
3039 int i
, retry_cnt
= 10;
3043 * BCM5709 context memory may be cached
3044 * in host memory so prepare the host memory
3047 val
= BNX_CTX_COMMAND_ENABLED
| BNX_CTX_COMMAND_MEM_INIT
3049 val
|= (BCM_PAGE_BITS
- 8) << 16;
3050 REG_WR(sc
, BNX_CTX_COMMAND
, val
);
3052 /* Wait for mem init command to complete. */
3053 for (i
= 0; i
< retry_cnt
; i
++) {
3054 val
= REG_RD(sc
, BNX_CTX_COMMAND
);
3055 if (!(val
& BNX_CTX_COMMAND_MEM_INIT
))
3061 /* ToDo: Consider returning an error here. */
3063 for (i
= 0; i
< sc
->ctx_pages
; i
++) {
3067 /* Set the physaddr of the context memory cache. */
3068 val
= (u_int32_t
)(sc
->ctx_segs
[i
].ds_addr
);
3069 REG_WR(sc
, BNX_CTX_HOST_PAGE_TBL_DATA0
, val
|
3070 BNX_CTX_HOST_PAGE_TBL_DATA0_VALID
);
3072 ((u_int64_t
)sc
->ctx_segs
[i
].ds_addr
>> 32);
3073 REG_WR(sc
, BNX_CTX_HOST_PAGE_TBL_DATA1
, val
);
3074 REG_WR(sc
, BNX_CTX_HOST_PAGE_TBL_CTRL
, i
|
3075 BNX_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ
);
3078 /* Verify that the context memory write was successful. */
3079 for (j
= 0; j
< retry_cnt
; j
++) {
3080 val
= REG_RD(sc
, BNX_CTX_HOST_PAGE_TBL_CTRL
);
3081 if ((val
& BNX_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ
) == 0)
3086 /* ToDo: Consider returning an error here. */
3089 u_int32_t vcid_addr
, offset
;
3092 * For the 5706/5708, context memory is local to
3093 * the controller, so initialize the controller
3097 vcid_addr
= GET_CID_ADDR(96);
3100 vcid_addr
-= PHY_CTX_SIZE
;
3102 REG_WR(sc
, BNX_CTX_VIRT_ADDR
, 0);
3103 REG_WR(sc
, BNX_CTX_PAGE_TBL
, vcid_addr
);
3105 for(offset
= 0; offset
< PHY_CTX_SIZE
; offset
+= 4) {
3106 CTX_WR(sc
, 0x00, offset
, 0);
3109 REG_WR(sc
, BNX_CTX_VIRT_ADDR
, vcid_addr
);
3110 REG_WR(sc
, BNX_CTX_PAGE_TBL
, vcid_addr
);
3115 /****************************************************************************/
3116 /* Fetch the permanent MAC address of the controller. */
3120 /****************************************************************************/
3122 bnx_get_mac_addr(struct bnx_softc
*sc
)
3124 u_int32_t mac_lo
= 0, mac_hi
= 0;
3127 * The NetXtreme II bootcode populates various NIC
3128 * power-on and runtime configuration items in a
3129 * shared memory area. The factory configured MAC
3130 * address is available from both NVRAM and the
3131 * shared memory area so we'll read the value from
3132 * shared memory for speed.
3135 mac_hi
= REG_RD_IND(sc
, sc
->bnx_shmem_base
+ BNX_PORT_HW_CFG_MAC_UPPER
);
3136 mac_lo
= REG_RD_IND(sc
, sc
->bnx_shmem_base
+ BNX_PORT_HW_CFG_MAC_LOWER
);
3138 if ((mac_lo
== 0) && (mac_hi
== 0)) {
3139 BNX_PRINTF(sc
, "%s(%d): Invalid Ethernet address!\n",
3140 __FILE__
, __LINE__
);
3142 sc
->eaddr
[0] = (u_char
)(mac_hi
>> 8);
3143 sc
->eaddr
[1] = (u_char
)(mac_hi
>> 0);
3144 sc
->eaddr
[2] = (u_char
)(mac_lo
>> 24);
3145 sc
->eaddr
[3] = (u_char
)(mac_lo
>> 16);
3146 sc
->eaddr
[4] = (u_char
)(mac_lo
>> 8);
3147 sc
->eaddr
[5] = (u_char
)(mac_lo
>> 0);
3150 DBPRINT(sc
, BNX_INFO
, "Permanent Ethernet address = "
3151 "%s\n", ether_sprintf(sc
->eaddr
));
3154 /****************************************************************************/
3155 /* Program the MAC address. */
3159 /****************************************************************************/
3161 bnx_set_mac_addr(struct bnx_softc
*sc
)
3164 const u_int8_t
*mac_addr
= CLLADDR(sc
->bnx_ec
.ec_if
.if_sadl
);
3166 DBPRINT(sc
, BNX_INFO
, "Setting Ethernet address = "
3167 "%s\n", ether_sprintf(sc
->eaddr
));
3169 val
= (mac_addr
[0] << 8) | mac_addr
[1];
3171 REG_WR(sc
, BNX_EMAC_MAC_MATCH0
, val
);
3173 val
= (mac_addr
[2] << 24) | (mac_addr
[3] << 16) |
3174 (mac_addr
[4] << 8) | mac_addr
[5];
3176 REG_WR(sc
, BNX_EMAC_MAC_MATCH1
, val
);
3179 /****************************************************************************/
3180 /* Stop the controller. */
3184 /****************************************************************************/
3186 bnx_stop(struct ifnet
*ifp
, int disable
)
3188 struct bnx_softc
*sc
= ifp
->if_softc
;
3190 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Entering %s()\n", __func__
);
3192 if ((ifp
->if_flags
& IFF_RUNNING
) == 0)
3195 callout_stop(&sc
->bnx_timeout
);
3197 mii_down(&sc
->bnx_mii
);
3199 ifp
->if_flags
&= ~(IFF_RUNNING
| IFF_OACTIVE
);
3201 /* Disable the transmit/receive blocks. */
3202 REG_WR(sc
, BNX_MISC_ENABLE_CLR_BITS
, 0x5ffffff);
3203 REG_RD(sc
, BNX_MISC_ENABLE_CLR_BITS
);
3206 bnx_disable_intr(sc
);
3208 /* Tell firmware that the driver is going away. */
3210 bnx_reset(sc
, BNX_DRV_MSG_CODE_RESET
);
3212 bnx_reset(sc
, BNX_DRV_MSG_CODE_SUSPEND_NO_WOL
);
3214 /* Free RX buffers. */
3215 bnx_free_rx_chain(sc
);
3217 /* Free TX buffers. */
3218 bnx_free_tx_chain(sc
);
3222 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Exiting %s()\n", __func__
);
3227 bnx_reset(struct bnx_softc
*sc
, u_int32_t reset_code
)
3229 struct pci_attach_args
*pa
= &(sc
->bnx_pa
);
3233 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Entering %s()\n", __func__
);
3235 /* Wait for pending PCI transactions to complete. */
3236 REG_WR(sc
, BNX_MISC_ENABLE_CLR_BITS
,
3237 BNX_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE
|
3238 BNX_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE
|
3239 BNX_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE
|
3240 BNX_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE
);
3241 val
= REG_RD(sc
, BNX_MISC_ENABLE_CLR_BITS
);
3245 if (BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5709
) {
3246 val
= REG_RD(sc
, BNX_MISC_NEW_CORE_CTL
);
3247 val
&= ~BNX_MISC_NEW_CORE_CTL_DMA_ENABLE
;
3248 REG_WR(sc
, BNX_MISC_NEW_CORE_CTL
, val
);
3251 /* Assume bootcode is running. */
3252 sc
->bnx_fw_timed_out
= 0;
3254 /* Give the firmware a chance to prepare for the reset. */
3255 rc
= bnx_fw_sync(sc
, BNX_DRV_MSG_DATA_WAIT0
| reset_code
);
3257 goto bnx_reset_exit
;
3259 /* Set a firmware reminder that this is a soft reset. */
3260 REG_WR_IND(sc
, sc
->bnx_shmem_base
+ BNX_DRV_RESET_SIGNATURE
,
3261 BNX_DRV_RESET_SIGNATURE_MAGIC
);
3263 /* Dummy read to force the chip to complete all current transactions. */
3264 val
= REG_RD(sc
, BNX_MISC_ID
);
3267 if (BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5709
) {
3268 REG_WR(sc
, BNX_MISC_COMMAND
, BNX_MISC_COMMAND_SW_RESET
);
3269 REG_RD(sc
, BNX_MISC_COMMAND
);
3272 val
= BNX_PCICFG_MISC_CONFIG_REG_WINDOW_ENA
|
3273 BNX_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP
;
3275 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
, BNX_PCICFG_MISC_CONFIG
,
3278 val
= BNX_PCICFG_MISC_CONFIG_CORE_RST_REQ
|
3279 BNX_PCICFG_MISC_CONFIG_REG_WINDOW_ENA
|
3280 BNX_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP
;
3281 REG_WR(sc
, BNX_PCICFG_MISC_CONFIG
, val
);
3283 /* Allow up to 30us for reset to complete. */
3284 for (i
= 0; i
< 10; i
++) {
3285 val
= REG_RD(sc
, BNX_PCICFG_MISC_CONFIG
);
3286 if ((val
& (BNX_PCICFG_MISC_CONFIG_CORE_RST_REQ
|
3287 BNX_PCICFG_MISC_CONFIG_CORE_RST_BSY
)) == 0) {
3293 /* Check that reset completed successfully. */
3294 if (val
& (BNX_PCICFG_MISC_CONFIG_CORE_RST_REQ
|
3295 BNX_PCICFG_MISC_CONFIG_CORE_RST_BSY
)) {
3296 BNX_PRINTF(sc
, "%s(%d): Reset failed!\n",
3297 __FILE__
, __LINE__
);
3299 goto bnx_reset_exit
;
3303 /* Make sure byte swapping is properly configured. */
3304 val
= REG_RD(sc
, BNX_PCI_SWAP_DIAG0
);
3305 if (val
!= 0x01020304) {
3306 BNX_PRINTF(sc
, "%s(%d): Byte swap is incorrect!\n",
3307 __FILE__
, __LINE__
);
3309 goto bnx_reset_exit
;
3312 /* Just completed a reset, assume that firmware is running again. */
3313 sc
->bnx_fw_timed_out
= 0;
3315 /* Wait for the firmware to finish its initialization. */
3316 rc
= bnx_fw_sync(sc
, BNX_DRV_MSG_DATA_WAIT1
| reset_code
);
3318 BNX_PRINTF(sc
, "%s(%d): Firmware did not complete "
3319 "initialization!\n", __FILE__
, __LINE__
);
3322 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Exiting %s()\n", __func__
);
3328 bnx_chipinit(struct bnx_softc
*sc
)
3330 struct pci_attach_args
*pa
= &(sc
->bnx_pa
);
3334 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Entering %s()\n", __func__
);
3336 /* Make sure the interrupt is not active. */
3337 REG_WR(sc
, BNX_PCICFG_INT_ACK_CMD
, BNX_PCICFG_INT_ACK_CMD_MASK_INT
);
3339 /* Initialize DMA byte/word swapping, configure the number of DMA */
3340 /* channels and PCI clock compensation delay. */
3341 val
= BNX_DMA_CONFIG_DATA_BYTE_SWAP
|
3342 BNX_DMA_CONFIG_DATA_WORD_SWAP
|
3343 #if BYTE_ORDER == BIG_ENDIAN
3344 BNX_DMA_CONFIG_CNTL_BYTE_SWAP
|
3346 BNX_DMA_CONFIG_CNTL_WORD_SWAP
|
3347 DMA_READ_CHANS
<< 12 |
3348 DMA_WRITE_CHANS
<< 16;
3350 val
|= (0x2 << 20) | BNX_DMA_CONFIG_CNTL_PCI_COMP_DLY
;
3352 if ((sc
->bnx_flags
& BNX_PCIX_FLAG
) && (sc
->bus_speed_mhz
== 133))
3353 val
|= BNX_DMA_CONFIG_PCI_FAST_CLK_CMP
;
3356 * This setting resolves a problem observed on certain Intel PCI
3357 * chipsets that cannot handle multiple outstanding DMA operations.
3358 * See errata E9_5706A1_65.
3360 if ((BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5706
) &&
3361 (BNX_CHIP_ID(sc
) != BNX_CHIP_ID_5706_A0
) &&
3362 !(sc
->bnx_flags
& BNX_PCIX_FLAG
))
3363 val
|= BNX_DMA_CONFIG_CNTL_PING_PONG_DMA
;
3365 REG_WR(sc
, BNX_DMA_CONFIG
, val
);
3367 /* Clear the PCI-X relaxed ordering bit. See errata E3_5708CA0_570. */
3368 if (sc
->bnx_flags
& BNX_PCIX_FLAG
) {
3369 val
= pci_conf_read(pa
->pa_pc
, pa
->pa_tag
, BNX_PCI_PCIX_CMD
);
3370 pci_conf_write(pa
->pa_pc
, pa
->pa_tag
, BNX_PCI_PCIX_CMD
,
3374 /* Enable the RX_V2P and Context state machines before access. */
3375 REG_WR(sc
, BNX_MISC_ENABLE_SET_BITS
,
3376 BNX_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE
|
3377 BNX_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE
|
3378 BNX_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE
);
3380 /* Initialize context mapping and zero out the quick contexts. */
3381 bnx_init_context(sc
);
3383 /* Initialize the on-boards CPUs */
3386 /* Prepare NVRAM for access. */
3387 if (bnx_init_nvram(sc
)) {
3389 goto bnx_chipinit_exit
;
3392 /* Set the kernel bypass block size */
3393 val
= REG_RD(sc
, BNX_MQ_CONFIG
);
3394 val
&= ~BNX_MQ_CONFIG_KNL_BYP_BLK_SIZE
;
3395 val
|= BNX_MQ_CONFIG_KNL_BYP_BLK_SIZE_256
;
3397 /* Enable bins used on the 5709. */
3398 if (BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5709
) {
3399 val
|= BNX_MQ_CONFIG_BIN_MQ_MODE
;
3400 if (BNX_CHIP_ID(sc
) == BNX_CHIP_ID_5709_A1
)
3401 val
|= BNX_MQ_CONFIG_HALT_DIS
;
3404 REG_WR(sc
, BNX_MQ_CONFIG
, val
);
3406 val
= 0x10000 + (MAX_CID_CNT
* MB_KERNEL_CTX_SIZE
);
3407 REG_WR(sc
, BNX_MQ_KNL_BYP_WIND_START
, val
);
3408 REG_WR(sc
, BNX_MQ_KNL_WIND_END
, val
);
3410 val
= (BCM_PAGE_BITS
- 8) << 24;
3411 REG_WR(sc
, BNX_RV2P_CONFIG
, val
);
3413 /* Configure page size. */
3414 val
= REG_RD(sc
, BNX_TBDR_CONFIG
);
3415 val
&= ~BNX_TBDR_CONFIG_PAGE_SIZE
;
3416 val
|= (BCM_PAGE_BITS
- 8) << 24 | 0x40;
3417 REG_WR(sc
, BNX_TBDR_CONFIG
, val
);
3420 /* Set the perfect match control register to default. */
3421 REG_WR_IND(sc
, BNX_RXP_PM_CTRL
, 0);
3425 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Exiting %s()\n", __func__
);
3430 /****************************************************************************/
3431 /* Initialize the controller in preparation to send/receive traffic. */
3434 /* 0 for success, positive value for failure. */
3435 /****************************************************************************/
3437 bnx_blockinit(struct bnx_softc
*sc
)
3442 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Entering %s()\n", __func__
);
3444 /* Load the hardware default MAC address. */
3445 bnx_set_mac_addr(sc
);
3447 /* Set the Ethernet backoff seed value */
3448 val
= sc
->eaddr
[0] + (sc
->eaddr
[1] << 8) + (sc
->eaddr
[2] << 16) +
3449 (sc
->eaddr
[3]) + (sc
->eaddr
[4] << 8) + (sc
->eaddr
[5] << 16);
3450 REG_WR(sc
, BNX_EMAC_BACKOFF_SEED
, val
);
3452 sc
->last_status_idx
= 0;
3453 sc
->rx_mode
= BNX_EMAC_RX_MODE_SORT_MODE
;
3455 /* Set up link change interrupt generation. */
3456 REG_WR(sc
, BNX_EMAC_ATTENTION_ENA
, BNX_EMAC_ATTENTION_ENA_LINK
);
3457 REG_WR(sc
, BNX_HC_ATTN_BITS_ENABLE
, STATUS_ATTN_BITS_LINK_STATE
);
3459 /* Program the physical address of the status block. */
3460 REG_WR(sc
, BNX_HC_STATUS_ADDR_L
, (u_int32_t
)(sc
->status_block_paddr
));
3461 REG_WR(sc
, BNX_HC_STATUS_ADDR_H
,
3462 (u_int32_t
)((u_int64_t
)sc
->status_block_paddr
>> 32));
3464 /* Program the physical address of the statistics block. */
3465 REG_WR(sc
, BNX_HC_STATISTICS_ADDR_L
,
3466 (u_int32_t
)(sc
->stats_block_paddr
));
3467 REG_WR(sc
, BNX_HC_STATISTICS_ADDR_H
,
3468 (u_int32_t
)((u_int64_t
)sc
->stats_block_paddr
>> 32));
3470 /* Program various host coalescing parameters. */
3471 REG_WR(sc
, BNX_HC_TX_QUICK_CONS_TRIP
, (sc
->bnx_tx_quick_cons_trip_int
3472 << 16) | sc
->bnx_tx_quick_cons_trip
);
3473 REG_WR(sc
, BNX_HC_RX_QUICK_CONS_TRIP
, (sc
->bnx_rx_quick_cons_trip_int
3474 << 16) | sc
->bnx_rx_quick_cons_trip
);
3475 REG_WR(sc
, BNX_HC_COMP_PROD_TRIP
, (sc
->bnx_comp_prod_trip_int
<< 16) |
3476 sc
->bnx_comp_prod_trip
);
3477 REG_WR(sc
, BNX_HC_TX_TICKS
, (sc
->bnx_tx_ticks_int
<< 16) |
3479 REG_WR(sc
, BNX_HC_RX_TICKS
, (sc
->bnx_rx_ticks_int
<< 16) |
3481 REG_WR(sc
, BNX_HC_COM_TICKS
, (sc
->bnx_com_ticks_int
<< 16) |
3483 REG_WR(sc
, BNX_HC_CMD_TICKS
, (sc
->bnx_cmd_ticks_int
<< 16) |
3485 REG_WR(sc
, BNX_HC_STATS_TICKS
, (sc
->bnx_stats_ticks
& 0xffff00));
3486 REG_WR(sc
, BNX_HC_STAT_COLLECT_TICKS
, 0xbb8); /* 3ms */
3487 REG_WR(sc
, BNX_HC_CONFIG
,
3488 (BNX_HC_CONFIG_RX_TMR_MODE
| BNX_HC_CONFIG_TX_TMR_MODE
|
3489 BNX_HC_CONFIG_COLLECT_STATS
));
3491 /* Clear the internal statistics counters. */
3492 REG_WR(sc
, BNX_HC_COMMAND
, BNX_HC_COMMAND_CLR_STAT_NOW
);
3494 /* Verify that bootcode is running. */
3495 reg
= REG_RD_IND(sc
, sc
->bnx_shmem_base
+ BNX_DEV_INFO_SIGNATURE
);
3497 DBRUNIF(DB_RANDOMTRUE(bnx_debug_bootcode_running_failure
),
3498 BNX_PRINTF(sc
, "%s(%d): Simulating bootcode failure.\n",
3499 __FILE__
, __LINE__
); reg
= 0);
3501 if ((reg
& BNX_DEV_INFO_SIGNATURE_MAGIC_MASK
) !=
3502 BNX_DEV_INFO_SIGNATURE_MAGIC
) {
3503 BNX_PRINTF(sc
, "%s(%d): Bootcode not running! Found: 0x%08X, "
3504 "Expected: 08%08X\n", __FILE__
, __LINE__
,
3505 (reg
& BNX_DEV_INFO_SIGNATURE_MAGIC_MASK
),
3506 BNX_DEV_INFO_SIGNATURE_MAGIC
);
3508 goto bnx_blockinit_exit
;
3511 /* Check if any management firmware is running. */
3512 reg
= REG_RD_IND(sc
, sc
->bnx_shmem_base
+ BNX_PORT_FEATURE
);
3513 if (reg
& (BNX_PORT_FEATURE_ASF_ENABLED
|
3514 BNX_PORT_FEATURE_IMD_ENABLED
)) {
3515 DBPRINT(sc
, BNX_INFO
, "Management F/W Enabled.\n");
3516 sc
->bnx_flags
|= BNX_MFW_ENABLE_FLAG
;
3519 sc
->bnx_fw_ver
= REG_RD_IND(sc
, sc
->bnx_shmem_base
+
3520 BNX_DEV_INFO_BC_REV
);
3522 DBPRINT(sc
, BNX_INFO
, "bootcode rev = 0x%08X\n", sc
->bnx_fw_ver
);
3525 if (BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5709
) {
3526 val
= REG_RD(sc
, BNX_MISC_NEW_CORE_CTL
);
3527 val
|= BNX_MISC_NEW_CORE_CTL_DMA_ENABLE
;
3528 REG_WR(sc
, BNX_MISC_NEW_CORE_CTL
, val
);
3531 /* Allow bootcode to apply any additional fixes before enabling MAC. */
3532 rc
= bnx_fw_sync(sc
, BNX_DRV_MSG_DATA_WAIT2
| BNX_DRV_MSG_CODE_RESET
);
3534 /* Enable link state change interrupt generation. */
3535 if (BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5709
) {
3536 REG_WR(sc
, BNX_MISC_ENABLE_SET_BITS
,
3537 BNX_MISC_ENABLE_DEFAULT_XI
);
3539 REG_WR(sc
, BNX_MISC_ENABLE_SET_BITS
, BNX_MISC_ENABLE_DEFAULT
);
3541 /* Enable all remaining blocks in the MAC. */
3542 REG_WR(sc
, BNX_MISC_ENABLE_SET_BITS
, 0x5ffffff);
3543 REG_RD(sc
, BNX_MISC_ENABLE_SET_BITS
);
3547 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Exiting %s()\n", __func__
);
3553 bnx_add_buf(struct bnx_softc
*sc
, struct mbuf
*m_new
, u_int16_t
*prod
,
3554 u_int16_t
*chain_prod
, u_int32_t
*prod_bseq
)
3561 u_int16_t debug_chain_prod
= *chain_prod
;
3563 u_int16_t first_chain_prod
;
3565 m_new
->m_len
= m_new
->m_pkthdr
.len
= sc
->mbuf_alloc_size
;
3567 /* Map the mbuf cluster into device memory. */
3568 map
= sc
->rx_mbuf_map
[*chain_prod
];
3569 first_chain_prod
= *chain_prod
;
3570 if (bus_dmamap_load_mbuf(sc
->bnx_dmatag
, map
, m_new
, BUS_DMA_NOWAIT
)) {
3571 BNX_PRINTF(sc
, "%s(%d): Error mapping mbuf into RX chain!\n",
3572 __FILE__
, __LINE__
);
3576 DBRUNIF(1, sc
->rx_mbuf_alloc
--);
3580 /* Make sure there is room in the receive chain. */
3581 if (map
->dm_nsegs
> sc
->free_rx_bd
) {
3582 bus_dmamap_unload(sc
->bnx_dmatag
, map
);
3587 /* Track the distribution of buffer segments. */
3588 sc
->rx_mbuf_segs
[map
->dm_nsegs
]++;
3591 bus_dmamap_sync(sc
->bnx_dmatag
, map
, 0, map
->dm_mapsize
,
3592 BUS_DMASYNC_PREREAD
);
3594 /* Update some debug statistics counters */
3595 DBRUNIF((sc
->free_rx_bd
< sc
->rx_low_watermark
),
3596 sc
->rx_low_watermark
= sc
->free_rx_bd
);
3597 DBRUNIF((sc
->free_rx_bd
== sc
->max_rx_bd
), sc
->rx_empty_count
++);
3600 * Setup the rx_bd for the first segment
3602 rxbd
= &sc
->rx_bd_chain
[RX_PAGE(*chain_prod
)][RX_IDX(*chain_prod
)];
3604 addr
= (u_int32_t
)(map
->dm_segs
[0].ds_addr
);
3605 rxbd
->rx_bd_haddr_lo
= htole32(addr
);
3606 addr
= (u_int32_t
)((u_int64_t
)map
->dm_segs
[0].ds_addr
>> 32);
3607 rxbd
->rx_bd_haddr_hi
= htole32(addr
);
3608 rxbd
->rx_bd_len
= htole32(map
->dm_segs
[0].ds_len
);
3609 rxbd
->rx_bd_flags
= htole32(RX_BD_FLAGS_START
);
3610 *prod_bseq
+= map
->dm_segs
[0].ds_len
;
3611 bus_dmamap_sync(sc
->bnx_dmatag
,
3612 sc
->rx_bd_chain_map
[RX_PAGE(*chain_prod
)],
3613 sizeof(struct rx_bd
) * RX_IDX(*chain_prod
), sizeof(struct rx_bd
),
3614 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
3616 for (i
= 1; i
< map
->dm_nsegs
; i
++) {
3617 *prod
= NEXT_RX_BD(*prod
);
3618 *chain_prod
= RX_CHAIN_IDX(*prod
);
3621 &sc
->rx_bd_chain
[RX_PAGE(*chain_prod
)][RX_IDX(*chain_prod
)];
3623 addr
= (u_int32_t
)(map
->dm_segs
[i
].ds_addr
);
3624 rxbd
->rx_bd_haddr_lo
= htole32(addr
);
3625 addr
= (u_int32_t
)((u_int64_t
)map
->dm_segs
[i
].ds_addr
>> 32);
3626 rxbd
->rx_bd_haddr_hi
= htole32(addr
);
3627 rxbd
->rx_bd_len
= htole32(map
->dm_segs
[i
].ds_len
);
3628 rxbd
->rx_bd_flags
= 0;
3629 *prod_bseq
+= map
->dm_segs
[i
].ds_len
;
3630 bus_dmamap_sync(sc
->bnx_dmatag
,
3631 sc
->rx_bd_chain_map
[RX_PAGE(*chain_prod
)],
3632 sizeof(struct rx_bd
) * RX_IDX(*chain_prod
),
3633 sizeof(struct rx_bd
), BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
3636 rxbd
->rx_bd_flags
|= htole32(RX_BD_FLAGS_END
);
3637 bus_dmamap_sync(sc
->bnx_dmatag
,
3638 sc
->rx_bd_chain_map
[RX_PAGE(*chain_prod
)],
3639 sizeof(struct rx_bd
) * RX_IDX(*chain_prod
),
3640 sizeof(struct rx_bd
), BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
3643 * Save the mbuf, ajust the map pointer (swap map for first and
3644 * last rx_bd entry to that rx_mbuf_ptr and rx_mbuf_map matches)
3645 * and update counter.
3647 sc
->rx_mbuf_ptr
[*chain_prod
] = m_new
;
3648 sc
->rx_mbuf_map
[first_chain_prod
] = sc
->rx_mbuf_map
[*chain_prod
];
3649 sc
->rx_mbuf_map
[*chain_prod
] = map
;
3650 sc
->free_rx_bd
-= map
->dm_nsegs
;
3652 DBRUN(BNX_VERBOSE_RECV
, bnx_dump_rx_mbuf_chain(sc
, debug_chain_prod
,
3654 *prod
= NEXT_RX_BD(*prod
);
3655 *chain_prod
= RX_CHAIN_IDX(*prod
);
3660 /****************************************************************************/
3661 /* Encapsulate an mbuf cluster into the rx_bd chain. */
3663 /* The NetXtreme II can support Jumbo frames by using multiple rx_bd's. */
3664 /* This routine will map an mbuf cluster into 1 or more rx_bd's as */
3668 /* 0 for success, positive value for failure. */
3669 /****************************************************************************/
3671 bnx_get_buf(struct bnx_softc
*sc
, u_int16_t
*prod
,
3672 u_int16_t
*chain_prod
, u_int32_t
*prod_bseq
)
3674 struct mbuf
*m_new
= NULL
;
3676 u_int16_t min_free_bd
;
3678 DBPRINT(sc
, (BNX_VERBOSE_RESET
| BNX_VERBOSE_RECV
), "Entering %s()\n",
3681 /* Make sure the inputs are valid. */
3682 DBRUNIF((*chain_prod
> MAX_RX_BD
),
3683 aprint_error_dev(sc
->bnx_dev
,
3684 "RX producer out of range: 0x%04X > 0x%04X\n",
3685 *chain_prod
, (u_int16_t
)MAX_RX_BD
));
3687 DBPRINT(sc
, BNX_VERBOSE_RECV
, "%s(enter): prod = 0x%04X, chain_prod = "
3688 "0x%04X, prod_bseq = 0x%08X\n", __func__
, *prod
, *chain_prod
,
3691 /* try to get in as many mbufs as possible */
3692 if (sc
->mbuf_alloc_size
== MCLBYTES
)
3693 min_free_bd
= (MCLBYTES
+ PAGE_SIZE
- 1) / PAGE_SIZE
;
3695 min_free_bd
= (BNX_MAX_JUMBO_MRU
+ PAGE_SIZE
- 1) / PAGE_SIZE
;
3696 while (sc
->free_rx_bd
>= min_free_bd
) {
3697 /* Simulate an mbuf allocation failure. */
3698 DBRUNIF(DB_RANDOMTRUE(bnx_debug_mbuf_allocation_failure
),
3699 aprint_error_dev(sc
->bnx_dev
,
3700 "Simulating mbuf allocation failure.\n");
3701 sc
->mbuf_sim_alloc_failed
++;
3703 goto bnx_get_buf_exit
);
3705 /* This is a new mbuf allocation. */
3706 MGETHDR(m_new
, M_DONTWAIT
, MT_DATA
);
3707 if (m_new
== NULL
) {
3708 DBPRINT(sc
, BNX_WARN
,
3709 "%s(%d): RX mbuf header allocation failed!\n",
3710 __FILE__
, __LINE__
);
3712 sc
->mbuf_alloc_failed
++;
3715 goto bnx_get_buf_exit
;
3718 DBRUNIF(1, sc
->rx_mbuf_alloc
++);
3720 /* Simulate an mbuf cluster allocation failure. */
3721 DBRUNIF(DB_RANDOMTRUE(bnx_debug_mbuf_allocation_failure
),
3723 sc
->rx_mbuf_alloc
--;
3724 sc
->mbuf_alloc_failed
++;
3725 sc
->mbuf_sim_alloc_failed
++;
3727 goto bnx_get_buf_exit
);
3729 if (sc
->mbuf_alloc_size
== MCLBYTES
)
3730 MCLGET(m_new
, M_DONTWAIT
);
3732 MEXTMALLOC(m_new
, sc
->mbuf_alloc_size
,
3734 if (!(m_new
->m_flags
& M_EXT
)) {
3735 DBPRINT(sc
, BNX_WARN
,
3736 "%s(%d): RX mbuf chain allocation failed!\n",
3737 __FILE__
, __LINE__
);
3741 DBRUNIF(1, sc
->rx_mbuf_alloc
--);
3742 sc
->mbuf_alloc_failed
++;
3745 goto bnx_get_buf_exit
;
3748 rc
= bnx_add_buf(sc
, m_new
, prod
, chain_prod
, prod_bseq
);
3750 goto bnx_get_buf_exit
;
3754 DBPRINT(sc
, BNX_VERBOSE_RECV
, "%s(exit): prod = 0x%04X, chain_prod "
3755 "= 0x%04X, prod_bseq = 0x%08X\n", __func__
, *prod
,
3756 *chain_prod
, *prod_bseq
);
3758 DBPRINT(sc
, (BNX_VERBOSE_RESET
| BNX_VERBOSE_RECV
), "Exiting %s()\n",
3765 bnx_alloc_pkts(struct bnx_softc
*sc
)
3767 struct ifnet
*ifp
= &sc
->bnx_ec
.ec_if
;
3768 struct bnx_pkt
*pkt
;
3771 for (i
= 0; i
< 4; i
++) { /* magic! */
3772 pkt
= pool_get(bnx_tx_pool
, PR_NOWAIT
);
3776 if (bus_dmamap_create(sc
->bnx_dmatag
,
3777 MCLBYTES
* BNX_MAX_SEGMENTS
, USABLE_TX_BD
,
3778 MCLBYTES
, 0, BUS_DMA_NOWAIT
| BUS_DMA_ALLOCNOW
,
3779 &pkt
->pkt_dmamap
) != 0)
3782 if (!ISSET(ifp
->if_flags
, IFF_UP
))
3785 mutex_enter(&sc
->tx_pkt_mtx
);
3786 TAILQ_INSERT_TAIL(&sc
->tx_free_pkts
, pkt
, pkt_entry
);
3788 mutex_exit(&sc
->tx_pkt_mtx
);
3791 return (i
== 0) ? ENOMEM
: 0;
3794 bus_dmamap_destroy(sc
->bnx_dmatag
, pkt
->pkt_dmamap
);
3796 pool_put(bnx_tx_pool
, pkt
);
3797 return (i
== 0) ? ENOMEM
: 0;
3800 /****************************************************************************/
3801 /* Initialize the TX context memory. */
3805 /****************************************************************************/
3807 bnx_init_tx_context(struct bnx_softc
*sc
)
3811 /* Initialize the context ID for an L2 TX chain. */
3812 if (BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5709
) {
3813 /* Set the CID type to support an L2 connection. */
3814 val
= BNX_L2CTX_TYPE_TYPE_L2
| BNX_L2CTX_TYPE_SIZE_L2
;
3815 CTX_WR(sc
, GET_CID_ADDR(TX_CID
), BNX_L2CTX_TYPE_XI
, val
);
3816 val
= BNX_L2CTX_CMD_TYPE_TYPE_L2
| (8 << 16);
3817 CTX_WR(sc
, GET_CID_ADDR(TX_CID
), BNX_L2CTX_CMD_TYPE_XI
, val
);
3819 /* Point the hardware to the first page in the chain. */
3820 val
= (u_int32_t
)((u_int64_t
)sc
->tx_bd_chain_paddr
[0] >> 32);
3821 CTX_WR(sc
, GET_CID_ADDR(TX_CID
),
3822 BNX_L2CTX_TBDR_BHADDR_HI_XI
, val
);
3823 val
= (u_int32_t
)(sc
->tx_bd_chain_paddr
[0]);
3824 CTX_WR(sc
, GET_CID_ADDR(TX_CID
),
3825 BNX_L2CTX_TBDR_BHADDR_LO_XI
, val
);
3827 /* Set the CID type to support an L2 connection. */
3828 val
= BNX_L2CTX_TYPE_TYPE_L2
| BNX_L2CTX_TYPE_SIZE_L2
;
3829 CTX_WR(sc
, GET_CID_ADDR(TX_CID
), BNX_L2CTX_TYPE
, val
);
3830 val
= BNX_L2CTX_CMD_TYPE_TYPE_L2
| (8 << 16);
3831 CTX_WR(sc
, GET_CID_ADDR(TX_CID
), BNX_L2CTX_CMD_TYPE
, val
);
3833 /* Point the hardware to the first page in the chain. */
3834 val
= (u_int32_t
)((u_int64_t
)sc
->tx_bd_chain_paddr
[0] >> 32);
3835 CTX_WR(sc
, GET_CID_ADDR(TX_CID
), BNX_L2CTX_TBDR_BHADDR_HI
, val
);
3836 val
= (u_int32_t
)(sc
->tx_bd_chain_paddr
[0]);
3837 CTX_WR(sc
, GET_CID_ADDR(TX_CID
), BNX_L2CTX_TBDR_BHADDR_LO
, val
);
3842 /****************************************************************************/
3843 /* Allocate memory and initialize the TX data structures. */
3846 /* 0 for success, positive value for failure. */
3847 /****************************************************************************/
3849 bnx_init_tx_chain(struct bnx_softc
*sc
)
3855 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Entering %s()\n", __func__
);
3857 /* Force an allocation of some dmamaps for tx up front */
3860 /* Set the initial TX producer/consumer indices. */
3863 sc
->tx_prod_bseq
= 0;
3865 sc
->max_tx_bd
= USABLE_TX_BD
;
3866 DBRUNIF(1, sc
->tx_hi_watermark
= USABLE_TX_BD
);
3867 DBRUNIF(1, sc
->tx_full_count
= 0);
3870 * The NetXtreme II supports a linked-list structure called
3871 * a Buffer Descriptor Chain (or BD chain). A BD chain
3872 * consists of a series of 1 or more chain pages, each of which
3873 * consists of a fixed number of BD entries.
3874 * The last BD entry on each page is a pointer to the next page
3875 * in the chain, and the last pointer in the BD chain
3876 * points back to the beginning of the chain.
3879 /* Set the TX next pointer chain entries. */
3880 for (i
= 0; i
< TX_PAGES
; i
++) {
3883 txbd
= &sc
->tx_bd_chain
[i
][USABLE_TX_BD_PER_PAGE
];
3885 /* Check if we've reached the last page. */
3886 if (i
== (TX_PAGES
- 1))
3891 addr
= (u_int32_t
)(sc
->tx_bd_chain_paddr
[j
]);
3892 txbd
->tx_bd_haddr_lo
= htole32(addr
);
3893 addr
= (u_int32_t
)((u_int64_t
)sc
->tx_bd_chain_paddr
[j
] >> 32);
3894 txbd
->tx_bd_haddr_hi
= htole32(addr
);
3895 bus_dmamap_sync(sc
->bnx_dmatag
, sc
->tx_bd_chain_map
[i
], 0,
3896 BNX_TX_CHAIN_PAGE_SZ
, BUS_DMASYNC_PREWRITE
);
3900 * Initialize the context ID for an L2 TX chain.
3902 bnx_init_tx_context(sc
);
3904 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Exiting %s()\n", __func__
);
3909 /****************************************************************************/
3910 /* Free memory and clear the TX data structures. */
3914 /****************************************************************************/
3916 bnx_free_tx_chain(struct bnx_softc
*sc
)
3918 struct bnx_pkt
*pkt
;
3921 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Entering %s()\n", __func__
);
3923 /* Unmap, unload, and free any mbufs still in the TX mbuf chain. */
3924 mutex_enter(&sc
->tx_pkt_mtx
);
3925 while ((pkt
= TAILQ_FIRST(&sc
->tx_used_pkts
)) != NULL
) {
3926 TAILQ_REMOVE(&sc
->tx_used_pkts
, pkt
, pkt_entry
);
3927 mutex_exit(&sc
->tx_pkt_mtx
);
3929 bus_dmamap_sync(sc
->bnx_dmatag
, pkt
->pkt_dmamap
, 0,
3930 pkt
->pkt_dmamap
->dm_mapsize
, BUS_DMASYNC_POSTWRITE
);
3931 bus_dmamap_unload(sc
->bnx_dmatag
, pkt
->pkt_dmamap
);
3933 m_freem(pkt
->pkt_mbuf
);
3934 DBRUNIF(1, sc
->tx_mbuf_alloc
--);
3936 mutex_enter(&sc
->tx_pkt_mtx
);
3937 TAILQ_INSERT_TAIL(&sc
->tx_free_pkts
, pkt
, pkt_entry
);
3940 /* Destroy all the dmamaps we allocated for TX */
3941 while ((pkt
= TAILQ_FIRST(&sc
->tx_free_pkts
)) != NULL
) {
3942 TAILQ_REMOVE(&sc
->tx_free_pkts
, pkt
, pkt_entry
);
3944 mutex_exit(&sc
->tx_pkt_mtx
);
3946 bus_dmamap_destroy(sc
->bnx_dmatag
, pkt
->pkt_dmamap
);
3947 pool_put(bnx_tx_pool
, pkt
);
3949 mutex_enter(&sc
->tx_pkt_mtx
);
3951 mutex_exit(&sc
->tx_pkt_mtx
);
3955 /* Clear each TX chain page. */
3956 for (i
= 0; i
< TX_PAGES
; i
++) {
3957 memset((char *)sc
->tx_bd_chain
[i
], 0, BNX_TX_CHAIN_PAGE_SZ
);
3958 bus_dmamap_sync(sc
->bnx_dmatag
, sc
->tx_bd_chain_map
[i
], 0,
3959 BNX_TX_CHAIN_PAGE_SZ
, BUS_DMASYNC_PREWRITE
);
3964 /* Check if we lost any mbufs in the process. */
3965 DBRUNIF((sc
->tx_mbuf_alloc
),
3966 aprint_error_dev(sc
->bnx_dev
,
3967 "Memory leak! Lost %d mbufs from tx chain!\n",
3968 sc
->tx_mbuf_alloc
));
3970 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Exiting %s()\n", __func__
);
3973 /****************************************************************************/
3974 /* Initialize the RX context memory. */
3978 /****************************************************************************/
3980 bnx_init_rx_context(struct bnx_softc
*sc
)
3984 /* Initialize the context ID for an L2 RX chain. */
3985 val
= BNX_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE
|
3986 BNX_L2CTX_CTX_TYPE_SIZE_L2
| (0x02 << 8);
3988 if (BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5709
) {
3989 u_int32_t lo_water
, hi_water
;
3991 lo_water
= BNX_L2CTX_RX_LO_WATER_MARK_DEFAULT
;
3992 hi_water
= USABLE_RX_BD
/ 4;
3994 lo_water
/= BNX_L2CTX_RX_LO_WATER_MARK_SCALE
;
3995 hi_water
/= BNX_L2CTX_RX_HI_WATER_MARK_SCALE
;
3999 else if (hi_water
== 0)
4002 (hi_water
<< BNX_L2CTX_RX_HI_WATER_MARK_SHIFT
);
4005 CTX_WR(sc
, GET_CID_ADDR(RX_CID
), BNX_L2CTX_CTX_TYPE
, val
);
4007 /* Setup the MQ BIN mapping for l2_ctx_host_bseq. */
4008 if (BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5709
) {
4009 val
= REG_RD(sc
, BNX_MQ_MAP_L2_5
);
4010 REG_WR(sc
, BNX_MQ_MAP_L2_5
, val
| BNX_MQ_MAP_L2_5_ARM
);
4013 /* Point the hardware to the first page in the chain. */
4014 val
= (u_int32_t
)((u_int64_t
)sc
->rx_bd_chain_paddr
[0] >> 32);
4015 CTX_WR(sc
, GET_CID_ADDR(RX_CID
), BNX_L2CTX_NX_BDHADDR_HI
, val
);
4016 val
= (u_int32_t
)(sc
->rx_bd_chain_paddr
[0]);
4017 CTX_WR(sc
, GET_CID_ADDR(RX_CID
), BNX_L2CTX_NX_BDHADDR_LO
, val
);
4020 /****************************************************************************/
4021 /* Allocate memory and initialize the RX data structures. */
4024 /* 0 for success, positive value for failure. */
4025 /****************************************************************************/
4027 bnx_init_rx_chain(struct bnx_softc
*sc
)
4031 u_int16_t prod
, chain_prod
;
4032 u_int32_t prod_bseq
, addr
;
4034 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Entering %s()\n", __func__
);
4036 /* Initialize the RX producer and consumer indices. */
4039 sc
->rx_prod_bseq
= 0;
4040 sc
->free_rx_bd
= USABLE_RX_BD
;
4041 sc
->max_rx_bd
= USABLE_RX_BD
;
4042 DBRUNIF(1, sc
->rx_low_watermark
= USABLE_RX_BD
);
4043 DBRUNIF(1, sc
->rx_empty_count
= 0);
4045 /* Initialize the RX next pointer chain entries. */
4046 for (i
= 0; i
< RX_PAGES
; i
++) {
4049 rxbd
= &sc
->rx_bd_chain
[i
][USABLE_RX_BD_PER_PAGE
];
4051 /* Check if we've reached the last page. */
4052 if (i
== (RX_PAGES
- 1))
4057 /* Setup the chain page pointers. */
4058 addr
= (u_int32_t
)((u_int64_t
)sc
->rx_bd_chain_paddr
[j
] >> 32);
4059 rxbd
->rx_bd_haddr_hi
= htole32(addr
);
4060 addr
= (u_int32_t
)(sc
->rx_bd_chain_paddr
[j
]);
4061 rxbd
->rx_bd_haddr_lo
= htole32(addr
);
4062 bus_dmamap_sync(sc
->bnx_dmatag
, sc
->rx_bd_chain_map
[i
],
4063 0, BNX_RX_CHAIN_PAGE_SZ
,
4064 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
4067 /* Allocate mbuf clusters for the rx_bd chain. */
4068 prod
= prod_bseq
= 0;
4069 chain_prod
= RX_CHAIN_IDX(prod
);
4070 if (bnx_get_buf(sc
, &prod
, &chain_prod
, &prod_bseq
)) {
4072 "Error filling RX chain: rx_bd[0x%04X]!\n", chain_prod
);
4075 /* Save the RX chain producer index. */
4077 sc
->rx_prod_bseq
= prod_bseq
;
4079 for (i
= 0; i
< RX_PAGES
; i
++)
4080 bus_dmamap_sync(sc
->bnx_dmatag
, sc
->rx_bd_chain_map
[i
], 0,
4081 sc
->rx_bd_chain_map
[i
]->dm_mapsize
,
4082 BUS_DMASYNC_PREREAD
| BUS_DMASYNC_PREWRITE
);
4084 /* Tell the chip about the waiting rx_bd's. */
4085 REG_WR16(sc
, MB_RX_CID_ADDR
+ BNX_L2CTX_HOST_BDIDX
, sc
->rx_prod
);
4086 REG_WR(sc
, MB_RX_CID_ADDR
+ BNX_L2CTX_HOST_BSEQ
, sc
->rx_prod_bseq
);
4088 bnx_init_rx_context(sc
);
4090 DBRUN(BNX_VERBOSE_RECV
, bnx_dump_rx_chain(sc
, 0, TOTAL_RX_BD
));
4092 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Exiting %s()\n", __func__
);
4097 /****************************************************************************/
4098 /* Free memory and clear the RX data structures. */
4102 /****************************************************************************/
4104 bnx_free_rx_chain(struct bnx_softc
*sc
)
4108 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Entering %s()\n", __func__
);
4110 /* Free any mbufs still in the RX mbuf chain. */
4111 for (i
= 0; i
< TOTAL_RX_BD
; i
++) {
4112 if (sc
->rx_mbuf_ptr
[i
] != NULL
) {
4113 if (sc
->rx_mbuf_map
[i
] != NULL
) {
4114 bus_dmamap_sync(sc
->bnx_dmatag
,
4115 sc
->rx_mbuf_map
[i
], 0,
4116 sc
->rx_mbuf_map
[i
]->dm_mapsize
,
4117 BUS_DMASYNC_POSTREAD
);
4118 bus_dmamap_unload(sc
->bnx_dmatag
,
4119 sc
->rx_mbuf_map
[i
]);
4121 m_freem(sc
->rx_mbuf_ptr
[i
]);
4122 sc
->rx_mbuf_ptr
[i
] = NULL
;
4123 DBRUNIF(1, sc
->rx_mbuf_alloc
--);
4127 /* Clear each RX chain page. */
4128 for (i
= 0; i
< RX_PAGES
; i
++)
4129 memset((char *)sc
->rx_bd_chain
[i
], 0, BNX_RX_CHAIN_PAGE_SZ
);
4131 sc
->free_rx_bd
= sc
->max_rx_bd
;
4133 /* Check if we lost any mbufs in the process. */
4134 DBRUNIF((sc
->rx_mbuf_alloc
),
4135 aprint_error_dev(sc
->bnx_dev
,
4136 "Memory leak! Lost %d mbufs from rx chain!\n",
4137 sc
->rx_mbuf_alloc
));
4139 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Exiting %s()\n", __func__
);
4142 /****************************************************************************/
4143 /* Handles PHY generated interrupt events. */
4147 /****************************************************************************/
4149 bnx_phy_intr(struct bnx_softc
*sc
)
4151 u_int32_t new_link_state
, old_link_state
;
4153 bus_dmamap_sync(sc
->bnx_dmatag
, sc
->status_map
, 0, BNX_STATUS_BLK_SZ
,
4154 BUS_DMASYNC_POSTREAD
);
4155 new_link_state
= sc
->status_block
->status_attn_bits
&
4156 STATUS_ATTN_BITS_LINK_STATE
;
4157 old_link_state
= sc
->status_block
->status_attn_bits_ack
&
4158 STATUS_ATTN_BITS_LINK_STATE
;
4160 /* Handle any changes if the link state has changed. */
4161 if (new_link_state
!= old_link_state
) {
4162 DBRUN(BNX_VERBOSE_INTR
, bnx_dump_status_block(sc
));
4164 callout_stop(&sc
->bnx_timeout
);
4167 /* Update the status_attn_bits_ack field in the status block. */
4168 if (new_link_state
) {
4169 REG_WR(sc
, BNX_PCICFG_STATUS_BIT_SET_CMD
,
4170 STATUS_ATTN_BITS_LINK_STATE
);
4171 DBPRINT(sc
, BNX_INFO
, "Link is now UP.\n");
4173 REG_WR(sc
, BNX_PCICFG_STATUS_BIT_CLEAR_CMD
,
4174 STATUS_ATTN_BITS_LINK_STATE
);
4175 DBPRINT(sc
, BNX_INFO
, "Link is now DOWN.\n");
4179 /* Acknowledge the link change interrupt. */
4180 REG_WR(sc
, BNX_EMAC_STATUS
, BNX_EMAC_STATUS_LINK_CHANGE
);
4183 /****************************************************************************/
4184 /* Handles received frame interrupt events. */
4188 /****************************************************************************/
4190 bnx_rx_intr(struct bnx_softc
*sc
)
4192 struct status_block
*sblk
= sc
->status_block
;
4193 struct ifnet
*ifp
= &sc
->bnx_ec
.ec_if
;
4194 u_int16_t hw_cons
, sw_cons
, sw_chain_cons
;
4195 u_int16_t sw_prod
, sw_chain_prod
;
4196 u_int32_t sw_prod_bseq
;
4197 struct l2_fhdr
*l2fhdr
;
4200 DBRUNIF(1, sc
->rx_interrupts
++);
4201 bus_dmamap_sync(sc
->bnx_dmatag
, sc
->status_map
, 0, BNX_STATUS_BLK_SZ
,
4202 BUS_DMASYNC_POSTREAD
);
4204 /* Prepare the RX chain pages to be accessed by the host CPU. */
4205 for (i
= 0; i
< RX_PAGES
; i
++)
4206 bus_dmamap_sync(sc
->bnx_dmatag
,
4207 sc
->rx_bd_chain_map
[i
], 0,
4208 sc
->rx_bd_chain_map
[i
]->dm_mapsize
,
4209 BUS_DMASYNC_POSTWRITE
);
4211 /* Get the hardware's view of the RX consumer index. */
4212 hw_cons
= sc
->hw_rx_cons
= sblk
->status_rx_quick_consumer_index0
;
4213 if ((hw_cons
& USABLE_RX_BD_PER_PAGE
) == USABLE_RX_BD_PER_PAGE
)
4216 /* Get working copies of the driver's view of the RX indices. */
4217 sw_cons
= sc
->rx_cons
;
4218 sw_prod
= sc
->rx_prod
;
4219 sw_prod_bseq
= sc
->rx_prod_bseq
;
4221 DBPRINT(sc
, BNX_INFO_RECV
, "%s(enter): sw_prod = 0x%04X, "
4222 "sw_cons = 0x%04X, sw_prod_bseq = 0x%08X\n",
4223 __func__
, sw_prod
, sw_cons
, sw_prod_bseq
);
4225 /* Prevent speculative reads from getting ahead of the status block. */
4226 bus_space_barrier(sc
->bnx_btag
, sc
->bnx_bhandle
, 0, 0,
4227 BUS_SPACE_BARRIER_READ
);
4229 /* Update some debug statistics counters */
4230 DBRUNIF((sc
->free_rx_bd
< sc
->rx_low_watermark
),
4231 sc
->rx_low_watermark
= sc
->free_rx_bd
);
4232 DBRUNIF((sc
->free_rx_bd
== USABLE_RX_BD
), sc
->rx_empty_count
++);
4235 * Scan through the receive chain as long
4236 * as there is work to do.
4238 while (sw_cons
!= hw_cons
) {
4244 /* Convert the producer/consumer indices to an actual
4247 sw_chain_cons
= RX_CHAIN_IDX(sw_cons
);
4248 sw_chain_prod
= RX_CHAIN_IDX(sw_prod
);
4250 /* Get the used rx_bd. */
4251 rxbd
= &sc
->rx_bd_chain
[RX_PAGE(sw_chain_cons
)][RX_IDX(sw_chain_cons
)];
4254 DBRUN(BNX_VERBOSE_RECV
, aprint_error("%s(): ", __func__
);
4255 bnx_dump_rxbd(sc
, sw_chain_cons
, rxbd
));
4257 /* The mbuf is stored with the last rx_bd entry of a packet. */
4258 if (sc
->rx_mbuf_ptr
[sw_chain_cons
] != NULL
) {
4260 /* Validate that this is the last rx_bd. */
4261 if ((rxbd
->rx_bd_flags
& RX_BD_FLAGS_END
) == 0) {
4262 printf("%s: Unexpected mbuf found in "
4263 "rx_bd[0x%04X]!\n", device_xname(sc
->bnx_dev
),
4268 /* DRC - ToDo: If the received packet is small, say less
4269 * than 128 bytes, allocate a new mbuf here,
4270 * copy the data to that mbuf, and recycle
4271 * the mapped jumbo frame.
4274 /* Unmap the mbuf from DMA space. */
4276 if (sc
->rx_mbuf_map
[sw_chain_cons
]->dm_mapsize
== 0) {
4277 printf("invalid map sw_cons 0x%x "
4279 "sw_chain_cons 0x%x "
4280 "sw_chain_prod 0x%x "
4282 "TOTAL_RX_BD_PER_PAGE 0x%x "
4283 "TOTAL_RX_BD 0x%x\n",
4284 sw_cons
, sw_prod
, sw_chain_cons
, sw_chain_prod
,
4286 (int)TOTAL_RX_BD_PER_PAGE
, (int)TOTAL_RX_BD
);
4289 bus_dmamap_sync(sc
->bnx_dmatag
,
4290 sc
->rx_mbuf_map
[sw_chain_cons
], 0,
4291 sc
->rx_mbuf_map
[sw_chain_cons
]->dm_mapsize
,
4292 BUS_DMASYNC_POSTREAD
);
4293 bus_dmamap_unload(sc
->bnx_dmatag
,
4294 sc
->rx_mbuf_map
[sw_chain_cons
]);
4296 /* Remove the mbuf from the driver's chain. */
4297 m
= sc
->rx_mbuf_ptr
[sw_chain_cons
];
4298 sc
->rx_mbuf_ptr
[sw_chain_cons
] = NULL
;
4301 * Frames received on the NetXteme II are prepended
4302 * with the l2_fhdr structure which provides status
4303 * information about the received frame (including
4304 * VLAN tags and checksum info) and are also
4305 * automatically adjusted to align the IP header
4306 * (i.e. two null bytes are inserted before the
4309 l2fhdr
= mtod(m
, struct l2_fhdr
*);
4311 len
= l2fhdr
->l2_fhdr_pkt_len
;
4312 status
= l2fhdr
->l2_fhdr_status
;
4314 DBRUNIF(DB_RANDOMTRUE(bnx_debug_l2fhdr_status_check
),
4315 aprint_error("Simulating l2_fhdr status error.\n");
4316 status
= status
| L2_FHDR_ERRORS_PHY_DECODE
);
4318 /* Watch for unusual sized frames. */
4319 DBRUNIF(((len
< BNX_MIN_MTU
) ||
4320 (len
> BNX_MAX_JUMBO_ETHER_MTU_VLAN
)),
4321 aprint_error_dev(sc
->bnx_dev
,
4322 "Unusual frame size found. "
4323 "Min(%d), Actual(%d), Max(%d)\n",
4324 (int)BNX_MIN_MTU
, len
,
4325 (int)BNX_MAX_JUMBO_ETHER_MTU_VLAN
);
4327 bnx_dump_mbuf(sc
, m
);
4328 bnx_breakpoint(sc
));
4330 len
-= ETHER_CRC_LEN
;
4332 /* Check the received frame for errors. */
4333 if ((status
& (L2_FHDR_ERRORS_BAD_CRC
|
4334 L2_FHDR_ERRORS_PHY_DECODE
|
4335 L2_FHDR_ERRORS_ALIGNMENT
|
4336 L2_FHDR_ERRORS_TOO_SHORT
|
4337 L2_FHDR_ERRORS_GIANT_FRAME
)) ||
4338 len
< (BNX_MIN_MTU
- ETHER_CRC_LEN
) ||
4340 (BNX_MAX_JUMBO_ETHER_MTU_VLAN
- ETHER_CRC_LEN
)) {
4342 DBRUNIF(1, sc
->l2fhdr_status_errors
++);
4344 /* Reuse the mbuf for a new frame. */
4345 if (bnx_add_buf(sc
, m
, &sw_prod
,
4346 &sw_chain_prod
, &sw_prod_bseq
)) {
4347 DBRUNIF(1, bnx_breakpoint(sc
));
4348 panic("%s: Can't reuse RX mbuf!\n",
4349 device_xname(sc
->bnx_dev
));
4355 * Get a new mbuf for the rx_bd. If no new
4356 * mbufs are available then reuse the current mbuf,
4357 * log an ierror on the interface, and generate
4358 * an error in the system log.
4360 if (bnx_get_buf(sc
, &sw_prod
, &sw_chain_prod
,
4362 DBRUN(BNX_WARN
, aprint_debug_dev(sc
->bnx_dev
,
4363 "Failed to allocate "
4364 "new mbuf, incoming frame dropped!\n"));
4368 /* Try and reuse the exisitng mbuf. */
4369 if (bnx_add_buf(sc
, m
, &sw_prod
,
4370 &sw_chain_prod
, &sw_prod_bseq
)) {
4371 DBRUNIF(1, bnx_breakpoint(sc
));
4372 panic("%s: Double mbuf allocation "
4374 device_xname(sc
->bnx_dev
));
4379 /* Skip over the l2_fhdr when passing the data up
4382 m_adj(m
, sizeof(struct l2_fhdr
) + ETHER_ALIGN
);
4384 /* Adjust the pckt length to match the received data. */
4385 m
->m_pkthdr
.len
= m
->m_len
= len
;
4387 /* Send the packet to the appropriate interface. */
4388 m
->m_pkthdr
.rcvif
= ifp
;
4390 DBRUN(BNX_VERBOSE_RECV
,
4391 struct ether_header
*eh
;
4392 eh
= mtod(m
, struct ether_header
*);
4393 aprint_error("%s: to: %s, from: %s, type: 0x%04X\n",
4394 __func__
, ether_sprintf(eh
->ether_dhost
),
4395 ether_sprintf(eh
->ether_shost
),
4396 htons(eh
->ether_type
)));
4398 /* Validate the checksum. */
4400 /* Check for an IP datagram. */
4401 if (status
& L2_FHDR_STATUS_IP_DATAGRAM
) {
4402 /* Check if the IP checksum is valid. */
4403 if ((l2fhdr
->l2_fhdr_ip_xsum
^ 0xffff)
4405 m
->m_pkthdr
.csum_flags
|=
4409 DBPRINT(sc
, BNX_WARN_SEND
,
4410 "%s(): Invalid IP checksum "
4413 l2fhdr
->l2_fhdr_ip_xsum
4418 /* Check for a valid TCP/UDP frame. */
4419 if (status
& (L2_FHDR_STATUS_TCP_SEGMENT
|
4420 L2_FHDR_STATUS_UDP_DATAGRAM
)) {
4421 /* Check for a good TCP/UDP checksum. */
4423 (L2_FHDR_ERRORS_TCP_XSUM
|
4424 L2_FHDR_ERRORS_UDP_XSUM
)) == 0) {
4425 m
->m_pkthdr
.csum_flags
|=
4429 DBPRINT(sc
, BNX_WARN_SEND
,
4430 "%s(): Invalid TCP/UDP "
4431 "checksum = 0x%04X!\n",
4433 l2fhdr
->l2_fhdr_tcp_udp_xsum
);
4438 * If we received a packet with a vlan tag,
4439 * attach that information to the packet.
4441 if ((status
& L2_FHDR_STATUS_L2_VLAN_TAG
) &&
4442 !(sc
->rx_mode
& BNX_EMAC_RX_MODE_KEEP_VLAN_TAG
)) {
4443 VLAN_INPUT_TAG(ifp
, m
,
4444 l2fhdr
->l2_fhdr_vlan_tag
,
4450 * Handle BPF listeners. Let the BPF
4451 * user see the packet.
4454 bpf_mtap(ifp
->if_bpf
, m
);
4457 /* Pass the mbuf off to the upper layers. */
4459 DBPRINT(sc
, BNX_VERBOSE_RECV
,
4460 "%s(): Passing received frame up.\n", __func__
);
4461 (*ifp
->if_input
)(ifp
, m
);
4462 DBRUNIF(1, sc
->rx_mbuf_alloc
--);
4466 sw_cons
= NEXT_RX_BD(sw_cons
);
4468 /* Refresh hw_cons to see if there's new work */
4469 if (sw_cons
== hw_cons
) {
4470 hw_cons
= sc
->hw_rx_cons
=
4471 sblk
->status_rx_quick_consumer_index0
;
4472 if ((hw_cons
& USABLE_RX_BD_PER_PAGE
) ==
4473 USABLE_RX_BD_PER_PAGE
)
4477 /* Prevent speculative reads from getting ahead of
4480 bus_space_barrier(sc
->bnx_btag
, sc
->bnx_bhandle
, 0, 0,
4481 BUS_SPACE_BARRIER_READ
);
4484 for (i
= 0; i
< RX_PAGES
; i
++)
4485 bus_dmamap_sync(sc
->bnx_dmatag
,
4486 sc
->rx_bd_chain_map
[i
], 0,
4487 sc
->rx_bd_chain_map
[i
]->dm_mapsize
,
4488 BUS_DMASYNC_PREWRITE
);
4490 sc
->rx_cons
= sw_cons
;
4491 sc
->rx_prod
= sw_prod
;
4492 sc
->rx_prod_bseq
= sw_prod_bseq
;
4494 REG_WR16(sc
, MB_RX_CID_ADDR
+ BNX_L2CTX_HOST_BDIDX
, sc
->rx_prod
);
4495 REG_WR(sc
, MB_RX_CID_ADDR
+ BNX_L2CTX_HOST_BSEQ
, sc
->rx_prod_bseq
);
4497 DBPRINT(sc
, BNX_INFO_RECV
, "%s(exit): rx_prod = 0x%04X, "
4498 "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
4499 __func__
, sc
->rx_prod
, sc
->rx_cons
, sc
->rx_prod_bseq
);
4502 /****************************************************************************/
4503 /* Handles transmit completion interrupt events. */
4507 /****************************************************************************/
4509 bnx_tx_intr(struct bnx_softc
*sc
)
4511 struct status_block
*sblk
= sc
->status_block
;
4512 struct ifnet
*ifp
= &sc
->bnx_ec
.ec_if
;
4513 struct bnx_pkt
*pkt
;
4515 u_int16_t hw_tx_cons
, sw_tx_cons
, sw_tx_chain_cons
;
4517 DBRUNIF(1, sc
->tx_interrupts
++);
4518 bus_dmamap_sync(sc
->bnx_dmatag
, sc
->status_map
, 0, BNX_STATUS_BLK_SZ
,
4519 BUS_DMASYNC_POSTREAD
);
4521 /* Get the hardware's view of the TX consumer index. */
4522 hw_tx_cons
= sc
->hw_tx_cons
= sblk
->status_tx_quick_consumer_index0
;
4524 /* Skip to the next entry if this is a chain page pointer. */
4525 if ((hw_tx_cons
& USABLE_TX_BD_PER_PAGE
) == USABLE_TX_BD_PER_PAGE
)
4528 sw_tx_cons
= sc
->tx_cons
;
4530 /* Prevent speculative reads from getting ahead of the status block. */
4531 bus_space_barrier(sc
->bnx_btag
, sc
->bnx_bhandle
, 0, 0,
4532 BUS_SPACE_BARRIER_READ
);
4534 /* Cycle through any completed TX chain page entries. */
4535 while (sw_tx_cons
!= hw_tx_cons
) {
4537 struct tx_bd
*txbd
= NULL
;
4539 sw_tx_chain_cons
= TX_CHAIN_IDX(sw_tx_cons
);
4541 DBPRINT(sc
, BNX_INFO_SEND
, "%s(): hw_tx_cons = 0x%04X, "
4542 "sw_tx_cons = 0x%04X, sw_tx_chain_cons = 0x%04X\n",
4543 __func__
, hw_tx_cons
, sw_tx_cons
, sw_tx_chain_cons
);
4545 DBRUNIF((sw_tx_chain_cons
> MAX_TX_BD
),
4546 aprint_error_dev(sc
->bnx_dev
,
4547 "TX chain consumer out of range! 0x%04X > 0x%04X\n",
4548 sw_tx_chain_cons
, (int)MAX_TX_BD
); bnx_breakpoint(sc
));
4550 DBRUNIF(1, txbd
= &sc
->tx_bd_chain
4551 [TX_PAGE(sw_tx_chain_cons
)][TX_IDX(sw_tx_chain_cons
)]);
4553 DBRUNIF((txbd
== NULL
),
4554 aprint_error_dev(sc
->bnx_dev
,
4555 "Unexpected NULL tx_bd[0x%04X]!\n", sw_tx_chain_cons
);
4556 bnx_breakpoint(sc
));
4558 DBRUN(BNX_INFO_SEND
, aprint_debug("%s: ", __func__
);
4559 bnx_dump_txbd(sc
, sw_tx_chain_cons
, txbd
));
4562 mutex_enter(&sc
->tx_pkt_mtx
);
4563 pkt
= TAILQ_FIRST(&sc
->tx_used_pkts
);
4564 if (pkt
!= NULL
&& pkt
->pkt_end_desc
== sw_tx_chain_cons
) {
4565 TAILQ_REMOVE(&sc
->tx_used_pkts
, pkt
, pkt_entry
);
4566 mutex_exit(&sc
->tx_pkt_mtx
);
4568 * Free the associated mbuf. Remember
4569 * that only the last tx_bd of a packet
4570 * has an mbuf pointer and DMA map.
4572 map
= pkt
->pkt_dmamap
;
4573 bus_dmamap_sync(sc
->bnx_dmatag
, map
, 0,
4574 map
->dm_mapsize
, BUS_DMASYNC_POSTWRITE
);
4575 bus_dmamap_unload(sc
->bnx_dmatag
, map
);
4577 m_freem(pkt
->pkt_mbuf
);
4578 DBRUNIF(1, sc
->tx_mbuf_alloc
--);
4582 mutex_enter(&sc
->tx_pkt_mtx
);
4583 TAILQ_INSERT_TAIL(&sc
->tx_free_pkts
, pkt
, pkt_entry
);
4585 mutex_exit(&sc
->tx_pkt_mtx
);
4588 DBPRINT(sc
, BNX_INFO_SEND
, "%s(%d) used_tx_bd %d\n",
4589 __FILE__
, __LINE__
, sc
->used_tx_bd
);
4591 sw_tx_cons
= NEXT_TX_BD(sw_tx_cons
);
4593 /* Refresh hw_cons to see if there's new work. */
4594 hw_tx_cons
= sc
->hw_tx_cons
=
4595 sblk
->status_tx_quick_consumer_index0
;
4596 if ((hw_tx_cons
& USABLE_TX_BD_PER_PAGE
) ==
4597 USABLE_TX_BD_PER_PAGE
)
4600 /* Prevent speculative reads from getting ahead of
4603 bus_space_barrier(sc
->bnx_btag
, sc
->bnx_bhandle
, 0, 0,
4604 BUS_SPACE_BARRIER_READ
);
4607 /* Clear the TX timeout timer. */
4610 /* Clear the tx hardware queue full flag. */
4611 if (sc
->used_tx_bd
< sc
->max_tx_bd
) {
4612 DBRUNIF((ifp
->if_flags
& IFF_OACTIVE
),
4613 aprint_debug_dev(sc
->bnx_dev
,
4614 "Open TX chain! %d/%d (used/total)\n",
4615 sc
->used_tx_bd
, sc
->max_tx_bd
));
4616 ifp
->if_flags
&= ~IFF_OACTIVE
;
4619 sc
->tx_cons
= sw_tx_cons
;
4622 /****************************************************************************/
4623 /* Disables interrupt generation. */
4627 /****************************************************************************/
4629 bnx_disable_intr(struct bnx_softc
*sc
)
4631 REG_WR(sc
, BNX_PCICFG_INT_ACK_CMD
, BNX_PCICFG_INT_ACK_CMD_MASK_INT
);
4632 REG_RD(sc
, BNX_PCICFG_INT_ACK_CMD
);
4635 /****************************************************************************/
4636 /* Enables interrupt generation. */
4640 /****************************************************************************/
4642 bnx_enable_intr(struct bnx_softc
*sc
)
4646 REG_WR(sc
, BNX_PCICFG_INT_ACK_CMD
, BNX_PCICFG_INT_ACK_CMD_INDEX_VALID
|
4647 BNX_PCICFG_INT_ACK_CMD_MASK_INT
| sc
->last_status_idx
);
4649 REG_WR(sc
, BNX_PCICFG_INT_ACK_CMD
, BNX_PCICFG_INT_ACK_CMD_INDEX_VALID
|
4650 sc
->last_status_idx
);
4652 val
= REG_RD(sc
, BNX_HC_COMMAND
);
4653 REG_WR(sc
, BNX_HC_COMMAND
, val
| BNX_HC_COMMAND_COAL_NOW
);
4656 /****************************************************************************/
4657 /* Handles controller initialization. */
4659 /****************************************************************************/
4661 bnx_init(struct ifnet
*ifp
)
4663 struct bnx_softc
*sc
= ifp
->if_softc
;
4664 u_int32_t ether_mtu
;
4667 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Entering %s()\n", __func__
);
4673 if ((error
= bnx_reset(sc
, BNX_DRV_MSG_CODE_RESET
)) != 0) {
4674 aprint_error_dev(sc
->bnx_dev
,
4675 "Controller reset failed!\n");
4679 if ((error
= bnx_chipinit(sc
)) != 0) {
4680 aprint_error_dev(sc
->bnx_dev
,
4681 "Controller initialization failed!\n");
4685 if ((error
= bnx_blockinit(sc
)) != 0) {
4686 aprint_error_dev(sc
->bnx_dev
,
4687 "Block initialization failed!\n");
4691 /* Calculate and program the Ethernet MRU size. */
4692 if (ifp
->if_mtu
<= ETHERMTU
) {
4693 ether_mtu
= BNX_MAX_STD_ETHER_MTU_VLAN
;
4694 sc
->mbuf_alloc_size
= MCLBYTES
;
4696 ether_mtu
= BNX_MAX_JUMBO_ETHER_MTU_VLAN
;
4697 sc
->mbuf_alloc_size
= BNX_MAX_JUMBO_MRU
;
4701 DBPRINT(sc
, BNX_INFO
, "%s(): setting MRU = %d\n",
4702 __func__
, ether_mtu
);
4705 * Program the MRU and enable Jumbo frame
4708 REG_WR(sc
, BNX_EMAC_RX_MTU_SIZE
, ether_mtu
|
4709 BNX_EMAC_RX_MTU_SIZE_JUMBO_ENA
);
4711 /* Calculate the RX Ethernet frame size for rx_bd's. */
4712 sc
->max_frame_size
= sizeof(struct l2_fhdr
) + 2 + ether_mtu
+ 8;
4714 DBPRINT(sc
, BNX_INFO
, "%s(): mclbytes = %d, mbuf_alloc_size = %d, "
4715 "max_frame_size = %d\n", __func__
, (int)MCLBYTES
,
4716 sc
->mbuf_alloc_size
, sc
->max_frame_size
);
4718 /* Program appropriate promiscuous/multicast filtering. */
4721 /* Init RX buffer descriptor chain. */
4722 bnx_init_rx_chain(sc
);
4724 /* Init TX buffer descriptor chain. */
4725 bnx_init_tx_chain(sc
);
4727 /* Enable host interrupts. */
4728 bnx_enable_intr(sc
);
4730 if ((error
= ether_mediachange(ifp
)) != 0)
4733 ifp
->if_flags
|= IFF_RUNNING
;
4734 ifp
->if_flags
&= ~IFF_OACTIVE
;
4736 callout_reset(&sc
->bnx_timeout
, hz
, bnx_tick
, sc
);
4739 DBPRINT(sc
, BNX_VERBOSE_RESET
, "Exiting %s()\n", __func__
);
4746 /****************************************************************************/
4747 /* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
4748 /* memory visible to the controller. */
4751 /* 0 for success, positive value for failure. */
4752 /****************************************************************************/
4754 bnx_tx_encap(struct bnx_softc
*sc
, struct mbuf
*m
)
4756 struct bnx_pkt
*pkt
;
4758 struct tx_bd
*txbd
= NULL
;
4759 u_int16_t vlan_tag
= 0, flags
= 0;
4760 u_int16_t chain_prod
, prod
;
4762 u_int16_t debug_prod
;
4764 u_int32_t addr
, prod_bseq
;
4769 mutex_enter(&sc
->tx_pkt_mtx
);
4770 pkt
= TAILQ_FIRST(&sc
->tx_free_pkts
);
4772 if (!ISSET(sc
->bnx_ec
.ec_if
.if_flags
, IFF_UP
)) {
4773 mutex_exit(&sc
->tx_pkt_mtx
);
4776 if (sc
->tx_pkt_count
<= TOTAL_TX_BD
) {
4777 mutex_exit(&sc
->tx_pkt_mtx
);
4778 if (bnx_alloc_pkts(sc
) == 0)
4781 mutex_exit(&sc
->tx_pkt_mtx
);
4785 TAILQ_REMOVE(&sc
->tx_free_pkts
, pkt
, pkt_entry
);
4786 mutex_exit(&sc
->tx_pkt_mtx
);
4788 /* Transfer any checksum offload flags to the bd. */
4789 if (m
->m_pkthdr
.csum_flags
) {
4790 if (m
->m_pkthdr
.csum_flags
& M_CSUM_IPv4
)
4791 flags
|= TX_BD_FLAGS_IP_CKSUM
;
4792 if (m
->m_pkthdr
.csum_flags
&
4793 (M_CSUM_TCPv4
| M_CSUM_UDPv4
))
4794 flags
|= TX_BD_FLAGS_TCP_UDP_CKSUM
;
4797 /* Transfer any VLAN tags to the bd. */
4798 mtag
= VLAN_OUTPUT_TAG(&sc
->bnx_ec
, m
);
4800 flags
|= TX_BD_FLAGS_VLAN_TAG
;
4801 vlan_tag
= VLAN_TAG_VALUE(mtag
);
4804 /* Map the mbuf into DMAable memory. */
4806 chain_prod
= TX_CHAIN_IDX(prod
);
4807 map
= pkt
->pkt_dmamap
;
4809 /* Map the mbuf into our DMA address space. */
4810 error
= bus_dmamap_load_mbuf(sc
->bnx_dmatag
, map
, m
, BUS_DMA_NOWAIT
);
4812 aprint_error_dev(sc
->bnx_dev
,
4813 "Error mapping mbuf into TX chain!\n");
4814 sc
->tx_dma_map_failures
++;
4817 bus_dmamap_sync(sc
->bnx_dmatag
, map
, 0, map
->dm_mapsize
,
4818 BUS_DMASYNC_PREWRITE
);
4819 /* Make sure there's room in the chain */
4820 if (map
->dm_nsegs
> (sc
->max_tx_bd
- sc
->used_tx_bd
))
4823 /* prod points to an empty tx_bd at this point. */
4824 prod_bseq
= sc
->tx_prod_bseq
;
4826 debug_prod
= chain_prod
;
4828 DBPRINT(sc
, BNX_INFO_SEND
,
4829 "%s(): Start: prod = 0x%04X, chain_prod = %04X, "
4830 "prod_bseq = 0x%08X\n",
4831 __func__
, prod
, chain_prod
, prod_bseq
);
4834 * Cycle through each mbuf segment that makes up
4835 * the outgoing frame, gathering the mapping info
4836 * for that segment and creating a tx_bd for the
4839 for (i
= 0; i
< map
->dm_nsegs
; i
++) {
4840 chain_prod
= TX_CHAIN_IDX(prod
);
4841 txbd
= &sc
->tx_bd_chain
[TX_PAGE(chain_prod
)][TX_IDX(chain_prod
)];
4843 addr
= (u_int32_t
)(map
->dm_segs
[i
].ds_addr
);
4844 txbd
->tx_bd_haddr_lo
= htole32(addr
);
4845 addr
= (u_int32_t
)((u_int64_t
)map
->dm_segs
[i
].ds_addr
>> 32);
4846 txbd
->tx_bd_haddr_hi
= htole32(addr
);
4847 txbd
->tx_bd_mss_nbytes
= htole16(map
->dm_segs
[i
].ds_len
);
4848 txbd
->tx_bd_vlan_tag
= htole16(vlan_tag
);
4849 txbd
->tx_bd_flags
= htole16(flags
);
4850 prod_bseq
+= map
->dm_segs
[i
].ds_len
;
4852 txbd
->tx_bd_flags
|= htole16(TX_BD_FLAGS_START
);
4853 prod
= NEXT_TX_BD(prod
);
4855 /* Set the END flag on the last TX buffer descriptor. */
4856 txbd
->tx_bd_flags
|= htole16(TX_BD_FLAGS_END
);
4858 DBRUN(BNX_INFO_SEND
, bnx_dump_tx_chain(sc
, debug_prod
, map
->dm_nsegs
));
4860 DBPRINT(sc
, BNX_INFO_SEND
,
4861 "%s(): End: prod = 0x%04X, chain_prod = %04X, "
4862 "prod_bseq = 0x%08X\n",
4863 __func__
, prod
, chain_prod
, prod_bseq
);
4866 pkt
->pkt_end_desc
= chain_prod
;
4868 mutex_enter(&sc
->tx_pkt_mtx
);
4869 TAILQ_INSERT_TAIL(&sc
->tx_used_pkts
, pkt
, pkt_entry
);
4870 mutex_exit(&sc
->tx_pkt_mtx
);
4872 sc
->used_tx_bd
+= map
->dm_nsegs
;
4873 DBPRINT(sc
, BNX_INFO_SEND
, "%s(%d) used_tx_bd %d\n",
4874 __FILE__
, __LINE__
, sc
->used_tx_bd
);
4876 /* Update some debug statistics counters */
4877 DBRUNIF((sc
->used_tx_bd
> sc
->tx_hi_watermark
),
4878 sc
->tx_hi_watermark
= sc
->used_tx_bd
);
4879 DBRUNIF(sc
->used_tx_bd
== sc
->max_tx_bd
, sc
->tx_full_count
++);
4880 DBRUNIF(1, sc
->tx_mbuf_alloc
++);
4882 DBRUN(BNX_VERBOSE_SEND
, bnx_dump_tx_mbuf_chain(sc
, chain_prod
,
4885 /* prod points to the next free tx_bd at this point. */
4887 sc
->tx_prod_bseq
= prod_bseq
;
4893 bus_dmamap_unload(sc
->bnx_dmatag
, map
);
4895 mutex_enter(&sc
->tx_pkt_mtx
);
4896 TAILQ_INSERT_TAIL(&sc
->tx_free_pkts
, pkt
, pkt_entry
);
4897 mutex_exit(&sc
->tx_pkt_mtx
);
4902 /****************************************************************************/
4903 /* Main transmit routine. */
4907 /****************************************************************************/
4909 bnx_start(struct ifnet
*ifp
)
4911 struct bnx_softc
*sc
= ifp
->if_softc
;
4912 struct mbuf
*m_head
= NULL
;
4914 u_int16_t tx_prod
, tx_chain_prod
;
4916 /* If there's no link or the transmit queue is empty then just exit. */
4917 if ((ifp
->if_flags
& (IFF_OACTIVE
|IFF_RUNNING
)) != IFF_RUNNING
) {
4918 DBPRINT(sc
, BNX_INFO_SEND
,
4919 "%s(): output active or device not running.\n", __func__
);
4920 goto bnx_start_exit
;
4923 /* prod points to the next free tx_bd. */
4924 tx_prod
= sc
->tx_prod
;
4925 tx_chain_prod
= TX_CHAIN_IDX(tx_prod
);
4927 DBPRINT(sc
, BNX_INFO_SEND
, "%s(): Start: tx_prod = 0x%04X, "
4928 "tx_chain_prod = %04X, tx_prod_bseq = 0x%08X, "
4929 "used_tx %d max_tx %d\n",
4930 __func__
, tx_prod
, tx_chain_prod
, sc
->tx_prod_bseq
,
4931 sc
->used_tx_bd
, sc
->max_tx_bd
);
4934 * Keep adding entries while there is space in the ring.
4936 while (sc
->used_tx_bd
< sc
->max_tx_bd
) {
4937 /* Check for any frames to send. */
4938 IFQ_POLL(&ifp
->if_snd
, m_head
);
4943 * Pack the data into the transmit ring. If we
4944 * don't have room, set the OACTIVE flag to wait
4945 * for the NIC to drain the chain.
4947 if (bnx_tx_encap(sc
, m_head
)) {
4948 ifp
->if_flags
|= IFF_OACTIVE
;
4949 DBPRINT(sc
, BNX_INFO_SEND
, "TX chain is closed for "
4950 "business! Total tx_bd used = %d\n",
4955 IFQ_DEQUEUE(&ifp
->if_snd
, m_head
);
4959 /* Send a copy of the frame to any BPF listeners. */
4961 bpf_mtap(ifp
->if_bpf
, m_head
);
4966 /* no packets were dequeued */
4967 DBPRINT(sc
, BNX_VERBOSE_SEND
,
4968 "%s(): No packets were dequeued\n", __func__
);
4969 goto bnx_start_exit
;
4972 /* Update the driver's counters. */
4973 tx_chain_prod
= TX_CHAIN_IDX(sc
->tx_prod
);
4975 DBPRINT(sc
, BNX_INFO_SEND
, "%s(): End: tx_prod = 0x%04X, tx_chain_prod "
4976 "= 0x%04X, tx_prod_bseq = 0x%08X\n", __func__
, tx_prod
,
4977 tx_chain_prod
, sc
->tx_prod_bseq
);
4979 /* Start the transmit. */
4980 REG_WR16(sc
, MB_TX_CID_ADDR
+ BNX_L2CTX_TX_HOST_BIDX
, sc
->tx_prod
);
4981 REG_WR(sc
, MB_TX_CID_ADDR
+ BNX_L2CTX_TX_HOST_BSEQ
, sc
->tx_prod_bseq
);
4983 /* Set the tx timeout. */
4984 ifp
->if_timer
= BNX_TX_TIMEOUT
;
4990 /****************************************************************************/
4991 /* Handles any IOCTL calls from the operating system. */
4994 /* 0 for success, positive value for failure. */
4995 /****************************************************************************/
4997 bnx_ioctl(struct ifnet
*ifp
, u_long command
, void *data
)
4999 struct bnx_softc
*sc
= ifp
->if_softc
;
5000 struct ifreq
*ifr
= (struct ifreq
*) data
;
5001 struct mii_data
*mii
= &sc
->bnx_mii
;
5008 if ((error
= ifioctl_common(ifp
, command
, data
)) != 0)
5010 /* XXX set an ifflags callback and let ether_ioctl
5011 * handle all of this.
5013 if (ifp
->if_flags
& IFF_UP
) {
5014 if (ifp
->if_flags
& IFF_RUNNING
)
5018 } else if (ifp
->if_flags
& IFF_RUNNING
)
5024 DBPRINT(sc
, BNX_VERBOSE
, "bnx_phy_flags = 0x%08X\n",
5027 error
= ifmedia_ioctl(ifp
, ifr
, &mii
->mii_media
, command
);
5031 error
= ether_ioctl(ifp
, command
, data
);
5034 if (error
== ENETRESET
) {
5035 if (ifp
->if_flags
& IFF_RUNNING
)
5044 /****************************************************************************/
5045 /* Transmit timeout handler. */
5049 /****************************************************************************/
5051 bnx_watchdog(struct ifnet
*ifp
)
5053 struct bnx_softc
*sc
= ifp
->if_softc
;
5055 DBRUN(BNX_WARN_SEND
, bnx_dump_driver_state(sc
);
5056 bnx_dump_status_block(sc
));
5058 * If we are in this routine because of pause frames, then
5059 * don't reset the hardware.
5061 if (REG_RD(sc
, BNX_EMAC_TX_STATUS
) & BNX_EMAC_TX_STATUS_XOFFED
)
5064 aprint_error_dev(sc
->bnx_dev
, "Watchdog timeout -- resetting!\n");
5066 /* DBRUN(BNX_FATAL, bnx_breakpoint(sc)); */
5074 * Interrupt handler.
5076 /****************************************************************************/
5077 /* Main interrupt entry point. Verifies that the controller generated the */
5078 /* interrupt and then calls a separate routine for handle the various */
5079 /* interrupt causes (PHY, TX, RX). */
5082 /* 0 for success, positive value for failure. */
5083 /****************************************************************************/
5087 struct bnx_softc
*sc
;
5089 u_int32_t status_attn_bits
;
5090 const struct status_block
*sblk
;
5093 if (!device_is_active(sc
->bnx_dev
))
5096 ifp
= &sc
->bnx_ec
.ec_if
;
5098 DBRUNIF(1, sc
->interrupts_generated
++);
5100 bus_dmamap_sync(sc
->bnx_dmatag
, sc
->status_map
, 0,
5101 sc
->status_map
->dm_mapsize
, BUS_DMASYNC_POSTWRITE
);
5104 * If the hardware status block index
5105 * matches the last value read by the
5106 * driver and we haven't asserted our
5107 * interrupt then there's nothing to do.
5109 if ((sc
->status_block
->status_idx
== sc
->last_status_idx
) &&
5110 (REG_RD(sc
, BNX_PCICFG_MISC_STATUS
) &
5111 BNX_PCICFG_MISC_STATUS_INTA_VALUE
))
5114 /* Ack the interrupt and stop others from occuring. */
5115 REG_WR(sc
, BNX_PCICFG_INT_ACK_CMD
,
5116 BNX_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM
|
5117 BNX_PCICFG_INT_ACK_CMD_MASK_INT
);
5119 /* Keep processing data as long as there is work to do. */
5121 sblk
= sc
->status_block
;
5122 status_attn_bits
= sblk
->status_attn_bits
;
5124 DBRUNIF(DB_RANDOMTRUE(bnx_debug_unexpected_attention
),
5125 aprint_debug("Simulating unexpected status attention bit set.");
5126 status_attn_bits
= status_attn_bits
|
5127 STATUS_ATTN_BITS_PARITY_ERROR
);
5129 /* Was it a link change interrupt? */
5130 if ((status_attn_bits
& STATUS_ATTN_BITS_LINK_STATE
) !=
5131 (sblk
->status_attn_bits_ack
&
5132 STATUS_ATTN_BITS_LINK_STATE
))
5135 /* If any other attention is asserted then the chip is toast. */
5136 if (((status_attn_bits
& ~STATUS_ATTN_BITS_LINK_STATE
) !=
5137 (sblk
->status_attn_bits_ack
&
5138 ~STATUS_ATTN_BITS_LINK_STATE
))) {
5139 DBRUN(1, sc
->unexpected_attentions
++);
5142 "Fatal attention detected: 0x%08X\n",
5143 sblk
->status_attn_bits
);
5146 if (bnx_debug_unexpected_attention
== 0)
5147 bnx_breakpoint(sc
));
5153 /* Check for any completed RX frames. */
5154 if (sblk
->status_rx_quick_consumer_index0
!=
5158 /* Check for any completed TX frames. */
5159 if (sblk
->status_tx_quick_consumer_index0
!=
5163 /* Save the status block index value for use during the
5166 sc
->last_status_idx
= sblk
->status_idx
;
5168 /* Prevent speculative reads from getting ahead of the
5171 bus_space_barrier(sc
->bnx_btag
, sc
->bnx_bhandle
, 0, 0,
5172 BUS_SPACE_BARRIER_READ
);
5174 /* If there's no work left then exit the isr. */
5175 if ((sblk
->status_rx_quick_consumer_index0
==
5177 (sblk
->status_tx_quick_consumer_index0
==
5182 bus_dmamap_sync(sc
->bnx_dmatag
, sc
->status_map
, 0,
5183 sc
->status_map
->dm_mapsize
, BUS_DMASYNC_PREWRITE
);
5185 /* Re-enable interrupts. */
5186 REG_WR(sc
, BNX_PCICFG_INT_ACK_CMD
,
5187 BNX_PCICFG_INT_ACK_CMD_INDEX_VALID
| sc
->last_status_idx
|
5188 BNX_PCICFG_INT_ACK_CMD_MASK_INT
);
5189 REG_WR(sc
, BNX_PCICFG_INT_ACK_CMD
,
5190 BNX_PCICFG_INT_ACK_CMD_INDEX_VALID
| sc
->last_status_idx
);
5192 /* Handle any frames that arrived while handling the interrupt. */
5193 if (!IFQ_IS_EMPTY(&ifp
->if_snd
))
5199 /****************************************************************************/
5200 /* Programs the various packet receive modes (broadcast and multicast). */
5204 /****************************************************************************/
5206 bnx_iff(struct bnx_softc
*sc
)
5208 struct ethercom
*ec
= &sc
->bnx_ec
;
5209 struct ifnet
*ifp
= &ec
->ec_if
;
5210 struct ether_multi
*enm
;
5211 struct ether_multistep step
;
5212 u_int32_t hashes
[NUM_MC_HASH_REGISTERS
] = { 0, 0, 0, 0, 0, 0, 0, 0 };
5213 u_int32_t rx_mode
, sort_mode
;
5216 /* Initialize receive mode default settings. */
5217 rx_mode
= sc
->rx_mode
& ~(BNX_EMAC_RX_MODE_PROMISCUOUS
|
5218 BNX_EMAC_RX_MODE_KEEP_VLAN_TAG
);
5219 sort_mode
= 1 | BNX_RPM_SORT_USER0_BC_EN
;
5220 ifp
->if_flags
&= ~IFF_ALLMULTI
;
5223 * ASF/IPMI/UMP firmware requires that VLAN tag stripping
5226 if (!(sc
->bnx_flags
& BNX_MFW_ENABLE_FLAG
))
5227 rx_mode
|= BNX_EMAC_RX_MODE_KEEP_VLAN_TAG
;
5230 * Check for promiscuous, all multicast, or selected
5231 * multicast address filtering.
5233 if (ifp
->if_flags
& IFF_PROMISC
) {
5234 DBPRINT(sc
, BNX_INFO
, "Enabling promiscuous mode.\n");
5236 ifp
->if_flags
|= IFF_ALLMULTI
;
5237 /* Enable promiscuous mode. */
5238 rx_mode
|= BNX_EMAC_RX_MODE_PROMISCUOUS
;
5239 sort_mode
|= BNX_RPM_SORT_USER0_PROM_EN
;
5240 } else if (ifp
->if_flags
& IFF_ALLMULTI
) {
5242 DBPRINT(sc
, BNX_INFO
, "Enabling all multicast mode.\n");
5244 ifp
->if_flags
|= IFF_ALLMULTI
;
5245 /* Enable all multicast addresses. */
5246 for (i
= 0; i
< NUM_MC_HASH_REGISTERS
; i
++)
5247 REG_WR(sc
, BNX_EMAC_MULTICAST_HASH0
+ (i
* 4),
5249 sort_mode
|= BNX_RPM_SORT_USER0_MC_EN
;
5251 /* Accept one or more multicast(s). */
5252 DBPRINT(sc
, BNX_INFO
, "Enabling selective multicast mode.\n");
5254 ETHER_FIRST_MULTI(step
, ec
, enm
);
5255 while (enm
!= NULL
) {
5256 if (memcmp(enm
->enm_addrlo
, enm
->enm_addrhi
,
5260 h
= ether_crc32_le(enm
->enm_addrlo
, ETHER_ADDR_LEN
) &
5262 hashes
[(h
& 0xE0) >> 5] |= 1 << (h
& 0x1F);
5263 ETHER_NEXT_MULTI(step
, enm
);
5266 for (i
= 0; i
< NUM_MC_HASH_REGISTERS
; i
++)
5267 REG_WR(sc
, BNX_EMAC_MULTICAST_HASH0
+ (i
* 4),
5270 sort_mode
|= BNX_RPM_SORT_USER0_MC_HSH_EN
;
5273 /* Only make changes if the recive mode has actually changed. */
5274 if (rx_mode
!= sc
->rx_mode
) {
5275 DBPRINT(sc
, BNX_VERBOSE
, "Enabling new receive mode: 0x%08X\n",
5278 sc
->rx_mode
= rx_mode
;
5279 REG_WR(sc
, BNX_EMAC_RX_MODE
, rx_mode
);
5282 /* Disable and clear the exisitng sort before enabling a new sort. */
5283 REG_WR(sc
, BNX_RPM_SORT_USER0
, 0x0);
5284 REG_WR(sc
, BNX_RPM_SORT_USER0
, sort_mode
);
5285 REG_WR(sc
, BNX_RPM_SORT_USER0
, sort_mode
| BNX_RPM_SORT_USER0_ENA
);
5288 /****************************************************************************/
5289 /* Called periodically to updates statistics from the controllers */
5290 /* statistics block. */
5294 /****************************************************************************/
5296 bnx_stats_update(struct bnx_softc
*sc
)
5298 struct ifnet
*ifp
= &sc
->bnx_ec
.ec_if
;
5299 struct statistics_block
*stats
;
5301 DBPRINT(sc
, BNX_EXCESSIVE
, "Entering %s()\n", __func__
);
5302 bus_dmamap_sync(sc
->bnx_dmatag
, sc
->status_map
, 0, BNX_STATUS_BLK_SZ
,
5303 BUS_DMASYNC_POSTREAD
);
5305 stats
= (struct statistics_block
*)sc
->stats_block
;
5308 * Update the interface statistics from the
5309 * hardware statistics.
5311 ifp
->if_collisions
= (u_long
)stats
->stat_EtherStatsCollisions
;
5313 ifp
->if_ierrors
= (u_long
)stats
->stat_EtherStatsUndersizePkts
+
5314 (u_long
)stats
->stat_EtherStatsOverrsizePkts
+
5315 (u_long
)stats
->stat_IfInMBUFDiscards
+
5316 (u_long
)stats
->stat_Dot3StatsAlignmentErrors
+
5317 (u_long
)stats
->stat_Dot3StatsFCSErrors
;
5319 ifp
->if_oerrors
= (u_long
)
5320 stats
->stat_emac_tx_stat_dot3statsinternalmactransmiterrors
+
5321 (u_long
)stats
->stat_Dot3StatsExcessiveCollisions
+
5322 (u_long
)stats
->stat_Dot3StatsLateCollisions
;
5325 * Certain controllers don't report
5326 * carrier sense errors correctly.
5327 * See errata E11_5708CA0_1165.
5329 if (!(BNX_CHIP_NUM(sc
) == BNX_CHIP_NUM_5706
) &&
5330 !(BNX_CHIP_ID(sc
) == BNX_CHIP_ID_5708_A0
))
5331 ifp
->if_oerrors
+= (u_long
) stats
->stat_Dot3StatsCarrierSenseErrors
;
5334 * Update the sysctl statistics from the
5335 * hardware statistics.
5337 sc
->stat_IfHCInOctets
= ((u_int64_t
)stats
->stat_IfHCInOctets_hi
<< 32) +
5338 (u_int64_t
) stats
->stat_IfHCInOctets_lo
;
5340 sc
->stat_IfHCInBadOctets
=
5341 ((u_int64_t
) stats
->stat_IfHCInBadOctets_hi
<< 32) +
5342 (u_int64_t
) stats
->stat_IfHCInBadOctets_lo
;
5344 sc
->stat_IfHCOutOctets
=
5345 ((u_int64_t
) stats
->stat_IfHCOutOctets_hi
<< 32) +
5346 (u_int64_t
) stats
->stat_IfHCOutOctets_lo
;
5348 sc
->stat_IfHCOutBadOctets
=
5349 ((u_int64_t
) stats
->stat_IfHCOutBadOctets_hi
<< 32) +
5350 (u_int64_t
) stats
->stat_IfHCOutBadOctets_lo
;
5352 sc
->stat_IfHCInUcastPkts
=
5353 ((u_int64_t
) stats
->stat_IfHCInUcastPkts_hi
<< 32) +
5354 (u_int64_t
) stats
->stat_IfHCInUcastPkts_lo
;
5356 sc
->stat_IfHCInMulticastPkts
=
5357 ((u_int64_t
) stats
->stat_IfHCInMulticastPkts_hi
<< 32) +
5358 (u_int64_t
) stats
->stat_IfHCInMulticastPkts_lo
;
5360 sc
->stat_IfHCInBroadcastPkts
=
5361 ((u_int64_t
) stats
->stat_IfHCInBroadcastPkts_hi
<< 32) +
5362 (u_int64_t
) stats
->stat_IfHCInBroadcastPkts_lo
;
5364 sc
->stat_IfHCOutUcastPkts
=
5365 ((u_int64_t
) stats
->stat_IfHCOutUcastPkts_hi
<< 32) +
5366 (u_int64_t
) stats
->stat_IfHCOutUcastPkts_lo
;
5368 sc
->stat_IfHCOutMulticastPkts
=
5369 ((u_int64_t
) stats
->stat_IfHCOutMulticastPkts_hi
<< 32) +
5370 (u_int64_t
) stats
->stat_IfHCOutMulticastPkts_lo
;
5372 sc
->stat_IfHCOutBroadcastPkts
=
5373 ((u_int64_t
) stats
->stat_IfHCOutBroadcastPkts_hi
<< 32) +
5374 (u_int64_t
) stats
->stat_IfHCOutBroadcastPkts_lo
;
5376 sc
->stat_emac_tx_stat_dot3statsinternalmactransmiterrors
=
5377 stats
->stat_emac_tx_stat_dot3statsinternalmactransmiterrors
;
5379 sc
->stat_Dot3StatsCarrierSenseErrors
=
5380 stats
->stat_Dot3StatsCarrierSenseErrors
;
5382 sc
->stat_Dot3StatsFCSErrors
= stats
->stat_Dot3StatsFCSErrors
;
5384 sc
->stat_Dot3StatsAlignmentErrors
=
5385 stats
->stat_Dot3StatsAlignmentErrors
;
5387 sc
->stat_Dot3StatsSingleCollisionFrames
=
5388 stats
->stat_Dot3StatsSingleCollisionFrames
;
5390 sc
->stat_Dot3StatsMultipleCollisionFrames
=
5391 stats
->stat_Dot3StatsMultipleCollisionFrames
;
5393 sc
->stat_Dot3StatsDeferredTransmissions
=
5394 stats
->stat_Dot3StatsDeferredTransmissions
;
5396 sc
->stat_Dot3StatsExcessiveCollisions
=
5397 stats
->stat_Dot3StatsExcessiveCollisions
;
5399 sc
->stat_Dot3StatsLateCollisions
= stats
->stat_Dot3StatsLateCollisions
;
5401 sc
->stat_EtherStatsCollisions
= stats
->stat_EtherStatsCollisions
;
5403 sc
->stat_EtherStatsFragments
= stats
->stat_EtherStatsFragments
;
5405 sc
->stat_EtherStatsJabbers
= stats
->stat_EtherStatsJabbers
;
5407 sc
->stat_EtherStatsUndersizePkts
= stats
->stat_EtherStatsUndersizePkts
;
5409 sc
->stat_EtherStatsOverrsizePkts
= stats
->stat_EtherStatsOverrsizePkts
;
5411 sc
->stat_EtherStatsPktsRx64Octets
=
5412 stats
->stat_EtherStatsPktsRx64Octets
;
5414 sc
->stat_EtherStatsPktsRx65Octetsto127Octets
=
5415 stats
->stat_EtherStatsPktsRx65Octetsto127Octets
;
5417 sc
->stat_EtherStatsPktsRx128Octetsto255Octets
=
5418 stats
->stat_EtherStatsPktsRx128Octetsto255Octets
;
5420 sc
->stat_EtherStatsPktsRx256Octetsto511Octets
=
5421 stats
->stat_EtherStatsPktsRx256Octetsto511Octets
;
5423 sc
->stat_EtherStatsPktsRx512Octetsto1023Octets
=
5424 stats
->stat_EtherStatsPktsRx512Octetsto1023Octets
;
5426 sc
->stat_EtherStatsPktsRx1024Octetsto1522Octets
=
5427 stats
->stat_EtherStatsPktsRx1024Octetsto1522Octets
;
5429 sc
->stat_EtherStatsPktsRx1523Octetsto9022Octets
=
5430 stats
->stat_EtherStatsPktsRx1523Octetsto9022Octets
;
5432 sc
->stat_EtherStatsPktsTx64Octets
=
5433 stats
->stat_EtherStatsPktsTx64Octets
;
5435 sc
->stat_EtherStatsPktsTx65Octetsto127Octets
=
5436 stats
->stat_EtherStatsPktsTx65Octetsto127Octets
;
5438 sc
->stat_EtherStatsPktsTx128Octetsto255Octets
=
5439 stats
->stat_EtherStatsPktsTx128Octetsto255Octets
;
5441 sc
->stat_EtherStatsPktsTx256Octetsto511Octets
=
5442 stats
->stat_EtherStatsPktsTx256Octetsto511Octets
;
5444 sc
->stat_EtherStatsPktsTx512Octetsto1023Octets
=
5445 stats
->stat_EtherStatsPktsTx512Octetsto1023Octets
;
5447 sc
->stat_EtherStatsPktsTx1024Octetsto1522Octets
=
5448 stats
->stat_EtherStatsPktsTx1024Octetsto1522Octets
;
5450 sc
->stat_EtherStatsPktsTx1523Octetsto9022Octets
=
5451 stats
->stat_EtherStatsPktsTx1523Octetsto9022Octets
;
5453 sc
->stat_XonPauseFramesReceived
= stats
->stat_XonPauseFramesReceived
;
5455 sc
->stat_XoffPauseFramesReceived
= stats
->stat_XoffPauseFramesReceived
;
5457 sc
->stat_OutXonSent
= stats
->stat_OutXonSent
;
5459 sc
->stat_OutXoffSent
= stats
->stat_OutXoffSent
;
5461 sc
->stat_FlowControlDone
= stats
->stat_FlowControlDone
;
5463 sc
->stat_MacControlFramesReceived
=
5464 stats
->stat_MacControlFramesReceived
;
5466 sc
->stat_XoffStateEntered
= stats
->stat_XoffStateEntered
;
5468 sc
->stat_IfInFramesL2FilterDiscards
=
5469 stats
->stat_IfInFramesL2FilterDiscards
;
5471 sc
->stat_IfInRuleCheckerDiscards
= stats
->stat_IfInRuleCheckerDiscards
;
5473 sc
->stat_IfInFTQDiscards
= stats
->stat_IfInFTQDiscards
;
5475 sc
->stat_IfInMBUFDiscards
= stats
->stat_IfInMBUFDiscards
;
5477 sc
->stat_IfInRuleCheckerP4Hit
= stats
->stat_IfInRuleCheckerP4Hit
;
5479 sc
->stat_CatchupInRuleCheckerDiscards
=
5480 stats
->stat_CatchupInRuleCheckerDiscards
;
5482 sc
->stat_CatchupInFTQDiscards
= stats
->stat_CatchupInFTQDiscards
;
5484 sc
->stat_CatchupInMBUFDiscards
= stats
->stat_CatchupInMBUFDiscards
;
5486 sc
->stat_CatchupInRuleCheckerP4Hit
=
5487 stats
->stat_CatchupInRuleCheckerP4Hit
;
5489 DBPRINT(sc
, BNX_EXCESSIVE
, "Exiting %s()\n", __func__
);
5495 struct bnx_softc
*sc
= xsc
;
5496 struct mii_data
*mii
;
5498 u_int16_t prod
, chain_prod
;
5499 u_int32_t prod_bseq
;
5502 /* Tell the firmware that the driver is still running. */
5504 msg
= (u_int32_t
)BNX_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE
;
5506 msg
= (u_int32_t
)++sc
->bnx_fw_drv_pulse_wr_seq
;
5508 REG_WR_IND(sc
, sc
->bnx_shmem_base
+ BNX_DRV_PULSE_MB
, msg
);
5510 /* Update the statistics from the hardware statistics block. */
5511 bnx_stats_update(sc
);
5513 /* Schedule the next tick. */
5514 callout_reset(&sc
->bnx_timeout
, hz
, bnx_tick
, sc
);
5519 /* try to get more RX buffers, just in case */
5521 prod_bseq
= sc
->rx_prod_bseq
;
5522 chain_prod
= RX_CHAIN_IDX(prod
);
5523 bnx_get_buf(sc
, &prod
, &chain_prod
, &prod_bseq
);
5525 sc
->rx_prod_bseq
= prod_bseq
;
5530 /****************************************************************************/
5531 /* BNX Debug Routines */
5532 /****************************************************************************/
5535 /****************************************************************************/
5536 /* Prints out information about an mbuf. */
5540 /****************************************************************************/
5542 bnx_dump_mbuf(struct bnx_softc
*sc
, struct mbuf
*m
)
5544 struct mbuf
*mp
= m
;
5547 /* Index out of range. */
5548 aprint_error("mbuf ptr is null!\n");
5553 aprint_debug("mbuf: vaddr = %p, m_len = %d, m_flags = ",
5556 if (mp
->m_flags
& M_EXT
)
5557 aprint_debug("M_EXT ");
5558 if (mp
->m_flags
& M_PKTHDR
)
5559 aprint_debug("M_PKTHDR ");
5562 if (mp
->m_flags
& M_EXT
)
5563 aprint_debug("- m_ext: vaddr = %p, ext_size = 0x%04zX\n",
5564 mp
, mp
->m_ext
.ext_size
);
5570 /****************************************************************************/
5571 /* Prints out the mbufs in the TX mbuf chain. */
5575 /****************************************************************************/
5577 bnx_dump_tx_mbuf_chain(struct bnx_softc
*sc
, int chain_prod
, int count
)
5583 aprint_debug_dev(sc
->bnx_dev
,
5584 "----------------------------"
5586 "----------------------------\n");
5588 for (i
= 0; i
< count
; i
++) {
5589 m
= sc
->tx_mbuf_ptr
[chain_prod
];
5590 BNX_PRINTF(sc
, "txmbuf[%d]\n", chain_prod
);
5591 bnx_dump_mbuf(sc
, m
);
5592 chain_prod
= TX_CHAIN_IDX(NEXT_TX_BD(chain_prod
));
5595 aprint_debug_dev(sc
->bnx_dev
,
5596 "--------------------------------------------"
5597 "----------------------------\n");
5602 * This routine prints the RX mbuf chain.
5605 bnx_dump_rx_mbuf_chain(struct bnx_softc
*sc
, int chain_prod
, int count
)
5610 aprint_debug_dev(sc
->bnx_dev
,
5611 "----------------------------"
5613 "----------------------------\n");
5615 for (i
= 0; i
< count
; i
++) {
5616 m
= sc
->rx_mbuf_ptr
[chain_prod
];
5617 BNX_PRINTF(sc
, "rxmbuf[0x%04X]\n", chain_prod
);
5618 bnx_dump_mbuf(sc
, m
);
5619 chain_prod
= RX_CHAIN_IDX(NEXT_RX_BD(chain_prod
));
5623 aprint_debug_dev(sc
->bnx_dev
,
5624 "--------------------------------------------"
5625 "----------------------------\n");
5629 bnx_dump_txbd(struct bnx_softc
*sc
, int idx
, struct tx_bd
*txbd
)
5631 if (idx
> MAX_TX_BD
)
5632 /* Index out of range. */
5633 BNX_PRINTF(sc
, "tx_bd[0x%04X]: Invalid tx_bd index!\n", idx
);
5634 else if ((idx
& USABLE_TX_BD_PER_PAGE
) == USABLE_TX_BD_PER_PAGE
)
5635 /* TX Chain page pointer. */
5636 BNX_PRINTF(sc
, "tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain "
5637 "page pointer\n", idx
, txbd
->tx_bd_haddr_hi
,
5638 txbd
->tx_bd_haddr_lo
);
5640 /* Normal tx_bd entry. */
5641 BNX_PRINTF(sc
, "tx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = "
5642 "0x%08X, vlan tag = 0x%4X, flags = 0x%08X\n", idx
,
5643 txbd
->tx_bd_haddr_hi
, txbd
->tx_bd_haddr_lo
,
5644 txbd
->tx_bd_mss_nbytes
, txbd
->tx_bd_vlan_tag
,
5649 bnx_dump_rxbd(struct bnx_softc
*sc
, int idx
, struct rx_bd
*rxbd
)
5651 if (idx
> MAX_RX_BD
)
5652 /* Index out of range. */
5653 BNX_PRINTF(sc
, "rx_bd[0x%04X]: Invalid rx_bd index!\n", idx
);
5654 else if ((idx
& USABLE_RX_BD_PER_PAGE
) == USABLE_RX_BD_PER_PAGE
)
5655 /* TX Chain page pointer. */
5656 BNX_PRINTF(sc
, "rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
5657 "pointer\n", idx
, rxbd
->rx_bd_haddr_hi
,
5658 rxbd
->rx_bd_haddr_lo
);
5660 /* Normal tx_bd entry. */
5661 BNX_PRINTF(sc
, "rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = "
5662 "0x%08X, flags = 0x%08X\n", idx
,
5663 rxbd
->rx_bd_haddr_hi
, rxbd
->rx_bd_haddr_lo
,
5664 rxbd
->rx_bd_len
, rxbd
->rx_bd_flags
);
5668 bnx_dump_l2fhdr(struct bnx_softc
*sc
, int idx
, struct l2_fhdr
*l2fhdr
)
5670 BNX_PRINTF(sc
, "l2_fhdr[0x%04X]: status = 0x%08X, "
5671 "pkt_len = 0x%04X, vlan = 0x%04x, ip_xsum = 0x%04X, "
5672 "tcp_udp_xsum = 0x%04X\n", idx
,
5673 l2fhdr
->l2_fhdr_status
, l2fhdr
->l2_fhdr_pkt_len
,
5674 l2fhdr
->l2_fhdr_vlan_tag
, l2fhdr
->l2_fhdr_ip_xsum
,
5675 l2fhdr
->l2_fhdr_tcp_udp_xsum
);
5679 * This routine prints the TX chain.
5682 bnx_dump_tx_chain(struct bnx_softc
*sc
, int tx_prod
, int count
)
5687 /* First some info about the tx_bd chain structure. */
5688 aprint_debug_dev(sc
->bnx_dev
,
5689 "----------------------------"
5691 "----------------------------\n");
5694 "page size = 0x%08X, tx chain pages = 0x%08X\n",
5695 (u_int32_t
)BCM_PAGE_SIZE
, (u_int32_t
) TX_PAGES
);
5698 "tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
5699 (u_int32_t
)TOTAL_TX_BD_PER_PAGE
, (u_int32_t
)USABLE_TX_BD_PER_PAGE
);
5701 BNX_PRINTF(sc
, "total tx_bd = 0x%08X\n", TOTAL_TX_BD
);
5703 aprint_error_dev(sc
->bnx_dev
, ""
5704 "-----------------------------"
5706 "-----------------------------\n");
5708 /* Now print out the tx_bd's themselves. */
5709 for (i
= 0; i
< count
; i
++) {
5710 txbd
= &sc
->tx_bd_chain
[TX_PAGE(tx_prod
)][TX_IDX(tx_prod
)];
5711 bnx_dump_txbd(sc
, tx_prod
, txbd
);
5712 tx_prod
= TX_CHAIN_IDX(NEXT_TX_BD(tx_prod
));
5715 aprint_debug_dev(sc
->bnx_dev
,
5716 "-----------------------------"
5718 "-----------------------------\n");
5722 * This routine prints the RX chain.
5725 bnx_dump_rx_chain(struct bnx_softc
*sc
, int rx_prod
, int count
)
5730 /* First some info about the tx_bd chain structure. */
5731 aprint_debug_dev(sc
->bnx_dev
,
5732 "----------------------------"
5734 "----------------------------\n");
5736 aprint_debug_dev(sc
->bnx_dev
, "----- RX_BD Chain -----\n");
5739 "page size = 0x%08X, rx chain pages = 0x%08X\n",
5740 (u_int32_t
)BCM_PAGE_SIZE
, (u_int32_t
)RX_PAGES
);
5743 "rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
5744 (u_int32_t
)TOTAL_RX_BD_PER_PAGE
, (u_int32_t
)USABLE_RX_BD_PER_PAGE
);
5746 BNX_PRINTF(sc
, "total rx_bd = 0x%08X\n", TOTAL_RX_BD
);
5748 aprint_error_dev(sc
->bnx_dev
,
5749 "----------------------------"
5751 "----------------------------\n");
5753 /* Now print out the rx_bd's themselves. */
5754 for (i
= 0; i
< count
; i
++) {
5755 rxbd
= &sc
->rx_bd_chain
[RX_PAGE(rx_prod
)][RX_IDX(rx_prod
)];
5756 bnx_dump_rxbd(sc
, rx_prod
, rxbd
);
5757 rx_prod
= RX_CHAIN_IDX(NEXT_RX_BD(rx_prod
));
5760 aprint_debug_dev(sc
->bnx_dev
,
5761 "----------------------------"
5763 "----------------------------\n");
5767 * This routine prints the status block.
5770 bnx_dump_status_block(struct bnx_softc
*sc
)
5772 struct status_block
*sblk
;
5773 bus_dmamap_sync(sc
->bnx_dmatag
, sc
->status_map
, 0, BNX_STATUS_BLK_SZ
,
5774 BUS_DMASYNC_POSTREAD
);
5776 sblk
= sc
->status_block
;
5778 aprint_debug_dev(sc
->bnx_dev
, "----------------------------- Status Block "
5779 "-----------------------------\n");
5782 "attn_bits = 0x%08X, attn_bits_ack = 0x%08X, index = 0x%04X\n",
5783 sblk
->status_attn_bits
, sblk
->status_attn_bits_ack
,
5786 BNX_PRINTF(sc
, "rx_cons0 = 0x%08X, tx_cons0 = 0x%08X\n",
5787 sblk
->status_rx_quick_consumer_index0
,
5788 sblk
->status_tx_quick_consumer_index0
);
5790 BNX_PRINTF(sc
, "status_idx = 0x%04X\n", sblk
->status_idx
);
5792 /* Theses indices are not used for normal L2 drivers. */
5793 if (sblk
->status_rx_quick_consumer_index1
||
5794 sblk
->status_tx_quick_consumer_index1
)
5795 BNX_PRINTF(sc
, "rx_cons1 = 0x%08X, tx_cons1 = 0x%08X\n",
5796 sblk
->status_rx_quick_consumer_index1
,
5797 sblk
->status_tx_quick_consumer_index1
);
5799 if (sblk
->status_rx_quick_consumer_index2
||
5800 sblk
->status_tx_quick_consumer_index2
)
5801 BNX_PRINTF(sc
, "rx_cons2 = 0x%08X, tx_cons2 = 0x%08X\n",
5802 sblk
->status_rx_quick_consumer_index2
,
5803 sblk
->status_tx_quick_consumer_index2
);
5805 if (sblk
->status_rx_quick_consumer_index3
||
5806 sblk
->status_tx_quick_consumer_index3
)
5807 BNX_PRINTF(sc
, "rx_cons3 = 0x%08X, tx_cons3 = 0x%08X\n",
5808 sblk
->status_rx_quick_consumer_index3
,
5809 sblk
->status_tx_quick_consumer_index3
);
5811 if (sblk
->status_rx_quick_consumer_index4
||
5812 sblk
->status_rx_quick_consumer_index5
)
5813 BNX_PRINTF(sc
, "rx_cons4 = 0x%08X, rx_cons5 = 0x%08X\n",
5814 sblk
->status_rx_quick_consumer_index4
,
5815 sblk
->status_rx_quick_consumer_index5
);
5817 if (sblk
->status_rx_quick_consumer_index6
||
5818 sblk
->status_rx_quick_consumer_index7
)
5819 BNX_PRINTF(sc
, "rx_cons6 = 0x%08X, rx_cons7 = 0x%08X\n",
5820 sblk
->status_rx_quick_consumer_index6
,
5821 sblk
->status_rx_quick_consumer_index7
);
5823 if (sblk
->status_rx_quick_consumer_index8
||
5824 sblk
->status_rx_quick_consumer_index9
)
5825 BNX_PRINTF(sc
, "rx_cons8 = 0x%08X, rx_cons9 = 0x%08X\n",
5826 sblk
->status_rx_quick_consumer_index8
,
5827 sblk
->status_rx_quick_consumer_index9
);
5829 if (sblk
->status_rx_quick_consumer_index10
||
5830 sblk
->status_rx_quick_consumer_index11
)
5831 BNX_PRINTF(sc
, "rx_cons10 = 0x%08X, rx_cons11 = 0x%08X\n",
5832 sblk
->status_rx_quick_consumer_index10
,
5833 sblk
->status_rx_quick_consumer_index11
);
5835 if (sblk
->status_rx_quick_consumer_index12
||
5836 sblk
->status_rx_quick_consumer_index13
)
5837 BNX_PRINTF(sc
, "rx_cons12 = 0x%08X, rx_cons13 = 0x%08X\n",
5838 sblk
->status_rx_quick_consumer_index12
,
5839 sblk
->status_rx_quick_consumer_index13
);
5841 if (sblk
->status_rx_quick_consumer_index14
||
5842 sblk
->status_rx_quick_consumer_index15
)
5843 BNX_PRINTF(sc
, "rx_cons14 = 0x%08X, rx_cons15 = 0x%08X\n",
5844 sblk
->status_rx_quick_consumer_index14
,
5845 sblk
->status_rx_quick_consumer_index15
);
5847 if (sblk
->status_completion_producer_index
||
5848 sblk
->status_cmd_consumer_index
)
5849 BNX_PRINTF(sc
, "com_prod = 0x%08X, cmd_cons = 0x%08X\n",
5850 sblk
->status_completion_producer_index
,
5851 sblk
->status_cmd_consumer_index
);
5853 aprint_debug_dev(sc
->bnx_dev
, "-------------------------------------------"
5854 "-----------------------------\n");
5858 * This routine prints the statistics block.
5861 bnx_dump_stats_block(struct bnx_softc
*sc
)
5863 struct statistics_block
*sblk
;
5864 bus_dmamap_sync(sc
->bnx_dmatag
, sc
->status_map
, 0, BNX_STATUS_BLK_SZ
,
5865 BUS_DMASYNC_POSTREAD
);
5867 sblk
= sc
->stats_block
;
5869 aprint_debug_dev(sc
->bnx_dev
, ""
5870 "-----------------------------"
5872 "-----------------------------\n");
5874 BNX_PRINTF(sc
, "IfHcInOctets = 0x%08X:%08X, "
5875 "IfHcInBadOctets = 0x%08X:%08X\n",
5876 sblk
->stat_IfHCInOctets_hi
, sblk
->stat_IfHCInOctets_lo
,
5877 sblk
->stat_IfHCInBadOctets_hi
, sblk
->stat_IfHCInBadOctets_lo
);
5879 BNX_PRINTF(sc
, "IfHcOutOctets = 0x%08X:%08X, "
5880 "IfHcOutBadOctets = 0x%08X:%08X\n",
5881 sblk
->stat_IfHCOutOctets_hi
, sblk
->stat_IfHCOutOctets_lo
,
5882 sblk
->stat_IfHCOutBadOctets_hi
, sblk
->stat_IfHCOutBadOctets_lo
);
5884 BNX_PRINTF(sc
, "IfHcInUcastPkts = 0x%08X:%08X, "
5885 "IfHcInMulticastPkts = 0x%08X:%08X\n",
5886 sblk
->stat_IfHCInUcastPkts_hi
, sblk
->stat_IfHCInUcastPkts_lo
,
5887 sblk
->stat_IfHCInMulticastPkts_hi
,
5888 sblk
->stat_IfHCInMulticastPkts_lo
);
5890 BNX_PRINTF(sc
, "IfHcInBroadcastPkts = 0x%08X:%08X, "
5891 "IfHcOutUcastPkts = 0x%08X:%08X\n",
5892 sblk
->stat_IfHCInBroadcastPkts_hi
,
5893 sblk
->stat_IfHCInBroadcastPkts_lo
,
5894 sblk
->stat_IfHCOutUcastPkts_hi
,
5895 sblk
->stat_IfHCOutUcastPkts_lo
);
5897 BNX_PRINTF(sc
, "IfHcOutMulticastPkts = 0x%08X:%08X, "
5898 "IfHcOutBroadcastPkts = 0x%08X:%08X\n",
5899 sblk
->stat_IfHCOutMulticastPkts_hi
,
5900 sblk
->stat_IfHCOutMulticastPkts_lo
,
5901 sblk
->stat_IfHCOutBroadcastPkts_hi
,
5902 sblk
->stat_IfHCOutBroadcastPkts_lo
);
5904 if (sblk
->stat_emac_tx_stat_dot3statsinternalmactransmiterrors
)
5905 BNX_PRINTF(sc
, "0x%08X : "
5906 "emac_tx_stat_dot3statsinternalmactransmiterrors\n",
5907 sblk
->stat_emac_tx_stat_dot3statsinternalmactransmiterrors
);
5909 if (sblk
->stat_Dot3StatsCarrierSenseErrors
)
5910 BNX_PRINTF(sc
, "0x%08X : Dot3StatsCarrierSenseErrors\n",
5911 sblk
->stat_Dot3StatsCarrierSenseErrors
);
5913 if (sblk
->stat_Dot3StatsFCSErrors
)
5914 BNX_PRINTF(sc
, "0x%08X : Dot3StatsFCSErrors\n",
5915 sblk
->stat_Dot3StatsFCSErrors
);
5917 if (sblk
->stat_Dot3StatsAlignmentErrors
)
5918 BNX_PRINTF(sc
, "0x%08X : Dot3StatsAlignmentErrors\n",
5919 sblk
->stat_Dot3StatsAlignmentErrors
);
5921 if (sblk
->stat_Dot3StatsSingleCollisionFrames
)
5922 BNX_PRINTF(sc
, "0x%08X : Dot3StatsSingleCollisionFrames\n",
5923 sblk
->stat_Dot3StatsSingleCollisionFrames
);
5925 if (sblk
->stat_Dot3StatsMultipleCollisionFrames
)
5926 BNX_PRINTF(sc
, "0x%08X : Dot3StatsMultipleCollisionFrames\n",
5927 sblk
->stat_Dot3StatsMultipleCollisionFrames
);
5929 if (sblk
->stat_Dot3StatsDeferredTransmissions
)
5930 BNX_PRINTF(sc
, "0x%08X : Dot3StatsDeferredTransmissions\n",
5931 sblk
->stat_Dot3StatsDeferredTransmissions
);
5933 if (sblk
->stat_Dot3StatsExcessiveCollisions
)
5934 BNX_PRINTF(sc
, "0x%08X : Dot3StatsExcessiveCollisions\n",
5935 sblk
->stat_Dot3StatsExcessiveCollisions
);
5937 if (sblk
->stat_Dot3StatsLateCollisions
)
5938 BNX_PRINTF(sc
, "0x%08X : Dot3StatsLateCollisions\n",
5939 sblk
->stat_Dot3StatsLateCollisions
);
5941 if (sblk
->stat_EtherStatsCollisions
)
5942 BNX_PRINTF(sc
, "0x%08X : EtherStatsCollisions\n",
5943 sblk
->stat_EtherStatsCollisions
);
5945 if (sblk
->stat_EtherStatsFragments
)
5946 BNX_PRINTF(sc
, "0x%08X : EtherStatsFragments\n",
5947 sblk
->stat_EtherStatsFragments
);
5949 if (sblk
->stat_EtherStatsJabbers
)
5950 BNX_PRINTF(sc
, "0x%08X : EtherStatsJabbers\n",
5951 sblk
->stat_EtherStatsJabbers
);
5953 if (sblk
->stat_EtherStatsUndersizePkts
)
5954 BNX_PRINTF(sc
, "0x%08X : EtherStatsUndersizePkts\n",
5955 sblk
->stat_EtherStatsUndersizePkts
);
5957 if (sblk
->stat_EtherStatsOverrsizePkts
)
5958 BNX_PRINTF(sc
, "0x%08X : EtherStatsOverrsizePkts\n",
5959 sblk
->stat_EtherStatsOverrsizePkts
);
5961 if (sblk
->stat_EtherStatsPktsRx64Octets
)
5962 BNX_PRINTF(sc
, "0x%08X : EtherStatsPktsRx64Octets\n",
5963 sblk
->stat_EtherStatsPktsRx64Octets
);
5965 if (sblk
->stat_EtherStatsPktsRx65Octetsto127Octets
)
5966 BNX_PRINTF(sc
, "0x%08X : EtherStatsPktsRx65Octetsto127Octets\n",
5967 sblk
->stat_EtherStatsPktsRx65Octetsto127Octets
);
5969 if (sblk
->stat_EtherStatsPktsRx128Octetsto255Octets
)
5970 BNX_PRINTF(sc
, "0x%08X : "
5971 "EtherStatsPktsRx128Octetsto255Octets\n",
5972 sblk
->stat_EtherStatsPktsRx128Octetsto255Octets
);
5974 if (sblk
->stat_EtherStatsPktsRx256Octetsto511Octets
)
5975 BNX_PRINTF(sc
, "0x%08X : "
5976 "EtherStatsPktsRx256Octetsto511Octets\n",
5977 sblk
->stat_EtherStatsPktsRx256Octetsto511Octets
);
5979 if (sblk
->stat_EtherStatsPktsRx512Octetsto1023Octets
)
5980 BNX_PRINTF(sc
, "0x%08X : "
5981 "EtherStatsPktsRx512Octetsto1023Octets\n",
5982 sblk
->stat_EtherStatsPktsRx512Octetsto1023Octets
);
5984 if (sblk
->stat_EtherStatsPktsRx1024Octetsto1522Octets
)
5985 BNX_PRINTF(sc
, "0x%08X : "
5986 "EtherStatsPktsRx1024Octetsto1522Octets\n",
5987 sblk
->stat_EtherStatsPktsRx1024Octetsto1522Octets
);
5989 if (sblk
->stat_EtherStatsPktsRx1523Octetsto9022Octets
)
5990 BNX_PRINTF(sc
, "0x%08X : "
5991 "EtherStatsPktsRx1523Octetsto9022Octets\n",
5992 sblk
->stat_EtherStatsPktsRx1523Octetsto9022Octets
);
5994 if (sblk
->stat_EtherStatsPktsTx64Octets
)
5995 BNX_PRINTF(sc
, "0x%08X : EtherStatsPktsTx64Octets\n",
5996 sblk
->stat_EtherStatsPktsTx64Octets
);
5998 if (sblk
->stat_EtherStatsPktsTx65Octetsto127Octets
)
5999 BNX_PRINTF(sc
, "0x%08X : EtherStatsPktsTx65Octetsto127Octets\n",
6000 sblk
->stat_EtherStatsPktsTx65Octetsto127Octets
);
6002 if (sblk
->stat_EtherStatsPktsTx128Octetsto255Octets
)
6003 BNX_PRINTF(sc
, "0x%08X : "
6004 "EtherStatsPktsTx128Octetsto255Octets\n",
6005 sblk
->stat_EtherStatsPktsTx128Octetsto255Octets
);
6007 if (sblk
->stat_EtherStatsPktsTx256Octetsto511Octets
)
6008 BNX_PRINTF(sc
, "0x%08X : "
6009 "EtherStatsPktsTx256Octetsto511Octets\n",
6010 sblk
->stat_EtherStatsPktsTx256Octetsto511Octets
);
6012 if (sblk
->stat_EtherStatsPktsTx512Octetsto1023Octets
)
6013 BNX_PRINTF(sc
, "0x%08X : "
6014 "EtherStatsPktsTx512Octetsto1023Octets\n",
6015 sblk
->stat_EtherStatsPktsTx512Octetsto1023Octets
);
6017 if (sblk
->stat_EtherStatsPktsTx1024Octetsto1522Octets
)
6018 BNX_PRINTF(sc
, "0x%08X : "
6019 "EtherStatsPktsTx1024Octetsto1522Octets\n",
6020 sblk
->stat_EtherStatsPktsTx1024Octetsto1522Octets
);
6022 if (sblk
->stat_EtherStatsPktsTx1523Octetsto9022Octets
)
6023 BNX_PRINTF(sc
, "0x%08X : "
6024 "EtherStatsPktsTx1523Octetsto9022Octets\n",
6025 sblk
->stat_EtherStatsPktsTx1523Octetsto9022Octets
);
6027 if (sblk
->stat_XonPauseFramesReceived
)
6028 BNX_PRINTF(sc
, "0x%08X : XonPauseFramesReceived\n",
6029 sblk
->stat_XonPauseFramesReceived
);
6031 if (sblk
->stat_XoffPauseFramesReceived
)
6032 BNX_PRINTF(sc
, "0x%08X : XoffPauseFramesReceived\n",
6033 sblk
->stat_XoffPauseFramesReceived
);
6035 if (sblk
->stat_OutXonSent
)
6036 BNX_PRINTF(sc
, "0x%08X : OutXonSent\n",
6037 sblk
->stat_OutXonSent
);
6039 if (sblk
->stat_OutXoffSent
)
6040 BNX_PRINTF(sc
, "0x%08X : OutXoffSent\n",
6041 sblk
->stat_OutXoffSent
);
6043 if (sblk
->stat_FlowControlDone
)
6044 BNX_PRINTF(sc
, "0x%08X : FlowControlDone\n",
6045 sblk
->stat_FlowControlDone
);
6047 if (sblk
->stat_MacControlFramesReceived
)
6048 BNX_PRINTF(sc
, "0x%08X : MacControlFramesReceived\n",
6049 sblk
->stat_MacControlFramesReceived
);
6051 if (sblk
->stat_XoffStateEntered
)
6052 BNX_PRINTF(sc
, "0x%08X : XoffStateEntered\n",
6053 sblk
->stat_XoffStateEntered
);
6055 if (sblk
->stat_IfInFramesL2FilterDiscards
)
6056 BNX_PRINTF(sc
, "0x%08X : IfInFramesL2FilterDiscards\n",
6057 sblk
->stat_IfInFramesL2FilterDiscards
);
6059 if (sblk
->stat_IfInRuleCheckerDiscards
)
6060 BNX_PRINTF(sc
, "0x%08X : IfInRuleCheckerDiscards\n",
6061 sblk
->stat_IfInRuleCheckerDiscards
);
6063 if (sblk
->stat_IfInFTQDiscards
)
6064 BNX_PRINTF(sc
, "0x%08X : IfInFTQDiscards\n",
6065 sblk
->stat_IfInFTQDiscards
);
6067 if (sblk
->stat_IfInMBUFDiscards
)
6068 BNX_PRINTF(sc
, "0x%08X : IfInMBUFDiscards\n",
6069 sblk
->stat_IfInMBUFDiscards
);
6071 if (sblk
->stat_IfInRuleCheckerP4Hit
)
6072 BNX_PRINTF(sc
, "0x%08X : IfInRuleCheckerP4Hit\n",
6073 sblk
->stat_IfInRuleCheckerP4Hit
);
6075 if (sblk
->stat_CatchupInRuleCheckerDiscards
)
6076 BNX_PRINTF(sc
, "0x%08X : CatchupInRuleCheckerDiscards\n",
6077 sblk
->stat_CatchupInRuleCheckerDiscards
);
6079 if (sblk
->stat_CatchupInFTQDiscards
)
6080 BNX_PRINTF(sc
, "0x%08X : CatchupInFTQDiscards\n",
6081 sblk
->stat_CatchupInFTQDiscards
);
6083 if (sblk
->stat_CatchupInMBUFDiscards
)
6084 BNX_PRINTF(sc
, "0x%08X : CatchupInMBUFDiscards\n",
6085 sblk
->stat_CatchupInMBUFDiscards
);
6087 if (sblk
->stat_CatchupInRuleCheckerP4Hit
)
6088 BNX_PRINTF(sc
, "0x%08X : CatchupInRuleCheckerP4Hit\n",
6089 sblk
->stat_CatchupInRuleCheckerP4Hit
);
6091 aprint_debug_dev(sc
->bnx_dev
,
6092 "-----------------------------"
6094 "-----------------------------\n");
6098 bnx_dump_driver_state(struct bnx_softc
*sc
)
6100 aprint_debug_dev(sc
->bnx_dev
,
6101 "-----------------------------"
6103 "-----------------------------\n");
6105 BNX_PRINTF(sc
, "%p - (sc) driver softc structure virtual "
6108 BNX_PRINTF(sc
, "%p - (sc->status_block) status block virtual address\n",
6111 BNX_PRINTF(sc
, "%p - (sc->stats_block) statistics block virtual "
6112 "address\n", sc
->stats_block
);
6114 BNX_PRINTF(sc
, "%p - (sc->tx_bd_chain) tx_bd chain virtual "
6115 "adddress\n", sc
->tx_bd_chain
);
6118 BNX_PRINTF(sc
, "%p - (sc->rx_bd_chain) rx_bd chain virtual address\n",
6121 BNX_PRINTF(sc
, "%p - (sc->tx_mbuf_ptr) tx mbuf chain virtual address\n",
6125 BNX_PRINTF(sc
, "%p - (sc->rx_mbuf_ptr) rx mbuf chain virtual address\n",
6129 " 0x%08X - (sc->interrupts_generated) h/w intrs\n",
6130 sc
->interrupts_generated
);
6133 " 0x%08X - (sc->rx_interrupts) rx interrupts handled\n",
6137 " 0x%08X - (sc->tx_interrupts) tx interrupts handled\n",
6141 " 0x%08X - (sc->last_status_idx) status block index\n",
6142 sc
->last_status_idx
);
6144 BNX_PRINTF(sc
, " 0x%08X - (sc->tx_prod) tx producer index\n",
6147 BNX_PRINTF(sc
, " 0x%08X - (sc->tx_cons) tx consumer index\n",
6151 " 0x%08X - (sc->tx_prod_bseq) tx producer bseq index\n",
6154 " 0x%08X - (sc->tx_mbuf_alloc) tx mbufs allocated\n",
6158 " 0x%08X - (sc->used_tx_bd) used tx_bd's\n",
6162 " 0x%08X/%08X - (sc->tx_hi_watermark) tx hi watermark\n",
6163 sc
->tx_hi_watermark
, sc
->max_tx_bd
);
6166 BNX_PRINTF(sc
, " 0x%08X - (sc->rx_prod) rx producer index\n",
6169 BNX_PRINTF(sc
, " 0x%08X - (sc->rx_cons) rx consumer index\n",
6173 " 0x%08X - (sc->rx_prod_bseq) rx producer bseq index\n",
6177 " 0x%08X - (sc->rx_mbuf_alloc) rx mbufs allocated\n",
6180 BNX_PRINTF(sc
, " 0x%08X - (sc->free_rx_bd) free rx_bd's\n",
6184 "0x%08X/%08X - (sc->rx_low_watermark) rx low watermark\n",
6185 sc
->rx_low_watermark
, sc
->max_rx_bd
);
6188 " 0x%08X - (sc->mbuf_alloc_failed) "
6189 "mbuf alloc failures\n",
6190 sc
->mbuf_alloc_failed
);
6193 " 0x%0X - (sc->mbuf_sim_allocated_failed) "
6194 "simulated mbuf alloc failures\n",
6195 sc
->mbuf_sim_alloc_failed
);
6197 aprint_debug_dev(sc
->bnx_dev
, "-------------------------------------------"
6198 "-----------------------------\n");
6202 bnx_dump_hw_state(struct bnx_softc
*sc
)
6207 aprint_debug_dev(sc
->bnx_dev
,
6208 "----------------------------"
6210 "----------------------------\n");
6212 BNX_PRINTF(sc
, "0x%08X : bootcode version\n", sc
->bnx_fw_ver
);
6214 val1
= REG_RD(sc
, BNX_MISC_ENABLE_STATUS_BITS
);
6215 BNX_PRINTF(sc
, "0x%08X : (0x%04X) misc_enable_status_bits\n",
6216 val1
, BNX_MISC_ENABLE_STATUS_BITS
);
6218 val1
= REG_RD(sc
, BNX_DMA_STATUS
);
6219 BNX_PRINTF(sc
, "0x%08X : (0x%04X) dma_status\n", val1
, BNX_DMA_STATUS
);
6221 val1
= REG_RD(sc
, BNX_CTX_STATUS
);
6222 BNX_PRINTF(sc
, "0x%08X : (0x%04X) ctx_status\n", val1
, BNX_CTX_STATUS
);
6224 val1
= REG_RD(sc
, BNX_EMAC_STATUS
);
6225 BNX_PRINTF(sc
, "0x%08X : (0x%04X) emac_status\n", val1
,
6228 val1
= REG_RD(sc
, BNX_RPM_STATUS
);
6229 BNX_PRINTF(sc
, "0x%08X : (0x%04X) rpm_status\n", val1
, BNX_RPM_STATUS
);
6231 val1
= REG_RD(sc
, BNX_TBDR_STATUS
);
6232 BNX_PRINTF(sc
, "0x%08X : (0x%04X) tbdr_status\n", val1
,
6235 val1
= REG_RD(sc
, BNX_TDMA_STATUS
);
6236 BNX_PRINTF(sc
, "0x%08X : (0x%04X) tdma_status\n", val1
,
6239 val1
= REG_RD(sc
, BNX_HC_STATUS
);
6240 BNX_PRINTF(sc
, "0x%08X : (0x%04X) hc_status\n", val1
, BNX_HC_STATUS
);
6242 aprint_debug_dev(sc
->bnx_dev
,
6243 "----------------------------"
6245 "----------------------------\n");
6247 aprint_debug_dev(sc
->bnx_dev
,
6248 "----------------------------"
6250 "----------------------------\n");
6252 for (i
= 0x400; i
< 0x8000; i
+= 0x10)
6253 BNX_PRINTF(sc
, "0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
6254 i
, REG_RD(sc
, i
), REG_RD(sc
, i
+ 0x4),
6255 REG_RD(sc
, i
+ 0x8), REG_RD(sc
, i
+ 0xC));
6257 aprint_debug_dev(sc
->bnx_dev
,
6258 "----------------------------"
6260 "----------------------------\n");
6264 bnx_breakpoint(struct bnx_softc
*sc
)
6266 /* Unreachable code to shut the compiler up about unused functions. */
6268 bnx_dump_txbd(sc
, 0, NULL
);
6269 bnx_dump_rxbd(sc
, 0, NULL
);
6270 bnx_dump_tx_mbuf_chain(sc
, 0, USABLE_TX_BD
);
6271 bnx_dump_rx_mbuf_chain(sc
, 0, sc
->max_rx_bd
);
6272 bnx_dump_l2fhdr(sc
, 0, NULL
);
6273 bnx_dump_tx_chain(sc
, 0, USABLE_TX_BD
);
6274 bnx_dump_rx_chain(sc
, 0, sc
->max_rx_bd
);
6275 bnx_dump_status_block(sc
);
6276 bnx_dump_stats_block(sc
);
6277 bnx_dump_driver_state(sc
);
6278 bnx_dump_hw_state(sc
);
6281 bnx_dump_driver_state(sc
);
6282 /* Print the important status block fields. */
6283 bnx_dump_status_block(sc
);
6286 /* Call the debugger. */