Author: davidch
Date: Thu Apr 21 23:06:00 2011
New Revision: 220932
URL: http://svn.freebsd.org/changeset/base/220932

Log:
  - Centralize driver tunables initialization/validation.
  - Centralize PCI resource allocation/release.
  - Enable flowid (TSS) support.
  - Added "per-fastpath" locks and watchdog timeouts.
  - Fixed problem where the CQ producer index was advanced beyond
    the size of the CQ ring during initialization.
  - Replaced hard-coded debug levels in some debug print statements.
  - More style(9) fixes.
  
  MFC after:    Two weeks

Modified:
  head/sys/dev/bxe/bxe_debug.h
  head/sys/dev/bxe/bxe_include.h
  head/sys/dev/bxe/if_bxe.c
  head/sys/dev/bxe/if_bxe.h

Modified: head/sys/dev/bxe/bxe_debug.h
==============================================================================
--- head/sys/dev/bxe/bxe_debug.h        Thu Apr 21 21:56:28 2011        
(r220931)
+++ head/sys/dev/bxe/bxe_debug.h        Thu Apr 21 23:06:00 2011        
(r220932)
@@ -159,50 +159,50 @@ extern uint32_t bxe_debug;
 #ifdef BXE_DEBUG
 
 /* Print a message based on the logging level and code path. */
