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 ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to