root/dev/pci/if_bnx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bnx_probe
  2. nswaph
  3. bnx_read_firmware
  4. bnx_attach
  5. bnx_attachhook
  6. bnx_detach
  7. bnx_shutdown
  8. bnx_reg_rd_ind
  9. bnx_reg_wr_ind
  10. bnx_ctx_wr
  11. bnx_miibus_read_reg
  12. bnx_miibus_write_reg
  13. bnx_miibus_statchg
  14. bnx_acquire_nvram_lock
  15. bnx_release_nvram_lock
  16. bnx_enable_nvram_write
  17. bnx_disable_nvram_write
  18. bnx_enable_nvram_access
  19. bnx_disable_nvram_access
  20. bnx_nvram_erase_page
  21. bnx_nvram_read_dword
  22. bnx_nvram_write_dword
  23. bnx_init_nvram
  24. bnx_nvram_read
  25. bnx_nvram_write
  26. bnx_nvram_test
  27. bnx_dma_free
  28. bnx_dma_alloc
  29. bnx_release_resources
  30. bnx_fw_sync
  31. bnx_load_rv2p_fw
  32. bnx_load_cpu_fw
  33. bnx_init_cpus
  34. bnx_init_context
  35. bnx_get_mac_addr
  36. bnx_set_mac_addr
  37. bnx_stop
  38. bnx_reset
  39. bnx_chipinit
  40. bnx_blockinit
  41. bnx_get_buf
  42. bnx_init_tx_chain
  43. bnx_free_tx_chain
  44. bnx_init_rx_chain
  45. bnx_free_rx_chain
  46. bnx_ifmedia_upd
  47. bnx_ifmedia_sts
  48. bnx_phy_intr
  49. bnx_rx_intr
  50. bnx_tx_intr
  51. bnx_disable_intr
  52. bnx_enable_intr
  53. bnx_init
  54. bnx_mgmt_init
  55. bnx_tx_encap
  56. bnx_start
  57. bnx_ioctl
  58. bnx_watchdog
  59. bnx_intr
  60. bnx_set_rx_mode
  61. bnx_stats_update
  62. bnx_tick
  63. bnx_dump_mbuf
  64. bnx_dump_tx_mbuf_chain
  65. bnx_dump_rx_mbuf_chain
  66. bnx_dump_txbd
  67. bnx_dump_rxbd
  68. bnx_dump_l2fhdr
  69. bnx_dump_tx_chain
  70. bnx_dump_rx_chain
  71. bnx_dump_status_block
  72. bnx_dump_stats_block
  73. bnx_dump_driver_state
  74. bnx_dump_hw_state
  75. bnx_breakpoint

    1 /*      $OpenBSD: if_bnx.c,v 1.53 2007/07/04 00:20:22 krw Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 2006 Broadcom Corporation
    5  *      David Christensen <davidch@broadcom.com>.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  *
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. Neither the name of Broadcom Corporation nor the name of its contributors
   17  *    may be used to endorse or promote products derived from this software
   18  *    without specific prior written consent.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS'
   21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
   24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   30  * THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 #if 0
   34 #include <sys/cdefs.h>
   35 __FBSDID("$FreeBSD: src/sys/dev/bce/if_bce.c,v 1.3 2006/04/13 14:12:26 ru Exp $");
   36 #endif
   37 
   38 /*
   39  * The following controllers are supported by this driver:
   40  *   BCM5706C A2, A3
   41  *   BCM5708C B1
   42  *
   43  * The following controllers are not supported by this driver:
   44  * (These are not "Production" versions of the controller.)
   45  * 
   46  *   BCM5706C A0, A1
   47  *   BCM5706S A0, A1, A2, A3
   48  *   BCM5708C A0, B0
   49  *   BCM5708S A0, B0, B1
   50  */
   51 
   52 #include <dev/pci/if_bnxreg.h>
   53 
   54 int bnx_COM_b06FwReleaseMajor;
   55 int bnx_COM_b06FwReleaseMinor;
   56 int bnx_COM_b06FwReleaseFix;
   57 u_int32_t bnx_COM_b06FwStartAddr;
   58 u_int32_t bnx_COM_b06FwTextAddr;
   59 int bnx_COM_b06FwTextLen;
   60 u_int32_t bnx_COM_b06FwDataAddr;
   61 int bnx_COM_b06FwDataLen;
   62 u_int32_t bnx_COM_b06FwRodataAddr;
   63 int bnx_COM_b06FwRodataLen;
   64 u_int32_t bnx_COM_b06FwBssAddr;
   65 int bnx_COM_b06FwBssLen;
   66 u_int32_t bnx_COM_b06FwSbssAddr;
   67 int bnx_COM_b06FwSbssLen;
   68 
   69 int bnx_RXP_b06FwReleaseMajor;
   70 int bnx_RXP_b06FwReleaseMinor;
   71 int bnx_RXP_b06FwReleaseFix;
   72 u_int32_t bnx_RXP_b06FwStartAddr;
   73 u_int32_t bnx_RXP_b06FwTextAddr;
   74 int bnx_RXP_b06FwTextLen;
   75 u_int32_t bnx_RXP_b06FwDataAddr;
   76 int bnx_RXP_b06FwDataLen;
   77 u_int32_t bnx_RXP_b06FwRodataAddr;
   78 int bnx_RXP_b06FwRodataLen;
   79 u_int32_t bnx_RXP_b06FwBssAddr;
   80 int bnx_RXP_b06FwBssLen;
   81 u_int32_t bnx_RXP_b06FwSbssAddr;
   82 int bnx_RXP_b06FwSbssLen;
   83 
   84 int bnx_TPAT_b06FwReleaseMajor;
   85 int bnx_TPAT_b06FwReleaseMinor;
   86 int bnx_TPAT_b06FwReleaseFix;
   87 u_int32_t bnx_TPAT_b06FwStartAddr;
   88 u_int32_t bnx_TPAT_b06FwTextAddr;
   89 int bnx_TPAT_b06FwTextLen;
   90 u_int32_t bnx_TPAT_b06FwDataAddr;
   91 int bnx_TPAT_b06FwDataLen;
   92 u_int32_t bnx_TPAT_b06FwRodataAddr;
   93 int bnx_TPAT_b06FwRodataLen;
   94 u_int32_t bnx_TPAT_b06FwBssAddr;
   95 int bnx_TPAT_b06FwBssLen;
   96 u_int32_t bnx_TPAT_b06FwSbssAddr;
   97 int bnx_TPAT_b06FwSbssLen;
   98 
   99 int bnx_TXP_b06FwReleaseMajor;
  100 int bnx_TXP_b06FwReleaseMinor;
  101 int bnx_TXP_b06FwReleaseFix;
  102 u_int32_t bnx_TXP_b06FwStartAddr;
  103 u_int32_t bnx_TXP_b06FwTextAddr;
  104 int bnx_TXP_b06FwTextLen;
  105 u_int32_t bnx_TXP_b06FwDataAddr;
  106 int bnx_TXP_b06FwDataLen;
  107 u_int32_t bnx_TXP_b06FwRodataAddr;
  108 int bnx_TXP_b06FwRodataLen;
  109 u_int32_t bnx_TXP_b06FwBssAddr;
  110 int bnx_TXP_b06FwBssLen;
  111 u_int32_t bnx_TXP_b06FwSbssAddr;
  112 int bnx_TXP_b06FwSbssLen;
  113 
  114 int bnx_rv2p_proc1len;
  115 int bnx_rv2p_proc2len;
  116 
  117 u_int32_t *bnx_COM_b06FwText;
  118 u_int32_t *bnx_COM_b06FwData;
  119 u_int32_t *bnx_COM_b06FwRodata;
  120 u_int32_t *bnx_COM_b06FwBss;
  121 u_int32_t *bnx_COM_b06FwSbss;
  122 
  123 u_int32_t *bnx_RXP_b06FwText;
  124 u_int32_t *bnx_RXP_b06FwData;
  125 u_int32_t *bnx_RXP_b06FwRodata;
  126 u_int32_t *bnx_RXP_b06FwBss;
  127 u_int32_t *bnx_RXP_b06FwSbss;
  128 
  129 u_int32_t *bnx_TPAT_b06FwText;
  130 u_int32_t *bnx_TPAT_b06FwData;
  131 u_int32_t *bnx_TPAT_b06FwRodata;
  132 u_int32_t *bnx_TPAT_b06FwBss;
  133 u_int32_t *bnx_TPAT_b06FwSbss;
  134 
  135 u_int32_t *bnx_TXP_b06FwText;
  136 u_int32_t *bnx_TXP_b06FwData;
  137 u_int32_t *bnx_TXP_b06FwRodata;
  138 u_int32_t *bnx_TXP_b06FwBss;
  139 u_int32_t *bnx_TXP_b06FwSbss;
  140 
  141 u_int32_t *bnx_rv2p_proc1;
  142 u_int32_t *bnx_rv2p_proc2;
  143 
  144 void    nswaph(u_int32_t *p, int wcount);
  145 
  146 /****************************************************************************/
  147 /* BNX Driver Version                                                       */
  148 /****************************************************************************/
  149 char bnx_driver_version[] = "v0.9.6";
  150 
  151 /****************************************************************************/
  152 /* BNX Debug Options                                                        */
  153 /****************************************************************************/
  154 #ifdef BNX_DEBUG
  155         u_int32_t bnx_debug = BNX_WARN;
  156 
  157         /*          0 = Never              */
  158         /*          1 = 1 in 2,147,483,648 */
  159         /*        256 = 1 in     8,388,608 */
  160         /*       2048 = 1 in     1,048,576 */
  161         /*      65536 = 1 in        32,768 */
  162         /*    1048576 = 1 in         2,048 */
  163         /*  268435456 = 1 in             8 */
  164         /*  536870912 = 1 in             4 */
  165         /* 1073741824 = 1 in             2 */
  166 
  167         /* Controls how often the l2_fhdr frame error check will fail. */
  168         int bnx_debug_l2fhdr_status_check = 0;
  169 
  170         /* Controls how often the unexpected attention check will fail. */
  171         int bnx_debug_unexpected_attention = 0;
  172 
  173         /* Controls how often to simulate an mbuf allocation failure. */
  174         int bnx_debug_mbuf_allocation_failure = 0;
  175 
  176         /* Controls how often to simulate a DMA mapping failure. */
  177         int bnx_debug_dma_map_addr_failure = 0;
  178 
  179         /* Controls how often to simulate a bootcode failure. */
  180         int bnx_debug_bootcode_running_failure = 0;
  181 #endif
  182 
  183 /****************************************************************************/
  184 /* PCI Device ID Table                                                      */
  185 /*                                                                          */
  186 /* Used by bnx_probe() to identify the devices supported by this driver.    */
  187 /****************************************************************************/
  188 const struct pci_matchid bnx_devices[] = {
  189         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5706 },
  190         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5706S },
  191         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5708 },
  192         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5708S }
  193 #if 0
  194         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5709 },
  195         { PCI_VENDOR_BROADCOM, PCI_PRODUCT_BROADCOM_BCM5709S }
  196 #endif
  197 };
  198 
  199 /****************************************************************************/
  200 /* Supported Flash NVRAM device data.                                       */
  201 /****************************************************************************/
  202 static struct flash_spec flash_table[] =
  203 {
  204         /* Slow EEPROM */
  205         {0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
  206          1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
  207          SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
  208          "EEPROM - slow"},
  209         /* Expansion entry 0001 */
  210         {0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
  211          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  212          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
  213          "Entry 0001"},
  214         /* Saifun SA25F010 (non-buffered flash) */
  215         /* strap, cfg1, & write1 need updates */
  216         {0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
  217          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  218          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
  219          "Non-buffered flash (128kB)"},
  220         /* Saifun SA25F020 (non-buffered flash) */
  221         /* strap, cfg1, & write1 need updates */
  222         {0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
  223          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  224          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
  225          "Non-buffered flash (256kB)"},
  226         /* Expansion entry 0100 */
  227         {0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
  228          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  229          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
  230          "Entry 0100"},
  231         /* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
  232         {0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,
  233          0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
  234          ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
  235          "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
  236         /* Entry 0110: ST M45PE20 (non-buffered flash)*/
  237         {0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
  238          0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
  239          ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
  240          "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
  241         /* Saifun SA25F005 (non-buffered flash) */
  242         /* strap, cfg1, & write1 need updates */
  243         {0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
  244          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  245          SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
  246          "Non-buffered flash (64kB)"},
  247         /* Fast EEPROM */
  248         {0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
  249          1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
  250          SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
  251          "EEPROM - fast"},
  252         /* Expansion entry 1001 */
  253         {0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
  254          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  255          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
  256          "Entry 1001"},
  257         /* Expansion entry 1010 */
  258         {0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
  259          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  260          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
  261          "Entry 1010"},
  262         /* ATMEL AT45DB011B (buffered flash) */
  263         {0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
  264          1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
  265          BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
  266          "Buffered flash (128kB)"},
  267         /* Expansion entry 1100 */
  268         {0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
  269          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  270          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
  271          "Entry 1100"},
  272         /* Expansion entry 1101 */
  273         {0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
  274          0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
  275          SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
  276          "Entry 1101"},
  277         /* Ateml Expansion entry 1110 */
  278         {0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
  279          1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
  280          BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
  281          "Entry 1110 (Atmel)"},
  282         /* ATMEL AT45DB021B (buffered flash) */
  283         {0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
  284          1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
  285          BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
  286          "Buffered flash (256kB)"},
  287 };
  288 
  289 /****************************************************************************/
  290 /* OpenBSD device entry points.                                             */
  291 /****************************************************************************/
  292 int     bnx_probe(struct device *, void *, void *);
  293 void    bnx_attach(struct device *, struct device *, void *);
  294 void    bnx_attachhook(void *);
  295 int     bnx_read_firmware(struct bnx_softc *sc);
  296 #if 0
  297 void    bnx_detach(void *);
  298 #endif
  299 void    bnx_shutdown(void *);
  300 
  301 /****************************************************************************/
  302 /* BNX Debug Data Structure Dump Routines                                   */
  303 /****************************************************************************/
  304 #ifdef BNX_DEBUG
  305 void    bnx_dump_mbuf(struct bnx_softc *, struct mbuf *);
  306 void    bnx_dump_tx_mbuf_chain(struct bnx_softc *, int, int);
  307 void    bnx_dump_rx_mbuf_chain(struct bnx_softc *, int, int);
  308 void    bnx_dump_txbd(struct bnx_softc *, int, struct tx_bd *);
  309 void    bnx_dump_rxbd(struct bnx_softc *, int, struct rx_bd *);
  310 void    bnx_dump_l2fhdr(struct bnx_softc *, int, struct l2_fhdr *);
  311 void    bnx_dump_tx_chain(struct bnx_softc *, int, int);
  312 void    bnx_dump_rx_chain(struct bnx_softc *, int, int);
  313 void    bnx_dump_status_block(struct bnx_softc *);
  314 void    bnx_dump_stats_block(struct bnx_softc *);
  315 void    bnx_dump_driver_state(struct bnx_softc *);
  316 void    bnx_dump_hw_state(struct bnx_softc *);
  317 void    bnx_breakpoint(struct bnx_softc *);
  318 #endif
  319 
  320 /****************************************************************************/
  321 /* BNX Register/Memory Access Routines                                      */
  322 /****************************************************************************/
  323 u_int32_t       bnx_reg_rd_ind(struct bnx_softc *, u_int32_t);
  324 void    bnx_reg_wr_ind(struct bnx_softc *, u_int32_t, u_int32_t);
  325 void    bnx_ctx_wr(struct bnx_softc *, u_int32_t, u_int32_t, u_int32_t);
  326 int     bnx_miibus_read_reg(struct device *, int, int);
  327 void    bnx_miibus_write_reg(struct device *, int, int, int);
  328 void    bnx_miibus_statchg(struct device *);
  329 
  330 /****************************************************************************/
  331 /* BNX NVRAM Access Routines                                                */
  332 /****************************************************************************/
  333 int     bnx_acquire_nvram_lock(struct bnx_softc *);
  334 int     bnx_release_nvram_lock(struct bnx_softc *);
  335 void    bnx_enable_nvram_access(struct bnx_softc *);
  336 void    bnx_disable_nvram_access(struct bnx_softc *);
  337 int     bnx_nvram_read_dword(struct bnx_softc *, u_int32_t, u_int8_t *,
  338             u_int32_t);
  339 int     bnx_init_nvram(struct bnx_softc *);
  340 int     bnx_nvram_read(struct bnx_softc *, u_int32_t, u_int8_t *, int);
  341 int     bnx_nvram_test(struct bnx_softc *);
  342 #ifdef BNX_NVRAM_WRITE_SUPPORT
  343 int     bnx_enable_nvram_write(struct bnx_softc *);
  344 void    bnx_disable_nvram_write(struct bnx_softc *);
  345 int     bnx_nvram_erase_page(struct bnx_softc *, u_int32_t);
  346 int     bnx_nvram_write_dword(struct bnx_softc *, u_int32_t, u_int8_t *,
  347             u_int32_t);
  348 int     bnx_nvram_write(struct bnx_softc *, u_int32_t, u_int8_t *, int);
  349 #endif
  350 
  351 /****************************************************************************/
  352 /*                                                                          */
  353 /****************************************************************************/
  354 int     bnx_dma_alloc(struct bnx_softc *);
  355 void    bnx_dma_free(struct bnx_softc *);
  356 void    bnx_release_resources(struct bnx_softc *);
  357 
  358 /****************************************************************************/
  359 /* BNX Firmware Synchronization and Load                                    */
  360 /****************************************************************************/
  361 int     bnx_fw_sync(struct bnx_softc *, u_int32_t);
  362 void    bnx_load_rv2p_fw(struct bnx_softc *, u_int32_t *, u_int32_t,
  363             u_int32_t);
  364 void    bnx_load_cpu_fw(struct bnx_softc *, struct cpu_reg *,
  365             struct fw_info *);
  366 void    bnx_init_cpus(struct bnx_softc *);
  367 
  368 void    bnx_stop(struct bnx_softc *);
  369 int     bnx_reset(struct bnx_softc *, u_int32_t);
  370 int     bnx_chipinit(struct bnx_softc *);
  371 int     bnx_blockinit(struct bnx_softc *);
  372 int     bnx_get_buf(struct bnx_softc *, struct mbuf *, u_int16_t *,
  373             u_int16_t *, u_int32_t *);
  374 
  375 int     bnx_init_tx_chain(struct bnx_softc *);
  376 int     bnx_init_rx_chain(struct bnx_softc *);
  377 void    bnx_free_rx_chain(struct bnx_softc *);
  378 void    bnx_free_tx_chain(struct bnx_softc *);
  379 
  380 int     bnx_tx_encap(struct bnx_softc *, struct mbuf **);
  381 void    bnx_start(struct ifnet *);
  382 int     bnx_ioctl(struct ifnet *, u_long, caddr_t);
  383 void    bnx_watchdog(struct ifnet *);
  384 int     bnx_ifmedia_upd(struct ifnet *);
  385 void    bnx_ifmedia_sts(struct ifnet *, struct ifmediareq *);
  386 void    bnx_init(void *);
  387 void    bnx_mgmt_init(struct bnx_softc *sc);
  388 
  389 void    bnx_init_context(struct bnx_softc *);
  390 void    bnx_get_mac_addr(struct bnx_softc *);
  391 void    bnx_set_mac_addr(struct bnx_softc *);
  392 void    bnx_phy_intr(struct bnx_softc *);
  393 void    bnx_rx_intr(struct bnx_softc *);
  394 void    bnx_tx_intr(struct bnx_softc *);
  395 void    bnx_disable_intr(struct bnx_softc *);
  396 void    bnx_enable_intr(struct bnx_softc *);
  397 
  398 int     bnx_intr(void *);
  399 void    bnx_set_rx_mode(struct bnx_softc *);
  400 void    bnx_stats_update(struct bnx_softc *);
  401 void    bnx_tick(void *);
  402 
  403 /****************************************************************************/
  404 /* OpenBSD device dispatch table.                                           */
  405 /****************************************************************************/
  406 struct cfattach bnx_ca = {
  407         sizeof(struct bnx_softc), bnx_probe, bnx_attach
  408 };
  409 
  410 struct cfdriver bnx_cd = {
  411         0, "bnx", DV_IFNET
  412 };
  413 
  414 /****************************************************************************/
  415 /* Device probe function.                                                   */
  416 /*                                                                          */
  417 /* Compares the device to the driver's list of supported devices and        */
  418 /* reports back to the OS whether this is the right driver for the device.  */
  419 /*                                                                          */
  420 /* Returns:                                                                 */
  421 /*   BUS_PROBE_DEFAULT on success, positive value on failure.               */
  422 /****************************************************************************/
  423 int
  424 bnx_probe(struct device *parent, void *match, void *aux)
  425 {
  426         return (pci_matchbyid((struct pci_attach_args *)aux, bnx_devices,
  427             sizeof(bnx_devices)/sizeof(bnx_devices[0])));
  428 }
  429 
  430 void
  431 nswaph(u_int32_t *p, int wcount)
  432 {
  433         for (; wcount; wcount -=4) {
  434                 *p = ntohl(*p);
  435                 p++;
  436         }
  437 }
  438 
  439 int
  440 bnx_read_firmware(struct bnx_softc *sc)
  441 {
  442         static struct bnx_firmware_header *hdr;
  443         u_char *p, *q;
  444         size_t size;
  445         int error;
  446 
  447         if (hdr)
  448                 return (0);
  449 
  450         if ((error = loadfirmware("bnx", &p, &size)) != 0)
  451                 return error;
  452 
  453         if (size < sizeof (struct bnx_firmware_header)) {
  454                 free(p, M_DEVBUF);
  455                 return EINVAL;
  456         }
  457 
  458         hdr = (struct bnx_firmware_header *)p;
  459 
  460         bnx_COM_b06FwReleaseMajor = ntohl(hdr->bnx_COM_b06FwReleaseMajor);
  461         bnx_COM_b06FwReleaseMinor = ntohl(hdr->bnx_COM_b06FwReleaseMinor);
  462         bnx_COM_b06FwReleaseFix = ntohl(hdr->bnx_COM_b06FwReleaseFix);
  463         bnx_COM_b06FwStartAddr = ntohl(hdr->bnx_COM_b06FwStartAddr);
  464         bnx_COM_b06FwTextAddr = ntohl(hdr->bnx_COM_b06FwTextAddr);
  465         bnx_COM_b06FwTextLen = ntohl(hdr->bnx_COM_b06FwTextLen);
  466         bnx_COM_b06FwDataAddr = ntohl(hdr->bnx_COM_b06FwDataAddr);
  467         bnx_COM_b06FwDataLen = ntohl(hdr->bnx_COM_b06FwDataLen);
  468         bnx_COM_b06FwRodataAddr = ntohl(hdr->bnx_COM_b06FwRodataAddr);
  469         bnx_COM_b06FwRodataLen = ntohl(hdr->bnx_COM_b06FwRodataLen);
  470         bnx_COM_b06FwBssAddr = ntohl(hdr->bnx_COM_b06FwBssAddr);
  471         bnx_COM_b06FwBssLen = ntohl(hdr->bnx_COM_b06FwBssLen);
  472         bnx_COM_b06FwSbssAddr = ntohl(hdr->bnx_COM_b06FwSbssAddr);
  473         bnx_COM_b06FwSbssLen = ntohl(hdr->bnx_COM_b06FwSbssLen);
  474 
  475         bnx_RXP_b06FwReleaseMajor = ntohl(hdr->bnx_RXP_b06FwReleaseMajor);
  476         bnx_RXP_b06FwReleaseMinor = ntohl(hdr->bnx_RXP_b06FwReleaseMinor);
  477         bnx_RXP_b06FwReleaseFix = ntohl(hdr->bnx_RXP_b06FwReleaseFix);
  478         bnx_RXP_b06FwStartAddr = ntohl(hdr->bnx_RXP_b06FwStartAddr);
  479         bnx_RXP_b06FwTextAddr = ntohl(hdr->bnx_RXP_b06FwTextAddr);
  480         bnx_RXP_b06FwTextLen = ntohl(hdr->bnx_RXP_b06FwTextLen);
  481         bnx_RXP_b06FwDataAddr = ntohl(hdr->bnx_RXP_b06FwDataAddr);
  482         bnx_RXP_b06FwDataLen = ntohl(hdr->bnx_RXP_b06FwDataLen);
  483         bnx_RXP_b06FwRodataAddr = ntohl(hdr->bnx_RXP_b06FwRodataAddr);
  484         bnx_RXP_b06FwRodataLen = ntohl(hdr->bnx_RXP_b06FwRodataLen);
  485         bnx_RXP_b06FwBssAddr = ntohl(hdr->bnx_RXP_b06FwBssAddr);
  486         bnx_RXP_b06FwBssLen = ntohl(hdr->bnx_RXP_b06FwBssLen);
  487         bnx_RXP_b06FwSbssAddr = ntohl(hdr->bnx_RXP_b06FwSbssAddr);
  488         bnx_RXP_b06FwSbssLen = ntohl(hdr->bnx_RXP_b06FwSbssLen);
  489 
  490         bnx_TPAT_b06FwReleaseMajor = ntohl(hdr->bnx_TPAT_b06FwReleaseMajor);
  491         bnx_TPAT_b06FwReleaseMinor = ntohl(hdr->bnx_TPAT_b06FwReleaseMinor);
  492         bnx_TPAT_b06FwReleaseFix = ntohl(hdr->bnx_TPAT_b06FwReleaseFix);
  493         bnx_TPAT_b06FwStartAddr = ntohl(hdr->bnx_TPAT_b06FwStartAddr);
  494         bnx_TPAT_b06FwTextAddr = ntohl(hdr->bnx_TPAT_b06FwTextAddr);
  495         bnx_TPAT_b06FwTextLen = ntohl(hdr->bnx_TPAT_b06FwTextLen);
  496         bnx_TPAT_b06FwDataAddr = ntohl(hdr->bnx_TPAT_b06FwDataAddr);
  497         bnx_TPAT_b06FwDataLen = ntohl(hdr->bnx_TPAT_b06FwDataLen);
  498         bnx_TPAT_b06FwRodataAddr = ntohl(hdr->bnx_TPAT_b06FwRodataAddr);
  499         bnx_TPAT_b06FwRodataLen = ntohl(hdr->bnx_TPAT_b06FwRodataLen);
  500         bnx_TPAT_b06FwBssAddr = ntohl(hdr->bnx_TPAT_b06FwBssAddr);
  501         bnx_TPAT_b06FwBssLen = ntohl(hdr->bnx_TPAT_b06FwBssLen);
  502         bnx_TPAT_b06FwSbssAddr = ntohl(hdr->bnx_TPAT_b06FwSbssAddr);
  503         bnx_TPAT_b06FwSbssLen = ntohl(hdr->bnx_TPAT_b06FwSbssLen);
  504 
  505         bnx_TXP_b06FwReleaseMajor = ntohl(hdr->bnx_TXP_b06FwReleaseMajor);
  506         bnx_TXP_b06FwReleaseMinor = ntohl(hdr->bnx_TXP_b06FwReleaseMinor);
  507         bnx_TXP_b06FwReleaseFix = ntohl(hdr->bnx_TXP_b06FwReleaseFix);
  508         bnx_TXP_b06FwStartAddr = ntohl(hdr->bnx_TXP_b06FwStartAddr);
  509         bnx_TXP_b06FwTextAddr = ntohl(hdr->bnx_TXP_b06FwTextAddr);
  510         bnx_TXP_b06FwTextLen = ntohl(hdr->bnx_TXP_b06FwTextLen);
  511         bnx_TXP_b06FwDataAddr = ntohl(hdr->bnx_TXP_b06FwDataAddr);
  512         bnx_TXP_b06FwDataLen = ntohl(hdr->bnx_TXP_b06FwDataLen);
  513         bnx_TXP_b06FwRodataAddr = ntohl(hdr->bnx_TXP_b06FwRodataAddr);
  514         bnx_TXP_b06FwRodataLen = ntohl(hdr->bnx_TXP_b06FwRodataLen);
  515         bnx_TXP_b06FwBssAddr = ntohl(hdr->bnx_TXP_b06FwBssAddr);
  516         bnx_TXP_b06FwBssLen = ntohl(hdr->bnx_TXP_b06FwBssLen);
  517         bnx_TXP_b06FwSbssAddr = ntohl(hdr->bnx_TXP_b06FwSbssAddr);
  518         bnx_TXP_b06FwSbssLen = ntohl(hdr->bnx_TXP_b06FwSbssLen);
  519 
  520         bnx_rv2p_proc1len = ntohl(hdr->bnx_rv2p_proc1len);
  521         bnx_rv2p_proc2len = ntohl(hdr->bnx_rv2p_proc2len);
  522 
  523         q = p + sizeof(*hdr);
  524 
  525         bnx_COM_b06FwText = (u_int32_t *)q;
  526         q += bnx_COM_b06FwTextLen;
  527         nswaph(bnx_COM_b06FwText, bnx_COM_b06FwTextLen);
  528         bnx_COM_b06FwData = (u_int32_t *)q;
  529         q += bnx_COM_b06FwDataLen;
  530         nswaph(bnx_COM_b06FwData, bnx_COM_b06FwDataLen);
  531         bnx_COM_b06FwRodata = (u_int32_t *)q;
  532         q += bnx_COM_b06FwRodataLen;
  533         nswaph(bnx_COM_b06FwRodata, bnx_COM_b06FwRodataLen);
  534         bnx_COM_b06FwBss = (u_int32_t *)q;
  535         q += bnx_COM_b06FwBssLen;
  536         nswaph(bnx_COM_b06FwBss, bnx_COM_b06FwBssLen);
  537         bnx_COM_b06FwSbss = (u_int32_t *)q;
  538         q += bnx_COM_b06FwSbssLen;
  539         nswaph(bnx_COM_b06FwSbss, bnx_COM_b06FwSbssLen);
  540 
  541         bnx_RXP_b06FwText = (u_int32_t *)q;
  542         q += bnx_RXP_b06FwTextLen;
  543         nswaph(bnx_RXP_b06FwText, bnx_RXP_b06FwTextLen);
  544         bnx_RXP_b06FwData = (u_int32_t *)q;
  545         q += bnx_RXP_b06FwDataLen;
  546         nswaph(bnx_RXP_b06FwData, bnx_RXP_b06FwDataLen);
  547         bnx_RXP_b06FwRodata = (u_int32_t *)q;
  548         q += bnx_RXP_b06FwRodataLen;
  549         nswaph(bnx_RXP_b06FwRodata, bnx_RXP_b06FwRodataLen);
  550         bnx_RXP_b06FwBss = (u_int32_t *)q;
  551         q += bnx_RXP_b06FwBssLen;
  552         nswaph(bnx_RXP_b06FwBss, bnx_RXP_b06FwBssLen);
  553         bnx_RXP_b06FwSbss = (u_int32_t *)q;
  554         q += bnx_RXP_b06FwSbssLen;
  555         nswaph(bnx_RXP_b06FwSbss, bnx_RXP_b06FwSbssLen);
  556 
  557         bnx_TPAT_b06FwText = (u_int32_t *)q;
  558         q += bnx_TPAT_b06FwTextLen;
  559         nswaph(bnx_TPAT_b06FwText, bnx_TPAT_b06FwTextLen);
  560         bnx_TPAT_b06FwData = (u_int32_t *)q;
  561         q += bnx_TPAT_b06FwDataLen;
  562         nswaph(bnx_TPAT_b06FwData, bnx_TPAT_b06FwDataLen);
  563         bnx_TPAT_b06FwRodata = (u_int32_t *)q;
  564         q += bnx_TPAT_b06FwRodataLen;
  565         nswaph(bnx_TPAT_b06FwRodata, bnx_TPAT_b06FwRodataLen);
  566         bnx_TPAT_b06FwBss = (u_int32_t *)q;
  567         q += bnx_TPAT_b06FwBssLen;
  568         nswaph(bnx_TPAT_b06FwBss, bnx_TPAT_b06FwBssLen);
  569         bnx_TPAT_b06FwSbss = (u_int32_t *)q;
  570         q += bnx_TPAT_b06FwSbssLen;
  571         nswaph(bnx_TPAT_b06FwSbss, bnx_TPAT_b06FwSbssLen);
  572 
  573         bnx_TXP_b06FwText = (u_int32_t *)q;
  574         q += bnx_TXP_b06FwTextLen;
  575         nswaph(bnx_TXP_b06FwText, bnx_TXP_b06FwTextLen);
  576         bnx_TXP_b06FwData = (u_int32_t *)q;
  577         q += bnx_TXP_b06FwDataLen;
  578         nswaph(bnx_TXP_b06FwData, bnx_TXP_b06FwDataLen);
  579         bnx_TXP_b06FwRodata = (u_int32_t *)q;
  580         q += bnx_TXP_b06FwRodataLen;
  581         nswaph(bnx_TXP_b06FwRodata, bnx_TXP_b06FwRodataLen);
  582         bnx_TXP_b06FwBss = (u_int32_t *)q;
  583         q += bnx_TXP_b06FwBssLen;
  584         nswaph(bnx_TXP_b06FwBss, bnx_TXP_b06FwBssLen);
  585         bnx_TXP_b06FwSbss = (u_int32_t *)q;
  586         q += bnx_TXP_b06FwSbssLen;
  587         nswaph(bnx_TXP_b06FwSbss, bnx_TXP_b06FwSbssLen);
  588 
  589         bnx_rv2p_proc1 = (u_int32_t *)q;
  590         q += bnx_rv2p_proc1len;
  591         nswaph(bnx_rv2p_proc1, bnx_rv2p_proc1len);
  592         bnx_rv2p_proc2 = (u_int32_t *)q;
  593         q += bnx_rv2p_proc2len;
  594         nswaph(bnx_rv2p_proc2, bnx_rv2p_proc2len);
  595         
  596         if (q - p != size) {
  597                 free(p, M_DEVBUF);
  598                 hdr = NULL;
  599                 return EINVAL;
  600         }
  601 
  602         return (0);
  603 }
  604 
  605 
  606 /****************************************************************************/
  607 /* Device attach function.                                                  */
  608 /*                                                                          */
  609 /* Allocates device resources, performs secondary chip identification,      */
  610 /* resets and initializes the hardware, and initializes driver instance     */
  611 /* variables.                                                               */
  612 /*                                                                          */
  613 /* Returns:                                                                 */
  614 /*   0 on success, positive value on failure.                               */
  615 /****************************************************************************/
  616 void
  617 bnx_attach(struct device *parent, struct device *self, void *aux)
  618 {
  619         struct bnx_softc        *sc = (struct bnx_softc *)self;
  620         struct pci_attach_args  *pa = aux;
  621         pci_chipset_tag_t       pc = pa->pa_pc;
  622         u_int32_t               val;
  623         pcireg_t                memtype;
  624         const char              *intrstr = NULL;
  625 
  626         sc->bnx_pa = *pa;
  627 
  628         /*
  629          * Map control/status registers.
  630         */
  631         memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, BNX_PCI_BAR0);  
  632         switch (memtype) {
  633         case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT:
  634         case PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_64BIT:
  635                 if (pci_mapreg_map(pa, BNX_PCI_BAR0,
  636                     memtype, 0, &sc->bnx_btag, &sc->bnx_bhandle,
  637                     NULL, &sc->bnx_size, 0) == 0)
  638                         break;
  639         default:
  640                 printf(": can't find mem space\n");
  641                 return;
  642         }
  643 
  644         if (pci_intr_map(pa, &sc->bnx_ih)) {
  645                 printf(": couldn't map interrupt\n");
  646                 goto bnx_attach_fail;
  647         }
  648         intrstr = pci_intr_string(pc, sc->bnx_ih);
  649 
  650         /*
  651          * Configure byte swap and enable indirect register access.
  652          * Rely on CPU to do target byte swapping on big endian systems.
  653          * Access to registers outside of PCI configurtion space are not
  654          * valid until this is done.
  655          */
  656         pci_conf_write(pa->pa_pc, pa->pa_tag, BNX_PCICFG_MISC_CONFIG,
  657             BNX_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
  658             BNX_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP);
  659 
  660         /* Save ASIC revsion info. */
  661         sc->bnx_chipid =  REG_RD(sc, BNX_MISC_ID);
  662 
  663         /* Weed out any non-production controller revisions. */
  664         switch(BNX_CHIP_ID(sc)) {
  665         case BNX_CHIP_ID_5706_A0:
  666         case BNX_CHIP_ID_5706_A1:
  667         case BNX_CHIP_ID_5708_A0:
  668         case BNX_CHIP_ID_5708_B0:
  669                 printf(": unsupported controller revision (%c%d)!\n",
  670                     (((pci_conf_read(pa->pa_pc, pa->pa_tag, 0x08) & 0xf0) >> 4)
  671                     + 'A'), (pci_conf_read(pa->pa_pc, pa->pa_tag, 0x08) & 0xf));
  672                 goto bnx_attach_fail;
  673         }
  674 
  675         if (BNX_CHIP_BOND_ID(sc) & BNX_CHIP_BOND_ID_SERDES_BIT) {
  676                 printf(": SerDes controllers are not supported!\n");
  677                 goto bnx_attach_fail;
  678         }
  679 
  680         /*
  681          * Find the base address for shared memory access.
  682          * Newer versions of bootcode use a signature and offset
  683          * while older versions use a fixed address.
  684          */
  685         val = REG_RD_IND(sc, BNX_SHM_HDR_SIGNATURE);
  686         if ((val & BNX_SHM_HDR_SIGNATURE_SIG_MASK) == BNX_SHM_HDR_SIGNATURE_SIG)
  687                 sc->bnx_shmem_base = REG_RD_IND(sc, BNX_SHM_HDR_ADDR_0);
  688         else
  689                 sc->bnx_shmem_base = HOST_VIEW_SHMEM_BASE;
  690 
  691         DBPRINT(sc, BNX_INFO, "bnx_shmem_base = 0x%08X\n", sc->bnx_shmem_base);
  692 
  693         /* Set initial device and PHY flags */
  694         sc->bnx_flags = 0;
  695         sc->bnx_phy_flags = 0;
  696 
  697         /* Get PCI bus information (speed and type). */
  698         val = REG_RD(sc, BNX_PCICFG_MISC_STATUS);
  699         if (val & BNX_PCICFG_MISC_STATUS_PCIX_DET) {
  700                 u_int32_t clkreg;
  701 
  702                 sc->bnx_flags |= BNX_PCIX_FLAG;
  703 
  704                 clkreg = REG_RD(sc, BNX_PCICFG_PCI_CLOCK_CONTROL_BITS);
  705 
  706                 clkreg &= BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET;
  707                 switch (clkreg) {
  708                 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_133MHZ:
  709                         sc->bus_speed_mhz = 133;
  710                         break;
  711 
  712                 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_95MHZ:
  713                         sc->bus_speed_mhz = 100;
  714                         break;
  715 
  716                 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_66MHZ:
  717                 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_80MHZ:
  718                         sc->bus_speed_mhz = 66;
  719                         break;
  720 
  721                 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_48MHZ:
  722                 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_55MHZ:
  723                         sc->bus_speed_mhz = 50;
  724                         break;
  725 
  726                 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_LOW:
  727                 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_32MHZ:
  728                 case BNX_PCICFG_PCI_CLOCK_CONTROL_BITS_PCI_CLK_SPD_DET_38MHZ:
  729                         sc->bus_speed_mhz = 33;
  730                         break;
  731                 }
  732         } else if (val & BNX_PCICFG_MISC_STATUS_M66EN)
  733                         sc->bus_speed_mhz = 66;
  734                 else
  735                         sc->bus_speed_mhz = 33;
  736 
  737         if (val & BNX_PCICFG_MISC_STATUS_32BIT_DET)
  738                 sc->bnx_flags |= BNX_PCI_32BIT_FLAG;
  739 
  740         printf(": %s\n", intrstr);
  741 
  742         /* Hookup IRQ last. */
  743         sc->bnx_intrhand = pci_intr_establish(pc, sc->bnx_ih, IPL_NET,
  744             bnx_intr, sc, sc->bnx_dev.dv_xname);
  745         if (sc->bnx_intrhand == NULL) {
  746                 printf("%s: couldn't establish interrupt\n",
  747                     sc->bnx_dev.dv_xname);
  748                 goto bnx_attach_fail;
  749         }
  750 
  751         mountroothook_establish(bnx_attachhook, sc);
  752         return;
  753 
  754 bnx_attach_fail:
  755         bnx_release_resources(sc);
  756         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
  757 }
  758 
  759 void
  760 bnx_attachhook(void *xsc)
  761 {
  762         struct bnx_softc *sc = xsc;
  763         struct pci_attach_args *pa = &sc->bnx_pa;
  764         struct ifnet            *ifp;
  765         u_int32_t               val;
  766         int error;
  767 
  768         if ((error = bnx_read_firmware(sc)) != 0) {
  769                 printf("%s: could not read firmware (error=%d)\n",
  770                     sc->bnx_dev.dv_xname, error);
  771                 return;
  772         }
  773 
  774         /* Reset the controller. */
  775         if (bnx_reset(sc, BNX_DRV_MSG_CODE_RESET))
  776                 goto bnx_attach_fail;
  777 
  778         /* Initialize the controller. */
  779         if (bnx_chipinit(sc)) {
  780                 printf("%s: Controller initialization failed!\n",
  781                     sc->bnx_dev.dv_xname);
  782                 goto bnx_attach_fail;
  783         }
  784 
  785         /* Perform NVRAM test. */
  786         if (bnx_nvram_test(sc)) {
  787                 printf("%s: NVRAM test failed!\n",
  788                     sc->bnx_dev.dv_xname);
  789                 goto bnx_attach_fail;
  790         }
  791 
  792         /* Fetch the permanent Ethernet MAC address. */
  793         bnx_get_mac_addr(sc);
  794 
  795         /*
  796          * Trip points control how many BDs
  797          * should be ready before generating an
  798          * interrupt while ticks control how long
  799          * a BD can sit in the chain before
  800          * generating an interrupt.  Set the default 
  801          * values for the RX and TX rings.
  802          */
  803 
  804 #ifdef BNX_DEBUG
  805         /* Force more frequent interrupts. */
  806         sc->bnx_tx_quick_cons_trip_int = 1;
  807         sc->bnx_tx_quick_cons_trip     = 1;
  808         sc->bnx_tx_ticks_int           = 0;
  809         sc->bnx_tx_ticks               = 0;
  810 
  811         sc->bnx_rx_quick_cons_trip_int = 1;
  812         sc->bnx_rx_quick_cons_trip     = 1;
  813         sc->bnx_rx_ticks_int           = 0;
  814         sc->bnx_rx_ticks               = 0;
  815 #else
  816         sc->bnx_tx_quick_cons_trip_int = 20;
  817         sc->bnx_tx_quick_cons_trip     = 20;
  818         sc->bnx_tx_ticks_int           = 80;
  819         sc->bnx_tx_ticks               = 80;
  820 
  821         sc->bnx_rx_quick_cons_trip_int = 6;
  822         sc->bnx_rx_quick_cons_trip     = 6;
  823         sc->bnx_rx_ticks_int           = 18;
  824         sc->bnx_rx_ticks               = 18;
  825 #endif
  826 
  827         /* Update statistics once every second. */
  828         sc->bnx_stats_ticks = 1000000 & 0xffff00;
  829 
  830         /*
  831          * The copper based NetXtreme II controllers
  832          * use an integrated PHY at address 1 while
  833          * the SerDes controllers use a PHY at
  834          * address 2.
  835          */
  836         sc->bnx_phy_addr = 1;
  837 
  838         if (BNX_CHIP_BOND_ID(sc) & BNX_CHIP_BOND_ID_SERDES_BIT) {
  839                 sc->bnx_phy_flags |= BNX_PHY_SERDES_FLAG;
  840                 sc->bnx_flags |= BNX_NO_WOL_FLAG;
  841                 if (BNX_CHIP_NUM(sc) == BNX_CHIP_NUM_5708) {
  842                         sc->bnx_phy_addr = 2;
  843                         val = REG_RD_IND(sc, sc->bnx_shmem_base +
  844                                          BNX_SHARED_HW_CFG_CONFIG);
  845                         if (val & BNX_SHARED_HW_CFG_PHY_2_5G)
  846                                 sc->bnx_phy_flags |= BNX_PHY_2_5G_CAPABLE_FLAG;
  847                 }
  848         }
  849 
  850         if (sc->bnx_phy_flags & BNX_PHY_SERDES_FLAG) {
  851                 printf(": SerDes is not supported by this driver!\n");
  852                 goto bnx_attach_fail;
  853         }
  854 
  855         /* Allocate DMA memory resources. */
  856         sc->bnx_dmatag = pa->pa_dmat;
  857         if (bnx_dma_alloc(sc)) {
  858                 printf("%s: DMA resource allocation failed!\n",
  859                     sc->bnx_dev.dv_xname);
  860                 goto bnx_attach_fail;
  861         }
  862 
  863         /* Initialize the ifnet interface. */
  864         ifp = &sc->arpcom.ac_if;
  865         ifp->if_softc = sc;
  866         ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
  867         ifp->if_ioctl = bnx_ioctl;
  868         ifp->if_start = bnx_start;
  869         ifp->if_watchdog = bnx_watchdog;
  870         if (sc->bnx_phy_flags & BNX_PHY_2_5G_CAPABLE_FLAG)
  871                 ifp->if_baudrate = IF_Gbps(2.5);
  872         else
  873                 ifp->if_baudrate = IF_Gbps(1);
  874         IFQ_SET_MAXLEN(&ifp->if_snd, USABLE_TX_BD - 1);
  875         IFQ_SET_READY(&ifp->if_snd);
  876         bcopy(sc->eaddr, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
  877         bcopy(sc->bnx_dev.dv_xname, ifp->if_xname, IFNAMSIZ);
  878 
  879         ifp->if_capabilities = IFCAP_VLAN_MTU;
  880 
  881 #ifdef BNX_CSUM
  882         ifp->if_capabilities |= IFCAP_CSUM_TCPv4 | IFCAP_CSUM_UDPv4;
  883 #endif  
  884 
  885 #if NVLAN > 0
  886         ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING;
  887 #endif
  888 
  889         sc->mbuf_alloc_size = BNX_MAX_MRU;
  890 
  891         printf("%s: address %s\n", sc->bnx_dev.dv_xname,
  892             ether_sprintf(sc->arpcom.ac_enaddr));
  893 
  894         sc->bnx_mii.mii_ifp = ifp;
  895         sc->bnx_mii.mii_readreg = bnx_miibus_read_reg;
  896         sc->bnx_mii.mii_writereg = bnx_miibus_write_reg;
  897         sc->bnx_mii.mii_statchg = bnx_miibus_statchg;
  898 
  899         /* Look for our PHY. */
  900         ifmedia_init(&sc->bnx_mii.mii_media, 0, bnx_ifmedia_upd,
  901             bnx_ifmedia_sts);
  902         mii_attach(&sc->bnx_dev, &sc->bnx_mii, 0xffffffff,
  903             MII_PHY_ANY, MII_OFFSET_ANY, 0);
  904 
  905         if (LIST_FIRST(&sc->bnx_mii.mii_phys) == NULL) {
  906                 printf("%s: no PHY found!\n", sc->bnx_dev.dv_xname);
  907                 ifmedia_add(&sc->bnx_mii.mii_media,
  908                     IFM_ETHER|IFM_MANUAL, 0, NULL);
  909                 ifmedia_set(&sc->bnx_mii.mii_media,
  910                     IFM_ETHER|IFM_MANUAL);
  911         } else {
  912                 ifmedia_set(&sc->bnx_mii.mii_media,
  913                     IFM_ETHER|IFM_AUTO);
  914         }
  915 
  916         /* Attach to the Ethernet interface list. */
  917         if_attach(ifp);
  918         ether_ifattach(ifp);
  919 
  920         timeout_set(&sc->bnx_timeout, bnx_tick, sc);
  921 
  922         /* Print some important debugging info. */
  923         DBRUN(BNX_INFO, bnx_dump_driver_state(sc));
  924 
  925         /* Get the firmware running so ASF still works. */
  926         bnx_mgmt_init(sc);
  927 
  928         /* Handle interrupts */
  929         sc->bnx_flags |= BNX_ACTIVE_FLAG;
  930 
  931         goto bnx_attach_exit;
  932 
  933 bnx_attach_fail:
  934         bnx_release_resources(sc);
  935 
  936 bnx_attach_exit:
  937         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
  938 }
  939 
  940 /****************************************************************************/
  941 /* Device detach function.                                                  */
  942 /*                                                                          */
  943 /* Stops the controller, resets the controller, and releases resources.     */
  944 /*                                                                          */
  945 /* Returns:                                                                 */
  946 /*   0 on success, positive value on failure.                               */
  947 /****************************************************************************/
  948 #if 0
  949 void
  950 bnx_detach(void *xsc)
  951 {
  952         struct bnx_softc *sc;
  953         struct ifnet *ifp = &sc->arpcom.ac_if;
  954 
  955         sc = device_get_softc(dev);
  956 
  957         DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
  958 
  959         /* Stop and reset the controller. */
  960         bnx_stop(sc);
  961         bnx_reset(sc, BNX_DRV_MSG_CODE_RESET);
  962 
  963         ether_ifdetach(ifp);
  964 
  965         /* If we have a child device on the MII bus remove it too. */
  966         if (sc->bnx_phy_flags & BNX_PHY_SERDES_FLAG) {
  967                 ifmedia_removeall(&sc->bnx_ifmedia);
  968         } else {
  969                 bus_generic_detach(dev);
  970                 device_delete_child(dev, sc->bnx_mii);
  971         }
  972 
  973         /* Release all remaining resources. */
  974         bnx_release_resources(sc);
  975 
  976         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
  977 
  978         return(0);
  979 }
  980 #endif
  981 
  982 /****************************************************************************/
  983 /* Device shutdown function.                                                */
  984 /*                                                                          */
  985 /* Stops and resets the controller.                                         */
  986 /*                                                                          */
  987 /* Returns:                                                                 */
  988 /*   Nothing                                                                */
  989 /****************************************************************************/
  990 void
  991 bnx_shutdown(void *xsc)
  992 {
  993         struct bnx_softc        *sc = (struct bnx_softc *)xsc;
  994 
  995         bnx_stop(sc);
  996         bnx_reset(sc, BNX_DRV_MSG_CODE_RESET);
  997 }
  998 
  999 /****************************************************************************/
 1000 /* Indirect register read.                                                  */
 1001 /*                                                                          */
 1002 /* Reads NetXtreme II registers using an index/data register pair in PCI    */
 1003 /* configuration space.  Using this mechanism avoids issues with posted     */
 1004 /* reads but is much slower than memory-mapped I/O.                         */
 1005 /*                                                                          */
 1006 /* Returns:                                                                 */
 1007 /*   The value of the register.                                             */
 1008 /****************************************************************************/
 1009 u_int32_t
 1010 bnx_reg_rd_ind(struct bnx_softc *sc, u_int32_t offset)
 1011 {
 1012         struct pci_attach_args  *pa = &(sc->bnx_pa);
 1013 
 1014         pci_conf_write(pa->pa_pc, pa->pa_tag, BNX_PCICFG_REG_WINDOW_ADDRESS,
 1015             offset);
 1016 #ifdef BNX_DEBUG
 1017         {
 1018                 u_int32_t val;
 1019                 val = pci_conf_read(pa->pa_pc, pa->pa_tag,
 1020                     BNX_PCICFG_REG_WINDOW);
 1021                 DBPRINT(sc, BNX_EXCESSIVE, "%s(); offset = 0x%08X, "
 1022                     "val = 0x%08X\n", __FUNCTION__, offset, val);
 1023                 return (val);
 1024         }
 1025 #else
 1026         return pci_conf_read(pa->pa_pc, pa->pa_tag, BNX_PCICFG_REG_WINDOW);
 1027 #endif
 1028 }
 1029 
 1030 /****************************************************************************/
 1031 /* Indirect register write.                                                 */
 1032 /*                                                                          */
 1033 /* Writes NetXtreme II registers using an index/data register pair in PCI   */
 1034 /* configuration space.  Using this mechanism avoids issues with posted     */
 1035 /* writes but is muchh slower than memory-mapped I/O.                       */
 1036 /*                                                                          */
 1037 /* Returns:                                                                 */
 1038 /*   Nothing.                                                               */
 1039 /****************************************************************************/
 1040 void
 1041 bnx_reg_wr_ind(struct bnx_softc *sc, u_int32_t offset, u_int32_t val)
 1042 {
 1043         struct pci_attach_args  *pa = &(sc->bnx_pa);
 1044 
 1045         DBPRINT(sc, BNX_EXCESSIVE, "%s(); offset = 0x%08X, val = 0x%08X\n",
 1046                 __FUNCTION__, offset, val);
 1047 
 1048         pci_conf_write(pa->pa_pc, pa->pa_tag, BNX_PCICFG_REG_WINDOW_ADDRESS,
 1049             offset);
 1050         pci_conf_write(pa->pa_pc, pa->pa_tag, BNX_PCICFG_REG_WINDOW, val);
 1051 }
 1052 
 1053 /****************************************************************************/
 1054 /* Context memory write.                                                    */
 1055 /*                                                                          */
 1056 /* The NetXtreme II controller uses context memory to track connection      */
 1057 /* information for L2 and higher network protocols.                         */
 1058 /*                                                                          */
 1059 /* Returns:                                                                 */
 1060 /*   Nothing.                                                               */
 1061 /****************************************************************************/
 1062 void
 1063 bnx_ctx_wr(struct bnx_softc *sc, u_int32_t cid_addr, u_int32_t offset,
 1064     u_int32_t val)
 1065 {
 1066 
 1067         DBPRINT(sc, BNX_EXCESSIVE, "%s(); cid_addr = 0x%08X, offset = 0x%08X, "
 1068                 "val = 0x%08X\n", __FUNCTION__, cid_addr, offset, val);
 1069 
 1070         offset += cid_addr;
 1071         REG_WR(sc, BNX_CTX_DATA_ADR, offset);
 1072         REG_WR(sc, BNX_CTX_DATA, val);
 1073 }
 1074 
 1075 /****************************************************************************/
 1076 /* PHY register read.                                                       */
 1077 /*                                                                          */
 1078 /* Implements register reads on the MII bus.                                */
 1079 /*                                                                          */
 1080 /* Returns:                                                                 */
 1081 /*   The value of the register.                                             */
 1082 /****************************************************************************/
 1083 int
 1084 bnx_miibus_read_reg(struct device *dev, int phy, int reg)
 1085 {
 1086         struct bnx_softc        *sc = (struct bnx_softc *)dev;
 1087         u_int32_t               val;
 1088         int                     i;
 1089 
 1090         /* Make sure we are accessing the correct PHY address. */
 1091         if (phy != sc->bnx_phy_addr) {
 1092                 DBPRINT(sc, BNX_VERBOSE,
 1093                     "Invalid PHY address %d for PHY read!\n", phy);
 1094                 return(0);
 1095         }
 1096 
 1097         if (sc->bnx_phy_flags & BNX_PHY_INT_MODE_AUTO_POLLING_FLAG) {
 1098                 val = REG_RD(sc, BNX_EMAC_MDIO_MODE);
 1099                 val &= ~BNX_EMAC_MDIO_MODE_AUTO_POLL;
 1100 
 1101                 REG_WR(sc, BNX_EMAC_MDIO_MODE, val);
 1102                 REG_RD(sc, BNX_EMAC_MDIO_MODE);
 1103 
 1104                 DELAY(40);
 1105         }
 1106 
 1107         val = BNX_MIPHY(phy) | BNX_MIREG(reg) |
 1108             BNX_EMAC_MDIO_COMM_COMMAND_READ | BNX_EMAC_MDIO_COMM_DISEXT |
 1109             BNX_EMAC_MDIO_COMM_START_BUSY;
 1110         REG_WR(sc, BNX_EMAC_MDIO_COMM, val);
 1111 
 1112         for (i = 0; i < BNX_PHY_TIMEOUT; i++) {
 1113                 DELAY(10);
 1114 
 1115                 val = REG_RD(sc, BNX_EMAC_MDIO_COMM);
 1116                 if (!(val & BNX_EMAC_MDIO_COMM_START_BUSY)) {
 1117                         DELAY(5);
 1118 
 1119                         val = REG_RD(sc, BNX_EMAC_MDIO_COMM);
 1120                         val &= BNX_EMAC_MDIO_COMM_DATA;
 1121 
 1122                         break;
 1123                 }
 1124         }
 1125 
 1126         if (val & BNX_EMAC_MDIO_COMM_START_BUSY) {
 1127                 BNX_PRINTF(sc, "%s(%d): Error: PHY read timeout! phy = %d, "
 1128                     "reg = 0x%04X\n", __FILE__, __LINE__, phy, reg);
 1129                 val = 0x0;
 1130         } else
 1131                 val = REG_RD(sc, BNX_EMAC_MDIO_COMM);
 1132 
 1133         DBPRINT(sc, BNX_EXCESSIVE,
 1134             "%s(): phy = %d, reg = 0x%04X, val = 0x%04X\n", __FUNCTION__, phy,
 1135             (u_int16_t) reg & 0xffff, (u_int16_t) val & 0xffff);
 1136 
 1137         if (sc->bnx_phy_flags & BNX_PHY_INT_MODE_AUTO_POLLING_FLAG) {
 1138                 val = REG_RD(sc, BNX_EMAC_MDIO_MODE);
 1139                 val |= BNX_EMAC_MDIO_MODE_AUTO_POLL;
 1140 
 1141                 REG_WR(sc, BNX_EMAC_MDIO_MODE, val);
 1142                 REG_RD(sc, BNX_EMAC_MDIO_MODE);
 1143 
 1144                 DELAY(40);
 1145         }
 1146 
 1147         return (val & 0xffff);
 1148 }
 1149 
 1150 /****************************************************************************/
 1151 /* PHY register write.                                                      */
 1152 /*                                                                          */
 1153 /* Implements register writes on the MII bus.                               */
 1154 /*                                                                          */
 1155 /* Returns:                                                                 */
 1156 /*   The value of the register.                                             */
 1157 /****************************************************************************/
 1158 void
 1159 bnx_miibus_write_reg(struct device *dev, int phy, int reg, int val)
 1160 {
 1161         struct bnx_softc        *sc = (struct bnx_softc *)dev;
 1162         u_int32_t               val1;
 1163         int                     i;
 1164 
 1165         /* Make sure we are accessing the correct PHY address. */
 1166         if (phy != sc->bnx_phy_addr) {
 1167                 DBPRINT(sc, BNX_WARN, "Invalid PHY address %d for PHY write!\n",
 1168                     phy);
 1169                 return;
 1170         }
 1171 
 1172         DBPRINT(sc, BNX_EXCESSIVE, "%s(): phy = %d, reg = 0x%04X, "
 1173             "val = 0x%04X\n", __FUNCTION__,
 1174             phy, (u_int16_t) reg & 0xffff, (u_int16_t) val & 0xffff);
 1175 
 1176         if (sc->bnx_phy_flags & BNX_PHY_INT_MODE_AUTO_POLLING_FLAG) {
 1177                 val1 = REG_RD(sc, BNX_EMAC_MDIO_MODE);
 1178                 val1 &= ~BNX_EMAC_MDIO_MODE_AUTO_POLL;
 1179 
 1180                 REG_WR(sc, BNX_EMAC_MDIO_MODE, val1);
 1181                 REG_RD(sc, BNX_EMAC_MDIO_MODE);
 1182 
 1183                 DELAY(40);
 1184         }
 1185 
 1186         val1 = BNX_MIPHY(phy) | BNX_MIREG(reg) | val |
 1187             BNX_EMAC_MDIO_COMM_COMMAND_WRITE |
 1188             BNX_EMAC_MDIO_COMM_START_BUSY | BNX_EMAC_MDIO_COMM_DISEXT;
 1189         REG_WR(sc, BNX_EMAC_MDIO_COMM, val1);
 1190 
 1191         for (i = 0; i < BNX_PHY_TIMEOUT; i++) {
 1192                 DELAY(10);
 1193 
 1194                 val1 = REG_RD(sc, BNX_EMAC_MDIO_COMM);
 1195                 if (!(val1 & BNX_EMAC_MDIO_COMM_START_BUSY)) {
 1196                         DELAY(5);
 1197                         break;
 1198                 }
 1199         }
 1200 
 1201         if (val1 & BNX_EMAC_MDIO_COMM_START_BUSY) {
 1202                 BNX_PRINTF(sc, "%s(%d): PHY write timeout!\n", __FILE__,
 1203                     __LINE__);
 1204         }
 1205 
 1206         if (sc->bnx_phy_flags & BNX_PHY_INT_MODE_AUTO_POLLING_FLAG) {
 1207                 val1 = REG_RD(sc, BNX_EMAC_MDIO_MODE);
 1208                 val1 |= BNX_EMAC_MDIO_MODE_AUTO_POLL;
 1209 
 1210                 REG_WR(sc, BNX_EMAC_MDIO_MODE, val1);
 1211                 REG_RD(sc, BNX_EMAC_MDIO_MODE);
 1212 
 1213                 DELAY(40);
 1214         }
 1215 }
 1216 
 1217 /****************************************************************************/
 1218 /* MII bus status change.                                                   */
 1219 /*                                                                          */
 1220 /* Called by the MII bus driver when the PHY establishes link to set the    */
 1221 /* MAC interface registers.                                                 */
 1222 /*                                                                          */
 1223 /* Returns:                                                                 */
 1224 /*   Nothing.                                                               */
 1225 /****************************************************************************/
 1226 void
 1227 bnx_miibus_statchg(struct device *dev)
 1228 {
 1229         struct bnx_softc        *sc = (struct bnx_softc *)dev;
 1230         struct mii_data         *mii = &sc->bnx_mii;
 1231 
 1232         BNX_CLRBIT(sc, BNX_EMAC_MODE, BNX_EMAC_MODE_PORT);
 1233 
 1234         /* Set MII or GMII inerface based on the speed negotiated by the PHY. */
 1235         if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T) {
 1236                 DBPRINT(sc, BNX_INFO, "Setting GMII interface.\n");
 1237                 BNX_SETBIT(sc, BNX_EMAC_MODE, BNX_EMAC_MODE_PORT_GMII);
 1238         } else {
 1239                 DBPRINT(sc, BNX_INFO, "Setting MII interface.\n");
 1240                 BNX_SETBIT(sc, BNX_EMAC_MODE, BNX_EMAC_MODE_PORT_MII);
 1241         }
 1242 
 1243         /* Set half or full duplex based on the duplicity
 1244          * negotiated by the PHY.
 1245          */
 1246         if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
 1247                 DBPRINT(sc, BNX_INFO, "Setting Full-Duplex interface.\n");
 1248                 BNX_CLRBIT(sc, BNX_EMAC_MODE, BNX_EMAC_MODE_HALF_DUPLEX);
 1249         } else {
 1250                 DBPRINT(sc, BNX_INFO, "Setting Half-Duplex interface.\n");
 1251                 BNX_SETBIT(sc, BNX_EMAC_MODE, BNX_EMAC_MODE_HALF_DUPLEX);
 1252         }
 1253 }
 1254 
 1255 /****************************************************************************/
 1256 /* Acquire NVRAM lock.                                                      */
 1257 /*                                                                          */
 1258 /* Before the NVRAM can be accessed the caller must acquire an NVRAM lock.  */
 1259 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
 1260 /* for use by the driver.                                                   */
 1261 /*                                                                          */
 1262 /* Returns:                                                                 */
 1263 /*   0 on success, positive value on failure.                               */
 1264 /****************************************************************************/
 1265 int
 1266 bnx_acquire_nvram_lock(struct bnx_softc *sc)
 1267 {
 1268         u_int32_t               val;
 1269         int                     j;
 1270 
 1271         DBPRINT(sc, BNX_VERBOSE, "Acquiring NVRAM lock.\n");
 1272 
 1273         /* Request access to the flash interface. */
 1274         REG_WR(sc, BNX_NVM_SW_ARB, BNX_NVM_SW_ARB_ARB_REQ_SET2);
 1275         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
 1276                 val = REG_RD(sc, BNX_NVM_SW_ARB);
 1277                 if (val & BNX_NVM_SW_ARB_ARB_ARB2)
 1278                         break;
 1279 
 1280                 DELAY(5);
 1281         }
 1282 
 1283         if (j >= NVRAM_TIMEOUT_COUNT) {
 1284                 DBPRINT(sc, BNX_WARN, "Timeout acquiring NVRAM lock!\n");
 1285                 return (EBUSY);
 1286         }
 1287 
 1288         return (0);
 1289 }
 1290 
 1291 /****************************************************************************/
 1292 /* Release NVRAM lock.                                                      */
 1293 /*                                                                          */
 1294 /* When the caller is finished accessing NVRAM the lock must be released.   */
 1295 /* Locks 0 and 2 are reserved, lock 1 is used by firmware and lock 2 is     */
 1296 /* for use by the driver.                                                   */
 1297 /*                                                                          */
 1298 /* Returns:                                                                 */
 1299 /*   0 on success, positive value on failure.                               */
 1300 /****************************************************************************/
 1301 int
 1302 bnx_release_nvram_lock(struct bnx_softc *sc)
 1303 {
 1304         int                     j;
 1305         u_int32_t               val;
 1306 
 1307         DBPRINT(sc, BNX_VERBOSE, "Releasing NVRAM lock.\n");
 1308 
 1309         /* Relinquish nvram interface. */
 1310         REG_WR(sc, BNX_NVM_SW_ARB, BNX_NVM_SW_ARB_ARB_REQ_CLR2);
 1311 
 1312         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
 1313                 val = REG_RD(sc, BNX_NVM_SW_ARB);
 1314                 if (!(val & BNX_NVM_SW_ARB_ARB_ARB2))
 1315                         break;
 1316 
 1317                 DELAY(5);
 1318         }
 1319 
 1320         if (j >= NVRAM_TIMEOUT_COUNT) {
 1321                 DBPRINT(sc, BNX_WARN, "Timeout reeasing NVRAM lock!\n");
 1322                 return (EBUSY);
 1323         }
 1324 
 1325         return (0);
 1326 }
 1327 
 1328 #ifdef BNX_NVRAM_WRITE_SUPPORT
 1329 /****************************************************************************/
 1330 /* Enable NVRAM write access.                                               */
 1331 /*                                                                          */
 1332 /* Before writing to NVRAM the caller must enable NVRAM writes.             */
 1333 /*                                                                          */
 1334 /* Returns:                                                                 */
 1335 /*   0 on success, positive value on failure.                               */
 1336 /****************************************************************************/
 1337 int
 1338 bnx_enable_nvram_write(struct bnx_softc *sc)
 1339 {
 1340         u_int32_t               val;
 1341 
 1342         DBPRINT(sc, BNX_VERBOSE, "Enabling NVRAM write.\n");
 1343 
 1344         val = REG_RD(sc, BNX_MISC_CFG);
 1345         REG_WR(sc, BNX_MISC_CFG, val | BNX_MISC_CFG_NVM_WR_EN_PCI);
 1346 
 1347         if (!sc->bnx_flash_info->buffered) {
 1348                 int j;
 1349 
 1350                 REG_WR(sc, BNX_NVM_COMMAND, BNX_NVM_COMMAND_DONE);
 1351                 REG_WR(sc, BNX_NVM_COMMAND,
 1352                     BNX_NVM_COMMAND_WREN | BNX_NVM_COMMAND_DOIT);
 1353 
 1354                 for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
 1355                         DELAY(5);
 1356 
 1357                         val = REG_RD(sc, BNX_NVM_COMMAND);
 1358                         if (val & BNX_NVM_COMMAND_DONE)
 1359                                 break;
 1360                 }
 1361 
 1362                 if (j >= NVRAM_TIMEOUT_COUNT) {
 1363                         DBPRINT(sc, BNX_WARN, "Timeout writing NVRAM!\n");
 1364                         return (EBUSY);
 1365                 }
 1366         }
 1367 
 1368         return (0);
 1369 }
 1370 
 1371 /****************************************************************************/
 1372 /* Disable NVRAM write access.                                              */
 1373 /*                                                                          */
 1374 /* When the caller is finished writing to NVRAM write access must be        */
 1375 /* disabled.                                                                */
 1376 /*                                                                          */
 1377 /* Returns:                                                                 */
 1378 /*   Nothing.                                                               */
 1379 /****************************************************************************/
 1380 void
 1381 bnx_disable_nvram_write(struct bnx_softc *sc)
 1382 {
 1383         u_int32_t               val;
 1384 
 1385         DBPRINT(sc, BNX_VERBOSE,  "Disabling NVRAM write.\n");
 1386 
 1387         val = REG_RD(sc, BNX_MISC_CFG);
 1388         REG_WR(sc, BNX_MISC_CFG, val & ~BNX_MISC_CFG_NVM_WR_EN);
 1389 }
 1390 #endif
 1391 
 1392 /****************************************************************************/
 1393 /* Enable NVRAM access.                                                     */
 1394 /*                                                                          */
 1395 /* Before accessing NVRAM for read or write operations the caller must      */
 1396 /* enabled NVRAM access.                                                    */
 1397 /*                                                                          */
 1398 /* Returns:                                                                 */
 1399 /*   Nothing.                                                               */
 1400 /****************************************************************************/
 1401 void
 1402 bnx_enable_nvram_access(struct bnx_softc *sc)
 1403 {
 1404         u_int32_t               val;
 1405 
 1406         DBPRINT(sc, BNX_VERBOSE, "Enabling NVRAM access.\n");
 1407 
 1408         val = REG_RD(sc, BNX_NVM_ACCESS_ENABLE);
 1409         /* Enable both bits, even on read. */
 1410         REG_WR(sc, BNX_NVM_ACCESS_ENABLE,
 1411             val | BNX_NVM_ACCESS_ENABLE_EN | BNX_NVM_ACCESS_ENABLE_WR_EN);
 1412 }
 1413 
 1414 /****************************************************************************/
 1415 /* Disable NVRAM access.                                                    */
 1416 /*                                                                          */
 1417 /* When the caller is finished accessing NVRAM access must be disabled.     */
 1418 /*                                                                          */
 1419 /* Returns:                                                                 */
 1420 /*   Nothing.                                                               */
 1421 /****************************************************************************/
 1422 void
 1423 bnx_disable_nvram_access(struct bnx_softc *sc)
 1424 {
 1425         u_int32_t               val;
 1426 
 1427         DBPRINT(sc, BNX_VERBOSE, "Disabling NVRAM access.\n");
 1428 
 1429         val = REG_RD(sc, BNX_NVM_ACCESS_ENABLE);
 1430 
 1431         /* Disable both bits, even after read. */
 1432         REG_WR(sc, BNX_NVM_ACCESS_ENABLE,
 1433             val & ~(BNX_NVM_ACCESS_ENABLE_EN | BNX_NVM_ACCESS_ENABLE_WR_EN));
 1434 }
 1435 
 1436 #ifdef BNX_NVRAM_WRITE_SUPPORT
 1437 /****************************************************************************/
 1438 /* Erase NVRAM page before writing.                                         */
 1439 /*                                                                          */
 1440 /* Non-buffered flash parts require that a page be erased before it is      */
 1441 /* written.                                                                 */
 1442 /*                                                                          */
 1443 /* Returns:                                                                 */
 1444 /*   0 on success, positive value on failure.                               */
 1445 /****************************************************************************/
 1446 int
 1447 bnx_nvram_erase_page(struct bnx_softc *sc, u_int32_t offset)
 1448 {
 1449         u_int32_t               cmd;
 1450         int                     j;
 1451 
 1452         /* Buffered flash doesn't require an erase. */
 1453         if (sc->bnx_flash_info->buffered)
 1454                 return (0);
 1455 
 1456         DBPRINT(sc, BNX_VERBOSE, "Erasing NVRAM page.\n");
 1457 
 1458         /* Build an erase command. */
 1459         cmd = BNX_NVM_COMMAND_ERASE | BNX_NVM_COMMAND_WR |
 1460             BNX_NVM_COMMAND_DOIT;
 1461 
 1462         /*
 1463          * Clear the DONE bit separately, set the NVRAM address to erase,
 1464          * and issue the erase command.
 1465          */
 1466         REG_WR(sc, BNX_NVM_COMMAND, BNX_NVM_COMMAND_DONE);
 1467         REG_WR(sc, BNX_NVM_ADDR, offset & BNX_NVM_ADDR_NVM_ADDR_VALUE);
 1468         REG_WR(sc, BNX_NVM_COMMAND, cmd);
 1469 
 1470         /* Wait for completion. */
 1471         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
 1472                 u_int32_t val;
 1473 
 1474                 DELAY(5);
 1475 
 1476                 val = REG_RD(sc, BNX_NVM_COMMAND);
 1477                 if (val & BNX_NVM_COMMAND_DONE)
 1478                         break;
 1479         }
 1480 
 1481         if (j >= NVRAM_TIMEOUT_COUNT) {
 1482                 DBPRINT(sc, BNX_WARN, "Timeout erasing NVRAM.\n");
 1483                 return (EBUSY);
 1484         }
 1485 
 1486         return (0);
 1487 }
 1488 #endif /* BNX_NVRAM_WRITE_SUPPORT */
 1489 
 1490 /****************************************************************************/
 1491 /* Read a dword (32 bits) from NVRAM.                                       */
 1492 /*                                                                          */
 1493 /* Read a 32 bit word from NVRAM.  The caller is assumed to have already    */
 1494 /* obtained the NVRAM lock and enabled the controller for NVRAM access.     */
 1495 /*                                                                          */
 1496 /* Returns:                                                                 */
 1497 /*   0 on success and the 32 bit value read, positive value on failure.     */
 1498 /****************************************************************************/
 1499 int
 1500 bnx_nvram_read_dword(struct bnx_softc *sc, u_int32_t offset,
 1501     u_int8_t *ret_val, u_int32_t cmd_flags)
 1502 {
 1503         u_int32_t               cmd;
 1504         int                     i, rc = 0;
 1505 
 1506         /* Build the command word. */
 1507         cmd = BNX_NVM_COMMAND_DOIT | cmd_flags;
 1508 
 1509         /* Calculate the offset for buffered flash. */
 1510         if (sc->bnx_flash_info->buffered)
 1511                 offset = ((offset / sc->bnx_flash_info->page_size) <<
 1512                     sc->bnx_flash_info->page_bits) +
 1513                     (offset % sc->bnx_flash_info->page_size);
 1514 
 1515         /*
 1516          * Clear the DONE bit separately, set the address to read,
 1517          * and issue the read.
 1518          */
 1519         REG_WR(sc, BNX_NVM_COMMAND, BNX_NVM_COMMAND_DONE);
 1520         REG_WR(sc, BNX_NVM_ADDR, offset & BNX_NVM_ADDR_NVM_ADDR_VALUE);
 1521         REG_WR(sc, BNX_NVM_COMMAND, cmd);
 1522 
 1523         /* Wait for completion. */
 1524         for (i = 0; i < NVRAM_TIMEOUT_COUNT; i++) {
 1525                 u_int32_t val;
 1526 
 1527                 DELAY(5);
 1528 
 1529                 val = REG_RD(sc, BNX_NVM_COMMAND);
 1530                 if (val & BNX_NVM_COMMAND_DONE) {
 1531                         val = REG_RD(sc, BNX_NVM_READ);
 1532 
 1533                         val = bnx_be32toh(val);
 1534                         memcpy(ret_val, &val, 4);
 1535                         break;
 1536                 }
 1537         }
 1538 
 1539         /* Check for errors. */
 1540         if (i >= NVRAM_TIMEOUT_COUNT) {
 1541                 BNX_PRINTF(sc, "%s(%d): Timeout error reading NVRAM at "
 1542                     "offset 0x%08X!\n", __FILE__, __LINE__, offset);
 1543                 rc = EBUSY;
 1544         }
 1545 
 1546         return(rc);
 1547 }
 1548 
 1549 #ifdef BNX_NVRAM_WRITE_SUPPORT
 1550 /****************************************************************************/
 1551 /* Write a dword (32 bits) to NVRAM.                                        */
 1552 /*                                                                          */
 1553 /* Write a 32 bit word to NVRAM.  The caller is assumed to have already     */
 1554 /* obtained the NVRAM lock, enabled the controller for NVRAM access, and    */
 1555 /* enabled NVRAM write access.                                              */
 1556 /*                                                                          */
 1557 /* Returns:                                                                 */
 1558 /*   0 on success, positive value on failure.                               */
 1559 /****************************************************************************/
 1560 int
 1561 bnx_nvram_write_dword(struct bnx_softc *sc, u_int32_t offset, u_int8_t *val,
 1562     u_int32_t cmd_flags)
 1563 {
 1564         u_int32_t               cmd, val32;
 1565         int                     j;
 1566 
 1567         /* Build the command word. */
 1568         cmd = BNX_NVM_COMMAND_DOIT | BNX_NVM_COMMAND_WR | cmd_flags;
 1569 
 1570         /* Calculate the offset for buffered flash. */
 1571         if (sc->bnx_flash_info->buffered)
 1572                 offset = ((offset / sc->bnx_flash_info->page_size) <<
 1573                     sc->bnx_flash_info->page_bits) +
 1574                     (offset % sc->bnx_flash_info->page_size);
 1575 
 1576         /*
 1577          * Clear the DONE bit separately, convert NVRAM data to big-endian,
 1578          * set the NVRAM address to write, and issue the write command
 1579          */
 1580         REG_WR(sc, BNX_NVM_COMMAND, BNX_NVM_COMMAND_DONE);
 1581         memcpy(&val32, val, 4);
 1582         val32 = htobe32(val32);
 1583         REG_WR(sc, BNX_NVM_WRITE, val32);
 1584         REG_WR(sc, BNX_NVM_ADDR, offset & BNX_NVM_ADDR_NVM_ADDR_VALUE);
 1585         REG_WR(sc, BNX_NVM_COMMAND, cmd);
 1586 
 1587         /* Wait for completion. */
 1588         for (j = 0; j < NVRAM_TIMEOUT_COUNT; j++) {
 1589                 DELAY(5);
 1590 
 1591                 if (REG_RD(sc, BNX_NVM_COMMAND) & BNX_NVM_COMMAND_DONE)
 1592                         break;
 1593         }
 1594         if (j >= NVRAM_TIMEOUT_COUNT) {
 1595                 BNX_PRINTF(sc, "%s(%d): Timeout error writing NVRAM at "
 1596                     "offset 0x%08X\n", __FILE__, __LINE__, offset);
 1597                 return (EBUSY);
 1598         }
 1599 
 1600         return (0);
 1601 }
 1602 #endif /* BNX_NVRAM_WRITE_SUPPORT */
 1603 
 1604 /****************************************************************************/
 1605 /* Initialize NVRAM access.                                                 */
 1606 /*                                                                          */
 1607 /* Identify the NVRAM device in use and prepare the NVRAM interface to      */
 1608 /* access that device.                                                      */
 1609 /*                                                                          */
 1610 /* Returns:                                                                 */
 1611 /*   0 on success, positive value on failure.                               */
 1612 /****************************************************************************/
 1613 int
 1614 bnx_init_nvram(struct bnx_softc *sc)
 1615 {
 1616         u_int32_t               val;
 1617         int                     j, entry_count, rc;
 1618         struct flash_spec       *flash;
 1619 
 1620         DBPRINT(sc,BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
 1621 
 1622         /* Determine the selected interface. */
 1623         val = REG_RD(sc, BNX_NVM_CFG1);
 1624 
 1625         entry_count = sizeof(flash_table) / sizeof(struct flash_spec);
 1626 
 1627         rc = 0;
 1628 
 1629         /*
 1630          * Flash reconfiguration is required to support additional
 1631          * NVRAM devices not directly supported in hardware.
 1632          * Check if the flash interface was reconfigured
 1633          * by the bootcode.
 1634          */
 1635 
 1636         if (val & 0x40000000) {
 1637                 /* Flash interface reconfigured by bootcode. */
 1638 
 1639                 DBPRINT(sc,BNX_INFO_LOAD, 
 1640                         "bnx_init_nvram(): Flash WAS reconfigured.\n");
 1641 
 1642                 for (j = 0, flash = &flash_table[0]; j < entry_count;
 1643                      j++, flash++) {
 1644                         if ((val & FLASH_BACKUP_STRAP_MASK) ==
 1645                             (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
 1646                                 sc->bnx_flash_info = flash;
 1647                                 break;
 1648                         }
 1649                 }
 1650         } else {
 1651                 /* Flash interface not yet reconfigured. */
 1652                 u_int32_t mask;
 1653 
 1654                 DBPRINT(sc,BNX_INFO_LOAD, 
 1655                         "bnx_init_nvram(): Flash was NOT reconfigured.\n");
 1656 
 1657                 if (val & (1 << 23))
 1658                         mask = FLASH_BACKUP_STRAP_MASK;
 1659                 else
 1660                         mask = FLASH_STRAP_MASK;
 1661 
 1662                 /* Look for the matching NVRAM device configuration data. */
 1663                 for (j = 0, flash = &flash_table[0]; j < entry_count;
 1664                     j++, flash++) {
 1665                         /* Check if the dev matches any of the known devices. */
 1666                         if ((val & mask) == (flash->strapping & mask)) {
 1667                                 /* Found a device match. */
 1668                                 sc->bnx_flash_info = flash;
 1669 
 1670                                 /* Request access to the flash interface. */
 1671                                 if ((rc = bnx_acquire_nvram_lock(sc)) != 0)
 1672                                         return (rc);
 1673 
 1674                                 /* Reconfigure the flash interface. */
 1675                                 bnx_enable_nvram_access(sc);
 1676                                 REG_WR(sc, BNX_NVM_CFG1, flash->config1);
 1677                                 REG_WR(sc, BNX_NVM_CFG2, flash->config2);
 1678                                 REG_WR(sc, BNX_NVM_CFG3, flash->config3);
 1679                                 REG_WR(sc, BNX_NVM_WRITE1, flash->write1);
 1680                                 bnx_disable_nvram_access(sc);
 1681                                 bnx_release_nvram_lock(sc);
 1682 
 1683                                 break;
 1684                         }
 1685                 }
 1686         }
 1687 
 1688         /* Check if a matching device was found. */
 1689         if (j == entry_count) {
 1690                 sc->bnx_flash_info = NULL;
 1691                 BNX_PRINTF(sc, "%s(%d): Unknown Flash NVRAM found!\n",
 1692                         __FILE__, __LINE__);
 1693                 rc = ENODEV;
 1694         }
 1695 
 1696         /* Write the flash config data to the shared memory interface. */
 1697         val = REG_RD_IND(sc, sc->bnx_shmem_base + BNX_SHARED_HW_CFG_CONFIG2);
 1698         val &= BNX_SHARED_HW_CFG2_NVM_SIZE_MASK;
 1699         if (val)
 1700                 sc->bnx_flash_size = val;
 1701         else
 1702                 sc->bnx_flash_size = sc->bnx_flash_info->total_size;
 1703 
 1704         DBPRINT(sc, BNX_INFO_LOAD, "bnx_init_nvram() flash->total_size = "
 1705             "0x%08X\n", sc->bnx_flash_info->total_size);
 1706 
 1707         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
 1708 
 1709         return (rc);
 1710 }
 1711 
 1712 /****************************************************************************/
 1713 /* Read an arbitrary range of data from NVRAM.                              */
 1714 /*                                                                          */
 1715 /* Prepares the NVRAM interface for access and reads the requested data     */
 1716 /* into the supplied buffer.                                                */
 1717 /*                                                                          */
 1718 /* Returns:                                                                 */
 1719 /*   0 on success and the data read, positive value on failure.             */
 1720 /****************************************************************************/
 1721 int
 1722 bnx_nvram_read(struct bnx_softc *sc, u_int32_t offset, u_int8_t *ret_buf,
 1723     int buf_size)
 1724 {
 1725         int                     rc = 0;
 1726         u_int32_t               cmd_flags, offset32, len32, extra;
 1727 
 1728         if (buf_size == 0)
 1729                 return (0);
 1730 
 1731         /* Request access to the flash interface. */
 1732         if ((rc = bnx_acquire_nvram_lock(sc)) != 0)
 1733                 return (rc);
 1734 
 1735         /* Enable access to flash interface */
 1736         bnx_enable_nvram_access(sc);
 1737 
 1738         len32 = buf_size;
 1739         offset32 = offset;
 1740         extra = 0;
 1741 
 1742         cmd_flags = 0;
 1743 
 1744         if (offset32 & 3) {
 1745                 u_int8_t buf[4];
 1746                 u_int32_t pre_len;
 1747 
 1748                 offset32 &= ~3;
 1749                 pre_len = 4 - (offset & 3);
 1750 
 1751                 if (pre_len >= len32) {
 1752                         pre_len = len32;
 1753                         cmd_flags =
 1754                             BNX_NVM_COMMAND_FIRST | BNX_NVM_COMMAND_LAST;
 1755                 } else
 1756                         cmd_flags = BNX_NVM_COMMAND_FIRST;
 1757 
 1758                 rc = bnx_nvram_read_dword(sc, offset32, buf, cmd_flags);
 1759 
 1760                 if (rc)
 1761                         return (rc);
 1762 
 1763                 memcpy(ret_buf, buf + (offset & 3), pre_len);
 1764 
 1765                 offset32 += 4;
 1766                 ret_buf += pre_len;
 1767                 len32 -= pre_len;
 1768         }
 1769 
 1770         if (len32 & 3) {
 1771                 extra = 4 - (len32 & 3);
 1772                 len32 = (len32 + 4) & ~3;
 1773         }
 1774 
 1775         if (len32 == 4) {
 1776                 u_int8_t buf[4];
 1777 
 1778                 if (cmd_flags)
 1779                         cmd_flags = BNX_NVM_COMMAND_LAST;
 1780                 else
 1781                         cmd_flags =
 1782                             BNX_NVM_COMMAND_FIRST | BNX_NVM_COMMAND_LAST;
 1783 
 1784                 rc = bnx_nvram_read_dword(sc, offset32, buf, cmd_flags);
 1785 
 1786                 memcpy(ret_buf, buf, 4 - extra);
 1787         } else if (len32 > 0) {
 1788                 u_int8_t buf[4];
 1789 
 1790                 /* Read the first word. */
 1791                 if (cmd_flags)
 1792                         cmd_flags = 0;
 1793                 else
 1794                         cmd_flags = BNX_NVM_COMMAND_FIRST;
 1795 
 1796                 rc = bnx_nvram_read_dword(sc, offset32, ret_buf, cmd_flags);
 1797 
 1798                 /* Advance to the next dword. */
 1799                 offset32 += 4;
 1800                 ret_buf += 4;
 1801                 len32 -= 4;
 1802 
 1803                 while (len32 > 4 && rc == 0) {
 1804                         rc = bnx_nvram_read_dword(sc, offset32, ret_buf, 0);
 1805 
 1806                         /* Advance to the next dword. */
 1807                         offset32 += 4;
 1808                         ret_buf += 4;
 1809                         len32 -= 4;
 1810                 }
 1811 
 1812                 if (rc)
 1813                         return (rc);
 1814 
 1815                 cmd_flags = BNX_NVM_COMMAND_LAST;
 1816                 rc = bnx_nvram_read_dword(sc, offset32, buf, cmd_flags);
 1817 
 1818                 memcpy(ret_buf, buf, 4 - extra);
 1819         }
 1820 
 1821         /* Disable access to flash interface and release the lock. */
 1822         bnx_disable_nvram_access(sc);
 1823         bnx_release_nvram_lock(sc);
 1824 
 1825         return (rc);
 1826 }
 1827 
 1828 #ifdef BNX_NVRAM_WRITE_SUPPORT
 1829 /****************************************************************************/
 1830 /* Write an arbitrary range of data from NVRAM.                             */
 1831 /*                                                                          */
 1832 /* Prepares the NVRAM interface for write access and writes the requested   */
 1833 /* data from the supplied buffer.  The caller is responsible for            */
 1834 /* calculating any appropriate CRCs.                                        */
 1835 /*                                                                          */
 1836 /* Returns:                                                                 */
 1837 /*   0 on success, positive value on failure.                               */
 1838 /****************************************************************************/
 1839 int
 1840 bnx_nvram_write(struct bnx_softc *sc, u_int32_t offset, u_int8_t *data_buf,
 1841     int buf_size)
 1842 {
 1843         u_int32_t               written, offset32, len32;
 1844         u_int8_t                *buf, start[4], end[4];
 1845         int                     rc = 0;
 1846         int                     align_start, align_end;
 1847 
 1848         buf = data_buf;
 1849         offset32 = offset;
 1850         len32 = buf_size;
 1851         align_start = align_end = 0;
 1852 
 1853         if ((align_start = (offset32 & 3))) {
 1854                 offset32 &= ~3;
 1855                 len32 += align_start;
 1856                 if ((rc = bnx_nvram_read(sc, offset32, start, 4)))
 1857                         return (rc);
 1858         }
 1859 
 1860         if (len32 & 3) {
 1861                 if ((len32 > 4) || !align_start) {
 1862                         align_end = 4 - (len32 & 3);
 1863                         len32 += align_end;
 1864                         if ((rc = bnx_nvram_read(sc, offset32 + len32 - 4,
 1865                             end, 4))) {
 1866                                 return (rc);
 1867                         }
 1868                 }
 1869         }
 1870 
 1871         if (align_start || align_end) {
 1872                 buf = malloc(len32, M_DEVBUF, M_NOWAIT);
 1873                 if (buf == 0)
 1874                         return (ENOMEM);
 1875 
 1876                 if (align_start)
 1877                         memcpy(buf, start, 4);
 1878 
 1879                 if (align_end)
 1880                         memcpy(buf + len32 - 4, end, 4);
 1881 
 1882                 memcpy(buf + align_start, data_buf, buf_size);
 1883         }
 1884 
 1885         written = 0;
 1886         while ((written < len32) && (rc == 0)) {
 1887                 u_int32_t page_start, page_end, data_start, data_end;
 1888                 u_int32_t addr, cmd_flags;
 1889                 int i;
 1890                 u_int8_t flash_buffer[264];
 1891 
 1892             /* Find the page_start addr */
 1893                 page_start = offset32 + written;
 1894                 page_start -= (page_start % sc->bnx_flash_info->page_size);
 1895                 /* Find the page_end addr */
 1896                 page_end = page_start + sc->bnx_flash_info->page_size;
 1897                 /* Find the data_start addr */
 1898                 data_start = (written == 0) ? offset32 : page_start;
 1899                 /* Find the data_end addr */
 1900                 data_end = (page_end > offset32 + len32) ?
 1901                     (offset32 + len32) : page_end;
 1902 
 1903                 /* Request access to the flash interface. */
 1904                 if ((rc = bnx_acquire_nvram_lock(sc)) != 0)
 1905                         goto nvram_write_end;
 1906 
 1907                 /* Enable access to flash interface */
 1908                 bnx_enable_nvram_access(sc);
 1909 
 1910                 cmd_flags = BNX_NVM_COMMAND_FIRST;
 1911                 if (sc->bnx_flash_info->buffered == 0) {
 1912                         int j;
 1913 
 1914                         /* Read the whole page into the buffer
 1915                          * (non-buffer flash only) */
 1916                         for (j = 0; j < sc->bnx_flash_info->page_size; j += 4) {
 1917                                 if (j == (sc->bnx_flash_info->page_size - 4))
 1918                                         cmd_flags |= BNX_NVM_COMMAND_LAST;
 1919 
 1920                                 rc = bnx_nvram_read_dword(sc,
 1921                                         page_start + j,
 1922                                         &flash_buffer[j],
 1923                                         cmd_flags);
 1924 
 1925                                 if (rc)
 1926                                         goto nvram_write_end;
 1927 
 1928                                 cmd_flags = 0;
 1929                         }
 1930                 }
 1931 
 1932                 /* Enable writes to flash interface (unlock write-protect) */
 1933                 if ((rc = bnx_enable_nvram_write(sc)) != 0)
 1934                         goto nvram_write_end;
 1935 
 1936                 /* Erase the page */
 1937                 if ((rc = bnx_nvram_erase_page(sc, page_start)) != 0)
 1938                         goto nvram_write_end;
 1939 
 1940                 /* Re-enable the write again for the actual write */
 1941                 bnx_enable_nvram_write(sc);
 1942 
 1943                 /* Loop to write back the buffer data from page_start to
 1944                  * data_start */
 1945                 i = 0;
 1946                 if (sc->bnx_flash_info->buffered == 0) {
 1947                         for (addr = page_start; addr < data_start;
 1948                                 addr += 4, i += 4) {
 1949 
 1950                                 rc = bnx_nvram_write_dword(sc, addr,
 1951                                     &flash_buffer[i], cmd_flags);
 1952 
 1953                                 if (rc != 0)
 1954                                         goto nvram_write_end;
 1955 
 1956                                 cmd_flags = 0;
 1957                         }
 1958                 }
 1959 
 1960                 /* Loop to write the new data from data_start to data_end */
 1961                 for (addr = data_start; addr < data_end; addr += 4, i++) {
 1962                         if ((addr == page_end - 4) ||
 1963                             ((sc->bnx_flash_info->buffered) &&
 1964                             (addr == data_end - 4))) {
 1965 
 1966                                 cmd_flags |= BNX_NVM_COMMAND_LAST;
 1967                         }
 1968 
 1969                         rc = bnx_nvram_write_dword(sc, addr, buf, cmd_flags);
 1970 
 1971                         if (rc != 0)
 1972                                 goto nvram_write_end;
 1973 
 1974                         cmd_flags = 0;
 1975                         buf += 4;
 1976                 }
 1977 
 1978                 /* Loop to write back the buffer data from data_end
 1979                  * to page_end */
 1980                 if (sc->bnx_flash_info->buffered == 0) {
 1981                         for (addr = data_end; addr < page_end;
 1982                             addr += 4, i += 4) {
 1983 
 1984                                 if (addr == page_end-4)
 1985                                         cmd_flags = BNX_NVM_COMMAND_LAST;
 1986 
 1987                                 rc = bnx_nvram_write_dword(sc, addr,
 1988                                     &flash_buffer[i], cmd_flags);
 1989 
 1990                                 if (rc != 0)
 1991                                         goto nvram_write_end;
 1992 
 1993                                 cmd_flags = 0;
 1994                         }
 1995                 }
 1996 
 1997                 /* Disable writes to flash interface (lock write-protect) */
 1998                 bnx_disable_nvram_write(sc);
 1999 
 2000                 /* Disable access to flash interface */
 2001                 bnx_disable_nvram_access(sc);
 2002                 bnx_release_nvram_lock(sc);
 2003 
 2004                 /* Increment written */
 2005                 written += data_end - data_start;
 2006         }
 2007 
 2008 nvram_write_end:
 2009         if (align_start || align_end)
 2010                 free(buf, M_DEVBUF);
 2011 
 2012         return (rc);
 2013 }
 2014 #endif /* BNX_NVRAM_WRITE_SUPPORT */
 2015 
 2016 /****************************************************************************/
 2017 /* Verifies that NVRAM is accessible and contains valid data.               */
 2018 /*                                                                          */
 2019 /* Reads the configuration data from NVRAM and verifies that the CRC is     */
 2020 /* correct.                                                                 */
 2021 /*                                                                          */
 2022 /* Returns:                                                                 */
 2023 /*   0 on success, positive value on failure.                               */
 2024 /****************************************************************************/
 2025 int
 2026 bnx_nvram_test(struct bnx_softc *sc)
 2027 {
 2028         u_int32_t               buf[BNX_NVRAM_SIZE / 4];
 2029         u_int8_t                *data = (u_int8_t *) buf;
 2030         int                     rc = 0;
 2031         u_int32_t               magic, csum;
 2032 
 2033         /*
 2034          * Check that the device NVRAM is valid by reading
 2035          * the magic value at offset 0.
 2036          */
 2037         if ((rc = bnx_nvram_read(sc, 0, data, 4)) != 0)
 2038                 goto bnx_nvram_test_done;
 2039 
 2040         magic = bnx_be32toh(buf[0]);
 2041         if (magic != BNX_NVRAM_MAGIC) {
 2042                 rc = ENODEV;
 2043                 BNX_PRINTF(sc, "%s(%d): Invalid NVRAM magic value! "
 2044                     "Expected: 0x%08X, Found: 0x%08X\n",
 2045                     __FILE__, __LINE__, BNX_NVRAM_MAGIC, magic);
 2046                 goto bnx_nvram_test_done;
 2047         }
 2048 
 2049         /*
 2050          * Verify that the device NVRAM includes valid
 2051          * configuration data.
 2052          */
 2053         if ((rc = bnx_nvram_read(sc, 0x100, data, BNX_NVRAM_SIZE)) != 0)
 2054                 goto bnx_nvram_test_done;
 2055 
 2056         csum = ether_crc32_le(data, 0x100);
 2057         if (csum != BNX_CRC32_RESIDUAL) {
 2058                 rc = ENODEV;
 2059                 BNX_PRINTF(sc, "%s(%d): Invalid Manufacturing Information "
 2060                     "NVRAM CRC! Expected: 0x%08X, Found: 0x%08X\n",
 2061                     __FILE__, __LINE__, BNX_CRC32_RESIDUAL, csum);
 2062                 goto bnx_nvram_test_done;
 2063         }
 2064 
 2065         csum = ether_crc32_le(data + 0x100, 0x100);
 2066         if (csum != BNX_CRC32_RESIDUAL) {
 2067                 BNX_PRINTF(sc, "%s(%d): Invalid Feature Configuration "
 2068                     "Information NVRAM CRC! Expected: 0x%08X, Found: 08%08X\n",
 2069                     __FILE__, __LINE__, BNX_CRC32_RESIDUAL, csum);
 2070                 rc = ENODEV;
 2071         }
 2072 
 2073 bnx_nvram_test_done:
 2074         return (rc);
 2075 }
 2076 
 2077 /****************************************************************************/
 2078 /* Free any DMA memory owned by the driver.                                 */
 2079 /*                                                                          */
 2080 /* Scans through each data structre that requires DMA memory and frees      */
 2081 /* the memory if allocated.                                                 */
 2082 /*                                                                          */
 2083 /* Returns:                                                                 */
 2084 /*   Nothing.                                                               */
 2085 /****************************************************************************/
 2086 void
 2087 bnx_dma_free(struct bnx_softc *sc)
 2088 {
 2089         int                     i;
 2090 
 2091         DBPRINT(sc,BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
 2092 
 2093         /* Destroy the status block. */
 2094         if (sc->status_block != NULL && sc->status_map != NULL) {
 2095                 bus_dmamap_unload(sc->bnx_dmatag, sc->status_map);
 2096                 bus_dmamem_unmap(sc->bnx_dmatag, (caddr_t)sc->status_block,
 2097                     BNX_STATUS_BLK_SZ);         
 2098                 bus_dmamem_free(sc->bnx_dmatag, &sc->status_seg,
 2099                     sc->status_rseg);
 2100                 bus_dmamap_destroy(sc->bnx_dmatag, sc->status_map);
 2101                 sc->status_block = NULL;
 2102                 sc->status_map = NULL;
 2103         }
 2104 
 2105         /* Destroy the statistics block. */
 2106         if (sc->stats_block != NULL && sc->stats_map != NULL) {
 2107                 bus_dmamap_unload(sc->bnx_dmatag, sc->stats_map);
 2108                 bus_dmamem_unmap(sc->bnx_dmatag, (caddr_t)sc->stats_block,
 2109                     BNX_STATS_BLK_SZ);          
 2110                 bus_dmamem_free(sc->bnx_dmatag, &sc->stats_seg,
 2111                     sc->stats_rseg);
 2112                 bus_dmamap_destroy(sc->bnx_dmatag, sc->stats_map);
 2113                 sc->stats_block = NULL;
 2114                 sc->stats_map = NULL;
 2115         }
 2116 
 2117         /* Free, unmap and destroy all TX buffer descriptor chain pages. */
 2118         for (i = 0; i < TX_PAGES; i++ ) {
 2119                 if (sc->tx_bd_chain[i] != NULL &&
 2120                     sc->tx_bd_chain_map[i] != NULL) {
 2121                         bus_dmamap_unload(sc->bnx_dmatag,
 2122                             sc->tx_bd_chain_map[i]);
 2123                         bus_dmamem_unmap(sc->bnx_dmatag,
 2124                             (caddr_t)sc->tx_bd_chain[i], BNX_TX_CHAIN_PAGE_SZ);
 2125                         bus_dmamem_free(sc->bnx_dmatag, &sc->tx_bd_chain_seg[i],
 2126                             sc->tx_bd_chain_rseg[i]);
 2127                         bus_dmamap_destroy(sc->bnx_dmatag,
 2128                             sc->tx_bd_chain_map[i]);
 2129                         sc->tx_bd_chain[i] = NULL;
 2130                         sc->tx_bd_chain_map[i] = NULL;
 2131                 }
 2132         }
 2133 
 2134         /* Unload and destroy the TX mbuf maps. */
 2135         for (i = 0; i < TOTAL_TX_BD; i++) {
 2136                 if (sc->tx_mbuf_map[i] != NULL) {
 2137                         bus_dmamap_unload(sc->bnx_dmatag, sc->tx_mbuf_map[i]);
 2138                         bus_dmamap_destroy(sc->bnx_dmatag, sc->tx_mbuf_map[i]);
 2139                 }
 2140         }
 2141 
 2142         /* Free, unmap and destroy all RX buffer descriptor chain pages. */
 2143         for (i = 0; i < RX_PAGES; i++ ) {
 2144                 if (sc->rx_bd_chain[i] != NULL &&
 2145                     sc->rx_bd_chain_map[i] != NULL) {
 2146                         bus_dmamap_unload(sc->bnx_dmatag,
 2147                             sc->rx_bd_chain_map[i]);
 2148                         bus_dmamem_unmap(sc->bnx_dmatag,
 2149                             (caddr_t)sc->rx_bd_chain[i], BNX_RX_CHAIN_PAGE_SZ);
 2150                         bus_dmamem_free(sc->bnx_dmatag, &sc->rx_bd_chain_seg[i],
 2151                             sc->rx_bd_chain_rseg[i]);
 2152 
 2153                         bus_dmamap_destroy(sc->bnx_dmatag,
 2154                             sc->rx_bd_chain_map[i]);
 2155                         sc->rx_bd_chain[i] = NULL;
 2156                         sc->rx_bd_chain_map[i] = NULL;
 2157                 }
 2158         }
 2159 
 2160         /* Unload and destroy the RX mbuf maps. */
 2161         for (i = 0; i < TOTAL_RX_BD; i++) {
 2162                 if (sc->rx_mbuf_map[i] != NULL) {
 2163                         bus_dmamap_unload(sc->bnx_dmatag, sc->rx_mbuf_map[i]);
 2164                         bus_dmamap_destroy(sc->bnx_dmatag, sc->rx_mbuf_map[i]);
 2165                 }
 2166         }
 2167 
 2168         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
 2169 }
 2170 
 2171 /****************************************************************************/
 2172 /* Allocate any DMA memory needed by the driver.                            */
 2173 /*                                                                          */
 2174 /* Allocates DMA memory needed for the various global structures needed by  */
 2175 /* hardware.                                                                */
 2176 /*                                                                          */
 2177 /* Returns:                                                                 */
 2178 /*   0 for success, positive value for failure.                             */
 2179 /****************************************************************************/
 2180 int
 2181 bnx_dma_alloc(struct bnx_softc *sc)
 2182 {
 2183         int                     i, rc = 0;
 2184 
 2185         DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
 2186 
 2187         /*
 2188          * Allocate DMA memory for the status block, map the memory into DMA
 2189          * space, and fetch the physical address of the block.
 2190          */
 2191         if (bus_dmamap_create(sc->bnx_dmatag, BNX_STATUS_BLK_SZ, 1,
 2192             BNX_STATUS_BLK_SZ, 0, BUS_DMA_NOWAIT, &sc->status_map)) {
 2193                 printf(": Could not create status block DMA map!\n");
 2194                 rc = ENOMEM;
 2195                 goto bnx_dma_alloc_exit;
 2196         }
 2197 
 2198         if (bus_dmamem_alloc(sc->bnx_dmatag, BNX_STATUS_BLK_SZ,
 2199             BNX_DMA_ALIGN, BNX_DMA_BOUNDARY, &sc->status_seg, 1,
 2200             &sc->status_rseg, BUS_DMA_NOWAIT)) {
 2201                 printf(": Could not allocate status block DMA memory!\n");
 2202                 rc = ENOMEM;
 2203                 goto bnx_dma_alloc_exit;
 2204         }
 2205 
 2206         if (bus_dmamem_map(sc->bnx_dmatag, &sc->status_seg, sc->status_rseg,
 2207             BNX_STATUS_BLK_SZ, (caddr_t *)&sc->status_block, BUS_DMA_NOWAIT)) {
 2208                 printf(": Could not map status block DMA memory!\n");
 2209                 rc = ENOMEM;
 2210                 goto bnx_dma_alloc_exit;
 2211         }
 2212 
 2213         if (bus_dmamap_load(sc->bnx_dmatag, sc->status_map,
 2214             sc->status_block, BNX_STATUS_BLK_SZ, NULL, BUS_DMA_NOWAIT)) {
 2215                 printf(": Could not load status block DMA memory!\n");
 2216                 rc = ENOMEM;
 2217                 goto bnx_dma_alloc_exit;
 2218         }
 2219 
 2220         sc->status_block_paddr = sc->status_map->dm_segs[0].ds_addr;
 2221         bzero(sc->status_block, BNX_STATUS_BLK_SZ);
 2222 
 2223         /* DRC - Fix for 64 bit addresses. */
 2224         DBPRINT(sc, BNX_INFO, "status_block_paddr = 0x%08X\n",
 2225                 (u_int32_t) sc->status_block_paddr);
 2226 
 2227         /*
 2228          * Allocate DMA memory for the statistics block, map the memory into
 2229          * DMA space, and fetch the physical address of the block.
 2230          */
 2231         if (bus_dmamap_create(sc->bnx_dmatag, BNX_STATS_BLK_SZ, 1,
 2232             BNX_STATS_BLK_SZ, 0, BUS_DMA_NOWAIT, &sc->stats_map)) {
 2233                 printf(": Could not create stats block DMA map!\n");
 2234                 rc = ENOMEM;
 2235                 goto bnx_dma_alloc_exit;
 2236         }
 2237 
 2238         if (bus_dmamem_alloc(sc->bnx_dmatag, BNX_STATS_BLK_SZ,
 2239             BNX_DMA_ALIGN, BNX_DMA_BOUNDARY, &sc->stats_seg, 1,
 2240             &sc->stats_rseg, BUS_DMA_NOWAIT)) {
 2241                 printf(": Could not allocate stats block DMA memory!\n");
 2242                 rc = ENOMEM;
 2243                 goto bnx_dma_alloc_exit;
 2244         }
 2245 
 2246         if (bus_dmamem_map(sc->bnx_dmatag, &sc->stats_seg, sc->stats_rseg,
 2247             BNX_STATS_BLK_SZ, (caddr_t *)&sc->stats_block, BUS_DMA_NOWAIT)) {
 2248                 printf(": Could not map stats block DMA memory!\n");
 2249                 rc = ENOMEM;
 2250                 goto bnx_dma_alloc_exit;
 2251         }
 2252 
 2253         if (bus_dmamap_load(sc->bnx_dmatag, sc->stats_map,
 2254             sc->stats_block, BNX_STATS_BLK_SZ, NULL, BUS_DMA_NOWAIT)) {
 2255                 printf(": Could not load status block DMA memory!\n");
 2256                 rc = ENOMEM;
 2257                 goto bnx_dma_alloc_exit;
 2258         }
 2259 
 2260         sc->stats_block_paddr = sc->stats_map->dm_segs[0].ds_addr;
 2261         bzero(sc->stats_block, BNX_STATS_BLK_SZ);
 2262 
 2263         /* DRC - Fix for 64 bit address. */
 2264         DBPRINT(sc,BNX_INFO, "stats_block_paddr = 0x%08X\n", 
 2265             (u_int32_t) sc->stats_block_paddr);
 2266 
 2267         /*
 2268          * Allocate DMA memory for the TX buffer descriptor chain,
 2269          * and fetch the physical address of the block.
 2270          */
 2271         for (i = 0; i < TX_PAGES; i++) {
 2272                 if (bus_dmamap_create(sc->bnx_dmatag, BNX_TX_CHAIN_PAGE_SZ, 1,
 2273                     BNX_TX_CHAIN_PAGE_SZ, 0, BUS_DMA_NOWAIT,
 2274                     &sc->tx_bd_chain_map[i])) {
 2275                         printf(": Could not create Tx desc %d DMA map!\n", i);
 2276                         rc = ENOMEM;
 2277                         goto bnx_dma_alloc_exit;
 2278                 }
 2279 
 2280                 if (bus_dmamem_alloc(sc->bnx_dmatag, BNX_TX_CHAIN_PAGE_SZ,
 2281                     BCM_PAGE_SIZE, BNX_DMA_BOUNDARY, &sc->tx_bd_chain_seg[i], 1,
 2282                     &sc->tx_bd_chain_rseg[i], BUS_DMA_NOWAIT)) {
 2283                         printf(": Could not allocate TX desc %d DMA memory!\n",
 2284                             i);
 2285                         rc = ENOMEM;
 2286                         goto bnx_dma_alloc_exit;
 2287                 }
 2288 
 2289                 if (bus_dmamem_map(sc->bnx_dmatag, &sc->tx_bd_chain_seg[i],
 2290                     sc->tx_bd_chain_rseg[i], BNX_TX_CHAIN_PAGE_SZ,
 2291                     (caddr_t *)&sc->tx_bd_chain[i], BUS_DMA_NOWAIT)) {
 2292                         printf(": Could not map TX desc %d DMA memory!\n", i);
 2293                         rc = ENOMEM;
 2294                         goto bnx_dma_alloc_exit;
 2295                 }
 2296 
 2297                 if (bus_dmamap_load(sc->bnx_dmatag, sc->tx_bd_chain_map[i],
 2298                     (caddr_t)sc->tx_bd_chain[i], BNX_TX_CHAIN_PAGE_SZ, NULL,
 2299                     BUS_DMA_NOWAIT)) {
 2300                         printf(": Could not load TX desc %d DMA memory!\n", i);
 2301                         rc = ENOMEM;
 2302                         goto bnx_dma_alloc_exit;
 2303                 }
 2304 
 2305                 sc->tx_bd_chain_paddr[i] =
 2306                     sc->tx_bd_chain_map[i]->dm_segs[0].ds_addr;
 2307 
 2308                 /* DRC - Fix for 64 bit systems. */
 2309                 DBPRINT(sc, BNX_INFO, "tx_bd_chain_paddr[%d] = 0x%08X\n", 
 2310                     i, (u_int32_t) sc->tx_bd_chain_paddr[i]);
 2311         }
 2312 
 2313         /*
 2314          * Create DMA maps for the TX buffer mbufs.
 2315          */
 2316         for (i = 0; i < TOTAL_TX_BD; i++) {
 2317                 if (bus_dmamap_create(sc->bnx_dmatag,
 2318                     MCLBYTES * BNX_MAX_SEGMENTS,
 2319                     USABLE_TX_BD - BNX_TX_SLACK_SPACE,
 2320                     MCLBYTES, 0, BUS_DMA_NOWAIT,
 2321                     &sc->tx_mbuf_map[i])) {
 2322                         printf(": Could not create Tx mbuf %d DMA map!\n", i);
 2323                         rc = ENOMEM;
 2324                         goto bnx_dma_alloc_exit;
 2325                 }
 2326         }
 2327 
 2328         /*
 2329          * Allocate DMA memory for the Rx buffer descriptor chain,
 2330          * and fetch the physical address of the block.
 2331          */
 2332         for (i = 0; i < RX_PAGES; i++) {
 2333                 if (bus_dmamap_create(sc->bnx_dmatag, BNX_RX_CHAIN_PAGE_SZ, 1,
 2334                     BNX_RX_CHAIN_PAGE_SZ, 0, BUS_DMA_NOWAIT,
 2335                     &sc->rx_bd_chain_map[i])) {
 2336                         printf(": Could not create Rx desc %d DMA map!\n", i);
 2337                         rc = ENOMEM;
 2338                         goto bnx_dma_alloc_exit;
 2339                 }
 2340 
 2341                 if (bus_dmamem_alloc(sc->bnx_dmatag, BNX_RX_CHAIN_PAGE_SZ,
 2342                     BCM_PAGE_SIZE, BNX_DMA_BOUNDARY, &sc->rx_bd_chain_seg[i], 1,
 2343                     &sc->rx_bd_chain_rseg[i], BUS_DMA_NOWAIT)) {
 2344                         printf(": Could not allocate Rx desc %d DMA memory!\n", 
 2345                             i);
 2346                         rc = ENOMEM;
 2347                         goto bnx_dma_alloc_exit;
 2348                 }
 2349 
 2350                 if (bus_dmamem_map(sc->bnx_dmatag, &sc->rx_bd_chain_seg[i],
 2351                     sc->rx_bd_chain_rseg[i], BNX_RX_CHAIN_PAGE_SZ,
 2352                     (caddr_t *)&sc->rx_bd_chain[i], BUS_DMA_NOWAIT)) {
 2353                         printf(": Could not map Rx desc %d DMA memory!\n", i);
 2354                         rc = ENOMEM;
 2355                         goto bnx_dma_alloc_exit;
 2356                 }
 2357 
 2358                 if (bus_dmamap_load(sc->bnx_dmatag, sc->rx_bd_chain_map[i],
 2359                     (caddr_t)sc->rx_bd_chain[i], BNX_RX_CHAIN_PAGE_SZ, NULL,
 2360                     BUS_DMA_NOWAIT)) {
 2361                         printf(": Could not load Rx desc %d DMA memory!\n", i);
 2362                         rc = ENOMEM;
 2363                         goto bnx_dma_alloc_exit;
 2364                 }
 2365 
 2366                 bzero(sc->rx_bd_chain[i], BNX_RX_CHAIN_PAGE_SZ);
 2367                 sc->rx_bd_chain_paddr[i] =
 2368                     sc->rx_bd_chain_map[i]->dm_segs[0].ds_addr;
 2369 
 2370                 /* DRC - Fix for 64 bit systems. */
 2371                 DBPRINT(sc, BNX_INFO, "rx_bd_chain_paddr[%d] = 0x%08X\n", 
 2372                     i, (u_int32_t) sc->rx_bd_chain_paddr[i]);
 2373         }
 2374 
 2375         /*
 2376          * Create DMA maps for the Rx buffer mbufs.
 2377          */
 2378         for (i = 0; i < TOTAL_RX_BD; i++) {
 2379                 if (bus_dmamap_create(sc->bnx_dmatag, BNX_MAX_MRU,
 2380                     BNX_MAX_SEGMENTS, BNX_MAX_MRU, 0, BUS_DMA_NOWAIT,
 2381                     &sc->rx_mbuf_map[i])) {
 2382                         printf(": Could not create Rx mbuf %d DMA map!\n", i);
 2383                         rc = ENOMEM;
 2384                         goto bnx_dma_alloc_exit;
 2385                 }
 2386         }
 2387 
 2388  bnx_dma_alloc_exit:
 2389         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
 2390 
 2391         return(rc);
 2392 }
 2393 
 2394 /****************************************************************************/
 2395 /* Release all resources used by the driver.                                */
 2396 /*                                                                          */
 2397 /* Releases all resources acquired by the driver including interrupts,      */
 2398 /* interrupt handler, interfaces, mutexes, and DMA memory.                  */
 2399 /*                                                                          */
 2400 /* Returns:                                                                 */
 2401 /*   Nothing.                                                               */
 2402 /****************************************************************************/
 2403 void
 2404 bnx_release_resources(struct bnx_softc *sc)
 2405 {
 2406         struct pci_attach_args  *pa = &(sc->bnx_pa);
 2407 
 2408         DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
 2409 
 2410         bnx_dma_free(sc);
 2411 
 2412         if (sc->bnx_intrhand != NULL)
 2413                 pci_intr_disestablish(pa->pa_pc, sc->bnx_intrhand);
 2414 
 2415         if (sc->bnx_size)
 2416                 bus_space_unmap(sc->bnx_btag, sc->bnx_bhandle, sc->bnx_size);
 2417 
 2418         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
 2419 }
 2420 
 2421 /****************************************************************************/
 2422 /* Firmware synchronization.                                                */
 2423 /*                                                                          */
 2424 /* Before performing certain events such as a chip reset, synchronize with  */
 2425 /* the firmware first.                                                      */
 2426 /*                                                                          */
 2427 /* Returns:                                                                 */
 2428 /*   0 for success, positive value for failure.                             */
 2429 /****************************************************************************/
 2430 int
 2431 bnx_fw_sync(struct bnx_softc *sc, u_int32_t msg_data)
 2432 {
 2433         int                     i, rc = 0;
 2434         u_int32_t               val;
 2435 
 2436         /* Don't waste any time if we've timed out before. */
 2437         if (sc->bnx_fw_timed_out) {
 2438                 rc = EBUSY;
 2439                 goto bnx_fw_sync_exit;
 2440         }
 2441 
 2442         /* Increment the message sequence number. */
 2443         sc->bnx_fw_wr_seq++;
 2444         msg_data |= sc->bnx_fw_wr_seq;
 2445 
 2446         DBPRINT(sc, BNX_VERBOSE, "bnx_fw_sync(): msg_data = 0x%08X\n",
 2447             msg_data);
 2448 
 2449         /* Send the message to the bootcode driver mailbox. */
 2450         REG_WR_IND(sc, sc->bnx_shmem_base + BNX_DRV_MB, msg_data);
 2451 
 2452         /* Wait for the bootcode to acknowledge the message. */
 2453         for (i = 0; i < FW_ACK_TIME_OUT_MS; i++) {
 2454                 /* Check for a response in the bootcode firmware mailbox. */
 2455                 val = REG_RD_IND(sc, sc->bnx_shmem_base + BNX_FW_MB);
 2456                 if ((val & BNX_FW_MSG_ACK) == (msg_data & BNX_DRV_MSG_SEQ))
 2457                         break;
 2458                 DELAY(1000);
 2459         }
 2460 
 2461         /* If we've timed out, tell the bootcode that we've stopped waiting. */
 2462         if (((val & BNX_FW_MSG_ACK) != (msg_data & BNX_DRV_MSG_SEQ)) &&
 2463                 ((msg_data & BNX_DRV_MSG_DATA) != BNX_DRV_MSG_DATA_WAIT0)) {
 2464                 BNX_PRINTF(sc, "%s(%d): Firmware synchronization timeout! "
 2465                     "msg_data = 0x%08X\n", __FILE__, __LINE__, msg_data);
 2466 
 2467                 msg_data &= ~BNX_DRV_MSG_CODE;
 2468                 msg_data |= BNX_DRV_MSG_CODE_FW_TIMEOUT;
 2469 
 2470                 REG_WR_IND(sc, sc->bnx_shmem_base + BNX_DRV_MB, msg_data);
 2471 
 2472                 sc->bnx_fw_timed_out = 1;
 2473                 rc = EBUSY;
 2474         }
 2475 
 2476 bnx_fw_sync_exit:
 2477         return (rc);
 2478 }
 2479 
 2480 /****************************************************************************/
 2481 /* Load Receive Virtual 2 Physical (RV2P) processor firmware.               */
 2482 /*                                                                          */
 2483 /* Returns:                                                                 */
 2484 /*   Nothing.                                                               */
 2485 /****************************************************************************/
 2486 void
 2487 bnx_load_rv2p_fw(struct bnx_softc *sc, u_int32_t *rv2p_code, 
 2488     u_int32_t rv2p_code_len, u_int32_t rv2p_proc)
 2489 {
 2490         int                     i;
 2491         u_int32_t               val;
 2492 
 2493         for (i = 0; i < rv2p_code_len; i += 8) {
 2494                 REG_WR(sc, BNX_RV2P_INSTR_HIGH, *rv2p_code);
 2495                 rv2p_code++;
 2496                 REG_WR(sc, BNX_RV2P_INSTR_LOW, *rv2p_code);
 2497                 rv2p_code++;
 2498 
 2499                 if (rv2p_proc == RV2P_PROC1) {
 2500                         val = (i / 8) | BNX_RV2P_PROC1_ADDR_CMD_RDWR;
 2501                         REG_WR(sc, BNX_RV2P_PROC1_ADDR_CMD, val);
 2502                 }
 2503                 else {
 2504                         val = (i / 8) | BNX_RV2P_PROC2_ADDR_CMD_RDWR;
 2505                         REG_WR(sc, BNX_RV2P_PROC2_ADDR_CMD, val);
 2506                 }
 2507         }
 2508 
 2509         /* Reset the processor, un-stall is done later. */
 2510         if (rv2p_proc == RV2P_PROC1)
 2511                 REG_WR(sc, BNX_RV2P_COMMAND, BNX_RV2P_COMMAND_PROC1_RESET);
 2512         else
 2513                 REG_WR(sc, BNX_RV2P_COMMAND, BNX_RV2P_COMMAND_PROC2_RESET);
 2514 }
 2515 
 2516 /****************************************************************************/
 2517 /* Load RISC processor firmware.                                            */
 2518 /*                                                                          */
 2519 /* Loads firmware from the file if_bnxfw.h into the scratchpad memory       */
 2520 /* associated with a particular processor.                                  */
 2521 /*                                                                          */
 2522 /* Returns:                                                                 */
 2523 /*   Nothing.                                                               */
 2524 /****************************************************************************/
 2525 void
 2526 bnx_load_cpu_fw(struct bnx_softc *sc, struct cpu_reg *cpu_reg,
 2527     struct fw_info *fw)
 2528 {
 2529         u_int32_t               offset;
 2530         u_int32_t               val;
 2531 
 2532         /* Halt the CPU. */
 2533         val = REG_RD_IND(sc, cpu_reg->mode);
 2534         val |= cpu_reg->mode_value_halt;
 2535         REG_WR_IND(sc, cpu_reg->mode, val);
 2536         REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
 2537 
 2538         /* Load the Text area. */
 2539         offset = cpu_reg->spad_base + (fw->text_addr - cpu_reg->mips_view_base);
 2540         if (fw->text) {
 2541                 int j;
 2542 
 2543                 for (j = 0; j < (fw->text_len / 4); j++, offset += 4)
 2544                         REG_WR_IND(sc, offset, fw->text[j]);
 2545         }
 2546 
 2547         /* Load the Data area. */
 2548         offset = cpu_reg->spad_base + (fw->data_addr - cpu_reg->mips_view_base);
 2549         if (fw->data) {
 2550                 int j;
 2551 
 2552                 for (j = 0; j < (fw->data_len / 4); j++, offset += 4)
 2553                         REG_WR_IND(sc, offset, fw->data[j]);
 2554         }
 2555 
 2556         /* Load the SBSS area. */
 2557         offset = cpu_reg->spad_base + (fw->sbss_addr - cpu_reg->mips_view_base);
 2558         if (fw->sbss) {
 2559                 int j;
 2560 
 2561                 for (j = 0; j < (fw->sbss_len / 4); j++, offset += 4)
 2562                         REG_WR_IND(sc, offset, fw->sbss[j]);
 2563         }
 2564 
 2565         /* Load the BSS area. */
 2566         offset = cpu_reg->spad_base + (fw->bss_addr - cpu_reg->mips_view_base);
 2567         if (fw->bss) {
 2568                 int j;
 2569 
 2570                 for (j = 0; j < (fw->bss_len/4); j++, offset += 4)
 2571                         REG_WR_IND(sc, offset, fw->bss[j]);
 2572         }
 2573 
 2574         /* Load the Read-Only area. */
 2575         offset = cpu_reg->spad_base +
 2576             (fw->rodata_addr - cpu_reg->mips_view_base);
 2577         if (fw->rodata) {
 2578                 int j;
 2579 
 2580                 for (j = 0; j < (fw->rodata_len / 4); j++, offset += 4)
 2581                         REG_WR_IND(sc, offset, fw->rodata[j]);
 2582         }
 2583 
 2584         /* Clear the pre-fetch instruction. */
 2585         REG_WR_IND(sc, cpu_reg->inst, 0);
 2586         REG_WR_IND(sc, cpu_reg->pc, fw->start_addr);
 2587 
 2588         /* Start the CPU. */
 2589         val = REG_RD_IND(sc, cpu_reg->mode);
 2590         val &= ~cpu_reg->mode_value_halt;
 2591         REG_WR_IND(sc, cpu_reg->state, cpu_reg->state_value_clear);
 2592         REG_WR_IND(sc, cpu_reg->mode, val);
 2593 }
 2594 
 2595 /****************************************************************************/
 2596 /* Initialize the RV2P, RX, TX, TPAT, and COM CPUs.                         */
 2597 /*                                                                          */
 2598 /* Loads the firmware for each CPU and starts the CPU.                      */
 2599 /*                                                                          */
 2600 /* Returns:                                                                 */
 2601 /*   Nothing.                                                               */
 2602 /****************************************************************************/
 2603 void
 2604 bnx_init_cpus(struct bnx_softc *sc)
 2605 {
 2606         struct cpu_reg cpu_reg;
 2607         struct fw_info fw;
 2608 
 2609         /* Initialize the RV2P processor. */
 2610         bnx_load_rv2p_fw(sc, bnx_rv2p_proc1, bnx_rv2p_proc1len,
 2611             RV2P_PROC1);
 2612         bnx_load_rv2p_fw(sc, bnx_rv2p_proc2, bnx_rv2p_proc2len,
 2613             RV2P_PROC2);
 2614 
 2615         /* Initialize the RX Processor. */
 2616         cpu_reg.mode = BNX_RXP_CPU_MODE;
 2617         cpu_reg.mode_value_halt = BNX_RXP_CPU_MODE_SOFT_HALT;
 2618         cpu_reg.mode_value_sstep = BNX_RXP_CPU_MODE_STEP_ENA;
 2619         cpu_reg.state = BNX_RXP_CPU_STATE;
 2620         cpu_reg.state_value_clear = 0xffffff;
 2621         cpu_reg.gpr0 = BNX_RXP_CPU_REG_FILE;
 2622         cpu_reg.evmask = BNX_RXP_CPU_EVENT_MASK;
 2623         cpu_reg.pc = BNX_RXP_CPU_PROGRAM_COUNTER;
 2624         cpu_reg.inst = BNX_RXP_CPU_INSTRUCTION;
 2625         cpu_reg.bp = BNX_RXP_CPU_HW_BREAKPOINT;
 2626         cpu_reg.spad_base = BNX_RXP_SCRATCH;
 2627         cpu_reg.mips_view_base = 0x8000000;
 2628 
 2629         fw.ver_major = bnx_RXP_b06FwReleaseMajor;
 2630         fw.ver_minor = bnx_RXP_b06FwReleaseMinor;
 2631         fw.ver_fix = bnx_RXP_b06FwReleaseFix;
 2632         fw.start_addr = bnx_RXP_b06FwStartAddr;
 2633 
 2634         fw.text_addr = bnx_RXP_b06FwTextAddr;
 2635         fw.text_len = bnx_RXP_b06FwTextLen;
 2636         fw.text_index = 0;
 2637         fw.text = bnx_RXP_b06FwText;
 2638 
 2639         fw.data_addr = bnx_RXP_b06FwDataAddr;
 2640         fw.data_len = bnx_RXP_b06FwDataLen;
 2641         fw.data_index = 0;
 2642         fw.data = bnx_RXP_b06FwData;
 2643 
 2644         fw.sbss_addr = bnx_RXP_b06FwSbssAddr;
 2645         fw.sbss_len = bnx_RXP_b06FwSbssLen;
 2646         fw.sbss_index = 0;
 2647         fw.sbss = bnx_RXP_b06FwSbss;
 2648 
 2649         fw.bss_addr = bnx_RXP_b06FwBssAddr;
 2650         fw.bss_len = bnx_RXP_b06FwBssLen;
 2651         fw.bss_index = 0;
 2652         fw.bss = bnx_RXP_b06FwBss;
 2653 
 2654         fw.rodata_addr = bnx_RXP_b06FwRodataAddr;
 2655         fw.rodata_len = bnx_RXP_b06FwRodataLen;
 2656         fw.rodata_index = 0;
 2657         fw.rodata = bnx_RXP_b06FwRodata;
 2658 
 2659         DBPRINT(sc, BNX_INFO_RESET, "Loading RX firmware.\n");
 2660         bnx_load_cpu_fw(sc, &cpu_reg, &fw);
 2661 
 2662         /* Initialize the TX Processor. */
 2663         cpu_reg.mode = BNX_TXP_CPU_MODE;
 2664         cpu_reg.mode_value_halt = BNX_TXP_CPU_MODE_SOFT_HALT;
 2665         cpu_reg.mode_value_sstep = BNX_TXP_CPU_MODE_STEP_ENA;
 2666         cpu_reg.state = BNX_TXP_CPU_STATE;
 2667         cpu_reg.state_value_clear = 0xffffff;
 2668         cpu_reg.gpr0 = BNX_TXP_CPU_REG_FILE;
 2669         cpu_reg.evmask = BNX_TXP_CPU_EVENT_MASK;
 2670         cpu_reg.pc = BNX_TXP_CPU_PROGRAM_COUNTER;
 2671         cpu_reg.inst = BNX_TXP_CPU_INSTRUCTION;
 2672         cpu_reg.bp = BNX_TXP_CPU_HW_BREAKPOINT;
 2673         cpu_reg.spad_base = BNX_TXP_SCRATCH;
 2674         cpu_reg.mips_view_base = 0x8000000;
 2675 
 2676         fw.ver_major = bnx_TXP_b06FwReleaseMajor;
 2677         fw.ver_minor = bnx_TXP_b06FwReleaseMinor;
 2678         fw.ver_fix = bnx_TXP_b06FwReleaseFix;
 2679         fw.start_addr = bnx_TXP_b06FwStartAddr;
 2680 
 2681         fw.text_addr = bnx_TXP_b06FwTextAddr;
 2682         fw.text_len = bnx_TXP_b06FwTextLen;
 2683         fw.text_index = 0;
 2684         fw.text = bnx_TXP_b06FwText;
 2685 
 2686         fw.data_addr = bnx_TXP_b06FwDataAddr;
 2687         fw.data_len = bnx_TXP_b06FwDataLen;
 2688         fw.data_index = 0;
 2689         fw.data = bnx_TXP_b06FwData;
 2690 
 2691         fw.sbss_addr = bnx_TXP_b06FwSbssAddr;
 2692         fw.sbss_len = bnx_TXP_b06FwSbssLen;
 2693         fw.sbss_index = 0;
 2694         fw.sbss = bnx_TXP_b06FwSbss;
 2695 
 2696         fw.bss_addr = bnx_TXP_b06FwBssAddr;
 2697         fw.bss_len = bnx_TXP_b06FwBssLen;
 2698         fw.bss_index = 0;
 2699         fw.bss = bnx_TXP_b06FwBss;
 2700 
 2701         fw.rodata_addr = bnx_TXP_b06FwRodataAddr;
 2702         fw.rodata_len = bnx_TXP_b06FwRodataLen;
 2703         fw.rodata_index = 0;
 2704         fw.rodata = bnx_TXP_b06FwRodata;
 2705 
 2706         DBPRINT(sc, BNX_INFO_RESET, "Loading TX firmware.\n");
 2707         bnx_load_cpu_fw(sc, &cpu_reg, &fw);
 2708 
 2709         /* Initialize the TX Patch-up Processor. */
 2710         cpu_reg.mode = BNX_TPAT_CPU_MODE;
 2711         cpu_reg.mode_value_halt = BNX_TPAT_CPU_MODE_SOFT_HALT;
 2712         cpu_reg.mode_value_sstep = BNX_TPAT_CPU_MODE_STEP_ENA;
 2713         cpu_reg.state = BNX_TPAT_CPU_STATE;
 2714         cpu_reg.state_value_clear = 0xffffff;
 2715         cpu_reg.gpr0 = BNX_TPAT_CPU_REG_FILE;
 2716         cpu_reg.evmask = BNX_TPAT_CPU_EVENT_MASK;
 2717         cpu_reg.pc = BNX_TPAT_CPU_PROGRAM_COUNTER;
 2718         cpu_reg.inst = BNX_TPAT_CPU_INSTRUCTION;
 2719         cpu_reg.bp = BNX_TPAT_CPU_HW_BREAKPOINT;
 2720         cpu_reg.spad_base = BNX_TPAT_SCRATCH;
 2721         cpu_reg.mips_view_base = 0x8000000;
 2722 
 2723         fw.ver_major = bnx_TPAT_b06FwReleaseMajor;
 2724         fw.ver_minor = bnx_TPAT_b06FwReleaseMinor;
 2725         fw.ver_fix = bnx_TPAT_b06FwReleaseFix;
 2726         fw.start_addr = bnx_TPAT_b06FwStartAddr;
 2727 
 2728         fw.text_addr = bnx_TPAT_b06FwTextAddr;
 2729         fw.text_len = bnx_TPAT_b06FwTextLen;
 2730         fw.text_index = 0;
 2731         fw.text = bnx_TPAT_b06FwText;
 2732 
 2733         fw.data_addr = bnx_TPAT_b06FwDataAddr;
 2734         fw.data_len = bnx_TPAT_b06FwDataLen;
 2735         fw.data_index = 0;
 2736         fw.data = bnx_TPAT_b06FwData;
 2737 
 2738         fw.sbss_addr = bnx_TPAT_b06FwSbssAddr;
 2739         fw.sbss_len = bnx_TPAT_b06FwSbssLen;
 2740         fw.sbss_index = 0;
 2741         fw.sbss = bnx_TPAT_b06FwSbss;
 2742 
 2743         fw.bss_addr = bnx_TPAT_b06FwBssAddr;
 2744         fw.bss_len = bnx_TPAT_b06FwBssLen;
 2745         fw.bss_index = 0;
 2746         fw.bss = bnx_TPAT_b06FwBss;
 2747 
 2748         fw.rodata_addr = bnx_TPAT_b06FwRodataAddr;
 2749         fw.rodata_len = bnx_TPAT_b06FwRodataLen;
 2750         fw.rodata_index = 0;
 2751         fw.rodata = bnx_TPAT_b06FwRodata;
 2752 
 2753         DBPRINT(sc, BNX_INFO_RESET, "Loading TPAT firmware.\n");
 2754         bnx_load_cpu_fw(sc, &cpu_reg, &fw);
 2755 
 2756         /* Initialize the Completion Processor. */
 2757         cpu_reg.mode = BNX_COM_CPU_MODE;
 2758         cpu_reg.mode_value_halt = BNX_COM_CPU_MODE_SOFT_HALT;
 2759         cpu_reg.mode_value_sstep = BNX_COM_CPU_MODE_STEP_ENA;
 2760         cpu_reg.state = BNX_COM_CPU_STATE;
 2761         cpu_reg.state_value_clear = 0xffffff;
 2762         cpu_reg.gpr0 = BNX_COM_CPU_REG_FILE;
 2763         cpu_reg.evmask = BNX_COM_CPU_EVENT_MASK;
 2764         cpu_reg.pc = BNX_COM_CPU_PROGRAM_COUNTER;
 2765         cpu_reg.inst = BNX_COM_CPU_INSTRUCTION;
 2766         cpu_reg.bp = BNX_COM_CPU_HW_BREAKPOINT;
 2767         cpu_reg.spad_base = BNX_COM_SCRATCH;
 2768         cpu_reg.mips_view_base = 0x8000000;
 2769 
 2770         fw.ver_major = bnx_COM_b06FwReleaseMajor;
 2771         fw.ver_minor = bnx_COM_b06FwReleaseMinor;
 2772         fw.ver_fix = bnx_COM_b06FwReleaseFix;
 2773         fw.start_addr = bnx_COM_b06FwStartAddr;
 2774 
 2775         fw.text_addr = bnx_COM_b06FwTextAddr;
 2776         fw.text_len = bnx_COM_b06FwTextLen;
 2777         fw.text_index = 0;
 2778         fw.text = bnx_COM_b06FwText;
 2779 
 2780         fw.data_addr = bnx_COM_b06FwDataAddr;
 2781         fw.data_len = bnx_COM_b06FwDataLen;
 2782         fw.data_index = 0;
 2783         fw.data = bnx_COM_b06FwData;
 2784 
 2785         fw.sbss_addr = bnx_COM_b06FwSbssAddr;
 2786         fw.sbss_len = bnx_COM_b06FwSbssLen;
 2787         fw.sbss_index = 0;
 2788         fw.sbss = bnx_COM_b06FwSbss;
 2789 
 2790         fw.bss_addr = bnx_COM_b06FwBssAddr;
 2791         fw.bss_len = bnx_COM_b06FwBssLen;
 2792         fw.bss_index = 0;
 2793         fw.bss = bnx_COM_b06FwBss;
 2794 
 2795         fw.rodata_addr = bnx_COM_b06FwRodataAddr;
 2796         fw.rodata_len = bnx_COM_b06FwRodataLen;
 2797         fw.rodata_index = 0;
 2798         fw.rodata = bnx_COM_b06FwRodata;
 2799 
 2800         DBPRINT(sc, BNX_INFO_RESET, "Loading COM firmware.\n");
 2801         bnx_load_cpu_fw(sc, &cpu_reg, &fw);
 2802 }
 2803 
 2804 /****************************************************************************/
 2805 /* Initialize context memory.                                               */
 2806 /*                                                                          */
 2807 /* Clears the memory associated with each Context ID (CID).                 */
 2808 /*                                                                          */
 2809 /* Returns:                                                                 */
 2810 /*   Nothing.                                                               */
 2811 /****************************************************************************/
 2812 void
 2813 bnx_init_context(struct bnx_softc *sc)
 2814 {
 2815         u_int32_t               vcid;
 2816 
 2817         vcid = 96;
 2818         while (vcid) {
 2819                 u_int32_t vcid_addr, pcid_addr, offset;
 2820 
 2821                 vcid--;
 2822 
 2823                 vcid_addr = GET_CID_ADDR(vcid);
 2824                 pcid_addr = vcid_addr;
 2825 
 2826                 REG_WR(sc, BNX_CTX_VIRT_ADDR, 0x00);
 2827                 REG_WR(sc, BNX_CTX_PAGE_TBL, pcid_addr);
 2828 
 2829                 /* Zero out the context. */
 2830                 for (offset = 0; offset < PHY_CTX_SIZE; offset += 4)
 2831                         CTX_WR(sc, 0x00, offset, 0);
 2832 
 2833                 REG_WR(sc, BNX_CTX_VIRT_ADDR, vcid_addr);
 2834                 REG_WR(sc, BNX_CTX_PAGE_TBL, pcid_addr);
 2835         }
 2836 }
 2837 
 2838 /****************************************************************************/
 2839 /* Fetch the permanent MAC address of the controller.                       */
 2840 /*                                                                          */
 2841 /* Returns:                                                                 */
 2842 /*   Nothing.                                                               */
 2843 /****************************************************************************/
 2844 void
 2845 bnx_get_mac_addr(struct bnx_softc *sc)
 2846 {
 2847         u_int32_t               mac_lo = 0, mac_hi = 0;
 2848 
 2849         /*
 2850          * The NetXtreme II bootcode populates various NIC
 2851          * power-on and runtime configuration items in a
 2852          * shared memory area.  The factory configured MAC
 2853          * address is available from both NVRAM and the
 2854          * shared memory area so we'll read the value from
 2855          * shared memory for speed.
 2856          */
 2857 
 2858         mac_hi = REG_RD_IND(sc, sc->bnx_shmem_base + BNX_PORT_HW_CFG_MAC_UPPER);
 2859         mac_lo = REG_RD_IND(sc, sc->bnx_shmem_base + BNX_PORT_HW_CFG_MAC_LOWER);
 2860 
 2861         if ((mac_lo == 0) && (mac_hi == 0)) {
 2862                 BNX_PRINTF(sc, "%s(%d): Invalid Ethernet address!\n",
 2863                     __FILE__, __LINE__);
 2864         } else {
 2865                 sc->eaddr[0] = (u_char)(mac_hi >> 8);
 2866                 sc->eaddr[1] = (u_char)(mac_hi >> 0);
 2867                 sc->eaddr[2] = (u_char)(mac_lo >> 24);
 2868                 sc->eaddr[3] = (u_char)(mac_lo >> 16);
 2869                 sc->eaddr[4] = (u_char)(mac_lo >> 8);
 2870                 sc->eaddr[5] = (u_char)(mac_lo >> 0);
 2871         }
 2872 
 2873         DBPRINT(sc, BNX_INFO, "Permanent Ethernet address = "
 2874             "%6D\n", sc->eaddr, ":");
 2875 }
 2876 
 2877 /****************************************************************************/
 2878 /* Program the MAC address.                                                 */
 2879 /*                                                                          */
 2880 /* Returns:                                                                 */
 2881 /*   Nothing.                                                               */
 2882 /****************************************************************************/
 2883 void
 2884 bnx_set_mac_addr(struct bnx_softc *sc)
 2885 {
 2886         u_int32_t               val;
 2887         u_int8_t                *mac_addr = sc->eaddr;
 2888 
 2889         DBPRINT(sc, BNX_INFO, "Setting Ethernet address = "
 2890             "%6D\n", sc->eaddr, ":");
 2891 
 2892         val = (mac_addr[0] << 8) | mac_addr[1];
 2893 
 2894         REG_WR(sc, BNX_EMAC_MAC_MATCH0, val);
 2895 
 2896         val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
 2897                 (mac_addr[4] << 8) | mac_addr[5];
 2898 
 2899         REG_WR(sc, BNX_EMAC_MAC_MATCH1, val);
 2900 }
 2901 
 2902 /****************************************************************************/
 2903 /* Stop the controller.                                                     */
 2904 /*                                                                          */
 2905 /* Returns:                                                                 */
 2906 /*   Nothing.                                                               */
 2907 /****************************************************************************/
 2908 void
 2909 bnx_stop(struct bnx_softc *sc)
 2910 {
 2911         struct ifnet            *ifp = &sc->arpcom.ac_if;
 2912         struct mii_data         *mii = NULL;
 2913 
 2914         DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
 2915 
 2916         mii = &sc->bnx_mii;
 2917 
 2918         timeout_del(&sc->bnx_timeout);
 2919 
 2920         ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
 2921 
 2922         /* Disable the transmit/receive blocks. */
 2923         REG_WR(sc, BNX_MISC_ENABLE_CLR_BITS, 0x5ffffff);
 2924         REG_RD(sc, BNX_MISC_ENABLE_CLR_BITS);
 2925         DELAY(20);
 2926 
 2927         bnx_disable_intr(sc);
 2928 
 2929         /* Tell firmware that the driver is going away. */
 2930         bnx_reset(sc, BNX_DRV_MSG_CODE_SUSPEND_NO_WOL);
 2931 
 2932         /* Free the RX lists. */
 2933         bnx_free_rx_chain(sc);
 2934 
 2935         /* Free TX buffers. */
 2936         bnx_free_tx_chain(sc);
 2937 
 2938         ifp->if_timer = 0;
 2939 
 2940         sc->bnx_link = 0;
 2941 
 2942         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
 2943 
 2944         bnx_mgmt_init(sc);
 2945 }
 2946 
 2947 int
 2948 bnx_reset(struct bnx_softc *sc, u_int32_t reset_code)
 2949 {
 2950         u_int32_t               val;
 2951         int                     i, rc = 0;
 2952 
 2953         DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
 2954 
 2955         /* Wait for pending PCI transactions to complete. */
 2956         REG_WR(sc, BNX_MISC_ENABLE_CLR_BITS,
 2957             BNX_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE |
 2958             BNX_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE |
 2959             BNX_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE |
 2960             BNX_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE);
 2961         val = REG_RD(sc, BNX_MISC_ENABLE_CLR_BITS);
 2962         DELAY(5);
 2963 
 2964         /* Assume bootcode is running. */
 2965         sc->bnx_fw_timed_out = 0;
 2966 
 2967         /* Give the firmware a chance to prepare for the reset. */
 2968         rc = bnx_fw_sync(sc, BNX_DRV_MSG_DATA_WAIT0 | reset_code);
 2969         if (rc)
 2970                 goto bnx_reset_exit;
 2971 
 2972         /* Set a firmware reminder that this is a soft reset. */
 2973         REG_WR_IND(sc, sc->bnx_shmem_base + BNX_DRV_RESET_SIGNATURE,
 2974             BNX_DRV_RESET_SIGNATURE_MAGIC);
 2975 
 2976         /* Dummy read to force the chip to complete all current transactions. */
 2977         val = REG_RD(sc, BNX_MISC_ID);
 2978 
 2979         /* Chip reset. */
 2980         val = BNX_PCICFG_MISC_CONFIG_CORE_RST_REQ |
 2981             BNX_PCICFG_MISC_CONFIG_REG_WINDOW_ENA |
 2982             BNX_PCICFG_MISC_CONFIG_TARGET_MB_WORD_SWAP;
 2983         REG_WR(sc, BNX_PCICFG_MISC_CONFIG, val);
 2984 
 2985         /* Allow up to 30us for reset to complete. */
 2986         for (i = 0; i < 10; i++) {
 2987                 val = REG_RD(sc, BNX_PCICFG_MISC_CONFIG);
 2988                 if ((val & (BNX_PCICFG_MISC_CONFIG_CORE_RST_REQ |
 2989                     BNX_PCICFG_MISC_CONFIG_CORE_RST_BSY)) == 0)
 2990                         break;
 2991 
 2992                 DELAY(10);
 2993         }
 2994 
 2995         /* Check that reset completed successfully. */
 2996         if (val & (BNX_PCICFG_MISC_CONFIG_CORE_RST_REQ |
 2997             BNX_PCICFG_MISC_CONFIG_CORE_RST_BSY)) {
 2998                 BNX_PRINTF(sc, "%s(%d): Reset failed!\n", __FILE__, __LINE__);
 2999                 rc = EBUSY;
 3000                 goto bnx_reset_exit;
 3001         }
 3002 
 3003         /* Make sure byte swapping is properly configured. */
 3004         val = REG_RD(sc, BNX_PCI_SWAP_DIAG0);
 3005         if (val != 0x01020304) {
 3006                 BNX_PRINTF(sc, "%s(%d): Byte swap is incorrect!\n",
 3007                     __FILE__, __LINE__);
 3008                 rc = ENODEV;
 3009                 goto bnx_reset_exit;
 3010         }
 3011 
 3012         /* Just completed a reset, assume that firmware is running again. */
 3013         sc->bnx_fw_timed_out = 0;
 3014 
 3015         /* Wait for the firmware to finish its initialization. */
 3016         rc = bnx_fw_sync(sc, BNX_DRV_MSG_DATA_WAIT1 | reset_code);
 3017         if (rc)
 3018                 BNX_PRINTF(sc, "%s(%d): Firmware did not complete "
 3019                     "initialization!\n", __FILE__, __LINE__);
 3020 
 3021 bnx_reset_exit:
 3022         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
 3023 
 3024         return (rc);
 3025 }
 3026 
 3027 int
 3028 bnx_chipinit(struct bnx_softc *sc)
 3029 {
 3030         struct pci_attach_args  *pa = &(sc->bnx_pa);
 3031         u_int32_t               val;
 3032         int                     rc = 0;
 3033 
 3034         DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
 3035 
 3036         /* Make sure the interrupt is not active. */
 3037         REG_WR(sc, BNX_PCICFG_INT_ACK_CMD, BNX_PCICFG_INT_ACK_CMD_MASK_INT);
 3038 
 3039         /* Initialize DMA byte/word swapping, configure the number of DMA  */
 3040         /* channels and PCI clock compensation delay.                      */
 3041         val = BNX_DMA_CONFIG_DATA_BYTE_SWAP |
 3042             BNX_DMA_CONFIG_DATA_WORD_SWAP |
 3043 #if BYTE_ORDER == BIG_ENDIAN
 3044             BNX_DMA_CONFIG_CNTL_BYTE_SWAP |
 3045 #endif
 3046             BNX_DMA_CONFIG_CNTL_WORD_SWAP |
 3047             DMA_READ_CHANS << 12 |
 3048             DMA_WRITE_CHANS << 16;
 3049 
 3050         val |= (0x2 << 20) | BNX_DMA_CONFIG_CNTL_PCI_COMP_DLY;
 3051 
 3052         if ((sc->bnx_flags & BNX_PCIX_FLAG) && (sc->bus_speed_mhz == 133))
 3053                 val |= BNX_DMA_CONFIG_PCI_FAST_CLK_CMP;
 3054 
 3055         /*
 3056          * This setting resolves a problem observed on certain Intel PCI
 3057          * chipsets that cannot handle multiple outstanding DMA operations.
 3058          * See errata E9_5706A1_65.
 3059          */
 3060         if ((BNX_CHIP_NUM(sc) == BNX_CHIP_NUM_5706) &&
 3061             (BNX_CHIP_ID(sc) != BNX_CHIP_ID_5706_A0) &&
 3062             !(sc->bnx_flags & BNX_PCIX_FLAG))
 3063                 val |= BNX_DMA_CONFIG_CNTL_PING_PONG_DMA;
 3064 
 3065         REG_WR(sc, BNX_DMA_CONFIG, val);
 3066 
 3067         /* Clear the PCI-X relaxed ordering bit. See errata E3_5708CA0_570. */
 3068         if (sc->bnx_flags & BNX_PCIX_FLAG) {
 3069                 u_int16_t val;
 3070 
 3071                 val = pci_conf_read(pa->pa_pc, pa->pa_tag, BNX_PCI_PCIX_CMD);
 3072                 pci_conf_write(pa->pa_pc, pa->pa_tag, BNX_PCI_PCIX_CMD,
 3073                     val & ~0x2);
 3074         }
 3075 
 3076         /* Enable the RX_V2P and Context state machines before access. */
 3077         REG_WR(sc, BNX_MISC_ENABLE_SET_BITS,
 3078             BNX_MISC_ENABLE_SET_BITS_HOST_COALESCE_ENABLE |
 3079             BNX_MISC_ENABLE_STATUS_BITS_RX_V2P_ENABLE |
 3080             BNX_MISC_ENABLE_STATUS_BITS_CONTEXT_ENABLE);
 3081 
 3082         /* Initialize context mapping and zero out the quick contexts. */
 3083         bnx_init_context(sc);
 3084 
 3085         /* Initialize the on-boards CPUs */
 3086         bnx_init_cpus(sc);
 3087 
 3088         /* Prepare NVRAM for access. */
 3089         if (bnx_init_nvram(sc)) {
 3090                 rc = ENODEV;
 3091                 goto bnx_chipinit_exit;
 3092         }
 3093 
 3094         /* Set the kernel bypass block size */
 3095         val = REG_RD(sc, BNX_MQ_CONFIG);
 3096         val &= ~BNX_MQ_CONFIG_KNL_BYP_BLK_SIZE;
 3097         val |= BNX_MQ_CONFIG_KNL_BYP_BLK_SIZE_256;
 3098         REG_WR(sc, BNX_MQ_CONFIG, val);
 3099 
 3100         val = 0x10000 + (MAX_CID_CNT * MB_KERNEL_CTX_SIZE);
 3101         REG_WR(sc, BNX_MQ_KNL_BYP_WIND_START, val);
 3102         REG_WR(sc, BNX_MQ_KNL_WIND_END, val);
 3103 
 3104         val = (BCM_PAGE_BITS - 8) << 24;
 3105         REG_WR(sc, BNX_RV2P_CONFIG, val);
 3106 
 3107         /* Configure page size. */
 3108         val = REG_RD(sc, BNX_TBDR_CONFIG);
 3109         val &= ~BNX_TBDR_CONFIG_PAGE_SIZE;
 3110         val |= (BCM_PAGE_BITS - 8) << 24 | 0x40;
 3111         REG_WR(sc, BNX_TBDR_CONFIG, val);
 3112 
 3113 bnx_chipinit_exit:
 3114         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
 3115 
 3116         return(rc);
 3117 }
 3118 
 3119 /****************************************************************************/
 3120 /* Initialize the controller in preparation to send/receive traffic.        */
 3121 /*                                                                          */
 3122 /* Returns:                                                                 */
 3123 /*   0 for success, positive value for failure.                             */
 3124 /****************************************************************************/
 3125 int
 3126 bnx_blockinit(struct bnx_softc *sc)
 3127 {
 3128         u_int32_t               reg, val;
 3129         int                     rc = 0;
 3130 
 3131         DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
 3132 
 3133         /* Load the hardware default MAC address. */
 3134         bnx_set_mac_addr(sc);
 3135 
 3136         /* Set the Ethernet backoff seed value */
 3137         val = sc->eaddr[0] + (sc->eaddr[1] << 8) + (sc->eaddr[2] << 16) +
 3138             (sc->eaddr[3]) + (sc->eaddr[4] << 8) + (sc->eaddr[5] << 16);
 3139         REG_WR(sc, BNX_EMAC_BACKOFF_SEED, val);
 3140 
 3141         sc->last_status_idx = 0;
 3142         sc->rx_mode = BNX_EMAC_RX_MODE_SORT_MODE;
 3143 
 3144         /* Set up link change interrupt generation. */
 3145         REG_WR(sc, BNX_EMAC_ATTENTION_ENA, BNX_EMAC_ATTENTION_ENA_LINK);
 3146 
 3147         /* Program the physical address of the status block. */
 3148         REG_WR(sc, BNX_HC_STATUS_ADDR_L, (u_int32_t)(sc->status_block_paddr));
 3149         REG_WR(sc, BNX_HC_STATUS_ADDR_H,
 3150             (u_int32_t)((u_int64_t)sc->status_block_paddr >> 32));
 3151 
 3152         /* Program the physical address of the statistics block. */
 3153         REG_WR(sc, BNX_HC_STATISTICS_ADDR_L,
 3154             (u_int32_t)(sc->stats_block_paddr));
 3155         REG_WR(sc, BNX_HC_STATISTICS_ADDR_H,
 3156             (u_int32_t)((u_int64_t)sc->stats_block_paddr >> 32));
 3157 
 3158         /* Program various host coalescing parameters. */
 3159         REG_WR(sc, BNX_HC_TX_QUICK_CONS_TRIP, (sc->bnx_tx_quick_cons_trip_int
 3160             << 16) | sc->bnx_tx_quick_cons_trip);
 3161         REG_WR(sc, BNX_HC_RX_QUICK_CONS_TRIP, (sc->bnx_rx_quick_cons_trip_int
 3162             << 16) | sc->bnx_rx_quick_cons_trip);
 3163         REG_WR(sc, BNX_HC_COMP_PROD_TRIP, (sc->bnx_comp_prod_trip_int << 16) |
 3164             sc->bnx_comp_prod_trip);
 3165         REG_WR(sc, BNX_HC_TX_TICKS, (sc->bnx_tx_ticks_int << 16) |
 3166             sc->bnx_tx_ticks);
 3167         REG_WR(sc, BNX_HC_RX_TICKS, (sc->bnx_rx_ticks_int << 16) |
 3168             sc->bnx_rx_ticks);
 3169         REG_WR(sc, BNX_HC_COM_TICKS, (sc->bnx_com_ticks_int << 16) |
 3170             sc->bnx_com_ticks);
 3171         REG_WR(sc, BNX_HC_CMD_TICKS, (sc->bnx_cmd_ticks_int << 16) |
 3172             sc->bnx_cmd_ticks);
 3173         REG_WR(sc, BNX_HC_STATS_TICKS, (sc->bnx_stats_ticks & 0xffff00));
 3174         REG_WR(sc, BNX_HC_STAT_COLLECT_TICKS, 0xbb8);  /* 3ms */
 3175         REG_WR(sc, BNX_HC_CONFIG,
 3176             (BNX_HC_CONFIG_RX_TMR_MODE | BNX_HC_CONFIG_TX_TMR_MODE |
 3177             BNX_HC_CONFIG_COLLECT_STATS));
 3178 
 3179         /* Clear the internal statistics counters. */
 3180         REG_WR(sc, BNX_HC_COMMAND, BNX_HC_COMMAND_CLR_STAT_NOW);
 3181 
 3182         /* Verify that bootcode is running. */
 3183         reg = REG_RD_IND(sc, sc->bnx_shmem_base + BNX_DEV_INFO_SIGNATURE);
 3184 
 3185         DBRUNIF(DB_RANDOMTRUE(bnx_debug_bootcode_running_failure),
 3186             BNX_PRINTF(sc, "%s(%d): Simulating bootcode failure.\n",
 3187             __FILE__, __LINE__); reg = 0);
 3188 
 3189         if ((reg & BNX_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
 3190             BNX_DEV_INFO_SIGNATURE_MAGIC) {
 3191                 BNX_PRINTF(sc, "%s(%d): Bootcode not running! Found: 0x%08X, "
 3192                     "Expected: 08%08X\n", __FILE__, __LINE__,
 3193                     (reg & BNX_DEV_INFO_SIGNATURE_MAGIC_MASK),
 3194                     BNX_DEV_INFO_SIGNATURE_MAGIC);
 3195                 rc = ENODEV;
 3196                 goto bnx_blockinit_exit;
 3197         }
 3198 
 3199         /* Check if any management firmware is running. */
 3200         reg = REG_RD_IND(sc, sc->bnx_shmem_base + BNX_PORT_FEATURE);
 3201         if (reg & (BNX_PORT_FEATURE_ASF_ENABLED |
 3202             BNX_PORT_FEATURE_IMD_ENABLED)) {
 3203                 DBPRINT(sc, BNX_INFO, "Management F/W Enabled.\n");
 3204                 sc->bnx_flags |= BNX_MFW_ENABLE_FLAG;
 3205         }
 3206 
 3207         sc->bnx_fw_ver = REG_RD_IND(sc, sc->bnx_shmem_base +
 3208             BNX_DEV_INFO_BC_REV);
 3209 
 3210         DBPRINT(sc, BNX_INFO, "bootcode rev = 0x%08X\n", sc->bnx_fw_ver);
 3211 
 3212         /* Allow bootcode to apply any additional fixes before enabling MAC. */
 3213         rc = bnx_fw_sync(sc, BNX_DRV_MSG_DATA_WAIT2 | BNX_DRV_MSG_CODE_RESET);
 3214 
 3215         /* Enable link state change interrupt generation. */
 3216         REG_WR(sc, BNX_HC_ATTN_BITS_ENABLE, STATUS_ATTN_BITS_LINK_STATE);
 3217 
 3218         /* Enable all remaining blocks in the MAC. */
 3219         REG_WR(sc, BNX_MISC_ENABLE_SET_BITS, 0x5ffffff);
 3220         REG_RD(sc, BNX_MISC_ENABLE_SET_BITS);
 3221         DELAY(20);
 3222 
 3223 bnx_blockinit_exit:
 3224         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
 3225 
 3226         return (rc);
 3227 }
 3228 
 3229 /****************************************************************************/
 3230 /* Encapsulate an mbuf cluster into the rx_bd chain.                        */
 3231 /*                                                                          */
 3232 /* The NetXtreme II can support Jumbo frames by using multiple rx_bd's.     */
 3233 /* This routine will map an mbuf cluster into 1 or more rx_bd's as          */
 3234 /* necessary.                                                               */
 3235 /*                                                                          */
 3236 /* Returns:                                                                 */
 3237 /*   0 for success, positive value for failure.                             */
 3238 /****************************************************************************/
 3239 int
 3240 bnx_get_buf(struct bnx_softc *sc, struct mbuf *m, u_int16_t *prod,
 3241     u_int16_t *chain_prod, u_int32_t *prod_bseq)
 3242 {
 3243         bus_dmamap_t            map;
 3244         struct mbuf             *m_new = NULL;
 3245         struct rx_bd            *rxbd;
 3246         int                     i, rc = 0;
 3247         u_int32_t               addr;
 3248 #ifdef BNX_DEBUG
 3249         u_int16_t               debug_chain_prod = *chain_prod;
 3250 #endif
 3251         u_int16_t               first_chain_prod;
 3252 
 3253         DBPRINT(sc, (BNX_VERBOSE_RESET | BNX_VERBOSE_RECV), "Entering %s()\n", 
 3254             __FUNCTION__);
 3255 
 3256         /* Make sure the inputs are valid. */
 3257         DBRUNIF((*chain_prod > MAX_RX_BD),
 3258             printf("%s: RX producer out of range: 0x%04X > 0x%04X\n",
 3259             *chain_prod, (u_int16_t) MAX_RX_BD));
 3260 
 3261         DBPRINT(sc, BNX_VERBOSE_RECV, "%s(enter): prod = 0x%04X, chain_prod = "
 3262             "0x%04X, prod_bseq = 0x%08X\n", __FUNCTION__, *prod, *chain_prod,
 3263             *prod_bseq);
 3264 
 3265         if (m == NULL) {
 3266                 DBRUNIF(DB_RANDOMTRUE(bnx_debug_mbuf_allocation_failure),
 3267                     BNX_PRINTF(sc, "Simulating mbuf allocation failure.\n");
 3268 
 3269                         sc->mbuf_alloc_failed++;
 3270                         rc = ENOBUFS;
 3271                         goto bnx_get_buf_exit);
 3272 
 3273                 /* This is a new mbuf allocation. */
 3274                 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
 3275                 if (m_new == NULL) {
 3276                         DBPRINT(sc, BNX_WARN,
 3277                             "%s(%d): RX mbuf header allocation failed!\n", 
 3278                             __FILE__, __LINE__);
 3279 
 3280                         DBRUNIF(1, sc->mbuf_alloc_failed++);
 3281 
 3282                         rc = ENOBUFS;
 3283                         goto bnx_get_buf_exit;
 3284                 }
 3285 
 3286                 DBRUNIF(1, sc->rx_mbuf_alloc++);
 3287                 MCLGET(m_new, M_DONTWAIT);
 3288                 if (!(m_new->m_flags & M_EXT)) {
 3289                         DBPRINT(sc, BNX_WARN,
 3290                             "%s(%d): RX mbuf chain allocation failed!\n", 
 3291                             __FILE__, __LINE__);
 3292                         
 3293                         m_freem(m_new);
 3294 
 3295                         DBRUNIF(1, sc->rx_mbuf_alloc--);
 3296                         DBRUNIF(1, sc->mbuf_alloc_failed++);
 3297 
 3298                         rc = ENOBUFS;
 3299                         goto bnx_get_buf_exit;
 3300                 }
 3301                         
 3302                 m_new->m_len = m_new->m_pkthdr.len = sc->mbuf_alloc_size;
 3303         } else {
 3304                 m_new = m;
 3305                 m_new->m_len = m_new->m_pkthdr.len = sc->mbuf_alloc_size;
 3306                 m_new->m_data = m_new->m_ext.ext_buf;
 3307         }
 3308 
 3309         /* Map the mbuf cluster into device memory. */
 3310         map = sc->rx_mbuf_map[*chain_prod];
 3311         first_chain_prod = *chain_prod;
 3312         if (bus_dmamap_load_mbuf(sc->bnx_dmatag, map, m_new, BUS_DMA_NOWAIT)) {
 3313                 BNX_PRINTF(sc, "%s(%d): Error mapping mbuf into RX chain!\n",
 3314                     __FILE__, __LINE__);
 3315 
 3316                 m_freem(m_new);
 3317 
 3318                 DBRUNIF(1, sc->rx_mbuf_alloc--);
 3319 
 3320                 rc = ENOBUFS;
 3321                 goto bnx_get_buf_exit;
 3322         }
 3323 
 3324         /* Watch for overflow. */
 3325         DBRUNIF((sc->free_rx_bd > USABLE_RX_BD),
 3326             printf("%s: Too many free rx_bd (0x%04X > 0x%04X)!\n", 
 3327             sc->free_rx_bd, (u_int16_t) USABLE_RX_BD));
 3328 
 3329         DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark), 
 3330             sc->rx_low_watermark = sc->free_rx_bd);
 3331 
 3332         /* Setup the rx_bd for the first segment. */
 3333         rxbd = &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
 3334 
 3335         addr = (u_int32_t)(map->dm_segs[0].ds_addr);
 3336         rxbd->rx_bd_haddr_lo = htole32(addr);
 3337         addr = (u_int32_t)((u_int64_t)map->dm_segs[0].ds_addr >> 32);
 3338         rxbd->rx_bd_haddr_hi = htole32(addr);
 3339         rxbd->rx_bd_len = htole32(map->dm_segs[0].ds_len);
 3340         rxbd->rx_bd_flags = htole32(RX_BD_FLAGS_START);
 3341         *prod_bseq += map->dm_segs[0].ds_len;
 3342 
 3343         for (i = 1; i < map->dm_nsegs; i++) {
 3344                 *prod = NEXT_RX_BD(*prod);
 3345                 *chain_prod = RX_CHAIN_IDX(*prod); 
 3346 
 3347                 rxbd =
 3348                     &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)];
 3349 
 3350                 addr = (u_int32_t)(map->dm_segs[i].ds_addr);
 3351                 rxbd->rx_bd_haddr_lo = htole32(addr);
 3352                 addr = (u_int32_t)((u_int64_t)map->dm_segs[i].ds_addr >> 32);
 3353                 rxbd->rx_bd_haddr_hi = htole32(addr);
 3354                 rxbd->rx_bd_len = htole32(map->dm_segs[i].ds_len);
 3355                 rxbd->rx_bd_flags = 0;
 3356                 *prod_bseq += map->dm_segs[i].ds_len;
 3357         }
 3358 
 3359         rxbd->rx_bd_flags |= htole32(RX_BD_FLAGS_END);
 3360 
 3361         /*
 3362          * Save the mbuf, adjust the map pointer (swap map for first and
 3363          * last rx_bd entry so that rx_mbuf_ptr and rx_mbuf_map matches)
 3364          * and update our counter.
 3365          */
 3366         sc->rx_mbuf_ptr[*chain_prod] = m_new;
 3367         sc->rx_mbuf_map[first_chain_prod] = sc->rx_mbuf_map[*chain_prod];
 3368         sc->rx_mbuf_map[*chain_prod] = map;
 3369         sc->free_rx_bd -= map->dm_nsegs;
 3370 
 3371         DBRUN(BNX_VERBOSE_RECV, bnx_dump_rx_mbuf_chain(sc, debug_chain_prod, 
 3372             map->dm_nsegs));
 3373 
 3374         DBPRINT(sc, BNX_VERBOSE_RECV, "%s(exit): prod = 0x%04X, chain_prod "
 3375             "= 0x%04X, prod_bseq = 0x%08X\n", __FUNCTION__, *prod,
 3376             *chain_prod, *prod_bseq);
 3377 
 3378 bnx_get_buf_exit:
 3379         DBPRINT(sc, (BNX_VERBOSE_RESET | BNX_VERBOSE_RECV), "Exiting %s()\n", 
 3380             __FUNCTION__);
 3381 
 3382         return(rc);
 3383 }
 3384 
 3385 /****************************************************************************/
 3386 /* Allocate memory and initialize the TX data structures.                   */
 3387 /*                                                                          */
 3388 /* Returns:                                                                 */
 3389 /*   0 for success, positive value for failure.                             */
 3390 /****************************************************************************/
 3391 int
 3392 bnx_init_tx_chain(struct bnx_softc *sc)
 3393 {
 3394         struct tx_bd            *txbd;
 3395         u_int32_t               val, addr;
 3396         int                     i, rc = 0;
 3397 
 3398         DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
 3399 
 3400         /* Set the initial TX producer/consumer indices. */
 3401         sc->tx_prod = 0;
 3402         sc->tx_cons = 0;
 3403         sc->tx_prod_bseq = 0;
 3404         sc->used_tx_bd = 0;
 3405         DBRUNIF(1, sc->tx_hi_watermark = USABLE_TX_BD);
 3406 
 3407         /*
 3408          * The NetXtreme II supports a linked-list structure called
 3409          * a Buffer Descriptor Chain (or BD chain).  A BD chain
 3410          * consists of a series of 1 or more chain pages, each of which
 3411          * consists of a fixed number of BD entries.
 3412          * The last BD entry on each page is a pointer to the next page
 3413          * in the chain, and the last pointer in the BD chain
 3414          * points back to the beginning of the chain.
 3415          */
 3416 
 3417         /* Set the TX next pointer chain entries. */
 3418         for (i = 0; i < TX_PAGES; i++) {
 3419                 int j;
 3420 
 3421                 txbd = &sc->tx_bd_chain[i][USABLE_TX_BD_PER_PAGE];
 3422 
 3423                 /* Check if we've reached the last page. */
 3424                 if (i == (TX_PAGES - 1))
 3425                         j = 0;
 3426                 else
 3427                         j = i + 1;
 3428 
 3429                 addr = (u_int32_t)(sc->tx_bd_chain_paddr[j]);
 3430                 txbd->tx_bd_haddr_lo = htole32(addr);
 3431                 addr = (u_int32_t)((u_int64_t)sc->tx_bd_chain_paddr[j] >> 32);
 3432                 txbd->tx_bd_haddr_hi = htole32(addr);
 3433         }
 3434 
 3435         /*
 3436          * Initialize the context ID for an L2 TX chain.
 3437          */
 3438         val = BNX_L2CTX_TYPE_TYPE_L2;
 3439         val |= BNX_L2CTX_TYPE_SIZE_L2;
 3440         CTX_WR(sc, GET_CID_ADDR(TX_CID), BNX_L2CTX_TYPE, val);
 3441 
 3442         val = BNX_L2CTX_CMD_TYPE_TYPE_L2 | (8 << 16);
 3443         CTX_WR(sc, GET_CID_ADDR(TX_CID), BNX_L2CTX_CMD_TYPE, val);
 3444 
 3445         /* Point the hardware to the first page in the chain. */
 3446         val = (u_int32_t)((u_int64_t)sc->tx_bd_chain_paddr[0] >> 32);
 3447         CTX_WR(sc, GET_CID_ADDR(TX_CID), BNX_L2CTX_TBDR_BHADDR_HI, val);
 3448         val = (u_int32_t)(sc->tx_bd_chain_paddr[0]);
 3449         CTX_WR(sc, GET_CID_ADDR(TX_CID), BNX_L2CTX_TBDR_BHADDR_LO, val);
 3450 
 3451         DBRUN(BNX_VERBOSE_SEND, bnx_dump_tx_chain(sc, 0, TOTAL_TX_BD));
 3452 
 3453         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
 3454 
 3455         return(rc);
 3456 }
 3457 
 3458 /****************************************************************************/
 3459 /* Free memory and clear the TX data structures.                            */
 3460 /*                                                                          */
 3461 /* Returns:                                                                 */
 3462 /*   Nothing.                                                               */
 3463 /****************************************************************************/
 3464 void
 3465 bnx_free_tx_chain(struct bnx_softc *sc)
 3466 {
 3467         int                     i;
 3468 
 3469         DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
 3470 
 3471         /* Unmap, unload, and free any mbufs still in the TX mbuf chain. */
 3472         for (i = 0; i < TOTAL_TX_BD; i++) {
 3473                 if (sc->tx_mbuf_ptr[i] != NULL) {
 3474                         if (sc->tx_mbuf_map != NULL)
 3475                                 bus_dmamap_sync(sc->bnx_dmatag,
 3476                                     sc->tx_mbuf_map[i], 0,
 3477                                     sc->tx_mbuf_map[i]->dm_mapsize,
 3478                                     BUS_DMASYNC_POSTWRITE);
 3479                         m_freem(sc->tx_mbuf_ptr[i]);
 3480                         sc->tx_mbuf_ptr[i] = NULL;
 3481                         DBRUNIF(1, sc->tx_mbuf_alloc--);
 3482                 }                       
 3483         }
 3484 
 3485         /* Clear each TX chain page. */
 3486         for (i = 0; i < TX_PAGES; i++)
 3487                 bzero((char *)sc->tx_bd_chain[i], BNX_TX_CHAIN_PAGE_SZ);
 3488 
 3489         /* Check if we lost any mbufs in the process. */
 3490         DBRUNIF((sc->tx_mbuf_alloc),
 3491             printf("%s: Memory leak! Lost %d mbufs from tx chain!\n",
 3492             sc->tx_mbuf_alloc));
 3493 
 3494         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
 3495 }
 3496 
 3497 /****************************************************************************/
 3498 /* Allocate memory and initialize the RX data structures.                   */
 3499 /*                                                                          */
 3500 /* Returns:                                                                 */
 3501 /*   0 for success, positive value for failure.                             */
 3502 /****************************************************************************/
 3503 int
 3504 bnx_init_rx_chain(struct bnx_softc *sc)
 3505 {
 3506         struct rx_bd            *rxbd;
 3507         int                     i, rc = 0;
 3508         u_int16_t               prod, chain_prod;
 3509         u_int32_t               prod_bseq, val, addr;
 3510 
 3511         DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
 3512 
 3513         /* Initialize the RX producer and consumer indices. */
 3514         sc->rx_prod = 0;
 3515         sc->rx_cons = 0;
 3516         sc->rx_prod_bseq = 0;
 3517         sc->free_rx_bd = BNX_RX_SLACK_SPACE;
 3518         DBRUNIF(1, sc->rx_low_watermark = USABLE_RX_BD);
 3519 
 3520         /* Initialize the RX next pointer chain entries. */
 3521         for (i = 0; i < RX_PAGES; i++) {
 3522                 int j;
 3523 
 3524                 rxbd = &sc->rx_bd_chain[i][USABLE_RX_BD_PER_PAGE];
 3525 
 3526                 /* Check if we've reached the last page. */
 3527                 if (i == (RX_PAGES - 1))
 3528                         j = 0;
 3529                 else
 3530                         j = i + 1;
 3531 
 3532                 /* Setup the chain page pointers. */
 3533                 addr = (u_int32_t)((u_int64_t)sc->rx_bd_chain_paddr[j] >> 32);
 3534                 rxbd->rx_bd_haddr_hi = htole32(addr);
 3535                 addr = (u_int32_t)(sc->rx_bd_chain_paddr[j]);
 3536                 rxbd->rx_bd_haddr_lo = htole32(addr);
 3537         }
 3538 
 3539         /* Initialize the context ID for an L2 RX chain. */
 3540         val = BNX_L2CTX_CTX_TYPE_CTX_BD_CHN_TYPE_VALUE;
 3541         val |= BNX_L2CTX_CTX_TYPE_SIZE_L2;
 3542         val |= 0x02 << 8;
 3543         CTX_WR(sc, GET_CID_ADDR(RX_CID), BNX_L2CTX_CTX_TYPE, val);
 3544 
 3545         /* Point the hardware to the first page in the chain. */
 3546         val = (u_int32_t)((u_int64_t)sc->rx_bd_chain_paddr[0] >> 32);
 3547         CTX_WR(sc, GET_CID_ADDR(RX_CID), BNX_L2CTX_NX_BDHADDR_HI, val);
 3548         val = (u_int32_t)(sc->rx_bd_chain_paddr[0]);
 3549         CTX_WR(sc, GET_CID_ADDR(RX_CID), BNX_L2CTX_NX_BDHADDR_LO, val);
 3550 
 3551         /* Allocate mbuf clusters for the rx_bd chain. */
 3552         prod = prod_bseq = 0;
 3553         while (prod < BNX_RX_SLACK_SPACE) {
 3554                 chain_prod = RX_CHAIN_IDX(prod);
 3555                 if (bnx_get_buf(sc, NULL, &prod, &chain_prod, &prod_bseq)) {
 3556                         BNX_PRINTF(sc, "Error filling RX chain: rx_bd[0x%04X]!\n",
 3557                                 chain_prod);
 3558                         rc = ENOBUFS;
 3559                         break;
 3560                 }
 3561                 prod = NEXT_RX_BD(prod);
 3562         }
 3563 
 3564         /* Save the RX chain producer index. */
 3565         sc->rx_prod = prod;
 3566         sc->rx_prod_bseq = prod_bseq;
 3567 
 3568         for (i = 0; i < RX_PAGES; i++)
 3569                 bus_dmamap_sync(sc->bnx_dmatag, sc->rx_bd_chain_map[i], 0,
 3570                     sc->rx_bd_chain_map[i]->dm_mapsize,
 3571                     BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
 3572 
 3573         /* Tell the chip about the waiting rx_bd's. */
 3574         REG_WR16(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BDIDX, sc->rx_prod);
 3575         REG_WR(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BSEQ, sc->rx_prod_bseq);
 3576 
 3577         DBRUN(BNX_VERBOSE_RECV, bnx_dump_rx_chain(sc, 0, TOTAL_RX_BD));
 3578 
 3579         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
 3580 
 3581         return(rc);
 3582 }
 3583 
 3584 /****************************************************************************/
 3585 /* Free memory and clear the RX data structures.                            */
 3586 /*                                                                          */
 3587 /* Returns:                                                                 */
 3588 /*   Nothing.                                                               */
 3589 /****************************************************************************/
 3590 void
 3591 bnx_free_rx_chain(struct bnx_softc *sc)
 3592 {
 3593         int                     i;
 3594 
 3595         DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
 3596 
 3597         /* Free any mbufs still in the RX mbuf chain. */
 3598         for (i = 0; i < TOTAL_RX_BD; i++) {
 3599                 if (sc->rx_mbuf_ptr[i] != NULL) {
 3600                         if (sc->rx_mbuf_map[i] != NULL)
 3601                                 bus_dmamap_sync(sc->bnx_dmatag,
 3602                                     sc->rx_mbuf_map[i], 0,
 3603                                     sc->rx_mbuf_map[i]->dm_mapsize,
 3604                                     BUS_DMASYNC_POSTREAD);
 3605                         m_freem(sc->rx_mbuf_ptr[i]);
 3606                         sc->rx_mbuf_ptr[i] = NULL;
 3607                         DBRUNIF(1, sc->rx_mbuf_alloc--);
 3608                 }
 3609         }
 3610 
 3611         /* Clear each RX chain page. */
 3612         for (i = 0; i < RX_PAGES; i++)
 3613                 bzero((char *)sc->rx_bd_chain[i], BNX_RX_CHAIN_PAGE_SZ);
 3614 
 3615         /* Check if we lost any mbufs in the process. */
 3616         DBRUNIF((sc->rx_mbuf_alloc),
 3617             printf("%s: Memory leak! Lost %d mbufs from rx chain!\n",
 3618             sc->rx_mbuf_alloc));
 3619 
 3620         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
 3621 }
 3622 
 3623 /****************************************************************************/
 3624 /* Set media options.                                                       */
 3625 /*                                                                          */
 3626 /* Returns:                                                                 */
 3627 /*   0 for success, positive value for failure.                             */
 3628 /****************************************************************************/
 3629 int
 3630 bnx_ifmedia_upd(struct ifnet *ifp)
 3631 {
 3632         struct bnx_softc        *sc;
 3633         struct mii_data         *mii;
 3634         struct ifmedia          *ifm;
 3635         int                     rc = 0;
 3636 
 3637         sc = ifp->if_softc;
 3638         ifm = &sc->bnx_ifmedia;
 3639 
 3640         /* DRC - ToDo: Add SerDes support. */
 3641 
 3642         mii = &sc->bnx_mii;
 3643         sc->bnx_link = 0;
 3644         if (mii->mii_instance) {
 3645                 struct mii_softc *miisc;
 3646                 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
 3647                         mii_phy_reset(miisc);
 3648         }
 3649         mii_mediachg(mii);
 3650 
 3651         return(rc);
 3652 }
 3653 
 3654 /****************************************************************************/
 3655 /* Reports current media status.                                            */
 3656 /*                                                                          */
 3657 /* Returns:                                                                 */
 3658 /*   Nothing.                                                               */
 3659 /****************************************************************************/
 3660 void
 3661 bnx_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
 3662 {
 3663         struct bnx_softc        *sc;
 3664         struct mii_data         *mii;
 3665         int                     s;
 3666 
 3667         sc = ifp->if_softc;
 3668 
 3669         s = splnet();
 3670 
 3671         mii = &sc->bnx_mii;
 3672 
 3673         /* DRC - ToDo: Add SerDes support. */
 3674 
 3675         mii_pollstat(mii);
 3676         ifmr->ifm_active = mii->mii_media_active;
 3677         ifmr->ifm_status = mii->mii_media_status;
 3678 
 3679         splx(s);
 3680 }
 3681 
 3682 /****************************************************************************/
 3683 /* Handles PHY generated interrupt events.                                  */
 3684 /*                                                                          */
 3685 /* Returns:                                                                 */
 3686 /*   Nothing.                                                               */
 3687 /****************************************************************************/
 3688 void
 3689 bnx_phy_intr(struct bnx_softc *sc)
 3690 {
 3691         u_int32_t               new_link_state, old_link_state;
 3692 
 3693         new_link_state = sc->status_block->status_attn_bits &
 3694             STATUS_ATTN_BITS_LINK_STATE;
 3695         old_link_state = sc->status_block->status_attn_bits_ack &
 3696             STATUS_ATTN_BITS_LINK_STATE;
 3697 
 3698         /* Handle any changes if the link state has changed. */
 3699         if (new_link_state != old_link_state) {
 3700                 DBRUN(BNX_VERBOSE_INTR, bnx_dump_status_block(sc));
 3701 
 3702                 sc->bnx_link = 0;
 3703                 timeout_del(&sc->bnx_timeout);
 3704                 bnx_tick(sc);
 3705 
 3706                 /* Update the status_attn_bits_ack field in the status block. */
 3707                 if (new_link_state) {
 3708                         REG_WR(sc, BNX_PCICFG_STATUS_BIT_SET_CMD,
 3709                             STATUS_ATTN_BITS_LINK_STATE);
 3710                         DBPRINT(sc, BNX_INFO, "Link is now UP.\n");
 3711                 } else {
 3712                         REG_WR(sc, BNX_PCICFG_STATUS_BIT_CLEAR_CMD,
 3713                             STATUS_ATTN_BITS_LINK_STATE);
 3714                         DBPRINT(sc, BNX_INFO, "Link is now DOWN.\n");
 3715                 }
 3716         }
 3717 
 3718         /* Acknowledge the link change interrupt. */
 3719         REG_WR(sc, BNX_EMAC_STATUS, BNX_EMAC_STATUS_LINK_CHANGE);
 3720 }
 3721 
 3722 /****************************************************************************/
 3723 /* Handles received frame interrupt events.                                 */
 3724 /*                                                                          */
 3725 /* Returns:                                                                 */
 3726 /*   Nothing.                                                               */
 3727 /****************************************************************************/
 3728 void
 3729 bnx_rx_intr(struct bnx_softc *sc)
 3730 {
 3731         struct status_block     *sblk = sc->status_block;
 3732         struct ifnet            *ifp = &sc->arpcom.ac_if;
 3733         u_int16_t               hw_cons, sw_cons, sw_chain_cons;
 3734         u_int16_t               sw_prod, sw_chain_prod;
 3735         u_int32_t               sw_prod_bseq;
 3736         struct l2_fhdr          *l2fhdr;
 3737         int                     i;
 3738 
 3739         DBRUNIF(1, sc->rx_interrupts++);
 3740 
 3741         /* Prepare the RX chain pages to be accessed by the host CPU. */
 3742         for (i = 0; i < RX_PAGES; i++)
 3743                 bus_dmamap_sync(sc->bnx_dmatag,
 3744                     sc->rx_bd_chain_map[i], 0,
 3745                     sc->rx_bd_chain_map[i]->dm_mapsize,
 3746                     BUS_DMASYNC_POSTWRITE);
 3747 
 3748         /* Get the hardware's view of the RX consumer index. */
 3749         hw_cons = sc->hw_rx_cons = sblk->status_rx_quick_consumer_index0;
 3750         if ((hw_cons & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
 3751                 hw_cons++;
 3752 
 3753         /* Get working copies of the driver's view of the RX indices. */
 3754         sw_cons = sc->rx_cons;
 3755         sw_prod = sc->rx_prod;
 3756         sw_prod_bseq = sc->rx_prod_bseq;
 3757 
 3758         DBPRINT(sc, BNX_INFO_RECV, "%s(enter): sw_prod = 0x%04X, "
 3759             "sw_cons = 0x%04X, sw_prod_bseq = 0x%08X\n",
 3760             __FUNCTION__, sw_prod, sw_cons, sw_prod_bseq);
 3761 
 3762         /* Prevent speculative reads from getting ahead of the status block. */
 3763         bus_space_barrier(sc->bnx_btag, sc->bnx_bhandle, 0, 0,
 3764             BUS_SPACE_BARRIER_READ);
 3765 
 3766         DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark),
 3767             sc->rx_low_watermark = sc->free_rx_bd);
 3768 
 3769         /* 
 3770          * Scan through the receive chain as long 
 3771          * as there is work to do.
 3772          */
 3773         while (sw_cons != hw_cons) {
 3774                 struct mbuf *m;
 3775                 struct rx_bd *rxbd;
 3776                 unsigned int len;
 3777                 u_int32_t status;
 3778 
 3779                 /* Convert the producer/consumer indices to an actual
 3780                  * rx_bd index.
 3781                  */
 3782                 sw_chain_cons = RX_CHAIN_IDX(sw_cons);
 3783                 sw_chain_prod = RX_CHAIN_IDX(sw_prod);
 3784 
 3785                 /* Get the used rx_bd. */
 3786                 rxbd = &sc->rx_bd_chain[RX_PAGE(sw_chain_cons)][RX_IDX(sw_chain_cons)];
 3787                 sc->free_rx_bd++;
 3788         
 3789                 DBRUN(BNX_VERBOSE_RECV, printf("%s(): ", __FUNCTION__); 
 3790                 bnx_dump_rxbd(sc, sw_chain_cons, rxbd));
 3791 
 3792                 /* The mbuf is stored with the last rx_bd entry of a packet. */
 3793                 if (sc->rx_mbuf_ptr[sw_chain_cons] != NULL) {
 3794                         /* Validate that this is the last rx_bd. */
 3795                         DBRUNIF((!(rxbd->rx_bd_flags & RX_BD_FLAGS_END)),
 3796                             printf("%s: Unexpected mbuf found in "
 3797                                 "rx_bd[0x%04X]!\n", sw_chain_cons);
 3798                                 bnx_breakpoint(sc));
 3799 
 3800                         /* DRC - ToDo: If the received packet is small, say less
 3801                          *             than 128 bytes, allocate a new mbuf here,
 3802                          *             copy the data to that mbuf, and recycle
 3803                          *             the mapped jumbo frame.
 3804                          */
 3805 
 3806                         /* Unmap the mbuf from DMA space. */
 3807                         bus_dmamap_sync(sc->bnx_dmatag,
 3808                             sc->rx_mbuf_map[sw_chain_cons], 0,
 3809                             sc->rx_mbuf_map[sw_chain_cons]->dm_mapsize,
 3810                             BUS_DMASYNC_POSTREAD);
 3811                         bus_dmamap_unload(sc->bnx_dmatag,
 3812                             sc->rx_mbuf_map[sw_chain_cons]);
 3813 
 3814                         /* Remove the mbuf from the driver's chain. */
 3815                         m = sc->rx_mbuf_ptr[sw_chain_cons];
 3816                         sc->rx_mbuf_ptr[sw_chain_cons] = NULL;
 3817 
 3818                         /*
 3819                          * Frames received on the NetXteme II are prepended 
 3820                          * with the l2_fhdr structure which provides status
 3821                          * information about the received frame (including
 3822                          * VLAN tags and checksum info) and are also
 3823                          * automatically adjusted to align the IP header
 3824                          * (i.e. two null bytes are inserted before the 
 3825                          * Ethernet header).
 3826                          */
 3827                         l2fhdr = mtod(m, struct l2_fhdr *);
 3828 
 3829                         len    = l2fhdr->l2_fhdr_pkt_len;
 3830                         status = l2fhdr->l2_fhdr_status;
 3831 
 3832                         DBRUNIF(DB_RANDOMTRUE(bnx_debug_l2fhdr_status_check),
 3833                             printf("Simulating l2_fhdr status error.\n");
 3834                             status = status | L2_FHDR_ERRORS_PHY_DECODE);
 3835 
 3836                         /* Watch for unusual sized frames. */
 3837                         DBRUNIF(((len < BNX_MIN_MTU) ||
 3838                             (len > BNX_MAX_JUMBO_ETHER_MTU_VLAN)),
 3839                             printf("%s: Unusual frame size found. "
 3840                             "Min(%d), Actual(%d), Max(%d)\n", (int)BNX_MIN_MTU,
 3841                             len, (int) BNX_MAX_JUMBO_ETHER_MTU_VLAN);
 3842 
 3843                         bnx_dump_mbuf(sc, m);
 3844                         bnx_breakpoint(sc));
 3845 
 3846                         len -= ETHER_CRC_LEN;
 3847 
 3848                         /* Check the received frame for errors. */
 3849                         if (status &  (L2_FHDR_ERRORS_BAD_CRC | 
 3850                             L2_FHDR_ERRORS_PHY_DECODE |
 3851                             L2_FHDR_ERRORS_ALIGNMENT | 
 3852                             L2_FHDR_ERRORS_TOO_SHORT |
 3853                             L2_FHDR_ERRORS_GIANT_FRAME)) {
 3854                                 ifp->if_ierrors++;
 3855                                 DBRUNIF(1, sc->l2fhdr_status_errors++);
 3856 
 3857                                 /* Reuse the mbuf for a new frame. */
 3858                                 if (bnx_get_buf(sc, m, &sw_prod,
 3859                                     &sw_chain_prod, &sw_prod_bseq)) {
 3860                                         DBRUNIF(1, bnx_breakpoint(sc));
 3861                                         panic("%s: Can't reuse RX mbuf!\n",
 3862                                             sc->bnx_dev.dv_xname);
 3863                                 }
 3864                                 goto bnx_rx_int_next_rx;
 3865                         }
 3866 
 3867                         /* 
 3868                          * Get a new mbuf for the rx_bd.   If no new
 3869                          * mbufs are available then reuse the current mbuf,
 3870                          * log an ierror on the interface, and generate
 3871                          * an error in the system log.
 3872                          */
 3873                         if (bnx_get_buf(sc, NULL, &sw_prod, &sw_chain_prod,
 3874                             &sw_prod_bseq)) {
 3875                                 DBRUN(BNX_WARN, BNX_PRINTF(sc, "Failed to allocate "
 3876                                         "new mbuf, incoming frame dropped!\n"));
 3877 
 3878                                 ifp->if_ierrors++;
 3879 
 3880                                 /* Try and reuse the exisitng mbuf. */
 3881                                 if (bnx_get_buf(sc, m, &sw_prod,
 3882                                     &sw_chain_prod, &sw_prod_bseq)) {
 3883                                         DBRUNIF(1, bnx_breakpoint(sc));
 3884                                         panic("%s: Double mbuf allocation "
 3885                                             "failure!", sc->bnx_dev.dv_xname);
 3886                                 }
 3887                                 goto bnx_rx_int_next_rx;
 3888                         }
 3889 
 3890                         /* Skip over the l2_fhdr when passing the data up
 3891                          * the stack.
 3892                          */
 3893                         m_adj(m, sizeof(struct l2_fhdr) + ETHER_ALIGN);
 3894 
 3895                         /* Adjust the pckt length to match the received data. */
 3896                         m->m_pkthdr.len = m->m_len = len;
 3897 
 3898                         /* Send the packet to the appropriate interface. */
 3899                         m->m_pkthdr.rcvif = ifp;
 3900 
 3901                         DBRUN(BNX_VERBOSE_RECV,
 3902                             struct ether_header *eh;
 3903                             eh = mtod(m, struct ether_header *);
 3904                             printf("%s: to: %6D, from: %6D, type: 0x%04X\n",
 3905                             __FUNCTION__, eh->ether_dhost, ":", 
 3906                             eh->ether_shost, ":", htons(eh->ether_type)));
 3907 
 3908                         /* Validate the checksum. */
 3909 
 3910                         /* Check for an IP datagram. */
 3911                         if (status & L2_FHDR_STATUS_IP_DATAGRAM) {
 3912                                 /* Check if the IP checksum is valid. */
 3913                                 if ((l2fhdr->l2_fhdr_ip_xsum ^ 0xffff)
 3914                                     == 0)
 3915                                         m->m_pkthdr.csum_flags |=
 3916                                             M_IPV4_CSUM_IN_OK;
 3917                                 else
 3918                                         DBPRINT(sc, BNX_WARN_SEND, 
 3919                                             "%s(): Invalid IP checksum "
 3920                                                 "= 0x%04X!\n",
 3921                                                 __FUNCTION__,
 3922                                                 l2fhdr->l2_fhdr_ip_xsum
 3923                                                 );
 3924                         }
 3925 
 3926                         /* Check for a valid TCP/UDP frame. */
 3927                         if (status & (L2_FHDR_STATUS_TCP_SEGMENT |
 3928                             L2_FHDR_STATUS_UDP_DATAGRAM)) {
 3929                                 /* Check for a good TCP/UDP checksum. */
 3930                                 if ((status &
 3931                                     (L2_FHDR_ERRORS_TCP_XSUM |
 3932                                     L2_FHDR_ERRORS_UDP_XSUM)) == 0) {
 3933                                         m->m_pkthdr.csum_flags |=
 3934                                             M_TCP_CSUM_IN_OK |
 3935                                             M_UDP_CSUM_IN_OK;
 3936                                 } else {
 3937                                         DBPRINT(sc, BNX_WARN_SEND, 
 3938                                             "%s(): Invalid TCP/UDP "
 3939                                             "checksum = 0x%04X!\n",
 3940                                             __FUNCTION__,
 3941                                             l2fhdr->l2_fhdr_tcp_udp_xsum);
 3942                                 }
 3943                         }
 3944 
 3945                         /*
 3946                          * If we received a packet with a vlan tag,
 3947                          * attach that information to the packet.
 3948                          */
 3949                         if ((status & L2_FHDR_STATUS_L2_VLAN_TAG) &&
 3950                             !(sc->rx_mode & BNX_EMAC_RX_MODE_KEEP_VLAN_TAG)) {
 3951 #if NVLAN > 0
 3952                                 struct ether_vlan_header vh;
 3953 
 3954                                 DBPRINT(sc, BNX_VERBOSE_SEND,
 3955                                     "%s(): VLAN tag = 0x%04X\n",
 3956                                     __FUNCTION__,
 3957                                     l2fhdr->l2_fhdr_vlan_tag);
 3958 
 3959                                 if (m->m_pkthdr.len < ETHER_HDR_LEN) {
 3960                                         m_freem(m);
 3961                                         goto bnx_rx_int_next_rx;
 3962                                 }
 3963                                 m_copydata(m, 0, ETHER_HDR_LEN, (caddr_t)&vh);
 3964                                 vh.evl_proto = vh.evl_encap_proto;
 3965                                 vh.evl_tag = htons(l2fhdr->l2_fhdr_vlan_tag);
 3966                                 vh.evl_encap_proto = htons(ETHERTYPE_VLAN);
 3967                                 m_adj(m, ETHER_HDR_LEN);
 3968                                 M_PREPEND(m, sizeof(vh), M_DONTWAIT);
 3969                                 if (m == NULL)
 3970                                         goto bnx_rx_int_next_rx;
 3971                                 m_copyback(m, 0, sizeof(vh), &vh);
 3972 #else
 3973                                 m_freem(m);
 3974                                 goto bnx_rx_int_next_rx;
 3975 #endif                  
 3976                         }
 3977 
 3978 #if NBPFILTER > 0
 3979                         /*
 3980                          * Handle BPF listeners. Let the BPF
 3981                          * user see the packet.
 3982                          */
 3983                         if (ifp->if_bpf)
 3984                                 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
 3985 #endif
 3986 
 3987                         /* Pass the mbuf off to the upper layers. */
 3988                         ifp->if_ipackets++;
 3989                         DBPRINT(sc, BNX_VERBOSE_RECV,
 3990                             "%s(): Passing received frame up.\n", __FUNCTION__);
 3991                         ether_input_mbuf(ifp, m);
 3992                         DBRUNIF(1, sc->rx_mbuf_alloc--);
 3993 
 3994 bnx_rx_int_next_rx:
 3995                         sw_prod = NEXT_RX_BD(sw_prod);
 3996                 }
 3997 
 3998                 sw_cons = NEXT_RX_BD(sw_cons);
 3999 
 4000                 /* Refresh hw_cons to see if there's new work */
 4001                 if (sw_cons == hw_cons) {
 4002                         hw_cons = sc->hw_rx_cons =
 4003                             sblk->status_rx_quick_consumer_index0;
 4004                         if ((hw_cons & USABLE_RX_BD_PER_PAGE) ==
 4005                             USABLE_RX_BD_PER_PAGE)
 4006                                 hw_cons++;
 4007                 }
 4008 
 4009                 /* Prevent speculative reads from getting ahead of
 4010                  * the status block.
 4011                  */
 4012                 bus_space_barrier(sc->bnx_btag, sc->bnx_bhandle, 0, 0, 
 4013                     BUS_SPACE_BARRIER_READ);
 4014         }
 4015 
 4016         for (i = 0; i < RX_PAGES; i++)
 4017                 bus_dmamap_sync(sc->bnx_dmatag,
 4018                     sc->rx_bd_chain_map[i], 0,
 4019                     sc->rx_bd_chain_map[i]->dm_mapsize,
 4020                     BUS_DMASYNC_PREWRITE);
 4021 
 4022         sc->rx_cons = sw_cons;
 4023         sc->rx_prod = sw_prod;
 4024         sc->rx_prod_bseq = sw_prod_bseq;
 4025 
 4026         REG_WR16(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BDIDX, sc->rx_prod);
 4027         REG_WR(sc, MB_RX_CID_ADDR + BNX_L2CTX_HOST_BSEQ, sc->rx_prod_bseq);
 4028 
 4029         DBPRINT(sc, BNX_INFO_RECV, "%s(exit): rx_prod = 0x%04X, "
 4030             "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n",
 4031             __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq);
 4032 }
 4033 
 4034 /****************************************************************************/
 4035 /* Handles transmit completion interrupt events.                            */
 4036 /*                                                                          */
 4037 /* Returns:                                                                 */
 4038 /*   Nothing.                                                               */
 4039 /****************************************************************************/
 4040 void
 4041 bnx_tx_intr(struct bnx_softc *sc)
 4042 {
 4043         struct status_block     *sblk = sc->status_block;
 4044         struct ifnet            *ifp = &sc->arpcom.ac_if;
 4045         u_int16_t               hw_tx_cons, sw_tx_cons, sw_tx_chain_cons;
 4046 
 4047         DBRUNIF(1, sc->tx_interrupts++);
 4048 
 4049         /* Get the hardware's view of the TX consumer index. */
 4050         hw_tx_cons = sc->hw_tx_cons = sblk->status_tx_quick_consumer_index0;
 4051 
 4052         /* Skip to the next entry if this is a chain page pointer. */
 4053         if ((hw_tx_cons & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
 4054                 hw_tx_cons++;
 4055 
 4056         sw_tx_cons = sc->tx_cons;
 4057 
 4058         /* Prevent speculative reads from getting ahead of the status block. */
 4059         bus_space_barrier(sc->bnx_btag, sc->bnx_bhandle, 0, 0, 
 4060             BUS_SPACE_BARRIER_READ);
 4061 
 4062         /* Cycle through any completed TX chain page entries. */
 4063         while (sw_tx_cons != hw_tx_cons) {
 4064 #ifdef BNX_DEBUG
 4065                 struct tx_bd *txbd = NULL;
 4066 #endif
 4067                 sw_tx_chain_cons = TX_CHAIN_IDX(sw_tx_cons);
 4068 
 4069                 DBPRINT(sc, BNX_INFO_SEND, "%s(): hw_tx_cons = 0x%04X, "
 4070                     "sw_tx_cons = 0x%04X, sw_tx_chain_cons = 0x%04X\n",
 4071                     __FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons);
 4072 
 4073                 DBRUNIF((sw_tx_chain_cons > MAX_TX_BD),
 4074                     printf("%s: TX chain consumer out of range! "
 4075                     " 0x%04X > 0x%04X\n", sw_tx_chain_cons, (int)MAX_TX_BD);
 4076                     bnx_breakpoint(sc));
 4077 
 4078                 DBRUNIF(1, txbd = &sc->tx_bd_chain
 4079                     [TX_PAGE(sw_tx_chain_cons)][TX_IDX(sw_tx_chain_cons)]);
 4080                 
 4081                 DBRUNIF((txbd == NULL),
 4082                     printf("%s: Unexpected NULL tx_bd[0x%04X]!\n", 
 4083                     sw_tx_chain_cons);
 4084                     bnx_breakpoint(sc));
 4085 
 4086                 DBRUN(BNX_INFO_SEND, printf("%s: ", __FUNCTION__);
 4087                     bnx_dump_txbd(sc, sw_tx_chain_cons, txbd));
 4088 
 4089                 /*
 4090                  * Free the associated mbuf. Remember
 4091                  * that only the last tx_bd of a packet
 4092                  * has an mbuf pointer and DMA map.
 4093                  */
 4094                 if (sc->tx_mbuf_ptr[sw_tx_chain_cons] != NULL) {
 4095                         /* Validate that this is the last tx_bd. */
 4096                         DBRUNIF((!(txbd->tx_bd_flags & TX_BD_FLAGS_END)),
 4097                             printf("%s: tx_bd END flag not set but "
 4098                             "txmbuf == NULL!\n");
 4099                             bnx_breakpoint(sc));
 4100 
 4101                         DBRUN(BNX_INFO_SEND,
 4102                             printf("%s: Unloading map/freeing mbuf "
 4103                             "from tx_bd[0x%04X]\n",
 4104                             __FUNCTION__, sw_tx_chain_cons));
 4105 
 4106                         /* Unmap the mbuf. */
 4107                         bus_dmamap_unload(sc->bnx_dmatag,
 4108                             sc->tx_mbuf_map[sw_tx_chain_cons]);
 4109         
 4110                         /* Free the mbuf. */
 4111                         m_freem(sc->tx_mbuf_ptr[sw_tx_chain_cons]);
 4112                         sc->tx_mbuf_ptr[sw_tx_chain_cons] = NULL;
 4113                         DBRUNIF(1, sc->tx_mbuf_alloc--);
 4114 
 4115                         ifp->if_opackets++;
 4116                 }
 4117 
 4118                 sc->used_tx_bd--;
 4119                 sw_tx_cons = NEXT_TX_BD(sw_tx_cons);
 4120 
 4121                 /* Refresh hw_cons to see if there's new work. */
 4122                 hw_tx_cons = sc->hw_tx_cons =
 4123                     sblk->status_tx_quick_consumer_index0;
 4124                 if ((hw_tx_cons & USABLE_TX_BD_PER_PAGE) ==
 4125                     USABLE_TX_BD_PER_PAGE)
 4126                         hw_tx_cons++;
 4127 
 4128                 /* Prevent speculative reads from getting ahead of
 4129                  * the status block.
 4130                  */
 4131                 bus_space_barrier(sc->bnx_btag, sc->bnx_bhandle, 0, 0, 
 4132                     BUS_SPACE_BARRIER_READ);
 4133         }
 4134 
 4135         /* Clear the TX timeout timer. */
 4136         ifp->if_timer = 0;
 4137 
 4138         /* Clear the tx hardware queue full flag. */
 4139         if ((sc->used_tx_bd + BNX_TX_SLACK_SPACE) < USABLE_TX_BD) {
 4140                 DBRUNIF((ifp->if_flags & IFF_OACTIVE),
 4141                     printf("%s: TX chain is open for business! Used "
 4142                     "tx_bd = %d\n", sc->used_tx_bd));
 4143                 ifp->if_flags &= ~IFF_OACTIVE;
 4144         }
 4145 
 4146         sc->tx_cons = sw_tx_cons;
 4147 }
 4148 
 4149 /****************************************************************************/
 4150 /* Disables interrupt generation.                                           */
 4151 /*                                                                          */
 4152 /* Returns:                                                                 */
 4153 /*   Nothing.                                                               */
 4154 /****************************************************************************/
 4155 void
 4156 bnx_disable_intr(struct bnx_softc *sc)
 4157 {
 4158         REG_WR(sc, BNX_PCICFG_INT_ACK_CMD, BNX_PCICFG_INT_ACK_CMD_MASK_INT);
 4159         REG_RD(sc, BNX_PCICFG_INT_ACK_CMD);
 4160 }
 4161 
 4162 /****************************************************************************/
 4163 /* Enables interrupt generation.                                            */
 4164 /*                                                                          */
 4165 /* Returns:                                                                 */
 4166 /*   Nothing.                                                               */
 4167 /****************************************************************************/
 4168 void
 4169 bnx_enable_intr(struct bnx_softc *sc)
 4170 {
 4171         u_int32_t               val;
 4172 
 4173         REG_WR(sc, BNX_PCICFG_INT_ACK_CMD, BNX_PCICFG_INT_ACK_CMD_INDEX_VALID |
 4174             BNX_PCICFG_INT_ACK_CMD_MASK_INT | sc->last_status_idx);
 4175 
 4176         REG_WR(sc, BNX_PCICFG_INT_ACK_CMD, BNX_PCICFG_INT_ACK_CMD_INDEX_VALID | 
 4177             sc->last_status_idx);
 4178 
 4179         val = REG_RD(sc, BNX_HC_COMMAND);
 4180         REG_WR(sc, BNX_HC_COMMAND, val | BNX_HC_COMMAND_COAL_NOW);
 4181 }
 4182 
 4183 /****************************************************************************/
 4184 /* Handles controller initialization.                                       */
 4185 /*                                                                          */
 4186 /* Returns:                                                                 */
 4187 /*   Nothing.                                                               */
 4188 /****************************************************************************/
 4189 void
 4190 bnx_init(void *xsc)
 4191 {
 4192         struct bnx_softc        *sc = (struct bnx_softc *)xsc;
 4193         struct ifnet            *ifp = &sc->arpcom.ac_if;
 4194         u_int32_t               ether_mtu;
 4195         int                     s;
 4196 
 4197         DBPRINT(sc, BNX_VERBOSE_RESET, "Entering %s()\n", __FUNCTION__);
 4198 
 4199         s = splnet();
 4200 
 4201         bnx_stop(sc);
 4202 
 4203         if (bnx_reset(sc, BNX_DRV_MSG_CODE_RESET)) {
 4204                 BNX_PRINTF(sc, "Controller reset failed!\n");
 4205                 goto bnx_init_exit;
 4206         }
 4207 
 4208         if (bnx_chipinit(sc)) {
 4209                 BNX_PRINTF(sc, "Controller initialization failed!\n");
 4210                 goto bnx_init_exit;
 4211         }
 4212 
 4213         if (bnx_blockinit(sc)) {
 4214                 BNX_PRINTF(sc, "Block initialization failed!\n");
 4215                 goto bnx_init_exit;
 4216         }
 4217 
 4218         /* Load our MAC address. */
 4219         bcopy(sc->arpcom.ac_enaddr, sc->eaddr, ETHER_ADDR_LEN);
 4220         bnx_set_mac_addr(sc);
 4221 
 4222         /* Calculate and program the Ethernet MRU size. */
 4223         ether_mtu = BNX_MAX_STD_ETHER_MTU_VLAN;
 4224 
 4225         DBPRINT(sc, BNX_INFO, "%s(): setting MRU = %d\n",
 4226             __FUNCTION__, ether_mtu);
 4227 
 4228         /*
 4229          * Program the MRU and enable Jumbo frame
 4230          * support.
 4231          */
 4232         REG_WR(sc, BNX_EMAC_RX_MTU_SIZE, ether_mtu |
 4233                 BNX_EMAC_RX_MTU_SIZE_JUMBO_ENA);
 4234 
 4235         /* Calculate the RX Ethernet frame size for rx_bd's. */
 4236         sc->max_frame_size = sizeof(struct l2_fhdr) + 2 + ether_mtu + 8;
 4237 
 4238         DBPRINT(sc, BNX_INFO, "%s(): mclbytes = %d, mbuf_alloc_size = %d, "
 4239             "max_frame_size = %d\n", __FUNCTION__, (int)MCLBYTES,
 4240             sc->mbuf_alloc_size, sc->max_frame_size);
 4241 
 4242         /* Program appropriate promiscuous/multicast filtering. */
 4243         bnx_set_rx_mode(sc);
 4244 
 4245         /* Init RX buffer descriptor chain. */
 4246         bnx_init_rx_chain(sc);
 4247 
 4248         /* Init TX buffer descriptor chain. */
 4249         bnx_init_tx_chain(sc);
 4250 
 4251         /* Enable host interrupts. */
 4252         bnx_enable_intr(sc);
 4253 
 4254         bnx_ifmedia_upd(ifp);
 4255 
 4256         ifp->if_flags |= IFF_RUNNING;
 4257         ifp->if_flags &= ~IFF_OACTIVE;
 4258 
 4259         timeout_add(&sc->bnx_timeout, hz);
 4260 
 4261 bnx_init_exit:
 4262         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
 4263 
 4264         splx(s);
 4265 
 4266         return;
 4267 }
 4268 
 4269 void
 4270 bnx_mgmt_init(struct bnx_softc *sc)
 4271 {
 4272         struct ifnet    *ifp = &sc->arpcom.ac_if;
 4273         u_int32_t       val;
 4274 
 4275         /* Check if the driver is still running and bail out if it is. */
 4276         if (ifp->if_flags & IFF_RUNNING)
 4277                 goto bnx_mgmt_init_exit;
 4278 
 4279         /* Initialize the on-boards CPUs */
 4280         bnx_init_cpus(sc);
 4281 
 4282         val = (BCM_PAGE_BITS - 8) << 24;
 4283         REG_WR(sc, BNX_RV2P_CONFIG, val);
 4284 
 4285         /* Enable all critical blocks in the MAC. */
 4286         REG_WR(sc, BNX_MISC_ENABLE_SET_BITS,
 4287                BNX_MISC_ENABLE_SET_BITS_RX_V2P_ENABLE |
 4288                BNX_MISC_ENABLE_SET_BITS_RX_DMA_ENABLE |
 4289                BNX_MISC_ENABLE_SET_BITS_COMPLETION_ENABLE);
 4290         REG_RD(sc, BNX_MISC_ENABLE_SET_BITS);
 4291         DELAY(20);
 4292 
 4293         bnx_ifmedia_upd(ifp);
 4294 
 4295 bnx_mgmt_init_exit:
 4296         DBPRINT(sc, BNX_VERBOSE_RESET, "Exiting %s()\n", __FUNCTION__);
 4297 }
 4298 
 4299 /****************************************************************************/
 4300 /* Encapsultes an mbuf cluster into the tx_bd chain structure and makes the */
 4301 /* memory visible to the controller.                                        */
 4302 /*                                                                          */
 4303 /* Returns:                                                                 */
 4304 /*   0 for success, positive value for failure.                             */
 4305 /****************************************************************************/
 4306 int
 4307 bnx_tx_encap(struct bnx_softc *sc, struct mbuf **m_head)
 4308 {
 4309         bus_dmamap_t            map;
 4310         struct tx_bd            *txbd = NULL;
 4311         struct mbuf             *m0;
 4312         u_int16_t               vlan_tag = 0, flags = 0;
 4313         u_int16_t               chain_prod, prod;
 4314 #ifdef BNX_DEBUG
 4315         u_int16_t               debug_prod;
 4316 #endif
 4317         u_int32_t               addr, prod_bseq;
 4318         int                     i, error, rc = 0;
 4319 
 4320         m0 = *m_head;
 4321         /* Transfer any checksum offload flags to the bd. */
 4322         if (m0->m_pkthdr.csum_flags) {
 4323                 if (m0->m_pkthdr.csum_flags & M_IPV4_CSUM_OUT)
 4324                         flags |= TX_BD_FLAGS_IP_CKSUM;
 4325                 if (m0->m_pkthdr.csum_flags &
 4326                     (M_TCPV4_CSUM_OUT | M_UDPV4_CSUM_OUT))
 4327                         flags |= TX_BD_FLAGS_TCP_UDP_CKSUM;
 4328         }
 4329 
 4330 #if NVLAN > 0
 4331         /* Transfer any VLAN tags to the bd. */
 4332         if ((m0->m_flags & (M_PROTO1|M_PKTHDR)) == (M_PROTO1|M_PKTHDR) &&
 4333             m0->m_pkthdr.rcvif != NULL) {
 4334                 struct ifvlan *ifv = m0->m_pkthdr.rcvif->if_softc;
 4335                 flags |= TX_BD_FLAGS_VLAN_TAG;
 4336                 vlan_tag = ifv->ifv_tag;
 4337         }
 4338 #endif
 4339 
 4340         /* Map the mbuf into DMAable memory. */
 4341         prod = sc->tx_prod;
 4342         chain_prod = TX_CHAIN_IDX(prod);
 4343         map = sc->tx_mbuf_map[chain_prod];
 4344 
 4345         /* Map the mbuf into our DMA address space. */
 4346         error = bus_dmamap_load_mbuf(sc->bnx_dmatag, map, m0, BUS_DMA_NOWAIT);
 4347         if (error != 0) {
 4348                 printf("%s: Error mapping mbuf into TX chain!\n",
 4349                     sc->bnx_dev.dv_xname);
 4350                 m_freem(m0);
 4351                 *m_head = NULL;
 4352                 return (error);
 4353         }
 4354 
 4355         /*
 4356          * The chip seems to require that at least 16 descriptors be kept
 4357          * empty at all times.  Make sure we honor that.
 4358          * XXX Would it be faster to assume worst case scenario for
 4359          * map->dm_nsegs and do this calculation higher up?
 4360          */
 4361         if (map->dm_nsegs > (USABLE_TX_BD - sc->used_tx_bd - BNX_TX_SLACK_SPACE)) {
 4362                 bus_dmamap_unload(sc->bnx_dmatag, map);
 4363                 return (ENOBUFS);
 4364         }
 4365 
 4366         /* prod points to an empty tx_bd at this point. */
 4367         prod_bseq = sc->tx_prod_bseq;
 4368 #ifdef BNX_DEBUG
 4369         debug_prod = chain_prod;
 4370 #endif
 4371 
 4372         DBPRINT(sc, BNX_INFO_SEND,
 4373                 "%s(): Start: prod = 0x%04X, chain_prod = %04X, "
 4374                 "prod_bseq = 0x%08X\n",
 4375                 __FUNCTION__, *prod, chain_prod, prod_bseq);
 4376 
 4377         /*
 4378          * Cycle through each mbuf segment that makes up
 4379          * the outgoing frame, gathering the mapping info
 4380          * for that segment and creating a tx_bd for the
 4381          * mbuf.
 4382          */
 4383         for (i = 0; i < map->dm_nsegs ; i++) {
 4384                 chain_prod = TX_CHAIN_IDX(prod);
 4385                 txbd = &sc->tx_bd_chain[TX_PAGE(chain_prod)][TX_IDX(chain_prod)];
 4386 
 4387                 addr = (u_int32_t)(map->dm_segs[i].ds_addr);
 4388                 txbd->tx_bd_haddr_lo = htole32(addr);
 4389                 addr = (u_int32_t)((u_int64_t)map->dm_segs[i].ds_addr >> 32);
 4390                 txbd->tx_bd_haddr_hi = htole32(addr);
 4391                 txbd->tx_bd_mss_nbytes = htole16(map->dm_segs[i].ds_len);
 4392                 txbd->tx_bd_vlan_tag = htole16(vlan_tag);
 4393                 txbd->tx_bd_flags = htole16(flags);
 4394                 prod_bseq += map->dm_segs[i].ds_len;
 4395                 if (i == 0)
 4396                         txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_START);
 4397                 prod = NEXT_TX_BD(prod);
 4398         }
 4399  
 4400         /* Set the END flag on the last TX buffer descriptor. */
 4401         txbd->tx_bd_flags |= htole16(TX_BD_FLAGS_END);
 4402 
 4403         DBRUN(BNX_INFO_SEND, bnx_dump_tx_chain(sc, debug_prod, nseg));
 4404 
 4405         DBPRINT(sc, BNX_INFO_SEND,
 4406                 "%s(): End: prod = 0x%04X, chain_prod = %04X, "
 4407                 "prod_bseq = 0x%08X\n",
 4408                 __FUNCTION__, prod, chain_prod, prod_bseq);
 4409 
 4410         /*
 4411          * Ensure that the mbuf pointer for this
 4412          * transmission is placed at the array
 4413          * index of the last descriptor in this
 4414          * chain.  This is done because a single
 4415          * map is used for all segments of the mbuf
 4416          * and we don't want to unload the map before
 4417          * all of the segments have been freed.
 4418          */
 4419         sc->tx_mbuf_ptr[chain_prod] = m0;
 4420         sc->used_tx_bd += map->dm_nsegs;
 4421 
 4422         DBRUNIF((sc->used_tx_bd > sc->tx_hi_watermark),
 4423             sc->tx_hi_watermark = sc->used_tx_bd);
 4424 
 4425         DBRUNIF(1, sc->tx_mbuf_alloc++);
 4426 
 4427         DBRUN(BNX_VERBOSE_SEND, bnx_dump_tx_mbuf_chain(sc, chain_prod, 
 4428             map_arg.maxsegs));
 4429 
 4430         /* prod points to the next free tx_bd at this point. */
 4431         sc->tx_prod = prod;
 4432         sc->tx_prod_bseq = prod_bseq;
 4433 
 4434         return (rc);
 4435 }
 4436 
 4437 /****************************************************************************/
 4438 /* Main transmit routine.                                                   */
 4439 /*                                                                          */
 4440 /* Returns:                                                                 */
 4441 /*   Nothing.                                                               */
 4442 /****************************************************************************/
 4443 void
 4444 bnx_start(struct ifnet *ifp)
 4445 {
 4446         struct bnx_softc        *sc = ifp->if_softc;
 4447         struct mbuf             *m_head = NULL;
 4448         int                     count = 0;
 4449         u_int16_t               tx_prod, tx_chain_prod;
 4450 
 4451         /* If there's no link or the transmit queue is empty then just exit. */
 4452         if (!sc->bnx_link || IFQ_IS_EMPTY(&ifp->if_snd)) {
 4453                 DBPRINT(sc, BNX_INFO_SEND,
 4454                     "%s(): No link or transmit queue empty.\n", __FUNCTION__);
 4455                 goto bnx_start_exit;
 4456         }
 4457 
 4458         /* prod points to the next free tx_bd. */
 4459         tx_prod = sc->tx_prod;
 4460         tx_chain_prod = TX_CHAIN_IDX(tx_prod);
 4461 
 4462         DBPRINT(sc, BNX_INFO_SEND, "%s(): Start: tx_prod = 0x%04X, "
 4463             "tx_chain_prod = %04X, tx_prod_bseq = 0x%08X\n",
 4464             __FUNCTION__, tx_prod, tx_chain_prod, sc->tx_prod_bseq);
 4465 
 4466         /*
 4467          * Keep adding entries while there is space in the ring.  We keep
 4468          * BNX_TX_SLACK_SPACE entries unused at all times.
 4469          */
 4470         while (sc->used_tx_bd < USABLE_TX_BD - BNX_TX_SLACK_SPACE) {
 4471                 /* Check for any frames to send. */
 4472                 IFQ_POLL(&ifp->if_snd, m_head);
 4473                 if (m_head == NULL)
 4474                         break;
 4475 
 4476                 /*
 4477                  * Pack the data into the transmit ring. If we
 4478                  * don't have room, set the OACTIVE flag to wait
 4479                  * for the NIC to drain the chain.
 4480                  */
 4481                 if (bnx_tx_encap(sc, &m_head)) {
 4482                         ifp->if_flags |= IFF_OACTIVE;
 4483                         DBPRINT(sc, BNX_INFO_SEND, "TX chain is closed for "
 4484                             "business! Total tx_bd used = %d\n",
 4485                             sc->used_tx_bd);
 4486                         break;
 4487                 }
 4488 
 4489                 IFQ_DEQUEUE(&ifp->if_snd, m_head);
 4490                 count++;
 4491 
 4492 #if NBPFILTER > 0
 4493                 /* Send a copy of the frame to any BPF listeners. */
 4494                 if (ifp->if_bpf)
 4495                         bpf_mtap(ifp->if_bpf, m_head, BPF_DIRECTION_OUT);
 4496 #endif
 4497         }
 4498 
 4499         if (count == 0) {
 4500                 /* no packets were dequeued */
 4501                 DBPRINT(sc, BNX_VERBOSE_SEND,
 4502                     "%s(): No packets were dequeued\n", __FUNCTION__);
 4503                 goto bnx_start_exit;
 4504         }
 4505 
 4506         /* Update the driver's counters. */
 4507         tx_chain_prod = TX_CHAIN_IDX(sc->tx_prod);
 4508 
 4509         DBPRINT(sc, BNX_INFO_SEND, "%s(): End: tx_prod = 0x%04X, tx_chain_prod "
 4510             "= 0x%04X, tx_prod_bseq = 0x%08X\n", __FUNCTION__, tx_prod,
 4511             tx_chain_prod, sc->tx_prod_bseq);
 4512 
 4513         /* Start the transmit. */
 4514         REG_WR16(sc, MB_TX_CID_ADDR + BNX_L2CTX_TX_HOST_BIDX, sc->tx_prod);
 4515         REG_WR(sc, MB_TX_CID_ADDR + BNX_L2CTX_TX_HOST_BSEQ, sc->tx_prod_bseq);
 4516 
 4517         /* Set the tx timeout. */
 4518         ifp->if_timer = BNX_TX_TIMEOUT;
 4519 
 4520 bnx_start_exit:
 4521         return;
 4522 }
 4523 
 4524 /****************************************************************************/
 4525 /* Handles any IOCTL calls from the operating system.                       */
 4526 /*                                                                          */
 4527 /* Returns:                                                                 */
 4528 /*   0 for success, positive value for failure.                             */
 4529 /****************************************************************************/
 4530 int
 4531 bnx_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 4532 {
 4533         struct bnx_softc        *sc = ifp->if_softc;
 4534         struct ifreq            *ifr = (struct ifreq *) data;
 4535         struct ifaddr           *ifa = (struct ifaddr *)data;
 4536         struct mii_data         *mii;
 4537         int                     s, error = 0;
 4538 
 4539         s = splnet();
 4540 
 4541         if ((error = ether_ioctl(ifp, &sc->arpcom, command, data)) > 0) {
 4542                 splx(s);
 4543                 return (error);
 4544         }
 4545 
 4546         switch (command) {
 4547         case SIOCSIFADDR:
 4548                 ifp->if_flags |= IFF_UP;
 4549                 if (!(ifp->if_flags & IFF_RUNNING))
 4550                         bnx_init(sc);
 4551 #ifdef INET
 4552                 if (ifa->ifa_addr->sa_family == AF_INET)
 4553                         arp_ifinit(&sc->arpcom, ifa);
 4554 #endif /* INET */
 4555                 break;
 4556 
 4557         case SIOCSIFMTU:
 4558                 if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ifp->if_hardmtu)
 4559                         error = EINVAL;
 4560                 else if (ifp->if_mtu != ifr->ifr_mtu)
 4561                         ifp->if_mtu = ifr->ifr_mtu;
 4562                 break;
 4563 
 4564         case SIOCSIFFLAGS:
 4565                 if (ifp->if_flags & IFF_UP) {
 4566                         if ((ifp->if_flags & IFF_RUNNING) &&
 4567                             ((ifp->if_flags ^ sc->bnx_if_flags) &
 4568                             (IFF_ALLMULTI | IFF_PROMISC)) != 0) {
 4569                                 bnx_set_rx_mode(sc);
 4570                         } else {
 4571                                 if (!(ifp->if_flags & IFF_RUNNING))
 4572                                         bnx_init(sc);
 4573                         }
 4574                 } else {
 4575                         if (ifp->if_flags & IFF_RUNNING)
 4576                                 bnx_stop(sc);
 4577                 }
 4578                 sc->bnx_if_flags = ifp->if_flags;
 4579                 break;
 4580 
 4581         case SIOCADDMULTI:
 4582         case SIOCDELMULTI:
 4583                 error = (command == SIOCADDMULTI)
 4584                         ? ether_addmulti(ifr, &sc->arpcom)
 4585                         : ether_delmulti(ifr, &sc->arpcom);
 4586 
 4587                 if (error == ENETRESET) {
 4588                         if (ifp->if_flags & IFF_RUNNING)
 4589                                 bnx_set_rx_mode(sc);
 4590                         error = 0;
 4591                 }
 4592                 break;
 4593 
 4594         case SIOCSIFMEDIA:
 4595         case SIOCGIFMEDIA:
 4596                 DBPRINT(sc, BNX_VERBOSE, "bnx_phy_flags = 0x%08X\n",
 4597                     sc->bnx_phy_flags);
 4598 
 4599                 if (sc->bnx_phy_flags & BNX_PHY_SERDES_FLAG)
 4600                         error = ifmedia_ioctl(ifp, ifr,
 4601                             &sc->bnx_ifmedia, command);
 4602                 else {
 4603                         mii = &sc->bnx_mii;
 4604                         error = ifmedia_ioctl(ifp, ifr,
 4605                             &mii->mii_media, command);
 4606                 }
 4607                 break;
 4608 
 4609         default:
 4610                 error = ENOTTY;
 4611                 break;
 4612         }
 4613 
 4614         splx(s);
 4615 
 4616         return (error);
 4617 }
 4618 
 4619 /****************************************************************************/
 4620 /* Transmit timeout handler.                                                */
 4621 /*                                                                          */
 4622 /* Returns:                                                                 */
 4623 /*   Nothing.                                                               */
 4624 /****************************************************************************/
 4625 void
 4626 bnx_watchdog(struct ifnet *ifp)
 4627 {
 4628         struct bnx_softc        *sc = ifp->if_softc;
 4629 
 4630         DBRUN(BNX_WARN_SEND, bnx_dump_driver_state(sc);
 4631             bnx_dump_status_block(sc));
 4632 
 4633         printf("%s: Watchdog timeout occurred, resetting!\n",
 4634             ifp->if_xname);
 4635 
 4636         /* DBRUN(BNX_FATAL, bnx_breakpoint(sc)); */
 4637 
 4638         bnx_init(sc);
 4639 
 4640         ifp->if_oerrors++;
 4641 }
 4642 
 4643 /*
 4644  * Interrupt handler.
 4645  */
 4646 /****************************************************************************/
 4647 /* Main interrupt entry point.  Verifies that the controller generated the  */
 4648 /* interrupt and then calls a separate routine for handle the various       */
 4649 /* interrupt causes (PHY, TX, RX).                                          */
 4650 /*                                                                          */
 4651 /* Returns:                                                                 */
 4652 /*   0 for success, positive value for failure.                             */
 4653 /****************************************************************************/
 4654 int
 4655 bnx_intr(void *xsc)
 4656 {
 4657         struct bnx_softc        *sc;
 4658         struct ifnet            *ifp;
 4659         u_int32_t               status_attn_bits;
 4660 
 4661         sc = xsc;
 4662         if ((sc->bnx_flags & BNX_ACTIVE_FLAG) == 0)
 4663                 return (0);
 4664 
 4665         ifp = &sc->arpcom.ac_if;
 4666 
 4667         DBRUNIF(1, sc->interrupts_generated++);
 4668 
 4669         bus_dmamap_sync(sc->bnx_dmatag, sc->status_map, 0,
 4670             sc->status_map->dm_mapsize, BUS_DMASYNC_POSTWRITE);
 4671 
 4672         /*
 4673          * If the hardware status block index
 4674          * matches the last value read by the
 4675          * driver and we haven't asserted our
 4676          * interrupt then there's nothing to do.
 4677          */
 4678         if ((sc->status_block->status_idx == sc->last_status_idx) && 
 4679             (REG_RD(sc, BNX_PCICFG_MISC_STATUS) &
 4680             BNX_PCICFG_MISC_STATUS_INTA_VALUE))
 4681                 return (0);
 4682 
 4683         /* Ack the interrupt and stop others from occuring. */
 4684         REG_WR(sc, BNX_PCICFG_INT_ACK_CMD,
 4685             BNX_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
 4686             BNX_PCICFG_INT_ACK_CMD_MASK_INT);
 4687 
 4688         /* Keep processing data as long as there is work to do. */
 4689         for (;;) {
 4690                 status_attn_bits = sc->status_block->status_attn_bits;
 4691 
 4692                 DBRUNIF(DB_RANDOMTRUE(bnx_debug_unexpected_attention),
 4693                     printf("Simulating unexpected status attention bit set.");
 4694                     status_attn_bits = status_attn_bits |
 4695                     STATUS_ATTN_BITS_PARITY_ERROR);
 4696 
 4697                 /* Was it a link change interrupt? */
 4698                 if ((status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) !=
 4699                     (sc->status_block->status_attn_bits_ack &
 4700                     STATUS_ATTN_BITS_LINK_STATE))
 4701                         bnx_phy_intr(sc);
 4702 
 4703                 /* If any other attention is asserted then the chip is toast. */
 4704                 if (((status_attn_bits & ~STATUS_ATTN_BITS_LINK_STATE) !=
 4705                     (sc->status_block->status_attn_bits_ack & 
 4706                     ~STATUS_ATTN_BITS_LINK_STATE))) {
 4707                         DBRUN(1, sc->unexpected_attentions++);
 4708 
 4709                         BNX_PRINTF(sc, "Fatal attention detected: 0x%08X\n",
 4710                             sc->status_block->status_attn_bits);
 4711 
 4712                         DBRUN(BNX_FATAL,
 4713                             if (bnx_debug_unexpected_attention == 0)
 4714                             bnx_breakpoint(sc));
 4715 
 4716                         bnx_init(sc);
 4717                         return (1);
 4718                 }
 4719 
 4720                 /* Check for any completed RX frames. */
 4721                 if (sc->status_block->status_rx_quick_consumer_index0 !=
 4722                     sc->hw_rx_cons)
 4723                         bnx_rx_intr(sc);
 4724 
 4725                 /* Check for any completed TX frames. */
 4726                 if (sc->status_block->status_tx_quick_consumer_index0 !=
 4727                     sc->hw_tx_cons)
 4728                         bnx_tx_intr(sc);
 4729 
 4730                 /* Save the status block index value for use during the
 4731                  * next interrupt.
 4732                  */
 4733                 sc->last_status_idx = sc->status_block->status_idx;
 4734 
 4735                 /* Prevent speculative reads from getting ahead of the
 4736                  * status block.
 4737                  */
 4738                 bus_space_barrier(sc->bnx_btag, sc->bnx_bhandle, 0, 0, 
 4739                     BUS_SPACE_BARRIER_READ);
 4740 
 4741                 /* If there's no work left then exit the isr. */
 4742                 if ((sc->status_block->status_rx_quick_consumer_index0 ==
 4743                     sc->hw_rx_cons) &&
 4744                     (sc->status_block->status_tx_quick_consumer_index0 ==
 4745                     sc->hw_tx_cons))
 4746                         break;
 4747         }
 4748 
 4749         bus_dmamap_sync(sc->bnx_dmatag, sc->status_map, 0,
 4750             sc->status_map->dm_mapsize, BUS_DMASYNC_PREWRITE);
 4751 
 4752         /* Re-enable interrupts. */
 4753         REG_WR(sc, BNX_PCICFG_INT_ACK_CMD,
 4754             BNX_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx |
 4755             BNX_PCICFG_INT_ACK_CMD_MASK_INT);
 4756         REG_WR(sc, BNX_PCICFG_INT_ACK_CMD,
 4757             BNX_PCICFG_INT_ACK_CMD_INDEX_VALID | sc->last_status_idx);
 4758 
 4759         /* Handle any frames that arrived while handling the interrupt. */
 4760         if (ifp->if_flags & IFF_RUNNING && !IFQ_IS_EMPTY(&ifp->if_snd))
 4761                 bnx_start(ifp);
 4762 
 4763         return (1);
 4764 }
 4765 
 4766 /****************************************************************************/
 4767 /* Programs the various packet receive modes (broadcast and multicast).     */
 4768 /*                                                                          */
 4769 /* Returns:                                                                 */
 4770 /*   Nothing.                                                               */
 4771 /****************************************************************************/
 4772 void
 4773 bnx_set_rx_mode(struct bnx_softc *sc)
 4774 {
 4775         struct arpcom           *ac = &sc->arpcom;
 4776         struct ifnet            *ifp = &ac->ac_if;
 4777         struct ether_multi      *enm;
 4778         struct ether_multistep  step;
 4779         u_int32_t               hashes[NUM_MC_HASH_REGISTERS] = { 0, 0, 0, 0, 0, 0, 0, 0 };
 4780         u_int32_t               rx_mode, sort_mode;
 4781         int                     h, i;
 4782 
 4783         /* Initialize receive mode default settings. */
 4784         rx_mode = sc->rx_mode & ~(BNX_EMAC_RX_MODE_PROMISCUOUS |
 4785             BNX_EMAC_RX_MODE_KEEP_VLAN_TAG);
 4786         sort_mode = 1 | BNX_RPM_SORT_USER0_BC_EN;
 4787 
 4788         /*
 4789          * ASF/IPMI/UMP firmware requires that VLAN tag stripping
 4790          * be enbled.
 4791          */
 4792         if (!(sc->bnx_flags & BNX_MFW_ENABLE_FLAG))
 4793                 rx_mode |= BNX_EMAC_RX_MODE_KEEP_VLAN_TAG;
 4794 
 4795         /*
 4796          * Check for promiscuous, all multicast, or selected
 4797          * multicast address filtering.
 4798          */
 4799         if (ifp->if_flags & IFF_PROMISC) {
 4800                 DBPRINT(sc, BNX_INFO, "Enabling promiscuous mode.\n");
 4801 
 4802                 /* Enable promiscuous mode. */
 4803                 rx_mode |= BNX_EMAC_RX_MODE_PROMISCUOUS;
 4804                 sort_mode |= BNX_RPM_SORT_USER0_PROM_EN;
 4805         } else if (ifp->if_flags & IFF_ALLMULTI) {
 4806 allmulti:
 4807                 DBPRINT(sc, BNX_INFO, "Enabling all multicast mode.\n");
 4808 
 4809                 /* Enable all multicast addresses. */
 4810                 for (i = 0; i < NUM_MC_HASH_REGISTERS; i++)
 4811                         REG_WR(sc, BNX_EMAC_MULTICAST_HASH0 + (i * 4),
 4812                             0xffffffff);
 4813                 sort_mode |= BNX_RPM_SORT_USER0_MC_EN;
 4814         } else {
 4815                 /* Accept one or more multicast(s). */
 4816                 DBPRINT(sc, BNX_INFO, "Enabling selective multicast mode.\n");
 4817 
 4818                 ETHER_FIRST_MULTI(step, ac, enm);
 4819                 while (enm != NULL) {
 4820                         if (bcmp(enm->enm_addrlo, enm->enm_addrhi,
 4821                             ETHER_ADDR_LEN)) {
 4822                                 ifp->if_flags |= IFF_ALLMULTI;
 4823                                 goto allmulti;
 4824                         }
 4825                         h = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN) &
 4826                             0xFF;
 4827                         hashes[(h & 0xE0) >> 5] |= 1 << (h & 0x1F);
 4828                         ETHER_NEXT_MULTI(step, enm);
 4829                 }
 4830 
 4831                 for (i = 0; i < NUM_MC_HASH_REGISTERS; i++)
 4832                         REG_WR(sc, BNX_EMAC_MULTICAST_HASH0 + (i * 4),
 4833                             hashes[i]);
 4834 
 4835                 sort_mode |= BNX_RPM_SORT_USER0_MC_HSH_EN;
 4836         }
 4837 
 4838         /* Only make changes if the recive mode has actually changed. */
 4839         if (rx_mode != sc->rx_mode) {
 4840                 DBPRINT(sc, BNX_VERBOSE, "Enabling new receive mode: 0x%08X\n", 
 4841                     rx_mode);
 4842 
 4843                 sc->rx_mode = rx_mode;
 4844                 REG_WR(sc, BNX_EMAC_RX_MODE, rx_mode);
 4845         }
 4846 
 4847         /* Disable and clear the exisitng sort before enabling a new sort. */
 4848         REG_WR(sc, BNX_RPM_SORT_USER0, 0x0);
 4849         REG_WR(sc, BNX_RPM_SORT_USER0, sort_mode);
 4850         REG_WR(sc, BNX_RPM_SORT_USER0, sort_mode | BNX_RPM_SORT_USER0_ENA);
 4851 }
 4852 
 4853 /****************************************************************************/
 4854 /* Called periodically to updates statistics from the controllers           */
 4855 /* statistics block.                                                        */
 4856 /*                                                                          */
 4857 /* Returns:                                                                 */
 4858 /*   Nothing.                                                               */
 4859 /****************************************************************************/
 4860 void
 4861 bnx_stats_update(struct bnx_softc *sc)
 4862 {
 4863         struct ifnet            *ifp = &sc->arpcom.ac_if;
 4864         struct statistics_block *stats;
 4865 
 4866         DBPRINT(sc, BNX_EXCESSIVE, "Entering %s()\n", __FUNCTION__);
 4867 
 4868         stats = (struct statistics_block *)sc->stats_block;
 4869 
 4870         /* 
 4871          * Update the interface statistics from the
 4872          * hardware statistics.
 4873          */
 4874         ifp->if_collisions = (u_long)stats->stat_EtherStatsCollisions;
 4875 
 4876         ifp->if_ierrors = (u_long)stats->stat_EtherStatsUndersizePkts +
 4877             (u_long)stats->stat_EtherStatsOverrsizePkts +
 4878             (u_long)stats->stat_IfInMBUFDiscards +
 4879             (u_long)stats->stat_Dot3StatsAlignmentErrors +
 4880             (u_long)stats->stat_Dot3StatsFCSErrors;
 4881 
 4882         ifp->if_oerrors = (u_long)
 4883             stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors +
 4884             (u_long)stats->stat_Dot3StatsExcessiveCollisions +
 4885             (u_long)stats->stat_Dot3StatsLateCollisions;
 4886 
 4887         /* 
 4888          * Certain controllers don't report 
 4889          * carrier sense errors correctly.
 4890          * See errata E11_5708CA0_1165. 
 4891          */
 4892         if (!(BNX_CHIP_NUM(sc) == BNX_CHIP_NUM_5706) &&
 4893             !(BNX_CHIP_ID(sc) == BNX_CHIP_ID_5708_A0))
 4894                 ifp->if_oerrors += (u_long) stats->stat_Dot3StatsCarrierSenseErrors;
 4895 
 4896         /*
 4897          * Update the sysctl statistics from the
 4898          * hardware statistics.
 4899          */
 4900         sc->stat_IfHCInOctets = ((u_int64_t)stats->stat_IfHCInOctets_hi << 32) +
 4901             (u_int64_t) stats->stat_IfHCInOctets_lo;
 4902 
 4903         sc->stat_IfHCInBadOctets =
 4904             ((u_int64_t) stats->stat_IfHCInBadOctets_hi << 32) + 
 4905             (u_int64_t) stats->stat_IfHCInBadOctets_lo;
 4906 
 4907         sc->stat_IfHCOutOctets =
 4908             ((u_int64_t) stats->stat_IfHCOutOctets_hi << 32) +
 4909             (u_int64_t) stats->stat_IfHCOutOctets_lo;
 4910 
 4911         sc->stat_IfHCOutBadOctets =
 4912             ((u_int64_t) stats->stat_IfHCOutBadOctets_hi << 32) +
 4913             (u_int64_t) stats->stat_IfHCOutBadOctets_lo;
 4914 
 4915         sc->stat_IfHCInUcastPkts =
 4916             ((u_int64_t) stats->stat_IfHCInUcastPkts_hi << 32) +
 4917             (u_int64_t) stats->stat_IfHCInUcastPkts_lo;
 4918 
 4919         sc->stat_IfHCInMulticastPkts =
 4920             ((u_int64_t) stats->stat_IfHCInMulticastPkts_hi << 32) +
 4921             (u_int64_t) stats->stat_IfHCInMulticastPkts_lo;
 4922 
 4923         sc->stat_IfHCInBroadcastPkts =
 4924             ((u_int64_t) stats->stat_IfHCInBroadcastPkts_hi << 32) +
 4925             (u_int64_t) stats->stat_IfHCInBroadcastPkts_lo;
 4926 
 4927         sc->stat_IfHCOutUcastPkts =
 4928            ((u_int64_t) stats->stat_IfHCOutUcastPkts_hi << 32) +
 4929             (u_int64_t) stats->stat_IfHCOutUcastPkts_lo;
 4930 
 4931         sc->stat_IfHCOutMulticastPkts =
 4932             ((u_int64_t) stats->stat_IfHCOutMulticastPkts_hi << 32) +
 4933             (u_int64_t) stats->stat_IfHCOutMulticastPkts_lo;
 4934 
 4935         sc->stat_IfHCOutBroadcastPkts =
 4936             ((u_int64_t) stats->stat_IfHCOutBroadcastPkts_hi << 32) +
 4937             (u_int64_t) stats->stat_IfHCOutBroadcastPkts_lo;
 4938 
 4939         sc->stat_emac_tx_stat_dot3statsinternalmactransmiterrors =
 4940             stats->stat_emac_tx_stat_dot3statsinternalmactransmiterrors;
 4941 
 4942         sc->stat_Dot3StatsCarrierSenseErrors =
 4943             stats->stat_Dot3StatsCarrierSenseErrors;
 4944 
 4945         sc->stat_Dot3StatsFCSErrors = stats->stat_Dot3StatsFCSErrors;
 4946 
 4947         sc->stat_Dot3StatsAlignmentErrors =
 4948             stats->stat_Dot3StatsAlignmentErrors;
 4949 
 4950         sc->stat_Dot3StatsSingleCollisionFrames =
 4951             stats->stat_Dot3StatsSingleCollisionFrames;
 4952 
 4953         sc->stat_Dot3StatsMultipleCollisionFrames =
 4954             stats->stat_Dot3StatsMultipleCollisionFrames;
 4955 
 4956         sc->stat_Dot3StatsDeferredTransmissions =
 4957             stats->stat_Dot3StatsDeferredTransmissions;
 4958 
 4959         sc->stat_Dot3StatsExcessiveCollisions =
 4960             stats->stat_Dot3StatsExcessiveCollisions;
 4961 
 4962         sc->stat_Dot3StatsLateCollisions = stats->stat_Dot3StatsLateCollisions;
 4963 
 4964         sc->stat_EtherStatsCollisions = stats->stat_EtherStatsCollisions;
 4965 
 4966         sc->stat_EtherStatsFragments = stats->stat_EtherStatsFragments;
 4967 
 4968         sc->stat_EtherStatsJabbers = stats->stat_EtherStatsJabbers;
 4969 
 4970         sc->stat_EtherStatsUndersizePkts = stats->stat_EtherStatsUndersizePkts;
 4971 
 4972         sc->stat_EtherStatsOverrsizePkts = stats->stat_EtherStatsOverrsizePkts;
 4973 
 4974         sc->stat_EtherStatsPktsRx64Octets =
 4975             stats->stat_EtherStatsPktsRx64Octets;
 4976 
 4977         sc->stat_EtherStatsPktsRx65Octetsto127Octets =
 4978             stats->stat_EtherStatsPktsRx65Octetsto127Octets;
 4979 
 4980         sc->stat_EtherStatsPktsRx128Octetsto255Octets =
 4981             stats->stat_EtherStatsPktsRx128Octetsto255Octets;
 4982 
 4983         sc->stat_EtherStatsPktsRx256Octetsto511Octets =
 4984             stats->stat_EtherStatsPktsRx256Octetsto511Octets;
 4985 
 4986         sc->stat_EtherStatsPktsRx512Octetsto1023Octets =
 4987             stats->stat_EtherStatsPktsRx512Octetsto1023Octets;
 4988 
 4989         sc->stat_EtherStatsPktsRx1024Octetsto1522Octets =
 4990             stats->stat_EtherStatsPktsRx1024Octetsto1522Octets;
 4991 
 4992         sc->stat_EtherStatsPktsRx1523Octetsto9022Octets =
 4993             stats->stat_EtherStatsPktsRx1523Octetsto9022Octets;
 4994 
 4995         sc->stat_EtherStatsPktsTx64Octets =
 4996             stats->stat_EtherStatsPktsTx64Octets;
 4997 
 4998         sc->stat_EtherStatsPktsTx65Octetsto127Octets =
 4999             stats->stat_EtherStatsPktsTx65Octetsto127Octets;
 5000 
 5001         sc->stat_EtherStatsPktsTx128Octetsto255Octets =
 5002             stats->stat_EtherStatsPktsTx128Octetsto255Octets;
 5003 
 5004         sc->stat_EtherStatsPktsTx256Octetsto511Octets =
 5005             stats->stat_EtherStatsPktsTx256Octetsto511Octets;
 5006 
 5007         sc->stat_EtherStatsPktsTx512Octetsto1023Octets =
 5008             stats->stat_EtherStatsPktsTx512Octetsto1023Octets;
 5009 
 5010         sc->stat_EtherStatsPktsTx1024Octetsto1522Octets =
 5011             stats->stat_EtherStatsPktsTx1024Octetsto1522Octets;
 5012 
 5013         sc->stat_EtherStatsPktsTx1523Octetsto9022Octets =
 5014             stats->stat_EtherStatsPktsTx1523Octetsto9022Octets;
 5015 
 5016         sc->stat_XonPauseFramesReceived = stats->stat_XonPauseFramesReceived;
 5017 
 5018         sc->stat_XoffPauseFramesReceived = stats->stat_XoffPauseFramesReceived;
 5019 
 5020         sc->stat_OutXonSent = stats->stat_OutXonSent;
 5021 
 5022         sc->stat_OutXoffSent = stats->stat_OutXoffSent;
 5023 
 5024         sc->stat_FlowControlDone = stats->stat_FlowControlDone;
 5025 
 5026         sc->stat_MacControlFramesReceived =
 5027             stats->stat_MacControlFramesReceived;
 5028 
 5029         sc->stat_XoffStateEntered = stats->stat_XoffStateEntered;
 5030 
 5031         sc->stat_IfInFramesL2FilterDiscards =
 5032             stats->stat_IfInFramesL2FilterDiscards;
 5033 
 5034         sc->stat_IfInRuleCheckerDiscards = stats->stat_IfInRuleCheckerDiscards;
 5035 
 5036         sc->stat_IfInFTQDiscards = stats->stat_IfInFTQDiscards;
 5037 
 5038         sc->stat_IfInMBUFDiscards = stats->stat_IfInMBUFDiscards;
 5039 
 5040         sc->stat_IfInRuleCheckerP4Hit = stats->stat_IfInRuleCheckerP4Hit;
 5041 
 5042         sc->stat_CatchupInRuleCheckerDiscards =
 5043             stats->stat_CatchupInRuleCheckerDiscards;
 5044 
 5045         sc->stat_CatchupInFTQDiscards = stats->stat_CatchupInFTQDiscards;
 5046 
 5047         sc->stat_CatchupInMBUFDiscards = stats->stat_CatchupInMBUFDiscards;
 5048 
 5049         sc->stat_CatchupInRuleCheckerP4Hit =
 5050             stats->stat_CatchupInRuleCheckerP4Hit;
 5051 
 5052         DBPRINT(sc, BNX_EXCESSIVE, "Exiting %s()\n", __FUNCTION__);
 5053 }
 5054 
 5055 void
 5056 bnx_tick(void *xsc)
 5057 {
 5058         struct bnx_softc        *sc = xsc;
 5059         struct ifnet            *ifp = &sc->arpcom.ac_if;
 5060         struct mii_data         *mii = NULL;
 5061         u_int32_t               msg;
 5062 
 5063         /* Tell the firmware that the driver is still running. */
 5064 #ifdef BNX_DEBUG
 5065         msg = (u_int32_t)BNX_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE;
 5066 #else
 5067         msg = (u_int32_t)++sc->bnx_fw_drv_pulse_wr_seq;
 5068 #endif
 5069         REG_WR_IND(sc, sc->bnx_shmem_base + BNX_DRV_PULSE_MB, msg);
 5070 
 5071         /* Update the statistics from the hardware statistics block. */
 5072         bnx_stats_update(sc);
 5073 
 5074         /* Schedule the next tick. */
 5075         timeout_add(&sc->bnx_timeout, hz);
 5076 
 5077         /* If link is up already up then we're done. */
 5078         if (sc->bnx_link)
 5079                 goto bnx_tick_exit;
 5080 
 5081         /* DRC - ToDo: Add SerDes support and check SerDes link here. */
 5082 
 5083         mii = &sc->bnx_mii;
 5084         mii_tick(mii);
 5085 
 5086         /* Check if the link has come up. */
 5087         if (!sc->bnx_link && mii->mii_media_status & IFM_ACTIVE &&
 5088             IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) {
 5089                 sc->bnx_link++;
 5090                 /* Now that link is up, handle any outstanding TX traffic. */
 5091                 if (!IFQ_IS_EMPTY(&ifp->if_snd))
 5092                         bnx_start(ifp);
 5093         }
 5094 
 5095 bnx_tick_exit:
 5096         return;
 5097 }
 5098 
 5099 /****************************************************************************/
 5100 /* BNX Debug Routines                                                       */
 5101 /****************************************************************************/
 5102 #ifdef BNX_DEBUG
 5103 
 5104 /****************************************************************************/
 5105 /* Prints out information about an mbuf.                                    */
 5106 /*                                                                          */
 5107 /* Returns:                                                                 */
 5108 /*   Nothing.                                                               */
 5109 /****************************************************************************/
 5110 void
 5111 bnx_dump_mbuf(struct bnx_softc *sc, struct mbuf *m)
 5112 {
 5113         struct mbuf             *mp = m;
 5114 
 5115         if (m == NULL) {
 5116                 /* Index out of range. */
 5117                 printf("mbuf ptr is null!\n");
 5118                 return;
 5119         }
 5120 
 5121         while (mp) {
 5122                 printf("mbuf: vaddr = %p, m_len = %d, m_flags = ", 
 5123                     mp, mp->m_len);
 5124 
 5125                 if (mp->m_flags & M_EXT)
 5126                         printf("M_EXT ");
 5127                 if (mp->m_flags & M_PKTHDR)
 5128                         printf("M_PKTHDR ");
 5129                 printf("\n");
 5130 
 5131                 if (mp->m_flags & M_EXT)
 5132                         printf("- m_ext: vaddr = %p, ext_size = 0x%04X\n", 
 5133                             mp, mp->m_ext.ext_size);
 5134 
 5135                 mp = mp->m_next;
 5136         }
 5137 }
 5138 
 5139 /****************************************************************************/
 5140 /* Prints out the mbufs in the TX mbuf chain.                               */
 5141 /*                                                                          */
 5142 /* Returns:                                                                 */
 5143 /*   Nothing.                                                               */
 5144 /****************************************************************************/
 5145 void
 5146 bnx_dump_tx_mbuf_chain(struct bnx_softc *sc, int chain_prod, int count)
 5147 {
 5148         struct mbuf             *m;
 5149         int                     i;
 5150 
 5151         BNX_PRINTF(sc,
 5152             "----------------------------"
 5153             "  tx mbuf data  "
 5154             "----------------------------\n");
 5155 
 5156         for (i = 0; i < count; i++) {
 5157                 m = sc->tx_mbuf_ptr[chain_prod];
 5158                 BNX_PRINTF(sc, "txmbuf[%d]\n", chain_prod);
 5159                 bnx_dump_mbuf(sc, m);
 5160                 chain_prod = TX_CHAIN_IDX(NEXT_TX_BD(chain_prod));
 5161         }
 5162 
 5163         BNX_PRINTF(sc,
 5164             "--------------------------------------------"
 5165             "----------------------------\n");
 5166 }
 5167 
 5168 /*
 5169  * This routine prints the RX mbuf chain.
 5170  */
 5171 void
 5172 bnx_dump_rx_mbuf_chain(struct bnx_softc *sc, int chain_prod, int count)
 5173 {
 5174         struct mbuf             *m;
 5175         int                     i;
 5176 
 5177         BNX_PRINTF(sc,
 5178             "----------------------------"
 5179             "  rx mbuf data  "
 5180             "----------------------------\n");
 5181 
 5182         for (i = 0; i < count; i++) {
 5183                 m = sc->rx_mbuf_ptr[chain_prod];
 5184                 BNX_PRINTF(sc, "rxmbuf[0x%04X]\n", chain_prod);
 5185                 bnx_dump_mbuf(sc, m);
 5186                 chain_prod = RX_CHAIN_IDX(NEXT_RX_BD(chain_prod));
 5187         }
 5188 
 5189 
 5190         BNX_PRINTF(sc,
 5191             "--------------------------------------------"
 5192             "----------------------------\n");
 5193 }
 5194 
 5195 void
 5196 bnx_dump_txbd(struct bnx_softc *sc, int idx, struct tx_bd *txbd)
 5197 {
 5198         if (idx > MAX_TX_BD)
 5199                 /* Index out of range. */
 5200                 BNX_PRINTF(sc, "tx_bd[0x%04X]: Invalid tx_bd index!\n", idx);
 5201         else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE)
 5202                 /* TX Chain page pointer. */
 5203                 BNX_PRINTF(sc, "tx_bd[0x%04X]: haddr = 0x%08X:%08X, chain "
 5204                     "page pointer\n", idx, txbd->tx_bd_haddr_hi,
 5205                     txbd->tx_bd_haddr_lo);
 5206         else
 5207                 /* Normal tx_bd entry. */
 5208                 BNX_PRINTF(sc, "tx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = "
 5209                     "0x%08X, vlan tag = 0x%4X, flags = 0x%08X\n", idx, 
 5210                     txbd->tx_bd_haddr_hi, txbd->tx_bd_haddr_lo,
 5211                     txbd->tx_bd_mss_nbytes, txbd->tx_bd_vlan_tag,
 5212                     txbd->tx_bd_flags);
 5213 }
 5214 
 5215 void
 5216 bnx_dump_rxbd(struct bnx_softc *sc, int idx, struct rx_bd *rxbd)
 5217 {
 5218         if (idx > MAX_RX_BD)
 5219                 /* Index out of range. */
 5220                 BNX_PRINTF(sc, "rx_bd[0x%04X]: Invalid rx_bd index!\n", idx);
 5221         else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE)
 5222                 /* TX Chain page pointer. */
 5223                 BNX_PRINTF(sc, "rx_bd[0x%04X]: haddr = 0x%08X:%08X, chain page "
 5224                     "pointer\n", idx, rxbd->rx_bd_haddr_hi,
 5225                     rxbd->rx_bd_haddr_lo);
 5226         else
 5227                 /* Normal tx_bd entry. */
 5228                 BNX_PRINTF(sc, "rx_bd[0x%04X]: haddr = 0x%08X:%08X, nbytes = "
 5229                     "0x%08X, flags = 0x%08X\n", idx, 
 5230                         rxbd->rx_bd_haddr_hi, rxbd->rx_bd_haddr_lo,
 5231                         rxbd->rx_bd_len, rxbd->rx_bd_flags);
 5232 }
 5233 
 5234 void
 5235 bnx_dump_l2fhdr(struct bnx_softc *sc, int idx, struct l2_fhdr *l2fhdr)
 5236 {
 5237         BNX_PRINTF(sc, "l2_fhdr[0x%04X]: status = 0x%08X, "
 5238             "pkt_len = 0x%04X, vlan = 0x%04x, ip_xsum = 0x%04X, "
 5239             "tcp_udp_xsum = 0x%04X\n", idx,
 5240             l2fhdr->l2_fhdr_status, l2fhdr->l2_fhdr_pkt_len,
 5241             l2fhdr->l2_fhdr_vlan_tag, l2fhdr->l2_fhdr_ip_xsum,
 5242             l2fhdr->l2_fhdr_tcp_udp_xsum);
 5243 }
 5244 
 5245 /*
 5246  * This routine prints the TX chain.
 5247  */
 5248 void
 5249 bnx_dump_tx_chain(struct bnx_softc *sc, int tx_prod, int count)
 5250 {
 5251         struct tx_bd            *txbd;
 5252         int                     i;
 5253 
 5254         /* First some info about the tx_bd chain structure. */
 5255         BNX_PRINTF(sc,
 5256             "----------------------------"
 5257             "  tx_bd  chain  "
 5258             "----------------------------\n");
 5259 
 5260         BNX_PRINTF(sc,
 5261             "page size      = 0x%08X, tx chain pages        = 0x%08X\n",
 5262             (u_int32_t)BCM_PAGE_SIZE, (u_int32_t) TX_PAGES);
 5263 
 5264         BNX_PRINTF(sc,
 5265             "tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n",
 5266             (u_int32_t)TOTAL_TX_BD_PER_PAGE, (u_int32_t)USABLE_TX_BD_PER_PAGE);
 5267 
 5268         BNX_PRINTF(sc, "total tx_bd    = 0x%08X\n", (u_int32_t)TOTAL_TX_BD);
 5269 
 5270         BNX_PRINTF(sc, ""
 5271             "-----------------------------"
 5272             "   tx_bd data   "
 5273             "-----------------------------\n");
 5274 
 5275         /* Now print out the tx_bd's themselves. */
 5276         for (i = 0; i < count; i++) {
 5277                 txbd = &sc->tx_bd_chain[TX_PAGE(tx_prod)][TX_IDX(tx_prod)];
 5278                 bnx_dump_txbd(sc, tx_prod, txbd);
 5279                 tx_prod = TX_CHAIN_IDX(NEXT_TX_BD(tx_prod));
 5280         }
 5281 
 5282         BNX_PRINTF(sc,
 5283             "-----------------------------"
 5284             "--------------"
 5285             "-----------------------------\n");
 5286 }
 5287 
 5288 /*
 5289  * This routine prints the RX chain.
 5290  */
 5291 void
 5292 bnx_dump_rx_chain(struct bnx_softc *sc, int rx_prod, int count)
 5293 {
 5294         struct rx_bd            *rxbd;
 5295         int                     i;
 5296 
 5297         /* First some info about the tx_bd chain structure. */
 5298         BNX_PRINTF(sc,
 5299             "----------------------------"
 5300             "  rx_bd  chain  "
 5301             "----------------------------\n");
 5302 
 5303         BNX_PRINTF(sc, "----- RX_BD Chain -----\n");
 5304 
 5305         BNX_PRINTF(sc,
 5306             "page size      = 0x%08X, rx chain pages        = 0x%08X\n",
 5307             (u_int32_t)BCM_PAGE_SIZE, (u_int32_t)RX_PAGES);
 5308 
 5309         BNX_PRINTF(sc,
 5310             "rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n",
 5311             (u_int32_t)TOTAL_RX_BD_PER_PAGE, (u_int32_t)USABLE_RX_BD_PER_PAGE);
 5312 
 5313         BNX_PRINTF(sc, "total rx_bd    = 0x%08X\n", (u_int32_t)TOTAL_RX_BD);
 5314 
 5315         BNX_PRINTF(sc,
 5316             "----------------------------"
 5317             "   rx_bd data   "
 5318             "----------------------------\n");
 5319 
 5320         /* Now print out the rx_bd's themselves. */
 5321         for (i = 0; i < count; i++) {
 5322                 rxbd = &sc->rx_bd_chain[RX_PAGE(rx_prod)][RX_IDX(rx_prod)];
 5323                 bnx_dump_rxbd(sc, rx_prod, rxbd);
 5324                 rx_prod = RX_CHAIN_IDX(NEXT_RX_BD(rx_prod));
 5325         }
 5326 
 5327         BNX_PRINTF(sc,
 5328             "----------------------------"
 5329             "--------------"
 5330             "----------------------------\n");
 5331 }
 5332 
 5333 /*
 5334  * This routine prints the status block.
 5335  */
 5336 void
 5337 bnx_dump_status_block(struct bnx_softc *sc)
 5338 {
 5339         struct status_block     *sblk;
 5340 
 5341         sblk = sc->status_block;
 5342 
 5343         BNX_PRINTF(sc, "----------------------------- Status Block "
 5344             "-----------------------------\n");
 5345 
 5346         BNX_PRINTF(sc,
 5347             "attn_bits  = 0x%08X, attn_bits_ack = 0x%08X, index = 0x%04X\n",
 5348             sblk->status_attn_bits, sblk->status_attn_bits_ack,
 5349             sblk->status_idx);
 5350 
 5351         BNX_PRINTF(sc, "rx_cons0   = 0x%08X, tx_cons0      = 0x%08X\n",
 5352             sblk->status_rx_quick_consumer_index0,
 5353             sblk->status_tx_quick_consumer_index0);
 5354 
 5355         BNX_PRINTF(sc, "status_idx = 0x%04X\n", sblk->status_idx);
 5356 
 5357         /* Theses indices are not used for normal L2 drivers. */
 5358         if (sblk->status_rx_quick_consumer_index1 || 
 5359                 sblk->status_tx_quick_consumer_index1)
 5360                 BNX_PRINTF(sc, "rx_cons1  = 0x%08X, tx_cons1      = 0x%08X\n",
 5361                     sblk->status_rx_quick_consumer_index1,
 5362                     sblk->status_tx_quick_consumer_index1);
 5363 
 5364         if (sblk->status_rx_quick_consumer_index2 || 
 5365                 sblk->status_tx_quick_consumer_index2)
 5366                 BNX_PRINTF(sc, "rx_cons2  = 0x%08X, tx_cons2      = 0x%08X\n",
 5367                     sblk->status_rx_quick_consumer_index2,
 5368                     sblk->status_tx_quick_consumer_index2);
 5369 
 5370         if (sblk->status_rx_quick_consumer_index3 || 
 5371                 sblk->status_tx_quick_consumer_index3)
 5372                 BNX_PRINTF(sc, "rx_cons3  = 0x%08X, tx_cons3      = 0x%08X\n",
 5373                     sblk->status_rx_quick_consumer_index3,
 5374                     sblk->status_tx_quick_consumer_index3);
 5375 
 5376         if (sblk->status_rx_quick_consumer_index4 || 
 5377                 sblk->status_rx_quick_consumer_index5)
 5378                 BNX_PRINTF(sc, "rx_cons4  = 0x%08X, rx_cons5      = 0x%08X\n",
 5379                     sblk->status_rx_quick_consumer_index4,
 5380                     sblk->status_rx_quick_consumer_index5);
 5381 
 5382         if (sblk->status_rx_quick_consumer_index6 || 
 5383                 sblk->status_rx_quick_consumer_index7)
 5384                 BNX_PRINTF(sc, "rx_cons6  = 0x%08X, rx_cons7      = 0x%08X\n",
 5385                     sblk->status_rx_quick_consumer_index6,
 5386                     sblk->status_rx_quick_consumer_index7);
 5387 
 5388         if (sblk->status_rx_quick_consumer_index8 || 
 5389                 sblk->status_rx_quick_consumer_index9)
 5390                 BNX_PRINTF(sc, "rx_cons8  = 0x%08X, rx_cons9      = 0x%08X\n",
 5391                     sblk->status_rx_quick_consumer_index8,
 5392                     sblk->status_rx_quick_consumer_index9);
 5393 
 5394         if (sblk->status_rx_quick_consumer_index10 || 
 5395                 sblk->status_rx_quick_consumer_index11)
 5396                 BNX_PRINTF(sc, "rx_cons10 = 0x%08X, rx_cons11     = 0x%08X\n",
 5397                     sblk->status_rx_quick_consumer_index10,
 5398                     sblk->status_rx_quick_consumer_index11);
 5399 
 5400         if (sblk->status_rx_quick_consumer_index12 || 
 5401                 sblk->status_rx_quick_consumer_index13)
 5402                 BNX_PRINTF(sc, "rx_cons12 = 0x%08X, rx_cons13     = 0x%08X\n",
 5403                     sblk->status_rx_quick_consumer_index12,
 5404                     sblk->status_rx_quick_consumer_index13);
 5405 
 5406         if (sblk->status_rx_quick_consumer_index14 || 
 5407                 sblk->status_rx_quick_consumer_index15)
 5408                 BNX_PRINTF(sc, "rx_cons14 = 0x%08X, rx_cons15     = 0x%08X\n",
 5409                     sblk->status_rx_quick_consumer_index14,
 5410                     sblk->status_rx_quick_consumer_index15);
 5411 
 5412         if (sblk->status_completion_producer_index || 
 5413                 sblk->status_cmd_consumer_index)
 5414                 BNX_PRINTF(sc, "com_prod  = 0x%08X, cmd_cons      = 0x%08X\n",
 5415                     sblk->status_completion_producer_index,
 5416                     sblk->status_cmd_consumer_index);
 5417 
 5418         BNX_PRINTF(sc, "-------------------------------------------"
 5419             "-----------------------------\n");
 5420 }
 5421 
 5422 /*
 5423  * This routine prints the statistics block.
 5424  */
 5425 void
 5426 bnx_dump_stats_block(struct bnx_softc *sc)
 5427 {
 5428         struct statistics_block *sblk;
 5429 
 5430         sblk = sc->stats_block;
 5431 
 5432         BNX_PRINTF(sc, ""
 5433             "-----------------------------"
 5434             " Stats  Block "
 5435             "-----------------------------\n");
 5436 
 5437         BNX_PRINTF(sc, "IfHcInOctets         = 0x%08X:%08X, "
 5438             "IfHcInBadOctets      = 0x%08X:%08X\n",
 5439             sblk->stat_IfHCInOctets_hi, sblk->stat_IfHCInOctets_lo,
 5440             sblk->stat_IfHCInBadOctets_hi, sblk->stat_IfHCInBadOctets_lo);
 5441 
 5442         BNX_PRINTF(sc, "IfHcOutOctets        = 0x%08X:%08X, "
 5443             "IfHcOutBadOctets     = 0x%08X:%08X\n",
 5444             sblk->stat_IfHCOutOctets_hi, sblk->stat_IfHCOutOctets_lo,
 5445             sblk->stat_IfHCOutBadOctets_hi, sblk->stat_IfHCOutBadOctets_lo);
 5446 
 5447         BNX_PRINTF(sc, "IfHcInUcastPkts      = 0x%08X:%08X, "
 5448             "IfHcInMulticastPkts  = 0x%08X:%08X\n",
 5449             sblk->stat_IfHCInUcastPkts_hi, sblk->stat_IfHCInUcastPkts_lo,
 5450             sblk->stat_IfHCInMulticastPkts_hi,
 5451             sblk->stat_IfHCInMulticastPkts_lo);
 5452 
 5453         BNX_PRINTF(sc, "IfHcInBroadcastPkts  = 0x%08X:%08X, "
 5454             "IfHcOutUcastPkts     = 0x%08X:%08X\n",
 5455             sblk->stat_IfHCInBroadcastPkts_hi,
 5456             sblk->stat_IfHCInBroadcastPkts_lo,
 5457             sblk->stat_IfHCOutUcastPkts_hi,
 5458             sblk->stat_IfHCOutUcastPkts_lo);
 5459 
 5460         BNX_PRINTF(sc, "IfHcOutMulticastPkts = 0x%08X:%08X, "
 5461             "IfHcOutBroadcastPkts = 0x%08X:%08X\n",
 5462             sblk->stat_IfHCOutMulticastPkts_hi,
 5463             sblk->stat_IfHCOutMulticastPkts_lo,
 5464             sblk->stat_IfHCOutBroadcastPkts_hi,
 5465             sblk->stat_IfHCOutBroadcastPkts_lo);
 5466 
 5467         if (sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors)
 5468                 BNX_PRINTF(sc, "0x%08X : "
 5469                     "emac_tx_stat_dot3statsinternalmactransmiterrors\n", 
 5470                     sblk->stat_emac_tx_stat_dot3statsinternalmactransmiterrors);
 5471 
 5472         if (sblk->stat_Dot3StatsCarrierSenseErrors)
 5473                 BNX_PRINTF(sc, "0x%08X : Dot3StatsCarrierSenseErrors\n",
 5474                     sblk->stat_Dot3StatsCarrierSenseErrors);
 5475 
 5476         if (sblk->stat_Dot3StatsFCSErrors)
 5477                 BNX_PRINTF(sc, "0x%08X : Dot3StatsFCSErrors\n",
 5478                     sblk->stat_Dot3StatsFCSErrors);
 5479 
 5480         if (sblk->stat_Dot3StatsAlignmentErrors)
 5481                 BNX_PRINTF(sc, "0x%08X : Dot3StatsAlignmentErrors\n",
 5482                     sblk->stat_Dot3StatsAlignmentErrors);
 5483 
 5484         if (sblk->stat_Dot3StatsSingleCollisionFrames)
 5485                 BNX_PRINTF(sc, "0x%08X : Dot3StatsSingleCollisionFrames\n",
 5486                     sblk->stat_Dot3StatsSingleCollisionFrames);
 5487 
 5488         if (sblk->stat_Dot3StatsMultipleCollisionFrames)
 5489                 BNX_PRINTF(sc, "0x%08X : Dot3StatsMultipleCollisionFrames\n",
 5490                     sblk->stat_Dot3StatsMultipleCollisionFrames);
 5491         
 5492         if (sblk->stat_Dot3StatsDeferredTransmissions)
 5493                 BNX_PRINTF(sc, "0x%08X : Dot3StatsDeferredTransmissions\n",
 5494                     sblk->stat_Dot3StatsDeferredTransmissions);
 5495 
 5496         if (sblk->stat_Dot3StatsExcessiveCollisions)
 5497                 BNX_PRINTF(sc, "0x%08X : Dot3StatsExcessiveCollisions\n",
 5498                     sblk->stat_Dot3StatsExcessiveCollisions);
 5499 
 5500         if (sblk->stat_Dot3StatsLateCollisions)
 5501                 BNX_PRINTF(sc, "0x%08X : Dot3StatsLateCollisions\n",
 5502                     sblk->stat_Dot3StatsLateCollisions);
 5503 
 5504         if (sblk->stat_EtherStatsCollisions)
 5505                 BNX_PRINTF(sc, "0x%08X : EtherStatsCollisions\n",
 5506                     sblk->stat_EtherStatsCollisions);
 5507 
 5508         if (sblk->stat_EtherStatsFragments) 
 5509                 BNX_PRINTF(sc, "0x%08X : EtherStatsFragments\n",
 5510                     sblk->stat_EtherStatsFragments);
 5511 
 5512         if (sblk->stat_EtherStatsJabbers)
 5513                 BNX_PRINTF(sc, "0x%08X : EtherStatsJabbers\n",
 5514                     sblk->stat_EtherStatsJabbers);
 5515 
 5516         if (sblk->stat_EtherStatsUndersizePkts)
 5517                 BNX_PRINTF(sc, "0x%08X : EtherStatsUndersizePkts\n",
 5518                     sblk->stat_EtherStatsUndersizePkts);
 5519 
 5520         if (sblk->stat_EtherStatsOverrsizePkts)
 5521                 BNX_PRINTF(sc, "0x%08X : EtherStatsOverrsizePkts\n",
 5522                     sblk->stat_EtherStatsOverrsizePkts);
 5523 
 5524         if (sblk->stat_EtherStatsPktsRx64Octets)
 5525                 BNX_PRINTF(sc, "0x%08X : EtherStatsPktsRx64Octets\n",
 5526                     sblk->stat_EtherStatsPktsRx64Octets);
 5527 
 5528         if (sblk->stat_EtherStatsPktsRx65Octetsto127Octets)
 5529                 BNX_PRINTF(sc, "0x%08X : EtherStatsPktsRx65Octetsto127Octets\n",
 5530                     sblk->stat_EtherStatsPktsRx65Octetsto127Octets);
 5531 
 5532         if (sblk->stat_EtherStatsPktsRx128Octetsto255Octets)
 5533                 BNX_PRINTF(sc, "0x%08X : "
 5534                     "EtherStatsPktsRx128Octetsto255Octets\n",
 5535                     sblk->stat_EtherStatsPktsRx128Octetsto255Octets);
 5536 
 5537         if (sblk->stat_EtherStatsPktsRx256Octetsto511Octets)
 5538                 BNX_PRINTF(sc, "0x%08X : "
 5539                     "EtherStatsPktsRx256Octetsto511Octets\n",
 5540                     sblk->stat_EtherStatsPktsRx256Octetsto511Octets);
 5541 
 5542         if (sblk->stat_EtherStatsPktsRx512Octetsto1023Octets)
 5543                 BNX_PRINTF(sc, "0x%08X : "
 5544                     "EtherStatsPktsRx512Octetsto1023Octets\n",
 5545                     sblk->stat_EtherStatsPktsRx512Octetsto1023Octets);
 5546 
 5547         if (sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets)
 5548                 BNX_PRINTF(sc, "0x%08X : "
 5549                     "EtherStatsPktsRx1024Octetsto1522Octets\n",
 5550                 sblk->stat_EtherStatsPktsRx1024Octetsto1522Octets);
 5551 
 5552         if (sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets)
 5553                 BNX_PRINTF(sc, "0x%08X : "
 5554                     "EtherStatsPktsRx1523Octetsto9022Octets\n",
 5555                     sblk->stat_EtherStatsPktsRx1523Octetsto9022Octets);
 5556 
 5557         if (sblk->stat_EtherStatsPktsTx64Octets)
 5558                 BNX_PRINTF(sc, "0x%08X : EtherStatsPktsTx64Octets\n",
 5559                     sblk->stat_EtherStatsPktsTx64Octets);
 5560 
 5561         if (sblk->stat_EtherStatsPktsTx65Octetsto127Octets)
 5562                 BNX_PRINTF(sc, "0x%08X : EtherStatsPktsTx65Octetsto127Octets\n",
 5563                     sblk->stat_EtherStatsPktsTx65Octetsto127Octets);
 5564 
 5565         if (sblk->stat_EtherStatsPktsTx128Octetsto255Octets)
 5566                 BNX_PRINTF(sc, "0x%08X : "
 5567                     "EtherStatsPktsTx128Octetsto255Octets\n",
 5568                     sblk->stat_EtherStatsPktsTx128Octetsto255Octets);
 5569 
 5570         if (sblk->stat_EtherStatsPktsTx256Octetsto511Octets)
 5571                 BNX_PRINTF(sc, "0x%08X : "
 5572                     "EtherStatsPktsTx256Octetsto511Octets\n",
 5573                     sblk->stat_EtherStatsPktsTx256Octetsto511Octets);
 5574 
 5575         if (sblk->stat_EtherStatsPktsTx512Octetsto1023Octets)
 5576                 BNX_PRINTF(sc, "0x%08X : "
 5577                     "EtherStatsPktsTx512Octetsto1023Octets\n",
 5578                     sblk->stat_EtherStatsPktsTx512Octetsto1023Octets);
 5579 
 5580         if (sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets)
 5581                 BNX_PRINTF(sc, "0x%08X : "
 5582                     "EtherStatsPktsTx1024Octetsto1522Octets\n",
 5583                     sblk->stat_EtherStatsPktsTx1024Octetsto1522Octets);
 5584 
 5585         if (sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets)
 5586                 BNX_PRINTF(sc, "0x%08X : "
 5587                     "EtherStatsPktsTx1523Octetsto9022Octets\n",
 5588                     sblk->stat_EtherStatsPktsTx1523Octetsto9022Octets);
 5589 
 5590         if (sblk->stat_XonPauseFramesReceived)
 5591                 BNX_PRINTF(sc, "0x%08X : XonPauseFramesReceived\n",
 5592                     sblk->stat_XonPauseFramesReceived);
 5593 
 5594         if (sblk->stat_XoffPauseFramesReceived)
 5595                 BNX_PRINTF(sc, "0x%08X : XoffPauseFramesReceived\n",
 5596                     sblk->stat_XoffPauseFramesReceived);
 5597 
 5598         if (sblk->stat_OutXonSent)
 5599                 BNX_PRINTF(sc, "0x%08X : OutXonSent\n",
 5600                     sblk->stat_OutXonSent);
 5601 
 5602         if (sblk->stat_OutXoffSent)
 5603                 BNX_PRINTF(sc, "0x%08X : OutXoffSent\n",
 5604                     sblk->stat_OutXoffSent);
 5605 
 5606         if (sblk->stat_FlowControlDone)
 5607                 BNX_PRINTF(sc, "0x%08X : FlowControlDone\n",
 5608                     sblk->stat_FlowControlDone);
 5609 
 5610         if (sblk->stat_MacControlFramesReceived)
 5611                 BNX_PRINTF(sc, "0x%08X : MacControlFramesReceived\n",
 5612                     sblk->stat_MacControlFramesReceived);
 5613 
 5614         if (sblk->stat_XoffStateEntered)
 5615                 BNX_PRINTF(sc, "0x%08X : XoffStateEntered\n",
 5616                     sblk->stat_XoffStateEntered);
 5617 
 5618         if (sblk->stat_IfInFramesL2FilterDiscards)
 5619                 BNX_PRINTF(sc, "0x%08X : IfInFramesL2FilterDiscards\n",
 5620                     sblk->stat_IfInFramesL2FilterDiscards);
 5621 
 5622         if (sblk->stat_IfInRuleCheckerDiscards)
 5623                 BNX_PRINTF(sc, "0x%08X : IfInRuleCheckerDiscards\n",
 5624                     sblk->stat_IfInRuleCheckerDiscards);
 5625 
 5626         if (sblk->stat_IfInFTQDiscards)
 5627                 BNX_PRINTF(sc, "0x%08X : IfInFTQDiscards\n",
 5628                     sblk->stat_IfInFTQDiscards);
 5629 
 5630         if (sblk->stat_IfInMBUFDiscards)
 5631                 BNX_PRINTF(sc, "0x%08X : IfInMBUFDiscards\n",
 5632                     sblk->stat_IfInMBUFDiscards);
 5633 
 5634         if (sblk->stat_IfInRuleCheckerP4Hit)
 5635                 BNX_PRINTF(sc, "0x%08X : IfInRuleCheckerP4Hit\n",
 5636                     sblk->stat_IfInRuleCheckerP4Hit);
 5637 
 5638         if (sblk->stat_CatchupInRuleCheckerDiscards)
 5639                 BNX_PRINTF(sc, "0x%08X : CatchupInRuleCheckerDiscards\n",
 5640                     sblk->stat_CatchupInRuleCheckerDiscards);
 5641 
 5642         if (sblk->stat_CatchupInFTQDiscards)
 5643                 BNX_PRINTF(sc, "0x%08X : CatchupInFTQDiscards\n",
 5644                     sblk->stat_CatchupInFTQDiscards);
 5645 
 5646         if (sblk->stat_CatchupInMBUFDiscards)
 5647                 BNX_PRINTF(sc, "0x%08X : CatchupInMBUFDiscards\n",
 5648                     sblk->stat_CatchupInMBUFDiscards);
 5649 
 5650         if (sblk->stat_CatchupInRuleCheckerP4Hit)
 5651                 BNX_PRINTF(sc, "0x%08X : CatchupInRuleCheckerP4Hit\n",
 5652                     sblk->stat_CatchupInRuleCheckerP4Hit);
 5653 
 5654         BNX_PRINTF(sc,
 5655             "-----------------------------"
 5656             "--------------"
 5657             "-----------------------------\n");
 5658 }
 5659 
 5660 void
 5661 bnx_dump_driver_state(struct bnx_softc *sc)
 5662 {
 5663         BNX_PRINTF(sc,
 5664             "-----------------------------"
 5665             " Driver State "
 5666             "-----------------------------\n");
 5667 
 5668         BNX_PRINTF(sc, "%p - (sc) driver softc structure virtual "
 5669             "address\n", sc);
 5670 
 5671         BNX_PRINTF(sc, "%p - (sc->status_block) status block virtual address\n",
 5672             sc->status_block);
 5673 
 5674         BNX_PRINTF(sc, "%p - (sc->stats_block) statistics block virtual "
 5675             "address\n", sc->stats_block);
 5676 
 5677         BNX_PRINTF(sc, "%p - (sc->tx_bd_chain) tx_bd chain virtual "
 5678             "adddress\n", sc->tx_bd_chain);
 5679 
 5680         BNX_PRINTF(sc, "%p - (sc->rx_bd_chain) rx_bd chain virtual address\n",
 5681             sc->rx_bd_chain);
 5682 
 5683         BNX_PRINTF(sc, "%p - (sc->tx_mbuf_ptr) tx mbuf chain virtual address\n",
 5684             sc->tx_mbuf_ptr);
 5685 
 5686         BNX_PRINTF(sc, "%p - (sc->rx_mbuf_ptr) rx mbuf chain virtual address\n",
 5687             sc->rx_mbuf_ptr);
 5688 
 5689         BNX_PRINTF(sc,
 5690             "         0x%08X - (sc->interrupts_generated) h/w intrs\n",
 5691             sc->interrupts_generated);
 5692         
 5693         BNX_PRINTF(sc,
 5694             "         0x%08X - (sc->rx_interrupts) rx interrupts handled\n",
 5695             sc->rx_interrupts);
 5696 
 5697         BNX_PRINTF(sc,
 5698             "         0x%08X - (sc->tx_interrupts) tx interrupts handled\n",
 5699             sc->tx_interrupts);
 5700 
 5701         BNX_PRINTF(sc,
 5702             "         0x%08X - (sc->last_status_idx) status block index\n",
 5703             sc->last_status_idx);
 5704 
 5705         BNX_PRINTF(sc, "         0x%08X - (sc->tx_prod) tx producer index\n",
 5706             sc->tx_prod);
 5707 
 5708         BNX_PRINTF(sc, "         0x%08X - (sc->tx_cons) tx consumer index\n",
 5709             sc->tx_cons);
 5710 
 5711         BNX_PRINTF(sc,
 5712             "         0x%08X - (sc->tx_prod_bseq) tx producer bseq index\n",
 5713             sc->tx_prod_bseq);
 5714 
 5715         BNX_PRINTF(sc, "         0x%08X - (sc->rx_prod) rx producer index\n",
 5716             sc->rx_prod);
 5717 
 5718         BNX_PRINTF(sc, "         0x%08X - (sc->rx_cons) rx consumer index\n",
 5719             sc->rx_cons);
 5720 
 5721         BNX_PRINTF(sc,
 5722             "         0x%08X - (sc->rx_prod_bseq) rx producer bseq index\n",
 5723             sc->rx_prod_bseq);
 5724 
 5725         BNX_PRINTF(sc,
 5726             "         0x%08X - (sc->rx_mbuf_alloc) rx mbufs allocated\n",
 5727             sc->rx_mbuf_alloc);
 5728 
 5729         BNX_PRINTF(sc, "         0x%08X - (sc->free_rx_bd) free rx_bd's\n",
 5730             sc->free_rx_bd);
 5731 
 5732         BNX_PRINTF(sc,
 5733             "0x%08X/%08X - (sc->rx_low_watermark) rx low watermark\n",
 5734             sc->rx_low_watermark, (u_int32_t) USABLE_RX_BD);
 5735 
 5736         BNX_PRINTF(sc,
 5737             "         0x%08X - (sc->txmbuf_alloc) tx mbufs allocated\n",
 5738             sc->tx_mbuf_alloc);
 5739 
 5740         BNX_PRINTF(sc,
 5741             "         0x%08X - (sc->rx_mbuf_alloc) rx mbufs allocated\n",
 5742             sc->rx_mbuf_alloc);
 5743 
 5744         BNX_PRINTF(sc, "         0x%08X - (sc->used_tx_bd) used tx_bd's\n",
 5745             sc->used_tx_bd);
 5746 
 5747         BNX_PRINTF(sc, "0x%08X/%08X - (sc->tx_hi_watermark) tx hi watermark\n",
 5748             sc->tx_hi_watermark, (u_int32_t) USABLE_TX_BD);
 5749 
 5750         BNX_PRINTF(sc,
 5751             "         0x%08X - (sc->mbuf_alloc_failed) failed mbuf alloc\n",
 5752             sc->mbuf_alloc_failed);
 5753 
 5754         BNX_PRINTF(sc, "-------------------------------------------"
 5755             "-----------------------------\n");
 5756 }
 5757 
 5758 void
 5759 bnx_dump_hw_state(struct bnx_softc *sc)
 5760 {
 5761         u_int32_t               val1;
 5762         int                     i;
 5763 
 5764         BNX_PRINTF(sc,
 5765             "----------------------------"
 5766             " Hardware State "
 5767             "----------------------------\n");
 5768 
 5769         BNX_PRINTF(sc, "0x%08X : bootcode version\n", sc->bnx_fw_ver);
 5770 
 5771         val1 = REG_RD(sc, BNX_MISC_ENABLE_STATUS_BITS);
 5772         BNX_PRINTF(sc, "0x%08X : (0x%04X) misc_enable_status_bits\n",
 5773             val1, BNX_MISC_ENABLE_STATUS_BITS);
 5774 
 5775         val1 = REG_RD(sc, BNX_DMA_STATUS);
 5776         BNX_PRINTF(sc, "0x%08X : (0x%04X) dma_status\n", val1, BNX_DMA_STATUS);
 5777 
 5778         val1 = REG_RD(sc, BNX_CTX_STATUS);
 5779         BNX_PRINTF(sc, "0x%08X : (0x%04X) ctx_status\n", val1, BNX_CTX_STATUS);
 5780 
 5781         val1 = REG_RD(sc, BNX_EMAC_STATUS);
 5782         BNX_PRINTF(sc, "0x%08X : (0x%04X) emac_status\n", val1,
 5783             BNX_EMAC_STATUS);
 5784 
 5785         val1 = REG_RD(sc, BNX_RPM_STATUS);
 5786         BNX_PRINTF(sc, "0x%08X : (0x%04X) rpm_status\n", val1, BNX_RPM_STATUS);
 5787 
 5788         val1 = REG_RD(sc, BNX_TBDR_STATUS);
 5789         BNX_PRINTF(sc, "0x%08X : (0x%04X) tbdr_status\n", val1,
 5790             BNX_TBDR_STATUS);
 5791 
 5792         val1 = REG_RD(sc, BNX_TDMA_STATUS);
 5793         BNX_PRINTF(sc, "0x%08X : (0x%04X) tdma_status\n", val1,
 5794             BNX_TDMA_STATUS);
 5795 
 5796         val1 = REG_RD(sc, BNX_HC_STATUS);
 5797         BNX_PRINTF(sc, "0x%08X : (0x%04X) hc_status\n", val1, BNX_HC_STATUS);
 5798 
 5799         BNX_PRINTF(sc, 
 5800             "----------------------------"
 5801             "----------------"
 5802             "----------------------------\n");
 5803 
 5804         BNX_PRINTF(sc, 
 5805             "----------------------------"
 5806             " Register  Dump "
 5807             "----------------------------\n");
 5808 
 5809         for (i = 0x400; i < 0x8000; i += 0x10)
 5810                 BNX_PRINTF(sc, "0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n",
 5811                     i, REG_RD(sc, i), REG_RD(sc, i + 0x4),
 5812                     REG_RD(sc, i + 0x8), REG_RD(sc, i + 0xC));
 5813 
 5814         BNX_PRINTF(sc, 
 5815             "----------------------------"
 5816             "----------------"
 5817             "----------------------------\n");
 5818 }
 5819 
 5820 void
 5821 bnx_breakpoint(struct bnx_softc *sc)
 5822 {
 5823         /* Unreachable code to shut the compiler up about unused functions. */
 5824         if (0) {
 5825                 bnx_dump_txbd(sc, 0, NULL);
 5826                 bnx_dump_rxbd(sc, 0, NULL);
 5827                 bnx_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD);
 5828                 bnx_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD);
 5829                 bnx_dump_l2fhdr(sc, 0, NULL);
 5830                 bnx_dump_tx_chain(sc, 0, USABLE_TX_BD);
 5831                 bnx_dump_rx_chain(sc, 0, USABLE_RX_BD);
 5832                 bnx_dump_status_block(sc);
 5833                 bnx_dump_stats_block(sc);
 5834                 bnx_dump_driver_state(sc);
 5835                 bnx_dump_hw_state(sc);
 5836         }
 5837 
 5838         bnx_dump_driver_state(sc);
 5839         /* Print the important status block fields. */
 5840         bnx_dump_status_block(sc);
 5841 
 5842 #if 0
 5843         /* Call the debugger. */
 5844         breakpoint();
 5845 #endif
 5846 
 5847         return;
 5848 }
 5849 #endif

/* [<][>][^][v][top][bottom][index][help] */