-#define DBPRINT(sc, level, format, args...)                                    
\
-       do {                                                                    
                                \
-               if (BXE_LOG_MSG(level)) {                                       
                \
-                       device_printf(sc->bxe_dev, format, ## args);    \
-               }                                                               
                                        \
+#define DBPRINT(sc, level, format, args...)                            \
+       do {                                                            \
+               if (BXE_LOG_MSG(level)) {                               \
+                       device_printf(sc->dev, format, ## args);        \
+               }                                                       \
        } while (0)
 
 /* Runs a particular command when debugging is enabled. */
-#define DBRUN(args...)                 \
-       do {                                            \
-               args;                                   \
+#define DBRUN(args...)                                                 \
+       do {                                                            \
+               args;                                                   \
        } while (0)
 
 /* Runs a particular command based on the logging level. */
-#define DBRUNLV(level, args...) \
-       if (BXE_MSG_LEVEL(level)) { \
-               args;                                   \
+#define DBRUNLV(level, args...)                                        \
+       if (BXE_MSG_LEVEL(level)) {                                     \
+               args;                                                   \
        }
 
 /* Runs a particular command based on the code path. */
-#define DBRUNCP(cp, args...)   \
-       if (BXE_CODE_PATH(cp)) {        \
-               args;                                   \
+#define DBRUNCP(cp, args...)                                           \
+       if (BXE_CODE_PATH(cp)) {                                        \
+               args;                                                   \
        }
 
 /* Runs a particular command based on a condition. */
-#define DBRUNIF(cond, args...) \
-       if (cond) {                                     \
-               args;                                   \
+#define DBRUNIF(cond, args...)                                         \
+       if (cond) {                                                     \
+               args;                                                   \
        }
 
 /* Runs a particular command based on the logging level and code path. */
-#define DBRUNMSG(msg, args...) \
-       if (BXE_LOG_MSG(msg)) {         \
-               args;                                   \
+#define DBRUNMSG(msg, args...)                                         \
+       if (BXE_LOG_MSG(msg)) {                                         \
+               args;                                                   \
        }
 
 /* Announces function entry. */
-#define DBENTER(cond)  \
-       DBPRINT(sc, (cond), "%s(enter:%d)\n", __FUNCTION__, curcpu) \
+#define DBENTER(cond)                                                  \
+       DBPRINT(sc, (cond), "%s(enter:%d)\n", __FUNCTION__, curcpu)
 
 /* Announces function exit. */
-#define DBEXIT(cond)   \
-       DBPRINT(sc, (cond), "%s(exit:%d)\n", __FUNCTION__, curcpu) \
+#define DBEXIT(cond)                                                   \
+       DBPRINT(sc, (cond), "%s(exit:%d)\n", __FUNCTION__, curcpu)
 
 /* Needed for random() function which is only used in debugging. */
 #include <sys/random.h>

Modified: head/sys/dev/bxe/bxe_include.h
==============================================================================
--- head/sys/dev/bxe/bxe_include.h      Thu Apr 21 21:56:28 2011        
(r220931)
+++ head/sys/dev/bxe/bxe_include.h      Thu Apr 21 23:06:00 2011        
(r220932)
@@ -61,21 +61,21 @@
 /*
  * Convenience definitions used in multiple files.
  */
-#define BXE_PRINTF(fmt, args...)                               \
-       do {                                                                    
        \
-               device_printf(sc->bxe_dev, fmt, ##args);\
+#define BXE_PRINTF(fmt, args...)                                       \
+       do {                                                            \
+               device_printf(sc->dev, fmt, ##args);                    \
        }while(0)
 
 
 #ifdef BXE_DEBUG
 
-#define REG_WR(sc, offset, val)                \
+#define REG_WR(sc, offset, val)                        \
        bxe_reg_write32(sc, offset, val)
-#define REG_WR8(sc, offset, val)       \
+#define REG_WR8(sc, offset, val)               \
        bxe_reg_write8(sc, offset, val)
-#define REG_WR16(sc, offset, val)      \
+#define REG_WR16(sc, offset, val)              \
        bxe_reg_write16(sc, offset, val)
-#define REG_WR32(sc, offset, val)      \
+#define REG_WR32(sc, offset, val)              \
        bxe_reg_write32(sc, offset, val)
 
 #define REG_RD(sc, offset)                     \
@@ -87,77 +87,77 @@
 #define REG_RD32(sc, offset)                   \
        bxe_reg_read32(sc, offset)
 
-#define REG_RD_IND(sc, offset)         \
+#define REG_RD_IND(sc, offset)                 \
        bxe_reg_rd_ind(sc, offset)
-#define REG_WR_IND(sc, offset, val)    \
+#define REG_WR_IND(sc, offset, val)            \
        bxe_reg_wr_ind(sc, offset, val)
 
 #else
 
-#define REG_WR(sc, offset, val)                \
+#define REG_WR(sc, offset, val)                                                
\
        bus_space_write_4(sc->bxe_btag, sc->bxe_bhandle, offset, val)
-#define REG_WR8(sc, offset, val)       \
+#define REG_WR8(sc, offset, val)                                       \
        bus_space_write_1(sc->bxe_btag, sc->bxe_bhandle, offset, val)
-#define REG_WR16(sc, offset, val)      \
+#define REG_WR16(sc, offset, val)                                      \
        bus_space_write_2(sc->bxe_btag, sc->bxe_bhandle, offset, val)
-#define REG_WR32(sc, offset, val)              \
+#define REG_WR32(sc, offset, val)                                      \
        bus_space_write_4(sc->bxe_btag, sc->bxe_bhandle, offset, val)
 
-#define REG_RD(sc, offset)                     \
+#define REG_RD(sc, offset)                                             \
        bus_space_read_4(sc->bxe_btag, sc->bxe_bhandle, offset)
-#define REG_RD8(sc, offset)                    \
+#define REG_RD8(sc, offset)                                            \
        bus_space_read_1(sc->bxe_btag, sc->bxe_bhandle, offset)
-#define REG_RD16(sc, offset)                   \
+#define REG_RD16(sc, offset)                                           \
        bus_space_read_2(sc->bxe_btag, sc->bxe_bhandle, offset)
-#define REG_RD32(sc, offset)                   \
+#define REG_RD32(sc, offset)                                           \
        bus_space_read_4(sc->bxe_btag, sc->bxe_bhandle, offset)
 
-#define REG_RD_IND(sc, offset)         \
+#define REG_RD_IND(sc, offset)                                         \
        bxe_reg_rd_ind(sc, offset)
-#define REG_WR_IND(sc, offset, val)    \
+#define REG_WR_IND(sc, offset, val)                                    \
        bxe_reg_wr_ind(sc, offset, val)
 
 #endif /* BXE_DEBUG */
 
 
 #define REG_RD_DMAE(sc, offset, val, len32)                            \
-       do {                                                                    
                        \
-               bxe_read_dmae(sc, offset, len32);                               
\
-               memcpy(val, BXE_SP(sc, wb_data[0]), len32 * 4); \
+       do {                                                            \
+               bxe_read_dmae(sc, offset, len32);                       \
+               memcpy(val, BXE_SP(sc, wb_data[0]), len32 * 4);         \
        } while (0)
 
 
 #define REG_WR_DMAE(sc, offset, val, len32)                            \
-       do {                                                                    
                        \
-               memcpy(BXE_SP(sc, wb_data[0]), val, len32 * 4); \
-               bxe_write_dmae(sc, BXE_SP_MAPPING(sc, wb_data), \
-                       offset, len32);                                         
                \
+       do {                                                            \
+               memcpy(BXE_SP(sc, wb_data[0]), val, len32 * 4);         \
+               bxe_write_dmae(sc, BXE_SP_MAPPING(sc, wb_data),         \
+                       offset, len32);                                 \
        } while (0)
 
 
-#define SHMEM_ADDR(sc, field)  (sc->common.shmem_base + \
+#define SHMEM_ADDR(sc, field)  (sc->common.shmem_base +                \
        offsetof(struct shmem_region, field))
 
-#define SHMEM_RD(sc, field) \
+#define SHMEM_RD(sc, field)                                            \
        REG_RD(sc, SHMEM_ADDR(sc, field))
-#define SHMEM_RD16(sc, field) \
+#define SHMEM_RD16(sc, field)                                          \
        REG_RD16(sc, SHMEM_ADDR(sc, field))
 
-#define SHMEM_WR(sc, field, val) \
+#define SHMEM_WR(sc, field, val)                                       \
        REG_WR(sc, SHMEM_ADDR(sc, field), val)
 
-#define SHMEM2_ADDR(sc, field)         (sc->common.shmem2_base + \
-                                                                        
offsetof(struct shmem2_region, field))
+#define SHMEM2_ADDR(sc, field)         (sc->common.shmem2_base +       \
+       offsetof(struct shmem2_region, field))
 #define SHMEM2_RD(sc, field)           REG_RD(sc, SHMEM2_ADDR(sc, field))
 #define SHMEM2_WR(sc, field, val)      REG_WR(sc, SHMEM2_ADDR(sc, field), val)
 
 
-#define EMAC_RD(sc, reg) \
+#define EMAC_RD(sc, reg)                                               \
        REG_RD(sc, emac_base + (uint32_t) reg)
-#define EMAC_WR(sc, reg, val) \
+#define EMAC_WR(sc, reg, val)                                          \
        REG_WR(sc, emac_base + (uint32_t) reg, val)
 
-#define BMAC_WR(sc, reg, val) \
+#define BMAC_WR(sc, reg, val)                                          \
        REG_WR(sc, GRCBASE_NIG + bmac_addr + reg, val)
 
 #endif /* _BXE_INCLUDE_H */

Modified: head/sys/dev/bxe/if_bxe.c
==============================================================================
--- head/sys/dev/bxe/if_bxe.c   Thu Apr 21 21:56:28 2011        (r220931)
+++ head/sys/dev/bxe/if_bxe.c   Thu Apr 21 23:06:00 2011        (r220932)
@@ -68,7 +68,7 @@ __FBSDID("$FreeBSD$");
 
 /* BXE Debug Options */
 #ifdef BXE_DEBUG
-uint32_t bxe_debug = BXE_INFO;
+uint32_t bxe_debug = BXE_WARN;
 
 
 /*          0 = Never              */
@@ -132,6 +132,7 @@ static int  bxe_attach(device_t);
 static int  bxe_detach(device_t);
 static int  bxe_shutdown(device_t);
 
+static void bxe_set_tunables(struct bxe_softc *);
 static void bxe_print_adapter_info(struct bxe_softc *);
 static void bxe_probe_pci_caps(struct bxe_softc *);
 static void bxe_link_settings_supported(struct bxe_softc *, uint32_t);
@@ -145,6 +146,8 @@ static int  bxe_stop_leading(struct bxe_
 static int  bxe_setup_multi(struct bxe_softc *, int);
 static int  bxe_stop_multi(struct bxe_softc *, int);
 static int  bxe_stop_locked(struct bxe_softc *, int);
+static int  bxe_alloc_buf_rings(struct bxe_softc *);
+static void bxe_free_buf_rings(struct bxe_softc *);
 static void bxe_init_locked(struct bxe_softc *, int);
 static int  bxe_wait_ramrod(struct bxe_softc *, int, int, int *, int);
 static void bxe_init_str_wr(struct bxe_softc *, uint32_t, const uint32_t *,
@@ -237,6 +240,10 @@ static void bxe_stats_handle(struct bxe_
 static int  bxe_tx_encap(struct bxe_fastpath *, struct mbuf **);
 static void bxe_tx_start(struct ifnet *);
 static void bxe_tx_start_locked(struct ifnet *, struct bxe_fastpath *);
+static int  bxe_tx_mq_start(struct ifnet *, struct mbuf *);
+static int  bxe_tx_mq_start_locked(struct ifnet *, struct bxe_fastpath *,
+    struct mbuf *);
+static void bxe_mq_flush(struct ifnet *ifp);
 static int  bxe_ioctl(struct ifnet *, u_long, caddr_t);
 static __inline int bxe_has_rx_work(struct bxe_fastpath *);
 static __inline int bxe_has_tx_work(struct bxe_fastpath *);
@@ -266,6 +273,8 @@ static struct mbuf *bxe_alloc_mbuf(struc
 static int  bxe_map_mbuf(struct bxe_fastpath *, struct mbuf *, bus_dma_tag_t,
            bus_dmamap_t, bus_dma_segment_t *);
 static struct mbuf *bxe_alloc_tpa_mbuf(struct bxe_fastpath *, int, int);
+static void bxe_alloc_mutexes(struct bxe_softc *);
+static void bxe_free_mutexes(struct bxe_softc *);
 static int  bxe_alloc_rx_sge(struct bxe_softc *, struct bxe_fastpath *,
            uint16_t);
 static void bxe_init_rx_chains(struct bxe_softc *);
@@ -322,7 +331,7 @@ static void bxe_tpa_stop(struct bxe_soft
 static void bxe_rxeof(struct bxe_fastpath *);
 static void bxe_txeof(struct bxe_fastpath *);
 static int  bxe_get_buf(struct bxe_fastpath *, struct mbuf *, uint16_t);
-static void bxe_watchdog(struct bxe_softc *);
+static int  bxe_watchdog(struct bxe_fastpath *fp);
 static int  bxe_change_mtu(struct bxe_softc *, int);
 static void bxe_tick(void *);
 static void bxe_add_sysctls(struct bxe_softc *);
@@ -481,8 +490,7 @@ SYSCTL_UINT(_hw_bxe, OID_AUTO, queue_cou
  * destination IP address and the source/destination TCP port).
  *
  */
-/* static int bxe_multi_mode = ETH_RSS_MODE_REGULAR; */
-static int bxe_multi_mode = ETH_RSS_MODE_DISABLED;
+static int bxe_multi_mode = ETH_RSS_MODE_REGULAR;
 TUNABLE_INT("hw.bxe.multi_mode", &bxe_multi_mode);
 SYSCTL_UINT(_hw_bxe, OID_AUTO, multi_mode, CTLFLAG_RDTUN, &bxe_multi_mode,
     0, "Multi-Queue Mode");
@@ -738,7 +746,7 @@ bxe_calc_vn_wsum(struct bxe_softc *sc)
        uint32_t vn_cfg, vn_min_rate;
        int all_zero, vn;
 
-       DBENTER(1);
+       DBENTER(BXE_VERBOSE_LOAD);
 
        all_zero = 1;
        sc->vn_wsum = 0;
@@ -764,7 +772,7 @@ bxe_calc_vn_wsum(struct bxe_softc *sc)
        else
                sc->cmng.flags.cmng_enables |= CMNG_FLAGS_PER_PORT_FAIRNESS_VN;
 
-       DBEXIT(1);
+       DBEXIT(BXE_VERBOSE_LOAD);
 }
 
 /*
@@ -784,7 +792,7 @@ bxe_init_vn_minmax(struct bxe_softc *sc,
        vn_cfg = sc->mf_config[vn];
        func = 2 * vn + BP_PORT(sc);
 
-       DBENTER(1);
+       DBENTER(BXE_VERBOSE_LOAD);
 
        /* If function is hidden - set min and max to zeroes. */
        if (vn_cfg & FUNC_MF_CFG_FUNC_HIDE) {
@@ -807,7 +815,7 @@ bxe_init_vn_minmax(struct bxe_softc *sc,
                if (vn_max_rate == 0)
                        return;
        }
-       DBPRINT(sc, 1,
+       DBPRINT(sc, BXE_INFO_LOAD,
            "%s(): func %d: vn_min_rate = %d, vn_max_rate = %d, wsum = %d.\n",
            __FUNCTION__, func, vn_min_rate, vn_max_rate, sc->vn_wsum);
 
@@ -846,7 +854,8 @@ bxe_init_vn_minmax(struct bxe_softc *sc,
                REG_WR(sc, BAR_XSTORM_INTMEM +
                    XSTORM_FAIRNESS_PER_VN_VARS_OFFSET(func) + (i * 4),
                    ((uint32_t *)(&m_fair_vn))[i]);
-       DBEXIT(1);
+
+       DBEXIT(BXE_VERBOSE_LOAD);
 }
 
 static void
@@ -854,6 +863,8 @@ bxe_congestionmgmt(struct bxe_softc *sc,
 {
        int vn;
 
+       DBENTER(BXE_VERBOSE_LOAD);
+
        /* Read mf conf from shmem. */
        if (readshm)
                bxe_read_mf_cfg(sc);
@@ -871,11 +882,14 @@ bxe_congestionmgmt(struct bxe_softc *sc,
        /* Always enable rate shaping and fairness. */
        sc->cmng.flags.cmng_enables |= CMNG_FLAGS_PER_PORT_RATE_SHAPING_VN;
 
-       DBPRINT(sc, 1, "rate shaping set\n");
+       DBPRINT(sc, BXE_VERBOSE_LOAD,
+           "%s(): Rate shaping set\n", __FUNCTION__);
 
        if (!sc->vn_wsum)
-               DBPRINT(sc, 1,
-                   "All MIN values are zeroes fairness is disabled\n");
+               DBPRINT(sc, BXE_INFO_LOAD, "%s(): All MIN values "
+                   "are zeroes, fairness is disabled\n", __FUNCTION__);
+
+       DBEXIT(BXE_VERBOSE_LOAD);
 }
 
 static void
@@ -883,19 +897,18 @@ bxe_dcc_event(struct bxe_softc *sc, uint
 {
        int i, port;
 
+       DBENTER(BXE_VERBOSE_LOAD);
+
        if (dcc_event & DRV_STATUS_DCC_DISABLE_ENABLE_PF) {
-               /*
-                * This is the only place besides the function initialization
-                * where the sc->bxe_flags can change so it is done without any
-                * locks
-                */
                if (sc->mf_config[BP_E1HVN(sc)] & FUNC_MF_CFG_FUNC_DISABLED) {
-                       DBPRINT(sc, 1, "mf_cfg function disabled\n");
-                       sc->bxe_flags = BXE_STATE_DISABLED;
+                       DBPRINT(sc, BXE_INFO_LOAD, "%s(): mf_cfg function "
+                           "disabled\n", __FUNCTION__);
+                       sc->state = BXE_STATE_DISABLED;
                        bxe_e1h_disable(sc);
                } else {
-                       DBPRINT(sc, 1, "mf_cfg function enabled\n");
-                       sc->bxe_flags = BXE_STATE_OPEN;
+                       DBPRINT(sc, BXE_INFO_LOAD, "%s(): mf_cfg function "
+                           "enabled\n", __FUNCTION__);
+                       sc->state = BXE_STATE_OPEN;
                        bxe_e1h_enable(sc);
                }
                dcc_event &= ~DRV_STATUS_DCC_DISABLE_ENABLE_PF;
@@ -915,6 +928,8 @@ bxe_dcc_event(struct bxe_softc *sc, uint
                bxe_fw_command(sc, DRV_MSG_CODE_DCC_FAILURE);
        else
                bxe_fw_command(sc, DRV_MSG_CODE_DCC_OK);
+
+       DBEXIT(BXE_VERBOSE_LOAD);
 }
 
 /*
@@ -935,7 +950,7 @@ bxe_probe(device_t dev)
        uint16_t did, sdid, svid, vid;
 
        sc = device_get_softc(dev);
-       sc->bxe_dev = dev;
+       sc->dev = dev;
        t = bxe_devs;
 
        /* Get the data for the device to be probed. */
@@ -1028,7 +1043,7 @@ bxe_print_adapter_info(struct bxe_softc 
                printf("TPA"); i++;
        }
 
-       printf(") Queues (");
+       printf("); Queues (");
        switch (sc->multi_mode) {
        case ETH_RSS_MODE_DISABLED:
                printf("None");
@@ -1079,7 +1094,7 @@ bxe_interrupt_allocate(struct bxe_softc 
        int msix_count, msix_required, msix_allocated;
 
        rc = 0;
-       dev = sc->bxe_dev;
+       dev = sc->dev;
        msi_count = 0;
        msi_required = 0;
        msi_allocated = 0;
@@ -1096,70 +1111,6 @@ bxe_interrupt_allocate(struct bxe_softc 
        for (i = 0; i < BXE_MAX_PRIORITY; i++)
                sc->pri_map[i] = 0;
 
-       /*
-        * Get our starting point for interrupt mode/number of queues.
-        * We will progressively step down from MSI-X to MSI to INTx
-        * and reduce the number of receive queues as necessary to
-        * match the system capabilities.
-        */
-       sc->multi_mode = bxe_multi_mode;
-       sc->int_mode = bxe_int_mode;
-
-       /*
-        * Verify the Priority -> Receive Queue mappings.
-        */
-       if (sc->int_mode > 0) {
-               /* Multi-queue modes require MSI/MSI-X. */
-               switch (sc->multi_mode) {
-               case ETH_RSS_MODE_DISABLED:
-                       /* No multi-queue mode requested. */
-                       sc->num_queues = 1;
-                       break;
-               case ETH_RSS_MODE_REGULAR:
-                       if (sc->int_mode > 1) {
-                               /*
-                                * Assume we can use MSI-X
-                                * (max of 16 receive queues).
-                                */
-                               sc->num_queues = min((bxe_queue_count ?
-                                   bxe_queue_count : mp_ncpus), MAX_CONTEXT);
-                       } else {
-                               /*
-                                * Assume we can use MSI
-                                * (max of 7 receive queues).
-                                */
-                               sc->num_queues = min((bxe_queue_count ?
-                                   bxe_queue_count : mp_ncpus),
-                                   BXE_MSI_VECTOR_COUNT - 1);
-                       }
-                       break;
-               default:
-                       BXE_PRINTF(
-                           "%s(%d): Unsupported multi_mode parameter (%d), "
-                           "disabling multi-queue support!\n", __FILE__,
-                           __LINE__, sc->multi_mode);
-                       sc->multi_mode = ETH_RSS_MODE_DISABLED;
-                       sc->num_queues = 1;
-                       break;
-               }
-       } else {
-               /* User has forced INTx mode. */
-               sc->multi_mode = ETH_RSS_MODE_DISABLED;
-               sc->num_queues = 1;
-       }
-
-       DBPRINT(sc, (BXE_VERBOSE_LOAD | BXE_VERBOSE_INTR),
-           "%s(): Requested: int_mode = %d, multi_mode = %d num_queues = %d\n",
-           __FUNCTION__, sc->int_mode, sc->multi_mode, sc->num_queues);
-
-#ifdef BXE_DEBUG
-       for (i = 0; i < BXE_MAX_PRIORITY; i++) {
-               DBPRINT(sc, (BXE_VERBOSE_LOAD | BXE_VERBOSE_INTR),
-                   "%s(): sc->pri_map[%d] = %d.\n", __FUNCTION__, i,
-                   sc->pri_map[i]);
-       }
-#endif
-
        /* Get the number of available MSI/MSI-X interrupts from the OS. */
        if (sc->int_mode > 0) {
                if (sc->bxe_cap_flags & BXE_MSIX_CAPABLE_FLAG)
@@ -1331,7 +1282,7 @@ bxe_interrupt_detach(struct bxe_softc *s
        device_t dev;
        int i;
 
-       dev = sc->bxe_dev;
+       dev = sc->dev;
        DBENTER(BXE_VERBOSE_RESET | BXE_VERBOSE_UNLOAD);
        /* Release interrupt resources. */
        if ((sc->bxe_flags & BXE_USING_MSIX_FLAG) && sc->msix_count) {
@@ -1381,7 +1332,7 @@ bxe_interrupt_attach(struct bxe_softc *s
        sc->tq = taskqueue_create_fast("bxe_spq", M_NOWAIT,
                taskqueue_thread_enqueue, &sc->tq);
        taskqueue_start_threads(&sc->tq, 1, PI_NET, "%s spq",
-               device_get_nameunit(sc->bxe_dev));
+               device_get_nameunit(sc->dev));
 #endif
 
        /* Setup interrupt handlers. */
@@ -1393,7 +1344,7 @@ bxe_interrupt_attach(struct bxe_softc *s
                 * driver instance to the interrupt handler for the
                 * slowpath.
                 */
-               rc = bus_setup_intr(sc->bxe_dev,
+               rc = bus_setup_intr(sc->dev,
                                    sc->bxe_msix_res[0],
                                    INTR_TYPE_NET | INTR_MPSAFE,
                                    NULL,
@@ -1420,7 +1371,7 @@ bxe_interrupt_attach(struct bxe_softc *s
                         * fastpath context to the interrupt handler in this
                         * case. Also the first msix_res was used by the sp.
                         */
-                       rc = bus_setup_intr(sc->bxe_dev,
+                       rc = bus_setup_intr(sc->dev,
                                            sc->bxe_msix_res[i + 1],
                                            INTR_TYPE_NET | INTR_MPSAFE,
                                            NULL,
@@ -1440,7 +1391,7 @@ bxe_interrupt_attach(struct bxe_softc *s
                        fp->tq = taskqueue_create_fast("bxe_fpq", M_NOWAIT,
                                taskqueue_thread_enqueue, &fp->tq);
                        taskqueue_start_threads(&fp->tq, 1, PI_NET, "%s fpq",
-                               device_get_nameunit(sc->bxe_dev));
+                               device_get_nameunit(sc->dev));
 #endif
                        fp->state = BXE_FP_STATE_IRQ;
                }
@@ -1452,7 +1403,7 @@ bxe_interrupt_attach(struct bxe_softc *s
                 * Setup the interrupt handler. Note that we pass the driver
                 * instance to the interrupt handler for the slowpath.
                 */
-               rc = bus_setup_intr(sc->bxe_dev,sc->bxe_msi_res[0],
+               rc = bus_setup_intr(sc->dev,sc->bxe_msi_res[0],
                                    INTR_TYPE_NET | INTR_MPSAFE,
                                    NULL,
                                    bxe_intr_sp,
@@ -1479,7 +1430,7 @@ bxe_interrupt_attach(struct bxe_softc *s
                         * fastpath context to the interrupt handler in this
                         * case.
                         */
-                       rc = bus_setup_intr(sc->bxe_dev,
+                       rc = bus_setup_intr(sc->dev,
                                            sc->bxe_msi_res[i + 1],
                                            INTR_TYPE_NET | INTR_MPSAFE,
                                            NULL,
@@ -1499,7 +1450,7 @@ bxe_interrupt_attach(struct bxe_softc *s
                        fp->tq = taskqueue_create_fast("bxe_fpq", M_NOWAIT,
                                        taskqueue_thread_enqueue, &fp->tq);
                        taskqueue_start_threads(&fp->tq, 1, PI_NET, "%s fpq",
-                               device_get_nameunit(sc->bxe_dev));
+                               device_get_nameunit(sc->dev));
 #endif
                }
 
@@ -1515,7 +1466,7 @@ bxe_interrupt_attach(struct bxe_softc *s
                 * driver instance to the interrupt handler which
                 * will handle both the slowpath and fastpath.
                 */
-               rc = bus_setup_intr(sc->bxe_dev,sc->bxe_irq_res,
+               rc = bus_setup_intr(sc->dev,sc->bxe_irq_res,
                    INTR_TYPE_NET | INTR_MPSAFE,
                    NULL,
                    bxe_intr_legacy,
@@ -1529,13 +1480,10 @@ bxe_interrupt_attach(struct bxe_softc *s
                }
 #ifdef BXE_TASK
                TASK_INIT(&fp->task, 0, bxe_task_fp, fp);
-               fp->tq = taskqueue_create_fast("bxe_fpq", M_NOWAIT,
-                                              taskqueue_thread_enqueue,
-                                              &fp->tq
-                                              );
-               taskqueue_start_threads(&fp->tq, 1, PI_NET, "%s fpq",
-                                       device_get_nameunit(sc->bxe_dev)
-                                       );
+               fp->tq = taskqueue_create_fast("bxe_fpq",
+                   M_NOWAIT, taskqueue_thread_enqueue, &fp->tq);
+               taskqueue_start_threads(&fp->tq, 1,
+                   PI_NET, "%s fpq", device_get_nameunit(sc->dev));
 #endif
        }
 
@@ -1562,7 +1510,7 @@ bxe_probe_pci_caps(struct bxe_softc *sc)
        uint32_t reg;
        uint16_t link_status;
 
-       dev = sc->bxe_dev;
+       dev = sc->dev;
        DBENTER(BXE_EXTREME_LOAD);
 
        /* Check if PCI Power Management capability is enabled. */
@@ -1679,46 +1627,118 @@ bxe_init_firmware(struct bxe_softc *sc)
        return (0);
 }
 
-/*
- * Device attach function.
- *
- * Allocates device resources, performs secondary chip identification,
- * resets and initializes the hardware, and initializes driver instance
- * variables.
- *
- * Returns:
- *   0 = Success, Positive value on failure.
- */
-static int
-bxe_attach(device_t dev)
+
+static void
+bxe_set_tunables(struct bxe_softc *sc)
 {
-       struct bxe_softc *sc;
-       struct ifnet *ifp;
-       int rid, rc;
+       /*
+        * Get our starting point for interrupt mode/number of queues.
+        * We will progressively step down from MSI-X to MSI to INTx
+        * and reduce the number of receive queues as necessary to
+        * match the system capabilities.
+        */
+       sc->multi_mode  = bxe_multi_mode;
+       sc->int_mode    = bxe_int_mode;
+       sc->tso_enable  = bxe_tso_enable;
 
-       sc = device_get_softc(dev);
-       DBENTER(BXE_VERBOSE_LOAD | BXE_VERBOSE_RESET);
+       /*
+        * Verify the Priority -> Receive Queue mappings.
+        */
+       if (sc->int_mode > 0) {
+               /* Multi-queue modes require MSI/MSI-X. */
+               switch (sc->multi_mode) {
+               case ETH_RSS_MODE_DISABLED:
+                       /* No multi-queue mode requested. */
+                       sc->num_queues = 1;
+                       break;
+               case ETH_RSS_MODE_REGULAR:
+                       if (sc->int_mode > 1) {
+                               /*
+                                * Assume we can use MSI-X
+                                * (max of 16 receive queues).
+                                */
+                               sc->num_queues = min((bxe_queue_count ?
+                                   bxe_queue_count : mp_ncpus), MAX_CONTEXT);
+                       } else {
+                               /*
+                                * Assume we can use MSI
+                                * (max of 7 receive queues).
+                                */
+                               sc->num_queues = min((bxe_queue_count ?
+                                   bxe_queue_count : mp_ncpus),
+                                   BXE_MSI_VECTOR_COUNT - 1);
+                       }
+                       break;
+               default:
+                       BXE_PRINTF(
+                           "%s(%d): Unsupported multi_mode parameter (%d), "
+                           "disabling multi-queue support!\n", __FILE__,
+                           __LINE__, sc->multi_mode);
+                       sc->multi_mode = ETH_RSS_MODE_DISABLED;
+                       sc->num_queues = 1;
+                       break;
+               }
+       } else {
+               /* User has forced INTx mode. */
+               sc->multi_mode = ETH_RSS_MODE_DISABLED;
+               sc->num_queues = 1;
+       }
 
-       sc->bxe_dev = dev;
-       sc->bxe_unit = device_get_unit(dev);
-       sc->bxe_func = pci_get_function(dev);
-       sc->bxe_flags = 0;
-       sc->state = BXE_STATE_CLOSED;
-       rc = 0;
+       DBPRINT(sc, (BXE_VERBOSE_LOAD | BXE_VERBOSE_INTR),
+           "%s(): Requested: int_mode = %d, multi_mode = %d num_queues = %d\n",
+           __FUNCTION__, sc->int_mode, sc->multi_mode, sc->num_queues);
 
-       /* Initialize mutexes. */
-       BXE_CORE_LOCK_INIT(sc, device_get_nameunit(dev));
-       BXE_SP_LOCK_INIT(sc, "bxe_sp_lock");
-       BXE_DMAE_LOCK_INIT(sc, "bxe_dmae_lock");
-       BXE_PHY_LOCK_INIT(sc, "bxe_phy_lock");
-       BXE_FWMB_LOCK_INIT(sc, "bxe_fwmb_lock");
-       BXE_PRINT_LOCK_INIT(sc, "bxe_print_lock");
+       /* Set transparent packet aggregation (TPA), aka LRO, flag. */
+       if (bxe_tpa_enable!= FALSE)
+               sc->bxe_flags |= BXE_TPA_ENABLE_FLAG;
 
-       /* Prepare the tick routine. */
-       callout_init(&sc->bxe_tick_callout, CALLOUT_MPSAFE);
+       /* Capture the stats enable/disable setting. */
+       if (bxe_stats_enable == FALSE)
+               sc->stats_enable = FALSE;
+       else
+               sc->stats_enable = TRUE;
 
-       /* Enable bus master capability */
-       pci_enable_busmaster(dev);
+       /* Select the host coalescing tick count values (limit values). */
+       if (bxe_tx_ticks > 100) {
+               BXE_PRINTF("%s(%d): bxe_tx_ticks too large "
+                   "(%d), setting default value of 50.\n",
+                   __FILE__, __LINE__, bxe_tx_ticks);
+               sc->tx_ticks = 50;
+       } else
+               sc->tx_ticks = bxe_tx_ticks;
+
+       if (bxe_rx_ticks > 100) {
+               BXE_PRINTF("%s(%d): bxe_rx_ticks too large "
+                   "(%d), setting default value of 25.\n",
+                   __FILE__, __LINE__, bxe_rx_ticks);
+               sc->rx_ticks = 25;
+       } else
+               sc->rx_ticks = bxe_rx_ticks;
+
+       /* Select the PCIe maximum read request size (MRRS). */
+       if (bxe_mrrs > 3)
+               sc->mrrs = 3;
+       else
+               sc->mrrs = bxe_mrrs;
+
+       /* Check for DCC support. */
+       if (bxe_dcc_enable == FALSE)
+               sc->dcc_enable = FALSE;
+       else
+               sc->dcc_enable = TRUE;
+}
+
+
+/*
+ * Returns:
+ *   0 = Success, !0 = Failure
+ */
+static int
+bxe_alloc_pci_resources(struct bxe_softc *sc)
+{
+       int rid, rc = 0;
+
+       DBENTER(BXE_VERBOSE_LOAD);
 
        /*
         * Allocate PCI memory resources for BAR0.
@@ -1726,32 +1746,32 @@ bxe_attach(device_t dev)
         * processor memory.
         */
        rid = PCIR_BAR(0);
-       sc->bxe_res = bus_alloc_resource_any(dev,
-           SYS_RES_MEMORY, &rid, RF_ACTIVE);
+       sc->bxe_res = bus_alloc_resource_any(
+           sc->dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
        if (sc->bxe_res == NULL) {
                BXE_PRINTF("%s(%d):PCI BAR0 memory allocation failed\n",
                    __FILE__, __LINE__);
                rc = ENXIO;
-               goto bxe_attach_fail;
+               goto bxe_alloc_pci_resources_exit;
        }
 
        /* Get OS resource handles for BAR0 memory. */
-       sc->bxe_btag    = rman_get_bustag(sc->bxe_res);
-       sc->bxe_bhandle = rman_get_bushandle(sc->bxe_res);
-       sc->bxe_vhandle = (vm_offset_t) rman_get_virtual(sc->bxe_res);
+       sc->bxe_btag    = rman_get_bustag(sc->bxe_res);
+       sc->bxe_bhandle = rman_get_bushandle(sc->bxe_res);
+       sc->bxe_vhandle = (vm_offset_t) rman_get_virtual(sc->bxe_res);
 
        /*
         * Allocate PCI memory resources for BAR2.
         * Doorbell (DB) memory.
         */
        rid = PCIR_BAR(2);
-       sc->bxe_db_res = bus_alloc_resource_any(dev,
-           SYS_RES_MEMORY, &rid, RF_ACTIVE);
+       sc->bxe_db_res = bus_alloc_resource_any(
+           sc->dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
        if (sc->bxe_db_res == NULL) {
                BXE_PRINTF("%s(%d): PCI BAR2 memory allocation failed\n",
                    __FILE__, __LINE__);
                rc = ENXIO;
-               goto bxe_attach_fail;
+               goto bxe_alloc_pci_resources_exit;
        }
 
        /* Get OS resource handles for BAR2 memory. */
@@ -1759,21 +1779,45 @@ bxe_attach(device_t dev)
        sc->bxe_db_bhandle = rman_get_bushandle(sc->bxe_db_res);
        sc->bxe_db_vhandle = (vm_offset_t) rman_get_virtual(sc->bxe_db_res);
 
-       /* Put indirect address registers into a sane state. */
-       pci_write_config(sc->bxe_dev, PCICFG_GRC_ADDRESS,
-           PCICFG_VENDOR_ID_OFFSET, 4);
-       REG_WR(sc, PXP2_REG_PGL_ADDR_88_F0 + BP_PORT(sc) * 16, 0);
-       REG_WR(sc, PXP2_REG_PGL_ADDR_8C_F0 + BP_PORT(sc) * 16, 0);
-       REG_WR(sc, PXP2_REG_PGL_ADDR_90_F0 + BP_PORT(sc) * 16, 0);
-       REG_WR(sc, PXP2_REG_PGL_ADDR_94_F0 + BP_PORT(sc) * 16, 0);
+bxe_alloc_pci_resources_exit:
+       DBEXIT(BXE_VERBOSE_LOAD);
+       return(rc);
+}
 
-       /* Get hardware info from shared memory and validate data. */
-       if (bxe_get_function_hwinfo(sc)) {
-               DBPRINT(sc, BXE_WARN,
-                   "%s(): Failed to get hardware info!\n", __FUNCTION__);
-               rc = ENODEV;
-               goto bxe_attach_fail;
+
+/*
+ * Returns:
+ *   None
+ */
+static void
+bxe_release_pci_resources(struct bxe_softc *sc)
+{
+       /* Release the PCIe BAR0 mapped memory. */
+       if (sc->bxe_res != NULL) {
+               DBPRINT(sc, (BXE_VERBOSE_LOAD | BXE_VERBOSE_RESET),
+                   "%s(): Releasing PCI BAR0 memory.\n", __FUNCTION__);
+               bus_release_resource(sc->dev,
+                   SYS_RES_MEMORY, PCIR_BAR(0), sc->bxe_res);
+       }
+
+       /* Release the PCIe BAR2 (doorbell) mapped memory. */
+       if (sc->bxe_db_res != NULL) {
+               DBPRINT(sc, (BXE_VERBOSE_LOAD | BXE_VERBOSE_RESET),
+                   "%s(): Releasing PCI BAR2 memory.\n", __FUNCTION__);
+               bus_release_resource(sc->dev,
+                   SYS_RES_MEMORY, PCIR_BAR(2), sc->bxe_db_res);
        }
+}
+
+
+/*
+ * Returns:
+ *   0 = Success, !0 = Failure
+ */
+static int
+bxe_media_detect(struct bxe_softc *sc)
+{
+       int rc = 0;
 
        /* Identify supported media based on the PHY type. */
        switch (XGXS_EXT_PHY_TYPE(sc->link_params.ext_phy_config)) {
@@ -1782,21 +1826,21 @@ bxe_attach(device_t dev)
                    "%s(): Found 10GBase-CX4 media.\n", __FUNCTION__);
                sc->media = IFM_10G_CX4;
                break;
-#if 0
-       /* ToDo: Configure correct media types for these PHYs. */
-       case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8071
-       case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072
-       case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073
-       case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705
-       case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706
-       case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726
-#endif
+       case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
+               /* Technically 10GBase-KR but report as 10GBase-SR*/
+       case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
                DBPRINT(sc, BXE_INFO_LOAD,
                    "%s(): Found 10GBase-SR media.\n", __FUNCTION__);
                sc->media = IFM_10G_SR;
                break;
+       case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
+       case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
+               DBPRINT(sc, BXE_INFO_LOAD,
+                   "%s(): Found 10Gb twinax media.\n", __FUNCTION__);
+               sc->media = IFM_10G_TWINAX;
+               break;
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
        case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
@@ -1811,10 +1855,71 @@ bxe_attach(device_t dev)
                    __FILE__, __LINE__);
                sc->media = 0;
                rc = ENODEV;
+       }
+
+       return (rc);
+}
+
+
+/*
+ * Device attach function.
+ *
+ * Allocates device resources, performs secondary chip identification,
+ * resets and initializes the hardware, and initializes driver instance
+ * variables.
+ *
+ * Returns:
+ *   0 = Success, Positive value on failure.
+ */
+static int
+bxe_attach(device_t dev)
+{
+       struct bxe_softc *sc;
+       struct ifnet *ifp;
+       int rc;
+
+       sc = device_get_softc(dev);
+       DBENTER(BXE_VERBOSE_LOAD | BXE_VERBOSE_RESET);
+
+       sc->dev = dev;
+       sc->bxe_unit = device_get_unit(dev);
+       sc->bxe_func = pci_get_function(dev);
+       sc->bxe_flags = 0;
+       sc->state = BXE_STATE_CLOSED;
+       rc = 0;
+       bxe_set_tunables(sc);
+
+       bxe_alloc_mutexes(sc);
+
+       /* Prepare the tick routine. */
+       callout_init(&sc->bxe_tick_callout, CALLOUT_MPSAFE);
+
+       /* Enable bus master capability */
+       pci_enable_busmaster(dev);
+
+       if ((rc = bxe_alloc_pci_resources(sc)) != 0)
+               goto bxe_attach_fail;
+
+       /* Put indirect address registers into a sane state. */
+       pci_write_config(sc->dev, PCICFG_GRC_ADDRESS,
+           PCICFG_VENDOR_ID_OFFSET, 4);
+       REG_WR(sc, PXP2_REG_PGL_ADDR_88_F0 + BP_PORT(sc) * 16, 0);
+       REG_WR(sc, PXP2_REG_PGL_ADDR_8C_F0 + BP_PORT(sc) * 16, 0);
+       REG_WR(sc, PXP2_REG_PGL_ADDR_90_F0 + BP_PORT(sc) * 16, 0);
+       REG_WR(sc, PXP2_REG_PGL_ADDR_94_F0 + BP_PORT(sc) * 16, 0);
+
+       /* Get hardware info from shared memory and validate data. */
+       if (bxe_get_function_hwinfo(sc)) {
+               DBPRINT(sc, BXE_WARN,
+                   "%s(): Failed to get hardware info!\n", __FUNCTION__);
+               rc = ENODEV;
                goto bxe_attach_fail;
        }
 
        /* Setup supported media options. */
+       if ((rc = bxe_media_detect(sc)) != 0)
+               goto bxe_attach_fail;
+
        ifmedia_init(&sc->bxe_ifmedia,
            IFM_IMASK, bxe_ifmedia_upd, bxe_ifmedia_status);
        ifmedia_add(&sc->bxe_ifmedia,
@@ -1823,7 +1928,8 @@ bxe_attach(device_t dev)
            IFM_ETHER | IFM_AUTO, 0, NULL);
        ifmedia_set(&sc->bxe_ifmedia,
            IFM_ETHER | IFM_AUTO);
-       sc->bxe_ifmedia.ifm_media = sc->bxe_ifmedia.ifm_cur->ifm_media;
+       sc->bxe_ifmedia.ifm_media =
+           sc->bxe_ifmedia.ifm_cur->ifm_media;
 
        /* Set init arrays */
        rc = bxe_init_firmware(sc);
@@ -1877,18 +1983,6 @@ bxe_attach(device_t dev)
        if (!BP_NOMCP(sc))
                bxe_undi_unload(sc);
 
-       /* Set TPA flag. */
-       if (bxe_tpa_enable){
-               sc->bxe_flags |= BXE_TPA_ENABLE_FLAG;
-       }else
-               sc->bxe_flags &= ~BXE_TPA_ENABLE_FLAG;
-
-       /* Select the PCIe maximum read request size. */
-       if (bxe_mrrs > 3)
-               sc->mrrs = 3;
-       else
-               sc->mrrs = bxe_mrrs;
-
        /*
         * Select the RX and TX ring sizes.  The actual
         * ring size for TX is complicated by the fact
@@ -1904,10 +1998,6 @@ bxe_attach(device_t dev)
        /* Assume receive IP/TCP/UDP checksum is enabled. */
        sc->rx_csum = 1;
 
-       /* Select the host coalescing tick count values. */
-       sc->tx_ticks = bxe_tx_ticks;
-       sc->rx_ticks = bxe_rx_ticks;
-
        /* Disable WoL. */
        sc->wol = 0;
 
@@ -1915,7 +2005,7 @@ bxe_attach(device_t dev)
        sc->mbuf_alloc_size  = MCLBYTES;
 
        /* Allocate DMA memory resources. */
-       if (bxe_dma_alloc(sc->bxe_dev)) {
+       if (bxe_dma_alloc(sc->dev)) {

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to