diff options
author | jfv <jfv@FreeBSD.org> | 2008-11-26 23:57:23 +0000 |
---|---|---|
committer | jfv <jfv@FreeBSD.org> | 2008-11-26 23:57:23 +0000 |
commit | acf860ad541ce9529aff0bf17061183badd98903 (patch) | |
tree | b0f0b3a2e29a0fc9f60b8bee9111f6827eb01416 /sys/dev/e1000/e1000_82541.c | |
parent | 62188214bdac09b8b3fe223bd994d8aef28db6db (diff) | |
download | FreeBSD-src-acf860ad541ce9529aff0bf17061183badd98903.zip FreeBSD-src-acf860ad541ce9529aff0bf17061183badd98903.tar.gz |
This delta is primarily a fix for es2lan devices that
will sometimes fail to initialize problem due to a lock
contention with management hardware. However, in order to
deliver that fix it was necessary to take a shared code
update as a whole, and this required scattered changes in
the core code to be compatible.
The em driver now has VLAN HW support added as the igb
driver had previously.
MFC after: ASAP - in time for 7.1 RELEASE
Diffstat (limited to 'sys/dev/e1000/e1000_82541.c')
-rw-r--r-- | sys/dev/e1000/e1000_82541.c | 145 |
1 files changed, 49 insertions, 96 deletions
diff --git a/sys/dev/e1000/e1000_82541.c b/sys/dev/e1000/e1000_82541.c index 81e68cf..03d1103 100644 --- a/sys/dev/e1000/e1000_82541.c +++ b/sys/dev/e1000/e1000_82541.c @@ -32,10 +32,13 @@ ******************************************************************************/ /*$FreeBSD$*/ -/* e1000_82541 - * e1000_82547 - * e1000_82541_rev_2 - * e1000_82547_rev_2 +/* + * 82541EI Gigabit Ethernet Controller + * 82541ER Gigabit Ethernet Controller + * 82541GI Gigabit Ethernet Controller + * 82541PI Gigabit Ethernet Controller + * 82547EI Gigabit Ethernet Controller + * 82547GI Gigabit Ethernet Controller */ #include "e1000_api.h" @@ -74,18 +77,9 @@ static const u16 e1000_igp_cable_length_table[] = (sizeof(e1000_igp_cable_length_table) / \ sizeof(e1000_igp_cable_length_table[0])) -struct e1000_dev_spec_82541 { - enum e1000_dsp_config dsp_config; - enum e1000_ffe_config ffe_config; - u16 spd_default; - bool phy_init_script; -}; - /** * e1000_init_phy_params_82541 - Init PHY func ptrs. * @hw: pointer to the HW structure - * - * This is a function pointer entry point called by the api module. **/ static s32 e1000_init_phy_params_82541(struct e1000_hw *hw) { @@ -129,8 +123,6 @@ out: /** * e1000_init_nvm_params_82541 - Init NVM func ptrs. * @hw: pointer to the HW structure - * - * This is a function pointer entry point called by the api module. **/ static s32 e1000_init_nvm_params_82541(struct e1000_hw *hw) { @@ -227,13 +219,10 @@ out: /** * e1000_init_mac_params_82541 - Init MAC func ptrs. * @hw: pointer to the HW structure - * - * This is a function pointer entry point called by the api module. **/ static s32 e1000_init_mac_params_82541(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; - s32 ret_val; DEBUGFUNC("e1000_init_mac_params_82541"); @@ -250,6 +239,8 @@ static s32 e1000_init_mac_params_82541(struct e1000_hw *hw) /* bus type/speed/width */ mac->ops.get_bus_info = e1000_get_bus_info_pci_generic; + /* function id */ + mac->ops.set_lan_id = e1000_set_lan_id_single_port; /* reset */ mac->ops.reset_hw = e1000_reset_hw_82541; /* hw initialization */ @@ -277,25 +268,17 @@ static s32 e1000_init_mac_params_82541(struct e1000_hw *hw) /* turn on/off LED */ mac->ops.led_on = e1000_led_on_generic; mac->ops.led_off = e1000_led_off_generic; - /* remove device */ - mac->ops.remove_device = e1000_remove_device_generic; /* clear hardware counters */ mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82541; - hw->dev_spec_size = sizeof(struct e1000_dev_spec_82541); - - /* Device-specific structure allocation */ - ret_val = e1000_alloc_zeroed_dev_spec_struct(hw, hw->dev_spec_size); - - return ret_val; + return E1000_SUCCESS; } /** * e1000_init_function_pointers_82541 - Init func ptrs. * @hw: pointer to the HW structure * - * The only function explicitly called by the api module to initialize - * all function pointers and parameters. + * Called to initialize all function pointers and parameters. **/ void e1000_init_function_pointers_82541(struct e1000_hw *hw) { @@ -310,8 +293,7 @@ void e1000_init_function_pointers_82541(struct e1000_hw *hw) * e1000_reset_hw_82541 - Reset hardware * @hw: pointer to the HW structure * - * This resets the hardware into a known state. This is a - * function pointer entry point called by the api module. + * This resets the hardware into a known state. **/ static s32 e1000_reset_hw_82541(struct e1000_hw *hw) { @@ -388,8 +370,7 @@ static s32 e1000_reset_hw_82541(struct e1000_hw *hw) * e1000_init_hw_82541 - Initialize hardware * @hw: pointer to the HW structure * - * This inits the hardware readying it for operation. This is a - * function pointer entry point called by the api module. + * This inits the hardware readying it for operation. **/ static s32 e1000_init_hw_82541(struct e1000_hw *hw) { @@ -452,7 +433,6 @@ static s32 e1000_init_hw_82541(struct e1000_hw *hw) * @duplex: pointer to duplex buffer * * Retrieve the current speed and duplex configuration. - * This is a function pointer entry point called by the api module. **/ static s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed, u16 *duplex) @@ -508,7 +488,6 @@ out: * semaphore (if necessary) and read/set/write the device control reset * bit in the PHY. Wait the appropriate delay time for the device to * reset and release the semaphore (if necessary). - * This is a function pointer entry point called by the api module. **/ static s32 e1000_phy_hw_reset_82541(struct e1000_hw *hw) { @@ -542,13 +521,12 @@ out: * Calls the appropriate function to configure the link for auto-neg or forced * speed and duplex. Then we check for link, once link is established calls * to configure collision distance and flow control are called. If link is - * not established, we return -E1000_ERR_PHY (-2). This is a function - * pointer entry point called by the api module. + * not established, we return -E1000_ERR_PHY (-2). **/ static s32 e1000_setup_copper_link_82541(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - struct e1000_dev_spec_82541 *dev_spec; + struct e1000_dev_spec_82541 *dev_spec = &hw->dev_spec._82541; s32 ret_val; u32 ctrl, ledctl; @@ -561,8 +539,6 @@ static s32 e1000_setup_copper_link_82541(struct e1000_hw *hw) hw->phy.reset_disable = FALSE; - dev_spec = (struct e1000_dev_spec_82541 *)hw->dev_spec; - /* Earlier revs of the IGP phy require us to force MDI. */ if (hw->mac.type == e1000_82541 || hw->mac.type == e1000_82547) { dev_spec->dsp_config = e1000_dsp_config_disabled; @@ -597,8 +573,7 @@ out: * @hw: pointer to the HW structure * * This checks the link condition of the adapter and stores the - * results in the hw->mac structure. This is a function pointer entry - * point called by the api module. + * results in the hw->mac structure. **/ static s32 e1000_check_for_link_82541(struct e1000_hw *hw) { @@ -684,13 +659,12 @@ out: * * 82541_rev_2 & 82547_rev_2 have the capability to configure the DSP when a * gigabit link is achieved to improve link quality. - * This is a function pointer entry point called by the api module. **/ static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, bool link_up) { struct e1000_phy_info *phy = &hw->phy; - struct e1000_dev_spec_82541 *dev_spec; + struct e1000_dev_spec_82541 *dev_spec = &hw->dev_spec._82541; s32 ret_val; u32 idle_errs = 0; u16 phy_data, phy_saved_data, speed, duplex, i; @@ -703,8 +677,6 @@ static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, DEBUGFUNC("e1000_config_dsp_after_link_change_82541"); - dev_spec = (struct e1000_dev_spec_82541 *)hw->dev_spec; - if (link_up) { ret_val = hw->mac.ops.get_link_up_info(hw, &speed, &duplex); if (ret_val) { @@ -898,8 +870,7 @@ out: * cable. By reading the AGC registers, which represent the * combination of coarse and fine gain value, the value can be put * into a lookup table to obtain the approximate cable length - * for each channel. This is a function pointer entry point called by the - * api module. + * for each channel. **/ static s32 e1000_get_cable_length_igp_82541(struct e1000_hw *hw) { @@ -973,8 +944,7 @@ out: * and enable Smartspeed. LPLU and Smartspeed are mutually exclusive. LPLU * is used during Dx states where the power conservation is most important. * During driver activity, SmartSpeed should be enabled so performance is - * maintained. This is a function pointer entry point called by the - * api module. + * maintained. **/ static s32 e1000_set_d3_lplu_state_82541(struct e1000_hw *hw, bool active) { @@ -1067,18 +1037,15 @@ out: * @hw: pointer to the HW structure * * This prepares the SW controllable LED for use and saves the current state - * of the LED so it can be later restored. This is a function pointer entry - * point called by the api module. + * of the LED so it can be later restored. **/ static s32 e1000_setup_led_82541(struct e1000_hw *hw) { - struct e1000_dev_spec_82541 *dev_spec; + struct e1000_dev_spec_82541 *dev_spec = &hw->dev_spec._82541; s32 ret_val; DEBUGFUNC("e1000_setup_led_82541"); - dev_spec = (struct e1000_dev_spec_82541 *)hw->dev_spec; - ret_val = hw->phy.ops.read_reg(hw, IGP01E1000_GMII_FIFO, &dev_spec->spd_default); @@ -1103,18 +1070,15 @@ out: * @hw: pointer to the HW structure * * Remove the current LED configuration and set the LED configuration - * to the default value, saved from the EEPROM. This is a function pointer - * entry point called by the api module. + * to the default value, saved from the EEPROM. **/ static s32 e1000_cleanup_led_82541(struct e1000_hw *hw) { - struct e1000_dev_spec_82541 *dev_spec; + struct e1000_dev_spec_82541 *dev_spec = &hw->dev_spec._82541; s32 ret_val; DEBUGFUNC("e1000_cleanup_led_82541"); - dev_spec = (struct e1000_dev_spec_82541 *)hw->dev_spec; - ret_val = hw->phy.ops.write_reg(hw, IGP01E1000_GMII_FIFO, dev_spec->spd_default); @@ -1135,14 +1099,12 @@ out: **/ static s32 e1000_phy_init_script_82541(struct e1000_hw *hw) { - struct e1000_dev_spec_82541 *dev_spec; + struct e1000_dev_spec_82541 *dev_spec = &hw->dev_spec._82541; u32 ret_val; u16 phy_saved_data; DEBUGFUNC("e1000_phy_init_script_82541"); - dev_spec = (struct e1000_dev_spec_82541 *)hw->dev_spec; - if (!dev_spec->phy_init_script) { ret_val = E1000_SUCCESS; goto out; @@ -1248,11 +1210,11 @@ out: * @state: boolean value used to enable/disable PHY init script * * Allows the driver to enable/disable the PHY init script, if the PHY is an - * IGP PHY. This is a function pointer entry point called by the api module. + * IGP PHY. **/ void e1000_init_script_state_82541(struct e1000_hw *hw, bool state) { - struct e1000_dev_spec_82541 *dev_spec; + struct e1000_dev_spec_82541 *dev_spec = &hw->dev_spec._82541; DEBUGFUNC("e1000_init_script_state_82541"); @@ -1261,13 +1223,6 @@ void e1000_init_script_state_82541(struct e1000_hw *hw, bool state) goto out; } - dev_spec = (struct e1000_dev_spec_82541 *)hw->dev_spec; - - if (!dev_spec) { - DEBUGOUT("dev_spec pointer is set to NULL.\n"); - goto out; - } - dev_spec->phy_init_script = state; out: @@ -1298,33 +1253,31 @@ static void e1000_power_down_phy_copper_82541(struct e1000_hw *hw) **/ static void e1000_clear_hw_cntrs_82541(struct e1000_hw *hw) { - volatile u32 temp; - DEBUGFUNC("e1000_clear_hw_cntrs_82541"); e1000_clear_hw_cntrs_base_generic(hw); - temp = E1000_READ_REG(hw, E1000_PRC64); - temp = E1000_READ_REG(hw, E1000_PRC127); - temp = E1000_READ_REG(hw, E1000_PRC255); - temp = E1000_READ_REG(hw, E1000_PRC511); - temp = E1000_READ_REG(hw, E1000_PRC1023); - temp = E1000_READ_REG(hw, E1000_PRC1522); - temp = E1000_READ_REG(hw, E1000_PTC64); - temp = E1000_READ_REG(hw, E1000_PTC127); - temp = E1000_READ_REG(hw, E1000_PTC255); - temp = E1000_READ_REG(hw, E1000_PTC511); - temp = E1000_READ_REG(hw, E1000_PTC1023); - temp = E1000_READ_REG(hw, E1000_PTC1522); - - temp = E1000_READ_REG(hw, E1000_ALGNERRC); - temp = E1000_READ_REG(hw, E1000_RXERRC); - temp = E1000_READ_REG(hw, E1000_TNCRS); - temp = E1000_READ_REG(hw, E1000_CEXTERR); - temp = E1000_READ_REG(hw, E1000_TSCTC); - temp = E1000_READ_REG(hw, E1000_TSCTFC); - - temp = E1000_READ_REG(hw, E1000_MGTPRC); - temp = E1000_READ_REG(hw, E1000_MGTPDC); - temp = E1000_READ_REG(hw, E1000_MGTPTC); + E1000_READ_REG(hw, E1000_PRC64); + E1000_READ_REG(hw, E1000_PRC127); + E1000_READ_REG(hw, E1000_PRC255); + E1000_READ_REG(hw, E1000_PRC511); + E1000_READ_REG(hw, E1000_PRC1023); + E1000_READ_REG(hw, E1000_PRC1522); + E1000_READ_REG(hw, E1000_PTC64); + E1000_READ_REG(hw, E1000_PTC127); + E1000_READ_REG(hw, E1000_PTC255); + E1000_READ_REG(hw, E1000_PTC511); + E1000_READ_REG(hw, E1000_PTC1023); + E1000_READ_REG(hw, E1000_PTC1522); + + E1000_READ_REG(hw, E1000_ALGNERRC); + E1000_READ_REG(hw, E1000_RXERRC); + E1000_READ_REG(hw, E1000_TNCRS); + E1000_READ_REG(hw, E1000_CEXTERR); + E1000_READ_REG(hw, E1000_TSCTC); + E1000_READ_REG(hw, E1000_TSCTFC); + + E1000_READ_REG(hw, E1000_MGTPRC); + E1000_READ_REG(hw, E1000_MGTPDC); + E1000_READ_REG(hw, E1000_MGTPTC); } |