1 /*- 2 * Copyright (c) 2006-2007 Broadcom Corporation 3 * David Christensen <davidch@broadcom.com>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of Broadcom Corporation nor the name of its contributors 15 * may be used to endorse or promote products derived from this software 16 * without specific prior written consent. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS' 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28 * THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * $FreeBSD: src/sys/dev/bce/if_bce.c,v 1.31 2007/05/16 23:34:11 davidch Exp $ 31 */ 32 33 /* 34 * The following controllers are supported by this driver: 35 * BCM5706C A2, A3 36 * BCM5706S A2, A3 37 * BCM5708C B1, B2 38 * BCM5708S B1, B2 39 * BCM5709C A1, C0 40 * BCM5716 C0 41 * 42 * The following controllers are not supported by this driver: 43 * BCM5706C A0, A1 44 * BCM5706S A0, A1 45 * BCM5708C A0, B0 46 * BCM5708S A0, B0 47 * BCM5709C A0, B0, B1 48 * BCM5709S A0, A1, B0, B1, B2, C0 49 */ 50 51 #include "opt_bce.h" 52 #include "opt_polling.h" 53 54 #include <sys/param.h> 55 #include <sys/bus.h> 56 #include <sys/endian.h> 57 #include <sys/kernel.h> 58 #include <sys/interrupt.h> 59 #include <sys/mbuf.h> 60 #include <sys/malloc.h> 61 #include <sys/queue.h> 62 #ifdef BCE_DEBUG 63 #include <sys/random.h> 64 #endif 65 #include <sys/rman.h> 66 #include <sys/serialize.h> 67 #include <sys/socket.h> 68 #include <sys/sockio.h> 69 #include <sys/sysctl.h> 70 71 #include <net/bpf.h> 72 #include <net/ethernet.h> 73 #include <net/if.h> 74 #include <net/if_arp.h> 75 #include <net/if_dl.h> 76 #include <net/if_media.h> 77 #include <net/if_types.h> 78 #include <net/ifq_var.h> 79 #include <net/vlan/if_vlan_var.h> 80 #include <net/vlan/if_vlan_ether.h> 81 82 #include <dev/netif/mii_layer/mii.h> 83 #include <dev/netif/mii_layer/miivar.h> 84 #include <dev/netif/mii_layer/brgphyreg.h> 85 86 #include <bus/pci/pcireg.h> 87 #include <bus/pci/pcivar.h> 88 89 #include "miibus_if.h" 90 91 #include <dev/netif/bce/if_bcereg.h> 92 #include <dev/netif/bce/if_bcefw.h> 93 94 /****************************************************************************/ 95 /* BCE Debug Options */ 96 /****************************************************************************/ 97 #ifdef BCE_DEBUG 98 99 static uint32_t bce_debug = BCE_WARN; 100 101 /* 102 * 0 = Never 103 * 1 = 1 in 2,147,483,648 104 * 256 = 1 in 8,388,608 105 * 2048 = 1 in 1,048,576 106 * 65536 = 1 in 32,768 107 * 1048576 = 1 in 2,048 108 * 268435456 = 1 in 8 109 * 536870912 = 1 in 4 110 * 1073741824 = 1 in 2 111 * 112 * bce_debug_l2fhdr_status_check: 113 * How often the l2_fhdr frame error check will fail. 114 * 115 * bce_debug_unexpected_attention: 116 * How often the unexpected attention check will fail. 117 * 118 * bce_debug_mbuf_allocation_failure: 119 * How often to simulate an mbuf allocation failure. 120 * 121 * bce_debug_dma_map_addr_failure: 122 * How often to simulate a DMA mapping failure. 123 * 124 * bce_debug_bootcode_running_failure: 125 * How often to simulate a bootcode failure. 126 */ 127 static int bce_debug_l2fhdr_status_check = 0; 128 static int bce_debug_unexpected_attention = 0; 129 static int bce_debug_mbuf_allocation_failure = 0; 130 static int bce_debug_dma_map_addr_failure = 0; 131 static int bce_debug_bootcode_running_failure = 0; 132 133 #endif /* BCE_DEBUG */ 134 135 136 /****************************************************************************/ 137 /* PCI Device ID Table */ 138 /* */ 139 /* Used by bce_probe() to identify the devices supported by this driver. */ 140 /****************************************************************************/ 141 #define BCE_DEVDESC_MAX 64 142 143 static struct bce_type bce_devs[] = { 144 /* BCM5706C Controllers and OEM boards. */ 145 { BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x3101, 146 "HP NC370T Multifunction Gigabit Server Adapter" }, 147 { BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x3106, 148 "HP NC370i Multifunction Gigabit Server Adapter" }, 149 { BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x3070, 150 "HP NC380T PCIe DP Multifunc Gig Server Adapter" }, 151 { BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x1709, 152 "HP NC371i Multifunction Gigabit Server Adapter" }, 153 { BRCM_VENDORID, BRCM_DEVICEID_BCM5706, PCI_ANY_ID, PCI_ANY_ID, 154 "Broadcom NetXtreme II BCM5706 1000Base-T" }, 155 156 /* BCM5706S controllers and OEM boards. */ 157 { BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, HP_VENDORID, 0x3102, 158 "HP NC370F Multifunction Gigabit Server Adapter" }, 159 { BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, PCI_ANY_ID, PCI_ANY_ID, 160 "Broadcom NetXtreme II BCM5706 1000Base-SX" }, 161 162 /* BCM5708C controllers and OEM boards. */ 163 { BRCM_VENDORID, BRCM_DEVICEID_BCM5708, HP_VENDORID, 0x7037, 164 "HP NC373T PCIe Multifunction Gig Server Adapter" }, 165 { BRCM_VENDORID, BRCM_DEVICEID_BCM5708, HP_VENDORID, 0x7038, 166 "HP NC373i Multifunction Gigabit Server Adapter" }, 167 { BRCM_VENDORID, BRCM_DEVICEID_BCM5708, HP_VENDORID, 0x7045, 168 "HP NC374m PCIe Multifunction Adapter" }, 169 { BRCM_VENDORID, BRCM_DEVICEID_BCM5708, PCI_ANY_ID, PCI_ANY_ID, 170 "Broadcom NetXtreme II BCM5708 1000Base-T" }, 171 172 /* BCM5708S controllers and OEM boards. */ 173 { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, HP_VENDORID, 0x1706, 174 "HP NC373m Multifunction Gigabit Server Adapter" }, 175 { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, HP_VENDORID, 0x703b, 176 "HP NC373i Multifunction Gigabit Server Adapter" }, 177 { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, HP_VENDORID, 0x703d, 178 "HP NC373F PCIe Multifunc Giga Server Adapter" }, 179 { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, PCI_ANY_ID, PCI_ANY_ID, 180 "Broadcom NetXtreme II BCM5708S 1000Base-T" }, 181 182 /* BCM5709C controllers and OEM boards. */ 183 { BRCM_VENDORID, BRCM_DEVICEID_BCM5709, HP_VENDORID, 0x7055, 184 "HP NC382i DP Multifunction Gigabit Server Adapter" }, 185 { BRCM_VENDORID, BRCM_DEVICEID_BCM5709, HP_VENDORID, 0x7059, 186 "HP NC382T PCIe DP Multifunction Gigabit Server Adapter" }, 187 { BRCM_VENDORID, BRCM_DEVICEID_BCM5709, PCI_ANY_ID, PCI_ANY_ID, 188 "Broadcom NetXtreme II BCM5709 1000Base-T" }, 189 190 /* BCM5709S controllers and OEM boards. */ 191 { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S, HP_VENDORID, 0x171d, 192 "HP NC382m DP 1GbE Multifunction BL-c Adapter" }, 193 { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S, HP_VENDORID, 0x7056, 194 "HP NC382i DP Multifunction Gigabit Server Adapter" }, 195 { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S, PCI_ANY_ID, PCI_ANY_ID, 196 "Broadcom NetXtreme II BCM5709 1000Base-SX" }, 197 198 /* BCM5716 controllers and OEM boards. */ 199 { BRCM_VENDORID, BRCM_DEVICEID_BCM5716, PCI_ANY_ID, PCI_ANY_ID, 200 "Broadcom NetXtreme II BCM5716 1000Base-T" }, 201 202 { 0, 0, 0, 0, NULL } 203 }; 204 205 206 /****************************************************************************/ 207 /* Supported Flash NVRAM device data. */ 208 /****************************************************************************/ 209 static const struct flash_spec flash_table[] = 210 { 211 #define BUFFERED_FLAGS (BCE_NV_BUFFERED | BCE_NV_TRANSLATE) 212 #define NONBUFFERED_FLAGS (BCE_NV_WREN) 213 214 /* Slow EEPROM */ 215 {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400, 216 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, 217 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, 218 "EEPROM - slow"}, 219 /* Expansion entry 0001 */ 220 {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406, 221 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 222 SAIFUN_FLASH_BYTE_ADDR_MASK, 0, 223 "Entry 0001"}, 224 /* Saifun SA25F010 (non-buffered flash) */ 225 /* strap, cfg1, & write1 need updates */ 226 {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406, 227 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 228 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2, 229 "Non-buffered flash (128kB)"}, 230 /* Saifun SA25F020 (non-buffered flash) */ 231 /* strap, cfg1, & write1 need updates */ 232 {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406, 233 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 234 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4, 235 "Non-buffered flash (256kB)"}, 236 /* Expansion entry 0100 */ 237 {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406, 238 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 239 SAIFUN_FLASH_BYTE_ADDR_MASK, 0, 240 "Entry 0100"}, 241 /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */ 242 {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406, 243 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE, 244 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2, 245 "Entry 0101: ST M45PE10 (128kB non-bufferred)"}, 246 /* Entry 0110: ST M45PE20 (non-buffered flash)*/ 247 {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406, 248 NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE, 249 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4, 250 "Entry 0110: ST M45PE20 (256kB non-bufferred)"}, 251 /* Saifun SA25F005 (non-buffered flash) */ 252 /* strap, cfg1, & write1 need updates */ 253 {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406, 254 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 255 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE, 256 "Non-buffered flash (64kB)"}, 257 /* Fast EEPROM */ 258 {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400, 259 BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, 260 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, 261 "EEPROM - fast"}, 262 /* Expansion entry 1001 */ 263 {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406, 264 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 265 SAIFUN_FLASH_BYTE_ADDR_MASK, 0, 266 "Entry 1001"}, 267 /* Expansion entry 1010 */ 268 {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406, 269 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 270 SAIFUN_FLASH_BYTE_ADDR_MASK, 0, 271 "Entry 1010"}, 272 /* ATMEL AT45DB011B (buffered flash) */ 273 {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400, 274 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, 275 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE, 276 "Buffered flash (128kB)"}, 277 /* Expansion entry 1100 */ 278 {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406, 279 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 280 SAIFUN_FLASH_BYTE_ADDR_MASK, 0, 281 "Entry 1100"}, 282 /* Expansion entry 1101 */ 283 {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406, 284 NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 285 SAIFUN_FLASH_BYTE_ADDR_MASK, 0, 286 "Entry 1101"}, 287 /* Ateml Expansion entry 1110 */ 288 {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400, 289 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, 290 BUFFERED_FLASH_BYTE_ADDR_MASK, 0, 291 "Entry 1110 (Atmel)"}, 292 /* ATMEL AT45DB021B (buffered flash) */ 293 {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400, 294 BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, 295 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2, 296 "Buffered flash (256kB)"}, 297 }; 298 299 /* 300 * The BCM5709 controllers transparently handle the 301 * differences between Atmel 264 byte pages and all 302 * flash devices which use 256 byte pages, so no 303 * logical-to-physical mapping is required in the 304 * driver. 305 */ 306 static struct flash_spec flash_5709 = { 307 .flags = BCE_NV_BUFFERED, 308 .page_bits = BCM5709_FLASH_PAGE_BITS, 309 .page_size = BCM5709_FLASH_PAGE_SIZE, 310 .addr_mask = BCM5709_FLASH_BYTE_ADDR_MASK, 311 .total_size = BUFFERED_FLASH_TOTAL_SIZE * 2, 312 .name = "5709/5716 buffered flash (256kB)", 313 }; 314 315 316 /****************************************************************************/ 317 /* DragonFly device entry points. */ 318 /****************************************************************************/ 319 static int bce_probe(device_t); 320 static int bce_attach(device_t); 321 static int bce_detach(device_t); 322 static void bce_shutdown(device_t); 323 324 /****************************************************************************/ 325 /* BCE Debug Data Structure Dump Routines */ 326 /****************************************************************************/ 327 #ifdef BCE_DEBUG 328 static void bce_dump_mbuf(struct bce_softc *, struct mbuf *); 329 static void bce_dump_tx_mbuf_chain(struct bce_softc *, int, int); 330 static void bce_dump_rx_mbuf_chain(struct bce_softc *, int, int); 331 static void bce_dump_txbd(struct bce_softc *, int, struct tx_bd *); 332 static void bce_dump_rxbd(struct bce_softc *, int, struct rx_bd *); 333 static void bce_dump_l2fhdr(struct bce_softc *, int, 334 struct l2_fhdr *) __unused; 335 static void bce_dump_tx_chain(struct bce_softc *, int, int); 336 static void bce_dump_rx_chain(struct bce_softc *, int, int); 337 static void bce_dump_status_block(struct bce_softc *); 338 static void bce_dump_driver_state(struct bce_softc *); 339 static void bce_dump_stats_block(struct bce_softc *) __unused; 340 static void bce_dump_hw_state(struct bce_softc *); 341 static void bce_dump_txp_state(struct bce_softc *); 342 static void bce_dump_rxp_state(struct bce_softc *) __unused; 343 static void bce_dump_tpat_state(struct bce_softc *) __unused; 344 static void bce_freeze_controller(struct bce_softc *) __unused; 345 static void bce_unfreeze_controller(struct bce_softc *) __unused; 346 static void bce_breakpoint(struct bce_softc *); 347 #endif /* BCE_DEBUG */ 348 349 350 /****************************************************************************/ 351 /* BCE Register/Memory Access Routines */ 352 /****************************************************************************/ 353 static uint32_t bce_reg_rd_ind(struct bce_softc *, uint32_t); 354 static void bce_reg_wr_ind(struct bce_softc *, uint32_t, uint32_t); 355 static void bce_shmem_wr(struct bce_softc *, uint32_t, uint32_t); 356 static uint32_t bce_shmem_rd(struct bce_softc *, u32); 357 static void bce_ctx_wr(struct bce_softc *, uint32_t, uint32_t, uint32_t); 358 static int bce_miibus_read_reg(device_t, int, int); 359 static int bce_miibus_write_reg(device_t, int, int, int); 360 static void bce_miibus_statchg(device_t); 361 362 363 /****************************************************************************/ 364 /* BCE NVRAM Access Routines */ 365 /****************************************************************************/ 366 static int bce_acquire_nvram_lock(struct bce_softc *); 367 static int bce_release_nvram_lock(struct bce_softc *); 368 static void bce_enable_nvram_access(struct bce_softc *); 369 static void bce_disable_nvram_access(struct bce_softc *); 370 static int bce_nvram_read_dword(struct bce_softc *, uint32_t, uint8_t *, 371 uint32_t); 372 static int bce_init_nvram(struct bce_softc *); 373 static int bce_nvram_read(struct bce_softc *, uint32_t, uint8_t *, int); 374 static int bce_nvram_test(struct bce_softc *); 375 376 /****************************************************************************/ 377 /* BCE DMA Allocate/Free Routines */ 378 /****************************************************************************/ 379 static int bce_dma_alloc(struct bce_softc *); 380 static void bce_dma_free(struct bce_softc *); 381 static void bce_dma_map_addr(void *, bus_dma_segment_t *, int, int); 382 383 /****************************************************************************/ 384 /* BCE Firmware Synchronization and Load */ 385 /****************************************************************************/ 386 static int bce_fw_sync(struct bce_softc *, uint32_t); 387 static void bce_load_rv2p_fw(struct bce_softc *, uint32_t *, 388 uint32_t, uint32_t); 389 static void bce_load_cpu_fw(struct bce_softc *, struct cpu_reg *, 390 struct fw_info *); 391 static void bce_start_cpu(struct bce_softc *, struct cpu_reg *); 392 static void bce_halt_cpu(struct bce_softc *, struct cpu_reg *); 393 static void bce_start_rxp_cpu(struct bce_softc *); 394 static void bce_init_rxp_cpu(struct bce_softc *); 395 static void bce_init_txp_cpu(struct bce_softc *); 396 static void bce_init_tpat_cpu(struct bce_softc *); 397 static void bce_init_cp_cpu(struct bce_softc *); 398 static void bce_init_com_cpu(struct bce_softc *); 399 static void bce_init_cpus(struct bce_softc *); 400 401 static void bce_stop(struct bce_softc *); 402 static int bce_reset(struct bce_softc *, uint32_t); 403 static int bce_chipinit(struct bce_softc *); 404 static int bce_blockinit(struct bce_softc *); 405 static int bce_newbuf_std(struct bce_softc *, uint16_t *, uint16_t *, 406 uint32_t *, int); 407 static void bce_setup_rxdesc_std(struct bce_softc *, uint16_t, uint32_t *); 408 static void bce_probe_pci_caps(struct bce_softc *); 409 static void bce_print_adapter_info(struct bce_softc *); 410 static void bce_get_media(struct bce_softc *); 411 412 static void bce_init_tx_context(struct bce_softc *); 413 static int bce_init_tx_chain(struct bce_softc *); 414 static void bce_init_rx_context(struct bce_softc *); 415 static int bce_init_rx_chain(struct bce_softc *); 416 static void bce_free_rx_chain(struct bce_softc *); 417 static void bce_free_tx_chain(struct bce_softc *); 418 419 static int bce_encap(struct bce_softc *, struct mbuf **); 420 static void bce_start(struct ifnet *); 421 static int bce_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *); 422 static void bce_watchdog(struct ifnet *); 423 static int bce_ifmedia_upd(struct ifnet *); 424 static void bce_ifmedia_sts(struct ifnet *, struct ifmediareq *); 425 static void bce_init(void *); 426 static void bce_mgmt_init(struct bce_softc *); 427 428 static int bce_init_ctx(struct bce_softc *); 429 static void bce_get_mac_addr(struct bce_softc *); 430 static void bce_set_mac_addr(struct bce_softc *); 431 static void bce_phy_intr(struct bce_softc *); 432 static void bce_rx_intr(struct bce_softc *, int); 433 static void bce_tx_intr(struct bce_softc *); 434 static void bce_disable_intr(struct bce_softc *); 435 static void bce_enable_intr(struct bce_softc *); 436 static void bce_reenable_intr(struct bce_softc *); 437 438 #ifdef DEVICE_POLLING 439 static void bce_poll(struct ifnet *, enum poll_cmd, int); 440 #endif 441 static void bce_intr(struct bce_softc *); 442 static void bce_intr_legacy(void *); 443 static void bce_intr_msi(void *); 444 static void bce_intr_msi_oneshot(void *); 445 static void bce_set_rx_mode(struct bce_softc *); 446 static void bce_stats_update(struct bce_softc *); 447 static void bce_tick(void *); 448 static void bce_tick_serialized(struct bce_softc *); 449 static void bce_pulse(void *); 450 static void bce_pulse_check_msi(struct bce_softc *); 451 static void bce_add_sysctls(struct bce_softc *); 452 453 static void bce_coal_change(struct bce_softc *); 454 static int bce_sysctl_tx_bds_int(SYSCTL_HANDLER_ARGS); 455 static int bce_sysctl_tx_bds(SYSCTL_HANDLER_ARGS); 456 static int bce_sysctl_tx_ticks_int(SYSCTL_HANDLER_ARGS); 457 static int bce_sysctl_tx_ticks(SYSCTL_HANDLER_ARGS); 458 static int bce_sysctl_rx_bds_int(SYSCTL_HANDLER_ARGS); 459 static int bce_sysctl_rx_bds(SYSCTL_HANDLER_ARGS); 460 static int bce_sysctl_rx_ticks_int(SYSCTL_HANDLER_ARGS); 461 static int bce_sysctl_rx_ticks(SYSCTL_HANDLER_ARGS); 462 static int bce_sysctl_coal_change(SYSCTL_HANDLER_ARGS, 463 uint32_t *, uint32_t); 464 465 /* 466 * NOTE: 467 * Don't set bce_tx_ticks_int/bce_tx_ticks to 1023. Linux's bnx2 468 * takes 1023 as the TX ticks limit. However, using 1023 will 469 * cause 5708(B2) to generate extra interrupts (~2000/s) even when 470 * there is _no_ network activity on the NIC. 471 */ 472 static uint32_t bce_tx_bds_int = 255; /* bcm: 20 */ 473 static uint32_t bce_tx_bds = 255; /* bcm: 20 */ 474 static uint32_t bce_tx_ticks_int = 1022; /* bcm: 80 */ 475 static uint32_t bce_tx_ticks = 1022; /* bcm: 80 */ 476 static uint32_t bce_rx_bds_int = 128; /* bcm: 6 */ 477 static uint32_t bce_rx_bds = 128; /* bcm: 6 */ 478 static uint32_t bce_rx_ticks_int = 125; /* bcm: 18 */ 479 static uint32_t bce_rx_ticks = 125; /* bcm: 18 */ 480 481 static int bce_msi_enable = 1; 482 483 static int bce_rx_pages = RX_PAGES_DEFAULT; 484 static int bce_tx_pages = TX_PAGES_DEFAULT; 485 486 TUNABLE_INT("hw.bce.tx_bds_int", &bce_tx_bds_int); 487 TUNABLE_INT("hw.bce.tx_bds", &bce_tx_bds); 488 TUNABLE_INT("hw.bce.tx_ticks_int", &bce_tx_ticks_int); 489 TUNABLE_INT("hw.bce.tx_ticks", &bce_tx_ticks); 490 TUNABLE_INT("hw.bce.rx_bds_int", &bce_rx_bds_int); 491 TUNABLE_INT("hw.bce.rx_bds", &bce_rx_bds); 492 TUNABLE_INT("hw.bce.rx_ticks_int", &bce_rx_ticks_int); 493 TUNABLE_INT("hw.bce.rx_ticks", &bce_rx_ticks); 494 TUNABLE_INT("hw.bce.msi.enable", &bce_msi_enable); 495 TUNABLE_INT("hw.bce.rx_pages", &bce_rx_pages); 496 TUNABLE_INT("hw.bce.tx_pages", &bce_tx_pages); 497 498 /****************************************************************************/ 499 /* DragonFly device dispatch table. */ 500 /****************************************************************************/ 501 static device_method_t bce_methods[] = { 502 /* Device interface */ 503 DEVMETHOD(device_probe, bce_probe), 504 DEVMETHOD(device_attach, bce_attach), 505 DEVMETHOD(device_detach, bce_detach), 506 DEVMETHOD(device_shutdown, bce_shutdown), 507 508 /* bus interface */ 509 DEVMETHOD(bus_print_child, bus_generic_print_child), 510 DEVMETHOD(bus_driver_added, bus_generic_driver_added), 511 512 /* MII interface */ 513 DEVMETHOD(miibus_readreg, bce_miibus_read_reg), 514 DEVMETHOD(miibus_writereg, bce_miibus_write_reg), 515 DEVMETHOD(miibus_statchg, bce_miibus_statchg), 516 517 { 0, 0 } 518 }; 519 520 static driver_t bce_driver = { 521 "bce", 522 bce_methods, 523 sizeof(struct bce_softc) 524 }; 525 526 static devclass_t bce_devclass; 527 528 529 DECLARE_DUMMY_MODULE(if_bce); 530 MODULE_DEPEND(bce, miibus, 1, 1, 1); 531 DRIVER_MODULE(if_bce, pci, bce_driver, bce_devclass, NULL, NULL); 532 DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, NULL, NULL); 533 534 535 /****************************************************************************/ 536 /* Device probe function. */ 537 /* */ 538 /* Compares the device to the driver's list of supported devices and */ 539 /* reports back to the OS whether this is the right driver for the device. */ 540 /* */ 541 /* Returns: */ 542 /* BUS_PROBE_DEFAULT on success, positive value on failure. */ 543 /****************************************************************************/ 544 static int 545 bce_probe(device_t dev) 546 { 547 struct bce_type *t; 548 uint16_t vid, did, svid, sdid; 549 550 /* Get the data for the device to be probed. */ 551 vid = pci_get_vendor(dev); 552 did = pci_get_device(dev); 553 svid = pci_get_subvendor(dev); 554 sdid = pci_get_subdevice(dev); 555 556 /* Look through the list of known devices for a match. */ 557 for (t = bce_devs; t->bce_name != NULL; ++t) { 558 if (vid == t->bce_vid && did == t->bce_did && 559 (svid == t->bce_svid || t->bce_svid == PCI_ANY_ID) && 560 (sdid == t->bce_sdid || t->bce_sdid == PCI_ANY_ID)) { 561 uint32_t revid = pci_read_config(dev, PCIR_REVID, 4); 562 char *descbuf; 563 564 descbuf = kmalloc(BCE_DEVDESC_MAX, M_TEMP, M_WAITOK); 565 566 /* Print out the device identity. */ 567 ksnprintf(descbuf, BCE_DEVDESC_MAX, "%s (%c%d)", 568 t->bce_name, 569 ((revid & 0xf0) >> 4) + 'A', revid & 0xf); 570 571 device_set_desc_copy(dev, descbuf); 572 kfree(descbuf, M_TEMP); 573 return 0; 574 } 575 } 576 return ENXIO; 577 } 578 579 580 /****************************************************************************/ 581 /* PCI Capabilities Probe Function. */ 582 /* */ 583 /* Walks the PCI capabiites list for the device to find what features are */ 584 /* supported. */ 585 /* */ 586 /* Returns: */ 587 /* None. */ 588 /****************************************************************************/ 589 static void 590 bce_print_adapter_info(struct bce_softc *sc) 591 { 592 device_printf(sc->bce_dev, "ASIC (0x%08X); ", sc->bce_chipid); 593 594 kprintf("Rev (%c%d); ", ((BCE_CHIP_ID(sc) & 0xf000) >> 12) + 'A', 595 ((BCE_CHIP_ID(sc) & 0x0ff0) >> 4)); 596 597 /* Bus info. */ 598 if (sc->bce_flags & BCE_PCIE_FLAG) { 599 kprintf("Bus (PCIe x%d, ", sc->link_width); 600 switch (sc->link_speed) { 601 case 1: 602 kprintf("2.5Gbps); "); 603 break; 604 case 2: 605 kprintf("5Gbps); "); 606 break; 607 default: 608 kprintf("Unknown link speed); "); 609 break; 610 } 611 } else { 612 kprintf("Bus (PCI%s, %s, %dMHz); ", 613 ((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""), 614 ((sc->bce_flags & BCE_PCI_32BIT_FLAG) ? "32-bit" : "64-bit"), 615 sc->bus_speed_mhz); 616 } 617 618 /* Firmware version and device features. */ 619 kprintf("B/C (%s)", sc->bce_bc_ver); 620 621 if ((sc->bce_flags & BCE_MFW_ENABLE_FLAG) || 622 (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)) { 623 kprintf("; Flags("); 624 if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) 625 kprintf("MFW[%s]", sc->bce_mfw_ver); 626 if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) 627 kprintf(" 2.5G"); 628 kprintf(")"); 629 } 630 kprintf("\n"); 631 } 632 633 634 /****************************************************************************/ 635 /* PCI Capabilities Probe Function. */ 636 /* */ 637 /* Walks the PCI capabiites list for the device to find what features are */ 638 /* supported. */ 639 /* */ 640 /* Returns: */ 641 /* None. */ 642 /****************************************************************************/ 643 static void 644 bce_probe_pci_caps(struct bce_softc *sc) 645 { 646 device_t dev = sc->bce_dev; 647 uint8_t ptr; 648 649 if (pci_is_pcix(dev)) 650 sc->bce_cap_flags |= BCE_PCIX_CAPABLE_FLAG; 651 652 ptr = pci_get_pciecap_ptr(dev); 653 if (ptr) { 654 uint16_t link_status = pci_read_config(dev, ptr + 0x12, 2); 655 656 sc->link_speed = link_status & 0xf; 657 sc->link_width = (link_status >> 4) & 0x3f; 658 sc->bce_cap_flags |= BCE_PCIE_CAPABLE_FLAG; 659 sc->bce_flags |= BCE_PCIE_FLAG; 660 } 661 } 662 663 664 /****************************************************************************/ 665 /* Device attach function. */ 666 /* */ 667 /* Allocates device resources, performs secondary chip identification, */ 668 /* resets and initializes the hardware, and initializes driver instance */ 669 /* variables. */ 670 /* */ 671 /* Returns: */ 672 /* 0 on success, positive value on failure. */ 673 /****************************************************************************/ 674 static int 675 bce_attach(device_t dev) 676 { 677 struct bce_softc *sc = device_get_softc(dev); 678 struct ifnet *ifp = &sc->arpcom.ac_if; 679 uint32_t val; 680 u_int irq_flags; 681 void (*irq_handle)(void *); 682 int rid, rc = 0; 683 int i, j; 684 struct mii_probe_args mii_args; 685 uintptr_t mii_priv = 0; 686 687 sc->bce_dev = dev; 688 if_initname(ifp, device_get_name(dev), device_get_unit(dev)); 689 690 pci_enable_busmaster(dev); 691 692 bce_probe_pci_caps(sc); 693 694 /* Allocate PCI memory resources. */ 695 rid = PCIR_BAR(0); 696 sc->bce_res_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 697 RF_ACTIVE | PCI_RF_DENSE); 698 if (sc->bce_res_mem == NULL) { 699 device_printf(dev, "PCI memory allocation failed\n"); 700 return ENXIO; 701 } 702 sc->bce_btag = rman_get_bustag(sc->bce_res_mem); 703 sc->bce_bhandle = rman_get_bushandle(sc->bce_res_mem); 704 705 /* Allocate PCI IRQ resources. */ 706 sc->bce_irq_type = pci_alloc_1intr(dev, bce_msi_enable, 707 &sc->bce_irq_rid, &irq_flags); 708 709 sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, 710 &sc->bce_irq_rid, irq_flags); 711 if (sc->bce_res_irq == NULL) { 712 device_printf(dev, "PCI map interrupt failed\n"); 713 rc = ENXIO; 714 goto fail; 715 } 716 717 /* 718 * Configure byte swap and enable indirect register access. 719 * Rely on CPU to do target byte swapping on big endian systems. 720 * Access to registers outside of PCI configurtion space are not 721 * valid until this is done. 722 */ 723 pci_write_config(dev, BCE_PCICFG_MISC_CONFIG, 724 BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | 725 BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4); 726 727 /* Save ASIC revsion info. */ 728 sc->bce_chipid = REG_RD(sc, BCE_MISC_ID); 729 730 /* Weed out any non-production controller revisions. */ 731 switch (BCE_CHIP_ID(sc)) { 732 case BCE_CHIP_ID_5706_A0: 733 case BCE_CHIP_ID_5706_A1: 734 case BCE_CHIP_ID_5708_A0: 735 case BCE_CHIP_ID_5708_B0: 736 case BCE_CHIP_ID_5709_A0: 737 case BCE_CHIP_ID_5709_B0: 738 case BCE_CHIP_ID_5709_B1: 739 #ifdef foo 740 /* 5709C B2 seems to work fine */ 741 case BCE_CHIP_ID_5709_B2: 742 #endif 743 device_printf(dev, "Unsupported chip id 0x%08x!\n", 744 BCE_CHIP_ID(sc)); 745 rc = ENODEV; 746 goto fail; 747 } 748 749 mii_priv |= BRGPHY_FLAG_WIRESPEED; 750 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) { 751 if (BCE_CHIP_REV(sc) == BCE_CHIP_REV_Ax || 752 BCE_CHIP_REV(sc) == BCE_CHIP_REV_Bx) 753 mii_priv |= BRGPHY_FLAG_NO_EARLYDAC; 754 } else { 755 mii_priv |= BRGPHY_FLAG_BER_BUG; 756 } 757 758 if (sc->bce_irq_type == PCI_INTR_TYPE_LEGACY) { 759 irq_handle = bce_intr_legacy; 760 } else if (sc->bce_irq_type == PCI_INTR_TYPE_MSI) { 761 irq_handle = bce_intr_msi; 762 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) { 763 irq_handle = bce_intr_msi_oneshot; 764 sc->bce_flags |= BCE_ONESHOT_MSI_FLAG; 765 } 766 } else { 767 panic("%s: unsupported intr type %d", 768 device_get_nameunit(dev), sc->bce_irq_type); 769 } 770 771 /* 772 * Find the base address for shared memory access. 773 * Newer versions of bootcode use a signature and offset 774 * while older versions use a fixed address. 775 */ 776 val = REG_RD_IND(sc, BCE_SHM_HDR_SIGNATURE); 777 if ((val & BCE_SHM_HDR_SIGNATURE_SIG_MASK) == 778 BCE_SHM_HDR_SIGNATURE_SIG) { 779 /* Multi-port devices use different offsets in shared memory. */ 780 sc->bce_shmem_base = REG_RD_IND(sc, 781 BCE_SHM_HDR_ADDR_0 + (pci_get_function(sc->bce_dev) << 2)); 782 } else { 783 sc->bce_shmem_base = HOST_VIEW_SHMEM_BASE; 784 } 785 DBPRINT(sc, BCE_INFO, "bce_shmem_base = 0x%08X\n", sc->bce_shmem_base); 786 787 /* Fetch the bootcode revision. */ 788 val = bce_shmem_rd(sc, BCE_DEV_INFO_BC_REV); 789 for (i = 0, j = 0; i < 3; i++) { 790 uint8_t num; 791 int k, skip0; 792 793 num = (uint8_t)(val >> (24 - (i * 8))); 794 for (k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) { 795 if (num >= k || !skip0 || k == 1) { 796 sc->bce_bc_ver[j++] = (num / k) + '0'; 797 skip0 = 0; 798 } 799 } 800 if (i != 2) 801 sc->bce_bc_ver[j++] = '.'; 802 } 803 804 /* Check if any management firwmare is running. */ 805 val = bce_shmem_rd(sc, BCE_PORT_FEATURE); 806 if (val & BCE_PORT_FEATURE_ASF_ENABLED) { 807 sc->bce_flags |= BCE_MFW_ENABLE_FLAG; 808 809 /* Allow time for firmware to enter the running state. */ 810 for (i = 0; i < 30; i++) { 811 val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION); 812 if (val & BCE_CONDITION_MFW_RUN_MASK) 813 break; 814 DELAY(10000); 815 } 816 } 817 818 /* Check the current bootcode state. */ 819 val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION) & 820 BCE_CONDITION_MFW_RUN_MASK; 821 if (val != BCE_CONDITION_MFW_RUN_UNKNOWN && 822 val != BCE_CONDITION_MFW_RUN_NONE) { 823 uint32_t addr = bce_shmem_rd(sc, BCE_MFW_VER_PTR); 824 825 for (i = 0, j = 0; j < 3; j++) { 826 val = bce_reg_rd_ind(sc, addr + j * 4); 827 val = bswap32(val); 828 memcpy(&sc->bce_mfw_ver[i], &val, 4); 829 i += 4; 830 } 831 } 832 833 /* Get PCI bus information (speed and type). */ 834 val = REG_RD(sc, BCE_PCICFG_MISC_STATUS); 835 if (val & BCE_PCICFG_MISC_STATUS_PCIX_DET) { 836 uint32_t clkreg; 837 838 sc->bce_flags |= BCE_PCIX_FLAG; 839 840 clkreg = REG_RD(sc, BCE_PCICFG_PCI_CLOCK_CONTROL_BITS) & 841 BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET; 842 switch (clkreg) { 843 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ: 844 sc->bus_speed_mhz = 133; 845 break; 846 847 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ: 848 sc->bus_speed_mhz = 100; 849 break; 850 851 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ: 852 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ: 853 sc->bus_speed_mhz = 66; 854 break; 855 856 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ: 857 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ: 858 sc->bus_speed_mhz = 50; 859 break; 860 861 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW: 862 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ: 863 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ: 864 sc->bus_speed_mhz = 33; 865 break; 866 } 867 } else { 868 if (val & BCE_PCICFG_MISC_STATUS_M66EN) 869 sc->bus_speed_mhz = 66; 870 else 871 sc->bus_speed_mhz = 33; 872 } 873 874 if (val & BCE_PCICFG_MISC_STATUS_32BIT_DET) 875 sc->bce_flags |= BCE_PCI_32BIT_FLAG; 876 877 /* Reset the controller. */ 878 rc = bce_reset(sc, BCE_DRV_MSG_CODE_RESET); 879 if (rc != 0) 880 goto fail; 881 882 /* Initialize the controller. */ 883 rc = bce_chipinit(sc); 884 if (rc != 0) { 885 device_printf(dev, "Controller initialization failed!\n"); 886 goto fail; 887 } 888 889 /* Perform NVRAM test. */ 890 rc = bce_nvram_test(sc); 891 if (rc != 0) { 892 device_printf(dev, "NVRAM test failed!\n"); 893 goto fail; 894 } 895 896 /* Fetch the permanent Ethernet MAC address. */ 897 bce_get_mac_addr(sc); 898 899 /* 900 * Trip points control how many BDs 901 * should be ready before generating an 902 * interrupt while ticks control how long 903 * a BD can sit in the chain before 904 * generating an interrupt. Set the default 905 * values for the RX and TX rings. 906 */ 907 908 #ifdef BCE_DRBUG 909 /* Force more frequent interrupts. */ 910 sc->bce_tx_quick_cons_trip_int = 1; 911 sc->bce_tx_quick_cons_trip = 1; 912 sc->bce_tx_ticks_int = 0; 913 sc->bce_tx_ticks = 0; 914 915 sc->bce_rx_quick_cons_trip_int = 1; 916 sc->bce_rx_quick_cons_trip = 1; 917 sc->bce_rx_ticks_int = 0; 918 sc->bce_rx_ticks = 0; 919 #else 920 sc->bce_tx_quick_cons_trip_int = bce_tx_bds_int; 921 sc->bce_tx_quick_cons_trip = bce_tx_bds; 922 sc->bce_tx_ticks_int = bce_tx_ticks_int; 923 sc->bce_tx_ticks = bce_tx_ticks; 924 925 sc->bce_rx_quick_cons_trip_int = bce_rx_bds_int; 926 sc->bce_rx_quick_cons_trip = bce_rx_bds; 927 sc->bce_rx_ticks_int = bce_rx_ticks_int; 928 sc->bce_rx_ticks = bce_rx_ticks; 929 #endif 930 931 /* Update statistics once every second. */ 932 sc->bce_stats_ticks = 1000000 & 0xffff00; 933 934 /* Find the media type for the adapter. */ 935 bce_get_media(sc); 936 937 /* Allocate DMA memory resources. */ 938 rc = bce_dma_alloc(sc); 939 if (rc != 0) { 940 device_printf(dev, "DMA resource allocation failed!\n"); 941 goto fail; 942 } 943 944 /* Initialize the ifnet interface. */ 945 ifp->if_softc = sc; 946 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 947 ifp->if_ioctl = bce_ioctl; 948 ifp->if_start = bce_start; 949 ifp->if_init = bce_init; 950 ifp->if_watchdog = bce_watchdog; 951 #ifdef DEVICE_POLLING 952 ifp->if_poll = bce_poll; 953 #endif 954 ifp->if_mtu = ETHERMTU; 955 ifp->if_hwassist = BCE_IF_HWASSIST; 956 ifp->if_capabilities = BCE_IF_CAPABILITIES; 957 ifp->if_capenable = ifp->if_capabilities; 958 ifq_set_maxlen(&ifp->if_snd, USABLE_TX_BD(sc)); 959 ifq_set_ready(&ifp->if_snd); 960 961 if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) 962 ifp->if_baudrate = IF_Gbps(2.5); 963 else 964 ifp->if_baudrate = IF_Gbps(1); 965 966 /* Assume a standard 1500 byte MTU size for mbuf allocations. */ 967 sc->mbuf_alloc_size = MCLBYTES; 968 969 /* 970 * Look for our PHY. 971 */ 972 mii_probe_args_init(&mii_args, bce_ifmedia_upd, bce_ifmedia_sts); 973 mii_args.mii_probemask = 1 << sc->bce_phy_addr; 974 mii_args.mii_privtag = MII_PRIVTAG_BRGPHY; 975 mii_args.mii_priv = mii_priv; 976 977 rc = mii_probe(dev, &sc->bce_miibus, &mii_args); 978 if (rc != 0) { 979 device_printf(dev, "PHY probe failed!\n"); 980 goto fail; 981 } 982 983 /* Attach to the Ethernet interface list. */ 984 ether_ifattach(ifp, sc->eaddr, NULL); 985 986 callout_init_mp(&sc->bce_tick_callout); 987 callout_init_mp(&sc->bce_pulse_callout); 988 989 /* Hookup IRQ last. */ 990 rc = bus_setup_intr(dev, sc->bce_res_irq, INTR_MPSAFE, irq_handle, sc, 991 &sc->bce_intrhand, ifp->if_serializer); 992 if (rc != 0) { 993 device_printf(dev, "Failed to setup IRQ!\n"); 994 ether_ifdetach(ifp); 995 goto fail; 996 } 997 998 ifp->if_cpuid = rman_get_cpuid(sc->bce_res_irq); 999 KKASSERT(ifp->if_cpuid >= 0 && ifp->if_cpuid < ncpus); 1000 1001 /* Print some important debugging info. */ 1002 DBRUN(BCE_INFO, bce_dump_driver_state(sc)); 1003 1004 /* Add the supported sysctls to the kernel. */ 1005 bce_add_sysctls(sc); 1006 1007 /* 1008 * The chip reset earlier notified the bootcode that 1009 * a driver is present. We now need to start our pulse 1010 * routine so that the bootcode is reminded that we're 1011 * still running. 1012 */ 1013 bce_pulse(sc); 1014 1015 /* Get the firmware running so IPMI still works */ 1016 bce_mgmt_init(sc); 1017 1018 if (bootverbose) 1019 bce_print_adapter_info(sc); 1020 1021 return 0; 1022 fail: 1023 bce_detach(dev); 1024 return(rc); 1025 } 1026 1027 1028 /****************************************************************************/ 1029 /* Device detach function. */ 1030 /* */ 1031 /* Stops the controller, resets the controller, and releases resources. */ 1032 /* */ 1033 /* Returns: */ 1034 /* 0 on success, positive value on failure. */ 1035 /****************************************************************************/ 1036 static int 1037 bce_detach(device_t dev) 1038 { 1039 struct bce_softc *sc = device_get_softc(dev); 1040 1041 if (device_is_attached(dev)) { 1042 struct ifnet *ifp = &sc->arpcom.ac_if; 1043 uint32_t msg; 1044 1045 /* Stop and reset the controller. */ 1046 lwkt_serialize_enter(ifp->if_serializer); 1047 callout_stop(&sc->bce_pulse_callout); 1048 bce_stop(sc); 1049 if (sc->bce_flags & BCE_NO_WOL_FLAG) 1050 msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN; 1051 else 1052 msg = BCE_DRV_MSG_CODE_UNLOAD; 1053 bce_reset(sc, msg); 1054 bus_teardown_intr(dev, sc->bce_res_irq, sc->bce_intrhand); 1055 lwkt_serialize_exit(ifp->if_serializer); 1056 1057 ether_ifdetach(ifp); 1058 } 1059 1060 /* If we have a child device on the MII bus remove it too. */ 1061 if (sc->bce_miibus) 1062 device_delete_child(dev, sc->bce_miibus); 1063 bus_generic_detach(dev); 1064 1065 if (sc->bce_res_irq != NULL) { 1066 bus_release_resource(dev, SYS_RES_IRQ, sc->bce_irq_rid, 1067 sc->bce_res_irq); 1068 } 1069 1070 if (sc->bce_irq_type == PCI_INTR_TYPE_MSI) 1071 pci_release_msi(dev); 1072 1073 if (sc->bce_res_mem != NULL) { 1074 bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), 1075 sc->bce_res_mem); 1076 } 1077 1078 bce_dma_free(sc); 1079 1080 if (sc->bce_sysctl_tree != NULL) 1081 sysctl_ctx_free(&sc->bce_sysctl_ctx); 1082 1083 return 0; 1084 } 1085 1086 1087 /****************************************************************************/ 1088 /* Device shutdown function. */ 1089 /* */ 1090 /* Stops and resets the controller. */ 1091 /* */ 1092 /* Returns: */ 1093 /* Nothing */ 1094 /****************************************************************************/ 1095 static void 1096 bce_shutdown(device_t dev) 1097 { 1098 struct bce_softc *sc = device_get_softc(dev); 1099 struct ifnet *ifp = &sc->arpcom.ac_if; 1100 uint32_t msg; 1101 1102 lwkt_serialize_enter(ifp->if_serializer); 1103 bce_stop(sc); 1104 if (sc->bce_flags & BCE_NO_WOL_FLAG) 1105 msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN; 1106 else 1107 msg = BCE_DRV_MSG_CODE_UNLOAD; 1108 bce_reset(sc, msg); 1109 lwkt_serialize_exit(ifp->if_serializer); 1110 } 1111 1112 1113 /****************************************************************************/ 1114 /* Indirect register read. */ 1115 /* */ 1116 /* Reads NetXtreme II registers using an index/data register pair in PCI */ 1117 /* configuration space. Using this mechanism avoids issues with posted */ 1118 /* reads but is much slower than memory-mapped I/O. */ 1119 /* */ 1120 /* Returns: */ 1121 /* The value of the register. */ 1122 /****************************************************************************/ 1123 static uint32_t 1124 bce_reg_rd_ind(struct bce_softc *sc, uint32_t offset) 1125 { 1126 device_t dev = sc->bce_dev; 1127 1128 pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4); 1129 #ifdef BCE_DEBUG 1130 { 1131 uint32_t val; 1132 val = pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4); 1133 DBPRINT(sc, BCE_EXCESSIVE, 1134 "%s(); offset = 0x%08X, val = 0x%08X\n", 1135 __func__, offset, val); 1136 return val; 1137 } 1138 #else 1139 return pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4); 1140 #endif 1141 } 1142 1143 1144 /****************************************************************************/ 1145 /* Indirect register write. */ 1146 /* */ 1147 /* Writes NetXtreme II registers using an index/data register pair in PCI */ 1148 /* configuration space. Using this mechanism avoids issues with posted */ 1149 /* writes but is muchh slower than memory-mapped I/O. */ 1150 /* */ 1151 /* Returns: */ 1152 /* Nothing. */ 1153 /****************************************************************************/ 1154 static void 1155 bce_reg_wr_ind(struct bce_softc *sc, uint32_t offset, uint32_t val) 1156 { 1157 device_t dev = sc->bce_dev; 1158 1159 DBPRINT(sc, BCE_EXCESSIVE, "%s(); offset = 0x%08X, val = 0x%08X\n", 1160 __func__, offset, val); 1161 1162 pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4); 1163 pci_write_config(dev, BCE_PCICFG_REG_WINDOW, val, 4); 1164 } 1165 1166 1167 /****************************************************************************/ 1168 /* Shared memory write. */ 1169 /* */ 1170 /* Writes NetXtreme II shared memory region. */ 1171 /* */ 1172 /* Returns: */ 1173 /* Nothing. */ 1174 /****************************************************************************/ 1175 static void 1176 bce_shmem_wr(struct bce_softc *sc, uint32_t offset, uint32_t val) 1177 { 1178 bce_reg_wr_ind(sc, sc->bce_shmem_base + offset, val); 1179 } 1180 1181 1182 /****************************************************************************/ 1183 /* Shared memory read. */ 1184 /* */ 1185 /* Reads NetXtreme II shared memory region. */ 1186 /* */ 1187 /* Returns: */ 1188 /* The 32 bit value read. */ 1189 /****************************************************************************/ 1190 static u32 1191 bce_shmem_rd(struct bce_softc *sc, uint32_t offset) 1192 { 1193 return bce_reg_rd_ind(sc, sc->bce_shmem_base + offset); 1194 } 1195 1196 1197 /****************************************************************************/ 1198 /* Context memory write. */ 1199 /* */ 1200 /* The NetXtreme II controller uses context memory to track connection */ 1201 /* information for L2 and higher network protocols. */ 1202 /* */ 1203 /* Returns: */ 1204 /* Nothing. */ 1205 /****************************************************************************/ 1206 static void 1207 bce_ctx_wr(struct bce_softc *sc, uint32_t cid_addr, uint32_t ctx_offset, 1208 uint32_t ctx_val) 1209 { 1210 uint32_t idx, offset = ctx_offset + cid_addr; 1211 uint32_t val, retry_cnt = 5; 1212 1213 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 1214 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 1215 REG_WR(sc, BCE_CTX_CTX_DATA, ctx_val); 1216 REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_WRITE_REQ)); 1217 1218 for (idx = 0; idx < retry_cnt; idx++) { 1219 val = REG_RD(sc, BCE_CTX_CTX_CTRL); 1220 if ((val & BCE_CTX_CTX_CTRL_WRITE_REQ) == 0) 1221 break; 1222 DELAY(5); 1223 } 1224 1225 if (val & BCE_CTX_CTX_CTRL_WRITE_REQ) { 1226 device_printf(sc->bce_dev, 1227 "Unable to write CTX memory: " 1228 "cid_addr = 0x%08X, offset = 0x%08X!\n", 1229 cid_addr, ctx_offset); 1230 } 1231 } else { 1232 REG_WR(sc, BCE_CTX_DATA_ADR, offset); 1233 REG_WR(sc, BCE_CTX_DATA, ctx_val); 1234 } 1235 } 1236 1237 1238 /****************************************************************************/ 1239 /* PHY register read. */ 1240 /* */ 1241 /* Implements register reads on the MII bus. */ 1242 /* */ 1243 /* Returns: */ 1244 /* The value of the register. */ 1245 /****************************************************************************/ 1246 static int 1247 bce_miibus_read_reg(device_t dev, int phy, int reg) 1248 { 1249 struct bce_softc *sc = device_get_softc(dev); 1250 uint32_t val; 1251 int i; 1252 1253 /* Make sure we are accessing the correct PHY address. */ 1254 KASSERT(phy == sc->bce_phy_addr, 1255 ("invalid phyno %d, should be %d\n", phy, sc->bce_phy_addr)); 1256 1257 if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) { 1258 val = REG_RD(sc, BCE_EMAC_MDIO_MODE); 1259 val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL; 1260 1261 REG_WR(sc, BCE_EMAC_MDIO_MODE, val); 1262 REG_RD(sc, BCE_EMAC_MDIO_MODE); 1263 1264 DELAY(40); 1265 } 1266 1267 val = BCE_MIPHY(phy) | BCE_MIREG(reg) | 1268 BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT | 1269 BCE_EMAC_MDIO_COMM_START_BUSY; 1270 REG_WR(sc, BCE_EMAC_MDIO_COMM, val); 1271 1272 for (i = 0; i < BCE_PHY_TIMEOUT; i++) { 1273 DELAY(10); 1274 1275 val = REG_RD(sc, BCE_EMAC_MDIO_COMM); 1276 if (!(val & BCE_EMAC_MDIO_COMM_START_BUSY)) { 1277 DELAY(5); 1278 1279 val = REG_RD(sc, BCE_EMAC_MDIO_COMM); 1280 val &= BCE_EMAC_MDIO_COMM_DATA; 1281 break; 1282 } 1283 } 1284 1285 if (val & BCE_EMAC_MDIO_COMM_START_BUSY) { 1286 if_printf(&sc->arpcom.ac_if, 1287 "Error: PHY read timeout! phy = %d, reg = 0x%04X\n", 1288 phy, reg); 1289 val = 0x0; 1290 } else { 1291 val = REG_RD(sc, BCE_EMAC_MDIO_COMM); 1292 } 1293 1294 DBPRINT(sc, BCE_EXCESSIVE, 1295 "%s(): phy = %d, reg = 0x%04X, val = 0x%04X\n", 1296 __func__, phy, (uint16_t)reg & 0xffff, (uint16_t) val & 0xffff); 1297 1298 if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) { 1299 val = REG_RD(sc, BCE_EMAC_MDIO_MODE); 1300 val |= BCE_EMAC_MDIO_MODE_AUTO_POLL; 1301 1302 REG_WR(sc, BCE_EMAC_MDIO_MODE, val); 1303 REG_RD(sc, BCE_EMAC_MDIO_MODE); 1304 1305 DELAY(40); 1306 } 1307 return (val & 0xffff); 1308 } 1309 1310 1311 /****************************************************************************/ 1312 /* PHY register write. */ 1313 /* */ 1314 /* Implements register writes on the MII bus. */ 1315 /* */ 1316 /* Returns: */ 1317 /* The value of the register. */ 1318 /****************************************************************************/ 1319 static int 1320 bce_miibus_write_reg(device_t dev, int phy, int reg, int val) 1321 { 1322 struct bce_softc *sc = device_get_softc(dev); 1323 uint32_t val1; 1324 int i; 1325 1326 /* Make sure we are accessing the correct PHY address. */ 1327 KASSERT(phy == sc->bce_phy_addr, 1328 ("invalid phyno %d, should be %d\n", phy, sc->bce_phy_addr)); 1329 1330 DBPRINT(sc, BCE_EXCESSIVE, 1331 "%s(): phy = %d, reg = 0x%04X, val = 0x%04X\n", 1332 __func__, phy, (uint16_t)(reg & 0xffff), 1333 (uint16_t)(val & 0xffff)); 1334 1335 if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) { 1336 val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE); 1337 val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL; 1338 1339 REG_WR(sc, BCE_EMAC_MDIO_MODE, val1); 1340 REG_RD(sc, BCE_EMAC_MDIO_MODE); 1341 1342 DELAY(40); 1343 } 1344 1345 val1 = BCE_MIPHY(phy) | BCE_MIREG(reg) | val | 1346 BCE_EMAC_MDIO_COMM_COMMAND_WRITE | 1347 BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT; 1348 REG_WR(sc, BCE_EMAC_MDIO_COMM, val1); 1349 1350 for (i = 0; i < BCE_PHY_TIMEOUT; i++) { 1351 DELAY(10); 1352 1353 val1 = REG_RD(sc, BCE_EMAC_MDIO_COMM); 1354 if (!(val1 & BCE_EMAC_MDIO_COMM_START_BUSY)) { 1355 DELAY(5); 1356 break; 1357 } 1358 } 1359 1360 if (val1 & BCE_EMAC_MDIO_COMM_START_BUSY) 1361 if_printf(&sc->arpcom.ac_if, "PHY write timeout!\n"); 1362 1363 if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) { 1364 val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE); 1365 val1 |= BCE_EMAC_MDIO_MODE_AUTO_POLL; 1366 1367 REG_WR(sc, BCE_EMAC_MDIO_MODE, val1); 1368 REG_RD(sc, BCE_EMAC_MDIO_MODE); 1369 1370 DELAY(40); 1371 } 1372 return 0; 1373 } 1374 1375 1376 /****************************************************************************/ 1377 /* MII bus status change. */ 1378 /* */ 1379 /* Called by the MII bus driver when the PHY establishes link to set the */ 1380 /* MAC interface registers. */ 1381 /* */ 1382 /* Returns: */ 1383 /* Nothing. */ 1384 /****************************************************************************/ 1385 static void 1386 bce_miibus_statchg(device_t dev) 1387 { 1388 struct bce_softc *sc = device_get_softc(dev); 1389 struct mii_data *mii = device_get_softc(sc->bce_miibus); 1390 1391 DBPRINT(sc, BCE_INFO, "mii_media_active = 0x%08X\n", 1392 mii->mii_media_active); 1393 1394 #ifdef BCE_DEBUG 1395 /* Decode the interface media flags. */ 1396 if_printf(&sc->arpcom.ac_if, "Media: ( "); 1397 switch(IFM_TYPE(mii->mii_media_active)) { 1398 case IFM_ETHER: 1399 kprintf("Ethernet )"); 1400 break; 1401 default: 1402 kprintf("Unknown )"); 1403 break; 1404 } 1405 1406 kprintf(" Media Options: ( "); 1407 switch(IFM_SUBTYPE(mii->mii_media_active)) { 1408 case IFM_AUTO: 1409 kprintf("Autoselect )"); 1410 break; 1411 case IFM_MANUAL: 1412 kprintf("Manual )"); 1413 break; 1414 case IFM_NONE: 1415 kprintf("None )"); 1416 break; 1417 case IFM_10_T: 1418 kprintf("10Base-T )"); 1419 break; 1420 case IFM_100_TX: 1421 kprintf("100Base-TX )"); 1422 break; 1423 case IFM_1000_SX: 1424 kprintf("1000Base-SX )"); 1425 break; 1426 case IFM_1000_T: 1427 kprintf("1000Base-T )"); 1428 break; 1429 default: 1430 kprintf("Other )"); 1431 break; 1432 } 1433 1434 kprintf(" Global Options: ("); 1435 if (mii->mii_media_active & IFM_FDX) 1436 kprintf(" FullDuplex"); 1437 if (mii->mii_media_active & IFM_HDX) 1438 kprintf(" HalfDuplex"); 1439 if (mii->mii_media_active & IFM_LOOP) 1440 kprintf(" Loopback"); 1441 if (mii->mii_media_active & IFM_FLAG0) 1442 kprintf(" Flag0"); 1443 if (mii->mii_media_active & IFM_FLAG1) 1444 kprintf(" Flag1"); 1445 if (mii->mii_media_active & IFM_FLAG2) 1446 kprintf(" Flag2"); 1447 kprintf(" )\n"); 1448 #endif 1449 1450 BCE_CLRBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_PORT); 1451 1452 /* 1453 * Set MII or GMII interface based on the speed negotiated 1454 * by the PHY. 1455 */ 1456 if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T || 1457 IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX) { 1458 DBPRINT(sc, BCE_INFO, "Setting GMII interface.\n"); 1459 BCE_SETBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_PORT_GMII); 1460 } else { 1461 DBPRINT(sc, BCE_INFO, "Setting MII interface.\n"); 1462 BCE_SETBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_PORT_MII); 1463 } 1464 1465 /* 1466 * Set half or full duplex based on the duplicity negotiated 1467 * by the PHY. 1468 */ 1469 if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) { 1470 DBPRINT(sc, BCE_INFO, "Setting Full-Duplex interface.\n"); 1471 BCE_CLRBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_HALF_DUPLEX); 1472 } else { 1473 DBPRINT(sc, BCE_INFO, "Setting Half-Duplex interface.\n"); 1474 BCE_SETBIT(sc, BCE_EMAC_MODE, BCE_EMAC_MODE_HALF_DUPLEX); 1475 } 1476 } 1477 1478 1479 /****************************************************************************/ 1480 /* Acquire NVRAM lock. */ 1481 /* */ 1482 /* Before the NVRAM can be accessed the caller must acquire an NVRAM lock. */ 1483 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is */ 1484 /* for use by the driver. */ 1485 /* */ 1486 /* Returns: */ 1487 /* 0 on success, positive value on failure. */ 1488 /****************************************************************************/ 1489 static int 1490 bce_acquire_nvram_lock(struct bce_softc *sc) 1491 { 1492 uint32_t val; 1493 int j; 1494 1495 DBPRINT(sc, BCE_VERBOSE, "Acquiring NVRAM lock.\n"); 1496 1497 /* Request access to the flash interface. */ 1498 REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_SET2); 1499 for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) { 1500 val = REG_RD(sc, BCE_NVM_SW_ARB); 1501 if (val & BCE_NVM_SW_ARB_ARB_ARB2) 1502 break; 1503 1504 DELAY(5); 1505 } 1506 1507 if (j >= NVRAM_TIMEOUT_COUNT) { 1508 DBPRINT(sc, BCE_WARN, "Timeout acquiring NVRAM lock!\n"); 1509 return EBUSY; 1510 } 1511 return 0; 1512 } 1513 1514 1515 /****************************************************************************/ 1516 /* Release NVRAM lock. */ 1517 /* */ 1518 /* When the caller is finished accessing NVRAM the lock must be released. */ 1519 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is */ 1520 /* for use by the driver. */ 1521 /* */ 1522 /* Returns: */ 1523 /* 0 on success, positive value on failure. */ 1524 /****************************************************************************/ 1525 static int 1526 bce_release_nvram_lock(struct bce_softc *sc) 1527 { 1528 int j; 1529 uint32_t val; 1530 1531 DBPRINT(sc, BCE_VERBOSE, "Releasing NVRAM lock.\n"); 1532 1533 /* 1534 * Relinquish nvram interface. 1535 */ 1536 REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_CLR2); 1537 1538 for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) { 1539 val = REG_RD(sc, BCE_NVM_SW_ARB); 1540 if (!(val & BCE_NVM_SW_ARB_ARB_ARB2)) 1541 break; 1542 1543 DELAY(5); 1544 } 1545 1546 if (j >= NVRAM_TIMEOUT_COUNT) { 1547 DBPRINT(sc, BCE_WARN, "Timeout reeasing NVRAM lock!\n"); 1548 return EBUSY; 1549 } 1550 return 0; 1551 } 1552 1553 1554 /****************************************************************************/ 1555 /* Enable NVRAM access. */ 1556 /* */ 1557 /* Before accessing NVRAM for read or write operations the caller must */ 1558 /* enabled NVRAM access. */ 1559 /* */ 1560 /* Returns: */ 1561 /* Nothing. */ 1562 /****************************************************************************/ 1563 static void 1564 bce_enable_nvram_access(struct bce_softc *sc) 1565 { 1566 uint32_t val; 1567 1568 DBPRINT(sc, BCE_VERBOSE, "Enabling NVRAM access.\n"); 1569 1570 val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE); 1571 /* Enable both bits, even on read. */ 1572 REG_WR(sc, BCE_NVM_ACCESS_ENABLE, 1573 val | BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN); 1574 } 1575 1576 1577 /****************************************************************************/ 1578 /* Disable NVRAM access. */ 1579 /* */ 1580 /* When the caller is finished accessing NVRAM access must be disabled. */ 1581 /* */ 1582 /* Returns: */ 1583 /* Nothing. */ 1584 /****************************************************************************/ 1585 static void 1586 bce_disable_nvram_access(struct bce_softc *sc) 1587 { 1588 uint32_t val; 1589 1590 DBPRINT(sc, BCE_VERBOSE, "Disabling NVRAM access.\n"); 1591 1592 val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE); 1593 1594 /* Disable both bits, even after read. */ 1595 REG_WR(sc, BCE_NVM_ACCESS_ENABLE, 1596 val & ~(BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN)); 1597 } 1598 1599 1600 /****************************************************************************/ 1601 /* Read a dword (32 bits) from NVRAM. */ 1602 /* */ 1603 /* Read a 32 bit word from NVRAM. The caller is assumed to have already */ 1604 /* obtained the NVRAM lock and enabled the controller for NVRAM access. */ 1605 /* */ 1606 /* Returns: */ 1607 /* 0 on success and the 32 bit value read, positive value on failure. */ 1608 /****************************************************************************/ 1609 static int 1610 bce_nvram_read_dword(struct bce_softc *sc, uint32_t offset, uint8_t *ret_val, 1611 uint32_t cmd_flags) 1612 { 1613 uint32_t cmd; 1614 int i, rc = 0; 1615 1616 /* Build the command word. */ 1617 cmd = BCE_NVM_COMMAND_DOIT | cmd_flags; 1618 1619 /* Calculate the offset for buffered flash. */ 1620 if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) { 1621 offset = ((offset / sc->bce_flash_info->page_size) << 1622 sc->bce_flash_info->page_bits) + 1623 (offset % sc->bce_flash_info->page_size); 1624 } 1625 1626 /* 1627 * Clear the DONE bit separately, set the address to read, 1628 * and issue the read. 1629 */ 1630 REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE); 1631 REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE); 1632 REG_WR(sc, BCE_NVM_COMMAND, cmd); 1633 1634 /* Wait for completion. */ 1635 for (i = 0; i < NVRAM_TIMEOUT_COUNT; i++) { 1636 uint32_t val; 1637 1638 DELAY(5); 1639 1640 val = REG_RD(sc, BCE_NVM_COMMAND); 1641 if (val & BCE_NVM_COMMAND_DONE) { 1642 val = REG_RD(sc, BCE_NVM_READ); 1643 1644 val = be32toh(val); 1645 memcpy(ret_val, &val, 4); 1646 break; 1647 } 1648 } 1649 1650 /* Check for errors. */ 1651 if (i >= NVRAM_TIMEOUT_COUNT) { 1652 if_printf(&sc->arpcom.ac_if, 1653 "Timeout error reading NVRAM at offset 0x%08X!\n", 1654 offset); 1655 rc = EBUSY; 1656 } 1657 return rc; 1658 } 1659 1660 1661 /****************************************************************************/ 1662 /* Initialize NVRAM access. */ 1663 /* */ 1664 /* Identify the NVRAM device in use and prepare the NVRAM interface to */ 1665 /* access that device. */ 1666 /* */ 1667 /* Returns: */ 1668 /* 0 on success, positive value on failure. */ 1669 /****************************************************************************/ 1670 static int 1671 bce_init_nvram(struct bce_softc *sc) 1672 { 1673 uint32_t val; 1674 int j, entry_count, rc = 0; 1675 const struct flash_spec *flash; 1676 1677 DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __func__); 1678 1679 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 1680 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 1681 sc->bce_flash_info = &flash_5709; 1682 goto bce_init_nvram_get_flash_size; 1683 } 1684 1685 /* Determine the selected interface. */ 1686 val = REG_RD(sc, BCE_NVM_CFG1); 1687 1688 entry_count = sizeof(flash_table) / sizeof(struct flash_spec); 1689 1690 /* 1691 * Flash reconfiguration is required to support additional 1692 * NVRAM devices not directly supported in hardware. 1693 * Check if the flash interface was reconfigured 1694 * by the bootcode. 1695 */ 1696 1697 if (val & 0x40000000) { 1698 /* Flash interface reconfigured by bootcode. */ 1699 1700 DBPRINT(sc, BCE_INFO_LOAD, 1701 "%s(): Flash WAS reconfigured.\n", __func__); 1702 1703 for (j = 0, flash = flash_table; j < entry_count; 1704 j++, flash++) { 1705 if ((val & FLASH_BACKUP_STRAP_MASK) == 1706 (flash->config1 & FLASH_BACKUP_STRAP_MASK)) { 1707 sc->bce_flash_info = flash; 1708 break; 1709 } 1710 } 1711 } else { 1712 /* Flash interface not yet reconfigured. */ 1713 uint32_t mask; 1714 1715 DBPRINT(sc, BCE_INFO_LOAD, 1716 "%s(): Flash was NOT reconfigured.\n", __func__); 1717 1718 if (val & (1 << 23)) 1719 mask = FLASH_BACKUP_STRAP_MASK; 1720 else 1721 mask = FLASH_STRAP_MASK; 1722 1723 /* Look for the matching NVRAM device configuration data. */ 1724 for (j = 0, flash = flash_table; j < entry_count; 1725 j++, flash++) { 1726 /* Check if the device matches any of the known devices. */ 1727 if ((val & mask) == (flash->strapping & mask)) { 1728 /* Found a device match. */ 1729 sc->bce_flash_info = flash; 1730 1731 /* Request access to the flash interface. */ 1732 rc = bce_acquire_nvram_lock(sc); 1733 if (rc != 0) 1734 return rc; 1735 1736 /* Reconfigure the flash interface. */ 1737 bce_enable_nvram_access(sc); 1738 REG_WR(sc, BCE_NVM_CFG1, flash->config1); 1739 REG_WR(sc, BCE_NVM_CFG2, flash->config2); 1740 REG_WR(sc, BCE_NVM_CFG3, flash->config3); 1741 REG_WR(sc, BCE_NVM_WRITE1, flash->write1); 1742 bce_disable_nvram_access(sc); 1743 bce_release_nvram_lock(sc); 1744 break; 1745 } 1746 } 1747 } 1748 1749 /* Check if a matching device was found. */ 1750 if (j == entry_count) { 1751 sc->bce_flash_info = NULL; 1752 if_printf(&sc->arpcom.ac_if, "Unknown Flash NVRAM found!\n"); 1753 return ENODEV; 1754 } 1755 1756 bce_init_nvram_get_flash_size: 1757 /* Write the flash config data to the shared memory interface. */ 1758 val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG2) & 1759 BCE_SHARED_HW_CFG2_NVM_SIZE_MASK; 1760 if (val) 1761 sc->bce_flash_size = val; 1762 else 1763 sc->bce_flash_size = sc->bce_flash_info->total_size; 1764 1765 DBPRINT(sc, BCE_INFO_LOAD, "%s() flash->total_size = 0x%08X\n", 1766 __func__, sc->bce_flash_info->total_size); 1767 1768 DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __func__); 1769 1770 return rc; 1771 } 1772 1773 1774 /****************************************************************************/ 1775 /* Read an arbitrary range of data from NVRAM. */ 1776 /* */ 1777 /* Prepares the NVRAM interface for access and reads the requested data */ 1778 /* into the supplied buffer. */ 1779 /* */ 1780 /* Returns: */ 1781 /* 0 on success and the data read, positive value on failure. */ 1782 /****************************************************************************/ 1783 static int 1784 bce_nvram_read(struct bce_softc *sc, uint32_t offset, uint8_t *ret_buf, 1785 int buf_size) 1786 { 1787 uint32_t cmd_flags, offset32, len32, extra; 1788 int rc = 0; 1789 1790 if (buf_size == 0) 1791 return 0; 1792 1793 /* Request access to the flash interface. */ 1794 rc = bce_acquire_nvram_lock(sc); 1795 if (rc != 0) 1796 return rc; 1797 1798 /* Enable access to flash interface */ 1799 bce_enable_nvram_access(sc); 1800 1801 len32 = buf_size; 1802 offset32 = offset; 1803 extra = 0; 1804 1805 cmd_flags = 0; 1806 1807 /* XXX should we release nvram lock if read_dword() fails? */ 1808 if (offset32 & 3) { 1809 uint8_t buf[4]; 1810 uint32_t pre_len; 1811 1812 offset32 &= ~3; 1813 pre_len = 4 - (offset & 3); 1814 1815 if (pre_len >= len32) { 1816 pre_len = len32; 1817 cmd_flags = BCE_NVM_COMMAND_FIRST | BCE_NVM_COMMAND_LAST; 1818 } else { 1819 cmd_flags = BCE_NVM_COMMAND_FIRST; 1820 } 1821 1822 rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags); 1823 if (rc) 1824 return rc; 1825 1826 memcpy(ret_buf, buf + (offset & 3), pre_len); 1827 1828 offset32 += 4; 1829 ret_buf += pre_len; 1830 len32 -= pre_len; 1831 } 1832 1833 if (len32 & 3) { 1834 extra = 4 - (len32 & 3); 1835 len32 = (len32 + 4) & ~3; 1836 } 1837 1838 if (len32 == 4) { 1839 uint8_t buf[4]; 1840 1841 if (cmd_flags) 1842 cmd_flags = BCE_NVM_COMMAND_LAST; 1843 else 1844 cmd_flags = BCE_NVM_COMMAND_FIRST | 1845 BCE_NVM_COMMAND_LAST; 1846 1847 rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags); 1848 1849 memcpy(ret_buf, buf, 4 - extra); 1850 } else if (len32 > 0) { 1851 uint8_t buf[4]; 1852 1853 /* Read the first word. */ 1854 if (cmd_flags) 1855 cmd_flags = 0; 1856 else 1857 cmd_flags = BCE_NVM_COMMAND_FIRST; 1858 1859 rc = bce_nvram_read_dword(sc, offset32, ret_buf, cmd_flags); 1860 1861 /* Advance to the next dword. */ 1862 offset32 += 4; 1863 ret_buf += 4; 1864 len32 -= 4; 1865 1866 while (len32 > 4 && rc == 0) { 1867 rc = bce_nvram_read_dword(sc, offset32, ret_buf, 0); 1868 1869 /* Advance to the next dword. */ 1870 offset32 += 4; 1871 ret_buf += 4; 1872 len32 -= 4; 1873 } 1874 1875 if (rc) 1876 goto bce_nvram_read_locked_exit; 1877 1878 cmd_flags = BCE_NVM_COMMAND_LAST; 1879 rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags); 1880 1881 memcpy(ret_buf, buf, 4 - extra); 1882 } 1883 1884 bce_nvram_read_locked_exit: 1885 /* Disable access to flash interface and release the lock. */ 1886 bce_disable_nvram_access(sc); 1887 bce_release_nvram_lock(sc); 1888 1889 return rc; 1890 } 1891 1892 1893 /****************************************************************************/ 1894 /* Verifies that NVRAM is accessible and contains valid data. */ 1895 /* */ 1896 /* Reads the configuration data from NVRAM and verifies that the CRC is */ 1897 /* correct. */ 1898 /* */ 1899 /* Returns: */ 1900 /* 0 on success, positive value on failure. */ 1901 /****************************************************************************/ 1902 static int 1903 bce_nvram_test(struct bce_softc *sc) 1904 { 1905 uint32_t buf[BCE_NVRAM_SIZE / 4]; 1906 uint32_t magic, csum; 1907 uint8_t *data = (uint8_t *)buf; 1908 int rc = 0; 1909 1910 /* 1911 * Check that the device NVRAM is valid by reading 1912 * the magic value at offset 0. 1913 */ 1914 rc = bce_nvram_read(sc, 0, data, 4); 1915 if (rc != 0) 1916 return rc; 1917 1918 magic = be32toh(buf[0]); 1919 if (magic != BCE_NVRAM_MAGIC) { 1920 if_printf(&sc->arpcom.ac_if, 1921 "Invalid NVRAM magic value! Expected: 0x%08X, " 1922 "Found: 0x%08X\n", BCE_NVRAM_MAGIC, magic); 1923 return ENODEV; 1924 } 1925 1926 /* 1927 * Verify that the device NVRAM includes valid 1928 * configuration data. 1929 */ 1930 rc = bce_nvram_read(sc, 0x100, data, BCE_NVRAM_SIZE); 1931 if (rc != 0) 1932 return rc; 1933 1934 csum = ether_crc32_le(data, 0x100); 1935 if (csum != BCE_CRC32_RESIDUAL) { 1936 if_printf(&sc->arpcom.ac_if, 1937 "Invalid Manufacturing Information NVRAM CRC! " 1938 "Expected: 0x%08X, Found: 0x%08X\n", 1939 BCE_CRC32_RESIDUAL, csum); 1940 return ENODEV; 1941 } 1942 1943 csum = ether_crc32_le(data + 0x100, 0x100); 1944 if (csum != BCE_CRC32_RESIDUAL) { 1945 if_printf(&sc->arpcom.ac_if, 1946 "Invalid Feature Configuration Information " 1947 "NVRAM CRC! Expected: 0x%08X, Found: 08%08X\n", 1948 BCE_CRC32_RESIDUAL, csum); 1949 rc = ENODEV; 1950 } 1951 return rc; 1952 } 1953 1954 1955 /****************************************************************************/ 1956 /* Identifies the current media type of the controller and sets the PHY */ 1957 /* address. */ 1958 /* */ 1959 /* Returns: */ 1960 /* Nothing. */ 1961 /****************************************************************************/ 1962 static void 1963 bce_get_media(struct bce_softc *sc) 1964 { 1965 uint32_t val; 1966 1967 sc->bce_phy_addr = 1; 1968 1969 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 1970 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 1971 uint32_t val = REG_RD(sc, BCE_MISC_DUAL_MEDIA_CTRL); 1972 uint32_t bond_id = val & BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID; 1973 uint32_t strap; 1974 1975 /* 1976 * The BCM5709S is software configurable 1977 * for Copper or SerDes operation. 1978 */ 1979 if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_C) { 1980 return; 1981 } else if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_S) { 1982 sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG; 1983 return; 1984 } 1985 1986 if (val & BCE_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE) { 1987 strap = (val & BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21; 1988 } else { 1989 strap = 1990 (val & BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8; 1991 } 1992 1993 if (pci_get_function(sc->bce_dev) == 0) { 1994 switch (strap) { 1995 case 0x4: 1996 case 0x5: 1997 case 0x6: 1998 sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG; 1999 break; 2000 } 2001 } else { 2002 switch (strap) { 2003 case 0x1: 2004 case 0x2: 2005 case 0x4: 2006 sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG; 2007 break; 2008 } 2009 } 2010 } else if (BCE_CHIP_BOND_ID(sc) & BCE_CHIP_BOND_ID_SERDES_BIT) { 2011 sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG; 2012 } 2013 2014 if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) { 2015 sc->bce_flags |= BCE_NO_WOL_FLAG; 2016 if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) { 2017 sc->bce_phy_addr = 2; 2018 val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG); 2019 if (val & BCE_SHARED_HW_CFG_PHY_2_5G) 2020 sc->bce_phy_flags |= BCE_PHY_2_5G_CAPABLE_FLAG; 2021 } 2022 } else if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) || 2023 (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708)) { 2024 sc->bce_phy_flags |= BCE_PHY_CRC_FIX_FLAG; 2025 } 2026 } 2027 2028 2029 /****************************************************************************/ 2030 /* Free any DMA memory owned by the driver. */ 2031 /* */ 2032 /* Scans through each data structre that requires DMA memory and frees */ 2033 /* the memory if allocated. */ 2034 /* */ 2035 /* Returns: */ 2036 /* Nothing. */ 2037 /****************************************************************************/ 2038 static void 2039 bce_dma_free(struct bce_softc *sc) 2040 { 2041 int i; 2042 2043 /* Destroy the status block. */ 2044 if (sc->status_tag != NULL) { 2045 if (sc->status_block != NULL) { 2046 bus_dmamap_unload(sc->status_tag, sc->status_map); 2047 bus_dmamem_free(sc->status_tag, sc->status_block, 2048 sc->status_map); 2049 } 2050 bus_dma_tag_destroy(sc->status_tag); 2051 } 2052 2053 /* Destroy the statistics block. */ 2054 if (sc->stats_tag != NULL) { 2055 if (sc->stats_block != NULL) { 2056 bus_dmamap_unload(sc->stats_tag, sc->stats_map); 2057 bus_dmamem_free(sc->stats_tag, sc->stats_block, 2058 sc->stats_map); 2059 } 2060 bus_dma_tag_destroy(sc->stats_tag); 2061 } 2062 2063 /* Destroy the CTX DMA stuffs. */ 2064 if (sc->ctx_tag != NULL) { 2065 for (i = 0; i < sc->ctx_pages; i++) { 2066 if (sc->ctx_block[i] != NULL) { 2067 bus_dmamap_unload(sc->ctx_tag, sc->ctx_map[i]); 2068 bus_dmamem_free(sc->ctx_tag, sc->ctx_block[i], 2069 sc->ctx_map[i]); 2070 } 2071 } 2072 bus_dma_tag_destroy(sc->ctx_tag); 2073 } 2074 2075 /* Destroy the TX buffer descriptor DMA stuffs. */ 2076 if (sc->tx_bd_chain_tag != NULL) { 2077 for (i = 0; i < sc->tx_pages; i++) { 2078 if (sc->tx_bd_chain[i] != NULL) { 2079 bus_dmamap_unload(sc->tx_bd_chain_tag, 2080 sc->tx_bd_chain_map[i]); 2081 bus_dmamem_free(sc->tx_bd_chain_tag, 2082 sc->tx_bd_chain[i], 2083 sc->tx_bd_chain_map[i]); 2084 } 2085 } 2086 bus_dma_tag_destroy(sc->tx_bd_chain_tag); 2087 } 2088 2089 /* Destroy the RX buffer descriptor DMA stuffs. */ 2090 if (sc->rx_bd_chain_tag != NULL) { 2091 for (i = 0; i < sc->rx_pages; i++) { 2092 if (sc->rx_bd_chain[i] != NULL) { 2093 bus_dmamap_unload(sc->rx_bd_chain_tag, 2094 sc->rx_bd_chain_map[i]); 2095 bus_dmamem_free(sc->rx_bd_chain_tag, 2096 sc->rx_bd_chain[i], 2097 sc->rx_bd_chain_map[i]); 2098 } 2099 } 2100 bus_dma_tag_destroy(sc->rx_bd_chain_tag); 2101 } 2102 2103 /* Destroy the TX mbuf DMA stuffs. */ 2104 if (sc->tx_mbuf_tag != NULL) { 2105 for (i = 0; i < TOTAL_TX_BD(sc); i++) { 2106 /* Must have been unloaded in bce_stop() */ 2107 KKASSERT(sc->tx_mbuf_ptr[i] == NULL); 2108 bus_dmamap_destroy(sc->tx_mbuf_tag, 2109 sc->tx_mbuf_map[i]); 2110 } 2111 bus_dma_tag_destroy(sc->tx_mbuf_tag); 2112 } 2113 2114 /* Destroy the RX mbuf DMA stuffs. */ 2115 if (sc->rx_mbuf_tag != NULL) { 2116 for (i = 0; i < TOTAL_RX_BD(sc); i++) { 2117 /* Must have been unloaded in bce_stop() */ 2118 KKASSERT(sc->rx_mbuf_ptr[i] == NULL); 2119 bus_dmamap_destroy(sc->rx_mbuf_tag, 2120 sc->rx_mbuf_map[i]); 2121 } 2122 bus_dmamap_destroy(sc->rx_mbuf_tag, sc->rx_mbuf_tmpmap); 2123 bus_dma_tag_destroy(sc->rx_mbuf_tag); 2124 } 2125 2126 /* Destroy the parent tag */ 2127 if (sc->parent_tag != NULL) 2128 bus_dma_tag_destroy(sc->parent_tag); 2129 2130 if (sc->tx_bd_chain_map != NULL) 2131 kfree(sc->tx_bd_chain_map, M_DEVBUF); 2132 if (sc->tx_bd_chain != NULL) 2133 kfree(sc->tx_bd_chain, M_DEVBUF); 2134 if (sc->tx_bd_chain_paddr != NULL) 2135 kfree(sc->tx_bd_chain_paddr, M_DEVBUF); 2136 2137 if (sc->rx_bd_chain_map != NULL) 2138 kfree(sc->rx_bd_chain_map, M_DEVBUF); 2139 if (sc->rx_bd_chain != NULL) 2140 kfree(sc->rx_bd_chain, M_DEVBUF); 2141 if (sc->rx_bd_chain_paddr != NULL) 2142 kfree(sc->rx_bd_chain_paddr, M_DEVBUF); 2143 2144 if (sc->tx_mbuf_map != NULL) 2145 kfree(sc->tx_mbuf_map, M_DEVBUF); 2146 if (sc->tx_mbuf_ptr != NULL) 2147 kfree(sc->tx_mbuf_ptr, M_DEVBUF); 2148 2149 if (sc->rx_mbuf_map != NULL) 2150 kfree(sc->rx_mbuf_map, M_DEVBUF); 2151 if (sc->rx_mbuf_ptr != NULL) 2152 kfree(sc->rx_mbuf_ptr, M_DEVBUF); 2153 if (sc->rx_mbuf_paddr != NULL) 2154 kfree(sc->rx_mbuf_paddr, M_DEVBUF); 2155 } 2156 2157 2158 /****************************************************************************/ 2159 /* Get DMA memory from the OS. */ 2160 /* */ 2161 /* Validates that the OS has provided DMA buffers in response to a */ 2162 /* bus_dmamap_load() call and saves the physical address of those buffers. */ 2163 /* When the callback is used the OS will return 0 for the mapping function */ 2164 /* (bus_dmamap_load()) so we use the value of map_arg->maxsegs to pass any */ 2165 /* failures back to the caller. */ 2166 /* */ 2167 /* Returns: */ 2168 /* Nothing. */ 2169 /****************************************************************************/ 2170 static void 2171 bce_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error) 2172 { 2173 bus_addr_t *busaddr = arg; 2174 2175 /* 2176 * Simulate a mapping failure. 2177 * XXX not correct. 2178 */ 2179 DBRUNIF(DB_RANDOMTRUE(bce_debug_dma_map_addr_failure), 2180 kprintf("bce: %s(%d): Simulating DMA mapping error.\n", 2181 __FILE__, __LINE__); 2182 error = ENOMEM); 2183 2184 /* Check for an error and signal the caller that an error occurred. */ 2185 if (error) 2186 return; 2187 2188 KASSERT(nseg == 1, ("only one segment is allowed")); 2189 *busaddr = segs->ds_addr; 2190 } 2191 2192 2193 /****************************************************************************/ 2194 /* Allocate any DMA memory needed by the driver. */ 2195 /* */ 2196 /* Allocates DMA memory needed for the various global structures needed by */ 2197 /* hardware. */ 2198 /* */ 2199 /* Memory alignment requirements: */ 2200 /* -----------------+----------+----------+----------+----------+ */ 2201 /* Data Structure | 5706 | 5708 | 5709 | 5716 | */ 2202 /* -----------------+----------+----------+----------+----------+ */ 2203 /* Status Block | 8 bytes | 8 bytes | 16 bytes | 16 bytes | */ 2204 /* Statistics Block | 8 bytes | 8 bytes | 16 bytes | 16 bytes | */ 2205 /* RX Buffers | 16 bytes | 16 bytes | 16 bytes | 16 bytes | */ 2206 /* PG Buffers | none | none | none | none | */ 2207 /* TX Buffers | none | none | none | none | */ 2208 /* Chain Pages(1) | 4KiB | 4KiB | 4KiB | 4KiB | */ 2209 /* Context Pages(1) | N/A | N/A | 4KiB | 4KiB | */ 2210 /* -----------------+----------+----------+----------+----------+ */ 2211 /* */ 2212 /* (1) Must align with CPU page size (BCM_PAGE_SZIE). */ 2213 /* */ 2214 /* Returns: */ 2215 /* 0 for success, positive value for failure. */ 2216 /****************************************************************************/ 2217 static int 2218 bce_dma_alloc(struct bce_softc *sc) 2219 { 2220 struct ifnet *ifp = &sc->arpcom.ac_if; 2221 int i, j, rc = 0, pages; 2222 bus_addr_t busaddr, max_busaddr; 2223 bus_size_t status_align, stats_align; 2224 2225 pages = device_getenv_int(sc->bce_dev, "rx_pages", bce_rx_pages); 2226 if (pages <= 0 || pages > RX_PAGES_MAX || !powerof2(pages)) { 2227 device_printf(sc->bce_dev, "invalid # of RX pages\n"); 2228 pages = RX_PAGES_DEFAULT; 2229 } 2230 sc->rx_pages = pages; 2231 2232 pages = device_getenv_int(sc->bce_dev, "tx_pages", bce_tx_pages); 2233 if (pages <= 0 || pages > TX_PAGES_MAX || !powerof2(pages)) { 2234 device_printf(sc->bce_dev, "invalid # of TX pages\n"); 2235 pages = TX_PAGES_DEFAULT; 2236 } 2237 sc->tx_pages = pages; 2238 2239 sc->tx_bd_chain_map = kmalloc(sizeof(bus_dmamap_t) * sc->tx_pages, 2240 M_DEVBUF, M_WAITOK | M_ZERO); 2241 sc->tx_bd_chain = kmalloc(sizeof(struct tx_bd *) * sc->tx_pages, 2242 M_DEVBUF, M_WAITOK | M_ZERO); 2243 sc->tx_bd_chain_paddr = kmalloc(sizeof(bus_addr_t) * sc->tx_pages, 2244 M_DEVBUF, M_WAITOK | M_ZERO); 2245 2246 sc->rx_bd_chain_map = kmalloc(sizeof(bus_dmamap_t) * sc->rx_pages, 2247 M_DEVBUF, M_WAITOK | M_ZERO); 2248 sc->rx_bd_chain = kmalloc(sizeof(struct rx_bd *) * sc->rx_pages, 2249 M_DEVBUF, M_WAITOK | M_ZERO); 2250 sc->rx_bd_chain_paddr = kmalloc(sizeof(bus_addr_t) * sc->rx_pages, 2251 M_DEVBUF, M_WAITOK | M_ZERO); 2252 2253 sc->tx_mbuf_map = kmalloc(sizeof(bus_dmamap_t) * TOTAL_TX_BD(sc), 2254 M_DEVBUF, M_WAITOK | M_ZERO); 2255 sc->tx_mbuf_ptr = kmalloc(sizeof(struct mbuf *) * TOTAL_TX_BD(sc), 2256 M_DEVBUF, M_WAITOK | M_ZERO); 2257 2258 sc->rx_mbuf_map = kmalloc(sizeof(bus_dmamap_t) * TOTAL_RX_BD(sc), 2259 M_DEVBUF, M_WAITOK | M_ZERO); 2260 sc->rx_mbuf_ptr = kmalloc(sizeof(struct mbuf *) * TOTAL_RX_BD(sc), 2261 M_DEVBUF, M_WAITOK | M_ZERO); 2262 sc->rx_mbuf_paddr = kmalloc(sizeof(bus_addr_t) * TOTAL_RX_BD(sc), 2263 M_DEVBUF, M_WAITOK | M_ZERO); 2264 2265 /* 2266 * The embedded PCIe to PCI-X bridge (EPB) 2267 * in the 5708 cannot address memory above 2268 * 40 bits (E7_5708CB1_23043 & E6_5708SB1_23043). 2269 */ 2270 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708) 2271 max_busaddr = BCE_BUS_SPACE_MAXADDR; 2272 else 2273 max_busaddr = BUS_SPACE_MAXADDR; 2274 2275 /* 2276 * BCM5709 and BCM5716 uses host memory as cache for context memory. 2277 */ 2278 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 2279 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 2280 sc->ctx_pages = BCE_CTX_BLK_SZ / BCM_PAGE_SIZE; 2281 if (sc->ctx_pages == 0) 2282 sc->ctx_pages = 1; 2283 if (sc->ctx_pages > BCE_CTX_PAGES) { 2284 device_printf(sc->bce_dev, "excessive ctx pages %d\n", 2285 sc->ctx_pages); 2286 return ENOMEM; 2287 } 2288 status_align = 16; 2289 stats_align = 16; 2290 } else { 2291 status_align = 8; 2292 stats_align = 8; 2293 } 2294 2295 /* 2296 * Allocate the parent bus DMA tag appropriate for PCI. 2297 */ 2298 rc = bus_dma_tag_create(NULL, 1, BCE_DMA_BOUNDARY, 2299 max_busaddr, BUS_SPACE_MAXADDR, 2300 NULL, NULL, 2301 BUS_SPACE_MAXSIZE_32BIT, 0, 2302 BUS_SPACE_MAXSIZE_32BIT, 2303 0, &sc->parent_tag); 2304 if (rc != 0) { 2305 if_printf(ifp, "Could not allocate parent DMA tag!\n"); 2306 return rc; 2307 } 2308 2309 /* 2310 * Allocate status block. 2311 */ 2312 sc->status_block = bus_dmamem_coherent_any(sc->parent_tag, 2313 status_align, BCE_STATUS_BLK_SZ, 2314 BUS_DMA_WAITOK | BUS_DMA_ZERO, 2315 &sc->status_tag, &sc->status_map, 2316 &sc->status_block_paddr); 2317 if (sc->status_block == NULL) { 2318 if_printf(ifp, "Could not allocate status block!\n"); 2319 return ENOMEM; 2320 } 2321 2322 /* 2323 * Allocate statistics block. 2324 */ 2325 sc->stats_block = bus_dmamem_coherent_any(sc->parent_tag, 2326 stats_align, BCE_STATS_BLK_SZ, 2327 BUS_DMA_WAITOK | BUS_DMA_ZERO, 2328 &sc->stats_tag, &sc->stats_map, 2329 &sc->stats_block_paddr); 2330 if (sc->stats_block == NULL) { 2331 if_printf(ifp, "Could not allocate statistics block!\n"); 2332 return ENOMEM; 2333 } 2334 2335 /* 2336 * Allocate context block, if needed 2337 */ 2338 if (sc->ctx_pages != 0) { 2339 rc = bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE, 0, 2340 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, 2341 NULL, NULL, 2342 BCM_PAGE_SIZE, 1, BCM_PAGE_SIZE, 2343 0, &sc->ctx_tag); 2344 if (rc != 0) { 2345 if_printf(ifp, "Could not allocate " 2346 "context block DMA tag!\n"); 2347 return rc; 2348 } 2349 2350 for (i = 0; i < sc->ctx_pages; i++) { 2351 rc = bus_dmamem_alloc(sc->ctx_tag, 2352 (void **)&sc->ctx_block[i], 2353 BUS_DMA_WAITOK | BUS_DMA_ZERO | 2354 BUS_DMA_COHERENT, 2355 &sc->ctx_map[i]); 2356 if (rc != 0) { 2357 if_printf(ifp, "Could not allocate %dth context " 2358 "DMA memory!\n", i); 2359 return rc; 2360 } 2361 2362 rc = bus_dmamap_load(sc->ctx_tag, sc->ctx_map[i], 2363 sc->ctx_block[i], BCM_PAGE_SIZE, 2364 bce_dma_map_addr, &busaddr, 2365 BUS_DMA_WAITOK); 2366 if (rc != 0) { 2367 if (rc == EINPROGRESS) { 2368 panic("%s coherent memory loading " 2369 "is still in progress!", ifp->if_xname); 2370 } 2371 if_printf(ifp, "Could not map %dth context " 2372 "DMA memory!\n", i); 2373 bus_dmamem_free(sc->ctx_tag, sc->ctx_block[i], 2374 sc->ctx_map[i]); 2375 sc->ctx_block[i] = NULL; 2376 return rc; 2377 } 2378 sc->ctx_paddr[i] = busaddr; 2379 } 2380 } 2381 2382 /* 2383 * Create a DMA tag for the TX buffer descriptor chain, 2384 * allocate and clear the memory, and fetch the 2385 * physical address of the block. 2386 */ 2387 rc = bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE, 0, 2388 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, 2389 NULL, NULL, 2390 BCE_TX_CHAIN_PAGE_SZ, 1, BCE_TX_CHAIN_PAGE_SZ, 2391 0, &sc->tx_bd_chain_tag); 2392 if (rc != 0) { 2393 if_printf(ifp, "Could not allocate " 2394 "TX descriptor chain DMA tag!\n"); 2395 return rc; 2396 } 2397 2398 for (i = 0; i < sc->tx_pages; i++) { 2399 rc = bus_dmamem_alloc(sc->tx_bd_chain_tag, 2400 (void **)&sc->tx_bd_chain[i], 2401 BUS_DMA_WAITOK | BUS_DMA_ZERO | 2402 BUS_DMA_COHERENT, 2403 &sc->tx_bd_chain_map[i]); 2404 if (rc != 0) { 2405 if_printf(ifp, "Could not allocate %dth TX descriptor " 2406 "chain DMA memory!\n", i); 2407 return rc; 2408 } 2409 2410 rc = bus_dmamap_load(sc->tx_bd_chain_tag, 2411 sc->tx_bd_chain_map[i], 2412 sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ, 2413 bce_dma_map_addr, &busaddr, 2414 BUS_DMA_WAITOK); 2415 if (rc != 0) { 2416 if (rc == EINPROGRESS) { 2417 panic("%s coherent memory loading " 2418 "is still in progress!", ifp->if_xname); 2419 } 2420 if_printf(ifp, "Could not map %dth TX descriptor " 2421 "chain DMA memory!\n", i); 2422 bus_dmamem_free(sc->tx_bd_chain_tag, 2423 sc->tx_bd_chain[i], 2424 sc->tx_bd_chain_map[i]); 2425 sc->tx_bd_chain[i] = NULL; 2426 return rc; 2427 } 2428 2429 sc->tx_bd_chain_paddr[i] = busaddr; 2430 /* DRC - Fix for 64 bit systems. */ 2431 DBPRINT(sc, BCE_INFO, "tx_bd_chain_paddr[%d] = 0x%08X\n", 2432 i, (uint32_t)sc->tx_bd_chain_paddr[i]); 2433 } 2434 2435 /* Create a DMA tag for TX mbufs. */ 2436 rc = bus_dma_tag_create(sc->parent_tag, 1, 0, 2437 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, 2438 NULL, NULL, 2439 /* BCE_MAX_JUMBO_ETHER_MTU_VLAN */MCLBYTES, 2440 BCE_MAX_SEGMENTS, MCLBYTES, 2441 BUS_DMA_ALLOCNOW | BUS_DMA_WAITOK | 2442 BUS_DMA_ONEBPAGE, 2443 &sc->tx_mbuf_tag); 2444 if (rc != 0) { 2445 if_printf(ifp, "Could not allocate TX mbuf DMA tag!\n"); 2446 return rc; 2447 } 2448 2449 /* Create DMA maps for the TX mbufs clusters. */ 2450 for (i = 0; i < TOTAL_TX_BD(sc); i++) { 2451 rc = bus_dmamap_create(sc->tx_mbuf_tag, 2452 BUS_DMA_WAITOK | BUS_DMA_ONEBPAGE, 2453 &sc->tx_mbuf_map[i]); 2454 if (rc != 0) { 2455 for (j = 0; j < i; ++j) { 2456 bus_dmamap_destroy(sc->tx_mbuf_tag, 2457 sc->tx_mbuf_map[i]); 2458 } 2459 bus_dma_tag_destroy(sc->tx_mbuf_tag); 2460 sc->tx_mbuf_tag = NULL; 2461 2462 if_printf(ifp, "Unable to create " 2463 "%dth TX mbuf DMA map!\n", i); 2464 return rc; 2465 } 2466 } 2467 2468 /* 2469 * Create a DMA tag for the RX buffer descriptor chain, 2470 * allocate and clear the memory, and fetch the physical 2471 * address of the blocks. 2472 */ 2473 rc = bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE, 0, 2474 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, 2475 NULL, NULL, 2476 BCE_RX_CHAIN_PAGE_SZ, 1, BCE_RX_CHAIN_PAGE_SZ, 2477 0, &sc->rx_bd_chain_tag); 2478 if (rc != 0) { 2479 if_printf(ifp, "Could not allocate " 2480 "RX descriptor chain DMA tag!\n"); 2481 return rc; 2482 } 2483 2484 for (i = 0; i < sc->rx_pages; i++) { 2485 rc = bus_dmamem_alloc(sc->rx_bd_chain_tag, 2486 (void **)&sc->rx_bd_chain[i], 2487 BUS_DMA_WAITOK | BUS_DMA_ZERO | 2488 BUS_DMA_COHERENT, 2489 &sc->rx_bd_chain_map[i]); 2490 if (rc != 0) { 2491 if_printf(ifp, "Could not allocate %dth RX descriptor " 2492 "chain DMA memory!\n", i); 2493 return rc; 2494 } 2495 2496 rc = bus_dmamap_load(sc->rx_bd_chain_tag, 2497 sc->rx_bd_chain_map[i], 2498 sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ, 2499 bce_dma_map_addr, &busaddr, 2500 BUS_DMA_WAITOK); 2501 if (rc != 0) { 2502 if (rc == EINPROGRESS) { 2503 panic("%s coherent memory loading " 2504 "is still in progress!", ifp->if_xname); 2505 } 2506 if_printf(ifp, "Could not map %dth RX descriptor " 2507 "chain DMA memory!\n", i); 2508 bus_dmamem_free(sc->rx_bd_chain_tag, 2509 sc->rx_bd_chain[i], 2510 sc->rx_bd_chain_map[i]); 2511 sc->rx_bd_chain[i] = NULL; 2512 return rc; 2513 } 2514 2515 sc->rx_bd_chain_paddr[i] = busaddr; 2516 /* DRC - Fix for 64 bit systems. */ 2517 DBPRINT(sc, BCE_INFO, "rx_bd_chain_paddr[%d] = 0x%08X\n", 2518 i, (uint32_t)sc->rx_bd_chain_paddr[i]); 2519 } 2520 2521 /* Create a DMA tag for RX mbufs. */ 2522 rc = bus_dma_tag_create(sc->parent_tag, BCE_DMA_RX_ALIGN, 0, 2523 BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, 2524 NULL, NULL, 2525 MCLBYTES, 1, MCLBYTES, 2526 BUS_DMA_ALLOCNOW | BUS_DMA_ALIGNED | 2527 BUS_DMA_WAITOK, 2528 &sc->rx_mbuf_tag); 2529 if (rc != 0) { 2530 if_printf(ifp, "Could not allocate RX mbuf DMA tag!\n"); 2531 return rc; 2532 } 2533 2534 /* Create tmp DMA map for RX mbuf clusters. */ 2535 rc = bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_WAITOK, 2536 &sc->rx_mbuf_tmpmap); 2537 if (rc != 0) { 2538 bus_dma_tag_destroy(sc->rx_mbuf_tag); 2539 sc->rx_mbuf_tag = NULL; 2540 2541 if_printf(ifp, "Could not create RX mbuf tmp DMA map!\n"); 2542 return rc; 2543 } 2544 2545 /* Create DMA maps for the RX mbuf clusters. */ 2546 for (i = 0; i < TOTAL_RX_BD(sc); i++) { 2547 rc = bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_WAITOK, 2548 &sc->rx_mbuf_map[i]); 2549 if (rc != 0) { 2550 for (j = 0; j < i; ++j) { 2551 bus_dmamap_destroy(sc->rx_mbuf_tag, 2552 sc->rx_mbuf_map[j]); 2553 } 2554 bus_dma_tag_destroy(sc->rx_mbuf_tag); 2555 sc->rx_mbuf_tag = NULL; 2556 2557 if_printf(ifp, "Unable to create " 2558 "%dth RX mbuf DMA map!\n", i); 2559 return rc; 2560 } 2561 } 2562 return 0; 2563 } 2564 2565 2566 /****************************************************************************/ 2567 /* Firmware synchronization. */ 2568 /* */ 2569 /* Before performing certain events such as a chip reset, synchronize with */ 2570 /* the firmware first. */ 2571 /* */ 2572 /* Returns: */ 2573 /* 0 for success, positive value for failure. */ 2574 /****************************************************************************/ 2575 static int 2576 bce_fw_sync(struct bce_softc *sc, uint32_t msg_data) 2577 { 2578 int i, rc = 0; 2579 uint32_t val; 2580 2581 /* Don't waste any time if we've timed out before. */ 2582 if (sc->bce_fw_timed_out) 2583 return EBUSY; 2584 2585 /* Increment the message sequence number. */ 2586 sc->bce_fw_wr_seq++; 2587 msg_data |= sc->bce_fw_wr_seq; 2588 2589 DBPRINT(sc, BCE_VERBOSE, "bce_fw_sync(): msg_data = 0x%08X\n", msg_data); 2590 2591 /* Send the message to the bootcode driver mailbox. */ 2592 bce_shmem_wr(sc, BCE_DRV_MB, msg_data); 2593 2594 /* Wait for the bootcode to acknowledge the message. */ 2595 for (i = 0; i < FW_ACK_TIME_OUT_MS; i++) { 2596 /* Check for a response in the bootcode firmware mailbox. */ 2597 val = bce_shmem_rd(sc, BCE_FW_MB); 2598 if ((val & BCE_FW_MSG_ACK) == (msg_data & BCE_DRV_MSG_SEQ)) 2599 break; 2600 DELAY(1000); 2601 } 2602 2603 /* If we've timed out, tell the bootcode that we've stopped waiting. */ 2604 if ((val & BCE_FW_MSG_ACK) != (msg_data & BCE_DRV_MSG_SEQ) && 2605 (msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0) { 2606 if_printf(&sc->arpcom.ac_if, 2607 "Firmware synchronization timeout! " 2608 "msg_data = 0x%08X\n", msg_data); 2609 2610 msg_data &= ~BCE_DRV_MSG_CODE; 2611 msg_data |= BCE_DRV_MSG_CODE_FW_TIMEOUT; 2612 2613 bce_shmem_wr(sc, BCE_DRV_MB, msg_data); 2614 2615 sc->bce_fw_timed_out = 1; 2616 rc = EBUSY; 2617 } 2618 return rc; 2619 } 2620 2621 2622 /****************************************************************************/ 2623 /* Load Receive Virtual 2 Physical (RV2P) processor firmware. */ 2624 /* */ 2625 /* Returns: */ 2626 /* Nothing. */ 2627 /****************************************************************************/ 2628 static void 2629 bce_load_rv2p_fw(struct bce_softc *sc, uint32_t *rv2p_code, 2630 uint32_t rv2p_code_len, uint32_t rv2p_proc) 2631 { 2632 int i; 2633 uint32_t val; 2634 2635 for (i = 0; i < rv2p_code_len; i += 8) { 2636 REG_WR(sc, BCE_RV2P_INSTR_HIGH, *rv2p_code); 2637 rv2p_code++; 2638 REG_WR(sc, BCE_RV2P_INSTR_LOW, *rv2p_code); 2639 rv2p_code++; 2640 2641 if (rv2p_proc == RV2P_PROC1) { 2642 val = (i / 8) | BCE_RV2P_PROC1_ADDR_CMD_RDWR; 2643 REG_WR(sc, BCE_RV2P_PROC1_ADDR_CMD, val); 2644 } else { 2645 val = (i / 8) | BCE_RV2P_PROC2_ADDR_CMD_RDWR; 2646 REG_WR(sc, BCE_RV2P_PROC2_ADDR_CMD, val); 2647 } 2648 } 2649 2650 /* Reset the processor, un-stall is done later. */ 2651 if (rv2p_proc == RV2P_PROC1) 2652 REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC1_RESET); 2653 else 2654 REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC2_RESET); 2655 } 2656 2657 2658 /****************************************************************************/ 2659 /* Load RISC processor firmware. */ 2660 /* */ 2661 /* Loads firmware from the file if_bcefw.h into the scratchpad memory */ 2662 /* associated with a particular processor. */ 2663 /* */ 2664 /* Returns: */ 2665 /* Nothing. */ 2666 /****************************************************************************/ 2667 static void 2668 bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg, 2669 struct fw_info *fw) 2670 { 2671 uint32_t offset; 2672 int j; 2673 2674 bce_halt_cpu(sc, cpu_reg); 2675 2676 /* Load the Text area. */ 2677 offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base); 2678 if (fw->text) { 2679 for (j = 0; j < (fw->text_len / 4); j++, offset += 4) 2680 REG_WR_IND(sc, offset, fw->text[j]); 2681 } 2682 2683 /* Load the Data area. */ 2684 offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base); 2685 if (fw->data) { 2686 for (j = 0; j < (fw->data_len / 4); j++, offset += 4) 2687 REG_WR_IND(sc, offset, fw->data[j]); 2688 } 2689 2690 /* Load the SBSS area. */ 2691 offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base); 2692 if (fw->sbss) { 2693 for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) 2694 REG_WR_IND(sc, offset, fw->sbss[j]); 2695 } 2696 2697 /* Load the BSS area. */ 2698 offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base); 2699 if (fw->bss) { 2700 for (j = 0; j < (fw->bss_len/4); j++, offset += 4) 2701 REG_WR_IND(sc, offset, fw->bss[j]); 2702 } 2703 2704 /* Load the Read-Only area. */ 2705 offset = cpu_reg->spad_base + 2706 (fw->rodata_addr - cpu_reg->mips_view_base); 2707 if (fw->rodata) { 2708 for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) 2709 REG_WR_IND(sc, offset, fw->rodata[j]); 2710 } 2711 2712 /* Clear the pre-fetch instruction and set the FW start address. */ 2713 REG_WR_IND(sc, cpu_reg->inst, 0); 2714 REG_WR_IND(sc, cpu_reg->pc, fw->start_addr); 2715 } 2716 2717 2718 /****************************************************************************/ 2719 /* Starts the RISC processor. */ 2720 /* */ 2721 /* Assumes the CPU starting address has already been set. */ 2722 /* */ 2723 /* Returns: */ 2724 /* Nothing. */ 2725 /****************************************************************************/ 2726 static void 2727 bce_start_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg) 2728 { 2729 uint32_t val; 2730 2731 /* Start the CPU. */ 2732 val = REG_RD_IND(sc, cpu_reg->mode); 2733 val &= ~cpu_reg->mode_value_halt; 2734 REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear); 2735 REG_WR_IND(sc, cpu_reg->mode, val); 2736 } 2737 2738 2739 /****************************************************************************/ 2740 /* Halts the RISC processor. */ 2741 /* */ 2742 /* Returns: */ 2743 /* Nothing. */ 2744 /****************************************************************************/ 2745 static void 2746 bce_halt_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg) 2747 { 2748 uint32_t val; 2749 2750 /* Halt the CPU. */ 2751 val = REG_RD_IND(sc, cpu_reg->mode); 2752 val |= cpu_reg->mode_value_halt; 2753 REG_WR_IND(sc, cpu_reg->mode, val); 2754 REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear); 2755 } 2756 2757 2758 /****************************************************************************/ 2759 /* Start the RX CPU. */ 2760 /* */ 2761 /* Returns: */ 2762 /* Nothing. */ 2763 /****************************************************************************/ 2764 static void 2765 bce_start_rxp_cpu(struct bce_softc *sc) 2766 { 2767 struct cpu_reg cpu_reg; 2768 2769 cpu_reg.mode = BCE_RXP_CPU_MODE; 2770 cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT; 2771 cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA; 2772 cpu_reg.state = BCE_RXP_CPU_STATE; 2773 cpu_reg.state_value_clear = 0xffffff; 2774 cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE; 2775 cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK; 2776 cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER; 2777 cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION; 2778 cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT; 2779 cpu_reg.spad_base = BCE_RXP_SCRATCH; 2780 cpu_reg.mips_view_base = 0x8000000; 2781 2782 bce_start_cpu(sc, &cpu_reg); 2783 } 2784 2785 2786 /****************************************************************************/ 2787 /* Initialize the RX CPU. */ 2788 /* */ 2789 /* Returns: */ 2790 /* Nothing. */ 2791 /****************************************************************************/ 2792 static void 2793 bce_init_rxp_cpu(struct bce_softc *sc) 2794 { 2795 struct cpu_reg cpu_reg; 2796 struct fw_info fw; 2797 2798 cpu_reg.mode = BCE_RXP_CPU_MODE; 2799 cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT; 2800 cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA; 2801 cpu_reg.state = BCE_RXP_CPU_STATE; 2802 cpu_reg.state_value_clear = 0xffffff; 2803 cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE; 2804 cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK; 2805 cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER; 2806 cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION; 2807 cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT; 2808 cpu_reg.spad_base = BCE_RXP_SCRATCH; 2809 cpu_reg.mips_view_base = 0x8000000; 2810 2811 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 2812 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 2813 fw.ver_major = bce_RXP_b09FwReleaseMajor; 2814 fw.ver_minor = bce_RXP_b09FwReleaseMinor; 2815 fw.ver_fix = bce_RXP_b09FwReleaseFix; 2816 fw.start_addr = bce_RXP_b09FwStartAddr; 2817 2818 fw.text_addr = bce_RXP_b09FwTextAddr; 2819 fw.text_len = bce_RXP_b09FwTextLen; 2820 fw.text_index = 0; 2821 fw.text = bce_RXP_b09FwText; 2822 2823 fw.data_addr = bce_RXP_b09FwDataAddr; 2824 fw.data_len = bce_RXP_b09FwDataLen; 2825 fw.data_index = 0; 2826 fw.data = bce_RXP_b09FwData; 2827 2828 fw.sbss_addr = bce_RXP_b09FwSbssAddr; 2829 fw.sbss_len = bce_RXP_b09FwSbssLen; 2830 fw.sbss_index = 0; 2831 fw.sbss = bce_RXP_b09FwSbss; 2832 2833 fw.bss_addr = bce_RXP_b09FwBssAddr; 2834 fw.bss_len = bce_RXP_b09FwBssLen; 2835 fw.bss_index = 0; 2836 fw.bss = bce_RXP_b09FwBss; 2837 2838 fw.rodata_addr = bce_RXP_b09FwRodataAddr; 2839 fw.rodata_len = bce_RXP_b09FwRodataLen; 2840 fw.rodata_index = 0; 2841 fw.rodata = bce_RXP_b09FwRodata; 2842 } else { 2843 fw.ver_major = bce_RXP_b06FwReleaseMajor; 2844 fw.ver_minor = bce_RXP_b06FwReleaseMinor; 2845 fw.ver_fix = bce_RXP_b06FwReleaseFix; 2846 fw.start_addr = bce_RXP_b06FwStartAddr; 2847 2848 fw.text_addr = bce_RXP_b06FwTextAddr; 2849 fw.text_len = bce_RXP_b06FwTextLen; 2850 fw.text_index = 0; 2851 fw.text = bce_RXP_b06FwText; 2852 2853 fw.data_addr = bce_RXP_b06FwDataAddr; 2854 fw.data_len = bce_RXP_b06FwDataLen; 2855 fw.data_index = 0; 2856 fw.data = bce_RXP_b06FwData; 2857 2858 fw.sbss_addr = bce_RXP_b06FwSbssAddr; 2859 fw.sbss_len = bce_RXP_b06FwSbssLen; 2860 fw.sbss_index = 0; 2861 fw.sbss = bce_RXP_b06FwSbss; 2862 2863 fw.bss_addr = bce_RXP_b06FwBssAddr; 2864 fw.bss_len = bce_RXP_b06FwBssLen; 2865 fw.bss_index = 0; 2866 fw.bss = bce_RXP_b06FwBss; 2867 2868 fw.rodata_addr = bce_RXP_b06FwRodataAddr; 2869 fw.rodata_len = bce_RXP_b06FwRodataLen; 2870 fw.rodata_index = 0; 2871 fw.rodata = bce_RXP_b06FwRodata; 2872 } 2873 2874 DBPRINT(sc, BCE_INFO_RESET, "Loading RX firmware.\n"); 2875 bce_load_cpu_fw(sc, &cpu_reg, &fw); 2876 /* Delay RXP start until initialization is complete. */ 2877 } 2878 2879 2880 /****************************************************************************/ 2881 /* Initialize the TX CPU. */ 2882 /* */ 2883 /* Returns: */ 2884 /* Nothing. */ 2885 /****************************************************************************/ 2886 static void 2887 bce_init_txp_cpu(struct bce_softc *sc) 2888 { 2889 struct cpu_reg cpu_reg; 2890 struct fw_info fw; 2891 2892 cpu_reg.mode = BCE_TXP_CPU_MODE; 2893 cpu_reg.mode_value_halt = BCE_TXP_CPU_MODE_SOFT_HALT; 2894 cpu_reg.mode_value_sstep = BCE_TXP_CPU_MODE_STEP_ENA; 2895 cpu_reg.state = BCE_TXP_CPU_STATE; 2896 cpu_reg.state_value_clear = 0xffffff; 2897 cpu_reg.gpr0 = BCE_TXP_CPU_REG_FILE; 2898 cpu_reg.evmask = BCE_TXP_CPU_EVENT_MASK; 2899 cpu_reg.pc = BCE_TXP_CPU_PROGRAM_COUNTER; 2900 cpu_reg.inst = BCE_TXP_CPU_INSTRUCTION; 2901 cpu_reg.bp = BCE_TXP_CPU_HW_BREAKPOINT; 2902 cpu_reg.spad_base = BCE_TXP_SCRATCH; 2903 cpu_reg.mips_view_base = 0x8000000; 2904 2905 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 2906 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 2907 fw.ver_major = bce_TXP_b09FwReleaseMajor; 2908 fw.ver_minor = bce_TXP_b09FwReleaseMinor; 2909 fw.ver_fix = bce_TXP_b09FwReleaseFix; 2910 fw.start_addr = bce_TXP_b09FwStartAddr; 2911 2912 fw.text_addr = bce_TXP_b09FwTextAddr; 2913 fw.text_len = bce_TXP_b09FwTextLen; 2914 fw.text_index = 0; 2915 fw.text = bce_TXP_b09FwText; 2916 2917 fw.data_addr = bce_TXP_b09FwDataAddr; 2918 fw.data_len = bce_TXP_b09FwDataLen; 2919 fw.data_index = 0; 2920 fw.data = bce_TXP_b09FwData; 2921 2922 fw.sbss_addr = bce_TXP_b09FwSbssAddr; 2923 fw.sbss_len = bce_TXP_b09FwSbssLen; 2924 fw.sbss_index = 0; 2925 fw.sbss = bce_TXP_b09FwSbss; 2926 2927 fw.bss_addr = bce_TXP_b09FwBssAddr; 2928 fw.bss_len = bce_TXP_b09FwBssLen; 2929 fw.bss_index = 0; 2930 fw.bss = bce_TXP_b09FwBss; 2931 2932 fw.rodata_addr = bce_TXP_b09FwRodataAddr; 2933 fw.rodata_len = bce_TXP_b09FwRodataLen; 2934 fw.rodata_index = 0; 2935 fw.rodata = bce_TXP_b09FwRodata; 2936 } else { 2937 fw.ver_major = bce_TXP_b06FwReleaseMajor; 2938 fw.ver_minor = bce_TXP_b06FwReleaseMinor; 2939 fw.ver_fix = bce_TXP_b06FwReleaseFix; 2940 fw.start_addr = bce_TXP_b06FwStartAddr; 2941 2942 fw.text_addr = bce_TXP_b06FwTextAddr; 2943 fw.text_len = bce_TXP_b06FwTextLen; 2944 fw.text_index = 0; 2945 fw.text = bce_TXP_b06FwText; 2946 2947 fw.data_addr = bce_TXP_b06FwDataAddr; 2948 fw.data_len = bce_TXP_b06FwDataLen; 2949 fw.data_index = 0; 2950 fw.data = bce_TXP_b06FwData; 2951 2952 fw.sbss_addr = bce_TXP_b06FwSbssAddr; 2953 fw.sbss_len = bce_TXP_b06FwSbssLen; 2954 fw.sbss_index = 0; 2955 fw.sbss = bce_TXP_b06FwSbss; 2956 2957 fw.bss_addr = bce_TXP_b06FwBssAddr; 2958 fw.bss_len = bce_TXP_b06FwBssLen; 2959 fw.bss_index = 0; 2960 fw.bss = bce_TXP_b06FwBss; 2961 2962 fw.rodata_addr = bce_TXP_b06FwRodataAddr; 2963 fw.rodata_len = bce_TXP_b06FwRodataLen; 2964 fw.rodata_index = 0; 2965 fw.rodata = bce_TXP_b06FwRodata; 2966 } 2967 2968 DBPRINT(sc, BCE_INFO_RESET, "Loading TX firmware.\n"); 2969 bce_load_cpu_fw(sc, &cpu_reg, &fw); 2970 bce_start_cpu(sc, &cpu_reg); 2971 } 2972 2973 2974 /****************************************************************************/ 2975 /* Initialize the TPAT CPU. */ 2976 /* */ 2977 /* Returns: */ 2978 /* Nothing. */ 2979 /****************************************************************************/ 2980 static void 2981 bce_init_tpat_cpu(struct bce_softc *sc) 2982 { 2983 struct cpu_reg cpu_reg; 2984 struct fw_info fw; 2985 2986 cpu_reg.mode = BCE_TPAT_CPU_MODE; 2987 cpu_reg.mode_value_halt = BCE_TPAT_CPU_MODE_SOFT_HALT; 2988 cpu_reg.mode_value_sstep = BCE_TPAT_CPU_MODE_STEP_ENA; 2989 cpu_reg.state = BCE_TPAT_CPU_STATE; 2990 cpu_reg.state_value_clear = 0xffffff; 2991 cpu_reg.gpr0 = BCE_TPAT_CPU_REG_FILE; 2992 cpu_reg.evmask = BCE_TPAT_CPU_EVENT_MASK; 2993 cpu_reg.pc = BCE_TPAT_CPU_PROGRAM_COUNTER; 2994 cpu_reg.inst = BCE_TPAT_CPU_INSTRUCTION; 2995 cpu_reg.bp = BCE_TPAT_CPU_HW_BREAKPOINT; 2996 cpu_reg.spad_base = BCE_TPAT_SCRATCH; 2997 cpu_reg.mips_view_base = 0x8000000; 2998 2999 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 3000 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 3001 fw.ver_major = bce_TPAT_b09FwReleaseMajor; 3002 fw.ver_minor = bce_TPAT_b09FwReleaseMinor; 3003 fw.ver_fix = bce_TPAT_b09FwReleaseFix; 3004 fw.start_addr = bce_TPAT_b09FwStartAddr; 3005 3006 fw.text_addr = bce_TPAT_b09FwTextAddr; 3007 fw.text_len = bce_TPAT_b09FwTextLen; 3008 fw.text_index = 0; 3009 fw.text = bce_TPAT_b09FwText; 3010 3011 fw.data_addr = bce_TPAT_b09FwDataAddr; 3012 fw.data_len = bce_TPAT_b09FwDataLen; 3013 fw.data_index = 0; 3014 fw.data = bce_TPAT_b09FwData; 3015 3016 fw.sbss_addr = bce_TPAT_b09FwSbssAddr; 3017 fw.sbss_len = bce_TPAT_b09FwSbssLen; 3018 fw.sbss_index = 0; 3019 fw.sbss = bce_TPAT_b09FwSbss; 3020 3021 fw.bss_addr = bce_TPAT_b09FwBssAddr; 3022 fw.bss_len = bce_TPAT_b09FwBssLen; 3023 fw.bss_index = 0; 3024 fw.bss = bce_TPAT_b09FwBss; 3025 3026 fw.rodata_addr = bce_TPAT_b09FwRodataAddr; 3027 fw.rodata_len = bce_TPAT_b09FwRodataLen; 3028 fw.rodata_index = 0; 3029 fw.rodata = bce_TPAT_b09FwRodata; 3030 } else { 3031 fw.ver_major = bce_TPAT_b06FwReleaseMajor; 3032 fw.ver_minor = bce_TPAT_b06FwReleaseMinor; 3033 fw.ver_fix = bce_TPAT_b06FwReleaseFix; 3034 fw.start_addr = bce_TPAT_b06FwStartAddr; 3035 3036 fw.text_addr = bce_TPAT_b06FwTextAddr; 3037 fw.text_len = bce_TPAT_b06FwTextLen; 3038 fw.text_index = 0; 3039 fw.text = bce_TPAT_b06FwText; 3040 3041 fw.data_addr = bce_TPAT_b06FwDataAddr; 3042 fw.data_len = bce_TPAT_b06FwDataLen; 3043 fw.data_index = 0; 3044 fw.data = bce_TPAT_b06FwData; 3045 3046 fw.sbss_addr = bce_TPAT_b06FwSbssAddr; 3047 fw.sbss_len = bce_TPAT_b06FwSbssLen; 3048 fw.sbss_index = 0; 3049 fw.sbss = bce_TPAT_b06FwSbss; 3050 3051 fw.bss_addr = bce_TPAT_b06FwBssAddr; 3052 fw.bss_len = bce_TPAT_b06FwBssLen; 3053 fw.bss_index = 0; 3054 fw.bss = bce_TPAT_b06FwBss; 3055 3056 fw.rodata_addr = bce_TPAT_b06FwRodataAddr; 3057 fw.rodata_len = bce_TPAT_b06FwRodataLen; 3058 fw.rodata_index = 0; 3059 fw.rodata = bce_TPAT_b06FwRodata; 3060 } 3061 3062 DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n"); 3063 bce_load_cpu_fw(sc, &cpu_reg, &fw); 3064 bce_start_cpu(sc, &cpu_reg); 3065 } 3066 3067 3068 /****************************************************************************/ 3069 /* Initialize the CP CPU. */ 3070 /* */ 3071 /* Returns: */ 3072 /* Nothing. */ 3073 /****************************************************************************/ 3074 static void 3075 bce_init_cp_cpu(struct bce_softc *sc) 3076 { 3077 struct cpu_reg cpu_reg; 3078 struct fw_info fw; 3079 3080 cpu_reg.mode = BCE_CP_CPU_MODE; 3081 cpu_reg.mode_value_halt = BCE_CP_CPU_MODE_SOFT_HALT; 3082 cpu_reg.mode_value_sstep = BCE_CP_CPU_MODE_STEP_ENA; 3083 cpu_reg.state = BCE_CP_CPU_STATE; 3084 cpu_reg.state_value_clear = 0xffffff; 3085 cpu_reg.gpr0 = BCE_CP_CPU_REG_FILE; 3086 cpu_reg.evmask = BCE_CP_CPU_EVENT_MASK; 3087 cpu_reg.pc = BCE_CP_CPU_PROGRAM_COUNTER; 3088 cpu_reg.inst = BCE_CP_CPU_INSTRUCTION; 3089 cpu_reg.bp = BCE_CP_CPU_HW_BREAKPOINT; 3090 cpu_reg.spad_base = BCE_CP_SCRATCH; 3091 cpu_reg.mips_view_base = 0x8000000; 3092 3093 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 3094 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 3095 fw.ver_major = bce_CP_b09FwReleaseMajor; 3096 fw.ver_minor = bce_CP_b09FwReleaseMinor; 3097 fw.ver_fix = bce_CP_b09FwReleaseFix; 3098 fw.start_addr = bce_CP_b09FwStartAddr; 3099 3100 fw.text_addr = bce_CP_b09FwTextAddr; 3101 fw.text_len = bce_CP_b09FwTextLen; 3102 fw.text_index = 0; 3103 fw.text = bce_CP_b09FwText; 3104 3105 fw.data_addr = bce_CP_b09FwDataAddr; 3106 fw.data_len = bce_CP_b09FwDataLen; 3107 fw.data_index = 0; 3108 fw.data = bce_CP_b09FwData; 3109 3110 fw.sbss_addr = bce_CP_b09FwSbssAddr; 3111 fw.sbss_len = bce_CP_b09FwSbssLen; 3112 fw.sbss_index = 0; 3113 fw.sbss = bce_CP_b09FwSbss; 3114 3115 fw.bss_addr = bce_CP_b09FwBssAddr; 3116 fw.bss_len = bce_CP_b09FwBssLen; 3117 fw.bss_index = 0; 3118 fw.bss = bce_CP_b09FwBss; 3119 3120 fw.rodata_addr = bce_CP_b09FwRodataAddr; 3121 fw.rodata_len = bce_CP_b09FwRodataLen; 3122 fw.rodata_index = 0; 3123 fw.rodata = bce_CP_b09FwRodata; 3124 } else { 3125 fw.ver_major = bce_CP_b06FwReleaseMajor; 3126 fw.ver_minor = bce_CP_b06FwReleaseMinor; 3127 fw.ver_fix = bce_CP_b06FwReleaseFix; 3128 fw.start_addr = bce_CP_b06FwStartAddr; 3129 3130 fw.text_addr = bce_CP_b06FwTextAddr; 3131 fw.text_len = bce_CP_b06FwTextLen; 3132 fw.text_index = 0; 3133 fw.text = bce_CP_b06FwText; 3134 3135 fw.data_addr = bce_CP_b06FwDataAddr; 3136 fw.data_len = bce_CP_b06FwDataLen; 3137 fw.data_index = 0; 3138 fw.data = bce_CP_b06FwData; 3139 3140 fw.sbss_addr = bce_CP_b06FwSbssAddr; 3141 fw.sbss_len = bce_CP_b06FwSbssLen; 3142 fw.sbss_index = 0; 3143 fw.sbss = bce_CP_b06FwSbss; 3144 3145 fw.bss_addr = bce_CP_b06FwBssAddr; 3146 fw.bss_len = bce_CP_b06FwBssLen; 3147 fw.bss_index = 0; 3148 fw.bss = bce_CP_b06FwBss; 3149 3150 fw.rodata_addr = bce_CP_b06FwRodataAddr; 3151 fw.rodata_len = bce_CP_b06FwRodataLen; 3152 fw.rodata_index = 0; 3153 fw.rodata = bce_CP_b06FwRodata; 3154 } 3155 3156 DBPRINT(sc, BCE_INFO_RESET, "Loading CP firmware.\n"); 3157 bce_load_cpu_fw(sc, &cpu_reg, &fw); 3158 bce_start_cpu(sc, &cpu_reg); 3159 } 3160 3161 3162 /****************************************************************************/ 3163 /* Initialize the COM CPU. */ 3164 /* */ 3165 /* Returns: */ 3166 /* Nothing. */ 3167 /****************************************************************************/ 3168 static void 3169 bce_init_com_cpu(struct bce_softc *sc) 3170 { 3171 struct cpu_reg cpu_reg; 3172 struct fw_info fw; 3173 3174 cpu_reg.mode = BCE_COM_CPU_MODE; 3175 cpu_reg.mode_value_halt = BCE_COM_CPU_MODE_SOFT_HALT; 3176 cpu_reg.mode_value_sstep = BCE_COM_CPU_MODE_STEP_ENA; 3177 cpu_reg.state = BCE_COM_CPU_STATE; 3178 cpu_reg.state_value_clear = 0xffffff; 3179 cpu_reg.gpr0 = BCE_COM_CPU_REG_FILE; 3180 cpu_reg.evmask = BCE_COM_CPU_EVENT_MASK; 3181 cpu_reg.pc = BCE_COM_CPU_PROGRAM_COUNTER; 3182 cpu_reg.inst = BCE_COM_CPU_INSTRUCTION; 3183 cpu_reg.bp = BCE_COM_CPU_HW_BREAKPOINT; 3184 cpu_reg.spad_base = BCE_COM_SCRATCH; 3185 cpu_reg.mips_view_base = 0x8000000; 3186 3187 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 3188 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 3189 fw.ver_major = bce_COM_b09FwReleaseMajor; 3190 fw.ver_minor = bce_COM_b09FwReleaseMinor; 3191 fw.ver_fix = bce_COM_b09FwReleaseFix; 3192 fw.start_addr = bce_COM_b09FwStartAddr; 3193 3194 fw.text_addr = bce_COM_b09FwTextAddr; 3195 fw.text_len = bce_COM_b09FwTextLen; 3196 fw.text_index = 0; 3197 fw.text = bce_COM_b09FwText; 3198 3199 fw.data_addr = bce_COM_b09FwDataAddr; 3200 fw.data_len = bce_COM_b09FwDataLen; 3201 fw.data_index = 0; 3202 fw.data = bce_COM_b09FwData; 3203 3204 fw.sbss_addr = bce_COM_b09FwSbssAddr; 3205 fw.sbss_len = bce_COM_b09FwSbssLen; 3206 fw.sbss_index = 0; 3207 fw.sbss = bce_COM_b09FwSbss; 3208 3209 fw.bss_addr = bce_COM_b09FwBssAddr; 3210 fw.bss_len = bce_COM_b09FwBssLen; 3211 fw.bss_index = 0; 3212 fw.bss = bce_COM_b09FwBss; 3213 3214 fw.rodata_addr = bce_COM_b09FwRodataAddr; 3215 fw.rodata_len = bce_COM_b09FwRodataLen; 3216 fw.rodata_index = 0; 3217 fw.rodata = bce_COM_b09FwRodata; 3218 } else { 3219 fw.ver_major = bce_COM_b06FwReleaseMajor; 3220 fw.ver_minor = bce_COM_b06FwReleaseMinor; 3221 fw.ver_fix = bce_COM_b06FwReleaseFix; 3222 fw.start_addr = bce_COM_b06FwStartAddr; 3223 3224 fw.text_addr = bce_COM_b06FwTextAddr; 3225 fw.text_len = bce_COM_b06FwTextLen; 3226 fw.text_index = 0; 3227 fw.text = bce_COM_b06FwText; 3228 3229 fw.data_addr = bce_COM_b06FwDataAddr; 3230 fw.data_len = bce_COM_b06FwDataLen; 3231 fw.data_index = 0; 3232 fw.data = bce_COM_b06FwData; 3233 3234 fw.sbss_addr = bce_COM_b06FwSbssAddr; 3235 fw.sbss_len = bce_COM_b06FwSbssLen; 3236 fw.sbss_index = 0; 3237 fw.sbss = bce_COM_b06FwSbss; 3238 3239 fw.bss_addr = bce_COM_b06FwBssAddr; 3240 fw.bss_len = bce_COM_b06FwBssLen; 3241 fw.bss_index = 0; 3242 fw.bss = bce_COM_b06FwBss; 3243 3244 fw.rodata_addr = bce_COM_b06FwRodataAddr; 3245 fw.rodata_len = bce_COM_b06FwRodataLen; 3246 fw.rodata_index = 0; 3247 fw.rodata = bce_COM_b06FwRodata; 3248 } 3249 3250 DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n"); 3251 bce_load_cpu_fw(sc, &cpu_reg, &fw); 3252 bce_start_cpu(sc, &cpu_reg); 3253 } 3254 3255 3256 /****************************************************************************/ 3257 /* Initialize the RV2P, RX, TX, TPAT, COM, and CP CPUs. */ 3258 /* */ 3259 /* Loads the firmware for each CPU and starts the CPU. */ 3260 /* */ 3261 /* Returns: */ 3262 /* Nothing. */ 3263 /****************************************************************************/ 3264 static void 3265 bce_init_cpus(struct bce_softc *sc) 3266 { 3267 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 3268 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 3269 if (BCE_CHIP_REV(sc) == BCE_CHIP_REV_Ax) { 3270 bce_load_rv2p_fw(sc, bce_xi90_rv2p_proc1, 3271 sizeof(bce_xi90_rv2p_proc1), RV2P_PROC1); 3272 bce_load_rv2p_fw(sc, bce_xi90_rv2p_proc2, 3273 sizeof(bce_xi90_rv2p_proc2), RV2P_PROC2); 3274 } else { 3275 bce_load_rv2p_fw(sc, bce_xi_rv2p_proc1, 3276 sizeof(bce_xi_rv2p_proc1), RV2P_PROC1); 3277 bce_load_rv2p_fw(sc, bce_xi_rv2p_proc2, 3278 sizeof(bce_xi_rv2p_proc2), RV2P_PROC2); 3279 } 3280 } else { 3281 bce_load_rv2p_fw(sc, bce_rv2p_proc1, 3282 sizeof(bce_rv2p_proc1), RV2P_PROC1); 3283 bce_load_rv2p_fw(sc, bce_rv2p_proc2, 3284 sizeof(bce_rv2p_proc2), RV2P_PROC2); 3285 } 3286 3287 bce_init_rxp_cpu(sc); 3288 bce_init_txp_cpu(sc); 3289 bce_init_tpat_cpu(sc); 3290 bce_init_com_cpu(sc); 3291 bce_init_cp_cpu(sc); 3292 } 3293 3294 3295 /****************************************************************************/ 3296 /* Initialize context memory. */ 3297 /* */ 3298 /* Clears the memory associated with each Context ID (CID). */ 3299 /* */ 3300 /* Returns: */ 3301 /* Nothing. */ 3302 /****************************************************************************/ 3303 static int 3304 bce_init_ctx(struct bce_softc *sc) 3305 { 3306 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 3307 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 3308 /* DRC: Replace this constant value with a #define. */ 3309 int i, retry_cnt = 10; 3310 uint32_t val; 3311 3312 /* 3313 * BCM5709 context memory may be cached 3314 * in host memory so prepare the host memory 3315 * for access. 3316 */ 3317 val = BCE_CTX_COMMAND_ENABLED | BCE_CTX_COMMAND_MEM_INIT | 3318 (1 << 12); 3319 val |= (BCM_PAGE_BITS - 8) << 16; 3320 REG_WR(sc, BCE_CTX_COMMAND, val); 3321 3322 /* Wait for mem init command to complete. */ 3323 for (i = 0; i < retry_cnt; i++) { 3324 val = REG_RD(sc, BCE_CTX_COMMAND); 3325 if (!(val & BCE_CTX_COMMAND_MEM_INIT)) 3326 break; 3327 DELAY(2); 3328 } 3329 if (i == retry_cnt) { 3330 device_printf(sc->bce_dev, 3331 "Context memory initialization failed!\n"); 3332 return ETIMEDOUT; 3333 } 3334 3335 for (i = 0; i < sc->ctx_pages; i++) { 3336 int j; 3337 3338 /* 3339 * Set the physical address of the context 3340 * memory cache. 3341 */ 3342 REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA0, 3343 BCE_ADDR_LO(sc->ctx_paddr[i] & 0xfffffff0) | 3344 BCE_CTX_HOST_PAGE_TBL_DATA0_VALID); 3345 REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA1, 3346 BCE_ADDR_HI(sc->ctx_paddr[i])); 3347 REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_CTRL, 3348 i | BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ); 3349 3350 /* 3351 * Verify that the context memory write was successful. 3352 */ 3353 for (j = 0; j < retry_cnt; j++) { 3354 val = REG_RD(sc, BCE_CTX_HOST_PAGE_TBL_CTRL); 3355 if ((val & 3356 BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) == 0) 3357 break; 3358 DELAY(5); 3359 } 3360 if (j == retry_cnt) { 3361 device_printf(sc->bce_dev, 3362 "Failed to initialize context page!\n"); 3363 return ETIMEDOUT; 3364 } 3365 } 3366 } else { 3367 uint32_t vcid_addr, offset; 3368 3369 /* 3370 * For the 5706/5708, context memory is local to 3371 * the controller, so initialize the controller 3372 * context memory. 3373 */ 3374 3375 vcid_addr = GET_CID_ADDR(96); 3376 while (vcid_addr) { 3377 vcid_addr -= PHY_CTX_SIZE; 3378 3379 REG_WR(sc, BCE_CTX_VIRT_ADDR, 0); 3380 REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr); 3381 3382 for (offset = 0; offset < PHY_CTX_SIZE; offset += 4) 3383 CTX_WR(sc, 0x00, offset, 0); 3384 3385 REG_WR(sc, BCE_CTX_VIRT_ADDR, vcid_addr); 3386 REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr); 3387 } 3388 } 3389 return 0; 3390 } 3391 3392 3393 /****************************************************************************/ 3394 /* Fetch the permanent MAC address of the controller. */ 3395 /* */ 3396 /* Returns: */ 3397 /* Nothing. */ 3398 /****************************************************************************/ 3399 static void 3400 bce_get_mac_addr(struct bce_softc *sc) 3401 { 3402 uint32_t mac_lo = 0, mac_hi = 0; 3403 3404 /* 3405 * The NetXtreme II bootcode populates various NIC 3406 * power-on and runtime configuration items in a 3407 * shared memory area. The factory configured MAC 3408 * address is available from both NVRAM and the 3409 * shared memory area so we'll read the value from 3410 * shared memory for speed. 3411 */ 3412 3413 mac_hi = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_UPPER); 3414 mac_lo = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_LOWER); 3415 3416 if (mac_lo == 0 && mac_hi == 0) { 3417 if_printf(&sc->arpcom.ac_if, "Invalid Ethernet address!\n"); 3418 } else { 3419 sc->eaddr[0] = (u_char)(mac_hi >> 8); 3420 sc->eaddr[1] = (u_char)(mac_hi >> 0); 3421 sc->eaddr[2] = (u_char)(mac_lo >> 24); 3422 sc->eaddr[3] = (u_char)(mac_lo >> 16); 3423 sc->eaddr[4] = (u_char)(mac_lo >> 8); 3424 sc->eaddr[5] = (u_char)(mac_lo >> 0); 3425 } 3426 3427 DBPRINT(sc, BCE_INFO, "Permanent Ethernet address = %6D\n", sc->eaddr, ":"); 3428 } 3429 3430 3431 /****************************************************************************/ 3432 /* Program the MAC address. */ 3433 /* */ 3434 /* Returns: */ 3435 /* Nothing. */ 3436 /****************************************************************************/ 3437 static void 3438 bce_set_mac_addr(struct bce_softc *sc) 3439 { 3440 const uint8_t *mac_addr = sc->eaddr; 3441 uint32_t val; 3442 3443 DBPRINT(sc, BCE_INFO, "Setting Ethernet address = %6D\n", 3444 sc->eaddr, ":"); 3445 3446 val = (mac_addr[0] << 8) | mac_addr[1]; 3447 REG_WR(sc, BCE_EMAC_MAC_MATCH0, val); 3448 3449 val = (mac_addr[2] << 24) | 3450 (mac_addr[3] << 16) | 3451 (mac_addr[4] << 8) | 3452 mac_addr[5]; 3453 REG_WR(sc, BCE_EMAC_MAC_MATCH1, val); 3454 } 3455 3456 3457 /****************************************************************************/ 3458 /* Stop the controller. */ 3459 /* */ 3460 /* Returns: */ 3461 /* Nothing. */ 3462 /****************************************************************************/ 3463 static void 3464 bce_stop(struct bce_softc *sc) 3465 { 3466 struct ifnet *ifp = &sc->arpcom.ac_if; 3467 3468 ASSERT_SERIALIZED(ifp->if_serializer); 3469 3470 callout_stop(&sc->bce_tick_callout); 3471 3472 /* Disable the transmit/receive blocks. */ 3473 REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS, BCE_MISC_ENABLE_CLR_DEFAULT); 3474 REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS); 3475 DELAY(20); 3476 3477 bce_disable_intr(sc); 3478 3479 /* Free the RX lists. */ 3480 bce_free_rx_chain(sc); 3481 3482 /* Free TX buffers. */ 3483 bce_free_tx_chain(sc); 3484 3485 sc->bce_link = 0; 3486 sc->bce_coalchg_mask = 0; 3487 3488 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 3489 ifp->if_timer = 0; 3490 } 3491 3492 3493 static int 3494 bce_reset(struct bce_softc *sc, uint32_t reset_code) 3495 { 3496 uint32_t val; 3497 int i, rc = 0; 3498 3499 /* Wait for pending PCI transactions to complete. */ 3500 REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS, 3501 BCE_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE | 3502 BCE_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE | 3503 BCE_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE | 3504 BCE_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE); 3505 val = REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS); 3506 DELAY(5); 3507 3508 /* Disable DMA */ 3509 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 3510 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 3511 val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL); 3512 val &= ~BCE_MISC_NEW_CORE_CTL_DMA_ENABLE; 3513 REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val); 3514 } 3515 3516 /* Assume bootcode is running. */ 3517 sc->bce_fw_timed_out = 0; 3518 sc->bce_drv_cardiac_arrest = 0; 3519 3520 /* Give the firmware a chance to prepare for the reset. */ 3521 rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT0 | reset_code); 3522 if (rc) { 3523 if_printf(&sc->arpcom.ac_if, 3524 "Firmware is not ready for reset\n"); 3525 return rc; 3526 } 3527 3528 /* Set a firmware reminder that this is a soft reset. */ 3529 bce_shmem_wr(sc, BCE_DRV_RESET_SIGNATURE, 3530 BCE_DRV_RESET_SIGNATURE_MAGIC); 3531 3532 /* Dummy read to force the chip to complete all current transactions. */ 3533 val = REG_RD(sc, BCE_MISC_ID); 3534 3535 /* Chip reset. */ 3536 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 3537 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 3538 REG_WR(sc, BCE_MISC_COMMAND, BCE_MISC_COMMAND_SW_RESET); 3539 REG_RD(sc, BCE_MISC_COMMAND); 3540 DELAY(5); 3541 3542 val = BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | 3543 BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP; 3544 3545 pci_write_config(sc->bce_dev, BCE_PCICFG_MISC_CONFIG, val, 4); 3546 } else { 3547 val = BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ | 3548 BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA | 3549 BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP; 3550 REG_WR(sc, BCE_PCICFG_MISC_CONFIG, val); 3551 3552 /* Allow up to 30us for reset to complete. */ 3553 for (i = 0; i < 10; i++) { 3554 val = REG_RD(sc, BCE_PCICFG_MISC_CONFIG); 3555 if ((val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ | 3556 BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) 3557 break; 3558 DELAY(10); 3559 } 3560 3561 /* Check that reset completed successfully. */ 3562 if (val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ | 3563 BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) { 3564 if_printf(&sc->arpcom.ac_if, "Reset failed!\n"); 3565 return EBUSY; 3566 } 3567 } 3568 3569 /* Make sure byte swapping is properly configured. */ 3570 val = REG_RD(sc, BCE_PCI_SWAP_DIAG0); 3571 if (val != 0x01020304) { 3572 if_printf(&sc->arpcom.ac_if, "Byte swap is incorrect!\n"); 3573 return ENODEV; 3574 } 3575 3576 /* Just completed a reset, assume that firmware is running again. */ 3577 sc->bce_fw_timed_out = 0; 3578 sc->bce_drv_cardiac_arrest = 0; 3579 3580 /* Wait for the firmware to finish its initialization. */ 3581 rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT1 | reset_code); 3582 if (rc) { 3583 if_printf(&sc->arpcom.ac_if, 3584 "Firmware did not complete initialization!\n"); 3585 } 3586 return rc; 3587 } 3588 3589 3590 static int 3591 bce_chipinit(struct bce_softc *sc) 3592 { 3593 uint32_t val; 3594 int rc = 0; 3595 3596 /* Make sure the interrupt is not active. */ 3597 REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_MASK_INT); 3598 REG_RD(sc, BCE_PCICFG_INT_ACK_CMD); 3599 3600 /* 3601 * Initialize DMA byte/word swapping, configure the number of DMA 3602 * channels and PCI clock compensation delay. 3603 */ 3604 val = BCE_DMA_CONFIG_DATA_BYTE_SWAP | 3605 BCE_DMA_CONFIG_DATA_WORD_SWAP | 3606 #if BYTE_ORDER == BIG_ENDIAN 3607 BCE_DMA_CONFIG_CNTL_BYTE_SWAP | 3608 #endif 3609 BCE_DMA_CONFIG_CNTL_WORD_SWAP | 3610 DMA_READ_CHANS << 12 | 3611 DMA_WRITE_CHANS << 16; 3612 3613 val |= (0x2 << 20) | BCE_DMA_CONFIG_CNTL_PCI_COMP_DLY; 3614 3615 if ((sc->bce_flags & BCE_PCIX_FLAG) && sc->bus_speed_mhz == 133) 3616 val |= BCE_DMA_CONFIG_PCI_FAST_CLK_CMP; 3617 3618 /* 3619 * This setting resolves a problem observed on certain Intel PCI 3620 * chipsets that cannot handle multiple outstanding DMA operations. 3621 * See errata E9_5706A1_65. 3622 */ 3623 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706 && 3624 BCE_CHIP_ID(sc) != BCE_CHIP_ID_5706_A0 && 3625 !(sc->bce_flags & BCE_PCIX_FLAG)) 3626 val |= BCE_DMA_CONFIG_CNTL_PING_PONG_DMA; 3627 3628 REG_WR(sc, BCE_DMA_CONFIG, val); 3629 3630 /* Enable the RX_V2P and Context state machines before access. */ 3631 REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, 3632 BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE | 3633 BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE | 3634 BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE); 3635 3636 /* Initialize context mapping and zero out the quick contexts. */ 3637 rc = bce_init_ctx(sc); 3638 if (rc != 0) 3639 return rc; 3640 3641 /* Initialize the on-boards CPUs */ 3642 bce_init_cpus(sc); 3643 3644 /* Enable management frames (NC-SI) to flow to the MCP. */ 3645 if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) { 3646 val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) | 3647 BCE_RPM_MGMT_PKT_CTRL_MGMT_EN; 3648 REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val); 3649 } 3650 3651 /* Prepare NVRAM for access. */ 3652 rc = bce_init_nvram(sc); 3653 if (rc != 0) 3654 return rc; 3655 3656 /* Set the kernel bypass block size */ 3657 val = REG_RD(sc, BCE_MQ_CONFIG); 3658 val &= ~BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE; 3659 val |= BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE_256; 3660 3661 /* Enable bins used on the 5709/5716. */ 3662 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 3663 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 3664 val |= BCE_MQ_CONFIG_BIN_MQ_MODE; 3665 if (BCE_CHIP_ID(sc) == BCE_CHIP_ID_5709_A1) 3666 val |= BCE_MQ_CONFIG_HALT_DIS; 3667 } 3668 3669 REG_WR(sc, BCE_MQ_CONFIG, val); 3670 3671 val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE); 3672 REG_WR(sc, BCE_MQ_KNL_BYP_WIND_START, val); 3673 REG_WR(sc, BCE_MQ_KNL_WIND_END, val); 3674 3675 /* Set the page size and clear the RV2P processor stall bits. */ 3676 val = (BCM_PAGE_BITS - 8) << 24; 3677 REG_WR(sc, BCE_RV2P_CONFIG, val); 3678 3679 /* Configure page size. */ 3680 val = REG_RD(sc, BCE_TBDR_CONFIG); 3681 val &= ~BCE_TBDR_CONFIG_PAGE_SIZE; 3682 val |= (BCM_PAGE_BITS - 8) << 24 | 0x40; 3683 REG_WR(sc, BCE_TBDR_CONFIG, val); 3684 3685 /* Set the perfect match control register to default. */ 3686 REG_WR_IND(sc, BCE_RXP_PM_CTRL, 0); 3687 3688 return 0; 3689 } 3690 3691 3692 /****************************************************************************/ 3693 /* Initialize the controller in preparation to send/receive traffic. */ 3694 /* */ 3695 /* Returns: */ 3696 /* 0 for success, positive value for failure. */ 3697 /****************************************************************************/ 3698 static int 3699 bce_blockinit(struct bce_softc *sc) 3700 { 3701 uint32_t reg, val; 3702 int rc = 0; 3703 3704 /* Load the hardware default MAC address. */ 3705 bce_set_mac_addr(sc); 3706 3707 /* Set the Ethernet backoff seed value */ 3708 val = sc->eaddr[0] + (sc->eaddr[1] << 8) + (sc->eaddr[2] << 16) + 3709 sc->eaddr[3] + (sc->eaddr[4] << 8) + (sc->eaddr[5] << 16); 3710 REG_WR(sc, BCE_EMAC_BACKOFF_SEED, val); 3711 3712 sc->last_status_idx = 0; 3713 sc->rx_mode = BCE_EMAC_RX_MODE_SORT_MODE; 3714 3715 sc->pulse_check_status_idx = 0xffff; 3716 3717 /* Set up link change interrupt generation. */ 3718 REG_WR(sc, BCE_EMAC_ATTENTION_ENA, BCE_EMAC_ATTENTION_ENA_LINK); 3719 3720 /* Program the physical address of the status block. */ 3721 REG_WR(sc, BCE_HC_STATUS_ADDR_L, BCE_ADDR_LO(sc->status_block_paddr)); 3722 REG_WR(sc, BCE_HC_STATUS_ADDR_H, BCE_ADDR_HI(sc->status_block_paddr)); 3723 3724 /* Program the physical address of the statistics block. */ 3725 REG_WR(sc, BCE_HC_STATISTICS_ADDR_L, 3726 BCE_ADDR_LO(sc->stats_block_paddr)); 3727 REG_WR(sc, BCE_HC_STATISTICS_ADDR_H, 3728 BCE_ADDR_HI(sc->stats_block_paddr)); 3729 3730 /* Program various host coalescing parameters. */ 3731 REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP, 3732 (sc->bce_tx_quick_cons_trip_int << 16) | 3733 sc->bce_tx_quick_cons_trip); 3734 REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP, 3735 (sc->bce_rx_quick_cons_trip_int << 16) | 3736 sc->bce_rx_quick_cons_trip); 3737 REG_WR(sc, BCE_HC_COMP_PROD_TRIP, 3738 (sc->bce_comp_prod_trip_int << 16) | sc->bce_comp_prod_trip); 3739 REG_WR(sc, BCE_HC_TX_TICKS, 3740 (sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks); 3741 REG_WR(sc, BCE_HC_RX_TICKS, 3742 (sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks); 3743 REG_WR(sc, BCE_HC_COM_TICKS, 3744 (sc->bce_com_ticks_int << 16) | sc->bce_com_ticks); 3745 REG_WR(sc, BCE_HC_CMD_TICKS, 3746 (sc->bce_cmd_ticks_int << 16) | sc->bce_cmd_ticks); 3747 REG_WR(sc, BCE_HC_STATS_TICKS, (sc->bce_stats_ticks & 0xffff00)); 3748 REG_WR(sc, BCE_HC_STAT_COLLECT_TICKS, 0xbb8); /* 3ms */ 3749 3750 val = BCE_HC_CONFIG_TX_TMR_MODE | BCE_HC_CONFIG_COLLECT_STATS; 3751 if (sc->bce_flags & BCE_ONESHOT_MSI_FLAG) { 3752 if (bootverbose) 3753 if_printf(&sc->arpcom.ac_if, "oneshot MSI\n"); 3754 val |= BCE_HC_CONFIG_ONE_SHOT | BCE_HC_CONFIG_USE_INT_PARAM; 3755 } 3756 REG_WR(sc, BCE_HC_CONFIG, val); 3757 3758 /* Clear the internal statistics counters. */ 3759 REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW); 3760 3761 /* Verify that bootcode is running. */ 3762 reg = bce_shmem_rd(sc, BCE_DEV_INFO_SIGNATURE); 3763 3764 DBRUNIF(DB_RANDOMTRUE(bce_debug_bootcode_running_failure), 3765 if_printf(&sc->arpcom.ac_if, 3766 "%s(%d): Simulating bootcode failure.\n", 3767 __FILE__, __LINE__); 3768 reg = 0); 3769 3770 if ((reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK) != 3771 BCE_DEV_INFO_SIGNATURE_MAGIC) { 3772 if_printf(&sc->arpcom.ac_if, 3773 "Bootcode not running! Found: 0x%08X, " 3774 "Expected: 08%08X\n", 3775 reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK, 3776 BCE_DEV_INFO_SIGNATURE_MAGIC); 3777 return ENODEV; 3778 } 3779 3780 /* Enable DMA */ 3781 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 3782 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 3783 val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL); 3784 val |= BCE_MISC_NEW_CORE_CTL_DMA_ENABLE; 3785 REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val); 3786 } 3787 3788 /* Allow bootcode to apply any additional fixes before enabling MAC. */ 3789 rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 | BCE_DRV_MSG_CODE_RESET); 3790 3791 /* Enable link state change interrupt generation. */ 3792 REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE); 3793 3794 /* Enable the RXP. */ 3795 bce_start_rxp_cpu(sc); 3796 3797 /* Disable management frames (NC-SI) from flowing to the MCP. */ 3798 if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) { 3799 val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) & 3800 ~BCE_RPM_MGMT_PKT_CTRL_MGMT_EN; 3801 REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val); 3802 } 3803 3804 /* Enable all remaining blocks in the MAC. */ 3805 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 3806 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 3807 REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, 3808 BCE_MISC_ENABLE_DEFAULT_XI); 3809 } else { 3810 REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT); 3811 } 3812 REG_RD(sc, BCE_MISC_ENABLE_SET_BITS); 3813 DELAY(20); 3814 3815 /* Save the current host coalescing block settings. */ 3816 sc->hc_command = REG_RD(sc, BCE_HC_COMMAND); 3817 3818 return 0; 3819 } 3820 3821 3822 /****************************************************************************/ 3823 /* Encapsulate an mbuf cluster into the rx_bd chain. */ 3824 /* */ 3825 /* The NetXtreme II can support Jumbo frames by using multiple rx_bd's. */ 3826 /* This routine will map an mbuf cluster into 1 or more rx_bd's as */ 3827 /* necessary. */ 3828 /* */ 3829 /* Returns: */ 3830 /* 0 for success, positive value for failure. */ 3831 /****************************************************************************/ 3832 static int 3833 bce_newbuf_std(struct bce_softc *sc, uint16_t *prod, uint16_t *chain_prod, 3834 uint32_t *prod_bseq, int init) 3835 { 3836 bus_dmamap_t map; 3837 bus_dma_segment_t seg; 3838 struct mbuf *m_new; 3839 int error, nseg; 3840 #ifdef BCE_DEBUG 3841 uint16_t debug_chain_prod = *chain_prod; 3842 #endif 3843 3844 /* Make sure the inputs are valid. */ 3845 DBRUNIF((*chain_prod > MAX_RX_BD(sc)), 3846 if_printf(&sc->arpcom.ac_if, "%s(%d): " 3847 "RX producer out of range: 0x%04X > 0x%04X\n", 3848 __FILE__, __LINE__, 3849 *chain_prod, (uint16_t)MAX_RX_BD(sc))); 3850 3851 DBPRINT(sc, BCE_VERBOSE_RECV, "%s(enter): prod = 0x%04X, chain_prod = 0x%04X, " 3852 "prod_bseq = 0x%08X\n", __func__, *prod, *chain_prod, *prod_bseq); 3853 3854 DBRUNIF(DB_RANDOMTRUE(bce_debug_mbuf_allocation_failure), 3855 if_printf(&sc->arpcom.ac_if, "%s(%d): " 3856 "Simulating mbuf allocation failure.\n", 3857 __FILE__, __LINE__); 3858 sc->mbuf_alloc_failed++; 3859 return ENOBUFS); 3860 3861 /* This is a new mbuf allocation. */ 3862 m_new = m_getcl(init ? MB_WAIT : MB_DONTWAIT, MT_DATA, M_PKTHDR); 3863 if (m_new == NULL) 3864 return ENOBUFS; 3865 DBRUNIF(1, sc->rx_mbuf_alloc++); 3866 3867 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 3868 3869 /* Map the mbuf cluster into device memory. */ 3870 error = bus_dmamap_load_mbuf_segment(sc->rx_mbuf_tag, 3871 sc->rx_mbuf_tmpmap, m_new, &seg, 1, &nseg, 3872 BUS_DMA_NOWAIT); 3873 if (error) { 3874 m_freem(m_new); 3875 if (init) { 3876 if_printf(&sc->arpcom.ac_if, 3877 "Error mapping mbuf into RX chain!\n"); 3878 } 3879 DBRUNIF(1, sc->rx_mbuf_alloc--); 3880 return error; 3881 } 3882 3883 if (sc->rx_mbuf_ptr[*chain_prod] != NULL) { 3884 bus_dmamap_unload(sc->rx_mbuf_tag, 3885 sc->rx_mbuf_map[*chain_prod]); 3886 } 3887 3888 map = sc->rx_mbuf_map[*chain_prod]; 3889 sc->rx_mbuf_map[*chain_prod] = sc->rx_mbuf_tmpmap; 3890 sc->rx_mbuf_tmpmap = map; 3891 3892 /* Watch for overflow. */ 3893 DBRUNIF((sc->free_rx_bd > USABLE_RX_BD(sc)), 3894 if_printf(&sc->arpcom.ac_if, "%s(%d): " 3895 "Too many free rx_bd (0x%04X > 0x%04X)!\n", 3896 __FILE__, __LINE__, sc->free_rx_bd, 3897 (uint16_t)USABLE_RX_BD(sc))); 3898 3899 /* Update some debug statistic counters */ 3900 DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark), 3901 sc->rx_low_watermark = sc->free_rx_bd); 3902 DBRUNIF((sc->free_rx_bd == 0), sc->rx_empty_count++); 3903 3904 /* Save the mbuf and update our counter. */ 3905 sc->rx_mbuf_ptr[*chain_prod] = m_new; 3906 sc->rx_mbuf_paddr[*chain_prod] = seg.ds_addr; 3907 sc->free_rx_bd--; 3908 3909 bce_setup_rxdesc_std(sc, *chain_prod, prod_bseq); 3910 3911 DBRUN(BCE_VERBOSE_RECV, 3912 bce_dump_rx_mbuf_chain(sc, debug_chain_prod, 1)); 3913 3914 DBPRINT(sc, BCE_VERBOSE_RECV, "%s(exit): prod = 0x%04X, chain_prod = 0x%04X, " 3915 "prod_bseq = 0x%08X\n", __func__, *prod, *chain_prod, *prod_bseq); 3916 3917 return 0; 3918 } 3919 3920 3921 static void 3922 bce_setup_rxdesc_std(struct bce_softc *sc, uint16_t chain_prod, uint32_t *prod_bseq) 3923 { 3924 struct rx_bd *rxbd; 3925 bus_addr_t paddr; 3926 int len; 3927 3928 paddr = sc->rx_mbuf_paddr[chain_prod]; 3929 len = sc->rx_mbuf_ptr[chain_prod]->m_len; 3930 3931 /* Setup the rx_bd for the first segment. */ 3932 rxbd = &sc->rx_bd_chain[RX_PAGE(chain_prod)][RX_IDX(chain_prod)]; 3933 3934 rxbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(paddr)); 3935 rxbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(paddr)); 3936 rxbd->rx_bd_len = htole32(len); 3937 rxbd->rx_bd_flags = htole32(RX_BD_FLAGS_START); 3938 *prod_bseq += len; 3939 3940 rxbd->rx_bd_flags |= htole32(RX_BD_FLAGS_END); 3941 } 3942 3943 3944 /****************************************************************************/ 3945 /* Initialize the TX context memory. */ 3946 /* */ 3947 /* Returns: */ 3948 /* Nothing */ 3949 /****************************************************************************/ 3950 static void 3951 bce_init_tx_context(struct bce_softc *sc) 3952 { 3953 uint32_t val; 3954 3955 /* Initialize the context ID for an L2 TX chain. */ 3956 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 3957 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 3958 /* Set the CID type to support an L2 connection. */ 3959 val = BCE_L2CTX_TX_TYPE_TYPE_L2 | BCE_L2CTX_TX_TYPE_SIZE_L2; 3960 CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE_XI, val); 3961 val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2 | (8 << 16); 3962 CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_CMD_TYPE_XI, val); 3963 3964 /* Point the hardware to the first page in the chain. */ 3965 val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]); 3966 CTX_WR(sc, GET_CID_ADDR(TX_CID), 3967 BCE_L2CTX_TX_TBDR_BHADDR_HI_XI, val); 3968 val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]); 3969 CTX_WR(sc, GET_CID_ADDR(TX_CID), 3970 BCE_L2CTX_TX_TBDR_BHADDR_LO_XI, val); 3971 } else { 3972 /* Set the CID type to support an L2 connection. */ 3973 val = BCE_L2CTX_TX_TYPE_TYPE_L2 | BCE_L2CTX_TX_TYPE_SIZE_L2; 3974 CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE, val); 3975 val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2 | (8 << 16); 3976 CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_CMD_TYPE, val); 3977 3978 /* Point the hardware to the first page in the chain. */ 3979 val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]); 3980 CTX_WR(sc, GET_CID_ADDR(TX_CID), 3981 BCE_L2CTX_TX_TBDR_BHADDR_HI, val); 3982 val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]); 3983 CTX_WR(sc, GET_CID_ADDR(TX_CID), 3984 BCE_L2CTX_TX_TBDR_BHADDR_LO, val); 3985 } 3986 } 3987 3988 3989 /****************************************************************************/ 3990 /* Allocate memory and initialize the TX data structures. */ 3991 /* */ 3992 /* Returns: */ 3993 /* 0 for success, positive value for failure. */ 3994 /****************************************************************************/ 3995 static int 3996 bce_init_tx_chain(struct bce_softc *sc) 3997 { 3998 struct tx_bd *txbd; 3999 int i, rc = 0; 4000 4001 DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __func__); 4002 4003 /* Set the initial TX producer/consumer indices. */ 4004 sc->tx_prod = 0; 4005 sc->tx_cons = 0; 4006 sc->tx_prod_bseq = 0; 4007 sc->used_tx_bd = 0; 4008 sc->max_tx_bd = USABLE_TX_BD(sc); 4009 DBRUNIF(1, sc->tx_hi_watermark = USABLE_TX_BD(sc)); 4010 DBRUNIF(1, sc->tx_full_count = 0); 4011 4012 /* 4013 * The NetXtreme II supports a linked-list structre called 4014 * a Buffer Descriptor Chain (or BD chain). A BD chain 4015 * consists of a series of 1 or more chain pages, each of which 4016 * consists of a fixed number of BD entries. 4017 * The last BD entry on each page is a pointer to the next page 4018 * in the chain, and the last pointer in the BD chain 4019 * points back to the beginning of the chain. 4020 */ 4021 4022 /* Set the TX next pointer chain entries. */ 4023 for (i = 0; i < sc->tx_pages; i++) { 4024 int j; 4025 4026 txbd = &sc->tx_bd_chain[i][USABLE_TX_BD_PER_PAGE]; 4027 4028 /* Check if we've reached the last page. */ 4029 if (i == (sc->tx_pages - 1)) 4030 j = 0; 4031 else 4032 j = i + 1; 4033 4034 txbd->tx_bd_haddr_hi = 4035 htole32(BCE_ADDR_HI(sc->tx_bd_chain_paddr[j])); 4036 txbd->tx_bd_haddr_lo = 4037 htole32(BCE_ADDR_LO(sc->tx_bd_chain_paddr[j])); 4038 } 4039 bce_init_tx_context(sc); 4040 4041 return(rc); 4042 } 4043 4044 4045 /****************************************************************************/ 4046 /* Free memory and clear the TX data structures. */ 4047 /* */ 4048 /* Returns: */ 4049 /* Nothing. */ 4050 /****************************************************************************/ 4051 static void 4052 bce_free_tx_chain(struct bce_softc *sc) 4053 { 4054 int i; 4055 4056 DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __func__); 4057 4058 /* Unmap, unload, and free any mbufs still in the TX mbuf chain. */ 4059 for (i = 0; i < TOTAL_TX_BD(sc); i++) { 4060 if (sc->tx_mbuf_ptr[i] != NULL) { 4061 bus_dmamap_unload(sc->tx_mbuf_tag, sc->tx_mbuf_map[i]); 4062 m_freem(sc->tx_mbuf_ptr[i]); 4063 sc->tx_mbuf_ptr[i] = NULL; 4064 DBRUNIF(1, sc->tx_mbuf_alloc--); 4065 } 4066 } 4067 4068 /* Clear each TX chain page. */ 4069 for (i = 0; i < sc->tx_pages; i++) 4070 bzero(sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ); 4071 sc->used_tx_bd = 0; 4072 4073 /* Check if we lost any mbufs in the process. */ 4074 DBRUNIF((sc->tx_mbuf_alloc), 4075 if_printf(&sc->arpcom.ac_if, 4076 "%s(%d): Memory leak! " 4077 "Lost %d mbufs from tx chain!\n", 4078 __FILE__, __LINE__, sc->tx_mbuf_alloc)); 4079 4080 DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __func__); 4081 } 4082 4083 4084 /****************************************************************************/ 4085 /* Initialize the RX context memory. */ 4086 /* */ 4087 /* Returns: */ 4088 /* Nothing */ 4089 /****************************************************************************/ 4090 static void 4091 bce_init_rx_context(struct bce_softc *sc) 4092 { 4093 uint32_t val; 4094 4095 /* Initialize the context ID for an L2 RX chain. */ 4096 val = BCE_L2CTX_RX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE | 4097 BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 | (0x02 << 8); 4098 4099 /* 4100 * Set the level for generating pause frames 4101 * when the number of available rx_bd's gets 4102 * too low (the low watermark) and the level 4103 * when pause frames can be stopped (the high 4104 * watermark). 4105 */ 4106 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 4107 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 4108 uint32_t lo_water, hi_water; 4109 4110 lo_water = BCE_L2CTX_RX_LO_WATER_MARK_DEFAULT; 4111 hi_water = USABLE_RX_BD(sc) / 4; 4112 4113 lo_water /= BCE_L2CTX_RX_LO_WATER_MARK_SCALE; 4114 hi_water /= BCE_L2CTX_RX_HI_WATER_MARK_SCALE; 4115 4116 if (hi_water > 0xf) 4117 hi_water = 0xf; 4118 else if (hi_water == 0) 4119 lo_water = 0; 4120 val |= lo_water | 4121 (hi_water << BCE_L2CTX_RX_HI_WATER_MARK_SHIFT); 4122 } 4123 4124 CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_CTX_TYPE, val); 4125 4126 /* Setup the MQ BIN mapping for l2_ctx_host_bseq. */ 4127 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 4128 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 4129 val = REG_RD(sc, BCE_MQ_MAP_L2_5); 4130 REG_WR(sc, BCE_MQ_MAP_L2_5, val | BCE_MQ_MAP_L2_5_ARM); 4131 } 4132 4133 /* Point the hardware to the first page in the chain. */ 4134 val = BCE_ADDR_HI(sc->rx_bd_chain_paddr[0]); 4135 CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_HI, val); 4136 val = BCE_ADDR_LO(sc->rx_bd_chain_paddr[0]); 4137 CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_LO, val); 4138 } 4139 4140 4141 /****************************************************************************/ 4142 /* Allocate memory and initialize the RX data structures. */ 4143 /* */ 4144 /* Returns: */ 4145 /* 0 for success, positive value for failure. */ 4146 /****************************************************************************/ 4147 static int 4148 bce_init_rx_chain(struct bce_softc *sc) 4149 { 4150 struct rx_bd *rxbd; 4151 int i, rc = 0; 4152 uint16_t prod, chain_prod; 4153 uint32_t prod_bseq; 4154 4155 DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __func__); 4156 4157 /* Initialize the RX producer and consumer indices. */ 4158 sc->rx_prod = 0; 4159 sc->rx_cons = 0; 4160 sc->rx_prod_bseq = 0; 4161 sc->free_rx_bd = USABLE_RX_BD(sc); 4162 sc->max_rx_bd = USABLE_RX_BD(sc); 4163 DBRUNIF(1, sc->rx_low_watermark = USABLE_RX_BD(sc)); 4164 DBRUNIF(1, sc->rx_empty_count = 0); 4165 4166 /* Initialize the RX next pointer chain entries. */ 4167 for (i = 0; i < sc->rx_pages; i++) { 4168 int j; 4169 4170 rxbd = &sc->rx_bd_chain[i][USABLE_RX_BD_PER_PAGE]; 4171 4172 /* Check if we've reached the last page. */ 4173 if (i == (sc->rx_pages - 1)) 4174 j = 0; 4175 else 4176 j = i + 1; 4177 4178 /* Setup the chain page pointers. */ 4179 rxbd->rx_bd_haddr_hi = 4180 htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j])); 4181 rxbd->rx_bd_haddr_lo = 4182 htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j])); 4183 } 4184 4185 /* Allocate mbuf clusters for the rx_bd chain. */ 4186 prod = prod_bseq = 0; 4187 while (prod < TOTAL_RX_BD(sc)) { 4188 chain_prod = RX_CHAIN_IDX(sc, prod); 4189 if (bce_newbuf_std(sc, &prod, &chain_prod, &prod_bseq, 1)) { 4190 if_printf(&sc->arpcom.ac_if, 4191 "Error filling RX chain: rx_bd[0x%04X]!\n", 4192 chain_prod); 4193 rc = ENOBUFS; 4194 break; 4195 } 4196 prod = NEXT_RX_BD(prod); 4197 } 4198 4199 /* Save the RX chain producer index. */ 4200 sc->rx_prod = prod; 4201 sc->rx_prod_bseq = prod_bseq; 4202 4203 /* Tell the chip about the waiting rx_bd's. */ 4204 REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BDIDX, 4205 sc->rx_prod); 4206 REG_WR(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BSEQ, 4207 sc->rx_prod_bseq); 4208 4209 bce_init_rx_context(sc); 4210 4211 return(rc); 4212 } 4213 4214 4215 /****************************************************************************/ 4216 /* Free memory and clear the RX data structures. */ 4217 /* */ 4218 /* Returns: */ 4219 /* Nothing. */ 4220 /****************************************************************************/ 4221 static void 4222 bce_free_rx_chain(struct bce_softc *sc) 4223 { 4224 int i; 4225 4226 DBPRINT(sc, BCE_VERBOSE_RESET, "Entering %s()\n", __func__); 4227 4228 /* Free any mbufs still in the RX mbuf chain. */ 4229 for (i = 0; i < TOTAL_RX_BD(sc); i++) { 4230 if (sc->rx_mbuf_ptr[i] != NULL) { 4231 bus_dmamap_unload(sc->rx_mbuf_tag, sc->rx_mbuf_map[i]); 4232 m_freem(sc->rx_mbuf_ptr[i]); 4233 sc->rx_mbuf_ptr[i] = NULL; 4234 DBRUNIF(1, sc->rx_mbuf_alloc--); 4235 } 4236 } 4237 4238 /* Clear each RX chain page. */ 4239 for (i = 0; i < sc->rx_pages; i++) 4240 bzero(sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ); 4241 4242 /* Check if we lost any mbufs in the process. */ 4243 DBRUNIF((sc->rx_mbuf_alloc), 4244 if_printf(&sc->arpcom.ac_if, 4245 "%s(%d): Memory leak! " 4246 "Lost %d mbufs from rx chain!\n", 4247 __FILE__, __LINE__, sc->rx_mbuf_alloc)); 4248 4249 DBPRINT(sc, BCE_VERBOSE_RESET, "Exiting %s()\n", __func__); 4250 } 4251 4252 4253 /****************************************************************************/ 4254 /* Set media options. */ 4255 /* */ 4256 /* Returns: */ 4257 /* 0 for success, positive value for failure. */ 4258 /****************************************************************************/ 4259 static int 4260 bce_ifmedia_upd(struct ifnet *ifp) 4261 { 4262 struct bce_softc *sc = ifp->if_softc; 4263 struct mii_data *mii = device_get_softc(sc->bce_miibus); 4264 int error = 0; 4265 4266 /* 4267 * 'mii' will be NULL, when this function is called on following 4268 * code path: bce_attach() -> bce_mgmt_init() 4269 */ 4270 if (mii != NULL) { 4271 /* Make sure the MII bus has been enumerated. */ 4272 sc->bce_link = 0; 4273 if (mii->mii_instance) { 4274 struct mii_softc *miisc; 4275 4276 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) 4277 mii_phy_reset(miisc); 4278 } 4279 error = mii_mediachg(mii); 4280 } 4281 return error; 4282 } 4283 4284 4285 /****************************************************************************/ 4286 /* Reports current media status. */ 4287 /* */ 4288 /* Returns: */ 4289 /* Nothing. */ 4290 /****************************************************************************/ 4291 static void 4292 bce_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 4293 { 4294 struct bce_softc *sc = ifp->if_softc; 4295 struct mii_data *mii = device_get_softc(sc->bce_miibus); 4296 4297 mii_pollstat(mii); 4298 ifmr->ifm_active = mii->mii_media_active; 4299 ifmr->ifm_status = mii->mii_media_status; 4300 } 4301 4302 4303 /****************************************************************************/ 4304 /* Handles PHY generated interrupt events. */ 4305 /* */ 4306 /* Returns: */ 4307 /* Nothing. */ 4308 /****************************************************************************/ 4309 static void 4310 bce_phy_intr(struct bce_softc *sc) 4311 { 4312 uint32_t new_link_state, old_link_state; 4313 struct ifnet *ifp = &sc->arpcom.ac_if; 4314 4315 ASSERT_SERIALIZED(ifp->if_serializer); 4316 4317 new_link_state = sc->status_block->status_attn_bits & 4318 STATUS_ATTN_BITS_LINK_STATE; 4319 old_link_state = sc->status_block->status_attn_bits_ack & 4320 STATUS_ATTN_BITS_LINK_STATE; 4321 4322 /* Handle any changes if the link state has changed. */ 4323 if (new_link_state != old_link_state) { /* XXX redundant? */ 4324 DBRUN(BCE_VERBOSE_INTR, bce_dump_status_block(sc)); 4325 4326 /* Update the status_attn_bits_ack field in the status block. */ 4327 if (new_link_state) { 4328 REG_WR(sc, BCE_PCICFG_STATUS_BIT_SET_CMD, 4329 STATUS_ATTN_BITS_LINK_STATE); 4330 if (bootverbose) 4331 if_printf(ifp, "Link is now UP.\n"); 4332 } else { 4333 REG_WR(sc, BCE_PCICFG_STATUS_BIT_CLEAR_CMD, 4334 STATUS_ATTN_BITS_LINK_STATE); 4335 if (bootverbose) 4336 if_printf(ifp, "Link is now DOWN.\n"); 4337 } 4338 4339 /* 4340 * Assume link is down and allow tick routine to 4341 * update the state based on the actual media state. 4342 */ 4343 sc->bce_link = 0; 4344 callout_stop(&sc->bce_tick_callout); 4345 bce_tick_serialized(sc); 4346 } 4347 4348 /* Acknowledge the link change interrupt. */ 4349 REG_WR(sc, BCE_EMAC_STATUS, BCE_EMAC_STATUS_LINK_CHANGE); 4350 } 4351 4352 4353 /****************************************************************************/ 4354 /* Reads the receive consumer value from the status block (skipping over */ 4355 /* chain page pointer if necessary). */ 4356 /* */ 4357 /* Returns: */ 4358 /* hw_cons */ 4359 /****************************************************************************/ 4360 static __inline uint16_t 4361 bce_get_hw_rx_cons(struct bce_softc *sc) 4362 { 4363 uint16_t hw_cons = sc->status_block->status_rx_quick_consumer_index0; 4364 4365 if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE) 4366 hw_cons++; 4367 return hw_cons; 4368 } 4369 4370 4371 /****************************************************************************/ 4372 /* Handles received frame interrupt events. */ 4373 /* */ 4374 /* Returns: */ 4375 /* Nothing. */ 4376 /****************************************************************************/ 4377 static void 4378 bce_rx_intr(struct bce_softc *sc, int count) 4379 { 4380 struct ifnet *ifp = &sc->arpcom.ac_if; 4381 uint16_t hw_cons, sw_cons, sw_chain_cons, sw_prod, sw_chain_prod; 4382 uint32_t sw_prod_bseq; 4383 4384 ASSERT_SERIALIZED(ifp->if_serializer); 4385 4386 DBRUNIF(1, sc->rx_interrupts++); 4387 4388 /* Get the hardware's view of the RX consumer index. */ 4389 hw_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc); 4390 4391 /* Get working copies of the driver's view of the RX indices. */ 4392 sw_cons = sc->rx_cons; 4393 sw_prod = sc->rx_prod; 4394 sw_prod_bseq = sc->rx_prod_bseq; 4395 4396 DBPRINT(sc, BCE_INFO_RECV, "%s(enter): sw_prod = 0x%04X, " 4397 "sw_cons = 0x%04X, sw_prod_bseq = 0x%08X\n", 4398 __func__, sw_prod, sw_cons, sw_prod_bseq); 4399 4400 /* Prevent speculative reads from getting ahead of the status block. */ 4401 bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0, 4402 BUS_SPACE_BARRIER_READ); 4403 4404 /* Update some debug statistics counters */ 4405 DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark), 4406 sc->rx_low_watermark = sc->free_rx_bd); 4407 DBRUNIF((sc->free_rx_bd == 0), sc->rx_empty_count++); 4408 4409 /* Scan through the receive chain as long as there is work to do. */ 4410 while (sw_cons != hw_cons) { 4411 struct mbuf *m = NULL; 4412 struct l2_fhdr *l2fhdr = NULL; 4413 struct rx_bd *rxbd; 4414 unsigned int len; 4415 uint32_t status = 0; 4416 4417 #ifdef DEVICE_POLLING 4418 if (count >= 0 && count-- == 0) { 4419 sc->hw_rx_cons = sw_cons; 4420 break; 4421 } 4422 #endif 4423 4424 /* 4425 * Convert the producer/consumer indices 4426 * to an actual rx_bd index. 4427 */ 4428 sw_chain_cons = RX_CHAIN_IDX(sc, sw_cons); 4429 sw_chain_prod = RX_CHAIN_IDX(sc, sw_prod); 4430 4431 /* Get the used rx_bd. */ 4432 rxbd = &sc->rx_bd_chain[RX_PAGE(sw_chain_cons)] 4433 [RX_IDX(sw_chain_cons)]; 4434 sc->free_rx_bd++; 4435 4436 DBRUN(BCE_VERBOSE_RECV, 4437 if_printf(ifp, "%s(): ", __func__); 4438 bce_dump_rxbd(sc, sw_chain_cons, rxbd)); 4439 4440 /* The mbuf is stored with the last rx_bd entry of a packet. */ 4441 if (sc->rx_mbuf_ptr[sw_chain_cons] != NULL) { 4442 /* Validate that this is the last rx_bd. */ 4443 DBRUNIF((!(rxbd->rx_bd_flags & RX_BD_FLAGS_END)), 4444 if_printf(ifp, "%s(%d): " 4445 "Unexpected mbuf found in rx_bd[0x%04X]!\n", 4446 __FILE__, __LINE__, sw_chain_cons); 4447 bce_breakpoint(sc)); 4448 4449 if (sw_chain_cons != sw_chain_prod) { 4450 if_printf(ifp, "RX cons(%d) != prod(%d), " 4451 "drop!\n", sw_chain_cons, 4452 sw_chain_prod); 4453 ifp->if_ierrors++; 4454 4455 bce_setup_rxdesc_std(sc, sw_chain_cons, 4456 &sw_prod_bseq); 4457 m = NULL; 4458 goto bce_rx_int_next_rx; 4459 } 4460 4461 /* Unmap the mbuf from DMA space. */ 4462 bus_dmamap_sync(sc->rx_mbuf_tag, 4463 sc->rx_mbuf_map[sw_chain_cons], 4464 BUS_DMASYNC_POSTREAD); 4465 4466 /* Save the mbuf from the driver's chain. */ 4467 m = sc->rx_mbuf_ptr[sw_chain_cons]; 4468 4469 /* 4470 * Frames received on the NetXteme II are prepended 4471 * with an l2_fhdr structure which provides status 4472 * information about the received frame (including 4473 * VLAN tags and checksum info). The frames are also 4474 * automatically adjusted to align the IP header 4475 * (i.e. two null bytes are inserted before the 4476 * Ethernet header). As a result the data DMA'd by 4477 * the controller into the mbuf is as follows: 4478 * 4479 * +---------+-----+---------------------+-----+ 4480 * | l2_fhdr | pad | packet data | FCS | 4481 * +---------+-----+---------------------+-----+ 4482 * 4483 * The l2_fhdr needs to be checked and skipped and the 4484 * FCS needs to be stripped before sending the packet 4485 * up the stack. 4486 */ 4487 l2fhdr = mtod(m, struct l2_fhdr *); 4488 4489 len = l2fhdr->l2_fhdr_pkt_len; 4490 status = l2fhdr->l2_fhdr_status; 4491 4492 DBRUNIF(DB_RANDOMTRUE(bce_debug_l2fhdr_status_check), 4493 if_printf(ifp, 4494 "Simulating l2_fhdr status error.\n"); 4495 status = status | L2_FHDR_ERRORS_PHY_DECODE); 4496 4497 /* Watch for unusual sized frames. */ 4498 DBRUNIF((len < BCE_MIN_MTU || 4499 len > BCE_MAX_JUMBO_ETHER_MTU_VLAN), 4500 if_printf(ifp, 4501 "%s(%d): Unusual frame size found. " 4502 "Min(%d), Actual(%d), Max(%d)\n", 4503 __FILE__, __LINE__, 4504 (int)BCE_MIN_MTU, len, 4505 (int)BCE_MAX_JUMBO_ETHER_MTU_VLAN); 4506 bce_dump_mbuf(sc, m); 4507 bce_breakpoint(sc)); 4508 4509 len -= ETHER_CRC_LEN; 4510 4511 /* Check the received frame for errors. */ 4512 if (status & (L2_FHDR_ERRORS_BAD_CRC | 4513 L2_FHDR_ERRORS_PHY_DECODE | 4514 L2_FHDR_ERRORS_ALIGNMENT | 4515 L2_FHDR_ERRORS_TOO_SHORT | 4516 L2_FHDR_ERRORS_GIANT_FRAME)) { 4517 ifp->if_ierrors++; 4518 DBRUNIF(1, sc->l2fhdr_status_errors++); 4519 4520 /* Reuse the mbuf for a new frame. */ 4521 bce_setup_rxdesc_std(sc, sw_chain_prod, 4522 &sw_prod_bseq); 4523 m = NULL; 4524 goto bce_rx_int_next_rx; 4525 } 4526 4527 /* 4528 * Get a new mbuf for the rx_bd. If no new 4529 * mbufs are available then reuse the current mbuf, 4530 * log an ierror on the interface, and generate 4531 * an error in the system log. 4532 */ 4533 if (bce_newbuf_std(sc, &sw_prod, &sw_chain_prod, 4534 &sw_prod_bseq, 0)) { 4535 DBRUN(BCE_WARN, 4536 if_printf(ifp, 4537 "%s(%d): Failed to allocate new mbuf, " 4538 "incoming frame dropped!\n", 4539 __FILE__, __LINE__)); 4540 4541 ifp->if_ierrors++; 4542 4543 /* Try and reuse the exisitng mbuf. */ 4544 bce_setup_rxdesc_std(sc, sw_chain_prod, 4545 &sw_prod_bseq); 4546 m = NULL; 4547 goto bce_rx_int_next_rx; 4548 } 4549 4550 /* 4551 * Skip over the l2_fhdr when passing 4552 * the data up the stack. 4553 */ 4554 m_adj(m, sizeof(struct l2_fhdr) + ETHER_ALIGN); 4555 4556 m->m_pkthdr.len = m->m_len = len; 4557 m->m_pkthdr.rcvif = ifp; 4558 4559 DBRUN(BCE_VERBOSE_RECV, 4560 struct ether_header *eh; 4561 eh = mtod(m, struct ether_header *); 4562 if_printf(ifp, "%s(): to: %6D, from: %6D, " 4563 "type: 0x%04X\n", __func__, 4564 eh->ether_dhost, ":", 4565 eh->ether_shost, ":", 4566 htons(eh->ether_type))); 4567 4568 /* Validate the checksum if offload enabled. */ 4569 if (ifp->if_capenable & IFCAP_RXCSUM) { 4570 /* Check for an IP datagram. */ 4571 if (status & L2_FHDR_STATUS_IP_DATAGRAM) { 4572 m->m_pkthdr.csum_flags |= 4573 CSUM_IP_CHECKED; 4574 4575 /* Check if the IP checksum is valid. */ 4576 if ((l2fhdr->l2_fhdr_ip_xsum ^ 4577 0xffff) == 0) { 4578 m->m_pkthdr.csum_flags |= 4579 CSUM_IP_VALID; 4580 } else { 4581 DBPRINT(sc, BCE_WARN_RECV, 4582 "%s(): Invalid IP checksum = 0x%04X!\n", 4583 __func__, l2fhdr->l2_fhdr_ip_xsum); 4584 } 4585 } 4586 4587 /* Check for a valid TCP/UDP frame. */ 4588 if (status & (L2_FHDR_STATUS_TCP_SEGMENT | 4589 L2_FHDR_STATUS_UDP_DATAGRAM)) { 4590 4591 /* Check for a good TCP/UDP checksum. */ 4592 if ((status & 4593 (L2_FHDR_ERRORS_TCP_XSUM | 4594 L2_FHDR_ERRORS_UDP_XSUM)) == 0) { 4595 m->m_pkthdr.csum_data = 4596 l2fhdr->l2_fhdr_tcp_udp_xsum; 4597 m->m_pkthdr.csum_flags |= 4598 CSUM_DATA_VALID | 4599 CSUM_PSEUDO_HDR; 4600 } else { 4601 DBPRINT(sc, BCE_WARN_RECV, 4602 "%s(): Invalid TCP/UDP checksum = 0x%04X!\n", 4603 __func__, l2fhdr->l2_fhdr_tcp_udp_xsum); 4604 } 4605 } 4606 } 4607 4608 ifp->if_ipackets++; 4609 bce_rx_int_next_rx: 4610 sw_prod = NEXT_RX_BD(sw_prod); 4611 } 4612 4613 sw_cons = NEXT_RX_BD(sw_cons); 4614 4615 /* If we have a packet, pass it up the stack */ 4616 if (m) { 4617 DBPRINT(sc, BCE_VERBOSE_RECV, 4618 "%s(): Passing received frame up.\n", __func__); 4619 4620 if (status & L2_FHDR_STATUS_L2_VLAN_TAG) { 4621 m->m_flags |= M_VLANTAG; 4622 m->m_pkthdr.ether_vlantag = 4623 l2fhdr->l2_fhdr_vlan_tag; 4624 } 4625 ifp->if_input(ifp, m); 4626 4627 DBRUNIF(1, sc->rx_mbuf_alloc--); 4628 } 4629 4630 /* 4631 * If polling(4) is not enabled, refresh hw_cons to see 4632 * whether there's new work. 4633 * 4634 * If polling(4) is enabled, i.e count >= 0, refreshing 4635 * should not be performed, so that we would not spend 4636 * too much time in RX processing. 4637 */ 4638 if (count < 0 && sw_cons == hw_cons) 4639 hw_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc); 4640 4641 /* 4642 * Prevent speculative reads from getting ahead 4643 * of the status block. 4644 */ 4645 bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0, 4646 BUS_SPACE_BARRIER_READ); 4647 } 4648 4649 sc->rx_cons = sw_cons; 4650 sc->rx_prod = sw_prod; 4651 sc->rx_prod_bseq = sw_prod_bseq; 4652 4653 REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BDIDX, 4654 sc->rx_prod); 4655 REG_WR(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BSEQ, 4656 sc->rx_prod_bseq); 4657 4658 DBPRINT(sc, BCE_INFO_RECV, "%s(exit): rx_prod = 0x%04X, " 4659 "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n", 4660 __func__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq); 4661 } 4662 4663 4664 /****************************************************************************/ 4665 /* Reads the transmit consumer value from the status block (skipping over */ 4666 /* chain page pointer if necessary). */ 4667 /* */ 4668 /* Returns: */ 4669 /* hw_cons */ 4670 /****************************************************************************/ 4671 static __inline uint16_t 4672 bce_get_hw_tx_cons(struct bce_softc *sc) 4673 { 4674 uint16_t hw_cons = sc->status_block->status_tx_quick_consumer_index0; 4675 4676 if ((hw_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE) 4677 hw_cons++; 4678 return hw_cons; 4679 } 4680 4681 4682 /****************************************************************************/ 4683 /* Handles transmit completion interrupt events. */ 4684 /* */ 4685 /* Returns: */ 4686 /* Nothing. */ 4687 /****************************************************************************/ 4688 static void 4689 bce_tx_intr(struct bce_softc *sc) 4690 { 4691 struct ifnet *ifp = &sc->arpcom.ac_if; 4692 uint16_t hw_tx_cons, sw_tx_cons, sw_tx_chain_cons; 4693 4694 ASSERT_SERIALIZED(ifp->if_serializer); 4695 4696 DBRUNIF(1, sc->tx_interrupts++); 4697 4698 /* Get the hardware's view of the TX consumer index. */ 4699 hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc); 4700 sw_tx_cons = sc->tx_cons; 4701 4702 /* Prevent speculative reads from getting ahead of the status block. */ 4703 bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0, 4704 BUS_SPACE_BARRIER_READ); 4705 4706 /* Cycle through any completed TX chain page entries. */ 4707 while (sw_tx_cons != hw_tx_cons) { 4708 #ifdef BCE_DEBUG 4709 struct tx_bd *txbd = NULL; 4710 #endif 4711 sw_tx_chain_cons = TX_CHAIN_IDX(sc, sw_tx_cons); 4712 4713 DBPRINT(sc, BCE_INFO_SEND, 4714 "%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, " 4715 "sw_tx_chain_cons = 0x%04X\n", 4716 __func__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons); 4717 4718 DBRUNIF((sw_tx_chain_cons > MAX_TX_BD(sc)), 4719 if_printf(ifp, "%s(%d): " 4720 "TX chain consumer out of range! " 4721 " 0x%04X > 0x%04X\n", 4722 __FILE__, __LINE__, sw_tx_chain_cons, 4723 (int)MAX_TX_BD(sc)); 4724 bce_breakpoint(sc)); 4725 4726 DBRUNIF(1, txbd = &sc->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)] 4727 [TX_IDX(sw_tx_chain_cons)]); 4728 4729 DBRUNIF((txbd == NULL), 4730 if_printf(ifp, "%s(%d): " 4731 "Unexpected NULL tx_bd[0x%04X]!\n", 4732 __FILE__, __LINE__, sw_tx_chain_cons); 4733 bce_breakpoint(sc)); 4734 4735 DBRUN(BCE_INFO_SEND, 4736 if_printf(ifp, "%s(): ", __func__); 4737 bce_dump_txbd(sc, sw_tx_chain_cons, txbd)); 4738 4739 /* 4740 * Free the associated mbuf. Remember 4741 * that only the last tx_bd of a packet 4742 * has an mbuf pointer and DMA map. 4743 */ 4744 if (sc->tx_mbuf_ptr[sw_tx_chain_cons] != NULL) { 4745 /* Validate that this is the last tx_bd. */ 4746 DBRUNIF((!(txbd->tx_bd_flags & TX_BD_FLAGS_END)), 4747 if_printf(ifp, "%s(%d): " 4748 "tx_bd END flag not set but " 4749 "txmbuf == NULL!\n", __FILE__, __LINE__); 4750 bce_breakpoint(sc)); 4751 4752 DBRUN(BCE_INFO_SEND, 4753 if_printf(ifp, "%s(): Unloading map/freeing mbuf " 4754 "from tx_bd[0x%04X]\n", __func__, 4755 sw_tx_chain_cons)); 4756 4757 /* Unmap the mbuf. */ 4758 bus_dmamap_unload(sc->tx_mbuf_tag, 4759 sc->tx_mbuf_map[sw_tx_chain_cons]); 4760 4761 /* Free the mbuf. */ 4762 m_freem(sc->tx_mbuf_ptr[sw_tx_chain_cons]); 4763 sc->tx_mbuf_ptr[sw_tx_chain_cons] = NULL; 4764 DBRUNIF(1, sc->tx_mbuf_alloc--); 4765 4766 ifp->if_opackets++; 4767 } 4768 4769 sc->used_tx_bd--; 4770 sw_tx_cons = NEXT_TX_BD(sw_tx_cons); 4771 4772 if (sw_tx_cons == hw_tx_cons) { 4773 /* Refresh hw_cons to see if there's new work. */ 4774 hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc); 4775 } 4776 4777 /* 4778 * Prevent speculative reads from getting 4779 * ahead of the status block. 4780 */ 4781 bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0, 4782 BUS_SPACE_BARRIER_READ); 4783 } 4784 4785 if (sc->used_tx_bd == 0) { 4786 /* Clear the TX timeout timer. */ 4787 ifp->if_timer = 0; 4788 } 4789 4790 /* Clear the tx hardware queue full flag. */ 4791 if (sc->max_tx_bd - sc->used_tx_bd >= BCE_TX_SPARE_SPACE) { 4792 DBRUNIF((ifp->if_flags & IFF_OACTIVE), 4793 DBPRINT(sc, BCE_WARN_SEND, 4794 "%s(): Open TX chain! %d/%d (used/total)\n", 4795 __func__, sc->used_tx_bd, sc->max_tx_bd)); 4796 ifp->if_flags &= ~IFF_OACTIVE; 4797 } 4798 sc->tx_cons = sw_tx_cons; 4799 } 4800 4801 4802 /****************************************************************************/ 4803 /* Disables interrupt generation. */ 4804 /* */ 4805 /* Returns: */ 4806 /* Nothing. */ 4807 /****************************************************************************/ 4808 static void 4809 bce_disable_intr(struct bce_softc *sc) 4810 { 4811 REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_MASK_INT); 4812 REG_RD(sc, BCE_PCICFG_INT_ACK_CMD); 4813 lwkt_serialize_handler_disable(sc->arpcom.ac_if.if_serializer); 4814 } 4815 4816 4817 /****************************************************************************/ 4818 /* Enables interrupt generation. */ 4819 /* */ 4820 /* Returns: */ 4821 /* Nothing. */ 4822 /****************************************************************************/ 4823 static void 4824 bce_enable_intr(struct bce_softc *sc) 4825 { 4826 lwkt_serialize_handler_enable(sc->arpcom.ac_if.if_serializer); 4827 4828 REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, 4829 BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | 4830 BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx); 4831 REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, 4832 BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx); 4833 4834 REG_WR(sc, BCE_HC_COMMAND, sc->hc_command | BCE_HC_COMMAND_COAL_NOW); 4835 } 4836 4837 4838 /****************************************************************************/ 4839 /* Reenables interrupt generation during interrupt handling. */ 4840 /* */ 4841 /* Returns: */ 4842 /* Nothing. */ 4843 /****************************************************************************/ 4844 static void 4845 bce_reenable_intr(struct bce_softc *sc) 4846 { 4847 if (sc->bce_irq_type == PCI_INTR_TYPE_LEGACY) { 4848 REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, 4849 BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | 4850 BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx); 4851 } 4852 REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, 4853 BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx); 4854 } 4855 4856 /****************************************************************************/ 4857 /* Handles controller initialization. */ 4858 /* */ 4859 /* Returns: */ 4860 /* Nothing. */ 4861 /****************************************************************************/ 4862 static void 4863 bce_init(void *xsc) 4864 { 4865 struct bce_softc *sc = xsc; 4866 struct ifnet *ifp = &sc->arpcom.ac_if; 4867 uint32_t ether_mtu; 4868 int error; 4869 4870 ASSERT_SERIALIZED(ifp->if_serializer); 4871 4872 /* Check if the driver is still running and bail out if it is. */ 4873 if (ifp->if_flags & IFF_RUNNING) 4874 return; 4875 4876 bce_stop(sc); 4877 4878 error = bce_reset(sc, BCE_DRV_MSG_CODE_RESET); 4879 if (error) { 4880 if_printf(ifp, "Controller reset failed!\n"); 4881 goto back; 4882 } 4883 4884 error = bce_chipinit(sc); 4885 if (error) { 4886 if_printf(ifp, "Controller initialization failed!\n"); 4887 goto back; 4888 } 4889 4890 error = bce_blockinit(sc); 4891 if (error) { 4892 if_printf(ifp, "Block initialization failed!\n"); 4893 goto back; 4894 } 4895 4896 /* Load our MAC address. */ 4897 bcopy(IF_LLADDR(ifp), sc->eaddr, ETHER_ADDR_LEN); 4898 bce_set_mac_addr(sc); 4899 4900 /* Calculate and program the Ethernet MTU size. */ 4901 ether_mtu = ETHER_HDR_LEN + EVL_ENCAPLEN + ifp->if_mtu + ETHER_CRC_LEN; 4902 4903 DBPRINT(sc, BCE_INFO, "%s(): setting mtu = %d\n", __func__, ether_mtu); 4904 4905 /* 4906 * Program the mtu, enabling jumbo frame 4907 * support if necessary. Also set the mbuf 4908 * allocation count for RX frames. 4909 */ 4910 if (ether_mtu > ETHER_MAX_LEN + EVL_ENCAPLEN) { 4911 #ifdef notyet 4912 REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, 4913 min(ether_mtu, BCE_MAX_JUMBO_ETHER_MTU) | 4914 BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA); 4915 sc->mbuf_alloc_size = MJUM9BYTES; 4916 #else 4917 panic("jumbo buffer is not supported yet"); 4918 #endif 4919 } else { 4920 REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu); 4921 sc->mbuf_alloc_size = MCLBYTES; 4922 } 4923 4924 /* Calculate the RX Ethernet frame size for rx_bd's. */ 4925 sc->max_frame_size = sizeof(struct l2_fhdr) + 2 + ether_mtu + 8; 4926 4927 DBPRINT(sc, BCE_INFO, 4928 "%s(): mclbytes = %d, mbuf_alloc_size = %d, " 4929 "max_frame_size = %d\n", 4930 __func__, (int)MCLBYTES, sc->mbuf_alloc_size, 4931 sc->max_frame_size); 4932 4933 /* Program appropriate promiscuous/multicast filtering. */ 4934 bce_set_rx_mode(sc); 4935 4936 /* Init RX buffer descriptor chain. */ 4937 bce_init_rx_chain(sc); /* XXX return value */ 4938 4939 /* Init TX buffer descriptor chain. */ 4940 bce_init_tx_chain(sc); /* XXX return value */ 4941 4942 #ifdef DEVICE_POLLING 4943 /* Disable interrupts if we are polling. */ 4944 if (ifp->if_flags & IFF_POLLING) { 4945 bce_disable_intr(sc); 4946 4947 REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP, 4948 (1 << 16) | sc->bce_rx_quick_cons_trip); 4949 REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP, 4950 (1 << 16) | sc->bce_tx_quick_cons_trip); 4951 } else 4952 #endif 4953 /* Enable host interrupts. */ 4954 bce_enable_intr(sc); 4955 4956 bce_ifmedia_upd(ifp); 4957 4958 ifp->if_flags |= IFF_RUNNING; 4959 ifp->if_flags &= ~IFF_OACTIVE; 4960 4961 callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc); 4962 back: 4963 if (error) 4964 bce_stop(sc); 4965 } 4966 4967 4968 /****************************************************************************/ 4969 /* Initialize the controller just enough so that any management firmware */ 4970 /* running on the device will continue to operate corectly. */ 4971 /* */ 4972 /* Returns: */ 4973 /* Nothing. */ 4974 /****************************************************************************/ 4975 static void 4976 bce_mgmt_init(struct bce_softc *sc) 4977 { 4978 struct ifnet *ifp = &sc->arpcom.ac_if; 4979 4980 /* Bail out if management firmware is not running. */ 4981 if (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)) 4982 return; 4983 4984 /* Enable all critical blocks in the MAC. */ 4985 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709 || 4986 BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716) { 4987 REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, 4988 BCE_MISC_ENABLE_DEFAULT_XI); 4989 } else { 4990 REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT); 4991 } 4992 REG_RD(sc, BCE_MISC_ENABLE_SET_BITS); 4993 DELAY(20); 4994 4995 bce_ifmedia_upd(ifp); 4996 } 4997 4998 4999 /****************************************************************************/ 5000 /* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */ 5001 /* memory visible to the controller. */ 5002 /* */ 5003 /* Returns: */ 5004 /* 0 for success, positive value for failure. */ 5005 /****************************************************************************/ 5006 static int 5007 bce_encap(struct bce_softc *sc, struct mbuf **m_head) 5008 { 5009 bus_dma_segment_t segs[BCE_MAX_SEGMENTS]; 5010 bus_dmamap_t map, tmp_map; 5011 struct mbuf *m0 = *m_head; 5012 struct tx_bd *txbd = NULL; 5013 uint16_t vlan_tag = 0, flags = 0; 5014 uint16_t chain_prod, chain_prod_start, prod; 5015 uint32_t prod_bseq; 5016 int i, error, maxsegs, nsegs; 5017 #ifdef BCE_DEBUG 5018 uint16_t debug_prod; 5019 #endif 5020 5021 /* Transfer any checksum offload flags to the bd. */ 5022 if (m0->m_pkthdr.csum_flags) { 5023 if (m0->m_pkthdr.csum_flags & CSUM_IP) 5024 flags |= TX_BD_FLAGS_IP_CKSUM; 5025 if (m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP)) 5026 flags |= TX_BD_FLAGS_TCP_UDP_CKSUM; 5027 } 5028 5029 /* Transfer any VLAN tags to the bd. */ 5030 if (m0->m_flags & M_VLANTAG) { 5031 flags |= TX_BD_FLAGS_VLAN_TAG; 5032 vlan_tag = m0->m_pkthdr.ether_vlantag; 5033 } 5034 5035 prod = sc->tx_prod; 5036 chain_prod_start = chain_prod = TX_CHAIN_IDX(sc, prod); 5037 5038 /* Map the mbuf into DMAable memory. */ 5039 map = sc->tx_mbuf_map[chain_prod_start]; 5040 5041 maxsegs = sc->max_tx_bd - sc->used_tx_bd; 5042 KASSERT(maxsegs >= BCE_TX_SPARE_SPACE, 5043 ("not enough segments %d", maxsegs)); 5044 if (maxsegs > BCE_MAX_SEGMENTS) 5045 maxsegs = BCE_MAX_SEGMENTS; 5046 5047 /* Map the mbuf into our DMA address space. */ 5048 error = bus_dmamap_load_mbuf_defrag(sc->tx_mbuf_tag, map, m_head, 5049 segs, maxsegs, &nsegs, BUS_DMA_NOWAIT); 5050 if (error) 5051 goto back; 5052 bus_dmamap_sync(sc->tx_mbuf_tag, map, BUS_DMASYNC_PREWRITE); 5053 5054 /* Reset m0 */ 5055 m0 = *m_head; 5056 5057 /* prod points to an empty tx_bd at this point. */ 5058 prod_bseq = sc->tx_prod_bseq; 5059 5060 #ifdef BCE_DEBUG 5061 debug_prod = chain_prod; 5062 #endif 5063 5064 DBPRINT(sc, BCE_INFO_SEND, 5065 "%s(): Start: prod = 0x%04X, chain_prod = %04X, " 5066 "prod_bseq = 0x%08X\n", 5067 __func__, prod, chain_prod, prod_bseq); 5068 5069 /* 5070 * Cycle through each mbuf segment that makes up 5071 * the outgoing frame, gathering the mapping info 5072 * for that segment and creating a tx_bd to for 5073 * the mbuf. 5074 */ 5075 for (i = 0; i < nsegs; i++) { 5076 chain_prod = TX_CHAIN_IDX(sc, prod); 5077 txbd= &sc->tx_bd_chain[TX_PAGE(chain_prod)][TX_IDX(chain_prod)]; 5078 5079 txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(segs[i].ds_addr)); 5080 txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(segs[i].ds_addr)); 5081 txbd->tx_bd_mss_nbytes = htole16(segs[i].ds_len); 5082 txbd->tx_bd_vlan_tag = htole16(vlan_tag); 5083 txbd->tx_bd_flags = htole16(flags); 5084 prod_bseq += segs[i].ds_len; 5085 if (i == 0) 5086 txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_START); 5087 prod = NEXT_TX_BD(prod); 5088 } 5089 5090 /* Set the END flag on the last TX buffer descriptor. */ 5091 txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_END); 5092 5093 DBRUN(BCE_EXCESSIVE_SEND, 5094 bce_dump_tx_chain(sc, debug_prod, nsegs)); 5095 5096 DBPRINT(sc, BCE_INFO_SEND, 5097 "%s(): End: prod = 0x%04X, chain_prod = %04X, " 5098 "prod_bseq = 0x%08X\n", 5099 __func__, prod, chain_prod, prod_bseq); 5100 5101 /* 5102 * Ensure that the mbuf pointer for this transmission 5103 * is placed at the array index of the last 5104 * descriptor in this chain. This is done 5105 * because a single map is used for all 5106 * segments of the mbuf and we don't want to 5107 * unload the map before all of the segments 5108 * have been freed. 5109 */ 5110 sc->tx_mbuf_ptr[chain_prod] = m0; 5111 5112 tmp_map = sc->tx_mbuf_map[chain_prod]; 5113 sc->tx_mbuf_map[chain_prod] = map; 5114 sc->tx_mbuf_map[chain_prod_start] = tmp_map; 5115 5116 sc->used_tx_bd += nsegs; 5117 5118 /* Update some debug statistic counters */ 5119 DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark), 5120 sc->tx_hi_watermark = sc->used_tx_bd); 5121 DBRUNIF((sc->used_tx_bd == sc->max_tx_bd), sc->tx_full_count++); 5122 DBRUNIF(1, sc->tx_mbuf_alloc++); 5123 5124 DBRUN(BCE_VERBOSE_SEND, 5125 bce_dump_tx_mbuf_chain(sc, chain_prod, nsegs)); 5126 5127 /* prod points to the next free tx_bd at this point. */ 5128 sc->tx_prod = prod; 5129 sc->tx_prod_bseq = prod_bseq; 5130 back: 5131 if (error) { 5132 m_freem(*m_head); 5133 *m_head = NULL; 5134 } 5135 return error; 5136 } 5137 5138 5139 /****************************************************************************/ 5140 /* Main transmit routine when called from another routine with a lock. */ 5141 /* */ 5142 /* Returns: */ 5143 /* Nothing. */ 5144 /****************************************************************************/ 5145 static void 5146 bce_start(struct ifnet *ifp) 5147 { 5148 struct bce_softc *sc = ifp->if_softc; 5149 int count = 0; 5150 5151 ASSERT_SERIALIZED(ifp->if_serializer); 5152 5153 /* If there's no link or the transmit queue is empty then just exit. */ 5154 if (!sc->bce_link) { 5155 ifq_purge(&ifp->if_snd); 5156 return; 5157 } 5158 5159 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 5160 return; 5161 5162 DBPRINT(sc, BCE_INFO_SEND, 5163 "%s(): Start: tx_prod = 0x%04X, tx_chain_prod = %04zX, " 5164 "tx_prod_bseq = 0x%08X\n", 5165 __func__, 5166 sc->tx_prod, TX_CHAIN_IDX(sc, sc->tx_prod), sc->tx_prod_bseq); 5167 5168 for (;;) { 5169 struct mbuf *m_head; 5170 5171 /* 5172 * We keep BCE_TX_SPARE_SPACE entries, so bce_encap() is 5173 * unlikely to fail. 5174 */ 5175 if (sc->max_tx_bd - sc->used_tx_bd < BCE_TX_SPARE_SPACE) { 5176 ifp->if_flags |= IFF_OACTIVE; 5177 break; 5178 } 5179 5180 /* Check for any frames to send. */ 5181 m_head = ifq_dequeue(&ifp->if_snd, NULL); 5182 if (m_head == NULL) 5183 break; 5184 5185 /* 5186 * Pack the data into the transmit ring. If we 5187 * don't have room, place the mbuf back at the 5188 * head of the queue and set the OACTIVE flag 5189 * to wait for the NIC to drain the chain. 5190 */ 5191 if (bce_encap(sc, &m_head)) { 5192 ifp->if_oerrors++; 5193 if (sc->used_tx_bd == 0) { 5194 continue; 5195 } else { 5196 ifp->if_flags |= IFF_OACTIVE; 5197 break; 5198 } 5199 } 5200 5201 count++; 5202 5203 /* Send a copy of the frame to any BPF listeners. */ 5204 ETHER_BPF_MTAP(ifp, m_head); 5205 } 5206 5207 if (count == 0) { 5208 /* no packets were dequeued */ 5209 DBPRINT(sc, BCE_VERBOSE_SEND, 5210 "%s(): No packets were dequeued\n", __func__); 5211 return; 5212 } 5213 5214 DBPRINT(sc, BCE_INFO_SEND, 5215 "%s(): End: tx_prod = 0x%04X, tx_chain_prod = 0x%04zX, " 5216 "tx_prod_bseq = 0x%08X\n", 5217 __func__, 5218 sc->tx_prod, TX_CHAIN_IDX(sc, sc->tx_prod), sc->tx_prod_bseq); 5219 5220 REG_WR(sc, BCE_MQ_COMMAND, 5221 REG_RD(sc, BCE_MQ_COMMAND) | BCE_MQ_COMMAND_NO_MAP_ERROR); 5222 5223 /* Start the transmit. */ 5224 REG_WR16(sc, MB_GET_CID_ADDR(TX_CID) + BCE_L2CTX_TX_HOST_BIDX, sc->tx_prod); 5225 REG_WR(sc, MB_GET_CID_ADDR(TX_CID) + BCE_L2CTX_TX_HOST_BSEQ, sc->tx_prod_bseq); 5226 5227 /* Set the tx timeout. */ 5228 ifp->if_timer = BCE_TX_TIMEOUT; 5229 } 5230 5231 5232 /****************************************************************************/ 5233 /* Handles any IOCTL calls from the operating system. */ 5234 /* */ 5235 /* Returns: */ 5236 /* 0 for success, positive value for failure. */ 5237 /****************************************************************************/ 5238 static int 5239 bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data, struct ucred *cr) 5240 { 5241 struct bce_softc *sc = ifp->if_softc; 5242 struct ifreq *ifr = (struct ifreq *)data; 5243 struct mii_data *mii; 5244 int mask, error = 0; 5245 5246 ASSERT_SERIALIZED(ifp->if_serializer); 5247 5248 switch(command) { 5249 case SIOCSIFMTU: 5250 /* Check that the MTU setting is supported. */ 5251 if (ifr->ifr_mtu < BCE_MIN_MTU || 5252 #ifdef notyet 5253 ifr->ifr_mtu > BCE_MAX_JUMBO_MTU 5254 #else 5255 ifr->ifr_mtu > ETHERMTU 5256 #endif 5257 ) { 5258 error = EINVAL; 5259 break; 5260 } 5261 5262 DBPRINT(sc, BCE_INFO, "Setting new MTU of %d\n", ifr->ifr_mtu); 5263 5264 ifp->if_mtu = ifr->ifr_mtu; 5265 ifp->if_flags &= ~IFF_RUNNING; /* Force reinitialize */ 5266 bce_init(sc); 5267 break; 5268 5269 case SIOCSIFFLAGS: 5270 if (ifp->if_flags & IFF_UP) { 5271 if (ifp->if_flags & IFF_RUNNING) { 5272 mask = ifp->if_flags ^ sc->bce_if_flags; 5273 5274 if (mask & (IFF_PROMISC | IFF_ALLMULTI)) 5275 bce_set_rx_mode(sc); 5276 } else { 5277 bce_init(sc); 5278 } 5279 } else if (ifp->if_flags & IFF_RUNNING) { 5280 bce_stop(sc); 5281 5282 /* If MFW is running, restart the controller a bit. */ 5283 if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) { 5284 bce_reset(sc, BCE_DRV_MSG_CODE_RESET); 5285 bce_chipinit(sc); 5286 bce_mgmt_init(sc); 5287 } 5288 } 5289 sc->bce_if_flags = ifp->if_flags; 5290 break; 5291 5292 case SIOCADDMULTI: 5293 case SIOCDELMULTI: 5294 if (ifp->if_flags & IFF_RUNNING) 5295 bce_set_rx_mode(sc); 5296 break; 5297 5298 case SIOCSIFMEDIA: 5299 case SIOCGIFMEDIA: 5300 DBPRINT(sc, BCE_VERBOSE, "bce_phy_flags = 0x%08X\n", 5301 sc->bce_phy_flags); 5302 DBPRINT(sc, BCE_VERBOSE, "Copper media set/get\n"); 5303 5304 mii = device_get_softc(sc->bce_miibus); 5305 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); 5306 break; 5307 5308 case SIOCSIFCAP: 5309 mask = ifr->ifr_reqcap ^ ifp->if_capenable; 5310 DBPRINT(sc, BCE_INFO, "Received SIOCSIFCAP = 0x%08X\n", 5311 (uint32_t) mask); 5312 5313 if (mask & IFCAP_HWCSUM) { 5314 ifp->if_capenable ^= (mask & IFCAP_HWCSUM); 5315 if (IFCAP_HWCSUM & ifp->if_capenable) 5316 ifp->if_hwassist = BCE_IF_HWASSIST; 5317 else 5318 ifp->if_hwassist = 0; 5319 } 5320 break; 5321 5322 default: 5323 error = ether_ioctl(ifp, command, data); 5324 break; 5325 } 5326 return error; 5327 } 5328 5329 5330 /****************************************************************************/ 5331 /* Transmit timeout handler. */ 5332 /* */ 5333 /* Returns: */ 5334 /* Nothing. */ 5335 /****************************************************************************/ 5336 static void 5337 bce_watchdog(struct ifnet *ifp) 5338 { 5339 struct bce_softc *sc = ifp->if_softc; 5340 5341 ASSERT_SERIALIZED(ifp->if_serializer); 5342 5343 DBRUN(BCE_VERBOSE_SEND, 5344 bce_dump_driver_state(sc); 5345 bce_dump_status_block(sc)); 5346 5347 /* 5348 * If we are in this routine because of pause frames, then 5349 * don't reset the hardware. 5350 */ 5351 if (REG_RD(sc, BCE_EMAC_TX_STATUS) & BCE_EMAC_TX_STATUS_XOFFED) 5352 return; 5353 5354 if_printf(ifp, "Watchdog timeout occurred, resetting!\n"); 5355 5356 /* DBRUN(BCE_FATAL, bce_breakpoint(sc)); */ 5357 5358 ifp->if_flags &= ~IFF_RUNNING; /* Force reinitialize */ 5359 bce_init(sc); 5360 5361 ifp->if_oerrors++; 5362 5363 if (!ifq_is_empty(&ifp->if_snd)) 5364 if_devstart(ifp); 5365 } 5366 5367 5368 #ifdef DEVICE_POLLING 5369 5370 static void 5371 bce_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) 5372 { 5373 struct bce_softc *sc = ifp->if_softc; 5374 struct status_block *sblk = sc->status_block; 5375 uint16_t hw_tx_cons, hw_rx_cons; 5376 5377 ASSERT_SERIALIZED(ifp->if_serializer); 5378 5379 switch (cmd) { 5380 case POLL_REGISTER: 5381 bce_disable_intr(sc); 5382 5383 REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP, 5384 (1 << 16) | sc->bce_rx_quick_cons_trip); 5385 REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP, 5386 (1 << 16) | sc->bce_tx_quick_cons_trip); 5387 return; 5388 case POLL_DEREGISTER: 5389 bce_enable_intr(sc); 5390 5391 REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP, 5392 (sc->bce_tx_quick_cons_trip_int << 16) | 5393 sc->bce_tx_quick_cons_trip); 5394 REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP, 5395 (sc->bce_rx_quick_cons_trip_int << 16) | 5396 sc->bce_rx_quick_cons_trip); 5397 return; 5398 default: 5399 break; 5400 } 5401 5402 if (cmd == POLL_AND_CHECK_STATUS) { 5403 uint32_t status_attn_bits; 5404 5405 status_attn_bits = sblk->status_attn_bits; 5406 5407 DBRUNIF(DB_RANDOMTRUE(bce_debug_unexpected_attention), 5408 if_printf(ifp, 5409 "Simulating unexpected status attention bit set."); 5410 status_attn_bits |= STATUS_ATTN_BITS_PARITY_ERROR); 5411 5412 /* Was it a link change interrupt? */ 5413 if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) != 5414 (sblk->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE)) 5415 bce_phy_intr(sc); 5416 5417 /* Clear any transient status updates during link state change. */ 5418 REG_WR(sc, BCE_HC_COMMAND, 5419 sc->hc_command | BCE_HC_COMMAND_COAL_NOW_WO_INT); 5420 REG_RD(sc, BCE_HC_COMMAND); 5421 5422 /* 5423 * If any other attention is asserted then 5424 * the chip is toast. 5425 */ 5426 if ((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) != 5427 (sblk->status_attn_bits_ack & 5428 ~STATUS_ATTN_BITS_LINK_STATE)) { 5429 DBRUN(1, sc->unexpected_attentions++); 5430 5431 if_printf(ifp, "Fatal attention detected: 0x%08X\n", 5432 sblk->status_attn_bits); 5433 5434 DBRUN(BCE_FATAL, 5435 if (bce_debug_unexpected_attention == 0) 5436 bce_breakpoint(sc)); 5437 5438 bce_init(sc); 5439 return; 5440 } 5441 } 5442 5443 hw_rx_cons = bce_get_hw_rx_cons(sc); 5444 hw_tx_cons = bce_get_hw_tx_cons(sc); 5445 5446 /* Check for any completed RX frames. */ 5447 if (hw_rx_cons != sc->hw_rx_cons) 5448 bce_rx_intr(sc, count); 5449 5450 /* Check for any completed TX frames. */ 5451 if (hw_tx_cons != sc->hw_tx_cons) 5452 bce_tx_intr(sc); 5453 5454 /* Check for new frames to transmit. */ 5455 if (!ifq_is_empty(&ifp->if_snd)) 5456 if_devstart(ifp); 5457 } 5458 5459 #endif /* DEVICE_POLLING */ 5460 5461 5462 /* 5463 * Interrupt handler. 5464 */ 5465 /****************************************************************************/ 5466 /* Main interrupt entry point. Verifies that the controller generated the */ 5467 /* interrupt and then calls a separate routine for handle the various */ 5468 /* interrupt causes (PHY, TX, RX). */ 5469 /* */ 5470 /* Returns: */ 5471 /* 0 for success, positive value for failure. */ 5472 /****************************************************************************/ 5473 static void 5474 bce_intr(struct bce_softc *sc) 5475 { 5476 struct ifnet *ifp = &sc->arpcom.ac_if; 5477 struct status_block *sblk; 5478 uint16_t hw_rx_cons, hw_tx_cons; 5479 5480 ASSERT_SERIALIZED(ifp->if_serializer); 5481 5482 DBPRINT(sc, BCE_EXCESSIVE, "Entering %s()\n", __func__); 5483 DBRUNIF(1, sc->interrupts_generated++); 5484 5485 sblk = sc->status_block; 5486 5487 /* Check if the hardware has finished any work. */ 5488 hw_rx_cons = bce_get_hw_rx_cons(sc); 5489 hw_tx_cons = bce_get_hw_tx_cons(sc); 5490 5491 /* Keep processing data as long as there is work to do. */ 5492 for (;;) { 5493 uint32_t status_attn_bits; 5494 5495 status_attn_bits = sblk->status_attn_bits; 5496 5497 DBRUNIF(DB_RANDOMTRUE(bce_debug_unexpected_attention), 5498 if_printf(ifp, 5499 "Simulating unexpected status attention bit set."); 5500 status_attn_bits |= STATUS_ATTN_BITS_PARITY_ERROR); 5501 5502 /* Was it a link change interrupt? */ 5503 if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) != 5504 (sblk->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE)) { 5505 bce_phy_intr(sc); 5506 5507 /* 5508 * Clear any transient status updates during link state 5509 * change. 5510 */ 5511 REG_WR(sc, BCE_HC_COMMAND, 5512 sc->hc_command | BCE_HC_COMMAND_COAL_NOW_WO_INT); 5513 REG_RD(sc, BCE_HC_COMMAND); 5514 } 5515 5516 /* 5517 * If any other attention is asserted then 5518 * the chip is toast. 5519 */ 5520 if ((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) != 5521 (sblk->status_attn_bits_ack & 5522 ~STATUS_ATTN_BITS_LINK_STATE)) { 5523 DBRUN(1, sc->unexpected_attentions++); 5524 5525 if_printf(ifp, "Fatal attention detected: 0x%08X\n", 5526 sblk->status_attn_bits); 5527 5528 DBRUN(BCE_FATAL, 5529 if (bce_debug_unexpected_attention == 0) 5530 bce_breakpoint(sc)); 5531 5532 bce_init(sc); 5533 return; 5534 } 5535 5536 /* Check for any completed RX frames. */ 5537 if (hw_rx_cons != sc->hw_rx_cons) 5538 bce_rx_intr(sc, -1); 5539 5540 /* Check for any completed TX frames. */ 5541 if (hw_tx_cons != sc->hw_tx_cons) 5542 bce_tx_intr(sc); 5543 5544 /* 5545 * Save the status block index value 5546 * for use during the next interrupt. 5547 */ 5548 sc->last_status_idx = sblk->status_idx; 5549 5550 /* 5551 * Prevent speculative reads from getting 5552 * ahead of the status block. 5553 */ 5554 bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0, 5555 BUS_SPACE_BARRIER_READ); 5556 5557 /* 5558 * If there's no work left then exit the 5559 * interrupt service routine. 5560 */ 5561 hw_rx_cons = bce_get_hw_rx_cons(sc); 5562 hw_tx_cons = bce_get_hw_tx_cons(sc); 5563 if ((hw_rx_cons == sc->hw_rx_cons) && (hw_tx_cons == sc->hw_tx_cons)) 5564 break; 5565 } 5566 5567 /* Re-enable interrupts. */ 5568 bce_reenable_intr(sc); 5569 5570 if (sc->bce_coalchg_mask) 5571 bce_coal_change(sc); 5572 5573 /* Handle any frames that arrived while handling the interrupt. */ 5574 if (!ifq_is_empty(&ifp->if_snd)) 5575 if_devstart(ifp); 5576 } 5577 5578 static void 5579 bce_intr_legacy(void *xsc) 5580 { 5581 struct bce_softc *sc = xsc; 5582 struct status_block *sblk; 5583 5584 sblk = sc->status_block; 5585 5586 /* 5587 * If the hardware status block index matches the last value 5588 * read by the driver and we haven't asserted our interrupt 5589 * then there's nothing to do. 5590 */ 5591 if (sblk->status_idx == sc->last_status_idx && 5592 (REG_RD(sc, BCE_PCICFG_MISC_STATUS) & 5593 BCE_PCICFG_MISC_STATUS_INTA_VALUE)) 5594 return; 5595 5596 /* Ack the interrupt and stop others from occuring. */ 5597 REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, 5598 BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM | 5599 BCE_PCICFG_INT_ACK_CMD_MASK_INT); 5600 5601 /* 5602 * Read back to deassert IRQ immediately to avoid too 5603 * many spurious interrupts. 5604 */ 5605 REG_RD(sc, BCE_PCICFG_INT_ACK_CMD); 5606 5607 bce_intr(sc); 5608 } 5609 5610 static void 5611 bce_intr_msi(void *xsc) 5612 { 5613 struct bce_softc *sc = xsc; 5614 5615 /* Ack the interrupt and stop others from occuring. */ 5616 REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, 5617 BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM | 5618 BCE_PCICFG_INT_ACK_CMD_MASK_INT); 5619 5620 bce_intr(sc); 5621 } 5622 5623 static void 5624 bce_intr_msi_oneshot(void *xsc) 5625 { 5626 bce_intr(xsc); 5627 } 5628 5629 5630 /****************************************************************************/ 5631 /* Programs the various packet receive modes (broadcast and multicast). */ 5632 /* */ 5633 /* Returns: */ 5634 /* Nothing. */ 5635 /****************************************************************************/ 5636 static void 5637 bce_set_rx_mode(struct bce_softc *sc) 5638 { 5639 struct ifnet *ifp = &sc->arpcom.ac_if; 5640 struct ifmultiaddr *ifma; 5641 uint32_t hashes[NUM_MC_HASH_REGISTERS] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 5642 uint32_t rx_mode, sort_mode; 5643 int h, i; 5644 5645 ASSERT_SERIALIZED(ifp->if_serializer); 5646 5647 /* Initialize receive mode default settings. */ 5648 rx_mode = sc->rx_mode & 5649 ~(BCE_EMAC_RX_MODE_PROMISCUOUS | 5650 BCE_EMAC_RX_MODE_KEEP_VLAN_TAG); 5651 sort_mode = 1 | BCE_RPM_SORT_USER0_BC_EN; 5652 5653 /* 5654 * ASF/IPMI/UMP firmware requires that VLAN tag stripping 5655 * be enbled. 5656 */ 5657 if (!(BCE_IF_CAPABILITIES & IFCAP_VLAN_HWTAGGING) && 5658 !(sc->bce_flags & BCE_MFW_ENABLE_FLAG)) 5659 rx_mode |= BCE_EMAC_RX_MODE_KEEP_VLAN_TAG; 5660 5661 /* 5662 * Check for promiscuous, all multicast, or selected 5663 * multicast address filtering. 5664 */ 5665 if (ifp->if_flags & IFF_PROMISC) { 5666 DBPRINT(sc, BCE_INFO, "Enabling promiscuous mode.\n"); 5667 5668 /* Enable promiscuous mode. */ 5669 rx_mode |= BCE_EMAC_RX_MODE_PROMISCUOUS; 5670 sort_mode |= BCE_RPM_SORT_USER0_PROM_EN; 5671 } else if (ifp->if_flags & IFF_ALLMULTI) { 5672 DBPRINT(sc, BCE_INFO, "Enabling all multicast mode.\n"); 5673 5674 /* Enable all multicast addresses. */ 5675 for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) { 5676 REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), 5677 0xffffffff); 5678 } 5679 sort_mode |= BCE_RPM_SORT_USER0_MC_EN; 5680 } else { 5681 /* Accept one or more multicast(s). */ 5682 DBPRINT(sc, BCE_INFO, "Enabling selective multicast mode.\n"); 5683 5684 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 5685 if (ifma->ifma_addr->sa_family != AF_LINK) 5686 continue; 5687 h = ether_crc32_le( 5688 LLADDR((struct sockaddr_dl *)ifma->ifma_addr), 5689 ETHER_ADDR_LEN) & 0xFF; 5690 hashes[(h & 0xE0) >> 5] |= 1 << (h & 0x1F); 5691 } 5692 5693 for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) { 5694 REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), 5695 hashes[i]); 5696 } 5697 sort_mode |= BCE_RPM_SORT_USER0_MC_HSH_EN; 5698 } 5699 5700 /* Only make changes if the recive mode has actually changed. */ 5701 if (rx_mode != sc->rx_mode) { 5702 DBPRINT(sc, BCE_VERBOSE, "Enabling new receive mode: 0x%08X\n", 5703 rx_mode); 5704 5705 sc->rx_mode = rx_mode; 5706 REG_WR(sc, BCE_EMAC_RX_MODE, rx_mode); 5707 } 5708 5709 /* Disable and clear the exisitng sort before enabling a new sort. */ 5710 REG_WR(sc, BCE_RPM_SORT_USER0, 0x0); 5711 REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode); 5712 REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode | BCE_RPM_SORT_USER0_ENA); 5713 } 5714 5715 5716 /****************************************************************************/ 5717 /* Called periodically to updates statistics from the controllers */ 5718 /* statistics block. */ 5719 /* */ 5720 /* Returns: */ 5721 /* Nothing. */ 5722 /****************************************************************************/ 5723 static void 5724 bce_stats_update(struct bce_softc *sc) 5725 { 5726 struct ifnet *ifp = &sc->arpcom.ac_if; 5727 struct statistics_block *stats = sc->stats_block; 5728 5729 DBPRINT(sc, BCE_EXCESSIVE, "Entering %s()\n", __func__); 5730 5731 ASSERT_SERIALIZED(ifp->if_serializer); 5732 5733 /* 5734 * Certain controllers don't report carrier sense errors correctly. 5735 * See errata E11_5708CA0_1165. 5736 */ 5737 if (!(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) && 5738 !(BCE_CHIP_ID(sc) == BCE_CHIP_ID_5708_A0)) { 5739 ifp->if_oerrors += 5740 (u_long)stats->stat_Dot3StatsCarrierSenseErrors; 5741 } 5742 5743 /* 5744 * Update the sysctl statistics from the hardware statistics. 5745 */ 5746 sc->stat_IfHCInOctets = 5747 ((uint64_t)stats->stat_IfHCInOctets_hi << 32) + 5748 (uint64_t)stats->stat_IfHCInOctets_lo; 5749 5750 sc->stat_IfHCInBadOctets = 5751 ((uint64_t)stats->stat_IfHCInBadOctets_hi << 32) + 5752 (uint64_t)stats->stat_IfHCInBadOctets_lo; 5753 5754 sc->stat_IfHCOutOctets = 5755 ((uint64_t)stats->stat_IfHCOutOctets_hi << 32) + 5756 (uint64_t)stats->stat_IfHCOutOctets_lo; 5757 5758 sc->stat_IfHCOutBadOctets = 5759 ((uint64_t)stats->stat_IfHCOutBadOctets_hi << 32) + 5760 (uint64_t)stats->stat_IfHCOutBadOctets_lo; 5761 5762 sc->stat_IfHCInUcastPkts = 5763 ((uint64_t)stats->stat_IfHCInUcastPkts_hi << 32) + 5764 (uint64_t)stats->stat_IfHCInUcastPkts_lo; 5765 5766 sc->stat_IfHCInMulticastPkts = 5767 ((uint64_t)stats->stat_IfHCInMulticastPkts_hi << 32) + 5768 (uint64_t)stats->stat_IfHCInMulticastPkts_lo; 5769 5770 sc->stat_IfHCInBroadcastPkts = 5771 ((uint64_t)stats->stat_IfHCInBroadcastPkts_hi << 32) + 5772 (uint64_t)stats->stat_IfHCInBroadcastPkts_lo; 5773 5774 sc->stat_IfHCOutUcastPkts = 5775 ((uint64_t)stats->stat_IfHCOutUcastPkts_hi << 32) + 5776 (uint64_t)stats->stat_IfHCOutUcastPkts_lo; 5777 5778 sc->stat_IfHCOutMulticastPkts = 5779 ((uint64_t)stats->stat_IfHCOutMulticastPkts_hi << 32) + 5780 (uint64_t)stats->stat_IfHCOutMulticastPkts_lo; 5781 5782 sc->stat_IfHCOutBroadcastPkts = 5783 ((uint64_t)stats->stat_IfHCOutBroadcastPkts_hi << 32) + 5784 (uint64_t)stats->stat_IfHCOutBroadcastPkts_lo; 5785 5786 sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors = 5787 stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors; 5788 5789 sc->stat_Dot3StatsCarrierSenseErrors = 5790 stats->stat_Dot3StatsCarrierSenseErrors; 5791 5792 sc->stat_Dot3StatsFCSErrors = 5793 stats->stat_Dot3StatsFCSErrors; 5794 5795 sc->stat_Dot3StatsAlignmentErrors = 5796 stats->stat_Dot3StatsAlignmentErrors; 5797 5798 sc->stat_Dot3StatsSingleCollisionFrames = 5799 stats->stat_Dot3StatsSingleCollisionFrames; 5800 5801 sc->stat_Dot3StatsMultipleCollisionFrames = 5802 stats->stat_Dot3StatsMultipleCollisionFrames; 5803 5804 sc->stat_Dot3StatsDeferredTransmissions = 5805 stats->stat_Dot3StatsDeferredTransmissions; 5806 5807 sc->stat_Dot3StatsExcessiveCollisions = 5808 stats->stat_Dot3StatsExcessiveCollisions; 5809 5810 sc->stat_Dot3StatsLateCollisions = 5811 stats->stat_Dot3StatsLateCollisions; 5812 5813 sc->stat_EtherStatsCollisions = 5814 stats->stat_EtherStatsCollisions; 5815 5816 sc->stat_EtherStatsFragments = 5817 stats->stat_EtherStatsFragments; 5818 5819 sc->stat_EtherStatsJabbers = 5820 stats->stat_EtherStatsJabbers; 5821 5822 sc->stat_EtherStatsUndersizePkts = 5823 stats->stat_EtherStatsUndersizePkts; 5824 5825 sc->stat_EtherStatsOverrsizePkts = 5826 stats->stat_EtherStatsOverrsizePkts; 5827 5828 sc->stat_EtherStatsPktsRx64Octets = 5829 stats->stat_EtherStatsPktsRx64Octets; 5830 5831 sc->stat_EtherStatsPktsRx65Octetsto127Octets = 5832 stats->stat_EtherStatsPktsRx65Octetsto127Octets; 5833 5834 sc->stat_EtherStatsPktsRx128Octetsto255Octets = 5835 stats->stat_EtherStatsPktsRx128Octetsto255Octets; 5836 5837 sc->stat_EtherStatsPktsRx256Octetsto511Octets = 5838 stats->stat_EtherStatsPktsRx256Octetsto511Octets; 5839 5840 sc->stat_EtherStatsPktsRx512Octetsto1023Octets = 5841 stats->stat_EtherStatsPktsRx512Octetsto1023Octets; 5842 5843 sc->stat_EtherStatsPktsRx1024Octetsto1522Octets = 5844 stats->stat_EtherStatsPktsRx1024Octetsto1522Octets; 5845 5846 sc->stat_EtherStatsPktsRx1523Octetsto9022Octets = 5847 stats->stat_EtherStatsPktsRx1523Octetsto9022Octets; 5848 5849 sc->stat_EtherStatsPktsTx64Octets = 5850 stats->stat_EtherStatsPktsTx64Octets; 5851 5852 sc->stat_EtherStatsPktsTx65Octetsto127Octets = 5853 stats->stat_EtherStatsPktsTx65Octetsto127Octets; 5854 5855 sc->stat_EtherStatsPktsTx128Octetsto255Octets = 5856 stats->stat_EtherStatsPktsTx128Octetsto255Octets; 5857 5858 sc->stat_EtherStatsPktsTx256Octetsto511Octets = 5859 stats->stat_EtherStatsPktsTx256Octetsto511Octets; 5860 5861 sc->stat_EtherStatsPktsTx512Octetsto1023Octets = 5862 stats->stat_EtherStatsPktsTx512Octetsto1023Octets; 5863 5864 sc->stat_EtherStatsPktsTx1024Octetsto1522Octets = 5865 stats->stat_EtherStatsPktsTx1024Octetsto1522Octets; 5866 5867 sc->stat_EtherStatsPktsTx1523Octetsto9022Octets = 5868 stats->stat_EtherStatsPktsTx1523Octetsto9022Octets; 5869 5870 sc->stat_XonPauseFramesReceived = 5871 stats->stat_XonPauseFramesReceived; 5872 5873 sc->stat_XoffPauseFramesReceived = 5874 stats->stat_XoffPauseFramesReceived; 5875 5876 sc->stat_OutXonSent = 5877 stats->stat_OutXonSent; 5878 5879 sc->stat_OutXoffSent = 5880 stats->stat_OutXoffSent; 5881 5882 sc->stat_FlowControlDone = 5883 stats->stat_FlowControlDone; 5884 5885 sc->stat_MacControlFramesReceived = 5886 stats->stat_MacControlFramesReceived; 5887 5888 sc->stat_XoffStateEntered = 5889 stats->stat_XoffStateEntered; 5890 5891 sc->stat_IfInFramesL2FilterDiscards = 5892 stats->stat_IfInFramesL2FilterDiscards; 5893 5894 sc->stat_IfInRuleCheckerDiscards = 5895 stats->stat_IfInRuleCheckerDiscards; 5896 5897 sc->stat_IfInFTQDiscards = 5898 stats->stat_IfInFTQDiscards; 5899 5900 sc->stat_IfInMBUFDiscards = 5901 stats->stat_IfInMBUFDiscards; 5902 5903 sc->stat_IfInRuleCheckerP4Hit = 5904 stats->stat_IfInRuleCheckerP4Hit; 5905 5906 sc->stat_CatchupInRuleCheckerDiscards = 5907 stats->stat_CatchupInRuleCheckerDiscards; 5908 5909 sc->stat_CatchupInFTQDiscards = 5910 stats->stat_CatchupInFTQDiscards; 5911 5912 sc->stat_CatchupInMBUFDiscards = 5913 stats->stat_CatchupInMBUFDiscards; 5914 5915 sc->stat_CatchupInRuleCheckerP4Hit = 5916 stats->stat_CatchupInRuleCheckerP4Hit; 5917 5918 sc->com_no_buffers = REG_RD_IND(sc, 0x120084); 5919 5920 /* 5921 * Update the interface statistics from the 5922 * hardware statistics. 5923 */ 5924 ifp->if_collisions = (u_long)sc->stat_EtherStatsCollisions; 5925 5926 ifp->if_ierrors = (u_long)sc->stat_EtherStatsUndersizePkts + 5927 (u_long)sc->stat_EtherStatsOverrsizePkts + 5928 (u_long)sc->stat_IfInMBUFDiscards + 5929 (u_long)sc->stat_Dot3StatsAlignmentErrors + 5930 (u_long)sc->stat_Dot3StatsFCSErrors + 5931 (u_long)sc->stat_IfInRuleCheckerDiscards + 5932 (u_long)sc->stat_IfInFTQDiscards + 5933 (u_long)sc->com_no_buffers; 5934 5935 ifp->if_oerrors = 5936 (u_long)sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors + 5937 (u_long)sc->stat_Dot3StatsExcessiveCollisions + 5938 (u_long)sc->stat_Dot3StatsLateCollisions; 5939 5940 DBPRINT(sc, BCE_EXCESSIVE, "Exiting %s()\n", __func__); 5941 } 5942 5943 5944 /****************************************************************************/ 5945 /* Periodic function to notify the bootcode that the driver is still */ 5946 /* present. */ 5947 /* */ 5948 /* Returns: */ 5949 /* Nothing. */ 5950 /****************************************************************************/ 5951 static void 5952 bce_pulse(void *xsc) 5953 { 5954 struct bce_softc *sc = xsc; 5955 struct ifnet *ifp = &sc->arpcom.ac_if; 5956 uint32_t msg; 5957 5958 lwkt_serialize_enter(ifp->if_serializer); 5959 5960 if (ifp->if_flags & IFF_RUNNING) { 5961 if (sc->bce_irq_type == PCI_INTR_TYPE_MSI && 5962 (sc->bce_flags & BCE_ONESHOT_MSI_FLAG) == 0) 5963 bce_pulse_check_msi(sc); 5964 } 5965 5966 /* Tell the firmware that the driver is still running. */ 5967 msg = (uint32_t)++sc->bce_fw_drv_pulse_wr_seq; 5968 bce_shmem_wr(sc, BCE_DRV_PULSE_MB, msg); 5969 5970 /* Update the bootcode condition. */ 5971 sc->bc_state = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION); 5972 5973 /* Report whether the bootcode still knows the driver is running. */ 5974 if (!sc->bce_drv_cardiac_arrest) { 5975 if (!(sc->bc_state & BCE_CONDITION_DRV_PRESENT)) { 5976 sc->bce_drv_cardiac_arrest = 1; 5977 if_printf(ifp, "Bootcode lost the driver pulse! " 5978 "(bc_state = 0x%08X)\n", sc->bc_state); 5979 } 5980 } else { 5981 /* 5982 * Not supported by all bootcode versions. 5983 * (v5.0.11+ and v5.2.1+) Older bootcode 5984 * will require the driver to reset the 5985 * controller to clear this condition. 5986 */ 5987 if (sc->bc_state & BCE_CONDITION_DRV_PRESENT) { 5988 sc->bce_drv_cardiac_arrest = 0; 5989 if_printf(ifp, "Bootcode found the driver pulse! " 5990 "(bc_state = 0x%08X)\n", sc->bc_state); 5991 } 5992 } 5993 5994 /* Schedule the next pulse. */ 5995 callout_reset(&sc->bce_pulse_callout, hz, bce_pulse, sc); 5996 5997 lwkt_serialize_exit(ifp->if_serializer); 5998 } 5999 6000 static void 6001 bce_pulse_check_msi(struct bce_softc *sc) 6002 { 6003 int check = 0; 6004 6005 if (bce_get_hw_rx_cons(sc) != sc->hw_rx_cons) { 6006 check = 1; 6007 } else if (bce_get_hw_tx_cons(sc) != sc->hw_tx_cons) { 6008 check = 1; 6009 } else { 6010 struct status_block *sblk = sc->status_block; 6011 6012 if ((sblk->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) != 6013 (sblk->status_attn_bits_ack & STATUS_ATTN_BITS_LINK_STATE)) 6014 check = 1; 6015 } 6016 6017 if (check) { 6018 uint32_t msi_ctrl; 6019 6020 msi_ctrl = REG_RD(sc, BCE_PCICFG_MSI_CONTROL); 6021 if ((msi_ctrl & BCE_PCICFG_MSI_CONTROL_ENABLE) == 0) 6022 return; 6023 6024 if (sc->pulse_check_status_idx == sc->last_status_idx) { 6025 if_printf(&sc->arpcom.ac_if, "missing MSI\n"); 6026 6027 REG_WR(sc, BCE_PCICFG_MSI_CONTROL, 6028 msi_ctrl & ~BCE_PCICFG_MSI_CONTROL_ENABLE); 6029 REG_WR(sc, BCE_PCICFG_MSI_CONTROL, msi_ctrl); 6030 6031 bce_intr_msi(sc); 6032 } 6033 } 6034 sc->pulse_check_status_idx = sc->last_status_idx; 6035 } 6036 6037 /****************************************************************************/ 6038 /* Periodic function to perform maintenance tasks. */ 6039 /* */ 6040 /* Returns: */ 6041 /* Nothing. */ 6042 /****************************************************************************/ 6043 static void 6044 bce_tick_serialized(struct bce_softc *sc) 6045 { 6046 struct ifnet *ifp = &sc->arpcom.ac_if; 6047 struct mii_data *mii; 6048 6049 ASSERT_SERIALIZED(ifp->if_serializer); 6050 6051 /* Update the statistics from the hardware statistics block. */ 6052 bce_stats_update(sc); 6053 6054 /* Schedule the next tick. */ 6055 callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc); 6056 6057 /* If link is up already up then we're done. */ 6058 if (sc->bce_link) 6059 return; 6060 6061 mii = device_get_softc(sc->bce_miibus); 6062 mii_tick(mii); 6063 6064 /* Check if the link has come up. */ 6065 if ((mii->mii_media_status & IFM_ACTIVE) && 6066 IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { 6067 sc->bce_link++; 6068 /* Now that link is up, handle any outstanding TX traffic. */ 6069 if (!ifq_is_empty(&ifp->if_snd)) 6070 if_devstart(ifp); 6071 } 6072 } 6073 6074 6075 static void 6076 bce_tick(void *xsc) 6077 { 6078 struct bce_softc *sc = xsc; 6079 struct ifnet *ifp = &sc->arpcom.ac_if; 6080 6081 lwkt_serialize_enter(ifp->if_serializer); 6082 bce_tick_serialized(sc); 6083 lwkt_serialize_exit(ifp->if_serializer); 6084 } 6085 6086 6087 #ifdef BCE_DEBUG 6088 /****************************************************************************/ 6089 /* Allows the driver state to be dumped through the sysctl interface. */ 6090 /* */ 6091 /* Returns: */ 6092 /* 0 for success, positive value for failure. */ 6093 /****************************************************************************/ 6094 static int 6095 bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS) 6096 { 6097 int error; 6098 int result; 6099 struct bce_softc *sc; 6100 6101 result = -1; 6102 error = sysctl_handle_int(oidp, &result, 0, req); 6103 6104 if (error || !req->newptr) 6105 return (error); 6106 6107 if (result == 1) { 6108 sc = (struct bce_softc *)arg1; 6109 bce_dump_driver_state(sc); 6110 } 6111 6112 return error; 6113 } 6114 6115 6116 /****************************************************************************/ 6117 /* Allows the hardware state to be dumped through the sysctl interface. */ 6118 /* */ 6119 /* Returns: */ 6120 /* 0 for success, positive value for failure. */ 6121 /****************************************************************************/ 6122 static int 6123 bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS) 6124 { 6125 int error; 6126 int result; 6127 struct bce_softc *sc; 6128 6129 result = -1; 6130 error = sysctl_handle_int(oidp, &result, 0, req); 6131 6132 if (error || !req->newptr) 6133 return (error); 6134 6135 if (result == 1) { 6136 sc = (struct bce_softc *)arg1; 6137 bce_dump_hw_state(sc); 6138 } 6139 6140 return error; 6141 } 6142 6143 6144 /****************************************************************************/ 6145 /* Provides a sysctl interface to allows dumping the RX chain. */ 6146 /* */ 6147 /* Returns: */ 6148 /* 0 for success, positive value for failure. */ 6149 /****************************************************************************/ 6150 static int 6151 bce_sysctl_dump_rx_chain(SYSCTL_HANDLER_ARGS) 6152 { 6153 int error; 6154 int result; 6155 struct bce_softc *sc; 6156 6157 result = -1; 6158 error = sysctl_handle_int(oidp, &result, 0, req); 6159 6160 if (error || !req->newptr) 6161 return (error); 6162 6163 if (result == 1) { 6164 sc = (struct bce_softc *)arg1; 6165 bce_dump_rx_chain(sc, 0, USABLE_RX_BD(sc)); 6166 } 6167 6168 return error; 6169 } 6170 6171 6172 /****************************************************************************/ 6173 /* Provides a sysctl interface to allows dumping the TX chain. */ 6174 /* */ 6175 /* Returns: */ 6176 /* 0 for success, positive value for failure. */ 6177 /****************************************************************************/ 6178 static int 6179 bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS) 6180 { 6181 int error; 6182 int result; 6183 struct bce_softc *sc; 6184 6185 result = -1; 6186 error = sysctl_handle_int(oidp, &result, 0, req); 6187 6188 if (error || !req->newptr) 6189 return (error); 6190 6191 if (result == 1) { 6192 sc = (struct bce_softc *)arg1; 6193 bce_dump_tx_chain(sc, 0, USABLE_TX_BD(sc)); 6194 } 6195 6196 return error; 6197 } 6198 6199 6200 /****************************************************************************/ 6201 /* Provides a sysctl interface to allow reading arbitrary registers in the */ 6202 /* device. DO NOT ENABLE ON PRODUCTION SYSTEMS! */ 6203 /* */ 6204 /* Returns: */ 6205 /* 0 for success, positive value for failure. */ 6206 /****************************************************************************/ 6207 static int 6208 bce_sysctl_reg_read(SYSCTL_HANDLER_ARGS) 6209 { 6210 struct bce_softc *sc; 6211 int error; 6212 uint32_t val, result; 6213 6214 result = -1; 6215 error = sysctl_handle_int(oidp, &result, 0, req); 6216 if (error || (req->newptr == NULL)) 6217 return (error); 6218 6219 /* Make sure the register is accessible. */ 6220 if (result < 0x8000) { 6221 sc = (struct bce_softc *)arg1; 6222 val = REG_RD(sc, result); 6223 if_printf(&sc->arpcom.ac_if, "reg 0x%08X = 0x%08X\n", 6224 result, val); 6225 } else if (result < 0x0280000) { 6226 sc = (struct bce_softc *)arg1; 6227 val = REG_RD_IND(sc, result); 6228 if_printf(&sc->arpcom.ac_if, "reg 0x%08X = 0x%08X\n", 6229 result, val); 6230 } 6231 return (error); 6232 } 6233 6234 6235 /****************************************************************************/ 6236 /* Provides a sysctl interface to allow reading arbitrary PHY registers in */ 6237 /* the device. DO NOT ENABLE ON PRODUCTION SYSTEMS! */ 6238 /* */ 6239 /* Returns: */ 6240 /* 0 for success, positive value for failure. */ 6241 /****************************************************************************/ 6242 static int 6243 bce_sysctl_phy_read(SYSCTL_HANDLER_ARGS) 6244 { 6245 struct bce_softc *sc; 6246 device_t dev; 6247 int error, result; 6248 uint16_t val; 6249 6250 result = -1; 6251 error = sysctl_handle_int(oidp, &result, 0, req); 6252 if (error || (req->newptr == NULL)) 6253 return (error); 6254 6255 /* Make sure the register is accessible. */ 6256 if (result < 0x20) { 6257 sc = (struct bce_softc *)arg1; 6258 dev = sc->bce_dev; 6259 val = bce_miibus_read_reg(dev, sc->bce_phy_addr, result); 6260 if_printf(&sc->arpcom.ac_if, 6261 "phy 0x%02X = 0x%04X\n", result, val); 6262 } 6263 return (error); 6264 } 6265 6266 6267 /****************************************************************************/ 6268 /* Provides a sysctl interface to forcing the driver to dump state and */ 6269 /* enter the debugger. DO NOT ENABLE ON PRODUCTION SYSTEMS! */ 6270 /* */ 6271 /* Returns: */ 6272 /* 0 for success, positive value for failure. */ 6273 /****************************************************************************/ 6274 static int 6275 bce_sysctl_breakpoint(SYSCTL_HANDLER_ARGS) 6276 { 6277 int error; 6278 int result; 6279 struct bce_softc *sc; 6280 6281 result = -1; 6282 error = sysctl_handle_int(oidp, &result, 0, req); 6283 6284 if (error || !req->newptr) 6285 return (error); 6286 6287 if (result == 1) { 6288 sc = (struct bce_softc *)arg1; 6289 bce_breakpoint(sc); 6290 } 6291 6292 return error; 6293 } 6294 #endif 6295 6296 6297 /****************************************************************************/ 6298 /* Adds any sysctl parameters for tuning or debugging purposes. */ 6299 /* */ 6300 /* Returns: */ 6301 /* 0 for success, positive value for failure. */ 6302 /****************************************************************************/ 6303 static void 6304 bce_add_sysctls(struct bce_softc *sc) 6305 { 6306 struct sysctl_ctx_list *ctx; 6307 struct sysctl_oid_list *children; 6308 6309 sysctl_ctx_init(&sc->bce_sysctl_ctx); 6310 sc->bce_sysctl_tree = SYSCTL_ADD_NODE(&sc->bce_sysctl_ctx, 6311 SYSCTL_STATIC_CHILDREN(_hw), 6312 OID_AUTO, 6313 device_get_nameunit(sc->bce_dev), 6314 CTLFLAG_RD, 0, ""); 6315 if (sc->bce_sysctl_tree == NULL) { 6316 device_printf(sc->bce_dev, "can't add sysctl node\n"); 6317 return; 6318 } 6319 6320 ctx = &sc->bce_sysctl_ctx; 6321 children = SYSCTL_CHILDREN(sc->bce_sysctl_tree); 6322 6323 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tx_bds_int", 6324 CTLTYPE_INT | CTLFLAG_RW, 6325 sc, 0, bce_sysctl_tx_bds_int, "I", 6326 "Send max coalesced BD count during interrupt"); 6327 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tx_bds", 6328 CTLTYPE_INT | CTLFLAG_RW, 6329 sc, 0, bce_sysctl_tx_bds, "I", 6330 "Send max coalesced BD count"); 6331 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tx_ticks_int", 6332 CTLTYPE_INT | CTLFLAG_RW, 6333 sc, 0, bce_sysctl_tx_ticks_int, "I", 6334 "Send coalescing ticks during interrupt"); 6335 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "tx_ticks", 6336 CTLTYPE_INT | CTLFLAG_RW, 6337 sc, 0, bce_sysctl_tx_ticks, "I", 6338 "Send coalescing ticks"); 6339 6340 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rx_bds_int", 6341 CTLTYPE_INT | CTLFLAG_RW, 6342 sc, 0, bce_sysctl_rx_bds_int, "I", 6343 "Receive max coalesced BD count during interrupt"); 6344 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rx_bds", 6345 CTLTYPE_INT | CTLFLAG_RW, 6346 sc, 0, bce_sysctl_rx_bds, "I", 6347 "Receive max coalesced BD count"); 6348 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rx_ticks_int", 6349 CTLTYPE_INT | CTLFLAG_RW, 6350 sc, 0, bce_sysctl_rx_ticks_int, "I", 6351 "Receive coalescing ticks during interrupt"); 6352 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "rx_ticks", 6353 CTLTYPE_INT | CTLFLAG_RW, 6354 sc, 0, bce_sysctl_rx_ticks, "I", 6355 "Receive coalescing ticks"); 6356 6357 SYSCTL_ADD_INT(ctx, children, OID_AUTO, "rx_pages", 6358 CTLFLAG_RD, &sc->rx_pages, 0, "# of RX pages"); 6359 SYSCTL_ADD_INT(ctx, children, OID_AUTO, "tx_pages", 6360 CTLFLAG_RD, &sc->tx_pages, 0, "# of TX pages"); 6361 6362 #ifdef BCE_DEBUG 6363 SYSCTL_ADD_INT(ctx, children, OID_AUTO, 6364 "rx_low_watermark", 6365 CTLFLAG_RD, &sc->rx_low_watermark, 6366 0, "Lowest level of free rx_bd's"); 6367 6368 SYSCTL_ADD_INT(ctx, children, OID_AUTO, 6369 "rx_empty_count", 6370 CTLFLAG_RD, &sc->rx_empty_count, 6371 0, "Number of times the RX chain was empty"); 6372 6373 SYSCTL_ADD_INT(ctx, children, OID_AUTO, 6374 "tx_hi_watermark", 6375 CTLFLAG_RD, &sc->tx_hi_watermark, 6376 0, "Highest level of used tx_bd's"); 6377 6378 SYSCTL_ADD_INT(ctx, children, OID_AUTO, 6379 "tx_full_count", 6380 CTLFLAG_RD, &sc->tx_full_count, 6381 0, "Number of times the TX chain was full"); 6382 6383 SYSCTL_ADD_INT(ctx, children, OID_AUTO, 6384 "l2fhdr_status_errors", 6385 CTLFLAG_RD, &sc->l2fhdr_status_errors, 6386 0, "l2_fhdr status errors"); 6387 6388 SYSCTL_ADD_INT(ctx, children, OID_AUTO, 6389 "unexpected_attentions", 6390 CTLFLAG_RD, &sc->unexpected_attentions, 6391 0, "unexpected attentions"); 6392 6393 SYSCTL_ADD_INT(ctx, children, OID_AUTO, 6394 "lost_status_block_updates", 6395 CTLFLAG_RD, &sc->lost_status_block_updates, 6396 0, "lost status block updates"); 6397 6398 SYSCTL_ADD_INT(ctx, children, OID_AUTO, 6399 "mbuf_alloc_failed", 6400 CTLFLAG_RD, &sc->mbuf_alloc_failed, 6401 0, "mbuf cluster allocation failures"); 6402 #endif 6403 6404 SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 6405 "stat_IfHCInOctets", 6406 CTLFLAG_RD, &sc->stat_IfHCInOctets, 6407 "Bytes received"); 6408 6409 SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 6410 "stat_IfHCInBadOctets", 6411 CTLFLAG_RD, &sc->stat_IfHCInBadOctets, 6412 "Bad bytes received"); 6413 6414 SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 6415 "stat_IfHCOutOctets", 6416 CTLFLAG_RD, &sc->stat_IfHCOutOctets, 6417 "Bytes sent"); 6418 6419 SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 6420 "stat_IfHCOutBadOctets", 6421 CTLFLAG_RD, &sc->stat_IfHCOutBadOctets, 6422 "Bad bytes sent"); 6423 6424 SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 6425 "stat_IfHCInUcastPkts", 6426 CTLFLAG_RD, &sc->stat_IfHCInUcastPkts, 6427 "Unicast packets received"); 6428 6429 SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 6430 "stat_IfHCInMulticastPkts", 6431 CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts, 6432 "Multicast packets received"); 6433 6434 SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 6435 "stat_IfHCInBroadcastPkts", 6436 CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts, 6437 "Broadcast packets received"); 6438 6439 SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 6440 "stat_IfHCOutUcastPkts", 6441 CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts, 6442 "Unicast packets sent"); 6443 6444 SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 6445 "stat_IfHCOutMulticastPkts", 6446 CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts, 6447 "Multicast packets sent"); 6448 6449 SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, 6450 "stat_IfHCOutBroadcastPkts", 6451 CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts, 6452 "Broadcast packets sent"); 6453 6454 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6455 "stat_emac_tx_stat_dot3statsinternalmactransmiterrors", 6456 CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors, 6457 0, "Internal MAC transmit errors"); 6458 6459 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6460 "stat_Dot3StatsCarrierSenseErrors", 6461 CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors, 6462 0, "Carrier sense errors"); 6463 6464 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6465 "stat_Dot3StatsFCSErrors", 6466 CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors, 6467 0, "Frame check sequence errors"); 6468 6469 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6470 "stat_Dot3StatsAlignmentErrors", 6471 CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors, 6472 0, "Alignment errors"); 6473 6474 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6475 "stat_Dot3StatsSingleCollisionFrames", 6476 CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames, 6477 0, "Single Collision Frames"); 6478 6479 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6480 "stat_Dot3StatsMultipleCollisionFrames", 6481 CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames, 6482 0, "Multiple Collision Frames"); 6483 6484 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6485 "stat_Dot3StatsDeferredTransmissions", 6486 CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions, 6487 0, "Deferred Transmissions"); 6488 6489 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6490 "stat_Dot3StatsExcessiveCollisions", 6491 CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions, 6492 0, "Excessive Collisions"); 6493 6494 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6495 "stat_Dot3StatsLateCollisions", 6496 CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions, 6497 0, "Late Collisions"); 6498 6499 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6500 "stat_EtherStatsCollisions", 6501 CTLFLAG_RD, &sc->stat_EtherStatsCollisions, 6502 0, "Collisions"); 6503 6504 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6505 "stat_EtherStatsFragments", 6506 CTLFLAG_RD, &sc->stat_EtherStatsFragments, 6507 0, "Fragments"); 6508 6509 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6510 "stat_EtherStatsJabbers", 6511 CTLFLAG_RD, &sc->stat_EtherStatsJabbers, 6512 0, "Jabbers"); 6513 6514 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6515 "stat_EtherStatsUndersizePkts", 6516 CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts, 6517 0, "Undersize packets"); 6518 6519 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6520 "stat_EtherStatsOverrsizePkts", 6521 CTLFLAG_RD, &sc->stat_EtherStatsOverrsizePkts, 6522 0, "stat_EtherStatsOverrsizePkts"); 6523 6524 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6525 "stat_EtherStatsPktsRx64Octets", 6526 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets, 6527 0, "Bytes received in 64 byte packets"); 6528 6529 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6530 "stat_EtherStatsPktsRx65Octetsto127Octets", 6531 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets, 6532 0, "Bytes received in 65 to 127 byte packets"); 6533 6534 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6535 "stat_EtherStatsPktsRx128Octetsto255Octets", 6536 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets, 6537 0, "Bytes received in 128 to 255 byte packets"); 6538 6539 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6540 "stat_EtherStatsPktsRx256Octetsto511Octets", 6541 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets, 6542 0, "Bytes received in 256 to 511 byte packets"); 6543 6544 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6545 "stat_EtherStatsPktsRx512Octetsto1023Octets", 6546 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets, 6547 0, "Bytes received in 512 to 1023 byte packets"); 6548 6549 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6550 "stat_EtherStatsPktsRx1024Octetsto1522Octets", 6551 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets, 6552 0, "Bytes received in 1024 t0 1522 byte packets"); 6553 6554 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6555 "stat_EtherStatsPktsRx1523Octetsto9022Octets", 6556 CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets, 6557 0, "Bytes received in 1523 to 9022 byte packets"); 6558 6559 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6560 "stat_EtherStatsPktsTx64Octets", 6561 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets, 6562 0, "Bytes sent in 64 byte packets"); 6563 6564 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6565 "stat_EtherStatsPktsTx65Octetsto127Octets", 6566 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets, 6567 0, "Bytes sent in 65 to 127 byte packets"); 6568 6569 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6570 "stat_EtherStatsPktsTx128Octetsto255Octets", 6571 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets, 6572 0, "Bytes sent in 128 to 255 byte packets"); 6573 6574 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6575 "stat_EtherStatsPktsTx256Octetsto511Octets", 6576 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets, 6577 0, "Bytes sent in 256 to 511 byte packets"); 6578 6579 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6580 "stat_EtherStatsPktsTx512Octetsto1023Octets", 6581 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets, 6582 0, "Bytes sent in 512 to 1023 byte packets"); 6583 6584 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6585 "stat_EtherStatsPktsTx1024Octetsto1522Octets", 6586 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets, 6587 0, "Bytes sent in 1024 to 1522 byte packets"); 6588 6589 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6590 "stat_EtherStatsPktsTx1523Octetsto9022Octets", 6591 CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets, 6592 0, "Bytes sent in 1523 to 9022 byte packets"); 6593 6594 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6595 "stat_XonPauseFramesReceived", 6596 CTLFLAG_RD, &sc->stat_XonPauseFramesReceived, 6597 0, "XON pause frames receved"); 6598 6599 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6600 "stat_XoffPauseFramesReceived", 6601 CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived, 6602 0, "XOFF pause frames received"); 6603 6604 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6605 "stat_OutXonSent", 6606 CTLFLAG_RD, &sc->stat_OutXonSent, 6607 0, "XON pause frames sent"); 6608 6609 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6610 "stat_OutXoffSent", 6611 CTLFLAG_RD, &sc->stat_OutXoffSent, 6612 0, "XOFF pause frames sent"); 6613 6614 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6615 "stat_FlowControlDone", 6616 CTLFLAG_RD, &sc->stat_FlowControlDone, 6617 0, "Flow control done"); 6618 6619 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6620 "stat_MacControlFramesReceived", 6621 CTLFLAG_RD, &sc->stat_MacControlFramesReceived, 6622 0, "MAC control frames received"); 6623 6624 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6625 "stat_XoffStateEntered", 6626 CTLFLAG_RD, &sc->stat_XoffStateEntered, 6627 0, "XOFF state entered"); 6628 6629 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6630 "stat_IfInFramesL2FilterDiscards", 6631 CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards, 6632 0, "Received L2 packets discarded"); 6633 6634 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6635 "stat_IfInRuleCheckerDiscards", 6636 CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards, 6637 0, "Received packets discarded by rule"); 6638 6639 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6640 "stat_IfInFTQDiscards", 6641 CTLFLAG_RD, &sc->stat_IfInFTQDiscards, 6642 0, "Received packet FTQ discards"); 6643 6644 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6645 "stat_IfInMBUFDiscards", 6646 CTLFLAG_RD, &sc->stat_IfInMBUFDiscards, 6647 0, "Received packets discarded due to lack of controller buffer memory"); 6648 6649 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6650 "stat_IfInRuleCheckerP4Hit", 6651 CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit, 6652 0, "Received packets rule checker hits"); 6653 6654 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6655 "stat_CatchupInRuleCheckerDiscards", 6656 CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards, 6657 0, "Received packets discarded in Catchup path"); 6658 6659 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6660 "stat_CatchupInFTQDiscards", 6661 CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards, 6662 0, "Received packets discarded in FTQ in Catchup path"); 6663 6664 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6665 "stat_CatchupInMBUFDiscards", 6666 CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards, 6667 0, "Received packets discarded in controller buffer memory in Catchup path"); 6668 6669 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6670 "stat_CatchupInRuleCheckerP4Hit", 6671 CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit, 6672 0, "Received packets rule checker hits in Catchup path"); 6673 6674 SYSCTL_ADD_UINT(ctx, children, OID_AUTO, 6675 "com_no_buffers", 6676 CTLFLAG_RD, &sc->com_no_buffers, 6677 0, "Valid packets received but no RX buffers available"); 6678 6679 #ifdef BCE_DEBUG 6680 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, 6681 "driver_state", CTLTYPE_INT | CTLFLAG_RW, 6682 (void *)sc, 0, 6683 bce_sysctl_driver_state, "I", "Drive state information"); 6684 6685 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, 6686 "hw_state", CTLTYPE_INT | CTLFLAG_RW, 6687 (void *)sc, 0, 6688 bce_sysctl_hw_state, "I", "Hardware state information"); 6689 6690 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, 6691 "dump_rx_chain", CTLTYPE_INT | CTLFLAG_RW, 6692 (void *)sc, 0, 6693 bce_sysctl_dump_rx_chain, "I", "Dump rx_bd chain"); 6694 6695 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, 6696 "dump_tx_chain", CTLTYPE_INT | CTLFLAG_RW, 6697 (void *)sc, 0, 6698 bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain"); 6699 6700 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, 6701 "breakpoint", CTLTYPE_INT | CTLFLAG_RW, 6702 (void *)sc, 0, 6703 bce_sysctl_breakpoint, "I", "Driver breakpoint"); 6704 6705 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, 6706 "reg_read", CTLTYPE_INT | CTLFLAG_RW, 6707 (void *)sc, 0, 6708 bce_sysctl_reg_read, "I", "Register read"); 6709 6710 SYSCTL_ADD_PROC(ctx, children, OID_AUTO, 6711 "phy_read", CTLTYPE_INT | CTLFLAG_RW, 6712 (void *)sc, 0, 6713 bce_sysctl_phy_read, "I", "PHY register read"); 6714 6715 #endif 6716 6717 } 6718 6719 6720 /****************************************************************************/ 6721 /* BCE Debug Routines */ 6722 /****************************************************************************/ 6723 #ifdef BCE_DEBUG 6724 6725 /****************************************************************************/ 6726 /* Freezes the controller to allow for a cohesive state dump. */ 6727 /* */ 6728 /* Returns: */ 6729 /* Nothing. */ 6730 /****************************************************************************/ 6731 static void 6732 bce_freeze_controller(struct bce_softc *sc) 6733 { 6734 uint32_t val; 6735 6736 val = REG_RD(sc, BCE_MISC_COMMAND); 6737 val |= BCE_MISC_COMMAND_DISABLE_ALL; 6738 REG_WR(sc, BCE_MISC_COMMAND, val); 6739 } 6740 6741 6742 /****************************************************************************/ 6743 /* Unfreezes the controller after a freeze operation. This may not always */ 6744 /* work and the controller will require a reset! */ 6745 /* */ 6746 /* Returns: */ 6747 /* Nothing. */ 6748 /****************************************************************************/ 6749 static void 6750 bce_unfreeze_controller(struct bce_softc *sc) 6751 { 6752 uint32_t val; 6753 6754 val = REG_RD(sc, BCE_MISC_COMMAND); 6755 val |= BCE_MISC_COMMAND_ENABLE_ALL; 6756 REG_WR(sc, BCE_MISC_COMMAND, val); 6757 } 6758 6759 6760 /****************************************************************************/ 6761 /* Prints out information about an mbuf. */ 6762 /* */ 6763 /* Returns: */ 6764 /* Nothing. */ 6765 /****************************************************************************/ 6766 static void 6767 bce_dump_mbuf(struct bce_softc *sc, struct mbuf *m) 6768 { 6769 struct ifnet *ifp = &sc->arpcom.ac_if; 6770 uint32_t val_hi, val_lo; 6771 struct mbuf *mp = m; 6772 6773 if (m == NULL) { 6774 /* Index out of range. */ 6775 if_printf(ifp, "mbuf: null pointer\n"); 6776 return; 6777 } 6778 6779 while (mp) { 6780 val_hi = BCE_ADDR_HI(mp); 6781 val_lo = BCE_ADDR_LO(mp); 6782 if_printf(ifp, "mbuf: vaddr = 0x%08X:%08X, m_len = %d, " 6783 "m_flags = ( ", val_hi, val_lo, mp->m_len); 6784 6785 if (mp->m_flags & M_EXT) 6786 kprintf("M_EXT "); 6787 if (mp->m_flags & M_PKTHDR) 6788 kprintf("M_PKTHDR "); 6789 if (mp->m_flags & M_EOR) 6790 kprintf("M_EOR "); 6791 #ifdef M_RDONLY 6792 if (mp->m_flags & M_RDONLY) 6793 kprintf("M_RDONLY "); 6794 #endif 6795 6796 val_hi = BCE_ADDR_HI(mp->m_data); 6797 val_lo = BCE_ADDR_LO(mp->m_data); 6798 kprintf(") m_data = 0x%08X:%08X\n", val_hi, val_lo); 6799 6800 if (mp->m_flags & M_PKTHDR) { 6801 if_printf(ifp, "- m_pkthdr: flags = ( "); 6802 if (mp->m_flags & M_BCAST) 6803 kprintf("M_BCAST "); 6804 if (mp->m_flags & M_MCAST) 6805 kprintf("M_MCAST "); 6806 if (mp->m_flags & M_FRAG) 6807 kprintf("M_FRAG "); 6808 if (mp->m_flags & M_FIRSTFRAG) 6809 kprintf("M_FIRSTFRAG "); 6810 if (mp->m_flags & M_LASTFRAG) 6811 kprintf("M_LASTFRAG "); 6812 #ifdef M_VLANTAG 6813 if (mp->m_flags & M_VLANTAG) 6814 kprintf("M_VLANTAG "); 6815 #endif 6816 #ifdef M_PROMISC 6817 if (mp->m_flags & M_PROMISC) 6818 kprintf("M_PROMISC "); 6819 #endif 6820 kprintf(") csum_flags = ( "); 6821 if (mp->m_pkthdr.csum_flags & CSUM_IP) 6822 kprintf("CSUM_IP "); 6823 if (mp->m_pkthdr.csum_flags & CSUM_TCP) 6824 kprintf("CSUM_TCP "); 6825 if (mp->m_pkthdr.csum_flags & CSUM_UDP) 6826 kprintf("CSUM_UDP "); 6827 if (mp->m_pkthdr.csum_flags & CSUM_IP_FRAGS) 6828 kprintf("CSUM_IP_FRAGS "); 6829 if (mp->m_pkthdr.csum_flags & CSUM_FRAGMENT) 6830 kprintf("CSUM_FRAGMENT "); 6831 #ifdef CSUM_TSO 6832 if (mp->m_pkthdr.csum_flags & CSUM_TSO) 6833 kprintf("CSUM_TSO "); 6834 #endif 6835 if (mp->m_pkthdr.csum_flags & CSUM_IP_CHECKED) 6836 kprintf("CSUM_IP_CHECKED "); 6837 if (mp->m_pkthdr.csum_flags & CSUM_IP_VALID) 6838 kprintf("CSUM_IP_VALID "); 6839 if (mp->m_pkthdr.csum_flags & CSUM_DATA_VALID) 6840 kprintf("CSUM_DATA_VALID "); 6841 kprintf(")\n"); 6842 } 6843 6844 if (mp->m_flags & M_EXT) { 6845 val_hi = BCE_ADDR_HI(mp->m_ext.ext_buf); 6846 val_lo = BCE_ADDR_LO(mp->m_ext.ext_buf); 6847 if_printf(ifp, "- m_ext: vaddr = 0x%08X:%08X, " 6848 "ext_size = %d\n", 6849 val_hi, val_lo, mp->m_ext.ext_size); 6850 } 6851 mp = mp->m_next; 6852 } 6853 } 6854 6855 6856 /****************************************************************************/ 6857 /* Prints out the mbufs in the TX mbuf chain. */ 6858 /* */ 6859 /* Returns: */ 6860 /* Nothing. */ 6861 /****************************************************************************/ 6862 static void 6863 bce_dump_tx_mbuf_chain(struct bce_softc *sc, int chain_prod, int count) 6864 { 6865 struct ifnet *ifp = &sc->arpcom.ac_if; 6866 int i; 6867 6868 if_printf(ifp, 6869 "----------------------------" 6870 " tx mbuf data " 6871 "----------------------------\n"); 6872 6873 for (i = 0; i < count; i++) { 6874 if_printf(ifp, "txmbuf[%d]\n", chain_prod); 6875 bce_dump_mbuf(sc, sc->tx_mbuf_ptr[chain_prod]); 6876 chain_prod = TX_CHAIN_IDX(sc, NEXT_TX_BD(chain_prod)); 6877 } 6878 6879 if_printf(ifp, 6880 "----------------------------" 6881 "----------------" 6882 "----------------------------\n"); 6883 } 6884 6885 6886 /****************************************************************************/ 6887 /* Prints out the mbufs in the RX mbuf chain. */ 6888 /* */ 6889 /* Returns: */ 6890 /* Nothing. */ 6891 /****************************************************************************/ 6892 static void 6893 bce_dump_rx_mbuf_chain(struct bce_softc *sc, int chain_prod, int count) 6894 { 6895 struct ifnet *ifp = &sc->arpcom.ac_if; 6896 int i; 6897 6898 if_printf(ifp, 6899 "----------------------------" 6900 " rx mbuf data " 6901 "----------------------------\n"); 6902 6903 for (i = 0; i < count; i++) { 6904 if_printf(ifp, "rxmbuf[0x%04X]\n", chain_prod); 6905 bce_dump_mbuf(sc, sc->rx_mbuf_ptr[chain_prod]); 6906 chain_prod = RX_CHAIN_IDX(sc, NEXT_RX_BD(chain_prod)); 6907 } 6908 6909 if_printf(ifp, 6910 "----------------------------" 6911 "----------------" 6912 "----------------------------\n"); 6913 } 6914 6915 6916 /****************************************************************************/ 6917 /* Prints out a tx_bd structure. */ 6918 /* */ 6919 /* Returns: */ 6920 /* Nothing. */ 6921 /****************************************************************************/ 6922 static void 6923 bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd) 6924 { 6925 struct ifnet *ifp = &sc->arpcom.ac_if; 6926 6927 if (idx > MAX_TX_BD(sc)) { 6928 /* Index out of range. */ 6929 if_printf(ifp, "tx_bd[0x%04X]: Invalid tx_bd index!\n", idx); 6930 } else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE) { 6931 /* TX Chain page pointer. */ 6932 if_printf(ifp, "tx_bd[0x%04X]: haddr = 0x%08X:%08X, " 6933 "chain page pointer\n", 6934 idx, txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo); 6935 } else { 6936 /* Normal tx_bd entry. */ 6937 if_printf(ifp, "tx_bd[0x%04X]: haddr = 0x%08X:%08X, " 6938 "nbytes = 0x%08X, " 6939 "vlan tag= 0x%04X, flags = 0x%04X (", 6940 idx, txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo, 6941 txbd->tx_bd_mss_nbytes, 6942 txbd->tx_bd_vlan_tag, txbd->tx_bd_flags); 6943 6944 if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT) 6945 kprintf(" CONN_FAULT"); 6946 6947 if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM) 6948 kprintf(" TCP_UDP_CKSUM"); 6949 6950 if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM) 6951 kprintf(" IP_CKSUM"); 6952 6953 if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG) 6954 kprintf(" VLAN"); 6955 6956 if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW) 6957 kprintf(" COAL_NOW"); 6958 6959 if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC) 6960 kprintf(" DONT_GEN_CRC"); 6961 6962 if (txbd->tx_bd_flags & TX_BD_FLAGS_START) 6963 kprintf(" START"); 6964 6965 if (txbd->tx_bd_flags & TX_BD_FLAGS_END) 6966 kprintf(" END"); 6967 6968 if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO) 6969 kprintf(" LSO"); 6970 6971 if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD) 6972 kprintf(" OPTION_WORD"); 6973 6974 if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS) 6975 kprintf(" FLAGS"); 6976 6977 if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP) 6978 kprintf(" SNAP"); 6979 6980 kprintf(" )\n"); 6981 } 6982 } 6983 6984 6985 /****************************************************************************/ 6986 /* Prints out a rx_bd structure. */ 6987 /* */ 6988 /* Returns: */ 6989 /* Nothing. */ 6990 /****************************************************************************/ 6991 static void 6992 bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd) 6993 { 6994 struct ifnet *ifp = &sc->arpcom.ac_if; 6995 6996 if (idx > MAX_RX_BD(sc)) { 6997 /* Index out of range. */ 6998 if_printf(ifp, "rx_bd[0x%04X]: Invalid rx_bd index!\n", idx); 6999 } else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE) { 7000 /* TX Chain page pointer. */ 7001 if_printf(ifp, "rx_bd[0x%04X]: haddr = 0x%08X:%08X, " 7002 "chain page pointer\n", 7003 idx, rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo); 7004 } else { 7005 /* Normal tx_bd entry. */ 7006 if_printf(ifp, "rx_bd[0x%04X]: haddr = 0x%08X:%08X, " 7007 "nbytes = 0x%08X, flags = 0x%08X\n", 7008 idx, rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo, 7009 rxbd->rx_bd_len, rxbd->rx_bd_flags); 7010 } 7011 } 7012 7013 7014 /****************************************************************************/ 7015 /* Prints out a l2_fhdr structure. */ 7016 /* */ 7017 /* Returns: */ 7018 /* Nothing. */ 7019 /****************************************************************************/ 7020 static void 7021 bce_dump_l2fhdr(struct bce_softc *sc, int idx, struct l2_fhdr *l2fhdr) 7022 { 7023 if_printf(&sc->arpcom.ac_if, "l2_fhdr[0x%04X]: status = 0x%08X, " 7024 "pkt_len = 0x%04X, vlan = 0x%04x, " 7025 "ip_xsum = 0x%04X, tcp_udp_xsum = 0x%04X\n", 7026 idx, l2fhdr->l2_fhdr_status, 7027 l2fhdr->l2_fhdr_pkt_len, l2fhdr->l2_fhdr_vlan_tag, 7028 l2fhdr->l2_fhdr_ip_xsum, l2fhdr->l2_fhdr_tcp_udp_xsum); 7029 } 7030 7031 7032 /****************************************************************************/ 7033 /* Prints out the tx chain. */ 7034 /* */ 7035 /* Returns: */ 7036 /* Nothing. */ 7037 /****************************************************************************/ 7038 static void 7039 bce_dump_tx_chain(struct bce_softc *sc, int tx_prod, int count) 7040 { 7041 struct ifnet *ifp = &sc->arpcom.ac_if; 7042 int i; 7043 7044 /* First some info about the tx_bd chain structure. */ 7045 if_printf(ifp, 7046 "----------------------------" 7047 " tx_bd chain " 7048 "----------------------------\n"); 7049 7050 if_printf(ifp, "page size = 0x%08X, " 7051 "tx chain pages = 0x%08X\n", 7052 (uint32_t)BCM_PAGE_SIZE, (uint32_t)sc->tx_pages); 7053 7054 if_printf(ifp, "tx_bd per page = 0x%08X, " 7055 "usable tx_bd per page = 0x%08X\n", 7056 (uint32_t)TOTAL_TX_BD_PER_PAGE, 7057 (uint32_t)USABLE_TX_BD_PER_PAGE); 7058 7059 if_printf(ifp, "total tx_bd = 0x%08X\n", (uint32_t)TOTAL_TX_BD(sc)); 7060 7061 if_printf(ifp, 7062 "----------------------------" 7063 " tx_bd data " 7064 "----------------------------\n"); 7065 7066 /* Now print out the tx_bd's themselves. */ 7067 for (i = 0; i < count; i++) { 7068 struct tx_bd *txbd; 7069 7070 txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)]; 7071 bce_dump_txbd(sc, tx_prod, txbd); 7072 tx_prod = TX_CHAIN_IDX(sc, NEXT_TX_BD(tx_prod)); 7073 } 7074 7075 if_printf(ifp, 7076 "----------------------------" 7077 "----------------" 7078 "----------------------------\n"); 7079 } 7080 7081 7082 /****************************************************************************/ 7083 /* Prints out the rx chain. */ 7084 /* */ 7085 /* Returns: */ 7086 /* Nothing. */ 7087 /****************************************************************************/ 7088 static void 7089 bce_dump_rx_chain(struct bce_softc *sc, int rx_prod, int count) 7090 { 7091 struct ifnet *ifp = &sc->arpcom.ac_if; 7092 int i; 7093 7094 /* First some info about the tx_bd chain structure. */ 7095 if_printf(ifp, 7096 "----------------------------" 7097 " rx_bd chain " 7098 "----------------------------\n"); 7099 7100 if_printf(ifp, "page size = 0x%08X, " 7101 "rx chain pages = 0x%08X\n", 7102 (uint32_t)BCM_PAGE_SIZE, (uint32_t)sc->rx_pages); 7103 7104 if_printf(ifp, "rx_bd per page = 0x%08X, " 7105 "usable rx_bd per page = 0x%08X\n", 7106 (uint32_t)TOTAL_RX_BD_PER_PAGE, 7107 (uint32_t)USABLE_RX_BD_PER_PAGE); 7108 7109 if_printf(ifp, "total rx_bd = 0x%08X\n", (uint32_t)TOTAL_RX_BD(sc)); 7110 7111 if_printf(ifp, 7112 "----------------------------" 7113 " rx_bd data " 7114 "----------------------------\n"); 7115 7116 /* Now print out the rx_bd's themselves. */ 7117 for (i = 0; i < count; i++) { 7118 struct rx_bd *rxbd; 7119 7120 rxbd = &sc->rx_bd_chain[RX_PAGE(rx_prod)][RX_IDX(rx_prod)]; 7121 bce_dump_rxbd(sc, rx_prod, rxbd); 7122 rx_prod = RX_CHAIN_IDX(sc, NEXT_RX_BD(rx_prod)); 7123 } 7124 7125 if_printf(ifp, 7126 "----------------------------" 7127 "----------------" 7128 "----------------------------\n"); 7129 } 7130 7131 7132 /****************************************************************************/ 7133 /* Prints out the status block from host memory. */ 7134 /* */ 7135 /* Returns: */ 7136 /* Nothing. */ 7137 /****************************************************************************/ 7138 static void 7139 bce_dump_status_block(struct bce_softc *sc) 7140 { 7141 struct status_block *sblk = sc->status_block; 7142 struct ifnet *ifp = &sc->arpcom.ac_if; 7143 7144 if_printf(ifp, 7145 "----------------------------" 7146 " Status Block " 7147 "----------------------------\n"); 7148 7149 if_printf(ifp, " 0x%08X - attn_bits\n", sblk->status_attn_bits); 7150 7151 if_printf(ifp, " 0x%08X - attn_bits_ack\n", 7152 sblk->status_attn_bits_ack); 7153 7154 if_printf(ifp, "0x%04X(0x%04X) - rx_cons0\n", 7155 sblk->status_rx_quick_consumer_index0, 7156 (uint16_t)RX_CHAIN_IDX(sc, sblk->status_rx_quick_consumer_index0)); 7157 7158 if_printf(ifp, "0x%04X(0x%04X) - tx_cons0\n", 7159 sblk->status_tx_quick_consumer_index0, 7160 (uint16_t)TX_CHAIN_IDX(sc, sblk->status_tx_quick_consumer_index0)); 7161 7162 if_printf(ifp, " 0x%04X - status_idx\n", sblk->status_idx); 7163 7164 /* Theses indices are not used for normal L2 drivers. */ 7165 if (sblk->status_rx_quick_consumer_index1) { 7166 if_printf(ifp, "0x%04X(0x%04X) - rx_cons1\n", 7167 sblk->status_rx_quick_consumer_index1, 7168 (uint16_t)RX_CHAIN_IDX(sc, 7169 sblk->status_rx_quick_consumer_index1)); 7170 } 7171 7172 if (sblk->status_tx_quick_consumer_index1) { 7173 if_printf(ifp, "0x%04X(0x%04X) - tx_cons1\n", 7174 sblk->status_tx_quick_consumer_index1, 7175 (uint16_t)TX_CHAIN_IDX(sc, 7176 sblk->status_tx_quick_consumer_index1)); 7177 } 7178 7179 if (sblk->status_rx_quick_consumer_index2) { 7180 if_printf(ifp, "0x%04X(0x%04X)- rx_cons2\n", 7181 sblk->status_rx_quick_consumer_index2, 7182 (uint16_t)RX_CHAIN_IDX(sc, 7183 sblk->status_rx_quick_consumer_index2)); 7184 } 7185 7186 if (sblk->status_tx_quick_consumer_index2) { 7187 if_printf(ifp, "0x%04X(0x%04X) - tx_cons2\n", 7188 sblk->status_tx_quick_consumer_index2, 7189 (uint16_t)TX_CHAIN_IDX(sc, 7190 sblk->status_tx_quick_consumer_index2)); 7191 } 7192 7193 if (sblk->status_rx_quick_consumer_index3) { 7194 if_printf(ifp, "0x%04X(0x%04X) - rx_cons3\n", 7195 sblk->status_rx_quick_consumer_index3, 7196 (uint16_t)RX_CHAIN_IDX(sc, 7197 sblk->status_rx_quick_consumer_index3)); 7198 } 7199 7200 if (sblk->status_tx_quick_consumer_index3) { 7201 if_printf(ifp, "0x%04X(0x%04X) - tx_cons3\n", 7202 sblk->status_tx_quick_consumer_index3, 7203 (uint16_t)TX_CHAIN_IDX(sc, 7204 sblk->status_tx_quick_consumer_index3)); 7205 } 7206 7207 if (sblk->status_rx_quick_consumer_index4 || 7208 sblk->status_rx_quick_consumer_index5) { 7209 if_printf(ifp, "rx_cons4 = 0x%08X, rx_cons5 = 0x%08X\n", 7210 sblk->status_rx_quick_consumer_index4, 7211 sblk->status_rx_quick_consumer_index5); 7212 } 7213 7214 if (sblk->status_rx_quick_consumer_index6 || 7215 sblk->status_rx_quick_consumer_index7) { 7216 if_printf(ifp, "rx_cons6 = 0x%08X, rx_cons7 = 0x%08X\n", 7217 sblk->status_rx_quick_consumer_index6, 7218 sblk->status_rx_quick_consumer_index7); 7219 } 7220 7221 if (sblk->status_rx_quick_consumer_index8 || 7222 sblk->status_rx_quick_consumer_index9) { 7223 if_printf(ifp, "rx_cons8 = 0x%08X, rx_cons9 = 0x%08X\n", 7224 sblk->status_rx_quick_consumer_index8, 7225 sblk->status_rx_quick_consumer_index9); 7226 } 7227 7228 if (sblk->status_rx_quick_consumer_index10 || 7229 sblk->status_rx_quick_consumer_index11) { 7230 if_printf(ifp, "rx_cons10 = 0x%08X, rx_cons11 = 0x%08X\n", 7231 sblk->status_rx_quick_consumer_index10, 7232 sblk->status_rx_quick_consumer_index11); 7233 } 7234 7235 if (sblk->status_rx_quick_consumer_index12 || 7236 sblk->status_rx_quick_consumer_index13) { 7237 if_printf(ifp, "rx_cons12 = 0x%08X, rx_cons13 = 0x%08X\n", 7238 sblk->status_rx_quick_consumer_index12, 7239 sblk->status_rx_quick_consumer_index13); 7240 } 7241 7242 if (sblk->status_rx_quick_consumer_index14 || 7243 sblk->status_rx_quick_consumer_index15) { 7244 if_printf(ifp, "rx_cons14 = 0x%08X, rx_cons15 = 0x%08X\n", 7245 sblk->status_rx_quick_consumer_index14, 7246 sblk->status_rx_quick_consumer_index15); 7247 } 7248 7249 if (sblk->status_completion_producer_index || 7250 sblk->status_cmd_consumer_index) { 7251 if_printf(ifp, "com_prod = 0x%08X, cmd_cons = 0x%08X\n", 7252 sblk->status_completion_producer_index, 7253 sblk->status_cmd_consumer_index); 7254 } 7255 7256 if_printf(ifp, 7257 "----------------------------" 7258 "----------------" 7259 "----------------------------\n"); 7260 } 7261 7262 7263 /****************************************************************************/ 7264 /* Prints out the statistics block. */ 7265 /* */ 7266 /* Returns: */ 7267 /* Nothing. */ 7268 /****************************************************************************/ 7269 static void 7270 bce_dump_stats_block(struct bce_softc *sc) 7271 { 7272 struct statistics_block *sblk = sc->stats_block; 7273 struct ifnet *ifp = &sc->arpcom.ac_if; 7274 7275 if_printf(ifp, 7276 "---------------" 7277 " Stats Block (All Stats Not Shown Are 0) " 7278 "---------------\n"); 7279 7280 if (sblk->stat_IfHCInOctets_hi || sblk->stat_IfHCInOctets_lo) { 7281 if_printf(ifp, "0x%08X:%08X : IfHcInOctets\n", 7282 sblk->stat_IfHCInOctets_hi, 7283 sblk->stat_IfHCInOctets_lo); 7284 } 7285 7286 if (sblk->stat_IfHCInBadOctets_hi || sblk->stat_IfHCInBadOctets_lo) { 7287 if_printf(ifp, "0x%08X:%08X : IfHcInBadOctets\n", 7288 sblk->stat_IfHCInBadOctets_hi, 7289 sblk->stat_IfHCInBadOctets_lo); 7290 } 7291 7292 if (sblk->stat_IfHCOutOctets_hi || sblk->stat_IfHCOutOctets_lo) { 7293 if_printf(ifp, "0x%08X:%08X : IfHcOutOctets\n", 7294 sblk->stat_IfHCOutOctets_hi, 7295 sblk->stat_IfHCOutOctets_lo); 7296 } 7297 7298 if (sblk->stat_IfHCOutBadOctets_hi || sblk->stat_IfHCOutBadOctets_lo) { 7299 if_printf(ifp, "0x%08X:%08X : IfHcOutBadOctets\n", 7300 sblk->stat_IfHCOutBadOctets_hi, 7301 sblk->stat_IfHCOutBadOctets_lo); 7302 } 7303 7304 if (sblk->stat_IfHCInUcastPkts_hi || sblk->stat_IfHCInUcastPkts_lo) { 7305 if_printf(ifp, "0x%08X:%08X : IfHcInUcastPkts\n", 7306 sblk->stat_IfHCInUcastPkts_hi, 7307 sblk->stat_IfHCInUcastPkts_lo); 7308 } 7309 7310 if (sblk->stat_IfHCInBroadcastPkts_hi || 7311 sblk->stat_IfHCInBroadcastPkts_lo) { 7312 if_printf(ifp, "0x%08X:%08X : IfHcInBroadcastPkts\n", 7313 sblk->stat_IfHCInBroadcastPkts_hi, 7314 sblk->stat_IfHCInBroadcastPkts_lo); 7315 } 7316 7317 if (sblk->stat_IfHCInMulticastPkts_hi || 7318 sblk->stat_IfHCInMulticastPkts_lo) { 7319 if_printf(ifp, "0x%08X:%08X : IfHcInMulticastPkts\n", 7320 sblk->stat_IfHCInMulticastPkts_hi, 7321 sblk->stat_IfHCInMulticastPkts_lo); 7322 } 7323 7324 if (sblk->stat_IfHCOutUcastPkts_hi || sblk->stat_IfHCOutUcastPkts_lo) { 7325 if_printf(ifp, "0x%08X:%08X : IfHcOutUcastPkts\n", 7326 sblk->stat_IfHCOutUcastPkts_hi, 7327 sblk->stat_IfHCOutUcastPkts_lo); 7328 } 7329 7330 if (sblk->stat_IfHCOutBroadcastPkts_hi || 7331 sblk->stat_IfHCOutBroadcastPkts_lo) { 7332 if_printf(ifp, "0x%08X:%08X : IfHcOutBroadcastPkts\n", 7333 sblk->stat_IfHCOutBroadcastPkts_hi, 7334 sblk->stat_IfHCOutBroadcastPkts_lo); 7335 } 7336 7337 if (sblk->stat_IfHCOutMulticastPkts_hi || 7338 sblk->stat_IfHCOutMulticastPkts_lo) { 7339 if_printf(ifp, "0x%08X:%08X : IfHcOutMulticastPkts\n", 7340 sblk->stat_IfHCOutMulticastPkts_hi, 7341 sblk->stat_IfHCOutMulticastPkts_lo); 7342 } 7343 7344 if (sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors) { 7345 if_printf(ifp, " 0x%08X : " 7346 "emac_tx_stat_dot3statsinternalmactransmiterrors\n", 7347 sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors); 7348 } 7349 7350 if (sblk->stat_Dot3StatsCarrierSenseErrors) { 7351 if_printf(ifp, " 0x%08X : " 7352 "Dot3StatsCarrierSenseErrors\n", 7353 sblk->stat_Dot3StatsCarrierSenseErrors); 7354 } 7355 7356 if (sblk->stat_Dot3StatsFCSErrors) { 7357 if_printf(ifp, " 0x%08X : Dot3StatsFCSErrors\n", 7358 sblk->stat_Dot3StatsFCSErrors); 7359 } 7360 7361 if (sblk->stat_Dot3StatsAlignmentErrors) { 7362 if_printf(ifp, " 0x%08X : Dot3StatsAlignmentErrors\n", 7363 sblk->stat_Dot3StatsAlignmentErrors); 7364 } 7365 7366 if (sblk->stat_Dot3StatsSingleCollisionFrames) { 7367 if_printf(ifp, " 0x%08X : " 7368 "Dot3StatsSingleCollisionFrames\n", 7369 sblk->stat_Dot3StatsSingleCollisionFrames); 7370 } 7371 7372 if (sblk->stat_Dot3StatsMultipleCollisionFrames) { 7373 if_printf(ifp, " 0x%08X : " 7374 "Dot3StatsMultipleCollisionFrames\n", 7375 sblk->stat_Dot3StatsMultipleCollisionFrames); 7376 } 7377 7378 if (sblk->stat_Dot3StatsDeferredTransmissions) { 7379 if_printf(ifp, " 0x%08X : " 7380 "Dot3StatsDeferredTransmissions\n", 7381 sblk->stat_Dot3StatsDeferredTransmissions); 7382 } 7383 7384 if (sblk->stat_Dot3StatsExcessiveCollisions) { 7385 if_printf(ifp, " 0x%08X : " 7386 "Dot3StatsExcessiveCollisions\n", 7387 sblk->stat_Dot3StatsExcessiveCollisions); 7388 } 7389 7390 if (sblk->stat_Dot3StatsLateCollisions) { 7391 if_printf(ifp, " 0x%08X : Dot3StatsLateCollisions\n", 7392 sblk->stat_Dot3StatsLateCollisions); 7393 } 7394 7395 if (sblk->stat_EtherStatsCollisions) { 7396 if_printf(ifp, " 0x%08X : EtherStatsCollisions\n", 7397 sblk->stat_EtherStatsCollisions); 7398 } 7399 7400 if (sblk->stat_EtherStatsFragments) { 7401 if_printf(ifp, " 0x%08X : EtherStatsFragments\n", 7402 sblk->stat_EtherStatsFragments); 7403 } 7404 7405 if (sblk->stat_EtherStatsJabbers) { 7406 if_printf(ifp, " 0x%08X : EtherStatsJabbers\n", 7407 sblk->stat_EtherStatsJabbers); 7408 } 7409 7410 if (sblk->stat_EtherStatsUndersizePkts) { 7411 if_printf(ifp, " 0x%08X : EtherStatsUndersizePkts\n", 7412 sblk->stat_EtherStatsUndersizePkts); 7413 } 7414 7415 if (sblk->stat_EtherStatsOverrsizePkts) { 7416 if_printf(ifp, " 0x%08X : EtherStatsOverrsizePkts\n", 7417 sblk->stat_EtherStatsOverrsizePkts); 7418 } 7419 7420 if (sblk->stat_EtherStatsPktsRx64Octets) { 7421 if_printf(ifp, " 0x%08X : EtherStatsPktsRx64Octets\n", 7422 sblk->stat_EtherStatsPktsRx64Octets); 7423 } 7424 7425 if (sblk->stat_EtherStatsPktsRx65Octetsto127Octets) { 7426 if_printf(ifp, " 0x%08X : " 7427 "EtherStatsPktsRx65Octetsto127Octets\n", 7428 sblk->stat_EtherStatsPktsRx65Octetsto127Octets); 7429 } 7430 7431 if (sblk->stat_EtherStatsPktsRx128Octetsto255Octets) { 7432 if_printf(ifp, " 0x%08X : " 7433 "EtherStatsPktsRx128Octetsto255Octets\n", 7434 sblk->stat_EtherStatsPktsRx128Octetsto255Octets); 7435 } 7436 7437 if (sblk->stat_EtherStatsPktsRx256Octetsto511Octets) { 7438 if_printf(ifp, " 0x%08X : " 7439 "EtherStatsPktsRx256Octetsto511Octets\n", 7440 sblk->stat_EtherStatsPktsRx256Octetsto511Octets); 7441 } 7442 7443 if (sblk->stat_EtherStatsPktsRx512Octetsto1023Octets) { 7444 if_printf(ifp, " 0x%08X : " 7445 "EtherStatsPktsRx512Octetsto1023Octets\n", 7446 sblk->stat_EtherStatsPktsRx512Octetsto1023Octets); 7447 } 7448 7449 if (sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets) { 7450 if_printf(ifp, " 0x%08X : " 7451 "EtherStatsPktsRx1024Octetsto1522Octets\n", 7452 sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets); 7453 } 7454 7455 if (sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets) { 7456 if_printf(ifp, " 0x%08X : " 7457 "EtherStatsPktsRx1523Octetsto9022Octets\n", 7458 sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets); 7459 } 7460 7461 if (sblk->stat_EtherStatsPktsTx64Octets) { 7462 if_printf(ifp, " 0x%08X : EtherStatsPktsTx64Octets\n", 7463 sblk->stat_EtherStatsPktsTx64Octets); 7464 } 7465 7466 if (sblk->stat_EtherStatsPktsTx65Octetsto127Octets) { 7467 if_printf(ifp, " 0x%08X : " 7468 "EtherStatsPktsTx65Octetsto127Octets\n", 7469 sblk->stat_EtherStatsPktsTx65Octetsto127Octets); 7470 } 7471 7472 if (sblk->stat_EtherStatsPktsTx128Octetsto255Octets) { 7473 if_printf(ifp, " 0x%08X : " 7474 "EtherStatsPktsTx128Octetsto255Octets\n", 7475 sblk->stat_EtherStatsPktsTx128Octetsto255Octets); 7476 } 7477 7478 if (sblk->stat_EtherStatsPktsTx256Octetsto511Octets) { 7479 if_printf(ifp, " 0x%08X : " 7480 "EtherStatsPktsTx256Octetsto511Octets\n", 7481 sblk->stat_EtherStatsPktsTx256Octetsto511Octets); 7482 } 7483 7484 if (sblk->stat_EtherStatsPktsTx512Octetsto1023Octets) { 7485 if_printf(ifp, " 0x%08X : " 7486 "EtherStatsPktsTx512Octetsto1023Octets\n", 7487 sblk->stat_EtherStatsPktsTx512Octetsto1023Octets); 7488 } 7489 7490 if (sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets) { 7491 if_printf(ifp, " 0x%08X : " 7492 "EtherStatsPktsTx1024Octetsto1522Octets\n", 7493 sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets); 7494 } 7495 7496 if (sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets) { 7497 if_printf(ifp, " 0x%08X : " 7498 "EtherStatsPktsTx1523Octetsto9022Octets\n", 7499 sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets); 7500 } 7501 7502 if (sblk->stat_XonPauseFramesReceived) { 7503 if_printf(ifp, " 0x%08X : XonPauseFramesReceived\n", 7504 sblk->stat_XonPauseFramesReceived); 7505 } 7506 7507 if (sblk->stat_XoffPauseFramesReceived) { 7508 if_printf(ifp, " 0x%08X : XoffPauseFramesReceived\n", 7509 sblk->stat_XoffPauseFramesReceived); 7510 } 7511 7512 if (sblk->stat_OutXonSent) { 7513 if_printf(ifp, " 0x%08X : OutXoffSent\n", 7514 sblk->stat_OutXonSent); 7515 } 7516 7517 if (sblk->stat_OutXoffSent) { 7518 if_printf(ifp, " 0x%08X : OutXoffSent\n", 7519 sblk->stat_OutXoffSent); 7520 } 7521 7522 if (sblk->stat_FlowControlDone) { 7523 if_printf(ifp, " 0x%08X : FlowControlDone\n", 7524 sblk->stat_FlowControlDone); 7525 } 7526 7527 if (sblk->stat_MacControlFramesReceived) { 7528 if_printf(ifp, " 0x%08X : MacControlFramesReceived\n", 7529 sblk->stat_MacControlFramesReceived); 7530 } 7531 7532 if (sblk->stat_XoffStateEntered) { 7533 if_printf(ifp, " 0x%08X : XoffStateEntered\n", 7534 sblk->stat_XoffStateEntered); 7535 } 7536 7537 if (sblk->stat_IfInFramesL2FilterDiscards) { 7538 if_printf(ifp, " 0x%08X : IfInFramesL2FilterDiscards\n", sblk->stat_IfInFramesL2FilterDiscards); 7539 } 7540 7541 if (sblk->stat_IfInRuleCheckerDiscards) { 7542 if_printf(ifp, " 0x%08X : IfInRuleCheckerDiscards\n", 7543 sblk->stat_IfInRuleCheckerDiscards); 7544 } 7545 7546 if (sblk->stat_IfInFTQDiscards) { 7547 if_printf(ifp, " 0x%08X : IfInFTQDiscards\n", 7548 sblk->stat_IfInFTQDiscards); 7549 } 7550 7551 if (sblk->stat_IfInMBUFDiscards) { 7552 if_printf(ifp, " 0x%08X : IfInMBUFDiscards\n", 7553 sblk->stat_IfInMBUFDiscards); 7554 } 7555 7556 if (sblk->stat_IfInRuleCheckerP4Hit) { 7557 if_printf(ifp, " 0x%08X : IfInRuleCheckerP4Hit\n", 7558 sblk->stat_IfInRuleCheckerP4Hit); 7559 } 7560 7561 if (sblk->stat_CatchupInRuleCheckerDiscards) { 7562 if_printf(ifp, " 0x%08X : " 7563 "CatchupInRuleCheckerDiscards\n", 7564 sblk->stat_CatchupInRuleCheckerDiscards); 7565 } 7566 7567 if (sblk->stat_CatchupInFTQDiscards) { 7568 if_printf(ifp, " 0x%08X : CatchupInFTQDiscards\n", 7569 sblk->stat_CatchupInFTQDiscards); 7570 } 7571 7572 if (sblk->stat_CatchupInMBUFDiscards) { 7573 if_printf(ifp, " 0x%08X : CatchupInMBUFDiscards\n", 7574 sblk->stat_CatchupInMBUFDiscards); 7575 } 7576 7577 if (sblk->stat_CatchupInRuleCheckerP4Hit) { 7578 if_printf(ifp, " 0x%08X : CatchupInRuleCheckerP4Hit\n", 7579 sblk->stat_CatchupInRuleCheckerP4Hit); 7580 } 7581 7582 if_printf(ifp, 7583 "----------------------------" 7584 "----------------" 7585 "----------------------------\n"); 7586 } 7587 7588 7589 /****************************************************************************/ 7590 /* Prints out a summary of the driver state. */ 7591 /* */ 7592 /* Returns: */ 7593 /* Nothing. */ 7594 /****************************************************************************/ 7595 static void 7596 bce_dump_driver_state(struct bce_softc *sc) 7597 { 7598 struct ifnet *ifp = &sc->arpcom.ac_if; 7599 uint32_t val_hi, val_lo; 7600 7601 if_printf(ifp, 7602 "-----------------------------" 7603 " Driver State " 7604 "-----------------------------\n"); 7605 7606 val_hi = BCE_ADDR_HI(sc); 7607 val_lo = BCE_ADDR_LO(sc); 7608 if_printf(ifp, "0x%08X:%08X - (sc) driver softc structure " 7609 "virtual address\n", val_hi, val_lo); 7610 7611 val_hi = BCE_ADDR_HI(sc->status_block); 7612 val_lo = BCE_ADDR_LO(sc->status_block); 7613 if_printf(ifp, "0x%08X:%08X - (sc->status_block) status block " 7614 "virtual address\n", val_hi, val_lo); 7615 7616 val_hi = BCE_ADDR_HI(sc->stats_block); 7617 val_lo = BCE_ADDR_LO(sc->stats_block); 7618 if_printf(ifp, "0x%08X:%08X - (sc->stats_block) statistics block " 7619 "virtual address\n", val_hi, val_lo); 7620 7621 val_hi = BCE_ADDR_HI(sc->tx_bd_chain); 7622 val_lo = BCE_ADDR_LO(sc->tx_bd_chain); 7623 if_printf(ifp, "0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain " 7624 "virtual adddress\n", val_hi, val_lo); 7625 7626 val_hi = BCE_ADDR_HI(sc->rx_bd_chain); 7627 val_lo = BCE_ADDR_LO(sc->rx_bd_chain); 7628 if_printf(ifp, "0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain " 7629 "virtual address\n", val_hi, val_lo); 7630 7631 val_hi = BCE_ADDR_HI(sc->tx_mbuf_ptr); 7632 val_lo = BCE_ADDR_LO(sc->tx_mbuf_ptr); 7633 if_printf(ifp, "0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain " 7634 "virtual address\n", val_hi, val_lo); 7635 7636 val_hi = BCE_ADDR_HI(sc->rx_mbuf_ptr); 7637 val_lo = BCE_ADDR_LO(sc->rx_mbuf_ptr); 7638 if_printf(ifp, "0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain " 7639 "virtual address\n", val_hi, val_lo); 7640 7641 if_printf(ifp, " 0x%08X - (sc->interrupts_generated) " 7642 "h/w intrs\n", sc->interrupts_generated); 7643 7644 if_printf(ifp, " 0x%08X - (sc->rx_interrupts) " 7645 "rx interrupts handled\n", sc->rx_interrupts); 7646 7647 if_printf(ifp, " 0x%08X - (sc->tx_interrupts) " 7648 "tx interrupts handled\n", sc->tx_interrupts); 7649 7650 if_printf(ifp, " 0x%08X - (sc->last_status_idx) " 7651 "status block index\n", sc->last_status_idx); 7652 7653 if_printf(ifp, " 0x%04X(0x%04X) - (sc->tx_prod) " 7654 "tx producer index\n", 7655 sc->tx_prod, (uint16_t)TX_CHAIN_IDX(sc, sc->tx_prod)); 7656 7657 if_printf(ifp, " 0x%04X(0x%04X) - (sc->tx_cons) " 7658 "tx consumer index\n", 7659 sc->tx_cons, (uint16_t)TX_CHAIN_IDX(sc, sc->tx_cons)); 7660 7661 if_printf(ifp, " 0x%08X - (sc->tx_prod_bseq) " 7662 "tx producer bseq index\n", sc->tx_prod_bseq); 7663 7664 if_printf(ifp, " 0x%04X(0x%04X) - (sc->rx_prod) " 7665 "rx producer index\n", 7666 sc->rx_prod, (uint16_t)RX_CHAIN_IDX(sc, sc->rx_prod)); 7667 7668 if_printf(ifp, " 0x%04X(0x%04X) - (sc->rx_cons) " 7669 "rx consumer index\n", 7670 sc->rx_cons, (uint16_t)RX_CHAIN_IDX(sc, sc->rx_cons)); 7671 7672 if_printf(ifp, " 0x%08X - (sc->rx_prod_bseq) " 7673 "rx producer bseq index\n", sc->rx_prod_bseq); 7674 7675 if_printf(ifp, " 0x%08X - (sc->rx_mbuf_alloc) " 7676 "rx mbufs allocated\n", sc->rx_mbuf_alloc); 7677 7678 if_printf(ifp, " 0x%08X - (sc->free_rx_bd) " 7679 "free rx_bd's\n", sc->free_rx_bd); 7680 7681 if_printf(ifp, "0x%08X/%08X - (sc->rx_low_watermark) rx " 7682 "low watermark\n", sc->rx_low_watermark, sc->max_rx_bd); 7683 7684 if_printf(ifp, " 0x%08X - (sc->txmbuf_alloc) " 7685 "tx mbufs allocated\n", sc->tx_mbuf_alloc); 7686 7687 if_printf(ifp, " 0x%08X - (sc->rx_mbuf_alloc) " 7688 "rx mbufs allocated\n", sc->rx_mbuf_alloc); 7689 7690 if_printf(ifp, " 0x%08X - (sc->used_tx_bd) used tx_bd's\n", 7691 sc->used_tx_bd); 7692 7693 if_printf(ifp, "0x%08X/%08X - (sc->tx_hi_watermark) tx hi watermark\n", 7694 sc->tx_hi_watermark, sc->max_tx_bd); 7695 7696 if_printf(ifp, " 0x%08X - (sc->mbuf_alloc_failed) " 7697 "failed mbuf alloc\n", sc->mbuf_alloc_failed); 7698 7699 if_printf(ifp, 7700 "----------------------------" 7701 "----------------" 7702 "----------------------------\n"); 7703 } 7704 7705 7706 /****************************************************************************/ 7707 /* Prints out the hardware state through a summary of important registers, */ 7708 /* followed by a complete register dump. */ 7709 /* */ 7710 /* Returns: */ 7711 /* Nothing. */ 7712 /****************************************************************************/ 7713 static void 7714 bce_dump_hw_state(struct bce_softc *sc) 7715 { 7716 struct ifnet *ifp = &sc->arpcom.ac_if; 7717 uint32_t val1; 7718 int i; 7719 7720 if_printf(ifp, 7721 "----------------------------" 7722 " Hardware State " 7723 "----------------------------\n"); 7724 7725 if_printf(ifp, "%s - bootcode version\n", sc->bce_bc_ver); 7726 7727 val1 = REG_RD(sc, BCE_MISC_ENABLE_STATUS_BITS); 7728 if_printf(ifp, "0x%08X - (0x%06X) misc_enable_status_bits\n", 7729 val1, BCE_MISC_ENABLE_STATUS_BITS); 7730 7731 val1 = REG_RD(sc, BCE_DMA_STATUS); 7732 if_printf(ifp, "0x%08X - (0x%04X) dma_status\n", val1, BCE_DMA_STATUS); 7733 7734 val1 = REG_RD(sc, BCE_CTX_STATUS); 7735 if_printf(ifp, "0x%08X - (0x%04X) ctx_status\n", val1, BCE_CTX_STATUS); 7736 7737 val1 = REG_RD(sc, BCE_EMAC_STATUS); 7738 if_printf(ifp, "0x%08X - (0x%04X) emac_status\n", 7739 val1, BCE_EMAC_STATUS); 7740 7741 val1 = REG_RD(sc, BCE_RPM_STATUS); 7742 if_printf(ifp, "0x%08X - (0x%04X) rpm_status\n", val1, BCE_RPM_STATUS); 7743 7744 val1 = REG_RD(sc, BCE_TBDR_STATUS); 7745 if_printf(ifp, "0x%08X - (0x%04X) tbdr_status\n", 7746 val1, BCE_TBDR_STATUS); 7747 7748 val1 = REG_RD(sc, BCE_TDMA_STATUS); 7749 if_printf(ifp, "0x%08X - (0x%04X) tdma_status\n", 7750 val1, BCE_TDMA_STATUS); 7751 7752 val1 = REG_RD(sc, BCE_HC_STATUS); 7753 if_printf(ifp, "0x%08X - (0x%06X) hc_status\n", val1, BCE_HC_STATUS); 7754 7755 val1 = REG_RD_IND(sc, BCE_TXP_CPU_STATE); 7756 if_printf(ifp, "0x%08X - (0x%06X) txp_cpu_state\n", 7757 val1, BCE_TXP_CPU_STATE); 7758 7759 val1 = REG_RD_IND(sc, BCE_TPAT_CPU_STATE); 7760 if_printf(ifp, "0x%08X - (0x%06X) tpat_cpu_state\n", 7761 val1, BCE_TPAT_CPU_STATE); 7762 7763 val1 = REG_RD_IND(sc, BCE_RXP_CPU_STATE); 7764 if_printf(ifp, "0x%08X - (0x%06X) rxp_cpu_state\n", 7765 val1, BCE_RXP_CPU_STATE); 7766 7767 val1 = REG_RD_IND(sc, BCE_COM_CPU_STATE); 7768 if_printf(ifp, "0x%08X - (0x%06X) com_cpu_state\n", 7769 val1, BCE_COM_CPU_STATE); 7770 7771 val1 = REG_RD_IND(sc, BCE_MCP_CPU_STATE); 7772 if_printf(ifp, "0x%08X - (0x%06X) mcp_cpu_state\n", 7773 val1, BCE_MCP_CPU_STATE); 7774 7775 val1 = REG_RD_IND(sc, BCE_CP_CPU_STATE); 7776 if_printf(ifp, "0x%08X - (0x%06X) cp_cpu_state\n", 7777 val1, BCE_CP_CPU_STATE); 7778 7779 if_printf(ifp, 7780 "----------------------------" 7781 "----------------" 7782 "----------------------------\n"); 7783 7784 if_printf(ifp, 7785 "----------------------------" 7786 " Register Dump " 7787 "----------------------------\n"); 7788 7789 for (i = 0x400; i < 0x8000; i += 0x10) { 7790 if_printf(ifp, "0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n", i, 7791 REG_RD(sc, i), 7792 REG_RD(sc, i + 0x4), 7793 REG_RD(sc, i + 0x8), 7794 REG_RD(sc, i + 0xc)); 7795 } 7796 7797 if_printf(ifp, 7798 "----------------------------" 7799 "----------------" 7800 "----------------------------\n"); 7801 } 7802 7803 7804 /****************************************************************************/ 7805 /* Prints out the TXP state. */ 7806 /* */ 7807 /* Returns: */ 7808 /* Nothing. */ 7809 /****************************************************************************/ 7810 static void 7811 bce_dump_txp_state(struct bce_softc *sc) 7812 { 7813 struct ifnet *ifp = &sc->arpcom.ac_if; 7814 uint32_t val1; 7815 int i; 7816 7817 if_printf(ifp, 7818 "----------------------------" 7819 " TXP State " 7820 "----------------------------\n"); 7821 7822 val1 = REG_RD_IND(sc, BCE_TXP_CPU_MODE); 7823 if_printf(ifp, "0x%08X - (0x%06X) txp_cpu_mode\n", 7824 val1, BCE_TXP_CPU_MODE); 7825 7826 val1 = REG_RD_IND(sc, BCE_TXP_CPU_STATE); 7827 if_printf(ifp, "0x%08X - (0x%06X) txp_cpu_state\n", 7828 val1, BCE_TXP_CPU_STATE); 7829 7830 val1 = REG_RD_IND(sc, BCE_TXP_CPU_EVENT_MASK); 7831 if_printf(ifp, "0x%08X - (0x%06X) txp_cpu_event_mask\n", 7832 val1, BCE_TXP_CPU_EVENT_MASK); 7833 7834 if_printf(ifp, 7835 "----------------------------" 7836 " Register Dump " 7837 "----------------------------\n"); 7838 7839 for (i = BCE_TXP_CPU_MODE; i < 0x68000; i += 0x10) { 7840 /* Skip the big blank spaces */ 7841 if (i < 0x454000 && i > 0x5ffff) { 7842 if_printf(ifp, "0x%04X: " 7843 "0x%08X 0x%08X 0x%08X 0x%08X\n", i, 7844 REG_RD_IND(sc, i), 7845 REG_RD_IND(sc, i + 0x4), 7846 REG_RD_IND(sc, i + 0x8), 7847 REG_RD_IND(sc, i + 0xc)); 7848 } 7849 } 7850 7851 if_printf(ifp, 7852 "----------------------------" 7853 "----------------" 7854 "----------------------------\n"); 7855 } 7856 7857 7858 /****************************************************************************/ 7859 /* Prints out the RXP state. */ 7860 /* */ 7861 /* Returns: */ 7862 /* Nothing. */ 7863 /****************************************************************************/ 7864 static void 7865 bce_dump_rxp_state(struct bce_softc *sc) 7866 { 7867 struct ifnet *ifp = &sc->arpcom.ac_if; 7868 uint32_t val1; 7869 int i; 7870 7871 if_printf(ifp, 7872 "----------------------------" 7873 " RXP State " 7874 "----------------------------\n"); 7875 7876 val1 = REG_RD_IND(sc, BCE_RXP_CPU_MODE); 7877 if_printf(ifp, "0x%08X - (0x%06X) rxp_cpu_mode\n", 7878 val1, BCE_RXP_CPU_MODE); 7879 7880 val1 = REG_RD_IND(sc, BCE_RXP_CPU_STATE); 7881 if_printf(ifp, "0x%08X - (0x%06X) rxp_cpu_state\n", 7882 val1, BCE_RXP_CPU_STATE); 7883 7884 val1 = REG_RD_IND(sc, BCE_RXP_CPU_EVENT_MASK); 7885 if_printf(ifp, "0x%08X - (0x%06X) rxp_cpu_event_mask\n", 7886 val1, BCE_RXP_CPU_EVENT_MASK); 7887 7888 if_printf(ifp, 7889 "----------------------------" 7890 " Register Dump " 7891 "----------------------------\n"); 7892 7893 for (i = BCE_RXP_CPU_MODE; i < 0xe8fff; i += 0x10) { 7894 /* Skip the big blank sapces */ 7895 if (i < 0xc5400 && i > 0xdffff) { 7896 if_printf(ifp, "0x%04X: " 7897 "0x%08X 0x%08X 0x%08X 0x%08X\n", i, 7898 REG_RD_IND(sc, i), 7899 REG_RD_IND(sc, i + 0x4), 7900 REG_RD_IND(sc, i + 0x8), 7901 REG_RD_IND(sc, i + 0xc)); 7902 } 7903 } 7904 7905 if_printf(ifp, 7906 "----------------------------" 7907 "----------------" 7908 "----------------------------\n"); 7909 } 7910 7911 7912 /****************************************************************************/ 7913 /* Prints out the TPAT state. */ 7914 /* */ 7915 /* Returns: */ 7916 /* Nothing. */ 7917 /****************************************************************************/ 7918 static void 7919 bce_dump_tpat_state(struct bce_softc *sc) 7920 { 7921 struct ifnet *ifp = &sc->arpcom.ac_if; 7922 uint32_t val1; 7923 int i; 7924 7925 if_printf(ifp, 7926 "----------------------------" 7927 " TPAT State " 7928 "----------------------------\n"); 7929 7930 val1 = REG_RD_IND(sc, BCE_TPAT_CPU_MODE); 7931 if_printf(ifp, "0x%08X - (0x%06X) tpat_cpu_mode\n", 7932 val1, BCE_TPAT_CPU_MODE); 7933 7934 val1 = REG_RD_IND(sc, BCE_TPAT_CPU_STATE); 7935 if_printf(ifp, "0x%08X - (0x%06X) tpat_cpu_state\n", 7936 val1, BCE_TPAT_CPU_STATE); 7937 7938 val1 = REG_RD_IND(sc, BCE_TPAT_CPU_EVENT_MASK); 7939 if_printf(ifp, "0x%08X - (0x%06X) tpat_cpu_event_mask\n", 7940 val1, BCE_TPAT_CPU_EVENT_MASK); 7941 7942 if_printf(ifp, 7943 "----------------------------" 7944 " Register Dump " 7945 "----------------------------\n"); 7946 7947 for (i = BCE_TPAT_CPU_MODE; i < 0xa3fff; i += 0x10) { 7948 /* Skip the big blank spaces */ 7949 if (i < 0x854000 && i > 0x9ffff) { 7950 if_printf(ifp, "0x%04X: " 7951 "0x%08X 0x%08X 0x%08X 0x%08X\n", i, 7952 REG_RD_IND(sc, i), 7953 REG_RD_IND(sc, i + 0x4), 7954 REG_RD_IND(sc, i + 0x8), 7955 REG_RD_IND(sc, i + 0xc)); 7956 } 7957 } 7958 7959 if_printf(ifp, 7960 "----------------------------" 7961 "----------------" 7962 "----------------------------\n"); 7963 } 7964 7965 7966 /****************************************************************************/ 7967 /* Prints out the driver state and then enters the debugger. */ 7968 /* */ 7969 /* Returns: */ 7970 /* Nothing. */ 7971 /****************************************************************************/ 7972 static void 7973 bce_breakpoint(struct bce_softc *sc) 7974 { 7975 #if 0 7976 bce_freeze_controller(sc); 7977 #endif 7978 7979 bce_dump_driver_state(sc); 7980 bce_dump_status_block(sc); 7981 bce_dump_tx_chain(sc, 0, TOTAL_TX_BD(sc)); 7982 bce_dump_hw_state(sc); 7983 bce_dump_txp_state(sc); 7984 7985 #if 0 7986 bce_unfreeze_controller(sc); 7987 #endif 7988 7989 /* Call the debugger. */ 7990 breakpoint(); 7991 } 7992 7993 #endif /* BCE_DEBUG */ 7994 7995 static int 7996 bce_sysctl_tx_bds_int(SYSCTL_HANDLER_ARGS) 7997 { 7998 struct bce_softc *sc = arg1; 7999 8000 return bce_sysctl_coal_change(oidp, arg1, arg2, req, 8001 &sc->bce_tx_quick_cons_trip_int, 8002 BCE_COALMASK_TX_BDS_INT); 8003 } 8004 8005 static int 8006 bce_sysctl_tx_bds(SYSCTL_HANDLER_ARGS) 8007 { 8008 struct bce_softc *sc = arg1; 8009 8010 return bce_sysctl_coal_change(oidp, arg1, arg2, req, 8011 &sc->bce_tx_quick_cons_trip, 8012 BCE_COALMASK_TX_BDS); 8013 } 8014 8015 static int 8016 bce_sysctl_tx_ticks_int(SYSCTL_HANDLER_ARGS) 8017 { 8018 struct bce_softc *sc = arg1; 8019 8020 return bce_sysctl_coal_change(oidp, arg1, arg2, req, 8021 &sc->bce_tx_ticks_int, 8022 BCE_COALMASK_TX_TICKS_INT); 8023 } 8024 8025 static int 8026 bce_sysctl_tx_ticks(SYSCTL_HANDLER_ARGS) 8027 { 8028 struct bce_softc *sc = arg1; 8029 8030 return bce_sysctl_coal_change(oidp, arg1, arg2, req, 8031 &sc->bce_tx_ticks, 8032 BCE_COALMASK_TX_TICKS); 8033 } 8034 8035 static int 8036 bce_sysctl_rx_bds_int(SYSCTL_HANDLER_ARGS) 8037 { 8038 struct bce_softc *sc = arg1; 8039 8040 return bce_sysctl_coal_change(oidp, arg1, arg2, req, 8041 &sc->bce_rx_quick_cons_trip_int, 8042 BCE_COALMASK_RX_BDS_INT); 8043 } 8044 8045 static int 8046 bce_sysctl_rx_bds(SYSCTL_HANDLER_ARGS) 8047 { 8048 struct bce_softc *sc = arg1; 8049 8050 return bce_sysctl_coal_change(oidp, arg1, arg2, req, 8051 &sc->bce_rx_quick_cons_trip, 8052 BCE_COALMASK_RX_BDS); 8053 } 8054 8055 static int 8056 bce_sysctl_rx_ticks_int(SYSCTL_HANDLER_ARGS) 8057 { 8058 struct bce_softc *sc = arg1; 8059 8060 return bce_sysctl_coal_change(oidp, arg1, arg2, req, 8061 &sc->bce_rx_ticks_int, 8062 BCE_COALMASK_RX_TICKS_INT); 8063 } 8064 8065 static int 8066 bce_sysctl_rx_ticks(SYSCTL_HANDLER_ARGS) 8067 { 8068 struct bce_softc *sc = arg1; 8069 8070 return bce_sysctl_coal_change(oidp, arg1, arg2, req, 8071 &sc->bce_rx_ticks, 8072 BCE_COALMASK_RX_TICKS); 8073 } 8074 8075 static int 8076 bce_sysctl_coal_change(SYSCTL_HANDLER_ARGS, uint32_t *coal, 8077 uint32_t coalchg_mask) 8078 { 8079 struct bce_softc *sc = arg1; 8080 struct ifnet *ifp = &sc->arpcom.ac_if; 8081 int error = 0, v; 8082 8083 lwkt_serialize_enter(ifp->if_serializer); 8084 8085 v = *coal; 8086 error = sysctl_handle_int(oidp, &v, 0, req); 8087 if (!error && req->newptr != NULL) { 8088 if (v < 0) { 8089 error = EINVAL; 8090 } else { 8091 *coal = v; 8092 sc->bce_coalchg_mask |= coalchg_mask; 8093 } 8094 } 8095 8096 lwkt_serialize_exit(ifp->if_serializer); 8097 return error; 8098 } 8099 8100 static void 8101 bce_coal_change(struct bce_softc *sc) 8102 { 8103 struct ifnet *ifp = &sc->arpcom.ac_if; 8104 8105 ASSERT_SERIALIZED(ifp->if_serializer); 8106 8107 if ((ifp->if_flags & IFF_RUNNING) == 0) { 8108 sc->bce_coalchg_mask = 0; 8109 return; 8110 } 8111 8112 if (sc->bce_coalchg_mask & 8113 (BCE_COALMASK_TX_BDS | BCE_COALMASK_TX_BDS_INT)) { 8114 REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP, 8115 (sc->bce_tx_quick_cons_trip_int << 16) | 8116 sc->bce_tx_quick_cons_trip); 8117 if (bootverbose) { 8118 if_printf(ifp, "tx_bds %u, tx_bds_int %u\n", 8119 sc->bce_tx_quick_cons_trip, 8120 sc->bce_tx_quick_cons_trip_int); 8121 } 8122 } 8123 8124 if (sc->bce_coalchg_mask & 8125 (BCE_COALMASK_TX_TICKS | BCE_COALMASK_TX_TICKS_INT)) { 8126 REG_WR(sc, BCE_HC_TX_TICKS, 8127 (sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks); 8128 if (bootverbose) { 8129 if_printf(ifp, "tx_ticks %u, tx_ticks_int %u\n", 8130 sc->bce_tx_ticks, sc->bce_tx_ticks_int); 8131 } 8132 } 8133 8134 if (sc->bce_coalchg_mask & 8135 (BCE_COALMASK_RX_BDS | BCE_COALMASK_RX_BDS_INT)) { 8136 REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP, 8137 (sc->bce_rx_quick_cons_trip_int << 16) | 8138 sc->bce_rx_quick_cons_trip); 8139 if (bootverbose) { 8140 if_printf(ifp, "rx_bds %u, rx_bds_int %u\n", 8141 sc->bce_rx_quick_cons_trip, 8142 sc->bce_rx_quick_cons_trip_int); 8143 } 8144 } 8145 8146 if (sc->bce_coalchg_mask & 8147 (BCE_COALMASK_RX_TICKS | BCE_COALMASK_RX_TICKS_INT)) { 8148 REG_WR(sc, BCE_HC_RX_TICKS, 8149 (sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks); 8150 if (bootverbose) { 8151 if_printf(ifp, "rx_ticks %u, rx_ticks_int %u\n", 8152 sc->bce_rx_ticks, sc->bce_rx_ticks_int); 8153 } 8154 } 8155 8156 sc->bce_coalchg_mask = 0; 8157 } 8158