The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/bce/if_bce.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2006-2014 QLogic Corporation
    3  *
    4  * Redistribution and use in source and binary forms, with or without
    5  * modification, are permitted provided that the following conditions
    6  * are met:
    7  *
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
   15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
   18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   24  * THE POSSIBILITY OF SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD: releng/11.0/sys/dev/bce/if_bce.c 298955 2016-05-03 03:41:25Z pfg $");
   29 
   30 /*
   31  * The following controllers are supported by this driver:
   32  *   BCM5706C A2, A3
   33  *   BCM5706S A2, A3
   34  *   BCM5708C B1, B2
   35  *   BCM5708S B1, B2
   36  *   BCM5709C A1, C0
   37  *   BCM5709S A1, C0
   38  *   BCM5716C C0
   39  *   BCM5716S C0
   40  *
   41  * The following controllers are not supported by this driver:
   42  *   BCM5706C A0, A1 (pre-production)
   43  *   BCM5706S A0, A1 (pre-production)
   44  *   BCM5708C A0, B0 (pre-production)
   45  *   BCM5708S A0, B0 (pre-production)
   46  *   BCM5709C A0  B0, B1, B2 (pre-production)
   47  *   BCM5709S A0, B0, B1, B2 (pre-production)
   48  */
   49 
   50 #include "opt_bce.h"
   51 
   52 #include <sys/param.h>
   53 #include <sys/endian.h>
   54 #include <sys/systm.h>
   55 #include <sys/sockio.h>
   56 #include <sys/lock.h>
   57 #include <sys/mbuf.h>
   58 #include <sys/malloc.h>
   59 #include <sys/mutex.h>
   60 #include <sys/kernel.h>
   61 #include <sys/module.h>
   62 #include <sys/socket.h>
   63 #include <sys/sysctl.h>
   64 #include <sys/queue.h>
   65 
   66 #include <net/bpf.h>
   67 #include <net/ethernet.h>
   68 #include <net/if.h>
   69 #include <net/if_var.h>
   70 #include <net/if_arp.h>
   71 #include <net/if_dl.h>
   72 #include <net/if_media.h>
   73 
   74 #include <net/if_types.h>
   75 #include <net/if_vlan_var.h>
   76 
   77 #include <netinet/in_systm.h>
   78 #include <netinet/in.h>
   79 #include <netinet/if_ether.h>
   80 #include <netinet/ip.h>
   81 #include <netinet/ip6.h>
   82 #include <netinet/tcp.h>
   83 #include <netinet/udp.h>
   84 
   85 #include <machine/bus.h>
   86 #include <machine/resource.h>
   87 #include <sys/bus.h>
   88 #include <sys/rman.h>
   89 
   90 #include <dev/mii/mii.h>
   91 #include <dev/mii/miivar.h>
   92 #include "miidevs.h"
   93 #include <dev/mii/brgphyreg.h>
   94 
   95 #include <dev/pci/pcireg.h>
   96 #include <dev/pci/pcivar.h>
   97 
   98 #include "miibus_if.h"
   99 
  100 #include <dev/bce/if_bcereg.h>
  101 #include <dev/bce/if_bcefw.h>
  102 
  103 /****************************************************************************/
  104 /* BCE Debug Options                                                        */
  105 /****************************************************************************/
  106 #ifdef BCE_DEBUG
  107         u32 bce_debug = BCE_WARN;
  108 
  109         /*          0 = Never              */
  110         /*          1 = 1 in 2,147,483,648 */
  111         /*        256 = 1 in     8,388,608 */
  112         /*       2048 = 1 in     1,048,576 */
  113         /*      65536 = 1 in        32,768 */
  114         /*    1048576 = 1 in         2,048 */
  115         /*  268435456 = 1 in             8 */
  116         /*  536870912 = 1 in             4 */
  117         /* 1073741824 = 1 in             2 */
  118 
  119         /* Controls how often the l2_fhdr frame error check will fail. */
  120         int l2fhdr_error_sim_control = 0;
  121 
  122         /* Controls how often the unexpected attention check will fail. */
  123         int unexpected_attention_sim_control = 0;
  124 
  125         /* Controls how often to simulate an mbuf allocation failure. */
  126         int mbuf_alloc_failed_sim_control = 0;
  127 
  128         /* Controls how often to simulate a DMA mapping failure. */
  129         int dma_map_addr_failed_sim_control = 0;
  130 
  131         /* Controls how often to simulate a bootcode failure. */
  132         int bootcode_running_failure_sim_control = 0;
  133 #endif
  134 
  135 /****************************************************************************/
  136 /* PCI Device ID Table                                                      */
  137 /*                                                                          */
  138 /* Used by bce_probe() to identify the devices supported by this driver.    */
  139 /****************************************************************************/
  140 #define BCE_DEVDESC_MAX         64
  141 
  142 static const struct bce_type bce_devs[] = {
  143         /* BCM5706C Controllers and OEM boards. */
  144         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3101,
  145                 "HP NC370T Multifunction Gigabit Server Adapter" },
  146         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3106,
  147                 "HP NC370i Multifunction Gigabit Server Adapter" },
  148         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x3070,
  149                 "HP NC380T PCIe DP Multifunc Gig Server Adapter" },
  150         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  HP_VENDORID, 0x1709,
  151                 "HP NC371i Multifunction Gigabit Server Adapter" },
  152         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706,  PCI_ANY_ID,  PCI_ANY_ID,
  153                 "QLogic NetXtreme II BCM5706 1000Base-T" },
  154 
  155         /* BCM5706S controllers and OEM boards. */
  156         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, HP_VENDORID, 0x3102,
  157                 "HP NC370F Multifunction Gigabit Server Adapter" },
  158         { BRCM_VENDORID, BRCM_DEVICEID_BCM5706S, PCI_ANY_ID,  PCI_ANY_ID,
  159                 "QLogic NetXtreme II BCM5706 1000Base-SX" },
  160 
  161         /* BCM5708C controllers and OEM boards. */
  162         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7037,
  163                 "HP NC373T PCIe Multifunction Gig Server Adapter" },
  164         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7038,
  165                 "HP NC373i Multifunction Gigabit Server Adapter" },
  166         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  HP_VENDORID, 0x7045,
  167                 "HP NC374m PCIe Multifunction Adapter" },
  168         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708,  PCI_ANY_ID,  PCI_ANY_ID,
  169                 "QLogic NetXtreme II BCM5708 1000Base-T" },
  170 
  171         /* BCM5708S controllers and OEM boards. */
  172         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x1706,
  173                 "HP NC373m Multifunction Gigabit Server Adapter" },
  174         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703b,
  175                 "HP NC373i Multifunction Gigabit Server Adapter" },
  176         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  HP_VENDORID, 0x703d,
  177                 "HP NC373F PCIe Multifunc Giga Server Adapter" },
  178         { BRCM_VENDORID, BRCM_DEVICEID_BCM5708S,  PCI_ANY_ID,  PCI_ANY_ID,
  179                 "QLogic NetXtreme II BCM5708 1000Base-SX" },
  180 
  181         /* BCM5709C controllers and OEM boards. */
  182         { BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7055,
  183                 "HP NC382i DP Multifunction Gigabit Server Adapter" },
  184         { BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  HP_VENDORID, 0x7059,
  185                 "HP NC382T PCIe DP Multifunction Gigabit Server Adapter" },
  186         { BRCM_VENDORID, BRCM_DEVICEID_BCM5709,  PCI_ANY_ID,  PCI_ANY_ID,
  187                 "QLogic NetXtreme II BCM5709 1000Base-T" },
  188 
  189         /* BCM5709S controllers and OEM boards. */
  190         { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x171d,
  191                 "HP NC382m DP 1GbE Multifunction BL-c Adapter" },
  192         { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  HP_VENDORID, 0x7056,
  193                 "HP NC382i DP Multifunction Gigabit Server Adapter" },
  194         { BRCM_VENDORID, BRCM_DEVICEID_BCM5709S,  PCI_ANY_ID,  PCI_ANY_ID,
  195                 "QLogic NetXtreme II BCM5709 1000Base-SX" },
  196 
  197         /* BCM5716 controllers and OEM boards. */
  198         { BRCM_VENDORID, BRCM_DEVICEID_BCM5716,  PCI_ANY_ID,  PCI_ANY_ID,
  199                 "QLogic NetXtreme II BCM5716 1000Base-T" },
  200 
  201         { 0, 0, 0, 0, NULL }
  202 };
  203 
  204 
  205 /****************************************************************************/
  206 /* Supported Flash NVRAM device data.                                       */
  207 /****************************************************************************/
  208 static const struct flash_spec flash_table[] =
  209 {
  210 #define BUFFERED_FLAGS          (BCE_NV_BUFFERED | BCE_NV_TRANSLATE)
  211 #define NONBUFFERED_FLAGS       (BCE_NV_WREN)
  212 
  213         /* Slow EEPROM */
  214         {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
  215          BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
  216          SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
  217          "EEPROM - slow"},
  218         /* Expansion entry 0001 */
  219         {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
  220          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  221          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
  222          "Entry 0001"},
  223         /* Saifun SA25F010 (non-buffered flash) */
  224         /* strap, cfg1, & write1 need updates */
  225         {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
  226          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  227          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
  228          "Non-buffered flash (128kB)"},
  229         /* Saifun SA25F020 (non-buffered flash) */
  230         /* strap, cfg1, & write1 need updates */
  231         {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
  232          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  233          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
  234          "Non-buffered flash (256kB)"},
  235         /* Expansion entry 0100 */
  236         {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
  237          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  238          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
  239          "Entry 0100"},
  240         /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
  241         {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
  242          NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
  243          ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
  244          "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
  245         /* Entry 0110: ST M45PE20 (non-buffered flash)*/
  246         {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
  247          NONBUFFERED_FLAGS, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
  248          ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
  249          "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
  250         /* Saifun SA25F005 (non-buffered flash) */
  251         /* strap, cfg1, & write1 need updates */
  252         {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
  253          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  254          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
  255          "Non-buffered flash (64kB)"},
  256         /* Fast EEPROM */
  257         {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
  258          BUFFERED_FLAGS, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
  259          SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
  260          "EEPROM - fast"},
  261         /* Expansion entry 1001 */
  262         {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
  263          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  264          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
  265          "Entry 1001"},
  266         /* Expansion entry 1010 */
  267         {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
  268          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  269          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
  270          "Entry 1010"},
  271         /* ATMEL AT45DB011B (buffered flash) */
  272         {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
  273          BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
  274          BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
  275          "Buffered flash (128kB)"},
  276         /* Expansion entry 1100 */
  277         {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
  278          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  279          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
  280          "Entry 1100"},
  281         /* Expansion entry 1101 */
  282         {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
  283          NONBUFFERED_FLAGS, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  284          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
  285          "Entry 1101"},
  286         /* Ateml Expansion entry 1110 */
  287         {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
  288          BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
  289          BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
  290          "Entry 1110 (Atmel)"},
  291         /* ATMEL AT45DB021B (buffered flash) */
  292         {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
  293          BUFFERED_FLAGS, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
  294          BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
  295          "Buffered flash (256kB)"},
  296 };
  297 
  298 /*
  299  * The BCM5709 controllers transparently handle the
  300  * differences between Atmel 264 byte pages and all
  301  * flash devices which use 256 byte pages, so no
  302  * logical-to-physical mapping is required in the
  303  * driver.
  304  */
  305 static const struct flash_spec flash_5709 = {
  306         .flags          = BCE_NV_BUFFERED,
  307         .page_bits      = BCM5709_FLASH_PAGE_BITS,
  308         .page_size      = BCM5709_FLASH_PAGE_SIZE,
  309         .addr_mask      = BCM5709_FLASH_BYTE_ADDR_MASK,
  310         .total_size     = BUFFERED_FLASH_TOTAL_SIZE * 2,
  311         .name           = "5709/5716 buffered flash (256kB)",
  312 };
  313 
  314 
  315 /****************************************************************************/
  316 /* FreeBSD device entry points.                                             */
  317 /****************************************************************************/
  318 static int  bce_probe                   (device_t);
  319 static int  bce_attach                  (device_t);
  320 static int  bce_detach                  (device_t);
  321 static int  bce_shutdown                (device_t);
  322 
  323 
  324 /****************************************************************************/
  325 /* BCE Debug Data Structure Dump Routines                                   */
  326 /****************************************************************************/
  327 #ifdef BCE_DEBUG
  328 static u32  bce_reg_rd                          (struct bce_softc *, u32);
  329 static void bce_reg_wr                          (struct bce_softc *, u32, u32);
  330 static void bce_reg_wr16                        (struct bce_softc *, u32, u16);
  331 static u32  bce_ctx_rd                          (struct bce_softc *, u32, u32);
  332 static void bce_dump_enet                       (struct bce_softc *, struct mbuf *);
  333 static void bce_dump_mbuf                       (struct bce_softc *, struct mbuf *);
  334 static void bce_dump_tx_mbuf_chain      (struct bce_softc *, u16, int);
  335 static void bce_dump_rx_mbuf_chain      (struct bce_softc *, u16, int);
  336 static void bce_dump_pg_mbuf_chain      (struct bce_softc *, u16, int);
  337 static void bce_dump_txbd                       (struct bce_softc *,
  338     int, struct tx_bd *);
  339 static void bce_dump_rxbd                       (struct bce_softc *,
  340     int, struct rx_bd *);
  341 static void bce_dump_pgbd                       (struct bce_softc *,
  342     int, struct rx_bd *);
  343 static void bce_dump_l2fhdr             (struct bce_softc *,
  344     int, struct l2_fhdr *);
  345 static void bce_dump_ctx                        (struct bce_softc *, u16);
  346 static void bce_dump_ftqs                       (struct bce_softc *);
  347 static void bce_dump_tx_chain           (struct bce_softc *, u16, int);
  348 static void bce_dump_rx_bd_chain        (struct bce_softc *, u16, int);
  349 static void bce_dump_pg_chain           (struct bce_softc *, u16, int);
  350 static void bce_dump_status_block       (struct bce_softc *);
  351 static void bce_dump_stats_block        (struct bce_softc *);
  352 static void bce_dump_driver_state       (struct bce_softc *);
  353 static void bce_dump_hw_state           (struct bce_softc *);
  354 static void bce_dump_shmem_state        (struct bce_softc *);
  355 static void bce_dump_mq_regs            (struct bce_softc *);
  356 static void bce_dump_bc_state           (struct bce_softc *);
  357 static void bce_dump_txp_state          (struct bce_softc *, int);
  358 static void bce_dump_rxp_state          (struct bce_softc *, int);
  359 static void bce_dump_tpat_state (struct bce_softc *, int);
  360 static void bce_dump_cp_state           (struct bce_softc *, int);
  361 static void bce_dump_com_state          (struct bce_softc *, int);
  362 static void bce_dump_rv2p_state (struct bce_softc *);
  363 static void bce_breakpoint                      (struct bce_softc *);
  364 #endif /*BCE_DEBUG */
  365 
  366 
  367 /****************************************************************************/
  368 /* BCE Register/Memory Access Routines                                      */
  369 /****************************************************************************/
  370 static u32  bce_reg_rd_ind              (struct bce_softc *, u32);
  371 static void bce_reg_wr_ind              (struct bce_softc *, u32, u32);
  372 static void bce_shmem_wr                (struct bce_softc *, u32, u32);
  373 static u32  bce_shmem_rd                (struct bce_softc *, u32);
  374 static void bce_ctx_wr                  (struct bce_softc *, u32, u32, u32);
  375 static int  bce_miibus_read_reg         (device_t, int, int);
  376 static int  bce_miibus_write_reg        (device_t, int, int, int);
  377 static void bce_miibus_statchg          (device_t);
  378 
  379 #ifdef BCE_DEBUG
  380 static int bce_sysctl_nvram_dump(SYSCTL_HANDLER_ARGS);
  381 #ifdef BCE_NVRAM_WRITE_SUPPORT
  382 static int bce_sysctl_nvram_write(SYSCTL_HANDLER_ARGS);
  383 #endif
  384 #endif
  385 
  386 /****************************************************************************/
  387 /* BCE NVRAM Access Routines                                                */
  388 /****************************************************************************/
  389 static int  bce_acquire_nvram_lock      (struct bce_softc *);
  390 static int  bce_release_nvram_lock      (struct bce_softc *);
  391 static void bce_enable_nvram_access(struct bce_softc *);
  392 static void bce_disable_nvram_access(struct bce_softc *);
  393 static int  bce_nvram_read_dword        (struct bce_softc *, u32, u8 *, u32);
  394 static int  bce_init_nvram                      (struct bce_softc *);
  395 static int  bce_nvram_read                      (struct bce_softc *, u32, u8 *, int);
  396 static int  bce_nvram_test                      (struct bce_softc *);
  397 #ifdef BCE_NVRAM_WRITE_SUPPORT
  398 static int  bce_enable_nvram_write      (struct bce_softc *);
  399 static void bce_disable_nvram_write(struct bce_softc *);
  400 static int  bce_nvram_erase_page        (struct bce_softc *, u32);
  401 static int  bce_nvram_write_dword       (struct bce_softc *, u32, u8 *, u32);
  402 static int  bce_nvram_write             (struct bce_softc *, u32, u8 *, int);
  403 #endif
  404 
  405 /****************************************************************************/
  406 /*                                                                          */
  407 /****************************************************************************/
  408 static void bce_get_rx_buffer_sizes(struct bce_softc *, int);
  409 static void bce_get_media                       (struct bce_softc *);
  410 static void bce_init_media                      (struct bce_softc *);
  411 static u32 bce_get_rphy_link            (struct bce_softc *);
  412 static void bce_dma_map_addr            (void *, bus_dma_segment_t *, int, int);
  413 static int  bce_dma_alloc                       (device_t);
  414 static void bce_dma_free                        (struct bce_softc *);
  415 static void bce_release_resources       (struct bce_softc *);
  416 
  417 /****************************************************************************/
  418 /* BCE Firmware Synchronization and Load                                    */
  419 /****************************************************************************/
  420 static void bce_fw_cap_init                     (struct bce_softc *);
  421 static int  bce_fw_sync                 (struct bce_softc *, u32);
  422 static void bce_load_rv2p_fw            (struct bce_softc *, const u32 *, u32,
  423     u32);
  424 static void bce_load_cpu_fw             (struct bce_softc *,
  425     struct cpu_reg *, struct fw_info *);
  426 static void bce_start_cpu                       (struct bce_softc *, struct cpu_reg *);
  427 static void bce_halt_cpu                        (struct bce_softc *, struct cpu_reg *);
  428 static void bce_start_rxp_cpu           (struct bce_softc *);
  429 static void bce_init_rxp_cpu            (struct bce_softc *);
  430 static void bce_init_txp_cpu            (struct bce_softc *);
  431 static void bce_init_tpat_cpu           (struct bce_softc *);
  432 static void bce_init_cp_cpu             (struct bce_softc *);
  433 static void bce_init_com_cpu            (struct bce_softc *);
  434 static void bce_init_cpus                       (struct bce_softc *);
  435 
  436 static void bce_print_adapter_info      (struct bce_softc *);
  437 static void bce_probe_pci_caps          (device_t, struct bce_softc *);
  438 static void bce_stop                            (struct bce_softc *);
  439 static int  bce_reset                           (struct bce_softc *, u32);
  440 static int  bce_chipinit                        (struct bce_softc *);
  441 static int  bce_blockinit                       (struct bce_softc *);
  442 
  443 static int  bce_init_tx_chain           (struct bce_softc *);
  444 static void bce_free_tx_chain           (struct bce_softc *);
  445 
  446 static int  bce_get_rx_buf              (struct bce_softc *, u16, u16, u32 *);
  447 static int  bce_init_rx_chain           (struct bce_softc *);
  448 static void bce_fill_rx_chain           (struct bce_softc *);
  449 static void bce_free_rx_chain           (struct bce_softc *);
  450 
  451 static int  bce_get_pg_buf              (struct bce_softc *, u16, u16);
  452 static int  bce_init_pg_chain           (struct bce_softc *);
  453 static void bce_fill_pg_chain           (struct bce_softc *);
  454 static void bce_free_pg_chain           (struct bce_softc *);
  455 
  456 static struct mbuf *bce_tso_setup       (struct bce_softc *,
  457     struct mbuf **, u16 *);
  458 static int  bce_tx_encap                        (struct bce_softc *, struct mbuf **);
  459 static void bce_start_locked            (struct ifnet *);
  460 static void bce_start                   (struct ifnet *);
  461 static int  bce_ioctl                   (struct ifnet *, u_long, caddr_t);
  462 static uint64_t bce_get_counter         (struct ifnet *, ift_counter);
  463 static void bce_watchdog                (struct bce_softc *);
  464 static int  bce_ifmedia_upd             (struct ifnet *);
  465 static int  bce_ifmedia_upd_locked      (struct ifnet *);
  466 static void bce_ifmedia_sts             (struct ifnet *, struct ifmediareq *);
  467 static void bce_ifmedia_sts_rphy        (struct bce_softc *, struct ifmediareq *);
  468 static void bce_init_locked             (struct bce_softc *);
  469 static void bce_init                            (void *);
  470 static void bce_mgmt_init_locked        (struct bce_softc *sc);
  471 
  472 static int  bce_init_ctx                        (struct bce_softc *);
  473 static void bce_get_mac_addr            (struct bce_softc *);
  474 static void bce_set_mac_addr            (struct bce_softc *);
  475 static void bce_phy_intr                        (struct bce_softc *);
  476 static inline u16 bce_get_hw_rx_cons    (struct bce_softc *);
  477 static void bce_rx_intr                 (struct bce_softc *);
  478 static void bce_tx_intr                 (struct bce_softc *);
  479 static void bce_disable_intr            (struct bce_softc *);
  480 static void bce_enable_intr             (struct bce_softc *, int);
  481 
  482 static void bce_intr                            (void *);
  483 static void bce_set_rx_mode             (struct bce_softc *);
  484 static void bce_stats_update            (struct bce_softc *);
  485 static void bce_tick                            (void *);
  486 static void bce_pulse                           (void *);
  487 static void bce_add_sysctls             (struct bce_softc *);
  488 
  489 
  490 /****************************************************************************/
  491 /* FreeBSD device dispatch table.                                           */
  492 /****************************************************************************/
  493 static device_method_t bce_methods[] = {
  494         /* Device interface (device_if.h) */
  495         DEVMETHOD(device_probe,         bce_probe),
  496         DEVMETHOD(device_attach,        bce_attach),
  497         DEVMETHOD(device_detach,        bce_detach),
  498         DEVMETHOD(device_shutdown,      bce_shutdown),
  499 /* Supported by device interface but not used here. */
  500 /*      DEVMETHOD(device_identify,      bce_identify),      */
  501 /*      DEVMETHOD(device_suspend,       bce_suspend),       */
  502 /*      DEVMETHOD(device_resume,        bce_resume),        */
  503 /*      DEVMETHOD(device_quiesce,       bce_quiesce),       */
  504 
  505         /* MII interface (miibus_if.h) */
  506         DEVMETHOD(miibus_readreg,       bce_miibus_read_reg),
  507         DEVMETHOD(miibus_writereg,      bce_miibus_write_reg),
  508         DEVMETHOD(miibus_statchg,       bce_miibus_statchg),
  509 /* Supported by MII interface but not used here.       */
  510 /*      DEVMETHOD(miibus_linkchg,       bce_miibus_linkchg),   */
  511 /*      DEVMETHOD(miibus_mediainit,     bce_miibus_mediainit), */
  512 
  513         DEVMETHOD_END
  514 };
  515 
  516 static driver_t bce_driver = {
  517         "bce",
  518         bce_methods,
  519         sizeof(struct bce_softc)
  520 };
  521 
  522 static devclass_t bce_devclass;
  523 
  524 MODULE_DEPEND(bce, pci, 1, 1, 1);
  525 MODULE_DEPEND(bce, ether, 1, 1, 1);
  526 MODULE_DEPEND(bce, miibus, 1, 1, 1);
  527 
  528 DRIVER_MODULE(bce, pci, bce_driver, bce_devclass, NULL, NULL);
  529 DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, NULL, NULL);
  530 
  531 
  532 /****************************************************************************/
  533 /* Tunable device values                                                    */
  534 /****************************************************************************/
  535 static SYSCTL_NODE(_hw, OID_AUTO, bce, CTLFLAG_RD, 0, "bce driver parameters");
  536 
  537 /* Allowable values are TRUE or FALSE */
  538 static int bce_verbose = TRUE;
  539 SYSCTL_INT(_hw_bce, OID_AUTO, verbose, CTLFLAG_RDTUN, &bce_verbose, 0,
  540     "Verbose output enable/disable");
  541 
  542 /* Allowable values are TRUE or FALSE */
  543 static int bce_tso_enable = TRUE;
  544 SYSCTL_INT(_hw_bce, OID_AUTO, tso_enable, CTLFLAG_RDTUN, &bce_tso_enable, 0,
  545     "TSO Enable/Disable");
  546 
  547 /* Allowable values are 0 (IRQ), 1 (MSI/IRQ), and 2 (MSI-X/MSI/IRQ) */
  548 /* ToDo: Add MSI-X support. */
  549 static int bce_msi_enable = 1;
  550 SYSCTL_INT(_hw_bce, OID_AUTO, msi_enable, CTLFLAG_RDTUN, &bce_msi_enable, 0,
  551     "MSI-X|MSI|INTx selector");
  552 
  553 /* Allowable values are 1, 2, 4, 8. */
  554 static int bce_rx_pages = DEFAULT_RX_PAGES;
  555 SYSCTL_UINT(_hw_bce, OID_AUTO, rx_pages, CTLFLAG_RDTUN, &bce_rx_pages, 0,
  556     "Receive buffer descriptor pages (1 page = 255 buffer descriptors)");
  557 
  558 /* Allowable values are 1, 2, 4, 8. */
  559 static int bce_tx_pages = DEFAULT_TX_PAGES;
  560 SYSCTL_UINT(_hw_bce, OID_AUTO, tx_pages, CTLFLAG_RDTUN, &bce_tx_pages, 0,
  561     "Transmit buffer descriptor pages (1 page = 255 buffer descriptors)");
  562 
  563 /* Allowable values are TRUE or FALSE. */
  564 static int bce_hdr_split = TRUE;
  565 SYSCTL_UINT(_hw_bce, OID_AUTO, hdr_split, CTLFLAG_RDTUN, &bce_hdr_split, 0,
  566     "Frame header/payload splitting Enable/Disable");
  567 
  568 /* Allowable values are TRUE or FALSE. */
  569 static int bce_strict_rx_mtu = FALSE;
  570 SYSCTL_UINT(_hw_bce, OID_AUTO, strict_rx_mtu, CTLFLAG_RDTUN,
  571     &bce_strict_rx_mtu, 0,
  572     "Enable/Disable strict RX frame size checking");
  573 
  574 /* Allowable values are 0 ... 100 */
  575 #ifdef BCE_DEBUG
  576 /* Generate 1 interrupt for every transmit completion. */
  577 static int bce_tx_quick_cons_trip_int = 1;
  578 #else
  579 /* Generate 1 interrupt for every 20 transmit completions. */
  580 static int bce_tx_quick_cons_trip_int = DEFAULT_TX_QUICK_CONS_TRIP_INT;
  581 #endif
  582 SYSCTL_UINT(_hw_bce, OID_AUTO, tx_quick_cons_trip_int, CTLFLAG_RDTUN,
  583     &bce_tx_quick_cons_trip_int, 0,
  584     "Transmit BD trip point during interrupts");
  585 
  586 /* Allowable values are 0 ... 100 */
  587 /* Generate 1 interrupt for every transmit completion. */
  588 #ifdef BCE_DEBUG
  589 static int bce_tx_quick_cons_trip = 1;
  590 #else
  591 /* Generate 1 interrupt for every 20 transmit completions. */
  592 static int bce_tx_quick_cons_trip = DEFAULT_TX_QUICK_CONS_TRIP;
  593 #endif
  594 SYSCTL_UINT(_hw_bce, OID_AUTO, tx_quick_cons_trip, CTLFLAG_RDTUN,
  595     &bce_tx_quick_cons_trip, 0,
  596     "Transmit BD trip point");
  597 
  598 /* Allowable values are 0 ... 100 */
  599 #ifdef BCE_DEBUG
  600 /* Generate an interrupt if 0us have elapsed since the last TX completion. */
  601 static int bce_tx_ticks_int = 0;
  602 #else
  603 /* Generate an interrupt if 80us have elapsed since the last TX completion. */
  604 static int bce_tx_ticks_int = DEFAULT_TX_TICKS_INT;
  605 #endif
  606 SYSCTL_UINT(_hw_bce, OID_AUTO, tx_ticks_int, CTLFLAG_RDTUN,
  607     &bce_tx_ticks_int, 0, "Transmit ticks count during interrupt");
  608 
  609 /* Allowable values are 0 ... 100 */
  610 #ifdef BCE_DEBUG
  611 /* Generate an interrupt if 0us have elapsed since the last TX completion. */
  612 static int bce_tx_ticks = 0;
  613 #else
  614 /* Generate an interrupt if 80us have elapsed since the last TX completion. */
  615 static int bce_tx_ticks = DEFAULT_TX_TICKS;
  616 #endif
  617 SYSCTL_UINT(_hw_bce, OID_AUTO, tx_ticks, CTLFLAG_RDTUN,
  618     &bce_tx_ticks, 0, "Transmit ticks count");
  619 
  620 /* Allowable values are 1 ... 100 */
  621 #ifdef BCE_DEBUG
  622 /* Generate 1 interrupt for every received frame. */
  623 static int bce_rx_quick_cons_trip_int = 1;
  624 #else
  625 /* Generate 1 interrupt for every 6 received frames. */
  626 static int bce_rx_quick_cons_trip_int = DEFAULT_RX_QUICK_CONS_TRIP_INT;
  627 #endif
  628 SYSCTL_UINT(_hw_bce, OID_AUTO, rx_quick_cons_trip_int, CTLFLAG_RDTUN,
  629     &bce_rx_quick_cons_trip_int, 0,
  630     "Receive BD trip point duirng interrupts");
  631 
  632 /* Allowable values are 1 ... 100 */
  633 #ifdef BCE_DEBUG
  634 /* Generate 1 interrupt for every received frame. */
  635 static int bce_rx_quick_cons_trip = 1;
  636 #else
  637 /* Generate 1 interrupt for every 6 received frames. */
  638 static int bce_rx_quick_cons_trip = DEFAULT_RX_QUICK_CONS_TRIP;
  639 #endif
  640 SYSCTL_UINT(_hw_bce, OID_AUTO, rx_quick_cons_trip, CTLFLAG_RDTUN,
  641     &bce_rx_quick_cons_trip, 0,
  642     "Receive BD trip point");
  643 
  644 /* Allowable values are 0 ... 100 */
  645 #ifdef BCE_DEBUG
  646 /* Generate an int. if 0us have elapsed since the last received frame. */
  647 static int bce_rx_ticks_int = 0;
  648 #else
  649 /* Generate an int. if 18us have elapsed since the last received frame. */
  650 static int bce_rx_ticks_int = DEFAULT_RX_TICKS_INT;
  651 #endif
  652 SYSCTL_UINT(_hw_bce, OID_AUTO, rx_ticks_int, CTLFLAG_RDTUN,
  653     &bce_rx_ticks_int, 0, "Receive ticks count during interrupt");
  654 
  655 /* Allowable values are 0 ... 100 */
  656 #ifdef BCE_DEBUG
  657 /* Generate an int. if 0us have elapsed since the last received frame. */
  658 static int bce_rx_ticks = 0;
  659 #else
  660 /* Generate an int. if 18us have elapsed since the last received frame. */
  661 static int bce_rx_ticks = DEFAULT_RX_TICKS;
  662 #endif
  663 SYSCTL_UINT(_hw_bce, OID_AUTO, rx_ticks, CTLFLAG_RDTUN,
  664     &bce_rx_ticks, 0, "Receive ticks count");
  665 
  666 
  667 /****************************************************************************/
  668 /* Device probe function.                                                   */
  669 /*                                                                          */
  670 /* Compares the device to the driver's list of supported devices and        */
  671 /* reports back to the OS whether this is the right driver for the device.  */
  672 /*                                                                          */
  673 /* Returns:                                                                 */
  674 /*   BUS_PROBE_DEFAULT on success, positive value on failure.               */
  675 /****************************************************************************/
  676 static int
  677 bce_probe(device_t dev)
  678 {
  679         const struct bce_type *t;
  680         struct bce_softc *sc;
  681         char *descbuf;
  682         u16 vid = 0, did = 0, svid = 0, sdid = 0;
  683 
  684         t = bce_devs;
  685 
  686         sc = device_get_softc(dev);
  687         sc->bce_unit = device_get_unit(dev);
  688         sc->bce_dev = dev;
  689 
  690         /* Get the data for the device to be probed. */
  691         vid  = pci_get_vendor(dev);
  692         did  = pci_get_device(dev);
  693         svid = pci_get_subvendor(dev);
  694         sdid = pci_get_subdevice(dev);
  695 
  696         DBPRINT(sc, BCE_EXTREME_LOAD,
  697             "%s(); VID = 0x%04X, DID = 0x%04X, SVID = 0x%04X, "
  698             "SDID = 0x%04X\n", __FUNCTION__, vid, did, svid, sdid);
  699 
  700         /* Look through the list of known devices for a match. */
  701         while(t->bce_name != NULL) {
  702 
  703                 if ((vid == t->bce_vid) && (did == t->bce_did) &&
  704                     ((svid == t->bce_svid) || (t->bce_svid == PCI_ANY_ID)) &&
  705                     ((sdid == t->bce_sdid) || (t->bce_sdid == PCI_ANY_ID))) {
  706 
  707                         descbuf = malloc(BCE_DEVDESC_MAX, M_TEMP, M_NOWAIT);
  708 
  709                         if (descbuf == NULL)
  710                                 return(ENOMEM);
  711 
  712                         /* Print out the device identity. */
  713                         snprintf(descbuf, BCE_DEVDESC_MAX, "%s (%c%d)",
  714                             t->bce_name, (((pci_read_config(dev,
  715                             PCIR_REVID, 4) & 0xf0) >> 4) + 'A'),
  716                             (pci_read_config(dev, PCIR_REVID, 4) & 0xf));
  717 
  718                         device_set_desc_copy(dev, descbuf);
  719                         free(descbuf, M_TEMP);
  720                         return(BUS_PROBE_DEFAULT);
  721                 }
  722                 t++;
  723         }
  724 
  725         return(ENXIO);
  726 }
  727 
  728 
  729 /****************************************************************************/
  730 /* PCI Capabilities Probe Function.                                         */
  731 /*                                                                          */
  732 /* Walks the PCI capabiites list for the device to find what features are   */
  733 /* supported.                                                               */
  734 /*                                                                          */
  735 /* Returns:                                                                 */
  736 /*   None.                                                                  */
  737 /****************************************************************************/
  738 static void
  739 bce_print_adapter_info(struct bce_softc *sc)
  740 {
  741         int i = 0;
  742 
  743         DBENTER(BCE_VERBOSE_LOAD);
  744 
  745         if (bce_verbose || bootverbose) {
  746                 BCE_PRINTF("ASIC (0x%08X); ", sc->bce_chipid);
  747                 printf("Rev (%c%d); ", ((BCE_CHIP_ID(sc) & 0xf000) >>
  748                     12) + 'A', ((BCE_CHIP_ID(sc) & 0x0ff0) >> 4));
  749 
  750 
  751                 /* Bus info. */
  752                 if (sc->bce_flags & BCE_PCIE_FLAG) {
  753                         printf("Bus (PCIe x%d, ", sc->link_width);
  754                         switch (sc->link_speed) {
  755                         case 1: printf("2.5Gbps); "); break;
  756                         case 2: printf("5Gbps); "); break;
  757                         default: printf("Unknown link speed); ");
  758                         }
  759                 } else {
  760                         printf("Bus (PCI%s, %s, %dMHz); ",
  761                             ((sc->bce_flags & BCE_PCIX_FLAG) ? "-X" : ""),
  762                             ((sc->bce_flags & BCE_PCI_32BIT_FLAG) ?
  763                             "32-bit" : "64-bit"), sc->bus_speed_mhz);
  764                 }
  765 
  766                 /* Firmware version and device features. */
  767                 printf("B/C (%s); Bufs (RX:%d;TX:%d;PG:%d); Flags (",
  768                     sc->bce_bc_ver,     sc->rx_pages, sc->tx_pages,
  769                     (bce_hdr_split == TRUE ? sc->pg_pages: 0));
  770 
  771                 if (bce_hdr_split == TRUE) {
  772                         printf("SPLT");
  773                         i++;
  774                 }
  775 
  776                 if (sc->bce_flags & BCE_USING_MSI_FLAG) {
  777                         if (i > 0) printf("|");
  778                         printf("MSI"); i++;
  779                 }
  780 
  781                 if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
  782                         if (i > 0) printf("|");
  783                         printf("MSI-X"); i++;
  784                 }
  785 
  786                 if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
  787                         if (i > 0) printf("|");
  788                         printf("2.5G"); i++;
  789                 }
  790 
  791                 if (sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) {
  792                         if (i > 0) printf("|");
  793                         printf("Remote PHY(%s)",
  794                             sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG ?
  795                             "FIBER" : "TP"); i++;
  796                 }
  797 
  798                 if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
  799                         if (i > 0) printf("|");
  800                         printf("MFW); MFW (%s)\n", sc->bce_mfw_ver);
  801                 } else {
  802                         printf(")\n");
  803                 }
  804 
  805                 printf("Coal (RX:%d,%d,%d,%d; TX:%d,%d,%d,%d)\n",
  806                     sc->bce_rx_quick_cons_trip_int,
  807                     sc->bce_rx_quick_cons_trip,
  808                     sc->bce_rx_ticks_int,
  809                     sc->bce_rx_ticks,
  810                     sc->bce_tx_quick_cons_trip_int,
  811                     sc->bce_tx_quick_cons_trip,
  812                     sc->bce_tx_ticks_int,
  813                     sc->bce_tx_ticks);
  814 
  815         }
  816 
  817         DBEXIT(BCE_VERBOSE_LOAD);
  818 }
  819 
  820 
  821 /****************************************************************************/
  822 /* PCI Capabilities Probe Function.                                         */
  823 /*                                                                          */
  824 /* Walks the PCI capabiites list for the device to find what features are   */
  825 /* supported.                                                               */
  826 /*                                                                          */
  827 /* Returns:                                                                 */
  828 /*   None.                                                                  */
  829 /****************************************************************************/
  830 static void
  831 bce_probe_pci_caps(device_t dev, struct bce_softc *sc)
  832 {
  833         u32 reg;
  834 
  835         DBENTER(BCE_VERBOSE_LOAD);
  836 
  837         /* Check if PCI-X capability is enabled. */
  838         if (pci_find_cap(dev, PCIY_PCIX, &reg) == 0) {
  839                 if (reg != 0)
  840                         sc->bce_cap_flags |= BCE_PCIX_CAPABLE_FLAG;
  841         }
  842 
  843         /* Check if PCIe capability is enabled. */
  844         if (pci_find_cap(dev, PCIY_EXPRESS, &reg) == 0) {
  845                 if (reg != 0) {
  846                         u16 link_status = pci_read_config(dev, reg + 0x12, 2);
  847                         DBPRINT(sc, BCE_INFO_LOAD, "PCIe link_status = "
  848                             "0x%08X\n", link_status);
  849                         sc->link_speed = link_status & 0xf;
  850                         sc->link_width = (link_status >> 4) & 0x3f;
  851                         sc->bce_cap_flags |= BCE_PCIE_CAPABLE_FLAG;
  852                         sc->bce_flags |= BCE_PCIE_FLAG;
  853                 }
  854         }
  855 
  856         /* Check if MSI capability is enabled. */
  857         if (pci_find_cap(dev, PCIY_MSI, &reg) == 0) {
  858                 if (reg != 0)
  859                         sc->bce_cap_flags |= BCE_MSI_CAPABLE_FLAG;
  860         }
  861 
  862         /* Check if MSI-X capability is enabled. */
  863         if (pci_find_cap(dev, PCIY_MSIX, &reg) == 0) {
  864                 if (reg != 0)
  865                         sc->bce_cap_flags |= BCE_MSIX_CAPABLE_FLAG;
  866         }
  867 
  868         DBEXIT(BCE_VERBOSE_LOAD);
  869 }
  870 
  871 
  872 /****************************************************************************/
  873 /* Load and validate user tunable settings.                                 */
  874 /*                                                                          */
  875 /* Returns:                                                                 */
  876 /*   Nothing.                                                               */
  877 /****************************************************************************/
  878 static void
  879 bce_set_tunables(struct bce_softc *sc)
  880 {
  881         /* Set sysctl values for RX page count. */
  882         switch (bce_rx_pages) {
  883         case 1:
  884                 /* fall-through */
  885         case 2:
  886                 /* fall-through */
  887         case 4:
  888                 /* fall-through */
  889         case 8:
  890                 sc->rx_pages = bce_rx_pages;
  891                 break;
  892         default:
  893                 sc->rx_pages = DEFAULT_RX_PAGES;
  894                 BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
  895                     "hw.bce.rx_pages!  Setting default of %d.\n",
  896                     __FILE__, __LINE__, bce_rx_pages, DEFAULT_RX_PAGES);
  897         }
  898 
  899         /* ToDo: Consider allowing user setting for pg_pages. */
  900         sc->pg_pages = min((sc->rx_pages * 4), MAX_PG_PAGES);
  901 
  902         /* Set sysctl values for TX page count. */
  903         switch (bce_tx_pages) {
  904         case 1:
  905                 /* fall-through */
  906         case 2:
  907                 /* fall-through */
  908         case 4:
  909                 /* fall-through */
  910         case 8:
  911                 sc->tx_pages = bce_tx_pages;
  912                 break;
  913         default:
  914                 sc->tx_pages = DEFAULT_TX_PAGES;
  915                 BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
  916                     "hw.bce.tx_pages!  Setting default of %d.\n",
  917                     __FILE__, __LINE__, bce_tx_pages, DEFAULT_TX_PAGES);
  918         }
  919 
  920         /*
  921          * Validate the TX trip point (i.e. the number of
  922          * TX completions before a status block update is
  923          * generated and an interrupt is asserted.
  924          */
  925         if (bce_tx_quick_cons_trip_int <= 100) {
  926                 sc->bce_tx_quick_cons_trip_int =
  927                     bce_tx_quick_cons_trip_int;
  928         } else {
  929                 BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
  930                     "hw.bce.tx_quick_cons_trip_int!  Setting default of %d.\n",
  931                     __FILE__, __LINE__, bce_tx_quick_cons_trip_int,
  932                     DEFAULT_TX_QUICK_CONS_TRIP_INT);
  933                 sc->bce_tx_quick_cons_trip_int =
  934                     DEFAULT_TX_QUICK_CONS_TRIP_INT;
  935         }
  936 
  937         if (bce_tx_quick_cons_trip <= 100) {
  938                 sc->bce_tx_quick_cons_trip =
  939                     bce_tx_quick_cons_trip;
  940         } else {
  941                 BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
  942                     "hw.bce.tx_quick_cons_trip!  Setting default of %d.\n",
  943                     __FILE__, __LINE__, bce_tx_quick_cons_trip,
  944                     DEFAULT_TX_QUICK_CONS_TRIP);
  945                 sc->bce_tx_quick_cons_trip =
  946                     DEFAULT_TX_QUICK_CONS_TRIP;
  947         }
  948 
  949         /*
  950          * Validate the TX ticks count (i.e. the maximum amount
  951          * of time to wait after the last TX completion has
  952          * occurred before a status block update is generated
  953          * and an interrupt is asserted.
  954          */
  955         if (bce_tx_ticks_int <= 100) {
  956                 sc->bce_tx_ticks_int =
  957                     bce_tx_ticks_int;
  958         } else {
  959                 BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
  960                     "hw.bce.tx_ticks_int!  Setting default of %d.\n",
  961                     __FILE__, __LINE__, bce_tx_ticks_int,
  962                     DEFAULT_TX_TICKS_INT);
  963                 sc->bce_tx_ticks_int =
  964                     DEFAULT_TX_TICKS_INT;
  965            }
  966 
  967         if (bce_tx_ticks <= 100) {
  968                 sc->bce_tx_ticks =
  969                     bce_tx_ticks;
  970         } else {
  971                 BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
  972                     "hw.bce.tx_ticks!  Setting default of %d.\n",
  973                     __FILE__, __LINE__, bce_tx_ticks,
  974                     DEFAULT_TX_TICKS);
  975                 sc->bce_tx_ticks =
  976                     DEFAULT_TX_TICKS;
  977         }
  978 
  979         /*
  980          * Validate the RX trip point (i.e. the number of
  981          * RX frames received before a status block update is
  982          * generated and an interrupt is asserted.
  983          */
  984         if (bce_rx_quick_cons_trip_int <= 100) {
  985                 sc->bce_rx_quick_cons_trip_int =
  986                     bce_rx_quick_cons_trip_int;
  987         } else {
  988                 BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
  989                     "hw.bce.rx_quick_cons_trip_int!  Setting default of %d.\n",
  990                     __FILE__, __LINE__, bce_rx_quick_cons_trip_int,
  991                     DEFAULT_RX_QUICK_CONS_TRIP_INT);
  992                 sc->bce_rx_quick_cons_trip_int =
  993                     DEFAULT_RX_QUICK_CONS_TRIP_INT;
  994         }
  995 
  996         if (bce_rx_quick_cons_trip <= 100) {
  997                 sc->bce_rx_quick_cons_trip =
  998                     bce_rx_quick_cons_trip;
  999         } else {
 1000                 BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
 1001                     "hw.bce.rx_quick_cons_trip!  Setting default of %d.\n",
 1002                     __FILE__, __LINE__, bce_rx_quick_cons_trip,
 1003                     DEFAULT_RX_QUICK_CONS_TRIP);
 1004                 sc->bce_rx_quick_cons_trip =
 1005                     DEFAULT_RX_QUICK_CONS_TRIP;
 1006         }
 1007 
 1008         /*
 1009          * Validate the RX ticks count (i.e. the maximum amount
 1010          * of time to wait after the last RX frame has been
 1011          * received before a status block update is generated
 1012          * and an interrupt is asserted.
 1013          */
 1014         if (bce_rx_ticks_int <= 100) {
 1015                 sc->bce_rx_ticks_int = bce_rx_ticks_int;
 1016         } else {
 1017                 BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
 1018                     "hw.bce.rx_ticks_int!  Setting default of %d.\n",
 1019                     __FILE__, __LINE__, bce_rx_ticks_int,
 1020                     DEFAULT_RX_TICKS_INT);
 1021                 sc->bce_rx_ticks_int = DEFAULT_RX_TICKS_INT;
 1022         }
 1023 
 1024         if (bce_rx_ticks <= 100) {
 1025                 sc->bce_rx_ticks = bce_rx_ticks;
 1026         } else {
 1027                 BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
 1028                     "hw.bce.rx_ticks!  Setting default of %d.\n",
 1029                     __FILE__, __LINE__, bce_rx_ticks,
 1030                     DEFAULT_RX_TICKS);
 1031                 sc->bce_rx_ticks = DEFAULT_RX_TICKS;
 1032         }
 1033 
 1034         /* Disabling both RX ticks and RX trips will prevent interrupts. */
 1035         if ((bce_rx_quick_cons_trip == 0) && (bce_rx_ticks == 0)) {
 1036                 BCE_PRINTF("%s(%d): Cannot set both hw.bce.rx_ticks and "
 1037                     "hw.bce.rx_quick_cons_trip to 0. Setting default values.\n",
 1038                    __FILE__, __LINE__);
 1039                 sc->bce_rx_ticks = DEFAULT_RX_TICKS;
 1040                 sc->bce_rx_quick_cons_trip = DEFAULT_RX_QUICK_CONS_TRIP;
 1041         }
 1042 
 1043         /* Disabling both TX ticks and TX trips will prevent interrupts. */
 1044         if ((bce_tx_quick_cons_trip == 0) && (bce_tx_ticks == 0)) {
 1045                 BCE_PRINTF("%s(%d): Cannot set both hw.bce.tx_ticks and "
 1046                     "hw.bce.tx_quick_cons_trip to 0. Setting default values.\n",
 1047                    __FILE__, __LINE__);
 1048                 sc->bce_tx_ticks = DEFAULT_TX_TICKS;
 1049                 sc->bce_tx_quick_cons_trip = DEFAULT_TX_QUICK_CONS_TRIP;
 1050         }
 1051 }
 1052 
 1053 
 1054 /****************************************************************************/
 1055 /* Device attach function.                                                  */
 1056 /*                                                                          */
 1057 /* Allocates device resources, performs secondary chip identification,      */
 1058 /* resets and initializes the hardware, and initializes driver instance     */
 1059 /* variables.                                                               */
 1060 /*                                                                          */
 1061 /* Returns:                                                                 */
 1062 /*   0 on success, positive value on failure.                               */
 1063 /****************************************************************************/
 1064 static int
 1065 bce_attach(device_t dev)
 1066 {
 1067         struct bce_softc *sc;
 1068         struct ifnet *ifp;
 1069         u32 val;
 1070         int count, error, rc = 0, rid;
 1071 
 1072         sc = device_get_softc(dev);
 1073         sc->bce_dev = dev;
 1074 
 1075         DBENTER(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
 1076 
 1077         sc->bce_unit = device_get_unit(dev);
 1078 
 1079         /* Set initial device and PHY flags */
 1080         sc->bce_flags = 0;
 1081         sc->bce_phy_flags = 0;
 1082 
 1083         bce_set_tunables(sc);
 1084 
 1085         pci_enable_busmaster(dev);
 1086 
 1087         /* Allocate PCI memory resources. */
 1088         rid = PCIR_BAR(0);
 1089         sc->bce_res_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
 1090                 &rid, RF_ACTIVE);
 1091 
 1092         if (sc->bce_res_mem == NULL) {
 1093                 BCE_PRINTF("%s(%d): PCI memory allocation failed\n",
 1094                     __FILE__, __LINE__);
 1095                 rc = ENXIO;
 1096                 goto bce_attach_fail;
 1097         }
 1098 
 1099         /* Get various resource handles. */
 1100         sc->bce_btag    = rman_get_bustag(sc->bce_res_mem);
 1101         sc->bce_bhandle = rman_get_bushandle(sc->bce_res_mem);
 1102         sc->bce_vhandle = (vm_offset_t) rman_get_virtual(sc->bce_res_mem);
 1103 
 1104         bce_probe_pci_caps(dev, sc);
 1105 
 1106         rid = 1;
 1107         count = 0;
 1108 #if 0
 1109         /* Try allocating MSI-X interrupts. */
 1110         if ((sc->bce_cap_flags & BCE_MSIX_CAPABLE_FLAG) &&
 1111                 (bce_msi_enable >= 2) &&
 1112                 ((sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
 1113                 &rid, RF_ACTIVE)) != NULL)) {
 1114 
 1115                 msi_needed = count = 1;
 1116 
 1117                 if (((error = pci_alloc_msix(dev, &count)) != 0) ||
 1118                         (count != msi_needed)) {
 1119                         BCE_PRINTF("%s(%d): MSI-X allocation failed! Requested = %d,"
 1120                                 "Received = %d, error = %d\n", __FILE__, __LINE__,
 1121                                 msi_needed, count, error);
 1122                         count = 0;
 1123                         pci_release_msi(dev);
 1124                         bus_release_resource(dev, SYS_RES_MEMORY, rid,
 1125                                 sc->bce_res_irq);
 1126                         sc->bce_res_irq = NULL;
 1127                 } else {
 1128                         DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI-X interrupt.\n",
 1129                                 __FUNCTION__);
 1130                         sc->bce_flags |= BCE_USING_MSIX_FLAG;
 1131                 }
 1132         }
 1133 #endif
 1134 
 1135         /* Try allocating a MSI interrupt. */
 1136         if ((sc->bce_cap_flags & BCE_MSI_CAPABLE_FLAG) &&
 1137                 (bce_msi_enable >= 1) && (count == 0)) {
 1138                 count = 1;
 1139                 if ((error = pci_alloc_msi(dev, &count)) != 0) {
 1140                         BCE_PRINTF("%s(%d): MSI allocation failed! "
 1141                             "error = %d\n", __FILE__, __LINE__, error);
 1142                         count = 0;
 1143                         pci_release_msi(dev);
 1144                 } else {
 1145                         DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using MSI "
 1146                             "interrupt.\n", __FUNCTION__);
 1147                         sc->bce_flags |= BCE_USING_MSI_FLAG;
 1148                         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
 1149                                 sc->bce_flags |= BCE_ONE_SHOT_MSI_FLAG;
 1150                         rid = 1;
 1151                 }
 1152         }
 1153 
 1154         /* Try allocating a legacy interrupt. */
 1155         if (count == 0) {
 1156                 DBPRINT(sc, BCE_INFO_LOAD, "%s(): Using INTx interrupt.\n",
 1157                         __FUNCTION__);
 1158                 rid = 0;
 1159         }
 1160 
 1161         sc->bce_res_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
 1162             &rid, RF_ACTIVE | (count != 0 ? 0 : RF_SHAREABLE));
 1163 
 1164         /* Report any IRQ allocation errors. */
 1165         if (sc->bce_res_irq == NULL) {
 1166                 BCE_PRINTF("%s(%d): PCI map interrupt failed!\n",
 1167                     __FILE__, __LINE__);
 1168                 rc = ENXIO;
 1169                 goto bce_attach_fail;
 1170         }
 1171 
 1172         /* Initialize mutex for the current device instance. */
 1173         BCE_LOCK_INIT(sc, device_get_nameunit(dev));
 1174 
 1175         /*
 1176          * Configure byte swap and enable indirect register access.
 1177          * Rely on CPU to do target byte swapping on big endian systems.
 1178          * Access to registers outside of PCI configurtion space are not
 1179          * valid until this is done.
 1180          */
 1181         pci_write_config(dev, BCE_PCICFG_MISC_CONFIG,
 1182             BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
 1183             BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP, 4);
 1184 
 1185         /* Save ASIC revsion info. */
 1186         sc->bce_chipid =  REG_RD(sc, BCE_MISC_ID);
 1187 
 1188         /* Weed out any non-production controller revisions. */
 1189         switch(BCE_CHIP_ID(sc)) {
 1190         case BCE_CHIP_ID_5706_A0:
 1191         case BCE_CHIP_ID_5706_A1:
 1192         case BCE_CHIP_ID_5708_A0:
 1193         case BCE_CHIP_ID_5708_B0:
 1194         case BCE_CHIP_ID_5709_A0:
 1195         case BCE_CHIP_ID_5709_B0:
 1196         case BCE_CHIP_ID_5709_B1:
 1197         case BCE_CHIP_ID_5709_B2:
 1198                 BCE_PRINTF("%s(%d): Unsupported controller "
 1199                     "revision (%c%d)!\n", __FILE__, __LINE__,
 1200                     (((pci_read_config(dev, PCIR_REVID, 4) &
 1201                     0xf0) >> 4) + 'A'), (pci_read_config(dev,
 1202                     PCIR_REVID, 4) & 0xf));
 1203                 rc = ENODEV;
 1204                 goto bce_attach_fail;
 1205         }
 1206 
 1207         /*
 1208          * The embedded PCIe to PCI-X bridge (EPB)
 1209          * in the 5708 cannot address memory above
 1210          * 40 bits (E7_5708CB1_23043 & E6_5708SB1_23043).
 1211          */
 1212         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708)
 1213                 sc->max_bus_addr = BCE_BUS_SPACE_MAXADDR;
 1214         else
 1215                 sc->max_bus_addr = BUS_SPACE_MAXADDR;
 1216 
 1217         /*
 1218          * Find the base address for shared memory access.
 1219          * Newer versions of bootcode use a signature and offset
 1220          * while older versions use a fixed address.
 1221          */
 1222         val = REG_RD_IND(sc, BCE_SHM_HDR_SIGNATURE);
 1223         if ((val & BCE_SHM_HDR_SIGNATURE_SIG_MASK) == BCE_SHM_HDR_SIGNATURE_SIG)
 1224                 /* Multi-port devices use different offsets in shared memory. */
 1225                 sc->bce_shmem_base = REG_RD_IND(sc, BCE_SHM_HDR_ADDR_0 +
 1226                     (pci_get_function(sc->bce_dev) << 2));
 1227         else
 1228                 sc->bce_shmem_base = HOST_VIEW_SHMEM_BASE;
 1229 
 1230         DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): bce_shmem_base = 0x%08X\n",
 1231             __FUNCTION__, sc->bce_shmem_base);
 1232 
 1233         /* Fetch the bootcode revision. */
 1234         val = bce_shmem_rd(sc, BCE_DEV_INFO_BC_REV);
 1235         for (int i = 0, j = 0; i < 3; i++) {
 1236                 u8 num;
 1237 
 1238                 num = (u8) (val >> (24 - (i * 8)));
 1239                 for (int k = 100, skip0 = 1; k >= 1; num %= k, k /= 10) {
 1240                         if (num >= k || !skip0 || k == 1) {
 1241                                 sc->bce_bc_ver[j++] = (num / k) + '';
 1242                                 skip0 = 0;
 1243                         }
 1244                 }
 1245 
 1246                 if (i != 2)
 1247                         sc->bce_bc_ver[j++] = '.';
 1248         }
 1249 
 1250         /* Check if any management firwmare is enabled. */
 1251         val = bce_shmem_rd(sc, BCE_PORT_FEATURE);
 1252         if (val & BCE_PORT_FEATURE_ASF_ENABLED) {
 1253                 sc->bce_flags |= BCE_MFW_ENABLE_FLAG;
 1254 
 1255                 /* Allow time for firmware to enter the running state. */
 1256                 for (int i = 0; i < 30; i++) {
 1257                         val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
 1258                         if (val & BCE_CONDITION_MFW_RUN_MASK)
 1259                                 break;
 1260                         DELAY(10000);
 1261                 }
 1262 
 1263                 /* Check if management firmware is running. */
 1264                 val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
 1265                 val &= BCE_CONDITION_MFW_RUN_MASK;
 1266                 if ((val != BCE_CONDITION_MFW_RUN_UNKNOWN) &&
 1267                     (val != BCE_CONDITION_MFW_RUN_NONE)) {
 1268                         u32 addr = bce_shmem_rd(sc, BCE_MFW_VER_PTR);
 1269                         int i = 0;
 1270 
 1271                         /* Read the management firmware version string. */
 1272                         for (int j = 0; j < 3; j++) {
 1273                                 val = bce_reg_rd_ind(sc, addr + j * 4);
 1274                                 val = bswap32(val);
 1275                                 memcpy(&sc->bce_mfw_ver[i], &val, 4);
 1276                                 i += 4;
 1277                         }
 1278                 } else {
 1279                         /* May cause firmware synchronization timeouts. */
 1280                         BCE_PRINTF("%s(%d): Management firmware enabled "
 1281                             "but not running!\n", __FILE__, __LINE__);
 1282                         strcpy(sc->bce_mfw_ver, "NOT RUNNING!");
 1283 
 1284                         /* ToDo: Any action the driver should take? */
 1285                 }
 1286         }
 1287 
 1288         /* Get PCI bus information (speed and type). */
 1289         val = REG_RD(sc, BCE_PCICFG_MISC_STATUS);
 1290         if (val & BCE_PCICFG_MISC_STATUS_PCIX_DET) {
 1291                 u32 clkreg;
 1292 
 1293                 sc->bce_flags |= BCE_PCIX_FLAG;
 1294 
 1295                 clkreg = REG_RD(sc, BCE_PCICFG_PCI_CLOCK_CONTROL_BITS);
 1296 
 1297                 clkreg &= BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
 1298                 switch (clkreg) {
 1299                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
 1300                         sc->bus_speed_mhz = 133;
 1301                         break;
 1302 
 1303                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
 1304                         sc->bus_speed_mhz = 100;
 1305                         break;
 1306 
 1307                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
 1308                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
 1309                         sc->bus_speed_mhz = 66;
 1310                         break;
 1311 
 1312                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
 1313                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
 1314                         sc->bus_speed_mhz = 50;
 1315                         break;
 1316 
 1317                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
 1318                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
 1319                 case BCE_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
 1320                         sc->bus_speed_mhz = 33;
 1321                         break;
 1322                 }
 1323         } else {
 1324                 if (val & BCE_PCICFG_MISC_STATUS_M66EN)
 1325                         sc->bus_speed_mhz = 66;
 1326                 else
 1327                         sc->bus_speed_mhz = 33;
 1328         }
 1329 
 1330         if (val & BCE_PCICFG_MISC_STATUS_32BIT_DET)
 1331                 sc->bce_flags |= BCE_PCI_32BIT_FLAG;
 1332 
 1333         /* Find the media type for the adapter. */
 1334         bce_get_media(sc);
 1335 
 1336         /* Reset controller and announce to bootcode that driver is present. */
 1337         if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
 1338                 BCE_PRINTF("%s(%d): Controller reset failed!\n",
 1339                     __FILE__, __LINE__);
 1340                 rc = ENXIO;
 1341                 goto bce_attach_fail;
 1342         }
 1343 
 1344         /* Initialize the controller. */
 1345         if (bce_chipinit(sc)) {
 1346                 BCE_PRINTF("%s(%d): Controller initialization failed!\n",
 1347                     __FILE__, __LINE__);
 1348                 rc = ENXIO;
 1349                 goto bce_attach_fail;
 1350         }
 1351 
 1352         /* Perform NVRAM test. */
 1353         if (bce_nvram_test(sc)) {
 1354                 BCE_PRINTF("%s(%d): NVRAM test failed!\n",
 1355                     __FILE__, __LINE__);
 1356                 rc = ENXIO;
 1357                 goto bce_attach_fail;
 1358         }
 1359 
 1360         /* Fetch the permanent Ethernet MAC address. */
 1361         bce_get_mac_addr(sc);
 1362 
 1363         /* Update statistics once every second. */
 1364         sc->bce_stats_ticks = 1000000 & 0xffff00;
 1365 
 1366         /* Store data needed by PHY driver for backplane applications */
 1367         sc->bce_shared_hw_cfg = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
 1368         sc->bce_port_hw_cfg   = bce_shmem_rd(sc, BCE_PORT_HW_CFG_CONFIG);
 1369 
 1370         /* Allocate DMA memory resources. */
 1371         if (bce_dma_alloc(dev)) {
 1372                 BCE_PRINTF("%s(%d): DMA resource allocation failed!\n",
 1373                     __FILE__, __LINE__);
 1374                 rc = ENXIO;
 1375                 goto bce_attach_fail;
 1376         }
 1377 
 1378         /* Allocate an ifnet structure. */
 1379         ifp = sc->bce_ifp = if_alloc(IFT_ETHER);
 1380         if (ifp == NULL) {
 1381                 BCE_PRINTF("%s(%d): Interface allocation failed!\n",
 1382                     __FILE__, __LINE__);
 1383                 rc = ENXIO;
 1384                 goto bce_attach_fail;
 1385         }
 1386 
 1387         /* Initialize the ifnet interface. */
 1388         ifp->if_softc   = sc;
 1389         if_initname(ifp, device_get_name(dev), device_get_unit(dev));
 1390         ifp->if_flags   = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
 1391         ifp->if_ioctl   = bce_ioctl;
 1392         ifp->if_start   = bce_start;
 1393         ifp->if_get_counter = bce_get_counter;
 1394         ifp->if_init    = bce_init;
 1395         ifp->if_mtu     = ETHERMTU;
 1396 
 1397         if (bce_tso_enable) {
 1398                 ifp->if_hwassist = BCE_IF_HWASSIST | CSUM_TSO;
 1399                 ifp->if_capabilities = BCE_IF_CAPABILITIES | IFCAP_TSO4 |
 1400                     IFCAP_VLAN_HWTSO;
 1401         } else {
 1402                 ifp->if_hwassist = BCE_IF_HWASSIST;
 1403                 ifp->if_capabilities = BCE_IF_CAPABILITIES;
 1404         }
 1405 
 1406 #if __FreeBSD_version >= 800505
 1407         /*
 1408          * Introducing IFCAP_LINKSTATE didn't bump __FreeBSD_version
 1409          * so it's approximate value.
 1410          */
 1411         if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
 1412                 ifp->if_capabilities |= IFCAP_LINKSTATE;
 1413 #endif
 1414 
 1415         ifp->if_capenable = ifp->if_capabilities;
 1416 
 1417         /*
 1418          * Assume standard mbuf sizes for buffer allocation.
 1419          * This may change later if the MTU size is set to
 1420          * something other than 1500.
 1421          */
 1422         bce_get_rx_buffer_sizes(sc,
 1423             (ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN));
 1424 
 1425         /* Recalculate our buffer allocation sizes. */
 1426         ifp->if_snd.ifq_drv_maxlen = USABLE_TX_BD_ALLOC;
 1427         IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
 1428         IFQ_SET_READY(&ifp->if_snd);
 1429 
 1430         if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG)
 1431                 ifp->if_baudrate = IF_Mbps(2500ULL);
 1432         else
 1433                 ifp->if_baudrate = IF_Mbps(1000);
 1434 
 1435         /* Handle any special PHY initialization for SerDes PHYs. */
 1436         bce_init_media(sc);
 1437 
 1438         if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
 1439                 ifmedia_init(&sc->bce_ifmedia, IFM_IMASK, bce_ifmedia_upd,
 1440                     bce_ifmedia_sts);
 1441                 /*
 1442                  * We can't manually override remote PHY's link and assume
 1443                  * PHY port configuration(Fiber or TP) is not changed after
 1444                  * device attach.  This may not be correct though.
 1445                  */
 1446                 if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) != 0) {
 1447                         if (sc->bce_phy_flags & BCE_PHY_2_5G_CAPABLE_FLAG) {
 1448                                 ifmedia_add(&sc->bce_ifmedia,
 1449                                     IFM_ETHER | IFM_2500_SX, 0, NULL);
 1450                                 ifmedia_add(&sc->bce_ifmedia,
 1451                                     IFM_ETHER | IFM_2500_SX | IFM_FDX, 0, NULL);
 1452                         }
 1453                         ifmedia_add(&sc->bce_ifmedia,
 1454                             IFM_ETHER | IFM_1000_SX, 0, NULL);
 1455                         ifmedia_add(&sc->bce_ifmedia,
 1456                             IFM_ETHER | IFM_1000_SX | IFM_FDX, 0, NULL);
 1457                 } else {
 1458                         ifmedia_add(&sc->bce_ifmedia,
 1459                             IFM_ETHER | IFM_10_T, 0, NULL);
 1460                         ifmedia_add(&sc->bce_ifmedia,
 1461                             IFM_ETHER | IFM_10_T | IFM_FDX, 0, NULL);
 1462                         ifmedia_add(&sc->bce_ifmedia,
 1463                             IFM_ETHER | IFM_100_TX, 0, NULL);
 1464                         ifmedia_add(&sc->bce_ifmedia,
 1465                             IFM_ETHER | IFM_100_TX | IFM_FDX, 0, NULL);
 1466                         ifmedia_add(&sc->bce_ifmedia,
 1467                             IFM_ETHER | IFM_1000_T, 0, NULL);
 1468                         ifmedia_add(&sc->bce_ifmedia,
 1469                             IFM_ETHER | IFM_1000_T | IFM_FDX, 0, NULL);
 1470                 }
 1471                 ifmedia_add(&sc->bce_ifmedia, IFM_ETHER | IFM_AUTO, 0, NULL);
 1472                 ifmedia_set(&sc->bce_ifmedia, IFM_ETHER | IFM_AUTO);
 1473                 sc->bce_ifmedia.ifm_media = sc->bce_ifmedia.ifm_cur->ifm_media;
 1474         } else {
 1475                 /* MII child bus by attaching the PHY. */
 1476                 rc = mii_attach(dev, &sc->bce_miibus, ifp, bce_ifmedia_upd,
 1477                     bce_ifmedia_sts, BMSR_DEFCAPMASK, sc->bce_phy_addr,
 1478                     MII_OFFSET_ANY, MIIF_DOPAUSE);
 1479                 if (rc != 0) {
 1480                         BCE_PRINTF("%s(%d): attaching PHYs failed\n", __FILE__,
 1481                             __LINE__);
 1482                         goto bce_attach_fail;
 1483                 }
 1484         }
 1485 
 1486         /* Attach to the Ethernet interface list. */
 1487         ether_ifattach(ifp, sc->eaddr);
 1488 
 1489 #if __FreeBSD_version < 500000
 1490         callout_init(&sc->bce_tick_callout);
 1491         callout_init(&sc->bce_pulse_callout);
 1492 #else
 1493         callout_init_mtx(&sc->bce_tick_callout, &sc->bce_mtx, 0);
 1494         callout_init_mtx(&sc->bce_pulse_callout, &sc->bce_mtx, 0);
 1495 #endif
 1496 
 1497         /* Hookup IRQ last. */
 1498         rc = bus_setup_intr(dev, sc->bce_res_irq, INTR_TYPE_NET | INTR_MPSAFE,
 1499                 NULL, bce_intr, sc, &sc->bce_intrhand);
 1500 
 1501         if (rc) {
 1502                 BCE_PRINTF("%s(%d): Failed to setup IRQ!\n",
 1503                     __FILE__, __LINE__);
 1504                 bce_detach(dev);
 1505                 goto bce_attach_exit;
 1506         }
 1507 
 1508         /*
 1509          * At this point we've acquired all the resources
 1510          * we need to run so there's no turning back, we're
 1511          * cleared for launch.
 1512          */
 1513 
 1514         /* Print some important debugging info. */
 1515         DBRUNMSG(BCE_INFO, bce_dump_driver_state(sc));
 1516 
 1517         /* Add the supported sysctls to the kernel. */
 1518         bce_add_sysctls(sc);
 1519 
 1520         BCE_LOCK(sc);
 1521 
 1522         /*
 1523          * The chip reset earlier notified the bootcode that
 1524          * a driver is present.  We now need to start our pulse
 1525          * routine so that the bootcode is reminded that we're
 1526          * still running.
 1527          */
 1528         bce_pulse(sc);
 1529 
 1530         bce_mgmt_init_locked(sc);
 1531         BCE_UNLOCK(sc);
 1532 
 1533         /* Finally, print some useful adapter info */
 1534         bce_print_adapter_info(sc);
 1535         DBPRINT(sc, BCE_FATAL, "%s(): sc = %p\n",
 1536                 __FUNCTION__, sc);
 1537 
 1538         goto bce_attach_exit;
 1539 
 1540 bce_attach_fail:
 1541         bce_release_resources(sc);
 1542 
 1543 bce_attach_exit:
 1544 
 1545         DBEXIT(BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
 1546 
 1547         return(rc);
 1548 }
 1549 
 1550 
 1551 /****************************************************************************/
 1552 /* Device detach function.                                                  */
 1553 /*                                                                          */
 1554 /* Stops the controller, resets the controller, and releases resources.     */
 1555 /*                                                                          */
 1556 /* Returns:                                                                 */
 1557 /*   0 on success, positive value on failure.                               */
 1558 /****************************************************************************/
 1559 static int
 1560 bce_detach(device_t dev)
 1561 {
 1562         struct bce_softc *sc = device_get_softc(dev);
 1563         struct ifnet *ifp;
 1564         u32 msg;
 1565 
 1566         DBENTER(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
 1567 
 1568         ifp = sc->bce_ifp;
 1569 
 1570         /* Stop and reset the controller. */
 1571         BCE_LOCK(sc);
 1572 
 1573         /* Stop the pulse so the bootcode can go to driver absent state. */
 1574         callout_stop(&sc->bce_pulse_callout);
 1575 
 1576         bce_stop(sc);
 1577         if (sc->bce_flags & BCE_NO_WOL_FLAG)
 1578                 msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
 1579         else
 1580                 msg = BCE_DRV_MSG_CODE_UNLOAD;
 1581         bce_reset(sc, msg);
 1582 
 1583         BCE_UNLOCK(sc);
 1584 
 1585         ether_ifdetach(ifp);
 1586 
 1587         /* If we have a child device on the MII bus remove it too. */
 1588         if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
 1589                 ifmedia_removeall(&sc->bce_ifmedia);
 1590         else {
 1591                 bus_generic_detach(dev);
 1592                 device_delete_child(dev, sc->bce_miibus);
 1593         }
 1594 
 1595         /* Release all remaining resources. */
 1596         bce_release_resources(sc);
 1597 
 1598         DBEXIT(BCE_VERBOSE_UNLOAD | BCE_VERBOSE_RESET);
 1599 
 1600         return(0);
 1601 }
 1602 
 1603 
 1604 /****************************************************************************/
 1605 /* Device shutdown function.                                                */
 1606 /*                                                                          */
 1607 /* Stops and resets the controller.                                         */
 1608 /*                                                                          */
 1609 /* Returns:                                                                 */
 1610 /*   0 on success, positive value on failure.                               */
 1611 /****************************************************************************/
 1612 static int
 1613 bce_shutdown(device_t dev)
 1614 {
 1615         struct bce_softc *sc = device_get_softc(dev);
 1616         u32 msg;
 1617 
 1618         DBENTER(BCE_VERBOSE);
 1619 
 1620         BCE_LOCK(sc);
 1621         bce_stop(sc);
 1622         if (sc->bce_flags & BCE_NO_WOL_FLAG)
 1623                 msg = BCE_DRV_MSG_CODE_UNLOAD_LNK_DN;
 1624         else
 1625                 msg = BCE_DRV_MSG_CODE_UNLOAD;
 1626         bce_reset(sc, msg);
 1627         BCE_UNLOCK(sc);
 1628 
 1629         DBEXIT(BCE_VERBOSE);
 1630 
 1631         return (0);
 1632 }
 1633 
 1634 
 1635 #ifdef BCE_DEBUG
 1636 /****************************************************************************/
 1637 /* Register read.                                                           */
 1638 /*                                                                          */
 1639 /* Returns:                                                                 */
 1640 /*   The value of the register.                                             */
 1641 /****************************************************************************/
 1642 static u32
 1643 bce_reg_rd(struct bce_softc *sc, u32 offset)
 1644 {
 1645         u32 val = REG_RD(sc, offset);
 1646         DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
 1647                 __FUNCTION__, offset, val);
 1648         return val;
 1649 }
 1650 
 1651 
 1652 /****************************************************************************/
 1653 /* Register write (16 bit).                                                 */
 1654 /*                                                                          */
 1655 /* Returns:                                                                 */
 1656 /*   Nothing.                                                               */
 1657 /****************************************************************************/
 1658 static void
 1659 bce_reg_wr16(struct bce_softc *sc, u32 offset, u16 val)
 1660 {
 1661         DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%04X\n",
 1662                 __FUNCTION__, offset, val);
 1663         REG_WR16(sc, offset, val);
 1664 }
 1665 
 1666 
 1667 /****************************************************************************/
 1668 /* Register write.                                                          */
 1669 /*                                                                          */
 1670 /* Returns:                                                                 */
 1671 /*   Nothing.                                                               */
 1672 /****************************************************************************/
 1673 static void
 1674 bce_reg_wr(struct bce_softc *sc, u32 offset, u32 val)
 1675 {
 1676         DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
 1677                 __FUNCTION__, offset, val);
 1678         REG_WR(sc, offset, val);
 1679 }
 1680 #endif
 1681 
 1682 /****************************************************************************/
 1683 /* Indirect register read.                                                  */
 1684 /*                                                                          */
 1685 /* Reads NetXtreme II registers using an index/data register pair in PCI    */
 1686 /* configuration space.  Using this mechanism avoids issues with posted     */
 1687 /* reads but is much slower than memory-mapped I/O.                         */
 1688 /*                                                                          */
 1689 /* Returns:                                                                 */
 1690 /*   The value of the register.                                             */
 1691 /****************************************************************************/
 1692 static u32
 1693 bce_reg_rd_ind(struct bce_softc *sc, u32 offset)
 1694 {
 1695         device_t dev;
 1696         dev = sc->bce_dev;
 1697 
 1698         pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
 1699 #ifdef BCE_DEBUG
 1700         {
 1701                 u32 val;
 1702                 val = pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
 1703                 DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
 1704                         __FUNCTION__, offset, val);
 1705                 return val;
 1706         }
 1707 #else
 1708         return pci_read_config(dev, BCE_PCICFG_REG_WINDOW, 4);
 1709 #endif
 1710 }
 1711 
 1712 
 1713 /****************************************************************************/
 1714 /* Indirect register write.                                                 */
 1715 /*                                                                          */
 1716 /* Writes NetXtreme II registers using an index/data register pair in PCI   */
 1717 /* configuration space.  Using this mechanism avoids issues with posted     */
 1718 /* writes but is muchh slower than memory-mapped I/O.                       */
 1719 /*                                                                          */
 1720 /* Returns:                                                                 */
 1721 /*   Nothing.                                                               */
 1722 /****************************************************************************/
 1723 static void
 1724 bce_reg_wr_ind(struct bce_softc *sc, u32 offset, u32 val)
 1725 {
 1726         device_t dev;
 1727         dev = sc->bce_dev;
 1728 
 1729         DBPRINT(sc, BCE_INSANE_REG, "%s(); offset = 0x%08X, val = 0x%08X\n",
 1730                 __FUNCTION__, offset, val);
 1731 
 1732         pci_write_config(dev, BCE_PCICFG_REG_WINDOW_ADDRESS, offset, 4);
 1733         pci_write_config(dev, BCE_PCICFG_REG_WINDOW, val, 4);
 1734 }
 1735 
 1736 
 1737 /****************************************************************************/
 1738 /* Shared memory write.                                                     */
 1739 /*                                                                          */
 1740 /* Writes NetXtreme II shared memory region.                                */
 1741 /*                                                                          */
 1742 /* Returns:                                                                 */
 1743 /*   Nothing.                                                               */
 1744 /****************************************************************************/
 1745 static void
 1746 bce_shmem_wr(struct bce_softc *sc, u32 offset, u32 val)
 1747 {
 1748         DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): Writing 0x%08X  to  "
 1749             "0x%08X\n", __FUNCTION__, val, offset);
 1750 
 1751         bce_reg_wr_ind(sc, sc->bce_shmem_base + offset, val);
 1752 }
 1753 
 1754 
 1755 /****************************************************************************/
 1756 /* Shared memory read.                                                      */
 1757 /*                                                                          */
 1758 /* Reads NetXtreme II shared memory region.                                 */
 1759 /*                                                                          */
 1760 /* Returns:                                                                 */
 1761 /*   The 32 bit value read.                                                 */
 1762 /****************************************************************************/
 1763 static u32
 1764 bce_shmem_rd(struct bce_softc *sc, u32 offset)
 1765 {
 1766         u32 val = bce_reg_rd_ind(sc, sc->bce_shmem_base + offset);
 1767 
 1768         DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "%s(): Reading 0x%08X from "
 1769             "0x%08X\n", __FUNCTION__, val, offset);
 1770 
 1771         return val;
 1772 }
 1773 
 1774 
 1775 #ifdef BCE_DEBUG
 1776 /****************************************************************************/
 1777 /* Context memory read.                                                     */
 1778 /*                                                                          */
 1779 /* The NetXtreme II controller uses context memory to track connection      */
 1780 /* information for L2 and higher network protocols.                         */
 1781 /*                                                                          */
 1782 /* Returns:                                                                 */
 1783 /*   The requested 32 bit value of context memory.                          */
 1784 /****************************************************************************/
 1785 static u32
 1786 bce_ctx_rd(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset)
 1787 {
 1788         u32 idx, offset, retry_cnt = 5, val;
 1789 
 1790         DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 ||
 1791             cid_addr & CTX_MASK), BCE_PRINTF("%s(): Invalid CID "
 1792             "address: 0x%08X.\n", __FUNCTION__, cid_addr));
 1793 
 1794         offset = ctx_offset + cid_addr;
 1795 
 1796         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 1797 
 1798                 REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_READ_REQ));
 1799 
 1800                 for (idx = 0; idx < retry_cnt; idx++) {
 1801                         val = REG_RD(sc, BCE_CTX_CTX_CTRL);
 1802                         if ((val & BCE_CTX_CTX_CTRL_READ_REQ) == 0)
 1803                                 break;
 1804                         DELAY(5);
 1805                 }
 1806 
 1807                 if (val & BCE_CTX_CTX_CTRL_READ_REQ)
 1808                         BCE_PRINTF("%s(%d); Unable to read CTX memory: "
 1809                             "cid_addr = 0x%08X, offset = 0x%08X!\n",
 1810                             __FILE__, __LINE__, cid_addr, ctx_offset);
 1811 
 1812                 val = REG_RD(sc, BCE_CTX_CTX_DATA);
 1813         } else {
 1814                 REG_WR(sc, BCE_CTX_DATA_ADR, offset);
 1815                 val = REG_RD(sc, BCE_CTX_DATA);
 1816         }
 1817 
 1818         DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
 1819                 "val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, val);
 1820 
 1821         return(val);
 1822 }
 1823 #endif
 1824 
 1825 
 1826 /****************************************************************************/
 1827 /* Context memory write.                                                    */
 1828 /*                                                                          */
 1829 /* The NetXtreme II controller uses context memory to track connection      */
 1830 /* information for L2 and higher network protocols.                         */
 1831 /*                                                                          */
 1832 /* Returns:                                                                 */
 1833 /*   Nothing.                                                               */
 1834 /****************************************************************************/
 1835 static void
 1836 bce_ctx_wr(struct bce_softc *sc, u32 cid_addr, u32 ctx_offset, u32 ctx_val)
 1837 {
 1838         u32 idx, offset = ctx_offset + cid_addr;
 1839         u32 val, retry_cnt = 5;
 1840 
 1841         DBPRINT(sc, BCE_EXTREME_CTX, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
 1842                 "val = 0x%08X\n", __FUNCTION__, cid_addr, ctx_offset, ctx_val);
 1843 
 1844         DBRUNIF((cid_addr > MAX_CID_ADDR || ctx_offset & 0x3 || cid_addr & CTX_MASK),
 1845                 BCE_PRINTF("%s(): Invalid CID address: 0x%08X.\n",
 1846                     __FUNCTION__, cid_addr));
 1847 
 1848         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 1849 
 1850                 REG_WR(sc, BCE_CTX_CTX_DATA, ctx_val);
 1851                 REG_WR(sc, BCE_CTX_CTX_CTRL, (offset | BCE_CTX_CTX_CTRL_WRITE_REQ));
 1852 
 1853                 for (idx = 0; idx < retry_cnt; idx++) {
 1854                         val = REG_RD(sc, BCE_CTX_CTX_CTRL);
 1855                         if ((val & BCE_CTX_CTX_CTRL_WRITE_REQ) == 0)
 1856                                 break;
 1857                         DELAY(5);
 1858                 }
 1859 
 1860                 if (val & BCE_CTX_CTX_CTRL_WRITE_REQ)
 1861                         BCE_PRINTF("%s(%d); Unable to write CTX memory: "
 1862                             "cid_addr = 0x%08X, offset = 0x%08X!\n",
 1863                             __FILE__, __LINE__, cid_addr, ctx_offset);
 1864 
 1865         } else {
 1866                 REG_WR(sc, BCE_CTX_DATA_ADR, offset);
 1867                 REG_WR(sc, BCE_CTX_DATA, ctx_val);
 1868         }
 1869 }
 1870 
 1871 
 1872 /****************************************************************************/
 1873 /* PHY register read.                                                       */
 1874 /*                                                                          */
 1875 /* Implements register reads on the MII bus.                                */
 1876 /*                                                                          */
 1877 /* Returns:                                                                 */
 1878 /*   The value of the register.                                             */
 1879 /****************************************************************************/
 1880 static int
 1881 bce_miibus_read_reg(device_t dev, int phy, int reg)
 1882 {
 1883         struct bce_softc *sc;
 1884         u32 val;
 1885         int i;
 1886 
 1887         sc = device_get_softc(dev);
 1888 
 1889     /*
 1890      * The 5709S PHY is an IEEE Clause 45 PHY
 1891      * with special mappings to work with IEEE
 1892      * Clause 22 register accesses.
 1893      */
 1894         if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
 1895                 if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
 1896                         reg += 0x10;
 1897         }
 1898 
 1899     if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
 1900                 val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
 1901                 val &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
 1902 
 1903                 REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
 1904                 REG_RD(sc, BCE_EMAC_MDIO_MODE);
 1905 
 1906                 DELAY(40);
 1907         }
 1908 
 1909 
 1910         val = BCE_MIPHY(phy) | BCE_MIREG(reg) |
 1911             BCE_EMAC_MDIO_COMM_COMMAND_READ | BCE_EMAC_MDIO_COMM_DISEXT |
 1912             BCE_EMAC_MDIO_COMM_START_BUSY;
 1913         REG_WR(sc, BCE_EMAC_MDIO_COMM, val);
 1914 
 1915         for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
 1916                 DELAY(10);
 1917 
 1918                 val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
 1919                 if (!(val & BCE_EMAC_MDIO_COMM_START_BUSY)) {
 1920                         DELAY(5);
 1921 
 1922                         val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
 1923                         val &= BCE_EMAC_MDIO_COMM_DATA;
 1924 
 1925                         break;
 1926                 }
 1927         }
 1928 
 1929         if (val & BCE_EMAC_MDIO_COMM_START_BUSY) {
 1930                 BCE_PRINTF("%s(%d): Error: PHY read timeout! phy = %d, "
 1931                     "reg = 0x%04X\n", __FILE__, __LINE__, phy, reg);
 1932                 val = 0x0;
 1933         } else {
 1934                 val = REG_RD(sc, BCE_EMAC_MDIO_COMM);
 1935         }
 1936 
 1937 
 1938         if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
 1939                 val = REG_RD(sc, BCE_EMAC_MDIO_MODE);
 1940                 val |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
 1941 
 1942                 REG_WR(sc, BCE_EMAC_MDIO_MODE, val);
 1943                 REG_RD(sc, BCE_EMAC_MDIO_MODE);
 1944 
 1945                 DELAY(40);
 1946         }
 1947 
 1948         DB_PRINT_PHY_REG(reg, val);
 1949         return (val & 0xffff);
 1950 }
 1951 
 1952 
 1953 /****************************************************************************/
 1954 /* PHY register write.                                                      */
 1955 /*                                                                          */
 1956 /* Implements register writes on the MII bus.                               */
 1957 /*                                                                          */
 1958 /* Returns:                                                                 */
 1959 /*   The value of the register.                                             */
 1960 /****************************************************************************/
 1961 static int
 1962 bce_miibus_write_reg(device_t dev, int phy, int reg, int val)
 1963 {
 1964         struct bce_softc *sc;
 1965         u32 val1;
 1966         int i;
 1967 
 1968         sc = device_get_softc(dev);
 1969 
 1970         DB_PRINT_PHY_REG(reg, val);
 1971 
 1972         /*
 1973          * The 5709S PHY is an IEEE Clause 45 PHY
 1974          * with special mappings to work with IEEE
 1975          * Clause 22 register accesses.
 1976          */
 1977         if ((sc->bce_phy_flags & BCE_PHY_IEEE_CLAUSE_45_FLAG) != 0) {
 1978                 if (reg >= MII_BMCR && reg <= MII_ANLPRNP)
 1979                         reg += 0x10;
 1980         }
 1981 
 1982         if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
 1983                 val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
 1984                 val1 &= ~BCE_EMAC_MDIO_MODE_AUTO_POLL;
 1985 
 1986                 REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
 1987                 REG_RD(sc, BCE_EMAC_MDIO_MODE);
 1988 
 1989                 DELAY(40);
 1990         }
 1991 
 1992         val1 = BCE_MIPHY(phy) | BCE_MIREG(reg) | val |
 1993             BCE_EMAC_MDIO_COMM_COMMAND_WRITE |
 1994             BCE_EMAC_MDIO_COMM_START_BUSY | BCE_EMAC_MDIO_COMM_DISEXT;
 1995         REG_WR(sc, BCE_EMAC_MDIO_COMM, val1);
 1996 
 1997         for (i = 0; i < BCE_PHY_TIMEOUT; i++) {
 1998                 DELAY(10);
 1999 
 2000                 val1 = REG_RD(sc, BCE_EMAC_MDIO_COMM);
 2001                 if (!(val1 & BCE_EMAC_MDIO_COMM_START_BUSY)) {
 2002                         DELAY(5);
 2003                         break;
 2004                 }
 2005         }
 2006 
 2007         if (val1 & BCE_EMAC_MDIO_COMM_START_BUSY)
 2008                 BCE_PRINTF("%s(%d): PHY write timeout!\n",
 2009                     __FILE__, __LINE__);
 2010 
 2011         if (sc->bce_phy_flags & BCE_PHY_INT_MODE_AUTO_POLLING_FLAG) {
 2012                 val1 = REG_RD(sc, BCE_EMAC_MDIO_MODE);
 2013                 val1 |= BCE_EMAC_MDIO_MODE_AUTO_POLL;
 2014 
 2015                 REG_WR(sc, BCE_EMAC_MDIO_MODE, val1);
 2016                 REG_RD(sc, BCE_EMAC_MDIO_MODE);
 2017 
 2018                 DELAY(40);
 2019         }
 2020 
 2021         return 0;
 2022 }
 2023 
 2024 
 2025 /****************************************************************************/
 2026 /* MII bus status change.                                                   */
 2027 /*                                                                          */
 2028 /* Called by the MII bus driver when the PHY establishes link to set the    */
 2029 /* MAC interface registers.                                                 */
 2030 /*                                                                          */
 2031 /* Returns:                                                                 */
 2032 /*   Nothing.                                                               */
 2033 /****************************************************************************/
 2034 static void
 2035 bce_miibus_statchg(device_t dev)
 2036 {
 2037         struct bce_softc *sc;
 2038         struct mii_data *mii;
 2039         struct ifmediareq ifmr;
 2040         int media_active, media_status, val;
 2041 
 2042         sc = device_get_softc(dev);
 2043 
 2044         DBENTER(BCE_VERBOSE_PHY);
 2045 
 2046         if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
 2047                 bzero(&ifmr, sizeof(ifmr));
 2048                 bce_ifmedia_sts_rphy(sc, &ifmr);
 2049                 media_active = ifmr.ifm_active;
 2050                 media_status = ifmr.ifm_status;
 2051         } else {
 2052                 mii = device_get_softc(sc->bce_miibus);
 2053                 media_active = mii->mii_media_active;
 2054                 media_status = mii->mii_media_status;
 2055         }
 2056 
 2057         /* Ignore invalid media status. */
 2058         if ((media_status & (IFM_ACTIVE | IFM_AVALID)) !=
 2059             (IFM_ACTIVE | IFM_AVALID))
 2060                 goto bce_miibus_statchg_exit;
 2061 
 2062         val = REG_RD(sc, BCE_EMAC_MODE);
 2063         val &= ~(BCE_EMAC_MODE_PORT | BCE_EMAC_MODE_HALF_DUPLEX |
 2064             BCE_EMAC_MODE_MAC_LOOP | BCE_EMAC_MODE_FORCE_LINK |
 2065             BCE_EMAC_MODE_25G);
 2066 
 2067         /* Set MII or GMII interface based on the PHY speed. */
 2068         switch (IFM_SUBTYPE(media_active)) {
 2069         case IFM_10_T:
 2070                 if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
 2071                         DBPRINT(sc, BCE_INFO_PHY,
 2072                             "Enabling 10Mb interface.\n");
 2073                         val |= BCE_EMAC_MODE_PORT_MII_10;
 2074                         break;
 2075                 }
 2076                 /* fall-through */
 2077         case IFM_100_TX:
 2078                 DBPRINT(sc, BCE_INFO_PHY, "Enabling MII interface.\n");
 2079                 val |= BCE_EMAC_MODE_PORT_MII;
 2080                 break;
 2081         case IFM_2500_SX:
 2082                 DBPRINT(sc, BCE_INFO_PHY, "Enabling 2.5G MAC mode.\n");
 2083                 val |= BCE_EMAC_MODE_25G;
 2084                 /* fall-through */
 2085         case IFM_1000_T:
 2086         case IFM_1000_SX:
 2087                 DBPRINT(sc, BCE_INFO_PHY, "Enabling GMII interface.\n");
 2088                 val |= BCE_EMAC_MODE_PORT_GMII;
 2089                 break;
 2090         default:
 2091                 DBPRINT(sc, BCE_INFO_PHY, "Unknown link speed, enabling "
 2092                     "default GMII interface.\n");
 2093                 val |= BCE_EMAC_MODE_PORT_GMII;
 2094         }
 2095 
 2096         /* Set half or full duplex based on PHY settings. */
 2097         if ((IFM_OPTIONS(media_active) & IFM_FDX) == 0) {
 2098                 DBPRINT(sc, BCE_INFO_PHY,
 2099                     "Setting Half-Duplex interface.\n");
 2100                 val |= BCE_EMAC_MODE_HALF_DUPLEX;
 2101         } else
 2102                 DBPRINT(sc, BCE_INFO_PHY,
 2103                     "Setting Full-Duplex interface.\n");
 2104 
 2105         REG_WR(sc, BCE_EMAC_MODE, val);
 2106 
 2107         if ((IFM_OPTIONS(media_active) & IFM_ETH_RXPAUSE) != 0) {
 2108                 DBPRINT(sc, BCE_INFO_PHY,
 2109                     "%s(): Enabling RX flow control.\n", __FUNCTION__);
 2110                 BCE_SETBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
 2111                 sc->bce_flags |= BCE_USING_RX_FLOW_CONTROL;
 2112         } else {
 2113                 DBPRINT(sc, BCE_INFO_PHY,
 2114                     "%s(): Disabling RX flow control.\n", __FUNCTION__);
 2115                 BCE_CLRBIT(sc, BCE_EMAC_RX_MODE, BCE_EMAC_RX_MODE_FLOW_EN);
 2116                 sc->bce_flags &= ~BCE_USING_RX_FLOW_CONTROL;
 2117         }
 2118 
 2119         if ((IFM_OPTIONS(media_active) & IFM_ETH_TXPAUSE) != 0) {
 2120                 DBPRINT(sc, BCE_INFO_PHY,
 2121                     "%s(): Enabling TX flow control.\n", __FUNCTION__);
 2122                 BCE_SETBIT(sc, BCE_EMAC_TX_MODE, BCE_EMAC_TX_MODE_FLOW_EN);
 2123                 sc->bce_flags |= BCE_USING_TX_FLOW_CONTROL;
 2124         } else {
 2125                 DBPRINT(sc, BCE_INFO_PHY,
 2126                     "%s(): Disabling TX flow control.\n", __FUNCTION__);
 2127                 BCE_CLRBIT(sc, BCE_EMAC_TX_MODE, BCE_EMAC_TX_MODE_FLOW_EN);
 2128                 sc->bce_flags &= ~BCE_USING_TX_FLOW_CONTROL;
 2129         }
 2130 
 2131         /* ToDo: Update watermarks in bce_init_rx_context(). */
 2132 
 2133 bce_miibus_statchg_exit:
 2134         DBEXIT(BCE_VERBOSE_PHY);
 2135 }
 2136 
 2137 
 2138 /****************************************************************************/
 2139 /* Acquire NVRAM lock.                                                      */
 2140 /*                                                                          */
 2141 /* Before the NVRAM can be accessed the caller must acquire an NVRAM lock.  */
 2142 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
 2143 /* for use by the driver.                                                   */
 2144 /*                                                                          */
 2145 /* Returns:                                                                 */
 2146 /*   0 on success, positive value on failure.                               */
 2147 /****************************************************************************/
 2148 static int
 2149 bce_acquire_nvram_lock(struct bce_softc *sc)
 2150 {
 2151         u32 val;
 2152         int j, rc = 0;
 2153 
 2154         DBENTER(BCE_VERBOSE_NVRAM);
 2155 
 2156         /* Request access to the flash interface. */
 2157         REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_SET2);
 2158         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
 2159                 val = REG_RD(sc, BCE_NVM_SW_ARB);
 2160                 if (val & BCE_NVM_SW_ARB_ARB_ARB2)
 2161                         break;
 2162 
 2163                 DELAY(5);
 2164         }
 2165 
 2166         if (j >= NVRAM_TIMEOUT_COUNT) {
 2167                 DBPRINT(sc, BCE_WARN, "Timeout acquiring NVRAM lock!\n");
 2168                 rc = EBUSY;
 2169         }
 2170 
 2171         DBEXIT(BCE_VERBOSE_NVRAM);
 2172         return (rc);
 2173 }
 2174 
 2175 
 2176 /****************************************************************************/
 2177 /* Release NVRAM lock.                                                      */
 2178 /*                                                                          */
 2179 /* When the caller is finished accessing NVRAM the lock must be released.   */
 2180 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
 2181 /* for use by the driver.                                                   */
 2182 /*                                                                          */
 2183 /* Returns:                                                                 */
 2184 /*   0 on success, positive value on failure.                               */
 2185 /****************************************************************************/
 2186 static int
 2187 bce_release_nvram_lock(struct bce_softc *sc)
 2188 {
 2189         u32 val;
 2190         int j, rc = 0;
 2191 
 2192         DBENTER(BCE_VERBOSE_NVRAM);
 2193 
 2194         /*
 2195          * Relinquish nvram interface.
 2196          */
 2197         REG_WR(sc, BCE_NVM_SW_ARB, BCE_NVM_SW_ARB_ARB_REQ_CLR2);
 2198 
 2199         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
 2200                 val = REG_RD(sc, BCE_NVM_SW_ARB);
 2201                 if (!(val & BCE_NVM_SW_ARB_ARB_ARB2))
 2202                         break;
 2203 
 2204                 DELAY(5);
 2205         }
 2206 
 2207         if (j >= NVRAM_TIMEOUT_COUNT) {
 2208                 DBPRINT(sc, BCE_WARN, "Timeout releasing NVRAM lock!\n");
 2209                 rc = EBUSY;
 2210         }
 2211 
 2212         DBEXIT(BCE_VERBOSE_NVRAM);
 2213         return (rc);
 2214 }
 2215 
 2216 
 2217 #ifdef BCE_NVRAM_WRITE_SUPPORT
 2218 /****************************************************************************/
 2219 /* Enable NVRAM write access.                                               */
 2220 /*                                                                          */
 2221 /* Before writing to NVRAM the caller must enable NVRAM writes.             */
 2222 /*                                                                          */
 2223 /* Returns:                                                                 */
 2224 /*   0 on success, positive value on failure.                               */
 2225 /****************************************************************************/
 2226 static int
 2227 bce_enable_nvram_write(struct bce_softc *sc)
 2228 {
 2229         u32 val;
 2230         int rc = 0;
 2231 
 2232         DBENTER(BCE_VERBOSE_NVRAM);
 2233 
 2234         val = REG_RD(sc, BCE_MISC_CFG);
 2235         REG_WR(sc, BCE_MISC_CFG, val | BCE_MISC_CFG_NVM_WR_EN_PCI);
 2236 
 2237         if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
 2238                 int j;
 2239 
 2240                 REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
 2241                 REG_WR(sc, BCE_NVM_COMMAND,     BCE_NVM_COMMAND_WREN | BCE_NVM_COMMAND_DOIT);
 2242 
 2243                 for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
 2244                         DELAY(5);
 2245 
 2246                         val = REG_RD(sc, BCE_NVM_COMMAND);
 2247                         if (val & BCE_NVM_COMMAND_DONE)
 2248                                 break;
 2249                 }
 2250 
 2251                 if (j >= NVRAM_TIMEOUT_COUNT) {
 2252                         DBPRINT(sc, BCE_WARN, "Timeout writing NVRAM!\n");
 2253                         rc = EBUSY;
 2254                 }
 2255         }
 2256 
 2257         DBENTER(BCE_VERBOSE_NVRAM);
 2258         return (rc);
 2259 }
 2260 
 2261 
 2262 /****************************************************************************/
 2263 /* Disable NVRAM write access.                                              */
 2264 /*                                                                          */
 2265 /* When the caller is finished writing to NVRAM write access must be        */
 2266 /* disabled.                                                                */
 2267 /*                                                                          */
 2268 /* Returns:                                                                 */
 2269 /*   Nothing.                                                               */
 2270 /****************************************************************************/
 2271 static void
 2272 bce_disable_nvram_write(struct bce_softc *sc)
 2273 {
 2274         u32 val;
 2275 
 2276         DBENTER(BCE_VERBOSE_NVRAM);
 2277 
 2278         val = REG_RD(sc, BCE_MISC_CFG);
 2279         REG_WR(sc, BCE_MISC_CFG, val & ~BCE_MISC_CFG_NVM_WR_EN);
 2280 
 2281         DBEXIT(BCE_VERBOSE_NVRAM);
 2282 
 2283 }
 2284 #endif
 2285 
 2286 
 2287 /****************************************************************************/
 2288 /* Enable NVRAM access.                                                     */
 2289 /*                                                                          */
 2290 /* Before accessing NVRAM for read or write operations the caller must      */
 2291 /* enabled NVRAM access.                                                    */
 2292 /*                                                                          */
 2293 /* Returns:                                                                 */
 2294 /*   Nothing.                                                               */
 2295 /****************************************************************************/
 2296 static void
 2297 bce_enable_nvram_access(struct bce_softc *sc)
 2298 {
 2299         u32 val;
 2300 
 2301         DBENTER(BCE_VERBOSE_NVRAM);
 2302 
 2303         val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
 2304         /* Enable both bits, even on read. */
 2305         REG_WR(sc, BCE_NVM_ACCESS_ENABLE, val |
 2306             BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN);
 2307 
 2308         DBEXIT(BCE_VERBOSE_NVRAM);
 2309 }
 2310 
 2311 
 2312 /****************************************************************************/
 2313 /* Disable NVRAM access.                                                    */
 2314 /*                                                                          */
 2315 /* When the caller is finished accessing NVRAM access must be disabled.     */
 2316 /*                                                                          */
 2317 /* Returns:                                                                 */
 2318 /*   Nothing.                                                               */
 2319 /****************************************************************************/
 2320 static void
 2321 bce_disable_nvram_access(struct bce_softc *sc)
 2322 {
 2323         u32 val;
 2324 
 2325         DBENTER(BCE_VERBOSE_NVRAM);
 2326 
 2327         val = REG_RD(sc, BCE_NVM_ACCESS_ENABLE);
 2328 
 2329         /* Disable both bits, even after read. */
 2330         REG_WR(sc, BCE_NVM_ACCESS_ENABLE, val &
 2331             ~(BCE_NVM_ACCESS_ENABLE_EN | BCE_NVM_ACCESS_ENABLE_WR_EN));
 2332 
 2333         DBEXIT(BCE_VERBOSE_NVRAM);
 2334 }
 2335 
 2336 
 2337 #ifdef BCE_NVRAM_WRITE_SUPPORT
 2338 /****************************************************************************/
 2339 /* Erase NVRAM page before writing.                                         */
 2340 /*                                                                          */
 2341 /* Non-buffered flash parts require that a page be erased before it is      */
 2342 /* written.                                                                 */
 2343 /*                                                                          */
 2344 /* Returns:                                                                 */
 2345 /*   0 on success, positive value on failure.                               */
 2346 /****************************************************************************/
 2347 static int
 2348 bce_nvram_erase_page(struct bce_softc *sc, u32 offset)
 2349 {
 2350         u32 cmd;
 2351         int j, rc = 0;
 2352 
 2353         DBENTER(BCE_VERBOSE_NVRAM);
 2354 
 2355         /* Buffered flash doesn't require an erase. */
 2356         if (sc->bce_flash_info->flags & BCE_NV_BUFFERED)
 2357                 goto bce_nvram_erase_page_exit;
 2358 
 2359         /* Build an erase command. */
 2360         cmd = BCE_NVM_COMMAND_ERASE | BCE_NVM_COMMAND_WR |
 2361             BCE_NVM_COMMAND_DOIT;
 2362 
 2363         /*
 2364          * Clear the DONE bit separately, set the NVRAM address to erase,
 2365          * and issue the erase command.
 2366          */
 2367         REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
 2368         REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
 2369         REG_WR(sc, BCE_NVM_COMMAND, cmd);
 2370 
 2371         /* Wait for completion. */
 2372         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
 2373                 u32 val;
 2374 
 2375                 DELAY(5);
 2376 
 2377                 val = REG_RD(sc, BCE_NVM_COMMAND);
 2378                 if (val & BCE_NVM_COMMAND_DONE)
 2379                         break;
 2380         }
 2381 
 2382         if (j >= NVRAM_TIMEOUT_COUNT) {
 2383                 DBPRINT(sc, BCE_WARN, "Timeout erasing NVRAM.\n");
 2384                 rc = EBUSY;
 2385         }
 2386 
 2387 bce_nvram_erase_page_exit:
 2388         DBEXIT(BCE_VERBOSE_NVRAM);
 2389         return (rc);
 2390 }
 2391 #endif /* BCE_NVRAM_WRITE_SUPPORT */
 2392 
 2393 
 2394 /****************************************************************************/
 2395 /* Read a dword (32 bits) from NVRAM.                                       */
 2396 /*                                                                          */
 2397 /* Read a 32 bit word from NVRAM.  The caller is assumed to have already    */
 2398 /* obtained the NVRAM lock and enabled the controller for NVRAM access.     */
 2399 /*                                                                          */
 2400 /* Returns:                                                                 */
 2401 /*   0 on success and the 32 bit value read, positive value on failure.     */
 2402 /****************************************************************************/
 2403 static int
 2404 bce_nvram_read_dword(struct bce_softc *sc,
 2405     u32 offset, u8 *ret_val, u32 cmd_flags)
 2406 {
 2407         u32 cmd;
 2408         int i, rc = 0;
 2409 
 2410         DBENTER(BCE_EXTREME_NVRAM);
 2411 
 2412         /* Build the command word. */
 2413         cmd = BCE_NVM_COMMAND_DOIT | cmd_flags;
 2414 
 2415         /* Calculate the offset for buffered flash if translation is used. */
 2416         if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
 2417                 offset = ((offset / sc->bce_flash_info->page_size) <<
 2418                     sc->bce_flash_info->page_bits) +
 2419                     (offset % sc->bce_flash_info->page_size);
 2420         }
 2421 
 2422         /*
 2423          * Clear the DONE bit separately, set the address to read,
 2424          * and issue the read.
 2425          */
 2426         REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
 2427         REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
 2428         REG_WR(sc, BCE_NVM_COMMAND, cmd);
 2429 
 2430         /* Wait for completion. */
 2431         for (i = 0; i < NVRAM_TIMEOUT_COUNT; i++) {
 2432                 u32 val;
 2433 
 2434                 DELAY(5);
 2435 
 2436                 val = REG_RD(sc, BCE_NVM_COMMAND);
 2437                 if (val & BCE_NVM_COMMAND_DONE) {
 2438                         val = REG_RD(sc, BCE_NVM_READ);
 2439 
 2440                         val = bce_be32toh(val);
 2441                         memcpy(ret_val, &val, 4);
 2442                         break;
 2443                 }
 2444         }
 2445 
 2446         /* Check for errors. */
 2447         if (i >= NVRAM_TIMEOUT_COUNT) {
 2448                 BCE_PRINTF("%s(%d): Timeout error reading NVRAM at "
 2449                     "offset 0x%08X!\n", __FILE__, __LINE__, offset);
 2450                 rc = EBUSY;
 2451         }
 2452 
 2453         DBEXIT(BCE_EXTREME_NVRAM);
 2454         return(rc);
 2455 }
 2456 
 2457 
 2458 #ifdef BCE_NVRAM_WRITE_SUPPORT
 2459 /****************************************************************************/
 2460 /* Write a dword (32 bits) to NVRAM.                                        */
 2461 /*                                                                          */
 2462 /* Write a 32 bit word to NVRAM.  The caller is assumed to have already     */
 2463 /* obtained the NVRAM lock, enabled the controller for NVRAM access, and    */
 2464 /* enabled NVRAM write access.                                              */
 2465 /*                                                                          */
 2466 /* Returns:                                                                 */
 2467 /*   0 on success, positive value on failure.                               */
 2468 /****************************************************************************/
 2469 static int
 2470 bce_nvram_write_dword(struct bce_softc *sc, u32 offset, u8 *val,
 2471         u32 cmd_flags)
 2472 {
 2473         u32 cmd, val32;
 2474         int j, rc = 0;
 2475 
 2476         DBENTER(BCE_VERBOSE_NVRAM);
 2477 
 2478         /* Build the command word. */
 2479         cmd = BCE_NVM_COMMAND_DOIT | BCE_NVM_COMMAND_WR | cmd_flags;
 2480 
 2481         /* Calculate the offset for buffered flash if translation is used. */
 2482         if (sc->bce_flash_info->flags & BCE_NV_TRANSLATE) {
 2483                 offset = ((offset / sc->bce_flash_info->page_size) <<
 2484                     sc->bce_flash_info->page_bits) +
 2485                     (offset % sc->bce_flash_info->page_size);
 2486         }
 2487 
 2488         /*
 2489          * Clear the DONE bit separately, convert NVRAM data to big-endian,
 2490          * set the NVRAM address to write, and issue the write command
 2491          */
 2492         REG_WR(sc, BCE_NVM_COMMAND, BCE_NVM_COMMAND_DONE);
 2493         memcpy(&val32, val, 4);
 2494         val32 = htobe32(val32);
 2495         REG_WR(sc, BCE_NVM_WRITE, val32);
 2496         REG_WR(sc, BCE_NVM_ADDR, offset & BCE_NVM_ADDR_NVM_ADDR_VALUE);
 2497         REG_WR(sc, BCE_NVM_COMMAND, cmd);
 2498 
 2499         /* Wait for completion. */
 2500         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
 2501                 DELAY(5);
 2502 
 2503                 if (REG_RD(sc, BCE_NVM_COMMAND) & BCE_NVM_COMMAND_DONE)
 2504                         break;
 2505         }
 2506         if (j >= NVRAM_TIMEOUT_COUNT) {
 2507                 BCE_PRINTF("%s(%d): Timeout error writing NVRAM at "
 2508                     "offset 0x%08X\n", __FILE__, __LINE__, offset);
 2509                 rc = EBUSY;
 2510         }
 2511 
 2512         DBEXIT(BCE_VERBOSE_NVRAM);
 2513         return (rc);
 2514 }
 2515 #endif /* BCE_NVRAM_WRITE_SUPPORT */
 2516 
 2517 
 2518 /****************************************************************************/
 2519 /* Initialize NVRAM access.                                                 */
 2520 /*                                                                          */
 2521 /* Identify the NVRAM device in use and prepare the NVRAM interface to      */
 2522 /* access that device.                                                      */
 2523 /*                                                                          */
 2524 /* Returns:                                                                 */
 2525 /*   0 on success, positive value on failure.                               */
 2526 /****************************************************************************/
 2527 static int
 2528 bce_init_nvram(struct bce_softc *sc)
 2529 {
 2530         u32 val;
 2531         int j, entry_count, rc = 0;
 2532         const struct flash_spec *flash;
 2533 
 2534         DBENTER(BCE_VERBOSE_NVRAM);
 2535 
 2536         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 2537                 sc->bce_flash_info = &flash_5709;
 2538                 goto bce_init_nvram_get_flash_size;
 2539         }
 2540 
 2541         /* Determine the selected interface. */
 2542         val = REG_RD(sc, BCE_NVM_CFG1);
 2543 
 2544         entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
 2545 
 2546         /*
 2547          * Flash reconfiguration is required to support additional
 2548          * NVRAM devices not directly supported in hardware.
 2549          * Check if the flash interface was reconfigured
 2550          * by the bootcode.
 2551          */
 2552 
 2553         if (val & 0x40000000) {
 2554                 /* Flash interface reconfigured by bootcode. */
 2555 
 2556                 DBPRINT(sc,BCE_INFO_LOAD,
 2557                         "bce_init_nvram(): Flash WAS reconfigured.\n");
 2558 
 2559                 for (j = 0, flash = &flash_table[0]; j < entry_count;
 2560                      j++, flash++) {
 2561                         if ((val & FLASH_BACKUP_STRAP_MASK) ==
 2562                             (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
 2563                                 sc->bce_flash_info = flash;
 2564                                 break;
 2565                         }
 2566                 }
 2567         } else {
 2568                 /* Flash interface not yet reconfigured. */
 2569                 u32 mask;
 2570 
 2571                 DBPRINT(sc, BCE_INFO_LOAD, "%s(): Flash was NOT reconfigured.\n",
 2572                         __FUNCTION__);
 2573 
 2574                 if (val & (1 << 23))
 2575                         mask = FLASH_BACKUP_STRAP_MASK;
 2576                 else
 2577                         mask = FLASH_STRAP_MASK;
 2578 
 2579                 /* Look for the matching NVRAM device configuration data. */
 2580                 for (j = 0, flash = &flash_table[0]; j < entry_count; j++, flash++) {
 2581 
 2582                         /* Check if the device matches any of the known devices. */
 2583                         if ((val & mask) == (flash->strapping & mask)) {
 2584                                 /* Found a device match. */
 2585                                 sc->bce_flash_info = flash;
 2586 
 2587                                 /* Request access to the flash interface. */
 2588                                 if ((rc = bce_acquire_nvram_lock(sc)) != 0)
 2589                                         return rc;
 2590 
 2591                                 /* Reconfigure the flash interface. */
 2592                                 bce_enable_nvram_access(sc);
 2593                                 REG_WR(sc, BCE_NVM_CFG1, flash->config1);
 2594                                 REG_WR(sc, BCE_NVM_CFG2, flash->config2);
 2595                                 REG_WR(sc, BCE_NVM_CFG3, flash->config3);
 2596                                 REG_WR(sc, BCE_NVM_WRITE1, flash->write1);
 2597                                 bce_disable_nvram_access(sc);
 2598                                 bce_release_nvram_lock(sc);
 2599 
 2600                                 break;
 2601                         }
 2602                 }
 2603         }
 2604 
 2605         /* Check if a matching device was found. */
 2606         if (j == entry_count) {
 2607                 sc->bce_flash_info = NULL;
 2608                 BCE_PRINTF("%s(%d): Unknown Flash NVRAM found!\n",
 2609                     __FILE__, __LINE__);
 2610                 DBEXIT(BCE_VERBOSE_NVRAM);
 2611                 return (ENODEV);
 2612         }
 2613 
 2614 bce_init_nvram_get_flash_size:
 2615         /* Write the flash config data to the shared memory interface. */
 2616         val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG2);
 2617         val &= BCE_SHARED_HW_CFG2_NVM_SIZE_MASK;
 2618         if (val)
 2619                 sc->bce_flash_size = val;
 2620         else
 2621                 sc->bce_flash_size = sc->bce_flash_info->total_size;
 2622 
 2623         DBPRINT(sc, BCE_INFO_LOAD, "%s(): Found %s, size = 0x%08X\n",
 2624             __FUNCTION__, sc->bce_flash_info->name,
 2625             sc->bce_flash_info->total_size);
 2626 
 2627         DBEXIT(BCE_VERBOSE_NVRAM);
 2628         return rc;
 2629 }
 2630 
 2631 
 2632 /****************************************************************************/
 2633 /* Read an arbitrary range of data from NVRAM.                              */
 2634 /*                                                                          */
 2635 /* Prepares the NVRAM interface for access and reads the requested data     */
 2636 /* into the supplied buffer.                                                */
 2637 /*                                                                          */
 2638 /* Returns:                                                                 */
 2639 /*   0 on success and the data read, positive value on failure.             */
 2640 /****************************************************************************/
 2641 static int
 2642 bce_nvram_read(struct bce_softc *sc, u32 offset, u8 *ret_buf,
 2643         int buf_size)
 2644 {
 2645         int rc = 0;
 2646         u32 cmd_flags, offset32, len32, extra;
 2647 
 2648         DBENTER(BCE_VERBOSE_NVRAM);
 2649 
 2650         if (buf_size == 0)
 2651                 goto bce_nvram_read_exit;
 2652 
 2653         /* Request access to the flash interface. */
 2654         if ((rc = bce_acquire_nvram_lock(sc)) != 0)
 2655                 goto bce_nvram_read_exit;
 2656 
 2657         /* Enable access to flash interface */
 2658         bce_enable_nvram_access(sc);
 2659 
 2660         len32 = buf_size;
 2661         offset32 = offset;
 2662         extra = 0;
 2663 
 2664         cmd_flags = 0;
 2665 
 2666         if (offset32 & 3) {
 2667                 u8 buf[4];
 2668                 u32 pre_len;
 2669 
 2670                 offset32 &= ~3;
 2671                 pre_len = 4 - (offset & 3);
 2672 
 2673                 if (pre_len >= len32) {
 2674                         pre_len = len32;
 2675                         cmd_flags = BCE_NVM_COMMAND_FIRST | BCE_NVM_COMMAND_LAST;
 2676                 }
 2677                 else {
 2678                         cmd_flags = BCE_NVM_COMMAND_FIRST;
 2679                 }
 2680 
 2681                 rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
 2682 
 2683                 if (rc)
 2684                         return rc;
 2685 
 2686                 memcpy(ret_buf, buf + (offset & 3), pre_len);
 2687 
 2688                 offset32 += 4;
 2689                 ret_buf += pre_len;
 2690                 len32 -= pre_len;
 2691         }
 2692 
 2693         if (len32 & 3) {
 2694                 extra = 4 - (len32 & 3);
 2695                 len32 = (len32 + 4) & ~3;
 2696         }
 2697 
 2698         if (len32 == 4) {
 2699                 u8 buf[4];
 2700 
 2701                 if (cmd_flags)
 2702                         cmd_flags = BCE_NVM_COMMAND_LAST;
 2703                 else
 2704                         cmd_flags = BCE_NVM_COMMAND_FIRST |
 2705                                     BCE_NVM_COMMAND_LAST;
 2706 
 2707                 rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
 2708 
 2709                 memcpy(ret_buf, buf, 4 - extra);
 2710         }
 2711         else if (len32 > 0) {
 2712                 u8 buf[4];
 2713 
 2714                 /* Read the first word. */
 2715                 if (cmd_flags)
 2716                         cmd_flags = 0;
 2717                 else
 2718                         cmd_flags = BCE_NVM_COMMAND_FIRST;
 2719 
 2720                 rc = bce_nvram_read_dword(sc, offset32, ret_buf, cmd_flags);
 2721 
 2722                 /* Advance to the next dword. */
 2723                 offset32 += 4;
 2724                 ret_buf += 4;
 2725                 len32 -= 4;
 2726 
 2727                 while (len32 > 4 && rc == 0) {
 2728                         rc = bce_nvram_read_dword(sc, offset32, ret_buf, 0);
 2729 
 2730                         /* Advance to the next dword. */
 2731                         offset32 += 4;
 2732                         ret_buf += 4;
 2733                         len32 -= 4;
 2734                 }
 2735 
 2736                 if (rc)
 2737                         goto bce_nvram_read_locked_exit;
 2738 
 2739                 cmd_flags = BCE_NVM_COMMAND_LAST;
 2740                 rc = bce_nvram_read_dword(sc, offset32, buf, cmd_flags);
 2741 
 2742                 memcpy(ret_buf, buf, 4 - extra);
 2743         }
 2744 
 2745 bce_nvram_read_locked_exit:
 2746         /* Disable access to flash interface and release the lock. */
 2747         bce_disable_nvram_access(sc);
 2748         bce_release_nvram_lock(sc);
 2749 
 2750 bce_nvram_read_exit:
 2751         DBEXIT(BCE_VERBOSE_NVRAM);
 2752         return rc;
 2753 }
 2754 
 2755 
 2756 #ifdef BCE_NVRAM_WRITE_SUPPORT
 2757 /****************************************************************************/
 2758 /* Write an arbitrary range of data from NVRAM.                             */
 2759 /*                                                                          */
 2760 /* Prepares the NVRAM interface for write access and writes the requested   */
 2761 /* data from the supplied buffer.  The caller is responsible for            */
 2762 /* calculating any appropriate CRCs.                                        */
 2763 /*                                                                          */
 2764 /* Returns:                                                                 */
 2765 /*   0 on success, positive value on failure.                               */
 2766 /****************************************************************************/
 2767 static int
 2768 bce_nvram_write(struct bce_softc *sc, u32 offset, u8 *data_buf,
 2769         int buf_size)
 2770 {
 2771         u32 written, offset32, len32;
 2772         u8 *buf, start[4], end[4];
 2773         int rc = 0;
 2774         int align_start, align_end;
 2775 
 2776         DBENTER(BCE_VERBOSE_NVRAM);
 2777 
 2778         buf = data_buf;
 2779         offset32 = offset;
 2780         len32 = buf_size;
 2781         align_start = align_end = 0;
 2782 
 2783         if ((align_start = (offset32 & 3))) {
 2784                 offset32 &= ~3;
 2785                 len32 += align_start;
 2786                 if ((rc = bce_nvram_read(sc, offset32, start, 4)))
 2787                         goto bce_nvram_write_exit;
 2788         }
 2789 
 2790         if (len32 & 3) {
 2791                 if ((len32 > 4) || !align_start) {
 2792                         align_end = 4 - (len32 & 3);
 2793                         len32 += align_end;
 2794                         if ((rc = bce_nvram_read(sc, offset32 + len32 - 4,
 2795                                 end, 4))) {
 2796                                 goto bce_nvram_write_exit;
 2797                         }
 2798                 }
 2799         }
 2800 
 2801         if (align_start || align_end) {
 2802                 buf = malloc(len32, M_DEVBUF, M_NOWAIT);
 2803                 if (buf == 0) {
 2804                         rc = ENOMEM;
 2805                         goto bce_nvram_write_exit;
 2806                 }
 2807 
 2808                 if (align_start) {
 2809                         memcpy(buf, start, 4);
 2810                 }
 2811 
 2812                 if (align_end) {
 2813                         memcpy(buf + len32 - 4, end, 4);
 2814                 }
 2815                 memcpy(buf + align_start, data_buf, buf_size);
 2816         }
 2817 
 2818         written = 0;
 2819         while ((written < len32) && (rc == 0)) {
 2820                 u32 page_start, page_end, data_start, data_end;
 2821                 u32 addr, cmd_flags;
 2822                 int i;
 2823                 u8 flash_buffer[264];
 2824 
 2825             /* Find the page_start addr */
 2826                 page_start = offset32 + written;
 2827                 page_start -= (page_start % sc->bce_flash_info->page_size);
 2828                 /* Find the page_end addr */
 2829                 page_end = page_start + sc->bce_flash_info->page_size;
 2830                 /* Find the data_start addr */
 2831                 data_start = (written == 0) ? offset32 : page_start;
 2832                 /* Find the data_end addr */
 2833                 data_end = (page_end > offset32 + len32) ?
 2834                         (offset32 + len32) : page_end;
 2835 
 2836                 /* Request access to the flash interface. */
 2837                 if ((rc = bce_acquire_nvram_lock(sc)) != 0)
 2838                         goto bce_nvram_write_exit;
 2839 
 2840                 /* Enable access to flash interface */
 2841                 bce_enable_nvram_access(sc);
 2842 
 2843                 cmd_flags = BCE_NVM_COMMAND_FIRST;
 2844                 if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
 2845                         int j;
 2846 
 2847                         /* Read the whole page into the buffer
 2848                          * (non-buffer flash only) */
 2849                         for (j = 0; j < sc->bce_flash_info->page_size; j += 4) {
 2850                                 if (j == (sc->bce_flash_info->page_size - 4)) {
 2851                                         cmd_flags |= BCE_NVM_COMMAND_LAST;
 2852                                 }
 2853                                 rc = bce_nvram_read_dword(sc,
 2854                                         page_start + j,
 2855                                         &flash_buffer[j],
 2856                                         cmd_flags);
 2857 
 2858                                 if (rc)
 2859                                         goto bce_nvram_write_locked_exit;
 2860 
 2861                                 cmd_flags = 0;
 2862                         }
 2863                 }
 2864 
 2865                 /* Enable writes to flash interface (unlock write-protect) */
 2866                 if ((rc = bce_enable_nvram_write(sc)) != 0)
 2867                         goto bce_nvram_write_locked_exit;
 2868 
 2869                 /* Erase the page */
 2870                 if ((rc = bce_nvram_erase_page(sc, page_start)) != 0)
 2871                         goto bce_nvram_write_locked_exit;
 2872 
 2873                 /* Re-enable the write again for the actual write */
 2874                 bce_enable_nvram_write(sc);
 2875 
 2876                 /* Loop to write back the buffer data from page_start to
 2877                  * data_start */
 2878                 i = 0;
 2879                 if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
 2880                         for (addr = page_start; addr < data_start;
 2881                                 addr += 4, i += 4) {
 2882 
 2883                                 rc = bce_nvram_write_dword(sc, addr,
 2884                                         &flash_buffer[i], cmd_flags);
 2885 
 2886                                 if (rc != 0)
 2887                                         goto bce_nvram_write_locked_exit;
 2888 
 2889                                 cmd_flags = 0;
 2890                         }
 2891                 }
 2892 
 2893                 /* Loop to write the new data from data_start to data_end */
 2894                 for (addr = data_start; addr < data_end; addr += 4, i++) {
 2895                         if ((addr == page_end - 4) ||
 2896                                 ((sc->bce_flash_info->flags & BCE_NV_BUFFERED) &&
 2897                                 (addr == data_end - 4))) {
 2898 
 2899                                 cmd_flags |= BCE_NVM_COMMAND_LAST;
 2900                         }
 2901                         rc = bce_nvram_write_dword(sc, addr, buf,
 2902                                 cmd_flags);
 2903 
 2904                         if (rc != 0)
 2905                                 goto bce_nvram_write_locked_exit;
 2906 
 2907                         cmd_flags = 0;
 2908                         buf += 4;
 2909                 }
 2910 
 2911                 /* Loop to write back the buffer data from data_end
 2912                  * to page_end */
 2913                 if (!(sc->bce_flash_info->flags & BCE_NV_BUFFERED)) {
 2914                         for (addr = data_end; addr < page_end;
 2915                                 addr += 4, i += 4) {
 2916 
 2917                                 if (addr == page_end-4) {
 2918                                         cmd_flags = BCE_NVM_COMMAND_LAST;
 2919                                 }
 2920                                 rc = bce_nvram_write_dword(sc, addr,
 2921                                         &flash_buffer[i], cmd_flags);
 2922 
 2923                                 if (rc != 0)
 2924                                         goto bce_nvram_write_locked_exit;
 2925 
 2926                                 cmd_flags = 0;
 2927                         }
 2928                 }
 2929 
 2930                 /* Disable writes to flash interface (lock write-protect) */
 2931                 bce_disable_nvram_write(sc);
 2932 
 2933                 /* Disable access to flash interface */
 2934                 bce_disable_nvram_access(sc);
 2935                 bce_release_nvram_lock(sc);
 2936 
 2937                 /* Increment written */
 2938                 written += data_end - data_start;
 2939         }
 2940 
 2941         goto bce_nvram_write_exit;
 2942 
 2943 bce_nvram_write_locked_exit:
 2944         bce_disable_nvram_write(sc);
 2945         bce_disable_nvram_access(sc);
 2946         bce_release_nvram_lock(sc);
 2947 
 2948 bce_nvram_write_exit:
 2949         if (align_start || align_end)
 2950                 free(buf, M_DEVBUF);
 2951 
 2952         DBEXIT(BCE_VERBOSE_NVRAM);
 2953         return (rc);
 2954 }
 2955 #endif /* BCE_NVRAM_WRITE_SUPPORT */
 2956 
 2957 
 2958 /****************************************************************************/
 2959 /* Verifies that NVRAM is accessible and contains valid data.               */
 2960 /*                                                                          */
 2961 /* Reads the configuration data from NVRAM and verifies that the CRC is     */
 2962 /* correct.                                                                 */
 2963 /*                                                                          */
 2964 /* Returns:                                                                 */
 2965 /*   0 on success, positive value on failure.                               */
 2966 /****************************************************************************/
 2967 static int
 2968 bce_nvram_test(struct bce_softc *sc)
 2969 {
 2970         u32 buf[BCE_NVRAM_SIZE / 4];
 2971         u8 *data = (u8 *) buf;
 2972         int rc = 0;
 2973         u32 magic, csum;
 2974 
 2975         DBENTER(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
 2976 
 2977         /*
 2978          * Check that the device NVRAM is valid by reading
 2979          * the magic value at offset 0.
 2980          */
 2981         if ((rc = bce_nvram_read(sc, 0, data, 4)) != 0) {
 2982                 BCE_PRINTF("%s(%d): Unable to read NVRAM!\n",
 2983                     __FILE__, __LINE__);
 2984                 goto bce_nvram_test_exit;
 2985         }
 2986 
 2987         /*
 2988          * Verify that offset 0 of the NVRAM contains
 2989          * a valid magic number.
 2990          */
 2991         magic = bce_be32toh(buf[0]);
 2992         if (magic != BCE_NVRAM_MAGIC) {
 2993                 rc = ENODEV;
 2994                 BCE_PRINTF("%s(%d): Invalid NVRAM magic value! "
 2995                     "Expected: 0x%08X, Found: 0x%08X\n",
 2996                     __FILE__, __LINE__, BCE_NVRAM_MAGIC, magic);
 2997                 goto bce_nvram_test_exit;
 2998         }
 2999 
 3000         /*
 3001          * Verify that the device NVRAM includes valid
 3002          * configuration data.
 3003          */
 3004         if ((rc = bce_nvram_read(sc, 0x100, data, BCE_NVRAM_SIZE)) != 0) {
 3005                 BCE_PRINTF("%s(%d): Unable to read manufacturing "
 3006                     "Information from  NVRAM!\n", __FILE__, __LINE__);
 3007                 goto bce_nvram_test_exit;
 3008         }
 3009 
 3010         csum = ether_crc32_le(data, 0x100);
 3011         if (csum != BCE_CRC32_RESIDUAL) {
 3012                 rc = ENODEV;
 3013                 BCE_PRINTF("%s(%d): Invalid manufacturing information "
 3014                     "NVRAM CRC! Expected: 0x%08X, Found: 0x%08X\n",
 3015                     __FILE__, __LINE__, BCE_CRC32_RESIDUAL, csum);
 3016                 goto bce_nvram_test_exit;
 3017         }
 3018 
 3019         csum = ether_crc32_le(data + 0x100, 0x100);
 3020         if (csum != BCE_CRC32_RESIDUAL) {
 3021                 rc = ENODEV;
 3022                 BCE_PRINTF("%s(%d): Invalid feature configuration "
 3023                     "information NVRAM CRC! Expected: 0x%08X, "
 3024                     "Found: 08%08X\n", __FILE__, __LINE__,
 3025                     BCE_CRC32_RESIDUAL, csum);
 3026         }
 3027 
 3028 bce_nvram_test_exit:
 3029         DBEXIT(BCE_VERBOSE_NVRAM | BCE_VERBOSE_LOAD | BCE_VERBOSE_RESET);
 3030         return rc;
 3031 }
 3032 
 3033 
 3034 /****************************************************************************/
 3035 /* Calculates the size of the buffers to allocate based on the MTU.         */
 3036 /*                                                                          */
 3037 /* Returns:                                                                 */
 3038 /*   Nothing.                                                               */
 3039 /****************************************************************************/
 3040 static void
 3041 bce_get_rx_buffer_sizes(struct bce_softc *sc, int mtu)
 3042 {
 3043         DBENTER(BCE_VERBOSE_LOAD);
 3044 
 3045         /* Use a single allocation type when header splitting enabled. */
 3046         if (bce_hdr_split == TRUE) {
 3047                 sc->rx_bd_mbuf_alloc_size = MHLEN;
 3048                 /* Make sure offset is 16 byte aligned for hardware. */
 3049                 sc->rx_bd_mbuf_align_pad =
 3050                         roundup2(MSIZE - MHLEN, 16) - (MSIZE - MHLEN);
 3051                 sc->rx_bd_mbuf_data_len = sc->rx_bd_mbuf_alloc_size -
 3052                         sc->rx_bd_mbuf_align_pad;
 3053         } else {
 3054                 if ((mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN +
 3055                     ETHER_CRC_LEN) > MCLBYTES) {
 3056                         /* Setup for jumbo RX buffer allocations. */
 3057                         sc->rx_bd_mbuf_alloc_size = MJUM9BYTES;
 3058                         sc->rx_bd_mbuf_align_pad  =
 3059                                 roundup2(MJUM9BYTES, 16) - MJUM9BYTES;
 3060                         sc->rx_bd_mbuf_data_len =
 3061                             sc->rx_bd_mbuf_alloc_size -
 3062                             sc->rx_bd_mbuf_align_pad;
 3063                 } else {
 3064                         /* Setup for standard RX buffer allocations. */
 3065                         sc->rx_bd_mbuf_alloc_size = MCLBYTES;
 3066                         sc->rx_bd_mbuf_align_pad  =
 3067                             roundup2(MCLBYTES, 16) - MCLBYTES;
 3068                         sc->rx_bd_mbuf_data_len =
 3069                             sc->rx_bd_mbuf_alloc_size -
 3070                             sc->rx_bd_mbuf_align_pad;
 3071                 }
 3072         }
 3073 
 3074 //      DBPRINT(sc, BCE_INFO_LOAD,
 3075         DBPRINT(sc, BCE_WARN,
 3076            "%s(): rx_bd_mbuf_alloc_size = %d, rx_bd_mbuf_data_len = %d, "
 3077            "rx_bd_mbuf_align_pad = %d\n", __FUNCTION__,
 3078            sc->rx_bd_mbuf_alloc_size, sc->rx_bd_mbuf_data_len,
 3079            sc->rx_bd_mbuf_align_pad);
 3080 
 3081         DBEXIT(BCE_VERBOSE_LOAD);
 3082 }
 3083 
 3084 /****************************************************************************/
 3085 /* Identifies the current media type of the controller and sets the PHY     */
 3086 /* address.                                                                 */
 3087 /*                                                                          */
 3088 /* Returns:                                                                 */
 3089 /*   Nothing.                                                               */
 3090 /****************************************************************************/
 3091 static void
 3092 bce_get_media(struct bce_softc *sc)
 3093 {
 3094         u32 val;
 3095 
 3096         DBENTER(BCE_VERBOSE_PHY);
 3097 
 3098         /* Assume PHY address for copper controllers. */
 3099         sc->bce_phy_addr = 1;
 3100 
 3101         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 3102                 u32 val = REG_RD(sc, BCE_MISC_DUAL_MEDIA_CTRL);
 3103                 u32 bond_id = val & BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID;
 3104                 u32 strap;
 3105 
 3106                 /*
 3107                  * The BCM5709S is software configurable
 3108                  * for Copper or SerDes operation.
 3109                  */
 3110                 if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_C) {
 3111                         DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded "
 3112                             "for copper.\n");
 3113                         goto bce_get_media_exit;
 3114                 } else if (bond_id == BCE_MISC_DUAL_MEDIA_CTRL_BOND_ID_S) {
 3115                         DBPRINT(sc, BCE_INFO_LOAD, "5709 bonded "
 3116                             "for dual media.\n");
 3117                         sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
 3118                         goto bce_get_media_exit;
 3119                 }
 3120 
 3121                 if (val & BCE_MISC_DUAL_MEDIA_CTRL_STRAP_OVERRIDE)
 3122                         strap = (val &
 3123                             BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL) >> 21;
 3124                 else
 3125                         strap = (val &
 3126                             BCE_MISC_DUAL_MEDIA_CTRL_PHY_CTRL_STRAP) >> 8;
 3127 
 3128                 if (pci_get_function(sc->bce_dev) == 0) {
 3129                         switch (strap) {
 3130                         case 0x4:
 3131                         case 0x5:
 3132                         case 0x6:
 3133                                 DBPRINT(sc, BCE_INFO_LOAD,
 3134                                     "BCM5709 s/w configured for SerDes.\n");
 3135                                 sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
 3136                                 break;
 3137                         default:
 3138                                 DBPRINT(sc, BCE_INFO_LOAD,
 3139                                     "BCM5709 s/w configured for Copper.\n");
 3140                                 break;
 3141                         }
 3142                 } else {
 3143                         switch (strap) {
 3144                         case 0x1:
 3145                         case 0x2:
 3146                         case 0x4:
 3147                                 DBPRINT(sc, BCE_INFO_LOAD,
 3148                                     "BCM5709 s/w configured for SerDes.\n");
 3149                                 sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
 3150                                 break;
 3151                         default:
 3152                                 DBPRINT(sc, BCE_INFO_LOAD,
 3153                                     "BCM5709 s/w configured for Copper.\n");
 3154                                 break;
 3155                         }
 3156                 }
 3157 
 3158         } else if (BCE_CHIP_BOND_ID(sc) & BCE_CHIP_BOND_ID_SERDES_BIT)
 3159                 sc->bce_phy_flags |= BCE_PHY_SERDES_FLAG;
 3160 
 3161         if (sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) {
 3162 
 3163                 sc->bce_flags |= BCE_NO_WOL_FLAG;
 3164 
 3165                 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
 3166                         sc->bce_phy_flags |= BCE_PHY_IEEE_CLAUSE_45_FLAG;
 3167 
 3168                 if (BCE_CHIP_NUM(sc) != BCE_CHIP_NUM_5706) {
 3169                         /* 5708S/09S/16S use a separate PHY for SerDes. */
 3170                         sc->bce_phy_addr = 2;
 3171 
 3172                         val = bce_shmem_rd(sc, BCE_SHARED_HW_CFG_CONFIG);
 3173                         if (val & BCE_SHARED_HW_CFG_PHY_2_5G) {
 3174                                 sc->bce_phy_flags |=
 3175                                     BCE_PHY_2_5G_CAPABLE_FLAG;
 3176                                 DBPRINT(sc, BCE_INFO_LOAD, "Found 2.5Gb "
 3177                                     "capable adapter\n");
 3178                         }
 3179                 }
 3180         } else if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) ||
 3181             (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5708))
 3182                 sc->bce_phy_flags |= BCE_PHY_CRC_FIX_FLAG;
 3183 
 3184 bce_get_media_exit:
 3185         DBPRINT(sc, (BCE_INFO_LOAD | BCE_INFO_PHY),
 3186                 "Using PHY address %d.\n", sc->bce_phy_addr);
 3187 
 3188         DBEXIT(BCE_VERBOSE_PHY);
 3189 }
 3190 
 3191 
 3192 /****************************************************************************/
 3193 /* Performs PHY initialization required before MII drivers access the       */
 3194 /* device.                                                                  */
 3195 /*                                                                          */
 3196 /* Returns:                                                                 */
 3197 /*   Nothing.                                                               */
 3198 /****************************************************************************/
 3199 static void
 3200 bce_init_media(struct bce_softc *sc)
 3201 {
 3202         if ((sc->bce_phy_flags & (BCE_PHY_IEEE_CLAUSE_45_FLAG |
 3203             BCE_PHY_REMOTE_CAP_FLAG)) == BCE_PHY_IEEE_CLAUSE_45_FLAG) {
 3204                 /*
 3205                  * Configure 5709S/5716S PHYs to use traditional IEEE
 3206                  * Clause 22 method. Otherwise we have no way to attach
 3207                  * the PHY in mii(4) layer. PHY specific configuration
 3208                  * is done in mii layer.
 3209                  */
 3210 
 3211                 /* Select auto-negotiation MMD of the PHY. */
 3212                 bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
 3213                     BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_ADDR_EXT);
 3214                 bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
 3215                     BRGPHY_ADDR_EXT, BRGPHY_ADDR_EXT_AN_MMD);
 3216 
 3217                 /* Set IEEE0 block of AN MMD (assumed in brgphy(4) code). */
 3218                 bce_miibus_write_reg(sc->bce_dev, sc->bce_phy_addr,
 3219                     BRGPHY_BLOCK_ADDR, BRGPHY_BLOCK_ADDR_COMBO_IEEE0);
 3220         }
 3221 }
 3222 
 3223 
 3224 /****************************************************************************/
 3225 /* Free any DMA memory owned by the driver.                                 */
 3226 /*                                                                          */
 3227 /* Scans through each data structre that requires DMA memory and frees      */
 3228 /* the memory if allocated.                                                 */
 3229 /*                                                                          */
 3230 /* Returns:                                                                 */
 3231 /*   Nothing.                                                               */
 3232 /****************************************************************************/
 3233 static void
 3234 bce_dma_free(struct bce_softc *sc)
 3235 {
 3236         int i;
 3237 
 3238         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
 3239 
 3240         /* Free, unmap, and destroy the status block. */
 3241         if (sc->status_block_paddr != 0) {
 3242                 bus_dmamap_unload(
 3243                     sc->status_tag,
 3244                     sc->status_map);
 3245                 sc->status_block_paddr = 0;
 3246         }
 3247 
 3248         if (sc->status_block != NULL) {
 3249                 bus_dmamem_free(
 3250                    sc->status_tag,
 3251                     sc->status_block,
 3252                     sc->status_map);
 3253                 sc->status_block = NULL;
 3254         }
 3255 
 3256         if (sc->status_tag != NULL) {
 3257                 bus_dma_tag_destroy(sc->status_tag);
 3258                 sc->status_tag = NULL;
 3259         }
 3260 
 3261 
 3262         /* Free, unmap, and destroy the statistics block. */
 3263         if (sc->stats_block_paddr != 0) {
 3264                 bus_dmamap_unload(
 3265                     sc->stats_tag,
 3266                     sc->stats_map);
 3267                 sc->stats_block_paddr = 0;
 3268         }
 3269 
 3270         if (sc->stats_block != NULL) {
 3271                 bus_dmamem_free(
 3272                     sc->stats_tag,
 3273                     sc->stats_block,
 3274                     sc->stats_map);
 3275                 sc->stats_block = NULL;
 3276         }
 3277 
 3278         if (sc->stats_tag != NULL) {
 3279                 bus_dma_tag_destroy(sc->stats_tag);
 3280                 sc->stats_tag = NULL;
 3281         }
 3282 
 3283 
 3284         /* Free, unmap and destroy all context memory pages. */
 3285         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 3286                 for (i = 0; i < sc->ctx_pages; i++ ) {
 3287                         if (sc->ctx_paddr[i] != 0) {
 3288                                 bus_dmamap_unload(
 3289                                     sc->ctx_tag,
 3290                                     sc->ctx_map[i]);
 3291                                 sc->ctx_paddr[i] = 0;
 3292                         }
 3293 
 3294                         if (sc->ctx_block[i] != NULL) {
 3295                                 bus_dmamem_free(
 3296                                     sc->ctx_tag,
 3297                                     sc->ctx_block[i],
 3298                                     sc->ctx_map[i]);
 3299                                 sc->ctx_block[i] = NULL;
 3300                         }
 3301                 }
 3302 
 3303                 /* Destroy the context memory tag. */
 3304                 if (sc->ctx_tag != NULL) {
 3305                         bus_dma_tag_destroy(sc->ctx_tag);
 3306                         sc->ctx_tag = NULL;
 3307                 }
 3308         }
 3309 
 3310 
 3311         /* Free, unmap and destroy all TX buffer descriptor chain pages. */
 3312         for (i = 0; i < sc->tx_pages; i++ ) {
 3313                 if (sc->tx_bd_chain_paddr[i] != 0) {
 3314                         bus_dmamap_unload(
 3315                             sc->tx_bd_chain_tag,
 3316                             sc->tx_bd_chain_map[i]);
 3317                         sc->tx_bd_chain_paddr[i] = 0;
 3318                 }
 3319 
 3320                 if (sc->tx_bd_chain[i] != NULL) {
 3321                         bus_dmamem_free(
 3322                             sc->tx_bd_chain_tag,
 3323                             sc->tx_bd_chain[i],
 3324                             sc->tx_bd_chain_map[i]);
 3325                         sc->tx_bd_chain[i] = NULL;
 3326                 }
 3327         }
 3328 
 3329         /* Destroy the TX buffer descriptor tag. */
 3330         if (sc->tx_bd_chain_tag != NULL) {
 3331                 bus_dma_tag_destroy(sc->tx_bd_chain_tag);
 3332                 sc->tx_bd_chain_tag = NULL;
 3333         }
 3334 
 3335 
 3336         /* Free, unmap and destroy all RX buffer descriptor chain pages. */
 3337         for (i = 0; i < sc->rx_pages; i++ ) {
 3338                 if (sc->rx_bd_chain_paddr[i] != 0) {
 3339                         bus_dmamap_unload(
 3340                             sc->rx_bd_chain_tag,
 3341                             sc->rx_bd_chain_map[i]);
 3342                         sc->rx_bd_chain_paddr[i] = 0;
 3343                 }
 3344 
 3345                 if (sc->rx_bd_chain[i] != NULL) {
 3346                         bus_dmamem_free(
 3347                             sc->rx_bd_chain_tag,
 3348                             sc->rx_bd_chain[i],
 3349                             sc->rx_bd_chain_map[i]);
 3350                         sc->rx_bd_chain[i] = NULL;
 3351                 }
 3352         }
 3353 
 3354         /* Destroy the RX buffer descriptor tag. */
 3355         if (sc->rx_bd_chain_tag != NULL) {
 3356                 bus_dma_tag_destroy(sc->rx_bd_chain_tag);
 3357                 sc->rx_bd_chain_tag = NULL;
 3358         }
 3359 
 3360 
 3361         /* Free, unmap and destroy all page buffer descriptor chain pages. */
 3362         if (bce_hdr_split == TRUE) {
 3363                 for (i = 0; i < sc->pg_pages; i++ ) {
 3364                         if (sc->pg_bd_chain_paddr[i] != 0) {
 3365                                 bus_dmamap_unload(
 3366                                     sc->pg_bd_chain_tag,
 3367                                     sc->pg_bd_chain_map[i]);
 3368                                 sc->pg_bd_chain_paddr[i] = 0;
 3369                         }
 3370 
 3371                         if (sc->pg_bd_chain[i] != NULL) {
 3372                                 bus_dmamem_free(
 3373                                     sc->pg_bd_chain_tag,
 3374                                     sc->pg_bd_chain[i],
 3375                                     sc->pg_bd_chain_map[i]);
 3376                                 sc->pg_bd_chain[i] = NULL;
 3377                         }
 3378                 }
 3379 
 3380                 /* Destroy the page buffer descriptor tag. */
 3381                 if (sc->pg_bd_chain_tag != NULL) {
 3382                         bus_dma_tag_destroy(sc->pg_bd_chain_tag);
 3383                         sc->pg_bd_chain_tag = NULL;
 3384                 }
 3385         }
 3386 
 3387 
 3388         /* Unload and destroy the TX mbuf maps. */
 3389         for (i = 0; i < MAX_TX_BD_AVAIL; i++) {
 3390                 if (sc->tx_mbuf_map[i] != NULL) {
 3391                         bus_dmamap_unload(sc->tx_mbuf_tag,
 3392                             sc->tx_mbuf_map[i]);
 3393                         bus_dmamap_destroy(sc->tx_mbuf_tag,
 3394                             sc->tx_mbuf_map[i]);
 3395                         sc->tx_mbuf_map[i] = NULL;
 3396                 }
 3397         }
 3398 
 3399         /* Destroy the TX mbuf tag. */
 3400         if (sc->tx_mbuf_tag != NULL) {
 3401                 bus_dma_tag_destroy(sc->tx_mbuf_tag);
 3402                 sc->tx_mbuf_tag = NULL;
 3403         }
 3404 
 3405         /* Unload and destroy the RX mbuf maps. */
 3406         for (i = 0; i < MAX_RX_BD_AVAIL; i++) {
 3407                 if (sc->rx_mbuf_map[i] != NULL) {
 3408                         bus_dmamap_unload(sc->rx_mbuf_tag,
 3409                             sc->rx_mbuf_map[i]);
 3410                         bus_dmamap_destroy(sc->rx_mbuf_tag,
 3411                             sc->rx_mbuf_map[i]);
 3412                         sc->rx_mbuf_map[i] = NULL;
 3413                 }
 3414         }
 3415 
 3416         /* Destroy the RX mbuf tag. */
 3417         if (sc->rx_mbuf_tag != NULL) {
 3418                 bus_dma_tag_destroy(sc->rx_mbuf_tag);
 3419                 sc->rx_mbuf_tag = NULL;
 3420         }
 3421 
 3422         /* Unload and destroy the page mbuf maps. */
 3423         if (bce_hdr_split == TRUE) {
 3424                 for (i = 0; i < MAX_PG_BD_AVAIL; i++) {
 3425                         if (sc->pg_mbuf_map[i] != NULL) {
 3426                                 bus_dmamap_unload(sc->pg_mbuf_tag,
 3427                                     sc->pg_mbuf_map[i]);
 3428                                 bus_dmamap_destroy(sc->pg_mbuf_tag,
 3429                                     sc->pg_mbuf_map[i]);
 3430                                 sc->pg_mbuf_map[i] = NULL;
 3431                         }
 3432                 }
 3433 
 3434                 /* Destroy the page mbuf tag. */
 3435                 if (sc->pg_mbuf_tag != NULL) {
 3436                         bus_dma_tag_destroy(sc->pg_mbuf_tag);
 3437                         sc->pg_mbuf_tag = NULL;
 3438                 }
 3439         }
 3440 
 3441         /* Destroy the parent tag */
 3442         if (sc->parent_tag != NULL) {
 3443                 bus_dma_tag_destroy(sc->parent_tag);
 3444                 sc->parent_tag = NULL;
 3445         }
 3446 
 3447         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_UNLOAD | BCE_VERBOSE_CTX);
 3448 }
 3449 
 3450 
 3451 /****************************************************************************/
 3452 /* Get DMA memory from the OS.                                              */
 3453 /*                                                                          */
 3454 /* Validates that the OS has provided DMA buffers in response to a          */
 3455 /* bus_dmamap_load() call and saves the physical address of those buffers.  */
 3456 /* When the callback is used the OS will return 0 for the mapping function  */
 3457 /* (bus_dmamap_load()) so we use the value of map_arg->maxsegs to pass any  */
 3458 /* failures back to the caller.                                             */
 3459 /*                                                                          */
 3460 /* Returns:                                                                 */
 3461 /*   Nothing.                                                               */
 3462 /****************************************************************************/
 3463 static void
 3464 bce_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 3465 {
 3466         bus_addr_t *busaddr = arg;
 3467 
 3468         KASSERT(nseg == 1, ("%s(): Too many segments returned (%d)!",
 3469             __FUNCTION__, nseg));
 3470         /* Simulate a mapping failure. */
 3471         DBRUNIF(DB_RANDOMTRUE(dma_map_addr_failed_sim_control),
 3472             error = ENOMEM);
 3473 
 3474         /* ToDo: How to increment debug sim_count variable here? */
 3475 
 3476         /* Check for an error and signal the caller that an error occurred. */
 3477         if (error) {
 3478                 *busaddr = 0;
 3479         } else {
 3480                 *busaddr = segs->ds_addr;
 3481         }
 3482 }
 3483 
 3484 
 3485 /****************************************************************************/
 3486 /* Allocate any DMA memory needed by the driver.                            */
 3487 /*                                                                          */
 3488 /* Allocates DMA memory needed for the various global structures needed by  */
 3489 /* hardware.                                                                */
 3490 /*                                                                          */
 3491 /* Memory alignment requirements:                                           */
 3492 /* +-----------------+----------+----------+----------+----------+          */
 3493 /* |                 |   5706   |   5708   |   5709   |   5716   |          */
 3494 /* +-----------------+----------+----------+----------+----------+          */
 3495 /* |Status Block     | 8 bytes  | 8 bytes  | 16 bytes | 16 bytes |          */
 3496 /* |Statistics Block | 8 bytes  | 8 bytes  | 16 bytes | 16 bytes |          */
 3497 /* |RX Buffers       | 16 bytes | 16 bytes | 16 bytes | 16 bytes |          */
 3498 /* |PG Buffers       |   none   |   none   |   none   |   none   |          */
 3499 /* |TX Buffers       |   none   |   none   |   none   |   none   |          */
 3500 /* |Chain Pages(1)   |   4KiB   |   4KiB   |   4KiB   |   4KiB   |          */
 3501 /* |Context Memory   |          |          |          |          |          */
 3502 /* +-----------------+----------+----------+----------+----------+          */
 3503 /*                                                                          */
 3504 /* (1) Must align with CPU page size (BCM_PAGE_SZIE).                       */
 3505 /*                                                                          */
 3506 /* Returns:                                                                 */
 3507 /*   0 for success, positive value for failure.                             */
 3508 /****************************************************************************/
 3509 static int
 3510 bce_dma_alloc(device_t dev)
 3511 {
 3512         struct bce_softc *sc;
 3513         int i, error, rc = 0;
 3514         bus_size_t max_size, max_seg_size;
 3515         int max_segments;
 3516 
 3517         sc = device_get_softc(dev);
 3518 
 3519         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
 3520 
 3521         /*
 3522          * Allocate the parent bus DMA tag appropriate for PCI.
 3523          */
 3524         if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, BCE_DMA_BOUNDARY,
 3525             sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
 3526             BUS_SPACE_MAXSIZE_32BIT, 0, BUS_SPACE_MAXSIZE_32BIT, 0, NULL, NULL,
 3527             &sc->parent_tag)) {
 3528                 BCE_PRINTF("%s(%d): Could not allocate parent DMA tag!\n",
 3529                     __FILE__, __LINE__);
 3530                 rc = ENOMEM;
 3531                 goto bce_dma_alloc_exit;
 3532         }
 3533 
 3534         /*
 3535          * Create a DMA tag for the status block, allocate and clear the
 3536          * memory, map the memory into DMA space, and fetch the physical
 3537          * address of the block.
 3538          */
 3539         if (bus_dma_tag_create(sc->parent_tag, BCE_DMA_ALIGN,
 3540             BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR,
 3541             NULL, NULL, BCE_STATUS_BLK_SZ, 1, BCE_STATUS_BLK_SZ,
 3542             0, NULL, NULL, &sc->status_tag)) {
 3543                 BCE_PRINTF("%s(%d): Could not allocate status block "
 3544                     "DMA tag!\n", __FILE__, __LINE__);
 3545                 rc = ENOMEM;
 3546                 goto bce_dma_alloc_exit;
 3547         }
 3548 
 3549         if(bus_dmamem_alloc(sc->status_tag, (void **)&sc->status_block,
 3550             BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
 3551             &sc->status_map)) {
 3552                 BCE_PRINTF("%s(%d): Could not allocate status block "
 3553                     "DMA memory!\n", __FILE__, __LINE__);
 3554                 rc = ENOMEM;
 3555                 goto bce_dma_alloc_exit;
 3556         }
 3557 
 3558         error = bus_dmamap_load(sc->status_tag, sc->status_map,
 3559             sc->status_block, BCE_STATUS_BLK_SZ, bce_dma_map_addr,
 3560             &sc->status_block_paddr, BUS_DMA_NOWAIT);
 3561 
 3562         if (error || sc->status_block_paddr == 0) {
 3563                 BCE_PRINTF("%s(%d): Could not map status block "
 3564                     "DMA memory!\n", __FILE__, __LINE__);
 3565                 rc = ENOMEM;
 3566                 goto bce_dma_alloc_exit;
 3567         }
 3568 
 3569         DBPRINT(sc, BCE_INFO_LOAD, "%s(): status_block_paddr = 0x%jX\n",
 3570             __FUNCTION__, (uintmax_t) sc->status_block_paddr);
 3571 
 3572         /*
 3573          * Create a DMA tag for the statistics block, allocate and clear the
 3574          * memory, map the memory into DMA space, and fetch the physical
 3575          * address of the block.
 3576          */
 3577         if (bus_dma_tag_create(sc->parent_tag, BCE_DMA_ALIGN,
 3578             BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR,
 3579             NULL, NULL, BCE_STATS_BLK_SZ, 1, BCE_STATS_BLK_SZ,
 3580             0, NULL, NULL, &sc->stats_tag)) {
 3581                 BCE_PRINTF("%s(%d): Could not allocate statistics block "
 3582                     "DMA tag!\n", __FILE__, __LINE__);
 3583                 rc = ENOMEM;
 3584                 goto bce_dma_alloc_exit;
 3585         }
 3586 
 3587         if (bus_dmamem_alloc(sc->stats_tag, (void **)&sc->stats_block,
 3588             BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT, &sc->stats_map)) {
 3589                 BCE_PRINTF("%s(%d): Could not allocate statistics block "
 3590                     "DMA memory!\n", __FILE__, __LINE__);
 3591                 rc = ENOMEM;
 3592                 goto bce_dma_alloc_exit;
 3593         }
 3594 
 3595         error = bus_dmamap_load(sc->stats_tag, sc->stats_map,
 3596             sc->stats_block, BCE_STATS_BLK_SZ, bce_dma_map_addr,
 3597             &sc->stats_block_paddr, BUS_DMA_NOWAIT);
 3598 
 3599         if (error || sc->stats_block_paddr == 0) {
 3600                 BCE_PRINTF("%s(%d): Could not map statistics block "
 3601                     "DMA memory!\n", __FILE__, __LINE__);
 3602                 rc = ENOMEM;
 3603                 goto bce_dma_alloc_exit;
 3604         }
 3605 
 3606         DBPRINT(sc, BCE_INFO_LOAD, "%s(): stats_block_paddr = 0x%jX\n",
 3607             __FUNCTION__, (uintmax_t) sc->stats_block_paddr);
 3608 
 3609         /* BCM5709 uses host memory as cache for context memory. */
 3610         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 3611                 sc->ctx_pages = 0x2000 / BCM_PAGE_SIZE;
 3612                 if (sc->ctx_pages == 0)
 3613                         sc->ctx_pages = 1;
 3614 
 3615                 DBRUNIF((sc->ctx_pages > 512),
 3616                     BCE_PRINTF("%s(%d): Too many CTX pages! %d > 512\n",
 3617                     __FILE__, __LINE__, sc->ctx_pages));
 3618 
 3619                 /*
 3620                  * Create a DMA tag for the context pages,
 3621                  * allocate and clear the memory, map the
 3622                  * memory into DMA space, and fetch the
 3623                  * physical address of the block.
 3624                  */
 3625                 if(bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
 3626                     BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR,
 3627                     NULL, NULL, BCM_PAGE_SIZE, 1, BCM_PAGE_SIZE,
 3628                     0, NULL, NULL, &sc->ctx_tag)) {
 3629                         BCE_PRINTF("%s(%d): Could not allocate CTX "
 3630                             "DMA tag!\n", __FILE__, __LINE__);
 3631                         rc = ENOMEM;
 3632                         goto bce_dma_alloc_exit;
 3633                 }
 3634 
 3635                 for (i = 0; i < sc->ctx_pages; i++) {
 3636 
 3637                         if(bus_dmamem_alloc(sc->ctx_tag,
 3638                             (void **)&sc->ctx_block[i],
 3639                             BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
 3640                             &sc->ctx_map[i])) {
 3641                                 BCE_PRINTF("%s(%d): Could not allocate CTX "
 3642                                     "DMA memory!\n", __FILE__, __LINE__);
 3643                                 rc = ENOMEM;
 3644                                 goto bce_dma_alloc_exit;
 3645                         }
 3646 
 3647                         error = bus_dmamap_load(sc->ctx_tag, sc->ctx_map[i],
 3648                             sc->ctx_block[i], BCM_PAGE_SIZE, bce_dma_map_addr,
 3649                             &sc->ctx_paddr[i], BUS_DMA_NOWAIT);
 3650 
 3651                         if (error || sc->ctx_paddr[i] == 0) {
 3652                                 BCE_PRINTF("%s(%d): Could not map CTX "
 3653                                     "DMA memory!\n", __FILE__, __LINE__);
 3654                                 rc = ENOMEM;
 3655                                 goto bce_dma_alloc_exit;
 3656                         }
 3657 
 3658                         DBPRINT(sc, BCE_INFO_LOAD, "%s(): ctx_paddr[%d] "
 3659                             "= 0x%jX\n", __FUNCTION__, i,
 3660                             (uintmax_t) sc->ctx_paddr[i]);
 3661                 }
 3662         }
 3663 
 3664         /*
 3665          * Create a DMA tag for the TX buffer descriptor chain,
 3666          * allocate and clear the  memory, and fetch the
 3667          * physical address of the block.
 3668          */
 3669         if(bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE, BCE_DMA_BOUNDARY,
 3670             sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
 3671             BCE_TX_CHAIN_PAGE_SZ, 1, BCE_TX_CHAIN_PAGE_SZ, 0,
 3672             NULL, NULL, &sc->tx_bd_chain_tag)) {
 3673                 BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
 3674                     "chain DMA tag!\n", __FILE__, __LINE__);
 3675                 rc = ENOMEM;
 3676                 goto bce_dma_alloc_exit;
 3677         }
 3678 
 3679         for (i = 0; i < sc->tx_pages; i++) {
 3680 
 3681                 if(bus_dmamem_alloc(sc->tx_bd_chain_tag,
 3682                     (void **)&sc->tx_bd_chain[i],
 3683                     BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
 3684                     &sc->tx_bd_chain_map[i])) {
 3685                         BCE_PRINTF("%s(%d): Could not allocate TX descriptor "
 3686                             "chain DMA memory!\n", __FILE__, __LINE__);
 3687                         rc = ENOMEM;
 3688                         goto bce_dma_alloc_exit;
 3689                 }
 3690 
 3691                 error = bus_dmamap_load(sc->tx_bd_chain_tag,
 3692                     sc->tx_bd_chain_map[i], sc->tx_bd_chain[i],
 3693                     BCE_TX_CHAIN_PAGE_SZ, bce_dma_map_addr,
 3694                     &sc->tx_bd_chain_paddr[i], BUS_DMA_NOWAIT);
 3695 
 3696                 if (error || sc->tx_bd_chain_paddr[i] == 0) {
 3697                         BCE_PRINTF("%s(%d): Could not map TX descriptor "
 3698                             "chain DMA memory!\n", __FILE__, __LINE__);
 3699                         rc = ENOMEM;
 3700                         goto bce_dma_alloc_exit;
 3701                 }
 3702 
 3703                 DBPRINT(sc, BCE_INFO_LOAD, "%s(): tx_bd_chain_paddr[%d] = "
 3704                     "0x%jX\n", __FUNCTION__, i,
 3705                     (uintmax_t) sc->tx_bd_chain_paddr[i]);
 3706         }
 3707 
 3708         /* Check the required size before mapping to conserve resources. */
 3709         if (bce_tso_enable) {
 3710                 max_size     = BCE_TSO_MAX_SIZE;
 3711                 max_segments = BCE_MAX_SEGMENTS;
 3712                 max_seg_size = BCE_TSO_MAX_SEG_SIZE;
 3713         } else {
 3714                 max_size     = MCLBYTES * BCE_MAX_SEGMENTS;
 3715                 max_segments = BCE_MAX_SEGMENTS;
 3716                 max_seg_size = MCLBYTES;
 3717         }
 3718 
 3719         /* Create a DMA tag for TX mbufs. */
 3720         if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
 3721             sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, max_size,
 3722             max_segments, max_seg_size, 0, NULL, NULL, &sc->tx_mbuf_tag)) {
 3723                 BCE_PRINTF("%s(%d): Could not allocate TX mbuf DMA tag!\n",
 3724                     __FILE__, __LINE__);
 3725                 rc = ENOMEM;
 3726                 goto bce_dma_alloc_exit;
 3727         }
 3728 
 3729         /* Create DMA maps for the TX mbufs clusters. */
 3730         for (i = 0; i < TOTAL_TX_BD_ALLOC; i++) {
 3731                 if (bus_dmamap_create(sc->tx_mbuf_tag, BUS_DMA_NOWAIT,
 3732                         &sc->tx_mbuf_map[i])) {
 3733                         BCE_PRINTF("%s(%d): Unable to create TX mbuf DMA "
 3734                             "map!\n", __FILE__, __LINE__);
 3735                         rc = ENOMEM;
 3736                         goto bce_dma_alloc_exit;
 3737                 }
 3738         }
 3739 
 3740         /*
 3741          * Create a DMA tag for the RX buffer descriptor chain,
 3742          * allocate and clear the memory, and fetch the physical
 3743          * address of the blocks.
 3744          */
 3745         if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
 3746                         BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR,
 3747                         sc->max_bus_addr, NULL, NULL,
 3748                         BCE_RX_CHAIN_PAGE_SZ, 1, BCE_RX_CHAIN_PAGE_SZ,
 3749                         0, NULL, NULL, &sc->rx_bd_chain_tag)) {
 3750                 BCE_PRINTF("%s(%d): Could not allocate RX descriptor chain "
 3751                     "DMA tag!\n", __FILE__, __LINE__);
 3752                 rc = ENOMEM;
 3753                 goto bce_dma_alloc_exit;
 3754         }
 3755 
 3756         for (i = 0; i < sc->rx_pages; i++) {
 3757 
 3758                 if (bus_dmamem_alloc(sc->rx_bd_chain_tag,
 3759                     (void **)&sc->rx_bd_chain[i],
 3760                     BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
 3761                     &sc->rx_bd_chain_map[i])) {
 3762                         BCE_PRINTF("%s(%d): Could not allocate RX descriptor "
 3763                             "chain DMA memory!\n", __FILE__, __LINE__);
 3764                         rc = ENOMEM;
 3765                         goto bce_dma_alloc_exit;
 3766                 }
 3767 
 3768                 error = bus_dmamap_load(sc->rx_bd_chain_tag,
 3769                     sc->rx_bd_chain_map[i], sc->rx_bd_chain[i],
 3770                     BCE_RX_CHAIN_PAGE_SZ, bce_dma_map_addr,
 3771                     &sc->rx_bd_chain_paddr[i], BUS_DMA_NOWAIT);
 3772 
 3773                 if (error || sc->rx_bd_chain_paddr[i] == 0) {
 3774                         BCE_PRINTF("%s(%d): Could not map RX descriptor "
 3775                             "chain DMA memory!\n", __FILE__, __LINE__);
 3776                         rc = ENOMEM;
 3777                         goto bce_dma_alloc_exit;
 3778                 }
 3779 
 3780                 DBPRINT(sc, BCE_INFO_LOAD, "%s(): rx_bd_chain_paddr[%d] = "
 3781                     "0x%jX\n", __FUNCTION__, i,
 3782                     (uintmax_t) sc->rx_bd_chain_paddr[i]);
 3783         }
 3784 
 3785         /*
 3786          * Create a DMA tag for RX mbufs.
 3787          */
 3788         if (bce_hdr_split == TRUE)
 3789                 max_size = ((sc->rx_bd_mbuf_alloc_size < MCLBYTES) ?
 3790                     MCLBYTES : sc->rx_bd_mbuf_alloc_size);
 3791         else
 3792                 max_size = MJUM9BYTES;
 3793 
 3794         DBPRINT(sc, BCE_INFO_LOAD, "%s(): Creating rx_mbuf_tag "
 3795             "(max size = 0x%jX)\n", __FUNCTION__, (uintmax_t)max_size);
 3796 
 3797         if (bus_dma_tag_create(sc->parent_tag, BCE_RX_BUF_ALIGN,
 3798             BCE_DMA_BOUNDARY, sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL,
 3799             max_size, 1, max_size, 0, NULL, NULL, &sc->rx_mbuf_tag)) {
 3800                 BCE_PRINTF("%s(%d): Could not allocate RX mbuf DMA tag!\n",
 3801                     __FILE__, __LINE__);
 3802                 rc = ENOMEM;
 3803                 goto bce_dma_alloc_exit;
 3804         }
 3805 
 3806         /* Create DMA maps for the RX mbuf clusters. */
 3807         for (i = 0; i < TOTAL_RX_BD_ALLOC; i++) {
 3808                 if (bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_NOWAIT,
 3809                     &sc->rx_mbuf_map[i])) {
 3810                         BCE_PRINTF("%s(%d): Unable to create RX mbuf "
 3811                             "DMA map!\n", __FILE__, __LINE__);
 3812                         rc = ENOMEM;
 3813                         goto bce_dma_alloc_exit;
 3814                 }
 3815         }
 3816 
 3817         if (bce_hdr_split == TRUE) {
 3818                 /*
 3819                  * Create a DMA tag for the page buffer descriptor chain,
 3820                  * allocate and clear the memory, and fetch the physical
 3821                  * address of the blocks.
 3822                  */
 3823                 if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
 3824                             BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR, sc->max_bus_addr,
 3825                             NULL, NULL, BCE_PG_CHAIN_PAGE_SZ, 1, BCE_PG_CHAIN_PAGE_SZ,
 3826                             0, NULL, NULL, &sc->pg_bd_chain_tag)) {
 3827                         BCE_PRINTF("%s(%d): Could not allocate page descriptor "
 3828                             "chain DMA tag!\n", __FILE__, __LINE__);
 3829                         rc = ENOMEM;
 3830                         goto bce_dma_alloc_exit;
 3831                 }
 3832 
 3833                 for (i = 0; i < sc->pg_pages; i++) {
 3834                         if (bus_dmamem_alloc(sc->pg_bd_chain_tag,
 3835                             (void **)&sc->pg_bd_chain[i],
 3836                             BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
 3837                             &sc->pg_bd_chain_map[i])) {
 3838                                 BCE_PRINTF("%s(%d): Could not allocate page "
 3839                                     "descriptor chain DMA memory!\n",
 3840                                     __FILE__, __LINE__);
 3841                                 rc = ENOMEM;
 3842                                 goto bce_dma_alloc_exit;
 3843                         }
 3844 
 3845                         error = bus_dmamap_load(sc->pg_bd_chain_tag,
 3846                             sc->pg_bd_chain_map[i], sc->pg_bd_chain[i],
 3847                             BCE_PG_CHAIN_PAGE_SZ, bce_dma_map_addr,
 3848                             &sc->pg_bd_chain_paddr[i], BUS_DMA_NOWAIT);
 3849 
 3850                         if (error || sc->pg_bd_chain_paddr[i] == 0) {
 3851                                 BCE_PRINTF("%s(%d): Could not map page descriptor "
 3852                                         "chain DMA memory!\n", __FILE__, __LINE__);
 3853                                 rc = ENOMEM;
 3854                                 goto bce_dma_alloc_exit;
 3855                         }
 3856 
 3857                         DBPRINT(sc, BCE_INFO_LOAD, "%s(): pg_bd_chain_paddr[%d] = "
 3858                                 "0x%jX\n", __FUNCTION__, i,
 3859                                 (uintmax_t) sc->pg_bd_chain_paddr[i]);
 3860                 }
 3861 
 3862                 /*
 3863                  * Create a DMA tag for page mbufs.
 3864                  */
 3865                 if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY,
 3866                     sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
 3867                     1, MCLBYTES, 0, NULL, NULL, &sc->pg_mbuf_tag)) {
 3868                         BCE_PRINTF("%s(%d): Could not allocate page mbuf "
 3869                                 "DMA tag!\n", __FILE__, __LINE__);
 3870                         rc = ENOMEM;
 3871                         goto bce_dma_alloc_exit;
 3872                 }
 3873 
 3874                 /* Create DMA maps for the page mbuf clusters. */
 3875                 for (i = 0; i < TOTAL_PG_BD_ALLOC; i++) {
 3876                         if (bus_dmamap_create(sc->pg_mbuf_tag, BUS_DMA_NOWAIT,
 3877                                 &sc->pg_mbuf_map[i])) {
 3878                                 BCE_PRINTF("%s(%d): Unable to create page mbuf "
 3879                                         "DMA map!\n", __FILE__, __LINE__);
 3880                                 rc = ENOMEM;
 3881                                 goto bce_dma_alloc_exit;
 3882                         }
 3883                 }
 3884         }
 3885 
 3886 bce_dma_alloc_exit:
 3887         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
 3888         return(rc);
 3889 }
 3890 
 3891 
 3892 /****************************************************************************/
 3893 /* Release all resources used by the driver.                                */
 3894 /*                                                                          */
 3895 /* Releases all resources acquired by the driver including interrupts,      */
 3896 /* interrupt handler, interfaces, mutexes, and DMA memory.                  */
 3897 /*                                                                          */
 3898 /* Returns:                                                                 */
 3899 /*   Nothing.                                                               */
 3900 /****************************************************************************/
 3901 static void
 3902 bce_release_resources(struct bce_softc *sc)
 3903 {
 3904         device_t dev;
 3905 
 3906         DBENTER(BCE_VERBOSE_RESET);
 3907 
 3908         dev = sc->bce_dev;
 3909 
 3910         bce_dma_free(sc);
 3911 
 3912         if (sc->bce_intrhand != NULL) {
 3913                 DBPRINT(sc, BCE_INFO_RESET, "Removing interrupt handler.\n");
 3914                 bus_teardown_intr(dev, sc->bce_res_irq, sc->bce_intrhand);
 3915         }
 3916 
 3917         if (sc->bce_res_irq != NULL) {
 3918                 DBPRINT(sc, BCE_INFO_RESET, "Releasing IRQ.\n");
 3919                 bus_release_resource(dev, SYS_RES_IRQ,
 3920                     rman_get_rid(sc->bce_res_irq), sc->bce_res_irq);
 3921         }
 3922 
 3923         if (sc->bce_flags & (BCE_USING_MSI_FLAG | BCE_USING_MSIX_FLAG)) {
 3924                 DBPRINT(sc, BCE_INFO_RESET, "Releasing MSI/MSI-X vector.\n");
 3925                 pci_release_msi(dev);
 3926         }
 3927 
 3928         if (sc->bce_res_mem != NULL) {
 3929                 DBPRINT(sc, BCE_INFO_RESET, "Releasing PCI memory.\n");
 3930                     bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0),
 3931                     sc->bce_res_mem);
 3932         }
 3933 
 3934         if (sc->bce_ifp != NULL) {
 3935                 DBPRINT(sc, BCE_INFO_RESET, "Releasing IF.\n");
 3936                 if_free(sc->bce_ifp);
 3937         }
 3938 
 3939         if (mtx_initialized(&sc->bce_mtx))
 3940                 BCE_LOCK_DESTROY(sc);
 3941 
 3942         DBEXIT(BCE_VERBOSE_RESET);
 3943 }
 3944 
 3945 
 3946 /****************************************************************************/
 3947 /* Firmware synchronization.                                                */
 3948 /*                                                                          */
 3949 /* Before performing certain events such as a chip reset, synchronize with  */
 3950 /* the firmware first.                                                      */
 3951 /*                                                                          */
 3952 /* Returns:                                                                 */
 3953 /*   0 for success, positive value for failure.                             */
 3954 /****************************************************************************/
 3955 static int
 3956 bce_fw_sync(struct bce_softc *sc, u32 msg_data)
 3957 {
 3958         int i, rc = 0;
 3959         u32 val;
 3960 
 3961         DBENTER(BCE_VERBOSE_RESET);
 3962 
 3963         /* Don't waste any time if we've timed out before. */
 3964         if (sc->bce_fw_timed_out == TRUE) {
 3965                 rc = EBUSY;
 3966                 goto bce_fw_sync_exit;
 3967         }
 3968 
 3969         /* Increment the message sequence number. */
 3970         sc->bce_fw_wr_seq++;
 3971         msg_data |= sc->bce_fw_wr_seq;
 3972 
 3973         DBPRINT(sc, BCE_VERBOSE_FIRMWARE, "bce_fw_sync(): msg_data = "
 3974             "0x%08X\n", msg_data);
 3975 
 3976         /* Send the message to the bootcode driver mailbox. */
 3977         bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
 3978 
 3979         /* Wait for the bootcode to acknowledge the message. */
 3980         for (i = 0; i < FW_ACK_TIME_OUT_MS; i++) {
 3981                 /* Check for a response in the bootcode firmware mailbox. */
 3982                 val = bce_shmem_rd(sc, BCE_FW_MB);
 3983                 if ((val & BCE_FW_MSG_ACK) == (msg_data & BCE_DRV_MSG_SEQ))
 3984                         break;
 3985                 DELAY(1000);
 3986         }
 3987 
 3988         /* If we've timed out, tell bootcode that we've stopped waiting. */
 3989         if (((val & BCE_FW_MSG_ACK) != (msg_data & BCE_DRV_MSG_SEQ)) &&
 3990             ((msg_data & BCE_DRV_MSG_DATA) != BCE_DRV_MSG_DATA_WAIT0)) {
 3991 
 3992                 BCE_PRINTF("%s(%d): Firmware synchronization timeout! "
 3993                     "msg_data = 0x%08X\n", __FILE__, __LINE__, msg_data);
 3994 
 3995                 msg_data &= ~BCE_DRV_MSG_CODE;
 3996                 msg_data |= BCE_DRV_MSG_CODE_FW_TIMEOUT;
 3997 
 3998                 bce_shmem_wr(sc, BCE_DRV_MB, msg_data);
 3999 
 4000                 sc->bce_fw_timed_out = TRUE;
 4001                 rc = EBUSY;
 4002         }
 4003 
 4004 bce_fw_sync_exit:
 4005         DBEXIT(BCE_VERBOSE_RESET);
 4006         return (rc);
 4007 }
 4008 
 4009 
 4010 /****************************************************************************/
 4011 /* Load Receive Virtual 2 Physical (RV2P) processor firmware.               */
 4012 /*                                                                          */
 4013 /* Returns:                                                                 */
 4014 /*   Nothing.                                                               */
 4015 /****************************************************************************/
 4016 static void
 4017 bce_load_rv2p_fw(struct bce_softc *sc, const u32 *rv2p_code,
 4018         u32 rv2p_code_len, u32 rv2p_proc)
 4019 {
 4020         int i;
 4021         u32 val;
 4022 
 4023         DBENTER(BCE_VERBOSE_RESET);
 4024 
 4025         /* Set the page size used by RV2P. */
 4026         if (rv2p_proc == RV2P_PROC2) {
 4027                 BCE_RV2P_PROC2_CHG_MAX_BD_PAGE(USABLE_RX_BD_PER_PAGE);
 4028         }
 4029 
 4030         for (i = 0; i < rv2p_code_len; i += 8) {
 4031                 REG_WR(sc, BCE_RV2P_INSTR_HIGH, *rv2p_code);
 4032                 rv2p_code++;
 4033                 REG_WR(sc, BCE_RV2P_INSTR_LOW, *rv2p_code);
 4034                 rv2p_code++;
 4035 
 4036                 if (rv2p_proc == RV2P_PROC1) {
 4037                         val = (i / 8) | BCE_RV2P_PROC1_ADDR_CMD_RDWR;
 4038                         REG_WR(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
 4039                 }
 4040                 else {
 4041                         val = (i / 8) | BCE_RV2P_PROC2_ADDR_CMD_RDWR;
 4042                         REG_WR(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
 4043                 }
 4044         }
 4045 
 4046         /* Reset the processor, un-stall is done later. */
 4047         if (rv2p_proc == RV2P_PROC1) {
 4048                 REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC1_RESET);
 4049         }
 4050         else {
 4051                 REG_WR(sc, BCE_RV2P_COMMAND, BCE_RV2P_COMMAND_PROC2_RESET);
 4052         }
 4053 
 4054         DBEXIT(BCE_VERBOSE_RESET);
 4055 }
 4056 
 4057 
 4058 /****************************************************************************/
 4059 /* Load RISC processor firmware.                                            */
 4060 /*                                                                          */
 4061 /* Loads firmware from the file if_bcefw.h into the scratchpad memory       */
 4062 /* associated with a particular processor.                                  */
 4063 /*                                                                          */
 4064 /* Returns:                                                                 */
 4065 /*   Nothing.                                                               */
 4066 /****************************************************************************/
 4067 static void
 4068 bce_load_cpu_fw(struct bce_softc *sc, struct cpu_reg *cpu_reg,
 4069         struct fw_info *fw)
 4070 {
 4071         u32 offset;
 4072 
 4073         DBENTER(BCE_VERBOSE_RESET);
 4074 
 4075     bce_halt_cpu(sc, cpu_reg);
 4076 
 4077         /* Load the Text area. */
 4078         offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
 4079         if (fw->text) {
 4080                 int j;
 4081 
 4082                 for (j = 0; j < (fw->text_len / 4); j++, offset += 4) {
 4083                         REG_WR_IND(sc, offset, fw->text[j]);
 4084                 }
 4085         }
 4086 
 4087         /* Load the Data area. */
 4088         offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
 4089         if (fw->data) {
 4090                 int j;
 4091 
 4092                 for (j = 0; j < (fw->data_len / 4); j++, offset += 4) {
 4093                         REG_WR_IND(sc, offset, fw->data[j]);
 4094                 }
 4095         }
 4096 
 4097         /* Load the SBSS area. */
 4098         offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
 4099         if (fw->sbss) {
 4100                 int j;
 4101 
 4102                 for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4) {
 4103                         REG_WR_IND(sc, offset, fw->sbss[j]);
 4104                 }
 4105         }
 4106 
 4107         /* Load the BSS area. */
 4108         offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
 4109         if (fw->bss) {
 4110                 int j;
 4111 
 4112                 for (j = 0; j < (fw->bss_len/4); j++, offset += 4) {
 4113                         REG_WR_IND(sc, offset, fw->bss[j]);
 4114                 }
 4115         }
 4116 
 4117         /* Load the Read-Only area. */
 4118         offset = cpu_reg->spad_base +
 4119                 (fw->rodata_addr - cpu_reg->mips_view_base);
 4120         if (fw->rodata) {
 4121                 int j;
 4122 
 4123                 for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4) {
 4124                         REG_WR_IND(sc, offset, fw->rodata[j]);
 4125                 }
 4126         }
 4127 
 4128         /* Clear the pre-fetch instruction and set the FW start address. */
 4129         REG_WR_IND(sc, cpu_reg->inst, 0);
 4130         REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
 4131 
 4132         DBEXIT(BCE_VERBOSE_RESET);
 4133 }
 4134 
 4135 
 4136 /****************************************************************************/
 4137 /* Starts the RISC processor.                                               */
 4138 /*                                                                          */
 4139 /* Assumes the CPU starting address has already been set.                   */
 4140 /*                                                                          */
 4141 /* Returns:                                                                 */
 4142 /*   Nothing.                                                               */
 4143 /****************************************************************************/
 4144 static void
 4145 bce_start_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
 4146 {
 4147         u32 val;
 4148 
 4149         DBENTER(BCE_VERBOSE_RESET);
 4150 
 4151         /* Start the CPU. */
 4152         val = REG_RD_IND(sc, cpu_reg->mode);
 4153         val &= ~cpu_reg->mode_value_halt;
 4154         REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
 4155         REG_WR_IND(sc, cpu_reg->mode, val);
 4156 
 4157         DBEXIT(BCE_VERBOSE_RESET);
 4158 }
 4159 
 4160 
 4161 /****************************************************************************/
 4162 /* Halts the RISC processor.                                                */
 4163 /*                                                                          */
 4164 /* Returns:                                                                 */
 4165 /*   Nothing.                                                               */
 4166 /****************************************************************************/
 4167 static void
 4168 bce_halt_cpu(struct bce_softc *sc, struct cpu_reg *cpu_reg)
 4169 {
 4170         u32 val;
 4171 
 4172         DBENTER(BCE_VERBOSE_RESET);
 4173 
 4174         /* Halt the CPU. */
 4175         val = REG_RD_IND(sc, cpu_reg->mode);
 4176         val |= cpu_reg->mode_value_halt;
 4177         REG_WR_IND(sc, cpu_reg->mode, val);
 4178         REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
 4179 
 4180         DBEXIT(BCE_VERBOSE_RESET);
 4181 }
 4182 
 4183 
 4184 /****************************************************************************/
 4185 /* Initialize the RX CPU.                                                   */
 4186 /*                                                                          */
 4187 /* Returns:                                                                 */
 4188 /*   Nothing.                                                               */
 4189 /****************************************************************************/
 4190 static void
 4191 bce_start_rxp_cpu(struct bce_softc *sc)
 4192 {
 4193         struct cpu_reg cpu_reg;
 4194 
 4195         DBENTER(BCE_VERBOSE_RESET);
 4196 
 4197         cpu_reg.mode = BCE_RXP_CPU_MODE;
 4198         cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
 4199         cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
 4200         cpu_reg.state = BCE_RXP_CPU_STATE;
 4201         cpu_reg.state_value_clear = 0xffffff;
 4202         cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
 4203         cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
 4204         cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
 4205         cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
 4206         cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
 4207         cpu_reg.spad_base = BCE_RXP_SCRATCH;
 4208         cpu_reg.mips_view_base = 0x8000000;
 4209 
 4210         DBPRINT(sc, BCE_INFO_RESET, "Starting RX firmware.\n");
 4211         bce_start_cpu(sc, &cpu_reg);
 4212 
 4213         DBEXIT(BCE_VERBOSE_RESET);
 4214 }
 4215 
 4216 
 4217 /****************************************************************************/
 4218 /* Initialize the RX CPU.                                                   */
 4219 /*                                                                          */
 4220 /* Returns:                                                                 */
 4221 /*   Nothing.                                                               */
 4222 /****************************************************************************/
 4223 static void
 4224 bce_init_rxp_cpu(struct bce_softc *sc)
 4225 {
 4226         struct cpu_reg cpu_reg;
 4227         struct fw_info fw;
 4228 
 4229         DBENTER(BCE_VERBOSE_RESET);
 4230 
 4231         cpu_reg.mode = BCE_RXP_CPU_MODE;
 4232         cpu_reg.mode_value_halt = BCE_RXP_CPU_MODE_SOFT_HALT;
 4233         cpu_reg.mode_value_sstep = BCE_RXP_CPU_MODE_STEP_ENA;
 4234         cpu_reg.state = BCE_RXP_CPU_STATE;
 4235         cpu_reg.state_value_clear = 0xffffff;
 4236         cpu_reg.gpr0 = BCE_RXP_CPU_REG_FILE;
 4237         cpu_reg.evmask = BCE_RXP_CPU_EVENT_MASK;
 4238         cpu_reg.pc = BCE_RXP_CPU_PROGRAM_COUNTER;
 4239         cpu_reg.inst = BCE_RXP_CPU_INSTRUCTION;
 4240         cpu_reg.bp = BCE_RXP_CPU_HW_BREAKPOINT;
 4241         cpu_reg.spad_base = BCE_RXP_SCRATCH;
 4242         cpu_reg.mips_view_base = 0x8000000;
 4243 
 4244         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 4245                 fw.ver_major = bce_RXP_b09FwReleaseMajor;
 4246                 fw.ver_minor = bce_RXP_b09FwReleaseMinor;
 4247                 fw.ver_fix = bce_RXP_b09FwReleaseFix;
 4248                 fw.start_addr = bce_RXP_b09FwStartAddr;
 4249 
 4250                 fw.text_addr = bce_RXP_b09FwTextAddr;
 4251                 fw.text_len = bce_RXP_b09FwTextLen;
 4252                 fw.text_index = 0;
 4253                 fw.text = bce_RXP_b09FwText;
 4254 
 4255                 fw.data_addr = bce_RXP_b09FwDataAddr;
 4256                 fw.data_len = bce_RXP_b09FwDataLen;
 4257                 fw.data_index = 0;
 4258                 fw.data = bce_RXP_b09FwData;
 4259 
 4260                 fw.sbss_addr = bce_RXP_b09FwSbssAddr;
 4261                 fw.sbss_len = bce_RXP_b09FwSbssLen;
 4262                 fw.sbss_index = 0;
 4263                 fw.sbss = bce_RXP_b09FwSbss;
 4264 
 4265                 fw.bss_addr = bce_RXP_b09FwBssAddr;
 4266                 fw.bss_len = bce_RXP_b09FwBssLen;
 4267                 fw.bss_index = 0;
 4268                 fw.bss = bce_RXP_b09FwBss;
 4269 
 4270                 fw.rodata_addr = bce_RXP_b09FwRodataAddr;
 4271                 fw.rodata_len = bce_RXP_b09FwRodataLen;
 4272                 fw.rodata_index = 0;
 4273                 fw.rodata = bce_RXP_b09FwRodata;
 4274         } else {
 4275                 fw.ver_major = bce_RXP_b06FwReleaseMajor;
 4276                 fw.ver_minor = bce_RXP_b06FwReleaseMinor;
 4277                 fw.ver_fix = bce_RXP_b06FwReleaseFix;
 4278                 fw.start_addr = bce_RXP_b06FwStartAddr;
 4279 
 4280                 fw.text_addr = bce_RXP_b06FwTextAddr;
 4281                 fw.text_len = bce_RXP_b06FwTextLen;
 4282                 fw.text_index = 0;
 4283                 fw.text = bce_RXP_b06FwText;
 4284 
 4285                 fw.data_addr = bce_RXP_b06FwDataAddr;
 4286                 fw.data_len = bce_RXP_b06FwDataLen;
 4287                 fw.data_index = 0;
 4288                 fw.data = bce_RXP_b06FwData;
 4289 
 4290                 fw.sbss_addr = bce_RXP_b06FwSbssAddr;
 4291                 fw.sbss_len = bce_RXP_b06FwSbssLen;
 4292                 fw.sbss_index = 0;
 4293                 fw.sbss = bce_RXP_b06FwSbss;
 4294 
 4295                 fw.bss_addr = bce_RXP_b06FwBssAddr;
 4296                 fw.bss_len = bce_RXP_b06FwBssLen;
 4297                 fw.bss_index = 0;
 4298                 fw.bss = bce_RXP_b06FwBss;
 4299 
 4300                 fw.rodata_addr = bce_RXP_b06FwRodataAddr;
 4301                 fw.rodata_len = bce_RXP_b06FwRodataLen;
 4302                 fw.rodata_index = 0;
 4303                 fw.rodata = bce_RXP_b06FwRodata;
 4304         }
 4305 
 4306         DBPRINT(sc, BCE_INFO_RESET, "Loading RX firmware.\n");
 4307         bce_load_cpu_fw(sc, &cpu_reg, &fw);
 4308 
 4309     /* Delay RXP start until initialization is complete. */
 4310 
 4311         DBEXIT(BCE_VERBOSE_RESET);
 4312 }
 4313 
 4314 
 4315 /****************************************************************************/
 4316 /* Initialize the TX CPU.                                                   */
 4317 /*                                                                          */
 4318 /* Returns:                                                                 */
 4319 /*   Nothing.                                                               */
 4320 /****************************************************************************/
 4321 static void
 4322 bce_init_txp_cpu(struct bce_softc *sc)
 4323 {
 4324         struct cpu_reg cpu_reg;
 4325         struct fw_info fw;
 4326 
 4327         DBENTER(BCE_VERBOSE_RESET);
 4328 
 4329         cpu_reg.mode = BCE_TXP_CPU_MODE;
 4330         cpu_reg.mode_value_halt = BCE_TXP_CPU_MODE_SOFT_HALT;
 4331         cpu_reg.mode_value_sstep = BCE_TXP_CPU_MODE_STEP_ENA;
 4332         cpu_reg.state = BCE_TXP_CPU_STATE;
 4333         cpu_reg.state_value_clear = 0xffffff;
 4334         cpu_reg.gpr0 = BCE_TXP_CPU_REG_FILE;
 4335         cpu_reg.evmask = BCE_TXP_CPU_EVENT_MASK;
 4336         cpu_reg.pc = BCE_TXP_CPU_PROGRAM_COUNTER;
 4337         cpu_reg.inst = BCE_TXP_CPU_INSTRUCTION;
 4338         cpu_reg.bp = BCE_TXP_CPU_HW_BREAKPOINT;
 4339         cpu_reg.spad_base = BCE_TXP_SCRATCH;
 4340         cpu_reg.mips_view_base = 0x8000000;
 4341 
 4342         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 4343                 fw.ver_major = bce_TXP_b09FwReleaseMajor;
 4344                 fw.ver_minor = bce_TXP_b09FwReleaseMinor;
 4345                 fw.ver_fix = bce_TXP_b09FwReleaseFix;
 4346                 fw.start_addr = bce_TXP_b09FwStartAddr;
 4347 
 4348                 fw.text_addr = bce_TXP_b09FwTextAddr;
 4349                 fw.text_len = bce_TXP_b09FwTextLen;
 4350                 fw.text_index = 0;
 4351                 fw.text = bce_TXP_b09FwText;
 4352 
 4353                 fw.data_addr = bce_TXP_b09FwDataAddr;
 4354                 fw.data_len = bce_TXP_b09FwDataLen;
 4355                 fw.data_index = 0;
 4356                 fw.data = bce_TXP_b09FwData;
 4357 
 4358                 fw.sbss_addr = bce_TXP_b09FwSbssAddr;
 4359                 fw.sbss_len = bce_TXP_b09FwSbssLen;
 4360                 fw.sbss_index = 0;
 4361                 fw.sbss = bce_TXP_b09FwSbss;
 4362 
 4363                 fw.bss_addr = bce_TXP_b09FwBssAddr;
 4364                 fw.bss_len = bce_TXP_b09FwBssLen;
 4365                 fw.bss_index = 0;
 4366                 fw.bss = bce_TXP_b09FwBss;
 4367 
 4368                 fw.rodata_addr = bce_TXP_b09FwRodataAddr;
 4369                 fw.rodata_len = bce_TXP_b09FwRodataLen;
 4370                 fw.rodata_index = 0;
 4371                 fw.rodata = bce_TXP_b09FwRodata;
 4372         } else {
 4373                 fw.ver_major = bce_TXP_b06FwReleaseMajor;
 4374                 fw.ver_minor = bce_TXP_b06FwReleaseMinor;
 4375                 fw.ver_fix = bce_TXP_b06FwReleaseFix;
 4376                 fw.start_addr = bce_TXP_b06FwStartAddr;
 4377 
 4378                 fw.text_addr = bce_TXP_b06FwTextAddr;
 4379                 fw.text_len = bce_TXP_b06FwTextLen;
 4380                 fw.text_index = 0;
 4381                 fw.text = bce_TXP_b06FwText;
 4382 
 4383                 fw.data_addr = bce_TXP_b06FwDataAddr;
 4384                 fw.data_len = bce_TXP_b06FwDataLen;
 4385                 fw.data_index = 0;
 4386                 fw.data = bce_TXP_b06FwData;
 4387 
 4388                 fw.sbss_addr = bce_TXP_b06FwSbssAddr;
 4389                 fw.sbss_len = bce_TXP_b06FwSbssLen;
 4390                 fw.sbss_index = 0;
 4391                 fw.sbss = bce_TXP_b06FwSbss;
 4392 
 4393                 fw.bss_addr = bce_TXP_b06FwBssAddr;
 4394                 fw.bss_len = bce_TXP_b06FwBssLen;
 4395                 fw.bss_index = 0;
 4396                 fw.bss = bce_TXP_b06FwBss;
 4397 
 4398                 fw.rodata_addr = bce_TXP_b06FwRodataAddr;
 4399                 fw.rodata_len = bce_TXP_b06FwRodataLen;
 4400                 fw.rodata_index = 0;
 4401                 fw.rodata = bce_TXP_b06FwRodata;
 4402         }
 4403 
 4404         DBPRINT(sc, BCE_INFO_RESET, "Loading TX firmware.\n");
 4405         bce_load_cpu_fw(sc, &cpu_reg, &fw);
 4406     bce_start_cpu(sc, &cpu_reg);
 4407 
 4408         DBEXIT(BCE_VERBOSE_RESET);
 4409 }
 4410 
 4411 
 4412 /****************************************************************************/
 4413 /* Initialize the TPAT CPU.                                                 */
 4414 /*                                                                          */
 4415 /* Returns:                                                                 */
 4416 /*   Nothing.                                                               */
 4417 /****************************************************************************/
 4418 static void
 4419 bce_init_tpat_cpu(struct bce_softc *sc)
 4420 {
 4421         struct cpu_reg cpu_reg;
 4422         struct fw_info fw;
 4423 
 4424         DBENTER(BCE_VERBOSE_RESET);
 4425 
 4426         cpu_reg.mode = BCE_TPAT_CPU_MODE;
 4427         cpu_reg.mode_value_halt = BCE_TPAT_CPU_MODE_SOFT_HALT;
 4428         cpu_reg.mode_value_sstep = BCE_TPAT_CPU_MODE_STEP_ENA;
 4429         cpu_reg.state = BCE_TPAT_CPU_STATE;
 4430         cpu_reg.state_value_clear = 0xffffff;
 4431         cpu_reg.gpr0 = BCE_TPAT_CPU_REG_FILE;
 4432         cpu_reg.evmask = BCE_TPAT_CPU_EVENT_MASK;
 4433         cpu_reg.pc = BCE_TPAT_CPU_PROGRAM_COUNTER;
 4434         cpu_reg.inst = BCE_TPAT_CPU_INSTRUCTION;
 4435         cpu_reg.bp = BCE_TPAT_CPU_HW_BREAKPOINT;
 4436         cpu_reg.spad_base = BCE_TPAT_SCRATCH;
 4437         cpu_reg.mips_view_base = 0x8000000;
 4438 
 4439         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 4440                 fw.ver_major = bce_TPAT_b09FwReleaseMajor;
 4441                 fw.ver_minor = bce_TPAT_b09FwReleaseMinor;
 4442                 fw.ver_fix = bce_TPAT_b09FwReleaseFix;
 4443                 fw.start_addr = bce_TPAT_b09FwStartAddr;
 4444 
 4445                 fw.text_addr = bce_TPAT_b09FwTextAddr;
 4446                 fw.text_len = bce_TPAT_b09FwTextLen;
 4447                 fw.text_index = 0;
 4448                 fw.text = bce_TPAT_b09FwText;
 4449 
 4450                 fw.data_addr = bce_TPAT_b09FwDataAddr;
 4451                 fw.data_len = bce_TPAT_b09FwDataLen;
 4452                 fw.data_index = 0;
 4453                 fw.data = bce_TPAT_b09FwData;
 4454 
 4455                 fw.sbss_addr = bce_TPAT_b09FwSbssAddr;
 4456                 fw.sbss_len = bce_TPAT_b09FwSbssLen;
 4457                 fw.sbss_index = 0;
 4458                 fw.sbss = bce_TPAT_b09FwSbss;
 4459 
 4460                 fw.bss_addr = bce_TPAT_b09FwBssAddr;
 4461                 fw.bss_len = bce_TPAT_b09FwBssLen;
 4462                 fw.bss_index = 0;
 4463                 fw.bss = bce_TPAT_b09FwBss;
 4464 
 4465                 fw.rodata_addr = bce_TPAT_b09FwRodataAddr;
 4466                 fw.rodata_len = bce_TPAT_b09FwRodataLen;
 4467                 fw.rodata_index = 0;
 4468                 fw.rodata = bce_TPAT_b09FwRodata;
 4469         } else {
 4470                 fw.ver_major = bce_TPAT_b06FwReleaseMajor;
 4471                 fw.ver_minor = bce_TPAT_b06FwReleaseMinor;
 4472                 fw.ver_fix = bce_TPAT_b06FwReleaseFix;
 4473                 fw.start_addr = bce_TPAT_b06FwStartAddr;
 4474 
 4475                 fw.text_addr = bce_TPAT_b06FwTextAddr;
 4476                 fw.text_len = bce_TPAT_b06FwTextLen;
 4477                 fw.text_index = 0;
 4478                 fw.text = bce_TPAT_b06FwText;
 4479 
 4480                 fw.data_addr = bce_TPAT_b06FwDataAddr;
 4481                 fw.data_len = bce_TPAT_b06FwDataLen;
 4482                 fw.data_index = 0;
 4483                 fw.data = bce_TPAT_b06FwData;
 4484 
 4485                 fw.sbss_addr = bce_TPAT_b06FwSbssAddr;
 4486                 fw.sbss_len = bce_TPAT_b06FwSbssLen;
 4487                 fw.sbss_index = 0;
 4488                 fw.sbss = bce_TPAT_b06FwSbss;
 4489 
 4490                 fw.bss_addr = bce_TPAT_b06FwBssAddr;
 4491                 fw.bss_len = bce_TPAT_b06FwBssLen;
 4492                 fw.bss_index = 0;
 4493                 fw.bss = bce_TPAT_b06FwBss;
 4494 
 4495                 fw.rodata_addr = bce_TPAT_b06FwRodataAddr;
 4496                 fw.rodata_len = bce_TPAT_b06FwRodataLen;
 4497                 fw.rodata_index = 0;
 4498                 fw.rodata = bce_TPAT_b06FwRodata;
 4499         }
 4500 
 4501         DBPRINT(sc, BCE_INFO_RESET, "Loading TPAT firmware.\n");
 4502         bce_load_cpu_fw(sc, &cpu_reg, &fw);
 4503         bce_start_cpu(sc, &cpu_reg);
 4504 
 4505         DBEXIT(BCE_VERBOSE_RESET);
 4506 }
 4507 
 4508 
 4509 /****************************************************************************/
 4510 /* Initialize the CP CPU.                                                   */
 4511 /*                                                                          */
 4512 /* Returns:                                                                 */
 4513 /*   Nothing.                                                               */
 4514 /****************************************************************************/
 4515 static void
 4516 bce_init_cp_cpu(struct bce_softc *sc)
 4517 {
 4518         struct cpu_reg cpu_reg;
 4519         struct fw_info fw;
 4520 
 4521         DBENTER(BCE_VERBOSE_RESET);
 4522 
 4523         cpu_reg.mode = BCE_CP_CPU_MODE;
 4524         cpu_reg.mode_value_halt = BCE_CP_CPU_MODE_SOFT_HALT;
 4525         cpu_reg.mode_value_sstep = BCE_CP_CPU_MODE_STEP_ENA;
 4526         cpu_reg.state = BCE_CP_CPU_STATE;
 4527         cpu_reg.state_value_clear = 0xffffff;
 4528         cpu_reg.gpr0 = BCE_CP_CPU_REG_FILE;
 4529         cpu_reg.evmask = BCE_CP_CPU_EVENT_MASK;
 4530         cpu_reg.pc = BCE_CP_CPU_PROGRAM_COUNTER;
 4531         cpu_reg.inst = BCE_CP_CPU_INSTRUCTION;
 4532         cpu_reg.bp = BCE_CP_CPU_HW_BREAKPOINT;
 4533         cpu_reg.spad_base = BCE_CP_SCRATCH;
 4534         cpu_reg.mips_view_base = 0x8000000;
 4535 
 4536         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 4537                 fw.ver_major = bce_CP_b09FwReleaseMajor;
 4538                 fw.ver_minor = bce_CP_b09FwReleaseMinor;
 4539                 fw.ver_fix = bce_CP_b09FwReleaseFix;
 4540                 fw.start_addr = bce_CP_b09FwStartAddr;
 4541 
 4542                 fw.text_addr = bce_CP_b09FwTextAddr;
 4543                 fw.text_len = bce_CP_b09FwTextLen;
 4544                 fw.text_index = 0;
 4545                 fw.text = bce_CP_b09FwText;
 4546 
 4547                 fw.data_addr = bce_CP_b09FwDataAddr;
 4548                 fw.data_len = bce_CP_b09FwDataLen;
 4549                 fw.data_index = 0;
 4550                 fw.data = bce_CP_b09FwData;
 4551 
 4552                 fw.sbss_addr = bce_CP_b09FwSbssAddr;
 4553                 fw.sbss_len = bce_CP_b09FwSbssLen;
 4554                 fw.sbss_index = 0;
 4555                 fw.sbss = bce_CP_b09FwSbss;
 4556 
 4557                 fw.bss_addr = bce_CP_b09FwBssAddr;
 4558                 fw.bss_len = bce_CP_b09FwBssLen;
 4559                 fw.bss_index = 0;
 4560                 fw.bss = bce_CP_b09FwBss;
 4561 
 4562                 fw.rodata_addr = bce_CP_b09FwRodataAddr;
 4563                 fw.rodata_len = bce_CP_b09FwRodataLen;
 4564                 fw.rodata_index = 0;
 4565                 fw.rodata = bce_CP_b09FwRodata;
 4566         } else {
 4567                 fw.ver_major = bce_CP_b06FwReleaseMajor;
 4568                 fw.ver_minor = bce_CP_b06FwReleaseMinor;
 4569                 fw.ver_fix = bce_CP_b06FwReleaseFix;
 4570                 fw.start_addr = bce_CP_b06FwStartAddr;
 4571 
 4572                 fw.text_addr = bce_CP_b06FwTextAddr;
 4573                 fw.text_len = bce_CP_b06FwTextLen;
 4574                 fw.text_index = 0;
 4575                 fw.text = bce_CP_b06FwText;
 4576 
 4577                 fw.data_addr = bce_CP_b06FwDataAddr;
 4578                 fw.data_len = bce_CP_b06FwDataLen;
 4579                 fw.data_index = 0;
 4580                 fw.data = bce_CP_b06FwData;
 4581 
 4582                 fw.sbss_addr = bce_CP_b06FwSbssAddr;
 4583                 fw.sbss_len = bce_CP_b06FwSbssLen;
 4584                 fw.sbss_index = 0;
 4585                 fw.sbss = bce_CP_b06FwSbss;
 4586 
 4587                 fw.bss_addr = bce_CP_b06FwBssAddr;
 4588                 fw.bss_len = bce_CP_b06FwBssLen;
 4589                 fw.bss_index = 0;
 4590                 fw.bss = bce_CP_b06FwBss;
 4591 
 4592                 fw.rodata_addr = bce_CP_b06FwRodataAddr;
 4593                 fw.rodata_len = bce_CP_b06FwRodataLen;
 4594                 fw.rodata_index = 0;
 4595                 fw.rodata = bce_CP_b06FwRodata;
 4596         }
 4597 
 4598         DBPRINT(sc, BCE_INFO_RESET, "Loading CP firmware.\n");
 4599         bce_load_cpu_fw(sc, &cpu_reg, &fw);
 4600         bce_start_cpu(sc, &cpu_reg);
 4601 
 4602         DBEXIT(BCE_VERBOSE_RESET);
 4603 }
 4604 
 4605 
 4606 /****************************************************************************/
 4607 /* Initialize the COM CPU.                                                 */
 4608 /*                                                                          */
 4609 /* Returns:                                                                 */
 4610 /*   Nothing.                                                               */
 4611 /****************************************************************************/
 4612 static void
 4613 bce_init_com_cpu(struct bce_softc *sc)
 4614 {
 4615         struct cpu_reg cpu_reg;
 4616         struct fw_info fw;
 4617 
 4618         DBENTER(BCE_VERBOSE_RESET);
 4619 
 4620         cpu_reg.mode = BCE_COM_CPU_MODE;
 4621         cpu_reg.mode_value_halt = BCE_COM_CPU_MODE_SOFT_HALT;
 4622         cpu_reg.mode_value_sstep = BCE_COM_CPU_MODE_STEP_ENA;
 4623         cpu_reg.state = BCE_COM_CPU_STATE;
 4624         cpu_reg.state_value_clear = 0xffffff;
 4625         cpu_reg.gpr0 = BCE_COM_CPU_REG_FILE;
 4626         cpu_reg.evmask = BCE_COM_CPU_EVENT_MASK;
 4627         cpu_reg.pc = BCE_COM_CPU_PROGRAM_COUNTER;
 4628         cpu_reg.inst = BCE_COM_CPU_INSTRUCTION;
 4629         cpu_reg.bp = BCE_COM_CPU_HW_BREAKPOINT;
 4630         cpu_reg.spad_base = BCE_COM_SCRATCH;
 4631         cpu_reg.mips_view_base = 0x8000000;
 4632 
 4633         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 4634                 fw.ver_major = bce_COM_b09FwReleaseMajor;
 4635                 fw.ver_minor = bce_COM_b09FwReleaseMinor;
 4636                 fw.ver_fix = bce_COM_b09FwReleaseFix;
 4637                 fw.start_addr = bce_COM_b09FwStartAddr;
 4638 
 4639                 fw.text_addr = bce_COM_b09FwTextAddr;
 4640                 fw.text_len = bce_COM_b09FwTextLen;
 4641                 fw.text_index = 0;
 4642                 fw.text = bce_COM_b09FwText;
 4643 
 4644                 fw.data_addr = bce_COM_b09FwDataAddr;
 4645                 fw.data_len = bce_COM_b09FwDataLen;
 4646                 fw.data_index = 0;
 4647                 fw.data = bce_COM_b09FwData;
 4648 
 4649                 fw.sbss_addr = bce_COM_b09FwSbssAddr;
 4650                 fw.sbss_len = bce_COM_b09FwSbssLen;
 4651                 fw.sbss_index = 0;
 4652                 fw.sbss = bce_COM_b09FwSbss;
 4653 
 4654                 fw.bss_addr = bce_COM_b09FwBssAddr;
 4655                 fw.bss_len = bce_COM_b09FwBssLen;
 4656                 fw.bss_index = 0;
 4657                 fw.bss = bce_COM_b09FwBss;
 4658 
 4659                 fw.rodata_addr = bce_COM_b09FwRodataAddr;
 4660                 fw.rodata_len = bce_COM_b09FwRodataLen;
 4661                 fw.rodata_index = 0;
 4662                 fw.rodata = bce_COM_b09FwRodata;
 4663         } else {
 4664                 fw.ver_major = bce_COM_b06FwReleaseMajor;
 4665                 fw.ver_minor = bce_COM_b06FwReleaseMinor;
 4666                 fw.ver_fix = bce_COM_b06FwReleaseFix;
 4667                 fw.start_addr = bce_COM_b06FwStartAddr;
 4668 
 4669                 fw.text_addr = bce_COM_b06FwTextAddr;
 4670                 fw.text_len = bce_COM_b06FwTextLen;
 4671                 fw.text_index = 0;
 4672                 fw.text = bce_COM_b06FwText;
 4673 
 4674                 fw.data_addr = bce_COM_b06FwDataAddr;
 4675                 fw.data_len = bce_COM_b06FwDataLen;
 4676                 fw.data_index = 0;
 4677                 fw.data = bce_COM_b06FwData;
 4678 
 4679                 fw.sbss_addr = bce_COM_b06FwSbssAddr;
 4680                 fw.sbss_len = bce_COM_b06FwSbssLen;
 4681                 fw.sbss_index = 0;
 4682                 fw.sbss = bce_COM_b06FwSbss;
 4683 
 4684                 fw.bss_addr = bce_COM_b06FwBssAddr;
 4685                 fw.bss_len = bce_COM_b06FwBssLen;
 4686                 fw.bss_index = 0;
 4687                 fw.bss = bce_COM_b06FwBss;
 4688 
 4689                 fw.rodata_addr = bce_COM_b06FwRodataAddr;
 4690                 fw.rodata_len = bce_COM_b06FwRodataLen;
 4691                 fw.rodata_index = 0;
 4692                 fw.rodata = bce_COM_b06FwRodata;
 4693         }
 4694 
 4695         DBPRINT(sc, BCE_INFO_RESET, "Loading COM firmware.\n");
 4696         bce_load_cpu_fw(sc, &cpu_reg, &fw);
 4697         bce_start_cpu(sc, &cpu_reg);
 4698 
 4699         DBEXIT(BCE_VERBOSE_RESET);
 4700 }
 4701 
 4702 
 4703 /****************************************************************************/
 4704 /* Initialize the RV2P, RX, TX, TPAT, COM, and CP CPUs.                     */
 4705 /*                                                                          */
 4706 /* Loads the firmware for each CPU and starts the CPU.                      */
 4707 /*                                                                          */
 4708 /* Returns:                                                                 */
 4709 /*   Nothing.                                                               */
 4710 /****************************************************************************/
 4711 static void
 4712 bce_init_cpus(struct bce_softc *sc)
 4713 {
 4714         DBENTER(BCE_VERBOSE_RESET);
 4715 
 4716         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 4717 
 4718                 if ((BCE_CHIP_REV(sc) == BCE_CHIP_REV_Ax)) {
 4719                         bce_load_rv2p_fw(sc, bce_xi90_rv2p_proc1,
 4720                             sizeof(bce_xi90_rv2p_proc1), RV2P_PROC1);
 4721                         bce_load_rv2p_fw(sc, bce_xi90_rv2p_proc2,
 4722                             sizeof(bce_xi90_rv2p_proc2), RV2P_PROC2);
 4723                 } else {
 4724                         bce_load_rv2p_fw(sc, bce_xi_rv2p_proc1,
 4725                             sizeof(bce_xi_rv2p_proc1), RV2P_PROC1);
 4726                         bce_load_rv2p_fw(sc, bce_xi_rv2p_proc2,
 4727                             sizeof(bce_xi_rv2p_proc2), RV2P_PROC2);
 4728                 }
 4729 
 4730         } else {
 4731                 bce_load_rv2p_fw(sc, bce_rv2p_proc1,
 4732                     sizeof(bce_rv2p_proc1), RV2P_PROC1);
 4733                 bce_load_rv2p_fw(sc, bce_rv2p_proc2,
 4734                     sizeof(bce_rv2p_proc2), RV2P_PROC2);
 4735         }
 4736 
 4737         bce_init_rxp_cpu(sc);
 4738         bce_init_txp_cpu(sc);
 4739         bce_init_tpat_cpu(sc);
 4740         bce_init_com_cpu(sc);
 4741         bce_init_cp_cpu(sc);
 4742 
 4743         DBEXIT(BCE_VERBOSE_RESET);
 4744 }
 4745 
 4746 
 4747 /****************************************************************************/
 4748 /* Initialize context memory.                                               */
 4749 /*                                                                          */
 4750 /* Clears the memory associated with each Context ID (CID).                 */
 4751 /*                                                                          */
 4752 /* Returns:                                                                 */
 4753 /*   Nothing.                                                               */
 4754 /****************************************************************************/
 4755 static int
 4756 bce_init_ctx(struct bce_softc *sc)
 4757 {
 4758         u32 offset, val, vcid_addr;
 4759         int i, j, rc, retry_cnt;
 4760 
 4761         rc = 0;
 4762         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
 4763 
 4764         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 4765                 retry_cnt = CTX_INIT_RETRY_COUNT;
 4766 
 4767                 DBPRINT(sc, BCE_INFO_CTX, "Initializing 5709 context.\n");
 4768 
 4769                 /*
 4770                  * BCM5709 context memory may be cached
 4771                  * in host memory so prepare the host memory
 4772                  * for access.
 4773                  */
 4774                 val = BCE_CTX_COMMAND_ENABLED |
 4775                     BCE_CTX_COMMAND_MEM_INIT | (1 << 12);
 4776                 val |= (BCM_PAGE_BITS - 8) << 16;
 4777                 REG_WR(sc, BCE_CTX_COMMAND, val);
 4778 
 4779                 /* Wait for mem init command to complete. */
 4780                 for (i = 0; i < retry_cnt; i++) {
 4781                         val = REG_RD(sc, BCE_CTX_COMMAND);
 4782                         if (!(val & BCE_CTX_COMMAND_MEM_INIT))
 4783                                 break;
 4784                         DELAY(2);
 4785                 }
 4786                 if ((val & BCE_CTX_COMMAND_MEM_INIT) != 0) {
 4787                         BCE_PRINTF("%s(): Context memory initialization failed!\n",
 4788                             __FUNCTION__);
 4789                         rc = EBUSY;
 4790                         goto init_ctx_fail;
 4791                 }
 4792 
 4793                 for (i = 0; i < sc->ctx_pages; i++) {
 4794                         /* Set the physical address of the context memory. */
 4795                         REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA0,
 4796                             BCE_ADDR_LO(sc->ctx_paddr[i] & 0xfffffff0) |
 4797                             BCE_CTX_HOST_PAGE_TBL_DATA0_VALID);
 4798                         REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_DATA1,
 4799                             BCE_ADDR_HI(sc->ctx_paddr[i]));
 4800                         REG_WR(sc, BCE_CTX_HOST_PAGE_TBL_CTRL, i |
 4801                             BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ);
 4802 
 4803                         /* Verify the context memory write was successful. */
 4804                         for (j = 0; j < retry_cnt; j++) {
 4805                                 val = REG_RD(sc, BCE_CTX_HOST_PAGE_TBL_CTRL);
 4806                                 if ((val &
 4807                                     BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) == 0)
 4808                                         break;
 4809                                 DELAY(5);
 4810                         }
 4811                         if ((val & BCE_CTX_HOST_PAGE_TBL_CTRL_WRITE_REQ) != 0) {
 4812                                 BCE_PRINTF("%s(): Failed to initialize "
 4813                                     "context page %d!\n", __FUNCTION__, i);
 4814                                 rc = EBUSY;
 4815                                 goto init_ctx_fail;
 4816                         }
 4817                 }
 4818         } else {
 4819 
 4820                 DBPRINT(sc, BCE_INFO, "Initializing 5706/5708 context.\n");
 4821 
 4822                 /*
 4823                  * For the 5706/5708, context memory is local to
 4824                  * the controller, so initialize the controller
 4825                  * context memory.
 4826                  */
 4827 
 4828                 vcid_addr = GET_CID_ADDR(96);
 4829                 while (vcid_addr) {
 4830 
 4831                         vcid_addr -= PHY_CTX_SIZE;
 4832 
 4833                         REG_WR(sc, BCE_CTX_VIRT_ADDR, 0);
 4834                         REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
 4835 
 4836                         for(offset = 0; offset < PHY_CTX_SIZE; offset += 4) {
 4837                                 CTX_WR(sc, 0x00, offset, 0);
 4838                         }
 4839 
 4840                         REG_WR(sc, BCE_CTX_VIRT_ADDR, vcid_addr);
 4841                         REG_WR(sc, BCE_CTX_PAGE_TBL, vcid_addr);
 4842                 }
 4843 
 4844         }
 4845 init_ctx_fail:
 4846         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX);
 4847         return (rc);
 4848 }
 4849 
 4850 
 4851 /****************************************************************************/
 4852 /* Fetch the permanent MAC address of the controller.                       */
 4853 /*                                                                          */
 4854 /* Returns:                                                                 */
 4855 /*   Nothing.                                                               */
 4856 /****************************************************************************/
 4857 static void
 4858 bce_get_mac_addr(struct bce_softc *sc)
 4859 {
 4860         u32 mac_lo = 0, mac_hi = 0;
 4861 
 4862         DBENTER(BCE_VERBOSE_RESET);
 4863 
 4864         /*
 4865          * The NetXtreme II bootcode populates various NIC
 4866          * power-on and runtime configuration items in a
 4867          * shared memory area.  The factory configured MAC
 4868          * address is available from both NVRAM and the
 4869          * shared memory area so we'll read the value from
 4870          * shared memory for speed.
 4871          */
 4872 
 4873         mac_hi = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_UPPER);
 4874         mac_lo = bce_shmem_rd(sc, BCE_PORT_HW_CFG_MAC_LOWER);
 4875 
 4876         if ((mac_lo == 0) && (mac_hi == 0)) {
 4877                 BCE_PRINTF("%s(%d): Invalid Ethernet address!\n",
 4878                     __FILE__, __LINE__);
 4879         } else {
 4880                 sc->eaddr[0] = (u_char)(mac_hi >> 8);
 4881                 sc->eaddr[1] = (u_char)(mac_hi >> 0);
 4882                 sc->eaddr[2] = (u_char)(mac_lo >> 24);
 4883                 sc->eaddr[3] = (u_char)(mac_lo >> 16);
 4884                 sc->eaddr[4] = (u_char)(mac_lo >> 8);
 4885                 sc->eaddr[5] = (u_char)(mac_lo >> 0);
 4886         }
 4887 
 4888         DBPRINT(sc, BCE_INFO_MISC, "Permanent Ethernet "
 4889             "address = %6D\n", sc->eaddr, ":");
 4890         DBEXIT(BCE_VERBOSE_RESET);
 4891 }
 4892 
 4893 
 4894 /****************************************************************************/
 4895 /* Program the MAC address.                                                 */
 4896 /*                                                                          */
 4897 /* Returns:                                                                 */
 4898 /*   Nothing.                                                               */
 4899 /****************************************************************************/
 4900 static void
 4901 bce_set_mac_addr(struct bce_softc *sc)
 4902 {
 4903         u32 val;
 4904         u8 *mac_addr = sc->eaddr;
 4905 
 4906         /* ToDo: Add support for setting multiple MAC addresses. */
 4907 
 4908         DBENTER(BCE_VERBOSE_RESET);
 4909         DBPRINT(sc, BCE_INFO_MISC, "Setting Ethernet address = "
 4910             "%6D\n", sc->eaddr, ":");
 4911 
 4912         val = (mac_addr[0] << 8) | mac_addr[1];
 4913 
 4914         REG_WR(sc, BCE_EMAC_MAC_MATCH0, val);
 4915 
 4916         val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
 4917             (mac_addr[4] << 8) | mac_addr[5];
 4918 
 4919         REG_WR(sc, BCE_EMAC_MAC_MATCH1, val);
 4920 
 4921         DBEXIT(BCE_VERBOSE_RESET);
 4922 }
 4923 
 4924 
 4925 /****************************************************************************/
 4926 /* Stop the controller.                                                     */
 4927 /*                                                                          */
 4928 /* Returns:                                                                 */
 4929 /*   Nothing.                                                               */
 4930 /****************************************************************************/
 4931 static void
 4932 bce_stop(struct bce_softc *sc)
 4933 {
 4934         struct ifnet *ifp;
 4935 
 4936         DBENTER(BCE_VERBOSE_RESET);
 4937 
 4938         BCE_LOCK_ASSERT(sc);
 4939 
 4940         ifp = sc->bce_ifp;
 4941 
 4942         callout_stop(&sc->bce_tick_callout);
 4943 
 4944         /* Disable the transmit/receive blocks. */
 4945         REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS, BCE_MISC_ENABLE_CLR_DEFAULT);
 4946         REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
 4947         DELAY(20);
 4948 
 4949         bce_disable_intr(sc);
 4950 
 4951         /* Free RX buffers. */
 4952         if (bce_hdr_split == TRUE) {
 4953                 bce_free_pg_chain(sc);
 4954         }
 4955         bce_free_rx_chain(sc);
 4956 
 4957         /* Free TX buffers. */
 4958         bce_free_tx_chain(sc);
 4959 
 4960         sc->watchdog_timer = 0;
 4961 
 4962         sc->bce_link_up = FALSE;
 4963 
 4964         ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
 4965 
 4966         DBEXIT(BCE_VERBOSE_RESET);
 4967 }
 4968 
 4969 
 4970 static int
 4971 bce_reset(struct bce_softc *sc, u32 reset_code)
 4972 {
 4973         u32 emac_mode_save, val;
 4974         int i, rc = 0;
 4975         static const u32 emac_mode_mask = BCE_EMAC_MODE_PORT |
 4976             BCE_EMAC_MODE_HALF_DUPLEX | BCE_EMAC_MODE_25G;
 4977 
 4978         DBENTER(BCE_VERBOSE_RESET);
 4979 
 4980         DBPRINT(sc, BCE_VERBOSE_RESET, "%s(): reset_code = 0x%08X\n",
 4981             __FUNCTION__, reset_code);
 4982 
 4983         /*
 4984          * If ASF/IPMI is operational, then the EMAC Mode register already
 4985          * contains appropriate values for the link settings that have
 4986          * been auto-negotiated.  Resetting the chip will clobber those
 4987          * values.  Save the important bits so we can restore them after
 4988          * the reset.
 4989          */
 4990         emac_mode_save = REG_RD(sc, BCE_EMAC_MODE) & emac_mode_mask;
 4991 
 4992         /* Wait for pending PCI transactions to complete. */
 4993         REG_WR(sc, BCE_MISC_ENABLE_CLR_BITS,
 4994             BCE_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
 4995             BCE_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
 4996             BCE_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
 4997             BCE_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
 4998         val = REG_RD(sc, BCE_MISC_ENABLE_CLR_BITS);
 4999         DELAY(5);
 5000 
 5001         /* Disable DMA */
 5002         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 5003                 val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
 5004                 val &= ~BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
 5005                 REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
 5006         }
 5007 
 5008         /* Assume bootcode is running. */
 5009         sc->bce_fw_timed_out = FALSE;
 5010         sc->bce_drv_cardiac_arrest = FALSE;
 5011 
 5012         /* Give the firmware a chance to prepare for the reset. */
 5013         rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT0 | reset_code);
 5014         if (rc)
 5015                 goto bce_reset_exit;
 5016 
 5017         /* Set a firmware reminder that this is a soft reset. */
 5018         bce_shmem_wr(sc, BCE_DRV_RESET_SIGNATURE, BCE_DRV_RESET_SIGNATURE_MAGIC);
 5019 
 5020         /* Dummy read to force the chip to complete all current transactions. */
 5021         val = REG_RD(sc, BCE_MISC_ID);
 5022 
 5023         /* Chip reset. */
 5024         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 5025                 REG_WR(sc, BCE_MISC_COMMAND, BCE_MISC_COMMAND_SW_RESET);
 5026                 REG_RD(sc, BCE_MISC_COMMAND);
 5027                 DELAY(5);
 5028 
 5029                 val = BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
 5030                     BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
 5031 
 5032                 pci_write_config(sc->bce_dev, BCE_PCICFG_MISC_CONFIG, val, 4);
 5033         } else {
 5034                 val = BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
 5035                     BCE_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
 5036                     BCE_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
 5037                 REG_WR(sc, BCE_PCICFG_MISC_CONFIG, val);
 5038 
 5039                 /* Allow up to 30us for reset to complete. */
 5040                 for (i = 0; i < 10; i++) {
 5041                         val = REG_RD(sc, BCE_PCICFG_MISC_CONFIG);
 5042                         if ((val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
 5043                             BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0) {
 5044                                 break;
 5045                         }
 5046                         DELAY(10);
 5047                 }
 5048 
 5049                 /* Check that reset completed successfully. */
 5050                 if (val & (BCE_PCICFG_MISC_CONFIG_CORE_RST_REQ |
 5051                     BCE_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
 5052                         BCE_PRINTF("%s(%d): Reset failed!\n",
 5053                             __FILE__, __LINE__);
 5054                         rc = EBUSY;
 5055                         goto bce_reset_exit;
 5056                 }
 5057         }
 5058 
 5059         /* Make sure byte swapping is properly configured. */
 5060         val = REG_RD(sc, BCE_PCI_SWAP_DIAG0);
 5061         if (val != 0x01020304) {
 5062                 BCE_PRINTF("%s(%d): Byte swap is incorrect!\n",
 5063                     __FILE__, __LINE__);
 5064                 rc = ENODEV;
 5065                 goto bce_reset_exit;
 5066         }
 5067 
 5068         /* Just completed a reset, assume that firmware is running again. */
 5069         sc->bce_fw_timed_out = FALSE;
 5070         sc->bce_drv_cardiac_arrest = FALSE;
 5071 
 5072         /* Wait for the firmware to finish its initialization. */
 5073         rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT1 | reset_code);
 5074         if (rc)
 5075                 BCE_PRINTF("%s(%d): Firmware did not complete "
 5076                     "initialization!\n", __FILE__, __LINE__);
 5077         /* Get firmware capabilities. */
 5078         bce_fw_cap_init(sc);
 5079 
 5080 bce_reset_exit:
 5081         /* Restore EMAC Mode bits needed to keep ASF/IPMI running. */
 5082         if (reset_code == BCE_DRV_MSG_CODE_RESET) {
 5083                 val = REG_RD(sc, BCE_EMAC_MODE);
 5084                 val = (val & ~emac_mode_mask) | emac_mode_save;
 5085                 REG_WR(sc, BCE_EMAC_MODE, val);
 5086         }
 5087 
 5088         DBEXIT(BCE_VERBOSE_RESET);
 5089         return (rc);
 5090 }
 5091 
 5092 
 5093 static int
 5094 bce_chipinit(struct bce_softc *sc)
 5095 {
 5096         u32 val;
 5097         int rc = 0;
 5098 
 5099         DBENTER(BCE_VERBOSE_RESET);
 5100 
 5101         bce_disable_intr(sc);
 5102 
 5103         /*
 5104          * Initialize DMA byte/word swapping, configure the number of DMA
 5105          * channels and PCI clock compensation delay.
 5106          */
 5107         val = BCE_DMA_CONFIG_DATA_BYTE_SWAP |
 5108             BCE_DMA_CONFIG_DATA_WORD_SWAP |
 5109 #if BYTE_ORDER == BIG_ENDIAN
 5110             BCE_DMA_CONFIG_CNTL_BYTE_SWAP |
 5111 #endif
 5112             BCE_DMA_CONFIG_CNTL_WORD_SWAP |
 5113             DMA_READ_CHANS << 12 |
 5114             DMA_WRITE_CHANS << 16;
 5115 
 5116         val |= (0x2 << 20) | BCE_DMA_CONFIG_CNTL_PCI_COMP_DLY;
 5117 
 5118         if ((sc->bce_flags & BCE_PCIX_FLAG) && (sc->bus_speed_mhz == 133))
 5119                 val |= BCE_DMA_CONFIG_PCI_FAST_CLK_CMP;
 5120 
 5121         /*
 5122          * This setting resolves a problem observed on certain Intel PCI
 5123          * chipsets that cannot handle multiple outstanding DMA operations.
 5124          * See errata E9_5706A1_65.
 5125          */
 5126         if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
 5127             (BCE_CHIP_ID(sc) != BCE_CHIP_ID_5706_A0) &&
 5128             !(sc->bce_flags & BCE_PCIX_FLAG))
 5129                 val |= BCE_DMA_CONFIG_CNTL_PING_PONG_DMA;
 5130 
 5131         REG_WR(sc, BCE_DMA_CONFIG, val);
 5132 
 5133         /* Enable the RX_V2P and Context state machines before access. */
 5134         REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
 5135             BCE_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
 5136             BCE_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
 5137             BCE_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
 5138 
 5139         /* Initialize context mapping and zero out the quick contexts. */
 5140         if ((rc = bce_init_ctx(sc)) != 0)
 5141                 goto bce_chipinit_exit;
 5142 
 5143         /* Initialize the on-boards CPUs */
 5144         bce_init_cpus(sc);
 5145 
 5146         /* Enable management frames (NC-SI) to flow to the MCP. */
 5147         if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
 5148                 val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) | BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
 5149                 REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
 5150         }
 5151 
 5152         /* Prepare NVRAM for access. */
 5153         if ((rc = bce_init_nvram(sc)) != 0)
 5154                 goto bce_chipinit_exit;
 5155 
 5156         /* Set the kernel bypass block size */
 5157         val = REG_RD(sc, BCE_MQ_CONFIG);
 5158         val &= ~BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE;
 5159         val |= BCE_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
 5160 
 5161         /* Enable bins used on the 5709. */
 5162         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 5163                 val |= BCE_MQ_CONFIG_BIN_MQ_MODE;
 5164                 if (BCE_CHIP_ID(sc) == BCE_CHIP_ID_5709_A1)
 5165                         val |= BCE_MQ_CONFIG_HALT_DIS;
 5166         }
 5167 
 5168         REG_WR(sc, BCE_MQ_CONFIG, val);
 5169 
 5170         val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
 5171         REG_WR(sc, BCE_MQ_KNL_BYP_WIND_START, val);
 5172         REG_WR(sc, BCE_MQ_KNL_WIND_END, val);
 5173 
 5174         /* Set the page size and clear the RV2P processor stall bits. */
 5175         val = (BCM_PAGE_BITS - 8) << 24;
 5176         REG_WR(sc, BCE_RV2P_CONFIG, val);
 5177 
 5178         /* Configure page size. */
 5179         val = REG_RD(sc, BCE_TBDR_CONFIG);
 5180         val &= ~BCE_TBDR_CONFIG_PAGE_SIZE;
 5181         val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
 5182         REG_WR(sc, BCE_TBDR_CONFIG, val);
 5183 
 5184         /* Set the perfect match control register to default. */
 5185         REG_WR_IND(sc, BCE_RXP_PM_CTRL, 0);
 5186 
 5187 bce_chipinit_exit:
 5188         DBEXIT(BCE_VERBOSE_RESET);
 5189 
 5190         return(rc);
 5191 }
 5192 
 5193 
 5194 /****************************************************************************/
 5195 /* Initialize the controller in preparation to send/receive traffic.        */
 5196 /*                                                                          */
 5197 /* Returns:                                                                 */
 5198 /*   0 for success, positive value for failure.                             */
 5199 /****************************************************************************/
 5200 static int
 5201 bce_blockinit(struct bce_softc *sc)
 5202 {
 5203         u32 reg, val;
 5204         int rc = 0;
 5205 
 5206         DBENTER(BCE_VERBOSE_RESET);
 5207 
 5208         /* Load the hardware default MAC address. */
 5209         bce_set_mac_addr(sc);
 5210 
 5211         /* Set the Ethernet backoff seed value */
 5212         val = sc->eaddr[0]         + (sc->eaddr[1] << 8) +
 5213               (sc->eaddr[2] << 16) + (sc->eaddr[3]     ) +
 5214               (sc->eaddr[4] << 8)  + (sc->eaddr[5] << 16);
 5215         REG_WR(sc, BCE_EMAC_BACKOFF_SEED, val);
 5216 
 5217         sc->last_status_idx = 0;
 5218         sc->rx_mode = BCE_EMAC_RX_MODE_SORT_MODE;
 5219 
 5220         /* Set up link change interrupt generation. */
 5221         REG_WR(sc, BCE_EMAC_ATTENTION_ENA, BCE_EMAC_ATTENTION_ENA_LINK);
 5222 
 5223         /* Program the physical address of the status block. */
 5224         REG_WR(sc, BCE_HC_STATUS_ADDR_L,
 5225             BCE_ADDR_LO(sc->status_block_paddr));
 5226         REG_WR(sc, BCE_HC_STATUS_ADDR_H,
 5227             BCE_ADDR_HI(sc->status_block_paddr));
 5228 
 5229         /* Program the physical address of the statistics block. */
 5230         REG_WR(sc, BCE_HC_STATISTICS_ADDR_L,
 5231             BCE_ADDR_LO(sc->stats_block_paddr));
 5232         REG_WR(sc, BCE_HC_STATISTICS_ADDR_H,
 5233             BCE_ADDR_HI(sc->stats_block_paddr));
 5234 
 5235         /*
 5236          * Program various host coalescing parameters.
 5237          * Trip points control how many BDs should be ready before generating
 5238          * an interrupt while ticks control how long a BD can sit in the chain
 5239          * before generating an interrupt.
 5240          */
 5241         REG_WR(sc, BCE_HC_TX_QUICK_CONS_TRIP,
 5242             (sc->bce_tx_quick_cons_trip_int << 16) |
 5243             sc->bce_tx_quick_cons_trip);
 5244         REG_WR(sc, BCE_HC_RX_QUICK_CONS_TRIP,
 5245             (sc->bce_rx_quick_cons_trip_int << 16) |
 5246             sc->bce_rx_quick_cons_trip);
 5247         REG_WR(sc, BCE_HC_TX_TICKS,
 5248             (sc->bce_tx_ticks_int << 16) | sc->bce_tx_ticks);
 5249         REG_WR(sc, BCE_HC_RX_TICKS,
 5250             (sc->bce_rx_ticks_int << 16) | sc->bce_rx_ticks);
 5251         REG_WR(sc, BCE_HC_STATS_TICKS, sc->bce_stats_ticks & 0xffff00);
 5252         REG_WR(sc, BCE_HC_STAT_COLLECT_TICKS, 0xbb8);  /* 3ms */
 5253         /* Not used for L2. */
 5254         REG_WR(sc, BCE_HC_COMP_PROD_TRIP, 0);
 5255         REG_WR(sc, BCE_HC_COM_TICKS, 0);
 5256         REG_WR(sc, BCE_HC_CMD_TICKS, 0);
 5257 
 5258         /* Configure the Host Coalescing block. */
 5259         val = BCE_HC_CONFIG_RX_TMR_MODE | BCE_HC_CONFIG_TX_TMR_MODE |
 5260             BCE_HC_CONFIG_COLLECT_STATS;
 5261 
 5262 #if 0
 5263         /* ToDo: Add MSI-X support. */
 5264         if (sc->bce_flags & BCE_USING_MSIX_FLAG) {
 5265                 u32 base = ((BCE_TX_VEC - 1) * BCE_HC_SB_CONFIG_SIZE) +
 5266                     BCE_HC_SB_CONFIG_1;
 5267 
 5268                 REG_WR(sc, BCE_HC_MSIX_BIT_VECTOR, BCE_HC_MSIX_BIT_VECTOR_VAL);
 5269 
 5270                 REG_WR(sc, base, BCE_HC_SB_CONFIG_1_TX_TMR_MODE |
 5271                     BCE_HC_SB_CONFIG_1_ONE_SHOT);
 5272 
 5273                 REG_WR(sc, base + BCE_HC_TX_QUICK_CONS_TRIP_OFF,
 5274                     (sc->tx_quick_cons_trip_int << 16) |
 5275                      sc->tx_quick_cons_trip);
 5276 
 5277                 REG_WR(sc, base + BCE_HC_TX_TICKS_OFF,
 5278                     (sc->tx_ticks_int << 16) | sc->tx_ticks);
 5279 
 5280                 val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
 5281         }
 5282 
 5283         /*
 5284          * Tell the HC block to automatically set the
 5285          * INT_MASK bit after an MSI/MSI-X interrupt
 5286          * is generated so the driver doesn't have to.
 5287          */
 5288         if (sc->bce_flags & BCE_ONE_SHOT_MSI_FLAG)
 5289                 val |= BCE_HC_CONFIG_ONE_SHOT;
 5290 
 5291         /* Set the MSI-X status blocks to 128 byte boundaries. */
 5292         if (sc->bce_flags & BCE_USING_MSIX_FLAG)
 5293                 val |= BCE_HC_CONFIG_SB_ADDR_INC_128B;
 5294 #endif
 5295 
 5296         REG_WR(sc, BCE_HC_CONFIG, val);
 5297 
 5298         /* Clear the internal statistics counters. */
 5299         REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
 5300 
 5301         /* Verify that bootcode is running. */
 5302         reg = bce_shmem_rd(sc, BCE_DEV_INFO_SIGNATURE);
 5303 
 5304         DBRUNIF(DB_RANDOMTRUE(bootcode_running_failure_sim_control),
 5305             BCE_PRINTF("%s(%d): Simulating bootcode failure.\n",
 5306             __FILE__, __LINE__);
 5307             reg = 0);
 5308 
 5309         if ((reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
 5310             BCE_DEV_INFO_SIGNATURE_MAGIC) {
 5311                 BCE_PRINTF("%s(%d): Bootcode not running! Found: 0x%08X, "
 5312                     "Expected: 08%08X\n", __FILE__, __LINE__,
 5313                     (reg & BCE_DEV_INFO_SIGNATURE_MAGIC_MASK),
 5314                     BCE_DEV_INFO_SIGNATURE_MAGIC);
 5315                 rc = ENODEV;
 5316                 goto bce_blockinit_exit;
 5317         }
 5318 
 5319         /* Enable DMA */
 5320         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 5321                 val = REG_RD(sc, BCE_MISC_NEW_CORE_CTL);
 5322                 val |= BCE_MISC_NEW_CORE_CTL_DMA_ENABLE;
 5323                 REG_WR(sc, BCE_MISC_NEW_CORE_CTL, val);
 5324         }
 5325 
 5326         /* Allow bootcode to apply additional fixes before enabling MAC. */
 5327         rc = bce_fw_sync(sc, BCE_DRV_MSG_DATA_WAIT2 |
 5328             BCE_DRV_MSG_CODE_RESET);
 5329 
 5330         /* Enable link state change interrupt generation. */
 5331         REG_WR(sc, BCE_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
 5332 
 5333         /* Enable the RXP. */
 5334         bce_start_rxp_cpu(sc);
 5335 
 5336         /* Disable management frames (NC-SI) from flowing to the MCP. */
 5337         if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
 5338                 val = REG_RD(sc, BCE_RPM_MGMT_PKT_CTRL) &
 5339                     ~BCE_RPM_MGMT_PKT_CTRL_MGMT_EN;
 5340                 REG_WR(sc, BCE_RPM_MGMT_PKT_CTRL, val);
 5341         }
 5342 
 5343         /* Enable all remaining blocks in the MAC. */
 5344         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
 5345                 REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
 5346                     BCE_MISC_ENABLE_DEFAULT_XI);
 5347         else
 5348                 REG_WR(sc, BCE_MISC_ENABLE_SET_BITS,
 5349                     BCE_MISC_ENABLE_DEFAULT);
 5350 
 5351         REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
 5352         DELAY(20);
 5353 
 5354         /* Save the current host coalescing block settings. */
 5355         sc->hc_command = REG_RD(sc, BCE_HC_COMMAND);
 5356 
 5357 bce_blockinit_exit:
 5358         DBEXIT(BCE_VERBOSE_RESET);
 5359 
 5360         return (rc);
 5361 }
 5362 
 5363 
 5364 /****************************************************************************/
 5365 /* Encapsulate an mbuf into the rx_bd chain.                                */
 5366 /*                                                                          */
 5367 /* Returns:                                                                 */
 5368 /*   0 for success, positive value for failure.                             */
 5369 /****************************************************************************/
 5370 static int
 5371 bce_get_rx_buf(struct bce_softc *sc, u16 prod, u16 chain_prod, u32 *prod_bseq)
 5372 {
 5373         bus_dma_segment_t segs[1];
 5374         struct mbuf *m_new = NULL;
 5375         struct rx_bd *rxbd;
 5376         int nsegs, error, rc = 0;
 5377 #ifdef BCE_DEBUG
 5378         u16 debug_chain_prod = chain_prod;
 5379 #endif
 5380 
 5381         DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
 5382 
 5383         /* Make sure the inputs are valid. */
 5384         DBRUNIF((chain_prod > MAX_RX_BD_ALLOC),
 5385             BCE_PRINTF("%s(%d): RX producer out of range: "
 5386             "0x%04X > 0x%04X\n", __FILE__, __LINE__,
 5387             chain_prod, (u16)MAX_RX_BD_ALLOC));
 5388 
 5389         DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
 5390             "chain_prod = 0x%04X, prod_bseq = 0x%08X\n", __FUNCTION__,
 5391             prod, chain_prod, *prod_bseq);
 5392 
 5393         /* Update some debug statistic counters */
 5394         DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
 5395             sc->rx_low_watermark = sc->free_rx_bd);
 5396         DBRUNIF((sc->free_rx_bd == sc->max_rx_bd),
 5397             sc->rx_empty_count++);
 5398 
 5399         /* Simulate an mbuf allocation failure. */
 5400         DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
 5401             sc->mbuf_alloc_failed_count++;
 5402             sc->mbuf_alloc_failed_sim_count++;
 5403             rc = ENOBUFS;
 5404             goto bce_get_rx_buf_exit);
 5405 
 5406         /* This is a new mbuf allocation. */
 5407         if (bce_hdr_split == TRUE)
 5408                 MGETHDR(m_new, M_NOWAIT, MT_DATA);
 5409         else
 5410                 m_new = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR,
 5411                     sc->rx_bd_mbuf_alloc_size);
 5412 
 5413         if (m_new == NULL) {
 5414                 sc->mbuf_alloc_failed_count++;
 5415                 rc = ENOBUFS;
 5416                 goto bce_get_rx_buf_exit;
 5417         }
 5418 
 5419         DBRUN(sc->debug_rx_mbuf_alloc++);
 5420 
 5421         /* Make sure we have a valid packet header. */
 5422         M_ASSERTPKTHDR(m_new);
 5423 
 5424         /* Initialize the mbuf size and pad if necessary for alignment. */
 5425         m_new->m_pkthdr.len = m_new->m_len = sc->rx_bd_mbuf_alloc_size;
 5426         m_adj(m_new, sc->rx_bd_mbuf_align_pad);
 5427 
 5428         /* ToDo: Consider calling m_fragment() to test error handling. */
 5429 
 5430         /* Map the mbuf cluster into device memory. */
 5431         error = bus_dmamap_load_mbuf_sg(sc->rx_mbuf_tag,
 5432             sc->rx_mbuf_map[chain_prod], m_new, segs, &nsegs, BUS_DMA_NOWAIT);
 5433 
 5434         /* Handle any mapping errors. */
 5435         if (error) {
 5436                 BCE_PRINTF("%s(%d): Error mapping mbuf into RX "
 5437                     "chain (%d)!\n", __FILE__, __LINE__, error);
 5438 
 5439                 sc->dma_map_addr_rx_failed_count++;
 5440                 m_freem(m_new);
 5441 
 5442                 DBRUN(sc->debug_rx_mbuf_alloc--);
 5443 
 5444                 rc = ENOBUFS;
 5445                 goto bce_get_rx_buf_exit;
 5446         }
 5447 
 5448         /* All mbufs must map to a single segment. */
 5449         KASSERT(nsegs == 1, ("%s(): Too many segments returned (%d)!",
 5450             __FUNCTION__, nsegs));
 5451 
 5452         /* Setup the rx_bd for the segment. */
 5453         rxbd = &sc->rx_bd_chain[RX_PAGE(chain_prod)][RX_IDX(chain_prod)];
 5454 
 5455         rxbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(segs[0].ds_addr));
 5456         rxbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(segs[0].ds_addr));
 5457         rxbd->rx_bd_len       = htole32(segs[0].ds_len);
 5458         rxbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
 5459         *prod_bseq += segs[0].ds_len;
 5460 
 5461         /* Save the mbuf and update our counter. */
 5462         sc->rx_mbuf_ptr[chain_prod] = m_new;
 5463         sc->free_rx_bd -= nsegs;
 5464 
 5465         DBRUNMSG(BCE_INSANE_RECV,
 5466             bce_dump_rx_mbuf_chain(sc, debug_chain_prod, nsegs));
 5467 
 5468         DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
 5469             "chain_prod = 0x%04X, prod_bseq = 0x%08X\n", __FUNCTION__, prod,
 5470             chain_prod, *prod_bseq);
 5471 
 5472 bce_get_rx_buf_exit:
 5473         DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
 5474 
 5475         return(rc);
 5476 }
 5477 
 5478 
 5479 /****************************************************************************/
 5480 /* Encapsulate an mbuf cluster into the page chain.                         */
 5481 /*                                                                          */
 5482 /* Returns:                                                                 */
 5483 /*   0 for success, positive value for failure.                             */
 5484 /****************************************************************************/
 5485 static int
 5486 bce_get_pg_buf(struct bce_softc *sc, u16 prod, u16 prod_idx)
 5487 {
 5488         bus_dma_segment_t segs[1];
 5489         struct mbuf *m_new = NULL;
 5490         struct rx_bd *pgbd;
 5491         int error, nsegs, rc = 0;
 5492 #ifdef BCE_DEBUG
 5493         u16 debug_prod_idx = prod_idx;
 5494 #endif
 5495 
 5496         DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
 5497 
 5498         /* Make sure the inputs are valid. */
 5499         DBRUNIF((prod_idx > MAX_PG_BD_ALLOC),
 5500             BCE_PRINTF("%s(%d): page producer out of range: "
 5501             "0x%04X > 0x%04X\n", __FILE__, __LINE__,
 5502             prod_idx, (u16)MAX_PG_BD_ALLOC));
 5503 
 5504         DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, "
 5505             "chain_prod = 0x%04X\n", __FUNCTION__, prod, prod_idx);
 5506 
 5507         /* Update counters if we've hit a new low or run out of pages. */
 5508         DBRUNIF((sc->free_pg_bd < sc->pg_low_watermark),
 5509             sc->pg_low_watermark = sc->free_pg_bd);
 5510         DBRUNIF((sc->free_pg_bd == sc->max_pg_bd), sc->pg_empty_count++);
 5511 
 5512         /* Simulate an mbuf allocation failure. */
 5513         DBRUNIF(DB_RANDOMTRUE(mbuf_alloc_failed_sim_control),
 5514             sc->mbuf_alloc_failed_count++;
 5515             sc->mbuf_alloc_failed_sim_count++;
 5516             rc = ENOBUFS;
 5517             goto bce_get_pg_buf_exit);
 5518 
 5519         /* This is a new mbuf allocation. */
 5520         m_new = m_getcl(M_NOWAIT, MT_DATA, 0);
 5521         if (m_new == NULL) {
 5522                 sc->mbuf_alloc_failed_count++;
 5523                 rc = ENOBUFS;
 5524                 goto bce_get_pg_buf_exit;
 5525         }
 5526 
 5527         DBRUN(sc->debug_pg_mbuf_alloc++);
 5528 
 5529         m_new->m_len = MCLBYTES;
 5530 
 5531         /* ToDo: Consider calling m_fragment() to test error handling. */
 5532 
 5533         /* Map the mbuf cluster into device memory. */
 5534         error = bus_dmamap_load_mbuf_sg(sc->pg_mbuf_tag,
 5535             sc->pg_mbuf_map[prod_idx], m_new, segs, &nsegs, BUS_DMA_NOWAIT);
 5536 
 5537         /* Handle any mapping errors. */
 5538         if (error) {
 5539                 BCE_PRINTF("%s(%d): Error mapping mbuf into page chain!\n",
 5540                     __FILE__, __LINE__);
 5541 
 5542                 m_freem(m_new);
 5543                 DBRUN(sc->debug_pg_mbuf_alloc--);
 5544 
 5545                 rc = ENOBUFS;
 5546                 goto bce_get_pg_buf_exit;
 5547         }
 5548 
 5549         /* All mbufs must map to a single segment. */
 5550         KASSERT(nsegs == 1, ("%s(): Too many segments returned (%d)!",
 5551             __FUNCTION__, nsegs));
 5552 
 5553         /* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREREAD) here? */
 5554 
 5555         /*
 5556          * The page chain uses the same rx_bd data structure
 5557          * as the receive chain but doesn't require a byte sequence (bseq).
 5558          */
 5559         pgbd = &sc->pg_bd_chain[PG_PAGE(prod_idx)][PG_IDX(prod_idx)];
 5560 
 5561         pgbd->rx_bd_haddr_lo  = htole32(BCE_ADDR_LO(segs[0].ds_addr));
 5562         pgbd->rx_bd_haddr_hi  = htole32(BCE_ADDR_HI(segs[0].ds_addr));
 5563         pgbd->rx_bd_len       = htole32(MCLBYTES);
 5564         pgbd->rx_bd_flags     = htole32(RX_BD_FLAGS_START | RX_BD_FLAGS_END);
 5565 
 5566         /* Save the mbuf and update our counter. */
 5567         sc->pg_mbuf_ptr[prod_idx] = m_new;
 5568         sc->free_pg_bd--;
 5569 
 5570         DBRUNMSG(BCE_INSANE_RECV,
 5571             bce_dump_pg_mbuf_chain(sc, debug_prod_idx, 1));
 5572 
 5573         DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): prod = 0x%04X, "
 5574             "prod_idx = 0x%04X\n", __FUNCTION__, prod, prod_idx);
 5575 
 5576 bce_get_pg_buf_exit:
 5577         DBEXIT(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD);
 5578 
 5579         return(rc);
 5580 }
 5581 
 5582 
 5583 /****************************************************************************/
 5584 /* Initialize the TX context memory.                                        */
 5585 /*                                                                          */
 5586 /* Returns:                                                                 */
 5587 /*   Nothing                                                                */
 5588 /****************************************************************************/
 5589 static void
 5590 bce_init_tx_context(struct bce_softc *sc)
 5591 {
 5592         u32 val;
 5593 
 5594         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
 5595 
 5596         /* Initialize the context ID for an L2 TX chain. */
 5597         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 5598                 /* Set the CID type to support an L2 connection. */
 5599                 val = BCE_L2CTX_TX_TYPE_TYPE_L2_XI |
 5600                     BCE_L2CTX_TX_TYPE_SIZE_L2_XI;
 5601                 CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE_XI, val);
 5602                 val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2_XI | (8 << 16);
 5603                 CTX_WR(sc, GET_CID_ADDR(TX_CID),
 5604                     BCE_L2CTX_TX_CMD_TYPE_XI, val);
 5605 
 5606                 /* Point the hardware to the first page in the chain. */
 5607                 val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
 5608                 CTX_WR(sc, GET_CID_ADDR(TX_CID),
 5609                     BCE_L2CTX_TX_TBDR_BHADDR_HI_XI, val);
 5610                 val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
 5611                 CTX_WR(sc, GET_CID_ADDR(TX_CID),
 5612                     BCE_L2CTX_TX_TBDR_BHADDR_LO_XI, val);
 5613         } else {
 5614                 /* Set the CID type to support an L2 connection. */
 5615                 val = BCE_L2CTX_TX_TYPE_TYPE_L2 | BCE_L2CTX_TX_TYPE_SIZE_L2;
 5616                 CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_TYPE, val);
 5617                 val = BCE_L2CTX_TX_CMD_TYPE_TYPE_L2 | (8 << 16);
 5618                 CTX_WR(sc, GET_CID_ADDR(TX_CID), BCE_L2CTX_TX_CMD_TYPE, val);
 5619 
 5620                 /* Point the hardware to the first page in the chain. */
 5621                 val = BCE_ADDR_HI(sc->tx_bd_chain_paddr[0]);
 5622                 CTX_WR(sc, GET_CID_ADDR(TX_CID),
 5623                     BCE_L2CTX_TX_TBDR_BHADDR_HI, val);
 5624                 val = BCE_ADDR_LO(sc->tx_bd_chain_paddr[0]);
 5625                 CTX_WR(sc, GET_CID_ADDR(TX_CID),
 5626                     BCE_L2CTX_TX_TBDR_BHADDR_LO, val);
 5627         }
 5628 
 5629         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
 5630 }
 5631 
 5632 
 5633 /****************************************************************************/
 5634 /* Allocate memory and initialize the TX data structures.                   */
 5635 /*                                                                          */
 5636 /* Returns:                                                                 */
 5637 /*   0 for success, positive value for failure.                             */
 5638 /****************************************************************************/
 5639 static int
 5640 bce_init_tx_chain(struct bce_softc *sc)
 5641 {
 5642         struct tx_bd *txbd;
 5643         int i, rc = 0;
 5644 
 5645         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
 5646 
 5647         /* Set the initial TX producer/consumer indices. */
 5648         sc->tx_prod        = 0;
 5649         sc->tx_cons        = 0;
 5650         sc->tx_prod_bseq   = 0;
 5651         sc->used_tx_bd     = 0;
 5652         sc->max_tx_bd      = USABLE_TX_BD_ALLOC;
 5653         DBRUN(sc->tx_hi_watermark = 0);
 5654         DBRUN(sc->tx_full_count = 0);
 5655 
 5656         /*
 5657          * The NetXtreme II supports a linked-list structre called
 5658          * a Buffer Descriptor Chain (or BD chain).  A BD chain
 5659          * consists of a series of 1 or more chain pages, each of which
 5660          * consists of a fixed number of BD entries.
 5661          * The last BD entry on each page is a pointer to the next page
 5662          * in the chain, and the last pointer in the BD chain
 5663          * points back to the beginning of the chain.
 5664          */
 5665 
 5666         /* Set the TX next pointer chain entries. */
 5667         for (i = 0; i < sc->tx_pages; i++) {
 5668                 int j;
 5669 
 5670                 txbd = &sc->tx_bd_chain[i][USABLE_TX_BD_PER_PAGE];
 5671 
 5672                 /* Check if we've reached the last page. */
 5673                 if (i == (sc->tx_pages - 1))
 5674                         j = 0;
 5675                 else
 5676                         j = i + 1;
 5677 
 5678                 txbd->tx_bd_haddr_hi =
 5679                     htole32(BCE_ADDR_HI(sc->tx_bd_chain_paddr[j]));
 5680                 txbd->tx_bd_haddr_lo =
 5681                     htole32(BCE_ADDR_LO(sc->tx_bd_chain_paddr[j]));
 5682         }
 5683 
 5684         bce_init_tx_context(sc);
 5685 
 5686         DBRUNMSG(BCE_INSANE_SEND, bce_dump_tx_chain(sc, 0, TOTAL_TX_BD_ALLOC));
 5687         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD);
 5688 
 5689         return(rc);
 5690 }
 5691 
 5692 
 5693 /****************************************************************************/
 5694 /* Free memory and clear the TX data structures.                            */
 5695 /*                                                                          */
 5696 /* Returns:                                                                 */
 5697 /*   Nothing.                                                               */
 5698 /****************************************************************************/
 5699 static void
 5700 bce_free_tx_chain(struct bce_softc *sc)
 5701 {
 5702         int i;
 5703 
 5704         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
 5705 
 5706         /* Unmap, unload, and free any mbufs still in the TX mbuf chain. */
 5707         for (i = 0; i < MAX_TX_BD_AVAIL; i++) {
 5708                 if (sc->tx_mbuf_ptr[i] != NULL) {
 5709                         if (sc->tx_mbuf_map[i] != NULL)
 5710                                 bus_dmamap_sync(sc->tx_mbuf_tag,
 5711                                     sc->tx_mbuf_map[i],
 5712                                     BUS_DMASYNC_POSTWRITE);
 5713                         m_freem(sc->tx_mbuf_ptr[i]);
 5714                         sc->tx_mbuf_ptr[i] = NULL;
 5715                         DBRUN(sc->debug_tx_mbuf_alloc--);
 5716                 }
 5717         }
 5718 
 5719         /* Clear each TX chain page. */
 5720         for (i = 0; i < sc->tx_pages; i++)
 5721                 bzero((char *)sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ);
 5722 
 5723         sc->used_tx_bd = 0;
 5724 
 5725         /* Check if we lost any mbufs in the process. */
 5726         DBRUNIF((sc->debug_tx_mbuf_alloc),
 5727             BCE_PRINTF("%s(%d): Memory leak! Lost %d mbufs "
 5728             "from tx chain!\n", __FILE__, __LINE__,
 5729             sc->debug_tx_mbuf_alloc));
 5730 
 5731         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD);
 5732 }
 5733 
 5734 
 5735 /****************************************************************************/
 5736 /* Initialize the RX context memory.                                        */
 5737 /*                                                                          */
 5738 /* Returns:                                                                 */
 5739 /*   Nothing                                                                */
 5740 /****************************************************************************/
 5741 static void
 5742 bce_init_rx_context(struct bce_softc *sc)
 5743 {
 5744         u32 val;
 5745 
 5746         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
 5747 
 5748         /* Init the type, size, and BD cache levels for the RX context. */
 5749         val = BCE_L2CTX_RX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE |
 5750             BCE_L2CTX_RX_CTX_TYPE_SIZE_L2 |
 5751             (0x02 << BCE_L2CTX_RX_BD_PRE_READ_SHIFT);
 5752 
 5753         /*
 5754          * Set the level for generating pause frames
 5755          * when the number of available rx_bd's gets
 5756          * too low (the low watermark) and the level
 5757          * when pause frames can be stopped (the high
 5758          * watermark).
 5759          */
 5760         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 5761                 u32 lo_water, hi_water;
 5762 
 5763                 if (sc->bce_flags & BCE_USING_TX_FLOW_CONTROL) {
 5764                         lo_water = BCE_L2CTX_RX_LO_WATER_MARK_DEFAULT;
 5765                 } else {
 5766                         lo_water = 0;
 5767                 }
 5768 
 5769                 if (lo_water >= USABLE_RX_BD_ALLOC) {
 5770                         lo_water = 0;
 5771                 }
 5772 
 5773                 hi_water = USABLE_RX_BD_ALLOC / 4;
 5774 
 5775                 if (hi_water <= lo_water) {
 5776                         lo_water = 0;
 5777                 }
 5778 
 5779                 lo_water /= BCE_L2CTX_RX_LO_WATER_MARK_SCALE;
 5780                 hi_water /= BCE_L2CTX_RX_HI_WATER_MARK_SCALE;
 5781 
 5782                 if (hi_water > 0xf)
 5783                         hi_water = 0xf;
 5784                 else if (hi_water == 0)
 5785                         lo_water = 0;
 5786 
 5787                 val |= (lo_water << BCE_L2CTX_RX_LO_WATER_MARK_SHIFT) |
 5788                     (hi_water << BCE_L2CTX_RX_HI_WATER_MARK_SHIFT);
 5789         }
 5790 
 5791         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_CTX_TYPE, val);
 5792 
 5793         /* Setup the MQ BIN mapping for l2_ctx_host_bseq. */
 5794         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
 5795                 val = REG_RD(sc, BCE_MQ_MAP_L2_5);
 5796                 REG_WR(sc, BCE_MQ_MAP_L2_5, val | BCE_MQ_MAP_L2_5_ARM);
 5797         }
 5798 
 5799         /* Point the hardware to the first page in the chain. */
 5800         val = BCE_ADDR_HI(sc->rx_bd_chain_paddr[0]);
 5801         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_HI, val);
 5802         val = BCE_ADDR_LO(sc->rx_bd_chain_paddr[0]);
 5803         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_BDHADDR_LO, val);
 5804 
 5805         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_CTX);
 5806 }
 5807 
 5808 
 5809 /****************************************************************************/
 5810 /* Allocate memory and initialize the RX data structures.                   */
 5811 /*                                                                          */
 5812 /* Returns:                                                                 */
 5813 /*   0 for success, positive value for failure.                             */
 5814 /****************************************************************************/
 5815 static int
 5816 bce_init_rx_chain(struct bce_softc *sc)
 5817 {
 5818         struct rx_bd *rxbd;
 5819         int i, rc = 0;
 5820 
 5821         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
 5822             BCE_VERBOSE_CTX);
 5823 
 5824         /* Initialize the RX producer and consumer indices. */
 5825         sc->rx_prod        = 0;
 5826         sc->rx_cons        = 0;
 5827         sc->rx_prod_bseq   = 0;
 5828         sc->free_rx_bd     = USABLE_RX_BD_ALLOC;
 5829         sc->max_rx_bd      = USABLE_RX_BD_ALLOC;
 5830 
 5831         /* Initialize the RX next pointer chain entries. */
 5832         for (i = 0; i < sc->rx_pages; i++) {
 5833                 int j;
 5834 
 5835                 rxbd = &sc->rx_bd_chain[i][USABLE_RX_BD_PER_PAGE];
 5836 
 5837                 /* Check if we've reached the last page. */
 5838                 if (i == (sc->rx_pages - 1))
 5839                         j = 0;
 5840                 else
 5841                         j = i + 1;
 5842 
 5843                 /* Setup the chain page pointers. */
 5844                 rxbd->rx_bd_haddr_hi =
 5845                     htole32(BCE_ADDR_HI(sc->rx_bd_chain_paddr[j]));
 5846                 rxbd->rx_bd_haddr_lo =
 5847                     htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j]));
 5848         }
 5849 
 5850         /* Fill up the RX chain. */
 5851         bce_fill_rx_chain(sc);
 5852 
 5853         DBRUN(sc->rx_low_watermark = USABLE_RX_BD_ALLOC);
 5854         DBRUN(sc->rx_empty_count = 0);
 5855         for (i = 0; i < sc->rx_pages; i++) {
 5856                 bus_dmamap_sync(sc->rx_bd_chain_tag, sc->rx_bd_chain_map[i],
 5857                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 5858         }
 5859 
 5860         bce_init_rx_context(sc);
 5861 
 5862         DBRUNMSG(BCE_EXTREME_RECV,
 5863             bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD_ALLOC));
 5864         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
 5865             BCE_VERBOSE_CTX);
 5866 
 5867         /* ToDo: Are there possible failure modes here? */
 5868 
 5869         return(rc);
 5870 }
 5871 
 5872 
 5873 /****************************************************************************/
 5874 /* Add mbufs to the RX chain until its full or an mbuf allocation error     */
 5875 /* occurs.                                                                  */
 5876 /*                                                                          */
 5877 /* Returns:                                                                 */
 5878 /*   Nothing                                                                */
 5879 /****************************************************************************/
 5880 static void
 5881 bce_fill_rx_chain(struct bce_softc *sc)
 5882 {
 5883         u16 prod, prod_idx;
 5884         u32 prod_bseq;
 5885 
 5886         DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
 5887             BCE_VERBOSE_CTX);
 5888 
 5889         /* Get the RX chain producer indices. */
 5890         prod      = sc->rx_prod;
 5891         prod_bseq = sc->rx_prod_bseq;
 5892 
 5893         /* Keep filling the RX chain until it's full. */
 5894         while (sc->free_rx_bd > 0) {
 5895                 prod_idx = RX_CHAIN_IDX(prod);
 5896                 if (bce_get_rx_buf(sc, prod, prod_idx, &prod_bseq)) {
 5897                         /* Bail out if we can't add an mbuf to the chain. */
 5898                         break;
 5899                 }
 5900                 prod = NEXT_RX_BD(prod);
 5901         }
 5902 
 5903         /* Save the RX chain producer indices. */
 5904         sc->rx_prod      = prod;
 5905         sc->rx_prod_bseq = prod_bseq;
 5906 
 5907         /* We should never end up pointing to a next page pointer. */
 5908         DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
 5909             BCE_PRINTF("%s(): Invalid rx_prod value: 0x%04X\n",
 5910             __FUNCTION__, rx_prod));
 5911 
 5912         /* Write the mailbox and tell the chip about the waiting rx_bd's. */
 5913         REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BDIDX, prod);
 5914         REG_WR(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_BSEQ, prod_bseq);
 5915 
 5916         DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
 5917             BCE_VERBOSE_CTX);
 5918 }
 5919 
 5920 
 5921 /****************************************************************************/
 5922 /* Free memory and clear the RX data structures.                            */
 5923 /*                                                                          */
 5924 /* Returns:                                                                 */
 5925 /*   Nothing.                                                               */
 5926 /****************************************************************************/
 5927 static void
 5928 bce_free_rx_chain(struct bce_softc *sc)
 5929 {
 5930         int i;
 5931 
 5932         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
 5933 
 5934         /* Free any mbufs still in the RX mbuf chain. */
 5935         for (i = 0; i < MAX_RX_BD_AVAIL; i++) {
 5936                 if (sc->rx_mbuf_ptr[i] != NULL) {
 5937                         if (sc->rx_mbuf_map[i] != NULL)
 5938                                 bus_dmamap_sync(sc->rx_mbuf_tag,
 5939                                     sc->rx_mbuf_map[i],
 5940                                     BUS_DMASYNC_POSTREAD);
 5941                         m_freem(sc->rx_mbuf_ptr[i]);
 5942                         sc->rx_mbuf_ptr[i] = NULL;
 5943                         DBRUN(sc->debug_rx_mbuf_alloc--);
 5944                 }
 5945         }
 5946 
 5947         /* Clear each RX chain page. */
 5948         for (i = 0; i < sc->rx_pages; i++)
 5949                 if (sc->rx_bd_chain[i] != NULL)
 5950                         bzero((char *)sc->rx_bd_chain[i],
 5951                             BCE_RX_CHAIN_PAGE_SZ);
 5952 
 5953         sc->free_rx_bd = sc->max_rx_bd;
 5954 
 5955         /* Check if we lost any mbufs in the process. */
 5956         DBRUNIF((sc->debug_rx_mbuf_alloc),
 5957             BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from rx chain!\n",
 5958             __FUNCTION__, sc->debug_rx_mbuf_alloc));
 5959 
 5960         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
 5961 }
 5962 
 5963 
 5964 /****************************************************************************/
 5965 /* Allocate memory and initialize the page data structures.                 */
 5966 /* Assumes that bce_init_rx_chain() has not already been called.            */
 5967 /*                                                                          */
 5968 /* Returns:                                                                 */
 5969 /*   0 for success, positive value for failure.                             */
 5970 /****************************************************************************/
 5971 static int
 5972 bce_init_pg_chain(struct bce_softc *sc)
 5973 {
 5974         struct rx_bd *pgbd;
 5975         int i, rc = 0;
 5976         u32 val;
 5977 
 5978         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
 5979                 BCE_VERBOSE_CTX);
 5980 
 5981         /* Initialize the page producer and consumer indices. */
 5982         sc->pg_prod        = 0;
 5983         sc->pg_cons        = 0;
 5984         sc->free_pg_bd     = USABLE_PG_BD_ALLOC;
 5985         sc->max_pg_bd      = USABLE_PG_BD_ALLOC;
 5986         DBRUN(sc->pg_low_watermark = sc->max_pg_bd);
 5987         DBRUN(sc->pg_empty_count = 0);
 5988 
 5989         /* Initialize the page next pointer chain entries. */
 5990         for (i = 0; i < sc->pg_pages; i++) {
 5991                 int j;
 5992 
 5993                 pgbd = &sc->pg_bd_chain[i][USABLE_PG_BD_PER_PAGE];
 5994 
 5995                 /* Check if we've reached the last page. */
 5996                 if (i == (sc->pg_pages - 1))
 5997                         j = 0;
 5998                 else
 5999                         j = i + 1;
 6000 
 6001                 /* Setup the chain page pointers. */
 6002                 pgbd->rx_bd_haddr_hi =
 6003                     htole32(BCE_ADDR_HI(sc->pg_bd_chain_paddr[j]));
 6004                 pgbd->rx_bd_haddr_lo =
 6005                     htole32(BCE_ADDR_LO(sc->pg_bd_chain_paddr[j]));
 6006         }
 6007 
 6008         /* Setup the MQ BIN mapping for host_pg_bidx. */
 6009         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
 6010                 REG_WR(sc, BCE_MQ_MAP_L2_3, BCE_MQ_MAP_L2_3_DEFAULT);
 6011 
 6012         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, 0);
 6013 
 6014         /* Configure the rx_bd and page chain mbuf cluster size. */
 6015         val = (sc->rx_bd_mbuf_data_len << 16) | MCLBYTES;
 6016         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_PG_BUF_SIZE, val);
 6017 
 6018         /* Configure the context reserved for jumbo support. */
 6019         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_RBDC_KEY,
 6020                 BCE_L2CTX_RX_RBDC_JUMBO_KEY);
 6021 
 6022         /* Point the hardware to the first page in the page chain. */
 6023         val = BCE_ADDR_HI(sc->pg_bd_chain_paddr[0]);
 6024         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_HI, val);
 6025         val = BCE_ADDR_LO(sc->pg_bd_chain_paddr[0]);
 6026         CTX_WR(sc, GET_CID_ADDR(RX_CID), BCE_L2CTX_RX_NX_PG_BDHADDR_LO, val);
 6027 
 6028         /* Fill up the page chain. */
 6029         bce_fill_pg_chain(sc);
 6030 
 6031         for (i = 0; i < sc->pg_pages; i++) {
 6032                 bus_dmamap_sync(sc->pg_bd_chain_tag, sc->pg_bd_chain_map[i],
 6033                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 6034         }
 6035 
 6036         DBRUNMSG(BCE_EXTREME_RECV,
 6037             bce_dump_pg_chain(sc, 0, TOTAL_PG_BD_ALLOC));
 6038         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD |
 6039                 BCE_VERBOSE_CTX);
 6040         return(rc);
 6041 }
 6042 
 6043 
 6044 /****************************************************************************/
 6045 /* Add mbufs to the page chain until its full or an mbuf allocation error   */
 6046 /* occurs.                                                                  */
 6047 /*                                                                          */
 6048 /* Returns:                                                                 */
 6049 /*   Nothing                                                                */
 6050 /****************************************************************************/
 6051 static void
 6052 bce_fill_pg_chain(struct bce_softc *sc)
 6053 {
 6054         u16 prod, prod_idx;
 6055 
 6056         DBENTER(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
 6057             BCE_VERBOSE_CTX);
 6058 
 6059         /* Get the page chain prodcuer index. */
 6060         prod = sc->pg_prod;
 6061 
 6062         /* Keep filling the page chain until it's full. */
 6063         while (sc->free_pg_bd > 0) {
 6064                 prod_idx = PG_CHAIN_IDX(prod);
 6065                 if (bce_get_pg_buf(sc, prod, prod_idx)) {
 6066                         /* Bail out if we can't add an mbuf to the chain. */
 6067                         break;
 6068                 }
 6069                 prod = NEXT_PG_BD(prod);
 6070         }
 6071 
 6072         /* Save the page chain producer index. */
 6073         sc->pg_prod = prod;
 6074 
 6075         DBRUNIF(((prod & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE),
 6076             BCE_PRINTF("%s(): Invalid pg_prod value: 0x%04X\n",
 6077             __FUNCTION__, pg_prod));
 6078 
 6079         /*
 6080          * Write the mailbox and tell the chip about
 6081          * the new rx_bd's in the page chain.
 6082          */
 6083         REG_WR16(sc, MB_GET_CID_ADDR(RX_CID) + BCE_L2MQ_RX_HOST_PG_BDIDX,
 6084             prod);
 6085 
 6086         DBEXIT(BCE_VERBOSE_RESET | BCE_EXTREME_RECV | BCE_VERBOSE_LOAD |
 6087             BCE_VERBOSE_CTX);
 6088 }
 6089 
 6090 
 6091 /****************************************************************************/
 6092 /* Free memory and clear the RX data structures.                            */
 6093 /*                                                                          */
 6094 /* Returns:                                                                 */
 6095 /*   Nothing.                                                               */
 6096 /****************************************************************************/
 6097 static void
 6098 bce_free_pg_chain(struct bce_softc *sc)
 6099 {
 6100         int i;
 6101 
 6102         DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
 6103 
 6104         /* Free any mbufs still in the mbuf page chain. */
 6105         for (i = 0; i < MAX_PG_BD_AVAIL; i++) {
 6106                 if (sc->pg_mbuf_ptr[i] != NULL) {
 6107                         if (sc->pg_mbuf_map[i] != NULL)
 6108                                 bus_dmamap_sync(sc->pg_mbuf_tag,
 6109                                     sc->pg_mbuf_map[i],
 6110                                     BUS_DMASYNC_POSTREAD);
 6111                         m_freem(sc->pg_mbuf_ptr[i]);
 6112                         sc->pg_mbuf_ptr[i] = NULL;
 6113                         DBRUN(sc->debug_pg_mbuf_alloc--);
 6114                 }
 6115         }
 6116 
 6117         /* Clear each page chain pages. */
 6118         for (i = 0; i < sc->pg_pages; i++)
 6119                 bzero((char *)sc->pg_bd_chain[i], BCE_PG_CHAIN_PAGE_SZ);
 6120 
 6121         sc->free_pg_bd = sc->max_pg_bd;
 6122 
 6123         /* Check if we lost any mbufs in the process. */
 6124         DBRUNIF((sc->debug_pg_mbuf_alloc),
 6125             BCE_PRINTF("%s(): Memory leak! Lost %d mbufs from page chain!\n",
 6126             __FUNCTION__, sc->debug_pg_mbuf_alloc));
 6127 
 6128         DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD);
 6129 }
 6130 
 6131 
 6132 static u32
 6133 bce_get_rphy_link(struct bce_softc *sc)
 6134 {
 6135         u32 advertise, link;
 6136         int fdpx;
 6137 
 6138         advertise = 0;
 6139         fdpx = 0;
 6140         if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) != 0)
 6141                 link = bce_shmem_rd(sc, BCE_RPHY_SERDES_LINK);
 6142         else
 6143                 link = bce_shmem_rd(sc, BCE_RPHY_COPPER_LINK);
 6144         if (link & BCE_NETLINK_ANEG_ENB)
 6145                 advertise |= BCE_NETLINK_ANEG_ENB;
 6146         if (link & BCE_NETLINK_SPEED_10HALF)
 6147                 advertise |= BCE_NETLINK_SPEED_10HALF;
 6148         if (link & BCE_NETLINK_SPEED_10FULL) {
 6149                 advertise |= BCE_NETLINK_SPEED_10FULL;
 6150                 fdpx++;
 6151         }
 6152         if (link & BCE_NETLINK_SPEED_100HALF)
 6153                 advertise |= BCE_NETLINK_SPEED_100HALF;
 6154         if (link & BCE_NETLINK_SPEED_100FULL) {
 6155                 advertise |= BCE_NETLINK_SPEED_100FULL;
 6156                 fdpx++;
 6157         }
 6158         if (link & BCE_NETLINK_SPEED_1000HALF)
 6159                 advertise |= BCE_NETLINK_SPEED_1000HALF;
 6160         if (link & BCE_NETLINK_SPEED_1000FULL) {
 6161                 advertise |= BCE_NETLINK_SPEED_1000FULL;
 6162                 fdpx++;
 6163         }
 6164         if (link & BCE_NETLINK_SPEED_2500HALF)
 6165                 advertise |= BCE_NETLINK_SPEED_2500HALF;
 6166         if (link & BCE_NETLINK_SPEED_2500FULL) {
 6167                 advertise |= BCE_NETLINK_SPEED_2500FULL;
 6168                 fdpx++;
 6169         }
 6170         if (fdpx)
 6171                 advertise |= BCE_NETLINK_FC_PAUSE_SYM |
 6172                     BCE_NETLINK_FC_PAUSE_ASYM;
 6173         if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
 6174                 advertise |= BCE_NETLINK_PHY_APP_REMOTE |
 6175                     BCE_NETLINK_ETH_AT_WIRESPEED;
 6176 
 6177         return (advertise);
 6178 }
 6179 
 6180 
 6181 /****************************************************************************/
 6182 /* Set media options.                                                       */
 6183 /*                                                                          */
 6184 /* Returns:                                                                 */
 6185 /*   0 for success, positive value for failure.                             */
 6186 /****************************************************************************/
 6187 static int
 6188 bce_ifmedia_upd(struct ifnet *ifp)
 6189 {
 6190         struct bce_softc *sc = ifp->if_softc;
 6191         int error;
 6192 
 6193         DBENTER(BCE_VERBOSE);
 6194 
 6195         BCE_LOCK(sc);
 6196         error = bce_ifmedia_upd_locked(ifp);
 6197         BCE_UNLOCK(sc);
 6198 
 6199         DBEXIT(BCE_VERBOSE);
 6200         return (error);
 6201 }
 6202 
 6203 
 6204 /****************************************************************************/
 6205 /* Set media options.                                                       */
 6206 /*                                                                          */
 6207 /* Returns:                                                                 */
 6208 /*   Nothing.                                                               */
 6209 /****************************************************************************/
 6210 static int
 6211 bce_ifmedia_upd_locked(struct ifnet *ifp)
 6212 {
 6213         struct bce_softc *sc = ifp->if_softc;
 6214         struct mii_data *mii;
 6215         struct mii_softc *miisc;
 6216         struct ifmedia *ifm;
 6217         u32 link;
 6218         int error, fdx;
 6219 
 6220         DBENTER(BCE_VERBOSE_PHY);
 6221 
 6222         error = 0;
 6223         BCE_LOCK_ASSERT(sc);
 6224 
 6225         sc->bce_link_up = FALSE;
 6226         if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
 6227                 ifm = &sc->bce_ifmedia;
 6228                 if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
 6229                         return (EINVAL);
 6230                 link = 0;
 6231                 fdx = IFM_OPTIONS(ifm->ifm_media) & IFM_FDX;
 6232                 switch(IFM_SUBTYPE(ifm->ifm_media)) {
 6233                 case IFM_AUTO:
 6234                         /*
 6235                          * Check advertised link of remote PHY by reading
 6236                          * BCE_RPHY_SERDES_LINK or BCE_RPHY_COPPER_LINK.
 6237                          * Always use the same link type of remote PHY.
 6238                          */
 6239                         link = bce_get_rphy_link(sc);
 6240                         break;
 6241                 case IFM_2500_SX:
 6242                         if ((sc->bce_phy_flags &
 6243                             (BCE_PHY_REMOTE_PORT_FIBER_FLAG |
 6244                             BCE_PHY_2_5G_CAPABLE_FLAG)) == 0)
 6245                                 return (EINVAL);
 6246                         /*
 6247                          * XXX
 6248                          * Have to enable forced 2.5Gbps configuration.
 6249                          */
 6250                         if (fdx != 0)
 6251                                 link |= BCE_NETLINK_SPEED_2500FULL;
 6252                         else
 6253                                 link |= BCE_NETLINK_SPEED_2500HALF;
 6254                         break;
 6255                 case IFM_1000_SX:
 6256                         if ((sc->bce_phy_flags &
 6257                             BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
 6258                                 return (EINVAL);
 6259                         /*
 6260                          * XXX
 6261                          * Have to disable 2.5Gbps configuration.
 6262                          */
 6263                         if (fdx != 0)
 6264                                 link = BCE_NETLINK_SPEED_1000FULL;
 6265                         else
 6266                                 link = BCE_NETLINK_SPEED_1000HALF;
 6267                         break;
 6268                 case IFM_1000_T:
 6269                         if (sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG)
 6270                                 return (EINVAL);
 6271                         if (fdx != 0)
 6272                                 link = BCE_NETLINK_SPEED_1000FULL;
 6273                         else
 6274                                 link = BCE_NETLINK_SPEED_1000HALF;
 6275                         break;
 6276                 case IFM_100_TX:
 6277                         if (sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG)
 6278                                 return (EINVAL);
 6279                         if (fdx != 0)
 6280                                 link = BCE_NETLINK_SPEED_100FULL;
 6281                         else
 6282                                 link = BCE_NETLINK_SPEED_100HALF;
 6283                         break;
 6284                 case IFM_10_T:
 6285                         if (sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG)
 6286                                 return (EINVAL);
 6287                         if (fdx != 0)
 6288                                 link = BCE_NETLINK_SPEED_10FULL;
 6289                         else
 6290                                 link = BCE_NETLINK_SPEED_10HALF;
 6291                         break;
 6292                 default:
 6293                         return (EINVAL);
 6294                 }
 6295                 if (IFM_SUBTYPE(ifm->ifm_media) != IFM_AUTO) {
 6296                         /*
 6297                          * XXX
 6298                          * Advertise pause capability for full-duplex media.
 6299                          */
 6300                         if (fdx != 0)
 6301                                 link |= BCE_NETLINK_FC_PAUSE_SYM |
 6302                                     BCE_NETLINK_FC_PAUSE_ASYM;
 6303                         if ((sc->bce_phy_flags &
 6304                             BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
 6305                                 link |= BCE_NETLINK_PHY_APP_REMOTE |
 6306                                     BCE_NETLINK_ETH_AT_WIRESPEED;
 6307                 }
 6308 
 6309                 bce_shmem_wr(sc, BCE_MB_ARGS_0, link);
 6310                 error = bce_fw_sync(sc, BCE_DRV_MSG_CODE_CMD_SET_LINK);
 6311         } else {
 6312                 mii = device_get_softc(sc->bce_miibus);
 6313 
 6314                 /* Make sure the MII bus has been enumerated. */
 6315                 if (mii) {
 6316                         LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
 6317                                 PHY_RESET(miisc);
 6318                         error = mii_mediachg(mii);
 6319                 }
 6320         }
 6321 
 6322         DBEXIT(BCE_VERBOSE_PHY);
 6323         return (error);
 6324 }
 6325 
 6326 
 6327 static void
 6328 bce_ifmedia_sts_rphy(struct bce_softc *sc, struct ifmediareq *ifmr)
 6329 {
 6330         struct ifnet *ifp;
 6331         u32 link;
 6332 
 6333         ifp = sc->bce_ifp;
 6334         BCE_LOCK_ASSERT(sc);
 6335 
 6336         ifmr->ifm_status = IFM_AVALID;
 6337         ifmr->ifm_active = IFM_ETHER;
 6338         link = bce_shmem_rd(sc, BCE_LINK_STATUS);
 6339         /* XXX Handle heart beat status? */
 6340         if ((link & BCE_LINK_STATUS_LINK_UP) != 0)
 6341                 ifmr->ifm_status |= IFM_ACTIVE;
 6342         else {
 6343                 ifmr->ifm_active |= IFM_NONE;
 6344                 ifp->if_baudrate = 0;
 6345                 return;
 6346         }
 6347         switch (link & BCE_LINK_STATUS_SPEED_MASK) {
 6348         case BCE_LINK_STATUS_10HALF:
 6349                 ifmr->ifm_active |= IFM_10_T | IFM_HDX;
 6350                 ifp->if_baudrate = IF_Mbps(10UL);
 6351                 break;
 6352         case BCE_LINK_STATUS_10FULL:
 6353                 ifmr->ifm_active |= IFM_10_T | IFM_FDX;
 6354                 ifp->if_baudrate = IF_Mbps(10UL);
 6355                 break;
 6356         case BCE_LINK_STATUS_100HALF:
 6357                 ifmr->ifm_active |= IFM_100_TX | IFM_HDX;
 6358                 ifp->if_baudrate = IF_Mbps(100UL);
 6359                 break;
 6360         case BCE_LINK_STATUS_100FULL:
 6361                 ifmr->ifm_active |= IFM_100_TX | IFM_FDX;
 6362                 ifp->if_baudrate = IF_Mbps(100UL);
 6363                 break;
 6364         case BCE_LINK_STATUS_1000HALF:
 6365                 if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
 6366                         ifmr->ifm_active |= IFM_1000_T | IFM_HDX;
 6367                 else
 6368                         ifmr->ifm_active |= IFM_1000_SX | IFM_HDX;
 6369                 ifp->if_baudrate = IF_Mbps(1000UL);
 6370                 break;
 6371         case BCE_LINK_STATUS_1000FULL:
 6372                 if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0)
 6373                         ifmr->ifm_active |= IFM_1000_T | IFM_FDX;
 6374                 else
 6375                         ifmr->ifm_active |= IFM_1000_SX | IFM_FDX;
 6376                 ifp->if_baudrate = IF_Mbps(1000UL);
 6377                 break;
 6378         case BCE_LINK_STATUS_2500HALF:
 6379                 if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0) {
 6380                         ifmr->ifm_active |= IFM_NONE;
 6381                         return;
 6382                 } else
 6383                         ifmr->ifm_active |= IFM_2500_SX | IFM_HDX;
 6384                 ifp->if_baudrate = IF_Mbps(2500UL);
 6385                 break;
 6386         case BCE_LINK_STATUS_2500FULL:
 6387                 if ((sc->bce_phy_flags & BCE_PHY_REMOTE_PORT_FIBER_FLAG) == 0) {
 6388                         ifmr->ifm_active |= IFM_NONE;
 6389                         return;
 6390                 } else
 6391                         ifmr->ifm_active |= IFM_2500_SX | IFM_FDX;
 6392                 ifp->if_baudrate = IF_Mbps(2500UL);
 6393                 break;
 6394         default:
 6395                 ifmr->ifm_active |= IFM_NONE;
 6396                 return;
 6397         }
 6398 
 6399         if ((link & BCE_LINK_STATUS_RX_FC_ENABLED) != 0)
 6400                 ifmr->ifm_active |= IFM_ETH_RXPAUSE;
 6401         if ((link & BCE_LINK_STATUS_TX_FC_ENABLED) != 0)
 6402                 ifmr->ifm_active |= IFM_ETH_TXPAUSE;
 6403 }
 6404 
 6405 
 6406 /****************************************************************************/
 6407 /* Reports current media status.                                            */
 6408 /*                                                                          */
 6409 /* Returns:                                                                 */
 6410 /*   Nothing.                                                               */
 6411 /****************************************************************************/
 6412 static void
 6413 bce_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 6414 {
 6415         struct bce_softc *sc = ifp->if_softc;
 6416         struct mii_data *mii;
 6417 
 6418         DBENTER(BCE_VERBOSE_PHY);
 6419 
 6420         BCE_LOCK(sc);
 6421 
 6422         if ((ifp->if_flags & IFF_UP) == 0) {
 6423                 BCE_UNLOCK(sc);
 6424                 return;
 6425         }
 6426 
 6427         if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
 6428                 bce_ifmedia_sts_rphy(sc, ifmr);
 6429         else {
 6430                 mii = device_get_softc(sc->bce_miibus);
 6431                 mii_pollstat(mii);
 6432                 ifmr->ifm_active = mii->mii_media_active;
 6433                 ifmr->ifm_status = mii->mii_media_status;
 6434         }
 6435 
 6436         BCE_UNLOCK(sc);
 6437 
 6438         DBEXIT(BCE_VERBOSE_PHY);
 6439 }
 6440 
 6441 
 6442 /****************************************************************************/
 6443 /* Handles PHY generated interrupt events.                                  */
 6444 /*                                                                          */
 6445 /* Returns:                                                                 */
 6446 /*   Nothing.                                                               */
 6447 /****************************************************************************/
 6448 static void
 6449 bce_phy_intr(struct bce_softc *sc)
 6450 {
 6451         u32 new_link_state, old_link_state;
 6452 
 6453         DBENTER(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
 6454 
 6455         DBRUN(sc->phy_interrupts++);
 6456 
 6457         new_link_state = sc->status_block->status_attn_bits &
 6458             STATUS_ATTN_BITS_LINK_STATE;
 6459         old_link_state = sc->status_block->status_attn_bits_ack &
 6460             STATUS_ATTN_BITS_LINK_STATE;
 6461 
 6462         /* Handle any changes if the link state has changed. */
 6463         if (new_link_state != old_link_state) {
 6464 
 6465                 /* Update the status_attn_bits_ack field. */
 6466                 if (new_link_state) {
 6467                         REG_WR(sc, BCE_PCICFG_STATUS_BIT_SET_CMD,
 6468                             STATUS_ATTN_BITS_LINK_STATE);
 6469                         DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now UP.\n",
 6470                             __FUNCTION__);
 6471                 } else {
 6472                         REG_WR(sc, BCE_PCICFG_STATUS_BIT_CLEAR_CMD,
 6473                             STATUS_ATTN_BITS_LINK_STATE);
 6474                         DBPRINT(sc, BCE_INFO_PHY, "%s(): Link is now DOWN.\n",
 6475                             __FUNCTION__);
 6476                 }
 6477 
 6478                 if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
 6479                         if (new_link_state) {
 6480                                 if (bootverbose)
 6481                                         if_printf(sc->bce_ifp, "link UP\n");
 6482                                 if_link_state_change(sc->bce_ifp,
 6483                                     LINK_STATE_UP);
 6484                         } else {
 6485                                 if (bootverbose)
 6486                                         if_printf(sc->bce_ifp, "link DOWN\n");
 6487                                 if_link_state_change(sc->bce_ifp,
 6488                                     LINK_STATE_DOWN);
 6489                         }
 6490                 }
 6491                 /*
 6492                  * Assume link is down and allow
 6493                  * tick routine to update the state
 6494                  * based on the actual media state.
 6495                  */
 6496                 sc->bce_link_up = FALSE;
 6497                 callout_stop(&sc->bce_tick_callout);
 6498                 bce_tick(sc);
 6499         }
 6500 
 6501         /* Acknowledge the link change interrupt. */
 6502         REG_WR(sc, BCE_EMAC_STATUS, BCE_EMAC_STATUS_LINK_CHANGE);
 6503 
 6504         DBEXIT(BCE_VERBOSE_PHY | BCE_VERBOSE_INTR);
 6505 }
 6506 
 6507 
 6508 /****************************************************************************/
 6509 /* Reads the receive consumer value from the status block (skipping over    */
 6510 /* chain page pointer if necessary).                                        */
 6511 /*                                                                          */
 6512 /* Returns:                                                                 */
 6513 /*   hw_cons                                                                */
 6514 /****************************************************************************/
 6515 static inline u16
 6516 bce_get_hw_rx_cons(struct bce_softc *sc)
 6517 {
 6518         u16 hw_cons;
 6519 
 6520         rmb();
 6521         hw_cons = sc->status_block->status_rx_quick_consumer_index0;
 6522         if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
 6523                 hw_cons++;
 6524 
 6525         return hw_cons;
 6526 }
 6527 
 6528 /****************************************************************************/
 6529 /* Handles received frame interrupt events.                                 */
 6530 /*                                                                          */
 6531 /* Returns:                                                                 */
 6532 /*   Nothing.                                                               */
 6533 /****************************************************************************/
 6534 static void
 6535 bce_rx_intr(struct bce_softc *sc)
 6536 {
 6537         struct ifnet *ifp = sc->bce_ifp;
 6538         struct l2_fhdr *l2fhdr;
 6539         struct ether_vlan_header *vh;
 6540         unsigned int pkt_len;
 6541         u16 sw_rx_cons, sw_rx_cons_idx, hw_rx_cons;
 6542         u32 status;
 6543         unsigned int rem_len;
 6544         u16 sw_pg_cons, sw_pg_cons_idx;
 6545 
 6546         DBENTER(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
 6547         DBRUN(sc->interrupts_rx++);
 6548         DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): rx_prod = 0x%04X, "
 6549             "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
 6550             __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
 6551 
 6552         /* Prepare the RX chain pages to be accessed by the host CPU. */
 6553         for (int i = 0; i < sc->rx_pages; i++)
 6554                 bus_dmamap_sync(sc->rx_bd_chain_tag,
 6555                     sc->rx_bd_chain_map[i], BUS_DMASYNC_POSTREAD);
 6556 
 6557         /* Prepare the page chain pages to be accessed by the host CPU. */
 6558         if (bce_hdr_split == TRUE) {
 6559                 for (int i = 0; i < sc->pg_pages; i++)
 6560                         bus_dmamap_sync(sc->pg_bd_chain_tag,
 6561                             sc->pg_bd_chain_map[i], BUS_DMASYNC_POSTREAD);
 6562         }
 6563 
 6564         /* Get the hardware's view of the RX consumer index. */
 6565         hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
 6566 
 6567         /* Get working copies of the driver's view of the consumer indices. */
 6568         sw_rx_cons = sc->rx_cons;
 6569         sw_pg_cons = sc->pg_cons;
 6570 
 6571         /* Update some debug statistics counters */
 6572         DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
 6573             sc->rx_low_watermark = sc->free_rx_bd);
 6574         DBRUNIF((sc->free_rx_bd == sc->max_rx_bd),
 6575             sc->rx_empty_count++);
 6576 
 6577         /* Scan through the receive chain as long as there is work to do */
 6578         /* ToDo: Consider setting a limit on the number of packets processed. */
 6579         rmb();
 6580         while (sw_rx_cons != hw_rx_cons) {
 6581                 struct mbuf *m0;
 6582 
 6583                 /* Convert the producer/consumer indices to an actual rx_bd index. */
 6584                 sw_rx_cons_idx = RX_CHAIN_IDX(sw_rx_cons);
 6585 
 6586                 /* Unmap the mbuf from DMA space. */
 6587                 bus_dmamap_sync(sc->rx_mbuf_tag,
 6588                     sc->rx_mbuf_map[sw_rx_cons_idx],
 6589                     BUS_DMASYNC_POSTREAD);
 6590                 bus_dmamap_unload(sc->rx_mbuf_tag,
 6591                     sc->rx_mbuf_map[sw_rx_cons_idx]);
 6592 
 6593                 /* Remove the mbuf from the RX chain. */
 6594                 m0 = sc->rx_mbuf_ptr[sw_rx_cons_idx];
 6595                 sc->rx_mbuf_ptr[sw_rx_cons_idx] = NULL;
 6596                 DBRUN(sc->debug_rx_mbuf_alloc--);
 6597                 sc->free_rx_bd++;
 6598 
 6599                 /*
 6600                  * Frames received on the NetXteme II are prepended
 6601                  * with an l2_fhdr structure which provides status
 6602                  * information about the received frame (including
 6603                  * VLAN tags and checksum info).  The frames are
 6604                  * also automatically adjusted to word align the IP
 6605                  * header (i.e. two null bytes are inserted before
 6606                  * the Ethernet header).  As a result the data
 6607                  * DMA'd by the controller into the mbuf looks
 6608                  * like this:
 6609                  *
 6610                  * +---------+-----+---------------------+-----+
 6611                  * | l2_fhdr | pad | packet data         | FCS |
 6612                  * +---------+-----+---------------------+-----+
 6613                  *
 6614                  * The l2_fhdr needs to be checked and skipped and
 6615                  * the FCS needs to be stripped before sending the
 6616                  * packet up the stack.
 6617                  */
 6618                 l2fhdr  = mtod(m0, struct l2_fhdr *);
 6619 
 6620                 /* Get the packet data + FCS length and the status. */
 6621                 pkt_len = l2fhdr->l2_fhdr_pkt_len;
 6622                 status  = l2fhdr->l2_fhdr_status;
 6623 
 6624                 /*
 6625                  * Skip over the l2_fhdr and pad, resulting in the
 6626                  * following data in the mbuf:
 6627                  * +---------------------+-----+
 6628                  * | packet data         | FCS |
 6629                  * +---------------------+-----+
 6630                  */
 6631                 m_adj(m0, sizeof(struct l2_fhdr) + ETHER_ALIGN);
 6632 
 6633                 /*
 6634                  * When split header mode is used, an ethernet frame
 6635                  * may be split across the receive chain and the
 6636                  * page chain. If that occurs an mbuf cluster must be
 6637                  * reassembled from the individual mbuf pieces.
 6638                  */
 6639                 if (bce_hdr_split == TRUE) {
 6640                         /*
 6641                          * Check whether the received frame fits in a single
 6642                          * mbuf or not (i.e. packet data + FCS <=
 6643                          * sc->rx_bd_mbuf_data_len bytes).
 6644                          */
 6645                         if (pkt_len > m0->m_len) {
 6646                                 /*
 6647                                  * The received frame is larger than a single mbuf.
 6648                                  * If the frame was a TCP frame then only the TCP
 6649                                  * header is placed in the mbuf, the remaining
 6650                                  * payload (including FCS) is placed in the page
 6651                                  * chain, the SPLIT flag is set, and the header
 6652                                  * length is placed in the IP checksum field.
 6653                                  * If the frame is not a TCP frame then the mbuf
 6654                                  * is filled and the remaining bytes are placed
 6655                                  * in the page chain.
 6656                                  */
 6657 
 6658                                 DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a large "
 6659                                         "packet.\n", __FUNCTION__);
 6660                                 DBRUN(sc->split_header_frames_rcvd++);
 6661 
 6662                                 /*
 6663                                  * When the page chain is enabled and the TCP
 6664                                  * header has been split from the TCP payload,
 6665                                  * the ip_xsum structure will reflect the length
 6666                                  * of the TCP header, not the IP checksum.  Set
 6667                                  * the packet length of the mbuf accordingly.
 6668                                  */
 6669                                 if (status & L2_FHDR_STATUS_SPLIT) {
 6670                                         m0->m_len = l2fhdr->l2_fhdr_ip_xsum;
 6671                                         DBRUN(sc->split_header_tcp_frames_rcvd++);
 6672                                 }
 6673 
 6674                                 rem_len = pkt_len - m0->m_len;
 6675 
 6676                                 /* Pull mbufs off the page chain for any remaining data. */
 6677                                 while (rem_len > 0) {
 6678                                         struct mbuf *m_pg;
 6679 
 6680                                         sw_pg_cons_idx = PG_CHAIN_IDX(sw_pg_cons);
 6681 
 6682                                         /* Remove the mbuf from the page chain. */
 6683                                         m_pg = sc->pg_mbuf_ptr[sw_pg_cons_idx];
 6684                                         sc->pg_mbuf_ptr[sw_pg_cons_idx] = NULL;
 6685                                         DBRUN(sc->debug_pg_mbuf_alloc--);
 6686                                         sc->free_pg_bd++;
 6687 
 6688                                         /* Unmap the page chain mbuf from DMA space. */
 6689                                         bus_dmamap_sync(sc->pg_mbuf_tag,
 6690                                                 sc->pg_mbuf_map[sw_pg_cons_idx],
 6691                                                 BUS_DMASYNC_POSTREAD);
 6692                                         bus_dmamap_unload(sc->pg_mbuf_tag,
 6693                                                 sc->pg_mbuf_map[sw_pg_cons_idx]);
 6694 
 6695                                         /* Adjust the mbuf length. */
 6696                                         if (rem_len < m_pg->m_len) {
 6697                                                 /* The mbuf chain is complete. */
 6698                                                 m_pg->m_len = rem_len;
 6699                                                 rem_len = 0;
 6700                                         } else {
 6701                                                 /* More packet data is waiting. */
 6702                                                 rem_len -= m_pg->m_len;
 6703                                         }
 6704 
 6705                                         /* Concatenate the mbuf cluster to the mbuf. */
 6706                                         m_cat(m0, m_pg);
 6707 
 6708                                         sw_pg_cons = NEXT_PG_BD(sw_pg_cons);
 6709                                 }
 6710 
 6711                                 /* Set the total packet length. */
 6712                                 m0->m_pkthdr.len = pkt_len;
 6713 
 6714                         } else {
 6715                                 /*
 6716                                  * The received packet is small and fits in a
 6717                                  * single mbuf (i.e. the l2_fhdr + pad + packet +
 6718                                  * FCS <= MHLEN).  In other words, the packet is
 6719                                  * 154 bytes or less in size.
 6720                                  */
 6721 
 6722                                 DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a small "
 6723                                         "packet.\n", __FUNCTION__);
 6724 
 6725                                 /* Set the total packet length. */
 6726                                 m0->m_pkthdr.len = m0->m_len = pkt_len;
 6727                         }
 6728                 } else
 6729                         /* Set the total packet length. */
 6730                         m0->m_pkthdr.len = m0->m_len = pkt_len;
 6731 
 6732                 /* Remove the trailing Ethernet FCS. */
 6733                 m_adj(m0, -ETHER_CRC_LEN);
 6734 
 6735                 /* Check that the resulting mbuf chain is valid. */
 6736                 DBRUN(m_sanity(m0, FALSE));
 6737                 DBRUNIF(((m0->m_len < ETHER_HDR_LEN) |
 6738                     (m0->m_pkthdr.len > BCE_MAX_JUMBO_ETHER_MTU_VLAN)),
 6739                     BCE_PRINTF("Invalid Ethernet frame size!\n");
 6740                     m_print(m0, 128));
 6741 
 6742                 DBRUNIF(DB_RANDOMTRUE(l2fhdr_error_sim_control),
 6743                     sc->l2fhdr_error_sim_count++;
 6744                     status = status | L2_FHDR_ERRORS_PHY_DECODE);
 6745 
 6746                 /* Check the received frame for errors. */
 6747                 if (status & (L2_FHDR_ERRORS_BAD_CRC |
 6748                     L2_FHDR_ERRORS_PHY_DECODE | L2_FHDR_ERRORS_ALIGNMENT |
 6749                     L2_FHDR_ERRORS_TOO_SHORT  | L2_FHDR_ERRORS_GIANT_FRAME)) {
 6750 
 6751                         /* Log the error and release the mbuf. */
 6752                         sc->l2fhdr_error_count++;
 6753                         m_freem(m0);
 6754                         m0 = NULL;
 6755                         goto bce_rx_intr_next_rx;
 6756                 }
 6757 
 6758                 /* Send the packet to the appropriate interface. */
 6759                 m0->m_pkthdr.rcvif = ifp;
 6760 
 6761                 /* Assume no hardware checksum. */
 6762                 m0->m_pkthdr.csum_flags = 0;
 6763 
 6764                 /* Validate the checksum if offload enabled. */
 6765                 if (ifp->if_capenable & IFCAP_RXCSUM) {
 6766                         /* Check for an IP datagram. */
 6767                         if (!(status & L2_FHDR_STATUS_SPLIT) &&
 6768                             (status & L2_FHDR_STATUS_IP_DATAGRAM)) {
 6769                                 m0->m_pkthdr.csum_flags |= CSUM_IP_CHECKED;
 6770                                 DBRUN(sc->csum_offload_ip++);
 6771                                 /* Check if the IP checksum is valid. */
 6772                                 if ((l2fhdr->l2_fhdr_ip_xsum ^ 0xffff) == 0)
 6773                                         m0->m_pkthdr.csum_flags |=
 6774                                             CSUM_IP_VALID;
 6775                         }
 6776 
 6777                         /* Check for a valid TCP/UDP frame. */
 6778                         if (status & (L2_FHDR_STATUS_TCP_SEGMENT |
 6779                             L2_FHDR_STATUS_UDP_DATAGRAM)) {
 6780 
 6781                                 /* Check for a good TCP/UDP checksum. */
 6782                                 if ((status & (L2_FHDR_ERRORS_TCP_XSUM |
 6783                                     L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
 6784                                         DBRUN(sc->csum_offload_tcp_udp++);
 6785                                         m0->m_pkthdr.csum_data =
 6786                                             l2fhdr->l2_fhdr_tcp_udp_xsum;
 6787                                         m0->m_pkthdr.csum_flags |=
 6788                                             (CSUM_DATA_VALID
 6789                                             | CSUM_PSEUDO_HDR);
 6790                                 }
 6791                         }
 6792                 }
 6793 
 6794                 /* Attach the VLAN tag. */
 6795                 if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) &&
 6796                     !(sc->rx_mode & BCE_EMAC_RX_MODE_KEEP_VLAN_TAG)) {
 6797                         DBRUN(sc->vlan_tagged_frames_rcvd++);
 6798                         if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) {
 6799                                 DBRUN(sc->vlan_tagged_frames_stripped++);
 6800 #if __FreeBSD_version < 700000
 6801                                 VLAN_INPUT_TAG(ifp, m0,
 6802                                     l2fhdr->l2_fhdr_vlan_tag, continue);
 6803 #else
 6804                                 m0->m_pkthdr.ether_vtag =
 6805                                     l2fhdr->l2_fhdr_vlan_tag;
 6806                                 m0->m_flags |= M_VLANTAG;
 6807 #endif
 6808                         } else {
 6809                                 /*
 6810                                  * bce(4) controllers can't disable VLAN
 6811                                  * tag stripping if management firmware
 6812                                  * (ASF/IPMI/UMP) is running. So we always
 6813                                  * strip VLAN tag and manually reconstruct
 6814                                  * the VLAN frame by appending stripped
 6815                                  * VLAN tag in driver if VLAN tag stripping
 6816                                  * was disabled.
 6817                                  *
 6818                                  * TODO: LLC SNAP handling.
 6819                                  */
 6820                                 bcopy(mtod(m0, uint8_t *),
 6821                                     mtod(m0, uint8_t *) - ETHER_VLAN_ENCAP_LEN,
 6822                                     ETHER_ADDR_LEN * 2);
 6823                                 m0->m_data -= ETHER_VLAN_ENCAP_LEN;
 6824                                 vh = mtod(m0, struct ether_vlan_header *);
 6825                                 vh->evl_encap_proto = htons(ETHERTYPE_VLAN);
 6826                                 vh->evl_tag = htons(l2fhdr->l2_fhdr_vlan_tag);
 6827                                 m0->m_pkthdr.len += ETHER_VLAN_ENCAP_LEN;
 6828                                 m0->m_len += ETHER_VLAN_ENCAP_LEN;
 6829                         }
 6830                 }
 6831 
 6832                 /* Increment received packet statistics. */
 6833                 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
 6834 
 6835 bce_rx_intr_next_rx:
 6836                 sw_rx_cons = NEXT_RX_BD(sw_rx_cons);
 6837 
 6838                 /* If we have a packet, pass it up the stack */
 6839                 if (m0) {
 6840                         /* Make sure we don't lose our place when we release the lock. */
 6841                         sc->rx_cons = sw_rx_cons;
 6842                         sc->pg_cons = sw_pg_cons;
 6843 
 6844                         BCE_UNLOCK(sc);
 6845                         (*ifp->if_input)(ifp, m0);
 6846                         BCE_LOCK(sc);
 6847 
 6848                         /* Recover our place. */
 6849                         sw_rx_cons = sc->rx_cons;
 6850                         sw_pg_cons = sc->pg_cons;
 6851                 }
 6852 
 6853                 /* Refresh hw_cons to see if there's new work */
 6854                 if (sw_rx_cons == hw_rx_cons)
 6855                         hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc);
 6856         }
 6857 
 6858         /* No new packets.  Refill the page chain. */
 6859         if (bce_hdr_split == TRUE) {
 6860                 sc->pg_cons = sw_pg_cons;
 6861                 bce_fill_pg_chain(sc);
 6862         }
 6863 
 6864         /* No new packets.  Refill the RX chain. */
 6865         sc->rx_cons = sw_rx_cons;
 6866         bce_fill_rx_chain(sc);
 6867 
 6868         /* Prepare the page chain pages to be accessed by the NIC. */
 6869         for (int i = 0; i < sc->rx_pages; i++)
 6870                 bus_dmamap_sync(sc->rx_bd_chain_tag,
 6871                     sc->rx_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
 6872 
 6873         if (bce_hdr_split == TRUE) {
 6874                 for (int i = 0; i < sc->pg_pages; i++)
 6875                         bus_dmamap_sync(sc->pg_bd_chain_tag,
 6876                             sc->pg_bd_chain_map[i], BUS_DMASYNC_PREWRITE);
 6877         }
 6878 
 6879         DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): rx_prod = 0x%04X, "
 6880             "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
 6881             __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
 6882         DBEXIT(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
 6883 }
 6884 
 6885 
 6886 /****************************************************************************/
 6887 /* Reads the transmit consumer value from the status block (skipping over   */
 6888 /* chain page pointer if necessary).                                        */
 6889 /*                                                                          */
 6890 /* Returns:                                                                 */
 6891 /*   hw_cons                                                                */
 6892 /****************************************************************************/
 6893 static inline u16
 6894 bce_get_hw_tx_cons(struct bce_softc *sc)
 6895 {
 6896         u16 hw_cons;
 6897 
 6898         mb();
 6899         hw_cons = sc->status_block->status_tx_quick_consumer_index0;
 6900         if ((hw_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
 6901                 hw_cons++;
 6902 
 6903         return hw_cons;
 6904 }
 6905 
 6906 
 6907 /****************************************************************************/
 6908 /* Handles transmit completion interrupt events.                            */
 6909 /*                                                                          */
 6910 /* Returns:                                                                 */
 6911 /*   Nothing.                                                               */
 6912 /****************************************************************************/
 6913 static void
 6914 bce_tx_intr(struct bce_softc *sc)
 6915 {
 6916         struct ifnet *ifp = sc->bce_ifp;
 6917         u16 hw_tx_cons, sw_tx_cons, sw_tx_chain_cons;
 6918 
 6919         DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
 6920         DBRUN(sc->interrupts_tx++);
 6921         DBPRINT(sc, BCE_EXTREME_SEND, "%s(enter): tx_prod = 0x%04X, "
 6922             "tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
 6923             __FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
 6924 
 6925         BCE_LOCK_ASSERT(sc);
 6926 
 6927         /* Get the hardware's view of the TX consumer index. */
 6928         hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
 6929         sw_tx_cons = sc->tx_cons;
 6930 
 6931         /* Prevent speculative reads of the status block. */
 6932         bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
 6933             BUS_SPACE_BARRIER_READ);
 6934 
 6935         /* Cycle through any completed TX chain page entries. */
 6936         while (sw_tx_cons != hw_tx_cons) {
 6937 #ifdef BCE_DEBUG
 6938                 struct tx_bd *txbd = NULL;
 6939 #endif
 6940                 sw_tx_chain_cons = TX_CHAIN_IDX(sw_tx_cons);
 6941 
 6942                 DBPRINT(sc, BCE_INFO_SEND,
 6943                     "%s(): hw_tx_cons = 0x%04X, sw_tx_cons = 0x%04X, "
 6944                     "sw_tx_chain_cons = 0x%04X\n",
 6945                     __FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
 6946 
 6947                 DBRUNIF((sw_tx_chain_cons > MAX_TX_BD_ALLOC),
 6948                     BCE_PRINTF("%s(%d): TX chain consumer out of range! "
 6949                     " 0x%04X > 0x%04X\n", __FILE__, __LINE__, sw_tx_chain_cons,
 6950                     (int) MAX_TX_BD_ALLOC);
 6951                     bce_breakpoint(sc));
 6952 
 6953                 DBRUN(txbd = &sc->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)]
 6954                     [TX_IDX(sw_tx_chain_cons)]);
 6955 
 6956                 DBRUNIF((txbd == NULL),
 6957                     BCE_PRINTF("%s(%d): Unexpected NULL tx_bd[0x%04X]!\n",
 6958                     __FILE__, __LINE__, sw_tx_chain_cons);
 6959                     bce_breakpoint(sc));
 6960 
 6961                 DBRUNMSG(BCE_INFO_SEND, BCE_PRINTF("%s(): ", __FUNCTION__);
 6962                     bce_dump_txbd(sc, sw_tx_chain_cons, txbd));
 6963 
 6964                 /*
 6965                  * Free the associated mbuf. Remember
 6966                  * that only the last tx_bd of a packet
 6967                  * has an mbuf pointer and DMA map.
 6968                  */
 6969                 if (sc->tx_mbuf_ptr[sw_tx_chain_cons] != NULL) {
 6970 
 6971                         /* Validate that this is the last tx_bd. */
 6972                         DBRUNIF((!(txbd->tx_bd_flags & TX_BD_FLAGS_END)),
 6973                             BCE_PRINTF("%s(%d): tx_bd END flag not set but "
 6974                             "txmbuf == NULL!\n", __FILE__, __LINE__);
 6975                             bce_breakpoint(sc));
 6976 
 6977                         DBRUNMSG(BCE_INFO_SEND,
 6978                             BCE_PRINTF("%s(): Unloading map/freeing mbuf "
 6979                             "from tx_bd[0x%04X]\n", __FUNCTION__,
 6980                             sw_tx_chain_cons));
 6981 
 6982                         /* Unmap the mbuf. */
 6983                         bus_dmamap_unload(sc->tx_mbuf_tag,
 6984                             sc->tx_mbuf_map[sw_tx_chain_cons]);
 6985 
 6986                         /* Free the mbuf. */
 6987                         m_freem(sc->tx_mbuf_ptr[sw_tx_chain_cons]);
 6988                         sc->tx_mbuf_ptr[sw_tx_chain_cons] = NULL;
 6989                         DBRUN(sc->debug_tx_mbuf_alloc--);
 6990 
 6991                         if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
 6992                 }
 6993 
 6994                 sc->used_tx_bd--;
 6995                 sw_tx_cons = NEXT_TX_BD(sw_tx_cons);
 6996 
 6997                 /* Refresh hw_cons to see if there's new work. */
 6998                 hw_tx_cons = sc->hw_tx_cons = bce_get_hw_tx_cons(sc);
 6999 
 7000                 /* Prevent speculative reads of the status block. */
 7001                 bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
 7002                     BUS_SPACE_BARRIER_READ);
 7003         }
 7004 
 7005         /* Clear the TX timeout timer. */
 7006         sc->watchdog_timer = 0;
 7007 
 7008         /* Clear the tx hardware queue full flag. */
 7009         if (sc->used_tx_bd < sc->max_tx_bd) {
 7010                 DBRUNIF((ifp->if_drv_flags & IFF_DRV_OACTIVE),
 7011                     DBPRINT(sc, BCE_INFO_SEND,
 7012                     "%s(): Open TX chain! %d/%d (used/total)\n",
 7013                     __FUNCTION__, sc->used_tx_bd, sc->max_tx_bd));
 7014                 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 7015         }
 7016 
 7017         sc->tx_cons = sw_tx_cons;
 7018 
 7019         DBPRINT(sc, BCE_EXTREME_SEND, "%s(exit): tx_prod = 0x%04X, "
 7020             "tx_cons = 0x%04X, tx_prod_bseq = 0x%08X\n",
 7021             __FUNCTION__, sc->tx_prod, sc->tx_cons, sc->tx_prod_bseq);
 7022         DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_INTR);
 7023 }
 7024 
 7025 
 7026 /****************************************************************************/
 7027 /* Disables interrupt generation.                                           */
 7028 /*                                                                          */
 7029 /* Returns:                                                                 */
 7030 /*   Nothing.                                                               */
 7031 /****************************************************************************/
 7032 static void
 7033 bce_disable_intr(struct bce_softc *sc)
 7034 {
 7035         DBENTER(BCE_VERBOSE_INTR);
 7036 
 7037         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD, BCE_PCICFG_INT_ACK_CMD_MASK_INT);
 7038         REG_RD(sc, BCE_PCICFG_INT_ACK_CMD);
 7039 
 7040         DBEXIT(BCE_VERBOSE_INTR);
 7041 }
 7042 
 7043 
 7044 /****************************************************************************/
 7045 /* Enables interrupt generation.                                            */
 7046 /*                                                                          */
 7047 /* Returns:                                                                 */
 7048 /*   Nothing.                                                               */
 7049 /****************************************************************************/
 7050 static void
 7051 bce_enable_intr(struct bce_softc *sc, int coal_now)
 7052 {
 7053         DBENTER(BCE_VERBOSE_INTR);
 7054 
 7055         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
 7056             BCE_PCICFG_INT_ACK_CMD_INDEX_VALID |
 7057             BCE_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
 7058 
 7059         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
 7060             BCE_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
 7061 
 7062         /* Force an immediate interrupt (whether there is new data or not). */
 7063         if (coal_now)
 7064                 REG_WR(sc, BCE_HC_COMMAND, sc->hc_command | BCE_HC_COMMAND_COAL_NOW);
 7065 
 7066         DBEXIT(BCE_VERBOSE_INTR);
 7067 }
 7068 
 7069 
 7070 /****************************************************************************/
 7071 /* Handles controller initialization.                                       */
 7072 /*                                                                          */
 7073 /* Returns:                                                                 */
 7074 /*   Nothing.                                                               */
 7075 /****************************************************************************/
 7076 static void
 7077 bce_init_locked(struct bce_softc *sc)
 7078 {
 7079         struct ifnet *ifp;
 7080         u32 ether_mtu = 0;
 7081 
 7082         DBENTER(BCE_VERBOSE_RESET);
 7083 
 7084         BCE_LOCK_ASSERT(sc);
 7085 
 7086         ifp = sc->bce_ifp;
 7087 
 7088         /* Check if the driver is still running and bail out if it is. */
 7089         if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 7090                 goto bce_init_locked_exit;
 7091 
 7092         bce_stop(sc);
 7093 
 7094         if (bce_reset(sc, BCE_DRV_MSG_CODE_RESET)) {
 7095                 BCE_PRINTF("%s(%d): Controller reset failed!\n",
 7096                     __FILE__, __LINE__);
 7097                 goto bce_init_locked_exit;
 7098         }
 7099 
 7100         if (bce_chipinit(sc)) {
 7101                 BCE_PRINTF("%s(%d): Controller initialization failed!\n",
 7102                     __FILE__, __LINE__);
 7103                 goto bce_init_locked_exit;
 7104         }
 7105 
 7106         if (bce_blockinit(sc)) {
 7107                 BCE_PRINTF("%s(%d): Block initialization failed!\n",
 7108                     __FILE__, __LINE__);
 7109                 goto bce_init_locked_exit;
 7110         }
 7111 
 7112         /* Load our MAC address. */
 7113         bcopy(IF_LLADDR(sc->bce_ifp), sc->eaddr, ETHER_ADDR_LEN);
 7114         bce_set_mac_addr(sc);
 7115 
 7116         if (bce_hdr_split == FALSE)
 7117                 bce_get_rx_buffer_sizes(sc, ifp->if_mtu);
 7118         /*
 7119          * Calculate and program the hardware Ethernet MTU
 7120          * size. Be generous on the receive if we have room
 7121          * and allowed by the user.
 7122          */
 7123         if (bce_strict_rx_mtu == TRUE)
 7124                 ether_mtu = ifp->if_mtu;
 7125         else {
 7126                 if (bce_hdr_split == TRUE) {
 7127                         if (ifp->if_mtu <= sc->rx_bd_mbuf_data_len + MCLBYTES)
 7128                                 ether_mtu = sc->rx_bd_mbuf_data_len +
 7129                                     MCLBYTES;
 7130                         else
 7131                                 ether_mtu = ifp->if_mtu;
 7132                 } else {
 7133                         if (ifp->if_mtu <= sc->rx_bd_mbuf_data_len)
 7134                                 ether_mtu = sc->rx_bd_mbuf_data_len;
 7135                         else
 7136                                 ether_mtu = ifp->if_mtu;
 7137                 }
 7138         }
 7139 
 7140         ether_mtu += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN;
 7141 
 7142         DBPRINT(sc, BCE_INFO_MISC, "%s(): setting h/w mtu = %d\n",
 7143             __FUNCTION__, ether_mtu);
 7144 
 7145         /* Program the mtu, enabling jumbo frame support if necessary. */
 7146         if (ether_mtu > (ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN))
 7147                 REG_WR(sc, BCE_EMAC_RX_MTU_SIZE,
 7148                     min(ether_mtu, BCE_MAX_JUMBO_ETHER_MTU) |
 7149                     BCE_EMAC_RX_MTU_SIZE_JUMBO_ENA);
 7150         else
 7151                 REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu);
 7152 
 7153         /* Program appropriate promiscuous/multicast filtering. */
 7154         bce_set_rx_mode(sc);
 7155 
 7156         if (bce_hdr_split == TRUE) {
 7157                 /* Init page buffer descriptor chain. */
 7158                 bce_init_pg_chain(sc);
 7159         }
 7160 
 7161         /* Init RX buffer descriptor chain. */
 7162         bce_init_rx_chain(sc);
 7163 
 7164         /* Init TX buffer descriptor chain. */
 7165         bce_init_tx_chain(sc);
 7166 
 7167         /* Enable host interrupts. */
 7168         bce_enable_intr(sc, 1);
 7169 
 7170         bce_ifmedia_upd_locked(ifp);
 7171 
 7172         /* Let the OS know the driver is up and running. */
 7173         ifp->if_drv_flags |= IFF_DRV_RUNNING;
 7174         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 7175 
 7176         callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
 7177 
 7178 bce_init_locked_exit:
 7179         DBEXIT(BCE_VERBOSE_RESET);
 7180 }
 7181 
 7182 
 7183 /****************************************************************************/
 7184 /* Initialize the controller just enough so that any management firmware    */
 7185 /* running on the device will continue to operate correctly.                */
 7186 /*                                                                          */
 7187 /* Returns:                                                                 */
 7188 /*   Nothing.                                                               */
 7189 /****************************************************************************/
 7190 static void
 7191 bce_mgmt_init_locked(struct bce_softc *sc)
 7192 {
 7193         struct ifnet *ifp;
 7194 
 7195         DBENTER(BCE_VERBOSE_RESET);
 7196 
 7197         BCE_LOCK_ASSERT(sc);
 7198 
 7199         /* Bail out if management firmware is not running. */
 7200         if (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)) {
 7201                 DBPRINT(sc, BCE_VERBOSE_SPECIAL,
 7202                     "No management firmware running...\n");
 7203                 goto bce_mgmt_init_locked_exit;
 7204         }
 7205 
 7206         ifp = sc->bce_ifp;
 7207 
 7208         /* Enable all critical blocks in the MAC. */
 7209         REG_WR(sc, BCE_MISC_ENABLE_SET_BITS, BCE_MISC_ENABLE_DEFAULT);
 7210         REG_RD(sc, BCE_MISC_ENABLE_SET_BITS);
 7211         DELAY(20);
 7212 
 7213         bce_ifmedia_upd_locked(ifp);
 7214 
 7215 bce_mgmt_init_locked_exit:
 7216         DBEXIT(BCE_VERBOSE_RESET);
 7217 }
 7218 
 7219 
 7220 /****************************************************************************/
 7221 /* Handles controller initialization when called from an unlocked routine.  */
 7222 /*                                                                          */
 7223 /* Returns:                                                                 */
 7224 /*   Nothing.                                                               */
 7225 /****************************************************************************/
 7226 static void
 7227 bce_init(void *xsc)
 7228 {
 7229         struct bce_softc *sc = xsc;
 7230 
 7231         DBENTER(BCE_VERBOSE_RESET);
 7232 
 7233         BCE_LOCK(sc);
 7234         bce_init_locked(sc);
 7235         BCE_UNLOCK(sc);
 7236 
 7237         DBEXIT(BCE_VERBOSE_RESET);
 7238 }
 7239 
 7240 
 7241 /****************************************************************************/
 7242 /* Modifies an mbuf for TSO on the hardware.                                */
 7243 /*                                                                          */
 7244 /* Returns:                                                                 */
 7245 /*   Pointer to a modified mbuf.                                            */
 7246 /****************************************************************************/
 7247 static struct mbuf *
 7248 bce_tso_setup(struct bce_softc *sc, struct mbuf **m_head, u16 *flags)
 7249 {
 7250         struct mbuf *m;
 7251         struct ether_header *eh;
 7252         struct ip *ip;
 7253         struct tcphdr *th;
 7254         u16 etype;
 7255         int hdr_len, ip_hlen = 0, tcp_hlen = 0, ip_len = 0;
 7256 
 7257         DBRUN(sc->tso_frames_requested++);
 7258 
 7259         /* Controller may modify mbuf chains. */
 7260         if (M_WRITABLE(*m_head) == 0) {
 7261                 m = m_dup(*m_head, M_NOWAIT);
 7262                 m_freem(*m_head);
 7263                 if (m == NULL) {
 7264                         sc->mbuf_alloc_failed_count++;
 7265                         *m_head = NULL;
 7266                         return (NULL);
 7267                 }
 7268                 *m_head = m;
 7269         }
 7270 
 7271         /*
 7272          * For TSO the controller needs two pieces of info,
 7273          * the MSS and the IP+TCP options length.
 7274          */
 7275         m = m_pullup(*m_head, sizeof(struct ether_header) + sizeof(struct ip));
 7276         if (m == NULL) {
 7277                 *m_head = NULL;
 7278                 return (NULL);
 7279         }
 7280         eh = mtod(m, struct ether_header *);
 7281         etype = ntohs(eh->ether_type);
 7282 
 7283         /* Check for supported TSO Ethernet types (only IPv4 for now) */
 7284         switch (etype) {
 7285         case ETHERTYPE_IP:
 7286                 ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
 7287                 /* TSO only supported for TCP protocol. */
 7288                 if (ip->ip_p != IPPROTO_TCP) {
 7289                         BCE_PRINTF("%s(%d): TSO enabled for non-TCP frame!.\n",
 7290                             __FILE__, __LINE__);
 7291                         m_freem(*m_head);
 7292                         *m_head = NULL;
 7293                         return (NULL);
 7294                 }
 7295 
 7296                 /* Get IP header length in bytes (min 20) */
 7297                 ip_hlen = ip->ip_hl << 2;
 7298                 m = m_pullup(*m_head, sizeof(struct ether_header) + ip_hlen +
 7299                     sizeof(struct tcphdr));
 7300                 if (m == NULL) {
 7301                         *m_head = NULL;
 7302                         return (NULL);
 7303                 }
 7304 
 7305                 /* Get the TCP header length in bytes (min 20) */
 7306                 ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
 7307                 th = (struct tcphdr *)((caddr_t)ip + ip_hlen);
 7308                 tcp_hlen = (th->th_off << 2);
 7309 
 7310                 /* Make sure all IP/TCP options live in the same buffer. */
 7311                 m = m_pullup(*m_head,  sizeof(struct ether_header)+ ip_hlen +
 7312                     tcp_hlen);
 7313                 if (m == NULL) {
 7314                         *m_head = NULL;
 7315                         return (NULL);
 7316                 }
 7317 
 7318                 /* Clear IP header length and checksum, will be calc'd by h/w. */
 7319                 ip = (struct ip *)(m->m_data + sizeof(struct ether_header));
 7320                 ip_len = ip->ip_len;
 7321                 ip->ip_len = 0;
 7322                 ip->ip_sum = 0;
 7323                 break;
 7324         case ETHERTYPE_IPV6:
 7325                 BCE_PRINTF("%s(%d): TSO over IPv6 not supported!.\n",
 7326                     __FILE__, __LINE__);
 7327                 m_freem(*m_head);
 7328                 *m_head = NULL;
 7329                 return (NULL);
 7330                 /* NOT REACHED */
 7331         default:
 7332                 BCE_PRINTF("%s(%d): TSO enabled for unsupported protocol!.\n",
 7333                     __FILE__, __LINE__);
 7334                 m_freem(*m_head);
 7335                 *m_head = NULL;
 7336                 return (NULL);
 7337         }
 7338 
 7339         hdr_len = sizeof(struct ether_header) + ip_hlen + tcp_hlen;
 7340 
 7341         DBPRINT(sc, BCE_EXTREME_SEND, "%s(): hdr_len = %d, e_hlen = %d, "
 7342             "ip_hlen = %d, tcp_hlen = %d, ip_len = %d\n",
 7343             __FUNCTION__, hdr_len, (int) sizeof(struct ether_header), ip_hlen,
 7344             tcp_hlen, ip_len);
 7345 
 7346         /* Set the LSO flag in the TX BD */
 7347         *flags |= TX_BD_FLAGS_SW_LSO;
 7348 
 7349         /* Set the length of IP + TCP options (in 32 bit words) */
 7350         *flags |= (((ip_hlen + tcp_hlen - sizeof(struct ip) -
 7351             sizeof(struct tcphdr)) >> 2) << 8);
 7352 
 7353         DBRUN(sc->tso_frames_completed++);
 7354         return (*m_head);
 7355 }
 7356 
 7357 
 7358 /****************************************************************************/
 7359 /* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
 7360 /* memory visible to the controller.                                        */
 7361 /*                                                                          */
 7362 /* Returns:                                                                 */
 7363 /*   0 for success, positive value for failure.                             */
 7364 /* Modified:                                                                */
 7365 /*   m_head: May be set to NULL if MBUF is excessively fragmented.          */
 7366 /****************************************************************************/
 7367 static int
 7368 bce_tx_encap(struct bce_softc *sc, struct mbuf **m_head)
 7369 {
 7370         bus_dma_segment_t segs[BCE_MAX_SEGMENTS];
 7371         bus_dmamap_t map;
 7372         struct tx_bd *txbd = NULL;
 7373         struct mbuf *m0;
 7374         u16 prod, chain_prod, mss = 0, vlan_tag = 0, flags = 0;
 7375         u32 prod_bseq;
 7376 
 7377 #ifdef BCE_DEBUG
 7378         u16 debug_prod;
 7379 #endif
 7380 
 7381         int i, error, nsegs, rc = 0;
 7382 
 7383         DBENTER(BCE_VERBOSE_SEND);
 7384 
 7385         /* Make sure we have room in the TX chain. */
 7386         if (sc->used_tx_bd >= sc->max_tx_bd)
 7387                 goto bce_tx_encap_exit;
 7388 
 7389         /* Transfer any checksum offload flags to the bd. */
 7390         m0 = *m_head;
 7391         if (m0->m_pkthdr.csum_flags) {
 7392                 if (m0->m_pkthdr.csum_flags & CSUM_TSO) {
 7393                         m0 = bce_tso_setup(sc, m_head, &flags);
 7394                         if (m0 == NULL) {
 7395                                 DBRUN(sc->tso_frames_failed++);
 7396                                 goto bce_tx_encap_exit;
 7397                         }
 7398                         mss = htole16(m0->m_pkthdr.tso_segsz);
 7399                 } else {
 7400                         if (m0->m_pkthdr.csum_flags & CSUM_IP)
 7401                                 flags |= TX_BD_FLAGS_IP_CKSUM;
 7402                         if (m0->m_pkthdr.csum_flags & (CSUM_TCP | CSUM_UDP))
 7403                                 flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
 7404                 }
 7405         }
 7406 
 7407         /* Transfer any VLAN tags to the bd. */
 7408         if (m0->m_flags & M_VLANTAG) {
 7409                 flags |= TX_BD_FLAGS_VLAN_TAG;
 7410                 vlan_tag = m0->m_pkthdr.ether_vtag;
 7411         }
 7412 
 7413         /* Map the mbuf into DMAable memory. */
 7414         prod = sc->tx_prod;
 7415         chain_prod = TX_CHAIN_IDX(prod);
 7416         map = sc->tx_mbuf_map[chain_prod];
 7417 
 7418         /* Map the mbuf into our DMA address space. */
 7419         error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag, map, m0,
 7420             segs, &nsegs, BUS_DMA_NOWAIT);
 7421 
 7422         /* Check if the DMA mapping was successful */
 7423         if (error == EFBIG) {
 7424                 sc->mbuf_frag_count++;
 7425 
 7426                 /* Try to defrag the mbuf. */
 7427                 m0 = m_collapse(*m_head, M_NOWAIT, BCE_MAX_SEGMENTS);
 7428                 if (m0 == NULL) {
 7429                         /* Defrag was unsuccessful */
 7430                         m_freem(*m_head);
 7431                         *m_head = NULL;
 7432                         sc->mbuf_alloc_failed_count++;
 7433                         rc = ENOBUFS;
 7434                         goto bce_tx_encap_exit;
 7435                 }
 7436 
 7437                 /* Defrag was successful, try mapping again */
 7438                 *m_head = m0;
 7439                 error = bus_dmamap_load_mbuf_sg(sc->tx_mbuf_tag,
 7440                     map, m0, segs, &nsegs, BUS_DMA_NOWAIT);
 7441 
 7442                 /* Still getting an error after a defrag. */
 7443                 if (error == ENOMEM) {
 7444                         /* Insufficient DMA buffers available. */
 7445                         sc->dma_map_addr_tx_failed_count++;
 7446                         rc = error;
 7447                         goto bce_tx_encap_exit;
 7448                 } else if (error != 0) {
 7449                         /* Release it and return an error. */
 7450                         BCE_PRINTF("%s(%d): Unknown error mapping mbuf into "
 7451                             "TX chain!\n", __FILE__, __LINE__);
 7452                         m_freem(m0);
 7453                         *m_head = NULL;
 7454                         sc->dma_map_addr_tx_failed_count++;
 7455                         rc = ENOBUFS;
 7456                         goto bce_tx_encap_exit;
 7457                 }
 7458         } else if (error == ENOMEM) {
 7459                 /* Insufficient DMA buffers available. */
 7460                 sc->dma_map_addr_tx_failed_count++;
 7461                 rc = error;
 7462                 goto bce_tx_encap_exit;
 7463         } else if (error != 0) {
 7464                 m_freem(m0);
 7465                 *m_head = NULL;
 7466                 sc->dma_map_addr_tx_failed_count++;
 7467                 rc = error;
 7468                 goto bce_tx_encap_exit;
 7469         }
 7470 
 7471         /* Make sure there's room in the chain */
 7472         if (nsegs > (sc->max_tx_bd - sc->used_tx_bd)) {
 7473                 bus_dmamap_unload(sc->tx_mbuf_tag, map);
 7474                 rc = ENOBUFS;
 7475                 goto bce_tx_encap_exit;
 7476         }
 7477 
 7478         /* prod points to an empty tx_bd at this point. */
 7479         prod_bseq  = sc->tx_prod_bseq;
 7480 
 7481 #ifdef BCE_DEBUG
 7482         debug_prod = chain_prod;
 7483 #endif
 7484 
 7485         DBPRINT(sc, BCE_INFO_SEND,
 7486             "%s(start): prod = 0x%04X, chain_prod = 0x%04X, "
 7487             "prod_bseq = 0x%08X\n",
 7488             __FUNCTION__, prod, chain_prod, prod_bseq);
 7489 
 7490         /*
 7491          * Cycle through each mbuf segment that makes up
 7492          * the outgoing frame, gathering the mapping info
 7493          * for that segment and creating a tx_bd for
 7494          * the mbuf.
 7495          */
 7496         for (i = 0; i < nsegs ; i++) {
 7497 
 7498                 chain_prod = TX_CHAIN_IDX(prod);
 7499                 txbd= &sc->tx_bd_chain[TX_PAGE(chain_prod)]
 7500                     [TX_IDX(chain_prod)];
 7501 
 7502                 txbd->tx_bd_haddr_lo =
 7503                     htole32(BCE_ADDR_LO(segs[i].ds_addr));
 7504                 txbd->tx_bd_haddr_hi =
 7505                     htole32(BCE_ADDR_HI(segs[i].ds_addr));
 7506                 txbd->tx_bd_mss_nbytes = htole32(mss << 16) |
 7507                     htole16(segs[i].ds_len);
 7508                 txbd->tx_bd_vlan_tag = htole16(vlan_tag);
 7509                 txbd->tx_bd_flags = htole16(flags);
 7510                 prod_bseq += segs[i].ds_len;
 7511                 if (i == 0)
 7512                         txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_START);
 7513                 prod = NEXT_TX_BD(prod);
 7514         }
 7515 
 7516         /* Set the END flag on the last TX buffer descriptor. */
 7517         txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_END);
 7518 
 7519         DBRUNMSG(BCE_EXTREME_SEND,
 7520             bce_dump_tx_chain(sc, debug_prod, nsegs));
 7521 
 7522         /*
 7523          * Ensure that the mbuf pointer for this transmission
 7524          * is placed at the array index of the last
 7525          * descriptor in this chain.  This is done
 7526          * because a single map is used for all
 7527          * segments of the mbuf and we don't want to
 7528          * unload the map before all of the segments
 7529          * have been freed.
 7530          */
 7531         sc->tx_mbuf_ptr[chain_prod] = m0;
 7532         sc->used_tx_bd += nsegs;
 7533 
 7534         /* Update some debug statistic counters */
 7535         DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
 7536             sc->tx_hi_watermark = sc->used_tx_bd);
 7537         DBRUNIF((sc->used_tx_bd == sc->max_tx_bd), sc->tx_full_count++);
 7538         DBRUNIF(sc->debug_tx_mbuf_alloc++);
 7539 
 7540         DBRUNMSG(BCE_EXTREME_SEND, bce_dump_tx_mbuf_chain(sc, chain_prod, 1));
 7541 
 7542         /* prod points to the next free tx_bd at this point. */
 7543         sc->tx_prod = prod;
 7544         sc->tx_prod_bseq = prod_bseq;
 7545 
 7546         /* Tell the chip about the waiting TX frames. */
 7547         REG_WR16(sc, MB_GET_CID_ADDR(TX_CID) +
 7548             BCE_L2MQ_TX_HOST_BIDX, sc->tx_prod);
 7549         REG_WR(sc, MB_GET_CID_ADDR(TX_CID) +
 7550             BCE_L2MQ_TX_HOST_BSEQ, sc->tx_prod_bseq);
 7551 
 7552 bce_tx_encap_exit:
 7553         DBEXIT(BCE_VERBOSE_SEND);
 7554         return(rc);
 7555 }
 7556 
 7557 
 7558 /****************************************************************************/
 7559 /* Main transmit routine when called from another routine with a lock.      */
 7560 /*                                                                          */
 7561 /* Returns:                                                                 */
 7562 /*   Nothing.                                                               */
 7563 /****************************************************************************/
 7564 static void
 7565 bce_start_locked(struct ifnet *ifp)
 7566 {
 7567         struct bce_softc *sc = ifp->if_softc;
 7568         struct mbuf *m_head = NULL;
 7569         int count = 0;
 7570         u16 tx_prod, tx_chain_prod;
 7571 
 7572         DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
 7573 
 7574         BCE_LOCK_ASSERT(sc);
 7575 
 7576         /* prod points to the next free tx_bd. */
 7577         tx_prod = sc->tx_prod;
 7578         tx_chain_prod = TX_CHAIN_IDX(tx_prod);
 7579 
 7580         DBPRINT(sc, BCE_INFO_SEND,
 7581             "%s(enter): tx_prod = 0x%04X, tx_chain_prod = 0x%04X, "
 7582             "tx_prod_bseq = 0x%08X\n",
 7583             __FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
 7584 
 7585         /* If there's no link or the transmit queue is empty then just exit. */
 7586         if (sc->bce_link_up == FALSE) {
 7587                 DBPRINT(sc, BCE_INFO_SEND, "%s(): No link.\n",
 7588                     __FUNCTION__);
 7589                 goto bce_start_locked_exit;
 7590         }
 7591 
 7592         if (IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
 7593                 DBPRINT(sc, BCE_INFO_SEND, "%s(): Transmit queue empty.\n",
 7594                     __FUNCTION__);
 7595                 goto bce_start_locked_exit;
 7596         }
 7597 
 7598         /*
 7599          * Keep adding entries while there is space in the ring.
 7600          */
 7601         while (sc->used_tx_bd < sc->max_tx_bd) {
 7602 
 7603                 /* Check for any frames to send. */
 7604                 IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head);
 7605 
 7606                 /* Stop when the transmit queue is empty. */
 7607                 if (m_head == NULL)
 7608                         break;
 7609 
 7610                 /*
 7611                  * Pack the data into the transmit ring. If we
 7612                  * don't have room, place the mbuf back at the
 7613                  * head of the queue and set the OACTIVE flag
 7614                  * to wait for the NIC to drain the chain.
 7615                  */
 7616                 if (bce_tx_encap(sc, &m_head)) {
 7617                         if (m_head != NULL)
 7618                                 IFQ_DRV_PREPEND(&ifp->if_snd, m_head);
 7619                         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 7620                         DBPRINT(sc, BCE_INFO_SEND,
 7621                             "TX chain is closed for business! Total "
 7622                             "tx_bd used = %d\n", sc->used_tx_bd);
 7623                         break;
 7624                 }
 7625 
 7626                 count++;
 7627 
 7628                 /* Send a copy of the frame to any BPF listeners. */
 7629                 ETHER_BPF_MTAP(ifp, m_head);
 7630         }
 7631 
 7632         /* Exit if no packets were dequeued. */
 7633         if (count == 0) {
 7634                 DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): No packets were "
 7635                     "dequeued\n", __FUNCTION__);
 7636                 goto bce_start_locked_exit;
 7637         }
 7638 
 7639         DBPRINT(sc, BCE_VERBOSE_SEND, "%s(): Inserted %d frames into "
 7640             "send queue.\n", __FUNCTION__, count);
 7641 
 7642         /* Set the tx timeout. */
 7643         sc->watchdog_timer = BCE_TX_TIMEOUT;
 7644 
 7645         DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_ctx(sc, TX_CID));
 7646         DBRUNMSG(BCE_VERBOSE_SEND, bce_dump_mq_regs(sc));
 7647 
 7648 bce_start_locked_exit:
 7649         DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_CTX);
 7650 }
 7651 
 7652 
 7653 /****************************************************************************/
 7654 /* Main transmit routine when called from another routine without a lock.   */
 7655 /*                                                                          */
 7656 /* Returns:                                                                 */
 7657 /*   Nothing.                                                               */
 7658 /****************************************************************************/
 7659 static void
 7660 bce_start(struct ifnet *ifp)
 7661 {
 7662         struct bce_softc *sc = ifp->if_softc;
 7663 
 7664         DBENTER(BCE_VERBOSE_SEND);
 7665 
 7666         BCE_LOCK(sc);
 7667         bce_start_locked(ifp);
 7668         BCE_UNLOCK(sc);
 7669 
 7670         DBEXIT(BCE_VERBOSE_SEND);
 7671 }
 7672 
 7673 
 7674 /****************************************************************************/
 7675 /* Handles any IOCTL calls from the operating system.                       */
 7676 /*                                                                          */
 7677 /* Returns:                                                                 */
 7678 /*   0 for success, positive value for failure.                             */
 7679 /****************************************************************************/
 7680 static int
 7681 bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 7682 {
 7683         struct bce_softc *sc = ifp->if_softc;
 7684         struct ifreq *ifr = (struct ifreq *) data;
 7685         struct mii_data *mii;
 7686         int mask, error = 0;
 7687 
 7688         DBENTER(BCE_VERBOSE_MISC);
 7689 
 7690         switch(command) {
 7691 
 7692         /* Set the interface MTU. */
 7693         case SIOCSIFMTU:
 7694                 /* Check that the MTU setting is supported. */
 7695                 if ((ifr->ifr_mtu < BCE_MIN_MTU) ||
 7696                         (ifr->ifr_mtu > BCE_MAX_JUMBO_MTU)) {
 7697                         error = EINVAL;
 7698                         break;
 7699                 }
 7700 
 7701                 DBPRINT(sc, BCE_INFO_MISC,
 7702                     "SIOCSIFMTU: Changing MTU from %d to %d\n",
 7703                     (int) ifp->if_mtu, (int) ifr->ifr_mtu);
 7704 
 7705                 BCE_LOCK(sc);
 7706                 ifp->if_mtu = ifr->ifr_mtu;
 7707                 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 7708                         ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 7709                         bce_init_locked(sc);
 7710                 }
 7711                 BCE_UNLOCK(sc);
 7712                 break;
 7713 
 7714         /* Set interface flags. */
 7715         case SIOCSIFFLAGS:
 7716                 DBPRINT(sc, BCE_VERBOSE_SPECIAL, "Received SIOCSIFFLAGS\n");
 7717 
 7718                 BCE_LOCK(sc);
 7719 
 7720                 /* Check if the interface is up. */
 7721                 if (ifp->if_flags & IFF_UP) {
 7722                         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 7723                                 /* Change promiscuous/multicast flags as necessary. */
 7724                                 bce_set_rx_mode(sc);
 7725                         } else {
 7726                                 /* Start the HW */
 7727                                 bce_init_locked(sc);
 7728                         }
 7729                 } else {
 7730                         /* The interface is down, check if driver is running. */
 7731                         if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 7732                                 bce_stop(sc);
 7733 
 7734                                 /* If MFW is running, restart the controller a bit. */
 7735                                 if (sc->bce_flags & BCE_MFW_ENABLE_FLAG) {
 7736                                         bce_reset(sc, BCE_DRV_MSG_CODE_RESET);
 7737                                         bce_chipinit(sc);
 7738                                         bce_mgmt_init_locked(sc);
 7739                                 }
 7740                         }
 7741                 }
 7742 
 7743                 BCE_UNLOCK(sc);
 7744                 break;
 7745 
 7746         /* Add/Delete multicast address */
 7747         case SIOCADDMULTI:
 7748         case SIOCDELMULTI:
 7749                 DBPRINT(sc, BCE_VERBOSE_MISC,
 7750                     "Received SIOCADDMULTI/SIOCDELMULTI\n");
 7751 
 7752                 BCE_LOCK(sc);
 7753                 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
 7754                         bce_set_rx_mode(sc);
 7755                 BCE_UNLOCK(sc);
 7756 
 7757                 break;
 7758 
 7759         /* Set/Get Interface media */
 7760         case SIOCSIFMEDIA:
 7761         case SIOCGIFMEDIA:
 7762                 DBPRINT(sc, BCE_VERBOSE_MISC,
 7763                     "Received SIOCSIFMEDIA/SIOCGIFMEDIA\n");
 7764                 if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0)
 7765                         error = ifmedia_ioctl(ifp, ifr, &sc->bce_ifmedia,
 7766                             command);
 7767                 else {
 7768                         mii = device_get_softc(sc->bce_miibus);
 7769                         error = ifmedia_ioctl(ifp, ifr, &mii->mii_media,
 7770                             command);
 7771                 }
 7772                 break;
 7773 
 7774         /* Set interface capability */
 7775         case SIOCSIFCAP:
 7776                 mask = ifr->ifr_reqcap ^ ifp->if_capenable;
 7777                 DBPRINT(sc, BCE_INFO_MISC,
 7778                     "Received SIOCSIFCAP = 0x%08X\n", (u32) mask);
 7779 
 7780                 /* Toggle the TX checksum capabilities enable flag. */
 7781                 if (mask & IFCAP_TXCSUM &&
 7782                     ifp->if_capabilities & IFCAP_TXCSUM) {
 7783                         ifp->if_capenable ^= IFCAP_TXCSUM;
 7784                         if (IFCAP_TXCSUM & ifp->if_capenable)
 7785                                 ifp->if_hwassist |= BCE_IF_HWASSIST;
 7786                         else
 7787                                 ifp->if_hwassist &= ~BCE_IF_HWASSIST;
 7788                 }
 7789 
 7790                 /* Toggle the RX checksum capabilities enable flag. */
 7791                 if (mask & IFCAP_RXCSUM &&
 7792                     ifp->if_capabilities & IFCAP_RXCSUM)
 7793                         ifp->if_capenable ^= IFCAP_RXCSUM;
 7794 
 7795                 /* Toggle the TSO capabilities enable flag. */
 7796                 if (bce_tso_enable && (mask & IFCAP_TSO4) &&
 7797                     ifp->if_capabilities & IFCAP_TSO4) {
 7798                         ifp->if_capenable ^= IFCAP_TSO4;
 7799                         if (IFCAP_TSO4 & ifp->if_capenable)
 7800                                 ifp->if_hwassist |= CSUM_TSO;
 7801                         else
 7802                                 ifp->if_hwassist &= ~CSUM_TSO;
 7803                 }
 7804 
 7805                 if (mask & IFCAP_VLAN_HWCSUM &&
 7806                     ifp->if_capabilities & IFCAP_VLAN_HWCSUM)
 7807                         ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
 7808 
 7809                 if ((mask & IFCAP_VLAN_HWTSO) != 0 &&
 7810                     (ifp->if_capabilities & IFCAP_VLAN_HWTSO) != 0)
 7811                         ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
 7812                 /*
 7813                  * Don't actually disable VLAN tag stripping as
 7814                  * management firmware (ASF/IPMI/UMP) requires the
 7815                  * feature. If VLAN tag stripping is disabled driver
 7816                  * will manually reconstruct the VLAN frame by
 7817                  * appending stripped VLAN tag.
 7818                  */
 7819                 if ((mask & IFCAP_VLAN_HWTAGGING) != 0 &&
 7820                     (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING)) {
 7821                         ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
 7822                         if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING)
 7823                             == 0)
 7824                                 ifp->if_capenable &= ~IFCAP_VLAN_HWTSO;
 7825                 }
 7826                 VLAN_CAPABILITIES(ifp);
 7827                 break;
 7828         default:
 7829                 /* We don't know how to handle the IOCTL, pass it on. */
 7830                 error = ether_ioctl(ifp, command, data);
 7831                 break;
 7832         }
 7833 
 7834         DBEXIT(BCE_VERBOSE_MISC);
 7835         return(error);
 7836 }
 7837 
 7838 
 7839 /****************************************************************************/
 7840 /* Transmit timeout handler.                                                */
 7841 /*                                                                          */
 7842 /* Returns:                                                                 */
 7843 /*   Nothing.                                                               */
 7844 /****************************************************************************/
 7845 static void
 7846 bce_watchdog(struct bce_softc *sc)
 7847 {
 7848         uint32_t status;
 7849 
 7850         DBENTER(BCE_EXTREME_SEND);
 7851 
 7852         BCE_LOCK_ASSERT(sc);
 7853 
 7854         status = 0;
 7855         /* If the watchdog timer hasn't expired then just exit. */
 7856         if (sc->watchdog_timer == 0 || --sc->watchdog_timer)
 7857                 goto bce_watchdog_exit;
 7858 
 7859         status = REG_RD(sc, BCE_EMAC_RX_STATUS);
 7860         /* If pause frames are active then don't reset the hardware. */
 7861         if ((sc->bce_flags & BCE_USING_RX_FLOW_CONTROL) != 0) {
 7862                 if ((status & BCE_EMAC_RX_STATUS_FFED) != 0) {
 7863                         /*
 7864                          * If link partner has us in XOFF state then wait for
 7865                          * the condition to clear.
 7866                          */
 7867                         sc->watchdog_timer = BCE_TX_TIMEOUT;
 7868                         goto bce_watchdog_exit;
 7869                 } else if ((status & BCE_EMAC_RX_STATUS_FF_RECEIVED) != 0 &&
 7870                         (status & BCE_EMAC_RX_STATUS_N_RECEIVED) != 0) {
 7871                         /*
 7872                          * If we're not currently XOFF'ed but have recently
 7873                          * been XOFF'd/XON'd then assume that's delaying TX
 7874                          * this time around.
 7875                          */
 7876                         sc->watchdog_timer = BCE_TX_TIMEOUT;
 7877                         goto bce_watchdog_exit;
 7878                 }
 7879                 /*
 7880                  * Any other condition is unexpected and the controller
 7881                  * should be reset.
 7882                  */
 7883         }
 7884 
 7885         BCE_PRINTF("%s(%d): Watchdog timeout occurred, resetting!\n",
 7886             __FILE__, __LINE__);
 7887 
 7888         DBRUNMSG(BCE_INFO,
 7889             bce_dump_driver_state(sc);
 7890             bce_dump_status_block(sc);
 7891             bce_dump_stats_block(sc);
 7892             bce_dump_ftqs(sc);
 7893             bce_dump_txp_state(sc, 0);
 7894             bce_dump_rxp_state(sc, 0);
 7895             bce_dump_tpat_state(sc, 0);
 7896             bce_dump_cp_state(sc, 0);
 7897             bce_dump_com_state(sc, 0));
 7898 
 7899         DBRUN(bce_breakpoint(sc));
 7900 
 7901         sc->bce_ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 7902 
 7903         bce_init_locked(sc);
 7904         sc->watchdog_timeouts++;
 7905 
 7906 bce_watchdog_exit:
 7907         REG_WR(sc, BCE_EMAC_RX_STATUS, status);
 7908         DBEXIT(BCE_EXTREME_SEND);
 7909 }
 7910 
 7911 
 7912 /*
 7913  * Interrupt handler.
 7914  */
 7915 /****************************************************************************/
 7916 /* Main interrupt entry point.  Verifies that the controller generated the  */
 7917 /* interrupt and then calls a separate routine for handle the various       */
 7918 /* interrupt causes (PHY, TX, RX).                                          */
 7919 /*                                                                          */
 7920 /* Returns:                                                                 */
 7921 /*   Nothing.                                                               */
 7922 /****************************************************************************/
 7923 static void
 7924 bce_intr(void *xsc)
 7925 {
 7926         struct bce_softc *sc;
 7927         struct ifnet *ifp;
 7928         u32 status_attn_bits;
 7929         u16 hw_rx_cons, hw_tx_cons;
 7930 
 7931         sc = xsc;
 7932         ifp = sc->bce_ifp;
 7933 
 7934         DBENTER(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
 7935         DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_status_block(sc));
 7936         DBRUNMSG(BCE_VERBOSE_INTR, bce_dump_stats_block(sc));
 7937 
 7938         BCE_LOCK(sc);
 7939 
 7940         DBRUN(sc->interrupts_generated++);
 7941 
 7942         /* Synchnorize before we read from interface's status block */
 7943         bus_dmamap_sync(sc->status_tag, sc->status_map, BUS_DMASYNC_POSTREAD);
 7944 
 7945         /*
 7946          * If the hardware status block index matches the last value read
 7947          * by the driver and we haven't asserted our interrupt then there's
 7948          * nothing to do.  This may only happen in case of INTx due to the
 7949          * interrupt arriving at the CPU before the status block is updated.
 7950          */
 7951         if ((sc->bce_flags & (BCE_USING_MSI_FLAG | BCE_USING_MSIX_FLAG)) == 0 &&
 7952             sc->status_block->status_idx == sc->last_status_idx &&
 7953             (REG_RD(sc, BCE_PCICFG_MISC_STATUS) &
 7954              BCE_PCICFG_MISC_STATUS_INTA_VALUE)) {
 7955                 DBPRINT(sc, BCE_VERBOSE_INTR, "%s(): Spurious interrupt.\n",
 7956                     __FUNCTION__);
 7957                 goto bce_intr_exit;
 7958         }
 7959 
 7960         /* Ack the interrupt and stop others from occurring. */
 7961         REG_WR(sc, BCE_PCICFG_INT_ACK_CMD,
 7962             BCE_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
 7963             BCE_PCICFG_INT_ACK_CMD_MASK_INT);
 7964 
 7965         /* Check if the hardware has finished any work. */
 7966         hw_rx_cons = bce_get_hw_rx_cons(sc);
 7967         hw_tx_cons = bce_get_hw_tx_cons(sc);
 7968 
 7969         /* Keep processing data as long as there is work to do. */
 7970         for (;;) {
 7971 
 7972                 status_attn_bits = sc->status_block->status_attn_bits;
 7973 
 7974                 DBRUNIF(DB_RANDOMTRUE(unexpected_attention_sim_control),
 7975                     BCE_PRINTF("Simulating unexpected status attention "
 7976                     "bit set.");
 7977                     sc->unexpected_attention_sim_count++;
 7978                     status_attn_bits = status_attn_bits |
 7979                     STATUS_ATTN_BITS_PARITY_ERROR);
 7980 
 7981                 /* Was it a link change interrupt? */
 7982                 if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
 7983                     (sc->status_block->status_attn_bits_ack &
 7984                      STATUS_ATTN_BITS_LINK_STATE)) {
 7985                         bce_phy_intr(sc);
 7986 
 7987                         /* Clear transient updates during link state change. */
 7988                         REG_WR(sc, BCE_HC_COMMAND, sc->hc_command |
 7989                             BCE_HC_COMMAND_COAL_NOW_WO_INT);
 7990                         REG_RD(sc, BCE_HC_COMMAND);
 7991                 }
 7992 
 7993                 /* If any other attention is asserted, the chip is toast. */
 7994                 if (((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
 7995                     (sc->status_block->status_attn_bits_ack &
 7996                     ~STATUS_ATTN_BITS_LINK_STATE))) {
 7997 
 7998                         sc->unexpected_attention_count++;
 7999 
 8000                         BCE_PRINTF("%s(%d): Fatal attention detected: "
 8001                             "0x%08X\n", __FILE__, __LINE__,
 8002                             sc->status_block->status_attn_bits);
 8003 
 8004                         DBRUNMSG(BCE_FATAL,
 8005                             if (unexpected_attention_sim_control == 0)
 8006                                 bce_breakpoint(sc));
 8007 
 8008                         bce_init_locked(sc);
 8009                         goto bce_intr_exit;
 8010                 }
 8011 
 8012                 /* Check for any completed RX frames. */
 8013                 if (hw_rx_cons != sc->hw_rx_cons)
 8014                         bce_rx_intr(sc);
 8015 
 8016                 /* Check for any completed TX frames. */
 8017                 if (hw_tx_cons != sc->hw_tx_cons)
 8018                         bce_tx_intr(sc);
 8019 
 8020                 /* Save status block index value for the next interrupt. */
 8021                 sc->last_status_idx = sc->status_block->status_idx;
 8022 
 8023                 /*
 8024                  * Prevent speculative reads from getting
 8025                  * ahead of the status block.
 8026                  */
 8027                 bus_space_barrier(sc->bce_btag, sc->bce_bhandle, 0, 0,
 8028                     BUS_SPACE_BARRIER_READ);
 8029 
 8030                 /*
 8031                  * If there's no work left then exit the
 8032                  * interrupt service routine.
 8033                  */
 8034                 hw_rx_cons = bce_get_hw_rx_cons(sc);
 8035                 hw_tx_cons = bce_get_hw_tx_cons(sc);
 8036 
 8037                 if ((hw_rx_cons == sc->hw_rx_cons) &&
 8038                     (hw_tx_cons == sc->hw_tx_cons))
 8039                         break;
 8040         }
 8041 
 8042         bus_dmamap_sync(sc->status_tag, sc->status_map, BUS_DMASYNC_PREREAD);
 8043 
 8044         /* Re-enable interrupts. */
 8045         bce_enable_intr(sc, 0);
 8046 
 8047         /* Handle any frames that arrived while handling the interrupt. */
 8048         if (ifp->if_drv_flags & IFF_DRV_RUNNING &&
 8049             !IFQ_DRV_IS_EMPTY(&ifp->if_snd))
 8050                 bce_start_locked(ifp);
 8051 
 8052 bce_intr_exit:
 8053         BCE_UNLOCK(sc);
 8054 
 8055         DBEXIT(BCE_VERBOSE_SEND | BCE_VERBOSE_RECV | BCE_VERBOSE_INTR);
 8056 }
 8057 
 8058 
 8059 /****************************************************************************/
 8060 /* Programs the various packet receive modes (broadcast and multicast).     */
 8061 /*                                                                          */
 8062 /* Returns:                                                                 */
 8063 /*   Nothing.                                                               */
 8064 /****************************************************************************/
 8065 static void
 8066 bce_set_rx_mode(struct bce_softc *sc)
 8067 {
 8068         struct ifnet *ifp;
 8069         struct ifmultiaddr *ifma;
 8070         u32 hashes[NUM_MC_HASH_REGISTERS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
 8071         u32 rx_mode, sort_mode;
 8072         int h, i;
 8073 
 8074         DBENTER(BCE_VERBOSE_MISC);
 8075 
 8076         BCE_LOCK_ASSERT(sc);
 8077 
 8078         ifp = sc->bce_ifp;
 8079 
 8080         /* Initialize receive mode default settings. */
 8081         rx_mode   = sc->rx_mode & ~(BCE_EMAC_RX_MODE_PROMISCUOUS |
 8082             BCE_EMAC_RX_MODE_KEEP_VLAN_TAG);
 8083         sort_mode = 1 | BCE_RPM_SORT_USER0_BC_EN;
 8084 
 8085         /*
 8086          * ASF/IPMI/UMP firmware requires that VLAN tag stripping
 8087          * be enbled.
 8088          */
 8089         if (!(BCE_IF_CAPABILITIES & IFCAP_VLAN_HWTAGGING) &&
 8090             (!(sc->bce_flags & BCE_MFW_ENABLE_FLAG)))
 8091                 rx_mode |= BCE_EMAC_RX_MODE_KEEP_VLAN_TAG;
 8092 
 8093         /*
 8094          * Check for promiscuous, all multicast, or selected
 8095          * multicast address filtering.
 8096          */
 8097         if (ifp->if_flags & IFF_PROMISC) {
 8098                 DBPRINT(sc, BCE_INFO_MISC, "Enabling promiscuous mode.\n");
 8099 
 8100                 /* Enable promiscuous mode. */
 8101                 rx_mode |= BCE_EMAC_RX_MODE_PROMISCUOUS;
 8102                 sort_mode |= BCE_RPM_SORT_USER0_PROM_EN;
 8103         } else if (ifp->if_flags & IFF_ALLMULTI) {
 8104                 DBPRINT(sc, BCE_INFO_MISC, "Enabling all multicast mode.\n");
 8105 
 8106                 /* Enable all multicast addresses. */
 8107                 for (i = 0; i < NUM_MC_HASH_REGISTERS; i++) {
 8108                         REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4),
 8109                             0xffffffff);
 8110                 }
 8111                 sort_mode |= BCE_RPM_SORT_USER0_MC_EN;
 8112         } else {
 8113                 /* Accept one or more multicast(s). */
 8114                 DBPRINT(sc, BCE_INFO_MISC, "Enabling selective multicast mode.\n");
 8115 
 8116                 if_maddr_rlock(ifp);
 8117                 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) {
 8118                         if (ifma->ifma_addr->sa_family != AF_LINK)
 8119                                 continue;
 8120                         h = ether_crc32_le(LLADDR((struct sockaddr_dl *)
 8121                             ifma->ifma_addr), ETHER_ADDR_LEN) & 0xFF;
 8122                             hashes[(h & 0xE0) >> 5] |= 1 << (h & 0x1F);
 8123                 }
 8124                 if_maddr_runlock(ifp);
 8125 
 8126                 for (i = 0; i < NUM_MC_HASH_REGISTERS; i++)
 8127                         REG_WR(sc, BCE_EMAC_MULTICAST_HASH0 + (i * 4), hashes[i]);
 8128 
 8129                 sort_mode |= BCE_RPM_SORT_USER0_MC_HSH_EN;
 8130         }
 8131 
 8132         /* Only make changes if the recive mode has actually changed. */
 8133         if (rx_mode != sc->rx_mode) {
 8134                 DBPRINT(sc, BCE_VERBOSE_MISC, "Enabling new receive mode: "
 8135                     "0x%08X\n", rx_mode);
 8136 
 8137                 sc->rx_mode = rx_mode;
 8138                 REG_WR(sc, BCE_EMAC_RX_MODE, rx_mode);
 8139         }
 8140 
 8141         /* Disable and clear the exisitng sort before enabling a new sort. */
 8142         REG_WR(sc, BCE_RPM_SORT_USER0, 0x0);
 8143         REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode);
 8144         REG_WR(sc, BCE_RPM_SORT_USER0, sort_mode | BCE_RPM_SORT_USER0_ENA);
 8145 
 8146         DBEXIT(BCE_VERBOSE_MISC);
 8147 }
 8148 
 8149 
 8150 /****************************************************************************/
 8151 /* Called periodically to updates statistics from the controllers           */
 8152 /* statistics block.                                                        */
 8153 /*                                                                          */
 8154 /* Returns:                                                                 */
 8155 /*   Nothing.                                                               */
 8156 /****************************************************************************/
 8157 static void
 8158 bce_stats_update(struct bce_softc *sc)
 8159 {
 8160         struct statistics_block *stats;
 8161 
 8162         DBENTER(BCE_EXTREME_MISC);
 8163 
 8164         bus_dmamap_sync(sc->stats_tag, sc->stats_map, BUS_DMASYNC_POSTREAD);
 8165 
 8166         stats = (struct statistics_block *) sc->stats_block;
 8167 
 8168         /*
 8169          * Update the sysctl statistics from the
 8170          * hardware statistics.
 8171          */
 8172         sc->stat_IfHCInOctets =
 8173             ((u64) stats->stat_IfHCInOctets_hi << 32) +
 8174              (u64) stats->stat_IfHCInOctets_lo;
 8175 
 8176         sc->stat_IfHCInBadOctets =
 8177             ((u64) stats->stat_IfHCInBadOctets_hi << 32) +
 8178              (u64) stats->stat_IfHCInBadOctets_lo;
 8179 
 8180         sc->stat_IfHCOutOctets =
 8181             ((u64) stats->stat_IfHCOutOctets_hi << 32) +
 8182              (u64) stats->stat_IfHCOutOctets_lo;
 8183 
 8184         sc->stat_IfHCOutBadOctets =
 8185             ((u64) stats->stat_IfHCOutBadOctets_hi << 32) +
 8186              (u64) stats->stat_IfHCOutBadOctets_lo;
 8187 
 8188         sc->stat_IfHCInUcastPkts =
 8189             ((u64) stats->stat_IfHCInUcastPkts_hi << 32) +
 8190              (u64) stats->stat_IfHCInUcastPkts_lo;
 8191 
 8192         sc->stat_IfHCInMulticastPkts =
 8193             ((u64) stats->stat_IfHCInMulticastPkts_hi << 32) +
 8194              (u64) stats->stat_IfHCInMulticastPkts_lo;
 8195 
 8196         sc->stat_IfHCInBroadcastPkts =
 8197             ((u64) stats->stat_IfHCInBroadcastPkts_hi << 32) +
 8198              (u64) stats->stat_IfHCInBroadcastPkts_lo;
 8199 
 8200         sc->stat_IfHCOutUcastPkts =
 8201             ((u64) stats->stat_IfHCOutUcastPkts_hi << 32) +
 8202              (u64) stats->stat_IfHCOutUcastPkts_lo;
 8203 
 8204         sc->stat_IfHCOutMulticastPkts =
 8205             ((u64) stats->stat_IfHCOutMulticastPkts_hi << 32) +
 8206              (u64) stats->stat_IfHCOutMulticastPkts_lo;
 8207 
 8208         sc->stat_IfHCOutBroadcastPkts =
 8209             ((u64) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
 8210              (u64) stats->stat_IfHCOutBroadcastPkts_lo;
 8211 
 8212         /* ToDo: Preserve counters beyond 32 bits? */
 8213         /* ToDo: Read the statistics from auto-clear regs? */
 8214 
 8215         sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors =
 8216             stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
 8217 
 8218         sc->stat_Dot3StatsCarrierSenseErrors =
 8219             stats->stat_Dot3StatsCarrierSenseErrors;
 8220 
 8221         sc->stat_Dot3StatsFCSErrors =
 8222             stats->stat_Dot3StatsFCSErrors;
 8223 
 8224         sc->stat_Dot3StatsAlignmentErrors =
 8225             stats->stat_Dot3StatsAlignmentErrors;
 8226 
 8227         sc->stat_Dot3StatsSingleCollisionFrames =
 8228             stats->stat_Dot3StatsSingleCollisionFrames;
 8229 
 8230         sc->stat_Dot3StatsMultipleCollisionFrames =
 8231             stats->stat_Dot3StatsMultipleCollisionFrames;
 8232 
 8233         sc->stat_Dot3StatsDeferredTransmissions =
 8234             stats->stat_Dot3StatsDeferredTransmissions;
 8235 
 8236         sc->stat_Dot3StatsExcessiveCollisions =
 8237             stats->stat_Dot3StatsExcessiveCollisions;
 8238 
 8239         sc->stat_Dot3StatsLateCollisions =
 8240             stats->stat_Dot3StatsLateCollisions;
 8241 
 8242         sc->stat_EtherStatsCollisions =
 8243             stats->stat_EtherStatsCollisions;
 8244 
 8245         sc->stat_EtherStatsFragments =
 8246             stats->stat_EtherStatsFragments;
 8247 
 8248         sc->stat_EtherStatsJabbers =
 8249             stats->stat_EtherStatsJabbers;
 8250 
 8251         sc->stat_EtherStatsUndersizePkts =
 8252             stats->stat_EtherStatsUndersizePkts;
 8253 
 8254         sc->stat_EtherStatsOversizePkts =
 8255              stats->stat_EtherStatsOversizePkts;
 8256 
 8257         sc->stat_EtherStatsPktsRx64Octets =
 8258             stats->stat_EtherStatsPktsRx64Octets;
 8259 
 8260         sc->stat_EtherStatsPktsRx65Octetsto127Octets =
 8261             stats->stat_EtherStatsPktsRx65Octetsto127Octets;
 8262 
 8263         sc->stat_EtherStatsPktsRx128Octetsto255Octets =
 8264             stats->stat_EtherStatsPktsRx128Octetsto255Octets;
 8265 
 8266         sc->stat_EtherStatsPktsRx256Octetsto511Octets =
 8267             stats->stat_EtherStatsPktsRx256Octetsto511Octets;
 8268 
 8269         sc->stat_EtherStatsPktsRx512Octetsto1023Octets =
 8270             stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
 8271 
 8272         sc->stat_EtherStatsPktsRx1024Octetsto1522Octets =
 8273             stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
 8274 
 8275         sc->stat_EtherStatsPktsRx1523Octetsto9022Octets =
 8276             stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
 8277 
 8278         sc->stat_EtherStatsPktsTx64Octets =
 8279             stats->stat_EtherStatsPktsTx64Octets;
 8280 
 8281         sc->stat_EtherStatsPktsTx65Octetsto127Octets =
 8282             stats->stat_EtherStatsPktsTx65Octetsto127Octets;
 8283 
 8284         sc->stat_EtherStatsPktsTx128Octetsto255Octets =
 8285             stats->stat_EtherStatsPktsTx128Octetsto255Octets;
 8286 
 8287         sc->stat_EtherStatsPktsTx256Octetsto511Octets =
 8288             stats->stat_EtherStatsPktsTx256Octetsto511Octets;
 8289 
 8290         sc->stat_EtherStatsPktsTx512Octetsto1023Octets =
 8291             stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
 8292 
 8293         sc->stat_EtherStatsPktsTx1024Octetsto1522Octets =
 8294             stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
 8295 
 8296         sc->stat_EtherStatsPktsTx1523Octetsto9022Octets =
 8297             stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
 8298 
 8299         sc->stat_XonPauseFramesReceived =
 8300             stats->stat_XonPauseFramesReceived;
 8301 
 8302         sc->stat_XoffPauseFramesReceived =
 8303             stats->stat_XoffPauseFramesReceived;
 8304 
 8305         sc->stat_OutXonSent =
 8306             stats->stat_OutXonSent;
 8307 
 8308         sc->stat_OutXoffSent =
 8309             stats->stat_OutXoffSent;
 8310 
 8311         sc->stat_FlowControlDone =
 8312             stats->stat_FlowControlDone;
 8313 
 8314         sc->stat_MacControlFramesReceived =
 8315             stats->stat_MacControlFramesReceived;
 8316 
 8317         sc->stat_XoffStateEntered =
 8318             stats->stat_XoffStateEntered;
 8319 
 8320         sc->stat_IfInFramesL2FilterDiscards =
 8321             stats->stat_IfInFramesL2FilterDiscards;
 8322 
 8323         sc->stat_IfInRuleCheckerDiscards =
 8324             stats->stat_IfInRuleCheckerDiscards;
 8325 
 8326         sc->stat_IfInFTQDiscards =
 8327             stats->stat_IfInFTQDiscards;
 8328 
 8329         sc->stat_IfInMBUFDiscards =
 8330             stats->stat_IfInMBUFDiscards;
 8331 
 8332         sc->stat_IfInRuleCheckerP4Hit =
 8333             stats->stat_IfInRuleCheckerP4Hit;
 8334 
 8335         sc->stat_CatchupInRuleCheckerDiscards =
 8336             stats->stat_CatchupInRuleCheckerDiscards;
 8337 
 8338         sc->stat_CatchupInFTQDiscards =
 8339             stats->stat_CatchupInFTQDiscards;
 8340 
 8341         sc->stat_CatchupInMBUFDiscards =
 8342             stats->stat_CatchupInMBUFDiscards;
 8343 
 8344         sc->stat_CatchupInRuleCheckerP4Hit =
 8345             stats->stat_CatchupInRuleCheckerP4Hit;
 8346 
 8347         sc->com_no_buffers = REG_RD_IND(sc, 0x120084);
 8348 
 8349         /* ToDo: Add additional statistics? */
 8350 
 8351         DBEXIT(BCE_EXTREME_MISC);
 8352 }
 8353 
 8354 static uint64_t
 8355 bce_get_counter(struct ifnet *ifp, ift_counter cnt)
 8356 {
 8357         struct bce_softc *sc;
 8358         uint64_t rv;
 8359 
 8360         sc = if_getsoftc(ifp);
 8361 
 8362         switch (cnt) {
 8363         case IFCOUNTER_COLLISIONS:
 8364                 return (sc->stat_EtherStatsCollisions);
 8365         case IFCOUNTER_IERRORS:
 8366                 return (sc->stat_EtherStatsUndersizePkts +
 8367                     sc->stat_EtherStatsOversizePkts +
 8368                     sc->stat_IfInMBUFDiscards +
 8369                     sc->stat_Dot3StatsAlignmentErrors +
 8370                     sc->stat_Dot3StatsFCSErrors +
 8371                     sc->stat_IfInRuleCheckerDiscards +
 8372                     sc->stat_IfInFTQDiscards +
 8373                     sc->l2fhdr_error_count +
 8374                     sc->com_no_buffers);
 8375         case IFCOUNTER_OERRORS:
 8376                 rv = sc->stat_Dot3StatsExcessiveCollisions +
 8377                     sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
 8378                     sc->stat_Dot3StatsLateCollisions +
 8379                     sc->watchdog_timeouts;
 8380                 /*
 8381                  * Certain controllers don't report
 8382                  * carrier sense errors correctly.
 8383                  * See errata E11_5708CA0_1165.
 8384                  */
 8385                 if (!(BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5706) &&
 8386                     !(BCE_CHIP_ID(sc) == BCE_CHIP_ID_5708_A0))
 8387                         rv += sc->stat_Dot3StatsCarrierSenseErrors;
 8388                 return (rv);
 8389         default:
 8390                 return (if_get_counter_default(ifp, cnt));
 8391         }
 8392 }
 8393 
 8394 
 8395 /****************************************************************************/
 8396 /* Periodic function to notify the bootcode that the driver is still        */
 8397 /* present.                                                                 */
 8398 /*                                                                          */
 8399 /* Returns:                                                                 */
 8400 /*   Nothing.                                                               */
 8401 /****************************************************************************/
 8402 static void
 8403 bce_pulse(void *xsc)
 8404 {
 8405         struct bce_softc *sc = xsc;
 8406         u32 msg;
 8407 
 8408         DBENTER(BCE_EXTREME_MISC);
 8409 
 8410         BCE_LOCK_ASSERT(sc);
 8411 
 8412         /* Tell the firmware that the driver is still running. */
 8413         msg = (u32) ++sc->bce_fw_drv_pulse_wr_seq;
 8414         bce_shmem_wr(sc, BCE_DRV_PULSE_MB, msg);
 8415 
 8416         /* Update the bootcode condition. */
 8417         sc->bc_state = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
 8418 
 8419         /* Report whether the bootcode still knows the driver is running. */
 8420         if (bce_verbose || bootverbose) {
 8421                 if (sc->bce_drv_cardiac_arrest == FALSE) {
 8422                         if (!(sc->bc_state & BCE_CONDITION_DRV_PRESENT)) {
 8423                                 sc->bce_drv_cardiac_arrest = TRUE;
 8424                                 BCE_PRINTF("%s(): Warning: bootcode "
 8425                                     "thinks driver is absent! "
 8426                                     "(bc_state = 0x%08X)\n",
 8427                                     __FUNCTION__, sc->bc_state);
 8428                         }
 8429                 } else {
 8430                         /*
 8431                          * Not supported by all bootcode versions.
 8432                          * (v5.0.11+ and v5.2.1+)  Older bootcode
 8433                          * will require the driver to reset the
 8434                          * controller to clear this condition.
 8435                          */
 8436                         if (sc->bc_state & BCE_CONDITION_DRV_PRESENT) {
 8437                                 sc->bce_drv_cardiac_arrest = FALSE;
 8438                                 BCE_PRINTF("%s(): Bootcode found the "
 8439                                     "driver pulse! (bc_state = 0x%08X)\n",
 8440                                     __FUNCTION__, sc->bc_state);
 8441                         }
 8442                 }
 8443         }
 8444 
 8445 
 8446         /* Schedule the next pulse. */
 8447         callout_reset(&sc->bce_pulse_callout, hz, bce_pulse, sc);
 8448 
 8449         DBEXIT(BCE_EXTREME_MISC);
 8450 }
 8451 
 8452 
 8453 /****************************************************************************/
 8454 /* Periodic function to perform maintenance tasks.                          */
 8455 /*                                                                          */
 8456 /* Returns:                                                                 */
 8457 /*   Nothing.                                                               */
 8458 /****************************************************************************/
 8459 static void
 8460 bce_tick(void *xsc)
 8461 {
 8462         struct bce_softc *sc = xsc;
 8463         struct mii_data *mii;
 8464         struct ifnet *ifp;
 8465         struct ifmediareq ifmr;
 8466 
 8467         ifp = sc->bce_ifp;
 8468 
 8469         DBENTER(BCE_EXTREME_MISC);
 8470 
 8471         BCE_LOCK_ASSERT(sc);
 8472 
 8473         /* Schedule the next tick. */
 8474         callout_reset(&sc->bce_tick_callout, hz, bce_tick, sc);
 8475 
 8476         /* Update the statistics from the hardware statistics block. */
 8477         bce_stats_update(sc);
 8478 
 8479         /* Ensure page and RX chains get refilled in low-memory situations. */
 8480         if (bce_hdr_split == TRUE)
 8481                 bce_fill_pg_chain(sc);
 8482         bce_fill_rx_chain(sc);
 8483 
 8484         /* Check that chip hasn't hung. */
 8485         bce_watchdog(sc);
 8486 
 8487         /* If link is up already up then we're done. */
 8488         if (sc->bce_link_up == TRUE)
 8489                 goto bce_tick_exit;
 8490 
 8491         /* Link is down.  Check what the PHY's doing. */
 8492         if ((sc->bce_phy_flags & BCE_PHY_REMOTE_CAP_FLAG) != 0) {
 8493                 bzero(&ifmr, sizeof(ifmr));
 8494                 bce_ifmedia_sts_rphy(sc, &ifmr);
 8495                 if ((ifmr.ifm_status & (IFM_ACTIVE | IFM_AVALID)) ==
 8496                     (IFM_ACTIVE | IFM_AVALID)) {
 8497                         sc->bce_link_up = TRUE;
 8498                         bce_miibus_statchg(sc->bce_dev);
 8499                 }
 8500         } else {
 8501                 mii = device_get_softc(sc->bce_miibus);
 8502                 mii_tick(mii);
 8503                 /* Check if the link has come up. */
 8504                 if ((mii->mii_media_status & IFM_ACTIVE) &&
 8505                     (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE)) {
 8506                         DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Link up!\n",
 8507                             __FUNCTION__);
 8508                         sc->bce_link_up = TRUE;
 8509                         if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
 8510                             IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX ||
 8511                             IFM_SUBTYPE(mii->mii_media_active) == IFM_2500_SX) &&
 8512                             (bce_verbose || bootverbose))
 8513                                 BCE_PRINTF("Gigabit link up!\n");
 8514                 }
 8515 
 8516         }
 8517         if (sc->bce_link_up == TRUE) {
 8518                 /* Now that link is up, handle any outstanding TX traffic. */
 8519                 if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
 8520                         DBPRINT(sc, BCE_VERBOSE_MISC, "%s(): Found "
 8521                             "pending TX traffic.\n", __FUNCTION__);
 8522                         bce_start_locked(ifp);
 8523                 }
 8524         }
 8525 
 8526 bce_tick_exit:
 8527         DBEXIT(BCE_EXTREME_MISC);
 8528 }
 8529 
 8530 static void
 8531 bce_fw_cap_init(struct bce_softc *sc)
 8532 {
 8533         u32 ack, cap, link;
 8534 
 8535         ack = 0;
 8536         cap = bce_shmem_rd(sc, BCE_FW_CAP_MB);
 8537         if ((cap & BCE_FW_CAP_SIGNATURE_MAGIC_MASK) !=
 8538             BCE_FW_CAP_SIGNATURE_MAGIC)
 8539                 return;
 8540         if ((cap & (BCE_FW_CAP_MFW_KEEP_VLAN | BCE_FW_CAP_BC_KEEP_VLAN)) ==
 8541             (BCE_FW_CAP_MFW_KEEP_VLAN | BCE_FW_CAP_BC_KEEP_VLAN))
 8542                 ack |= BCE_DRV_ACK_CAP_SIGNATURE_MAGIC |
 8543                     BCE_FW_CAP_MFW_KEEP_VLAN | BCE_FW_CAP_BC_KEEP_VLAN;
 8544         if ((sc->bce_phy_flags & BCE_PHY_SERDES_FLAG) != 0 &&
 8545             (cap & BCE_FW_CAP_REMOTE_PHY_CAP) != 0) {
 8546                 sc->bce_phy_flags &= ~BCE_PHY_REMOTE_PORT_FIBER_FLAG;
 8547                 sc->bce_phy_flags |= BCE_PHY_REMOTE_CAP_FLAG;
 8548                 link = bce_shmem_rd(sc, BCE_LINK_STATUS);
 8549                 if ((link & BCE_LINK_STATUS_SERDES_LINK) != 0)
 8550                         sc->bce_phy_flags |= BCE_PHY_REMOTE_PORT_FIBER_FLAG;
 8551                 ack |= BCE_DRV_ACK_CAP_SIGNATURE_MAGIC |
 8552                     BCE_FW_CAP_REMOTE_PHY_CAP;
 8553         }
 8554 
 8555         if (ack != 0)
 8556                 bce_shmem_wr(sc, BCE_DRV_ACK_CAP_MB, ack);
 8557 }
 8558 
 8559 
 8560 #ifdef BCE_DEBUG
 8561 /****************************************************************************/
 8562 /* Allows the driver state to be dumped through the sysctl interface.       */
 8563 /*                                                                          */
 8564 /* Returns:                                                                 */
 8565 /*   0 for success, positive value for failure.                             */
 8566 /****************************************************************************/
 8567 static int
 8568 bce_sysctl_driver_state(SYSCTL_HANDLER_ARGS)
 8569 {
 8570         int error;
 8571         int result;
 8572         struct bce_softc *sc;
 8573 
 8574         result = -1;
 8575         error = sysctl_handle_int(oidp, &result, 0, req);
 8576 
 8577         if (error || !req->newptr)
 8578                 return (error);
 8579 
 8580         if (result == 1) {
 8581                 sc = (struct bce_softc *)arg1;
 8582                 bce_dump_driver_state(sc);
 8583         }
 8584 
 8585         return error;
 8586 }
 8587 
 8588 
 8589 /****************************************************************************/
 8590 /* Allows the hardware state to be dumped through the sysctl interface.     */
 8591 /*                                                                          */
 8592 /* Returns:                                                                 */
 8593 /*   0 for success, positive value for failure.                             */
 8594 /****************************************************************************/
 8595 static int
 8596 bce_sysctl_hw_state(SYSCTL_HANDLER_ARGS)
 8597 {
 8598         int error;
 8599         int result;
 8600         struct bce_softc *sc;
 8601 
 8602         result = -1;
 8603         error = sysctl_handle_int(oidp, &result, 0, req);
 8604 
 8605         if (error || !req->newptr)
 8606                 return (error);
 8607 
 8608         if (result == 1) {
 8609                 sc = (struct bce_softc *)arg1;
 8610                 bce_dump_hw_state(sc);
 8611         }
 8612 
 8613         return error;
 8614 }
 8615 
 8616 
 8617 /****************************************************************************/
 8618 /* Allows the status block to be dumped through the sysctl interface.       */
 8619 /*                                                                          */
 8620 /* Returns:                                                                 */
 8621 /*   0 for success, positive value for failure.                             */
 8622 /****************************************************************************/
 8623 static int
 8624 bce_sysctl_status_block(SYSCTL_HANDLER_ARGS)
 8625 {
 8626         int error;
 8627         int result;
 8628         struct bce_softc *sc;
 8629 
 8630         result = -1;
 8631         error = sysctl_handle_int(oidp, &result, 0, req);
 8632 
 8633         if (error || !req->newptr)
 8634                 return (error);
 8635 
 8636         if (result == 1) {
 8637                 sc = (struct bce_softc *)arg1;
 8638                 bce_dump_status_block(sc);
 8639         }
 8640 
 8641         return error;
 8642 }
 8643 
 8644 
 8645 /****************************************************************************/
 8646 /* Allows the stats block to be dumped through the sysctl interface.        */
 8647 /*                                                                          */
 8648 /* Returns:                                                                 */
 8649 /*   0 for success, positive value for failure.                             */
 8650 /****************************************************************************/
 8651 static int
 8652 bce_sysctl_stats_block(SYSCTL_HANDLER_ARGS)
 8653 {
 8654         int error;
 8655         int result;
 8656         struct bce_softc *sc;
 8657 
 8658         result = -1;
 8659         error = sysctl_handle_int(oidp, &result, 0, req);
 8660 
 8661         if (error || !req->newptr)
 8662                 return (error);
 8663 
 8664         if (result == 1) {
 8665                 sc = (struct bce_softc *)arg1;
 8666                 bce_dump_stats_block(sc);
 8667         }
 8668 
 8669         return error;
 8670 }
 8671 
 8672 
 8673 /****************************************************************************/
 8674 /* Allows the stat counters to be cleared without unloading/reloading the   */
 8675 /* driver.                                                                  */
 8676 /*                                                                          */
 8677 /* Returns:                                                                 */
 8678 /*   0 for success, positive value for failure.                             */
 8679 /****************************************************************************/
 8680 static int
 8681 bce_sysctl_stats_clear(SYSCTL_HANDLER_ARGS)
 8682 {
 8683         int error;
 8684         int result;
 8685         struct bce_softc *sc;
 8686 
 8687         result = -1;
 8688         error = sysctl_handle_int(oidp, &result, 0, req);
 8689 
 8690         if (error || !req->newptr)
 8691                 return (error);
 8692 
 8693         if (result == 1) {
 8694                 sc = (struct bce_softc *)arg1;
 8695                 struct statistics_block *stats;
 8696 
 8697                 stats = (struct statistics_block *) sc->stats_block;
 8698                 bzero(stats, sizeof(struct statistics_block));
 8699                 bus_dmamap_sync(sc->stats_tag, sc->stats_map,
 8700                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 8701 
 8702                 /* Clear the internal H/W statistics counters. */
 8703                 REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW);
 8704 
 8705                 /* Reset the driver maintained statistics. */
 8706                 sc->interrupts_rx =
 8707                     sc->interrupts_tx = 0;
 8708                 sc->tso_frames_requested =
 8709                     sc->tso_frames_completed =
 8710                     sc->tso_frames_failed = 0;
 8711                 sc->rx_empty_count =
 8712                     sc->tx_full_count = 0;
 8713                 sc->rx_low_watermark = USABLE_RX_BD_ALLOC;
 8714                 sc->tx_hi_watermark = 0;
 8715                 sc->l2fhdr_error_count =
 8716                     sc->l2fhdr_error_sim_count = 0;
 8717                 sc->mbuf_alloc_failed_count =
 8718                     sc->mbuf_alloc_failed_sim_count = 0;
 8719                 sc->dma_map_addr_rx_failed_count =
 8720                     sc->dma_map_addr_tx_failed_count = 0;
 8721                 sc->mbuf_frag_count = 0;
 8722                 sc->csum_offload_tcp_udp =
 8723                     sc->csum_offload_ip = 0;
 8724                 sc->vlan_tagged_frames_rcvd =
 8725                     sc->vlan_tagged_frames_stripped = 0;
 8726                 sc->split_header_frames_rcvd =
 8727                     sc->split_header_tcp_frames_rcvd = 0;
 8728 
 8729                 /* Clear firmware maintained statistics. */
 8730                 REG_WR_IND(sc, 0x120084, 0);
 8731         }
 8732 
 8733         return error;
 8734 }
 8735 
 8736 
 8737 /****************************************************************************/
 8738 /* Allows the shared memory contents to be dumped through the sysctl  .     */
 8739 /* interface.                                                               */
 8740 /*                                                                          */
 8741 /* Returns:                                                                 */
 8742 /*   0 for success, positive value for failure.                             */
 8743 /****************************************************************************/
 8744 static int
 8745 bce_sysctl_shmem_state(SYSCTL_HANDLER_ARGS)
 8746 {
 8747         int error;
 8748         int result;
 8749         struct bce_softc *sc;
 8750 
 8751         result = -1;
 8752         error = sysctl_handle_int(oidp, &result, 0, req);
 8753 
 8754         if (error || !req->newptr)
 8755                 return (error);
 8756 
 8757         if (result == 1) {
 8758                 sc = (struct bce_softc *)arg1;
 8759                 bce_dump_shmem_state(sc);
 8760         }
 8761 
 8762         return error;
 8763 }
 8764 
 8765 
 8766 /****************************************************************************/
 8767 /* Allows the bootcode state to be dumped through the sysctl interface.     */
 8768 /*                                                                          */
 8769 /* Returns:                                                                 */
 8770 /*   0 for success, positive value for failure.                             */
 8771 /****************************************************************************/
 8772 static int
 8773 bce_sysctl_bc_state(SYSCTL_HANDLER_ARGS)
 8774 {
 8775         int error;
 8776         int result;
 8777         struct bce_softc *sc;
 8778 
 8779         result = -1;
 8780         error = sysctl_handle_int(oidp, &result, 0, req);
 8781 
 8782         if (error || !req->newptr)
 8783                 return (error);
 8784 
 8785         if (result == 1) {
 8786                 sc = (struct bce_softc *)arg1;
 8787                 bce_dump_bc_state(sc);
 8788         }
 8789 
 8790         return error;
 8791 }
 8792 
 8793 
 8794 /****************************************************************************/
 8795 /* Provides a sysctl interface to allow dumping the RX BD chain.            */
 8796 /*                                                                          */
 8797 /* Returns:                                                                 */
 8798 /*   0 for success, positive value for failure.                             */
 8799 /****************************************************************************/
 8800 static int
 8801 bce_sysctl_dump_rx_bd_chain(SYSCTL_HANDLER_ARGS)
 8802 {
 8803         int error;
 8804         int result;
 8805         struct bce_softc *sc;
 8806 
 8807         result = -1;
 8808         error = sysctl_handle_int(oidp, &result, 0, req);
 8809 
 8810         if (error || !req->newptr)
 8811                 return (error);
 8812 
 8813         if (result == 1) {
 8814                 sc = (struct bce_softc *)arg1;
 8815                 bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD_ALLOC);
 8816         }
 8817 
 8818         return error;
 8819 }
 8820 
 8821 
 8822 /****************************************************************************/
 8823 /* Provides a sysctl interface to allow dumping the RX MBUF chain.          */
 8824 /*                                                                          */
 8825 /* Returns:                                                                 */
 8826 /*   0 for success, positive value for failure.                             */
 8827 /****************************************************************************/
 8828 static int
 8829 bce_sysctl_dump_rx_mbuf_chain(SYSCTL_HANDLER_ARGS)
 8830 {
 8831         int error;
 8832         int result;
 8833         struct bce_softc *sc;
 8834 
 8835         result = -1;
 8836         error = sysctl_handle_int(oidp, &result, 0, req);
 8837 
 8838         if (error || !req->newptr)
 8839                 return (error);
 8840 
 8841         if (result == 1) {
 8842                 sc = (struct bce_softc *)arg1;
 8843                 bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD_ALLOC);
 8844         }
 8845 
 8846         return error;
 8847 }
 8848 
 8849 
 8850 /****************************************************************************/
 8851 /* Provides a sysctl interface to allow dumping the TX chain.               */
 8852 /*                                                                          */
 8853 /* Returns:                                                                 */
 8854 /*   0 for success, positive value for failure.                             */
 8855 /****************************************************************************/
 8856 static int
 8857 bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS)
 8858 {
 8859         int error;
 8860         int result;
 8861         struct bce_softc *sc;
 8862 
 8863         result = -1;
 8864         error = sysctl_handle_int(oidp, &result, 0, req);
 8865 
 8866         if (error || !req->newptr)
 8867                 return (error);
 8868 
 8869         if (result == 1) {
 8870                 sc = (struct bce_softc *)arg1;
 8871                 bce_dump_tx_chain(sc, 0, TOTAL_TX_BD_ALLOC);
 8872         }
 8873 
 8874         return error;
 8875 }
 8876 
 8877 
 8878 /****************************************************************************/
 8879 /* Provides a sysctl interface to allow dumping the page chain.             */
 8880 /*                                                                          */
 8881 /* Returns:                                                                 */
 8882 /*   0 for success, positive value for failure.                             */
 8883 /****************************************************************************/
 8884 static int
 8885 bce_sysctl_dump_pg_chain(SYSCTL_HANDLER_ARGS)
 8886 {
 8887         int error;
 8888         int result;
 8889         struct bce_softc *sc;
 8890 
 8891         result = -1;
 8892         error = sysctl_handle_int(oidp, &result, 0, req);
 8893 
 8894         if (error || !req->newptr)
 8895                 return (error);
 8896 
 8897         if (result == 1) {
 8898                 sc = (struct bce_softc *)arg1;
 8899                 bce_dump_pg_chain(sc, 0, TOTAL_PG_BD_ALLOC);
 8900         }
 8901 
 8902         return error;
 8903 }
 8904 
 8905 /****************************************************************************/
 8906 /* Provides a sysctl interface to allow reading arbitrary NVRAM offsets in  */
 8907 /* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
 8908 /*                                                                          */
 8909 /* Returns:                                                                 */
 8910 /*   0 for success, positive value for failure.                             */
 8911 /****************************************************************************/
 8912 static int
 8913 bce_sysctl_nvram_read(SYSCTL_HANDLER_ARGS)
 8914 {
 8915         struct bce_softc *sc = (struct bce_softc *)arg1;
 8916         int error;
 8917         u32 result;
 8918         u32 val[1];
 8919         u8 *data = (u8 *) val;
 8920 
 8921         result = -1;
 8922         error = sysctl_handle_int(oidp, &result, 0, req);
 8923         if (error || (req->newptr == NULL))
 8924                 return (error);
 8925 
 8926         error = bce_nvram_read(sc, result, data, 4);
 8927 
 8928         BCE_PRINTF("offset 0x%08X = 0x%08X\n", result, bce_be32toh(val[0]));
 8929 
 8930         return (error);
 8931 }
 8932 
 8933 
 8934 /****************************************************************************/
 8935 /* Provides a sysctl interface to allow reading arbitrary registers in the  */
 8936 /* device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                            */
 8937 /*                                                                          */
 8938 /* Returns:                                                                 */
 8939 /*   0 for success, positive value for failure.                             */
 8940 /****************************************************************************/
 8941 static int
 8942 bce_sysctl_reg_read(SYSCTL_HANDLER_ARGS)
 8943 {
 8944         struct bce_softc *sc = (struct bce_softc *)arg1;
 8945         int error;
 8946         u32 val, result;
 8947 
 8948         result = -1;
 8949         error = sysctl_handle_int(oidp, &result, 0, req);
 8950         if (error || (req->newptr == NULL))
 8951                 return (error);
 8952 
 8953         /* Make sure the register is accessible. */
 8954         if (result < 0x8000) {
 8955                 val = REG_RD(sc, result);
 8956                 BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
 8957         } else if (result < 0x0280000) {
 8958                 val = REG_RD_IND(sc, result);
 8959                 BCE_PRINTF("reg 0x%08X = 0x%08X\n", result, val);
 8960         }
 8961 
 8962         return (error);
 8963 }
 8964 
 8965 
 8966 /****************************************************************************/
 8967 /* Provides a sysctl interface to allow reading arbitrary PHY registers in  */
 8968 /* the device.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                        */
 8969 /*                                                                          */
 8970 /* Returns:                                                                 */
 8971 /*   0 for success, positive value for failure.                             */
 8972 /****************************************************************************/
 8973 static int
 8974 bce_sysctl_phy_read(SYSCTL_HANDLER_ARGS)
 8975 {
 8976         struct bce_softc *sc;
 8977         device_t dev;
 8978         int error, result;
 8979         u16 val;
 8980 
 8981         result = -1;
 8982         error = sysctl_handle_int(oidp, &result, 0, req);
 8983         if (error || (req->newptr == NULL))
 8984                 return (error);
 8985 
 8986         /* Make sure the register is accessible. */
 8987         if (result < 0x20) {
 8988                 sc = (struct bce_softc *)arg1;
 8989                 dev = sc->bce_dev;
 8990                 val = bce_miibus_read_reg(dev, sc->bce_phy_addr, result);
 8991                 BCE_PRINTF("phy 0x%02X = 0x%04X\n", result, val);
 8992         }
 8993         return (error);
 8994 }
 8995 
 8996 
 8997 /****************************************************************************/
 8998 /* Provides a sysctl interface for dumping the nvram contents.              */
 8999 /* DO NOT ENABLE ON PRODUCTION SYSTEMS!                                     */
 9000 /*                                                                          */
 9001 /* Returns:                                                                 */
 9002 /*   0 for success, positive errno for failure.                             */
 9003 /****************************************************************************/
 9004 static int
 9005 bce_sysctl_nvram_dump(SYSCTL_HANDLER_ARGS)
 9006 {
 9007         struct bce_softc *sc = (struct bce_softc *)arg1;
 9008         int error, i;
 9009 
 9010         if (sc->nvram_buf == NULL)
 9011                 sc->nvram_buf = malloc(sc->bce_flash_size,
 9012                                     M_TEMP, M_ZERO | M_WAITOK);
 9013 
 9014         error = 0;
 9015         if (req->oldlen == sc->bce_flash_size) {
 9016                 for (i = 0; i < sc->bce_flash_size && error == 0; i++)
 9017                         error = bce_nvram_read(sc, i, &sc->nvram_buf[i], 1);
 9018         }
 9019 
 9020         if (error == 0)
 9021                 error = SYSCTL_OUT(req, sc->nvram_buf, sc->bce_flash_size);
 9022 
 9023         return error;
 9024 }
 9025 
 9026 #ifdef BCE_NVRAM_WRITE_SUPPORT
 9027 /****************************************************************************/
 9028 /* Provides a sysctl interface for writing to nvram.                        */
 9029 /* DO NOT ENABLE ON PRODUCTION SYSTEMS!                                     */
 9030 /*                                                                          */
 9031 /* Returns:                                                                 */
 9032 /*   0 for success, positive errno for failure.                             */
 9033 /****************************************************************************/
 9034 static int
 9035 bce_sysctl_nvram_write(SYSCTL_HANDLER_ARGS)
 9036 {
 9037         struct bce_softc *sc = (struct bce_softc *)arg1;
 9038         int error;
 9039 
 9040         if (sc->nvram_buf == NULL)
 9041                 sc->nvram_buf = malloc(sc->bce_flash_size,
 9042                                     M_TEMP, M_ZERO | M_WAITOK);
 9043         else
 9044                 bzero(sc->nvram_buf, sc->bce_flash_size);
 9045 
 9046         error = SYSCTL_IN(req, sc->nvram_buf, sc->bce_flash_size);
 9047         if (error == 0)
 9048                 return (error);
 9049 
 9050         if (req->newlen == sc->bce_flash_size)
 9051                 error = bce_nvram_write(sc, 0, sc->nvram_buf,
 9052                             sc->bce_flash_size);
 9053 
 9054 
 9055         return error;
 9056 }
 9057 #endif
 9058 
 9059 
 9060 /****************************************************************************/
 9061 /* Provides a sysctl interface to allow reading a CID.                      */
 9062 /*                                                                          */
 9063 /* Returns:                                                                 */
 9064 /*   0 for success, positive value for failure.                             */
 9065 /****************************************************************************/
 9066 static int
 9067 bce_sysctl_dump_ctx(SYSCTL_HANDLER_ARGS)
 9068 {
 9069         struct bce_softc *sc;
 9070         int error, result;
 9071 
 9072         result = -1;
 9073         error = sysctl_handle_int(oidp, &result, 0, req);
 9074         if (error || (req->newptr == NULL))
 9075                 return (error);
 9076 
 9077         /* Make sure the register is accessible. */
 9078         if (result <= TX_CID) {
 9079                 sc = (struct bce_softc *)arg1;
 9080                 bce_dump_ctx(sc, result);
 9081         }
 9082 
 9083         return (error);
 9084 }
 9085 
 9086 
 9087 /****************************************************************************/
 9088 /* Provides a sysctl interface to forcing the driver to dump state and      */
 9089 /* enter the debugger.  DO NOT ENABLE ON PRODUCTION SYSTEMS!                */
 9090 /*                                                                          */
 9091 /* Returns:                                                                 */
 9092 /*   0 for success, positive value for failure.                             */
 9093 /****************************************************************************/
 9094 static int
 9095 bce_sysctl_breakpoint(SYSCTL_HANDLER_ARGS)
 9096 {
 9097         int error;
 9098         int result;
 9099         struct bce_softc *sc;
 9100 
 9101         result = -1;
 9102         error = sysctl_handle_int(oidp, &result, 0, req);
 9103 
 9104         if (error || !req->newptr)
 9105                 return (error);
 9106 
 9107         if (result == 1) {
 9108                 sc = (struct bce_softc *)arg1;
 9109                 bce_breakpoint(sc);
 9110         }
 9111 
 9112         return error;
 9113 }
 9114 #endif
 9115 
 9116 /****************************************************************************/
 9117 /* Adds any sysctl parameters for tuning or debugging purposes.             */
 9118 /*                                                                          */
 9119 /* Returns:                                                                 */
 9120 /*   0 for success, positive value for failure.                             */
 9121 /****************************************************************************/
 9122 static void
 9123 bce_add_sysctls(struct bce_softc *sc)
 9124 {
 9125         struct sysctl_ctx_list *ctx;
 9126         struct sysctl_oid_list *children;
 9127 
 9128         DBENTER(BCE_VERBOSE_MISC);
 9129 
 9130         ctx = device_get_sysctl_ctx(sc->bce_dev);
 9131         children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->bce_dev));
 9132 
 9133 #ifdef BCE_DEBUG
 9134         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
 9135             "l2fhdr_error_sim_control",
 9136             CTLFLAG_RW, &l2fhdr_error_sim_control,
 9137             0, "Debug control to force l2fhdr errors");
 9138 
 9139         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
 9140             "l2fhdr_error_sim_count",
 9141             CTLFLAG_RD, &sc->l2fhdr_error_sim_count,
 9142             0, "Number of simulated l2_fhdr errors");
 9143 #endif
 9144 
 9145         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9146             "l2fhdr_error_count",
 9147             CTLFLAG_RD, &sc->l2fhdr_error_count,
 9148             0, "Number of l2_fhdr errors");
 9149 
 9150 #ifdef BCE_DEBUG
 9151         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
 9152             "mbuf_alloc_failed_sim_control",
 9153             CTLFLAG_RW, &mbuf_alloc_failed_sim_control,
 9154             0, "Debug control to force mbuf allocation failures");
 9155 
 9156         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9157             "mbuf_alloc_failed_sim_count",
 9158             CTLFLAG_RD, &sc->mbuf_alloc_failed_sim_count,
 9159             0, "Number of simulated mbuf cluster allocation failures");
 9160 #endif
 9161 
 9162         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9163             "mbuf_alloc_failed_count",
 9164             CTLFLAG_RD, &sc->mbuf_alloc_failed_count,
 9165             0, "Number of mbuf allocation failures");
 9166 
 9167         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9168             "mbuf_frag_count",
 9169             CTLFLAG_RD, &sc->mbuf_frag_count,
 9170             0, "Number of fragmented mbufs");
 9171 
 9172 #ifdef BCE_DEBUG
 9173         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
 9174             "dma_map_addr_failed_sim_control",
 9175             CTLFLAG_RW, &dma_map_addr_failed_sim_control,
 9176             0, "Debug control to force DMA mapping failures");
 9177 
 9178         /* ToDo: Figure out how to update this value in bce_dma_map_addr(). */
 9179         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9180             "dma_map_addr_failed_sim_count",
 9181             CTLFLAG_RD, &sc->dma_map_addr_failed_sim_count,
 9182             0, "Number of simulated DMA mapping failures");
 9183 
 9184 #endif
 9185 
 9186         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9187             "dma_map_addr_rx_failed_count",
 9188             CTLFLAG_RD, &sc->dma_map_addr_rx_failed_count,
 9189             0, "Number of RX DMA mapping failures");
 9190 
 9191         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9192             "dma_map_addr_tx_failed_count",
 9193             CTLFLAG_RD, &sc->dma_map_addr_tx_failed_count,
 9194             0, "Number of TX DMA mapping failures");
 9195 
 9196 #ifdef BCE_DEBUG
 9197         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
 9198             "unexpected_attention_sim_control",
 9199             CTLFLAG_RW, &unexpected_attention_sim_control,
 9200             0, "Debug control to simulate unexpected attentions");
 9201 
 9202         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9203             "unexpected_attention_sim_count",
 9204             CTLFLAG_RW, &sc->unexpected_attention_sim_count,
 9205             0, "Number of simulated unexpected attentions");
 9206 #endif
 9207 
 9208         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9209             "unexpected_attention_count",
 9210             CTLFLAG_RW, &sc->unexpected_attention_count,
 9211             0, "Number of unexpected attentions");
 9212 
 9213 #ifdef BCE_DEBUG
 9214         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
 9215             "debug_bootcode_running_failure",
 9216             CTLFLAG_RW, &bootcode_running_failure_sim_control,
 9217             0, "Debug control to force bootcode running failures");
 9218 
 9219         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
 9220             "rx_low_watermark",
 9221             CTLFLAG_RD, &sc->rx_low_watermark,
 9222             0, "Lowest level of free rx_bd's");
 9223 
 9224         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9225             "rx_empty_count",
 9226             CTLFLAG_RD, &sc->rx_empty_count,
 9227             "Number of times the RX chain was empty");
 9228 
 9229         SYSCTL_ADD_INT(ctx, children, OID_AUTO,
 9230             "tx_hi_watermark",
 9231             CTLFLAG_RD, &sc->tx_hi_watermark,
 9232             0, "Highest level of used tx_bd's");
 9233 
 9234         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9235             "tx_full_count",
 9236             CTLFLAG_RD, &sc->tx_full_count,
 9237             "Number of times the TX chain was full");
 9238 
 9239         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9240             "tso_frames_requested",
 9241             CTLFLAG_RD, &sc->tso_frames_requested,
 9242             "Number of TSO frames requested");
 9243 
 9244         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9245             "tso_frames_completed",
 9246             CTLFLAG_RD, &sc->tso_frames_completed,
 9247             "Number of TSO frames completed");
 9248 
 9249         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9250             "tso_frames_failed",
 9251             CTLFLAG_RD, &sc->tso_frames_failed,
 9252             "Number of TSO frames failed");
 9253 
 9254         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9255             "csum_offload_ip",
 9256             CTLFLAG_RD, &sc->csum_offload_ip,
 9257             "Number of IP checksum offload frames");
 9258 
 9259         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9260             "csum_offload_tcp_udp",
 9261             CTLFLAG_RD, &sc->csum_offload_tcp_udp,
 9262             "Number of TCP/UDP checksum offload frames");
 9263 
 9264         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9265             "vlan_tagged_frames_rcvd",
 9266             CTLFLAG_RD, &sc->vlan_tagged_frames_rcvd,
 9267             "Number of VLAN tagged frames received");
 9268 
 9269         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9270             "vlan_tagged_frames_stripped",
 9271             CTLFLAG_RD, &sc->vlan_tagged_frames_stripped,
 9272             "Number of VLAN tagged frames stripped");
 9273 
 9274         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9275             "interrupts_rx",
 9276             CTLFLAG_RD, &sc->interrupts_rx,
 9277             "Number of RX interrupts");
 9278 
 9279         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9280             "interrupts_tx",
 9281             CTLFLAG_RD, &sc->interrupts_tx,
 9282             "Number of TX interrupts");
 9283 
 9284         if (bce_hdr_split == TRUE) {
 9285                 SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9286                     "split_header_frames_rcvd",
 9287                     CTLFLAG_RD, &sc->split_header_frames_rcvd,
 9288                     "Number of split header frames received");
 9289 
 9290                 SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9291                     "split_header_tcp_frames_rcvd",
 9292                     CTLFLAG_RD, &sc->split_header_tcp_frames_rcvd,
 9293                     "Number of split header TCP frames received");
 9294         }
 9295 
 9296         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9297             "nvram_dump", CTLTYPE_OPAQUE | CTLFLAG_RD,
 9298             (void *)sc, 0,
 9299             bce_sysctl_nvram_dump, "S", "");
 9300 
 9301 #ifdef BCE_NVRAM_WRITE_SUPPORT
 9302         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9303             "nvram_write", CTLTYPE_OPAQUE | CTLFLAG_WR,
 9304             (void *)sc, 0,
 9305             bce_sysctl_nvram_write, "S", "");
 9306 #endif
 9307 #endif /* BCE_DEBUG */
 9308 
 9309         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9310             "stat_IfHcInOctets",
 9311             CTLFLAG_RD, &sc->stat_IfHCInOctets,
 9312             "Bytes received");
 9313 
 9314         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9315             "stat_IfHCInBadOctets",
 9316             CTLFLAG_RD, &sc->stat_IfHCInBadOctets,
 9317             "Bad bytes received");
 9318 
 9319         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9320             "stat_IfHCOutOctets",
 9321             CTLFLAG_RD, &sc->stat_IfHCOutOctets,
 9322             "Bytes sent");
 9323 
 9324         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9325             "stat_IfHCOutBadOctets",
 9326             CTLFLAG_RD, &sc->stat_IfHCOutBadOctets,
 9327             "Bad bytes sent");
 9328 
 9329         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9330             "stat_IfHCInUcastPkts",
 9331             CTLFLAG_RD, &sc->stat_IfHCInUcastPkts,
 9332             "Unicast packets received");
 9333 
 9334         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9335             "stat_IfHCInMulticastPkts",
 9336             CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts,
 9337             "Multicast packets received");
 9338 
 9339         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9340             "stat_IfHCInBroadcastPkts",
 9341             CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts,
 9342             "Broadcast packets received");
 9343 
 9344         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9345             "stat_IfHCOutUcastPkts",
 9346             CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts,
 9347             "Unicast packets sent");
 9348 
 9349         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9350             "stat_IfHCOutMulticastPkts",
 9351             CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts,
 9352             "Multicast packets sent");
 9353 
 9354         SYSCTL_ADD_QUAD(ctx, children, OID_AUTO,
 9355             "stat_IfHCOutBroadcastPkts",
 9356             CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts,
 9357             "Broadcast packets sent");
 9358 
 9359         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9360             "stat_emac_tx_stat_dot3statsinternalmactransmiterrors",
 9361             CTLFLAG_RD, &sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors,
 9362             0, "Internal MAC transmit errors");
 9363 
 9364         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9365             "stat_Dot3StatsCarrierSenseErrors",
 9366             CTLFLAG_RD, &sc->stat_Dot3StatsCarrierSenseErrors,
 9367             0, "Carrier sense errors");
 9368 
 9369         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9370             "stat_Dot3StatsFCSErrors",
 9371             CTLFLAG_RD, &sc->stat_Dot3StatsFCSErrors,
 9372             0, "Frame check sequence errors");
 9373 
 9374         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9375             "stat_Dot3StatsAlignmentErrors",
 9376             CTLFLAG_RD, &sc->stat_Dot3StatsAlignmentErrors,
 9377             0, "Alignment errors");
 9378 
 9379         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9380             "stat_Dot3StatsSingleCollisionFrames",
 9381             CTLFLAG_RD, &sc->stat_Dot3StatsSingleCollisionFrames,
 9382             0, "Single Collision Frames");
 9383 
 9384         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9385             "stat_Dot3StatsMultipleCollisionFrames",
 9386             CTLFLAG_RD, &sc->stat_Dot3StatsMultipleCollisionFrames,
 9387             0, "Multiple Collision Frames");
 9388 
 9389         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9390             "stat_Dot3StatsDeferredTransmissions",
 9391             CTLFLAG_RD, &sc->stat_Dot3StatsDeferredTransmissions,
 9392             0, "Deferred Transmissions");
 9393 
 9394         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9395             "stat_Dot3StatsExcessiveCollisions",
 9396             CTLFLAG_RD, &sc->stat_Dot3StatsExcessiveCollisions,
 9397             0, "Excessive Collisions");
 9398 
 9399         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9400             "stat_Dot3StatsLateCollisions",
 9401             CTLFLAG_RD, &sc->stat_Dot3StatsLateCollisions,
 9402             0, "Late Collisions");
 9403 
 9404         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9405             "stat_EtherStatsCollisions",
 9406             CTLFLAG_RD, &sc->stat_EtherStatsCollisions,
 9407             0, "Collisions");
 9408 
 9409         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9410             "stat_EtherStatsFragments",
 9411             CTLFLAG_RD, &sc->stat_EtherStatsFragments,
 9412             0, "Fragments");
 9413 
 9414         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9415             "stat_EtherStatsJabbers",
 9416             CTLFLAG_RD, &sc->stat_EtherStatsJabbers,
 9417             0, "Jabbers");
 9418 
 9419         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9420             "stat_EtherStatsUndersizePkts",
 9421             CTLFLAG_RD, &sc->stat_EtherStatsUndersizePkts,
 9422             0, "Undersize packets");
 9423 
 9424         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9425             "stat_EtherStatsOversizePkts",
 9426             CTLFLAG_RD, &sc->stat_EtherStatsOversizePkts,
 9427             0, "stat_EtherStatsOversizePkts");
 9428 
 9429         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9430             "stat_EtherStatsPktsRx64Octets",
 9431             CTLFLAG_RD, &sc->stat_EtherStatsPktsRx64Octets,
 9432             0, "Bytes received in 64 byte packets");
 9433 
 9434         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9435             "stat_EtherStatsPktsRx65Octetsto127Octets",
 9436             CTLFLAG_RD, &sc->stat_EtherStatsPktsRx65Octetsto127Octets,
 9437             0, "Bytes received in 65 to 127 byte packets");
 9438 
 9439         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9440             "stat_EtherStatsPktsRx128Octetsto255Octets",
 9441             CTLFLAG_RD, &sc->stat_EtherStatsPktsRx128Octetsto255Octets,
 9442             0, "Bytes received in 128 to 255 byte packets");
 9443 
 9444         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9445             "stat_EtherStatsPktsRx256Octetsto511Octets",
 9446             CTLFLAG_RD, &sc->stat_EtherStatsPktsRx256Octetsto511Octets,
 9447             0, "Bytes received in 256 to 511 byte packets");
 9448 
 9449         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9450             "stat_EtherStatsPktsRx512Octetsto1023Octets",
 9451             CTLFLAG_RD, &sc->stat_EtherStatsPktsRx512Octetsto1023Octets,
 9452             0, "Bytes received in 512 to 1023 byte packets");
 9453 
 9454         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9455             "stat_EtherStatsPktsRx1024Octetsto1522Octets",
 9456             CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1024Octetsto1522Octets,
 9457             0, "Bytes received in 1024 t0 1522 byte packets");
 9458 
 9459         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9460             "stat_EtherStatsPktsRx1523Octetsto9022Octets",
 9461             CTLFLAG_RD, &sc->stat_EtherStatsPktsRx1523Octetsto9022Octets,
 9462             0, "Bytes received in 1523 to 9022 byte packets");
 9463 
 9464         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9465             "stat_EtherStatsPktsTx64Octets",
 9466             CTLFLAG_RD, &sc->stat_EtherStatsPktsTx64Octets,
 9467             0, "Bytes sent in 64 byte packets");
 9468 
 9469         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9470             "stat_EtherStatsPktsTx65Octetsto127Octets",
 9471             CTLFLAG_RD, &sc->stat_EtherStatsPktsTx65Octetsto127Octets,
 9472             0, "Bytes sent in 65 to 127 byte packets");
 9473 
 9474         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9475             "stat_EtherStatsPktsTx128Octetsto255Octets",
 9476             CTLFLAG_RD, &sc->stat_EtherStatsPktsTx128Octetsto255Octets,
 9477             0, "Bytes sent in 128 to 255 byte packets");
 9478 
 9479         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9480             "stat_EtherStatsPktsTx256Octetsto511Octets",
 9481             CTLFLAG_RD, &sc->stat_EtherStatsPktsTx256Octetsto511Octets,
 9482             0, "Bytes sent in 256 to 511 byte packets");
 9483 
 9484         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9485             "stat_EtherStatsPktsTx512Octetsto1023Octets",
 9486             CTLFLAG_RD, &sc->stat_EtherStatsPktsTx512Octetsto1023Octets,
 9487             0, "Bytes sent in 512 to 1023 byte packets");
 9488 
 9489         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9490             "stat_EtherStatsPktsTx1024Octetsto1522Octets",
 9491             CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1024Octetsto1522Octets,
 9492             0, "Bytes sent in 1024 to 1522 byte packets");
 9493 
 9494         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9495             "stat_EtherStatsPktsTx1523Octetsto9022Octets",
 9496             CTLFLAG_RD, &sc->stat_EtherStatsPktsTx1523Octetsto9022Octets,
 9497             0, "Bytes sent in 1523 to 9022 byte packets");
 9498 
 9499         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9500             "stat_XonPauseFramesReceived",
 9501             CTLFLAG_RD, &sc->stat_XonPauseFramesReceived,
 9502             0, "XON pause frames receved");
 9503 
 9504         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9505             "stat_XoffPauseFramesReceived",
 9506             CTLFLAG_RD, &sc->stat_XoffPauseFramesReceived,
 9507             0, "XOFF pause frames received");
 9508 
 9509         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9510             "stat_OutXonSent",
 9511             CTLFLAG_RD, &sc->stat_OutXonSent,
 9512             0, "XON pause frames sent");
 9513 
 9514         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9515             "stat_OutXoffSent",
 9516             CTLFLAG_RD, &sc->stat_OutXoffSent,
 9517             0, "XOFF pause frames sent");
 9518 
 9519         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9520             "stat_FlowControlDone",
 9521             CTLFLAG_RD, &sc->stat_FlowControlDone,
 9522             0, "Flow control done");
 9523 
 9524         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9525             "stat_MacControlFramesReceived",
 9526             CTLFLAG_RD, &sc->stat_MacControlFramesReceived,
 9527             0, "MAC control frames received");
 9528 
 9529         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9530             "stat_XoffStateEntered",
 9531             CTLFLAG_RD, &sc->stat_XoffStateEntered,
 9532             0, "XOFF state entered");
 9533 
 9534         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9535             "stat_IfInFramesL2FilterDiscards",
 9536             CTLFLAG_RD, &sc->stat_IfInFramesL2FilterDiscards,
 9537             0, "Received L2 packets discarded");
 9538 
 9539         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9540             "stat_IfInRuleCheckerDiscards",
 9541             CTLFLAG_RD, &sc->stat_IfInRuleCheckerDiscards,
 9542             0, "Received packets discarded by rule");
 9543 
 9544         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9545             "stat_IfInFTQDiscards",
 9546             CTLFLAG_RD, &sc->stat_IfInFTQDiscards,
 9547             0, "Received packet FTQ discards");
 9548 
 9549         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9550             "stat_IfInMBUFDiscards",
 9551             CTLFLAG_RD, &sc->stat_IfInMBUFDiscards,
 9552             0, "Received packets discarded due to lack "
 9553             "of controller buffer memory");
 9554 
 9555         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9556             "stat_IfInRuleCheckerP4Hit",
 9557             CTLFLAG_RD, &sc->stat_IfInRuleCheckerP4Hit,
 9558             0, "Received packets rule checker hits");
 9559 
 9560         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9561             "stat_CatchupInRuleCheckerDiscards",
 9562             CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerDiscards,
 9563             0, "Received packets discarded in Catchup path");
 9564 
 9565         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9566             "stat_CatchupInFTQDiscards",
 9567             CTLFLAG_RD, &sc->stat_CatchupInFTQDiscards,
 9568             0, "Received packets discarded in FTQ in Catchup path");
 9569 
 9570         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9571             "stat_CatchupInMBUFDiscards",
 9572             CTLFLAG_RD, &sc->stat_CatchupInMBUFDiscards,
 9573             0, "Received packets discarded in controller "
 9574             "buffer memory in Catchup path");
 9575 
 9576         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9577             "stat_CatchupInRuleCheckerP4Hit",
 9578             CTLFLAG_RD, &sc->stat_CatchupInRuleCheckerP4Hit,
 9579             0, "Received packets rule checker hits in Catchup path");
 9580 
 9581         SYSCTL_ADD_UINT(ctx, children, OID_AUTO,
 9582             "com_no_buffers",
 9583             CTLFLAG_RD, &sc->com_no_buffers,
 9584             0, "Valid packets received but no RX buffers available");
 9585 
 9586 #ifdef BCE_DEBUG
 9587         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9588             "driver_state", CTLTYPE_INT | CTLFLAG_RW,
 9589             (void *)sc, 0,
 9590             bce_sysctl_driver_state, "I", "Drive state information");
 9591 
 9592         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9593             "hw_state", CTLTYPE_INT | CTLFLAG_RW,
 9594             (void *)sc, 0,
 9595             bce_sysctl_hw_state, "I", "Hardware state information");
 9596 
 9597         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9598             "status_block", CTLTYPE_INT | CTLFLAG_RW,
 9599             (void *)sc, 0,
 9600             bce_sysctl_status_block, "I", "Dump status block");
 9601 
 9602         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9603             "stats_block", CTLTYPE_INT | CTLFLAG_RW,
 9604             (void *)sc, 0,
 9605             bce_sysctl_stats_block, "I", "Dump statistics block");
 9606 
 9607         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9608             "stats_clear", CTLTYPE_INT | CTLFLAG_RW,
 9609             (void *)sc, 0,
 9610             bce_sysctl_stats_clear, "I", "Clear statistics block");
 9611 
 9612         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9613             "shmem_state", CTLTYPE_INT | CTLFLAG_RW,
 9614             (void *)sc, 0,
 9615             bce_sysctl_shmem_state, "I", "Shared memory state information");
 9616 
 9617         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9618             "bc_state", CTLTYPE_INT | CTLFLAG_RW,
 9619             (void *)sc, 0,
 9620             bce_sysctl_bc_state, "I", "Bootcode state information");
 9621 
 9622         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9623             "dump_rx_bd_chain", CTLTYPE_INT | CTLFLAG_RW,
 9624             (void *)sc, 0,
 9625             bce_sysctl_dump_rx_bd_chain, "I", "Dump RX BD chain");
 9626 
 9627         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9628             "dump_rx_mbuf_chain", CTLTYPE_INT | CTLFLAG_RW,
 9629             (void *)sc, 0,
 9630             bce_sysctl_dump_rx_mbuf_chain, "I", "Dump RX MBUF chain");
 9631 
 9632         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9633             "dump_tx_chain", CTLTYPE_INT | CTLFLAG_RW,
 9634             (void *)sc, 0,
 9635             bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain");
 9636 
 9637         if (bce_hdr_split == TRUE) {
 9638                 SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9639                     "dump_pg_chain", CTLTYPE_INT | CTLFLAG_RW,
 9640                     (void *)sc, 0,
 9641                     bce_sysctl_dump_pg_chain, "I", "Dump page chain");
 9642         }
 9643 
 9644         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9645             "dump_ctx", CTLTYPE_INT | CTLFLAG_RW,
 9646             (void *)sc, 0,
 9647             bce_sysctl_dump_ctx, "I", "Dump context memory");
 9648 
 9649         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9650             "breakpoint", CTLTYPE_INT | CTLFLAG_RW,
 9651             (void *)sc, 0,
 9652             bce_sysctl_breakpoint, "I", "Driver breakpoint");
 9653 
 9654         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9655             "reg_read", CTLTYPE_INT | CTLFLAG_RW,
 9656             (void *)sc, 0,
 9657             bce_sysctl_reg_read, "I", "Register read");
 9658 
 9659         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9660             "nvram_read", CTLTYPE_INT | CTLFLAG_RW,
 9661             (void *)sc, 0,
 9662             bce_sysctl_nvram_read, "I", "NVRAM read");
 9663 
 9664         SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
 9665             "phy_read", CTLTYPE_INT | CTLFLAG_RW,
 9666             (void *)sc, 0,
 9667             bce_sysctl_phy_read, "I", "PHY register read");
 9668 
 9669 #endif
 9670 
 9671         DBEXIT(BCE_VERBOSE_MISC);
 9672 }
 9673 
 9674 
 9675 /****************************************************************************/
 9676 /* BCE Debug Routines                                                       */
 9677 /****************************************************************************/
 9678 #ifdef BCE_DEBUG
 9679 
 9680 /****************************************************************************/
 9681 /* Freezes the controller to allow for a cohesive state dump.               */
 9682 /*                                                                          */
 9683 /* Returns:                                                                 */
 9684 /*   Nothing.                                                               */
 9685 /****************************************************************************/
 9686 static __attribute__ ((noinline)) void
 9687 bce_freeze_controller(struct bce_softc *sc)
 9688 {
 9689         u32 val;
 9690         val = REG_RD(sc, BCE_MISC_COMMAND);
 9691         val |= BCE_MISC_COMMAND_DISABLE_ALL;
 9692         REG_WR(sc, BCE_MISC_COMMAND, val);
 9693 }
 9694 
 9695 
 9696 /****************************************************************************/
 9697 /* Unfreezes the controller after a freeze operation.  This may not always  */
 9698 /* work and the controller will require a reset!                            */
 9699 /*                                                                          */
 9700 /* Returns:                                                                 */
 9701 /*   Nothing.                                                               */
 9702 /****************************************************************************/
 9703 static __attribute__ ((noinline)) void
 9704 bce_unfreeze_controller(struct bce_softc *sc)
 9705 {
 9706         u32 val;
 9707         val = REG_RD(sc, BCE_MISC_COMMAND);
 9708         val |= BCE_MISC_COMMAND_ENABLE_ALL;
 9709         REG_WR(sc, BCE_MISC_COMMAND, val);
 9710 }
 9711 
 9712 
 9713 /****************************************************************************/
 9714 /* Prints out Ethernet frame information from an mbuf.                      */
 9715 /*                                                                          */
 9716 /* Partially decode an Ethernet frame to look at some important headers.    */
 9717 /*                                                                          */
 9718 /* Returns:                                                                 */
 9719 /*   Nothing.                                                               */
 9720 /****************************************************************************/
 9721 static __attribute__ ((noinline)) void
 9722 bce_dump_enet(struct bce_softc *sc, struct mbuf *m)
 9723 {
 9724         struct ether_vlan_header *eh;
 9725         u16 etype;
 9726         int ehlen;
 9727         struct ip *ip;
 9728         struct tcphdr *th;
 9729         struct udphdr *uh;
 9730         struct arphdr *ah;
 9731 
 9732         BCE_PRINTF(
 9733             "-----------------------------"
 9734             " Frame Decode "
 9735             "-----------------------------\n");
 9736 
 9737         eh = mtod(m, struct ether_vlan_header *);
 9738 
 9739         /* Handle VLAN encapsulation if present. */
 9740         if (eh->evl_encap_proto == htons(ETHERTYPE_VLAN)) {
 9741                 etype = ntohs(eh->evl_proto);
 9742                 ehlen = ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
 9743         } else {
 9744                 etype = ntohs(eh->evl_encap_proto);
 9745                 ehlen = ETHER_HDR_LEN;
 9746         }
 9747 
 9748         /* ToDo: Add VLAN output. */
 9749         BCE_PRINTF("enet: dest = %6D, src = %6D, type = 0x%04X, hlen = %d\n",
 9750             eh->evl_dhost, ":", eh->evl_shost, ":", etype, ehlen);
 9751 
 9752         switch (etype) {
 9753         case ETHERTYPE_IP:
 9754                 ip = (struct ip *)(m->m_data + ehlen);
 9755                 BCE_PRINTF("--ip: dest = 0x%08X , src = 0x%08X, "
 9756                     "len = %d bytes, protocol = 0x%02X, xsum = 0x%04X\n",
 9757                     ntohl(ip->ip_dst.s_addr), ntohl(ip->ip_src.s_addr),
 9758                     ntohs(ip->ip_len), ip->ip_p, ntohs(ip->ip_sum));
 9759 
 9760                 switch (ip->ip_p) {
 9761                 case IPPROTO_TCP:
 9762                         th = (struct tcphdr *)((caddr_t)ip + (ip->ip_hl << 2));
 9763                         BCE_PRINTF("-tcp: dest = %d, src = %d, hlen = "
 9764                             "%d bytes, flags = 0x%b, csum = 0x%04X\n",
 9765                             ntohs(th->th_dport), ntohs(th->th_sport),
 9766                             (th->th_off << 2), th->th_flags,
 9767                             "\2\10CWR\07ECE\06URG\05ACK\04PSH\03RST"
 9768                             "\02SYN\01FIN", ntohs(th->th_sum));
 9769                         break;
 9770                 case IPPROTO_UDP:
 9771                         uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
 9772                         BCE_PRINTF("-udp: dest = %d, src = %d, len = %d "
 9773                             "bytes, csum = 0x%04X\n", ntohs(uh->uh_dport),
 9774                             ntohs(uh->uh_sport), ntohs(uh->uh_ulen),
 9775                             ntohs(uh->uh_sum));
 9776                         break;
 9777                 case IPPROTO_ICMP:
 9778                         BCE_PRINTF("icmp:\n");
 9779                         break;
 9780                 default:
 9781                         BCE_PRINTF("----: Other IP protocol.\n");
 9782                         }
 9783                 break;
 9784         case ETHERTYPE_IPV6:
 9785                 BCE_PRINTF("ipv6: No decode supported.\n");
 9786                 break;
 9787         case ETHERTYPE_ARP:
 9788                 BCE_PRINTF("-arp: ");
 9789                 ah = (struct arphdr *) (m->m_data + ehlen);
 9790                 switch (ntohs(ah->ar_op)) {
 9791                 case ARPOP_REVREQUEST:
 9792                         printf("reverse ARP request\n");
 9793                         break;
 9794                 case ARPOP_REVREPLY:
 9795                         printf("reverse ARP reply\n");
 9796                         break;
 9797                 case ARPOP_REQUEST:
 9798                         printf("ARP request\n");
 9799                         break;
 9800                 case ARPOP_REPLY:
 9801                         printf("ARP reply\n");
 9802                         break;
 9803                 default:
 9804                         printf("other ARP operation\n");
 9805                 }
 9806                 break;
 9807         default:
 9808                 BCE_PRINTF("----: Other protocol.\n");
 9809         }
 9810 
 9811         BCE_PRINTF(
 9812                 "-----------------------------"
 9813                 "--------------"
 9814                 "-----------------------------\n");
 9815 }
 9816 
 9817 
 9818 /****************************************************************************/
 9819 /* Prints out information about an mbuf.                                    */
 9820 /*                                                                          */
 9821 /* Returns:                                                                 */
 9822 /*   Nothing.                                                               */
 9823 /****************************************************************************/
 9824 static __attribute__ ((noinline)) void
 9825 bce_dump_mbuf(struct bce_softc *sc, struct mbuf *m)
 9826 {
 9827         struct mbuf *mp = m;
 9828 
 9829         if (m == NULL) {
 9830                 BCE_PRINTF("mbuf: null pointer\n");
 9831                 return;
 9832         }
 9833 
 9834         while (mp) {
 9835                 BCE_PRINTF("mbuf: %p, m_len = %d, m_flags = 0x%b, "
 9836                     "m_data = %p\n", mp, mp->m_len, mp->m_flags,
 9837                     "\2\1M_EXT\2M_PKTHDR\3M_EOR\4M_RDONLY", mp->m_data);
 9838 
 9839                 if (mp->m_flags & M_PKTHDR) {
 9840                         BCE_PRINTF("- m_pkthdr: len = %d, flags = 0x%b, "
 9841                             "csum_flags = %b\n", mp->m_pkthdr.len,
 9842                             mp->m_flags, M_FLAG_PRINTF,
 9843                             mp->m_pkthdr.csum_flags, CSUM_BITS);
 9844                 }
 9845 
 9846                 if (mp->m_flags & M_EXT) {
 9847                         BCE_PRINTF("- m_ext: %p, ext_size = %d, type = ",
 9848                             mp->m_ext.ext_buf, mp->m_ext.ext_size);
 9849                         switch (mp->m_ext.ext_type) {
 9850                         case EXT_CLUSTER:
 9851                                 printf("EXT_CLUSTER\n"); break;
 9852                         case EXT_SFBUF:
 9853                                 printf("EXT_SFBUF\n"); break;
 9854                         case EXT_JUMBO9:
 9855                                 printf("EXT_JUMBO9\n"); break;
 9856                         case EXT_JUMBO16:
 9857                                 printf("EXT_JUMBO16\n"); break;
 9858                         case EXT_PACKET:
 9859                                 printf("EXT_PACKET\n"); break;
 9860                         case EXT_MBUF:
 9861                                 printf("EXT_MBUF\n"); break;
 9862                         case EXT_NET_DRV:
 9863                                 printf("EXT_NET_DRV\n"); break;
 9864                         case EXT_MOD_TYPE:
 9865                                 printf("EXT_MDD_TYPE\n"); break;
 9866                         case EXT_DISPOSABLE:
 9867                                 printf("EXT_DISPOSABLE\n"); break;
 9868                         case EXT_EXTREF:
 9869                                 printf("EXT_EXTREF\n"); break;
 9870                         default:
 9871                                 printf("UNKNOWN\n");
 9872                         }
 9873                 }
 9874 
 9875                 mp = mp->m_next;
 9876         }
 9877 }
 9878 
 9879 
 9880 /****************************************************************************/
 9881 /* Prints out the mbufs in the TX mbuf chain.                               */
 9882 /*                                                                          */
 9883 /* Returns:                                                                 */
 9884 /*   Nothing.                                                               */
 9885 /****************************************************************************/
 9886 static __attribute__ ((noinline)) void
 9887 bce_dump_tx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
 9888 {
 9889         struct mbuf *m;
 9890 
 9891         BCE_PRINTF(
 9892                 "----------------------------"
 9893                 "  tx mbuf data  "
 9894                 "----------------------------\n");
 9895 
 9896         for (int i = 0; i < count; i++) {
 9897                 m = sc->tx_mbuf_ptr[chain_prod];
 9898                 BCE_PRINTF("txmbuf[0x%04X]\n", chain_prod);
 9899                 bce_dump_mbuf(sc, m);
 9900                 chain_prod = TX_CHAIN_IDX(NEXT_TX_BD(chain_prod));
 9901         }
 9902 
 9903         BCE_PRINTF(
 9904                 "----------------------------"
 9905                 "----------------"
 9906                 "----------------------------\n");
 9907 }
 9908 
 9909 
 9910 /****************************************************************************/
 9911 /* Prints out the mbufs in the RX mbuf chain.                               */
 9912 /*                                                                          */
 9913 /* Returns:                                                                 */
 9914 /*   Nothing.                                                               */
 9915 /****************************************************************************/
 9916 static __attribute__ ((noinline)) void
 9917 bce_dump_rx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
 9918 {
 9919         struct mbuf *m;
 9920 
 9921         BCE_PRINTF(
 9922                 "----------------------------"
 9923                 "  rx mbuf data  "
 9924                 "----------------------------\n");
 9925 
 9926         for (int i = 0; i < count; i++) {
 9927                 m = sc->rx_mbuf_ptr[chain_prod];
 9928                 BCE_PRINTF("rxmbuf[0x%04X]\n", chain_prod);
 9929                 bce_dump_mbuf(sc, m);
 9930                 chain_prod = RX_CHAIN_IDX(NEXT_RX_BD(chain_prod));
 9931         }
 9932 
 9933 
 9934         BCE_PRINTF(
 9935                 "----------------------------"
 9936                 "----------------"
 9937                 "----------------------------\n");
 9938 }
 9939 
 9940 
 9941 /****************************************************************************/
 9942 /* Prints out the mbufs in the mbuf page chain.                             */
 9943 /*                                                                          */
 9944 /* Returns:                                                                 */
 9945 /*   Nothing.                                                               */
 9946 /****************************************************************************/
 9947 static __attribute__ ((noinline)) void
 9948 bce_dump_pg_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count)
 9949 {
 9950         struct mbuf *m;
 9951 
 9952         BCE_PRINTF(
 9953                 "----------------------------"
 9954                 "  pg mbuf data  "
 9955                 "----------------------------\n");
 9956 
 9957         for (int i = 0; i < count; i++) {
 9958                 m = sc->pg_mbuf_ptr[chain_prod];
 9959                 BCE_PRINTF("pgmbuf[0x%04X]\n", chain_prod);
 9960                 bce_dump_mbuf(sc, m);
 9961                 chain_prod = PG_CHAIN_IDX(NEXT_PG_BD(chain_prod));
 9962         }
 9963 
 9964 
 9965         BCE_PRINTF(
 9966                 "----------------------------"
 9967                 "----------------"
 9968                 "----------------------------\n");
 9969 }
 9970 
 9971 
 9972 /****************************************************************************/
 9973 /* Prints out a tx_bd structure.                                            */
 9974 /*                                                                          */
 9975 /* Returns:                                                                 */
 9976 /*   Nothing.                                                               */
 9977 /****************************************************************************/
 9978 static __attribute__ ((noinline)) void
 9979 bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd)
 9980 {
 9981         int i = 0;
 9982 
 9983         if (idx > MAX_TX_BD_ALLOC)
 9984                 /* Index out of range. */
 9985                 BCE_PRINTF("tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
 9986         else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
 9987                 /* TX Chain page pointer. */
 9988                 BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
 9989                     "pointer\n", idx, txbd->tx_bd_haddr_hi,
 9990                     txbd->tx_bd_haddr_lo);
 9991         else {
 9992                 /* Normal tx_bd entry. */
 9993                 BCE_PRINTF("tx_bd[0x%04X]: haddr = 0x%08X:%08X, "
 9994                     "mss_nbytes = 0x%08X, vlan tag = 0x%04X, flags = "
 9995                     "0x%04X (", idx, txbd->tx_bd_haddr_hi,
 9996                     txbd->tx_bd_haddr_lo, txbd->tx_bd_mss_nbytes,
 9997                     txbd->tx_bd_vlan_tag, txbd->tx_bd_flags);
 9998 
 9999                 if (txbd->tx_bd_flags & TX_BD_FLAGS_CONN_FAULT) {
10000                         if (i>0)
10001                                 printf("|");
10002                         printf("CONN_FAULT");
10003                         i++;
10004                 }
10005 
10006                 if (txbd->tx_bd_flags & TX_BD_FLAGS_TCP_UDP_CKSUM) {
10007                         if (i>0)
10008                                 printf("|");
10009                         printf("TCP_UDP_CKSUM");
10010                         i++;
10011                 }
10012 
10013                 if (txbd->tx_bd_flags & TX_BD_FLAGS_IP_CKSUM) {
10014                         if (i>0)
10015                                 printf("|");
10016                         printf("IP_CKSUM");
10017                         i++;
10018                 }
10019 
10020                 if (txbd->tx_bd_flags & TX_BD_FLAGS_VLAN_TAG) {
10021                         if (i>0)
10022                                 printf("|");
10023                         printf("VLAN");
10024                         i++;
10025                 }
10026 
10027                 if (txbd->tx_bd_flags & TX_BD_FLAGS_COAL_NOW) {
10028                         if (i>0)
10029                                 printf("|");
10030                         printf("COAL_NOW");
10031                         i++;
10032                 }
10033 
10034                 if (txbd->tx_bd_flags & TX_BD_FLAGS_DONT_GEN_CRC) {
10035                         if (i>0)
10036                                 printf("|");
10037                         printf("DONT_GEN_CRC");
10038                         i++;
10039                 }
10040 
10041                 if (txbd->tx_bd_flags & TX_BD_FLAGS_START) {
10042                         if (i>0)
10043                                 printf("|");
10044                         printf("START");
10045                         i++;
10046                 }
10047 
10048                 if (txbd->tx_bd_flags & TX_BD_FLAGS_END) {
10049                         if (i>0)
10050                                 printf("|");
10051                         printf("END");
10052                         i++;
10053                 }
10054 
10055                 if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_LSO) {
10056                         if (i>0)
10057                                 printf("|");
10058                         printf("LSO");
10059                         i++;
10060                 }
10061 
10062                 if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_OPTION_WORD) {
10063                         if (i>0)
10064                                 printf("|");
10065                         printf("SW_OPTION=%d", ((txbd->tx_bd_flags &
10066                             TX_BD_FLAGS_SW_OPTION_WORD) >> 8)); i++;
10067                 }
10068 
10069                 if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_FLAGS) {
10070                         if (i>0)
10071                                 printf("|");
10072                         printf("SW_FLAGS");
10073                         i++;
10074                 }
10075 
10076                 if (txbd->tx_bd_flags & TX_BD_FLAGS_SW_SNAP) {
10077                         if (i>0)
10078                                 printf("|");
10079                         printf("SNAP)");
10080                 } else {
10081                         printf(")\n");
10082                 }
10083         }
10084 }
10085 
10086 
10087 /****************************************************************************/
10088 /* Prints out a rx_bd structure.                                            */
10089 /*                                                                          */
10090 /* Returns:                                                                 */
10091 /*   Nothing.                                                               */
10092 /****************************************************************************/
10093 static __attribute__ ((noinline)) void
10094 bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd)
10095 {
10096         if (idx > MAX_RX_BD_ALLOC)
10097                 /* Index out of range. */
10098                 BCE_PRINTF("rx_bd[0x%04X]: Invalid rx_bd index!\n", idx);
10099         else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
10100                 /* RX Chain page pointer. */
10101                 BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
10102                     "pointer\n", idx, rxbd->rx_bd_haddr_hi,
10103                     rxbd->rx_bd_haddr_lo);
10104         else
10105                 /* Normal rx_bd entry. */
10106                 BCE_PRINTF("rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = "
10107                     "0x%08X, flags = 0x%08X\n", idx, rxbd->rx_bd_haddr_hi,
10108                     rxbd->rx_bd_haddr_lo, rxbd->rx_bd_len,
10109                     rxbd->rx_bd_flags);
10110 }
10111 
10112 
10113 /****************************************************************************/
10114 /* Prints out a rx_bd structure in the page chain.                          */
10115 /*                                                                          */
10116 /* Returns:                                                                 */
10117 /*   Nothing.                                                               */
10118 /****************************************************************************/
10119 static __attribute__ ((noinline)) void
10120 bce_dump_pgbd(struct bce_softc *sc, int idx, struct rx_bd *pgbd)
10121 {
10122         if (idx > MAX_PG_BD_ALLOC)
10123                 /* Index out of range. */
10124                 BCE_PRINTF("pg_bd[0x%04X]: Invalid pg_bd index!\n", idx);
10125         else if ((idx & USABLE_PG_BD_PER_PAGE) == USABLE_PG_BD_PER_PAGE)
10126                 /* Page Chain page pointer. */
10127                 BCE_PRINTF("px_bd[0x%04X]: haddr = 0x%08X:%08X, chain page pointer\n",
10128                         idx, pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo);
10129         else
10130                 /* Normal rx_bd entry. */
10131                 BCE_PRINTF("pg_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = 0x%08X, "
10132                         "flags = 0x%08X\n", idx,
10133                         pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo,
10134                         pgbd->rx_bd_len, pgbd->rx_bd_flags);
10135 }
10136 
10137 
10138 /****************************************************************************/
10139 /* Prints out a l2_fhdr structure.                                          */
10140 /*                                                                          */
10141 /* Returns:                                                                 */
10142 /*   Nothing.                                                               */
10143 /****************************************************************************/
10144 static __attribute__ ((noinline)) void
10145 bce_dump_l2fhdr(struct bce_softc *sc, int idx, struct l2_fhdr *l2fhdr)
10146 {
10147         BCE_PRINTF("l2_fhdr[0x%04X]: status = 0x%b, "
10148                 "pkt_len = %d, vlan = 0x%04x, ip_xsum/hdr_len = 0x%04X, "
10149                 "tcp_udp_xsum = 0x%04X\n", idx,
10150                 l2fhdr->l2_fhdr_status, BCE_L2FHDR_PRINTFB,
10151                 l2fhdr->l2_fhdr_pkt_len, l2fhdr->l2_fhdr_vlan_tag,
10152                 l2fhdr->l2_fhdr_ip_xsum, l2fhdr->l2_fhdr_tcp_udp_xsum);
10153 }
10154 
10155 
10156 /****************************************************************************/
10157 /* Prints out context memory info.  (Only useful for CID 0 to 16.)          */
10158 /*                                                                          */
10159 /* Returns:                                                                 */
10160 /*   Nothing.                                                               */
10161 /****************************************************************************/
10162 static __attribute__ ((noinline)) void
10163 bce_dump_ctx(struct bce_softc *sc, u16 cid)
10164 {
10165         if (cid > TX_CID) {
10166                 BCE_PRINTF(" Unknown CID\n");
10167                 return;
10168         }
10169 
10170         BCE_PRINTF(
10171             "----------------------------"
10172             "    CTX Data    "
10173             "----------------------------\n");
10174 
10175         BCE_PRINTF("     0x%04X - (CID) Context ID\n", cid);
10176 
10177         if (cid == RX_CID) {
10178                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BDIDX) host rx "
10179                    "producer index\n",
10180                     CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_HOST_BDIDX));
10181                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_BSEQ) host "
10182                     "byte sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
10183                     BCE_L2CTX_RX_HOST_BSEQ));
10184                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BSEQ) h/w byte sequence\n",
10185                     CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BSEQ));
10186                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_HI) h/w buffer "
10187                     "descriptor address\n",
10188                     CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_HI));
10189                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDHADDR_LO) h/w buffer "
10190                     "descriptor address\n",
10191                     CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_RX_NX_BDHADDR_LO));
10192                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_BDIDX) h/w rx consumer "
10193                     "index\n", CTX_RD(sc, GET_CID_ADDR(cid),
10194                     BCE_L2CTX_RX_NX_BDIDX));
10195                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_HOST_PG_BDIDX) host page "
10196                     "producer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
10197                     BCE_L2CTX_RX_HOST_PG_BDIDX));
10198                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_PG_BUF_SIZE) host rx_bd/page "
10199                     "buffer size\n", CTX_RD(sc, GET_CID_ADDR(cid),
10200                     BCE_L2CTX_RX_PG_BUF_SIZE));
10201                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_HI) h/w page "
10202                     "chain address\n", CTX_RD(sc, GET_CID_ADDR(cid),
10203                     BCE_L2CTX_RX_NX_PG_BDHADDR_HI));
10204                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDHADDR_LO) h/w page "
10205                     "chain address\n", CTX_RD(sc, GET_CID_ADDR(cid),
10206                     BCE_L2CTX_RX_NX_PG_BDHADDR_LO));
10207                 BCE_PRINTF(" 0x%08X - (L2CTX_RX_NX_PG_BDIDX) h/w page "
10208                     "consumer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
10209                     BCE_L2CTX_RX_NX_PG_BDIDX));
10210         } else if (cid == TX_CID) {
10211                 if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
10212                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE_XI) ctx type\n",
10213                             CTX_RD(sc, GET_CID_ADDR(cid),
10214                             BCE_L2CTX_TX_TYPE_XI));
10215                         BCE_PRINTF(" 0x%08X - (L2CTX_CMD_TX_TYPE_XI) ctx "
10216                             "cmd\n", CTX_RD(sc, GET_CID_ADDR(cid),
10217                             BCE_L2CTX_TX_CMD_TYPE_XI));
10218                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI_XI) "
10219                             "h/w buffer descriptor address\n",
10220                             CTX_RD(sc, GET_CID_ADDR(cid),
10221                             BCE_L2CTX_TX_TBDR_BHADDR_HI_XI));
10222                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO_XI) "
10223                             "h/w buffer descriptor address\n",
10224                             CTX_RD(sc, GET_CID_ADDR(cid),
10225                             BCE_L2CTX_TX_TBDR_BHADDR_LO_XI));
10226                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX_XI) "
10227                             "host producer index\n",
10228                             CTX_RD(sc, GET_CID_ADDR(cid),
10229                             BCE_L2CTX_TX_HOST_BIDX_XI));
10230                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ_XI) "
10231                             "host byte sequence\n",
10232                             CTX_RD(sc, GET_CID_ADDR(cid),
10233                             BCE_L2CTX_TX_HOST_BSEQ_XI));
10234                 } else {
10235                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_TYPE) ctx type\n",
10236                             CTX_RD(sc, GET_CID_ADDR(cid), BCE_L2CTX_TX_TYPE));
10237                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_CMD_TYPE) ctx cmd\n",
10238                             CTX_RD(sc, GET_CID_ADDR(cid),
10239                             BCE_L2CTX_TX_CMD_TYPE));
10240                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BDHADDR_HI) "
10241                             "h/w buffer descriptor address\n",
10242                             CTX_RD(sc, GET_CID_ADDR(cid),
10243                             BCE_L2CTX_TX_TBDR_BHADDR_HI));
10244                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_TBDR_BHADDR_LO) "
10245                             "h/w buffer descriptor address\n",
10246                             CTX_RD(sc, GET_CID_ADDR(cid),
10247                             BCE_L2CTX_TX_TBDR_BHADDR_LO));
10248                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BIDX) host "
10249                             "producer index\n", CTX_RD(sc, GET_CID_ADDR(cid),
10250                             BCE_L2CTX_TX_HOST_BIDX));
10251                         BCE_PRINTF(" 0x%08X - (L2CTX_TX_HOST_BSEQ) host byte "
10252                             "sequence\n", CTX_RD(sc, GET_CID_ADDR(cid),
10253                             BCE_L2CTX_TX_HOST_BSEQ));
10254                 }
10255         }
10256 
10257         BCE_PRINTF(
10258            "----------------------------"
10259            "    Raw CTX     "
10260            "----------------------------\n");
10261 
10262         for (int i = 0x0; i < 0x300; i += 0x10) {
10263                 BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n", i,
10264                    CTX_RD(sc, GET_CID_ADDR(cid), i),
10265                    CTX_RD(sc, GET_CID_ADDR(cid), i + 0x4),
10266                    CTX_RD(sc, GET_CID_ADDR(cid), i + 0x8),
10267                    CTX_RD(sc, GET_CID_ADDR(cid), i + 0xc));
10268         }
10269 
10270 
10271         BCE_PRINTF(
10272            "----------------------------"
10273            "----------------"
10274            "----------------------------\n");
10275 }
10276 
10277 
10278 /****************************************************************************/
10279 /* Prints out the FTQ data.                                                 */
10280 /*                                                                          */
10281 /* Returns:                                                                */
10282 /*   Nothing.                                                               */
10283 /****************************************************************************/
10284 static __attribute__ ((noinline)) void
10285 bce_dump_ftqs(struct bce_softc *sc)
10286 {
10287         u32 cmd, ctl, cur_depth, max_depth, valid_cnt, val;
10288 
10289         BCE_PRINTF(
10290             "----------------------------"
10291             "    FTQ Data    "
10292             "----------------------------\n");
10293 
10294         BCE_PRINTF("   FTQ    Command    Control   Depth_Now  "
10295             "Max_Depth  Valid_Cnt \n");
10296         BCE_PRINTF(" ------- ---------- ---------- ---------- "
10297             "---------- ----------\n");
10298 
10299         /* Setup the generic statistic counters for the FTQ valid count. */
10300         val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PPQ_VALID_CNT << 24) |
10301             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPCQ_VALID_CNT  << 16) |
10302             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RXPQ_VALID_CNT   <<  8) |
10303             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RLUPQ_VALID_CNT);
10304         REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
10305 
10306         val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TSCHQ_VALID_CNT  << 24) |
10307             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RDMAQ_VALID_CNT  << 16) |
10308             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PTQ_VALID_CNT <<  8) |
10309             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PMQ_VALID_CNT);
10310         REG_WR(sc, BCE_HC_STAT_GEN_SEL_1, val);
10311 
10312         val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TPATQ_VALID_CNT  << 24) |
10313             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TDMAQ_VALID_CNT  << 16) |
10314             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TXPQ_VALID_CNT   <<  8) |
10315             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TBDRQ_VALID_CNT);
10316         REG_WR(sc, BCE_HC_STAT_GEN_SEL_2, val);
10317 
10318         val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMQ_VALID_CNT   << 24) |
10319             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMTQ_VALID_CNT  << 16) |
10320             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_COMXQ_VALID_CNT  <<  8) |
10321             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_TASQ_VALID_CNT);
10322         REG_WR(sc, BCE_HC_STAT_GEN_SEL_3, val);
10323 
10324         /* Input queue to the Receive Lookup state machine */
10325         cmd = REG_RD(sc, BCE_RLUP_FTQ_CMD);
10326         ctl = REG_RD(sc, BCE_RLUP_FTQ_CTL);
10327         cur_depth = (ctl & BCE_RLUP_FTQ_CTL_CUR_DEPTH) >> 22;
10328         max_depth = (ctl & BCE_RLUP_FTQ_CTL_MAX_DEPTH) >> 12;
10329         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
10330         BCE_PRINTF(" RLUP    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10331             cmd, ctl, cur_depth, max_depth, valid_cnt);
10332 
10333         /* Input queue to the Receive Processor */
10334         cmd = REG_RD_IND(sc, BCE_RXP_FTQ_CMD);
10335         ctl = REG_RD_IND(sc, BCE_RXP_FTQ_CTL);
10336         cur_depth = (ctl & BCE_RXP_FTQ_CTL_CUR_DEPTH) >> 22;
10337         max_depth = (ctl & BCE_RXP_FTQ_CTL_MAX_DEPTH) >> 12;
10338         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
10339         BCE_PRINTF(" RXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10340             cmd, ctl, cur_depth, max_depth, valid_cnt);
10341 
10342         /* Input queue to the Recevie Processor */
10343         cmd = REG_RD_IND(sc, BCE_RXP_CFTQ_CMD);
10344         ctl = REG_RD_IND(sc, BCE_RXP_CFTQ_CTL);
10345         cur_depth = (ctl & BCE_RXP_CFTQ_CTL_CUR_DEPTH) >> 22;
10346         max_depth = (ctl & BCE_RXP_CFTQ_CTL_MAX_DEPTH) >> 12;
10347         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
10348         BCE_PRINTF(" RXPC    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10349             cmd, ctl, cur_depth, max_depth, valid_cnt);
10350 
10351         /* Input queue to the Receive Virtual to Physical state machine */
10352         cmd = REG_RD(sc, BCE_RV2P_PFTQ_CMD);
10353         ctl = REG_RD(sc, BCE_RV2P_PFTQ_CTL);
10354         cur_depth = (ctl & BCE_RV2P_PFTQ_CTL_CUR_DEPTH) >> 22;
10355         max_depth = (ctl & BCE_RV2P_PFTQ_CTL_MAX_DEPTH) >> 12;
10356         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
10357         BCE_PRINTF(" RV2PP   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10358             cmd, ctl, cur_depth, max_depth, valid_cnt);
10359 
10360         /* Input queue to the Recevie Virtual to Physical state machine */
10361         cmd = REG_RD(sc, BCE_RV2P_MFTQ_CMD);
10362         ctl = REG_RD(sc, BCE_RV2P_MFTQ_CTL);
10363         cur_depth = (ctl & BCE_RV2P_MFTQ_CTL_CUR_DEPTH) >> 22;
10364         max_depth = (ctl & BCE_RV2P_MFTQ_CTL_MAX_DEPTH) >> 12;
10365         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT4);
10366         BCE_PRINTF(" RV2PM   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10367             cmd, ctl, cur_depth, max_depth, valid_cnt);
10368 
10369         /* Input queue to the Receive Virtual to Physical state machine */
10370         cmd = REG_RD(sc, BCE_RV2P_TFTQ_CMD);
10371         ctl = REG_RD(sc, BCE_RV2P_TFTQ_CTL);
10372         cur_depth = (ctl & BCE_RV2P_TFTQ_CTL_CUR_DEPTH) >> 22;
10373         max_depth = (ctl & BCE_RV2P_TFTQ_CTL_MAX_DEPTH) >> 12;
10374         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT5);
10375         BCE_PRINTF(" RV2PT   0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10376             cmd, ctl, cur_depth, max_depth, valid_cnt);
10377 
10378         /* Input queue to the Receive DMA state machine */
10379         cmd = REG_RD(sc, BCE_RDMA_FTQ_CMD);
10380         ctl = REG_RD(sc, BCE_RDMA_FTQ_CTL);
10381         cur_depth = (ctl & BCE_RDMA_FTQ_CTL_CUR_DEPTH) >> 22;
10382         max_depth = (ctl & BCE_RDMA_FTQ_CTL_MAX_DEPTH) >> 12;
10383         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT6);
10384         BCE_PRINTF(" RDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10385             cmd, ctl, cur_depth, max_depth, valid_cnt);
10386 
10387         /* Input queue to the Transmit Scheduler state machine */
10388         cmd = REG_RD(sc, BCE_TSCH_FTQ_CMD);
10389         ctl = REG_RD(sc, BCE_TSCH_FTQ_CTL);
10390         cur_depth = (ctl & BCE_TSCH_FTQ_CTL_CUR_DEPTH) >> 22;
10391         max_depth = (ctl & BCE_TSCH_FTQ_CTL_MAX_DEPTH) >> 12;
10392         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT7);
10393         BCE_PRINTF(" TSCH    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10394             cmd, ctl, cur_depth, max_depth, valid_cnt);
10395 
10396         /* Input queue to the Transmit Buffer Descriptor state machine */
10397         cmd = REG_RD(sc, BCE_TBDR_FTQ_CMD);
10398         ctl = REG_RD(sc, BCE_TBDR_FTQ_CTL);
10399         cur_depth = (ctl & BCE_TBDR_FTQ_CTL_CUR_DEPTH) >> 22;
10400         max_depth = (ctl & BCE_TBDR_FTQ_CTL_MAX_DEPTH) >> 12;
10401         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT8);
10402         BCE_PRINTF(" TBDR    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10403             cmd, ctl, cur_depth, max_depth, valid_cnt);
10404 
10405         /* Input queue to the Transmit Processor */
10406         cmd = REG_RD_IND(sc, BCE_TXP_FTQ_CMD);
10407         ctl = REG_RD_IND(sc, BCE_TXP_FTQ_CTL);
10408         cur_depth = (ctl & BCE_TXP_FTQ_CTL_CUR_DEPTH) >> 22;
10409         max_depth = (ctl & BCE_TXP_FTQ_CTL_MAX_DEPTH) >> 12;
10410         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT9);
10411         BCE_PRINTF(" TXP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10412             cmd, ctl, cur_depth, max_depth, valid_cnt);
10413 
10414         /* Input queue to the Transmit DMA state machine */
10415         cmd = REG_RD(sc, BCE_TDMA_FTQ_CMD);
10416         ctl = REG_RD(sc, BCE_TDMA_FTQ_CTL);
10417         cur_depth = (ctl & BCE_TDMA_FTQ_CTL_CUR_DEPTH) >> 22;
10418         max_depth = (ctl & BCE_TDMA_FTQ_CTL_MAX_DEPTH) >> 12;
10419         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT10);
10420         BCE_PRINTF(" TDMA    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10421             cmd, ctl, cur_depth, max_depth, valid_cnt);
10422 
10423         /* Input queue to the Transmit Patch-Up Processor */
10424         cmd = REG_RD_IND(sc, BCE_TPAT_FTQ_CMD);
10425         ctl = REG_RD_IND(sc, BCE_TPAT_FTQ_CTL);
10426         cur_depth = (ctl & BCE_TPAT_FTQ_CTL_CUR_DEPTH) >> 22;
10427         max_depth = (ctl & BCE_TPAT_FTQ_CTL_MAX_DEPTH) >> 12;
10428         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT11);
10429         BCE_PRINTF(" TPAT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10430             cmd, ctl, cur_depth, max_depth, valid_cnt);
10431 
10432         /* Input queue to the Transmit Assembler state machine */
10433         cmd = REG_RD_IND(sc, BCE_TAS_FTQ_CMD);
10434         ctl = REG_RD_IND(sc, BCE_TAS_FTQ_CTL);
10435         cur_depth = (ctl & BCE_TAS_FTQ_CTL_CUR_DEPTH) >> 22;
10436         max_depth = (ctl & BCE_TAS_FTQ_CTL_MAX_DEPTH) >> 12;
10437         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT12);
10438         BCE_PRINTF(" TAS     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10439             cmd, ctl, cur_depth, max_depth, valid_cnt);
10440 
10441         /* Input queue to the Completion Processor */
10442         cmd = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CMD);
10443         ctl = REG_RD_IND(sc, BCE_COM_COMXQ_FTQ_CTL);
10444         cur_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_CUR_DEPTH) >> 22;
10445         max_depth = (ctl & BCE_COM_COMXQ_FTQ_CTL_MAX_DEPTH) >> 12;
10446         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT13);
10447         BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10448             cmd, ctl, cur_depth, max_depth, valid_cnt);
10449 
10450         /* Input queue to the Completion Processor */
10451         cmd = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CMD);
10452         ctl = REG_RD_IND(sc, BCE_COM_COMTQ_FTQ_CTL);
10453         cur_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_CUR_DEPTH) >> 22;
10454         max_depth = (ctl & BCE_COM_COMTQ_FTQ_CTL_MAX_DEPTH) >> 12;
10455         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT14);
10456         BCE_PRINTF(" COMT    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10457             cmd, ctl, cur_depth, max_depth, valid_cnt);
10458 
10459         /* Input queue to the Completion Processor */
10460         cmd = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CMD);
10461         ctl = REG_RD_IND(sc, BCE_COM_COMQ_FTQ_CTL);
10462         cur_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_CUR_DEPTH) >> 22;
10463         max_depth = (ctl & BCE_COM_COMQ_FTQ_CTL_MAX_DEPTH) >> 12;
10464         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT15);
10465         BCE_PRINTF(" COMX    0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10466             cmd, ctl, cur_depth, max_depth, valid_cnt);
10467 
10468         /* Setup the generic statistic counters for the FTQ valid count. */
10469         val = (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CSQ_VALID_CNT  << 16) |
10470             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_CPQ_VALID_CNT  <<  8) |
10471             (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_MGMQ_VALID_CNT);
10472 
10473         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709)
10474                 val = val |
10475                     (BCE_HC_STAT_GEN_SEL_0_GEN_SEL_0_RV2PCSQ_VALID_CNT_XI <<
10476                      24);
10477         REG_WR(sc, BCE_HC_STAT_GEN_SEL_0, val);
10478 
10479         /* Input queue to the Management Control Processor */
10480         cmd = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CMD);
10481         ctl = REG_RD_IND(sc, BCE_MCP_MCPQ_FTQ_CTL);
10482         cur_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_CUR_DEPTH) >> 22;
10483         max_depth = (ctl & BCE_MCP_MCPQ_FTQ_CTL_MAX_DEPTH) >> 12;
10484         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT0);
10485         BCE_PRINTF(" MCP     0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10486             cmd, ctl, cur_depth, max_depth, valid_cnt);
10487 
10488         /* Input queue to the Command Processor */
10489         cmd = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CMD);
10490         ctl = REG_RD_IND(sc, BCE_CP_CPQ_FTQ_CTL);
10491         cur_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_CUR_DEPTH) >> 22;
10492         max_depth = (ctl & BCE_CP_CPQ_FTQ_CTL_MAX_DEPTH) >> 12;
10493         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT1);
10494         BCE_PRINTF(" CP      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10495             cmd, ctl, cur_depth, max_depth, valid_cnt);
10496 
10497         /* Input queue to the Completion Scheduler state machine */
10498         cmd = REG_RD(sc, BCE_CSCH_CH_FTQ_CMD);
10499         ctl = REG_RD(sc, BCE_CSCH_CH_FTQ_CTL);
10500         cur_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_CUR_DEPTH) >> 22;
10501         max_depth = (ctl & BCE_CSCH_CH_FTQ_CTL_MAX_DEPTH) >> 12;
10502         valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT2);
10503         BCE_PRINTF(" CS      0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10504             cmd, ctl, cur_depth, max_depth, valid_cnt);
10505 
10506         if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) {
10507                 /* Input queue to the RV2P Command Scheduler */
10508                 cmd = REG_RD(sc, BCE_RV2PCSR_FTQ_CMD);
10509                 ctl = REG_RD(sc, BCE_RV2PCSR_FTQ_CTL);
10510                 cur_depth = (ctl & 0xFFC00000) >> 22;
10511                 max_depth = (ctl & 0x003FF000) >> 12;
10512                 valid_cnt = REG_RD(sc, BCE_HC_STAT_GEN_STAT3);
10513                 BCE_PRINTF(" RV2PCSR 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X\n",
10514                     cmd, ctl, cur_depth, max_depth, valid_cnt);
10515         }
10516 
10517         BCE_PRINTF(
10518             "----------------------------"
10519             "----------------"
10520             "----------------------------\n");
10521 }
10522 
10523 
10524 /****************************************************************************/
10525 /* Prints out the TX chain.                                                 */
10526 /*                                                                          */
10527 /* Returns:                                                                 */
10528 /*   Nothing.                                                               */
10529 /****************************************************************************/
10530 static __attribute__ ((noinline)) void
10531 bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count)
10532 {
10533         struct tx_bd *txbd;
10534 
10535         /* First some info about the tx_bd chain structure. */
10536         BCE_PRINTF(
10537             "----------------------------"
10538             "  tx_bd  chain  "
10539             "----------------------------\n");
10540 
10541         BCE_PRINTF("page size      = 0x%08X, tx chain pages        = 0x%08X\n",
10542             (u32) BCM_PAGE_SIZE, (u32) sc->tx_pages);
10543         BCE_PRINTF("tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
10544             (u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE);
10545         BCE_PRINTF("total tx_bd    = 0x%08X\n", (u32) TOTAL_TX_BD_ALLOC);
10546 
10547         BCE_PRINTF(
10548             "----------------------------"
10549             "   tx_bd data   "
10550             "----------------------------\n");
10551 
10552         /* Now print out a decoded list of TX buffer descriptors. */
10553         for (int i = 0; i < count; i++) {
10554                 txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
10555                 bce_dump_txbd(sc, tx_prod, txbd);
10556                 tx_prod++;
10557         }
10558 
10559         BCE_PRINTF(
10560             "----------------------------"
10561             "----------------"
10562             "----------------------------\n");
10563 }
10564 
10565 
10566 /****************************************************************************/
10567 /* Prints out the RX chain.                                                 */
10568 /*                                                                          */
10569 /* Returns:                                                                 */
10570 /*   Nothing.                                                               */
10571 /****************************************************************************/
10572 static __attribute__ ((noinline)) void
10573 bce_dump_rx_bd_chain(struct bce_softc *sc, u16 rx_prod, int count)
10574 {
10575         struct rx_bd *rxbd;
10576 
10577         /* First some info about the rx_bd chain structure. */
10578         BCE_PRINTF(
10579             "----------------------------"
10580             "  rx_bd  chain  "
10581             "----------------------------\n");
10582 
10583         BCE_PRINTF("page size      = 0x%08X, rx chain pages        = 0x%08X\n",
10584             (u32) BCM_PAGE_SIZE, (u32) sc->rx_pages);
10585 
10586         BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
10587             (u32) TOTAL_RX_BD_PER_PAGE, (u32) USABLE_RX_BD_PER_PAGE);
10588 
10589         BCE_PRINTF("total rx_bd    = 0x%08X\n", (u32) TOTAL_RX_BD_ALLOC);
10590 
10591         BCE_PRINTF(
10592             "----------------------------"
10593             "   rx_bd data   "
10594             "----------------------------\n");
10595 
10596         /* Now print out the rx_bd's themselves. */
10597         for (int i = 0; i < count; i++) {
10598                 rxbd = &sc->rx_bd_chain[RX_PAGE(rx_prod)][RX_IDX(rx_prod)];
10599                 bce_dump_rxbd(sc, rx_prod, rxbd);
10600                 rx_prod = RX_CHAIN_IDX(rx_prod + 1);
10601         }
10602 
10603         BCE_PRINTF(
10604             "----------------------------"
10605             "----------------"
10606             "----------------------------\n");
10607 }
10608 
10609 
10610 /****************************************************************************/
10611 /* Prints out the page chain.                                               */
10612 /*                                                                          */
10613 /* Returns:                                                                 */
10614 /*   Nothing.                                                               */
10615 /****************************************************************************/
10616 static __attribute__ ((noinline)) void
10617 bce_dump_pg_chain(struct bce_softc *sc, u16 pg_prod, int count)
10618 {
10619         struct rx_bd *pgbd;
10620 
10621         /* First some info about the page chain structure. */
10622         BCE_PRINTF(
10623             "----------------------------"
10624             "   page chain   "
10625             "----------------------------\n");
10626 
10627         BCE_PRINTF("page size      = 0x%08X, pg chain pages        = 0x%08X\n",
10628             (u32) BCM_PAGE_SIZE, (u32) sc->pg_pages);
10629 
10630         BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
10631             (u32) TOTAL_PG_BD_PER_PAGE, (u32) USABLE_PG_BD_PER_PAGE);
10632 
10633         BCE_PRINTF("total pg_bd             = 0x%08X\n", (u32) TOTAL_PG_BD_ALLOC);
10634 
10635         BCE_PRINTF(
10636             "----------------------------"
10637             "   page data    "
10638             "----------------------------\n");
10639 
10640         /* Now print out the rx_bd's themselves. */
10641         for (int i = 0; i < count; i++) {
10642                 pgbd = &sc->pg_bd_chain[PG_PAGE(pg_prod)][PG_IDX(pg_prod)];
10643                 bce_dump_pgbd(sc, pg_prod, pgbd);
10644                 pg_prod = PG_CHAIN_IDX(pg_prod + 1);
10645         }
10646 
10647         BCE_PRINTF(
10648             "----------------------------"
10649             "----------------"
10650             "----------------------------\n");
10651 }
10652 
10653 
10654 #define BCE_PRINT_RX_CONS(arg)                                          \
10655 if (sblk->status_rx_quick_consumer_index##arg)                          \
10656         BCE_PRINTF("0x%04X(0x%04X) - rx_quick_consumer_index%d\n",      \
10657             sblk->status_rx_quick_consumer_index##arg, (u16)            \
10658             RX_CHAIN_IDX(sblk->status_rx_quick_consumer_index##arg),    \
10659             arg);
10660 
10661 
10662 #define BCE_PRINT_TX_CONS(arg)                                          \
10663 if (sblk->status_tx_quick_consumer_index##arg)                          \
10664         BCE_PRINTF("0x%04X(0x%04X) - tx_quick_consumer_index%d\n",      \
10665             sblk->status_tx_quick_consumer_index##arg, (u16)            \
10666             TX_CHAIN_IDX(sblk->status_tx_quick_consumer_index##arg),    \
10667             arg);
10668 
10669 /****************************************************************************/
10670 /* Prints out the status block from host memory.                            */
10671 /*                                                                          */
10672 /* Returns:                                                                 */
10673 /*   Nothing.                                                               */
10674 /****************************************************************************/
10675 static __attribute__ ((noinline)) void
10676 bce_dump_status_block(struct bce_softc *sc)
10677 {
10678         struct status_block *sblk;
10679 
10680         bus_dmamap_sync(sc->status_tag, sc->status_map, BUS_DMASYNC_POSTREAD);
10681 
10682         sblk = sc->status_block;
10683 
10684         BCE_PRINTF(
10685             "----------------------------"
10686             "  Status Block  "
10687             "----------------------------\n");
10688 
10689         /* Theses indices are used for normal L2 drivers. */
10690         BCE_PRINTF("    0x%08X - attn_bits\n",
10691             sblk->status_attn_bits);
10692 
10693         BCE_PRINTF("    0x%08X - attn_bits_ack\n",
10694             sblk->status_attn_bits_ack);
10695 
10696         BCE_PRINT_RX_CONS(0);
10697         BCE_PRINT_TX_CONS(0)
10698 
10699         BCE_PRINTF("        0x%04X - status_idx\n", sblk->status_idx);
10700 
10701         /* Theses indices are not used for normal L2 drivers. */
10702         BCE_PRINT_RX_CONS(1);   BCE_PRINT_RX_CONS(2);   BCE_PRINT_RX_CONS(3);
10703         BCE_PRINT_RX_CONS(4);   BCE_PRINT_RX_CONS(5);   BCE_PRINT_RX_CONS(6);
10704         BCE_PRINT_RX_CONS(7);   BCE_PRINT_RX_CONS(8);   BCE_PRINT_RX_CONS(9);
10705         BCE_PRINT_RX_CONS(10);  BCE_PRINT_RX_CONS(11);  BCE_PRINT_RX_CONS(12);
10706         BCE_PRINT_RX_CONS(13);  BCE_PRINT_RX_CONS(14);  BCE_PRINT_RX_CONS(15);
10707 
10708         BCE_PRINT_TX_CONS(1);   BCE_PRINT_TX_CONS(2);   BCE_PRINT_TX_CONS(3);
10709 
10710         if (sblk->status_completion_producer_index ||
10711             sblk->status_cmd_consumer_index)
10712                 BCE_PRINTF("com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
10713                     sblk->status_completion_producer_index,
10714                     sblk->status_cmd_consumer_index);
10715 
10716         BCE_PRINTF(
10717             "----------------------------"
10718             "----------------"
10719             "----------------------------\n");
10720 }
10721 
10722 
10723 #define BCE_PRINT_64BIT_STAT(arg)                               \
10724 if (sblk->arg##_lo || sblk->arg##_hi)                           \
10725         BCE_PRINTF("0x%08X:%08X : %s\n", sblk->arg##_hi,        \
10726             sblk->arg##_lo, #arg);
10727 
10728 #define BCE_PRINT_32BIT_STAT(arg)                               \
10729 if (sblk->arg)                                                  \
10730         BCE_PRINTF("         0x%08X : %s\n",                    \
10731             sblk->arg, #arg);
10732 
10733 /****************************************************************************/
10734 /* Prints out the statistics block from host memory.                        */
10735 /*                                                                          */
10736 /* Returns:                                                                 */
10737 /*   Nothing.                                                               */
10738 /****************************************************************************/
10739 static __attribute__ ((noinline)) void
10740 bce_dump_stats_block(struct bce_softc *sc)
10741 {
10742         struct statistics_block *sblk;
10743 
10744         bus_dmamap_sync(sc->stats_tag, sc->stats_map, BUS_DMASYNC_POSTREAD);
10745 
10746         sblk = sc->stats_block;
10747 
10748         BCE_PRINTF(
10749             "---------------"
10750             " Stats Block  (All Stats Not Shown Are 0) "
10751             "---------------\n");
10752 
10753         BCE_PRINT_64BIT_STAT(stat_IfHCInOctets);
10754         BCE_PRINT_64BIT_STAT(stat_IfHCInBadOctets);
10755         BCE_PRINT_64BIT_STAT(stat_IfHCOutOctets);
10756         BCE_PRINT_64BIT_STAT(stat_IfHCOutBadOctets);
10757         BCE_PRINT_64BIT_STAT(stat_IfHCInUcastPkts);
10758         BCE_PRINT_64BIT_STAT(stat_IfHCInBroadcastPkts);
10759         BCE_PRINT_64BIT_STAT(stat_IfHCInMulticastPkts);
10760         BCE_PRINT_64BIT_STAT(stat_IfHCOutUcastPkts);
10761         BCE_PRINT_64BIT_STAT(stat_IfHCOutBroadcastPkts);
10762         BCE_PRINT_64BIT_STAT(stat_IfHCOutMulticastPkts);
10763         BCE_PRINT_32BIT_STAT(
10764             stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
10765         BCE_PRINT_32BIT_STAT(stat_Dot3StatsCarrierSenseErrors);
10766         BCE_PRINT_32BIT_STAT(stat_Dot3StatsFCSErrors);
10767         BCE_PRINT_32BIT_STAT(stat_Dot3StatsAlignmentErrors);
10768         BCE_PRINT_32BIT_STAT(stat_Dot3StatsSingleCollisionFrames);
10769         BCE_PRINT_32BIT_STAT(stat_Dot3StatsMultipleCollisionFrames);
10770         BCE_PRINT_32BIT_STAT(stat_Dot3StatsDeferredTransmissions);
10771         BCE_PRINT_32BIT_STAT(stat_Dot3StatsExcessiveCollisions);
10772         BCE_PRINT_32BIT_STAT(stat_Dot3StatsLateCollisions);
10773         BCE_PRINT_32BIT_STAT(stat_EtherStatsCollisions);
10774         BCE_PRINT_32BIT_STAT(stat_EtherStatsFragments);
10775         BCE_PRINT_32BIT_STAT(stat_EtherStatsJabbers);
10776         BCE_PRINT_32BIT_STAT(stat_EtherStatsUndersizePkts);
10777         BCE_PRINT_32BIT_STAT(stat_EtherStatsOversizePkts);
10778         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx64Octets);
10779         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx65Octetsto127Octets);
10780         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx128Octetsto255Octets);
10781         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx256Octetsto511Octets);
10782         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx512Octetsto1023Octets);
10783         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1024Octetsto1522Octets);
10784         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsRx1523Octetsto9022Octets);
10785         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx64Octets);
10786         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx65Octetsto127Octets);
10787         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx128Octetsto255Octets);
10788         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx256Octetsto511Octets);
10789         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx512Octetsto1023Octets);
10790         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1024Octetsto1522Octets);
10791         BCE_PRINT_32BIT_STAT(stat_EtherStatsPktsTx1523Octetsto9022Octets);
10792         BCE_PRINT_32BIT_STAT(stat_XonPauseFramesReceived);
10793         BCE_PRINT_32BIT_STAT(stat_XoffPauseFramesReceived);
10794         BCE_PRINT_32BIT_STAT(stat_OutXonSent);
10795         BCE_PRINT_32BIT_STAT(stat_OutXoffSent);
10796         BCE_PRINT_32BIT_STAT(stat_FlowControlDone);
10797         BCE_PRINT_32BIT_STAT(stat_MacControlFramesReceived);
10798         BCE_PRINT_32BIT_STAT(stat_XoffStateEntered);
10799         BCE_PRINT_32BIT_STAT(stat_IfInFramesL2FilterDiscards);
10800         BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerDiscards);
10801         BCE_PRINT_32BIT_STAT(stat_IfInFTQDiscards);
10802         BCE_PRINT_32BIT_STAT(stat_IfInMBUFDiscards);
10803         BCE_PRINT_32BIT_STAT(stat_IfInRuleCheckerP4Hit);
10804         BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerDiscards);
10805         BCE_PRINT_32BIT_STAT(stat_CatchupInFTQDiscards);
10806         BCE_PRINT_32BIT_STAT(stat_CatchupInMBUFDiscards);
10807         BCE_PRINT_32BIT_STAT(stat_CatchupInRuleCheckerP4Hit);
10808 
10809         BCE_PRINTF(
10810             "----------------------------"
10811             "----------------"
10812             "----------------------------\n");
10813 }
10814 
10815 
10816 /****************************************************************************/
10817 /* Prints out a summary of the driver state.                                */
10818 /*                                                                          */
10819 /* Returns:                                                                 */
10820 /*   Nothing.                                                               */
10821 /****************************************************************************/
10822 static __attribute__ ((noinline)) void
10823 bce_dump_driver_state(struct bce_softc *sc)
10824 {
10825         u32 val_hi, val_lo;
10826 
10827         BCE_PRINTF(
10828             "-----------------------------"
10829             " Driver State "
10830             "-----------------------------\n");
10831 
10832         val_hi = BCE_ADDR_HI(sc);
10833         val_lo = BCE_ADDR_LO(sc);
10834         BCE_PRINTF("0x%08X:%08X - (sc) driver softc structure virtual "
10835             "address\n", val_hi, val_lo);
10836 
10837         val_hi = BCE_ADDR_HI(sc->bce_vhandle);
10838         val_lo = BCE_ADDR_LO(sc->bce_vhandle);
10839         BCE_PRINTF("0x%08X:%08X - (sc->bce_vhandle) PCI BAR virtual "
10840             "address\n", val_hi, val_lo);
10841 
10842         val_hi = BCE_ADDR_HI(sc->status_block);
10843         val_lo = BCE_ADDR_LO(sc->status_block);
10844         BCE_PRINTF("0x%08X:%08X - (sc->status_block) status block "
10845             "virtual address\n",        val_hi, val_lo);
10846 
10847         val_hi = BCE_ADDR_HI(sc->stats_block);
10848         val_lo = BCE_ADDR_LO(sc->stats_block);
10849         BCE_PRINTF("0x%08X:%08X - (sc->stats_block) statistics block "
10850             "virtual address\n", val_hi, val_lo);
10851 
10852         val_hi = BCE_ADDR_HI(sc->tx_bd_chain);
10853         val_lo = BCE_ADDR_LO(sc->tx_bd_chain);
10854         BCE_PRINTF("0x%08X:%08X - (sc->tx_bd_chain) tx_bd chain "
10855             "virtual adddress\n", val_hi, val_lo);
10856 
10857         val_hi = BCE_ADDR_HI(sc->rx_bd_chain);
10858         val_lo = BCE_ADDR_LO(sc->rx_bd_chain);
10859         BCE_PRINTF("0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain "
10860             "virtual address\n", val_hi, val_lo);
10861 
10862         if (bce_hdr_split == TRUE) {
10863                 val_hi = BCE_ADDR_HI(sc->pg_bd_chain);
10864                 val_lo = BCE_ADDR_LO(sc->pg_bd_chain);
10865                 BCE_PRINTF("0x%08X:%08X - (sc->pg_bd_chain) page chain "
10866                     "virtual address\n", val_hi, val_lo);
10867         }
10868 
10869         val_hi = BCE_ADDR_HI(sc->tx_mbuf_ptr);
10870         val_lo = BCE_ADDR_LO(sc->tx_mbuf_ptr);
10871         BCE_PRINTF("0x%08X:%08X - (sc->tx_mbuf_ptr) tx mbuf chain "
10872             "virtual address\n",        val_hi, val_lo);
10873 
10874         val_hi = BCE_ADDR_HI(sc->rx_mbuf_ptr);
10875         val_lo = BCE_ADDR_LO(sc->rx_mbuf_ptr);
10876         BCE_PRINTF("0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain "
10877             "virtual address\n", val_hi, val_lo);
10878 
10879         if (bce_hdr_split == TRUE) {
10880                 val_hi = BCE_ADDR_HI(sc->pg_mbuf_ptr);
10881                 val_lo = BCE_ADDR_LO(sc->pg_mbuf_ptr);
10882                 BCE_PRINTF("0x%08X:%08X - (sc->pg_mbuf_ptr) page mbuf chain "
10883                     "virtual address\n", val_hi, val_lo);
10884         }
10885 
10886         BCE_PRINTF(" 0x%016llX - (sc->interrupts_generated) "
10887             "h/w intrs\n",
10888             (long long unsigned int) sc->interrupts_generated);
10889 
10890         BCE_PRINTF(" 0x%016llX - (sc->interrupts_rx) "
10891             "rx interrupts handled\n",
10892             (long long unsigned int) sc->interrupts_rx);
10893 
10894         BCE_PRINTF(" 0x%016llX - (sc->interrupts_tx) "
10895             "tx interrupts handled\n",
10896             (long long unsigned int) sc->interrupts_tx);
10897 
10898         BCE_PRINTF(" 0x%016llX - (sc->phy_interrupts) "
10899             "phy interrupts handled\n",
10900             (long long unsigned int) sc->phy_interrupts);
10901 
10902         BCE_PRINTF("         0x%08X - (sc->last_status_idx) "
10903             "status block index\n", sc->last_status_idx);
10904 
10905         BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_prod) tx producer "
10906             "index\n", sc->tx_prod, (u16) TX_CHAIN_IDX(sc->tx_prod));
10907 
10908         BCE_PRINTF("     0x%04X(0x%04X) - (sc->tx_cons) tx consumer "
10909             "index\n", sc->tx_cons, (u16) TX_CHAIN_IDX(sc->tx_cons));
10910 
10911         BCE_PRINTF("         0x%08X - (sc->tx_prod_bseq) tx producer "
10912             "byte seq index\n", sc->tx_prod_bseq);
10913 
10914         BCE_PRINTF("         0x%08X - (sc->debug_tx_mbuf_alloc) tx "
10915             "mbufs allocated\n", sc->debug_tx_mbuf_alloc);
10916 
10917         BCE_PRINTF("         0x%08X - (sc->used_tx_bd) used "
10918             "tx_bd's\n", sc->used_tx_bd);
10919 
10920         BCE_PRINTF("      0x%04X/0x%04X - (sc->tx_hi_watermark)/"
10921             "(sc->max_tx_bd)\n", sc->tx_hi_watermark, sc->max_tx_bd);
10922 
10923         BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_prod) rx producer "
10924             "index\n", sc->rx_prod, (u16) RX_CHAIN_IDX(sc->rx_prod));
10925 
10926         BCE_PRINTF("     0x%04X(0x%04X) - (sc->rx_cons) rx consumer "
10927             "index\n", sc->rx_cons, (u16) RX_CHAIN_IDX(sc->rx_cons));
10928 
10929         BCE_PRINTF("         0x%08X - (sc->rx_prod_bseq) rx producer "
10930             "byte seq index\n", sc->rx_prod_bseq);
10931 
10932         BCE_PRINTF("      0x%04X/0x%04X - (sc->rx_low_watermark)/"
10933                    "(sc->max_rx_bd)\n", sc->rx_low_watermark, sc->max_rx_bd);
10934 
10935         BCE_PRINTF("         0x%08X - (sc->debug_rx_mbuf_alloc) rx "
10936             "mbufs allocated\n", sc->debug_rx_mbuf_alloc);
10937 
10938         BCE_PRINTF("         0x%08X - (sc->free_rx_bd) free "
10939             "rx_bd's\n", sc->free_rx_bd);
10940 
10941         if (bce_hdr_split == TRUE) {
10942                 BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_prod) page producer "
10943                     "index\n", sc->pg_prod, (u16) PG_CHAIN_IDX(sc->pg_prod));
10944 
10945                 BCE_PRINTF("     0x%04X(0x%04X) - (sc->pg_cons) page consumer "
10946                     "index\n", sc->pg_cons, (u16) PG_CHAIN_IDX(sc->pg_cons));
10947 
10948                 BCE_PRINTF("         0x%08X - (sc->debug_pg_mbuf_alloc) page "
10949                     "mbufs allocated\n", sc->debug_pg_mbuf_alloc);
10950         }
10951 
10952         BCE_PRINTF("         0x%08X - (sc->free_pg_bd) free page "
10953             "rx_bd's\n", sc->free_pg_bd);
10954 
10955         BCE_PRINTF("      0x%04X/0x%04X - (sc->pg_low_watermark)/"
10956             "(sc->max_pg_bd)\n", sc->pg_low_watermark, sc->max_pg_bd);
10957 
10958         BCE_PRINTF("         0x%08X - (sc->mbuf_alloc_failed_count) "
10959             "mbuf alloc failures\n", sc->mbuf_alloc_failed_count);
10960 
10961         BCE_PRINTF("         0x%08X - (sc->bce_flags) "
10962             "bce mac flags\n", sc->bce_flags);
10963 
10964         BCE_PRINTF("         0x%08X - (sc->bce_phy_flags) "
10965             "bce phy flags\n", sc->bce_phy_flags);
10966 
10967         BCE_PRINTF(
10968             "----------------------------"
10969             "----------------"
10970             "----------------------------\n");
10971 }
10972 
10973 
10974 /****************************************************************************/
10975 /* Prints out the hardware state through a summary of important register,   */
10976 /* followed by a complete register dump.                                    */
10977 /*                                                                          */
10978 /* Returns:                                                                 */
10979 /*   Nothing.                                                               */
10980 /****************************************************************************/
10981 static __attribute__ ((noinline)) void
10982 bce_dump_hw_state(struct bce_softc *sc)
10983 {
10984         u32 val;
10985 
10986         BCE_PRINTF(
10987             "----------------------------"
10988             " Hardware State "
10989             "----------------------------\n");
10990 
10991         BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
10992 
10993         val = REG_RD(sc, BCE_MISC_ENABLE_STATUS_BITS);
10994         BCE_PRINTF("0x%08X - (0x%06X) misc_enable_status_bits\n",
10995             val, BCE_MISC_ENABLE_STATUS_BITS);
10996 
10997         val = REG_RD(sc, BCE_DMA_STATUS);
10998         BCE_PRINTF("0x%08X - (0x%06X) dma_status\n",
10999             val, BCE_DMA_STATUS);
11000 
11001         val = REG_RD(sc, BCE_CTX_STATUS);
11002         BCE_PRINTF("0x%08X - (0x%06X) ctx_status\n",
11003             val, BCE_CTX_STATUS);
11004 
11005         val = REG_RD(sc, BCE_EMAC_STATUS);
11006         BCE_PRINTF("0x%08X - (0x%06X) emac_status\n",
11007             val, BCE_EMAC_STATUS);
11008 
11009         val = REG_RD(sc, BCE_RPM_STATUS);
11010         BCE_PRINTF("0x%08X - (0x%06X) rpm_status\n",
11011             val, BCE_RPM_STATUS);
11012 
11013         /* ToDo: Create a #define for this constant. */
11014         val = REG_RD(sc, 0x2004);
11015         BCE_PRINTF("0x%08X - (0x%06X) rlup_status\n",
11016             val, 0x2004);
11017 
11018         val = REG_RD(sc, BCE_RV2P_STATUS);
11019         BCE_PRINTF("0x%08X - (0x%06X) rv2p_status\n",
11020             val, BCE_RV2P_STATUS);
11021 
11022         /* ToDo: Create a #define for this constant. */
11023         val = REG_RD(sc, 0x2c04);
11024         BCE_PRINTF("0x%08X - (0x%06X) rdma_status\n",
11025             val, 0x2c04);
11026 
11027         val = REG_RD(sc, BCE_TBDR_STATUS);
11028         BCE_PRINTF("0x%08X - (0x%06X) tbdr_status\n",
11029             val, BCE_TBDR_STATUS);
11030 
11031         val = REG_RD(sc, BCE_TDMA_STATUS);
11032         BCE_PRINTF("0x%08X - (0x%06X) tdma_status\n",
11033             val, BCE_TDMA_STATUS);
11034 
11035         val = REG_RD(sc, BCE_HC_STATUS);
11036         BCE_PRINTF("0x%08X - (0x%06X) hc_status\n",
11037             val, BCE_HC_STATUS);
11038 
11039         val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
11040         BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n",
11041             val, BCE_TXP_CPU_STATE);
11042 
11043         val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
11044         BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n",
11045             val, BCE_TPAT_CPU_STATE);
11046 
11047         val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
11048         BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n",
11049             val, BCE_RXP_CPU_STATE);
11050 
11051         val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
11052         BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n",
11053             val, BCE_COM_CPU_STATE);
11054 
11055         val = REG_RD_IND(sc, BCE_MCP_CPU_STATE);
11056         BCE_PRINTF("0x%08X - (0x%06X) mcp_cpu_state\n",
11057             val, BCE_MCP_CPU_STATE);
11058 
11059         val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
11060         BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n",
11061             val, BCE_CP_CPU_STATE);
11062 
11063         BCE_PRINTF(
11064             "----------------------------"
11065             "----------------"
11066             "----------------------------\n");
11067 
11068         BCE_PRINTF(
11069             "----------------------------"
11070             " Register  Dump "
11071             "----------------------------\n");
11072 
11073         for (int i = 0x400; i < 0x8000; i += 0x10) {
11074                 BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
11075                     i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
11076                     REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
11077         }
11078 
11079         BCE_PRINTF(
11080             "----------------------------"
11081             "----------------"
11082             "----------------------------\n");
11083 }
11084 
11085 
11086 /****************************************************************************/
11087 /* Prints out the contentst of shared memory which is used for host driver  */
11088 /* to bootcode firmware communication.                                      */
11089 /*                                                                          */
11090 /* Returns:                                                                 */
11091 /*   Nothing.                                                               */
11092 /****************************************************************************/
11093 static __attribute__ ((noinline)) void
11094 bce_dump_shmem_state(struct bce_softc *sc)
11095 {
11096         BCE_PRINTF(
11097             "----------------------------"
11098             " Hardware State "
11099             "----------------------------\n");
11100 
11101         BCE_PRINTF("0x%08X - Shared memory base address\n",
11102             sc->bce_shmem_base);
11103         BCE_PRINTF("%s - bootcode version\n",
11104             sc->bce_bc_ver);
11105 
11106         BCE_PRINTF(
11107             "----------------------------"
11108             "   Shared Mem   "
11109             "----------------------------\n");
11110 
11111         for (int i = 0x0; i < 0x200; i += 0x10) {
11112                 BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
11113                     i, bce_shmem_rd(sc, i), bce_shmem_rd(sc, i + 0x4),
11114                     bce_shmem_rd(sc, i + 0x8), bce_shmem_rd(sc, i + 0xC));
11115         }
11116 
11117         BCE_PRINTF(
11118             "----------------------------"
11119             "----------------"
11120             "----------------------------\n");
11121 }
11122 
11123 
11124 /****************************************************************************/
11125 /* Prints out the mailbox queue registers.                                  */
11126 /*                                                                          */
11127 /* Returns:                                                                 */
11128 /*   Nothing.                                                               */
11129 /****************************************************************************/
11130 static __attribute__ ((noinline)) void
11131 bce_dump_mq_regs(struct bce_softc *sc)
11132 {
11133         BCE_PRINTF(
11134             "----------------------------"
11135             "    MQ Regs     "
11136             "----------------------------\n");
11137 
11138         BCE_PRINTF(
11139             "----------------------------"
11140             "----------------"
11141             "----------------------------\n");
11142 
11143         for (int i = 0x3c00; i < 0x4000; i += 0x10) {
11144                 BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
11145                     i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
11146                     REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
11147         }
11148 
11149         BCE_PRINTF(
11150             "----------------------------"
11151             "----------------"
11152             "----------------------------\n");
11153 }
11154 
11155 
11156 /****************************************************************************/
11157 /* Prints out the bootcode state.                                           */
11158 /*                                                                          */
11159 /* Returns:                                                                 */
11160 /*   Nothing.                                                               */
11161 /****************************************************************************/
11162 static __attribute__ ((noinline)) void
11163 bce_dump_bc_state(struct bce_softc *sc)
11164 {
11165         u32 val;
11166 
11167         BCE_PRINTF(
11168             "----------------------------"
11169             " Bootcode State "
11170             "----------------------------\n");
11171 
11172         BCE_PRINTF("%s - bootcode version\n", sc->bce_bc_ver);
11173 
11174         val = bce_shmem_rd(sc, BCE_BC_RESET_TYPE);
11175         BCE_PRINTF("0x%08X - (0x%06X) reset_type\n",
11176             val, BCE_BC_RESET_TYPE);
11177 
11178         val = bce_shmem_rd(sc, BCE_BC_STATE);
11179         BCE_PRINTF("0x%08X - (0x%06X) state\n",
11180             val, BCE_BC_STATE);
11181 
11182         val = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION);
11183         BCE_PRINTF("0x%08X - (0x%06X) condition\n",
11184             val, BCE_BC_STATE_CONDITION);
11185 
11186         val = bce_shmem_rd(sc, BCE_BC_STATE_DEBUG_CMD);
11187         BCE_PRINTF("0x%08X - (0x%06X) debug_cmd\n",
11188             val, BCE_BC_STATE_DEBUG_CMD);
11189 
11190         BCE_PRINTF(
11191             "----------------------------"
11192             "----------------"
11193             "----------------------------\n");
11194 }
11195 
11196 
11197 /****************************************************************************/
11198 /* Prints out the TXP processor state.                                      */
11199 /*                                                                          */
11200 /* Returns:                                                                 */
11201 /*   Nothing.                                                               */
11202 /****************************************************************************/
11203 static __attribute__ ((noinline)) void
11204 bce_dump_txp_state(struct bce_softc *sc, int regs)
11205 {
11206         u32 val;
11207         u32 fw_version[3];
11208 
11209         BCE_PRINTF(
11210             "----------------------------"
11211             "   TXP  State   "
11212             "----------------------------\n");
11213 
11214         for (int i = 0; i < 3; i++)
11215                 fw_version[i] = htonl(REG_RD_IND(sc,
11216                     (BCE_TXP_SCRATCH + 0x10 + i * 4)));
11217         BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11218 
11219         val = REG_RD_IND(sc, BCE_TXP_CPU_MODE);
11220         BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_mode\n",
11221             val, BCE_TXP_CPU_MODE);
11222 
11223         val = REG_RD_IND(sc, BCE_TXP_CPU_STATE);
11224         BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_state\n",
11225             val, BCE_TXP_CPU_STATE);
11226 
11227         val = REG_RD_IND(sc, BCE_TXP_CPU_EVENT_MASK);
11228         BCE_PRINTF("0x%08X - (0x%06X) txp_cpu_event_mask\n",
11229             val, BCE_TXP_CPU_EVENT_MASK);
11230 
11231         if (regs) {
11232                 BCE_PRINTF(
11233                     "----------------------------"
11234                     " Register  Dump "
11235                     "----------------------------\n");
11236 
11237                 for (int i = BCE_TXP_CPU_MODE; i < 0x68000; i += 0x10) {
11238                         /* Skip the big blank spaces */
11239                         if (i < 0x454000 && i > 0x5ffff)
11240                                 BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11241                                     "0x%08X 0x%08X\n", i,
11242                                     REG_RD_IND(sc, i),
11243                                     REG_RD_IND(sc, i + 0x4),
11244                                     REG_RD_IND(sc, i + 0x8),
11245                                     REG_RD_IND(sc, i + 0xC));
11246                 }
11247         }
11248 
11249         BCE_PRINTF(
11250             "----------------------------"
11251             "----------------"
11252             "----------------------------\n");
11253 }
11254 
11255 
11256 /****************************************************************************/
11257 /* Prints out the RXP processor state.                                      */
11258 /*                                                                          */
11259 /* Returns:                                                                 */
11260 /*   Nothing.                                                               */
11261 /****************************************************************************/
11262 static __attribute__ ((noinline)) void
11263 bce_dump_rxp_state(struct bce_softc *sc, int regs)
11264 {
11265         u32 val;
11266         u32 fw_version[3];
11267 
11268         BCE_PRINTF(
11269             "----------------------------"
11270             "   RXP  State   "
11271             "----------------------------\n");
11272 
11273         for (int i = 0; i < 3; i++)
11274                 fw_version[i] = htonl(REG_RD_IND(sc,
11275                     (BCE_RXP_SCRATCH + 0x10 + i * 4)));
11276 
11277         BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11278 
11279         val = REG_RD_IND(sc, BCE_RXP_CPU_MODE);
11280         BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_mode\n",
11281             val, BCE_RXP_CPU_MODE);
11282 
11283         val = REG_RD_IND(sc, BCE_RXP_CPU_STATE);
11284         BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_state\n",
11285             val, BCE_RXP_CPU_STATE);
11286 
11287         val = REG_RD_IND(sc, BCE_RXP_CPU_EVENT_MASK);
11288         BCE_PRINTF("0x%08X - (0x%06X) rxp_cpu_event_mask\n",
11289             val, BCE_RXP_CPU_EVENT_MASK);
11290 
11291         if (regs) {
11292                 BCE_PRINTF(
11293                     "----------------------------"
11294                     " Register  Dump "
11295                     "----------------------------\n");
11296 
11297                 for (int i = BCE_RXP_CPU_MODE; i < 0xe8fff; i += 0x10) {
11298                         /* Skip the big blank sapces */
11299                         if (i < 0xc5400 && i > 0xdffff)
11300                                 BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11301                                     "0x%08X 0x%08X\n", i,
11302                                     REG_RD_IND(sc, i),
11303                                     REG_RD_IND(sc, i + 0x4),
11304                                     REG_RD_IND(sc, i + 0x8),
11305                                     REG_RD_IND(sc, i + 0xC));
11306                 }
11307         }
11308 
11309         BCE_PRINTF(
11310             "----------------------------"
11311             "----------------"
11312             "----------------------------\n");
11313 }
11314 
11315 
11316 /****************************************************************************/
11317 /* Prints out the TPAT processor state.                                     */
11318 /*                                                                          */
11319 /* Returns:                                                                 */
11320 /*   Nothing.                                                               */
11321 /****************************************************************************/
11322 static __attribute__ ((noinline)) void
11323 bce_dump_tpat_state(struct bce_softc *sc, int regs)
11324 {
11325         u32 val;
11326         u32 fw_version[3];
11327 
11328         BCE_PRINTF(
11329             "----------------------------"
11330             "   TPAT State   "
11331             "----------------------------\n");
11332 
11333         for (int i = 0; i < 3; i++)
11334                 fw_version[i] = htonl(REG_RD_IND(sc,
11335                     (BCE_TPAT_SCRATCH + 0x410 + i * 4)));
11336 
11337         BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11338 
11339         val = REG_RD_IND(sc, BCE_TPAT_CPU_MODE);
11340         BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_mode\n",
11341             val, BCE_TPAT_CPU_MODE);
11342 
11343         val = REG_RD_IND(sc, BCE_TPAT_CPU_STATE);
11344         BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_state\n",
11345             val, BCE_TPAT_CPU_STATE);
11346 
11347         val = REG_RD_IND(sc, BCE_TPAT_CPU_EVENT_MASK);
11348         BCE_PRINTF("0x%08X - (0x%06X) tpat_cpu_event_mask\n",
11349             val, BCE_TPAT_CPU_EVENT_MASK);
11350 
11351         if (regs) {
11352                 BCE_PRINTF(
11353                     "----------------------------"
11354                     " Register  Dump "
11355                     "----------------------------\n");
11356 
11357                 for (int i = BCE_TPAT_CPU_MODE; i < 0xa3fff; i += 0x10) {
11358                         /* Skip the big blank spaces */
11359                         if (i < 0x854000 && i > 0x9ffff)
11360                                 BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11361                                     "0x%08X 0x%08X\n", i,
11362                                     REG_RD_IND(sc, i),
11363                                     REG_RD_IND(sc, i + 0x4),
11364                                     REG_RD_IND(sc, i + 0x8),
11365                                     REG_RD_IND(sc, i + 0xC));
11366                 }
11367         }
11368 
11369         BCE_PRINTF(
11370                 "----------------------------"
11371                 "----------------"
11372                 "----------------------------\n");
11373 }
11374 
11375 
11376 /****************************************************************************/
11377 /* Prints out the Command Procesor (CP) state.                              */
11378 /*                                                                          */
11379 /* Returns:                                                                 */
11380 /*   Nothing.                                                               */
11381 /****************************************************************************/
11382 static __attribute__ ((noinline)) void
11383 bce_dump_cp_state(struct bce_softc *sc, int regs)
11384 {
11385         u32 val;
11386         u32 fw_version[3];
11387 
11388         BCE_PRINTF(
11389             "----------------------------"
11390             "    CP State    "
11391             "----------------------------\n");
11392 
11393         for (int i = 0; i < 3; i++)
11394                 fw_version[i] = htonl(REG_RD_IND(sc,
11395                     (BCE_CP_SCRATCH + 0x10 + i * 4)));
11396 
11397         BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11398 
11399         val = REG_RD_IND(sc, BCE_CP_CPU_MODE);
11400         BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_mode\n",
11401             val, BCE_CP_CPU_MODE);
11402 
11403         val = REG_RD_IND(sc, BCE_CP_CPU_STATE);
11404         BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_state\n",
11405             val, BCE_CP_CPU_STATE);
11406 
11407         val = REG_RD_IND(sc, BCE_CP_CPU_EVENT_MASK);
11408         BCE_PRINTF("0x%08X - (0x%06X) cp_cpu_event_mask\n", val,
11409             BCE_CP_CPU_EVENT_MASK);
11410 
11411         if (regs) {
11412                 BCE_PRINTF(
11413                     "----------------------------"
11414                     " Register  Dump "
11415                     "----------------------------\n");
11416 
11417                 for (int i = BCE_CP_CPU_MODE; i < 0x1aa000; i += 0x10) {
11418                         /* Skip the big blank spaces */
11419                         if (i < 0x185400 && i > 0x19ffff)
11420                                 BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11421                                     "0x%08X 0x%08X\n", i,
11422                                     REG_RD_IND(sc, i),
11423                                     REG_RD_IND(sc, i + 0x4),
11424                                     REG_RD_IND(sc, i + 0x8),
11425                                     REG_RD_IND(sc, i + 0xC));
11426                 }
11427         }
11428 
11429         BCE_PRINTF(
11430             "----------------------------"
11431             "----------------"
11432             "----------------------------\n");
11433 }
11434 
11435 
11436 /****************************************************************************/
11437 /* Prints out the Completion Procesor (COM) state.                          */
11438 /*                                                                          */
11439 /* Returns:                                                                 */
11440 /*   Nothing.                                                               */
11441 /****************************************************************************/
11442 static __attribute__ ((noinline)) void
11443 bce_dump_com_state(struct bce_softc *sc, int regs)
11444 {
11445         u32 val;
11446         u32 fw_version[4];
11447 
11448         BCE_PRINTF(
11449             "----------------------------"
11450             "   COM State    "
11451             "----------------------------\n");
11452 
11453         for (int i = 0; i < 3; i++)
11454                 fw_version[i] = htonl(REG_RD_IND(sc,
11455                     (BCE_COM_SCRATCH + 0x10 + i * 4)));
11456 
11457         BCE_PRINTF("Firmware version - %s\n", (char *) fw_version);
11458 
11459         val = REG_RD_IND(sc, BCE_COM_CPU_MODE);
11460         BCE_PRINTF("0x%08X - (0x%06X) com_cpu_mode\n",
11461             val, BCE_COM_CPU_MODE);
11462 
11463         val = REG_RD_IND(sc, BCE_COM_CPU_STATE);
11464         BCE_PRINTF("0x%08X - (0x%06X) com_cpu_state\n",
11465             val, BCE_COM_CPU_STATE);
11466 
11467         val = REG_RD_IND(sc, BCE_COM_CPU_EVENT_MASK);
11468         BCE_PRINTF("0x%08X - (0x%06X) com_cpu_event_mask\n", val,
11469             BCE_COM_CPU_EVENT_MASK);
11470 
11471         if (regs) {
11472                 BCE_PRINTF(
11473                     "----------------------------"
11474                     " Register  Dump "
11475                     "----------------------------\n");
11476 
11477                 for (int i = BCE_COM_CPU_MODE; i < 0x1053e8; i += 0x10) {
11478                         BCE_PRINTF("0x%04X: 0x%08X 0x%08X "
11479                             "0x%08X 0x%08X\n", i,
11480                             REG_RD_IND(sc, i),
11481                             REG_RD_IND(sc, i + 0x4),
11482                             REG_RD_IND(sc, i + 0x8),
11483                             REG_RD_IND(sc, i + 0xC));
11484                 }
11485         }
11486 
11487         BCE_PRINTF(
11488                 "----------------------------"
11489                 "----------------"
11490                 "----------------------------\n");
11491 }
11492 
11493 
11494 /****************************************************************************/
11495 /* Prints out the Receive Virtual 2 Physical (RV2P) state.                  */
11496 /*                                                                          */
11497 /* Returns:                                                                 */
11498 /*   Nothing.                                                               */
11499 /****************************************************************************/
11500 static __attribute__ ((noinline)) void
11501 bce_dump_rv2p_state(struct bce_softc *sc)
11502 {
11503         u32 val, pc1, pc2, fw_ver_high, fw_ver_low;
11504 
11505         BCE_PRINTF(
11506             "----------------------------"
11507             "   RV2P State   "
11508             "----------------------------\n");
11509 
11510         /* Stall the RV2P processors. */
11511         val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
11512         val |= BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2;
11513         REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
11514 
11515         /* Read the firmware version. */
11516         val = 0x00000001;
11517         REG_WR_IND(sc, BCE_RV2P_PROC1_ADDR_CMD, val);
11518         fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
11519         fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) &
11520             BCE_RV2P_INSTR_HIGH_HIGH;
11521         BCE_PRINTF("RV2P1 Firmware version - 0x%08X:0x%08X\n",
11522             fw_ver_high, fw_ver_low);
11523 
11524         val = 0x00000001;
11525         REG_WR_IND(sc, BCE_RV2P_PROC2_ADDR_CMD, val);
11526         fw_ver_low = REG_RD_IND(sc, BCE_RV2P_INSTR_LOW);
11527         fw_ver_high = REG_RD_IND(sc, BCE_RV2P_INSTR_HIGH) &
11528             BCE_RV2P_INSTR_HIGH_HIGH;
11529         BCE_PRINTF("RV2P2 Firmware version - 0x%08X:0x%08X\n",
11530             fw_ver_high, fw_ver_low);
11531 
11532         /* Resume the RV2P processors. */
11533         val = REG_RD_IND(sc, BCE_RV2P_CONFIG);
11534         val &= ~(BCE_RV2P_CONFIG_STALL_PROC1 | BCE_RV2P_CONFIG_STALL_PROC2);
11535         REG_WR_IND(sc, BCE_RV2P_CONFIG, val);
11536 
11537         /* Fetch the program counter value. */
11538         val = 0x68007800;
11539         REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
11540         val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
11541         pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
11542         pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
11543         BCE_PRINTF("0x%08X - RV2P1 program counter (1st read)\n", pc1);
11544         BCE_PRINTF("0x%08X - RV2P2 program counter (1st read)\n", pc2);
11545 
11546         /* Fetch the program counter value again to see if it is advancing. */
11547         val = 0x68007800;
11548         REG_WR_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK, val);
11549         val = REG_RD_IND(sc, BCE_RV2P_DEBUG_VECT_PEEK);
11550         pc1 = (val & BCE_RV2P_DEBUG_VECT_PEEK_1_VALUE);
11551         pc2 = (val & BCE_RV2P_DEBUG_VECT_PEEK_2_VALUE) >> 16;
11552         BCE_PRINTF("0x%08X - RV2P1 program counter (2nd read)\n", pc1);
11553         BCE_PRINTF("0x%08X - RV2P2 program counter (2nd read)\n", pc2);
11554 
11555         BCE_PRINTF(
11556             "----------------------------"
11557             "----------------"
11558             "----------------------------\n");
11559 }
11560 
11561 
11562 /****************************************************************************/
11563 /* Prints out the driver state and then enters the debugger.                */
11564 /*                                                                          */
11565 /* Returns:                                                                 */
11566 /*   Nothing.                                                               */
11567 /****************************************************************************/
11568 static __attribute__ ((noinline)) void
11569 bce_breakpoint(struct bce_softc *sc)
11570 {
11571 
11572         /*
11573          * Unreachable code to silence compiler warnings
11574          * about unused functions.
11575          */
11576         if (0) {
11577                 bce_freeze_controller(sc);
11578                 bce_unfreeze_controller(sc);
11579                 bce_dump_enet(sc, NULL);
11580                 bce_dump_txbd(sc, 0, NULL);
11581                 bce_dump_rxbd(sc, 0, NULL);
11582                 bce_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD_ALLOC);
11583                 bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD_ALLOC);
11584                 bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD_ALLOC);
11585                 bce_dump_l2fhdr(sc, 0, NULL);
11586                 bce_dump_ctx(sc, RX_CID);
11587                 bce_dump_ftqs(sc);
11588                 bce_dump_tx_chain(sc, 0, USABLE_TX_BD_ALLOC);
11589                 bce_dump_rx_bd_chain(sc, 0, USABLE_RX_BD_ALLOC);
11590                 bce_dump_pg_chain(sc, 0, USABLE_PG_BD_ALLOC);
11591                 bce_dump_status_block(sc);
11592                 bce_dump_stats_block(sc);
11593                 bce_dump_driver_state(sc);
11594                 bce_dump_hw_state(sc);
11595                 bce_dump_bc_state(sc);
11596                 bce_dump_txp_state(sc, 0);
11597                 bce_dump_rxp_state(sc, 0);
11598                 bce_dump_tpat_state(sc, 0);
11599                 bce_dump_cp_state(sc, 0);
11600                 bce_dump_com_state(sc, 0);
11601                 bce_dump_rv2p_state(sc);
11602                 bce_dump_pgbd(sc, 0, NULL);
11603         }
11604 
11605         bce_dump_status_block(sc);
11606         bce_dump_driver_state(sc);
11607 
11608         /* Call the debugger. */
11609         breakpoint();
11610 }
11611 #endif

Cache object: 389b9e43115243fff91cd10d3ad0a61e


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.