1c2fa353ps/*- 2ebda8d9pfg * SPDX-License-Identifier: BSD-2-Clause 3ebda8d9pfg * 48095e01davidcs * Copyright (c) 2006-2014 QLogic Corporation 5c2fa353ps * 6c2fa353ps * Redistribution and use in source and binary forms, with or without 7c2fa353ps * modification, are permitted provided that the following conditions 8c2fa353ps * are met: 9c2fa353ps * 10c2fa353ps * 1. Redistributions of source code must retain the above copyright 11c2fa353ps * notice, this list of conditions and the following disclaimer. 12c2fa353ps * 2. Redistributions in binary form must reproduce the above copyright 13c2fa353ps * notice, this list of conditions and the following disclaimer in the 14c2fa353ps * documentation and/or other materials provided with the distribution. 15c2fa353ps * 16c2fa353ps * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS' 17c2fa353ps * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18c2fa353ps * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19c2fa353ps * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20c2fa353ps * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21c2fa353ps * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22c2fa353ps * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23c2fa353ps * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24c2fa353ps * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25c2fa353ps * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 26c2fa353ps * THE POSSIBILITY OF SUCH DAMAGE. 27c2fa353ps */ 28c2fa353ps 29c2fa353ps#include <sys/cdefs.h> 30c2fa353ps__FBSDID("$FreeBSD$"); 31c2fa353ps 32c2fa353ps/* 33c2fa353ps * The following controllers are supported by this driver: 34c2fa353ps * BCM5706C A2, A3 35179a317davidch * BCM5706S A2, A3 366ab1aa7davidch * BCM5708C B1, B2 37179a317davidch * BCM5708S B1, B2 38fecec6adavidch * BCM5709C A1, C0 3950b21e3davidch * BCM5709S A1, C0 40d037577davidch * BCM5716C C0 41d037577davidch * BCM5716S C0 42c2fa353ps * 43c2fa353ps * The following controllers are not supported by this driver: 44179a317davidch * BCM5706C A0, A1 (pre-production) 45179a317davidch * BCM5706S A0, A1 (pre-production) 46179a317davidch * BCM5708C A0, B0 (pre-production) 47179a317davidch * BCM5708S A0, B0 (pre-production) 482156989davidch * BCM5709C A0 B0, B1, B2 (pre-production) 4950b21e3davidch * BCM5709S A0, B0, B1, B2 (pre-production) 50c2fa353ps */ 51c2fa353ps 52cc2c59eps#include "opt_bce.h" 53cc2c59eps 54b86044bglebius#include <sys/param.h> 55b86044bglebius#include <sys/endian.h> 56b86044bglebius#include <sys/systm.h> 57b86044bglebius#include <sys/sockio.h> 58b86044bglebius#include <sys/lock.h> 59b86044bglebius#include <sys/mbuf.h> 60b86044bglebius#include <sys/malloc.h> 61b86044bglebius#include <sys/mutex.h> 62b86044bglebius#include <sys/kernel.h> 63b86044bglebius#include <sys/module.h> 64b86044bglebius#include <sys/socket.h> 65b86044bglebius#include <sys/sysctl.h> 66b86044bglebius#include <sys/queue.h> 67b86044bglebius 68b86044bglebius#include <net/bpf.h> 69b86044bglebius#include <net/ethernet.h> 70b86044bglebius#include <net/if.h> 71b86044bglebius#include <net/if_var.h> 72b86044bglebius#include <net/if_arp.h> 73b86044bglebius#include <net/if_dl.h> 74b86044bglebius#include <net/if_media.h> 75b86044bglebius 76b86044bglebius#include <net/if_types.h> 77b86044bglebius#include <net/if_vlan_var.h> 78b86044bglebius 79b86044bglebius#include <netinet/in_systm.h> 80b86044bglebius#include <netinet/in.h> 81b86044bglebius#include <netinet/if_ether.h> 82b86044bglebius#include <netinet/ip.h> 83b86044bglebius#include <netinet/ip6.h> 84b86044bglebius#include <netinet/tcp.h> 85b86044bglebius#include <netinet/udp.h> 86b86044bglebius 87b86044bglebius#include <machine/bus.h> 88b86044bglebius#include <machine/resource.h> 89b86044bglebius#include <sys/bus.h> 90b86044bglebius#include <sys/rman.h> 91b86044bglebius 92b86044bglebius#include <dev/mii/mii.h> 93b86044bglebius#include <dev/mii/miivar.h> 94b86044bglebius#include "miidevs.h" 95b86044bglebius#include <dev/mii/brgphyreg.h> 96b86044bglebius 97b86044bglebius#include <dev/pci/pcireg.h> 98b86044bglebius#include <dev/pci/pcivar.h> 99b86044bglebius 100b86044bglebius#include "miibus_if.h" 101b86044bglebius 102c2fa353ps#include <dev/bce/if_bcereg.h> 103c2fa353ps#include <dev/bce/if_bcefw.h> 104c2fa353ps 105c2fa353ps/****************************************************************************/ 106c2fa353ps/* BCE Debug Options */ 107c2fa353ps/****************************************************************************/ 108c2fa353ps#ifdef BCE_DEBUG 109c2fa353ps u32 bce_debug = BCE_WARN; 110c2fa353ps 111c2fa353ps /* 0 = Never */ 112c2fa353ps /* 1 = 1 in 2,147,483,648 */ 113c2fa353ps /* 256 = 1 in 8,388,608 */ 114c2fa353ps /* 2048 = 1 in 1,048,576 */ 115c2fa353ps /* 65536 = 1 in 32,768 */ 116c2fa353ps /* 1048576 = 1 in 2,048 */ 117c2fa353ps /* 268435456 = 1 in 8 */ 118c2fa353ps /* 536870912 = 1 in 4 */ 119c2fa353ps /* 1073741824 = 1 in 2 */ 120c2fa353ps 121c2fa353ps /* Controls how often the l2_fhdr frame error check will fail. */ 1223b8bffcdavidch int l2fhdr_error_sim_control = 0; 123c2fa353ps 124c2fa353ps /* Controls how often the unexpected attention check will fail. */ 1253b8bffcdavidch int unexpected_attention_sim_control = 0; 126c2fa353ps 127c2fa353ps /* Controls how often to simulate an mbuf allocation failure. */ 1283b8bffcdavidch int mbuf_alloc_failed_sim_control = 0; 129c2fa353ps 130c2fa353ps /* Controls how often to simulate a DMA mapping failure. */ 1313b8bffcdavidch int dma_map_addr_failed_sim_control = 0; 132c2fa353ps 133c2fa353ps /* Controls how often to simulate a bootcode failure. */ 1343b8bffcdavidch int bootcode_running_failure_sim_control = 0; 135c2fa353ps#endif 1360f2382bdavidch 1371a7f080davidch/****************************************************************************/ 138c2fa353ps/* PCI Device ID Table */ 139c2fa353ps/* */ 140c2fa353ps/* Used by bce_probe() to identify the devices supported by this driver. */ 141c2fa353ps/****************************************************************************/ 142c2fa353ps#define BCE_DEVDESC_MAX 64 143c2fa353ps 1448dc4f9cmariusstatic const struct bce_type bce_devs[] = { 145c2fa353ps /* BCM5706C Controllers and OEM boards. */ 146c2fa353ps { BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x3101, 147c2fa353ps "HP NC370T Multifunction Gigabit Server Adapter" }, 148c2fa353ps { BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x3106, 149c2fa353ps "HP NC370i Multifunction Gigabit Server Adapter" }, 150b997fbddelphij { BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x3070, 151b531710delphij "HP NC380T PCIe DP Multifunc Gig Server Adapter" }, 152b531710delphij { BRCM_VENDORID, BRCM_DEVICEID_BCM5706, HP_VENDORID, 0x1709, 153b531710delphij "HP NC371i Multifunction Gigabit Server Adapter" }, 154c2fa353ps { BRCM_VENDORID, BRCM_DEVICEID_BCM5706, PCI_ANY_ID, PCI_ANY_ID, 1558095e01davidcs "QLogic NetXtreme II BCM5706 1000Base-T" }, 156c2fa353ps 157c2fa353ps /* BCM5706S controllers and OEM boards. */ 158c2fa353ps { BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, HP_VENDORID, 0x3102, 159c2fa353ps "HP NC370F Multifunction Gigabit Server Adapter" }, 160c2fa353ps { BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, PCI_ANY_ID, PCI_ANY_ID, 1618095e01davidcs "QLogic NetXtreme II BCM5706 1000Base-SX" }, 162c2fa353ps 163c2fa353ps /* BCM5708C controllers and OEM boards. */ 164b997fbddelphij { BRCM_VENDORID, BRCM_DEVICEID_BCM5708, HP_VENDORID, 0x7037, 165b531710delphij "HP NC373T PCIe Multifunction Gig Server Adapter" }, 166b997fbddelphij { BRCM_VENDORID, BRCM_DEVICEID_BCM5708, HP_VENDORID, 0x7038, 167b531710delphij "HP NC373i Multifunction Gigabit Server Adapter" }, 168b531710delphij { BRCM_VENDORID, BRCM_DEVICEID_BCM5708, HP_VENDORID, 0x7045, 169b531710delphij "HP NC374m PCIe Multifunction Adapter" }, 170c2fa353ps { BRCM_VENDORID, BRCM_DEVICEID_BCM5708, PCI_ANY_ID, PCI_ANY_ID, 1718095e01davidcs "QLogic NetXtreme II BCM5708 1000Base-T" }, 172c2fa353ps 173c2fa353ps /* BCM5708S controllers and OEM boards. */ 174b997fbddelphij { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, HP_VENDORID, 0x1706, 175b531710delphij "HP NC373m Multifunction Gigabit Server Adapter" }, 176b997fbddelphij { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, HP_VENDORID, 0x703b, 177b531710delphij "HP NC373i Multifunction Gigabit Server Adapter" }, 178b997fbddelphij { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, HP_VENDORID, 0x703d, 179b531710delphij "HP NC373F PCIe Multifunc Giga Server Adapter" }, 18021803eascottl { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S, PCI_ANY_ID, PCI_ANY_ID, 1818095e01davidcs "QLogic NetXtreme II BCM5708 1000Base-SX" }, 1822156989davidch 1832156989davidch /* BCM5709C controllers and OEM boards. */ 184b997fbddelphij { BRCM_VENDORID, BRCM_DEVICEID_BCM5709, HP_VENDORID, 0x7055, 185b531710delphij "HP NC382i DP Multifunction Gigabit Server Adapter" }, 186b997fbddelphij { BRCM_VENDORID, BRCM_DEVICEID_BCM5709, HP_VENDORID, 0x7059, 187b531710delphij "HP NC382T PCIe DP Multifunction Gigabit Server Adapter" }, 1882156989davidch { BRCM_VENDORID, BRCM_DEVICEID_BCM5709, PCI_ANY_ID, PCI_ANY_ID, 1898095e01davidcs "QLogic NetXtreme II BCM5709 1000Base-T" }, 1902156989davidch 1912156989davidch /* BCM5709S controllers and OEM boards. */ 192b997fbddelphij { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S, HP_VENDORID, 0x171d, 193b531710delphij "HP NC382m DP 1GbE Multifunction BL-c Adapter" }, 194b997fbddelphij { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S, HP_VENDORID, 0x7056, 195b531710delphij "HP NC382i DP Multifunction Gigabit Server Adapter" }, 1962156989davidch { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S, PCI_ANY_ID, PCI_ANY_ID, 1978095e01davidcs "QLogic NetXtreme II BCM5709 1000Base-SX" }, 1982156989davidch 1992156989davidch /* BCM5716 controllers and OEM boards. */ 2002156989davidch { BRCM_VENDORID, BRCM_DEVICEID_BCM5716, PCI_ANY_ID, PCI_ANY_ID, 2018095e01davidcs "QLogic NetXtreme II BCM5716 1000Base-T" }, 202c2fa353ps { 0, 0, 0, 0, NULL } 203c2fa353ps}; 204c2fa353ps 205c2fa353ps/****************************************************************************/ 206c2fa353ps/* Supported Flash NVRAM device data. */ 207c2fa353ps/****************************************************************************/ 2088dc4f9cmariusstatic const struct flash_spec flash_table[] = 209c2fa353ps{ 2102156989davidch#define BUFFERED_FLAGS (BCE_NV_BUFFERED | BCE_NV_TRANSLATE) 2112156989davidch#define NONBUFFERED_FLAGS (BCE_NV_WREN) 2122156989davidch 213c2fa353ps /* Slow EEPROM */ 214c2fa353ps {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400, 2152156989davidch BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, 216c2fa353ps SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, 217c2fa353ps "EEPROM - slow"}, 218c2fa353ps /* Expansion entry 0001 */ 219c2fa353ps {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406, 2202156989davidch NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 221c2fa353ps SAIFUN_FLASH_BYTE_ADDR_MASK, 0, 222c2fa353ps "Entry 0001"}, 223c2fa353ps /* Saifun SA25F010 (non-buffered flash) */ 224c2fa353ps /* strap, cfg1, & write1 need updates */ 225c2fa353ps {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406, 2262156989davidch NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 227c2fa353ps SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2, 228c2fa353ps "Non-buffered flash (128kB)"}, 229c2fa353ps /* Saifun SA25F020 (non-buffered flash) */ 230c2fa353ps /* strap, cfg1, & write1 need updates */ 231c2fa353ps {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406, 2322156989davidch NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 233c2fa353ps SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4, 234c2fa353ps "Non-buffered flash (256kB)"}, 235c2fa353ps /* Expansion entry 0100 */ 236c2fa353ps {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406, 2372156989davidch NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 238c2fa353ps SAIFUN_FLASH_BYTE_ADDR_MASK, 0, 239c2fa353ps "Entry 0100"}, 240c2fa353ps /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */ 241c2fa353ps {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406, 2422156989davidch NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE, 243c2fa353ps ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2, 244c2fa353ps "Entry 0101: ST M45PE10 (128kB non-bufferred)"}, 245c2fa353ps /* Entry 0110: ST M45PE20 (non-buffered flash)*/ 246c2fa353ps {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406, 2472156989davidch NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE, 248c2fa353ps ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4, 249c2fa353ps "Entry 0110: ST M45PE20 (256kB non-bufferred)"}, 250c2fa353ps /* Saifun SA25F005 (non-buffered flash) */ 251c2fa353ps /* strap, cfg1, & write1 need updates */ 252c2fa353ps {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406, 2532156989davidch NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 254c2fa353ps SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE, 255c2fa353ps "Non-buffered flash (64kB)"}, 256c2fa353ps /* Fast EEPROM */ 257c2fa353ps {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400, 2582156989davidch BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE, 259c2fa353ps SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE, 260c2fa353ps "EEPROM - fast"}, 261c2fa353ps /* Expansion entry 1001 */ 262c2fa353ps {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406, 2632156989davidch NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 264c2fa353ps SAIFUN_FLASH_BYTE_ADDR_MASK, 0, 265c2fa353ps "Entry 1001"}, 266c2fa353ps /* Expansion entry 1010 */ 267c2fa353ps {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406, 2682156989davidch NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 269c2fa353ps SAIFUN_FLASH_BYTE_ADDR_MASK, 0, 270c2fa353ps "Entry 1010"}, 271c2fa353ps /* ATMEL AT45DB011B (buffered flash) */ 272c2fa353ps {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400, 2732156989davidch BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, 274c2fa353ps BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE, 275c2fa353ps "Buffered flash (128kB)"}, 276c2fa353ps /* Expansion entry 1100 */ 277c2fa353ps {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406, 2782156989davidch NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 279c2fa353ps SAIFUN_FLASH_BYTE_ADDR_MASK, 0, 280c2fa353ps "Entry 1100"}, 281c2fa353ps /* Expansion entry 1101 */ 282c2fa353ps {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406, 2832156989davidch NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE, 284c2fa353ps SAIFUN_FLASH_BYTE_ADDR_MASK, 0, 285c2fa353ps "Entry 1101"}, 286c2fa353ps /* Ateml Expansion entry 1110 */ 287c2fa353ps {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400, 2882156989davidch BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, 289c2fa353ps BUFFERED_FLASH_BYTE_ADDR_MASK, 0, 290c2fa353ps "Entry 1110 (Atmel)"}, 291c2fa353ps /* ATMEL AT45DB021B (buffered flash) */ 292c2fa353ps {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400, 2932156989davidch BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE, 294c2fa353ps BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2, 295c2fa353ps "Buffered flash (256kB)"}, 296c2fa353ps}; 297c2fa353ps 2982156989davidch/* 2992156989davidch * The BCM5709 controllers transparently handle the 3002156989davidch * differences between Atmel 264 byte pages and all 3012156989davidch * flash devices which use 256 byte pages, so no 3022156989davidch * logical-to-physical mapping is required in the 3032156989davidch * driver. 3042156989davidch */ 3058dc4f9cmariusstatic const struct flash_spec flash_5709 = { 3062156989davidch .flags = BCE_NV_BUFFERED, 3072156989davidch .page_bits = BCM5709_FLASH_PAGE_BITS, 3082156989davidch .page_size = BCM5709_FLASH_PAGE_SIZE, 3092156989davidch .addr_mask = BCM5709_FLASH_BYTE_ADDR_MASK, 3102156989davidch .total_size = BUFFERED_FLASH_TOTAL_SIZE * 2, 311fecec6adavidch .name = "5709/5716 buffered flash (256kB)", 3122156989davidch}; 3132156989davidch 314c2fa353ps/****************************************************************************/ 315c2fa353ps/* FreeBSD device entry points. */ 316c2fa353ps/****************************************************************************/ 317d037577davidchstatic int bce_probe (device_t); 318d037577davidchstatic int bce_attach (device_t); 319d037577davidchstatic int bce_detach (device_t); 320d037577davidchstatic int bce_shutdown (device_t); 321c2fa353ps 322c2fa353ps/****************************************************************************/ 323c2fa353ps/* BCE Debug Data Structure Dump Routines */ 324c2fa353ps/****************************************************************************/ 325c2fa353ps#ifdef BCE_DEBUG 32693acd8bdavidchstatic u32 bce_reg_rd (struct bce_softc *, u32); 32793acd8bdavidchstatic void bce_reg_wr (struct bce_softc *, u32, u32); 32893acd8bdavidchstatic void bce_reg_wr16 (struct bce_softc *, u32, u16); 32993acd8bdavidchstatic u32 bce_ctx_rd (struct bce_softc *, u32, u32); 33093acd8bdavidchstatic void bce_dump_enet (struct bce_softc *, struct mbuf *); 33193acd8bdavidchstatic void bce_dump_mbuf (struct bce_softc *, struct mbuf *); 332179a317davidchstatic void bce_dump_tx_mbuf_chain (struct bce_softc *, u16, int); 333179a317davidchstatic void bce_dump_rx_mbuf_chain (struct bce_softc *, u16, int); 3342156989davidchstatic void bce_dump_pg_mbuf_chain (struct bce_softc *, u16, int); 33593acd8bdavidchstatic void bce_dump_txbd (struct bce_softc *, 336d037577davidch int, struct tx_bd *); 33793acd8bdavidchstatic void bce_dump_rxbd (struct bce_softc *, 338d037577davidch int, struct rx_bd *); 33993acd8bdavidchstatic void bce_dump_pgbd (struct bce_softc *, 340d037577davidch int, struct rx_bd *); 341d037577davidchstatic void bce_dump_l2fhdr (struct bce_softc *, 342d037577davidch int, struct l2_fhdr *); 34393acd8bdavidchstatic void bce_dump_ctx (struct bce_softc *, u16); 34493acd8bdavidchstatic void bce_dump_ftqs (struct bce_softc *); 345179a317davidchstatic void bce_dump_tx_chain (struct bce_softc *, u16, int); 346d037577davidchstatic void bce_dump_rx_bd_chain (struct bce_softc *, u16, int); 3472156989davidchstatic void bce_dump_pg_chain (struct bce_softc *, u16, int); 348c2fa353psstatic void bce_dump_status_block (struct bce_softc *); 349c2fa353psstatic void bce_dump_stats_block (struct bce_softc *); 350c2fa353psstatic void bce_dump_driver_state (struct bce_softc *); 351c2fa353psstatic void bce_dump_hw_state (struct bce_softc *); 35293acd8bdavidchstatic void bce_dump_shmem_state (struct bce_softc *); 353d037577davidchstatic void bce_dump_mq_regs (struct bce_softc *); 354f35e9ebdavidchstatic void bce_dump_bc_state (struct bce_softc *); 3552156989davidchstatic void bce_dump_txp_state (struct bce_softc *, int); 3562156989davidchstatic void bce_dump_rxp_state (struct bce_softc *, int); 35793acd8bdavidchstatic void bce_dump_tpat_state (struct bce_softc *, int); 3582156989davidchstatic void bce_dump_cp_state (struct bce_softc *, int); 3592156989davidchstatic void bce_dump_com_state (struct bce_softc *, int); 36093acd8bdavidchstatic void bce_dump_rv2p_state (struct bce_softc *); 36193acd8bdavidchstatic void bce_breakpoint (struct bce_softc *); 36293acd8bdavidch#endif /*BCE_DEBUG */ 363c2fa353ps 364c2fa353ps/****************************************************************************/ 365c2fa353ps/* BCE Register/Memory Access Routines */ 366c2fa353ps/****************************************************************************/ 367d037577davidchstatic u32 bce_reg_rd_ind (struct bce_softc *, u32); 368d037577davidchstatic void bce_reg_wr_ind (struct bce_softc *, u32, u32); 369d037577davidchstatic void bce_shmem_wr (struct bce_softc *, u32, u32); 370d037577davidchstatic u32 bce_shmem_rd (struct bce_softc *, u32); 371d037577davidchstatic void bce_ctx_wr (struct bce_softc *, u32, u32, u32); 372c2fa353psstatic int bce_miibus_read_reg (device_t, int, int); 373c2fa353psstatic int bce_miibus_write_reg (device_t, int, int, int); 374c2fa353psstatic void bce_miibus_statchg (device_t); 375c2fa353ps 37681421f8ambrisko#ifdef BCE_DEBUG 3776bdddc8davidchstatic int bce_sysctl_nvram_dump(SYSCTL_HANDLER_ARGS); 37881421f8ambrisko#ifdef BCE_NVRAM_WRITE_SUPPORT 3796bdddc8davidchstatic int bce_sysctl_nvram_write(SYSCTL_HANDLER_ARGS); 38081421f8ambrisko#endif 38181421f8ambrisko#endif 382c2fa353ps 383c2fa353ps/****************************************************************************/ 384c2fa353ps/* BCE NVRAM Access Routines */ 385c2fa353ps/****************************************************************************/ 386c2fa353psstatic int bce_acquire_nvram_lock (struct bce_softc *); 387c2fa353psstatic int bce_release_nvram_lock (struct bce_softc *); 38893acd8bdavidchstatic void bce_enable_nvram_access(struct bce_softc *); 38993acd8bdavidchstatic void bce_disable_nvram_access(struct bce_softc *); 390c2fa353psstatic int bce_nvram_read_dword (struct bce_softc *, u32, u8 *, u32); 39193acd8bdavidchstatic int bce_init_nvram (struct bce_softc *); 39293acd8bdavidchstatic int bce_nvram_read (struct bce_softc *, u32, u8 *, int); 39393acd8bdavidchstatic int bce_nvram_test (struct bce_softc *); 394c2fa353ps#ifdef BCE_NVRAM_WRITE_SUPPORT 395c2fa353psstatic int bce_enable_nvram_write (struct bce_softc *); 39693acd8bdavidchstatic void bce_disable_nvram_write(struct bce_softc *); 397c2fa353psstatic int bce_nvram_erase_page (struct bce_softc *, u32); 398c2fa353psstatic int bce_nvram_write_dword (struct bce_softc *, u32, u8 *, u32); 399d037577davidchstatic int bce_nvram_write (struct bce_softc *, u32, u8 *, int); 400c2fa353ps#endif 401c2fa353ps 402c2fa353ps/****************************************************************************/ 403c2fa353ps/* */ 404c2fa353ps/****************************************************************************/ 40593acd8bdavidchstatic void bce_get_rx_buffer_sizes(struct bce_softc *, int); 40693acd8bdavidchstatic void bce_get_media (struct bce_softc *); 40793acd8bdavidchstatic void bce_init_media (struct bce_softc *); 40862a2488yongaristatic u32 bce_get_rphy_link (struct bce_softc *); 40993acd8bdavidchstatic void bce_dma_map_addr (void *, bus_dma_segment_t *, int, int); 41093acd8bdavidchstatic int bce_dma_alloc (device_t); 41193acd8bdavidchstatic void bce_dma_free (struct bce_softc *); 412c2fa353psstatic void bce_release_resources (struct bce_softc *); 413c2fa353ps 414c2fa353ps/****************************************************************************/ 415c2fa353ps/* BCE Firmware Synchronization and Load */ 416c2fa353ps/****************************************************************************/ 41762a2488yongaristatic void bce_fw_cap_init (struct bce_softc *); 418d037577davidchstatic int bce_fw_sync (struct bce_softc *, u32); 419c9d284cmariusstatic void bce_load_rv2p_fw (struct bce_softc *, const u32 *, u32, 420c9d284cmarius u32); 4215724de4davidchstatic void bce_load_cpu_fw (struct bce_softc *, 422d037577davidch struct cpu_reg *, struct fw_info *); 42393acd8bdavidchstatic void bce_start_cpu (struct bce_softc *, struct cpu_reg *); 42493acd8bdavidchstatic void bce_halt_cpu (struct bce_softc *, struct cpu_reg *); 425d037577davidchstatic void bce_start_rxp_cpu (struct bce_softc *); 4262156989davidchstatic void bce_init_rxp_cpu (struct bce_softc *); 4272156989davidchstatic void bce_init_txp_cpu (struct bce_softc *); 4282156989davidchstatic void bce_init_tpat_cpu (struct bce_softc *); 429d037577davidchstatic void bce_init_cp_cpu (struct bce_softc *); 4302156989davidchstatic void bce_init_com_cpu (struct bce_softc *); 43193acd8bdavidchstatic void bce_init_cpus (struct bce_softc *); 432c2fa353ps 43393acd8bdavidchstatic void bce_print_adapter_info (struct bce_softc *); 4342156989davidchstatic void bce_probe_pci_caps (device_t, struct bce_softc *); 43593acd8bdavidchstatic void bce_stop (struct bce_softc *); 43693acd8bdavidchstatic int bce_reset (struct bce_softc *, u32); 43793acd8bdavidchstatic int bce_chipinit (struct bce_softc *); 43893acd8bdavidchstatic int bce_blockinit (struct bce_softc *); 439c2fa353ps 440c2fa353psstatic int bce_init_tx_chain (struct bce_softc *); 441179a317davidchstatic void bce_free_tx_chain (struct bce_softc *); 442179a317davidch 443910939cmariusstatic int bce_get_rx_buf (struct bce_softc *, u16, u16, u32 *); 444c2fa353psstatic int bce_init_rx_chain (struct bce_softc *); 445179a317davidchstatic void bce_fill_rx_chain (struct bce_softc *); 446c2fa353psstatic void bce_free_rx_chain (struct bce_softc *); 4472156989davidch 448910939cmariusstatic int bce_get_pg_buf (struct bce_softc *, u16, u16); 449179a317davidchstatic int bce_init_pg_chain (struct bce_softc *); 450179a317davidchstatic void bce_fill_pg_chain (struct bce_softc *); 4512156989davidchstatic void bce_free_pg_chain (struct bce_softc *); 452c2fa353ps 4535724de4davidchstatic struct mbuf *bce_tso_setup (struct bce_softc *, 454d037577davidch struct mbuf **, u16 *); 45593acd8bdavidchstatic int bce_tx_encap (struct bce_softc *, struct mbuf **); 456c2fa353psstatic void bce_start_locked (struct ifnet *); 457fe82580glebiusstatic void bce_start (struct ifnet *); 458fe82580glebiusstatic int bce_ioctl (struct ifnet *, u_long, caddr_t); 459fe82580glebiusstatic uint64_t bce_get_counter (struct ifnet *, ift_counter); 460fe82580glebiusstatic void bce_watchdog (struct bce_softc *); 461d037577davidchstatic int bce_ifmedia_upd (struct ifnet *); 4620e81d4dyongaristatic int bce_ifmedia_upd_locked (struct ifnet *); 463d037577davidchstatic void bce_ifmedia_sts (struct ifnet *, struct ifmediareq *); 46462a2488yongaristatic void bce_ifmedia_sts_rphy (struct bce_softc *, struct ifmediareq *); 465d037577davidchstatic void bce_init_locked (struct bce_softc *); 46693acd8bdavidchstatic void bce_init (void *); 467788fd40davidchstatic void bce_mgmt_init_locked (struct bce_softc *sc); 468c2fa353ps 46993acd8bdavidchstatic int bce_init_ctx (struct bce_softc *); 470c2fa353psstatic void bce_get_mac_addr (struct bce_softc *); 471c2fa353psstatic void bce_set_mac_addr (struct bce_softc *); 47293acd8bdavidchstatic void bce_phy_intr (struct bce_softc *); 473d037577davidchstatic inline u16 bce_get_hw_rx_cons (struct bce_softc *); 474d037577davidchstatic void bce_rx_intr (struct bce_softc *); 475d037577davidchstatic void bce_tx_intr (struct bce_softc *); 476c2fa353psstatic void bce_disable_intr (struct bce_softc *); 477d037577davidchstatic void bce_enable_intr (struct bce_softc *, int); 4782156989davidch 47993acd8bdavidchstatic void bce_intr (void *); 480d037577davidchstatic void bce_set_rx_mode (struct bce_softc *); 481c2fa353psstatic void bce_stats_update (struct bce_softc *); 48293acd8bdavidchstatic void bce_tick (void *); 48393acd8bdavidchstatic void bce_pulse (void *); 484d037577davidchstatic void bce_add_sysctls (struct bce_softc *); 485c2fa353ps 486c2fa353ps/****************************************************************************/ 487c2fa353ps/* FreeBSD device dispatch table. */ 488c2fa353ps/****************************************************************************/ 489c2fa353psstatic device_method_t bce_methods[] = { 490179a317davidch /* Device interface (device_if.h) */ 491c2fa353ps DEVMETHOD(device_probe, bce_probe), 492c2fa353ps DEVMETHOD(device_attach, bce_attach), 493c2fa353ps DEVMETHOD(device_detach, bce_detach), 494c2fa353ps DEVMETHOD(device_shutdown, bce_shutdown), 4950f2382bdavidch/* Supported by device interface but not used here. */ 496179a317davidch/* DEVMETHOD(device_identify, bce_identify), */ 497179a317davidch/* DEVMETHOD(device_suspend, bce_suspend), */ 498179a317davidch/* DEVMETHOD(device_resume, bce_resume), */ 499179a317davidch/* DEVMETHOD(device_quiesce, bce_quiesce), */ 500c2fa353ps 501179a317davidch /* MII interface (miibus_if.h) */ 502c2fa353ps DEVMETHOD(miibus_readreg, bce_miibus_read_reg), 503c2fa353ps DEVMETHOD(miibus_writereg, bce_miibus_write_reg), 504c2fa353ps DEVMETHOD(miibus_statchg, bce_miibus_statchg), 5050f2382bdavidch/* Supported by MII interface but not used here. */ 506179a317davidch/* DEVMETHOD(miibus_linkchg, bce_miibus_linkchg), */ 507179a317davidch/* DEVMETHOD(miibus_mediainit, bce_miibus_mediainit), */ 508c2fa353ps 50917e14c6marius DEVMETHOD_END 510c2fa353ps}; 511c2fa353ps 512c2fa353psstatic driver_t bce_driver = { 513c2fa353ps "bce", 514c2fa353ps bce_methods, 515c2fa353ps sizeof(struct bce_softc) 516c2fa353ps}; 517c2fa353ps 518c2fa353psstatic devclass_t bce_devclass; 519c2fa353ps 520c2fa353psMODULE_DEPEND(bce, pci, 1, 1, 1); 521c2fa353psMODULE_DEPEND(bce, ether, 1, 1, 1); 522c2fa353psMODULE_DEPEND(bce, miibus, 1, 1, 1); 523c2fa353ps 5248dc4f9cmariusDRIVER_MODULE(bce, pci, bce_driver, bce_devclass, NULL, NULL); 5258dc4f9cmariusDRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, NULL, NULL); 526b0ccb12impMODULE_PNP_INFO("U16:vendor;U16:device;U16:#;U16:#;D:#", pci, bce, 5278efc2b3imp bce_devs, nitems(bce_devs) - 1); 528d5a0460davidch 5290dfe831davidch/****************************************************************************/ 5300dfe831davidch/* Tunable device values */ 5310dfe831davidch/****************************************************************************/ 532ad355b0kaktusstatic SYSCTL_NODE(_hw, OID_AUTO, bce, CTLFLAG_RD | CTLFLAG_MPSAFE, 0, 533ad355b0kaktus "bce driver parameters"); 534179a317davidch 535d5a0460davidch/* Allowable values are TRUE or FALSE */ 53693acd8bdavidchstatic int bce_verbose = TRUE; 53793acd8bdavidchSYSCTL_INT(_hw_bce, OID_AUTO, verbose, CTLFLAG_RDTUN, &bce_verbose, 0, 53893acd8bdavidch "Verbose output enable/disable"); 53993acd8bdavidch 54093acd8bdavidch/* Allowable values are TRUE or FALSE */ 5412156989davidchstatic int bce_tso_enable = TRUE; 5428045b08mdfSYSCTL_INT(_hw_bce, OID_AUTO, tso_enable, CTLFLAG_RDTUN, &bce_tso_enable, 0, 54393acd8bdavidch "TSO Enable/Disable"); 544179a317davidch 5452156989davidch/* Allowable values are 0 (IRQ), 1 (MSI/IRQ), and 2 (MSI-X/MSI/IRQ) */ 5462156989davidch/* ToDo: Add MSI-X support. */ 5472156989davidchstatic int bce_msi_enable = 1; 5488045b08mdfSYSCTL_INT(_hw_bce, OID_AUTO, msi_enable, CTLFLAG_RDTUN, &bce_msi_enable, 0, 54993acd8bdavidch "MSI-X|MSI|INTx selector"); 55093acd8bdavidch 55193acd8bdavidch/* Allowable values are 1, 2, 4, 8. */ 55293acd8bdavidchstatic int bce_rx_pages = DEFAULT_RX_PAGES; 55393acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, rx_pages, CTLFLAG_RDTUN, &bce_rx_pages, 0, 55493acd8bdavidch "Receive buffer descriptor pages (1 page = 255 buffer descriptors)"); 55593acd8bdavidch 55693acd8bdavidch/* Allowable values are 1, 2, 4, 8. */ 55793acd8bdavidchstatic int bce_tx_pages = DEFAULT_TX_PAGES; 55893acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, tx_pages, CTLFLAG_RDTUN, &bce_tx_pages, 0, 55993acd8bdavidch "Transmit buffer descriptor pages (1 page = 255 buffer descriptors)"); 56093acd8bdavidch 56193acd8bdavidch/* Allowable values are TRUE or FALSE. */ 56293acd8bdavidchstatic int bce_hdr_split = TRUE; 56393acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, hdr_split, CTLFLAG_RDTUN, &bce_hdr_split, 0, 56493acd8bdavidch "Frame header/payload splitting Enable/Disable"); 56593acd8bdavidch 56693acd8bdavidch/* Allowable values are TRUE or FALSE. */ 56793acd8bdavidchstatic int bce_strict_rx_mtu = FALSE; 568680cd1fdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, strict_rx_mtu, CTLFLAG_RDTUN, 56993acd8bdavidch &bce_strict_rx_mtu, 0, 57093acd8bdavidch "Enable/Disable strict RX frame size checking"); 57193acd8bdavidch 57293acd8bdavidch/* Allowable values are 0 ... 100 */ 57393acd8bdavidch#ifdef BCE_DEBUG 57493acd8bdavidch/* Generate 1 interrupt for every transmit completion. */ 57593acd8bdavidchstatic int bce_tx_quick_cons_trip_int = 1; 57693acd8bdavidch#else 57793acd8bdavidch/* Generate 1 interrupt for every 20 transmit completions. */ 57893acd8bdavidchstatic int bce_tx_quick_cons_trip_int = DEFAULT_TX_QUICK_CONS_TRIP_INT; 57993acd8bdavidch#endif 58093acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, tx_quick_cons_trip_int, CTLFLAG_RDTUN, 58193acd8bdavidch &bce_tx_quick_cons_trip_int, 0, 58293acd8bdavidch "Transmit BD trip point during interrupts"); 5830f2382bdavidch 58493acd8bdavidch/* Allowable values are 0 ... 100 */ 58593acd8bdavidch/* Generate 1 interrupt for every transmit completion. */ 58693acd8bdavidch#ifdef BCE_DEBUG 58793acd8bdavidchstatic int bce_tx_quick_cons_trip = 1; 58893acd8bdavidch#else 58993acd8bdavidch/* Generate 1 interrupt for every 20 transmit completions. */ 59093acd8bdavidchstatic int bce_tx_quick_cons_trip = DEFAULT_TX_QUICK_CONS_TRIP; 59193acd8bdavidch#endif 59293acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, tx_quick_cons_trip, CTLFLAG_RDTUN, 59393acd8bdavidch &bce_tx_quick_cons_trip, 0, 59493acd8bdavidch "Transmit BD trip point"); 59593acd8bdavidch 59693acd8bdavidch/* Allowable values are 0 ... 100 */ 59793acd8bdavidch#ifdef BCE_DEBUG 59893acd8bdavidch/* Generate an interrupt if 0us have elapsed since the last TX completion. */ 59993acd8bdavidchstatic int bce_tx_ticks_int = 0; 60093acd8bdavidch#else 60193acd8bdavidch/* Generate an interrupt if 80us have elapsed since the last TX completion. */ 60293acd8bdavidchstatic int bce_tx_ticks_int = DEFAULT_TX_TICKS_INT; 60393acd8bdavidch#endif 60493acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, tx_ticks_int, CTLFLAG_RDTUN, 60593acd8bdavidch &bce_tx_ticks_int, 0, "Transmit ticks count during interrupt"); 60693acd8bdavidch 60793acd8bdavidch/* Allowable values are 0 ... 100 */ 60893acd8bdavidch#ifdef BCE_DEBUG 60993acd8bdavidch/* Generate an interrupt if 0us have elapsed since the last TX completion. */ 61093acd8bdavidchstatic int bce_tx_ticks = 0; 61193acd8bdavidch#else 61293acd8bdavidch/* Generate an interrupt if 80us have elapsed since the last TX completion. */ 61393acd8bdavidchstatic int bce_tx_ticks = DEFAULT_TX_TICKS; 61493acd8bdavidch#endif 61593acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, tx_ticks, CTLFLAG_RDTUN, 61693acd8bdavidch &bce_tx_ticks, 0, "Transmit ticks count"); 61793acd8bdavidch 61893acd8bdavidch/* Allowable values are 1 ... 100 */ 61993acd8bdavidch#ifdef BCE_DEBUG 62093acd8bdavidch/* Generate 1 interrupt for every received frame. */ 62193acd8bdavidchstatic int bce_rx_quick_cons_trip_int = 1; 62293acd8bdavidch#else 62393acd8bdavidch/* Generate 1 interrupt for every 6 received frames. */ 62493acd8bdavidchstatic int bce_rx_quick_cons_trip_int = DEFAULT_RX_QUICK_CONS_TRIP_INT; 62593acd8bdavidch#endif 62693acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, rx_quick_cons_trip_int, CTLFLAG_RDTUN, 62793acd8bdavidch &bce_rx_quick_cons_trip_int, 0, 62893acd8bdavidch "Receive BD trip point duirng interrupts"); 62993acd8bdavidch 63093acd8bdavidch/* Allowable values are 1 ... 100 */ 63193acd8bdavidch#ifdef BCE_DEBUG 63293acd8bdavidch/* Generate 1 interrupt for every received frame. */ 63393acd8bdavidchstatic int bce_rx_quick_cons_trip = 1; 63493acd8bdavidch#else 63593acd8bdavidch/* Generate 1 interrupt for every 6 received frames. */ 63693acd8bdavidchstatic int bce_rx_quick_cons_trip = DEFAULT_RX_QUICK_CONS_TRIP; 63793acd8bdavidch#endif 63893acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, rx_quick_cons_trip, CTLFLAG_RDTUN, 63993acd8bdavidch &bce_rx_quick_cons_trip, 0, 64093acd8bdavidch "Receive BD trip point"); 64193acd8bdavidch 64293acd8bdavidch/* Allowable values are 0 ... 100 */ 64393acd8bdavidch#ifdef BCE_DEBUG 64493acd8bdavidch/* Generate an int. if 0us have elapsed since the last received frame. */ 64593acd8bdavidchstatic int bce_rx_ticks_int = 0; 64693acd8bdavidch#else 64793acd8bdavidch/* Generate an int. if 18us have elapsed since the last received frame. */ 64893acd8bdavidchstatic int bce_rx_ticks_int = DEFAULT_RX_TICKS_INT; 64993acd8bdavidch#endif 65093acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, rx_ticks_int, CTLFLAG_RDTUN, 65193acd8bdavidch &bce_rx_ticks_int, 0, "Receive ticks count during interrupt"); 65293acd8bdavidch 65393acd8bdavidch/* Allowable values are 0 ... 100 */ 65493acd8bdavidch#ifdef BCE_DEBUG 65593acd8bdavidch/* Generate an int. if 0us have elapsed since the last received frame. */ 65693acd8bdavidchstatic int bce_rx_ticks = 0; 65793acd8bdavidch#else 65893acd8bdavidch/* Generate an int. if 18us have elapsed since the last received frame. */ 65993acd8bdavidchstatic int bce_rx_ticks = DEFAULT_RX_TICKS; 66093acd8bdavidch#endif 66193acd8bdavidchSYSCTL_UINT(_hw_bce, OID_AUTO, rx_ticks, CTLFLAG_RDTUN, 66293acd8bdavidch &bce_rx_ticks, 0, "Receive ticks count"); 663d5a0460davidch 664c2fa353ps/****************************************************************************/ 665c2fa353ps/* Device probe function. */ 666c2fa353ps/* */ 667c2fa353ps/* Compares the device to the driver's list of supported devices and */ 668c2fa353ps/* reports back to the OS whether this is the right driver for the device. */ 669c2fa353ps/* */ 670c2fa353ps/* Returns: */ 671c2fa353ps/* BUS_PROBE_DEFAULT on success, positive value on failure. */ 672c2fa353ps/****************************************************************************/ 673c2fa353psstatic int 674c2fa353psbce_probe(device_t dev) 675c2fa353ps{ 6768dc4f9cmarius const struct bce_type *t; 677c2fa353ps struct bce_softc *sc; 678c2fa353ps char *descbuf; 679c2fa353ps u16 vid = 0, did = 0, svid = 0, sdid = 0; 680c2fa353ps 681c2fa353ps t = bce_devs; 682c2fa353ps 683c2fa353ps sc = device_get_softc(dev); 684c2fa353ps sc->bce_unit = device_get_unit(dev); 685c2fa353ps sc->bce_dev = dev; 686c2fa353ps 687c2fa353ps /* Get the data for the device to be probed. */ 688c2fa353ps vid = pci_get_vendor(dev); 689c2fa353ps did = pci_get_device(dev); 690c2fa353ps svid = pci_get_subvendor(dev); 691c2fa353ps sdid = pci_get_subdevice(dev); 692c2fa353ps 6932156989davidch DBPRINT(sc, BCE_EXTREME_LOAD, 694d037577davidch "%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, " 695d037577davidch "SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid); 696c2fa353ps 697c2fa353ps /* Look through the list of known devices for a match. */ 698c2fa353ps while(t->bce_name != NULL) { 6992156989davidch if ((vid == t->bce_vid) && (did == t->bce_did) && 700d037577davidch ((svid == t->bce_svid) || (t->bce_svid == PCI_ANY_ID)) && 701d037577davidch ((sdid == t->bce_sdid) || (t->bce_sdid == PCI_ANY_ID))) { 702c2fa353ps descbuf = malloc(BCE_DEVDESC_MAX, M_TEMP, M_NOWAIT); 703c2fa353ps 704c2fa353ps if (descbuf == NULL) 705c2fa353ps return(ENOMEM); 706c2fa353ps 707c2fa353ps /* Print out the device identity. */ 7082156989davidch snprintf(descbuf, BCE_DEVDESC_MAX, "%s (%c%d)", 7095724de4davidch t->bce_name, (((pci_read_config(dev, 710d037577davidch PCIR_REVID, 4) & 0xf0) >> 4) + 'A'), 7116ab1aa7davidch (pci_read_config(dev, PCIR_REVID, 4) & 0xf)); 712c2fa353ps 713c2fa353ps device_set_desc_copy(dev, descbuf); 714c2fa353ps free(descbuf, M_TEMP); 715c2fa353ps return(BUS_PROBE_DEFAULT); 716c2fa353ps } 717c2fa353ps t++; 718c2fa353ps } 719c2fa353ps 720c2fa353ps return(ENXIO); 721c2fa353ps} 722c2fa353ps 723c2fa353ps/****************************************************************************/ 7242156989davidch/* PCI Capabilities Probe Function. */ 7252156989davidch/* */ 7262156989davidch/* Walks the PCI capabiites list for the device to find what features are */ 7272156989davidch/* supported. */ 7282156989davidch/* */ 7292156989davidch/* Returns: */ 7302156989davidch/* None. */ 7312156989davidch/****************************************************************************/ 7322156989davidchstatic void 7332156989davidchbce_print_adapter_info(struct bce_softc *sc) 7342156989davidch{ 7355724de4davidch int i = 0; 736daf61e7davidch 7372156989davidch DBENTER(BCE_VERBOSE_LOAD); 7382156989davidch 73993acd8bdavidch if (bce_verbose || bootverbose) { 7405724de4davidch BCE_PRINTF("ASIC (0x%08X); ", sc->bce_chipid); 7415724de4davidch printf("Rev (%c%d); ", ((BCE_CHIP_ID(sc) & 0xf000) >> 7425724de4davidch 12) + 'A', ((BCE_CHIP_ID(sc) & 0x0ff0) >> 4)); 7435724de4davidch 7445724de4davidch /* Bus info. */ 7455724de4davidch if (sc->bce_flags & BCE_PCIE_FLAG) { 7465724de4davidch printf("Bus (PCIe x%d, ", sc->link_width); 7475724de4davidch switch (sc->link_speed) { 7485724de4davidch case 1: printf("2.5Gbps); "); break; 7495724de4davidch case 2: printf("5Gbps); "); break; 7505724de4davidch default: printf("Unknown link speed); "); 7515724de4davidch } 7525724de4davidch } else { 7535724de4davidch printf("Bus (PCI%s, %s, %dMHz); ", 7545724de4davidch ((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""), 7555724de4davidch ((sc->bce_flags & BCE_PCI_32BIT_FLAG) ? 7565724de4davidch "32-bit" : "64-bit"), sc->bus_speed_mhz); 7572156989davidch } 7582156989davidch 7595724de4davidch /* Firmware version and device features. */ 76093acd8bdavidch printf("B/C (%s); Bufs (RX:%d;TX:%d;PG:%d); Flags (", 76193acd8bdavidch sc->bce_bc_ver, sc->rx_pages, sc->tx_pages, 76293acd8bdavidch (bce_hdr_split == TRUE ? sc->pg_pages: 0)); 763daf61e7davidch 76493acd8bdavidch if (bce_hdr_split == TRUE) { 76593acd8bdavidch printf("SPLT"); 76693acd8bdavidch i++; 76793acd8bdavidch } 768569289cdavidch 7695724de4davidch if (sc->bce_flags & BCE_USING_MSI_FLAG) { 7705724de4davidch if (i > 0) printf("|"); 7715724de4davidch printf("MSI"); i++; 7725724de4davidch } 773daf61e7davidch 7745724de4davidch if (sc->bce_flags & BCE_USING_MSIX_FLAG) { 7755724de4davidch if (i > 0) printf("|"); 7765724de4davidch printf("MSI-X"); i++; 7775724de4davidch } 778daf61e7davidch 7795724de4davidch if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) { 7805724de4davidch if (i > 0) printf("|"); 7815724de4davidch printf("2.5G"); i++; 7825724de4davidch } 783daf61e7davidch 78462a2488yongari if (sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) { 78562a2488yongari if (i > 0) printf("|"); 78662a2488yongari printf("Remote PHY(%s)", 78762a2488yongari sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG ? 78862a2488yongari "FIBER" : "TP"); i++; 78962a2488yongari } 79062a2488yongari 7915724de4davidch if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) { 7925724de4davidch if (i > 0) printf("|"); 7935724de4davidch printf("MFW); MFW (%s)\n", sc->bce_mfw_ver); 7945724de4davidch } else { 7955724de4davidch printf(")\n"); 7965724de4davidch } 79793acd8bdavidch 79893acd8bdavidch printf("Coal (RX:%d,%d,%d,%d; TX:%d,%d,%d,%d)\n", 79993acd8bdavidch sc->bce_rx_quick_cons_trip_int, 80093acd8bdavidch sc->bce_rx_quick_cons_trip, 80193acd8bdavidch sc->bce_rx_ticks_int, 80293acd8bdavidch sc->bce_rx_ticks, 80393acd8bdavidch sc->bce_tx_quick_cons_trip_int, 80493acd8bdavidch sc->bce_tx_quick_cons_trip, 80593acd8bdavidch sc->bce_tx_ticks_int, 80693acd8bdavidch sc->bce_tx_ticks); 807d037577davidch } 8082156989davidch 8095297261phk DBEXIT(BCE_VERBOSE_LOAD); 8102156989davidch} 8112156989davidch 8122156989davidch/****************************************************************************/ 8132156989davidch/* PCI Capabilities Probe Function. */ 8142156989davidch/* */ 8152156989davidch/* Walks the PCI capabiites list for the device to find what features are */ 8162156989davidch/* supported. */ 8172156989davidch/* */ 8182156989davidch/* Returns: */ 8192156989davidch/* None. */ 8202156989davidch/****************************************************************************/ 8212156989davidchstatic void 8222156989davidchbce_probe_pci_caps(device_t dev, struct bce_softc *sc) 8232156989davidch{ 8242156989davidch u32 reg; 8252156989davidch 8262156989davidch DBENTER(BCE_VERBOSE_LOAD); 8272156989davidch 8282156989davidch /* Check if PCI-X capability is enabled. */ 82900c3c01jhb if (pci_find_cap(dev, PCIY_PCIX, ®) == 0) { 8302156989davidch if (reg != 0) 8312156989davidch sc->bce_cap_flags |= BCE_PCIX_CAPABLE_FLAG; 8322156989davidch } 8332156989davidch 8342156989davidch /* Check if PCIe capability is enabled. */ 83500c3c01jhb if (pci_find_cap(dev, PCIY_EXPRESS, ®) == 0) { 8362156989davidch if (reg != 0) { 8372156989davidch u16 link_status = pci_read_config(dev, reg + 0x12, 2); 838d037577davidch DBPRINT(sc, BCE_INFO_LOAD, "PCIe link_status = " 839d037577davidch "0x%08X\n", link_status); 8402156989davidch sc->link_speed = link_status & 0xf; 8412156989davidch sc->link_width = (link_status >> 4) & 0x3f; 8422156989davidch sc->bce_cap_flags |= BCE_PCIE_CAPABLE_FLAG; 8432156989davidch sc->bce_flags |= BCE_PCIE_FLAG; 8442156989davidch } 8452156989davidch } 8462156989davidch 8472156989