From 996cd16e296fb4e793c681b1c5eb54b365a0d398 Mon Sep 17 00:00:00 2001 From: yongari Date: Mon, 9 Jan 2012 18:32:45 +0000 Subject: [PATCH] MFC r210522,213489,218423,218527: r210522: Fix an apparent typo. r213489: Add the capability to read the complete contents of the NVRAM via sysctl dev.bce..nvram_dump Add the capability to write the complete contents of the NVRAM via sysctl dev.bce..nvram_write These are only available if the kernel option BCE_DEBUG is enabled. The nvram_write sysctl also requires the kernel option BCE_NVRAM_WRITE_SUPPORT to be enabled. These are to be used at your own caution. Since the MAC addresses are stored in the NVRAM, if you dump one NIC and restore it on another NIC the destination NIC's MAC addresses will not be preserved. A tool can be made using these sysctl's to manage the on-chip firmware. r218423: - 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. r218527: - Added error checking to nvram read functions. - Minor style updates. git-svn-id: svn://svn.freebsd.org/base/stable/8@229859 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/conf/options | 1 + sys/dev/bce/if_bce.c | 1594 +++++++++++++++++++++++++-------------- sys/dev/bce/if_bcereg.h | 323 ++++---- 3 files changed, 1201 insertions(+), 717 deletions(-) diff --git a/sys/conf/options b/sys/conf/options index cf10890be..cda82decd 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -695,6 +695,7 @@ ED_SIC opt_ed.h # bce driver BCE_DEBUG opt_bce.h +BCE_NVRAM_WRITE_SUPPORT opt_bce.h SOCKBUF_DEBUG opt_global.h diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c index f3b80c280..a215f071f 100644 --- a/sys/dev/bce/if_bce.c +++ b/sys/dev/bce/if_bce.c @@ -88,12 +88,6 @@ __FBSDID("$FreeBSD$"); int bootcode_running_failure_sim_control = 0; #endif -/****************************************************************************/ -/* BCE Build Time Options */ -/****************************************************************************/ -/* #define BCE_NVRAM_WRITE_SUPPORT 1 */ - - /****************************************************************************/ /* PCI Device ID Table */ /* */ @@ -287,48 +281,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 */ /****************************************************************************/ @@ -343,21 +332,27 @@ static int bce_miibus_read_reg (device_t, int, int); static int bce_miibus_write_reg (device_t, int, int, int); static void bce_miibus_statchg (device_t); +#ifdef BCE_DEBUG +static int bce_sysctl_nvram_dump(SYSCTL_HANDLER_ARGS); +#ifdef BCE_NVRAM_WRITE_SUPPORT +static int bce_sysctl_nvram_write(SYSCTL_HANDLER_ARGS); +#endif +#endif /****************************************************************************/ /* BCE NVRAM Access Routines */ /****************************************************************************/ 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); @@ -366,12 +361,12 @@ static int bce_nvram_write (struct bce_softc *, u32, u8 *, 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_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 *); /****************************************************************************/ @@ -381,69 +376,67 @@ static int bce_fw_sync (struct bce_softc *, u32); 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 *); @@ -498,24 +491,149 @@ DRIVER_MODULE(miibus, bce, miibus_driver, miibus_devclass, 0, 0); /****************************************************************************/ 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_UINT(_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_UINT(_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"); -/* 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 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"); + +/* 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"); /****************************************************************************/ @@ -597,7 +715,7 @@ bce_print_adapter_info(struct bce_softc *sc) 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)); @@ -619,12 +737,14 @@ bce_print_adapter_info(struct bce_softc *sc) } /* 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("|"); @@ -647,6 +767,17 @@ bce_print_adapter_info(struct bce_softc *sc) } 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); @@ -704,6 +835,189 @@ bce_probe_pci_caps(device_t dev, struct bce_softc *sc) } +/****************************************************************************/ +/* 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. */ /* */ @@ -733,6 +1047,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. */ @@ -1021,37 +1337,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; @@ -1105,23 +1397,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); @@ -2594,9 +2874,9 @@ bce_nvram_write(struct bce_softc *sc, u32 offset, u8 *data_buf, goto bce_nvram_write_exit; bce_nvram_write_locked_exit: - bce_disable_nvram_write(sc); - bce_disable_nvram_access(sc); - bce_release_nvram_lock(sc); + bce_disable_nvram_write(sc); + bce_disable_nvram_access(sc); + bce_release_nvram_lock(sc); bce_nvram_write_exit: if (align_start || align_end) @@ -2641,7 +2921,7 @@ bce_nvram_test(struct bce_softc *sc) * Verify that offset 0 of the NVRAM contains * a valid magic number. */ - magic = bce_be32toh(buf[0]); + magic = bce_be32toh(buf[0]); if (magic != BCE_NVRAM_MAGIC) { rc = ENODEV; BCE_PRINTF("%s(%d): Invalid NVRAM magic value! " @@ -2684,6 +2964,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. */ @@ -2918,7 +3250,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, @@ -2946,7 +3278,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, @@ -2973,38 +3305,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]); @@ -3021,7 +3353,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]); @@ -3037,24 +3369,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) { @@ -3296,7 +3628,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], @@ -3347,7 +3679,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 " @@ -3373,7 +3705,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], @@ -3405,12 +3737,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 " @@ -3429,7 +3760,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 " @@ -3439,78 +3770,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); - - if (error) { - BCE_PRINTF("%s(%d): Could not map page descriptor " - "chain DMA memory!\n", __FILE__, __LINE__); - rc = ENOMEM; - goto bce_dma_alloc_exit; - } + 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; + } - DBPRINT(sc, BCE_INFO_LOAD, "%s(): pg_bd_chain_paddr[%d] = " - "0x%jX\n", __FUNCTION__, i, - (uintmax_t) sc->pg_bd_chain_paddr[i]); - } + 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); - /* - * Create a DMA tag for page mbufs. - */ - max_size = max_seg_size = ((sc->pg_bd_mbuf_alloc_size < MCLBYTES) ? - MCLBYTES : sc->pg_bd_mbuf_alloc_size); + if (error) { + BCE_PRINTF("%s(%d): Could not map page descriptor " + "chain DMA memory!\n", __FILE__, __LINE__); + rc = ENOMEM; + goto bce_dma_alloc_exit; + } - if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY, - sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, - max_size, 1, max_seg_size, 0, NULL, NULL, &sc->pg_mbuf_tag)) { - BCE_PRINTF("%s(%d): Could not allocate page mbuf " - "DMA tag!\n", __FILE__, __LINE__); - rc = ENOMEM; - goto bce_dma_alloc_exit; - } + DBPRINT(sc, BCE_INFO_LOAD, "%s(): pg_bd_chain_paddr[%d] = " + "0x%jX\n", __FUNCTION__, i, + (uintmax_t) sc->pg_bd_chain_paddr[i]); + } - /* Create DMA maps for the page mbuf clusters. */ - for (i = 0; i < TOTAL_PG_BD; i++) { - if (bus_dmamap_create(sc->pg_mbuf_tag, BUS_DMA_NOWAIT, - &sc->pg_mbuf_map[i])) { - BCE_PRINTF("%s(%d): Unable to create page mbuf " - "DMA map!\n", __FILE__, __LINE__); + /* + * Create a DMA tag for page mbufs. + */ + max_size = max_seg_size = ((sc->pg_bd_mbuf_alloc_size < MCLBYTES) ? + MCLBYTES : sc->pg_bd_mbuf_alloc_size); + + if (bus_dma_tag_create(sc->parent_tag, 1, BCE_DMA_BOUNDARY, + sc->max_bus_addr, BUS_SPACE_MAXADDR, NULL, NULL, + max_size, 1, max_seg_size, 0, NULL, NULL, &sc->pg_mbuf_tag)) { + BCE_PRINTF("%s(%d): Could not allocate page mbuf " + "DMA tag!\n", __FILE__, __LINE__); rc = ENOMEM; goto bce_dma_alloc_exit; } + + /* Create DMA maps for the page mbuf clusters. */ + for (i = 0; i < TOTAL_PG_BD_ALLOC; i++) { + if (bus_dmamap_create(sc->pg_mbuf_tag, BUS_DMA_NOWAIT, + &sc->pg_mbuf_map[i])) { + BCE_PRINTF("%s(%d): Unable to create page mbuf " + "DMA map!\n", __FILE__, __LINE__); + rc = ENOMEM; + goto bce_dma_alloc_exit; + } + } } -#endif bce_dma_alloc_exit: DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_CTX); @@ -4578,9 +4908,9 @@ bce_stop(struct bce_softc *sc) bce_disable_intr(sc); /* Free RX buffers. */ -#ifdef BCE_JUMBO_HDRSPLIT - bce_free_pg_chain(sc); -#endif + if (bce_hdr_split == TRUE) { + bce_free_pg_chain(sc); + } bce_free_rx_chain(sc); /* Free TX buffers. */ @@ -4988,10 +5318,10 @@ bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod, DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD); /* Make sure the inputs are valid. */ - DBRUNIF((*chain_prod > MAX_RX_BD), + DBRUNIF((*chain_prod > MAX_RX_BD_ALLOC), BCE_PRINTF("%s(%d): RX producer out of range: " "0x%04X > 0x%04X\n", __FILE__, __LINE__, - *chain_prod, (u16) MAX_RX_BD)); + *chain_prod, (u16) MAX_RX_BD_ALLOC)); DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, " "chain_prod = 0x%04X, prod_bseq = 0x%08X\n", __FUNCTION__, @@ -5014,12 +5344,11 @@ bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod, goto bce_get_rx_buf_exit); /* This is a new mbuf allocation. */ -#ifdef BCE_JUMBO_HDRSPLIT - MGETHDR(m_new, M_DONTWAIT, MT_DATA); -#else - m_new = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, - sc->rx_bd_mbuf_alloc_size); -#endif + if (bce_hdr_split == TRUE) + MGETHDR(m_new, M_DONTWAIT, MT_DATA); + else + m_new = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, + sc->rx_bd_mbuf_alloc_size); if (m_new == NULL) { sc->mbuf_alloc_failed_count++; @@ -5092,7 +5421,6 @@ bce_get_rx_buf_exit: } -#ifdef BCE_JUMBO_HDRSPLIT /****************************************************************************/ /* Encapsulate an mbuf cluster into the page chain. */ /* */ @@ -5115,10 +5443,10 @@ bce_get_pg_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod, DBENTER(BCE_EXTREME_RESET | BCE_EXTREME_RECV | BCE_EXTREME_LOAD); /* Make sure the inputs are valid. */ - DBRUNIF((*prod_idx > MAX_PG_BD), + DBRUNIF((*prod_idx > MAX_PG_BD_ALLOC), BCE_PRINTF("%s(%d): page producer out of range: " "0x%04X > 0x%04X\n", __FILE__, __LINE__, - *prod_idx, (u16) MAX_PG_BD)); + *prod_idx, (u16) MAX_PG_BD_ALLOC)); DBPRINT(sc, BCE_EXTREME_RECV, "%s(enter): prod = 0x%04X, " "chain_prod = 0x%04X\n", __FUNCTION__, *prod, *prod_idx); @@ -5203,7 +5531,6 @@ bce_get_pg_buf_exit: return(rc); } -#endif /* BCE_JUMBO_HDRSPLIT */ /****************************************************************************/ @@ -5275,7 +5602,7 @@ bce_init_tx_chain(struct bce_softc *sc) sc->tx_cons = 0; sc->tx_prod_bseq = 0; sc->used_tx_bd = 0; - sc->max_tx_bd = USABLE_TX_BD; + sc->max_tx_bd = USABLE_TX_BD_ALLOC; DBRUN(sc->tx_hi_watermark = 0); DBRUN(sc->tx_full_count = 0); @@ -5290,24 +5617,26 @@ bce_init_tx_chain(struct bce_softc *sc) */ /* Set the TX next pointer chain entries. */ - for (i = 0; i < TX_PAGES; i++) { + for (i = 0; i < sc->tx_pages; i++) { int j; txbd = &sc->tx_bd_chain[i][USABLE_TX_BD_PER_PAGE]; /* Check if we've reached the last page. */ - if (i == (TX_PAGES - 1)) + if (i == (sc->tx_pages - 1)) j = 0; else j = i + 1; - txbd->tx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->tx_bd_chain_paddr[j])); - txbd->tx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->tx_bd_chain_paddr[j])); + txbd->tx_bd_haddr_hi = + htole32(BCE_ADDR_HI(sc->tx_bd_chain_paddr[j])); + txbd->tx_bd_haddr_lo = + htole32(BCE_ADDR_LO(sc->tx_bd_chain_paddr[j])); } bce_init_tx_context(sc); - DBRUNMSG(BCE_INSANE_SEND, bce_dump_tx_chain(sc, 0, TOTAL_TX_BD)); + DBRUNMSG(BCE_INSANE_SEND, bce_dump_tx_chain(sc, 0, TOTAL_TX_BD_ALLOC)); DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_LOAD); return(rc); @@ -5328,7 +5657,7 @@ bce_free_tx_chain(struct bce_softc *sc) DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_SEND | BCE_VERBOSE_UNLOAD); /* Unmap, unload, and free any mbufs still in the TX mbuf chain. */ - for (i = 0; i < TOTAL_TX_BD; i++) { + for (i = 0; i < MAX_TX_BD_AVAIL; i++) { if (sc->tx_mbuf_ptr[i] != NULL) { if (sc->tx_mbuf_map[i] != NULL) bus_dmamap_sync(sc->tx_mbuf_tag, @@ -5341,7 +5670,7 @@ bce_free_tx_chain(struct bce_softc *sc) } /* Clear each TX chain page. */ - for (i = 0; i < TX_PAGES; i++) + for (i = 0; i < sc->tx_pages; i++) bzero((char *)sc->tx_bd_chain[i], BCE_TX_CHAIN_PAGE_SZ); sc->used_tx_bd = 0; @@ -5384,17 +5713,17 @@ bce_init_rx_context(struct bce_softc *sc) if (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) { u32 lo_water, hi_water; - if (sc->bce_flags && BCE_USING_TX_FLOW_CONTROL) { + if (sc->bce_flags & BCE_USING_TX_FLOW_CONTROL) { lo_water = BCE_L2CTX_RX_LO_WATER_MARK_DEFAULT; } else { lo_water = 0; } - if (lo_water >= USABLE_RX_BD) { + if (lo_water >= USABLE_RX_BD_ALLOC) { lo_water = 0; } - hi_water = USABLE_RX_BD / 4; + hi_water = USABLE_RX_BD_ALLOC / 4; if (hi_water <= lo_water) { lo_water = 0; @@ -5449,17 +5778,17 @@ bce_init_rx_chain(struct bce_softc *sc) sc->rx_prod = 0; sc->rx_cons = 0; sc->rx_prod_bseq = 0; - sc->free_rx_bd = USABLE_RX_BD; - sc->max_rx_bd = USABLE_RX_BD; + sc->free_rx_bd = USABLE_RX_BD_ALLOC; + sc->max_rx_bd = USABLE_RX_BD_ALLOC; /* Initialize the RX next pointer chain entries. */ - for (i = 0; i < RX_PAGES; i++) { + for (i = 0; i < sc->rx_pages; i++) { int j; rxbd = &sc->rx_bd_chain[i][USABLE_RX_BD_PER_PAGE]; /* Check if we've reached the last page. */ - if (i == (RX_PAGES - 1)) + if (i == (sc->rx_pages - 1)) j = 0; else j = i + 1; @@ -5474,16 +5803,17 @@ bce_init_rx_chain(struct bce_softc *sc) /* Fill up the RX chain. */ bce_fill_rx_chain(sc); - DBRUN(sc->rx_low_watermark = USABLE_RX_BD); + DBRUN(sc->rx_low_watermark = USABLE_RX_BD_ALLOC); DBRUN(sc->rx_empty_count = 0); - for (i = 0; i < RX_PAGES; i++) { + for (i = 0; i < sc->rx_pages; i++) { bus_dmamap_sync(sc->rx_bd_chain_tag, sc->rx_bd_chain_map[i], BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); } bce_init_rx_context(sc); - DBRUNMSG(BCE_EXTREME_RECV, bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD)); + DBRUNMSG(BCE_EXTREME_RECV, + bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD_ALLOC)); DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD | BCE_VERBOSE_CTX); @@ -5557,7 +5887,7 @@ bce_free_rx_chain(struct bce_softc *sc) DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD); /* Free any mbufs still in the RX mbuf chain. */ - for (i = 0; i < TOTAL_RX_BD; i++) { + for (i = 0; i < MAX_RX_BD_AVAIL; i++) { if (sc->rx_mbuf_ptr[i] != NULL) { if (sc->rx_mbuf_map[i] != NULL) bus_dmamap_sync(sc->rx_mbuf_tag, @@ -5570,7 +5900,7 @@ bce_free_rx_chain(struct bce_softc *sc) } /* Clear each RX chain page. */ - for (i = 0; i < RX_PAGES; i++) + for (i = 0; i < sc->rx_pages; i++) if (sc->rx_bd_chain[i] != NULL) { bzero((char *)sc->rx_bd_chain[i], BCE_RX_CHAIN_PAGE_SZ); @@ -5587,7 +5917,6 @@ bce_free_rx_chain(struct bce_softc *sc) } -#ifdef BCE_JUMBO_HDRSPLIT /****************************************************************************/ /* Allocate memory and initialize the page data structures. */ /* Assumes that bce_init_rx_chain() has not already been called. */ @@ -5608,26 +5937,28 @@ bce_init_pg_chain(struct bce_softc *sc) /* Initialize the page producer and consumer indices. */ sc->pg_prod = 0; sc->pg_cons = 0; - sc->free_pg_bd = USABLE_PG_BD; - sc->max_pg_bd = USABLE_PG_BD; + sc->free_pg_bd = USABLE_PG_BD_ALLOC; + sc->max_pg_bd = USABLE_PG_BD_ALLOC; DBRUN(sc->pg_low_watermark = sc->max_pg_bd); DBRUN(sc->pg_empty_count = 0); /* Initialize the page next pointer chain entries. */ - for (i = 0; i < PG_PAGES; i++) { + for (i = 0; i < sc->pg_pages; i++) { int j; pgbd = &sc->pg_bd_chain[i][USABLE_PG_BD_PER_PAGE]; /* Check if we've reached the last page. */ - if (i == (PG_PAGES - 1)) + if (i == (sc->pg_pages - 1)) j = 0; else j = i + 1; /* Setup the chain page pointers. */ - pgbd->rx_bd_haddr_hi = htole32(BCE_ADDR_HI(sc->pg_bd_chain_paddr[j])); - pgbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->pg_bd_chain_paddr[j])); + pgbd->rx_bd_haddr_hi = + htole32(BCE_ADDR_HI(sc->pg_bd_chain_paddr[j])); + pgbd->rx_bd_haddr_lo = + htole32(BCE_ADDR_LO(sc->pg_bd_chain_paddr[j])); } /* Setup the MQ BIN mapping for host_pg_bidx. */ @@ -5653,12 +5984,13 @@ bce_init_pg_chain(struct bce_softc *sc) /* Fill up the page chain. */ bce_fill_pg_chain(sc); - for (i = 0; i < PG_PAGES; i++) { + for (i = 0; i < sc->pg_pages; i++) { bus_dmamap_sync(sc->pg_bd_chain_tag, sc->pg_bd_chain_map[i], BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); } - DBRUNMSG(BCE_EXTREME_RECV, bce_dump_pg_chain(sc, 0, TOTAL_PG_BD)); + DBRUNMSG(BCE_EXTREME_RECV, + bce_dump_pg_chain(sc, 0, TOTAL_PG_BD_ALLOC)); DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_LOAD | BCE_VERBOSE_CTX); return(rc); @@ -5726,7 +6058,7 @@ bce_free_pg_chain(struct bce_softc *sc) DBENTER(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD); /* Free any mbufs still in the mbuf page chain. */ - for (i = 0; i < TOTAL_PG_BD; i++) { + for (i = 0; i < MAX_PG_BD_AVAIL; i++) { if (sc->pg_mbuf_ptr[i] != NULL) { if (sc->pg_mbuf_map[i] != NULL) bus_dmamap_sync(sc->pg_mbuf_tag, @@ -5739,7 +6071,7 @@ bce_free_pg_chain(struct bce_softc *sc) } /* Clear each page chain pages. */ - for (i = 0; i < PG_PAGES; i++) + for (i = 0; i < sc->pg_pages; i++) bzero((char *)sc->pg_bd_chain[i], BCE_PG_CHAIN_PAGE_SZ); sc->free_pg_bd = sc->max_pg_bd; @@ -5751,7 +6083,6 @@ bce_free_pg_chain(struct bce_softc *sc) DBEXIT(BCE_VERBOSE_RESET | BCE_VERBOSE_RECV | BCE_VERBOSE_UNLOAD); } -#endif /* BCE_JUMBO_HDRSPLIT */ /****************************************************************************/ @@ -5932,10 +6263,8 @@ bce_rx_intr(struct bce_softc *sc) unsigned int pkt_len; u16 sw_rx_cons, sw_rx_cons_idx, hw_rx_cons; u32 status; -#ifdef BCE_JUMBO_HDRSPLIT unsigned int rem_len; u16 sw_pg_cons, sw_pg_cons_idx; -#endif DBENTER(BCE_VERBOSE_RECV | BCE_VERBOSE_INTR); DBRUN(sc->interrupts_rx++); @@ -5944,26 +6273,23 @@ bce_rx_intr(struct bce_softc *sc) __FUNCTION__, sc->rx_prod, sc->rx_cons, sc->rx_prod_bseq); /* Prepare the RX chain pages to be accessed by the host CPU. */ - for (int i = 0; i < RX_PAGES; i++) + for (int i = 0; i < sc->rx_pages; i++) bus_dmamap_sync(sc->rx_bd_chain_tag, sc->rx_bd_chain_map[i], BUS_DMASYNC_POSTREAD); -#ifdef BCE_JUMBO_HDRSPLIT /* Prepare the page chain pages to be accessed by the host CPU. */ - for (int i = 0; i < PG_PAGES; i++) - bus_dmamap_sync(sc->pg_bd_chain_tag, - sc->pg_bd_chain_map[i], BUS_DMASYNC_POSTREAD); -#endif + if (bce_hdr_split == TRUE) { + for (int i = 0; i < sc->pg_pages; i++) + bus_dmamap_sync(sc->pg_bd_chain_tag, + sc->pg_bd_chain_map[i], BUS_DMASYNC_POSTREAD); + } /* Get the hardware's view of the RX consumer index. */ hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc); /* Get working copies of the driver's view of the consumer indices. */ sw_rx_cons = sc->rx_cons; - -#ifdef BCE_JUMBO_HDRSPLIT sw_pg_cons = sc->pg_cons; -#endif /* Update some debug statistics counters */ DBRUNIF((sc->free_rx_bd < sc->rx_low_watermark), @@ -6006,7 +6332,7 @@ bce_rx_intr(struct bce_softc *sc) * with an l2_fhdr structure which provides status * information about the received frame (including * VLAN tags and checksum info). The frames are - * also automatically adjusted to align the IP + * also automatically adjusted to word align the IP * header (i.e. two null bytes are inserted before * the Ethernet header). As a result the data * DMA'd by the controller into the mbuf looks @@ -6035,96 +6361,104 @@ bce_rx_intr(struct bce_softc *sc) */ m_adj(m0, sizeof(struct l2_fhdr) + ETHER_ALIGN); -#ifdef BCE_JUMBO_HDRSPLIT /* - * Check whether the received frame fits in a single - * mbuf or not (i.e. packet data + FCS <= - * sc->rx_bd_mbuf_data_len bytes). + * When split header mode is used, an ethernet frame + * may be split across the receive chain and the + * page chain. If that occurs an mbuf cluster must be + * reassembled from the individual mbuf pieces. */ - if (pkt_len > m0->m_len) { - /* - * The received frame is larger than a single mbuf. - * If the frame was a TCP frame then only the TCP - * header is placed in the mbuf, the remaining - * payload (including FCS) is placed in the page - * chain, the SPLIT flag is set, and the header - * length is placed in the IP checksum field. - * If the frame is not a TCP frame then the mbuf - * is filled and the remaining bytes are placed - * in the page chain. - */ - - DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a large " - "packet.\n", __FUNCTION__); - + if (bce_hdr_split == TRUE) { /* - * When the page chain is enabled and the TCP - * header has been split from the TCP payload, - * the ip_xsum structure will reflect the length - * of the TCP header, not the IP checksum. Set - * the packet length of the mbuf accordingly. + * Check whether the received frame fits in a single + * mbuf or not (i.e. packet data + FCS <= + * sc->rx_bd_mbuf_data_len bytes). */ - if (status & L2_FHDR_STATUS_SPLIT) - m0->m_len = l2fhdr->l2_fhdr_ip_xsum; - - rem_len = pkt_len - m0->m_len; - - /* Pull mbufs off the page chain for the remaining data. */ - while (rem_len > 0) { - struct mbuf *m_pg; - - sw_pg_cons_idx = PG_CHAIN_IDX(sw_pg_cons); + if (pkt_len > m0->m_len) { + /* + * The received frame is larger than a single mbuf. + * If the frame was a TCP frame then only the TCP + * header is placed in the mbuf, the remaining + * payload (including FCS) is placed in the page + * chain, the SPLIT flag is set, and the header + * length is placed in the IP checksum field. + * If the frame is not a TCP frame then the mbuf + * is filled and the remaining bytes are placed + * in the page chain. + */ - /* Remove the mbuf from the page chain. */ - m_pg = sc->pg_mbuf_ptr[sw_pg_cons_idx]; - sc->pg_mbuf_ptr[sw_pg_cons_idx] = NULL; - DBRUN(sc->debug_pg_mbuf_alloc--); - sc->free_pg_bd++; + DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a large " + "packet.\n", __FUNCTION__); + DBRUN(sc->split_header_frames_rcvd++); - /* Unmap the page chain mbuf from DMA space. */ - bus_dmamap_sync(sc->pg_mbuf_tag, - sc->pg_mbuf_map[sw_pg_cons_idx], - BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->pg_mbuf_tag, - sc->pg_mbuf_map[sw_pg_cons_idx]); - - /* Adjust the mbuf length. */ - if (rem_len < m_pg->m_len) { - /* The mbuf chain is complete. */ - m_pg->m_len = rem_len; - rem_len = 0; - } else { - /* More packet data is waiting. */ - rem_len -= m_pg->m_len; + /* + * When the page chain is enabled and the TCP + * header has been split from the TCP payload, + * the ip_xsum structure will reflect the length + * of the TCP header, not the IP checksum. Set + * the packet length of the mbuf accordingly. + */ + if (status & L2_FHDR_STATUS_SPLIT) { + m0->m_len = l2fhdr->l2_fhdr_ip_xsum; + DBRUN(sc->split_header_tcp_frames_rcvd++); } - /* Concatenate the mbuf cluster to the mbuf. */ - m_cat(m0, m_pg); - - sw_pg_cons = NEXT_PG_BD(sw_pg_cons); - } + rem_len = pkt_len - m0->m_len; + + /* Pull mbufs off the page chain for any remaining data. */ + while (rem_len > 0) { + struct mbuf *m_pg; + + sw_pg_cons_idx = PG_CHAIN_IDX(sw_pg_cons); + + /* Remove the mbuf from the page chain. */ + m_pg = sc->pg_mbuf_ptr[sw_pg_cons_idx]; + sc->pg_mbuf_ptr[sw_pg_cons_idx] = NULL; + DBRUN(sc->debug_pg_mbuf_alloc--); + sc->free_pg_bd++; + + /* Unmap the page chain mbuf from DMA space. */ + bus_dmamap_sync(sc->pg_mbuf_tag, + sc->pg_mbuf_map[sw_pg_cons_idx], + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->pg_mbuf_tag, + sc->pg_mbuf_map[sw_pg_cons_idx]); + + /* Adjust the mbuf length. */ + if (rem_len < m_pg->m_len) { + /* The mbuf chain is complete. */ + m_pg->m_len = rem_len; + rem_len = 0; + } else { + /* More packet data is waiting. */ + rem_len -= m_pg->m_len; + } + + /* Concatenate the mbuf cluster to the mbuf. */ + m_cat(m0, m_pg); + + sw_pg_cons = NEXT_PG_BD(sw_pg_cons); + } - /* Set the total packet length. */ - m0->m_pkthdr.len = pkt_len; + /* Set the total packet length. */ + m0->m_pkthdr.len = pkt_len; - } else { - /* - * The received packet is small and fits in a - * single mbuf (i.e. the l2_fhdr + pad + packet + - * FCS <= MHLEN). In other words, the packet is - * 154 bytes or less in size. - */ + } else { + /* + * The received packet is small and fits in a + * single mbuf (i.e. the l2_fhdr + pad + packet + + * FCS <= MHLEN). In other words, the packet is + * 154 bytes or less in size. + */ - DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a small " - "packet.\n", __FUNCTION__); + DBPRINT(sc, BCE_INFO_RECV, "%s(): Found a small " + "packet.\n", __FUNCTION__); + /* Set the total packet length. */ + m0->m_pkthdr.len = m0->m_len = pkt_len; + } + } else /* Set the total packet length. */ m0->m_pkthdr.len = m0->m_len = pkt_len; - } -#else - /* Set the total packet length. */ - m0->m_pkthdr.len = m0->m_len = pkt_len; -#endif /* Remove the trailing Ethernet FCS. */ m_adj(m0, -ETHER_CRC_LEN); @@ -6133,8 +6467,8 @@ bce_rx_intr(struct bce_softc *sc) DBRUN(m_sanity(m0, FALSE)); DBRUNIF(((m0->m_len < ETHER_HDR_LEN) | (m0->m_pkthdr.len > BCE_MAX_JUMBO_ETHER_MTU_VLAN)), - BCE_PRINTF("Invalid Ethernet frame size!\n"); - m_print(m0, 128)); + BCE_PRINTF("Invalid Ethernet frame size!\n"); + m_print(m0, 128)); DBRUNIF(DB_RANDOMTRUE(l2fhdr_error_sim_control), sc->l2fhdr_error_sim_count++; @@ -6193,7 +6527,9 @@ bce_rx_intr(struct bce_softc *sc) /* Attach the VLAN tag. */ if (status & L2_FHDR_STATUS_L2_VLAN_TAG) { + DBRUN(sc->vlan_tagged_frames_rcvd++); if (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) { + DBRUN(sc->vlan_tagged_frames_stripped++); #if __FreeBSD_version < 700000 VLAN_INPUT_TAG(ifp, m0, l2fhdr->l2_fhdr_vlan_tag, continue); @@ -6236,9 +6572,7 @@ bce_rx_int_next_rx: if (m0) { /* Make sure we don't lose our place when we release the lock. */ sc->rx_cons = sw_rx_cons; -#ifdef BCE_JUMBO_HDRSPLIT sc->pg_cons = sw_pg_cons; -#endif BCE_UNLOCK(sc); (*ifp->if_input)(ifp, m0); @@ -6246,9 +6580,7 @@ bce_rx_int_next_rx: /* Recover our place. */ sw_rx_cons = sc->rx_cons; -#ifdef BCE_JUMBO_HDRSPLIT sw_pg_cons = sc->pg_cons; -#endif } /* Refresh hw_cons to see if there's new work */ @@ -6256,26 +6588,26 @@ bce_rx_int_next_rx: hw_rx_cons = sc->hw_rx_cons = bce_get_hw_rx_cons(sc); } -#ifdef BCE_JUMBO_HDRSPLIT /* No new packets. Refill the page chain. */ - sc->pg_cons = sw_pg_cons; - bce_fill_pg_chain(sc); -#endif + if (bce_hdr_split == TRUE) { + sc->pg_cons = sw_pg_cons; + bce_fill_pg_chain(sc); + } /* No new packets. Refill the RX chain. */ sc->rx_cons = sw_rx_cons; bce_fill_rx_chain(sc); /* Prepare the page chain pages to be accessed by the NIC. */ - for (int i = 0; i < RX_PAGES; i++) + for (int i = 0; i < sc->rx_pages; i++) bus_dmamap_sync(sc->rx_bd_chain_tag, sc->rx_bd_chain_map[i], BUS_DMASYNC_PREWRITE); -#ifdef BCE_JUMBO_HDRSPLIT - for (int i = 0; i < PG_PAGES; i++) - bus_dmamap_sync(sc->pg_bd_chain_tag, - sc->pg_bd_chain_map[i], BUS_DMASYNC_PREWRITE); -#endif + if (bce_hdr_split == TRUE) { + for (int i = 0; i < sc->pg_pages; i++) + bus_dmamap_sync(sc->pg_bd_chain_tag, + sc->pg_bd_chain_map[i], BUS_DMASYNC_PREWRITE); + } DBPRINT(sc, BCE_EXTREME_RECV, "%s(exit): rx_prod = 0x%04X, " "rx_cons = 0x%04X, rx_prod_bseq = 0x%08X\n", @@ -6345,10 +6677,10 @@ bce_tx_intr(struct bce_softc *sc) "sw_tx_chain_cons = 0x%04X\n", __FUNCTION__, hw_tx_cons, sw_tx_cons, sw_tx_chain_cons); - DBRUNIF((sw_tx_chain_cons > MAX_TX_BD), + DBRUNIF((sw_tx_chain_cons > MAX_TX_BD_ALLOC), BCE_PRINTF("%s(%d): TX chain consumer out of range! " " 0x%04X > 0x%04X\n", __FILE__, __LINE__, sw_tx_chain_cons, - (int) MAX_TX_BD); + (int) MAX_TX_BD_ALLOC); bce_breakpoint(sc)); DBRUN(txbd = &sc->tx_bd_chain[TX_PAGE(sw_tx_chain_cons)] @@ -6516,19 +6848,26 @@ bce_init_locked(struct bce_softc *sc) /* * Calculate and program the hardware Ethernet MTU - * size. Be generous on the receive if we have room. + * size. Be generous on the receive if we have room + * and allowed by the user. */ -#ifdef BCE_JUMBO_HDRSPLIT - if (ifp->if_mtu <= (sc->rx_bd_mbuf_data_len + - sc->pg_bd_mbuf_alloc_size)) - ether_mtu = sc->rx_bd_mbuf_data_len + - sc->pg_bd_mbuf_alloc_size; -#else - if (ifp->if_mtu <= sc->rx_bd_mbuf_data_len) - ether_mtu = sc->rx_bd_mbuf_data_len; -#endif - else + if (bce_strict_rx_mtu == TRUE) ether_mtu = ifp->if_mtu; + else { + if (bce_hdr_split == TRUE) { + if (ifp->if_mtu <= (sc->rx_bd_mbuf_data_len + + sc->pg_bd_mbuf_alloc_size)) + ether_mtu = sc->rx_bd_mbuf_data_len + + sc->pg_bd_mbuf_alloc_size; + else + ether_mtu = ifp->if_mtu; + } else { + if (ifp->if_mtu <= sc->rx_bd_mbuf_data_len) + ether_mtu = sc->rx_bd_mbuf_data_len; + else + ether_mtu = ifp->if_mtu; + } + } ether_mtu += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + ETHER_CRC_LEN; @@ -6543,22 +6882,16 @@ bce_init_locked(struct bce_softc *sc) else REG_WR(sc, BCE_EMAC_RX_MTU_SIZE, ether_mtu); - DBPRINT(sc, BCE_INFO_LOAD, - "%s(): rx_bd_mbuf_alloc_size = %d, rx_bce_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); - /* Program appropriate promiscuous/multicast filtering. */ bce_set_rx_mode(sc); -#ifdef BCE_JUMBO_HDRSPLIT - DBPRINT(sc, BCE_INFO_LOAD, "%s(): pg_bd_mbuf_alloc_size = %d\n", - __FUNCTION__, sc->pg_bd_mbuf_alloc_size); + if (bce_hdr_split == TRUE) { + DBPRINT(sc, BCE_INFO_LOAD, "%s(): pg_bd_mbuf_alloc_size = %d\n", + __FUNCTION__, sc->pg_bd_mbuf_alloc_size); - /* Init page buffer descriptor chain. */ - bce_init_pg_chain(sc); -#endif + /* Init page buffer descriptor chain. */ + bce_init_pg_chain(sc); + } /* Init RX buffer descriptor chain. */ bce_init_rx_chain(sc); @@ -6717,7 +7050,7 @@ bce_tso_setup(struct bce_softc *sc, struct mbuf **m_head, u16 *flags) return (NULL); } - /* IP header length and checksum will be calc'd by hardware */ + /* Clear IP header length and checksum, will be calc'd by h/w. */ ip = (struct ip *)(m->m_data + sizeof(struct ether_header)); ip_len = ip->ip_len; ip->ip_len = 0; @@ -7086,7 +7419,7 @@ bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data) struct bce_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; struct mii_data *mii; - int mask, error = 0, reinit; + int mask, error = 0; DBENTER(BCE_VERBOSE_MISC); @@ -7107,40 +7440,22 @@ bce_ioctl(struct ifnet *ifp, u_long command, caddr_t data) BCE_LOCK(sc); ifp->if_mtu = ifr->ifr_mtu; - reinit = 0; - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - /* - * Because allocation size is used in RX - * buffer allocation, stop controller if - * it is already running. - */ - bce_stop(sc); - reinit = 1; - } -#ifdef BCE_JUMBO_HDRSPLIT - /* No buffer allocation size changes are necessary. */ -#else - /* Recalculate our buffer allocation sizes. */ - if ((ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + - ETHER_CRC_LEN) > MCLBYTES) { - 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 { - 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 - if (reinit != 0) + if (bce_hdr_split == FALSE) { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + /* + * Because allocation size is used in RX + * buffer allocation, stop controller if + * it is already running. + */ + bce_stop(sc); + } + + bce_get_rx_buffer_sizes(sc, ifp->if_mtu); + bce_init_locked(sc); + } + BCE_UNLOCK(sc); break; @@ -7817,7 +8132,7 @@ bce_pulse(void *xsc) sc->bc_state = bce_shmem_rd(sc, BCE_BC_STATE_CONDITION); /* Report whether the bootcode still knows the driver is running. */ - if (bootverbose) { + if (bce_verbose || bootverbose) { if (sc->bce_drv_cardiac_arrest == FALSE) { if (!(sc->bc_state & BCE_CONDITION_DRV_PRESENT)) { sc->bce_drv_cardiac_arrest = TRUE; @@ -7875,10 +8190,13 @@ bce_tick(void *xsc) /* Update the statistics from the hardware statistics block. */ bce_stats_update(sc); + /* + * ToDo: This is a safety measure. Need to re-evaluate + * high level processing logic and eliminate this code. + */ /* Top off the receive and page chains. */ -#ifdef BCE_JUMBO_HDRSPLIT - bce_fill_pg_chain(sc); -#endif + if (bce_hdr_split == TRUE) + bce_fill_pg_chain(sc); bce_fill_rx_chain(sc); /* Check that chip hasn't hung. */ @@ -7901,7 +8219,7 @@ bce_tick(void *xsc) if ((IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T || IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX || IFM_SUBTYPE(mii->mii_media_active) == IFM_2500_SX) && - bootverbose) + (bce_verbose || bootverbose)) BCE_PRINTF("Gigabit link up!\n"); /* Now that link is up, handle any outstanding TX traffic. */ @@ -7917,7 +8235,6 @@ bce_tick_exit: return; } - #ifdef BCE_DEBUG /****************************************************************************/ /* Allows the driver state to be dumped through the sysctl interface. */ @@ -8053,6 +8370,10 @@ bce_sysctl_stats_clear(SYSCTL_HANDLER_ARGS) if (result == 1) { sc = (struct bce_softc *)arg1; + struct statistics_block *stats; + + stats = (struct statistics_block *) sc->stats_block; + bzero(stats, sizeof(struct statistics_block)); /* Clear the internal H/W statistics counters. */ REG_WR(sc, BCE_HC_COMMAND, BCE_HC_COMMAND_CLR_STAT_NOW); @@ -8065,7 +8386,7 @@ bce_sysctl_stats_clear(SYSCTL_HANDLER_ARGS) sc->tso_frames_failed = 0; sc->rx_empty_count = sc->tx_full_count = 0; - sc->rx_low_watermark = USABLE_RX_BD; + sc->rx_low_watermark = USABLE_RX_BD_ALLOC; sc->tx_hi_watermark = 0; sc->l2fhdr_error_count = sc->l2fhdr_error_sim_count = 0; @@ -8075,9 +8396,11 @@ bce_sysctl_stats_clear(SYSCTL_HANDLER_ARGS) sc->dma_map_addr_tx_failed_count = 0; sc->mbuf_frag_count = 0; sc->csum_offload_tcp_udp = - sc->csum_offload_ip = 0; + sc->csum_offload_ip = 0; sc->vlan_tagged_frames_rcvd = - sc->vlan_tagged_frames_stripped = 0; + sc->vlan_tagged_frames_stripped = 0; + sc->split_header_frames_rcvd = + sc->split_header_tcp_frames_rcvd = 0; /* Clear firmware maintained statistics. */ REG_WR_IND(sc, 0x120084, 0); @@ -8087,6 +8410,35 @@ bce_sysctl_stats_clear(SYSCTL_HANDLER_ARGS) } +/****************************************************************************/ +/* Allows the shared memory contents to be dumped through the sysctl . */ +/* interface. */ +/* */ +/* Returns: */ +/* 0 for success, positive value for failure. */ +/****************************************************************************/ +static int +bce_sysctl_shmem_state(SYSCTL_HANDLER_ARGS) +{ + int error; + int result; + struct bce_softc *sc; + + result = -1; + error = sysctl_handle_int(oidp, &result, 0, req); + + if (error || !req->newptr) + return (error); + + if (result == 1) { + sc = (struct bce_softc *)arg1; + bce_dump_shmem_state(sc); + } + + return error; +} + + /****************************************************************************/ /* Allows the bootcode state to be dumped through the sysctl interface. */ /* */ @@ -8136,7 +8488,7 @@ bce_sysctl_dump_rx_bd_chain(SYSCTL_HANDLER_ARGS) if (result == 1) { sc = (struct bce_softc *)arg1; - bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD); + bce_dump_rx_bd_chain(sc, 0, TOTAL_RX_BD_ALLOC); } return error; @@ -8164,7 +8516,7 @@ bce_sysctl_dump_rx_mbuf_chain(SYSCTL_HANDLER_ARGS) if (result == 1) { sc = (struct bce_softc *)arg1; - bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD); + bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD_ALLOC); } return error; @@ -8192,14 +8544,13 @@ bce_sysctl_dump_tx_chain(SYSCTL_HANDLER_ARGS) if (result == 1) { sc = (struct bce_softc *)arg1; - bce_dump_tx_chain(sc, 0, TOTAL_TX_BD); + bce_dump_tx_chain(sc, 0, TOTAL_TX_BD_ALLOC); } return error; } -#ifdef BCE_JUMBO_HDRSPLIT /****************************************************************************/ /* Provides a sysctl interface to allow dumping the page chain. */ /* */ @@ -8221,12 +8572,11 @@ bce_sysctl_dump_pg_chain(SYSCTL_HANDLER_ARGS) if (result == 1) { sc = (struct bce_softc *)arg1; - bce_dump_pg_chain(sc, 0, TOTAL_PG_BD); + bce_dump_pg_chain(sc, 0, TOTAL_PG_BD_ALLOC); } return error; } -#endif /****************************************************************************/ /* Provides a sysctl interface to allow reading arbitrary NVRAM offsets in */ @@ -8249,7 +8599,8 @@ bce_sysctl_nvram_read(SYSCTL_HANDLER_ARGS) if (error || (req->newptr == NULL)) return (error); - bce_nvram_read(sc, result, data, 4); + error = bce_nvram_read(sc, result, data, 4); + BCE_PRINTF("offset 0x%08X = 0x%08X\n", result, bce_be32toh(val[0])); return (error); @@ -8319,6 +8670,69 @@ bce_sysctl_phy_read(SYSCTL_HANDLER_ARGS) } +/****************************************************************************/ +/* Provides a sysctl interface for dumping the nvram contents. */ +/* DO NOT ENABLE ON PRODUCTION SYSTEMS! */ +/* */ +/* Returns: */ +/* 0 for success, positive errno for failure. */ +/****************************************************************************/ +static int +bce_sysctl_nvram_dump(SYSCTL_HANDLER_ARGS) +{ + struct bce_softc *sc = (struct bce_softc *)arg1; + int error, i; + + if (sc->nvram_buf == NULL) + sc->nvram_buf = malloc(sc->bce_flash_size, + M_TEMP, M_ZERO | M_WAITOK); + + error = 0; + if (req->oldlen == sc->bce_flash_size) { + for (i = 0; i < sc->bce_flash_size && error == 0; i++) + error = bce_nvram_read(sc, i, &sc->nvram_buf[i], 1); + } + + if (error == 0) + error = SYSCTL_OUT(req, sc->nvram_buf, sc->bce_flash_size); + + return error; +} + +#ifdef BCE_NVRAM_WRITE_SUPPORT +/****************************************************************************/ +/* Provides a sysctl interface for writing to nvram. */ +/* DO NOT ENABLE ON PRODUCTION SYSTEMS! */ +/* */ +/* Returns: */ +/* 0 for success, positive errno for failure. */ +/****************************************************************************/ +static int +bce_sysctl_nvram_write(SYSCTL_HANDLER_ARGS) +{ + struct bce_softc *sc = (struct bce_softc *)arg1; + int error; + + if (sc->nvram_buf == NULL) + sc->nvram_buf = malloc(sc->bce_flash_size, + M_TEMP, M_ZERO | M_WAITOK); + else + bzero(sc->nvram_buf, sc->bce_flash_size); + + error = SYSCTL_IN(req, sc->nvram_buf, sc->bce_flash_size); + if (error == 0) + return (error); + + if (req->newlen == sc->bce_flash_size) + error = bce_nvram_write(sc, 0, sc->nvram_buf, + sc->bce_flash_size); + + + return error; +} +#endif + + /****************************************************************************/ /* Provides a sysctl interface to allow reading a CID. */ /* */ @@ -8346,7 +8760,7 @@ bce_sysctl_dump_ctx(SYSCTL_HANDLER_ARGS) } - /****************************************************************************/ +/****************************************************************************/ /* Provides a sysctl interface to forcing the driver to dump state and */ /* enter the debugger. DO NOT ENABLE ON PRODUCTION SYSTEMS! */ /* */ @@ -8375,7 +8789,6 @@ bce_sysctl_breakpoint(SYSCTL_HANDLER_ARGS) } #endif - /****************************************************************************/ /* Adds any sysctl parameters for tuning or debugging purposes. */ /* */ @@ -8484,113 +8897,137 @@ bce_add_sysctls(struct bce_softc *sc) CTLFLAG_RD, &sc->rx_low_watermark, 0, "Lowest level of free rx_bd's"); - SYSCTL_ADD_INT(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "rx_empty_count", CTLFLAG_RD, &sc->rx_empty_count, - 0, "Number of times the RX chain was empty"); + "Number of times the RX chain was empty"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "tx_hi_watermark", CTLFLAG_RD, &sc->tx_hi_watermark, 0, "Highest level of used tx_bd's"); - SYSCTL_ADD_INT(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "tx_full_count", CTLFLAG_RD, &sc->tx_full_count, - 0, "Number of times the TX chain was full"); + "Number of times the TX chain was full"); - SYSCTL_ADD_INT(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "tso_frames_requested", CTLFLAG_RD, &sc->tso_frames_requested, - 0, "Number of TSO frames requested"); + "Number of TSO frames requested"); - SYSCTL_ADD_INT(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "tso_frames_completed", CTLFLAG_RD, &sc->tso_frames_completed, - 0, "Number of TSO frames completed"); + "Number of TSO frames completed"); - SYSCTL_ADD_INT(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "tso_frames_failed", CTLFLAG_RD, &sc->tso_frames_failed, - 0, "Number of TSO frames failed"); + "Number of TSO frames failed"); - SYSCTL_ADD_INT(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "csum_offload_ip", CTLFLAG_RD, &sc->csum_offload_ip, - 0, "Number of IP checksum offload frames"); + "Number of IP checksum offload frames"); - SYSCTL_ADD_INT(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "csum_offload_tcp_udp", CTLFLAG_RD, &sc->csum_offload_tcp_udp, - 0, "Number of TCP/UDP checksum offload frames"); + "Number of TCP/UDP checksum offload frames"); - SYSCTL_ADD_INT(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "vlan_tagged_frames_rcvd", CTLFLAG_RD, &sc->vlan_tagged_frames_rcvd, - 0, "Number of VLAN tagged frames received"); + "Number of VLAN tagged frames received"); - SYSCTL_ADD_INT(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "vlan_tagged_frames_stripped", CTLFLAG_RD, &sc->vlan_tagged_frames_stripped, - 0, "Number of VLAN tagged frames stripped"); + "Number of VLAN tagged frames stripped"); - SYSCTL_ADD_UINT(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "interrupts_rx", CTLFLAG_RD, &sc->interrupts_rx, - 0, "Number of RX interrupts"); + "Number of RX interrupts"); - SYSCTL_ADD_UINT(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "interrupts_tx", CTLFLAG_RD, &sc->interrupts_tx, - 0, "Number of TX interrupts"); + "Number of TX interrupts"); + + if (bce_hdr_split == TRUE) { + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, + "split_header_frames_rcvd", + CTLFLAG_RD, &sc->split_header_frames_rcvd, + "Number of split header frames received"); + + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, + "split_header_tcp_frames_rcvd", + CTLFLAG_RD, &sc->split_header_tcp_frames_rcvd, + "Number of split header TCP frames received"); + } + + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, + "nvram_dump", CTLTYPE_OPAQUE | CTLFLAG_RD, + (void *)sc, 0, + bce_sysctl_nvram_dump, "S", ""); + +#ifdef BCE_NVRAM_WRITE_SUPPORT + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, + "nvram_write", CTLTYPE_OPAQUE | CTLFLAG_WR, + (void *)sc, 0, + bce_sysctl_nvram_write, "S", ""); #endif +#endif /* BCE_DEBUG */ - SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "stat_IfHcInOctets", CTLFLAG_RD, &sc->stat_IfHCInOctets, "Bytes received"); - SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "stat_IfHCInBadOctets", CTLFLAG_RD, &sc->stat_IfHCInBadOctets, "Bad bytes received"); - SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "stat_IfHCOutOctets", CTLFLAG_RD, &sc->stat_IfHCOutOctets, "Bytes sent"); - SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "stat_IfHCOutBadOctets", CTLFLAG_RD, &sc->stat_IfHCOutBadOctets, "Bad bytes sent"); - SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "stat_IfHCInUcastPkts", CTLFLAG_RD, &sc->stat_IfHCInUcastPkts, "Unicast packets received"); - SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "stat_IfHCInMulticastPkts", CTLFLAG_RD, &sc->stat_IfHCInMulticastPkts, "Multicast packets received"); - SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "stat_IfHCInBroadcastPkts", CTLFLAG_RD, &sc->stat_IfHCInBroadcastPkts, "Broadcast packets received"); - SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "stat_IfHCOutUcastPkts", CTLFLAG_RD, &sc->stat_IfHCOutUcastPkts, "Unicast packets sent"); - SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "stat_IfHCOutMulticastPkts", CTLFLAG_RD, &sc->stat_IfHCOutMulticastPkts, "Multicast packets sent"); - SYSCTL_ADD_ULONG(ctx, children, OID_AUTO, + SYSCTL_ADD_QUAD(ctx, children, OID_AUTO, "stat_IfHCOutBroadcastPkts", CTLFLAG_RD, &sc->stat_IfHCOutBroadcastPkts, "Broadcast packets sent"); @@ -8848,6 +9285,11 @@ bce_add_sysctls(struct bce_softc *sc) (void *)sc, 0, bce_sysctl_stats_clear, "I", "Clear statistics block"); + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, + "shmem_state", CTLTYPE_INT | CTLFLAG_RW, + (void *)sc, 0, + bce_sysctl_shmem_state, "I", "Shared memory state information"); + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "bc_state", CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, @@ -8868,12 +9310,13 @@ bce_add_sysctls(struct bce_softc *sc) (void *)sc, 0, bce_sysctl_dump_tx_chain, "I", "Dump tx_bd chain"); -#ifdef BCE_JUMBO_HDRSPLIT - SYSCTL_ADD_PROC(ctx, children, OID_AUTO, - "dump_pg_chain", CTLTYPE_INT | CTLFLAG_RW, - (void *)sc, 0, - bce_sysctl_dump_pg_chain, "I", "Dump page chain"); -#endif + if (bce_hdr_split == TRUE) { + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, + "dump_pg_chain", CTLTYPE_INT | CTLFLAG_RW, + (void *)sc, 0, + bce_sysctl_dump_pg_chain, "I", "Dump page chain"); + } + SYSCTL_ADD_PROC(ctx, children, OID_AUTO, "dump_ctx", CTLTYPE_INT | CTLFLAG_RW, (void *)sc, 0, @@ -9177,7 +9620,6 @@ bce_dump_rx_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count) } -#ifdef BCE_JUMBO_HDRSPLIT /****************************************************************************/ /* Prints out the mbufs in the mbuf page chain. */ /* */ @@ -9207,7 +9649,6 @@ bce_dump_pg_mbuf_chain(struct bce_softc *sc, u16 chain_prod, int count) "----------------" "----------------------------\n"); } -#endif /****************************************************************************/ @@ -9221,7 +9662,7 @@ bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd) { int i = 0; - if (idx > MAX_TX_BD) + if (idx > MAX_TX_BD_ALLOC) /* Index out of range. */ BCE_PRINTF("tx_bd[0x%04X]: Invalid tx_bd index!\n", idx); else if ((idx & USABLE_TX_BD_PER_PAGE) == USABLE_TX_BD_PER_PAGE) @@ -9334,7 +9775,7 @@ bce_dump_txbd(struct bce_softc *sc, int idx, struct tx_bd *txbd) static __attribute__ ((noinline)) void bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd) { - if (idx > MAX_RX_BD) + if (idx > MAX_RX_BD_ALLOC) /* Index out of range. */ BCE_PRINTF("rx_bd[0x%04X]: Invalid rx_bd index!\n", idx); else if ((idx & USABLE_RX_BD_PER_PAGE) == USABLE_RX_BD_PER_PAGE) @@ -9351,7 +9792,6 @@ bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd) } -#ifdef BCE_JUMBO_HDRSPLIT /****************************************************************************/ /* Prints out a rx_bd structure in the page chain. */ /* */ @@ -9361,7 +9801,7 @@ bce_dump_rxbd(struct bce_softc *sc, int idx, struct rx_bd *rxbd) static __attribute__ ((noinline)) void bce_dump_pgbd(struct bce_softc *sc, int idx, struct rx_bd *pgbd) { - if (idx > MAX_PG_BD) + if (idx > MAX_PG_BD_ALLOC) /* Index out of range. */ BCE_PRINTF("pg_bd[0x%04X]: Invalid pg_bd index!\n", idx); else if ((idx & USABLE_PG_BD_PER_PAGE) == USABLE_PG_BD_PER_PAGE) @@ -9375,7 +9815,6 @@ bce_dump_pgbd(struct bce_softc *sc, int idx, struct rx_bd *pgbd) pgbd->rx_bd_haddr_hi, pgbd->rx_bd_haddr_lo, pgbd->rx_bd_len, pgbd->rx_bd_flags); } -#endif /****************************************************************************/ @@ -9782,10 +10221,10 @@ bce_dump_tx_chain(struct bce_softc *sc, u16 tx_prod, int count) "----------------------------\n"); BCE_PRINTF("page size = 0x%08X, tx chain pages = 0x%08X\n", - (u32) BCM_PAGE_SIZE, (u32) TX_PAGES); + (u32) BCM_PAGE_SIZE, (u32) sc->tx_pages); BCE_PRINTF("tx_bd per page = 0x%08X, usable tx_bd per page = 0x%08X\n", (u32) TOTAL_TX_BD_PER_PAGE, (u32) USABLE_TX_BD_PER_PAGE); - BCE_PRINTF("total tx_bd = 0x%08X\n", (u32) TOTAL_TX_BD); + BCE_PRINTF("total tx_bd = 0x%08X\n", (u32) TOTAL_TX_BD_ALLOC); BCE_PRINTF( "----------------------------" @@ -9824,12 +10263,12 @@ bce_dump_rx_bd_chain(struct bce_softc *sc, u16 rx_prod, int count) "----------------------------\n"); BCE_PRINTF("page size = 0x%08X, rx chain pages = 0x%08X\n", - (u32) BCM_PAGE_SIZE, (u32) RX_PAGES); + (u32) BCM_PAGE_SIZE, (u32) sc->rx_pages); BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n", (u32) TOTAL_RX_BD_PER_PAGE, (u32) USABLE_RX_BD_PER_PAGE); - BCE_PRINTF("total rx_bd = 0x%08X\n", (u32) TOTAL_RX_BD); + BCE_PRINTF("total rx_bd = 0x%08X\n", (u32) TOTAL_RX_BD_ALLOC); BCE_PRINTF( "----------------------------" @@ -9850,7 +10289,6 @@ bce_dump_rx_bd_chain(struct bce_softc *sc, u16 rx_prod, int count) } -#ifdef BCE_JUMBO_HDRSPLIT /****************************************************************************/ /* Prints out the page chain. */ /* */ @@ -9869,13 +10307,12 @@ bce_dump_pg_chain(struct bce_softc *sc, u16 pg_prod, int count) "----------------------------\n"); BCE_PRINTF("page size = 0x%08X, pg chain pages = 0x%08X\n", - (u32) BCM_PAGE_SIZE, (u32) PG_PAGES); + (u32) BCM_PAGE_SIZE, (u32) sc->pg_pages); BCE_PRINTF("rx_bd per page = 0x%08X, usable rx_bd per page = 0x%08X\n", (u32) TOTAL_PG_BD_PER_PAGE, (u32) USABLE_PG_BD_PER_PAGE); - BCE_PRINTF("total rx_bd = 0x%08X, max_pg_bd = 0x%08X\n", - (u32) TOTAL_PG_BD, (u32) MAX_PG_BD); + BCE_PRINTF("total pg_bd = 0x%08X\n", (u32) TOTAL_PG_BD_ALLOC); BCE_PRINTF( "----------------------------" @@ -9894,7 +10331,6 @@ bce_dump_pg_chain(struct bce_softc *sc, u16 pg_prod, int count) "----------------" "----------------------------\n"); } -#endif #define BCE_PRINT_RX_CONS(arg) \ @@ -10101,12 +10537,12 @@ bce_dump_driver_state(struct bce_softc *sc) BCE_PRINTF("0x%08X:%08X - (sc->rx_bd_chain) rx_bd chain " "virtual address\n", val_hi, val_lo); -#ifdef BCE_JUMBO_HDRSPLIT - val_hi = BCE_ADDR_HI(sc->pg_bd_chain); - val_lo = BCE_ADDR_LO(sc->pg_bd_chain); - BCE_PRINTF("0x%08X:%08X - (sc->pg_bd_chain) page chain " - "virtual address\n", val_hi, val_lo); -#endif + if (bce_hdr_split == TRUE) { + val_hi = BCE_ADDR_HI(sc->pg_bd_chain); + val_lo = BCE_ADDR_LO(sc->pg_bd_chain); + BCE_PRINTF("0x%08X:%08X - (sc->pg_bd_chain) page chain " + "virtual address\n", val_hi, val_lo); + } val_hi = BCE_ADDR_HI(sc->tx_mbuf_ptr); val_lo = BCE_ADDR_LO(sc->tx_mbuf_ptr); @@ -10118,24 +10554,28 @@ bce_dump_driver_state(struct bce_softc *sc) BCE_PRINTF("0x%08X:%08X - (sc->rx_mbuf_ptr) rx mbuf chain " "virtual address\n", val_hi, val_lo); -#ifdef BCE_JUMBO_HDRSPLIT - val_hi = BCE_ADDR_HI(sc->pg_mbuf_ptr); - val_lo = BCE_ADDR_LO(sc->pg_mbuf_ptr); - BCE_PRINTF("0x%08X:%08X - (sc->pg_mbuf_ptr) page mbuf chain " - "virtual address\n", val_hi, val_lo); -#endif + if (bce_hdr_split == TRUE) { + val_hi = BCE_ADDR_HI(sc->pg_mbuf_ptr); + val_lo = BCE_ADDR_LO(sc->pg_mbuf_ptr); + BCE_PRINTF("0x%08X:%08X - (sc->pg_mbuf_ptr) page mbuf chain " + "virtual address\n", val_hi, val_lo); + } - BCE_PRINTF(" 0x%08X - (sc->interrupts_generated) " - "h/w intrs\n", sc->interrupts_generated); + BCE_PRINTF(" 0x%016llX - (sc->interrupts_generated) " + "h/w intrs\n", + (long long unsigned int) sc->interrupts_generated); - BCE_PRINTF(" 0x%08X - (sc->interrupts_rx) " - "rx interrupts handled\n", sc->interrupts_rx); + BCE_PRINTF(" 0x%016llX - (sc->interrupts_rx) " + "rx interrupts handled\n", + (long long unsigned int) sc->interrupts_rx); - BCE_PRINTF(" 0x%08X - (sc->interrupts_tx) " - "tx interrupts handled\n", sc->interrupts_tx); + BCE_PRINTF(" 0x%016llX - (sc->interrupts_tx) " + "tx interrupts handled\n", + (long long unsigned int) sc->interrupts_tx); - BCE_PRINTF(" 0x%08X - (sc->phy_interrupts) " - "phy interrupts handled\n", sc->phy_interrupts); + BCE_PRINTF(" 0x%016llX - (sc->phy_interrupts) " + "phy interrupts handled\n", + (long long unsigned int) sc->phy_interrupts); BCE_PRINTF(" 0x%08X - (sc->last_status_idx) " "status block index\n", sc->last_status_idx); @@ -10155,8 +10595,8 @@ bce_dump_driver_state(struct bce_softc *sc) BCE_PRINTF(" 0x%08X - (sc->used_tx_bd) used " "tx_bd's\n", sc->used_tx_bd); - BCE_PRINTF("0x%08X/%08X - (sc->tx_hi_watermark) tx hi " - "watermark\n", sc->tx_hi_watermark, sc->max_tx_bd); + BCE_PRINTF(" 0x%04X/0x%04X - (sc->tx_hi_watermark)/" + "(sc->max_tx_bd)\n", sc->tx_hi_watermark, sc->max_tx_bd); BCE_PRINTF(" 0x%04X(0x%04X) - (sc->rx_prod) rx producer " "index\n", sc->rx_prod, (u16) RX_CHAIN_IDX(sc->rx_prod)); @@ -10167,28 +10607,31 @@ bce_dump_driver_state(struct bce_softc *sc) BCE_PRINTF(" 0x%08X - (sc->rx_prod_bseq) rx producer " "byte seq index\n", sc->rx_prod_bseq); + BCE_PRINTF(" 0x%04X/0x%04X - (sc->rx_low_watermark)/" + "(sc->max_rx_bd)\n", sc->rx_low_watermark, sc->max_rx_bd); + BCE_PRINTF(" 0x%08X - (sc->debug_rx_mbuf_alloc) rx " "mbufs allocated\n", sc->debug_rx_mbuf_alloc); BCE_PRINTF(" 0x%08X - (sc->free_rx_bd) free " "rx_bd's\n", sc->free_rx_bd); -#ifdef BCE_JUMBO_HDRSPLIT - BCE_PRINTF(" 0x%04X(0x%04X) - (sc->pg_prod) page producer " - "index\n", sc->pg_prod, (u16) PG_CHAIN_IDX(sc->pg_prod)); + if (bce_hdr_split == TRUE) { + BCE_PRINTF(" 0x%04X(0x%04X) - (sc->pg_prod) page producer " + "index\n", sc->pg_prod, (u16) PG_CHAIN_IDX(sc->pg_prod)); - BCE_PRINTF(" 0x%04X(0x%04X) - (sc->pg_cons) page consumer " - "index\n", sc->pg_cons, (u16) PG_CHAIN_IDX(sc->pg_cons)); + BCE_PRINTF(" 0x%04X(0x%04X) - (sc->pg_cons) page consumer " + "index\n", sc->pg_cons, (u16) PG_CHAIN_IDX(sc->pg_cons)); - BCE_PRINTF(" 0x%08X - (sc->debug_pg_mbuf_alloc) page " - "mbufs allocated\n", sc->debug_pg_mbuf_alloc); + BCE_PRINTF(" 0x%08X - (sc->debug_pg_mbuf_alloc) page " + "mbufs allocated\n", sc->debug_pg_mbuf_alloc); + } BCE_PRINTF(" 0x%08X - (sc->free_pg_bd) free page " "rx_bd's\n", sc->free_pg_bd); - BCE_PRINTF("0x%08X/%08X - (sc->pg_low_watermark) page low " - "watermark\n", sc->pg_low_watermark, sc->max_pg_bd); -#endif + BCE_PRINTF(" 0x%04X/0x%04X - (sc->pg_low_watermark)/" + "(sc->max_pg_bd)\n", sc->pg_low_watermark, sc->max_pg_bd); BCE_PRINTF(" 0x%08X - (sc->mbuf_alloc_failed_count) " "mbuf alloc failures\n", sc->mbuf_alloc_failed_count); @@ -10318,6 +10761,44 @@ bce_dump_hw_state(struct bce_softc *sc) } +/****************************************************************************/ +/* Prints out the contentst of shared memory which is used for host driver */ +/* to bootcode firmware communication. */ +/* */ +/* Returns: */ +/* Nothing. */ +/****************************************************************************/ +static __attribute__ ((noinline)) void +bce_dump_shmem_state(struct bce_softc *sc) +{ + BCE_PRINTF( + "----------------------------" + " Hardware State " + "----------------------------\n"); + + BCE_PRINTF("0x%08X - Shared memory base address\n", + sc->bce_shmem_base); + BCE_PRINTF("%s - bootcode version\n", + sc->bce_bc_ver); + + BCE_PRINTF( + "----------------------------" + " Shared Mem " + "----------------------------\n"); + + for (int i = 0x0; i < 0x200; i += 0x10) { + BCE_PRINTF("0x%04X: 0x%08X 0x%08X 0x%08X 0x%08X\n", + i, bce_shmem_rd(sc, i), bce_shmem_rd(sc, i + 0x4), + bce_shmem_rd(sc, i + 0x8), bce_shmem_rd(sc, i + 0xC)); + } + + BCE_PRINTF( + "----------------------------" + "----------------" + "----------------------------\n"); +} + + /****************************************************************************/ /* Prints out the mailbox queue registers. */ /* */ @@ -10776,13 +11257,15 @@ bce_breakpoint(struct bce_softc *sc) bce_dump_enet(sc, NULL); bce_dump_txbd(sc, 0, NULL); bce_dump_rxbd(sc, 0, NULL); - bce_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD); - bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD); + bce_dump_tx_mbuf_chain(sc, 0, USABLE_TX_BD_ALLOC); + bce_dump_rx_mbuf_chain(sc, 0, USABLE_RX_BD_ALLOC); + bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD_ALLOC); bce_dump_l2fhdr(sc, 0, NULL); bce_dump_ctx(sc, RX_CID); bce_dump_ftqs(sc); - bce_dump_tx_chain(sc, 0, USABLE_TX_BD); - bce_dump_rx_bd_chain(sc, 0, USABLE_RX_BD); + bce_dump_tx_chain(sc, 0, USABLE_TX_BD_ALLOC); + bce_dump_rx_bd_chain(sc, 0, USABLE_RX_BD_ALLOC); + bce_dump_pg_chain(sc, 0, USABLE_PG_BD_ALLOC); bce_dump_status_block(sc); bce_dump_stats_block(sc); bce_dump_driver_state(sc); @@ -10794,12 +11277,7 @@ bce_breakpoint(struct bce_softc *sc) bce_dump_cp_state(sc, 0); bce_dump_com_state(sc, 0); bce_dump_rv2p_state(sc); - -#ifdef BCE_JUMBO_HDRSPLIT bce_dump_pgbd(sc, 0, NULL); - bce_dump_pg_mbuf_chain(sc, 0, USABLE_PG_BD); - bce_dump_pg_chain(sc, 0, USABLE_PG_BD); -#endif } bce_dump_status_block(sc); diff --git a/sys/dev/bce/if_bcereg.h b/sys/dev/bce/if_bcereg.h index 172f33c66..f74c4d208 100644 --- a/sys/dev/bce/if_bcereg.h +++ b/sys/dev/bce/if_bcereg.h @@ -302,18 +302,18 @@ #define BCE_CP_INTR 0x00000008 #define BCE_CP_UNLOAD 0x00000010 #define BCE_CP_RESET 0x00000020 -#define BCE_CP_PHY 0x00000040 +#define BCE_CP_PHY 0x00000040 #define BCE_CP_NVRAM 0x00000080 -#define BCE_CP_FIRMWARE 0x00000100 -#define BCE_CP_CTX 0x00000200 -#define BCE_CP_REG 0x00000400 +#define BCE_CP_FIRMWARE 0x00000100 +#define BCE_CP_CTX 0x00000200 +#define BCE_CP_REG 0x00000400 #define BCE_CP_MISC 0x00400000 #define BCE_CP_SPECIAL 0x00800000 -#define BCE_CP_ALL 0x00FFFFFF +#define BCE_CP_ALL 0x00FFFFFF #define BCE_CP_MASK 0x00FFFFFF -#define BCE_LEVEL_FATAL 0x00000000 +#define BCE_LEVEL_FATAL 0x00000000 #define BCE_LEVEL_WARN 0x01000000 #define BCE_LEVEL_INFO 0x02000000 #define BCE_LEVEL_VERBOSE 0x03000000 @@ -326,28 +326,28 @@ #define BCE_INFO_LOAD (BCE_CP_LOAD | BCE_LEVEL_INFO) #define BCE_VERBOSE_LOAD (BCE_CP_LOAD | BCE_LEVEL_VERBOSE) #define BCE_EXTREME_LOAD (BCE_CP_LOAD | BCE_LEVEL_EXTREME) -#define BCE_INSANE_LOAD (BCE_CP_LOAD | BCE_LEVEL_INSANE) +#define BCE_INSANE_LOAD (BCE_CP_LOAD | BCE_LEVEL_INSANE) #define BCE_WARN_SEND (BCE_CP_SEND | BCE_LEVEL_WARN) #define BCE_INFO_SEND (BCE_CP_SEND | BCE_LEVEL_INFO) #define BCE_VERBOSE_SEND (BCE_CP_SEND | BCE_LEVEL_VERBOSE) #define BCE_EXTREME_SEND (BCE_CP_SEND | BCE_LEVEL_EXTREME) -#define BCE_INSANE_SEND (BCE_CP_SEND | BCE_LEVEL_INSANE) +#define BCE_INSANE_SEND (BCE_CP_SEND | BCE_LEVEL_INSANE) #define BCE_WARN_RECV (BCE_CP_RECV | BCE_LEVEL_WARN) #define BCE_INFO_RECV (BCE_CP_RECV | BCE_LEVEL_INFO) #define BCE_VERBOSE_RECV (BCE_CP_RECV | BCE_LEVEL_VERBOSE) #define BCE_EXTREME_RECV (BCE_CP_RECV | BCE_LEVEL_EXTREME) -#define BCE_INSANE_RECV (BCE_CP_RECV | BCE_LEVEL_INSANE) +#define BCE_INSANE_RECV (BCE_CP_RECV | BCE_LEVEL_INSANE) #define BCE_WARN_INTR (BCE_CP_INTR | BCE_LEVEL_WARN) #define BCE_INFO_INTR (BCE_CP_INTR | BCE_LEVEL_INFO) #define BCE_VERBOSE_INTR (BCE_CP_INTR | BCE_LEVEL_VERBOSE) #define BCE_EXTREME_INTR (BCE_CP_INTR | BCE_LEVEL_EXTREME) -#define BCE_INSANE_INTR (BCE_CP_INTR | BCE_LEVEL_INSANE) +#define BCE_INSANE_INTR (BCE_CP_INTR | BCE_LEVEL_INSANE) -#define BCE_WARN_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_WARN) -#define BCE_INFO_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_INFO) +#define BCE_WARN_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_WARN) +#define BCE_INFO_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_INFO) #define BCE_VERBOSE_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_VERBOSE) #define BCE_EXTREME_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_EXTREME) #define BCE_INSANE_UNLOAD (BCE_CP_UNLOAD | BCE_LEVEL_INSANE) @@ -360,8 +360,8 @@ #define BCE_WARN_PHY (BCE_CP_PHY | BCE_LEVEL_WARN) #define BCE_INFO_PHY (BCE_CP_PHY | BCE_LEVEL_INFO) -#define BCE_VERBOSE_PHY (BCE_CP_PHY | BCE_LEVEL_VERBOSE) -#define BCE_EXTREME_PHY (BCE_CP_PHY | BCE_LEVEL_EXTREME) +#define BCE_VERBOSE_PHY (BCE_CP_PHY | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_PHY (BCE_CP_PHY | BCE_LEVEL_EXTREME) #define BCE_INSANE_PHY (BCE_CP_PHY | BCE_LEVEL_INSANE) #define BCE_WARN_NVRAM (BCE_CP_NVRAM | BCE_LEVEL_WARN) @@ -372,40 +372,40 @@ #define BCE_WARN_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_WARN) #define BCE_INFO_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_INFO) -#define BCE_VERBOSE_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_VERBOSE) -#define BCE_EXTREME_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_EXTREME) -#define BCE_INSANE_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_INSANE) +#define BCE_VERBOSE_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_EXTREME) +#define BCE_INSANE_FIRMWARE (BCE_CP_FIRMWARE | BCE_LEVEL_INSANE) #define BCE_WARN_CTX (BCE_CP_CTX | BCE_LEVEL_WARN) #define BCE_INFO_CTX (BCE_CP_CTX | BCE_LEVEL_INFO) -#define BCE_VERBOSE_CTX (BCE_CP_CTX | BCE_LEVEL_VERBOSE) -#define BCE_EXTREME_CTX (BCE_CP_CTX | BCE_LEVEL_EXTREME) +#define BCE_VERBOSE_CTX (BCE_CP_CTX | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_CTX (BCE_CP_CTX | BCE_LEVEL_EXTREME) #define BCE_INSANE_CTX (BCE_CP_CTX | BCE_LEVEL_INSANE) #define BCE_WARN_REG (BCE_CP_REG | BCE_LEVEL_WARN) #define BCE_INFO_REG (BCE_CP_REG | BCE_LEVEL_INFO) -#define BCE_VERBOSE_REG (BCE_CP_REG | BCE_LEVEL_VERBOSE) -#define BCE_EXTREME_REG (BCE_CP_REG | BCE_LEVEL_EXTREME) +#define BCE_VERBOSE_REG (BCE_CP_REG | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_REG (BCE_CP_REG | BCE_LEVEL_EXTREME) #define BCE_INSANE_REG (BCE_CP_REG | BCE_LEVEL_INSANE) #define BCE_WARN_MISC (BCE_CP_MISC | BCE_LEVEL_WARN) #define BCE_INFO_MISC (BCE_CP_MISC | BCE_LEVEL_INFO) #define BCE_VERBOSE_MISC (BCE_CP_MISC | BCE_LEVEL_VERBOSE) #define BCE_EXTREME_MISC (BCE_CP_MISC | BCE_LEVEL_EXTREME) -#define BCE_INSANE_MISC (BCE_CP_MISC | BCE_LEVEL_INSANE) +#define BCE_INSANE_MISC (BCE_CP_MISC | BCE_LEVEL_INSANE) #define BCE_WARN_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_WARN) #define BCE_INFO_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_INFO) -#define BCE_VERBOSE_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_VERBOSE) -#define BCE_EXTREME_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_EXTREME) +#define BCE_VERBOSE_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_VERBOSE) +#define BCE_EXTREME_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_EXTREME) #define BCE_INSANE_SPECIAL (BCE_CP_SPECIAL | BCE_LEVEL_INSANE) -#define BCE_FATAL (BCE_CP_ALL | BCE_LEVEL_FATAL) -#define BCE_WARN (BCE_CP_ALL | BCE_LEVEL_WARN) -#define BCE_INFO (BCE_CP_ALL | BCE_LEVEL_INFO) +#define BCE_FATAL (BCE_CP_ALL | BCE_LEVEL_FATAL) +#define BCE_WARN (BCE_CP_ALL | BCE_LEVEL_WARN) +#define BCE_INFO (BCE_CP_ALL | BCE_LEVEL_INFO) #define BCE_VERBOSE (BCE_CP_ALL | BCE_LEVEL_VERBOSE) #define BCE_EXTREME (BCE_CP_ALL | BCE_LEVEL_EXTREME) -#define BCE_INSANE (BCE_CP_ALL | BCE_LEVEL_INSANE) +#define BCE_INSANE (BCE_CP_ALL | BCE_LEVEL_INSANE) #define BCE_CODE_PATH(cp) ((cp & BCE_CP_MASK) & bce_debug) #define BCE_MSG_LEVEL(lv) \ @@ -1153,20 +1153,19 @@ struct tx_bd { u32 tx_bd_haddr_lo; u32 tx_bd_mss_nbytes; u16 tx_bd_flags; +#define TX_BD_FLAGS_CONN_FAULT (1<<0) +#define TX_BD_FLAGS_TCP_UDP_CKSUM (1<<1) +#define TX_BD_FLAGS_IP_CKSUM (1<<2) +#define TX_BD_FLAGS_VLAN_TAG (1<<3) +#define TX_BD_FLAGS_COAL_NOW (1<<4) +#define TX_BD_FLAGS_DONT_GEN_CRC (1<<5) +#define TX_BD_FLAGS_END (1<<6) +#define TX_BD_FLAGS_START (1<<7) +#define TX_BD_FLAGS_SW_OPTION_WORD (0x1f<<8) +#define TX_BD_FLAGS_SW_FLAGS (1<<13) +#define TX_BD_FLAGS_SW_SNAP (1<<14) +#define TX_BD_FLAGS_SW_LSO (1<<15) u16 tx_bd_vlan_tag; - #define TX_BD_FLAGS_CONN_FAULT (1<<0) - #define TX_BD_FLAGS_TCP_UDP_CKSUM (1<<1) - #define TX_BD_FLAGS_IP_CKSUM (1<<2) - #define TX_BD_FLAGS_VLAN_TAG (1<<3) - #define TX_BD_FLAGS_COAL_NOW (1<<4) - #define TX_BD_FLAGS_DONT_GEN_CRC (1<<5) - #define TX_BD_FLAGS_END (1<<6) - #define TX_BD_FLAGS_START (1<<7) - #define TX_BD_FLAGS_SW_OPTION_WORD (0x1f<<8) - #define TX_BD_FLAGS_SW_FLAGS (1<<13) - #define TX_BD_FLAGS_SW_SNAP (1<<14) - #define TX_BD_FLAGS_SW_LSO (1<<15) - }; @@ -1178,11 +1177,10 @@ struct rx_bd { u32 rx_bd_haddr_lo; u32 rx_bd_len; u32 rx_bd_flags; - #define RX_BD_FLAGS_NOPUSH (1<<0) - #define RX_BD_FLAGS_DUMMY (1<<1) - #define RX_BD_FLAGS_END (1<<2) - #define RX_BD_FLAGS_START (1<<3) - +#define RX_BD_FLAGS_NOPUSH (1<<0) +#define RX_BD_FLAGS_DUMMY (1<<1) +#define RX_BD_FLAGS_END (1<<2) +#define RX_BD_FLAGS_START (1<<3) }; @@ -1385,6 +1383,7 @@ struct l2_fhdr { #define L2_FHDR_ERRORS_ALIGNMENT (1<<19) #define L2_FHDR_ERRORS_TOO_SHORT (1<<20) #define L2_FHDR_ERRORS_GIANT_FRAME (1<<21) + #define L2_FHDR_ERRORS_IPV4_BAD_LEN (1<<22) #define L2_FHDR_ERRORS_TCP_XSUM (1<<28) #define L2_FHDR_ERRORS_UDP_XSUM (1<<31) @@ -1403,36 +1402,39 @@ struct l2_fhdr { }; #define BCE_L2FHDR_PRINTFB \ - "\20" \ + "\20" \ "\40UDP_XSUM_ERR" \ - "\37b30" \ - "\36b29" \ + "\37b30" \ + "\36b29" \ "\35TCP_XSUM_ERR" \ - "\34b27" \ - "\33b26" \ - "\32b25" \ - "\31b24" \ - "\30b23" \ - "\27b22" \ + "\34b27" \ + "\33b26" \ + "\32b25" \ + "\31b24" \ + "\30b23" \ + "\27IPv4_BAL_LEN" \ "\26GIANT_ERR" \ "\25SHORT_ERR" \ "\24ALIGN_ERR" \ "\23PHY_ERR" \ "\22CRC_ERR" \ - "\21SPLIT" \ - "\20UDP" \ - "\17TCP" \ - "\16IP" \ - "\15b12" \ - "\14b11" \ - "\13b10" \ - "\12b09" \ - "\11RSS" \ - "\10SNAP" \ - "\07VLAN" \ - "\06P4" \ - "\05P3" \ - "\04P2" + "\21SPLIT" \ + "\20UDP" \ + "\17TCP" \ + "\16IP" \ + "\15SORT_b3" \ + "\14SORT_b2" \ + "\13SORT_b1" \ + "\12SORT_b0" \ + "\11RSS" \ + "\10SNAP" \ + "\07VLAN" \ + "\06P4" \ + "\05P3" \ + "\04P2" \ + "\03RULE_b2" \ + "\02RULE_b1" \ + "\01RULE_b0" /* @@ -6148,18 +6150,20 @@ struct l2_fhdr { * Page count must remain a power of 2 for all * of the math to work correctly. */ -#define TX_PAGES 2 -#define TOTAL_TX_BD_PER_PAGE (BCM_PAGE_SIZE / sizeof(struct tx_bd)) -#define USABLE_TX_BD_PER_PAGE (TOTAL_TX_BD_PER_PAGE - 1) -#define TOTAL_TX_BD (TOTAL_TX_BD_PER_PAGE * TX_PAGES) -#define USABLE_TX_BD (USABLE_TX_BD_PER_PAGE * TX_PAGES) -#define MAX_TX_BD (TOTAL_TX_BD - 1) +#define DEFAULT_TX_PAGES 2 +#define MAX_TX_PAGES 8 +#define TOTAL_TX_BD_PER_PAGE (BCM_PAGE_SIZE / sizeof(struct tx_bd)) +#define USABLE_TX_BD_PER_PAGE (TOTAL_TX_BD_PER_PAGE - 1) +#define MAX_TX_BD_AVAIL (MAX_TX_PAGES * TOTAL_TX_BD_PER_PAGE) +#define TOTAL_TX_BD_ALLOC (TOTAL_TX_BD_PER_PAGE * sc->tx_pages) +#define USABLE_TX_BD_ALLOC (USABLE_TX_BD_PER_PAGE * sc->tx_pages) +#define MAX_TX_BD_ALLOC (TOTAL_TX_BD_ALLOC - 1) /* Advance to the next tx_bd, skipping any next page pointers. */ #define NEXT_TX_BD(x) (((x) & USABLE_TX_BD_PER_PAGE) == \ (USABLE_TX_BD_PER_PAGE - 1)) ? (x) + 2 : (x) + 1 -#define TX_CHAIN_IDX(x) ((x) & MAX_TX_BD) +#define TX_CHAIN_IDX(x) ((x) & MAX_TX_BD_ALLOC) #define TX_PAGE(x) (((x) & ~USABLE_TX_BD_PER_PAGE) >> (BCM_PAGE_BITS - 4)) #define TX_IDX(x) ((x) & USABLE_TX_BD_PER_PAGE) @@ -6168,45 +6172,46 @@ struct l2_fhdr { * Page count must remain a power of 2 for all * of the math to work correctly. */ -#define RX_PAGES 2 -#define TOTAL_RX_BD_PER_PAGE (BCM_PAGE_SIZE / sizeof(struct rx_bd)) -#define USABLE_RX_BD_PER_PAGE (TOTAL_RX_BD_PER_PAGE - 1) -#define TOTAL_RX_BD (TOTAL_RX_BD_PER_PAGE * RX_PAGES) -#define USABLE_RX_BD (USABLE_RX_BD_PER_PAGE * RX_PAGES) -#define MAX_RX_BD (TOTAL_RX_BD - 1) +#define DEFAULT_RX_PAGES 2 +#define MAX_RX_PAGES 8 +#define TOTAL_RX_BD_PER_PAGE (BCM_PAGE_SIZE / sizeof(struct rx_bd)) +#define USABLE_RX_BD_PER_PAGE (TOTAL_RX_BD_PER_PAGE - 1) +#define MAX_RX_BD_AVAIL (MAX_RX_PAGES * TOTAL_RX_BD_PER_PAGE) +#define TOTAL_RX_BD_ALLOC (TOTAL_RX_BD_PER_PAGE * sc->rx_pages) +#define USABLE_RX_BD_ALLOC (USABLE_RX_BD_PER_PAGE * sc->rx_pages) +#define MAX_RX_BD_ALLOC (TOTAL_RX_BD_ALLOC - 1) /* Advance to the next rx_bd, skipping any next page pointers. */ #define NEXT_RX_BD(x) (((x) & USABLE_RX_BD_PER_PAGE) == \ (USABLE_RX_BD_PER_PAGE - 1)) ? (x) + 2 : (x) + 1 -#define RX_CHAIN_IDX(x) ((x) & MAX_RX_BD) +#define RX_CHAIN_IDX(x) ((x) & MAX_RX_BD_ALLOC) #define RX_PAGE(x) (((x) & ~USABLE_RX_BD_PER_PAGE) >> (BCM_PAGE_BITS - 4)) #define RX_IDX(x) ((x) & USABLE_RX_BD_PER_PAGE) -#ifdef BCE_JUMBO_HDRSPLIT /* * To accomodate jumbo frames, the page chain should * be 4 times larger than the receive chain. */ -#define PG_PAGES (RX_PAGES * 4) -#define TOTAL_PG_BD_PER_PAGE (BCM_PAGE_SIZE / sizeof(struct rx_bd)) -#define USABLE_PG_BD_PER_PAGE (TOTAL_PG_BD_PER_PAGE - 1) -#define TOTAL_PG_BD (TOTAL_PG_BD_PER_PAGE * PG_PAGES) -#define USABLE_PG_BD (USABLE_PG_BD_PER_PAGE * PG_PAGES) -#define MAX_PG_BD (TOTAL_PG_BD - 1) +#define DEFAULT_PG_PAGES (DEFAULT_RX_PAGES * 4) +#define MAX_PG_PAGES (MAX_RX_PAGES * 4) +#define TOTAL_PG_BD_PER_PAGE (BCM_PAGE_SIZE / sizeof(struct rx_bd)) +#define USABLE_PG_BD_PER_PAGE (TOTAL_PG_BD_PER_PAGE - 1) +#define MAX_PG_BD_AVAIL (MAX_PG_PAGES * TOTAL_PG_BD_PER_PAGE) +#define TOTAL_PG_BD_ALLOC (TOTAL_PG_BD_PER_PAGE * sc->pg_pages) +#define USABLE_PG_BD_ALLOC (USABLE_PG_BD_PER_PAGE * sc->pg_pages) +#define MAX_PG_BD_ALLOC (TOTAL_PG_BD_ALLOC - 1) /* Advance to the next pg_bd, skipping any next page pointers. */ #define NEXT_PG_BD(x) (((x) & USABLE_PG_BD_PER_PAGE) == \ (USABLE_PG_BD_PER_PAGE - 1)) ? (x) + 2 : (x) + 1 -#define PG_CHAIN_IDX(x) ((x) & MAX_PG_BD) +#define PG_CHAIN_IDX(x) ((x) & MAX_PG_BD_ALLOC) #define PG_PAGE(x) (((x) & ~USABLE_PG_BD_PER_PAGE) >> (BCM_PAGE_BITS - 4)) #define PG_IDX(x) ((x) & USABLE_PG_BD_PER_PAGE) -#endif /* BCE_JUMBO_HDRSPLIT */ - #define CTX_INIT_RETRY_COUNT 10 /* Context size. */ @@ -6234,6 +6239,15 @@ struct l2_fhdr { #define TX_CID 16 #define RX_CID 0 +#define DEFAULT_TX_QUICK_CONS_TRIP_INT 20 +#define DEFAULT_TX_QUICK_CONS_TRIP 20 +#define DEFAULT_TX_TICKS_INT 80 +#define DEFAULT_TX_TICKS 80 +#define DEFAULT_RX_QUICK_CONS_TRIP_INT 6 +#define DEFAULT_RX_QUICK_CONS_TRIP 6 +#define DEFAULT_RX_TICKS_INT 18 +#define DEFAULT_RX_TICKS 18 + /****************************************************************************/ /* BCE Processor Firmwware Load Definitions */ /****************************************************************************/ @@ -6528,26 +6542,27 @@ struct bce_softc /* The device handle for the MII bus child device. */ device_t bce_miibus; - /* Driver maintained TX chain pointers and byte counter. */ + /* Driver maintained RX chain pointers and byte counter. */ u16 rx_prod; u16 rx_cons; /* Counts the bytes used in the RX chain. */ u32 rx_prod_bseq; + + /* Driver maintained TX chain pointers and byte counter. */ u16 tx_prod; u16 tx_cons; /* Counts the bytes used in the TX chain. */ u32 tx_prod_bseq; -#ifdef BCE_JUMBO_HDRSPLIT + /* Driver maintained PG chain pointers. */ u16 pg_prod; u16 pg_cons; -#endif int bce_link_up; - struct callout bce_tick_callout; - struct callout bce_pulse_callout; + struct callout bce_tick_callout; + struct callout bce_pulse_callout; /* Ticks until chip reset */ int watchdog_timer; @@ -6557,10 +6572,7 @@ struct bce_softc int rx_bd_mbuf_alloc_size; int rx_bd_mbuf_data_len; int rx_bd_mbuf_align_pad; - -#ifdef BCE_JUMBO_HDRSPLIT int pg_bd_mbuf_alloc_size; -#endif /* Receive mode settings (i.e promiscuous, multicast, etc.). */ u32 rx_mode; @@ -6569,30 +6581,31 @@ struct bce_softc bus_dma_tag_t parent_tag; /* H/W maintained TX buffer descriptor chain structure. */ + int tx_pages; bus_dma_tag_t tx_bd_chain_tag; - bus_dmamap_t tx_bd_chain_map[TX_PAGES]; - struct tx_bd *tx_bd_chain[TX_PAGES]; - bus_addr_t tx_bd_chain_paddr[TX_PAGES]; + bus_dmamap_t tx_bd_chain_map[MAX_TX_PAGES]; + struct tx_bd *tx_bd_chain[MAX_TX_PAGES]; + bus_addr_t tx_bd_chain_paddr[MAX_TX_PAGES]; /* H/W maintained RX buffer descriptor chain structure. */ + int rx_pages; bus_dma_tag_t rx_bd_chain_tag; - bus_dmamap_t rx_bd_chain_map[RX_PAGES]; - struct rx_bd *rx_bd_chain[RX_PAGES]; - bus_addr_t rx_bd_chain_paddr[RX_PAGES]; + bus_dmamap_t rx_bd_chain_map[MAX_RX_PAGES]; + struct rx_bd *rx_bd_chain[MAX_RX_PAGES]; + bus_addr_t rx_bd_chain_paddr[MAX_RX_PAGES]; -#ifdef BCE_JUMBO_HDRSPLIT /* H/W maintained page buffer descriptor chain structure. */ + int pg_pages; bus_dma_tag_t pg_bd_chain_tag; - bus_dmamap_t pg_bd_chain_map[PG_PAGES]; - struct rx_bd *pg_bd_chain[PG_PAGES]; - bus_addr_t pg_bd_chain_paddr[PG_PAGES]; -#endif + bus_dmamap_t pg_bd_chain_map[MAX_PG_PAGES]; + struct rx_bd *pg_bd_chain[MAX_PG_PAGES]; + bus_addr_t pg_bd_chain_paddr[MAX_PG_PAGES]; /* H/W maintained status block. */ bus_dma_tag_t status_tag; bus_dmamap_t status_map; struct status_block *status_block; - bus_addr_t status_block_paddr; + bus_addr_t status_block_paddr; /* Driver maintained status block values. */ u16 last_status_idx; @@ -6603,49 +6616,41 @@ struct bce_softc bus_dma_tag_t stats_tag; bus_dmamap_t stats_map; struct statistics_block *stats_block; - bus_addr_t stats_block_paddr; + bus_addr_t stats_block_paddr; /* H/W maintained context block. */ - int ctx_pages; + int ctx_pages; bus_dma_tag_t ctx_tag; /* BCM5709/16 use host memory for context. */ bus_dmamap_t ctx_map[BCE_MAX_CONTEXT]; - void *ctx_block[BCE_MAX_CONTEXT]; - bus_addr_t ctx_paddr[BCE_MAX_CONTEXT]; + void *ctx_block[BCE_MAX_CONTEXT]; + bus_addr_t ctx_paddr[BCE_MAX_CONTEXT]; /* Bus tag for RX/TX mbufs. */ bus_dma_tag_t rx_mbuf_tag; bus_dma_tag_t tx_mbuf_tag; - -#ifdef BCE_JUMBO_HDRSPLIT bus_dma_tag_t pg_mbuf_tag; -#endif /* S/W maintained mbuf TX chain structure. */ - bus_dmamap_t tx_mbuf_map[TOTAL_TX_BD]; - struct mbuf *tx_mbuf_ptr[TOTAL_TX_BD]; + bus_dmamap_t tx_mbuf_map[MAX_TX_BD_AVAIL]; + struct mbuf *tx_mbuf_ptr[MAX_TX_BD_AVAIL]; /* S/W maintained mbuf RX chain structure. */ - bus_dmamap_t rx_mbuf_map[TOTAL_RX_BD]; - struct mbuf *rx_mbuf_ptr[TOTAL_RX_BD]; + bus_dmamap_t rx_mbuf_map[MAX_RX_BD_AVAIL]; + struct mbuf *rx_mbuf_ptr[MAX_RX_BD_AVAIL]; -#ifdef BCE_JUMBO_HDRSPLIT /* S/W maintained mbuf page chain structure. */ - bus_dmamap_t pg_mbuf_map[TOTAL_PG_BD]; - struct mbuf *pg_mbuf_ptr[TOTAL_PG_BD]; -#endif + bus_dmamap_t pg_mbuf_map[MAX_PG_BD_AVAIL]; + struct mbuf *pg_mbuf_ptr[MAX_PG_BD_AVAIL]; /* Track the number of buffer descriptors in use. */ u16 free_rx_bd; u16 max_rx_bd; u16 used_tx_bd; u16 max_tx_bd; - -#ifdef BCE_JUMBO_HDRSPLIT u16 free_pg_bd; u16 max_pg_bd; -#endif /* Provides access to hardware statistics through sysctl. */ u64 stat_IfHCInOctets; @@ -6731,63 +6736,63 @@ struct bce_softc /* Track the number of enqueued mbufs. */ int debug_tx_mbuf_alloc; int debug_rx_mbuf_alloc; - -#ifdef BCE_JUMBO_HDRSPLIT int debug_pg_mbuf_alloc; -#endif /* Track how many and what type of interrupts are generated. */ - u32 interrupts_generated; - u32 interrupts_handled; - u32 interrupts_rx; - u32 interrupts_tx; - u32 phy_interrupts; - - /* Track interrupt time (25MHz clock). */ - u64 rx_intr_time; - u64 tx_intr_time; + u64 interrupts_generated; + u64 interrupts_handled; + u64 interrupts_rx; + u64 interrupts_tx; + u64 phy_interrupts; /* Lowest number of rx_bd's free. */ - u32 rx_low_watermark; + u16 rx_low_watermark; /* Number of times the RX chain was empty. */ - u32 rx_empty_count; + u64 rx_empty_count; -#ifdef BCE_JUMBO_HDRSPLIT /* Lowest number of pages free. */ - u32 pg_low_watermark; + u16 pg_low_watermark; /* Number of times the page chain was empty. */ - u32 pg_empty_count; -#endif + u64 pg_empty_count; /* Greatest number of tx_bd's used. */ - u32 tx_hi_watermark; + u16 tx_hi_watermark; /* Number of times the TX chain was full. */ - u32 tx_full_count; + u64 tx_full_count; /* Number of TSO frames requested. */ - u32 tso_frames_requested; + u64 tso_frames_requested; /* Number of TSO frames completed. */ - u32 tso_frames_completed; + u64 tso_frames_completed; /* Number of TSO frames failed. */ - u32 tso_frames_failed; + u64 tso_frames_failed; /* Number of IP checksum offload frames.*/ - u32 csum_offload_ip; + u64 csum_offload_ip; /* Number of TCP/UDP checksum offload frames.*/ - u32 csum_offload_tcp_udp; + u64 csum_offload_tcp_udp; /* Number of VLAN tagged frames received. */ - u32 vlan_tagged_frames_rcvd; + u64 vlan_tagged_frames_rcvd; /* Number of VLAN tagged frames stripped. */ - u32 vlan_tagged_frames_stripped; -#endif + u64 vlan_tagged_frames_stripped; + + /* Number of split header frames received. */ + u64 split_header_frames_rcvd; + + /* Number of split header TCP frames received. */ + u64 split_header_tcp_frames_rcvd; + + /* Buffer with NVRAM contents for the NIC. */ + u8 *nvram_buf; +#endif /* BCE_DEBUG */ }; #endif /* __BCEREG_H_DEFINED */ -- 2.45.0