svn commit: r218423 - head/sys/dev/bce
David Christensen
davidch at FreeBSD.org
Mon Feb 7 23:00:24 UTC 2011
Author: davidch
Date: Mon Feb 7 23:00:24 2011
New Revision: 218423
URL: http://svn.freebsd.org/changeset/base/218423
Log:
- Added systcls for header splitting, RX/TX buffer count, interrupt
coalescing, strict RX MTU, verbose output, and shared memory debug.
- Added additional debug counters (VLAN tags and split header frames).
- Updated debug counters to 64 bit definitions.
- Updated l2fhdr bit definitions.
- Combined RX buffer sizing into a single function.
- Added buffer size and interrupt coalescing settings to adapter info
printout.
Submitted by: davidch
MFC after: 2 weeks
Modified:
head/sys/dev/bce/if_bce.c
head/sys/dev/bce/if_bcereg.h
Modified: head/sys/dev/bce/if_bce.c
==============================================================================
--- head/sys/dev/bce/if_bce.c Mon Feb 7 22:37:27 2011 (r218422)
+++ head/sys/dev/bce/if_bce.c Mon Feb 7 23:00:24 2011 (r218423)
@@ -287,48 +287,43 @@ static int bce_shutdown (device_t);
/* BCE Debug Data Structure Dump Routines */
/****************************************************************************/
#ifdef BCE_DEBUG
-static u32 bce_reg_rd (struct bce_softc *, u32);
-static void bce_reg_wr (struct bce_softc *, u32, u32);
-static void bce_reg_wr16 (struct bce_softc *, u32, u16);
-static u32 bce_ctx_rd (struct bce_softc *, u32, u32);
-static void bce_dump_enet (struct bce_softc *, struct mbuf *);
-static void bce_dump_mbuf (struct bce_softc *, struct mbuf *);
+static u32 bce_reg_rd (struct bce_softc *, u32);
+static void bce_reg_wr (struct bce_softc *, u32, u32);
+static void bce_reg_wr16 (struct bce_softc *, u32, u16);
+static u32 bce_ctx_rd (struct bce_softc *, u32, u32);
+static void bce_dump_enet (struct bce_softc *, struct mbuf *);
+static void bce_dump_mbuf (struct bce_softc *, struct mbuf *);
static void bce_dump_tx_mbuf_chain (struct bce_softc *, u16, int);
static void bce_dump_rx_mbuf_chain (struct bce_softc *, u16, int);
-#ifdef BCE_JUMBO_HDRSPLIT
static void bce_dump_pg_mbuf_chain (struct bce_softc *, u16, int);
-#endif
-static void bce_dump_txbd (struct bce_softc *,
+static void bce_dump_txbd (struct bce_softc *,
int, struct tx_bd *);
-static void bce_dump_rxbd (struct bce_softc *,
+static void bce_dump_rxbd (struct bce_softc *,
int, struct rx_bd *);
-#ifdef BCE_JUMBO_HDRSPLIT
-static void bce_dump_pgbd (struct bce_softc *,
+static void bce_dump_pgbd (struct bce_softc *,
int, struct rx_bd *);
-#endif
static void bce_dump_l2fhdr (struct bce_softc *,
int, struct l2_fhdr *);
-static void bce_dump_ctx (struct bce_softc *, u16);
-static void bce_dump_ftqs (struct bce_softc *);
+static void bce_dump_ctx (struct bce_softc *, u16);
+static void bce_dump_ftqs (struct bce_softc *);
static void bce_dump_tx_chain (struct bce_softc *, u16, int);
static void bce_dump_rx_bd_chain (struct bce_softc *, u16, int);
-#ifdef BCE_JUMBO_HDRSPLIT
static void bce_dump_pg_chain (struct bce_softc *, u16, int);
-#endif
static void bce_dump_status_block (struct bce_softc *);
static void bce_dump_stats_block (struct bce_softc *);
static void bce_dump_driver_state (struct bce_softc *);
static void bce_dump_hw_state (struct bce_softc *);
+static void bce_dump_shmem_state (struct bce_softc *);
static void bce_dump_mq_regs (struct bce_softc *);
static void bce_dump_bc_state (struct bce_softc *);
static void bce_dump_txp_state (struct bce_softc *, int);
static void bce_dump_rxp_state (struct bce_softc *, int);
-static void bce_dump_tpat_state (struct bce_softc *, int);
+static void bce_dump_tpat_state (struct bce_softc *, int);
static void bce_dump_cp_state (struct bce_softc *, int);
static void bce_dump_com_state (struct bce_softc *, int);
-static void bce_dump_rv2p_state (struct bce_softc *);
-static void bce_breakpoint (struct bce_softc *);
-#endif
+static void bce_dump_rv2p_state (struct bce_softc *);
+static void bce_breakpoint (struct bce_softc *);
+#endif /*BCE_DEBUG */
/****************************************************************************/
@@ -355,15 +350,15 @@ static int sysctl_nvram_write(SYSCTL_HAN
/****************************************************************************/
static int bce_acquire_nvram_lock (struct bce_softc *);
static int bce_release_nvram_lock (struct bce_softc *);
-static void bce_enable_nvram_access (struct bce_softc *);
-static void bce_disable_nvram_access (struct bce_softc *);
+static void bce_enable_nvram_access(struct bce_softc *);
+static void bce_disable_nvram_access(struct bce_softc *);
static int bce_nvram_read_dword (struct bce_softc *, u32, u8 *, u32);
-static int bce_init_nvram (struct bce_softc *);
-static int bce_nvram_read (struct bce_softc *, u32, u8 *, int);
-static int bce_nvram_test (struct bce_softc *);
+static int bce_init_nvram (struct bce_softc *);
+static int bce_nvram_read (struct bce_softc *, u32, u8 *, int);
+static int bce_nvram_test (struct bce_softc *);
#ifdef BCE_NVRAM_WRITE_SUPPORT
static int bce_enable_nvram_write (struct bce_softc *);
-static void bce_disable_nvram_write (struct bce_softc *);
+static void bce_disable_nvram_write(struct bce_softc *);
static int bce_nvram_erase_page (struct bce_softc *, u32);
static int bce_nvram_write_dword (struct bce_softc *, u32, u8 *, u32);
static int bce_nvram_write (struct bce_softc *, u32, u8 *, int);
@@ -372,12 +367,12 @@ static int bce_nvram_write (struct bce
/****************************************************************************/
/* */
/****************************************************************************/
-static void bce_get_media (struct bce_softc *);
-static void bce_init_media (struct bce_softc *);
-static void bce_dma_map_addr (void *,
- bus_dma_segment_t *, int, int);
-static int bce_dma_alloc (device_t);
-static void bce_dma_free (struct bce_softc *);
+static void bce_get_rx_buffer_sizes(struct bce_softc *, int);
+static void bce_get_media (struct bce_softc *);
+static void bce_init_media (struct bce_softc *);
+static void bce_dma_map_addr (void *, bus_dma_segment_t *, int, int);
+static int bce_dma_alloc (device_t);
+static void bce_dma_free (struct bce_softc *);
static void bce_release_resources (struct bce_softc *);
/****************************************************************************/
@@ -387,69 +382,67 @@ static int bce_fw_sync (struct bce_so
static void bce_load_rv2p_fw (struct bce_softc *, u32 *, u32, u32);
static void bce_load_cpu_fw (struct bce_softc *,
struct cpu_reg *, struct fw_info *);
-static void bce_start_cpu (struct bce_softc *, struct cpu_reg *);
-static void bce_halt_cpu (struct bce_softc *, struct cpu_reg *);
+static void bce_start_cpu (struct bce_softc *, struct cpu_reg *);
+static void bce_halt_cpu (struct bce_softc *, struct cpu_reg *);
static void bce_start_rxp_cpu (struct bce_softc *);
static void bce_init_rxp_cpu (struct bce_softc *);
static void bce_init_txp_cpu (struct bce_softc *);
static void bce_init_tpat_cpu (struct bce_softc *);
static void bce_init_cp_cpu (struct bce_softc *);
static void bce_init_com_cpu (struct bce_softc *);
-static void bce_init_cpus (struct bce_softc *);
+static void bce_init_cpus (struct bce_softc *);
-static void bce_print_adapter_info (struct bce_softc *);
+static void bce_print_adapter_info (struct bce_softc *);
static void bce_probe_pci_caps (device_t, struct bce_softc *);
-static void bce_stop (struct bce_softc *);
-static int bce_reset (struct bce_softc *, u32);
-static int bce_chipinit (struct bce_softc *);
-static int bce_blockinit (struct bce_softc *);
+static void bce_stop (struct bce_softc *);
+static int bce_reset (struct bce_softc *, u32);
+static int bce_chipinit (struct bce_softc *);
+static int bce_blockinit (struct bce_softc *);
static int bce_init_tx_chain (struct bce_softc *);
static void bce_free_tx_chain (struct bce_softc *);
-static int bce_get_rx_buf (struct bce_softc *,
+static int bce_get_rx_buf (struct bce_softc *,
struct mbuf *, u16 *, u16 *, u32 *);
static int bce_init_rx_chain (struct bce_softc *);
static void bce_fill_rx_chain (struct bce_softc *);
static void bce_free_rx_chain (struct bce_softc *);
-#ifdef BCE_JUMBO_HDRSPLIT
-static int bce_get_pg_buf (struct bce_softc *,
+static int bce_get_pg_buf (struct bce_softc *,
struct mbuf *, u16 *, u16 *);
static int bce_init_pg_chain (struct bce_softc *);
static void bce_fill_pg_chain (struct bce_softc *);
static void bce_free_pg_chain (struct bce_softc *);
-#endif
static struct mbuf *bce_tso_setup (struct bce_softc *,
struct mbuf **, u16 *);
-static int bce_tx_encap (struct bce_softc *, struct mbuf **);
+static int bce_tx_encap (struct bce_softc *, struct mbuf **);
static void bce_start_locked (struct ifnet *);
-static void bce_start (struct ifnet *);
-static int bce_ioctl (struct ifnet *, u_long, caddr_t);
-static void bce_watchdog (struct bce_softc *);
+static void bce_start (struct ifnet *);
+static int bce_ioctl (struct ifnet *, u_long, caddr_t);
+static void bce_watchdog (struct bce_softc *);
static int bce_ifmedia_upd (struct ifnet *);
static int bce_ifmedia_upd_locked (struct ifnet *);
static void bce_ifmedia_sts (struct ifnet *, struct ifmediareq *);
static void bce_init_locked (struct bce_softc *);
-static void bce_init (void *);
+static void bce_init (void *);
static void bce_mgmt_init_locked (struct bce_softc *sc);
-static int bce_init_ctx (struct bce_softc *);
+static int bce_init_ctx (struct bce_softc *);
static void bce_get_mac_addr (struct bce_softc *);
static void bce_set_mac_addr (struct bce_softc *);
-static void bce_phy_intr (struct bce_softc *);
+static void bce_phy_intr (struct bce_softc *);
static inline u16 bce_get_hw_rx_cons (struct bce_softc *);
static void bce_rx_intr (struct bce_softc *);
static void bce_tx_intr (struct bce_softc *);
static void bce_disable_intr (struct bce_softc *);
static void bce_enable_intr (struct bce_softc *, int);
-static void bce_intr (void *);
+static void bce_intr (void *);
static void bce_set_rx_mode (struct bce_softc *);
static void bce_stats_update (struct bce_softc *);
-static void bce_tick (void *);
-static void bce_pulse (void *);
+static void bce_tick (void *);
+static void bce_pulse (void *);
static void bce_add_sysctls (struct bce_softc *);
@@ -505,23 +498,148 @@ DRIVER_MODULE(miibus, bce, miibus_driver
SYSCTL_NODE(_hw, OID_AUTO, bce, CTLFLAG_RD, 0, "bce driver parameters");
/* Allowable values are TRUE or FALSE */
+static int bce_verbose = TRUE;
+TUNABLE_INT("hw.bce.verbose", &bce_verbose);
+SYSCTL_INT(_hw_bce, OID_AUTO, verbose, CTLFLAG_RDTUN, &bce_verbose, 0,
+ "Verbose output enable/disable");
+
+/* Allowable values are TRUE or FALSE */
static int bce_tso_enable = TRUE;
TUNABLE_INT("hw.bce.tso_enable", &bce_tso_enable);
SYSCTL_INT(_hw_bce, OID_AUTO, tso_enable, CTLFLAG_RDTUN, &bce_tso_enable, 0,
-"TSO Enable/Disable");
+ "TSO Enable/Disable");
/* Allowable values are 0 (IRQ), 1 (MSI/IRQ), and 2 (MSI-X/MSI/IRQ) */
/* ToDo: Add MSI-X support. */
static int bce_msi_enable = 1;
TUNABLE_INT("hw.bce.msi_enable", &bce_msi_enable);
SYSCTL_INT(_hw_bce, OID_AUTO, msi_enable, CTLFLAG_RDTUN, &bce_msi_enable, 0,
-"MSI-X|MSI|INTx selector");
+ "MSI-X|MSI|INTx selector");
+
+/* Allowable values are 1, 2, 4, 8. */
+static int bce_rx_pages = DEFAULT_RX_PAGES;
+TUNABLE_INT("hw.bce.rx_pages", &bce_rx_pages);
+SYSCTL_UINT(_hw_bce, OID_AUTO, rx_pages, CTLFLAG_RDTUN, &bce_rx_pages, 0,
+ "Receive buffer descriptor pages (1 page = 255 buffer descriptors)");
+
+/* Allowable values are 1, 2, 4, 8. */
+static int bce_tx_pages = DEFAULT_TX_PAGES;
+TUNABLE_INT("hw.bce.tx_pages", &bce_tx_pages);
+SYSCTL_UINT(_hw_bce, OID_AUTO, tx_pages, CTLFLAG_RDTUN, &bce_tx_pages, 0,
+ "Transmit buffer descriptor pages (1 page = 255 buffer descriptors)");
+
+/* Allowable values are TRUE or FALSE. */
+static int bce_hdr_split = TRUE;
+TUNABLE_INT("hw.bce.hdr_split", &bce_hdr_split);
+SYSCTL_UINT(_hw_bce, OID_AUTO, hdr_split, CTLFLAG_RDTUN, &bce_hdr_split, 0,
+ "Frame header/payload splitting Enable/Disable");
+
+/* Allowable values are TRUE or FALSE. */
+static int bce_strict_rx_mtu = FALSE;
+TUNABLE_INT("hw.bce.strict_rx_mtu", &bce_strict_rx_mtu);
+SYSCTL_UINT(_hw_bce, OID_AUTO, loose_rx_mtu, CTLFLAG_RDTUN,
+ &bce_strict_rx_mtu, 0,
+ "Enable/Disable strict RX frame size checking");
+
+/* Allowable values are 0 ... 100 */
+#ifdef BCE_DEBUG
+/* Generate 1 interrupt for every transmit completion. */
+static int bce_tx_quick_cons_trip_int = 1;
+#else
+/* Generate 1 interrupt for every 20 transmit completions. */
+static int bce_tx_quick_cons_trip_int = DEFAULT_TX_QUICK_CONS_TRIP_INT;
+#endif
+TUNABLE_INT("hw.bce.tx_quick_cons_trip_int", &bce_tx_quick_cons_trip_int);
+SYSCTL_UINT(_hw_bce, OID_AUTO, tx_quick_cons_trip_int, CTLFLAG_RDTUN,
+ &bce_tx_quick_cons_trip_int, 0,
+ "Transmit BD trip point during interrupts");
+
+/* Allowable values are 0 ... 100 */
+/* Generate 1 interrupt for every transmit completion. */
+#ifdef BCE_DEBUG
+static int bce_tx_quick_cons_trip = 1;
+#else
+/* Generate 1 interrupt for every 20 transmit completions. */
+static int bce_tx_quick_cons_trip = DEFAULT_TX_QUICK_CONS_TRIP;
+#endif
+TUNABLE_INT("hw.bce.tx_quick_cons_trip", &bce_tx_quick_cons_trip);
+SYSCTL_UINT(_hw_bce, OID_AUTO, tx_quick_cons_trip, CTLFLAG_RDTUN,
+ &bce_tx_quick_cons_trip, 0,
+ "Transmit BD trip point");
+
+/* Allowable values are 0 ... 100 */
+#ifdef BCE_DEBUG
+/* Generate an interrupt if 0us have elapsed since the last TX completion. */
+static int bce_tx_ticks_int = 0;
+#else
+/* Generate an interrupt if 80us have elapsed since the last TX completion. */
+static int bce_tx_ticks_int = DEFAULT_TX_TICKS_INT;
+#endif
+TUNABLE_INT("hw.bce.tx_ticks_int", &bce_tx_ticks_int);
+SYSCTL_UINT(_hw_bce, OID_AUTO, tx_ticks_int, CTLFLAG_RDTUN,
+ &bce_tx_ticks_int, 0, "Transmit ticks count during interrupt");
+
+/* Allowable values are 0 ... 100 */
+#ifdef BCE_DEBUG
+/* Generate an interrupt if 0us have elapsed since the last TX completion. */
+static int bce_tx_ticks = 0;
+#else
+/* Generate an interrupt if 80us have elapsed since the last TX completion. */
+static int bce_tx_ticks = DEFAULT_TX_TICKS;
+#endif
+TUNABLE_INT("hw.bce.tx_ticks", &bce_tx_ticks);
+SYSCTL_UINT(_hw_bce, OID_AUTO, tx_ticks, CTLFLAG_RDTUN,
+ &bce_tx_ticks, 0, "Transmit ticks count");
-/* ToDo: Add tunable to enable/disable strict MTU handling. */
-/* Currently allows "loose" RX MTU checking (i.e. sets the */
-/* H/W RX MTU to the size of the largest receive buffer, or */
-/* 2048 bytes). This will cause a UNH failure but is more */
-/* desireable from a functional perspective. */
+/* Allowable values are 1 ... 100 */
+#ifdef BCE_DEBUG
+/* Generate 1 interrupt for every received frame. */
+static int bce_rx_quick_cons_trip_int = 1;
+#else
+/* Generate 1 interrupt for every 6 received frames. */
+static int bce_rx_quick_cons_trip_int = DEFAULT_RX_QUICK_CONS_TRIP_INT;
+#endif
+TUNABLE_INT("hw.bce.rx_quick_cons_trip_int", &bce_rx_quick_cons_trip_int);
+SYSCTL_UINT(_hw_bce, OID_AUTO, rx_quick_cons_trip_int, CTLFLAG_RDTUN,
+ &bce_rx_quick_cons_trip_int, 0,
+ "Receive BD trip point duirng interrupts");
+
+/* Allowable values are 1 ... 100 */
+#ifdef BCE_DEBUG
+/* Generate 1 interrupt for every received frame. */
+static int bce_rx_quick_cons_trip = 1;
+#else
+/* Generate 1 interrupt for every 6 received frames. */
+static int bce_rx_quick_cons_trip = DEFAULT_RX_QUICK_CONS_TRIP;
+#endif
+TUNABLE_INT("hw.bce.rx_quick_cons_trip", &bce_rx_quick_cons_trip);
+SYSCTL_UINT(_hw_bce, OID_AUTO, rx_quick_cons_trip, CTLFLAG_RDTUN,
+ &bce_rx_quick_cons_trip, 0,
+ "Receive BD trip point");
+
+/* Allowable values are 0 ... 100 */
+#ifdef BCE_DEBUG
+/* Generate an int. if 0us have elapsed since the last received frame. */
+static int bce_rx_ticks_int = 0;
+#else
+/* Generate an int. if 18us have elapsed since the last received frame. */
+static int bce_rx_ticks_int = DEFAULT_RX_TICKS_INT;
+#endif
+TUNABLE_INT("hw.bce.rx_ticks_int", &bce_rx_ticks_int);
+SYSCTL_UINT(_hw_bce, OID_AUTO, rx_ticks_int, CTLFLAG_RDTUN,
+ &bce_rx_ticks_int, 0, "Receive ticks count during interrupt");
+
+/* Allowable values are 0 ... 100 */
+#ifdef BCE_DEBUG
+/* Generate an int. if 0us have elapsed since the last received frame. */
+static int bce_rx_ticks = 0;
+#else
+/* Generate an int. if 18us have elapsed since the last received frame. */
+static int bce_rx_ticks = DEFAULT_RX_TICKS;
+#endif
+TUNABLE_INT("hw.bce.rx_ticks", &bce_rx_ticks);
+SYSCTL_UINT(_hw_bce, OID_AUTO, rx_ticks, CTLFLAG_RDTUN,
+ &bce_rx_ticks, 0, "Receive ticks count");
/****************************************************************************/
@@ -603,7 +721,7 @@ bce_print_adapter_info(struct bce_softc
DBENTER(BCE_VERBOSE_LOAD);
- if (bootverbose) {
+ if (bce_verbose || bootverbose) {
BCE_PRINTF("ASIC (0x%08X); ", sc->bce_chipid);
printf("Rev (%c%d); ", ((BCE_CHIP_ID(sc) & 0xf000) >>
12) + 'A', ((BCE_CHIP_ID(sc) & 0x0ff0) >> 4));
@@ -625,12 +743,14 @@ bce_print_adapter_info(struct bce_softc
}
/* Firmware version and device features. */
- printf("B/C (%s); Flags (", sc->bce_bc_ver);
+ printf("B/C (%s); Bufs (RX:%d;TX:%d;PG:%d); Flags (",
+ sc->bce_bc_ver, sc->rx_pages, sc->tx_pages,
+ (bce_hdr_split == TRUE ? sc->pg_pages: 0));
- #ifdef BCE_JUMBO_HDRSPLIT
- printf("SPLT");
- i++;
- #endif
+ if (bce_hdr_split == TRUE) {
+ printf("SPLT");
+ i++;
+ }
if (sc->bce_flags & BCE_USING_MSI_FLAG) {
if (i > 0) printf("|");
@@ -653,6 +773,17 @@ bce_print_adapter_info(struct bce_softc
} else {
printf(")\n");
}
+
+ printf("Coal (RX:%d,%d,%d,%d; TX:%d,%d,%d,%d)\n",
+ sc->bce_rx_quick_cons_trip_int,
+ sc->bce_rx_quick_cons_trip,
+ sc->bce_rx_ticks_int,
+ sc->bce_rx_ticks,
+ sc->bce_tx_quick_cons_trip_int,
+ sc->bce_tx_quick_cons_trip,
+ sc->bce_tx_ticks_int,
+ sc->bce_tx_ticks);
+
}
DBEXIT(BCE_VERBOSE_LOAD);
@@ -711,6 +842,189 @@ bce_probe_pci_caps(device_t dev, struct
/****************************************************************************/
+/* Load and validate user tunable settings. */
+/* */
+/* Returns: */
+/* Nothing. */
+/****************************************************************************/
+static void
+bce_set_tunables(struct bce_softc *sc)
+{
+ /* Set sysctl values for RX page count. */
+ switch (bce_rx_pages) {
+ case 1:
+ /* fall-through */
+ case 2:
+ /* fall-through */
+ case 4:
+ /* fall-through */
+ case 8:
+ sc->rx_pages = bce_rx_pages;
+ break;
+ default:
+ sc->rx_pages = DEFAULT_RX_PAGES;
+ BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
+ "hw.bce.rx_pages! Setting default of %d.\n",
+ __FILE__, __LINE__, bce_rx_pages, DEFAULT_RX_PAGES);
+ }
+
+ /* ToDo: Consider allowing user setting for pg_pages. */
+ sc->pg_pages = min((sc->rx_pages * 4), MAX_PG_PAGES);
+
+ /* Set sysctl values for TX page count. */
+ switch (bce_tx_pages) {
+ case 1:
+ /* fall-through */
+ case 2:
+ /* fall-through */
+ case 4:
+ /* fall-through */
+ case 8:
+ sc->tx_pages = bce_tx_pages;
+ break;
+ default:
+ sc->tx_pages = DEFAULT_TX_PAGES;
+ BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
+ "hw.bce.tx_pages! Setting default of %d.\n",
+ __FILE__, __LINE__, bce_tx_pages, DEFAULT_TX_PAGES);
+ }
+
+ /*
+ * Validate the TX trip point (i.e. the number of
+ * TX completions before a status block update is
+ * generated and an interrupt is asserted.
+ */
+ if (bce_tx_quick_cons_trip_int <= 100) {
+ sc->bce_tx_quick_cons_trip_int =
+ bce_tx_quick_cons_trip_int;
+ } else {
+ BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
+ "hw.bce.tx_quick_cons_trip_int! Setting default of %d.\n",
+ __FILE__, __LINE__, bce_tx_quick_cons_trip_int,
+ DEFAULT_TX_QUICK_CONS_TRIP_INT);
+ sc->bce_tx_quick_cons_trip_int =
+ DEFAULT_TX_QUICK_CONS_TRIP_INT;
+ }
+
+ if (bce_tx_quick_cons_trip <= 100) {
+ sc->bce_tx_quick_cons_trip =
+ bce_tx_quick_cons_trip;
+ } else {
+ BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
+ "hw.bce.tx_quick_cons_trip! Setting default of %d.\n",
+ __FILE__, __LINE__, bce_tx_quick_cons_trip,
+ DEFAULT_TX_QUICK_CONS_TRIP);
+ sc->bce_tx_quick_cons_trip =
+ DEFAULT_TX_QUICK_CONS_TRIP;
+ }
+
+ /*
+ * Validate the TX ticks count (i.e. the maximum amount
+ * of time to wait after the last TX completion has
+ * occurred before a status block update is generated
+ * and an interrupt is asserted.
+ */
+ if (bce_tx_ticks_int <= 100) {
+ sc->bce_tx_ticks_int =
+ bce_tx_ticks_int;
+ } else {
+ BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
+ "hw.bce.tx_ticks_int! Setting default of %d.\n",
+ __FILE__, __LINE__, bce_tx_ticks_int,
+ DEFAULT_TX_TICKS_INT);
+ sc->bce_tx_ticks_int =
+ DEFAULT_TX_TICKS_INT;
+ }
+
+ if (bce_tx_ticks <= 100) {
+ sc->bce_tx_ticks =
+ bce_tx_ticks;
+ } else {
+ BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
+ "hw.bce.tx_ticks! Setting default of %d.\n",
+ __FILE__, __LINE__, bce_tx_ticks,
+ DEFAULT_TX_TICKS);
+ sc->bce_tx_ticks =
+ DEFAULT_TX_TICKS;
+ }
+
+ /*
+ * Validate the RX trip point (i.e. the number of
+ * RX frames received before a status block update is
+ * generated and an interrupt is asserted.
+ */
+ if (bce_rx_quick_cons_trip_int <= 100) {
+ sc->bce_rx_quick_cons_trip_int =
+ bce_rx_quick_cons_trip_int;
+ } else {
+ BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
+ "hw.bce.rx_quick_cons_trip_int! Setting default of %d.\n",
+ __FILE__, __LINE__, bce_rx_quick_cons_trip_int,
+ DEFAULT_RX_QUICK_CONS_TRIP_INT);
+ sc->bce_rx_quick_cons_trip_int =
+ DEFAULT_RX_QUICK_CONS_TRIP_INT;
+ }
+
+ if (bce_rx_quick_cons_trip <= 100) {
+ sc->bce_rx_quick_cons_trip =
+ bce_rx_quick_cons_trip;
+ } else {
+ BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
+ "hw.bce.rx_quick_cons_trip! Setting default of %d.\n",
+ __FILE__, __LINE__, bce_rx_quick_cons_trip,
+ DEFAULT_RX_QUICK_CONS_TRIP);
+ sc->bce_rx_quick_cons_trip =
+ DEFAULT_RX_QUICK_CONS_TRIP;
+ }
+
+ /*
+ * Validate the RX ticks count (i.e. the maximum amount
+ * of time to wait after the last RX frame has been
+ * received before a status block update is generated
+ * and an interrupt is asserted.
+ */
+ if (bce_rx_ticks_int <= 100) {
+ sc->bce_rx_ticks_int = bce_rx_ticks_int;
+ } else {
+ BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
+ "hw.bce.rx_ticks_int! Setting default of %d.\n",
+ __FILE__, __LINE__, bce_rx_ticks_int,
+ DEFAULT_RX_TICKS_INT);
+ sc->bce_rx_ticks_int = DEFAULT_RX_TICKS_INT;
+ }
+
+ if (bce_rx_ticks <= 100) {
+ sc->bce_rx_ticks = bce_rx_ticks;
+ } else {
+ BCE_PRINTF("%s(%d): Illegal value (%d) specified for "
+ "hw.bce.rx_ticks! Setting default of %d.\n",
+ __FILE__, __LINE__, bce_rx_ticks,
+ DEFAULT_RX_TICKS);
+ sc->bce_rx_ticks = DEFAULT_RX_TICKS;
+ }
+
+ /* Disabling both RX ticks and RX trips will prevent interrupts. */
+ if ((bce_rx_quick_cons_trip == 0) && (bce_rx_ticks == 0)) {
+ BCE_PRINTF("%s(%d): Cannot set both hw.bce.rx_ticks and "
+ "hw.bce.rx_quick_cons_trip to 0. Setting default values.\n",
+ __FILE__, __LINE__);
+ sc->bce_rx_ticks = DEFAULT_RX_TICKS;
+ sc->bce_rx_quick_cons_trip = DEFAULT_RX_QUICK_CONS_TRIP;
+ }
+
+ /* Disabling both TX ticks and TX trips will prevent interrupts. */
+ if ((bce_tx_quick_cons_trip == 0) && (bce_tx_ticks == 0)) {
+ BCE_PRINTF("%s(%d): Cannot set both hw.bce.tx_ticks and "
+ "hw.bce.tx_quick_cons_trip to 0. Setting default values.\n",
+ __FILE__, __LINE__);
+ sc->bce_tx_ticks = DEFAULT_TX_TICKS;
+ sc->bce_tx_quick_cons_trip = DEFAULT_TX_QUICK_CONS_TRIP;
+ }
+
+}
+
+
+/****************************************************************************/
/* Device attach function. */
/* */
/* Allocates device resources, performs secondary chip identification, */
@@ -739,6 +1053,8 @@ bce_attach(device_t dev)
sc->bce_flags = 0;
sc->bce_phy_flags = 0;
+ bce_set_tunables(sc);
+
pci_enable_busmaster(dev);
/* Allocate PCI memory resources. */
@@ -1028,37 +1344,13 @@ bce_attach(device_t dev)
* values for the RX and TX chains.
*/
-#ifdef BCE_DEBUG
- /* Force more frequent interrupts. */
- sc->bce_tx_quick_cons_trip_int = 1;
- sc->bce_tx_quick_cons_trip = 1;
- sc->bce_tx_ticks_int = 0;
- sc->bce_tx_ticks = 0;
-
- sc->bce_rx_quick_cons_trip_int = 1;
- sc->bce_rx_quick_cons_trip = 1;
- sc->bce_rx_ticks_int = 0;
- sc->bce_rx_ticks = 0;
-#else
- /* Improve throughput at the expense of increased latency. */
- sc->bce_tx_quick_cons_trip_int = 20;
- sc->bce_tx_quick_cons_trip = 20;
- sc->bce_tx_ticks_int = 80;
- sc->bce_tx_ticks = 80;
-
- sc->bce_rx_quick_cons_trip_int = 6;
- sc->bce_rx_quick_cons_trip = 6;
- sc->bce_rx_ticks_int = 18;
- sc->bce_rx_ticks = 18;
-#endif
-
/* Not used for L2. */
- sc->bce_comp_prod_trip_int = 0;
- sc->bce_comp_prod_trip = 0;
- sc->bce_com_ticks_int = 0;
- sc->bce_com_ticks = 0;
- sc->bce_cmd_ticks_int = 0;
- sc->bce_cmd_ticks = 0;
+ sc->bce_comp_prod_trip_int = 0;
+ sc->bce_comp_prod_trip = 0;
+ sc->bce_com_ticks_int = 0;
+ sc->bce_com_ticks = 0;
+ sc->bce_cmd_ticks_int = 0;
+ sc->bce_cmd_ticks = 0;
/* Update statistics once every second. */
sc->bce_stats_ticks = 1000000 & 0xffff00;
@@ -1112,23 +1404,11 @@ bce_attach(device_t dev)
* This may change later if the MTU size is set to
* something other than 1500.
*/
-#ifdef BCE_JUMBO_HDRSPLIT
- sc->rx_bd_mbuf_alloc_size = MHLEN;
- /* Make sure offset is 16 byte aligned for hardware. */
- sc->rx_bd_mbuf_align_pad =
- roundup2((MSIZE - MHLEN), 16) - (MSIZE - MHLEN);
- sc->rx_bd_mbuf_data_len = sc->rx_bd_mbuf_alloc_size -
- sc->rx_bd_mbuf_align_pad;
- sc->pg_bd_mbuf_alloc_size = MCLBYTES;
-#else
- sc->rx_bd_mbuf_alloc_size = MCLBYTES;
- sc->rx_bd_mbuf_align_pad =
- roundup2(MCLBYTES, 16) - MCLBYTES;
- sc->rx_bd_mbuf_data_len = sc->rx_bd_mbuf_alloc_size -
- sc->rx_bd_mbuf_align_pad;
-#endif
+ bce_get_rx_buffer_sizes(sc,
+ (ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN));
- ifp->if_snd.ifq_drv_maxlen = USABLE_TX_BD;
+ /* Recalculate our buffer allocation sizes. */
+ ifp->if_snd.ifq_drv_maxlen = USABLE_TX_BD_ALLOC;
IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
IFQ_SET_READY(&ifp->if_snd);
@@ -2695,6 +2975,58 @@ bce_nvram_test_exit:
/****************************************************************************/
+/* Calculates the size of the buffers to allocate based on the MTU. */
+/* */
+/* Returns: */
+/* Nothing. */
+/****************************************************************************/
+static void
+bce_get_rx_buffer_sizes(struct bce_softc *sc, int mtu)
+{
+ DBENTER(BCE_VERBOSE_LOAD);
+
+ /* Use a single allocation type when header splitting enabled. */
+ if (bce_hdr_split == TRUE) {
+ sc->rx_bd_mbuf_alloc_size = MHLEN;
+ /* Make sure offset is 16 byte aligned for hardware. */
+ sc->rx_bd_mbuf_align_pad =
+ roundup2((MSIZE - MHLEN), 16) - (MSIZE - MHLEN);
+ sc->rx_bd_mbuf_data_len = sc->rx_bd_mbuf_alloc_size -
+ sc->rx_bd_mbuf_align_pad;
+ sc->pg_bd_mbuf_alloc_size = MCLBYTES;
+ } else {
+ if ((mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN +
+ ETHER_CRC_LEN) > MCLBYTES) {
+ /* Setup for jumbo RX buffer allocations. */
+ sc->rx_bd_mbuf_alloc_size = MJUM9BYTES;
+ sc->rx_bd_mbuf_align_pad =
+ roundup2(MJUM9BYTES, 16) - MJUM9BYTES;
+ sc->rx_bd_mbuf_data_len =
+ sc->rx_bd_mbuf_alloc_size -
+ sc->rx_bd_mbuf_align_pad;
+ } else {
+ /* Setup for standard RX buffer allocations. */
+ sc->rx_bd_mbuf_alloc_size = MCLBYTES;
+ sc->rx_bd_mbuf_align_pad =
+ roundup2(MCLBYTES, 16) - MCLBYTES;
+ sc->rx_bd_mbuf_data_len =
+ sc->rx_bd_mbuf_alloc_size -
+ sc->rx_bd_mbuf_align_pad;
+ }
+ }
+
+// DBPRINT(sc, BCE_INFO_LOAD,
+ DBPRINT(sc, BCE_WARN,
+ "%s(): rx_bd_mbuf_alloc_size = %d, rx_bd_mbuf_data_len = %d, "
+ "rx_bd_mbuf_align_pad = %d\n", __FUNCTION__,
+ sc->rx_bd_mbuf_alloc_size, sc->rx_bd_mbuf_data_len,
+ sc->rx_bd_mbuf_align_pad);
+
+ DBEXIT(BCE_VERBOSE_LOAD);
+
+}
+
+/****************************************************************************/
/* Identifies the current media type of the controller and sets the PHY */
/* address. */
/* */
@@ -2929,7 +3261,7 @@ bce_dma_free(struct bce_softc *sc)
/* Free, unmap and destroy all TX buffer descriptor chain pages. */
- for (i = 0; i < TX_PAGES; i++ ) {
+ for (i = 0; i < sc->tx_pages; i++ ) {
if (sc->tx_bd_chain[i] != NULL) {
bus_dmamem_free(
sc->tx_bd_chain_tag,
@@ -2957,7 +3289,7 @@ bce_dma_free(struct bce_softc *sc)
/* Free, unmap and destroy all RX buffer descriptor chain pages. */
- for (i = 0; i < RX_PAGES; i++ ) {
+ for (i = 0; i < sc->rx_pages; i++ ) {
if (sc->rx_bd_chain[i] != NULL) {
bus_dmamem_free(
sc->rx_bd_chain_tag,
@@ -2984,38 +3316,38 @@ bce_dma_free(struct bce_softc *sc)
}
-#ifdef BCE_JUMBO_HDRSPLIT
/* Free, unmap and destroy all page buffer descriptor chain pages. */
- for (i = 0; i < PG_PAGES; i++ ) {
- if (sc->pg_bd_chain[i] != NULL) {
- bus_dmamem_free(
- sc->pg_bd_chain_tag,
- sc->pg_bd_chain[i],
- sc->pg_bd_chain_map[i]);
- sc->pg_bd_chain[i] = NULL;
+ if (bce_hdr_split == TRUE) {
+ for (i = 0; i < sc->pg_pages; i++ ) {
+ if (sc->pg_bd_chain[i] != NULL) {
+ bus_dmamem_free(
+ sc->pg_bd_chain_tag,
+ sc->pg_bd_chain[i],
+ sc->pg_bd_chain_map[i]);
+ sc->pg_bd_chain[i] = NULL;
+ }
+
+ if (sc->pg_bd_chain_map[i] != NULL) {
+ bus_dmamap_unload(
+ sc->pg_bd_chain_tag,
+ sc->pg_bd_chain_map[i]);
+ bus_dmamap_destroy(
+ sc->pg_bd_chain_tag,
+ sc->pg_bd_chain_map[i]);
+ sc->pg_bd_chain_map[i] = NULL;
+ }
}
- if (sc->pg_bd_chain_map[i] != NULL) {
- bus_dmamap_unload(
- sc->pg_bd_chain_tag,
- sc->pg_bd_chain_map[i]);
- bus_dmamap_destroy(
- sc->pg_bd_chain_tag,
- sc->pg_bd_chain_map[i]);
- sc->pg_bd_chain_map[i] = NULL;
+ /* Destroy the page buffer descriptor tag. */
+ if (sc->pg_bd_chain_tag != NULL) {
+ bus_dma_tag_destroy(sc->pg_bd_chain_tag);
+ sc->pg_bd_chain_tag = NULL;
}
}
- /* Destroy the page buffer descriptor tag. */
- if (sc->pg_bd_chain_tag != NULL) {
- bus_dma_tag_destroy(sc->pg_bd_chain_tag);
- sc->pg_bd_chain_tag = NULL;
- }
-#endif
-
/* Unload and destroy the TX mbuf maps. */
- for (i = 0; i < TOTAL_TX_BD; i++) {
+ for (i = 0; i < MAX_TX_BD_AVAIL; i++) {
if (sc->tx_mbuf_map[i] != NULL) {
bus_dmamap_unload(sc->tx_mbuf_tag,
sc->tx_mbuf_map[i]);
@@ -3032,7 +3364,7 @@ bce_dma_free(struct bce_softc *sc)
}
/* Unload and destroy the RX mbuf maps. */
- for (i = 0; i < TOTAL_RX_BD; i++) {
+ for (i = 0; i < MAX_RX_BD_AVAIL; i++) {
if (sc->rx_mbuf_map[i] != NULL) {
bus_dmamap_unload(sc->rx_mbuf_tag,
sc->rx_mbuf_map[i]);
@@ -3048,24 +3380,24 @@ bce_dma_free(struct bce_softc *sc)
sc->rx_mbuf_tag = NULL;
}
-#ifdef BCE_JUMBO_HDRSPLIT
/* Unload and destroy the page mbuf maps. */
- for (i = 0; i < TOTAL_PG_BD; i++) {
- if (sc->pg_mbuf_map[i] != NULL) {
- bus_dmamap_unload(sc->pg_mbuf_tag,
- sc->pg_mbuf_map[i]);
- bus_dmamap_destroy(sc->pg_mbuf_tag,
- sc->pg_mbuf_map[i]);
- sc->pg_mbuf_map[i] = NULL;
+ if (bce_hdr_split == TRUE) {
+ for (i = 0; i < MAX_PG_BD_AVAIL; i++) {
+ if (sc->pg_mbuf_map[i] != NULL) {
+ bus_dmamap_unload(sc->pg_mbuf_tag,
+ sc->pg_mbuf_map[i]);
+ bus_dmamap_destroy(sc->pg_mbuf_tag,
+ sc->pg_mbuf_map[i]);
+ sc->pg_mbuf_map[i] = NULL;
+ }
}
- }
- /* Destroy the page mbuf tag. */
- if (sc->pg_mbuf_tag != NULL) {
- bus_dma_tag_destroy(sc->pg_mbuf_tag);
- sc->pg_mbuf_tag = NULL;
+ /* Destroy the page mbuf tag. */
+ if (sc->pg_mbuf_tag != NULL) {
+ bus_dma_tag_destroy(sc->pg_mbuf_tag);
+ sc->pg_mbuf_tag = NULL;
+ }
}
-#endif
/* Destroy the parent tag */
if (sc->parent_tag != NULL) {
@@ -3308,7 +3640,7 @@ bce_dma_alloc(device_t dev)
goto bce_dma_alloc_exit;
}
- for (i = 0; i < TX_PAGES; i++) {
+ for (i = 0; i < sc->tx_pages; i++) {
if(bus_dmamem_alloc(sc->tx_bd_chain_tag,
(void **)&sc->tx_bd_chain[i],
@@ -3359,7 +3691,7 @@ bce_dma_alloc(device_t dev)
}
/* Create DMA maps for the TX mbufs clusters. */
- for (i = 0; i < TOTAL_TX_BD; i++) {
+ for (i = 0; i < TOTAL_TX_BD_ALLOC; i++) {
if (bus_dmamap_create(sc->tx_mbuf_tag, BUS_DMA_NOWAIT,
&sc->tx_mbuf_map[i])) {
BCE_PRINTF("%s(%d): Unable to create TX mbuf DMA "
@@ -3385,7 +3717,7 @@ bce_dma_alloc(device_t dev)
goto bce_dma_alloc_exit;
}
- for (i = 0; i < RX_PAGES; i++) {
+ for (i = 0; i < sc->rx_pages; i++) {
if (bus_dmamem_alloc(sc->rx_bd_chain_tag,
(void **)&sc->rx_bd_chain[i],
@@ -3417,12 +3749,11 @@ bce_dma_alloc(device_t dev)
/*
* Create a DMA tag for RX mbufs.
*/
-#ifdef BCE_JUMBO_HDRSPLIT
- max_size = max_seg_size = ((sc->rx_bd_mbuf_alloc_size < MCLBYTES) ?
- MCLBYTES : sc->rx_bd_mbuf_alloc_size);
-#else
- max_size = max_seg_size = MJUM9BYTES;
-#endif
+ if (bce_hdr_split == TRUE)
+ max_size = max_seg_size = ((sc->rx_bd_mbuf_alloc_size < MCLBYTES) ?
+ MCLBYTES : sc->rx_bd_mbuf_alloc_size);
+ else
+ max_size = max_seg_size = MJUM9BYTES;
max_segments = 1;
DBPRINT(sc, BCE_INFO_LOAD, "%s(): Creating rx_mbuf_tag "
@@ -3441,7 +3772,7 @@ bce_dma_alloc(device_t dev)
}
/* Create DMA maps for the RX mbuf clusters. */
- for (i = 0; i < TOTAL_RX_BD; i++) {
+ for (i = 0; i < TOTAL_RX_BD_ALLOC; i++) {
if (bus_dmamap_create(sc->rx_mbuf_tag, BUS_DMA_NOWAIT,
&sc->rx_mbuf_map[i])) {
BCE_PRINTF("%s(%d): Unable to create RX mbuf "
@@ -3451,78 +3782,77 @@ bce_dma_alloc(device_t dev)
}
}
-#ifdef BCE_JUMBO_HDRSPLIT
- /*
- * Create a DMA tag for the page buffer descriptor chain,
- * allocate and clear the memory, and fetch the physical
- * address of the blocks.
- */
- if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
- BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR, sc->max_bus_addr,
- NULL, NULL, BCE_PG_CHAIN_PAGE_SZ, 1, BCE_PG_CHAIN_PAGE_SZ,
- 0, NULL, NULL, &sc->pg_bd_chain_tag)) {
- BCE_PRINTF("%s(%d): Could not allocate page descriptor "
- "chain DMA tag!\n", __FILE__, __LINE__);
- rc = ENOMEM;
- goto bce_dma_alloc_exit;
- }
-
- for (i = 0; i < PG_PAGES; i++) {
-
- if (bus_dmamem_alloc(sc->pg_bd_chain_tag,
- (void **)&sc->pg_bd_chain[i],
- BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
- &sc->pg_bd_chain_map[i])) {
- BCE_PRINTF("%s(%d): Could not allocate page "
- "descriptor chain DMA memory!\n",
- __FILE__, __LINE__);
+ if (bce_hdr_split == TRUE) {
+ /*
+ * Create a DMA tag for the page buffer descriptor chain,
+ * allocate and clear the memory, and fetch the physical
+ * address of the blocks.
+ */
+ if (bus_dma_tag_create(sc->parent_tag, BCM_PAGE_SIZE,
+ BCE_DMA_BOUNDARY, BUS_SPACE_MAXADDR, sc->max_bus_addr,
+ NULL, NULL, BCE_PG_CHAIN_PAGE_SZ, 1, BCE_PG_CHAIN_PAGE_SZ,
+ 0, NULL, NULL, &sc->pg_bd_chain_tag)) {
+ BCE_PRINTF("%s(%d): Could not allocate page descriptor "
+ "chain DMA tag!\n", __FILE__, __LINE__);
rc = ENOMEM;
goto bce_dma_alloc_exit;
}
- error = bus_dmamap_load(sc->pg_bd_chain_tag,
- sc->pg_bd_chain_map[i], sc->pg_bd_chain[i],
- BCE_PG_CHAIN_PAGE_SZ, bce_dma_map_addr,
- &sc->pg_bd_chain_paddr[i], BUS_DMA_NOWAIT);
+ for (i = 0; i < sc->pg_pages; i++) {
+ if (bus_dmamem_alloc(sc->pg_bd_chain_tag,
+ (void **)&sc->pg_bd_chain[i],
+ BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
+ &sc->pg_bd_chain_map[i])) {
+ BCE_PRINTF("%s(%d): Could not allocate page "
+ "descriptor chain DMA memory!\n",
+ __FILE__, __LINE__);
+ rc = ENOMEM;
+ goto bce_dma_alloc_exit;
+ }
- if (error) {
- BCE_PRINTF("%s(%d): Could not map page descriptor "
- "chain DMA memory!\n", __FILE__, __LINE__);
- rc = ENOMEM;
- goto bce_dma_alloc_exit;
- }
+ error = bus_dmamap_load(sc->pg_bd_chain_tag,
+ sc->pg_bd_chain_map[i], sc->pg_bd_chain[i],
+ BCE_PG_CHAIN_PAGE_SZ, bce_dma_map_addr,
+ &sc->pg_bd_chain_paddr[i], BUS_DMA_NOWAIT);
- DBPRINT(sc, BCE_INFO_LOAD, "%s(): pg_bd_chain_paddr[%d] = "
- "0x%jX\n", __FUNCTION__, i,
- (uintmax_t) sc->pg_bd_chain_paddr[i]);
- }
+ if (error) {
+ BCE_PRINTF("%s(%d): Could not map page descriptor "
+ "chain DMA memory!\n", __FILE__, __LINE__);
+ rc = ENOMEM;
+ goto bce_dma_alloc_exit;
+ }
- /*
- * Create a DMA tag for page mbufs.
- */
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list