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