svn commit: r219761 - in projects/altix/sys: dev/e1000 ia64/ia64
kern
Marcel Moolenaar
marcel at FreeBSD.org
Fri Mar 18 23:48:06 UTC 2011
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 ***
More information about the svn-src-projects
mailing list