svn commit: r220932 - head/sys/dev/bxe
David Christensen
davidch at FreeBSD.org
Thu Apr 21 23:06:00 UTC 2011
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 ***
More information about the svn-src-head
mailing list