From owner-svn-src-projects@FreeBSD.ORG Fri Mar 18 23:48:06 2011 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6448D1065672; Fri, 18 Mar 2011 23:48:06 +0000 (UTC) (envelope-from marcel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 536AD8FC14; Fri, 18 Mar 2011 23:48:06 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p2INm6Jj083710; Fri, 18 Mar 2011 23:48:06 GMT (envelope-from marcel@svn.freebsd.org) Received: (from marcel@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p2INm6Lq083701; Fri, 18 Mar 2011 23:48:06 GMT (envelope-from marcel@svn.freebsd.org) Message-Id: <201103182348.p2INm6Lq083701@svn.freebsd.org> From: Marcel Moolenaar Date: Fri, 18 Mar 2011 23:48:06 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r219761 - in projects/altix/sys: dev/e1000 ia64/ia64 kern X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Mar 2011 23:48:06 -0000 Author: marcel Date: Fri Mar 18 23:48:06 2011 New Revision: 219761 URL: http://svn.freebsd.org/changeset/base/219761 Log: Merge svn+ssh://svn.freebsd.org/base/head@219760 Modified: projects/altix/sys/dev/e1000/e1000_82575.c projects/altix/sys/dev/e1000/e1000_82575.h projects/altix/sys/dev/e1000/e1000_defines.h projects/altix/sys/dev/e1000/e1000_phy.c projects/altix/sys/dev/e1000/if_em.c projects/altix/sys/dev/e1000/if_em.h projects/altix/sys/dev/e1000/if_igb.c projects/altix/sys/dev/e1000/if_igb.h projects/altix/sys/dev/e1000/if_lem.h projects/altix/sys/ia64/ia64/genassym.c projects/altix/sys/ia64/ia64/locore.S Directory Properties: projects/altix/lib/libstand/ (props changed) projects/altix/sys/ (props changed) projects/altix/sys/amd64/include/xen/ (props changed) projects/altix/sys/boot/i386/efi/ (props changed) projects/altix/sys/boot/ia64/efi/ (props changed) projects/altix/sys/boot/ia64/ski/ (props changed) projects/altix/sys/boot/powerpc/boot1.chrp/ (props changed) projects/altix/sys/boot/powerpc/ofw/ (props changed) projects/altix/sys/cddl/contrib/opensolaris/ (props changed) projects/altix/sys/conf/ (props changed) projects/altix/sys/contrib/dev/acpica/ (props changed) projects/altix/sys/contrib/octeon-sdk/ (props changed) projects/altix/sys/contrib/pf/ (props changed) projects/altix/sys/contrib/x86emu/ (props changed) projects/altix/sys/kern/subr_busdma.c (props changed) Modified: projects/altix/sys/dev/e1000/e1000_82575.c ============================================================================== --- projects/altix/sys/dev/e1000/e1000_82575.c Fri Mar 18 22:56:53 2011 (r219760) +++ projects/altix/sys/dev/e1000/e1000_82575.c Fri Mar 18 23:48:06 2011 (r219761) @@ -36,7 +36,6 @@ * 82575EB Gigabit Network Connection * 82575EB Gigabit Backplane Connection * 82575GB Gigabit Network Connection - * 82575GB Gigabit Network Connection * 82576 Gigabit Network Connection * 82576 Quad Port Gigabit Mezzanine Adapter */ @@ -44,7 +43,6 @@ #include "e1000_api.h" static s32 e1000_init_phy_params_82575(struct e1000_hw *hw); -static s32 e1000_init_nvm_params_82575(struct e1000_hw *hw); static s32 e1000_init_mac_params_82575(struct e1000_hw *hw); static s32 e1000_acquire_phy_82575(struct e1000_hw *hw); static void e1000_release_phy_82575(struct e1000_hw *hw); @@ -197,12 +195,14 @@ static s32 e1000_init_phy_params_82575(s switch (phy->id) { case I347AT4_E_PHY_ID: case M88E1112_E_PHY_ID: + case M88E1340M_E_PHY_ID: case M88E1111_I_PHY_ID: phy->type = e1000_phy_m88; phy->ops.check_polarity = e1000_check_polarity_m88; phy->ops.get_info = e1000_get_phy_info_m88; if (phy->id == I347AT4_E_PHY_ID || - phy->id == M88E1112_E_PHY_ID) + phy->id == M88E1112_E_PHY_ID || + phy->id == M88E1340M_E_PHY_ID) phy->ops.get_cable_length = e1000_get_cable_length_m88_gen2; else phy->ops.get_cable_length = e1000_get_cable_length_m88; @@ -241,7 +241,7 @@ out: * e1000_init_nvm_params_82575 - Init NVM func ptrs. * @hw: pointer to the HW structure **/ -static s32 e1000_init_nvm_params_82575(struct e1000_hw *hw) +s32 e1000_init_nvm_params_82575(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; u32 eecd = E1000_READ_REG(hw, E1000_EECD); @@ -258,7 +258,6 @@ static s32 e1000_init_nvm_params_82575(s size += NVM_WORD_SIZE_BASE_SHIFT; nvm->word_size = 1 << size; - nvm->opcode_bits = 8; nvm->delay_usec = 1; switch (nvm->override) { @@ -278,20 +277,23 @@ static s32 e1000_init_nvm_params_82575(s nvm->type = e1000_nvm_eeprom_spi; - if (nvm->word_size == (1 << 15)) { + if (nvm->word_size == (1 << 15)) nvm->page_size = 128; - } - /* Function Pointers */ - nvm->ops.acquire = e1000_acquire_nvm_82575; - if (nvm->word_size < (1 << 15)) { - nvm->ops.read = e1000_read_nvm_eerd; - } else { - nvm->ops.read = e1000_read_nvm_spi; - } - nvm->ops.release = e1000_release_nvm_82575; - nvm->ops.valid_led_default = e1000_valid_led_default_82575; + nvm->ops.acquire = e1000_acquire_nvm_82575; + nvm->ops.release = e1000_release_nvm_82575; + if (nvm->word_size < (1 << 15)) + nvm->ops.read = e1000_read_nvm_eerd; + else + nvm->ops.read = e1000_read_nvm_spi; + + nvm->ops.write = e1000_write_nvm_spi; + nvm->ops.validate = e1000_validate_nvm_checksum_generic; + nvm->ops.update = e1000_update_nvm_checksum_generic; + nvm->ops.valid_led_default = e1000_valid_led_default_82575; + + /* override genric family function pointers for specific descendants */ switch (hw->mac.type) { case e1000_82580: nvm->ops.validate = e1000_validate_nvm_checksum_82580; @@ -302,10 +304,8 @@ static s32 e1000_init_nvm_params_82575(s nvm->ops.update = e1000_update_nvm_checksum_i350; break; default: - nvm->ops.validate = e1000_validate_nvm_checksum_generic; - nvm->ops.update = e1000_update_nvm_checksum_generic; + break; } - nvm->ops.write = e1000_write_nvm_spi; return E1000_SUCCESS; } @@ -889,9 +889,7 @@ static s32 e1000_acquire_nvm_82575(struc ret_val = e1000_acquire_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); if (ret_val) goto out; - ret_val = e1000_acquire_nvm_generic(hw); - if (ret_val) e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); @@ -910,7 +908,6 @@ static void e1000_release_nvm_82575(stru { DEBUGFUNC("e1000_release_nvm_82575"); - e1000_release_nvm_generic(hw); e1000_release_swfw_sync_82575(hw, E1000_SWFW_EEP_SM); } @@ -1365,7 +1362,8 @@ static s32 e1000_setup_copper_link_82575 switch (hw->phy.type) { case e1000_phy_m88: if (hw->phy.id == I347AT4_E_PHY_ID || - hw->phy.id == M88E1112_E_PHY_ID) + hw->phy.id == M88E1112_E_PHY_ID || + hw->phy.id == M88E1340M_E_PHY_ID) ret_val = e1000_copper_link_setup_m88_gen2(hw); else ret_val = e1000_copper_link_setup_m88(hw); @@ -1840,7 +1838,6 @@ out: return ret_val; } - /** * e1000_vmdq_set_anti_spoofing_pf - enable or disable anti-spoofing * @hw: pointer to the hardware struct @@ -1986,7 +1983,7 @@ out: * e1000_reset_mdicnfg_82580 - Reset MDICNFG destination and com_mdio bits * @hw: pointer to the HW structure * - * This resets the MDICNFG.Destination and MDICNFG.Com_MDIO bits based on + * This resets the the MDICNFG.Destination and MDICNFG.Com_MDIO bits based on * the values found in the EEPROM. This addresses an issue in which these * bits are not restored from EEPROM after reset. **/ Modified: projects/altix/sys/dev/e1000/e1000_82575.h ============================================================================== --- projects/altix/sys/dev/e1000/e1000_82575.h Fri Mar 18 22:56:53 2011 (r219760) +++ projects/altix/sys/dev/e1000/e1000_82575.h Fri Mar 18 23:48:06 2011 (r219761) @@ -469,6 +469,8 @@ struct e1000_adv_tx_context_desc { void e1000_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable); void e1000_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf); void e1000_vmdq_set_replication_pf(struct e1000_hw *hw, bool enable); +s32 e1000_init_nvm_params_82575(struct e1000_hw *hw); + enum e1000_promisc_type { e1000_promisc_disabled = 0, /* all promisc modes disabled */ e1000_promisc_unicast = 1, /* unicast promiscuous enabled */ Modified: projects/altix/sys/dev/e1000/e1000_defines.h ============================================================================== --- projects/altix/sys/dev/e1000/e1000_defines.h Fri Mar 18 22:56:53 2011 (r219760) +++ projects/altix/sys/dev/e1000/e1000_defines.h Fri Mar 18 23:48:06 2011 (r219761) @@ -76,8 +76,8 @@ #define E1000_WUFC_FLX3 0x00080000 /* Flexible Filter 3 Enable */ #define E1000_WUFC_FLX4 0x00100000 /* Flexible Filter 4 Enable */ #define E1000_WUFC_FLX5 0x00200000 /* Flexible Filter 5 Enable */ -#define E1000_WUFC_FLX6 0x00400000 /* Flexible Filter 6 Enable */ -#define E1000_WUFC_FLX7 0x00800000 /* Flexible Filter 7 Enable */ +#define E1000_WUFC_FLX6 0x00400000 /* Flexible Filter 6 Enable */ +#define E1000_WUFC_FLX7 0x00800000 /* Flexible Filter 7 Enable */ #define E1000_WUFC_FW_RST 0x80000000 /* Wake on FW Reset Enable */ #define E1000_WUFC_ALL_FILTERS_PHY_4 0x0000F0FF /*Mask for all wakeup filters*/ #define E1000_WUFC_FLX_OFFSET_PHY 12 /* Offset to the Flexible Filters bits */ @@ -249,6 +249,7 @@ #define E1000_RXD_SPC_CFI_MASK 0x1000 /* CFI is bit 12 */ #define E1000_RXD_SPC_CFI_SHIFT 12 +#define E1000_RXDEXT_STATERR_LB 0x00040000 #define E1000_RXDEXT_STATERR_CE 0x01000000 #define E1000_RXDEXT_STATERR_SE 0x02000000 #define E1000_RXDEXT_STATERR_SEQ 0x04000000 @@ -1478,7 +1479,8 @@ #define M88E1011_I_REV_4 0x04 #define M88E1111_I_PHY_ID 0x01410CC0 #define M88E1112_E_PHY_ID 0x01410C90 -#define I347AT4_E_PHY_ID 0x01410DC0 +#define I347AT4_E_PHY_ID 0x01410DC0 +#define M88E1340M_E_PHY_ID 0x01410DF0 #define GG82563_E_PHY_ID 0x01410CA0 #define IGP03E1000_E_PHY_ID 0x02A80390 #define IFE_E_PHY_ID 0x02A80330 @@ -1764,11 +1766,10 @@ #define E1000_RTTBCNRC_RF_INT_MASK \ (E1000_RTTBCNRC_RF_DEC_MASK << E1000_RTTBCNRC_RF_INT_SHIFT) - /* DMA Coalescing register fields */ #define E1000_DMACR_DMACWT_MASK 0x00003FFF /* DMA Coalescing * Watchdog Timer */ -#define E1000_DMACR_DMACTHR_MASK 0x00FF0000 /* DMA Coalescing Receive +#define E1000_DMACR_DMACTHR_MASK 0x00FF0000 /* DMA Coalescing Rx * Threshold */ #define E1000_DMACR_DMACTHR_SHIFT 16 #define E1000_DMACR_DMAC_LX_MASK 0x30000000 /* Lx when no PCIe @@ -1781,15 +1782,15 @@ #define E1000_DMCTLX_TTLX_MASK 0x00000FFF /* Time to LX request */ -#define E1000_DMCRTRH_UTRESH_MASK 0x0007FFFF /* Receive Traffic Rate +#define E1000_DMCRTRH_UTRESH_MASK 0x0007FFFF /* Rx Traffic Rate * Threshold */ -#define E1000_DMCRTRH_LRPRCW 0x80000000 /* Rcv packet rate in +#define E1000_DMCRTRH_LRPRCW 0x80000000 /* Rx packet rate in * current window */ -#define E1000_DMCCNT_CCOUNT_MASK 0x01FFFFFF /* DMA Coal Rcv Traffic +#define E1000_DMCCNT_CCOUNT_MASK 0x01FFFFFF /* DMA Coal Rx Traffic * Current Cnt */ -#define E1000_FCRTC_RTH_COAL_MASK 0x0003FFF0 /* Flow ctrl Rcv Threshold +#define E1000_FCRTC_RTH_COAL_MASK 0x0003FFF0 /* Flow ctrl Rx Threshold * High val */ #define E1000_FCRTC_RTH_COAL_SHIFT 4 #define E1000_PCIEMISC_LX_DECISION 0x00000080 /* Lx power decision based Modified: projects/altix/sys/dev/e1000/e1000_phy.c ============================================================================== --- projects/altix/sys/dev/e1000/e1000_phy.c Fri Mar 18 22:56:53 2011 (r219760) +++ projects/altix/sys/dev/e1000/e1000_phy.c Fri Mar 18 23:48:06 2011 (r219761) @@ -255,10 +255,6 @@ s32 e1000_read_phy_reg_mdic(struct e1000 E1000_WRITE_REG(hw, E1000_MDIC, mdic); - /* Workaround for Si errata */ - if ((hw->phy.type == e1000_phy_82577) && (hw->revision_id <= 2)) - msec_delay(10); - /* * Poll the ready bit to see if the MDI read completed * Increasing the time out as testing showed failures with @@ -326,10 +322,6 @@ s32 e1000_write_phy_reg_mdic(struct e100 E1000_WRITE_REG(hw, E1000_MDIC, mdic); - /* Workaround for Si errata */ - if ((hw->phy.type == e1000_phy_82577) && (hw->revision_id <= 2)) - msec_delay(10); - /* * Poll the ready bit to see if the MDI read completed * Increasing the time out as testing showed failures with @@ -1656,6 +1648,7 @@ s32 e1000_phy_force_speed_duplex_m88(str if (!link) { if (hw->phy.type != e1000_phy_m88 || hw->phy.id == I347AT4_E_PHY_ID || + hw->phy.id == M88E1340M_E_PHY_ID || hw->phy.id == M88E1112_E_PHY_ID) { DEBUGOUT("Link taking longer than expected.\n"); } else { @@ -1683,6 +1676,7 @@ s32 e1000_phy_force_speed_duplex_m88(str if (hw->phy.type != e1000_phy_m88 || hw->phy.id == I347AT4_E_PHY_ID || + hw->phy.id == M88E1340M_E_PHY_ID || hw->phy.id == M88E1112_E_PHY_ID) goto out; @@ -2233,6 +2227,7 @@ s32 e1000_get_cable_length_m88_gen2(stru DEBUGFUNC("e1000_get_cable_length_m88_gen2"); switch (hw->phy.id) { + case M88E1340M_E_PHY_ID: case I347AT4_E_PHY_ID: /* Remember the original page select and set it to 7 */ ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT, @@ -2787,6 +2782,7 @@ enum e1000_phy_type e1000_get_phy_type_f case M88E1011_I_PHY_ID: case I347AT4_E_PHY_ID: case M88E1112_E_PHY_ID: + case M88E1340M_E_PHY_ID: phy_type = e1000_phy_m88; break; case IGP01E1000_I_PHY_ID: /* IGP 1 & 2 share this */ Modified: projects/altix/sys/dev/e1000/if_em.c ============================================================================== --- projects/altix/sys/dev/e1000/if_em.c Fri Mar 18 22:56:53 2011 (r219760) +++ projects/altix/sys/dev/e1000/if_em.c Fri Mar 18 23:48:06 2011 (r219761) @@ -93,7 +93,7 @@ int em_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char em_driver_version[] = "7.1.9"; +char em_driver_version[] = "7.2.2"; /********************************************************************* * PCI Device ID Table @@ -284,9 +284,7 @@ static void em_handle_tx(void *context, static void em_handle_rx(void *context, int pending); static void em_handle_link(void *context, int pending); -static void em_add_rx_process_limit(struct adapter *, const char *, - const char *, int *, int); -static void em_set_flow_cntrl(struct adapter *, const char *, +static void em_set_sysctl_value(struct adapter *, const char *, const char *, int *, int); static __inline void em_rx_discard(struct rx_ring *, int); @@ -365,6 +363,10 @@ TUNABLE_INT("hw.em.rx_process_limit", &e static int em_fc_setting = e1000_fc_full; TUNABLE_INT("hw.em.fc_setting", &em_fc_setting); +/* Energy efficient ethernet - default to OFF */ +static int eee_setting = 0; +TUNABLE_INT("hw.em.eee_setting", &eee_setting); + /* Global used in WOL setup with multiport cards */ static int global_quad_port_a = 0; @@ -433,12 +435,14 @@ static int em_attach(device_t dev) { struct adapter *adapter; + struct e1000_hw *hw; int error = 0; INIT_DEBUGOUT("em_attach: begin"); adapter = device_get_softc(dev); adapter->dev = adapter->osdep.dev = dev; + hw = &adapter->hw; EM_CORE_LOCK_INIT(adapter, device_get_nameunit(dev)); /* SYSCTL stuff */ @@ -470,11 +474,11 @@ em_attach(device_t dev) ** must happen after the MAC is ** identified */ - if ((adapter->hw.mac.type == e1000_ich8lan) || - (adapter->hw.mac.type == e1000_ich9lan) || - (adapter->hw.mac.type == e1000_ich10lan) || - (adapter->hw.mac.type == e1000_pchlan) || - (adapter->hw.mac.type == e1000_pch2lan)) { + if ((hw->mac.type == e1000_ich8lan) || + (hw->mac.type == e1000_ich9lan) || + (hw->mac.type == e1000_ich10lan) || + (hw->mac.type == e1000_pchlan) || + (hw->mac.type == e1000_pch2lan)) { int rid = EM_BAR_TYPE_FLASH; adapter->flash = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); @@ -484,7 +488,7 @@ em_attach(device_t dev) goto err_pci; } /* This is used in the shared code */ - adapter->hw.flash_address = (u8 *)adapter->flash; + hw->flash_address = (u8 *)adapter->flash; adapter->osdep.flash_bus_space_tag = rman_get_bustag(adapter->flash); adapter->osdep.flash_bus_space_handle = @@ -492,39 +496,39 @@ em_attach(device_t dev) } /* Do Shared Code initialization */ - if (e1000_setup_init_funcs(&adapter->hw, TRUE)) { + if (e1000_setup_init_funcs(hw, TRUE)) { device_printf(dev, "Setup of Shared code failed\n"); error = ENXIO; goto err_pci; } - e1000_get_bus_info(&adapter->hw); + e1000_get_bus_info(hw); /* Set up some sysctls for the tunable interrupt delays */ em_add_int_delay_sysctl(adapter, "rx_int_delay", "receive interrupt delay in usecs", &adapter->rx_int_delay, - E1000_REGISTER(&adapter->hw, E1000_RDTR), em_rx_int_delay_dflt); + E1000_REGISTER(hw, E1000_RDTR), em_rx_int_delay_dflt); em_add_int_delay_sysctl(adapter, "tx_int_delay", "transmit interrupt delay in usecs", &adapter->tx_int_delay, - E1000_REGISTER(&adapter->hw, E1000_TIDV), em_tx_int_delay_dflt); + E1000_REGISTER(hw, E1000_TIDV), em_tx_int_delay_dflt); em_add_int_delay_sysctl(adapter, "rx_abs_int_delay", "receive interrupt delay limit in usecs", &adapter->rx_abs_int_delay, - E1000_REGISTER(&adapter->hw, E1000_RADV), + E1000_REGISTER(hw, E1000_RADV), em_rx_abs_int_delay_dflt); em_add_int_delay_sysctl(adapter, "tx_abs_int_delay", "transmit interrupt delay limit in usecs", &adapter->tx_abs_int_delay, - E1000_REGISTER(&adapter->hw, E1000_TADV), + E1000_REGISTER(hw, E1000_TADV), em_tx_abs_int_delay_dflt); /* Sysctl for limiting the amount of work done in the taskqueue */ - em_add_rx_process_limit(adapter, "rx_processing_limit", + em_set_sysctl_value(adapter, "rx_processing_limit", "max number of rx packets to process", &adapter->rx_process_limit, em_rx_process_limit); /* Sysctl for setting the interface flow control */ - em_set_flow_cntrl(adapter, "flow_control", + em_set_sysctl_value(adapter, "flow_control", "configure flow control", &adapter->fc_setting, em_fc_setting); @@ -549,15 +553,15 @@ em_attach(device_t dev) } else adapter->num_rx_desc = em_rxd; - adapter->hw.mac.autoneg = DO_AUTO_NEG; - adapter->hw.phy.autoneg_wait_to_complete = FALSE; - adapter->hw.phy.autoneg_advertised = AUTONEG_ADV_DEFAULT; + hw->mac.autoneg = DO_AUTO_NEG; + hw->phy.autoneg_wait_to_complete = FALSE; + hw->phy.autoneg_advertised = AUTONEG_ADV_DEFAULT; /* Copper options */ - if (adapter->hw.phy.media_type == e1000_media_type_copper) { - adapter->hw.phy.mdix = AUTO_ALL_MODES; - adapter->hw.phy.disable_polarity_correction = FALSE; - adapter->hw.phy.ms_type = EM_MASTER_SLAVE; + if (hw->phy.media_type == e1000_media_type_copper) { + hw->phy.mdix = AUTO_ALL_MODES; + hw->phy.disable_polarity_correction = FALSE; + hw->phy.ms_type = EM_MASTER_SLAVE; } /* @@ -571,7 +575,7 @@ em_attach(device_t dev) * This controls when hardware reports transmit completion * status. */ - adapter->hw.mac.report_tx_early = 1; + hw->mac.report_tx_early = 1; /* ** Get queue/ring memory @@ -591,25 +595,31 @@ em_attach(device_t dev) } /* Check SOL/IDER usage */ - if (e1000_check_reset_block(&adapter->hw)) + if (e1000_check_reset_block(hw)) device_printf(dev, "PHY reset is blocked" " due to SOL/IDER session.\n"); + /* Sysctl for setting Energy Efficient Ethernet */ + em_set_sysctl_value(adapter, "eee_control", + "enable Energy Efficient Ethernet", + &hw->dev_spec.ich8lan.eee_disable, eee_setting); + /* ** Start from a known state, this is ** important in reading the nvm and ** mac from that. */ - e1000_reset_hw(&adapter->hw); + e1000_reset_hw(hw); + /* Make sure we have a good EEPROM before we read from it */ - if (e1000_validate_nvm_checksum(&adapter->hw) < 0) { + if (e1000_validate_nvm_checksum(hw) < 0) { /* ** Some PCI-E parts fail the first check due to ** the link being in sleep state, call it again, ** if it fails a second time its a real issue. */ - if (e1000_validate_nvm_checksum(&adapter->hw) < 0) { + if (e1000_validate_nvm_checksum(hw) < 0) { device_printf(dev, "The EEPROM Checksum Is Not Valid\n"); error = EIO; @@ -618,14 +628,14 @@ em_attach(device_t dev) } /* Copy the permanent MAC address out of the EEPROM */ - if (e1000_read_mac_addr(&adapter->hw) < 0) { + if (e1000_read_mac_addr(hw) < 0) { device_printf(dev, "EEPROM read error while reading MAC" " address\n"); error = EIO; goto err_late; } - if (!em_is_valid_ether_addr(adapter->hw.mac.addr)) { + if (!em_is_valid_ether_addr(hw->mac.addr)) { device_printf(dev, "Invalid MAC address\n"); error = EIO; goto err_late; @@ -655,7 +665,7 @@ em_attach(device_t dev) /* Initialize statistics */ em_update_stats_counters(adapter); - adapter->hw.mac.get_link_status = 1; + hw->mac.get_link_status = 1; em_update_link_status(adapter); /* Register for VLAN events */ @@ -927,11 +937,10 @@ em_start_locked(struct ifnet *ifp, struc if (!adapter->link_active) return; - /* Call cleanup if number of TX descriptors low */ - if (txr->tx_avail <= EM_TX_CLEANUP_THRESHOLD) - em_txeof(txr); - while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { + /* Call cleanup if number of TX descriptors low */ + if (txr->tx_avail <= EM_TX_CLEANUP_THRESHOLD) + em_txeof(txr); if (txr->tx_avail < EM_MAX_SCATTER) { ifp->if_drv_flags |= IFF_DRV_OACTIVE; break; @@ -1411,8 +1420,7 @@ em_poll(struct ifnet *ifp, enum poll_cmd if (!drbr_empty(ifp, txr->br)) em_mq_start_locked(ifp, txr, NULL); #else - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - em_start_locked(ifp, txr); + em_start_locked(ifp, txr); #endif EM_TX_UNLOCK(txr); @@ -1475,24 +1483,20 @@ em_handle_que(void *context, int pending struct ifnet *ifp = adapter->ifp; struct tx_ring *txr = adapter->tx_rings; struct rx_ring *rxr = adapter->rx_rings; - bool more; if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - more = em_rxeof(rxr, adapter->rx_process_limit, NULL); - + bool more = em_rxeof(rxr, adapter->rx_process_limit, NULL); EM_TX_LOCK(txr); em_txeof(txr); #ifdef EM_MULTIQUEUE if (!drbr_empty(ifp, txr->br)) em_mq_start_locked(ifp, txr, NULL); #else - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - em_start_locked(ifp, txr); + em_start_locked(ifp, txr); #endif - em_txeof(txr); EM_TX_UNLOCK(txr); - if (more) { + if (more || (ifp->if_drv_flags & IFF_DRV_OACTIVE)) { taskqueue_enqueue(adapter->tq, &adapter->que_task); return; } @@ -1601,10 +1605,8 @@ em_handle_tx(void *context, int pending) if (!drbr_empty(ifp, txr->br)) em_mq_start_locked(ifp, txr, NULL); #else - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - em_start_locked(ifp, txr); + em_start_locked(ifp, txr); #endif - em_txeof(txr); E1000_WRITE_REG(&adapter->hw, E1000_IMS, txr->ims); EM_TX_UNLOCK(txr); } @@ -2179,6 +2181,7 @@ em_local_timer(void *arg) struct adapter *adapter = arg; struct ifnet *ifp = adapter->ifp; struct tx_ring *txr = adapter->tx_rings; + struct rx_ring *rxr = adapter->rx_rings; EM_CORE_LOCK_ASSERT(adapter); @@ -2190,6 +2193,13 @@ em_local_timer(void *arg) e1000_get_laa_state_82571(&adapter->hw)) e1000_rar_set(&adapter->hw, adapter->hw.mac.addr, 0); + /* trigger tq to refill rx ring queue if it is empty */ + for (int i = 0; i < adapter->num_queues; i++, rxr++) { + if (rxr->next_to_check == rxr->next_to_refresh) { + taskqueue_enqueue(rxr->tq, &rxr->rx_task); + } + } + /* ** Don't do TX watchdog check if we've been paused */ @@ -3730,17 +3740,17 @@ em_txeof(struct tx_ring *txr) txr->queue_status = EM_QUEUE_HUNG; /* - * If we have enough room, clear IFF_DRV_OACTIVE + * If we have a minimum free, clear IFF_DRV_OACTIVE * to tell the stack that it is OK to send packets. */ - if (txr->tx_avail > EM_TX_CLEANUP_THRESHOLD) { + if (txr->tx_avail > EM_MAX_SCATTER) ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - /* Disable watchdog if all clean */ - if (txr->tx_avail == adapter->num_tx_desc) { - txr->queue_status = EM_QUEUE_IDLE; - return (FALSE); - } - } + + /* Disable watchdog if all clean */ + if (txr->tx_avail == adapter->num_tx_desc) { + txr->queue_status = EM_QUEUE_IDLE; + return (FALSE); + } return (TRUE); } @@ -3758,11 +3768,19 @@ em_refresh_mbufs(struct rx_ring *rxr, in struct mbuf *m; bus_dma_segment_t segs[1]; struct em_buffer *rxbuf; - int i, error, nsegs, cleaned; + int i, j, error, nsegs; + bool cleaned = FALSE; + + i = j = rxr->next_to_refresh; + /* + ** Get one descriptor beyond + ** our work mark to control + ** the loop. + */ + if (++j == adapter->num_rx_desc) + j = 0; - i = rxr->next_to_refresh; - cleaned = -1; - while (i != limit) { + while (j != limit) { rxbuf = &rxr->rx_buffers[i]; if (rxbuf->m_head == NULL) { m = m_getjcl(M_DONTWAIT, MT_DATA, @@ -3796,21 +3814,22 @@ em_refresh_mbufs(struct rx_ring *rxr, in bus_dmamap_sync(rxr->rxtag, rxbuf->map, BUS_DMASYNC_PREREAD); rxr->rx_base[i].buffer_addr = htole64(segs[0].ds_addr); + cleaned = TRUE; - cleaned = i; - /* Calculate next index */ - if (++i == adapter->num_rx_desc) - i = 0; + i = j; /* Next is precalulated for us */ rxr->next_to_refresh = i; + /* Calculate next controlling index */ + if (++j == adapter->num_rx_desc) + j = 0; } update: /* ** Update the tail pointer only if, ** and as far as we have refreshed. */ - if (cleaned != -1) /* Update tail index */ + if (cleaned) E1000_WRITE_REG(&adapter->hw, - E1000_RDT(rxr->me), cleaned); + E1000_RDT(rxr->me), rxr->next_to_refresh); return; } @@ -3888,36 +3907,32 @@ em_setup_receive_ring(struct rx_ring *rx struct adapter *adapter = rxr->adapter; struct em_buffer *rxbuf; bus_dma_segment_t seg[1]; - int rsize, nsegs, error; + int i, j, nsegs, error; /* Clear the ring contents */ EM_RX_LOCK(rxr); - rsize = roundup2(adapter->num_rx_desc * - sizeof(struct e1000_rx_desc), EM_DBA_ALIGN); - bzero((void *)rxr->rx_base, rsize); - /* - ** Free current RX buffer structs and their mbufs - */ - for (int i = 0; i < adapter->num_rx_desc; i++) { - rxbuf = &rxr->rx_buffers[i]; - if (rxbuf->m_head != NULL) { - bus_dmamap_sync(rxr->rxtag, rxbuf->map, - BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(rxr->rxtag, rxbuf->map); - m_freem(rxbuf->m_head); - } + /* Invalidate all descriptors */ + for (i = 0; i < adapter->num_rx_desc; i++) { + struct e1000_rx_desc* cur; + cur = &rxr->rx_base[i]; + cur->status = 0; } /* Now replenish the mbufs */ - for (int j = 0; j != adapter->num_rx_desc; ++j) { + i = j = rxr->next_to_refresh; + if (++j == adapter->num_rx_desc) + j = 0; - rxbuf = &rxr->rx_buffers[j]; + while(j != rxr->next_to_check) { + rxbuf = &rxr->rx_buffers[i]; rxbuf->m_head = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, adapter->rx_mbuf_sz); - if (rxbuf->m_head == NULL) - return (ENOBUFS); + if (rxbuf->m_head == NULL) { + error = ENOBUFS; + goto fail; + } rxbuf->m_head->m_len = adapter->rx_mbuf_sz; rxbuf->m_head->m_flags &= ~M_HASFCS; /* we strip it */ rxbuf->m_head->m_pkthdr.len = adapter->rx_mbuf_sz; @@ -3929,25 +3944,24 @@ em_setup_receive_ring(struct rx_ring *rx if (error != 0) { m_freem(rxbuf->m_head); rxbuf->m_head = NULL; - return (error); + goto fail; } bus_dmamap_sync(rxr->rxtag, rxbuf->map, BUS_DMASYNC_PREREAD); /* Update descriptor */ - rxr->rx_base[j].buffer_addr = htole64(seg[0].ds_addr); + rxr->rx_base[i].buffer_addr = htole64(seg[0].ds_addr); + i = j; + if (++j == adapter->num_rx_desc) + j = 0; } - - /* Setup our descriptor indices */ - rxr->next_to_check = 0; - rxr->next_to_refresh = 0; - +fail: + rxr->next_to_refresh = i; bus_dmamap_sync(rxr->rxdma.dma_tag, rxr->rxdma.dma_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); - EM_RX_UNLOCK(rxr); - return (0); + return (error); } /********************************************************************* @@ -3959,9 +3973,9 @@ static int em_setup_receive_structures(struct adapter *adapter) { struct rx_ring *rxr = adapter->rx_rings; - int j; + int q; - for (j = 0; j < adapter->num_queues; j++, rxr++) + for (q = 0; q < adapter->num_queues; q++, rxr++) if (em_setup_receive_ring(rxr)) goto fail; @@ -3970,11 +3984,12 @@ fail: /* * Free RX buffers allocated so far, we will only handle * the rings that completed, the failing case will have - * cleaned up for itself. 'j' failed, so its the terminus. + * cleaned up for itself. 'q' failed, so its the terminus. */ - for (int i = 0; i < j; ++i) { + for (int i = 0, n = 0; i < q; ++i) { rxr = &adapter->rx_rings[i]; - for (int n = 0; n < adapter->num_rx_desc; n++) { + n = rxr->next_to_check; + while(n != rxr->next_to_refresh) { struct em_buffer *rxbuf; rxbuf = &rxr->rx_buffers[n]; if (rxbuf->m_head != NULL) { @@ -3984,7 +3999,11 @@ fail: m_freem(rxbuf->m_head); rxbuf->m_head = NULL; } + if (++n == adapter->num_rx_desc) + n = 0; } + rxr->next_to_check = 0; + rxr->next_to_refresh = 0; } return (ENOBUFS); @@ -4025,7 +4044,8 @@ em_free_receive_buffers(struct rx_ring * INIT_DEBUGOUT("free_receive_buffers: begin"); if (rxr->rx_buffers != NULL) { - for (int i = 0; i < adapter->num_rx_desc; i++) { + int i = rxr->next_to_check; + while(i != rxr->next_to_refresh) { rxbuf = &rxr->rx_buffers[i]; if (rxbuf->map != NULL) { bus_dmamap_sync(rxr->rxtag, rxbuf->map, @@ -4037,9 +4057,13 @@ em_free_receive_buffers(struct rx_ring * m_freem(rxbuf->m_head); rxbuf->m_head = NULL; } + if (++i == adapter->num_rx_desc) + i = 0; } free(rxr->rx_buffers, M_DEVBUF); rxr->rx_buffers = NULL; + rxr->next_to_check = 0; + rxr->next_to_refresh = 0; } if (rxr->rxtag != NULL) { @@ -4122,8 +4146,8 @@ em_initialize_receive_unit(struct adapte E1000_WRITE_REG(hw, E1000_RDBAH(i), (u32)(bus_addr >> 32)); E1000_WRITE_REG(hw, E1000_RDBAL(i), (u32)bus_addr); /* Setup the Head and Tail Descriptor Pointers */ - E1000_WRITE_REG(hw, E1000_RDH(i), 0); - E1000_WRITE_REG(hw, E1000_RDT(i), adapter->num_rx_desc - 1); + E1000_WRITE_REG(hw, E1000_RDH(i), rxr->next_to_check); + E1000_WRITE_REG(hw, E1000_RDT(i), rxr->next_to_refresh); } /* Set early receive threshold on appropriate hw */ @@ -4303,7 +4327,8 @@ next_desc: } /* Catch any remaining refresh work */ - em_refresh_mbufs(rxr, i); + if (processed != 0 || i == rxr->next_to_refresh) + em_refresh_mbufs(rxr, i); rxr->next_to_check = i; if (done != NULL) @@ -4743,10 +4768,8 @@ em_enable_wakeup(device_t dev) if ((adapter->hw.mac.type == e1000_ich8lan) || (adapter->hw.mac.type == e1000_pchlan) || (adapter->hw.mac.type == e1000_ich9lan) || - (adapter->hw.mac.type == e1000_ich10lan)) { + (adapter->hw.mac.type == e1000_ich10lan)) e1000_disable_gig_wol_ich8lan(&adapter->hw); - e1000_hv_phy_powerdown_workaround_ich8lan(&adapter->hw); - } /* Keep the laser running on Fiber adapters */ if (adapter->hw.phy.media_type == e1000_media_type_fiber || @@ -5442,17 +5465,7 @@ em_add_int_delay_sysctl(struct adapter * } static void -em_add_rx_process_limit(struct adapter *adapter, const char *name, - const char *description, int *limit, int value) -{ - *limit = value; - SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), - OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description); -} - -static void -em_set_flow_cntrl(struct adapter *adapter, const char *name, +em_set_sysctl_value(struct adapter *adapter, const char *name, const char *description, int *limit, int value) { *limit = value; Modified: projects/altix/sys/dev/e1000/if_em.h ============================================================================== --- projects/altix/sys/dev/e1000/if_em.h Fri Mar 18 22:56:53 2011 (r219760) +++ projects/altix/sys/dev/e1000/if_em.h Fri Mar 18 23:48:06 2011 (r219761) @@ -212,6 +212,10 @@ #define EM_BAR_MEM_TYPE_64BIT 0x00000004 #define EM_MSIX_BAR 3 /* On 82575 */ +#if !defined(SYSTCL_ADD_UQUAD) +#define SYSCTL_ADD_UQUAD SYSCTL_ADD_QUAD +#endif + /* Defines for printing debug information */ #define DEBUG_INIT 0 #define DEBUG_IOCTL 0 Modified: projects/altix/sys/dev/e1000/if_igb.c ============================================================================== --- projects/altix/sys/dev/e1000/if_igb.c Fri Mar 18 22:56:53 2011 (r219760) +++ projects/altix/sys/dev/e1000/if_igb.c Fri Mar 18 23:48:06 2011 (r219761) @@ -1,6 +1,6 @@ /****************************************************************************** - Copyright (c) 2001-2011, Intel Corporation + Copyright (c) 2001-2010, Intel Corporation All rights reserved. Redistribution and use in source and binary forms, with or without @@ -99,7 +99,7 @@ int igb_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char igb_driver_version[] = "version - 2.1.4"; +char igb_driver_version[] = "version - 2.1.7"; /********************************************************************* @@ -255,14 +255,13 @@ static void igb_enable_wakeup(device static void igb_led_func(void *, int); static int igb_irq_fast(void *); -static void igb_add_rx_process_limit(struct adapter *, const char *, - const char *, int *, int); +static void igb_msix_que(void *); +static void igb_msix_link(void *); static void igb_handle_que(void *context, int pending); static void igb_handle_link(void *context, int pending); -/* These are MSIX only irq handlers */ -static void igb_msix_que(void *); -static void igb_msix_link(void *); +static void igb_set_sysctl_value(struct adapter *, const char *, + const char *, int *, int); #ifdef DEVICE_POLLING static poll_handler_t igb_poll; @@ -350,6 +349,17 @@ TUNABLE_INT("hw.igb.rx_process_limit", & static int igb_fc_setting = e1000_fc_full; TUNABLE_INT("hw.igb.fc_setting", &igb_fc_setting); +/* Energy Efficient Ethernet - default to off */ +static int igb_eee_setting = FALSE; +TUNABLE_INT("hw.igb.ee_setting", &igb_eee_setting); + +/* +** DMA Coalescing, only for i350 - default to off, +** this feature is for power savings +*/ +static int igb_dma_coalesce = FALSE; +TUNABLE_INT("hw.igb.dma_coalesce", &igb_dma_coalesce); + /********************************************************************* * Device identification routine * @@ -430,11 +440,6 @@ igb_attach(device_t dev) OID_AUTO, "nvm", CTLTYPE_INT|CTLFLAG_RW, adapter, 0, igb_sysctl_nvm_info, "I", "NVM Information"); - SYSCTL_ADD_INT(device_get_sysctl_ctx(adapter->dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(adapter->dev)), - OID_AUTO, "flow_control", CTLTYPE_INT|CTLFLAG_RW, - &igb_fc_setting, 0, "Flow Control"); - SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "enable_aim", CTLTYPE_INT|CTLFLAG_RW, @@ -461,11 +466,16 @@ igb_attach(device_t dev) e1000_get_bus_info(&adapter->hw); - /* Sysctls for limiting the amount of work done in the taskqueue */ - igb_add_rx_process_limit(adapter, "rx_processing_limit", + /* Sysctl for limiting the amount of work done in the taskqueue */ + igb_set_sysctl_value(adapter, "rx_processing_limit", "max number of rx packets to process", &adapter->rx_process_limit, igb_rx_process_limit); + /* Sysctl for setting the interface flow control */ + igb_set_sysctl_value(adapter, "flow_control", + "configure flow control", + &adapter->fc_setting, igb_fc_setting); + /* * Validate number of transmit and receive descriptors. It * must not exceed hardware maximum, and must be multiple @@ -537,6 +547,18 @@ igb_attach(device_t dev) goto err_late; } + /* Some adapter-specific advanced features */ + if (adapter->hw.mac.type >= e1000_i350) { + igb_set_sysctl_value(adapter, "dma_coalesce", + "configure dma coalesce", + &adapter->dma_coalesce, igb_dma_coalesce); + igb_set_sysctl_value(adapter, "eee_control", + "enable Energy Efficient Ethernet", + &adapter->hw.dev_spec._82575.eee_disable, + igb_eee_setting); + e1000_set_eee_i350(&adapter->hw); + } + /* ** Start from a known state, this is ** important in reading the nvm and @@ -1436,6 +1458,10 @@ igb_msix_que(void *arg) more_tx = igb_txeof(txr); IGB_TX_UNLOCK(txr); + /* If RX ring is depleted do refresh first */ + if (rxr->next_to_check == rxr->next_to_refresh) + igb_refresh_mbufs(rxr, rxr->next_to_check); + more_rx = igb_rxeof(que, adapter->rx_process_limit, NULL); if (igb_enable_aim == FALSE) @@ -1938,7 +1964,7 @@ igb_local_timer(void *arg) out: callout_reset(&adapter->timer, hz, igb_local_timer, adapter); #ifndef DEVICE_POLLING - /* Fire off all queue interrupts - deadlock protection */ + /* Schedule all queue interrupts - deadlock protection */ E1000_WRITE_REG(&adapter->hw, E1000_EICS, adapter->que_mask); #endif return; @@ -1963,7 +1989,9 @@ igb_update_link_status(struct adapter *a struct ifnet *ifp = adapter->ifp; device_t dev = adapter->dev; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***