diff options
Diffstat (limited to 'sys')
30 files changed, 2097 insertions, 1989 deletions
diff --git a/sys/conf/files b/sys/conf/files index acc024c..b010b35 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -625,17 +625,19 @@ dev/em/e1000_82543.c optional em \ compile-with "${NORMAL_C} -I$S/dev/em" dev/em/e1000_82571.c optional em \ compile-with "${NORMAL_C} -I$S/dev/em" -dev/em/e1000_api.c optional em \ +dev/em/e1000_api.c optional em igb \ compile-with "${NORMAL_C} -I$S/dev/em" -dev/em/e1000_ich8lan.c optional em \ +dev/em/e1000_ich8lan.c optional em igb \ compile-with "${NORMAL_C} -I$S/dev/em" -dev/em/e1000_mac.c optional em \ +dev/em/e1000_mac.c optional em igb \ compile-with "${NORMAL_C} -I$S/dev/em" -dev/em/e1000_manage.c optional em \ +dev/em/e1000_manage.c optional em igb \ compile-with "${NORMAL_C} -I$S/dev/em" -dev/em/e1000_nvm.c optional em \ +dev/em/e1000_nvm.c optional em igb \ compile-with "${NORMAL_C} -I$S/dev/em" -dev/em/e1000_phy.c optional em \ +dev/em/e1000_phy.c optional em igb \ + compile-with "${NORMAL_C} -I$S/dev/em" +dev/em/e1000_osdep.c optional em igb \ compile-with "${NORMAL_C} -I$S/dev/em" dev/en/if_en_pci.c optional en pci dev/en/midway.c optional en @@ -713,16 +715,6 @@ dev/igb/if_igb.c optional igb \ compile-with "${NORMAL_C} -I$S/dev/igb" dev/igb/e1000_82575.c optional igb \ compile-with "${NORMAL_C} -I$S/dev/igb" -dev/igb/e1000_api.c optional igb \ - compile-with "${NORMAL_C} -I$S/dev/igb" -dev/igb/e1000_mac.c optional igb \ - compile-with "${NORMAL_C} -I$S/dev/igb" -dev/igb/e1000_manage.c optional igb \ - compile-with "${NORMAL_C} -I$S/dev/igb" -dev/igb/e1000_nvm.c optional igb \ - compile-with "${NORMAL_C} -I$S/dev/igb" -dev/igb/e1000_phy.c optional igb \ - compile-with "${NORMAL_C} -I$S/dev/igb" dev/iicbus/ad7418.c optional ad7418 dev/iicbus/ds1672.c optional ds1672 dev/iicbus/icee.c optional icee diff --git a/sys/dev/em/e1000_80003es2lan.c b/sys/dev/em/e1000_80003es2lan.c index c0159da..a17b861 100644 --- a/sys/dev/em/e1000_80003es2lan.c +++ b/sys/dev/em/e1000_80003es2lan.c @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,9 +29,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ /* e1000_80003es2lan */ @@ -39,38 +38,38 @@ #include "e1000_api.h" #include "e1000_80003es2lan.h" -STATIC s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw); -STATIC s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw); -STATIC s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw); -STATIC s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw); -STATIC void e1000_release_phy_80003es2lan(struct e1000_hw *hw); -STATIC s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw); -STATIC void e1000_release_nvm_80003es2lan(struct e1000_hw *hw); -STATIC s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, +static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw); +static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw); +static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw); +static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw); +static void e1000_release_phy_80003es2lan(struct e1000_hw *hw); +static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw); +static void e1000_release_nvm_80003es2lan(struct e1000_hw *hw); +static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, u32 offset, u16 *data); -STATIC s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, +static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, u32 offset, u16 data); -STATIC s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, +static s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); -STATIC s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw); -STATIC s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw); -STATIC s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw); -STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, +static s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw); +static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw); +static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw); +static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, u16 *duplex); -STATIC s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw); -STATIC s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw); -STATIC s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw); -STATIC void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw); +static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw); +static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw); +static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw); +static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw); static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex); static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw); static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw); static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw); static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask); -STATIC s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw); -STATIC void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw); +static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw); +static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw); /* * A table for the GG82563 cable length where the range is defined @@ -89,10 +88,9 @@ static const u16 e1000_gg82563_cable_length_table[] = * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) +static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_init_phy_params_80003es2lan"); @@ -101,8 +99,8 @@ STATIC s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) phy->type = e1000_phy_none; goto out; } else { - func->power_up_phy = e1000_power_up_phy_copper; - func->power_down_phy = e1000_power_down_phy_copper_80003es2lan; + phy->ops.power_up = e1000_power_up_phy_copper; + phy->ops.power_down = e1000_power_down_phy_copper_80003es2lan; } phy->addr = 1; @@ -110,20 +108,20 @@ STATIC s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) phy->reset_delay_us = 100; phy->type = e1000_phy_gg82563; - func->acquire_phy = e1000_acquire_phy_80003es2lan; - func->check_polarity = e1000_check_polarity_m88; - func->check_reset_block = e1000_check_reset_block_generic; - func->commit_phy = e1000_phy_sw_reset_generic; - func->get_cfg_done = e1000_get_cfg_done_80003es2lan; - func->get_phy_info = e1000_get_phy_info_m88; - func->release_phy = e1000_release_phy_80003es2lan; - func->reset_phy = e1000_phy_hw_reset_generic; - func->set_d3_lplu_state = e1000_set_d3_lplu_state_generic; - - func->force_speed_duplex = e1000_phy_force_speed_duplex_80003es2lan; - func->get_cable_length = e1000_get_cable_length_80003es2lan; - func->read_phy_reg = e1000_read_phy_reg_gg82563_80003es2lan; - func->write_phy_reg = e1000_write_phy_reg_gg82563_80003es2lan; + phy->ops.acquire = e1000_acquire_phy_80003es2lan; + phy->ops.check_polarity = e1000_check_polarity_m88; + phy->ops.check_reset_block = e1000_check_reset_block_generic; + phy->ops.commit = e1000_phy_sw_reset_generic; + phy->ops.get_cfg_done = e1000_get_cfg_done_80003es2lan; + phy->ops.get_info = e1000_get_phy_info_m88; + phy->ops.release = e1000_release_phy_80003es2lan; + phy->ops.reset = e1000_phy_hw_reset_generic; + phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic; + + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_80003es2lan; + phy->ops.get_cable_length = e1000_get_cable_length_80003es2lan; + phy->ops.read_reg = e1000_read_phy_reg_gg82563_80003es2lan; + phy->ops.write_reg = e1000_write_phy_reg_gg82563_80003es2lan; /* This can only be done after all function pointers are setup. */ ret_val = e1000_get_phy_id(hw); @@ -144,10 +142,9 @@ out: * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) +static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; - struct e1000_functions *func = &hw->func; u32 eecd = E1000_READ_REG(hw, E1000_EECD); u16 size; @@ -187,13 +184,13 @@ STATIC s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) nvm->word_size = 1 << size; /* Function Pointers */ - func->acquire_nvm = e1000_acquire_nvm_80003es2lan; - func->read_nvm = e1000_read_nvm_eerd; - func->release_nvm = e1000_release_nvm_80003es2lan; - func->update_nvm = e1000_update_nvm_checksum_generic; - func->valid_led_default = e1000_valid_led_default_generic; - func->validate_nvm = e1000_validate_nvm_checksum_generic; - func->write_nvm = e1000_write_nvm_80003es2lan; + nvm->ops.acquire = e1000_acquire_nvm_80003es2lan; + nvm->ops.read = e1000_read_nvm_eerd; + nvm->ops.release = e1000_release_nvm_80003es2lan; + nvm->ops.update = e1000_update_nvm_checksum_generic; + nvm->ops.valid_led_default = e1000_valid_led_default_generic; + nvm->ops.validate = e1000_validate_nvm_checksum_generic; + nvm->ops.write = e1000_write_nvm_80003es2lan; return E1000_SUCCESS; } @@ -204,10 +201,9 @@ STATIC s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw) * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) +static s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; - struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_init_mac_params_80003es2lan"); @@ -236,28 +232,28 @@ STATIC s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) /* Function pointers */ /* bus type/speed/width */ - func->get_bus_info = e1000_get_bus_info_pcie_generic; + mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic; /* reset */ - func->reset_hw = e1000_reset_hw_80003es2lan; + mac->ops.reset_hw = e1000_reset_hw_80003es2lan; /* hw initialization */ - func->init_hw = e1000_init_hw_80003es2lan; + mac->ops.init_hw = e1000_init_hw_80003es2lan; /* link setup */ - func->setup_link = e1000_setup_link_generic; + mac->ops.setup_link = e1000_setup_link_generic; /* physical interface link setup */ - func->setup_physical_interface = + mac->ops.setup_physical_interface = (hw->phy.media_type == e1000_media_type_copper) ? e1000_setup_copper_link_80003es2lan : e1000_setup_fiber_serdes_link_generic; /* check for link */ switch (hw->phy.media_type) { case e1000_media_type_copper: - func->check_for_link = e1000_check_for_copper_link_generic; + mac->ops.check_for_link = e1000_check_for_copper_link_generic; break; case e1000_media_type_fiber: - func->check_for_link = e1000_check_for_fiber_link_generic; + mac->ops.check_for_link = e1000_check_for_fiber_link_generic; break; case e1000_media_type_internal_serdes: - func->check_for_link = e1000_check_for_serdes_link_generic; + mac->ops.check_for_link = e1000_check_for_serdes_link_generic; break; default: ret_val = -E1000_ERR_CONFIG; @@ -265,32 +261,32 @@ STATIC s32 e1000_init_mac_params_80003es2lan(struct e1000_hw *hw) break; } /* check management mode */ - func->check_mng_mode = e1000_check_mng_mode_generic; + mac->ops.check_mng_mode = e1000_check_mng_mode_generic; /* multicast address update */ - func->update_mc_addr_list = e1000_update_mc_addr_list_generic; + mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; /* writing VFTA */ - func->write_vfta = e1000_write_vfta_generic; + mac->ops.write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ - func->clear_vfta = e1000_clear_vfta_generic; + mac->ops.clear_vfta = e1000_clear_vfta_generic; /* setting MTA */ - func->mta_set = e1000_mta_set_generic; + mac->ops.mta_set = e1000_mta_set_generic; /* read mac address */ - func->read_mac_addr = e1000_read_mac_addr_80003es2lan; + mac->ops.read_mac_addr = e1000_read_mac_addr_80003es2lan; /* blink LED */ - func->blink_led = e1000_blink_led_generic; + mac->ops.blink_led = e1000_blink_led_generic; /* setup LED */ - func->setup_led = e1000_setup_led_generic; + mac->ops.setup_led = e1000_setup_led_generic; /* cleanup LED */ - func->cleanup_led = e1000_cleanup_led_generic; + mac->ops.cleanup_led = e1000_cleanup_led_generic; /* turn on/off LED */ - func->led_on = e1000_led_on_generic; - func->led_off = e1000_led_off_generic; + mac->ops.led_on = e1000_led_on_generic; + mac->ops.led_off = e1000_led_off_generic; /* remove device */ - func->remove_device = e1000_remove_device_generic; + mac->ops.remove_device = e1000_remove_device_generic; /* clear hardware counters */ - func->clear_hw_cntrs = e1000_clear_hw_cntrs_80003es2lan; + mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_80003es2lan; /* link info */ - func->get_link_up_info = e1000_get_link_up_info_80003es2lan; + mac->ops.get_link_up_info = e1000_get_link_up_info_80003es2lan; out: return ret_val; @@ -307,9 +303,9 @@ void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw) { DEBUGFUNC("e1000_init_function_pointers_80003es2lan"); - hw->func.init_mac_params = e1000_init_mac_params_80003es2lan; - hw->func.init_nvm_params = e1000_init_nvm_params_80003es2lan; - hw->func.init_phy_params = e1000_init_phy_params_80003es2lan; + hw->mac.ops.init_params = e1000_init_mac_params_80003es2lan; + hw->nvm.ops.init_params = e1000_init_nvm_params_80003es2lan; + hw->phy.ops.init_params = e1000_init_phy_params_80003es2lan; } /** @@ -319,7 +315,7 @@ void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw) * A wrapper to acquire access rights to the correct PHY. This is a * function pointer entry point called by the api module. **/ -STATIC s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw) +static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw) { u16 mask; @@ -338,7 +334,7 @@ STATIC s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw) * A wrapper to release access rights to the correct PHY. This is a * function pointer entry point called by the api module. **/ -STATIC void e1000_release_phy_80003es2lan(struct e1000_hw *hw) +static void e1000_release_phy_80003es2lan(struct e1000_hw *hw) { u16 mask; @@ -357,7 +353,7 @@ STATIC void e1000_release_phy_80003es2lan(struct e1000_hw *hw) * Acquire the semaphore to access the EEPROM. This is a function * pointer entry point called by the api module. **/ -STATIC s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw) +static s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw) { s32 ret_val; @@ -383,7 +379,7 @@ out: * Release the semaphore used to access the EEPROM. This is a * function pointer entry point called by the api module. **/ -STATIC void e1000_release_nvm_80003es2lan(struct e1000_hw *hw) +static void e1000_release_nvm_80003es2lan(struct e1000_hw *hw) { DEBUGFUNC("e1000_release_nvm_80003es2lan"); @@ -476,7 +472,7 @@ static void e1000_release_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask) * Read the GG82563 PHY register. This is a function pointer entry * point called by the api module. **/ -STATIC s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, +static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, u32 offset, u16 *data) { s32 ret_val; @@ -545,7 +541,7 @@ out: * Write to the GG82563 PHY register. This is a function pointer entry * point called by the api module. **/ -STATIC s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, +static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, u32 offset, u16 data) { s32 ret_val; @@ -616,7 +612,7 @@ out: * Write "words" of data to the ESB2 NVM. This is a function * pointer entry point called by the api module. **/ -STATIC s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, +static s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { DEBUGFUNC("e1000_write_nvm_80003es2lan"); @@ -631,7 +627,7 @@ STATIC s32 e1000_write_nvm_80003es2lan(struct e1000_hw *hw, u16 offset, * Wait a specific amount of time for manageability processes to complete. * This is a function pointer entry point called by the phy module. **/ -STATIC s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw) +static s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw) { s32 timeout = PHY_CFG_TIMEOUT; s32 ret_val = E1000_SUCCESS; @@ -665,30 +661,33 @@ out: * Force the speed and duplex settings onto the PHY. This is a * function pointer entry point called by the phy module. **/ -STATIC s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) +static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) { - s32 ret_val; + s32 ret_val = E1000_SUCCESS; u16 phy_data; bool link; DEBUGFUNC("e1000_phy_force_speed_duplex_80003es2lan"); + if (!(hw->phy.ops.read_reg)) + goto out; + /* * Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI * forced whenever speed and duplex are forced. */ - ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); + ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if (ret_val) goto out; phy_data &= ~GG82563_PSCR_CROSSOVER_MODE_AUTO; - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_SPEC_CTRL, phy_data); + ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, phy_data); if (ret_val) goto out; DEBUGOUT1("GG82563 PSCR: %X\n", phy_data); - ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &phy_data); + ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_data); if (ret_val) goto out; @@ -697,7 +696,7 @@ STATIC s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) /* Reset the phy to commit changes. */ phy_data |= MII_CR_RESET; - ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, phy_data); + ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_data); if (ret_val) goto out; @@ -729,7 +728,7 @@ STATIC s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) goto out; } - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data); + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &phy_data); if (ret_val) goto out; @@ -748,7 +747,7 @@ STATIC s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) * duplex. */ phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX; - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data); + ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, phy_data); out: return ret_val; @@ -761,15 +760,18 @@ out: * Find the approximate cable length as measured by the GG82563 PHY. * This is a function pointer entry point called by the phy module. **/ -STATIC s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw) +static s32 e1000_get_cable_length_80003es2lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - s32 ret_val; + s32 ret_val = E1000_SUCCESS; u16 phy_data, index; DEBUGFUNC("e1000_get_cable_length_80003es2lan"); - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_DSP_DISTANCE, &phy_data); + if (!(hw->phy.ops.read_reg)) + goto out; + + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_DSP_DISTANCE, &phy_data); if (ret_val) goto out; @@ -792,7 +794,7 @@ out: * 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_80003es2lan(struct e1000_hw *hw, u16 *speed, +static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, u16 *duplex) { s32 ret_val; @@ -827,7 +829,7 @@ out: * Perform a global reset to the ESB2 controller. * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) +static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) { u32 ctrl, icr; s32 ret_val; @@ -879,7 +881,7 @@ out: * Initialize the hw bits, LED, VFTA, MTA, link and hw counters. * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) +static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 reg_data; @@ -899,7 +901,7 @@ STATIC s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) /* Disabling VLAN filtering */ DEBUGOUT("Initializing the IEEE VLAN\n"); - e1000_clear_vfta(hw); + mac->ops.clear_vfta(hw); /* Setup the receive address. */ e1000_init_rx_addrs_generic(hw, mac->rar_entry_count); @@ -910,7 +912,7 @@ STATIC s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw) E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); /* Setup link and flow control */ - ret_val = e1000_setup_link(hw); + ret_val = mac->ops.setup_link(hw); /* Set the transmit descriptor write-back policy */ reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0)); @@ -1017,7 +1019,7 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) DEBUGFUNC("e1000_copper_link_setup_gg82563_80003es2lan"); if (!phy->reset_disable) { - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, &data); if (ret_val) goto out; @@ -1026,7 +1028,7 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) /* Use 25MHz for both link down and 1000Base-T for Tx clock. */ data |= GG82563_MSCR_TX_CLK_1000MBPS_25; - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, + ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_MAC_SPEC_CTRL, data); if (ret_val) goto out; @@ -1039,7 +1041,7 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) * 2 - MDI-X mode * 3 - Auto for 1000Base-T only (MDI-X for 10/100Base-T modes) */ - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_SPEC_CTRL, &data); + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL, &data); if (ret_val) goto out; @@ -1069,12 +1071,12 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) if (phy->disable_polarity_correction) data |= GG82563_PSCR_POLARITY_REVERSAL_DISABLE; - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_SPEC_CTRL, data); + ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL, data); if (ret_val) goto out; /* SW Reset the PHY so all changes take effect */ - ret_val = e1000_phy_commit(hw); + ret_val = hw->phy.ops.commit(hw); if (ret_val) { DEBUGOUT("Error Resetting the PHY\n"); goto out; @@ -1102,12 +1104,12 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) if (ret_val) goto out; - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_SPEC_CTRL_2, &data); + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_SPEC_CTRL_2, &data); if (ret_val) goto out; data &= ~GG82563_PSCR2_REVERSE_AUTO_NEG; - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_SPEC_CTRL_2, data); + ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_SPEC_CTRL_2, data); if (ret_val) goto out; @@ -1115,7 +1117,7 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) ctrl_ext &= ~(E1000_CTRL_EXT_LINK_MODE_MASK); E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, &data); + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, &data); if (ret_val) goto out; @@ -1124,23 +1126,23 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) * firmware will have already initialized them. We only initialize * them if the HW is not in IAMT mode. */ - if (!(e1000_check_mng_mode(hw))) { + if (!(hw->mac.ops.check_mng_mode(hw))) { /* Enable Electrical Idle on the PHY */ data |= GG82563_PMCR_ENABLE_ELECTRICAL_IDLE; - ret_val = e1000_write_phy_reg(hw, + ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_PWR_MGMT_CTRL, data); if (ret_val) goto out; do { - ret_val = e1000_read_phy_reg(hw, + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, &data); if (ret_val) goto out; - ret_val = e1000_read_phy_reg(hw, + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, &data2); if (ret_val) @@ -1149,7 +1151,7 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) } while ((data != data2) && (i < GG82563_MAX_KMRN_RETRY)); data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; - ret_val = e1000_write_phy_reg(hw, + ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, data); @@ -1161,12 +1163,12 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) * Workaround: Disable padding in Kumeran interface in the MAC * and in the PHY to avoid CRC errors. */ - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_INBAND_CTRL, &data); + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_INBAND_CTRL, &data); if (ret_val) goto out; data |= GG82563_ICR_DIS_PADDING; - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_INBAND_CTRL, data); + ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_INBAND_CTRL, data); if (ret_val) goto out; @@ -1181,7 +1183,7 @@ out: * Essentially a wrapper for setting up all things "copper" related. * This is a function pointer entry point called by the mac module. **/ -STATIC s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw) +static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw) { u32 ctrl; s32 ret_val; @@ -1263,12 +1265,12 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) do { - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); if (ret_val) goto out; - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data2); if (ret_val) goto out; @@ -1280,7 +1282,7 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex) else reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); + ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); out: return ret_val; @@ -1317,12 +1319,12 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) do { - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data); if (ret_val) goto out; - ret_val = e1000_read_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, + ret_val = hw->phy.ops.read_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, ®_data2); if (ret_val) goto out; @@ -1330,7 +1332,7 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) } while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY)); reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER; - ret_val = e1000_write_phy_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); + ret_val = hw->phy.ops.write_reg(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data); out: return ret_val; @@ -1340,7 +1342,7 @@ out: * e1000_read_mac_addr_80003es2lan - Read device MAC address * @hw: pointer to the HW structure **/ -STATIC s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw) +static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; @@ -1358,10 +1360,11 @@ STATIC s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw) * In the case of a PHY power down to save power, or to turn off link during a * driver unload, or wake on lan is not enabled, remove the link. **/ -STATIC void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw) +static void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw) { /* If the management interface is not enabled, then power down */ - if (!(e1000_check_mng_mode(hw) || e1000_check_reset_block(hw))) + if (!(hw->mac.ops.check_mng_mode(hw) || + hw->phy.ops.check_reset_block(hw))) e1000_power_down_phy_copper(hw); return; @@ -1373,7 +1376,7 @@ STATIC void e1000_power_down_phy_copper_80003es2lan(struct e1000_hw *hw) * * Clears the hardware counters by reading the counter registers. **/ -STATIC void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw) +static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw) { volatile u32 temp; diff --git a/sys/dev/em/e1000_82540.c b/sys/dev/em/e1000_82540.c index c3c5bf5..0598075 100644 --- a/sys/dev/em/e1000_82540.c +++ b/sys/dev/em/e1000_82540.c @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,9 +29,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ /* e1000_82540 * e1000_82545 @@ -42,18 +41,18 @@ #include "e1000_api.h" -STATIC s32 e1000_init_phy_params_82540(struct e1000_hw *hw); -STATIC s32 e1000_init_nvm_params_82540(struct e1000_hw *hw); -STATIC s32 e1000_init_mac_params_82540(struct e1000_hw *hw); +static s32 e1000_init_phy_params_82540(struct e1000_hw *hw); +static s32 e1000_init_nvm_params_82540(struct e1000_hw *hw); +static s32 e1000_init_mac_params_82540(struct e1000_hw *hw); static s32 e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw); -STATIC void e1000_clear_hw_cntrs_82540(struct e1000_hw *hw); -STATIC s32 e1000_init_hw_82540(struct e1000_hw *hw); -STATIC s32 e1000_reset_hw_82540(struct e1000_hw *hw); +static void e1000_clear_hw_cntrs_82540(struct e1000_hw *hw); +static s32 e1000_init_hw_82540(struct e1000_hw *hw); +static s32 e1000_reset_hw_82540(struct e1000_hw *hw); static s32 e1000_set_phy_mode_82540(struct e1000_hw *hw); static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw); -STATIC s32 e1000_setup_copper_link_82540(struct e1000_hw *hw); -STATIC s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw); -STATIC void e1000_power_down_phy_copper_82540(struct e1000_hw *hw); +static s32 e1000_setup_copper_link_82540(struct e1000_hw *hw); +static s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw); +static void e1000_power_down_phy_copper_82540(struct e1000_hw *hw); /** * e1000_init_phy_params_82540 - Init PHY func ptrs. @@ -61,29 +60,28 @@ STATIC void e1000_power_down_phy_copper_82540(struct e1000_hw *hw); * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_phy_params_82540(struct e1000_hw *hw) +static s32 e1000_init_phy_params_82540(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; - phy->addr = 1; - phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; - phy->reset_delay_us = 10000; - phy->type = e1000_phy_m88; + phy->addr = 1; + phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; + phy->reset_delay_us = 10000; + phy->type = e1000_phy_m88; /* Function Pointers */ - func->check_polarity = e1000_check_polarity_m88; - func->commit_phy = e1000_phy_sw_reset_generic; - func->force_speed_duplex = e1000_phy_force_speed_duplex_m88; - func->get_cable_length = e1000_get_cable_length_m88; - func->get_cfg_done = e1000_get_cfg_done_generic; - func->read_phy_reg = e1000_read_phy_reg_m88; - func->reset_phy = e1000_phy_hw_reset_generic; - func->write_phy_reg = e1000_write_phy_reg_m88; - func->get_phy_info = e1000_get_phy_info_m88; - func->power_up_phy = e1000_power_up_phy_copper; - func->power_down_phy = e1000_power_down_phy_copper_82540; + phy->ops.check_polarity = e1000_check_polarity_m88; + phy->ops.commit = e1000_phy_sw_reset_generic; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; + phy->ops.get_cable_length = e1000_get_cable_length_m88; + phy->ops.get_cfg_done = e1000_get_cfg_done_generic; + phy->ops.read_reg = e1000_read_phy_reg_m88; + phy->ops.reset = e1000_phy_hw_reset_generic; + phy->ops.write_reg = e1000_write_phy_reg_m88; + phy->ops.get_info = e1000_get_phy_info_m88; + phy->ops.power_up = e1000_power_up_phy_copper; + phy->ops.power_down = e1000_power_down_phy_copper_82540; ret_val = e1000_get_phy_id(hw); if (ret_val) @@ -115,10 +113,9 @@ out: * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_nvm_params_82540(struct e1000_hw *hw) +static s32 e1000_init_nvm_params_82540(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; - struct e1000_functions *func = &hw->func; u32 eecd = E1000_READ_REG(hw, E1000_EECD); DEBUGFUNC("e1000_init_nvm_params_82540"); @@ -142,13 +139,13 @@ STATIC s32 e1000_init_nvm_params_82540(struct e1000_hw *hw) } /* Function Pointers */ - func->acquire_nvm = e1000_acquire_nvm_generic; - func->read_nvm = e1000_read_nvm_microwire; - func->release_nvm = e1000_release_nvm_generic; - func->update_nvm = e1000_update_nvm_checksum_generic; - func->valid_led_default = e1000_valid_led_default_generic; - func->validate_nvm = e1000_validate_nvm_checksum_generic; - func->write_nvm = e1000_write_nvm_microwire; + nvm->ops.acquire = e1000_acquire_nvm_generic; + nvm->ops.read = e1000_read_nvm_microwire; + nvm->ops.release = e1000_release_nvm_generic; + nvm->ops.update = e1000_update_nvm_checksum_generic; + nvm->ops.valid_led_default = e1000_valid_led_default_generic; + nvm->ops.validate = e1000_validate_nvm_checksum_generic; + nvm->ops.write = e1000_write_nvm_microwire; return E1000_SUCCESS; } @@ -159,10 +156,9 @@ STATIC s32 e1000_init_nvm_params_82540(struct e1000_hw *hw) * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_mac_params_82540(struct e1000_hw *hw) +static s32 e1000_init_mac_params_82540(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; - struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_init_mac_params_82540"); @@ -192,28 +188,28 @@ STATIC s32 e1000_init_mac_params_82540(struct e1000_hw *hw) /* Function pointers */ /* bus type/speed/width */ - func->get_bus_info = e1000_get_bus_info_pci_generic; + mac->ops.get_bus_info = e1000_get_bus_info_pci_generic; /* reset */ - func->reset_hw = e1000_reset_hw_82540; + mac->ops.reset_hw = e1000_reset_hw_82540; /* hw initialization */ - func->init_hw = e1000_init_hw_82540; + mac->ops.init_hw = e1000_init_hw_82540; /* link setup */ - func->setup_link = e1000_setup_link_generic; + mac->ops.setup_link = e1000_setup_link_generic; /* physical interface setup */ - func->setup_physical_interface = + mac->ops.setup_physical_interface = (hw->phy.media_type == e1000_media_type_copper) ? e1000_setup_copper_link_82540 : e1000_setup_fiber_serdes_link_82540; /* check for link */ switch (hw->phy.media_type) { case e1000_media_type_copper: - func->check_for_link = e1000_check_for_copper_link_generic; + mac->ops.check_for_link = e1000_check_for_copper_link_generic; break; case e1000_media_type_fiber: - func->check_for_link = e1000_check_for_fiber_link_generic; + mac->ops.check_for_link = e1000_check_for_fiber_link_generic; break; case e1000_media_type_internal_serdes: - func->check_for_link = e1000_check_for_serdes_link_generic; + mac->ops.check_for_link = e1000_check_for_serdes_link_generic; break; default: ret_val = -E1000_ERR_CONFIG; @@ -221,27 +217,27 @@ STATIC s32 e1000_init_mac_params_82540(struct e1000_hw *hw) break; } /* link info */ - func->get_link_up_info = + mac->ops.get_link_up_info = (hw->phy.media_type == e1000_media_type_copper) ? e1000_get_speed_and_duplex_copper_generic : e1000_get_speed_and_duplex_fiber_serdes_generic; /* multicast address update */ - func->update_mc_addr_list = e1000_update_mc_addr_list_generic; + mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; /* writing VFTA */ - func->write_vfta = e1000_write_vfta_generic; + mac->ops.write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ - func->clear_vfta = e1000_clear_vfta_generic; + mac->ops.clear_vfta = e1000_clear_vfta_generic; /* setting MTA */ - func->mta_set = e1000_mta_set_generic; + mac->ops.mta_set = e1000_mta_set_generic; /* setup LED */ - func->setup_led = e1000_setup_led_generic; + mac->ops.setup_led = e1000_setup_led_generic; /* cleanup LED */ - func->cleanup_led = e1000_cleanup_led_generic; + mac->ops.cleanup_led = e1000_cleanup_led_generic; /* turn on/off LED */ - func->led_on = e1000_led_on_generic; - func->led_off = e1000_led_off_generic; + mac->ops.led_on = e1000_led_on_generic; + mac->ops.led_off = e1000_led_off_generic; /* clear hardware counters */ - func->clear_hw_cntrs = e1000_clear_hw_cntrs_82540; + mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82540; out: return ret_val; @@ -258,9 +254,9 @@ void e1000_init_function_pointers_82540(struct e1000_hw *hw) { DEBUGFUNC("e1000_init_function_pointers_82540"); - hw->func.init_mac_params = e1000_init_mac_params_82540; - hw->func.init_nvm_params = e1000_init_nvm_params_82540; - hw->func.init_phy_params = e1000_init_phy_params_82540; + hw->mac.ops.init_params = e1000_init_mac_params_82540; + hw->nvm.ops.init_params = e1000_init_nvm_params_82540; + hw->phy.ops.init_params = e1000_init_phy_params_82540; } /** @@ -270,7 +266,7 @@ void e1000_init_function_pointers_82540(struct e1000_hw *hw) * This resets the hardware into a known state. This is a * function pointer entry point called by the api module. **/ -STATIC s32 e1000_reset_hw_82540(struct e1000_hw *hw) +static s32 e1000_reset_hw_82540(struct e1000_hw *hw) { u32 ctrl, icr, manc; s32 ret_val = E1000_SUCCESS; @@ -329,7 +325,7 @@ STATIC s32 e1000_reset_hw_82540(struct e1000_hw *hw) * This inits the hardware readying it for operation. This is a * function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_hw_82540(struct e1000_hw *hw) +static s32 e1000_init_hw_82540(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 txdctl, ctrl_ext; @@ -350,7 +346,7 @@ STATIC s32 e1000_init_hw_82540(struct e1000_hw *hw) if (mac->type < e1000_82545_rev_3) E1000_WRITE_REG(hw, E1000_VET, 0); - e1000_clear_vfta(hw); + mac->ops.clear_vfta(hw); /* Setup the receive address. */ e1000_init_rx_addrs_generic(hw, mac->rar_entry_count); @@ -374,7 +370,7 @@ STATIC s32 e1000_init_hw_82540(struct e1000_hw *hw) e1000_pcix_mmrbc_workaround_generic(hw); /* Setup link and flow control */ - ret_val = e1000_setup_link(hw); + ret_val = mac->ops.setup_link(hw); txdctl = E1000_READ_REG(hw, E1000_TXDCTL(0)); txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | @@ -413,7 +409,7 @@ STATIC s32 e1000_init_hw_82540(struct e1000_hw *hw) * not established, we return -E1000_ERR_PHY (-2). This is a function * pointer entry point called by the api module. **/ -STATIC s32 e1000_setup_copper_link_82540(struct e1000_hw *hw) +static s32 e1000_setup_copper_link_82540(struct e1000_hw *hw) { u32 ctrl; s32 ret_val = E1000_SUCCESS; @@ -432,11 +428,11 @@ STATIC s32 e1000_setup_copper_link_82540(struct e1000_hw *hw) if (hw->mac.type == e1000_82545_rev_3 || hw->mac.type == e1000_82546_rev_3) { - ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &data); + ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &data); if (ret_val) goto out; data |= 0x00000008; - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, data); + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, data); if (ret_val) goto out; } @@ -461,7 +457,7 @@ out: * setup, poll for link. This is a function pointer entry point called by * the api module. **/ -STATIC s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw) +static s32 e1000_setup_fiber_serdes_link_82540(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; s32 ret_val = E1000_SUCCESS; @@ -507,14 +503,14 @@ static s32 e1000_adjust_serdes_amplitude_82540(struct e1000_hw *hw) DEBUGFUNC("e1000_adjust_serdes_amplitude_82540"); - ret_val = e1000_read_nvm(hw, NVM_SERDES_AMPLITUDE, 1, &nvm_data); + ret_val = hw->nvm.ops.read(hw, NVM_SERDES_AMPLITUDE, 1, &nvm_data); if (ret_val) goto out; if (nvm_data != NVM_RESERVED_WORD) { /* Adjust serdes output amplitude only. */ nvm_data &= NVM_SERDES_AMPLITUDE_MASK; - ret_val = e1000_write_phy_reg(hw, + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_EXT_CTRL, nvm_data); if (ret_val) @@ -541,41 +537,41 @@ static s32 e1000_set_vco_speed_82540(struct e1000_hw *hw) /* Set PHY register 30, page 5, bit 8 to 0 */ - ret_val = e1000_read_phy_reg(hw, + ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_PAGE_SELECT, &default_page); if (ret_val) goto out; - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005); + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0005); if (ret_val) goto out; - ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data); + ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data); if (ret_val) goto out; phy_data &= ~M88E1000_PHY_VCO_REG_BIT8; - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data); + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data); if (ret_val) goto out; /* Set PHY register 30, page 4, bit 11 to 1 */ - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004); + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0004); if (ret_val) goto out; - ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data); + ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_GEN_CONTROL, &phy_data); if (ret_val) goto out; phy_data |= M88E1000_PHY_VCO_REG_BIT11; - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data); + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, phy_data); if (ret_val) goto out; - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, default_page); out: @@ -602,20 +598,20 @@ static s32 e1000_set_phy_mode_82540(struct e1000_hw *hw) if (hw->mac.type != e1000_82545_rev_3) goto out; - ret_val = e1000_read_nvm(hw, NVM_PHY_CLASS_WORD, 1, &nvm_data); + ret_val = hw->nvm.ops.read(hw, NVM_PHY_CLASS_WORD, 1, &nvm_data); if (ret_val) { ret_val = -E1000_ERR_PHY; goto out; } if ((nvm_data != NVM_RESERVED_WORD) && (nvm_data & NVM_PHY_CLASS_A)) { - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x000B); if (ret_val) { ret_val = -E1000_ERR_PHY; goto out; } - ret_val = e1000_write_phy_reg(hw, + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x8104); if (ret_val) { @@ -637,7 +633,7 @@ out: * In the case of a PHY power down to save power, or to turn off link during a * driver unload, or wake on lan is not enabled, remove the link. **/ -STATIC void e1000_power_down_phy_copper_82540(struct e1000_hw *hw) +static void e1000_power_down_phy_copper_82540(struct e1000_hw *hw) { /* If the management interface is not enabled, then power down */ if (!(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_SMBUS_EN)) @@ -652,7 +648,7 @@ STATIC void e1000_power_down_phy_copper_82540(struct e1000_hw *hw) * * Clears the hardware counters by reading the counter registers. **/ -STATIC void e1000_clear_hw_cntrs_82540(struct e1000_hw *hw) +static void e1000_clear_hw_cntrs_82540(struct e1000_hw *hw) { volatile u32 temp; diff --git a/sys/dev/em/e1000_82541.c b/sys/dev/em/e1000_82541.c index d7b2956..4a43b32 100644 --- a/sys/dev/em/e1000_82541.c +++ b/sys/dev/em/e1000_82541.c @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,9 +29,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ /* e1000_82541 * e1000_82547 @@ -42,26 +41,26 @@ #include "e1000_api.h" #include "e1000_82541.h" -STATIC s32 e1000_init_phy_params_82541(struct e1000_hw *hw); -STATIC s32 e1000_init_nvm_params_82541(struct e1000_hw *hw); -STATIC s32 e1000_init_mac_params_82541(struct e1000_hw *hw); -STATIC s32 e1000_reset_hw_82541(struct e1000_hw *hw); -STATIC s32 e1000_init_hw_82541(struct e1000_hw *hw); -STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed, +static s32 e1000_init_phy_params_82541(struct e1000_hw *hw); +static s32 e1000_init_nvm_params_82541(struct e1000_hw *hw); +static s32 e1000_init_mac_params_82541(struct e1000_hw *hw); +static s32 e1000_reset_hw_82541(struct e1000_hw *hw); +static s32 e1000_init_hw_82541(struct e1000_hw *hw); +static s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed, u16 *duplex); -STATIC s32 e1000_phy_hw_reset_82541(struct e1000_hw *hw); -STATIC s32 e1000_setup_copper_link_82541(struct e1000_hw *hw); -STATIC s32 e1000_check_for_link_82541(struct e1000_hw *hw); -STATIC s32 e1000_get_cable_length_igp_82541(struct e1000_hw *hw); -STATIC s32 e1000_set_d3_lplu_state_82541(struct e1000_hw *hw, +static s32 e1000_phy_hw_reset_82541(struct e1000_hw *hw); +static s32 e1000_setup_copper_link_82541(struct e1000_hw *hw); +static s32 e1000_check_for_link_82541(struct e1000_hw *hw); +static s32 e1000_get_cable_length_igp_82541(struct e1000_hw *hw); +static s32 e1000_set_d3_lplu_state_82541(struct e1000_hw *hw, bool active); -STATIC s32 e1000_setup_led_82541(struct e1000_hw *hw); -STATIC s32 e1000_cleanup_led_82541(struct e1000_hw *hw); -STATIC void e1000_clear_hw_cntrs_82541(struct e1000_hw *hw); +static s32 e1000_setup_led_82541(struct e1000_hw *hw); +static s32 e1000_cleanup_led_82541(struct e1000_hw *hw); +static void e1000_clear_hw_cntrs_82541(struct e1000_hw *hw); static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, bool link_up); static s32 e1000_phy_init_script_82541(struct e1000_hw *hw); -STATIC void e1000_power_down_phy_copper_82541(struct e1000_hw *hw); +static void e1000_power_down_phy_copper_82541(struct e1000_hw *hw); static const u16 e1000_igp_cable_length_table[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, @@ -89,31 +88,30 @@ struct e1000_dev_spec_82541 { * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_phy_params_82541(struct e1000_hw *hw) +static s32 e1000_init_phy_params_82541(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_init_phy_params_82541"); - phy->addr = 1; - phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; - phy->reset_delay_us = 10000; - phy->type = e1000_phy_igp; + phy->addr = 1; + phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; + phy->reset_delay_us = 10000; + phy->type = e1000_phy_igp; /* Function Pointers */ - func->check_polarity = e1000_check_polarity_igp; - func->force_speed_duplex = e1000_phy_force_speed_duplex_igp; - func->get_cable_length = e1000_get_cable_length_igp_82541; - func->get_cfg_done = e1000_get_cfg_done_generic; - func->get_phy_info = e1000_get_phy_info_igp; - func->read_phy_reg = e1000_read_phy_reg_igp; - func->reset_phy = e1000_phy_hw_reset_82541; - func->set_d3_lplu_state = e1000_set_d3_lplu_state_82541; - func->write_phy_reg = e1000_write_phy_reg_igp; - func->power_up_phy = e1000_power_up_phy_copper; - func->power_down_phy = e1000_power_down_phy_copper_82541; + phy->ops.check_polarity = e1000_check_polarity_igp; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp; + phy->ops.get_cable_length = e1000_get_cable_length_igp_82541; + phy->ops.get_cfg_done = e1000_get_cfg_done_generic; + phy->ops.get_info = e1000_get_phy_info_igp; + phy->ops.read_reg = e1000_read_phy_reg_igp; + phy->ops.reset = e1000_phy_hw_reset_82541; + phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_82541; + phy->ops.write_reg = e1000_write_phy_reg_igp; + phy->ops.power_up = e1000_power_up_phy_copper; + phy->ops.power_down = e1000_power_down_phy_copper_82541; ret_val = e1000_get_phy_id(hw); if (ret_val) @@ -135,10 +133,9 @@ out: * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_nvm_params_82541(struct e1000_hw *hw) +static s32 e1000_init_nvm_params_82541(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; - struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; u32 eecd = E1000_READ_REG(hw, E1000_EECD); u16 size; @@ -178,13 +175,13 @@ STATIC s32 e1000_init_nvm_params_82541(struct e1000_hw *hw) ? 32 : 8; /* Function Pointers */ - func->acquire_nvm = e1000_acquire_nvm_generic; - func->read_nvm = e1000_read_nvm_spi; - func->release_nvm = e1000_release_nvm_generic; - func->update_nvm = e1000_update_nvm_checksum_generic; - func->valid_led_default = e1000_valid_led_default_generic; - func->validate_nvm = e1000_validate_nvm_checksum_generic; - func->write_nvm = e1000_write_nvm_spi; + nvm->ops.acquire = e1000_acquire_nvm_generic; + nvm->ops.read = e1000_read_nvm_spi; + nvm->ops.release = e1000_release_nvm_generic; + nvm->ops.update = e1000_update_nvm_checksum_generic; + nvm->ops.valid_led_default = e1000_valid_led_default_generic; + nvm->ops.validate = e1000_validate_nvm_checksum_generic; + nvm->ops.write = e1000_write_nvm_spi; /* * nvm->word_size must be discovered after the pointers @@ -193,7 +190,7 @@ STATIC s32 e1000_init_nvm_params_82541(struct e1000_hw *hw) * read will work. */ nvm->word_size = 64; - ret_val = e1000_read_nvm(hw, NVM_CFG, 1, &size); + ret_val = nvm->ops.read(hw, NVM_CFG, 1, &size); if (ret_val) goto out; size = (size & NVM_SIZE_MASK) >> NVM_SIZE_SHIFT; @@ -215,13 +212,13 @@ STATIC s32 e1000_init_nvm_params_82541(struct e1000_hw *hw) ? 256 : 64; /* Function Pointers */ - func->acquire_nvm = e1000_acquire_nvm_generic; - func->read_nvm = e1000_read_nvm_microwire; - func->release_nvm = e1000_release_nvm_generic; - func->update_nvm = e1000_update_nvm_checksum_generic; - func->valid_led_default = e1000_valid_led_default_generic; - func->validate_nvm = e1000_validate_nvm_checksum_generic; - func->write_nvm = e1000_write_nvm_microwire; + nvm->ops.acquire = e1000_acquire_nvm_generic; + nvm->ops.read = e1000_read_nvm_microwire; + nvm->ops.release = e1000_release_nvm_generic; + nvm->ops.update = e1000_update_nvm_checksum_generic; + nvm->ops.valid_led_default = e1000_valid_led_default_generic; + nvm->ops.validate = e1000_validate_nvm_checksum_generic; + nvm->ops.write = e1000_write_nvm_microwire; } out: @@ -234,10 +231,9 @@ out: * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_mac_params_82541(struct e1000_hw *hw) +static s32 e1000_init_mac_params_82541(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; - struct e1000_functions *func = &hw->func; s32 ret_val; DEBUGFUNC("e1000_init_mac_params_82541"); @@ -254,38 +250,38 @@ STATIC s32 e1000_init_mac_params_82541(struct e1000_hw *hw) /* Function Pointers */ /* bus type/speed/width */ - func->get_bus_info = e1000_get_bus_info_pci_generic; + mac->ops.get_bus_info = e1000_get_bus_info_pci_generic; /* reset */ - func->reset_hw = e1000_reset_hw_82541; + mac->ops.reset_hw = e1000_reset_hw_82541; /* hw initialization */ - func->init_hw = e1000_init_hw_82541; + mac->ops.init_hw = e1000_init_hw_82541; /* link setup */ - func->setup_link = e1000_setup_link_generic; + mac->ops.setup_link = e1000_setup_link_generic; /* physical interface link setup */ - func->setup_physical_interface = e1000_setup_copper_link_82541; + mac->ops.setup_physical_interface = e1000_setup_copper_link_82541; /* check for link */ - func->check_for_link = e1000_check_for_link_82541; + mac->ops.check_for_link = e1000_check_for_link_82541; /* link info */ - func->get_link_up_info = e1000_get_link_up_info_82541; + mac->ops.get_link_up_info = e1000_get_link_up_info_82541; /* multicast address update */ - func->update_mc_addr_list = e1000_update_mc_addr_list_generic; + mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; /* writing VFTA */ - func->write_vfta = e1000_write_vfta_generic; + mac->ops.write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ - func->clear_vfta = e1000_clear_vfta_generic; + mac->ops.clear_vfta = e1000_clear_vfta_generic; /* setting MTA */ - func->mta_set = e1000_mta_set_generic; + mac->ops.mta_set = e1000_mta_set_generic; /* setup LED */ - func->setup_led = e1000_setup_led_82541; + mac->ops.setup_led = e1000_setup_led_82541; /* cleanup LED */ - func->cleanup_led = e1000_cleanup_led_82541; + mac->ops.cleanup_led = e1000_cleanup_led_82541; /* turn on/off LED */ - func->led_on = e1000_led_on_generic; - func->led_off = e1000_led_off_generic; + mac->ops.led_on = e1000_led_on_generic; + mac->ops.led_off = e1000_led_off_generic; /* remove device */ - func->remove_device = e1000_remove_device_generic; + mac->ops.remove_device = e1000_remove_device_generic; /* clear hardware counters */ - func->clear_hw_cntrs = e1000_clear_hw_cntrs_82541; + mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82541; hw->dev_spec_size = sizeof(struct e1000_dev_spec_82541); @@ -306,9 +302,9 @@ void e1000_init_function_pointers_82541(struct e1000_hw *hw) { DEBUGFUNC("e1000_init_function_pointers_82541"); - hw->func.init_mac_params = e1000_init_mac_params_82541; - hw->func.init_nvm_params = e1000_init_nvm_params_82541; - hw->func.init_phy_params = e1000_init_phy_params_82541; + hw->mac.ops.init_params = e1000_init_mac_params_82541; + hw->nvm.ops.init_params = e1000_init_nvm_params_82541; + hw->phy.ops.init_params = e1000_init_phy_params_82541; } /** @@ -318,7 +314,7 @@ void e1000_init_function_pointers_82541(struct e1000_hw *hw) * This resets the hardware into a known state. This is a * function pointer entry point called by the api module. **/ -STATIC s32 e1000_reset_hw_82541(struct e1000_hw *hw) +static s32 e1000_reset_hw_82541(struct e1000_hw *hw) { u32 ledctl, ctrl, icr, manc; @@ -396,7 +392,7 @@ STATIC s32 e1000_reset_hw_82541(struct e1000_hw *hw) * This inits the hardware readying it for operation. This is a * function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_hw_82541(struct e1000_hw *hw) +static s32 e1000_init_hw_82541(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 i, txdctl; @@ -413,7 +409,7 @@ STATIC s32 e1000_init_hw_82541(struct e1000_hw *hw) /* Disabling VLAN filtering */ DEBUGOUT("Initializing the IEEE VLAN\n"); - e1000_clear_vfta(hw); + mac->ops.clear_vfta(hw); /* Setup the receive address. */ e1000_init_rx_addrs_generic(hw, mac->rar_entry_count); @@ -432,7 +428,7 @@ STATIC s32 e1000_init_hw_82541(struct e1000_hw *hw) } /* Setup link and flow control */ - ret_val = e1000_setup_link(hw); + ret_val = mac->ops.setup_link(hw); txdctl = E1000_READ_REG(hw, E1000_TXDCTL(0)); txdctl = (txdctl & ~E1000_TXDCTL_WTHRESH) | @@ -459,7 +455,7 @@ STATIC s32 e1000_init_hw_82541(struct e1000_hw *hw) * 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, +static s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed, u16 *duplex) { struct e1000_phy_info *phy = &hw->phy; @@ -481,14 +477,14 @@ STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed, * Here we set the duplex settings to match the duplex in the * link partner's capabilities. */ - ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_EXP, &data); + ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_EXP, &data); if (ret_val) goto out; if (!(data & NWAY_ER_LP_NWAY_CAPS)) { *duplex = HALF_DUPLEX; } else { - ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY, &data); + ret_val = phy->ops.read_reg(hw, PHY_LP_ABILITY, &data); if (ret_val) goto out; @@ -515,7 +511,7 @@ out: * 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) +static s32 e1000_phy_hw_reset_82541(struct e1000_hw *hw) { s32 ret_val; u32 ledctl; @@ -550,7 +546,7 @@ out: * not established, we return -E1000_ERR_PHY (-2). This is a function * pointer entry point called by the api module. **/ -STATIC s32 e1000_setup_copper_link_82541(struct e1000_hw *hw) +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; @@ -605,7 +601,7 @@ out: * results in the hw->mac structure. This is a function pointer entry * point called by the api module. **/ -STATIC s32 e1000_check_for_link_82541(struct e1000_hw *hw) +static s32 e1000_check_for_link_82541(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; s32 ret_val; @@ -711,7 +707,7 @@ static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, dev_spec = (struct e1000_dev_spec_82541 *)hw->dev_spec; if (link_up) { - ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex); + ret_val = hw->mac.ops.get_link_up_info(hw, &speed, &duplex); if (ret_val) { DEBUGOUT("Error getting link speed and duplex\n"); goto out; @@ -722,7 +718,7 @@ static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, goto out; } - ret_val = e1000_get_cable_length(hw); + ret_val = phy->ops.get_cable_length(hw); if (ret_val) goto out; @@ -730,7 +726,7 @@ static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, phy->min_cable_length >= 50) { for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) { - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, dsp_reg_array[i], &phy_data); if (ret_val) @@ -738,7 +734,7 @@ static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, dsp_reg_array[i], phy_data); if (ret_val) @@ -754,13 +750,13 @@ static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, } /* clear previous idle error counts */ - ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data); + ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &phy_data); if (ret_val) goto out; for (i = 0; i < ffe_idle_err_timeout; i++) { usec_delay(1000); - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &phy_data); if (ret_val) @@ -770,7 +766,7 @@ static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, if (idle_errs > SR_1000T_PHY_EXCESSIVE_IDLE_ERR_COUNT) { dev_spec->ffe_config = e1000_ffe_config_active; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_DSP_FFE, IGP01E1000_PHY_DSP_FFE_CM_CP); if (ret_val) @@ -788,26 +784,26 @@ static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, * Save off the current value of register 0x2F5B * to be restored at the end of the routines. */ - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, 0x2F5B, &phy_saved_data); if (ret_val) goto out; /* Disable the PHY transmitter */ - ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003); + ret_val = phy->ops.write_reg(hw, 0x2F5B, 0x0003); if (ret_val) goto out; msec_delay_irq(20); - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, 0x0000, IGP01E1000_IEEE_FORCE_GIG); if (ret_val) goto out; for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) { - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, dsp_reg_array[i], &phy_data); if (ret_val) @@ -816,14 +812,14 @@ static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, phy_data &= ~IGP01E1000_PHY_EDAC_MU_INDEX; phy_data |= IGP01E1000_PHY_EDAC_SIGN_EXT_9_BITS; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, dsp_reg_array[i], phy_data); if (ret_val) goto out; } - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, 0x0000, IGP01E1000_IEEE_RESTART_AUTONEG); if (ret_val) @@ -832,7 +828,7 @@ static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, msec_delay_irq(20); /* Now enable the transmitter */ - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, 0x2F5B, phy_saved_data); if (ret_val) @@ -850,30 +846,30 @@ static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, * Save off the current value of register 0x2F5B * to be restored at the end of the routines. */ - ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data); + ret_val = phy->ops.read_reg(hw, 0x2F5B, &phy_saved_data); if (ret_val) goto out; /* Disable the PHY transmitter */ - ret_val = e1000_write_phy_reg(hw, 0x2F5B, 0x0003); + ret_val = phy->ops.write_reg(hw, 0x2F5B, 0x0003); if (ret_val) goto out; msec_delay_irq(20); - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, 0x0000, IGP01E1000_IEEE_FORCE_GIG); if (ret_val) goto out; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_DSP_FFE, IGP01E1000_PHY_DSP_FFE_DEFAULT); if (ret_val) goto out; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, 0x0000, IGP01E1000_IEEE_RESTART_AUTONEG); if (ret_val) @@ -882,7 +878,7 @@ static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, msec_delay_irq(20); /* Now enable the transmitter */ - ret_val = e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data); + ret_val = phy->ops.write_reg(hw, 0x2F5B, phy_saved_data); if (ret_val) goto out; @@ -906,7 +902,7 @@ out: * for each channel. This is a function pointer entry point called by the * api module. **/ -STATIC s32 e1000_get_cable_length_igp_82541(struct e1000_hw *hw) +static s32 e1000_get_cable_length_igp_82541(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val = E1000_SUCCESS; @@ -923,7 +919,7 @@ STATIC s32 e1000_get_cable_length_igp_82541(struct e1000_hw *hw) /* Read the AGC registers for all channels */ for (i = 0; i < IGP01E1000_PHY_CHANNEL_NUM; i++) { - ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &data); + ret_val = phy->ops.read_reg(hw, agc_reg_array[i], &data); if (ret_val) goto out; @@ -974,14 +970,14 @@ out: * Success returns 0, Failure returns 1 * * The low power link up (lplu) state is set to the power management level D3 - * and SmartSpeed is disabled when active is true, else clear lplu for D3 + * and SmartSpeed is disabled when active is TRUE, else clear lplu for D3 * 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. **/ -STATIC s32 e1000_set_d3_lplu_state_82541(struct e1000_hw *hw, bool active) +static s32 e1000_set_d3_lplu_state_82541(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -999,13 +995,13 @@ STATIC s32 e1000_set_d3_lplu_state_82541(struct e1000_hw *hw, bool active) break; } - ret_val = e1000_read_phy_reg(hw, IGP01E1000_GMII_FIFO, &data); + ret_val = phy->ops.read_reg(hw, IGP01E1000_GMII_FIFO, &data); if (ret_val) goto out; if (!active) { data &= ~IGP01E1000_GMII_FLEX_SPD; - ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, data); + ret_val = phy->ops.write_reg(hw, IGP01E1000_GMII_FIFO, data); if (ret_val) goto out; @@ -1016,27 +1012,27 @@ STATIC s32 e1000_set_d3_lplu_state_82541(struct e1000_hw *hw, bool active) * SmartSpeed, so performance is maintained. */ if (phy->smart_speed == e1000_smart_speed_on) { - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &data); if (ret_val) goto out; data |= IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); if (ret_val) goto out; } else if (phy->smart_speed == e1000_smart_speed_off) { - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &data); if (ret_val) goto out; data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); if (ret_val) @@ -1046,19 +1042,19 @@ STATIC s32 e1000_set_d3_lplu_state_82541(struct e1000_hw *hw, bool active) (phy->autoneg_advertised == E1000_ALL_NOT_GIG) || (phy->autoneg_advertised == E1000_ALL_10_SPEED)) { data |= IGP01E1000_GMII_FLEX_SPD; - ret_val = e1000_write_phy_reg(hw, IGP01E1000_GMII_FIFO, data); + ret_val = phy->ops.write_reg(hw, IGP01E1000_GMII_FIFO, data); if (ret_val) goto out; /* When LPLU is enabled, we should disable SmartSpeed */ - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &data); if (ret_val) goto out; data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); } @@ -1075,7 +1071,7 @@ out: * of the LED so it can be later restored. This is a function pointer entry * point called by the api module. **/ -STATIC s32 e1000_setup_led_82541(struct e1000_hw *hw) +static s32 e1000_setup_led_82541(struct e1000_hw *hw) { struct e1000_dev_spec_82541 *dev_spec; s32 ret_val; @@ -1084,15 +1080,15 @@ STATIC s32 e1000_setup_led_82541(struct e1000_hw *hw) dev_spec = (struct e1000_dev_spec_82541 *)hw->dev_spec; - ret_val = e1000_read_phy_reg(hw, - IGP01E1000_GMII_FIFO, - &dev_spec->spd_default); + ret_val = hw->phy.ops.read_reg(hw, + IGP01E1000_GMII_FIFO, + &dev_spec->spd_default); if (ret_val) goto out; - ret_val = e1000_write_phy_reg(hw, - IGP01E1000_GMII_FIFO, - (u16)(dev_spec->spd_default & + ret_val = hw->phy.ops.write_reg(hw, + IGP01E1000_GMII_FIFO, + (u16)(dev_spec->spd_default & ~IGP01E1000_GMII_SPD)); if (ret_val) goto out; @@ -1111,7 +1107,7 @@ out: * to the default value, saved from the EEPROM. This is a function pointer * entry point called by the api module. **/ -STATIC s32 e1000_cleanup_led_82541(struct e1000_hw *hw) +static s32 e1000_cleanup_led_82541(struct e1000_hw *hw) { struct e1000_dev_spec_82541 *dev_spec; s32 ret_val; @@ -1120,9 +1116,9 @@ STATIC s32 e1000_cleanup_led_82541(struct e1000_hw *hw) dev_spec = (struct e1000_dev_spec_82541 *)hw->dev_spec; - ret_val = e1000_write_phy_reg(hw, - IGP01E1000_GMII_FIFO, - dev_spec->spd_default); + ret_val = hw->phy.ops.write_reg(hw, + IGP01E1000_GMII_FIFO, + dev_spec->spd_default); if (ret_val) goto out; @@ -1160,63 +1156,63 @@ static s32 e1000_phy_init_script_82541(struct e1000_hw *hw) * Save off the current value of register 0x2F5B to be restored at * the end of this routine. */ - ret_val = e1000_read_phy_reg(hw, 0x2F5B, &phy_saved_data); + ret_val = hw->phy.ops.read_reg(hw, 0x2F5B, &phy_saved_data); /* Disabled the PHY transmitter */ - e1000_write_phy_reg(hw, 0x2F5B, 0x0003); + hw->phy.ops.write_reg(hw, 0x2F5B, 0x0003); msec_delay(20); - e1000_write_phy_reg(hw, 0x0000, 0x0140); + hw->phy.ops.write_reg(hw, 0x0000, 0x0140); msec_delay(5); switch (hw->mac.type) { case e1000_82541: case e1000_82547: - e1000_write_phy_reg(hw, 0x1F95, 0x0001); + hw->phy.ops.write_reg(hw, 0x1F95, 0x0001); - e1000_write_phy_reg(hw, 0x1F71, 0xBD21); + hw->phy.ops.write_reg(hw, 0x1F71, 0xBD21); - e1000_write_phy_reg(hw, 0x1F79, 0x0018); + hw->phy.ops.write_reg(hw, 0x1F79, 0x0018); - e1000_write_phy_reg(hw, 0x1F30, 0x1600); + hw->phy.ops.write_reg(hw, 0x1F30, 0x1600); - e1000_write_phy_reg(hw, 0x1F31, 0x0014); + hw->phy.ops.write_reg(hw, 0x1F31, 0x0014); - e1000_write_phy_reg(hw, 0x1F32, 0x161C); + hw->phy.ops.write_reg(hw, 0x1F32, 0x161C); - e1000_write_phy_reg(hw, 0x1F94, 0x0003); + hw->phy.ops.write_reg(hw, 0x1F94, 0x0003); - e1000_write_phy_reg(hw, 0x1F96, 0x003F); + hw->phy.ops.write_reg(hw, 0x1F96, 0x003F); - e1000_write_phy_reg(hw, 0x2010, 0x0008); + hw->phy.ops.write_reg(hw, 0x2010, 0x0008); break; case e1000_82541_rev_2: case e1000_82547_rev_2: - e1000_write_phy_reg(hw, 0x1F73, 0x0099); + hw->phy.ops.write_reg(hw, 0x1F73, 0x0099); break; default: break; } - e1000_write_phy_reg(hw, 0x0000, 0x3300); + hw->phy.ops.write_reg(hw, 0x0000, 0x3300); msec_delay(20); /* Now enable the transmitter */ - e1000_write_phy_reg(hw, 0x2F5B, phy_saved_data); + hw->phy.ops.write_reg(hw, 0x2F5B, phy_saved_data); if (hw->mac.type == e1000_82547) { u16 fused, fine, coarse; /* Move to analog registers page */ - e1000_read_phy_reg(hw, + hw->phy.ops.read_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused); if (!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) { - e1000_read_phy_reg(hw, + hw->phy.ops.read_reg(hw, IGP01E1000_ANALOG_FUSE_STATUS, &fused); @@ -1234,10 +1230,10 @@ static s32 e1000_phy_init_script_82541(struct e1000_hw *hw) (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) | (coarse & IGP01E1000_ANALOG_FUSE_COARSE_MASK); - e1000_write_phy_reg(hw, + hw->phy.ops.write_reg(hw, IGP01E1000_ANALOG_FUSE_CONTROL, fused); - e1000_write_phy_reg(hw, + hw->phy.ops.write_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS, IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL); } @@ -1286,7 +1282,7 @@ out: * In the case of a PHY power down to save power, or to turn off link during a * driver unload, or wake on lan is not enabled, remove the link. **/ -STATIC void e1000_power_down_phy_copper_82541(struct e1000_hw *hw) +static void e1000_power_down_phy_copper_82541(struct e1000_hw *hw) { /* If the management interface is not enabled, then power down */ if (!(E1000_READ_REG(hw, E1000_MANC) & E1000_MANC_SMBUS_EN)) @@ -1301,7 +1297,7 @@ STATIC void e1000_power_down_phy_copper_82541(struct e1000_hw *hw) * * Clears the hardware counters by reading the counter registers. **/ -STATIC void e1000_clear_hw_cntrs_82541(struct e1000_hw *hw) +static void e1000_clear_hw_cntrs_82541(struct e1000_hw *hw) { volatile u32 temp; diff --git a/sys/dev/em/e1000_82542.c b/sys/dev/em/e1000_82542.c index 04f27f6..0f76202 100644 --- a/sys/dev/em/e1000_82542.c +++ b/sys/dev/em/e1000_82542.c @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,25 +29,25 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ /* e1000_82542 (rev 1 & 2) */ #include "e1000_api.h" -STATIC s32 e1000_init_phy_params_82542(struct e1000_hw *hw); -STATIC s32 e1000_init_nvm_params_82542(struct e1000_hw *hw); -STATIC s32 e1000_init_mac_params_82542(struct e1000_hw *hw); -STATIC s32 e1000_get_bus_info_82542(struct e1000_hw *hw); -STATIC s32 e1000_reset_hw_82542(struct e1000_hw *hw); -STATIC s32 e1000_init_hw_82542(struct e1000_hw *hw); -STATIC s32 e1000_setup_link_82542(struct e1000_hw *hw); -STATIC s32 e1000_led_on_82542(struct e1000_hw *hw); -STATIC s32 e1000_led_off_82542(struct e1000_hw *hw); -STATIC void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw); +static s32 e1000_init_phy_params_82542(struct e1000_hw *hw); +static s32 e1000_init_nvm_params_82542(struct e1000_hw *hw); +static s32 e1000_init_mac_params_82542(struct e1000_hw *hw); +static s32 e1000_get_bus_info_82542(struct e1000_hw *hw); +static s32 e1000_reset_hw_82542(struct e1000_hw *hw); +static s32 e1000_init_hw_82542(struct e1000_hw *hw); +static s32 e1000_setup_link_82542(struct e1000_hw *hw); +static s32 e1000_led_on_82542(struct e1000_hw *hw); +static s32 e1000_led_off_82542(struct e1000_hw *hw); +static void e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index); +static void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw); struct e1000_dev_spec_82542 { bool dma_fairness; @@ -59,7 +59,7 @@ struct e1000_dev_spec_82542 { * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_phy_params_82542(struct e1000_hw *hw) +static s32 e1000_init_phy_params_82542(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val = E1000_SUCCESS; @@ -77,10 +77,9 @@ STATIC s32 e1000_init_phy_params_82542(struct e1000_hw *hw) * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_nvm_params_82542(struct e1000_hw *hw) +static s32 e1000_init_nvm_params_82542(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; - struct e1000_functions *func = &hw->func; DEBUGFUNC("e1000_init_nvm_params_82542"); @@ -91,11 +90,11 @@ STATIC s32 e1000_init_nvm_params_82542(struct e1000_hw *hw) nvm->word_size = 64; /* Function Pointers */ - func->read_nvm = e1000_read_nvm_microwire; - func->release_nvm = e1000_stop_nvm; - func->write_nvm = e1000_write_nvm_microwire; - func->update_nvm = e1000_update_nvm_checksum_generic; - func->validate_nvm = e1000_validate_nvm_checksum_generic; + nvm->ops.read = e1000_read_nvm_microwire; + nvm->ops.release = e1000_stop_nvm; + nvm->ops.write = e1000_write_nvm_microwire; + nvm->ops.update = e1000_update_nvm_checksum_generic; + nvm->ops.validate = e1000_validate_nvm_checksum_generic; return E1000_SUCCESS; } @@ -106,10 +105,9 @@ STATIC s32 e1000_init_nvm_params_82542(struct e1000_hw *hw) * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_mac_params_82542(struct e1000_hw *hw) +static s32 e1000_init_mac_params_82542(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; - struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_init_mac_params_82542"); @@ -125,34 +123,36 @@ STATIC s32 e1000_init_mac_params_82542(struct e1000_hw *hw) /* Function pointers */ /* bus type/speed/width */ - func->get_bus_info = e1000_get_bus_info_82542; + mac->ops.get_bus_info = e1000_get_bus_info_82542; /* reset */ - func->reset_hw = e1000_reset_hw_82542; + mac->ops.reset_hw = e1000_reset_hw_82542; /* hw initialization */ - func->init_hw = e1000_init_hw_82542; + mac->ops.init_hw = e1000_init_hw_82542; /* link setup */ - func->setup_link = e1000_setup_link_82542; + mac->ops.setup_link = e1000_setup_link_82542; /* phy/fiber/serdes setup */ - func->setup_physical_interface = e1000_setup_fiber_serdes_link_generic; + mac->ops.setup_physical_interface = e1000_setup_fiber_serdes_link_generic; /* check for link */ - func->check_for_link = e1000_check_for_fiber_link_generic; + mac->ops.check_for_link = e1000_check_for_fiber_link_generic; /* multicast address update */ - func->update_mc_addr_list = e1000_update_mc_addr_list_generic; + mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; /* writing VFTA */ - func->write_vfta = e1000_write_vfta_generic; + mac->ops.write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ - func->clear_vfta = e1000_clear_vfta_generic; + mac->ops.clear_vfta = e1000_clear_vfta_generic; /* setting MTA */ - func->mta_set = e1000_mta_set_generic; + mac->ops.mta_set = e1000_mta_set_generic; + /* set RAR */ + mac->ops.rar_set = e1000_rar_set_82542; /* turn on/off LED */ - func->led_on = e1000_led_on_82542; - func->led_off = e1000_led_off_82542; + mac->ops.led_on = e1000_led_on_82542; + mac->ops.led_off = e1000_led_off_82542; /* remove device */ - func->remove_device = e1000_remove_device_generic; + mac->ops.remove_device = e1000_remove_device_generic; /* clear hardware counters */ - func->clear_hw_cntrs = e1000_clear_hw_cntrs_82542; + mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82542; /* link info */ - func->get_link_up_info = e1000_get_speed_and_duplex_fiber_serdes_generic; + mac->ops.get_link_up_info = e1000_get_speed_and_duplex_fiber_serdes_generic; hw->dev_spec_size = sizeof(struct e1000_dev_spec_82542); @@ -173,9 +173,9 @@ void e1000_init_function_pointers_82542(struct e1000_hw *hw) { DEBUGFUNC("e1000_init_function_pointers_82542"); - hw->func.init_mac_params = e1000_init_mac_params_82542; - hw->func.init_nvm_params = e1000_init_nvm_params_82542; - hw->func.init_phy_params = e1000_init_phy_params_82542; + hw->mac.ops.init_params = e1000_init_mac_params_82542; + hw->nvm.ops.init_params = e1000_init_nvm_params_82542; + hw->phy.ops.init_params = e1000_init_phy_params_82542; } /** @@ -186,7 +186,7 @@ void e1000_init_function_pointers_82542(struct e1000_hw *hw) * adapter is attached and stores it in the hw structure. This is a function * pointer entry point called by the api module. **/ -STATIC s32 e1000_get_bus_info_82542(struct e1000_hw *hw) +static s32 e1000_get_bus_info_82542(struct e1000_hw *hw) { DEBUGFUNC("e1000_get_bus_info_82542"); @@ -204,7 +204,7 @@ STATIC s32 e1000_get_bus_info_82542(struct e1000_hw *hw) * This resets the hardware into a known state. This is a * function pointer entry point called by the api module. **/ -STATIC s32 e1000_reset_hw_82542(struct e1000_hw *hw) +static s32 e1000_reset_hw_82542(struct e1000_hw *hw) { struct e1000_bus_info *bus = &hw->bus; s32 ret_val = E1000_SUCCESS; @@ -235,7 +235,7 @@ STATIC s32 e1000_reset_hw_82542(struct e1000_hw *hw) DEBUGOUT("Issuing a global reset to 82542/82543 MAC\n"); E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST); - e1000_reload_nvm(hw); + hw->nvm.ops.reload(hw); msec_delay(2); E1000_WRITE_REG(hw, E1000_IMC, 0xffffffff); @@ -256,7 +256,7 @@ STATIC s32 e1000_reset_hw_82542(struct e1000_hw *hw) * This inits the hardware readying it for operation. This is a * function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_hw_82542(struct e1000_hw *hw) +static s32 e1000_init_hw_82542(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; struct e1000_dev_spec_82542 *dev_spec; @@ -270,7 +270,7 @@ STATIC s32 e1000_init_hw_82542(struct e1000_hw *hw) /* Disabling VLAN filtering */ E1000_WRITE_REG(hw, E1000_VET, 0); - e1000_clear_vfta(hw); + mac->ops.clear_vfta(hw); /* For 82542 (rev 2.0), disable MWI and put the receiver into reset */ if (hw->revision_id == E1000_REVISION_2) { @@ -333,10 +333,9 @@ STATIC s32 e1000_init_hw_82542(struct e1000_hw *hw) * and the transmitter and receiver are not enabled. This is a function * pointer entry point called by the api module. **/ -STATIC s32 e1000_setup_link_82542(struct e1000_hw *hw) +static s32 e1000_setup_link_82542(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; - struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_setup_link_82542"); @@ -360,7 +359,7 @@ STATIC s32 e1000_setup_link_82542(struct e1000_hw *hw) DEBUGOUT1("After fix-ups FlowControl is now = %x\n", hw->fc.type); /* Call the necessary subroutine to configure the link. */ - ret_val = func->setup_physical_interface(hw); + ret_val = mac->ops.setup_physical_interface(hw); if (ret_val) goto out; @@ -391,7 +390,7 @@ out: * Turns the SW defined LED on. This is a function pointer entry point * called by the api module. **/ -STATIC s32 e1000_led_on_82542(struct e1000_hw *hw) +static s32 e1000_led_on_82542(struct e1000_hw *hw) { u32 ctrl = E1000_READ_REG(hw, E1000_CTRL); @@ -411,7 +410,7 @@ STATIC s32 e1000_led_on_82542(struct e1000_hw *hw) * Turns the SW defined LED off. This is a function pointer entry point * called by the api module. **/ -STATIC s32 e1000_led_off_82542(struct e1000_hw *hw) +static s32 e1000_led_off_82542(struct e1000_hw *hw) { u32 ctrl = E1000_READ_REG(hw, E1000_CTRL); @@ -425,6 +424,41 @@ STATIC s32 e1000_led_off_82542(struct e1000_hw *hw) } /** + * e1000_rar_set_82542 - Set receive address register + * @hw: pointer to the HW structure + * @addr: pointer to the receive address + * @index: receive address array register + * + * Sets the receive address array register at index to the address passed + * in by addr. + **/ +static void e1000_rar_set_82542(struct e1000_hw *hw, u8 *addr, u32 index) +{ + u32 rar_low, rar_high; + + DEBUGFUNC("e1000_rar_set_82542"); + + /* + * HW expects these in little endian so we reverse the byte order + * from network order (big endian) to little endian + */ + rar_low = ((u32) addr[0] | + ((u32) addr[1] << 8) | + ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); + + rar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); + + /* If MAC address zero, no need to set the AV bit */ + if (rar_low || rar_high) { + if (!hw->mac.disable_av) + rar_high |= E1000_RAH_AV; + } + + E1000_WRITE_REG_ARRAY(hw, E1000_RA, (index << 1), rar_low); + E1000_WRITE_REG_ARRAY(hw, E1000_RA, ((index << 1) + 1), rar_high); +} + +/** * e1000_translate_register_82542 - Translate the proper register offset * @reg: e1000 register to be read * @@ -527,7 +561,7 @@ u32 e1000_translate_register_82542(u32 reg) * * Clears the hardware counters by reading the counter registers. **/ -STATIC void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw) +static void e1000_clear_hw_cntrs_82542(struct e1000_hw *hw) { volatile u32 temp; diff --git a/sys/dev/em/e1000_82543.c b/sys/dev/em/e1000_82543.c index 5a4fdbc..1312a8f 100644 --- a/sys/dev/em/e1000_82543.c +++ b/sys/dev/em/e1000_82543.c @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,9 +29,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ /* e1000_82543 * e1000_82544 @@ -40,28 +39,28 @@ #include "e1000_api.h" #include "e1000_82543.h" -STATIC s32 e1000_init_phy_params_82543(struct e1000_hw *hw); -STATIC s32 e1000_init_nvm_params_82543(struct e1000_hw *hw); -STATIC s32 e1000_init_mac_params_82543(struct e1000_hw *hw); -STATIC s32 e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset, +static s32 e1000_init_phy_params_82543(struct e1000_hw *hw); +static s32 e1000_init_nvm_params_82543(struct e1000_hw *hw); +static s32 e1000_init_mac_params_82543(struct e1000_hw *hw); +static s32 e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 *data); -STATIC s32 e1000_write_phy_reg_82543(struct e1000_hw *hw, u32 offset, +static s32 e1000_write_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 data); -STATIC s32 e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw); -STATIC s32 e1000_phy_hw_reset_82543(struct e1000_hw *hw); -STATIC s32 e1000_reset_hw_82543(struct e1000_hw *hw); -STATIC s32 e1000_init_hw_82543(struct e1000_hw *hw); -STATIC s32 e1000_setup_link_82543(struct e1000_hw *hw); -STATIC s32 e1000_setup_copper_link_82543(struct e1000_hw *hw); -STATIC s32 e1000_setup_fiber_link_82543(struct e1000_hw *hw); -STATIC s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw); -STATIC s32 e1000_check_for_fiber_link_82543(struct e1000_hw *hw); -STATIC s32 e1000_led_on_82543(struct e1000_hw *hw); -STATIC s32 e1000_led_off_82543(struct e1000_hw *hw); -STATIC void e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, +static s32 e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw); +static s32 e1000_phy_hw_reset_82543(struct e1000_hw *hw); +static s32 e1000_reset_hw_82543(struct e1000_hw *hw); +static s32 e1000_init_hw_82543(struct e1000_hw *hw); +static s32 e1000_setup_link_82543(struct e1000_hw *hw); +static s32 e1000_setup_copper_link_82543(struct e1000_hw *hw); +static s32 e1000_setup_fiber_link_82543(struct e1000_hw *hw); +static s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw); +static s32 e1000_check_for_fiber_link_82543(struct e1000_hw *hw); +static s32 e1000_led_on_82543(struct e1000_hw *hw); +static s32 e1000_led_off_82543(struct e1000_hw *hw); +static void e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, u32 value); -STATIC void e1000_mta_set_82543(struct e1000_hw *hw, u32 hash_value); -STATIC void e1000_clear_hw_cntrs_82543(struct e1000_hw *hw); +static void e1000_mta_set_82543(struct e1000_hw *hw, u32 hash_value); +static void e1000_clear_hw_cntrs_82543(struct e1000_hw *hw); static s32 e1000_config_mac_to_phy_82543(struct e1000_hw *hw); static bool e1000_init_phy_disabled_82543(struct e1000_hw *hw); static void e1000_lower_mdi_clk_82543(struct e1000_hw *hw, u32 *ctrl); @@ -85,10 +84,9 @@ struct e1000_dev_spec_82543 { * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_phy_params_82543(struct e1000_hw *hw) +static s32 e1000_init_phy_params_82543(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_init_phy_params_82543"); @@ -97,8 +95,8 @@ STATIC s32 e1000_init_phy_params_82543(struct e1000_hw *hw) phy->type = e1000_phy_none; goto out; } else { - func->power_up_phy = e1000_power_up_phy_copper; - func->power_down_phy = e1000_power_down_phy_copper; + phy->ops.power_up = e1000_power_up_phy_copper; + phy->ops.power_down = e1000_power_down_phy_copper; } phy->addr = 1; @@ -107,21 +105,21 @@ STATIC s32 e1000_init_phy_params_82543(struct e1000_hw *hw) phy->type = e1000_phy_m88; /* Function Pointers */ - func->check_polarity = e1000_check_polarity_m88; - func->commit_phy = e1000_phy_sw_reset_generic; - func->force_speed_duplex = e1000_phy_force_speed_duplex_82543; - func->get_cable_length = e1000_get_cable_length_m88; - func->get_cfg_done = e1000_get_cfg_done_generic; - func->read_phy_reg = (hw->mac.type == e1000_82543) + phy->ops.check_polarity = e1000_check_polarity_m88; + phy->ops.commit = e1000_phy_sw_reset_generic; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_82543; + phy->ops.get_cable_length = e1000_get_cable_length_m88; + phy->ops.get_cfg_done = e1000_get_cfg_done_generic; + phy->ops.read_reg = (hw->mac.type == e1000_82543) ? e1000_read_phy_reg_82543 : e1000_read_phy_reg_m88; - func->reset_phy = (hw->mac.type == e1000_82543) + phy->ops.reset = (hw->mac.type == e1000_82543) ? e1000_phy_hw_reset_82543 : e1000_phy_hw_reset_generic; - func->write_phy_reg = (hw->mac.type == e1000_82543) + phy->ops.write_reg = (hw->mac.type == e1000_82543) ? e1000_write_phy_reg_82543 : e1000_write_phy_reg_m88; - func->get_phy_info = e1000_get_phy_info_m88; + phy->ops.get_info = e1000_get_phy_info_m88; /* * The external PHY of the 82543 can be in a funky state. @@ -129,7 +127,7 @@ STATIC s32 e1000_init_phy_params_82543(struct e1000_hw *hw) * the PHY ID. */ if (!e1000_init_phy_disabled_82543(hw)) { - ret_val = e1000_phy_hw_reset(hw); + ret_val = phy->ops.reset(hw); if (ret_val) { DEBUGOUT("Resetting PHY during init failed.\n"); goto out; @@ -171,10 +169,9 @@ out: * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_nvm_params_82543(struct e1000_hw *hw) +static s32 e1000_init_nvm_params_82543(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; - struct e1000_functions *func = &hw->func; DEBUGFUNC("e1000_init_nvm_params_82543"); @@ -185,11 +182,11 @@ STATIC s32 e1000_init_nvm_params_82543(struct e1000_hw *hw) nvm->opcode_bits = 3; /* Function Pointers */ - func->read_nvm = e1000_read_nvm_microwire; - func->update_nvm = e1000_update_nvm_checksum_generic; - func->valid_led_default = e1000_valid_led_default_generic; - func->validate_nvm = e1000_validate_nvm_checksum_generic; - func->write_nvm = e1000_write_nvm_microwire; + nvm->ops.read = e1000_read_nvm_microwire; + nvm->ops.update = e1000_update_nvm_checksum_generic; + nvm->ops.valid_led_default = e1000_valid_led_default_generic; + nvm->ops.validate = e1000_validate_nvm_checksum_generic; + nvm->ops.write = e1000_write_nvm_microwire; return E1000_SUCCESS; } @@ -200,10 +197,9 @@ STATIC s32 e1000_init_nvm_params_82543(struct e1000_hw *hw) * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_mac_params_82543(struct e1000_hw *hw) +static s32 e1000_init_mac_params_82543(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; - struct e1000_functions *func = &hw->func; s32 ret_val; DEBUGFUNC("e1000_init_mac_params_82543"); @@ -227,43 +223,43 @@ STATIC s32 e1000_init_mac_params_82543(struct e1000_hw *hw) /* Function pointers */ /* bus type/speed/width */ - func->get_bus_info = e1000_get_bus_info_pci_generic; + mac->ops.get_bus_info = e1000_get_bus_info_pci_generic; /* reset */ - func->reset_hw = e1000_reset_hw_82543; + mac->ops.reset_hw = e1000_reset_hw_82543; /* hw initialization */ - func->init_hw = e1000_init_hw_82543; + mac->ops.init_hw = e1000_init_hw_82543; /* link setup */ - func->setup_link = e1000_setup_link_82543; + mac->ops.setup_link = e1000_setup_link_82543; /* physical interface setup */ - func->setup_physical_interface = + mac->ops.setup_physical_interface = (hw->phy.media_type == e1000_media_type_copper) ? e1000_setup_copper_link_82543 : e1000_setup_fiber_link_82543; /* check for link */ - func->check_for_link = + mac->ops.check_for_link = (hw->phy.media_type == e1000_media_type_copper) ? e1000_check_for_copper_link_82543 : e1000_check_for_fiber_link_82543; /* link info */ - func->get_link_up_info = + mac->ops.get_link_up_info = (hw->phy.media_type == e1000_media_type_copper) ? e1000_get_speed_and_duplex_copper_generic : e1000_get_speed_and_duplex_fiber_serdes_generic; /* multicast address update */ - func->update_mc_addr_list = e1000_update_mc_addr_list_generic; + mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; /* writing VFTA */ - func->write_vfta = e1000_write_vfta_82543; + mac->ops.write_vfta = e1000_write_vfta_82543; /* clearing VFTA */ - func->clear_vfta = e1000_clear_vfta_generic; + mac->ops.clear_vfta = e1000_clear_vfta_generic; /* setting MTA */ - func->mta_set = e1000_mta_set_82543; + mac->ops.mta_set = e1000_mta_set_82543; /* turn on/off LED */ - func->led_on = e1000_led_on_82543; - func->led_off = e1000_led_off_82543; + mac->ops.led_on = e1000_led_on_82543; + mac->ops.led_off = e1000_led_off_82543; /* remove device */ - func->remove_device = e1000_remove_device_generic; + mac->ops.remove_device = e1000_remove_device_generic; /* clear hardware counters */ - func->clear_hw_cntrs = e1000_clear_hw_cntrs_82543; + mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82543; hw->dev_spec_size = sizeof(struct e1000_dev_spec_82543); @@ -292,9 +288,9 @@ void e1000_init_function_pointers_82543(struct e1000_hw *hw) { DEBUGFUNC("e1000_init_function_pointers_82543"); - hw->func.init_mac_params = e1000_init_mac_params_82543; - hw->func.init_nvm_params = e1000_init_nvm_params_82543; - hw->func.init_phy_params = e1000_init_phy_params_82543; + hw->mac.ops.init_params = e1000_init_mac_params_82543; + hw->nvm.ops.init_params = e1000_init_nvm_params_82543; + hw->phy.ops.init_params = e1000_init_phy_params_82543; } /** @@ -425,7 +421,7 @@ static void e1000_set_tbi_sbp_82543(struct e1000_hw *hw, bool state) * @hw: pointer to the HW structure * * Returns the current status of whether PHY initialization is disabled. - * True if PHY initialization is disabled else false. + * True if PHY initialization is disabled else FALSE. **/ static bool e1000_init_phy_disabled_82543(struct e1000_hw *hw) { @@ -539,7 +535,7 @@ out: * * Reads the PHY at offset and stores the information read to data. **/ -STATIC s32 e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 *data) +static s32 e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 *data) { u32 mdic; s32 ret_val = E1000_SUCCESS; @@ -595,7 +591,7 @@ out: * * Writes data to the PHY at offset. **/ -STATIC s32 e1000_write_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 data) +static s32 e1000_write_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 data) { u32 mdic; s32 ret_val = E1000_SUCCESS; @@ -791,7 +787,7 @@ static u16 e1000_shift_in_mdi_bits_82543(struct e1000_hw *hw) * if the PHY is not auto-negotiating and the speed is forced to 10Mbit, * then call the function for polarity reversal workaround. **/ -STATIC s32 e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw) +static s32 e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw) { s32 ret_val; @@ -819,23 +815,26 @@ out: **/ static s32 e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw) { - s32 ret_val; + s32 ret_val = E1000_SUCCESS; u16 mii_status_reg; u16 i; bool link; + if (!(hw->phy.ops.write_reg)) + goto out; + /* Polarity reversal workaround for forced 10F/10H links. */ /* Disable the transmitter on the PHY */ - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019); + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019); if (ret_val) goto out; - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF); + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFFF); if (ret_val) goto out; - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000); + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000); if (ret_val) goto out; @@ -849,11 +848,11 @@ static s32 e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw) * to be clear. */ - ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); + ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg); if (ret_val) goto out; - ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); + ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &mii_status_reg); if (ret_val) goto out; @@ -867,23 +866,23 @@ static s32 e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw) /* Now we will re-enable the transmitter on the PHY */ - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019); + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0019); if (ret_val) goto out; msec_delay_irq(50); - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0); + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFFF0); if (ret_val) goto out; msec_delay_irq(50); - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00); + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xFF00); if (ret_val) goto out; msec_delay_irq(50); - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000); + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0x0000); if (ret_val) goto out; - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000); + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x0000); if (ret_val) goto out; @@ -908,9 +907,8 @@ out: * has been accomplished, clear the PHY_RESET_DIR bit to take the PHY out * of reset. This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_phy_hw_reset_82543(struct e1000_hw *hw) +static s32 e1000_phy_hw_reset_82543(struct e1000_hw *hw) { - struct e1000_functions *func = &hw->func; u32 ctrl_ext; s32 ret_val; @@ -935,7 +933,10 @@ STATIC s32 e1000_phy_hw_reset_82543(struct e1000_hw *hw) usec_delay(150); - ret_val = func->get_cfg_done(hw); + if (!(hw->phy.ops.get_cfg_done)) + return E1000_SUCCESS; + + ret_val = hw->phy.ops.get_cfg_done(hw); return ret_val; } @@ -947,7 +948,7 @@ STATIC s32 e1000_phy_hw_reset_82543(struct e1000_hw *hw) * This resets the hardware into a known state. This is a * function pointer entry point called by the api module. **/ -STATIC s32 e1000_reset_hw_82543(struct e1000_hw *hw) +static s32 e1000_reset_hw_82543(struct e1000_hw *hw) { u32 ctrl, icr; s32 ret_val = E1000_SUCCESS; @@ -986,7 +987,7 @@ STATIC s32 e1000_reset_hw_82543(struct e1000_hw *hw) * After MAC reset, force reload of NVM to restore power-on * settings to device. */ - e1000_reload_nvm(hw); + hw->nvm.ops.reload(hw); msec_delay(2); /* Masking off and clearing any pending interrupts */ @@ -1002,7 +1003,7 @@ STATIC s32 e1000_reset_hw_82543(struct e1000_hw *hw) * * This inits the hardware readying it for operation. **/ -STATIC s32 e1000_init_hw_82543(struct e1000_hw *hw) +static s32 e1000_init_hw_82543(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; struct e1000_dev_spec_82543 *dev_spec; @@ -1022,7 +1023,7 @@ STATIC s32 e1000_init_hw_82543(struct e1000_hw *hw) /* Disabling VLAN filtering */ E1000_WRITE_REG(hw, E1000_VET, 0); - e1000_clear_vfta(hw); + mac->ops.clear_vfta(hw); /* Setup the receive address. */ e1000_init_rx_addrs_generic(hw, mac->rar_entry_count); @@ -1047,7 +1048,7 @@ STATIC s32 e1000_init_hw_82543(struct e1000_hw *hw) e1000_pcix_mmrbc_workaround_generic(hw); /* Setup link and flow control */ - ret_val = e1000_setup_link(hw); + ret_val = mac->ops.setup_link(hw); /* * Clear all of the statistics registers (clear on read). It is @@ -1074,7 +1075,7 @@ out: * should be established. Assumes the hardware has previously been reset * and the transmitter and receiver are not enabled. **/ -STATIC s32 e1000_setup_link_82543(struct e1000_hw *hw) +static s32 e1000_setup_link_82543(struct e1000_hw *hw) { u32 ctrl_ext; s32 ret_val; @@ -1090,7 +1091,7 @@ STATIC s32 e1000_setup_link_82543(struct e1000_hw *hw) * signal detection. So this should be done before phy setup. */ if (hw->mac.type == e1000_82543) { - ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); + ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &data); if (ret_val) { DEBUGOUT("NVM Read Error\n"); ret_val = -E1000_ERR_NVM; @@ -1115,7 +1116,7 @@ out: * for link, once link is established calls to configure collision distance * and flow control are called. **/ -STATIC s32 e1000_setup_copper_link_82543(struct e1000_hw *hw) +static s32 e1000_setup_copper_link_82543(struct e1000_hw *hw) { u32 ctrl; s32 ret_val; @@ -1133,7 +1134,7 @@ STATIC s32 e1000_setup_copper_link_82543(struct e1000_hw *hw) if (hw->mac.type == e1000_82543) { ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); E1000_WRITE_REG(hw, E1000_CTRL, ctrl); - ret_val = e1000_phy_hw_reset(hw); + ret_val = hw->phy.ops.reset(hw); if (ret_val) goto out; hw->phy.reset_disable = FALSE; @@ -1206,7 +1207,7 @@ out: * Configures collision distance and flow control for fiber links. Upon * successful setup, poll for link. **/ -STATIC s32 e1000_setup_fiber_link_82543(struct e1000_hw *hw) +static s32 e1000_setup_fiber_link_82543(struct e1000_hw *hw) { u32 ctrl; s32 ret_val; @@ -1256,7 +1257,7 @@ out: * - configure flow control after link up * - configure tbi compatibility **/ -STATIC s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw) +static s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 icr, rctl; @@ -1346,7 +1347,7 @@ STATIC s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw) * at gigabit speed, we turn on TBI compatibility. */ if (e1000_tbi_compatibility_enabled_82543(hw)) { - ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex); + ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex); if (ret_val) { DEBUGOUT("Error getting link speed and duplex\n"); return ret_val; @@ -1393,7 +1394,7 @@ out: * Checks for link up on the hardware. If link is not up and we have * a signal, then we need to force link up. **/ -STATIC s32 e1000_check_for_fiber_link_82543(struct e1000_hw *hw) +static s32 e1000_check_for_fiber_link_82543(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 rxcw, ctrl, status; @@ -1466,11 +1467,14 @@ out: static s32 e1000_config_mac_to_phy_82543(struct e1000_hw *hw) { u32 ctrl; - s32 ret_val; + s32 ret_val = E1000_SUCCESS; u16 phy_data; DEBUGFUNC("e1000_config_mac_to_phy_82543"); + if (!(hw->phy.ops.read_reg)) + goto out; + /* Set the bits to force speed and duplex */ ctrl = E1000_READ_REG(hw, E1000_CTRL); ctrl |= (E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX); @@ -1480,7 +1484,7 @@ static s32 e1000_config_mac_to_phy_82543(struct e1000_hw *hw) * Set up duplex in the Device Control and Transmit Control * registers depending on negotiated values. */ - ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); + ret_val = hw->phy.ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); if (ret_val) goto out; @@ -1514,7 +1518,7 @@ out: * This writes a 32-bit value to a 32-bit offset in the VLAN filter * table. **/ -STATIC void e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, u32 value) +static void e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, u32 value) { u32 temp; @@ -1541,7 +1545,7 @@ STATIC void e1000_write_vfta_82543(struct e1000_hw *hw, u32 offset, u32 value) * current value is read, the new bit is OR'd in and the new value is * written back into the register. **/ -STATIC void e1000_mta_set_82543(struct e1000_hw *hw, u32 hash_value) +static void e1000_mta_set_82543(struct e1000_hw *hw, u32 hash_value) { u32 hash_bit, hash_reg, mta, temp; @@ -1577,7 +1581,7 @@ STATIC void e1000_mta_set_82543(struct e1000_hw *hw, u32 hash_value) * Turns the SW defined LED on. This is a function pointer entry point * called by the api module. **/ -STATIC s32 e1000_led_on_82543(struct e1000_hw *hw) +static s32 e1000_led_on_82543(struct e1000_hw *hw) { u32 ctrl = E1000_READ_REG(hw, E1000_CTRL); @@ -1605,7 +1609,7 @@ STATIC s32 e1000_led_on_82543(struct e1000_hw *hw) * Turns the SW defined LED off. This is a function pointer entry point * called by the api module. **/ -STATIC s32 e1000_led_off_82543(struct e1000_hw *hw) +static s32 e1000_led_off_82543(struct e1000_hw *hw) { u32 ctrl = E1000_READ_REG(hw, E1000_CTRL); @@ -1631,7 +1635,7 @@ STATIC s32 e1000_led_off_82543(struct e1000_hw *hw) * * Clears the hardware counters by reading the counter registers. **/ -STATIC void e1000_clear_hw_cntrs_82543(struct e1000_hw *hw) +static void e1000_clear_hw_cntrs_82543(struct e1000_hw *hw) { volatile u32 temp; diff --git a/sys/dev/em/e1000_82571.c b/sys/dev/em/e1000_82571.c index 8d9d32a..7a2e209 100644 --- a/sys/dev/em/e1000_82571.c +++ b/sys/dev/em/e1000_82571.c @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,9 +29,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ /* e1000_82571 * e1000_82572 @@ -42,29 +41,29 @@ #include "e1000_api.h" #include "e1000_82571.h" -STATIC s32 e1000_init_phy_params_82571(struct e1000_hw *hw); -STATIC s32 e1000_init_nvm_params_82571(struct e1000_hw *hw); -STATIC s32 e1000_init_mac_params_82571(struct e1000_hw *hw); -STATIC s32 e1000_acquire_nvm_82571(struct e1000_hw *hw); -STATIC void e1000_release_nvm_82571(struct e1000_hw *hw); -STATIC s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, +static s32 e1000_init_phy_params_82571(struct e1000_hw *hw); +static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw); +static s32 e1000_init_mac_params_82571(struct e1000_hw *hw); +static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw); +static void e1000_release_nvm_82571(struct e1000_hw *hw); +static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); -STATIC s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw); -STATIC s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw); -STATIC s32 e1000_get_cfg_done_82571(struct e1000_hw *hw); -STATIC s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, +static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw); +static s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw); +static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw); +static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active); -STATIC s32 e1000_reset_hw_82571(struct e1000_hw *hw); -STATIC s32 e1000_init_hw_82571(struct e1000_hw *hw); -STATIC void e1000_clear_vfta_82571(struct e1000_hw *hw); -STATIC void e1000_update_mc_addr_list_82571(struct e1000_hw *hw, +static s32 e1000_reset_hw_82571(struct e1000_hw *hw); +static s32 e1000_init_hw_82571(struct e1000_hw *hw); +static void e1000_clear_vfta_82571(struct e1000_hw *hw); +static void e1000_update_mc_addr_list_82571(struct e1000_hw *hw, u8 *mc_addr_list, u32 mc_addr_count, u32 rar_used_count, u32 rar_count); -STATIC s32 e1000_setup_link_82571(struct e1000_hw *hw); -STATIC s32 e1000_setup_copper_link_82571(struct e1000_hw *hw); -STATIC s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw); -STATIC s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data); -STATIC void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw); +static s32 e1000_setup_link_82571(struct e1000_hw *hw); +static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw); +static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw); +static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data); +static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw); static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw); static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw); static s32 e1000_get_phy_id_82571(struct e1000_hw *hw); @@ -72,8 +71,8 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw); static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); -STATIC s32 e1000_read_mac_addr_82571(struct e1000_hw *hw); -STATIC void e1000_power_down_phy_copper_82571(struct e1000_hw *hw); +static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw); +static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw); struct e1000_dev_spec_82571 { bool laa_is_present; @@ -85,10 +84,9 @@ struct e1000_dev_spec_82571 { * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_phy_params_82571(struct e1000_hw *hw) +static s32 e1000_init_phy_params_82571(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_init_phy_params_82571"); @@ -102,26 +100,26 @@ STATIC s32 e1000_init_phy_params_82571(struct e1000_hw *hw) phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; phy->reset_delay_us = 100; - func->acquire_phy = e1000_get_hw_semaphore_82571; - func->check_polarity = e1000_check_polarity_igp; - func->check_reset_block = e1000_check_reset_block_generic; - func->release_phy = e1000_put_hw_semaphore_82571; - func->reset_phy = e1000_phy_hw_reset_generic; - func->set_d0_lplu_state = e1000_set_d0_lplu_state_82571; - func->set_d3_lplu_state = e1000_set_d3_lplu_state_generic; - func->power_up_phy = e1000_power_up_phy_copper; - func->power_down_phy = e1000_power_down_phy_copper_82571; + phy->ops.acquire = e1000_get_hw_semaphore_82571; + phy->ops.check_polarity = e1000_check_polarity_igp; + phy->ops.check_reset_block = e1000_check_reset_block_generic; + phy->ops.release = e1000_put_hw_semaphore_82571; + phy->ops.reset = e1000_phy_hw_reset_generic; + phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_82571; + phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_generic; + phy->ops.power_up = e1000_power_up_phy_copper; + phy->ops.power_down = e1000_power_down_phy_copper_82571; switch (hw->mac.type) { case e1000_82571: case e1000_82572: - phy->type = e1000_phy_igp_2; - func->get_cfg_done = e1000_get_cfg_done_82571; - func->get_phy_info = e1000_get_phy_info_igp; - func->force_speed_duplex = e1000_phy_force_speed_duplex_igp; - func->get_cable_length = e1000_get_cable_length_igp_2; - func->read_phy_reg = e1000_read_phy_reg_igp; - func->write_phy_reg = e1000_write_phy_reg_igp; + phy->type = e1000_phy_igp_2; + phy->ops.get_cfg_done = e1000_get_cfg_done_82571; + phy->ops.get_info = e1000_get_phy_info_igp; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_igp; + phy->ops.get_cable_length = e1000_get_cable_length_igp_2; + phy->ops.read_reg = e1000_read_phy_reg_igp; + phy->ops.write_reg = e1000_write_phy_reg_igp; /* This uses above function pointers */ ret_val = e1000_get_phy_id_82571(hw); @@ -133,14 +131,14 @@ STATIC s32 e1000_init_phy_params_82571(struct e1000_hw *hw) } break; case e1000_82573: - phy->type = e1000_phy_m88; - func->get_cfg_done = e1000_get_cfg_done_generic; - func->get_phy_info = e1000_get_phy_info_m88; - func->commit_phy = e1000_phy_sw_reset_generic; - func->force_speed_duplex = e1000_phy_force_speed_duplex_m88; - func->get_cable_length = e1000_get_cable_length_m88; - func->read_phy_reg = e1000_read_phy_reg_m88; - func->write_phy_reg = e1000_write_phy_reg_m88; + phy->type = e1000_phy_m88; + phy->ops.get_cfg_done = e1000_get_cfg_done_generic; + phy->ops.get_info = e1000_get_phy_info_m88; + phy->ops.commit = e1000_phy_sw_reset_generic; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; + phy->ops.get_cable_length = e1000_get_cable_length_m88; + phy->ops.read_reg = e1000_read_phy_reg_m88; + phy->ops.write_reg = e1000_write_phy_reg_m88; /* This uses above function pointers */ ret_val = e1000_get_phy_id_82571(hw); @@ -152,25 +150,6 @@ STATIC s32 e1000_init_phy_params_82571(struct e1000_hw *hw) goto out; } break; - case e1000_82574: - phy->type = e1000_phy_bm; - func->get_cfg_done = e1000_get_cfg_done_generic; - func->get_phy_info = e1000_get_phy_info_m88; - func->commit_phy = e1000_phy_sw_reset_generic; - func->force_speed_duplex = e1000_phy_force_speed_duplex_m88; - func->get_cable_length = e1000_get_cable_length_m88; - func->read_phy_reg = e1000_read_phy_reg_bm2; - func->write_phy_reg = e1000_write_phy_reg_bm2; - - /* This uses above function pointers */ - ret_val = e1000_get_phy_id_82571(hw); - /* Verify PHY ID */ - if (phy->id != BME1000_E_PHY_ID_R2) { - ret_val = -E1000_ERR_PHY; - DEBUGOUT1("PHY ID unknown: type = 0x%08x\n", phy->id); - goto out; - } - break; default: ret_val = -E1000_ERR_PHY; goto out; @@ -187,10 +166,9 @@ out: * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) +static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; - struct e1000_functions *func = &hw->func; u32 eecd = E1000_READ_REG(hw, E1000_EECD); u16 size; @@ -215,7 +193,6 @@ STATIC s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) switch (hw->mac.type) { case e1000_82573: - case e1000_82574: if (((eecd >> 15) & 0x3) == 0x3) { nvm->type = e1000_nvm_flash_hw; nvm->word_size = 2048; @@ -246,13 +223,13 @@ STATIC s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) } /* Function Pointers */ - func->acquire_nvm = e1000_acquire_nvm_82571; - func->read_nvm = e1000_read_nvm_eerd; - func->release_nvm = e1000_release_nvm_82571; - func->update_nvm = e1000_update_nvm_checksum_82571; - func->validate_nvm = e1000_validate_nvm_checksum_82571; - func->valid_led_default = e1000_valid_led_default_82571; - func->write_nvm = e1000_write_nvm_82571; + nvm->ops.acquire = e1000_acquire_nvm_82571; + nvm->ops.read = e1000_read_nvm_eerd; + nvm->ops.release = e1000_release_nvm_82571; + nvm->ops.update = e1000_update_nvm_checksum_82571; + nvm->ops.validate = e1000_validate_nvm_checksum_82571; + nvm->ops.valid_led_default = e1000_valid_led_default_82571; + nvm->ops.write = e1000_write_nvm_82571; return E1000_SUCCESS; } @@ -263,10 +240,9 @@ STATIC s32 e1000_init_nvm_params_82571(struct e1000_hw *hw) * * This is a function pointer entry point called by the api module. **/ -STATIC s32 e1000_init_mac_params_82571(struct e1000_hw *hw) +static s32 e1000_init_mac_params_82571(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; - struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_init_mac_params_82571"); @@ -303,28 +279,28 @@ STATIC s32 e1000_init_mac_params_82571(struct e1000_hw *hw) /* Function pointers */ /* bus type/speed/width */ - func->get_bus_info = e1000_get_bus_info_pcie_generic; + mac->ops.get_bus_info = e1000_get_bus_info_pcie_generic; /* reset */ - func->reset_hw = e1000_reset_hw_82571; + mac->ops.reset_hw = e1000_reset_hw_82571; /* hw initialization */ - func->init_hw = e1000_init_hw_82571; + mac->ops.init_hw = e1000_init_hw_82571; /* link setup */ - func->setup_link = e1000_setup_link_82571; + mac->ops.setup_link = e1000_setup_link_82571; /* physical interface link setup */ - func->setup_physical_interface = + mac->ops.setup_physical_interface = (hw->phy.media_type == e1000_media_type_copper) ? e1000_setup_copper_link_82571 : e1000_setup_fiber_serdes_link_82571; /* check for link */ switch (hw->phy.media_type) { case e1000_media_type_copper: - func->check_for_link = e1000_check_for_copper_link_generic; + mac->ops.check_for_link = e1000_check_for_copper_link_generic; break; case e1000_media_type_fiber: - func->check_for_link = e1000_check_for_fiber_link_generic; + mac->ops.check_for_link = e1000_check_for_fiber_link_generic; break; case e1000_media_type_internal_serdes: - func->check_for_link = e1000_check_for_serdes_link_generic; + mac->ops.check_for_link = e1000_check_for_serdes_link_generic; break; default: ret_val = -E1000_ERR_CONFIG; @@ -332,32 +308,32 @@ STATIC s32 e1000_init_mac_params_82571(struct e1000_hw *hw) break; } /* check management mode */ - func->check_mng_mode = e1000_check_mng_mode_generic; + mac->ops.check_mng_mode = e1000_check_mng_mode_generic; /* multicast address update */ - func->update_mc_addr_list = e1000_update_mc_addr_list_82571; + mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_82571; /* writing VFTA */ - func->write_vfta = e1000_write_vfta_generic; + mac->ops.write_vfta = e1000_write_vfta_generic; /* clearing VFTA */ - func->clear_vfta = e1000_clear_vfta_82571; + mac->ops.clear_vfta = e1000_clear_vfta_82571; /* setting MTA */ - func->mta_set = e1000_mta_set_generic; + mac->ops.mta_set = e1000_mta_set_generic; /* read mac address */ - func->read_mac_addr = e1000_read_mac_addr_82571; + mac->ops.read_mac_addr = e1000_read_mac_addr_82571; /* blink LED */ - func->blink_led = e1000_blink_led_generic; + mac->ops.blink_led = e1000_blink_led_generic; /* setup LED */ - func->setup_led = e1000_setup_led_generic; + mac->ops.setup_led = e1000_setup_led_generic; /* cleanup LED */ - func->cleanup_led = e1000_cleanup_led_generic; + mac->ops.cleanup_led = e1000_cleanup_led_generic; /* turn on/off LED */ - func->led_on = e1000_led_on_generic; - func->led_off = e1000_led_off_generic; + mac->ops.led_on = e1000_led_on_generic; + mac->ops.led_off = e1000_led_off_generic; /* remove device */ - func->remove_device = e1000_remove_device_generic; + mac->ops.remove_device = e1000_remove_device_generic; /* clear hardware counters */ - func->clear_hw_cntrs = e1000_clear_hw_cntrs_82571; + mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_82571; /* link info */ - func->get_link_up_info = + mac->ops.get_link_up_info = (hw->phy.media_type == e1000_media_type_copper) ? e1000_get_speed_and_duplex_copper_generic : e1000_get_speed_and_duplex_fiber_serdes_generic; @@ -382,9 +358,9 @@ void e1000_init_function_pointers_82571(struct e1000_hw *hw) { DEBUGFUNC("e1000_init_function_pointers_82571"); - hw->func.init_mac_params = e1000_init_mac_params_82571; - hw->func.init_nvm_params = e1000_init_nvm_params_82571; - hw->func.init_phy_params = e1000_init_phy_params_82571; + hw->mac.ops.init_params = e1000_init_mac_params_82571; + hw->nvm.ops.init_params = e1000_init_nvm_params_82571; + hw->phy.ops.init_params = e1000_init_phy_params_82571; } /** @@ -398,7 +374,6 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val = E1000_SUCCESS; - u16 phy_id = 0; DEBUGFUNC("e1000_get_phy_id_82571"); @@ -416,26 +391,11 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw) case e1000_82573: ret_val = e1000_get_phy_id(hw); break; - case e1000_82574: - ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id); - if (ret_val) - goto out; - - phy->id = (u32)(phy_id << 16); - usec_delay(20); - ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id); - if (ret_val) - goto out; - - phy->id |= (u32)(phy_id); - phy->revision = (u32)(phy_id & ~PHY_REVISION_MASK); - break; default: ret_val = -E1000_ERR_PHY; break; } -out: return ret_val; } @@ -506,7 +466,7 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) * for EEPROM access grant bit. If the access grant bit is not set, release * hardware semaphore. **/ -STATIC s32 e1000_acquire_nvm_82571(struct e1000_hw *hw) +static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw) { s32 ret_val; @@ -516,7 +476,7 @@ STATIC s32 e1000_acquire_nvm_82571(struct e1000_hw *hw) if (ret_val) goto out; - if (hw->mac.type != e1000_82573 && hw->mac.type != e1000_82574) + if (hw->mac.type != e1000_82573) ret_val = e1000_acquire_nvm_generic(hw); if (ret_val) @@ -532,7 +492,7 @@ out: * * Stop any current commands to the EEPROM and clear the EEPROM request bit. **/ -STATIC void e1000_release_nvm_82571(struct e1000_hw *hw) +static void e1000_release_nvm_82571(struct e1000_hw *hw) { DEBUGFUNC("e1000_release_nvm_82571"); @@ -552,7 +512,7 @@ STATIC void e1000_release_nvm_82571(struct e1000_hw *hw) * If e1000_update_nvm_checksum is not called after this function, the * EEPROM will most likely contain an invalid checksum. **/ -STATIC s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, +static s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { s32 ret_val = E1000_SUCCESS; @@ -561,7 +521,6 @@ STATIC s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, switch (hw->mac.type) { case e1000_82573: - case e1000_82574: ret_val = e1000_write_nvm_eewr_82571(hw, offset, words, data); break; case e1000_82571: @@ -584,7 +543,7 @@ STATIC s32 e1000_write_nvm_82571(struct e1000_hw *hw, u16 offset, u16 words, * up to the checksum. Then calculates the EEPROM checksum and writes the * value to the EEPROM. **/ -STATIC s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw) +static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw) { u32 eecd; s32 ret_val; @@ -652,7 +611,7 @@ out: * Calculates the EEPROM checksum by reading/adding each word of the EEPROM * and then verifies that the sum of the EEPROM is equal to 0xBABA. **/ -STATIC s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw) +static s32 e1000_validate_nvm_checksum_82571(struct e1000_hw *hw) { DEBUGFUNC("e1000_validate_nvm_checksum_82571"); @@ -722,7 +681,7 @@ out: * * Reads the management control register for the config done bit to be set. **/ -STATIC s32 e1000_get_cfg_done_82571(struct e1000_hw *hw) +static s32 e1000_get_cfg_done_82571(struct e1000_hw *hw) { s32 timeout = PHY_CFG_TIMEOUT; s32 ret_val = E1000_SUCCESS; @@ -756,41 +715,40 @@ out: * of either 10 or 10/100 or 10/100/1000 at all duplexes. This is a function * pointer entry point only called by PHY setup routines. **/ -STATIC s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) +static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; - s32 ret_val; + s32 ret_val = E1000_SUCCESS; u16 data; DEBUGFUNC("e1000_set_d0_lplu_state_82571"); - ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data); + if (!(phy->ops.read_reg)) + goto out; + + ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data); if (ret_val) goto out; if (active) { data |= IGP02E1000_PM_D0_LPLU; - ret_val = e1000_write_phy_reg(hw, - IGP02E1000_PHY_POWER_MGMT, - data); + ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT, + data); if (ret_val) goto out; /* When LPLU is enabled, we should disable SmartSpeed */ - ret_val = e1000_read_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + &data); data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - data); + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, + data); if (ret_val) goto out; } else { data &= ~IGP02E1000_PM_D0_LPLU; - ret_val = e1000_write_phy_reg(hw, - IGP02E1000_PHY_POWER_MGMT, - data); + ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT, + data); /* * LPLU and SmartSpeed are mutually exclusive. LPLU is used * during Dx states where the power conservation is most @@ -798,27 +756,27 @@ STATIC s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) * SmartSpeed, so performance is maintained. */ if (phy->smart_speed == e1000_smart_speed_on) { - ret_val = e1000_read_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); + ret_val = phy->ops.read_reg(hw, + IGP01E1000_PHY_PORT_CONFIG, + &data); if (ret_val) goto out; data |= IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); if (ret_val) goto out; } else if (phy->smart_speed == e1000_smart_speed_off) { - ret_val = e1000_read_phy_reg(hw, - IGP01E1000_PHY_PORT_CONFIG, - &data); + ret_val = phy->ops.read_reg(hw, + IGP01E1000_PHY_PORT_CONFIG, + &data); if (ret_val) goto out; data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); if (ret_val) @@ -837,7 +795,7 @@ out: * This resets the hardware into a known state. This is a * function pointer entry point called by the api module. **/ -STATIC s32 e1000_reset_hw_82571(struct e1000_hw *hw) +static s32 e1000_reset_hw_82571(struct e1000_hw *hw) { u32 ctrl, extcnf_ctrl, ctrl_ext, icr; s32 ret_val; @@ -867,7 +825,7 @@ STATIC s32 e1000_reset_hw_82571(struct e1000_hw *hw) * Must acquire the MDIO ownership before MAC reset. * Ownership defaults to firmware after a reset. */ - if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) { + if (hw->mac.type == e1000_82573) { extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; @@ -908,7 +866,7 @@ STATIC s32 e1000_reset_hw_82571(struct e1000_hw *hw) * Need to wait for Phy configuration completion before accessing * NVM and Phy. */ - if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) + if (hw->mac.type == e1000_82573) msec_delay(25); /* Clear any pending interrupt events. */ @@ -928,7 +886,7 @@ out: * * This inits the hardware readying it for operation. **/ -STATIC s32 e1000_init_hw_82571(struct e1000_hw *hw) +static s32 e1000_init_hw_82571(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 reg_data; @@ -948,7 +906,7 @@ STATIC s32 e1000_init_hw_82571(struct e1000_hw *hw) /* Disabling VLAN filtering */ DEBUGOUT("Initializing the IEEE VLAN\n"); - e1000_clear_vfta(hw); + mac->ops.clear_vfta(hw); /* Setup the receive address. */ /* @@ -966,7 +924,7 @@ STATIC s32 e1000_init_hw_82571(struct e1000_hw *hw) E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); /* Setup link and flow control */ - ret_val = e1000_setup_link(hw); + ret_val = mac->ops.setup_link(hw); /* Set the transmit descriptor write-back policy */ reg_data = E1000_READ_REG(hw, E1000_TXDCTL(0)); @@ -976,7 +934,7 @@ STATIC s32 e1000_init_hw_82571(struct e1000_hw *hw) E1000_WRITE_REG(hw, E1000_TXDCTL(0), reg_data); /* ...for both queues. */ - if (mac->type != e1000_82573 && mac->type != e1000_82574) { + if (mac->type != e1000_82573) { reg_data = E1000_READ_REG(hw, E1000_TXDCTL(1)); reg_data = (reg_data & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB | @@ -1056,14 +1014,14 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) } /* Device Control */ - if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) { + if (hw->mac.type == e1000_82573) { reg = E1000_READ_REG(hw, E1000_CTRL); reg &= ~(1 << 29); E1000_WRITE_REG(hw, E1000_CTRL, reg); } /* Extended Device Control */ - if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) { + if (hw->mac.type == e1000_82573) { reg = E1000_READ_REG(hw, E1000_CTRL_EXT); reg &= ~(1 << 23); reg |= (1 << 22); @@ -1081,7 +1039,7 @@ out: * Clears the register array which contains the VLAN filter table by * setting all the values to 0. **/ -STATIC void e1000_clear_vfta_82571(struct e1000_hw *hw) +static void e1000_clear_vfta_82571(struct e1000_hw *hw) { u32 offset; u32 vfta_value = 0; @@ -1090,7 +1048,7 @@ STATIC void e1000_clear_vfta_82571(struct e1000_hw *hw) DEBUGFUNC("e1000_clear_vfta_82571"); - if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) { + if (hw->mac.type == e1000_82573) { if (hw->mng_cookie.vlan_id != 0) { /* * The VFTA is a 4096b bit-field, each identifying @@ -1131,7 +1089,7 @@ STATIC void e1000_clear_vfta_82571(struct e1000_hw *hw) * The parameter rar_count will usually be hw->mac.rar_entry_count * unless there are workarounds that change this. **/ -STATIC void e1000_update_mc_addr_list_82571(struct e1000_hw *hw, +static void e1000_update_mc_addr_list_82571(struct e1000_hw *hw, u8 *mc_addr_list, u32 mc_addr_count, u32 rar_used_count, u32 rar_count) { @@ -1154,7 +1112,7 @@ STATIC void e1000_update_mc_addr_list_82571(struct e1000_hw *hw, * should be established. Assumes the hardware has previously been reset * and the transmitter and receiver are not enabled. **/ -STATIC s32 e1000_setup_link_82571(struct e1000_hw *hw) +static s32 e1000_setup_link_82571(struct e1000_hw *hw) { DEBUGFUNC("e1000_setup_link_82571"); @@ -1163,7 +1121,7 @@ STATIC s32 e1000_setup_link_82571(struct e1000_hw *hw) * the default flow control setting, so we explicitly * set it to full. */ - if (hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) + if (hw->mac.type == e1000_82573 && hw->fc.type == e1000_fc_default) hw->fc.type = e1000_fc_full; return e1000_setup_link_generic(hw); @@ -1177,7 +1135,7 @@ STATIC s32 e1000_setup_link_82571(struct e1000_hw *hw) * for link, once link is established calls to configure collision distance * and flow control are called. **/ -STATIC s32 e1000_setup_copper_link_82571(struct e1000_hw *hw) +static s32 e1000_setup_copper_link_82571(struct e1000_hw *hw) { u32 ctrl, led_ctrl; s32 ret_val; @@ -1223,7 +1181,7 @@ out: * Configures collision distance and flow control for fiber and serdes links. * Upon successful setup, poll for link. **/ -STATIC s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw) +static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw) { DEBUGFUNC("e1000_setup_fiber_serdes_link_82571"); @@ -1254,22 +1212,23 @@ STATIC s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw) * Read the EEPROM for the current default LED configuration. If the * LED configuration is not valid, set to a valid LED configuration. **/ -STATIC s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data) +static s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data) { s32 ret_val; DEBUGFUNC("e1000_valid_led_default_82571"); - ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data); + ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data); if (ret_val) { DEBUGOUT("NVM Read Error\n"); goto out; } - if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) && + if (hw->mac.type == e1000_82573 && *data == ID_LED_RESERVED_F746) *data = ID_LED_DEFAULT_82573; - else if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) + else if (*data == ID_LED_RESERVED_0000 || + *data == ID_LED_RESERVED_FFFF) *data = ID_LED_DEFAULT; out: return ret_val; @@ -1361,7 +1320,7 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw) * Check bit 4 of word 10h. If it is 0, firmware is done updating * 10h-12h. Checksum may need to be fixed. */ - ret_val = e1000_read_nvm(hw, 0x10, 1, &data); + ret_val = nvm->ops.read(hw, 0x10, 1, &data); if (ret_val) goto out; @@ -1374,16 +1333,16 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw) * we need to set this bit to a 1 and update the * checksum. */ - ret_val = e1000_read_nvm(hw, 0x23, 1, &data); + ret_val = nvm->ops.read(hw, 0x23, 1, &data); if (ret_val) goto out; if (!(data & 0x8000)) { data |= 0x8000; - ret_val = e1000_write_nvm(hw, 0x23, 1, &data); + ret_val = nvm->ops.write(hw, 0x23, 1, &data); if (ret_val) goto out; - ret_val = e1000_update_nvm_checksum(hw); + ret_val = nvm->ops.update(hw); } } @@ -1395,7 +1354,7 @@ out: * e1000_read_mac_addr_82571 - Read device MAC address * @hw: pointer to the HW structure **/ -STATIC s32 e1000_read_mac_addr_82571(struct e1000_hw *hw) +static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; @@ -1413,10 +1372,16 @@ STATIC s32 e1000_read_mac_addr_82571(struct e1000_hw *hw) * In the case of a PHY power down to save power, or to turn off link during a * driver unload, or wake on lan is not enabled, remove the link. **/ -STATIC void e1000_power_down_phy_copper_82571(struct e1000_hw *hw) +static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw) { + struct e1000_phy_info *phy = &hw->phy; + struct e1000_mac_info *mac = &hw->mac; + + if (!(phy->ops.check_reset_block)) + return; + /* If the management interface is not enabled, then power down */ - if (!(e1000_check_mng_mode(hw) || e1000_check_reset_block(hw))) + if (!(mac->ops.check_mng_mode(hw) || phy->ops.check_reset_block(hw))) e1000_power_down_phy_copper(hw); return; @@ -1428,7 +1393,7 @@ STATIC void e1000_power_down_phy_copper_82571(struct e1000_hw *hw) * * Clears the hardware counters by reading the counter registers. **/ -STATIC void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw) +static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw) { volatile u32 temp; diff --git a/sys/dev/em/e1000_82571.h b/sys/dev/em/e1000_82571.h index 186c4cd..e6469ea 100644 --- a/sys/dev/em/e1000_82571.h +++ b/sys/dev/em/e1000_82571.h @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,9 +29,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ #ifndef _E1000_82571_H_ #define _E1000_82571_H_ @@ -44,12 +43,4 @@ #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 -/* Intr Throttling - RW */ -#define E1000_EITR_82574(_n) (0x000E8 + (0x4 * (_n))) - -#define E1000_EIAC_82574 0x000DC /* Ext. Interrupt Auto Clear - RW */ -#define E1000_EIAC_MASK_82574 0x01500000 - -#define E1000_RXCFGL 0x0B634 /* TimeSync Rx EtherType & Msg Type Reg - RW */ - #endif diff --git a/sys/dev/em/e1000_api.c b/sys/dev/em/e1000_api.c index 57e0b3e..ead54d6 100644 --- a/sys/dev/em/e1000_api.c +++ b/sys/dev/em/e1000_api.c @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,9 +29,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ #include "e1000_api.h" #include "e1000_mac.h" @@ -49,8 +48,8 @@ s32 e1000_init_mac_params(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; - if (hw->func.init_mac_params) { - ret_val = hw->func.init_mac_params(hw); + if (hw->mac.ops.init_params) { + ret_val = hw->mac.ops.init_params(hw); if (ret_val) { DEBUGOUT("MAC Initialization Error\n"); goto out; @@ -75,8 +74,8 @@ s32 e1000_init_nvm_params(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; - if (hw->func.init_nvm_params) { - ret_val = hw->func.init_nvm_params(hw); + if (hw->nvm.ops.init_params) { + ret_val = hw->nvm.ops.init_params(hw); if (ret_val) { DEBUGOUT("NVM Initialization Error\n"); goto out; @@ -101,8 +100,8 @@ s32 e1000_init_phy_params(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; - if (hw->func.init_phy_params) { - ret_val = hw->func.init_phy_params(hw); + if (hw->phy.ops.init_params) { + ret_val = hw->phy.ops.init_params(hw); if (ret_val) { DEBUGOUT("PHY Initialization Error\n"); goto out; @@ -217,9 +216,6 @@ s32 e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_82573L: mac->type = e1000_82573; break; - case E1000_DEV_ID_82574L: - mac->type = e1000_82574; - break; case E1000_DEV_ID_80003ES2LAN_COPPER_DPT: case E1000_DEV_ID_80003ES2LAN_SERDES_DPT: case E1000_DEV_ID_80003ES2LAN_COPPER_SPT: @@ -240,13 +236,15 @@ s32 e1000_set_mac_type(struct e1000_hw *hw) case E1000_DEV_ID_ICH9_IFE_G: case E1000_DEV_ID_ICH9_IGP_M: case E1000_DEV_ID_ICH9_IGP_M_AMT: + case E1000_DEV_ID_ICH9_IGP_M_V: case E1000_DEV_ID_ICH9_IGP_AMT: case E1000_DEV_ID_ICH9_IGP_C: mac->type = e1000_ich9lan; break; - case E1000_DEV_ID_ICH10_D_BM_LM: - case E1000_DEV_ID_ICH10_D_BM_LF: - mac->type = e1000_ich10lan; + case E1000_DEV_ID_82575EB_COPPER: + case E1000_DEV_ID_82575EB_FIBER_SERDES: + case E1000_DEV_ID_82575GB_QUAD_COPPER: + mac->type = e1000_82575; break; default: /* Should never have loaded on this device */ @@ -287,18 +285,12 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device) } /* - * Init some generic function pointers that are currently all pointing - * to generic implementations. We do this first allowing a driver - * module to override it afterward. + * Init function pointers to generic implementations. We do this first + * allowing a driver module to override it afterward. */ - hw->func.config_collision_dist = e1000_config_collision_dist_generic; - hw->func.rar_set = e1000_rar_set_generic; - hw->func.validate_mdi_setting = e1000_validate_mdi_setting_generic; - hw->func.mng_host_if_write = e1000_mng_host_if_write_generic; - hw->func.mng_write_cmd_header = e1000_mng_write_cmd_header_generic; - hw->func.mng_enable_host_if = e1000_mng_enable_host_if_generic; - hw->func.wait_autoneg = e1000_wait_autoneg_generic; - hw->func.reload_nvm = e1000_reload_nvm_generic; + e1000_init_mac_ops_generic(hw); + e1000_init_phy_ops_generic(hw); + e1000_init_nvm_ops_generic(hw); /* * Set up the init function pointers. These are functions within the @@ -331,7 +323,6 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device) case e1000_82571: case e1000_82572: case e1000_82573: - case e1000_82574: e1000_init_function_pointers_82571(hw); break; case e1000_80003es2lan: @@ -339,9 +330,11 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device) break; case e1000_ich8lan: case e1000_ich9lan: - case e1000_ich10lan: e1000_init_function_pointers_ich8lan(hw); break; + case e1000_82575: + e1000_init_function_pointers_82575(hw); + break; default: DEBUGOUT("Hardware not supported\n"); ret_val = -E1000_ERR_CONFIG; @@ -380,8 +373,8 @@ out: **/ void e1000_remove_device(struct e1000_hw *hw) { - if (hw->func.remove_device) - hw->func.remove_device(hw); + if (hw->mac.ops.remove_device) + hw->mac.ops.remove_device(hw); } /** @@ -394,8 +387,8 @@ void e1000_remove_device(struct e1000_hw *hw) **/ s32 e1000_get_bus_info(struct e1000_hw *hw) { - if (hw->func.get_bus_info) - return hw->func.get_bus_info(hw); + if (hw->mac.ops.get_bus_info) + return hw->mac.ops.get_bus_info(hw); return E1000_SUCCESS; } @@ -409,8 +402,8 @@ s32 e1000_get_bus_info(struct e1000_hw *hw) **/ void e1000_clear_vfta(struct e1000_hw *hw) { - if (hw->func.clear_vfta) - hw->func.clear_vfta (hw); + if (hw->mac.ops.clear_vfta) + hw->mac.ops.clear_vfta (hw); } /** @@ -424,8 +417,8 @@ void e1000_clear_vfta(struct e1000_hw *hw) **/ void e1000_write_vfta(struct e1000_hw *hw, u32 offset, u32 value) { - if (hw->func.write_vfta) - hw->func.write_vfta(hw, offset, value); + if (hw->mac.ops.write_vfta) + hw->mac.ops.write_vfta(hw, offset, value); } /** @@ -447,12 +440,12 @@ void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list, u32 mc_addr_count, u32 rar_used_count, u32 rar_count) { - if (hw->func.update_mc_addr_list) - hw->func.update_mc_addr_list(hw, - mc_addr_list, - mc_addr_count, - rar_used_count, - rar_count); + if (hw->mac.ops.update_mc_addr_list) + hw->mac.ops.update_mc_addr_list(hw, + mc_addr_list, + mc_addr_count, + rar_used_count, + rar_count); } /** @@ -478,8 +471,8 @@ s32 e1000_force_mac_fc(struct e1000_hw *hw) **/ s32 e1000_check_for_link(struct e1000_hw *hw) { - if (hw->func.check_for_link) - return hw->func.check_for_link(hw); + if (hw->mac.ops.check_for_link) + return hw->mac.ops.check_for_link(hw); return -E1000_ERR_CONFIG; } @@ -493,8 +486,8 @@ s32 e1000_check_for_link(struct e1000_hw *hw) **/ bool e1000_check_mng_mode(struct e1000_hw *hw) { - if (hw->func.check_mng_mode) - return hw->func.check_mng_mode(hw); + if (hw->mac.ops.check_mng_mode) + return hw->mac.ops.check_mng_mode(hw); return FALSE; } @@ -521,8 +514,8 @@ s32 e1000_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length) **/ s32 e1000_reset_hw(struct e1000_hw *hw) { - if (hw->func.reset_hw) - return hw->func.reset_hw(hw); + if (hw->mac.ops.reset_hw) + return hw->mac.ops.reset_hw(hw); return -E1000_ERR_CONFIG; } @@ -536,8 +529,8 @@ s32 e1000_reset_hw(struct e1000_hw *hw) **/ s32 e1000_init_hw(struct e1000_hw *hw) { - if (hw->func.init_hw) - return hw->func.init_hw(hw); + if (hw->mac.ops.init_hw) + return hw->mac.ops.init_hw(hw); return -E1000_ERR_CONFIG; } @@ -552,8 +545,8 @@ s32 e1000_init_hw(struct e1000_hw *hw) **/ s32 e1000_setup_link(struct e1000_hw *hw) { - if (hw->func.setup_link) - return hw->func.setup_link(hw); + if (hw->mac.ops.setup_link) + return hw->mac.ops.setup_link(hw); return -E1000_ERR_CONFIG; } @@ -570,8 +563,8 @@ s32 e1000_setup_link(struct e1000_hw *hw) **/ s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex) { - if (hw->func.get_link_up_info) - return hw->func.get_link_up_info(hw, speed, duplex); + if (hw->mac.ops.get_link_up_info) + return hw->mac.ops.get_link_up_info(hw, speed, duplex); return -E1000_ERR_CONFIG; } @@ -586,8 +579,8 @@ s32 e1000_get_speed_and_duplex(struct e1000_hw *hw, u16 *speed, u16 *duplex) **/ s32 e1000_setup_led(struct e1000_hw *hw) { - if (hw->func.setup_led) - return hw->func.setup_led(hw); + if (hw->mac.ops.setup_led) + return hw->mac.ops.setup_led(hw); return E1000_SUCCESS; } @@ -601,8 +594,8 @@ s32 e1000_setup_led(struct e1000_hw *hw) **/ s32 e1000_cleanup_led(struct e1000_hw *hw) { - if (hw->func.cleanup_led) - return hw->func.cleanup_led(hw); + if (hw->mac.ops.cleanup_led) + return hw->mac.ops.cleanup_led(hw); return E1000_SUCCESS; } @@ -617,8 +610,8 @@ s32 e1000_cleanup_led(struct e1000_hw *hw) **/ s32 e1000_blink_led(struct e1000_hw *hw) { - if (hw->func.blink_led) - return hw->func.blink_led(hw); + if (hw->mac.ops.blink_led) + return hw->mac.ops.blink_led(hw); return E1000_SUCCESS; } @@ -632,8 +625,8 @@ s32 e1000_blink_led(struct e1000_hw *hw) **/ s32 e1000_led_on(struct e1000_hw *hw) { - if (hw->func.led_on) - return hw->func.led_on(hw); + if (hw->mac.ops.led_on) + return hw->mac.ops.led_on(hw); return E1000_SUCCESS; } @@ -647,8 +640,8 @@ s32 e1000_led_on(struct e1000_hw *hw) **/ s32 e1000_led_off(struct e1000_hw *hw) { - if (hw->func.led_off) - return hw->func.led_off(hw); + if (hw->mac.ops.led_off) + return hw->mac.ops.led_off(hw); return E1000_SUCCESS; } @@ -699,8 +692,8 @@ s32 e1000_disable_pcie_master(struct e1000_hw *hw) **/ void e1000_config_collision_dist(struct e1000_hw *hw) { - if (hw->func.config_collision_dist) - hw->func.config_collision_dist(hw); + if (hw->mac.ops.config_collision_dist) + hw->mac.ops.config_collision_dist(hw); } /** @@ -713,8 +706,8 @@ void e1000_config_collision_dist(struct e1000_hw *hw) **/ void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) { - if (hw->func.rar_set) - hw->func.rar_set(hw, addr, index); + if (hw->mac.ops.rar_set) + hw->mac.ops.rar_set(hw, addr, index); } /** @@ -725,8 +718,8 @@ void e1000_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) **/ s32 e1000_validate_mdi_setting(struct e1000_hw *hw) { - if (hw->func.validate_mdi_setting) - return hw->func.validate_mdi_setting(hw); + if (hw->mac.ops.validate_mdi_setting) + return hw->mac.ops.validate_mdi_setting(hw); return E1000_SUCCESS; } @@ -741,8 +734,8 @@ s32 e1000_validate_mdi_setting(struct e1000_hw *hw) **/ void e1000_mta_set(struct e1000_hw *hw, u32 hash_value) { - if (hw->func.mta_set) - hw->func.mta_set(hw, hash_value); + if (hw->mac.ops.mta_set) + hw->mac.ops.mta_set(hw, hash_value); } /** @@ -788,9 +781,9 @@ bool e1000_enable_tx_pkt_filtering(struct e1000_hw *hw) s32 e1000_mng_host_if_write(struct e1000_hw * hw, u8 *buffer, u16 length, u16 offset, u8 *sum) { - if (hw->func.mng_host_if_write) - return hw->func.mng_host_if_write(hw, buffer, length, offset, - sum); + if (hw->mac.ops.mng_host_if_write) + return hw->mac.ops.mng_host_if_write(hw, buffer, length, + offset, sum); return E1000_NOT_IMPLEMENTED; } @@ -805,8 +798,8 @@ s32 e1000_mng_host_if_write(struct e1000_hw * hw, u8 *buffer, u16 length, s32 e1000_mng_write_cmd_header(struct e1000_hw *hw, struct e1000_host_mng_command_header *hdr) { - if (hw->func.mng_write_cmd_header) - return hw->func.mng_write_cmd_header(hw, hdr); + if (hw->mac.ops.mng_write_cmd_header) + return hw->mac.ops.mng_write_cmd_header(hw, hdr); return E1000_NOT_IMPLEMENTED; } @@ -823,8 +816,8 @@ s32 e1000_mng_write_cmd_header(struct e1000_hw *hw, **/ s32 e1000_mng_enable_host_if(struct e1000_hw * hw) { - if (hw->func.mng_enable_host_if) - return hw->func.mng_enable_host_if(hw); + if (hw->mac.ops.mng_enable_host_if) + return hw->mac.ops.mng_enable_host_if(hw); return E1000_NOT_IMPLEMENTED; } @@ -838,8 +831,8 @@ s32 e1000_mng_enable_host_if(struct e1000_hw * hw) **/ s32 e1000_wait_autoneg(struct e1000_hw *hw) { - if (hw->func.wait_autoneg) - return hw->func.wait_autoneg(hw); + if (hw->mac.ops.wait_autoneg) + return hw->mac.ops.wait_autoneg(hw); return E1000_SUCCESS; } @@ -853,8 +846,8 @@ s32 e1000_wait_autoneg(struct e1000_hw *hw) **/ s32 e1000_check_reset_block(struct e1000_hw *hw) { - if (hw->func.check_reset_block) - return hw->func.check_reset_block(hw); + if (hw->phy.ops.check_reset_block) + return hw->phy.ops.check_reset_block(hw); return E1000_SUCCESS; } @@ -870,8 +863,8 @@ s32 e1000_check_reset_block(struct e1000_hw *hw) **/ s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data) { - if (hw->func.read_phy_reg) - return hw->func.read_phy_reg(hw, offset, data); + if (hw->phy.ops.read_reg) + return hw->phy.ops.read_reg(hw, offset, data); return E1000_SUCCESS; } @@ -887,8 +880,36 @@ s32 e1000_read_phy_reg(struct e1000_hw *hw, u32 offset, u16 *data) **/ s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data) { - if (hw->func.write_phy_reg) - return hw->func.write_phy_reg(hw, offset, data); + if (hw->phy.ops.write_reg) + return hw->phy.ops.write_reg(hw, offset, data); + + return E1000_SUCCESS; +} + +/** + * e1000_release_phy - Generic release PHY + * @hw: pointer to the HW structure + * + * Return if silicon family does not require a semaphore when accessing the + * PHY. + **/ +void e1000_release_phy(struct e1000_hw *hw) +{ + if (hw->phy.ops.release) + hw->phy.ops.release(hw); +} + +/** + * e1000_acquire_phy - Generic acquire PHY + * @hw: pointer to the HW structure + * + * Return success if silicon family does not require a semaphore when + * accessing the PHY. + **/ +s32 e1000_acquire_phy(struct e1000_hw *hw) +{ + if (hw->phy.ops.acquire) + return hw->phy.ops.acquire(hw); return E1000_SUCCESS; } @@ -933,8 +954,8 @@ s32 e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data) **/ s32 e1000_get_cable_length(struct e1000_hw *hw) { - if (hw->func.get_cable_length) - return hw->func.get_cable_length(hw); + if (hw->phy.ops.get_cable_length) + return hw->phy.ops.get_cable_length(hw); return E1000_SUCCESS; } @@ -949,8 +970,8 @@ s32 e1000_get_cable_length(struct e1000_hw *hw) **/ s32 e1000_get_phy_info(struct e1000_hw *hw) { - if (hw->func.get_phy_info) - return hw->func.get_phy_info(hw); + if (hw->phy.ops.get_info) + return hw->phy.ops.get_info(hw); return E1000_SUCCESS; } @@ -964,8 +985,8 @@ s32 e1000_get_phy_info(struct e1000_hw *hw) **/ s32 e1000_phy_hw_reset(struct e1000_hw *hw) { - if (hw->func.reset_phy) - return hw->func.reset_phy(hw); + if (hw->phy.ops.reset) + return hw->phy.ops.reset(hw); return E1000_SUCCESS; } @@ -979,21 +1000,21 @@ s32 e1000_phy_hw_reset(struct e1000_hw *hw) **/ s32 e1000_phy_commit(struct e1000_hw *hw) { - if (hw->func.commit_phy) - return hw->func.commit_phy(hw); + if (hw->phy.ops.commit) + return hw->phy.ops.commit(hw); return E1000_SUCCESS; } /** - * e1000_set_d3_lplu_state - Sets low power link up state for D0 + * e1000_set_d0_lplu_state - Sets low power link up state for D0 * @hw: pointer to the HW structure * @active: boolean used to enable/disable lplu * * Success returns 0, Failure returns 1 * * The low power link up (lplu) state is set to the power management level D0 - * and SmartSpeed is disabled when active is true, else clear lplu for D0 + * and SmartSpeed is disabled when active is TRUE, else clear lplu for D0 * 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 @@ -1001,8 +1022,8 @@ s32 e1000_phy_commit(struct e1000_hw *hw) **/ s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) { - if (hw->func.set_d0_lplu_state) - return hw->func.set_d0_lplu_state(hw, active); + if (hw->phy.ops.set_d0_lplu_state) + return hw->phy.ops.set_d0_lplu_state(hw, active); return E1000_SUCCESS; } @@ -1015,7 +1036,7 @@ s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) * Success returns 0, Failure returns 1 * * The low power link up (lplu) state is set to the power management level D3 - * and SmartSpeed is disabled when active is true, else clear lplu for D3 + * and SmartSpeed is disabled when active is TRUE, else clear lplu for D3 * 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 @@ -1023,8 +1044,8 @@ s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active) **/ s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active) { - if (hw->func.set_d3_lplu_state) - return hw->func.set_d3_lplu_state(hw, active); + if (hw->phy.ops.set_d3_lplu_state) + return hw->phy.ops.set_d3_lplu_state(hw, active); return E1000_SUCCESS; } @@ -1039,8 +1060,8 @@ s32 e1000_set_d3_lplu_state(struct e1000_hw *hw, bool active) **/ s32 e1000_read_mac_addr(struct e1000_hw *hw) { - if (hw->func.read_mac_addr) - return hw->func.read_mac_addr(hw); + if (hw->mac.ops.read_mac_addr) + return hw->mac.ops.read_mac_addr(hw); return e1000_read_mac_addr_generic(hw); } @@ -1069,8 +1090,8 @@ s32 e1000_read_pba_num(struct e1000_hw *hw, u32 *pba_num) **/ s32 e1000_validate_nvm_checksum(struct e1000_hw *hw) { - if (hw->func.validate_nvm) - return hw->func.validate_nvm(hw); + if (hw->nvm.ops.validate) + return hw->nvm.ops.validate(hw); return -E1000_ERR_CONFIG; } @@ -1084,8 +1105,8 @@ s32 e1000_validate_nvm_checksum(struct e1000_hw *hw) **/ s32 e1000_update_nvm_checksum(struct e1000_hw *hw) { - if (hw->func.update_nvm) - return hw->func.update_nvm(hw); + if (hw->nvm.ops.update) + return hw->nvm.ops.update(hw); return -E1000_ERR_CONFIG; } @@ -1099,8 +1120,8 @@ s32 e1000_update_nvm_checksum(struct e1000_hw *hw) **/ void e1000_reload_nvm(struct e1000_hw *hw) { - if (hw->func.reload_nvm) - hw->func.reload_nvm(hw); + if (hw->nvm.ops.reload) + hw->nvm.ops.reload(hw); } /** @@ -1115,8 +1136,8 @@ void e1000_reload_nvm(struct e1000_hw *hw) **/ s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { - if (hw->func.read_nvm) - return hw->func.read_nvm(hw, offset, words, data); + if (hw->nvm.ops.read) + return hw->nvm.ops.read(hw, offset, words, data); return -E1000_ERR_CONFIG; } @@ -1133,8 +1154,8 @@ s32 e1000_read_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) **/ s32 e1000_write_nvm(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { - if (hw->func.write_nvm) - return hw->func.write_nvm(hw, offset, words, data); + if (hw->nvm.ops.write) + return hw->nvm.ops.write(hw, offset, words, data); return E1000_SUCCESS; } @@ -1164,8 +1185,8 @@ s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, u32 offset, **/ void e1000_power_up_phy(struct e1000_hw *hw) { - if (hw->func.power_up_phy) - hw->func.power_up_phy(hw); + if (hw->phy.ops.power_up) + hw->phy.ops.power_up(hw); e1000_setup_link(hw); } @@ -1179,7 +1200,7 @@ void e1000_power_up_phy(struct e1000_hw *hw) **/ void e1000_power_down_phy(struct e1000_hw *hw) { - if (hw->func.power_down_phy) - hw->func.power_down_phy(hw); + if (hw->phy.ops.power_down) + hw->phy.ops.power_down(hw); } diff --git a/sys/dev/em/e1000_api.h b/sys/dev/em/e1000_api.h index 2423b96..921b194 100644 --- a/sys/dev/em/e1000_api.h +++ b/sys/dev/em/e1000_api.h @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,9 +29,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ #ifndef _E1000_API_H_ #define _E1000_API_H_ @@ -47,6 +46,7 @@ extern void e1000_init_function_pointers_82571(struct e1000_hw *hw); extern void e1000_init_function_pointers_82541(struct e1000_hw *hw); extern void e1000_init_function_pointers_80003es2lan(struct e1000_hw *hw); extern void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw); +extern void e1000_init_function_pointers_82575(struct e1000_hw *hw); s32 e1000_set_mac_type(struct e1000_hw *hw); s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device); @@ -87,6 +87,8 @@ s32 e1000_write_phy_reg(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, u32 offset, u8 data); s32 e1000_get_phy_info(struct e1000_hw *hw); +void e1000_release_phy(struct e1000_hw *hw); +s32 e1000_acquire_phy(struct e1000_hw *hw); s32 e1000_phy_hw_reset(struct e1000_hw *hw); s32 e1000_phy_commit(struct e1000_hw *hw); void e1000_power_up_phy(struct e1000_hw *hw); diff --git a/sys/dev/em/e1000_defines.h b/sys/dev/em/e1000_defines.h index a40fa4b..516db57 100644 --- a/sys/dev/em/e1000_defines.h +++ b/sys/dev/em/e1000_defines.h @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,9 +29,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ #ifndef _E1000_DEFINES_H_ #define _E1000_DEFINES_H_ @@ -155,7 +154,6 @@ #define E1000_CTRL_EXT_DF_PAREN 0x02000000 /* descriptor FIFO parity error detection enable */ #define E1000_CTRL_EXT_GHOST_PAREN 0x40000000 #define E1000_CTRL_EXT_PBA_CLR 0x80000000 /* PBA Clear */ -#define E1000_CTRL_EXT_LSECCK 0x00001000 #define E1000_I2CCMD_REG_ADDR_SHIFT 16 #define E1000_I2CCMD_REG_ADDR 0x00FF0000 #define E1000_I2CCMD_PHY_ADDR_SHIFT 24 @@ -204,13 +202,6 @@ #define E1000_RXDEXT_STATERR_IPE 0x40000000 #define E1000_RXDEXT_STATERR_RXE 0x80000000 -#define E1000_RXDEXT_LSECH 0x01000000 -#define E1000_RXDEXT_LSECE_MASK 0x60000000 -#define E1000_RXDEXT_LSECE_NO_ERROR 0x00000000 -#define E1000_RXDEXT_LSECE_NO_SA_MATCH 0x20000000 -#define E1000_RXDEXT_LSECE_REPLAY_DETECT 0x40000000 -#define E1000_RXDEXT_LSECE_BAD_SIG 0x60000000 - /* mask to determine if packets should be dropped due to frame errors */ #define E1000_RXD_ERR_FRAME_ERR_MASK ( \ E1000_RXD_ERR_CE | \ @@ -565,8 +556,6 @@ #define E1000_TXD_CMD_TSE 0x04000000 /* TCP Seg enable */ #define E1000_TXD_STAT_TC 0x00000004 /* Tx Underrun */ /* Extended desc bits for Linksec and timesync */ -#define E1000_TXD_CMD_LINKSEC 0x10000000 /* Apply LinkSec on packet */ -#define E1000_TXD_EXTCMD_TSTAMP 0x00000010 /* IEEE1588 Timestamp packet */ /* Transmit Control */ #define E1000_TCTL_RST 0x00000001 /* software reset */ @@ -726,11 +715,6 @@ #define E1000_ICR_DSW 0x00000020 /* FW changed the status of DISSW bit in the FWSM */ #define E1000_ICR_PHYINT 0x00001000 /* LAN connected device generates an interrupt */ #define E1000_ICR_EPRST 0x00100000 /* ME hardware reset occurs */ -#define E1000_ICR_RXQ0 0x00100000 /* Rx Queue 0 Interrupt */ -#define E1000_ICR_RXQ1 0x00200000 /* Rx Queue 1 Interrupt */ -#define E1000_ICR_TXQ0 0x00400000 /* Tx Queue 0 Interrupt */ -#define E1000_ICR_TXQ1 0x00800000 /* Tx Queue 1 Interrupt */ -#define E1000_ICR_OTHER 0x01000000 /* Other Interrupts */ /* Extended Interrupt Cause Read */ #define E1000_EICR_RX_QUEUE0 0x00000001 /* Rx Queue 0 Interrupt */ @@ -803,11 +787,6 @@ #define E1000_IMS_DSW E1000_ICR_DSW #define E1000_IMS_PHYINT E1000_ICR_PHYINT #define E1000_IMS_EPRST E1000_ICR_EPRST -#define E1000_IMS_RXQ0 E1000_ICR_RXQ0 /* Rx Queue 0 Interrupt */ -#define E1000_IMS_RXQ1 E1000_ICR_RXQ1 /* Rx Queue 1 Interrupt */ -#define E1000_IMS_TXQ0 E1000_ICR_TXQ0 /* Tx Queue 0 Interrupt */ -#define E1000_IMS_TXQ1 E1000_ICR_TXQ1 /* Tx Queue 1 Interrupt */ -#define E1000_IMS_OTHER E1000_ICR_OTHER /* Other Interrupts */ /* Extended Interrupt Mask Set */ #define E1000_EIMS_RX_QUEUE0 E1000_EICR_RX_QUEUE0 /* Rx Queue 0 Interrupt */ @@ -1447,5 +1426,4 @@ #define E1000_GEN_CTL_ADDRESS_SHIFT 8 #define E1000_GEN_POLL_TIMEOUT 640 -#define UNREFERENCED_PARAMETER(_p) #endif diff --git a/sys/dev/em/e1000_hw.h b/sys/dev/em/e1000_hw.h index 11ae79b..ebc20bf 100644 --- a/sys/dev/em/e1000_hw.h +++ b/sys/dev/em/e1000_hw.h @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,9 +29,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ #ifndef _E1000_HW_H_ #define _E1000_HW_H_ @@ -96,7 +95,6 @@ struct e1000_hw; #define E1000_DEV_ID_82573E 0x108B #define E1000_DEV_ID_82573E_IAMT 0x108C #define E1000_DEV_ID_82573L 0x109A -#define E1000_DEV_ID_82574L 0x10D3 #define E1000_DEV_ID_80003ES2LAN_COPPER_DPT 0x1096 #define E1000_DEV_ID_80003ES2LAN_SERDES_DPT 0x1098 #define E1000_DEV_ID_80003ES2LAN_COPPER_SPT 0x10BA @@ -109,14 +107,16 @@ struct e1000_hw; #define E1000_DEV_ID_ICH8_IFE_G 0x10C5 #define E1000_DEV_ID_ICH8_IGP_M 0x104D #define E1000_DEV_ID_ICH9_IGP_M 0x10BF -#define E1000_DEV_ID_ICH9_IGP_M_AMT 0x10BE +#define E1000_DEV_ID_ICH9_IGP_M_AMT 0x10F5 +#define E1000_DEV_ID_ICH9_IGP_M_V 0x10CB #define E1000_DEV_ID_ICH9_IGP_AMT 0x10BD #define E1000_DEV_ID_ICH9_IGP_C 0x294C #define E1000_DEV_ID_ICH9_IFE 0x10C0 #define E1000_DEV_ID_ICH9_IFE_GT 0x10C3 #define E1000_DEV_ID_ICH9_IFE_G 0x10C2 -#define E1000_DEV_ID_ICH10_D_BM_LM 0x10DE -#define E1000_DEV_ID_ICH10_D_BM_LF 0x10DF +#define E1000_DEV_ID_82575EB_COPPER 0x10A7 +#define E1000_DEV_ID_82575EB_FIBER_SERDES 0x10A9 +#define E1000_DEV_ID_82575GB_QUAD_COPPER 0x10D6 #define E1000_REVISION_0 0 #define E1000_REVISION_1 1 @@ -146,12 +146,11 @@ typedef enum { e1000_82571, e1000_82572, e1000_82573, - e1000_82574, e1000_80003es2lan, e1000_ich8lan, e1000_ich9lan, - e1000_ich10lan, - e1000_num_macs /* List is 1-based, so subtract 1 for true count. */ + e1000_82575, + e1000_num_macs /* List is 1-based, so subtract 1 for TRUE count. */ } e1000_mac_type; typedef enum { @@ -521,9 +520,9 @@ struct e1000_host_mng_command_info { #include "e1000_nvm.h" #include "e1000_manage.h" -struct e1000_functions { +struct e1000_mac_operations { /* Function pointers for the MAC. */ - s32 (*init_mac_params)(struct e1000_hw *); + s32 (*init_params)(struct e1000_hw *); s32 (*blink_led)(struct e1000_hw *); s32 (*check_for_link)(struct e1000_hw *); bool (*check_mng_mode)(struct e1000_hw *hw); @@ -553,39 +552,42 @@ struct e1000_functions { struct e1000_host_mng_command_header*); s32 (*mng_enable_host_if)(struct e1000_hw*); s32 (*wait_autoneg)(struct e1000_hw*); +}; - /* Function pointers for the PHY. */ - s32 (*init_phy_params)(struct e1000_hw *); - s32 (*acquire_phy)(struct e1000_hw *); +struct e1000_phy_operations { + s32 (*init_params)(struct e1000_hw *); + s32 (*acquire)(struct e1000_hw *); s32 (*check_polarity)(struct e1000_hw *); s32 (*check_reset_block)(struct e1000_hw *); - s32 (*commit_phy)(struct e1000_hw *); + s32 (*commit)(struct e1000_hw *); s32 (*force_speed_duplex)(struct e1000_hw *); s32 (*get_cfg_done)(struct e1000_hw *hw); s32 (*get_cable_length)(struct e1000_hw *); - s32 (*get_phy_info)(struct e1000_hw *); - s32 (*read_phy_reg)(struct e1000_hw *, u32, u16 *); - void (*release_phy)(struct e1000_hw *); - s32 (*reset_phy)(struct e1000_hw *); + s32 (*get_info)(struct e1000_hw *); + s32 (*read_reg)(struct e1000_hw *, u32, u16 *); + void (*release)(struct e1000_hw *); + s32 (*reset)(struct e1000_hw *); s32 (*set_d0_lplu_state)(struct e1000_hw *, bool); s32 (*set_d3_lplu_state)(struct e1000_hw *, bool); - s32 (*write_phy_reg)(struct e1000_hw *, u32, u16); - void (*power_up_phy)(struct e1000_hw *); - void (*power_down_phy)(struct e1000_hw *); - - /* Function pointers for the NVM. */ - s32 (*init_nvm_params)(struct e1000_hw *); - s32 (*acquire_nvm)(struct e1000_hw *); - s32 (*read_nvm)(struct e1000_hw *, u16, u16, u16 *); - void (*release_nvm)(struct e1000_hw *); - void (*reload_nvm)(struct e1000_hw *); - s32 (*update_nvm)(struct e1000_hw *); + s32 (*write_reg)(struct e1000_hw *, u32, u16); + void (*power_up)(struct e1000_hw *); + void (*power_down)(struct e1000_hw *); +}; + +struct e1000_nvm_operations { + s32 (*init_params)(struct e1000_hw *); + s32 (*acquire)(struct e1000_hw *); + s32 (*read)(struct e1000_hw *, u16, u16, u16 *); + void (*release)(struct e1000_hw *); + void (*reload)(struct e1000_hw *); + s32 (*update)(struct e1000_hw *); s32 (*valid_led_default)(struct e1000_hw *, u16 *); - s32 (*validate_nvm)(struct e1000_hw *); - s32 (*write_nvm)(struct e1000_hw *, u16, u16, u16 *); + s32 (*validate)(struct e1000_hw *); + s32 (*write)(struct e1000_hw *, u16, u16, u16 *); }; struct e1000_mac_info { + struct e1000_mac_operations ops; u8 addr[6]; u8 perm_addr[6]; @@ -625,6 +627,7 @@ struct e1000_mac_info { }; struct e1000_phy_info { + struct e1000_phy_operations ops; e1000_phy_type type; e1000_1000t_rx_status local_rx; @@ -658,6 +661,7 @@ struct e1000_phy_info { }; struct e1000_nvm_info { + struct e1000_nvm_operations ops; e1000_nvm_type type; e1000_nvm_override override; @@ -700,7 +704,6 @@ struct e1000_hw { u8 *flash_address; unsigned long io_base; - struct e1000_functions func; struct e1000_mac_info mac; struct e1000_fc_info fc; struct e1000_phy_info phy; diff --git a/sys/dev/em/e1000_ich8lan.c b/sys/dev/em/e1000_ich8lan.c index 29b80e9..149d66b 100644 --- a/sys/dev/em/e1000_ich8lan.c +++ b/sys/dev/em/e1000_ich8lan.c @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,9 +29,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ /* e1000_ich8lan * e1000_ich9lan @@ -40,60 +39,58 @@ #include "e1000_api.h" #include "e1000_ich8lan.h" -STATIC s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw); -STATIC void e1000_release_swflag_ich8lan(struct e1000_hw *hw); -STATIC bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, +static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw); +static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw); +static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw); +static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw); +static void e1000_release_swflag_ich8lan(struct e1000_hw *hw); +static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); +static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw); +static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw); +static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw); +static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw); +static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw); +static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active); -STATIC s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, +static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active); -STATIC s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, +static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); -STATIC s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, +static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); -STATIC s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, +static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw); +static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw); +static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data); -STATIC s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_init_hw_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_setup_link_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, +static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw); +static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw); +static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw); +static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw); +static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw); +static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed, u16 *duplex); -STATIC s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_led_on_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_led_off_ich8lan(struct e1000_hw *hw); -STATIC void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank); +static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw); +static s32 e1000_led_on_ich8lan(struct e1000_hw *hw); +static s32 e1000_led_off_ich8lan(struct e1000_hw *hw); +static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw); +static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank); static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout); static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw); static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw); static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw); static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw); -STATIC s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, - u32 offset, u8* data); static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, u8 size, u16* data); -STATIC s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, +static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset, u16 *data); static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, u8 byte); -STATIC s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, +static s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, u8 data); static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, u8 size, u16 data); -STATIC s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw); -STATIC void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw); +static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw); +static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw); /* ICH GbE Flash Hardware Sequencing Flash Status Register bit breakdown */ /* Offset 04h HSFSTS */ @@ -152,33 +149,32 @@ struct e1000_dev_spec_ich8lan { * * Initialize family-specific PHY parameters and function pointers. **/ -STATIC s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) +static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; u16 i = 0; DEBUGFUNC("e1000_init_phy_params_ich8lan"); - phy->addr = 1; - phy->reset_delay_us = 100; - - func->acquire_phy = e1000_acquire_swflag_ich8lan; - func->check_polarity = e1000_check_polarity_ife_ich8lan; - func->check_reset_block = e1000_check_reset_block_ich8lan; - func->force_speed_duplex = e1000_phy_force_speed_duplex_ich8lan; - func->get_cable_length = e1000_get_cable_length_igp_2; - func->get_cfg_done = e1000_get_cfg_done_ich8lan; - func->get_phy_info = e1000_get_phy_info_ich8lan; - func->read_phy_reg = e1000_read_phy_reg_igp; - func->release_phy = e1000_release_swflag_ich8lan; - func->reset_phy = e1000_phy_hw_reset_ich8lan; - func->set_d0_lplu_state = e1000_set_d0_lplu_state_ich8lan; - func->set_d3_lplu_state = e1000_set_d3_lplu_state_ich8lan; - func->write_phy_reg = e1000_write_phy_reg_igp; - func->power_up_phy = e1000_power_up_phy_copper; - func->power_down_phy = e1000_power_down_phy_copper_ich8lan; + phy->addr = 1; + phy->reset_delay_us = 100; + + phy->ops.acquire = e1000_acquire_swflag_ich8lan; + phy->ops.check_polarity = e1000_check_polarity_ife_ich8lan; + phy->ops.check_reset_block = e1000_check_reset_block_ich8lan; + phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_ich8lan; + phy->ops.get_cable_length = e1000_get_cable_length_igp_2; + phy->ops.get_cfg_done = e1000_get_cfg_done_ich8lan; + phy->ops.get_info = e1000_get_phy_info_ich8lan; + phy->ops.read_reg = e1000_read_phy_reg_igp; + phy->ops.release = e1000_release_swflag_ich8lan; + phy->ops.reset = e1000_phy_hw_reset_ich8lan; + phy->ops.set_d0_lplu_state = e1000_set_d0_lplu_state_ich8lan; + phy->ops.set_d3_lplu_state = e1000_set_d3_lplu_state_ich8lan; + phy->ops.write_reg = e1000_write_phy_reg_igp; + phy->ops.power_up = e1000_power_up_phy_copper; + phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; /* * We may need to do this twice - once for IGP and if that fails, @@ -186,8 +182,8 @@ STATIC s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) */ ret_val = e1000_determine_phy_address(hw); if (ret_val) { - func->write_phy_reg = e1000_write_phy_reg_bm; - func->read_phy_reg = e1000_read_phy_reg_bm; + phy->ops.write_reg = e1000_write_phy_reg_bm; + phy->ops.read_reg = e1000_read_phy_reg_bm; ret_val = e1000_determine_phy_address(hw); if (ret_val) { DEBUGOUT("Cannot determine PHY address. Erroring out\n"); @@ -219,9 +215,9 @@ STATIC s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) case BME1000_E_PHY_ID: phy->type = e1000_phy_bm; phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; - func->read_phy_reg = e1000_read_phy_reg_bm; - func->write_phy_reg = e1000_write_phy_reg_bm; - func->commit_phy = e1000_phy_sw_reset_generic; + phy->ops.read_reg = e1000_read_phy_reg_bm; + phy->ops.write_reg = e1000_write_phy_reg_bm; + phy->ops.commit = e1000_phy_sw_reset_generic; break; default: ret_val = -E1000_ERR_PHY; @@ -239,10 +235,9 @@ out: * Initialize family-specific NVM parameters and function * pointers. **/ -STATIC s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) +static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; - struct e1000_functions *func = &hw->func; struct e1000_dev_spec_ich8lan *dev_spec; u32 gfpreg, sector_base_addr, sector_end_addr; s32 ret_val = E1000_SUCCESS; @@ -299,13 +294,13 @@ STATIC s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) } /* Function Pointers */ - func->acquire_nvm = e1000_acquire_swflag_ich8lan; - func->read_nvm = e1000_read_nvm_ich8lan; - func->release_nvm = e1000_release_swflag_ich8lan; - func->update_nvm = e1000_update_nvm_checksum_ich8lan; - func->valid_led_default = e1000_valid_led_default_ich8lan; - func->validate_nvm = e1000_validate_nvm_checksum_ich8lan; - func->write_nvm = e1000_write_nvm_ich8lan; + nvm->ops.acquire = e1000_acquire_swflag_ich8lan; + nvm->ops.read = e1000_read_nvm_ich8lan; + nvm->ops.release = e1000_release_swflag_ich8lan; + nvm->ops.update = e1000_update_nvm_checksum_ich8lan; + nvm->ops.valid_led_default = e1000_valid_led_default_ich8lan; + nvm->ops.validate = e1000_validate_nvm_checksum_ich8lan; + nvm->ops.write = e1000_write_nvm_ich8lan; out: return ret_val; @@ -318,10 +313,9 @@ out: * Initialize family-specific MAC parameters and function * pointers. **/ -STATIC s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) +static s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; - struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_init_mac_params_ich8lan"); @@ -343,38 +337,38 @@ STATIC s32 e1000_init_mac_params_ich8lan(struct e1000_hw *hw) /* Function pointers */ /* bus type/speed/width */ - func->get_bus_info = e1000_get_bus_info_ich8lan; + mac->ops.get_bus_info = e1000_get_bus_info_ich8lan; /* reset */ - func->reset_hw = e1000_reset_hw_ich8lan; + mac->ops.reset_hw = e1000_reset_hw_ich8lan; /* hw initialization */ - func->init_hw = e1000_init_hw_ich8lan; + mac->ops.init_hw = e1000_init_hw_ich8lan; /* link setup */ - func->setup_link = e1000_setup_link_ich8lan; + mac->ops.setup_link = e1000_setup_link_ich8lan; /* physical interface setup */ - func->setup_physical_interface = e1000_setup_copper_link_ich8lan; + mac->ops.setup_physical_interface = e1000_setup_copper_link_ich8lan; /* check for link */ - func->check_for_link = e1000_check_for_copper_link_generic; + mac->ops.check_for_link = e1000_check_for_copper_link_generic; /* check management mode */ - func->check_mng_mode = e1000_check_mng_mode_ich8lan; + mac->ops.check_mng_mode = e1000_check_mng_mode_ich8lan; /* link info */ - func->get_link_up_info = e1000_get_link_up_info_ich8lan; + mac->ops.get_link_up_info = e1000_get_link_up_info_ich8lan; /* multicast address update */ - func->update_mc_addr_list = e1000_update_mc_addr_list_generic; + mac->ops.update_mc_addr_list = e1000_update_mc_addr_list_generic; /* setting MTA */ - func->mta_set = e1000_mta_set_generic; + mac->ops.mta_set = e1000_mta_set_generic; /* blink LED */ - func->blink_led = e1000_blink_led_generic; + mac->ops.blink_led = e1000_blink_led_generic; /* setup LED */ - func->setup_led = e1000_setup_led_generic; + mac->ops.setup_led = e1000_setup_led_generic; /* cleanup LED */ - func->cleanup_led = e1000_cleanup_led_ich8lan; + mac->ops.cleanup_led = e1000_cleanup_led_ich8lan; /* turn on/off LED */ - func->led_on = e1000_led_on_ich8lan; - func->led_off = e1000_led_off_ich8lan; + mac->ops.led_on = e1000_led_on_ich8lan; + mac->ops.led_off = e1000_led_off_ich8lan; /* remove device */ - func->remove_device = e1000_remove_device_generic; + mac->ops.remove_device = e1000_remove_device_generic; /* clear hardware counters */ - func->clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan; + mac->ops.clear_hw_cntrs = e1000_clear_hw_cntrs_ich8lan; hw->dev_spec_size = sizeof(struct e1000_dev_spec_ich8lan); @@ -402,9 +396,9 @@ void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw) { DEBUGFUNC("e1000_init_function_pointers_ich8lan"); - hw->func.init_mac_params = e1000_init_mac_params_ich8lan; - hw->func.init_nvm_params = e1000_init_nvm_params_ich8lan; - hw->func.init_phy_params = e1000_init_phy_params_ich8lan; + hw->mac.ops.init_params = e1000_init_mac_params_ich8lan; + hw->nvm.ops.init_params = e1000_init_nvm_params_ich8lan; + hw->phy.ops.init_params = e1000_init_phy_params_ich8lan; } /** @@ -415,7 +409,7 @@ void e1000_init_function_pointers_ich8lan(struct e1000_hw *hw) * operations. This is a function pointer entry point only called by * read/write routines for the PHY and NVM parts. **/ -STATIC s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) +static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) { u32 extcnf_ctrl, timeout = PHY_CFG_TIMEOUT; s32 ret_val = E1000_SUCCESS; @@ -454,7 +448,7 @@ out: * This is a function pointer entry point only called by read/write * routines for the PHY and NVM parts. **/ -STATIC void e1000_release_swflag_ich8lan(struct e1000_hw *hw) +static void e1000_release_swflag_ich8lan(struct e1000_hw *hw) { u32 extcnf_ctrl; @@ -475,7 +469,7 @@ STATIC void e1000_release_swflag_ich8lan(struct e1000_hw *hw) * This is a function pointer entry point only called by read/write * routines for the PHY and NVM parts. **/ -STATIC bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw) +static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw) { u32 fwsm; @@ -495,7 +489,7 @@ STATIC bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw) * This is a function pointer entry point only called by * reset routines. **/ -STATIC s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) +static s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) { u32 fwsm; @@ -515,7 +509,7 @@ STATIC s32 e1000_check_reset_block_ich8lan(struct e1000_hw *hw) * This is a function pointer entry point only called by * PHY setup routines. **/ -STATIC s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw) +static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -529,25 +523,25 @@ STATIC s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw) goto out; } - ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &data); + ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &data); if (ret_val) goto out; e1000_phy_force_speed_duplex_setup(hw, &data); - ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, data); + ret_val = phy->ops.write_reg(hw, PHY_CONTROL, data); if (ret_val) goto out; /* Disable MDI-X support for 10/100 */ - ret_val = e1000_read_phy_reg(hw, IFE_PHY_MDIX_CONTROL, &data); + ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data); if (ret_val) goto out; data &= ~IFE_PMC_AUTO_MDIX; data &= ~IFE_PMC_FORCE_MDIX; - ret_val = e1000_write_phy_reg(hw, IFE_PHY_MDIX_CONTROL, data); + ret_val = phy->ops.write_reg(hw, IFE_PHY_MDIX_CONTROL, data); if (ret_val) goto out; @@ -590,9 +584,10 @@ out: * This is a function pointer entry point called by drivers * or other shared routines. **/ -STATIC s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) +static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; + struct e1000_nvm_info *nvm = &hw->nvm; u32 i, data, cnf_size, cnf_base_addr, sw_cfg_mask; s32 ret_val; u16 loop = E1000_ICH8_LAN_INIT_TIMEOUT; @@ -670,14 +665,14 @@ STATIC s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) word_addr = (u16)(cnf_base_addr << 1); for (i = 0; i < cnf_size; i++) { - ret_val = e1000_read_nvm(hw, + ret_val = nvm->ops.read(hw, (word_addr + i * 2), 1, ®_data); if (ret_val) goto out; - ret_val = e1000_read_nvm(hw, + ret_val = nvm->ops.read(hw, (word_addr + i * 2 + 1), 1, ®_addr); @@ -692,7 +687,7 @@ STATIC s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) reg_addr |= phy_page; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, (u32)reg_addr, reg_data); if (ret_val) @@ -712,7 +707,7 @@ out: * This is a function pointer entry point called by drivers * or other shared routines. **/ -STATIC s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw) +static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw) { s32 ret_val = -E1000_ERR_PHY_TYPE; @@ -760,7 +755,7 @@ static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw) goto out; } - ret_val = e1000_read_phy_reg(hw, IFE_PHY_SPECIAL_CONTROL, &data); + ret_val = phy->ops.read_reg(hw, IFE_PHY_SPECIAL_CONTROL, &data); if (ret_val) goto out; phy->polarity_correction = (data & IFE_PSC_AUTO_POLARITY_DISABLE) @@ -777,7 +772,7 @@ static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw) : e1000_rev_polarity_normal; } - ret_val = e1000_read_phy_reg(hw, IFE_PHY_MDIX_CONTROL, &data); + ret_val = phy->ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, &data); if (ret_val) goto out; @@ -800,7 +795,7 @@ out: * This function is only called by other family-specific * routines. **/ -STATIC s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw) +static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; s32 ret_val; @@ -820,7 +815,7 @@ STATIC s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw) mask = IFE_PSC_FORCE_POLARITY; } - ret_val = e1000_read_phy_reg(hw, offset, &phy_data); + ret_val = phy->ops.read_reg(hw, offset, &phy_data); if (!ret_val) phy->cable_polarity = (phy_data & mask) @@ -843,7 +838,7 @@ STATIC s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw) * This is a function pointer entry point only called by * PHY setup routines. **/ -STATIC s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, +static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; @@ -871,11 +866,11 @@ STATIC s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, e1000_gig_downshift_workaround_ich8lan(hw); /* When LPLU is enabled, we should disable SmartSpeed */ - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &data); data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); if (ret_val) @@ -891,27 +886,27 @@ STATIC s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, * SmartSpeed, so performance is maintained. */ if (phy->smart_speed == e1000_smart_speed_on) { - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &data); if (ret_val) goto out; data |= IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); if (ret_val) goto out; } else if (phy->smart_speed == e1000_smart_speed_off) { - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &data); if (ret_val) goto out; data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); if (ret_val) @@ -936,7 +931,7 @@ out: * This is a function pointer entry point only called by * PHY setup routines. **/ -STATIC s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, +static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; @@ -958,27 +953,27 @@ STATIC s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, * SmartSpeed, so performance is maintained. */ if (phy->smart_speed == e1000_smart_speed_on) { - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &data); if (ret_val) goto out; data |= IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); if (ret_val) goto out; } else if (phy->smart_speed == e1000_smart_speed_off) { - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &data); if (ret_val) goto out; data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); if (ret_val) @@ -999,14 +994,14 @@ STATIC s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, e1000_gig_downshift_workaround_ich8lan(hw); /* When LPLU is enabled, we should disable SmartSpeed */ - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &data); if (ret_val) goto out; data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); } @@ -1022,49 +1017,13 @@ out: * * Reads signature byte from the NVM using the flash access registers. **/ -STATIC s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) +static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) { s32 ret_val = E1000_SUCCESS; - struct e1000_nvm_info *nvm = &hw->nvm; - /* flash bank size is in words */ - u32 bank1_offset = nvm->flash_bank_size * sizeof(u16); - u32 act_offset = E1000_ICH_NVM_SIG_WORD * 2 + 1; - u8 bank_high_byte = 0; - - if (hw->mac.type != e1000_ich10lan) { - if (E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_SEC1VAL) - *bank = 1; - else - *bank = 0; - } else if (hw->dev_spec != NULL) { - /* - * Make sure the signature for bank 0 is valid, - * if not check for bank1 - */ - e1000_read_flash_byte_ich8lan(hw, act_offset, &bank_high_byte); - if ((bank_high_byte & 0xC0) == 0x80) { - *bank = 0; - } else { - /* - * find if segment 1 is valid by verifying - * bit 15:14 = 10b in word 0x13 - */ - e1000_read_flash_byte_ich8lan(hw, - act_offset + bank1_offset, - &bank_high_byte); - - /* bank1 has a valid signature equivalent to SEC1V */ - if ((bank_high_byte & 0xC0) == 0x80) { - *bank = 1; - } else { - DEBUGOUT("ERROR: EEPROM not present\n"); - ret_val = -E1000_ERR_NVM; - } - } - } else { - DEBUGOUT("DEV SPEC is NULL\n"); - ret_val = -E1000_ERR_NVM; - } + if (E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_SEC1VAL) + *bank = 1; + else + *bank = 0; return ret_val; } @@ -1078,7 +1037,7 @@ STATIC s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) * * Reads a word(s) from the NVM using the flash access registers. **/ -STATIC s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, +static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; @@ -1105,7 +1064,7 @@ STATIC s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, goto out; } - ret_val = e1000_acquire_nvm(hw); + ret_val = nvm->ops.acquire(hw); if (ret_val) goto out; @@ -1130,7 +1089,7 @@ STATIC s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, } } - e1000_release_nvm(hw); + nvm->ops.release(hw); out: return ret_val; @@ -1260,7 +1219,7 @@ static s32 e1000_flash_cycle_ich8lan(struct e1000_hw *hw, u32 timeout) * Reads the flash word at offset into data. Offset is converted * to bytes before read. **/ -STATIC s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset, +static s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset, u16 *data) { s32 ret_val; @@ -1282,30 +1241,6 @@ out: } /** - * e1000_read_flash_byte_ich8lan - Read byte from flash - * @hw: pointer to the HW structure - * @offset: The offset of the byte to read. - * @data: Pointer to a byte to store the value read. - * - * Reads a single byte from the NVM using the flash access registers. - **/ -STATIC s32 e1000_read_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, - u8* data) -{ - s32 ret_val = E1000_SUCCESS; - u16 word = 0; - - ret_val = e1000_read_flash_data_ich8lan(hw, offset, 1, &word); - if (ret_val) - goto out; - - *data = (u8)word; - -out: - return ret_val; -} - -/** * e1000_read_flash_data_ich8lan - Read byte or word from NVM * @hw: pointer to the HW structure * @offset: The offset (in bytes) of the byte or word to read. @@ -1397,7 +1332,7 @@ out: * * Writes a byte or word to the NVM using the flash access registers. **/ -STATIC s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, +static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { struct e1000_nvm_info *nvm = &hw->nvm; @@ -1422,7 +1357,7 @@ STATIC s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, goto out; } - ret_val = e1000_acquire_nvm(hw); + ret_val = nvm->ops.acquire(hw); if (ret_val) goto out; @@ -1431,7 +1366,7 @@ STATIC s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, dev_spec->shadow_ram[offset+i].value = data[i]; } - e1000_release_nvm(hw); + nvm->ops.release(hw); out: return ret_val; @@ -1448,7 +1383,7 @@ out: * After a successful commit, the shadow ram is cleared and is ready for * future writes. **/ -STATIC s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) +static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) { struct e1000_nvm_info *nvm = &hw->nvm; struct e1000_dev_spec_ich8lan *dev_spec; @@ -1467,7 +1402,7 @@ STATIC s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) if (nvm->type != e1000_nvm_flash_sw) goto out; - ret_val = e1000_acquire_nvm(hw); + ret_val = nvm->ops.acquire(hw); if (ret_val) goto out; @@ -1540,7 +1475,7 @@ STATIC s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) */ if (ret_val) { DEBUGOUT("Flash commit failed.\n"); - e1000_release_nvm(hw); + nvm->ops.release(hw); goto out; } @@ -1557,7 +1492,7 @@ STATIC s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) act_offset * 2 + 1, (u8)(data >> 8)); if (ret_val) { - e1000_release_nvm(hw); + nvm->ops.release(hw); goto out; } @@ -1570,7 +1505,7 @@ STATIC s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1; ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0); if (ret_val) { - e1000_release_nvm(hw); + nvm->ops.release(hw); goto out; } @@ -1580,13 +1515,13 @@ STATIC s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) dev_spec->shadow_ram[i].value = 0xFFFF; } - e1000_release_nvm(hw); + nvm->ops.release(hw); /* * Reload the EEPROM, or else modifications will not appear * until after the next adapter reset. */ - e1000_reload_nvm(hw); + nvm->ops.reload(hw); msec_delay(10); out: @@ -1602,7 +1537,7 @@ out: * not calculated, in which case we need to calculate the checksum and set * bit 6. **/ -STATIC s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) +static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; u16 data; @@ -1615,16 +1550,16 @@ STATIC s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw) * was prepared by OEM software and did not calculate the * checksum...a likely scenario. */ - ret_val = e1000_read_nvm(hw, 0x19, 1, &data); + ret_val = hw->nvm.ops.read(hw, 0x19, 1, &data); if (ret_val) goto out; if ((data & 0x40) == 0) { data |= 0x40; - ret_val = e1000_write_nvm(hw, 0x19, 1, &data); + ret_val = hw->nvm.ops.write(hw, 0x19, 1, &data); if (ret_val) goto out; - ret_val = e1000_update_nvm_checksum(hw); + ret_val = hw->nvm.ops.update(hw); if (ret_val) goto out; } @@ -1725,7 +1660,7 @@ out: * * Writes a single byte to the NVM using the flash access registers. **/ -STATIC s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, +static s32 e1000_write_flash_byte_ich8lan(struct e1000_hw *hw, u32 offset, u8 data) { u16 word = (u16)data; @@ -1780,7 +1715,7 @@ out: * Erases the bank specified. Each bank is a 4k block. Banks are 0 based. * bank N is 4096 * N + flash_reg_addr. **/ -STATIC s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) +static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) { struct e1000_nvm_info *nvm = &hw->nvm; union ich8_hws_flash_status hsfsts; @@ -1906,13 +1841,13 @@ out: * settings is all 0's or F's, set the LED default to a valid LED default * setting. **/ -STATIC s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data) +static s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data) { s32 ret_val; DEBUGFUNC("e1000_valid_led_default_ich8lan"); - ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data); + ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data); if (ret_val) { DEBUGOUT("NVM Read Error\n"); goto out; @@ -1933,7 +1868,7 @@ out: * ICH8 use the PCI Express bus, but does not contain a PCI Express Capability * register, so the the bus width is hard coded. **/ -STATIC s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw) +static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw) { struct e1000_bus_info *bus = &hw->bus; s32 ret_val; @@ -1961,7 +1896,7 @@ STATIC s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw) * Does a full reset of the hardware which includes a reset of the PHY and * MAC. **/ -STATIC s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) +static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) { u32 ctrl, icr, kab; s32 ret_val; @@ -2001,7 +1936,7 @@ STATIC s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) ctrl = E1000_READ_REG(hw, E1000_CTRL); - if (!e1000_check_reset_block(hw) && !hw->phy.reset_disable) { + if (!hw->phy.ops.check_reset_block(hw) && !hw->phy.reset_disable) { /* * PHY HW reset requires MAC CORE reset at the same * time to make sure the interface between MAC and the @@ -2046,7 +1981,7 @@ STATIC s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) * - setup transmit descriptors * - clear statistics **/ -STATIC s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) +static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; u32 ctrl_ext, txdctl, snoop; @@ -2073,7 +2008,7 @@ STATIC s32 e1000_init_hw_ich8lan(struct e1000_hw *hw) E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); /* Setup link and flow control */ - ret_val = e1000_setup_link(hw); + ret_val = mac->ops.setup_link(hw); /* Set the transmit descriptor write-back policy for both queues */ txdctl = E1000_READ_REG(hw, E1000_TXDCTL(0)); @@ -2181,14 +2116,13 @@ out: * should be established. Assumes the hardware has previously been reset * and the transmitter and receiver are not enabled. **/ -STATIC s32 e1000_setup_link_ich8lan(struct e1000_hw *hw) +static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw) { - struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_setup_link_ich8lan"); - if (e1000_check_reset_block(hw)) + if (hw->phy.ops.check_reset_block(hw)) goto out; /* @@ -2204,7 +2138,7 @@ STATIC s32 e1000_setup_link_ich8lan(struct e1000_hw *hw) DEBUGOUT1("After fix-ups FlowControl is now = %x\n", hw->fc.type); /* Continue to configure the copper link. */ - ret_val = func->setup_physical_interface(hw); + ret_val = hw->mac.ops.setup_physical_interface(hw); if (ret_val) goto out; @@ -2224,7 +2158,7 @@ out: * when polling the PHY, then call the generic setup_copper_link to finish * configuring the copper link. **/ -STATIC s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) +static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) { u32 ctrl; s32 ret_val; @@ -2264,7 +2198,8 @@ STATIC s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) } if (hw->phy.type == e1000_phy_ife) { - ret_val = e1000_read_phy_reg(hw, IFE_PHY_MDIX_CONTROL, ®_data); + ret_val = hw->phy.ops.read_reg(hw, IFE_PHY_MDIX_CONTROL, + ®_data); if (ret_val) goto out; @@ -2282,7 +2217,8 @@ STATIC s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) reg_data |= IFE_PMC_AUTO_MDIX; break; } - ret_val = e1000_write_phy_reg(hw, IFE_PHY_MDIX_CONTROL, reg_data); + ret_val = hw->phy.ops.write_reg(hw, IFE_PHY_MDIX_CONTROL, + reg_data); if (ret_val) goto out; } @@ -2302,7 +2238,7 @@ out: * information and then calls the Kumeran lock loss workaround for links at * gigabit speeds. **/ -STATIC s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed, +static s32 e1000_get_link_up_info_ich8lan(struct e1000_hw *hw, u16 *speed, u16 *duplex) { s32 ret_val; @@ -2372,11 +2308,11 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw) for (i = 0; i < 10; i++) { /* read once to clear */ - ret_val = e1000_read_phy_reg(hw, IGP3_KMRN_DIAG, &data); + ret_val = hw->phy.ops.read_reg(hw, IGP3_KMRN_DIAG, &data); if (ret_val) goto out; /* and again to get new status */ - ret_val = e1000_read_phy_reg(hw, IGP3_KMRN_DIAG, &data); + ret_val = hw->phy.ops.read_reg(hw, IGP3_KMRN_DIAG, &data); if (ret_val) goto out; @@ -2387,7 +2323,7 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw) } /* Issue PHY reset */ - e1000_phy_hw_reset(hw); + hw->phy.ops.reset(hw); msec_delay_irq(5); } /* Disable GigE link negotiation */ @@ -2479,14 +2415,14 @@ void e1000_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw) e1000_gig_downshift_workaround_ich8lan(hw); /* Write VR power-down enable */ - e1000_read_phy_reg(hw, IGP3_VR_CTRL, &data); + hw->phy.ops.read_reg(hw, IGP3_VR_CTRL, &data); data &= ~IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK; - e1000_write_phy_reg(hw, + hw->phy.ops.write_reg(hw, IGP3_VR_CTRL, data | IGP3_VR_CTRL_MODE_SHUTDOWN); /* Read it back and test */ - e1000_read_phy_reg(hw, IGP3_VR_CTRL, &data); + hw->phy.ops.read_reg(hw, IGP3_VR_CTRL, &data); data &= IGP3_VR_CTRL_DEV_POWERDOWN_MODE_MASK; if ((data == IGP3_VR_CTRL_MODE_SHUTDOWN) || retry) break; @@ -2547,16 +2483,13 @@ out: * 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation * to a lower speed. * - * Should only be called for ICH9m and ICH10 devices. + * Should only be called for ICH9. **/ void e1000_disable_gig_wol_ich8lan(struct e1000_hw *hw) { u32 phy_ctrl; - if ((hw->mac.type == e1000_ich10lan) || - ((hw->mac.type == e1000_ich9lan) && - ((hw->device_id == E1000_DEV_ID_ICH9_IGP_M) || - (hw->device_id == E1000_DEV_ID_ICH9_IGP_M_AMT)))) { + if (hw->mac.type == e1000_ich9lan) { phy_ctrl = E1000_READ_REG(hw, E1000_PHY_CTRL); phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE; @@ -2572,14 +2505,14 @@ void e1000_disable_gig_wol_ich8lan(struct e1000_hw *hw) * * Return the LED back to the default configuration. **/ -STATIC s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw) +static s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_cleanup_led_ich8lan"); if (hw->phy.type == e1000_phy_ife) - ret_val = e1000_write_phy_reg(hw, + ret_val = hw->phy.ops.write_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0); else @@ -2594,14 +2527,14 @@ STATIC s32 e1000_cleanup_led_ich8lan(struct e1000_hw *hw) * * Turn on the LEDs. **/ -STATIC s32 e1000_led_on_ich8lan(struct e1000_hw *hw) +static s32 e1000_led_on_ich8lan(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_led_on_ich8lan"); if (hw->phy.type == e1000_phy_ife) - ret_val = e1000_write_phy_reg(hw, + ret_val = hw->phy.ops.write_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_ON)); else @@ -2616,14 +2549,14 @@ STATIC s32 e1000_led_on_ich8lan(struct e1000_hw *hw) * * Turn off the LEDs. **/ -STATIC s32 e1000_led_off_ich8lan(struct e1000_hw *hw) +static s32 e1000_led_off_ich8lan(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_led_off_ich8lan"); if (hw->phy.type == e1000_phy_ife) - ret_val = e1000_write_phy_reg(hw, + ret_val = hw->phy.ops.write_reg(hw, IFE_PHY_SPECIAL_CONTROL_LED, (IFE_PSCL_PROBE_MODE | IFE_PSCL_PROBE_LEDS_OFF)); else @@ -2642,25 +2575,16 @@ STATIC s32 e1000_led_off_ich8lan(struct e1000_hw *hw) * E1000_SUCCESS. If we were to return with error, EEPROM-less silicon * would not be able to be reset or change link. **/ -STATIC s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw) +static s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw) { s32 ret_val = E1000_SUCCESS; - u32 bank = 0; e1000_get_cfg_done_generic(hw); /* If EEPROM is not marked present, init the IGP 3 PHY manually */ - if (hw->mac.type != e1000_ich10lan) { - if (((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) && - (hw->phy.type == e1000_phy_igp_3)) { - e1000_phy_init_script_igp3(hw); - } - } else { - if (e1000_valid_nvm_bank_detect_ich8lan(hw, &bank)) { - /* Maybe we should do a basic Boazman config */ - DEBUGOUT("EEPROM not present\n"); - ret_val = -E1000_ERR_CONFIG; - } + if (((E1000_READ_REG(hw, E1000_EECD) & E1000_EECD_PRES) == 0) && + (hw->phy.type == e1000_phy_igp_3)) { + e1000_phy_init_script_igp3(hw); } return ret_val; @@ -2673,10 +2597,13 @@ STATIC s32 e1000_get_cfg_done_ich8lan(struct e1000_hw *hw) * In the case of a PHY power down to save power, or to turn off link during a * driver unload, or wake on lan is not enabled, remove the link. **/ -STATIC void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw) +static void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw) { + struct e1000_phy_info *phy = &hw->phy; + struct e1000_mac_info *mac = &hw->mac; + /* If the management interface is not enabled, then power down */ - if (!(e1000_check_mng_mode(hw) || e1000_check_reset_block(hw))) + if (!(mac->ops.check_mng_mode(hw) || phy->ops.check_reset_block(hw))) e1000_power_down_phy_copper(hw); return; @@ -2689,7 +2616,7 @@ STATIC void e1000_power_down_phy_copper_ich8lan(struct e1000_hw *hw) * Clears hardware counters specific to the silicon family and calls * clear_hw_cntrs_generic to clear all general purpose counters. **/ -STATIC void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw) +static void e1000_clear_hw_cntrs_ich8lan(struct e1000_hw *hw) { volatile u32 temp; diff --git a/sys/dev/em/e1000_ich8lan.h b/sys/dev/em/e1000_ich8lan.h index 32102ee..caa23a0 100644 --- a/sys/dev/em/e1000_ich8lan.h +++ b/sys/dev/em/e1000_ich8lan.h @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,9 +29,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ #ifndef _E1000_ICH8LAN_H_ #define _E1000_ICH8LAN_H_ @@ -113,9 +112,4 @@ E1000_IMS_PHYINT | \ E1000_IMS_EPRST) -/* Additional interrupt register bit definitions */ -#define E1000_ICR_LSECPNC 0x00004000 /* PN threshold - client */ -#define E1000_IMS_LSECPNC E1000_ICR_LSECPNC /* PN threshold - client */ -#define E1000_ICS_LSECPNC E1000_ICR_LSECPNC /* PN threshold - client */ - #endif diff --git a/sys/dev/em/e1000_mac.c b/sys/dev/em/e1000_mac.c index 511a816..fa50d81 100644 --- a/sys/dev/em/e1000_mac.c +++ b/sys/dev/em/e1000_mac.c @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,14 +29,139 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ #include "e1000_api.h" #include "e1000_mac.h" /** + * e1000_init_mac_ops_generic - Initialize MAC function pointers + * @hw: pointer to the HW structure + * + * Setups up the function pointers to no-op functions + **/ +void e1000_init_mac_ops_generic(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + DEBUGFUNC("e1000_init_mac_ops_generic"); + + /* General Setup */ + mac->ops.init_params = e1000_null_ops_generic; + mac->ops.init_hw = e1000_null_ops_generic; + mac->ops.reset_hw = e1000_null_ops_generic; + mac->ops.setup_physical_interface = e1000_null_ops_generic; + mac->ops.get_bus_info = e1000_null_ops_generic; + mac->ops.read_mac_addr = e1000_read_mac_addr_generic; + mac->ops.remove_device = e1000_remove_device_generic; + mac->ops.config_collision_dist = e1000_config_collision_dist_generic; + mac->ops.clear_hw_cntrs = e1000_null_mac_generic; + /* LED */ + mac->ops.cleanup_led = e1000_null_ops_generic; + mac->ops.setup_led = e1000_null_ops_generic; + mac->ops.blink_led = e1000_null_ops_generic; + mac->ops.led_on = e1000_null_ops_generic; + mac->ops.led_off = e1000_null_ops_generic; + /* LINK */ + mac->ops.setup_link = e1000_null_ops_generic; + mac->ops.get_link_up_info = e1000_null_link_info; + mac->ops.check_for_link = e1000_null_ops_generic; + mac->ops.wait_autoneg = e1000_wait_autoneg_generic; + /* Management */ + mac->ops.check_mng_mode = e1000_null_mng_mode; + mac->ops.mng_host_if_write = e1000_mng_host_if_write_generic; + mac->ops.mng_write_cmd_header = e1000_mng_write_cmd_header_generic; + mac->ops.mng_enable_host_if = e1000_mng_enable_host_if_generic; + /* VLAN, MC, etc. */ + mac->ops.update_mc_addr_list = e1000_null_update_mc; + mac->ops.clear_vfta = e1000_null_mac_generic; + mac->ops.write_vfta = e1000_null_write_vfta; + mac->ops.mta_set = e1000_null_mta_set; + mac->ops.rar_set = e1000_rar_set_generic; + mac->ops.validate_mdi_setting = e1000_validate_mdi_setting_generic; +} + +/** + * e1000_null_ops_generic - No-op function, returns 0 + * @hw: pointer to the HW structure + **/ +s32 e1000_null_ops_generic(struct e1000_hw *hw) +{ + DEBUGFUNC("e1000_null_ops_generic"); + return E1000_SUCCESS; +} + +/** + * e1000_null_mac_generic - No-op function, return void + * @hw: pointer to the HW structure + **/ +void e1000_null_mac_generic(struct e1000_hw *hw) +{ + DEBUGFUNC("e1000_null_mac_generic"); + return; +} + +/** + * e1000_null_link_info - No-op function, return 0 + * @hw: pointer to the HW structure + **/ +s32 e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d) +{ + DEBUGFUNC("e1000_null_link_info"); + return E1000_SUCCESS; +} + +/** + * e1000_null_mng_mode - No-op function, return FALSE + * @hw: pointer to the HW structure + **/ +bool e1000_null_mng_mode(struct e1000_hw *hw) +{ + DEBUGFUNC("e1000_null_mng_mode"); + return FALSE; +} + +/** + * e1000_null_update_mc - No-op function, return void + * @hw: pointer to the HW structure + **/ +void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a, u32 b, u32 c) +{ + DEBUGFUNC("e1000_null_update_mc"); + return; +} + +/** + * e1000_null_write_vfta - No-op function, return void + * @hw: pointer to the HW structure + **/ +void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b) +{ + DEBUGFUNC("e1000_null_write_vfta"); + return; +} + +/** + * e1000_null_set_mta - No-op function, return void + * @hw: pointer to the HW structure + **/ +void e1000_null_mta_set(struct e1000_hw *hw, u32 a) +{ + DEBUGFUNC("e1000_null_mta_set"); + return; +} + +/** + * e1000_null_rar_set - No-op function, return void + * @hw: pointer to the HW structure + **/ +void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a) +{ + DEBUGFUNC("e1000_null_rar_set"); + return; +} + +/** * e1000_remove_device_generic - Free device specific structure * @hw: pointer to the HW structure * @@ -207,7 +332,7 @@ void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count) /* Setup the receive address */ DEBUGOUT("Programming MAC Address into RAR[0]\n"); - e1000_rar_set_generic(hw, hw->mac.addr, 0); + hw->mac.ops.rar_set(hw, hw->mac.addr, 0); /* Zero out the other (rar_entry_count - 1) receive addresses */ DEBUGOUT1("Clearing RAR[1-%u]\n", rar_count-1); @@ -239,7 +364,7 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) DEBUGFUNC("e1000_check_alt_mac_addr_generic"); - ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, + ret_val = hw->nvm.ops.read(hw, NVM_ALT_MAC_ADDR_PTR, 1, &nvm_alt_mac_addr_offset); if (ret_val) { DEBUGOUT("NVM Read Error\n"); @@ -256,7 +381,7 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) for (i = 0; i < ETH_ADDR_LEN; i += 2) { offset = nvm_alt_mac_addr_offset + (i >> 1); - ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data); + ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); if (ret_val) { DEBUGOUT("NVM Read Error\n"); goto out; @@ -275,7 +400,7 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) for (i = 0; i < ETH_ADDR_LEN; i++) hw->mac.addr[i] = hw->mac.perm_addr[i] = alt_mac_addr[i]; - e1000_rar_set(hw, hw->mac.perm_addr, 0); + hw->mac.ops.rar_set(hw, hw->mac.perm_addr, 0); out: return ret_val; @@ -381,7 +506,7 @@ void e1000_update_mc_addr_list_generic(struct e1000_hw *hw, */ for (i = rar_used_count; i < rar_count; i++) { if (mc_addr_count) { - e1000_rar_set(hw, mc_addr_list, i); + hw->mac.ops.rar_set(hw, mc_addr_list, i); mc_addr_count--; mc_addr_list += ETH_ADDR_LEN; } else { @@ -403,7 +528,7 @@ void e1000_update_mc_addr_list_generic(struct e1000_hw *hw, for (; mc_addr_count > 0; mc_addr_count--) { hash_value = e1000_hash_mc_addr(hw, mc_addr_list); DEBUGOUT1("Hash value = 0x%03X\n", hash_value); - e1000_mta_set(hw, hash_value); + hw->mac.ops.mta_set(hw, hash_value); mc_addr_list += ETH_ADDR_LEN; } } @@ -821,7 +946,6 @@ out: **/ s32 e1000_setup_link_generic(struct e1000_hw *hw) { - struct e1000_functions *func = &hw->func; s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_setup_link_generic"); @@ -830,8 +954,9 @@ s32 e1000_setup_link_generic(struct e1000_hw *hw) * In the case of the phy reset being blocked, we already have a link. * We do not need to set it up again. */ - if (e1000_check_reset_block(hw)) - goto out; + if (hw->phy.ops.check_reset_block) + if (hw->phy.ops.check_reset_block(hw)) + goto out; /* * If flow control is set to default, set flow control based on @@ -853,7 +978,7 @@ s32 e1000_setup_link_generic(struct e1000_hw *hw) DEBUGOUT1("After fix-ups FlowControl is now = %x\n", hw->fc.type); /* Call the necessary media_type subroutine to configure the link. */ - ret_val = func->setup_physical_interface(hw); + ret_val = hw->mac.ops.setup_physical_interface(hw); if (ret_val) goto out; @@ -969,7 +1094,7 @@ s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) DEBUGFUNC("e1000_poll_fiber_serdes_link_generic"); /* - * If we have a signal (the cable is plugged in, or assumed true for + * If we have a signal (the cable is plugged in, or assumed TRUE for * serdes media) then poll for a "Link-Up" indication in the Device * Status Register. Time-out if a link isn't seen in 500 milliseconds * seconds (Auto-negotiation should complete in less than 500 @@ -990,7 +1115,7 @@ s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) * link up if we detect a signal. This will allow us to * communicate with non-autonegotiating link partners. */ - ret_val = e1000_check_for_link(hw); + ret_val = hw->mac.ops.check_for_link(hw); if (ret_val) { DEBUGOUT("Error while checking for link\n"); goto out; @@ -1144,7 +1269,7 @@ s32 e1000_set_default_fc_generic(struct e1000_hw *hw) * control setting, then the variable hw->fc will * be initialized based on a value in the EEPROM. */ - ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data); + ret_val = hw->nvm.ops.read(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data); if (ret_val) { DEBUGOUT("NVM Read Error\n"); @@ -1242,6 +1367,7 @@ out: s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) { struct e1000_mac_info *mac = &hw->mac; + struct e1000_phy_info *phy = &hw->phy; s32 ret_val = E1000_SUCCESS; u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg; u16 speed, duplex; @@ -1279,10 +1405,10 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) * has completed. We read this twice because this reg has * some "sticky" (latched) bits. */ - ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); + ret_val = phy->ops.read_reg(hw, PHY_STATUS, &mii_status_reg); if (ret_val) goto out; - ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg); + ret_val = phy->ops.read_reg(hw, PHY_STATUS, &mii_status_reg); if (ret_val) goto out; @@ -1299,11 +1425,11 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) * Page Ability Register (Address 5) to determine how * flow control was negotiated. */ - ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, + ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg); if (ret_val) goto out; - ret_val = e1000_read_phy_reg(hw, PHY_LP_ABILITY, + ret_val = phy->ops.read_reg(hw, PHY_LP_ABILITY, &mii_nway_lp_ability_reg); if (ret_val) goto out; @@ -1403,7 +1529,7 @@ s32 e1000_config_fc_after_link_up_generic(struct e1000_hw *hw) * negotiated to HALF DUPLEX, flow control should not be * enabled per IEEE 802.3 spec. */ - ret_val = e1000_get_speed_and_duplex(hw, &speed, &duplex); + ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex); if (ret_val) { DEBUGOUT("Error getting link speed and duplex\n"); goto out; @@ -1479,7 +1605,6 @@ s32 e1000_get_speed_and_duplex_fiber_serdes_generic(struct e1000_hw *hw, u16 *speed, u16 *duplex) { DEBUGFUNC("e1000_get_speed_and_duplex_fiber_serdes_generic"); - UNREFERENCED_PARAMETER(hw); *speed = SPEED_1000; *duplex = FULL_DUPLEX; @@ -1605,7 +1730,7 @@ s32 e1000_valid_led_default_generic(struct e1000_hw *hw, u16 *data) DEBUGFUNC("e1000_valid_led_default_generic"); - ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data); + ret_val = hw->nvm.ops.read(hw, NVM_ID_LED_SETTINGS, 1, data); if (ret_val) { DEBUGOUT("NVM Read Error\n"); goto out; @@ -1635,7 +1760,7 @@ s32 e1000_id_led_init_generic(struct e1000_hw * hw) DEBUGFUNC("e1000_id_led_init_generic"); - ret_val = hw->func.valid_led_default(hw, &data); + ret_val = hw->nvm.ops.valid_led_default(hw, &data); if (ret_val) goto out; @@ -1699,7 +1824,7 @@ s32 e1000_setup_led_generic(struct e1000_hw *hw) DEBUGFUNC("e1000_setup_led_generic"); - if (hw->func.setup_led != e1000_setup_led_generic) { + if (hw->mac.ops.setup_led != e1000_setup_led_generic) { ret_val = -E1000_ERR_CONFIG; goto out; } @@ -1735,7 +1860,7 @@ s32 e1000_cleanup_led_generic(struct e1000_hw *hw) DEBUGFUNC("e1000_cleanup_led_generic"); - if (hw->func.cleanup_led != e1000_cleanup_led_generic) { + if (hw->mac.ops.cleanup_led != e1000_cleanup_led_generic) { ret_val = -E1000_ERR_CONFIG; goto out; } diff --git a/sys/dev/em/e1000_mac.h b/sys/dev/em/e1000_mac.h index 8e98628..5992764 100644 --- a/sys/dev/em/e1000_mac.h +++ b/sys/dev/em/e1000_mac.h @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,9 +29,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ #ifndef _E1000_MAC_H_ #define _E1000_MAC_H_ @@ -40,6 +39,15 @@ * Functions that should not be called directly from drivers but can be used * by other files in this 'shared code' */ +void e1000_init_mac_ops_generic(struct e1000_hw *hw); +void e1000_null_mac_generic(struct e1000_hw *hw); +s32 e1000_null_ops_generic(struct e1000_hw *hw); +s32 e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d); +bool e1000_null_mng_mode(struct e1000_hw *hw); +void e1000_null_update_mc(struct e1000_hw *hw, u8 *h, u32 a, u32 b, u32 c); +void e1000_null_write_vfta(struct e1000_hw *hw, u32 a, u32 b); +void e1000_null_mta_set(struct e1000_hw *hw, u32 a); +void e1000_null_rar_set(struct e1000_hw *hw, u8 *h, u32 a); s32 e1000_blink_led_generic(struct e1000_hw *hw); s32 e1000_check_for_copper_link_generic(struct e1000_hw *hw); s32 e1000_check_for_fiber_link_generic(struct e1000_hw *hw); diff --git a/sys/dev/em/e1000_manage.c b/sys/dev/em/e1000_manage.c index fea5384..db47d73 100644 --- a/sys/dev/em/e1000_manage.c +++ b/sys/dev/em/e1000_manage.c @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,9 +29,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ #include "e1000_api.h" #include "e1000_manage.h" @@ -109,8 +108,8 @@ out: * e1000_check_mng_mode_generic - Generic check management mode * @hw: pointer to the HW structure * - * Reads the firmware semaphore register and returns true (>0) if - * manageability is enabled, else false (0). + * Reads the firmware semaphore register and returns TRUE (>0) if + * manageability is enabled, else FALSE (0). **/ bool e1000_check_mng_mode_generic(struct e1000_hw *hw) { @@ -143,7 +142,7 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw) DEBUGFUNC("e1000_enable_tx_pkt_filtering_generic"); /* No manageability, no filtering */ - if (!e1000_check_mng_mode(hw)) { + if (!hw->mac.ops.check_mng_mode(hw)) { tx_filter = FALSE; goto out; } @@ -152,7 +151,7 @@ bool e1000_enable_tx_pkt_filtering_generic(struct e1000_hw *hw) * If we can't read from the host interface for whatever * reason, disable filtering. */ - ret_val = e1000_mng_enable_host_if(hw); + ret_val = hw->mac.ops.mng_enable_host_if(hw); if (ret_val != E1000_SUCCESS) { tx_filter = FALSE; goto out; @@ -213,18 +212,18 @@ s32 e1000_mng_write_dhcp_info_generic(struct e1000_hw * hw, u8 *buffer, hdr.checksum = 0; /* Enable the host interface */ - ret_val = e1000_mng_enable_host_if(hw); + ret_val = hw->mac.ops.mng_enable_host_if(hw); if (ret_val) goto out; /* Populate the host interface with the contents of "buffer". */ - ret_val = e1000_mng_host_if_write(hw, buffer, length, + ret_val = hw->mac.ops.mng_host_if_write(hw, buffer, length, sizeof(hdr), &(hdr.checksum)); if (ret_val) goto out; /* Write the manageability command header */ - ret_val = e1000_mng_write_cmd_header(hw, &hdr); + ret_val = hw->mac.ops.mng_write_cmd_header(hw, &hdr); if (ret_val) goto out; diff --git a/sys/dev/em/e1000_nvm.c b/sys/dev/em/e1000_nvm.c index 6ea278a..a44b195 100644 --- a/sys/dev/em/e1000_nvm.c +++ b/sys/dev/em/e1000_nvm.c @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,13 +29,76 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ +******************************************************************************/ +/*$FreeBSD$*/ #include "e1000_api.h" #include "e1000_nvm.h" /** + * e1000_init_nvm_ops_generic - Initialize NVM function pointers + * @hw: pointer to the HW structure + * + * Setups up the function pointers to no-op functions + **/ +void e1000_init_nvm_ops_generic(struct e1000_hw *hw) +{ + struct e1000_nvm_info *nvm = &hw->nvm; + DEBUGFUNC("e1000_init_nvm_ops_generic"); + + /* Initialize function pointers */ + nvm->ops.init_params = e1000_null_ops_generic; + nvm->ops.acquire = e1000_null_ops_generic; + nvm->ops.read = e1000_null_read_nvm; + nvm->ops.release = e1000_null_nvm_generic; + nvm->ops.reload = e1000_reload_nvm_generic; + nvm->ops.update = e1000_null_ops_generic; + nvm->ops.valid_led_default = e1000_null_led_default; + nvm->ops.validate = e1000_null_ops_generic; + nvm->ops.write = e1000_null_write_nvm; +} + +/** + * e1000_null_nvm_read - No-op function, return 0 + * @hw: pointer to the HW structure + **/ +s32 e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c) +{ + DEBUGFUNC("e1000_null_read_nvm"); + return E1000_SUCCESS; +} + +/** + * e1000_null_nvm_generic - No-op function, return void + * @hw: pointer to the HW structure + **/ +void e1000_null_nvm_generic(struct e1000_hw *hw) +{ + DEBUGFUNC("e1000_null_nvm_generic"); + return; +} + +/** + * e1000_null_led_default - No-op function, return 0 + * @hw: pointer to the HW structure + **/ +s32 e1000_null_led_default(struct e1000_hw *hw, u16 *data) +{ + DEBUGFUNC("e1000_null_led_default"); + return E1000_SUCCESS; +} + +/** + * e1000_null_write_nvm - No-op function, return 0 + * @hw: pointer to the HW structure + **/ +s32 e1000_null_write_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c) +{ + DEBUGFUNC("e1000_null_write_nvm"); + return E1000_SUCCESS; +} + +/** * e1000_raise_eec_clk - Raise EEPROM clock * @hw: pointer to the HW structure * @eecd: pointer to the EEPROM @@ -395,7 +458,7 @@ s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) goto out; } - ret_val = e1000_acquire_nvm(hw); + ret_val = nvm->ops.acquire(hw); if (ret_val) goto out; @@ -423,7 +486,7 @@ s32 e1000_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) } release: - e1000_release_nvm(hw); + nvm->ops.release(hw); out: return ret_val; @@ -459,7 +522,7 @@ s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, goto out; } - ret_val = e1000_acquire_nvm(hw); + ret_val = nvm->ops.acquire(hw); if (ret_val) goto out; @@ -482,7 +545,7 @@ s32 e1000_read_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, } release: - e1000_release_nvm(hw); + nvm->ops.release(hw); out: return ret_val; @@ -564,7 +627,7 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) goto out; } - ret_val = e1000_acquire_nvm(hw); + ret_val = nvm->ops.acquire(hw); if (ret_val) goto out; @@ -613,7 +676,7 @@ s32 e1000_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) msec_delay(10); release: - e1000_release_nvm(hw); + nvm->ops.release(hw); out: return ret_val; @@ -653,7 +716,7 @@ s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, goto out; } - ret_val = e1000_acquire_nvm(hw); + ret_val = nvm->ops.acquire(hw); if (ret_val) goto out; @@ -703,7 +766,7 @@ s32 e1000_write_nvm_microwire(struct e1000_hw *hw, u16 offset, u16 words, e1000_shift_out_eec_bits(hw, 0, (u16)(nvm->address_bits - 2)); release: - e1000_release_nvm(hw); + nvm->ops.release(hw); out: return ret_val; @@ -724,14 +787,14 @@ s32 e1000_read_pba_num_generic(struct e1000_hw *hw, u32 *pba_num) DEBUGFUNC("e1000_read_pba_num_generic"); - ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); + ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); if (ret_val) { DEBUGOUT("NVM Read Error\n"); goto out; } *pba_num = (u32)(nvm_data << 16); - ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &nvm_data); + ret_val = hw->nvm.ops.read(hw, NVM_PBA_OFFSET_1, 1, &nvm_data); if (ret_val) { DEBUGOUT("NVM Read Error\n"); goto out; @@ -759,7 +822,7 @@ s32 e1000_read_mac_addr_generic(struct e1000_hw *hw) for (i = 0; i < ETH_ADDR_LEN; i += 2) { offset = i >> 1; - ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data); + ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); if (ret_val) { DEBUGOUT("NVM Read Error\n"); goto out; @@ -795,7 +858,7 @@ s32 e1000_validate_nvm_checksum_generic(struct e1000_hw *hw) DEBUGFUNC("e1000_validate_nvm_checksum_generic"); for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { - ret_val = e1000_read_nvm(hw, i, 1, &nvm_data); + ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data); if (ret_val) { DEBUGOUT("NVM Read Error\n"); goto out; @@ -830,7 +893,7 @@ s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw) DEBUGFUNC("e1000_update_nvm_checksum"); for (i = 0; i < NVM_CHECKSUM_REG; i++) { - ret_val = e1000_read_nvm(hw, i, 1, &nvm_data); + ret_val = hw->nvm.ops.read(hw, i, 1, &nvm_data); if (ret_val) { DEBUGOUT("NVM Read Error while updating checksum.\n"); goto out; @@ -838,7 +901,7 @@ s32 e1000_update_nvm_checksum_generic(struct e1000_hw *hw) checksum += nvm_data; } checksum = (u16) NVM_SUM - checksum; - ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum); + ret_val = hw->nvm.ops.write(hw, NVM_CHECKSUM_REG, 1, &checksum); if (ret_val) { DEBUGOUT("NVM Write Error while updating checksum.\n"); } @@ -867,33 +930,3 @@ void e1000_reload_nvm_generic(struct e1000_hw *hw) E1000_WRITE_FLUSH(hw); } -/* Function pointers local to this file and not intended for public use */ - -/** - * e1000_acquire_nvm - Acquire exclusive access to EEPROM - * @hw: pointer to the HW structure - * - * For those silicon families which have implemented a NVM acquire function, - * run the defined function else return success. - **/ -s32 e1000_acquire_nvm(struct e1000_hw *hw) -{ - if (hw->func.acquire_nvm) - return hw->func.acquire_nvm(hw); - - return E1000_SUCCESS; -} - -/** - * e1000_release_nvm - Release exclusive access to EEPROM - * @hw: pointer to the HW structure - * - * For those silicon families which have implemented a NVM release function, - * run the defined function else return success. - **/ -void e1000_release_nvm(struct e1000_hw *hw) -{ - if (hw->func.release_nvm) - hw->func.release_nvm(hw); -} - diff --git a/sys/dev/em/e1000_nvm.h b/sys/dev/em/e1000_nvm.h index 33aced1..d0ab33c 100644 --- a/sys/dev/em/e1000_nvm.h +++ b/sys/dev/em/e1000_nvm.h @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,13 +29,17 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ #ifndef _E1000_NVM_H_ #define _E1000_NVM_H_ +void e1000_init_nvm_ops_generic(struct e1000_hw *hw); +s32 e1000_null_read_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c); +void e1000_null_nvm_generic(struct e1000_hw *hw); +s32 e1000_null_led_default(struct e1000_hw *hw, u16 *data); +s32 e1000_null_write_nvm(struct e1000_hw *hw, u16 a, u16 b, u16 *c); s32 e1000_acquire_nvm_generic(struct e1000_hw *hw); s32 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg); @@ -59,10 +63,6 @@ void e1000_stop_nvm(struct e1000_hw *hw); void e1000_release_nvm_generic(struct e1000_hw *hw); void e1000_reload_nvm_generic(struct e1000_hw *hw); -/* Function pointers */ -s32 e1000_acquire_nvm(struct e1000_hw *hw); -void e1000_release_nvm(struct e1000_hw *hw); - #define E1000_STM_OPCODE 0xDB00 #endif diff --git a/sys/dev/em/e1000_osdep.c b/sys/dev/em/e1000_osdep.c new file mode 100644 index 0000000..60be867 --- /dev/null +++ b/sys/dev/em/e1000_osdep.c @@ -0,0 +1,101 @@ +/****************************************************************************** + + Copyright (c) 2001-2008, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ +/*$FreeBSD$*/ + +#include "e1000_api.h" + +/* + * NOTE: the following routines using the e1000 + * naming style are provided to the shared + * code but are OS specific + */ + +void +e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) +{ + pci_write_config(((struct e1000_osdep *)hw->back)->dev, reg, *value, 2); +} + +void +e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) +{ + *value = pci_read_config(((struct e1000_osdep *)hw->back)->dev, reg, 2); +} + +void +e1000_pci_set_mwi(struct e1000_hw *hw) +{ + pci_write_config(((struct e1000_osdep *)hw->back)->dev, PCIR_COMMAND, + (hw->bus.pci_cmd_word | CMD_MEM_WRT_INVALIDATE), 2); +} + +void +e1000_pci_clear_mwi(struct e1000_hw *hw) +{ + pci_write_config(((struct e1000_osdep *)hw->back)->dev, PCIR_COMMAND, + (hw->bus.pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE), 2); +} + +/* + * Read the PCI Express capabilities + */ +int32_t +e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) +{ + u32 result; + + pci_find_extcap(((struct e1000_osdep *)hw->back)->dev, + reg, &result); + *value = (u16)result; + return (E1000_SUCCESS); +} + +int32_t +e1000_alloc_zeroed_dev_spec_struct(struct e1000_hw *hw, uint32_t size) +{ + int32_t error = 0; + + hw->dev_spec = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO); + if (hw->dev_spec == NULL) + error = ENOMEM; + + return (error); +} + +void +e1000_free_dev_spec_struct(struct e1000_hw *hw) +{ + if (hw->dev_spec != NULL) + free(hw->dev_spec, M_DEVBUF); + return; +} diff --git a/sys/dev/em/e1000_osdep.h b/sys/dev/em/e1000_osdep.h index 7564850..8a63950 100644 --- a/sys/dev/em/e1000_osdep.h +++ b/sys/dev/em/e1000_osdep.h @@ -1,36 +1,36 @@ -/************************************************************************** - -Copyright (c) 2001-2008, Intel Corporation -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -***************************************************************************/ -/* $FreeBSD$ */ +/****************************************************************************** + + Copyright (c) 2001-2008, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ +/*$FreeBSD$*/ #ifndef _FREEBSD_OS_H_ @@ -71,11 +71,13 @@ POSSIBILITY OF SUCH DAMAGE. #define DEBUGOUT3(S,A,B,C) #define DEBUGOUT7(S,A,B,C,D,E,F,G) -#define STATIC static -#define FALSE 0 -#define TRUE 1 -#define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */ -#define PCI_COMMAND_REGISTER PCIR_COMMAND +#define STATIC static +#define FALSE 0 +#define false FALSE /* shared code stupidity */ +#define TRUE 1 +#define true TRUE +#define CMD_MEM_WRT_INVALIDATE 0x0010 /* BIT_4 */ +#define PCI_COMMAND_REGISTER PCIR_COMMAND /* ** These typedefs are necessary due to the new @@ -102,12 +104,8 @@ struct e1000_osdep struct device *dev; }; -#ifdef NO_82542_SUPPORT -#define E1000_REGISTER(hw, reg) reg -#else #define E1000_REGISTER(hw, reg) (((hw)->mac.type >= e1000_82543) \ ? reg : e1000_translate_register_82542(reg)) -#endif #define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, E1000_STATUS) diff --git a/sys/dev/em/e1000_phy.c b/sys/dev/em/e1000_phy.c index cd04895..af0f663 100644 --- a/sys/dev/em/e1000_phy.c +++ b/sys/dev/em/e1000_phy.c @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,18 +29,13 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ #include "e1000_api.h" #include "e1000_phy.h" -static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw); -STATIC void e1000_release_phy(struct e1000_hw *hw); -STATIC s32 e1000_acquire_phy(struct e1000_hw *hw); static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg); - /* Cable length tables */ static const u16 e1000_m88_cable_length_table[] = { 0, 50, 80, 110, 140, 140, E1000_CABLE_LENGTH_UNDEFINED }; @@ -62,6 +57,77 @@ static const u16 e1000_igp_2_cable_length_table[] = sizeof(e1000_igp_2_cable_length_table[0])) /** + * e1000_init_phy_ops_generic - Initialize PHY function pointers + * @hw: pointer to the HW structure + * + * Setups up the function pointers to no-op functions + **/ +void e1000_init_phy_ops_generic(struct e1000_hw *hw) +{ + struct e1000_phy_info *phy = &hw->phy; + DEBUGFUNC("e1000_init_phy_ops_generic"); + + /* Initialize function pointers */ + phy->ops.init_params = e1000_null_ops_generic; + phy->ops.acquire = e1000_null_ops_generic; + phy->ops.check_polarity = e1000_null_ops_generic; + phy->ops.check_reset_block = e1000_null_ops_generic; + phy->ops.commit = e1000_null_ops_generic; + phy->ops.force_speed_duplex = e1000_null_ops_generic; + phy->ops.get_cfg_done = e1000_null_ops_generic; + phy->ops.get_cable_length = e1000_null_ops_generic; + phy->ops.get_info = e1000_null_ops_generic; + phy->ops.read_reg = e1000_null_read_reg; + phy->ops.release = e1000_null_phy_generic; + phy->ops.reset = e1000_null_ops_generic; + phy->ops.set_d0_lplu_state = e1000_null_lplu_state; + phy->ops.set_d3_lplu_state = e1000_null_lplu_state; + phy->ops.write_reg = e1000_null_write_reg; + phy->ops.power_up = e1000_null_phy_generic; + phy->ops.power_down = e1000_null_phy_generic; +} + +/** + * e1000_null_read_reg - No-op function, return 0 + * @hw: pointer to the HW structure + **/ +s32 e1000_null_read_reg(struct e1000_hw *hw, u32 offset, u16 *data) +{ + DEBUGFUNC("e1000_null_read_reg"); + return E1000_SUCCESS; +} + +/** + * e1000_null_phy_generic - No-op function, return void + * @hw: pointer to the HW structure + **/ +void e1000_null_phy_generic(struct e1000_hw *hw) +{ + DEBUGFUNC("e1000_null_phy_generic"); + return; +} + +/** + * e1000_null_lplu_state - No-op function, return 0 + * @hw: pointer to the HW structure + **/ +s32 e1000_null_lplu_state(struct e1000_hw *hw, bool active) +{ + DEBUGFUNC("e1000_null_lplu_state"); + return E1000_SUCCESS; +} + +/** + * e1000_null_write_reg - No-op function, return 0 + * @hw: pointer to the HW structure + **/ +s32 e1000_null_write_reg(struct e1000_hw *hw, u32 offset, u16 data) +{ + DEBUGFUNC("e1000_null_write_reg"); + return E1000_SUCCESS; +} + +/** * e1000_check_reset_block_generic - Check if PHY reset is blocked * @hw: pointer to the HW structure * @@ -96,13 +162,16 @@ s32 e1000_get_phy_id(struct e1000_hw *hw) DEBUGFUNC("e1000_get_phy_id"); - ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id); + if (!(phy->ops.read_reg)) + goto out; + + ret_val = phy->ops.read_reg(hw, PHY_ID1, &phy_id); if (ret_val) goto out; phy->id = (u32)(phy_id << 16); usec_delay(20); - ret_val = e1000_read_phy_reg(hw, PHY_ID2, &phy_id); + ret_val = phy->ops.read_reg(hw, PHY_ID2, &phy_id); if (ret_val) goto out; @@ -121,15 +190,18 @@ out: **/ s32 e1000_phy_reset_dsp_generic(struct e1000_hw *hw) { - s32 ret_val; + s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_phy_reset_dsp_generic"); - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1); + if (!(hw->phy.ops.write_reg)) + goto out; + + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0xC1); if (ret_val) goto out; - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_GEN_CONTROL, 0); + ret_val = hw->phy.ops.write_reg(hw, M88E1000_PHY_GEN_CONTROL, 0); out: return ret_val; @@ -152,12 +224,6 @@ s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data) DEBUGFUNC("e1000_read_phy_reg_mdic"); - if (offset > MAX_PHY_REG_ADDRESS) { - DEBUGOUT1("PHY Address %d is out of range\n", offset); - ret_val = -E1000_ERR_PARAM; - goto out; - } - /* * Set up Op-code, Phy Address, and register offset in the MDI * Control register. The MAC will take care of interfacing with the @@ -212,12 +278,6 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) DEBUGFUNC("e1000_write_phy_reg_mdic"); - if (offset > MAX_PHY_REG_ADDRESS) { - DEBUGOUT1("PHY Address %d is out of range\n", offset); - ret_val = -E1000_ERR_PARAM; - goto out; - } - /* * Set up Op-code, Phy Address, and register offset in the MDI * Control register. The MAC will take care of interfacing with the @@ -268,11 +328,14 @@ out: **/ s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data) { - s32 ret_val; + s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_read_phy_reg_m88"); - ret_val = e1000_acquire_phy(hw); + if (!(hw->phy.ops.acquire)) + goto out; + + ret_val = hw->phy.ops.acquire(hw); if (ret_val) goto out; @@ -280,7 +343,7 @@ s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data) MAX_PHY_REG_ADDRESS & offset, data); - e1000_release_phy(hw); + hw->phy.ops.release(hw); out: return ret_val; @@ -297,11 +360,14 @@ out: **/ s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data) { - s32 ret_val; + s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_write_phy_reg_m88"); - ret_val = e1000_acquire_phy(hw); + if (!(hw->phy.ops.acquire)) + goto out; + + ret_val = hw->phy.ops.acquire(hw); if (ret_val) goto out; @@ -309,7 +375,7 @@ s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data) MAX_PHY_REG_ADDRESS & offset, data); - e1000_release_phy(hw); + hw->phy.ops.release(hw); out: return ret_val; @@ -327,11 +393,14 @@ out: **/ s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data) { - s32 ret_val; + s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_read_phy_reg_igp"); - ret_val = e1000_acquire_phy(hw); + if (!(hw->phy.ops.acquire)) + goto out; + + ret_val = hw->phy.ops.acquire(hw); if (ret_val) goto out; @@ -340,7 +409,7 @@ s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data) IGP01E1000_PHY_PAGE_SELECT, (u16)offset); if (ret_val) { - e1000_release_phy(hw); + hw->phy.ops.release(hw); goto out; } } @@ -349,7 +418,7 @@ s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data) MAX_PHY_REG_ADDRESS & offset, data); - e1000_release_phy(hw); + hw->phy.ops.release(hw); out: return ret_val; @@ -366,11 +435,14 @@ out: **/ s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data) { - s32 ret_val; + s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_write_phy_reg_igp"); - ret_val = e1000_acquire_phy(hw); + if (!(hw->phy.ops.acquire)) + goto out; + + ret_val = hw->phy.ops.acquire(hw); if (ret_val) goto out; @@ -379,7 +451,7 @@ s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data) IGP01E1000_PHY_PAGE_SELECT, (u16)offset); if (ret_val) { - e1000_release_phy(hw); + hw->phy.ops.release(hw); goto out; } } @@ -388,7 +460,7 @@ s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data) MAX_PHY_REG_ADDRESS & offset, data); - e1000_release_phy(hw); + hw->phy.ops.release(hw); out: return ret_val; @@ -407,11 +479,14 @@ out: s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data) { u32 kmrnctrlsta; - s32 ret_val; + s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_read_kmrn_reg_generic"); - ret_val = e1000_acquire_phy(hw); + if (!(hw->phy.ops.acquire)) + goto out; + + ret_val = hw->phy.ops.acquire(hw); if (ret_val) goto out; @@ -424,7 +499,7 @@ s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data) kmrnctrlsta = E1000_READ_REG(hw, E1000_KMRNCTRLSTA); *data = (u16)kmrnctrlsta; - e1000_release_phy(hw); + hw->phy.ops.release(hw); out: return ret_val; @@ -443,11 +518,14 @@ out: s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data) { u32 kmrnctrlsta; - s32 ret_val; + s32 ret_val = E1000_SUCCESS; DEBUGFUNC("e1000_write_kmrn_reg_generic"); - ret_val = e1000_acquire_phy(hw); + if (!(hw->phy.ops.acquire)) + goto out; + + ret_val = hw->phy.ops.acquire(hw); if (ret_val) goto out; @@ -456,7 +534,7 @@ s32 e1000_write_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 data) E1000_WRITE_REG(hw, E1000_KMRNCTRLSTA, kmrnctrlsta); usec_delay(2); - e1000_release_phy(hw); + hw->phy.ops.release(hw); out: return ret_val; @@ -483,7 +561,7 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw) } /* Enable CRS on TX. This must be set for half-duplex operation. */ - ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); + ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if (ret_val) goto out; @@ -532,18 +610,16 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw) if (phy->type == e1000_phy_bm) phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT; - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); + ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); if (ret_val) goto out; - if ((phy->type == e1000_phy_m88) && - (phy->revision < E1000_REVISION_4) && - (phy->id != BME1000_E_PHY_ID_R2)) { + if ((phy->type == e1000_phy_m88) && (phy->revision < E1000_REVISION_4)) { /* * Force TX_CLK in the Extended PHY Specific Control Register * to 25MHz clock. */ - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); if (ret_val) @@ -563,7 +639,7 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw) phy_data |= (M88E1000_EPSCR_MASTER_DOWNSHIFT_1X | M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X); } - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data); if (ret_val) @@ -571,7 +647,7 @@ s32 e1000_copper_link_setup_m88(struct e1000_hw *hw) } /* Commit the changes. */ - ret_val = e1000_phy_commit(hw); + ret_val = phy->ops.commit(hw); if (ret_val) { DEBUGOUT("Error committing the PHY changes\n"); goto out; @@ -607,8 +683,11 @@ s32 e1000_copper_link_setup_igp(struct e1000_hw *hw) goto out; } - /* Wait 15ms for MAC to configure PHY from NVM settings. */ - msec_delay(15); + /* + * Wait 100ms for MAC to configure PHY from NVM settings, to avoid + * timeout issues when LFS is enabled. + */ + msec_delay(100); /* * The NVM settings will configure LPLU in D3 for @@ -630,7 +709,7 @@ s32 e1000_copper_link_setup_igp(struct e1000_hw *hw) goto out; } /* Configure mdi-mdix settings */ - ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data); + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &data); if (ret_val) goto out; @@ -648,7 +727,7 @@ s32 e1000_copper_link_setup_igp(struct e1000_hw *hw) data |= IGP01E1000_PSCR_AUTO_MDIX; break; } - ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, data); + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, data); if (ret_val) goto out; @@ -661,31 +740,31 @@ s32 e1000_copper_link_setup_igp(struct e1000_hw *hw) */ if (phy->autoneg_advertised == ADVERTISE_1000_FULL) { /* Disable SmartSpeed */ - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &data); if (ret_val) goto out; data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); if (ret_val) goto out; /* Set auto Master/Slave resolution process */ - ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &data); + ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data); if (ret_val) goto out; data &= ~CR_1000T_MS_ENABLE; - ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, data); + ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data); if (ret_val) goto out; } - ret_val = e1000_read_phy_reg(hw, PHY_1000T_CTRL, &data); + ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &data); if (ret_val) goto out; @@ -709,7 +788,7 @@ s32 e1000_copper_link_setup_igp(struct e1000_hw *hw) default: break; } - ret_val = e1000_write_phy_reg(hw, PHY_1000T_CTRL, data); + ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, data); if (ret_val) goto out; } @@ -760,12 +839,12 @@ s32 e1000_copper_link_autoneg(struct e1000_hw *hw) * Restart auto-negotiation by setting the Auto Neg Enable bit and * the Auto Neg Restart bit in the PHY control register. */ - ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &phy_ctrl); + ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_ctrl); if (ret_val) goto out; phy_ctrl |= (MII_CR_AUTO_NEG_EN | MII_CR_RESTART_AUTO_NEG); - ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, phy_ctrl); + ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_ctrl); if (ret_val) goto out; @@ -809,13 +888,13 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw) phy->autoneg_advertised &= phy->autoneg_mask; /* Read the MII Auto-Neg Advertisement Register (Address 4). */ - ret_val = e1000_read_phy_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg); + ret_val = phy->ops.read_reg(hw, PHY_AUTONEG_ADV, &mii_autoneg_adv_reg); if (ret_val) goto out; if (phy->autoneg_mask & ADVERTISE_1000_FULL) { /* Read the MII 1000Base-T Control Register (Address 9). */ - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, PHY_1000T_CTRL, &mii_1000t_ctrl_reg); if (ret_val) @@ -938,14 +1017,14 @@ s32 e1000_phy_setup_autoneg(struct e1000_hw *hw) goto out; } - ret_val = e1000_write_phy_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg); + ret_val = phy->ops.write_reg(hw, PHY_AUTONEG_ADV, mii_autoneg_adv_reg); if (ret_val) goto out; DEBUGOUT1("Auto-Neg Advertising %x\n", mii_autoneg_adv_reg); if (phy->autoneg_mask & ADVERTISE_1000_FULL) { - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, PHY_1000T_CTRL, mii_1000t_ctrl_reg); if (ret_val) @@ -986,7 +1065,7 @@ s32 e1000_setup_copper_link_generic(struct e1000_hw *hw) * depending on user settings. */ DEBUGOUT("Forcing Speed and Duplex\n"); - ret_val = e1000_phy_force_speed_duplex(hw); + ret_val = hw->phy.ops.force_speed_duplex(hw); if (ret_val) { DEBUGOUT("Error Forcing Speed and Duplex\n"); goto out; @@ -1033,13 +1112,13 @@ s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw) DEBUGFUNC("e1000_phy_force_speed_duplex_igp"); - ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &phy_data); + ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data); if (ret_val) goto out; e1000_phy_force_speed_duplex_setup(hw, &phy_data); - ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, phy_data); + ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data); if (ret_val) goto out; @@ -1047,14 +1126,14 @@ s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw) * Clear Auto-Crossover to force MDI manually. IGP requires MDI * forced whenever speed and duplex are forced. */ - ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data); + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data); if (ret_val) goto out; phy_data &= ~IGP01E1000_PSCR_AUTO_MDIX; phy_data &= ~IGP01E1000_PSCR_FORCE_MDI_MDIX; - ret_val = e1000_write_phy_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data); + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CTRL, phy_data); if (ret_val) goto out; @@ -1112,18 +1191,18 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) * Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI * forced whenever speed and duplex are forced. */ - ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); + ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if (ret_val) goto out; phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); + ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); if (ret_val) goto out; DEBUGOUT1("M88E1000 PSCR: %X\n", phy_data); - ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &phy_data); + ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data); if (ret_val) goto out; @@ -1132,7 +1211,7 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) /* Reset the phy to commit changes. */ phy_data |= MII_CR_RESET; - ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, phy_data); + ret_val = phy->ops.write_reg(hw, PHY_CONTROL, phy_data); if (ret_val) goto out; @@ -1153,7 +1232,7 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) * We didn't get link. * Reset the DSP and cross our fingers. */ - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, M88E1000_PHY_PAGE_SELECT, 0x001d); if (ret_val) @@ -1172,7 +1251,7 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) goto out; } - ret_val = e1000_read_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); + ret_val = phy->ops.read_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data); if (ret_val) goto out; @@ -1182,7 +1261,7 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) * the reset value of 2.5MHz. */ phy_data |= M88E1000_EPSCR_TX_CLK_25; - ret_val = e1000_write_phy_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data); + ret_val = phy->ops.write_reg(hw, M88E1000_EXT_PHY_SPEC_CTRL, phy_data); if (ret_val) goto out; @@ -1190,12 +1269,12 @@ s32 e1000_phy_force_speed_duplex_m88(struct e1000_hw *hw) * In addition, we must re-enable CRS on Tx for both half and full * duplex. */ - ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); + ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if (ret_val) goto out; phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX; - ret_val = e1000_write_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); + ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); out: return ret_val; @@ -1271,7 +1350,7 @@ void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl) * Success returns 0, Failure returns 1 * * The low power link up (lplu) state is set to the power management level D3 - * and SmartSpeed is disabled when active is true, else clear lplu for D3 + * and SmartSpeed is disabled when active is TRUE, else clear lplu for D3 * 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 @@ -1280,18 +1359,21 @@ void e1000_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl) s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active) { struct e1000_phy_info *phy = &hw->phy; - s32 ret_val; + s32 ret_val = E1000_SUCCESS; u16 data; DEBUGFUNC("e1000_set_d3_lplu_state_generic"); - ret_val = e1000_read_phy_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data); + if (!(hw->phy.ops.read_reg)) + goto out; + + ret_val = phy->ops.read_reg(hw, IGP02E1000_PHY_POWER_MGMT, &data); if (ret_val) goto out; if (!active) { data &= ~IGP02E1000_PM_D3_LPLU; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT, data); if (ret_val) @@ -1303,27 +1385,27 @@ s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active) * SmartSpeed, so performance is maintained. */ if (phy->smart_speed == e1000_smart_speed_on) { - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &data); if (ret_val) goto out; data |= IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); if (ret_val) goto out; } else if (phy->smart_speed == e1000_smart_speed_off) { - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &data); if (ret_val) goto out; data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); if (ret_val) @@ -1333,21 +1415,21 @@ s32 e1000_set_d3_lplu_state_generic(struct e1000_hw *hw, bool active) (phy->autoneg_advertised == E1000_ALL_NOT_GIG) || (phy->autoneg_advertised == E1000_ALL_10_SPEED)) { data |= IGP02E1000_PM_D3_LPLU; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP02E1000_PHY_POWER_MGMT, data); if (ret_val) goto out; /* When LPLU is enabled, we should disable SmartSpeed */ - ret_val = e1000_read_phy_reg(hw, + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_CONFIG, &data); if (ret_val) goto out; data &= ~IGP01E1000_PSCFR_SMART_SPEED; - ret_val = e1000_write_phy_reg(hw, + ret_val = phy->ops.write_reg(hw, IGP01E1000_PHY_PORT_CONFIG, data); } @@ -1392,7 +1474,7 @@ s32 e1000_check_downshift_generic(struct e1000_hw *hw) goto out; } - ret_val = e1000_read_phy_reg(hw, offset, &phy_data); + ret_val = phy->ops.read_reg(hw, offset, &phy_data); if (!ret_val) phy->speed_downgraded = (phy_data & mask) ? TRUE : FALSE; @@ -1417,7 +1499,7 @@ s32 e1000_check_polarity_m88(struct e1000_hw *hw) DEBUGFUNC("e1000_check_polarity_m88"); - ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &data); + ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &data); if (!ret_val) phy->cable_polarity = (data & M88E1000_PSSR_REV_POLARITY) @@ -1448,7 +1530,7 @@ s32 e1000_check_polarity_igp(struct e1000_hw *hw) * Polarity is determined based on the speed of * our connection. */ - ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data); + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data); if (ret_val) goto out; @@ -1465,7 +1547,7 @@ s32 e1000_check_polarity_igp(struct e1000_hw *hw) mask = IGP01E1000_PSSR_POLARITY_REVERSED; } - ret_val = e1000_read_phy_reg(hw, offset, &data); + ret_val = phy->ops.read_reg(hw, offset, &data); if (!ret_val) phy->cable_polarity = (data & mask) @@ -1490,12 +1572,15 @@ s32 e1000_wait_autoneg_generic(struct e1000_hw *hw) DEBUGFUNC("e1000_wait_autoneg_generic"); + if (!(hw->phy.ops.read_reg)) + return E1000_SUCCESS; + /* Break after autoneg completes or PHY_AUTO_NEG_LIMIT expires. */ for (i = PHY_AUTO_NEG_LIMIT; i > 0; i--) { - ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_status); + ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); if (ret_val) break; - ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_status); + ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); if (ret_val) break; if (phy_status & MII_SR_AUTONEG_COMPLETE) @@ -1527,16 +1612,19 @@ s32 e1000_phy_has_link_generic(struct e1000_hw *hw, u32 iterations, DEBUGFUNC("e1000_phy_has_link_generic"); + if (!(hw->phy.ops.read_reg)) + return E1000_SUCCESS; + for (i = 0; i < iterations; i++) { /* * Some PHYs require the PHY_STATUS register to be read * twice due to the link bit being sticky. No harm doing * it across the board. */ - ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_status); + ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); if (ret_val) break; - ret_val = e1000_read_phy_reg(hw, PHY_STATUS, &phy_status); + ret_val = hw->phy.ops.read_reg(hw, PHY_STATUS, &phy_status); if (ret_val) break; if (phy_status & MII_SR_LINK_STATUS) @@ -1575,7 +1663,7 @@ s32 e1000_get_cable_length_m88(struct e1000_hw *hw) DEBUGFUNC("e1000_get_cable_length_m88"); - ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); + ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); if (ret_val) goto out; @@ -1618,7 +1706,7 @@ s32 e1000_get_cable_length_igp_2(struct e1000_hw *hw) /* Read the AGC registers for all channels */ for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) { - ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data); + ret_val = phy->ops.read_reg(hw, agc_reg_array[i], &phy_data); if (ret_val) goto out; @@ -1699,7 +1787,7 @@ s32 e1000_get_phy_info_m88(struct e1000_hw *hw) goto out; } - ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); + ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); if (ret_val) goto out; @@ -1711,7 +1799,7 @@ s32 e1000_get_phy_info_m88(struct e1000_hw *hw) if (ret_val) goto out; - ret_val = e1000_read_phy_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); + ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_STATUS, &phy_data); if (ret_val) goto out; @@ -1722,7 +1810,7 @@ s32 e1000_get_phy_info_m88(struct e1000_hw *hw) if (ret_val) goto out; - ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &phy_data); + ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &phy_data); if (ret_val) goto out; @@ -1778,7 +1866,7 @@ s32 e1000_get_phy_info_igp(struct e1000_hw *hw) if (ret_val) goto out; - ret_val = e1000_read_phy_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data); + ret_val = phy->ops.read_reg(hw, IGP01E1000_PHY_PORT_STATUS, &data); if (ret_val) goto out; @@ -1790,7 +1878,7 @@ s32 e1000_get_phy_info_igp(struct e1000_hw *hw) if (ret_val) goto out; - ret_val = e1000_read_phy_reg(hw, PHY_1000T_STATUS, &data); + ret_val = phy->ops.read_reg(hw, PHY_1000T_STATUS, &data); if (ret_val) goto out; @@ -1820,17 +1908,20 @@ out: **/ s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw) { - s32 ret_val; + s32 ret_val = E1000_SUCCESS; u16 phy_ctrl; DEBUGFUNC("e1000_phy_sw_reset_generic"); - ret_val = e1000_read_phy_reg(hw, PHY_CONTROL, &phy_ctrl); + if (!(hw->phy.ops.read_reg)) + goto out; + + ret_val = hw->phy.ops.read_reg(hw, PHY_CONTROL, &phy_ctrl); if (ret_val) goto out; phy_ctrl |= MII_CR_RESET; - ret_val = e1000_write_phy_reg(hw, PHY_CONTROL, phy_ctrl); + ret_val = hw->phy.ops.write_reg(hw, PHY_CONTROL, phy_ctrl); if (ret_val) goto out; @@ -1852,18 +1943,18 @@ out: s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - s32 ret_val; + s32 ret_val = E1000_SUCCESS; u32 ctrl; DEBUGFUNC("e1000_phy_hw_reset_generic"); - ret_val = e1000_check_reset_block(hw); + ret_val = phy->ops.check_reset_block(hw); if (ret_val) { ret_val = E1000_SUCCESS; goto out; } - ret_val = e1000_acquire_phy(hw); + ret_val = phy->ops.acquire(hw); if (ret_val) goto out; @@ -1878,9 +1969,9 @@ s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw) usec_delay(150); - e1000_release_phy(hw); + phy->ops.release(hw); - ret_val = e1000_get_phy_cfg_done(hw); + ret_val = phy->ops.get_cfg_done(hw); out: return ret_val; @@ -1896,73 +1987,12 @@ out: s32 e1000_get_cfg_done_generic(struct e1000_hw *hw) { DEBUGFUNC("e1000_get_cfg_done_generic"); - UNREFERENCED_PARAMETER(hw); msec_delay_irq(10); return E1000_SUCCESS; } -/* Internal function pointers */ - -/** - * e1000_get_phy_cfg_done - Generic PHY configuration done - * @hw: pointer to the HW structure - * - * Return success if silicon family did not implement a family specific - * get_cfg_done function. - **/ -static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw) -{ - if (hw->func.get_cfg_done) - return hw->func.get_cfg_done(hw); - - return E1000_SUCCESS; -} - -/** - * e1000_release_phy - Generic release PHY - * @hw: pointer to the HW structure - * - * Return if silicon family does not require a semaphore when accessing the - * PHY. - **/ -STATIC void e1000_release_phy(struct e1000_hw *hw) -{ - if (hw->func.release_phy) - hw->func.release_phy(hw); -} - -/** - * e1000_acquire_phy - Generic acquire PHY - * @hw: pointer to the HW structure - * - * Return success if silicon family does not require a semaphore when - * accessing the PHY. - **/ -STATIC s32 e1000_acquire_phy(struct e1000_hw *hw) -{ - if (hw->func.acquire_phy) - return hw->func.acquire_phy(hw); - - return E1000_SUCCESS; -} - -/** - * e1000_phy_force_speed_duplex - Generic force PHY speed/duplex - * @hw: pointer to the HW structure - * - * When the silicon family has not implemented a forced speed/duplex - * function for the PHY, simply return E1000_SUCCESS. - **/ -s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw) -{ - if (hw->func.force_speed_duplex) - return hw->func.force_speed_duplex(hw); - - return E1000_SUCCESS; -} - /** * e1000_phy_init_script_igp3 - Inits the IGP3 PHY * @hw: pointer to the HW structure @@ -1975,75 +2005,75 @@ s32 e1000_phy_init_script_igp3(struct e1000_hw *hw) /* PHY init IGP 3 */ /* Enable rise/fall, 10-mode work in class-A */ - e1000_write_phy_reg(hw, 0x2F5B, 0x9018); + hw->phy.ops.write_reg(hw, 0x2F5B, 0x9018); /* Remove all caps from Replica path filter */ - e1000_write_phy_reg(hw, 0x2F52, 0x0000); + hw->phy.ops.write_reg(hw, 0x2F52, 0x0000); /* Bias trimming for ADC, AFE and Driver (Default) */ - e1000_write_phy_reg(hw, 0x2FB1, 0x8B24); + hw->phy.ops.write_reg(hw, 0x2FB1, 0x8B24); /* Increase Hybrid poly bias */ - e1000_write_phy_reg(hw, 0x2FB2, 0xF8F0); + hw->phy.ops.write_reg(hw, 0x2FB2, 0xF8F0); /* Add 4% to Tx amplitude in Gig mode */ - e1000_write_phy_reg(hw, 0x2010, 0x10B0); + hw->phy.ops.write_reg(hw, 0x2010, 0x10B0); /* Disable trimming (TTT) */ - e1000_write_phy_reg(hw, 0x2011, 0x0000); + hw->phy.ops.write_reg(hw, 0x2011, 0x0000); /* Poly DC correction to 94.6% + 2% for all channels */ - e1000_write_phy_reg(hw, 0x20DD, 0x249A); + hw->phy.ops.write_reg(hw, 0x20DD, 0x249A); /* ABS DC correction to 95.9% */ - e1000_write_phy_reg(hw, 0x20DE, 0x00D3); + hw->phy.ops.write_reg(hw, 0x20DE, 0x00D3); /* BG temp curve trim */ - e1000_write_phy_reg(hw, 0x28B4, 0x04CE); + hw->phy.ops.write_reg(hw, 0x28B4, 0x04CE); /* Increasing ADC OPAMP stage 1 currents to max */ - e1000_write_phy_reg(hw, 0x2F70, 0x29E4); + hw->phy.ops.write_reg(hw, 0x2F70, 0x29E4); /* Force 1000 ( required for enabling PHY regs configuration) */ - e1000_write_phy_reg(hw, 0x0000, 0x0140); + hw->phy.ops.write_reg(hw, 0x0000, 0x0140); /* Set upd_freq to 6 */ - e1000_write_phy_reg(hw, 0x1F30, 0x1606); + hw->phy.ops.write_reg(hw, 0x1F30, 0x1606); /* Disable NPDFE */ - e1000_write_phy_reg(hw, 0x1F31, 0xB814); + hw->phy.ops.write_reg(hw, 0x1F31, 0xB814); /* Disable adaptive fixed FFE (Default) */ - e1000_write_phy_reg(hw, 0x1F35, 0x002A); + hw->phy.ops.write_reg(hw, 0x1F35, 0x002A); /* Enable FFE hysteresis */ - e1000_write_phy_reg(hw, 0x1F3E, 0x0067); + hw->phy.ops.write_reg(hw, 0x1F3E, 0x0067); /* Fixed FFE for short cable lengths */ - e1000_write_phy_reg(hw, 0x1F54, 0x0065); + hw->phy.ops.write_reg(hw, 0x1F54, 0x0065); /* Fixed FFE for medium cable lengths */ - e1000_write_phy_reg(hw, 0x1F55, 0x002A); + hw->phy.ops.write_reg(hw, 0x1F55, 0x002A); /* Fixed FFE for long cable lengths */ - e1000_write_phy_reg(hw, 0x1F56, 0x002A); + hw->phy.ops.write_reg(hw, 0x1F56, 0x002A); /* Enable Adaptive Clip Threshold */ - e1000_write_phy_reg(hw, 0x1F72, 0x3FB0); + hw->phy.ops.write_reg(hw, 0x1F72, 0x3FB0); /* AHT reset limit to 1 */ - e1000_write_phy_reg(hw, 0x1F76, 0xC0FF); + hw->phy.ops.write_reg(hw, 0x1F76, 0xC0FF); /* Set AHT master delay to 127 msec */ - e1000_write_phy_reg(hw, 0x1F77, 0x1DEC); + hw->phy.ops.write_reg(hw, 0x1F77, 0x1DEC); /* Set scan bits for AHT */ - e1000_write_phy_reg(hw, 0x1F78, 0xF9EF); + hw->phy.ops.write_reg(hw, 0x1F78, 0xF9EF); /* Set AHT Preset bits */ - e1000_write_phy_reg(hw, 0x1F79, 0x0210); + hw->phy.ops.write_reg(hw, 0x1F79, 0x0210); /* Change integ_factor of channel A to 3 */ - e1000_write_phy_reg(hw, 0x1895, 0x0003); + hw->phy.ops.write_reg(hw, 0x1895, 0x0003); /* Change prop_factor of channels BCD to 8 */ - e1000_write_phy_reg(hw, 0x1796, 0x0008); + hw->phy.ops.write_reg(hw, 0x1796, 0x0008); /* Change cg_icount + enable integbp for channels BCD */ - e1000_write_phy_reg(hw, 0x1798, 0xD008); + hw->phy.ops.write_reg(hw, 0x1798, 0xD008); /* * Change cg_icount + enable integbp + change prop_factor_master * to 8 for channel A */ - e1000_write_phy_reg(hw, 0x1898, 0xD918); + hw->phy.ops.write_reg(hw, 0x1898, 0xD918); /* Disable AHT in Slave mode on channel A */ - e1000_write_phy_reg(hw, 0x187A, 0x0800); + hw->phy.ops.write_reg(hw, 0x187A, 0x0800); /* * Enable LPLU and disable AN to 1000 in non-D0a states, * Enable SPD+B2B */ - e1000_write_phy_reg(hw, 0x0019, 0x008D); + hw->phy.ops.write_reg(hw, 0x0019, 0x008D); /* Enable restart AN on an1000_dis change */ - e1000_write_phy_reg(hw, 0x001B, 0x2080); + hw->phy.ops.write_reg(hw, 0x001B, 0x2080); /* Enable wh_fifo read clock in 10/100 modes */ - e1000_write_phy_reg(hw, 0x0014, 0x0045); + hw->phy.ops.write_reg(hw, 0x0014, 0x0045); /* Restart AN, Speed selection is 1000 */ - e1000_write_phy_reg(hw, 0x0000, 0x1340); + hw->phy.ops.write_reg(hw, 0x0000, 0x1340); return E1000_SUCCESS; } @@ -2102,27 +2132,31 @@ s32 e1000_determine_phy_address(struct e1000_hw* hw) { s32 ret_val = -E1000_ERR_PHY_TYPE; u32 phy_addr= 0; - u32 i = 0; + u32 i; e1000_phy_type phy_type = e1000_phy_unknown; - do { - for (phy_addr = 0; phy_addr < E1000_MAX_PHY_ADDR; phy_addr++) { - hw->phy.addr = phy_addr; + for (phy_addr = 0; phy_addr < E1000_MAX_PHY_ADDR; phy_addr++) { + hw->phy.addr = phy_addr; + i = 0; + + do { e1000_get_phy_id(hw); phy_type = e1000_get_phy_type_from_id(hw->phy.id); /* - * If phy_type is valid, break - we found our - * PHY address - */ + * If phy_type is valid, break - we found our + * PHY address + */ if (phy_type != e1000_phy_unknown) { ret_val = E1000_SUCCESS; - break; + goto out; } - } - i++; - } while ((ret_val != E1000_SUCCESS) && (i < 100)); + msec_delay(1); + i++; + } while (i < 10); + } +out: return ret_val; } @@ -2167,7 +2201,7 @@ s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) goto out; } - ret_val = e1000_acquire_phy(hw); + ret_val = hw->phy.ops.acquire(hw); if (ret_val) goto out; @@ -2191,7 +2225,7 @@ s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) ret_val = e1000_write_phy_reg_mdic(hw, page_select, (page << page_shift)); if (ret_val) { - e1000_release_phy(hw); + hw->phy.ops.release(hw); goto out; } } @@ -2200,7 +2234,7 @@ s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data) MAX_PHY_REG_ADDRESS & offset, data); - e1000_release_phy(hw); + hw->phy.ops.release(hw); out: return ret_val; @@ -2223,7 +2257,7 @@ s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) u32 page = offset >> IGP_PAGE_SHIFT; u32 page_shift = 0; - DEBUGFUNC("e1000_write_phy_reg_bm"); + DEBUGFUNC("e1000_read_phy_reg_bm"); /* Page 800 works differently than the rest so it has its own func */ if (page == BM_WUC_PAGE) { @@ -2232,7 +2266,7 @@ s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) goto out; } - ret_val = e1000_acquire_phy(hw); + ret_val = hw->phy.ops.acquire(hw); if (ret_val) goto out; @@ -2256,7 +2290,7 @@ s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) ret_val = e1000_write_phy_reg_mdic(hw, page_select, (page << page_shift)); if (ret_val) { - e1000_release_phy(hw); + hw->phy.ops.release(hw); goto out; } } @@ -2264,106 +2298,7 @@ s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data) ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, data); - e1000_release_phy(hw); - -out: - return ret_val; -} - -/** - * e1000_read_phy_reg_bm2 - Read BM PHY register - * @hw: pointer to the HW structure - * @offset: register offset to be read - * @data: pointer to the read data - * - * Acquires semaphore, if necessary, then reads the PHY register at offset - * and storing the retrieved information in data. Release any acquired - * semaphores before exiting. - **/ -s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data) -{ - s32 ret_val; - u16 page = (u16)(offset >> IGP_PAGE_SHIFT); - - DEBUGFUNC("e1000_write_phy_reg_bm2"); - - /* Page 800 works differently than the rest so it has its own func */ - if (page == BM_WUC_PAGE) { - ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data, - TRUE); - goto out; - } - - ret_val = e1000_acquire_phy(hw); - if (ret_val) - goto out; - - hw->phy.addr = 1; - - if (offset > MAX_PHY_MULTI_PAGE_REG) { - - /* Page is shifted left, PHY expects (page x 32) */ - ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT, - page); - - if (ret_val) { - e1000_release_phy(hw); - goto out; - } - } - - ret_val = e1000_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); - e1000_release_phy(hw); - -out: - return ret_val; -} - -/** - * e1000_write_phy_reg_bm2 - Write BM PHY register - * @hw: pointer to the HW structure - * @offset: register offset to write to - * @data: data to write at register offset - * - * Acquires semaphore, if necessary, then writes the data to PHY register - * at the offset. Release any acquired semaphores before exiting. - **/ -s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data) -{ - s32 ret_val; - u16 page = (u16)(offset >> IGP_PAGE_SHIFT); - - DEBUGFUNC("e1000_write_phy_reg_bm2"); - - /* Page 800 works differently than the rest so it has its own func */ - if (page == BM_WUC_PAGE) { - ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data, - FALSE); - goto out; - } - - ret_val = e1000_acquire_phy(hw); - if (ret_val) - goto out; - - hw->phy.addr = 1; - - if (offset > MAX_PHY_MULTI_PAGE_REG) { - /* Page is shifted left, PHY expects (page x 32) */ - ret_val = e1000_write_phy_reg_mdic(hw, BM_PHY_PAGE_SELECT, - page); - - if (ret_val) { - e1000_release_phy(hw); - goto out; - } - } - - ret_val = e1000_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, - data); - - e1000_release_phy(hw); + hw->phy.ops.release(hw); out: return ret_val; @@ -2396,7 +2331,7 @@ s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, DEBUGFUNC("e1000_read_phy_wakeup_reg_bm"); - ret_val = e1000_acquire_phy(hw); + ret_val = hw->phy.ops.acquire(hw); if (ret_val) { DEBUGOUT("Could not acquire PHY\n"); phy_acquired = 0; @@ -2475,7 +2410,7 @@ s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, out: if (phy_acquired == 1) - e1000_release_phy(hw); + hw->phy.ops.release(hw); return ret_val; } @@ -2492,9 +2427,9 @@ void e1000_power_up_phy_copper(struct e1000_hw *hw) u16 mii_reg = 0; /* The PHY will retain its settings across a power down/up cycle */ - e1000_read_phy_reg(hw, PHY_CONTROL, &mii_reg); + hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg); mii_reg &= ~MII_CR_POWER_DOWN; - e1000_write_phy_reg(hw, PHY_CONTROL, mii_reg); + hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg); } /** @@ -2510,8 +2445,8 @@ void e1000_power_down_phy_copper(struct e1000_hw *hw) u16 mii_reg = 0; /* The PHY will retain its settings across a power down/up cycle */ - e1000_read_phy_reg(hw, PHY_CONTROL, &mii_reg); + hw->phy.ops.read_reg(hw, PHY_CONTROL, &mii_reg); mii_reg |= MII_CR_POWER_DOWN; - e1000_write_phy_reg(hw, PHY_CONTROL, mii_reg); + hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg); msec_delay(1); } diff --git a/sys/dev/em/e1000_phy.h b/sys/dev/em/e1000_phy.h index c4b72fe..16d3d70 100644 --- a/sys/dev/em/e1000_phy.h +++ b/sys/dev/em/e1000_phy.h @@ -1,4 +1,4 @@ -/******************************************************************************* +/****************************************************************************** Copyright (c) 2001-2008, Intel Corporation All rights reserved. @@ -29,9 +29,8 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*******************************************************************************/ -/* $FreeBSD$ */ - +******************************************************************************/ +/*$FreeBSD$*/ #ifndef _E1000_PHY_H_ #define _E1000_PHY_H_ @@ -49,12 +48,16 @@ typedef enum { e1000_smart_speed_off } e1000_smart_speed; +void e1000_init_phy_ops_generic(struct e1000_hw *hw); +s32 e1000_null_read_reg(struct e1000_hw *hw, u32 offset, u16 *data); +void e1000_null_phy_generic(struct e1000_hw *hw); +s32 e1000_null_lplu_state(struct e1000_hw *hw, bool active); +s32 e1000_null_write_reg(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_check_downshift_generic(struct e1000_hw *hw); s32 e1000_check_polarity_m88(struct e1000_hw *hw); s32 e1000_check_polarity_igp(struct e1000_hw *hw); s32 e1000_check_reset_block_generic(struct e1000_hw *hw); s32 e1000_copper_link_autoneg(struct e1000_hw *hw); -s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw); s32 e1000_copper_link_setup_igp(struct e1000_hw *hw); s32 e1000_copper_link_setup_m88(struct e1000_hw *hw); s32 e1000_phy_force_speed_duplex_igp(struct e1000_hw *hw); @@ -89,8 +92,6 @@ s32 e1000_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data); s32 e1000_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data); s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data, bool read); -s32 e1000_read_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 *data); -s32 e1000_write_phy_reg_bm2(struct e1000_hw *hw, u32 offset, u16 data); void e1000_power_up_phy_copper(struct e1000_hw *hw); void e1000_power_down_phy_copper(struct e1000_hw *hw); s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data); @@ -121,7 +122,11 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data); /* BM PHY Copper Specific Control 1 */ #define BM_CS_CTRL1 16 -#define BM_CR_CTRL1_ENERGY_DETECT 0x0300 /* Enable Energy Detect */ +#define BM_CS_CTRL1_ENERGY_DETECT 0x0300 /* Enable Energy Detect */ + +/* BM PHY Copper Specific States */ +#define BM_CS_STATUS 17 +#define BM_CS_STATUS_ENERGY_DETECT 0x0010 /* Energy Detect Status */ #define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 #define IGP01E1000_PHY_POLARITY_MASK 0x0078 diff --git a/sys/dev/em/if_em.c b/sys/dev/em/if_em.c index c5f412c..584b4be 100644 --- a/sys/dev/em/if_em.c +++ b/sys/dev/em/if_em.c @@ -1,36 +1,36 @@ -/************************************************************************** - -Copyright (c) 2001-2008, Intel Corporation -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -***************************************************************************/ -/* $FreeBSD$ */ +/****************************************************************************** + + Copyright (c) 2001-2008, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ +/*$FreeBSD$*/ #ifdef HAVE_KERNEL_OPTION_HEADERS #include "opt_device_polling.h" @@ -86,7 +86,7 @@ int em_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char em_driver_version[] = "6.8.4"; +char em_driver_version[] = "6.8.8"; /********************************************************************* @@ -187,7 +187,6 @@ static em_vendor_info_t em_vendor_info_array[] = { 0x8086, E1000_DEV_ID_ICH9_IFE, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_ICH9_IFE_GT, PCI_ANY_ID, PCI_ANY_ID, 0}, { 0x8086, E1000_DEV_ID_ICH9_IFE_G, PCI_ANY_ID, PCI_ANY_ID, 0}, - /* required last entry */ { 0, 0, 0, 0, 0} }; @@ -285,7 +284,8 @@ static void em_get_hw_control(struct adapter *); static void em_release_hw_control(struct adapter *); static void em_enable_wakeup(device_t); -#ifndef EM_FAST_IRQ + +#ifdef EM_LEGACY_IRQ static void em_intr(void *); #else /* FAST IRQ */ #if __FreeBSD_version < 700000 @@ -302,7 +302,7 @@ static void em_handle_rxtx(void *context, int pending); static void em_handle_rx(void *context, int pending); static void em_handle_tx(void *context, int pending); static void em_handle_link(void *context, int pending); -#endif /* EM_FAST_IRQ */ +#endif /* EM_LEGACY_IRQ */ #ifdef DEVICE_POLLING static poll_handler_t em_poll; @@ -361,7 +361,7 @@ TUNABLE_INT("hw.em.rxd", &em_rxd); TUNABLE_INT("hw.em.txd", &em_txd); TUNABLE_INT("hw.em.smart_pwr_down", &em_smart_pwr_down); -#ifdef EM_FAST_IRQ +#ifndef EM_LEGACY_IRQ /* How many packets rxeof tries to clean at a time */ static int em_rx_process_limit = 100; TUNABLE_INT("hw.em.rx_process_limit", &em_rx_process_limit); @@ -523,7 +523,7 @@ em_attach(device_t dev) em_tx_abs_int_delay_dflt); } -#ifdef EM_FAST_IRQ +#ifndef EM_LEGACY_IRQ /* Sysctls for limiting the amount of work done in the taskqueue */ em_add_rx_process_limit(adapter, "rx_processing_limit", "max number of rx packets to process", &adapter->rx_process_limit, @@ -1180,6 +1180,7 @@ em_ioctl(struct ifnet *ifp, u_long command, caddr_t data) break; } + default: error = ether_ioctl(ifp, command, data); break; @@ -1211,8 +1212,11 @@ em_watchdog(struct adapter *adapter) ** Finally, anytime all descriptors are clean the timer is ** set to 0. */ - if ((adapter->watchdog_timer == 0) || (--adapter->watchdog_timer)) + EM_TX_LOCK(adapter); + if ((adapter->watchdog_timer == 0) || (--adapter->watchdog_timer)) { + EM_TX_UNLOCK(adapter); return; + } /* If we are in this routine because of pause frames, then * don't reset the hardware. @@ -1220,6 +1224,7 @@ em_watchdog(struct adapter *adapter) if (E1000_READ_REG(&adapter->hw, E1000_STATUS) & E1000_STATUS_TXOFF) { adapter->watchdog_timer = EM_TX_TIMEOUT; + EM_TX_UNLOCK(adapter); return; } @@ -1378,6 +1383,7 @@ em_init_locked(struct adapter *adapter) callout_reset(&adapter->timer, hz, em_local_timer, adapter); e1000_clear_hw_cntrs_base_generic(&adapter->hw); + #ifdef DEVICE_POLLING /* * Only enable interrupts if we are not polling, make sure @@ -1389,6 +1395,7 @@ em_init_locked(struct adapter *adapter) #endif /* DEVICE_POLLING */ em_enable_intr(adapter); + /* Don't reset the phy next time init gets called */ adapter->hw.phy.reset_disable = TRUE; } @@ -1427,7 +1434,6 @@ em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { callout_stop(&adapter->timer); adapter->hw.mac.get_link_status = 1; - e1000_check_for_link(&adapter->hw); em_update_link_status(adapter); callout_reset(&adapter->timer, hz, em_local_timer, adapter); @@ -1445,7 +1451,7 @@ em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) } #endif /* DEVICE_POLLING */ -#ifndef EM_FAST_IRQ +#ifdef EM_LEGACY_IRQ /********************************************************************* * * Legacy Interrupt Service routine @@ -1496,7 +1502,6 @@ em_intr(void *arg) if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { callout_stop(&adapter->timer); adapter->hw.mac.get_link_status = 1; - e1000_check_for_link(&adapter->hw); em_update_link_status(adapter); /* Deal with TX cruft when link lost */ em_tx_purge(adapter); @@ -1524,15 +1529,11 @@ em_handle_link(void *context, int pending) ifp = adapter->ifp; - EM_CORE_LOCK(adapter); - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - EM_CORE_UNLOCK(adapter); + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) return; - } + EM_CORE_LOCK(adapter); callout_stop(&adapter->timer); - adapter->hw.mac.get_link_status = 1; - e1000_check_for_link(&adapter->hw); em_update_link_status(adapter); /* Deal with TX cruft when link lost */ em_tx_purge(adapter); @@ -1540,12 +1541,6 @@ em_handle_link(void *context, int pending) EM_CORE_UNLOCK(adapter); } -#if __FreeBSD_version >= 700000 -#if !defined(NET_LOCK_GIANT) -#define NET_LOCK_GIANT() -#define NET_UNLOCK_GIANT() -#endif -#endif /* Combined RX/TX handler, used by Legacy and MSI */ static void @@ -1554,7 +1549,6 @@ em_handle_rxtx(void *context, int pending) struct adapter *adapter = context; struct ifnet *ifp = adapter->ifp; - NET_LOCK_GIANT(); if (ifp->if_drv_flags & IFF_DRV_RUNNING) { if (em_rxeof(adapter, adapter->rx_process_limit) != 0) @@ -1651,8 +1645,10 @@ em_irq_fast(void *arg) taskqueue_enqueue(adapter->tq, &adapter->rxtx_task); /* Link status change */ - if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) + if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { + adapter->hw.mac.get_link_status = 1; taskqueue_enqueue(taskqueue_fast, &adapter->link_task); + } if (reg_icr & E1000_ICR_RXO) adapter->rx_overruns++; @@ -1748,7 +1744,6 @@ em_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) INIT_DEBUGOUT("em_media_status: begin"); EM_CORE_LOCK(adapter); - e1000_check_for_link(&adapter->hw); em_update_link_status(adapter); ifmr->ifm_status = IFM_AVALID; @@ -1993,7 +1988,12 @@ em_xmit(struct adapter *adapter, struct mbuf **m_headp) tso_desc = TRUE; } else #endif - if (m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) + /* + ** Timesync needs to check the packet header + ** so call checksum code to do so, but don't + ** penalize the code if not defined. + */ + if (m_head->m_pkthdr.csum_flags & CSUM_OFFLOAD) em_transmit_checksum_setup(adapter, m_head, &txd_upper, &txd_lower); @@ -2378,7 +2378,6 @@ em_local_timer(void *arg) EM_CORE_LOCK_ASSERT(adapter); - e1000_check_for_link(&adapter->hw); em_update_link_status(adapter); em_update_stats_counters(adapter); @@ -2404,45 +2403,66 @@ em_local_timer(void *arg) static void em_update_link_status(struct adapter *adapter) { + struct e1000_hw *hw = &adapter->hw; struct ifnet *ifp = adapter->ifp; device_t dev = adapter->dev; + u32 link_check = 0; + + /* Get the cached link value or read phy for real */ + switch (hw->phy.media_type) { + case e1000_media_type_copper: + if (hw->mac.get_link_status) { + /* Do the work to read phy */ + e1000_check_for_link(hw); + link_check = !hw->mac.get_link_status; + } else + link_check = TRUE; + break; + case e1000_media_type_fiber: + e1000_check_for_link(hw); + link_check = (E1000_READ_REG(hw, E1000_STATUS) & + E1000_STATUS_LU); + break; + case e1000_media_type_internal_serdes: + e1000_check_for_link(hw); + link_check = adapter->hw.mac.serdes_has_link; + break; + default: + case e1000_media_type_unknown: + break; + } - if (E1000_READ_REG(&adapter->hw, E1000_STATUS) & - E1000_STATUS_LU) { - if (adapter->link_active == 0) { - e1000_get_speed_and_duplex(&adapter->hw, - &adapter->link_speed, &adapter->link_duplex); - /* Check if we must disable SPEED_MODE bit on PCI-E */ - if ((adapter->link_speed != SPEED_1000) && - ((adapter->hw.mac.type == e1000_82571) || - (adapter->hw.mac.type == e1000_82572))) { - int tarc0; - - tarc0 = E1000_READ_REG(&adapter->hw, - E1000_TARC(0)); - tarc0 &= ~SPEED_MODE_BIT; - E1000_WRITE_REG(&adapter->hw, - E1000_TARC(0), tarc0); - } - if (bootverbose) - device_printf(dev, "Link is up %d Mbps %s\n", - adapter->link_speed, - ((adapter->link_duplex == FULL_DUPLEX) ? - "Full Duplex" : "Half Duplex")); - adapter->link_active = 1; - adapter->smartspeed = 0; - ifp->if_baudrate = adapter->link_speed * 1000000; - if_link_state_change(ifp, LINK_STATE_UP); - } - } else { - if (adapter->link_active == 1) { - ifp->if_baudrate = adapter->link_speed = 0; - adapter->link_duplex = 0; - if (bootverbose) - device_printf(dev, "Link is Down\n"); - adapter->link_active = 0; - if_link_state_change(ifp, LINK_STATE_DOWN); + /* Now check for a transition */ + if (link_check && (adapter->link_active == 0)) { + e1000_get_speed_and_duplex(hw, &adapter->link_speed, + &adapter->link_duplex); + /* Check if we must disable SPEED_MODE bit on PCI-E */ + if ((adapter->link_speed != SPEED_1000) && + ((hw->mac.type == e1000_82571) || + (hw->mac.type == e1000_82572))) { + int tarc0; + tarc0 = E1000_READ_REG(hw, E1000_TARC(0)); + tarc0 &= ~SPEED_MODE_BIT; + E1000_WRITE_REG(hw, E1000_TARC(0), tarc0); } + if (bootverbose) + device_printf(dev, "Link is up %d Mbps %s\n", + adapter->link_speed, + ((adapter->link_duplex == FULL_DUPLEX) ? + "Full Duplex" : "Half Duplex")); + adapter->link_active = 1; + adapter->smartspeed = 0; + ifp->if_baudrate = adapter->link_speed * 1000000; + if_link_state_change(ifp, LINK_STATE_UP); + } else if (!link_check && (adapter->link_active == 1)) { + ifp->if_baudrate = adapter->link_speed = 0; + adapter->link_duplex = 0; + if (bootverbose) + device_printf(dev, "Link is Down\n"); + adapter->link_active = 0; + /* Link down, disable watchdog */ + adapter->watchdog_timer = FALSE; + if_link_state_change(ifp, LINK_STATE_DOWN); } } @@ -2473,6 +2493,7 @@ em_stop(void *arg) /* Tell the stack that the interface is no longer active */ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + e1000_reset_hw(&adapter->hw); if (adapter->hw.mac.type >= e1000_82544) E1000_WRITE_REG(&adapter->hw, E1000_WUC, 0); @@ -2616,7 +2637,7 @@ em_allocate_legacy(struct adapter *adapter) return (ENXIO); } -#ifndef EM_FAST_IRQ +#ifdef EM_LEGACY_IRQ /* We do Legacy setup */ if ((error = bus_setup_intr(dev, adapter->res[0], #if __FreeBSD_version > 700000 @@ -2654,7 +2675,7 @@ em_allocate_legacy(struct adapter *adapter) adapter->tq = NULL; return (error); } -#endif /* EM_FAST_IRQ */ +#endif /* EM_LEGACY_IRQ */ return (0); } @@ -3383,9 +3404,6 @@ em_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp, tx_buffer = &adapter->tx_buffer_area[curr_txd]; TXD = (struct e1000_context_desc *) &adapter->tx_desc_base[curr_txd]; - *txd_lower = E1000_TXD_CMD_DEXT | /* Extended descr type */ - E1000_TXD_DTYP_D; /* Data descr */ - /* * Determine where frame payload starts. * Jump over vlan headers if already present, @@ -3488,6 +3506,8 @@ em_transmit_checksum_setup(struct adapter *adapter, struct mbuf *mp, break; } + *txd_lower = E1000_TXD_CMD_DEXT | /* Extended descr type */ + E1000_TXD_DTYP_D; /* Data descr */ TXD->tcp_seg_setup.data = htole32(0); TXD->cmd_and_length = htole32(adapter->txd_cmd | E1000_TXD_CMD_DEXT | cmd); @@ -3651,6 +3671,7 @@ em_tso_setup(struct adapter *adapter, struct mbuf *mp, u32 *txd_upper, return TRUE; } + #endif /* __FreeBSD_version >= 700000 */ /********************************************************************** @@ -4274,7 +4295,7 @@ discard: i = 0; if (m != NULL) { adapter->next_rx_desc_to_check = i; -#ifndef EM_FAST_IRQ +#ifdef EM_LEGACY_IRQ EM_CORE_UNLOCK(adapter); (*ifp->if_input)(ifp, m); EM_CORE_LOCK(adapter); @@ -4557,84 +4578,6 @@ em_is_valid_ether_addr(u8 *addr) } /* - * NOTE: the following routines using the e1000 - * naming style are provided to the shared - * code which expects that rather than 'em' - */ - -void -e1000_write_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value) -{ - pci_write_config(((struct e1000_osdep *)hw->back)->dev, reg, *value, 2); -} - -void -e1000_read_pci_cfg(struct e1000_hw *hw, u32 reg, u16 *value) -{ - *value = pci_read_config(((struct e1000_osdep *)hw->back)->dev, reg, 2); -} - -void -e1000_pci_set_mwi(struct e1000_hw *hw) -{ - pci_write_config(((struct e1000_osdep *)hw->back)->dev, PCIR_COMMAND, - (hw->bus.pci_cmd_word | CMD_MEM_WRT_INVALIDATE), 2); -} - -void -e1000_pci_clear_mwi(struct e1000_hw *hw) -{ - pci_write_config(((struct e1000_osdep *)hw->back)->dev, PCIR_COMMAND, - (hw->bus.pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE), 2); -} - -/* - * Read the PCI Express capabilities - */ -int -e1000_read_pcie_cap_reg(struct e1000_hw *hw, u32 reg, u16 *value) -{ - int error = E1000_SUCCESS; - u16 cap_off; - - switch (hw->mac.type) { - - case e1000_82571: - case e1000_82572: - case e1000_82573: - case e1000_80003es2lan: - cap_off = 0xE0; - e1000_read_pci_cfg(hw, cap_off + reg, value); - break; - default: - error = ~E1000_NOT_IMPLEMENTED; - break; - } - - return (error); -} - -int -e1000_alloc_zeroed_dev_spec_struct(struct e1000_hw *hw, u32 size) -{ - int32_t error = 0; - - hw->dev_spec = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO); - if (hw->dev_spec == NULL) - error = ENOMEM; - - return (error); -} - -void -e1000_free_dev_spec_struct(struct e1000_hw *hw) -{ - if (hw->dev_spec != NULL) - free(hw->dev_spec, M_DEVBUF); - return; -} - -/* * Enable PCI Wake On Lan capability */ void @@ -5054,7 +4997,7 @@ em_add_int_delay_sysctl(struct adapter *adapter, const char *name, info, 0, em_sysctl_int_delay, "I", description); } -#ifdef EM_FAST_IRQ +#ifndef EM_LEGACY_IRQ static void em_add_rx_process_limit(struct adapter *adapter, const char *name, const char *description, int *limit, int value) @@ -5065,3 +5008,4 @@ em_add_rx_process_limit(struct adapter *adapter, const char *name, OID_AUTO, name, CTLTYPE_INT|CTLFLAG_RW, limit, value, description); } #endif + diff --git a/sys/dev/em/if_em.h b/sys/dev/em/if_em.h index bd5bf62..9a3b0b4 100644 --- a/sys/dev/em/if_em.h +++ b/sys/dev/em/if_em.h @@ -37,9 +37,6 @@ POSSIBILITY OF SUCH DAMAGE. /* Tunables */ -/* Set FAST Interrupt handling as default */ -#define EM_FAST_IRQ - /* * EM_TXD: Maximum number of Transmit Descriptors * Valid Range: 80-256 for 82542 and 82543-based adapters diff --git a/sys/dev/igb/e1000_mac.c b/sys/dev/igb/e1000_mac.c index bdf4fd8..fa50d81 100644 --- a/sys/dev/igb/e1000_mac.c +++ b/sys/dev/igb/e1000_mac.c @@ -112,7 +112,7 @@ s32 e1000_null_link_info(struct e1000_hw *hw, u16 *s, u16 *d) } /** - * e1000_null_mng_mode - No-op function, return false + * e1000_null_mng_mode - No-op function, return FALSE * @hw: pointer to the HW structure **/ bool e1000_null_mng_mode(struct e1000_hw *hw) @@ -332,7 +332,7 @@ void e1000_init_rx_addrs_generic(struct e1000_hw *hw, u16 rar_count) /* Setup the receive address */ DEBUGOUT("Programming MAC Address into RAR[0]\n"); - e1000_rar_set_generic(hw, hw->mac.addr, 0); + hw->mac.ops.rar_set(hw, hw->mac.addr, 0); /* Zero out the other (rar_entry_count - 1) receive addresses */ DEBUGOUT1("Clearing RAR[1-%u]\n", rar_count-1); @@ -1094,7 +1094,7 @@ s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) DEBUGFUNC("e1000_poll_fiber_serdes_link_generic"); /* - * If we have a signal (the cable is plugged in, or assumed true for + * If we have a signal (the cable is plugged in, or assumed TRUE for * serdes media) then poll for a "Link-Up" indication in the Device * Status Register. Time-out if a link isn't seen in 500 milliseconds * seconds (Auto-negotiation should complete in less than 500 diff --git a/sys/dev/igb/e1000_osdep.c b/sys/dev/igb/e1000_osdep.c new file mode 100644 index 0000000..60be867 --- /dev/null +++ b/sys/dev/igb/e1000_osdep.c @@ -0,0 +1,101 @@ +/****************************************************************************** + + Copyright (c) 2001-2008, Intel Corporation + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of the Intel Corporation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +******************************************************************************/ +/*$FreeBSD$*/ + +#include "e1000_api.h" + +/* + * NOTE: the following routines using the e1000 + * naming style are provided to the shared + * code but are OS specific + */ + +void +e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) +{ + pci_write_config(((struct e1000_osdep *)hw->back)->dev, reg, *value, 2); +} + +void +e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) +{ + *value = pci_read_config(((struct e1000_osdep *)hw->back)->dev, reg, 2); +} + +void +e1000_pci_set_mwi(struct e1000_hw *hw) +{ + pci_write_config(((struct e1000_osdep *)hw->back)->dev, PCIR_COMMAND, + (hw->bus.pci_cmd_word | CMD_MEM_WRT_INVALIDATE), 2); +} + +void +e1000_pci_clear_mwi(struct e1000_hw *hw) +{ + pci_write_config(((struct e1000_osdep *)hw->back)->dev, PCIR_COMMAND, + (hw->bus.pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE), 2); +} + +/* + * Read the PCI Express capabilities + */ +int32_t +e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) +{ + u32 result; + + pci_find_extcap(((struct e1000_osdep *)hw->back)->dev, + reg, &result); + *value = (u16)result; + return (E1000_SUCCESS); +} + +int32_t +e1000_alloc_zeroed_dev_spec_struct(struct e1000_hw *hw, uint32_t size) +{ + int32_t error = 0; + + hw->dev_spec = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO); + if (hw->dev_spec == NULL) + error = ENOMEM; + + return (error); +} + +void +e1000_free_dev_spec_struct(struct e1000_hw *hw) +{ + if (hw->dev_spec != NULL) + free(hw->dev_spec, M_DEVBUF); + return; +} diff --git a/sys/dev/igb/if_igb.c b/sys/dev/igb/if_igb.c index 1f878bf..59243ee 100644 --- a/sys/dev/igb/if_igb.c +++ b/sys/dev/igb/if_igb.c @@ -88,7 +88,7 @@ int igb_display_debug_stats = 0; /********************************************************************* * Driver version: *********************************************************************/ -char igb_driver_version[] = "1.1.4"; +char igb_driver_version[] = "version - 1.1.6"; /********************************************************************* @@ -173,7 +173,7 @@ static bool igb_rxeof(struct rx_ring *, int); static int igb_fixup_rx(struct rx_ring *); #endif static void igb_rx_checksum(u32, struct mbuf *); -static bool igb_tx_ctx_setup(struct tx_ring *, struct mbuf *); +static int igb_tx_ctx_setup(struct tx_ring *, struct mbuf *); static bool igb_tso_setup(struct tx_ring *, struct mbuf *, u32 *); static void igb_set_promisc(struct adapter *); static void igb_disable_promisc(struct adapter *); @@ -943,11 +943,14 @@ igb_watchdog(struct adapter *adapter) ** if any time out we do the reset. */ for (int i = 0; i < adapter->num_tx_queues; i++, txr++) { + IGB_TX_LOCK(txr); if (txr->watchdog_timer == 0 || - (--txr->watchdog_timer)) + (--txr->watchdog_timer)) { + IGB_TX_UNLOCK(txr); continue; - else { + } else { tx_hang = TRUE; + IGB_TX_UNLOCK(txr); break; } } @@ -960,8 +963,11 @@ igb_watchdog(struct adapter *adapter) if (E1000_READ_REG(&adapter->hw, E1000_STATUS) & E1000_STATUS_TXOFF) { txr = adapter->tx_rings; /* reset pointer */ - for (int i = 0; i < adapter->num_tx_queues; i++, txr++) + for (int i = 0; i < adapter->num_tx_queues; i++, txr++) { + IGB_TX_LOCK(txr); txr->watchdog_timer = IGB_TX_TIMEOUT; + IGB_TX_UNLOCK(txr); + } return; } @@ -1129,7 +1135,6 @@ igb_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { callout_stop(&adapter->timer); adapter->hw.mac.get_link_status = 1; - e1000_check_for_link(&adapter->hw); igb_update_link_status(adapter); callout_reset(&adapter->timer, hz, igb_local_timer, adapter); @@ -1143,7 +1148,7 @@ igb_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) igb_txeof(txr); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - igb_start_locked(txr, ifp); + igb_start_locked(txr); IGB_TX_UNLOCK(txr); } #endif /* DEVICE_POLLING */ @@ -1162,14 +1167,9 @@ igb_handle_link(void *context, int pending) IGB_CORE_LOCK(adapter); callout_stop(&adapter->timer); - adapter->hw.mac.get_link_status = 1; - e1000_check_for_link(&adapter->hw); igb_update_link_status(adapter); callout_reset(&adapter->timer, hz, igb_local_timer, adapter); IGB_CORE_UNLOCK(adapter); - /* Rearm this interrupt */ - E1000_WRITE_REG(&adapter->hw, E1000_IMS, E1000_IMS_LSC); - E1000_WRITE_REG(&adapter->hw, E1000_EIMS, E1000_EIMS_OTHER); } static void @@ -1237,10 +1237,12 @@ static int igb_irq_fast(void *arg) { struct adapter *adapter = arg; - struct ifnet *ifp; + struct ifnet *ifp = adapter->ifp; uint32_t reg_icr; - ifp = adapter->ifp; + /* Should not happen, but... */ + if (ifp->if_capenable & IFCAP_POLLING) + return FILTER_STRAY; reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR); @@ -1264,8 +1266,10 @@ igb_irq_fast(void *arg) taskqueue_enqueue(adapter->tq, &adapter->rxtx_task); /* Link status change */ - if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) + if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { + adapter->hw.mac.get_link_status = 1; taskqueue_enqueue(taskqueue_fast, &adapter->link_task); + } if (reg_icr & E1000_ICR_RXO) adapter->rx_overruns++; @@ -1330,15 +1334,13 @@ static void igb_msix_link(void *arg) { struct adapter *adapter = arg; - u32 eicr, icr; + u32 icr; ++adapter->link_irq; - eicr = E1000_READ_REG(&adapter->hw, E1000_EICR); - if (eicr & E1000_EIMS_OTHER) { - icr = E1000_READ_REG(&adapter->hw, E1000_ICR); - if (!(icr & E1000_ICR_LSC)) - goto spurious; - } + icr = E1000_READ_REG(&adapter->hw, E1000_ICR); + if (!(icr & E1000_ICR_LSC)) + goto spurious; + adapter->hw.mac.get_link_status = 1; taskqueue_enqueue(taskqueue_fast, &adapter->link_task); spurious: @@ -1365,7 +1367,6 @@ igb_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) INIT_DEBUGOUT("igb_media_status: begin"); IGB_CORE_LOCK(adapter); - e1000_check_for_link(&adapter->hw); igb_update_link_status(adapter); ifmr->ifm_status = IFM_AVALID; @@ -1482,7 +1483,7 @@ igb_xmit(struct tx_ring *txr, struct mbuf **m_headp) struct mbuf *m_head; u32 olinfo_status = 0, cmd_type_len = 0; int nsegs, i, j, error, first, last = 0; - u32 hdrlen = 0; + u32 hdrlen = 0, offload = 0; m_head = *m_headp; @@ -1580,9 +1581,9 @@ igb_xmit(struct tx_ring *txr, struct mbuf **m_headp) return (ENXIO); } else /* Do all other context descriptor setup */ - if (igb_tx_ctx_setup(txr, m_head)) + offload = igb_tx_ctx_setup(txr, m_head); + if (offload == TRUE) olinfo_status |= E1000_TXD_POPTS_TXSM << 8; - /* Calculate payload length */ olinfo_status |= ((m_head->m_pkthdr.len - hdrlen) << E1000_ADVTXD_PAYLEN_SHIFT); @@ -1732,7 +1733,6 @@ igb_local_timer(void *arg) IGB_CORE_LOCK_ASSERT(adapter); - e1000_check_for_link(&adapter->hw); igb_update_link_status(adapter); igb_update_stats_counters(adapter); @@ -1752,37 +1752,58 @@ igb_local_timer(void *arg) static void igb_update_link_status(struct adapter *adapter) { + struct e1000_hw *hw = &adapter->hw; struct ifnet *ifp = adapter->ifp; device_t dev = adapter->dev; struct tx_ring *txr = adapter->tx_rings; + u32 link_check = 0; + + /* Get the cached link value or read for real */ + switch (hw->phy.media_type) { + case e1000_media_type_copper: + if (hw->mac.get_link_status) { + /* Do the work to read phy */ + e1000_check_for_link(hw); + link_check = !hw->mac.get_link_status; + } else + link_check = TRUE; + break; + case e1000_media_type_fiber: + e1000_check_for_link(hw); + link_check = (E1000_READ_REG(hw, E1000_STATUS) & + E1000_STATUS_LU); + break; + case e1000_media_type_internal_serdes: + e1000_check_for_link(hw); + link_check = adapter->hw.mac.serdes_has_link; + break; + default: + case e1000_media_type_unknown: + break; + } - if (E1000_READ_REG(&adapter->hw, E1000_STATUS) & - E1000_STATUS_LU) { - if (adapter->link_active == 0) { - e1000_get_speed_and_duplex(&adapter->hw, - &adapter->link_speed, &adapter->link_duplex); - if (bootverbose) - device_printf(dev, "Link is up %d Mbps %s\n", - adapter->link_speed, - ((adapter->link_duplex == FULL_DUPLEX) ? - "Full Duplex" : "Half Duplex")); - adapter->link_active = 1; - ifp->if_baudrate = adapter->link_speed * 1000000; - if_link_state_change(ifp, LINK_STATE_UP); - } - } else { - if (adapter->link_active == 1) { - ifp->if_baudrate = adapter->link_speed = 0; - adapter->link_duplex = 0; - if (bootverbose) - device_printf(dev, "Link is Down\n"); - adapter->link_active = 0; - if_link_state_change(ifp, LINK_STATE_DOWN); - /* Turn off watchdogs */ - for (int i = 0; i < adapter->num_tx_queues; - i++, txr++) - txr->watchdog_timer = FALSE; - } + /* Now we check if a transition has happened */ + if (link_check && (adapter->link_active == 0)) { + e1000_get_speed_and_duplex(&adapter->hw, + &adapter->link_speed, &adapter->link_duplex); + if (bootverbose) + device_printf(dev, "Link is up %d Mbps %s\n", + adapter->link_speed, + ((adapter->link_duplex == FULL_DUPLEX) ? + "Full Duplex" : "Half Duplex")); + adapter->link_active = 1; + ifp->if_baudrate = adapter->link_speed * 1000000; + if_link_state_change(ifp, LINK_STATE_UP); + } else if (!link_check && (adapter->link_active == 1)) { + ifp->if_baudrate = adapter->link_speed = 0; + adapter->link_duplex = 0; + if (bootverbose) + device_printf(dev, "Link is Down\n"); + adapter->link_active = 0; + if_link_state_change(ifp, LINK_STATE_DOWN); + /* Turn off watchdogs */ + for (int i = 0; i < adapter->num_tx_queues; i++, txr++) + txr->watchdog_timer = FALSE; } } @@ -1988,7 +2009,7 @@ igb_allocate_msix(struct adapter *adapter) txr->msix = adapter->rid[vector] - 1; } else { txr->eims = 1 << vector; - txr->msix = adapter->rid[vector]; + txr->msix = vector; } } @@ -2017,7 +2038,7 @@ igb_allocate_msix(struct adapter *adapter) rxr->msix = adapter->rid[vector] - 1; } else { rxr->eims = 1 << vector; - rxr->msix = adapter->rid[vector]; + rxr->msix = vector; } } @@ -2040,7 +2061,7 @@ igb_allocate_msix(struct adapter *adapter) if (adapter->hw.mac.type == e1000_82575) adapter->linkvec = adapter->rid[vector] - 1; else - adapter->linkvec = adapter->rid[vector]; + adapter->linkvec = vector; /* Make tasklet for deferred link interrupt handling */ TASK_INIT(&adapter->link_task, 0, igb_handle_link, adapter); @@ -2298,7 +2319,10 @@ igb_setup_interface(device_t dev, struct adapter *adapter) ifp->if_capenable |= IFCAP_VLAN_HWTAGGING | IFCAP_VLAN_MTU; #ifdef DEVICE_POLLING - ifp->if_capabilities |= IFCAP_POLLING; + if (adapter->msix > 1) + device_printf(adapter->dev, "POLLING not supported with MSIX\n"); + else + ifp->if_capabilities |= IFCAP_POLLING; #endif /* @@ -2889,7 +2913,7 @@ igb_tso_setup(struct tx_ring *txr, struct mbuf *mp, u32 *hdrlen) * **********************************************************************/ -static boolean_t +static int igb_tx_ctx_setup(struct tx_ring *txr, struct mbuf *mp) { struct adapter *adapter = txr->adapter; @@ -3740,9 +3764,6 @@ discard: } rxr->next_to_check = i; - if (--i < 0) - i = adapter->num_rx_desc - 1; - /* Advance the E1000's Receive Queue #0 "Tail Pointer". */ E1000_WRITE_REG(&adapter->hw, E1000_RDT(rxr->me), rxr->last_cleaned); IGB_RX_UNLOCK(rxr); @@ -3792,7 +3813,7 @@ igb_fixup_rx(struct rx_ring *rxr) rxr->fmp = n; } else { adapter->dropped_pkts++; - m_freem(rxr->fmp); + m_freem(adapter->fmp); rxr->fmp = NULL; error = ENOMEM; } @@ -3982,71 +4003,6 @@ igb_is_valid_ether_addr(uint8_t *addr) return (TRUE); } -/* - * NOTE: the following routines using the e1000 - * naming style are provided to the shared - * code which expects that rather than 'em' - */ - -void -e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) -{ - pci_write_config(((struct e1000_osdep *)hw->back)->dev, reg, *value, 2); -} - -void -e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) -{ - *value = pci_read_config(((struct e1000_osdep *)hw->back)->dev, reg, 2); -} - -void -e1000_pci_set_mwi(struct e1000_hw *hw) -{ - pci_write_config(((struct e1000_osdep *)hw->back)->dev, PCIR_COMMAND, - (hw->bus.pci_cmd_word | CMD_MEM_WRT_INVALIDATE), 2); -} - -void -e1000_pci_clear_mwi(struct e1000_hw *hw) -{ - pci_write_config(((struct e1000_osdep *)hw->back)->dev, PCIR_COMMAND, - (hw->bus.pci_cmd_word & ~CMD_MEM_WRT_INVALIDATE), 2); -} - -/* - * Read the PCI Express capabilities - */ -int32_t -e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value) -{ - u32 result; - - pci_find_extcap(((struct e1000_osdep *)hw->back)->dev, - reg, &result); - *value = (u16)result; - return (E1000_SUCCESS); -} - -int32_t -e1000_alloc_zeroed_dev_spec_struct(struct e1000_hw *hw, uint32_t size) -{ - int32_t error = 0; - - hw->dev_spec = malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO); - if (hw->dev_spec == NULL) - error = ENOMEM; - - return (error); -} - -void -e1000_free_dev_spec_struct(struct e1000_hw *hw) -{ - if (hw->dev_spec != NULL) - free(hw->dev_spec, M_DEVBUF); - return; -} /* * Enable PCI Wake On Lan capability @@ -4207,26 +4163,26 @@ igb_print_debug_info(struct adapter *adapter) device_printf(dev, "Queue(%d) tdh = %d, tdt = %d\n", i, E1000_READ_REG(&adapter->hw, E1000_TDH(i)), E1000_READ_REG(&adapter->hw, E1000_TDT(i))); - device_printf(dev, "no descriptors avail event = %lld\n", - (long long)txr->no_desc_avail); - device_printf(dev, "TX(%d) IRQ Handled = %lld\n", txr->me, - (long long)txr->tx_irq); - device_printf(dev, "TX(%d) Packets sent = %lld\n", txr->me, - (long long)txr->tx_packets); + device_printf(dev, "no descriptors avail event = %lu\n", + txr->no_desc_avail); + device_printf(dev, "TX(%d) MSIX IRQ Handled = %lu\n", txr->me, + txr->tx_irq); + device_printf(dev, "TX(%d) Packets sent = %lu\n", txr->me, + txr->tx_packets); } for (int i = 0; i < adapter->num_rx_queues; i++, rxr++) { device_printf(dev, "Queue(%d) rdh = %d, rdt = %d\n", i, E1000_READ_REG(&adapter->hw, E1000_RDH(i)), E1000_READ_REG(&adapter->hw, E1000_RDT(i))); - device_printf(dev, "RX(%d) Packets received = %lld\n", rxr->me, - (long long)rxr->rx_packets); - device_printf(dev, "RX(%d) Byte count = %lld\n", rxr->me, - (long long)rxr->rx_bytes); - device_printf(dev, "RX(%d) IRQ Handled = %lld\n", rxr->me, - (long long)rxr->rx_irq); + device_printf(dev, "RX(%d) Packets received = %lu\n", rxr->me, + rxr->rx_packets); + device_printf(dev, "RX(%d) Byte count = %lu\n", rxr->me, + rxr->rx_bytes); + device_printf(dev, "RX(%d) MSIX IRQ Handled = %lu\n", rxr->me, + rxr->rx_irq); } - device_printf(dev, "LINK IRQ Handled = %u\n", adapter->link_irq); + device_printf(dev, "LINK MSIX IRQ Handled = %u\n", adapter->link_irq); device_printf(dev, "Std mbuf failed = %ld\n", adapter->mbuf_alloc_failed); diff --git a/sys/modules/em/Makefile b/sys/modules/em/Makefile index 4d831f4..6fe050b 100644 --- a/sys/modules/em/Makefile +++ b/sys/modules/em/Makefile @@ -5,7 +5,7 @@ SRCS = device_if.h bus_if.h pci_if.h SRCS += if_em.c $(SHARED_SRCS) SHARED_SRCS = e1000_api.c e1000_phy.c e1000_nvm.c e1000_mac.c e1000_manage.c SHARED_SRCS += e1000_80003es2lan.c e1000_82542.c e1000_82541.c e1000_82543.c -SHARED_SRCS += e1000_82540.c e1000_ich8lan.c e1000_82571.c +SHARED_SRCS += e1000_82540.c e1000_ich8lan.c e1000_82571.c e1000_osdep.c CFLAGS+= -I${.CURDIR}/../../dev/em diff --git a/sys/modules/igb/Makefile b/sys/modules/igb/Makefile index 2547550..ceb440e 100644 --- a/sys/modules/igb/Makefile +++ b/sys/modules/igb/Makefile @@ -4,7 +4,7 @@ KMOD = if_igb SRCS = device_if.h bus_if.h pci_if.h SRCS += if_igb.c $(SHARED_SRCS) SHARED_SRCS = e1000_api.c e1000_phy.c e1000_nvm.c e1000_mac.c e1000_manage.c -SHARED_SRCS += e1000_82575.c +SHARED_SRCS += e1000_osdep.c e1000_82575.c CFLAGS += -I${.CURDIR}/../../dev/igb |