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