Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 Apr 2011 23:06:00 +0000 (UTC)
From:      David Christensen <davidch@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r220932 - head/sys/dev/bxe
Message-ID:  <201104212306.p3LN60dp016020@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201104212306.p3LN60dp016020>