From owner-svn-src-all@FreeBSD.ORG Mon Feb 7 23:00:24 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A38B21065672; Mon, 7 Feb 2011 23:00:24 +0000 (UTC) (envelope-from davidch@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 9007F8FC13; Mon, 7 Feb 2011 23:00:24 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p17N0OOL025543; Mon, 7 Feb 2011 23:00:24 GMT (envelope-from davidch@svn.freebsd.org) Received: (from davidch@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p17N0OUh025540; Mon, 7 Feb 2011 23:00:24 GMT (envelope-from davidch@svn.freebsd.org) Message-Id: <201102072300.p17N0OUh025540@svn.freebsd.org> From: David Christensen Date: Mon, 7 Feb 2011 23:00:24 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r218423 - head/sys/dev/bce X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 Feb 2011 23:00:24 -0000 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 ***