From 9d514d84b92dc7bd134ec57eb7acb796a66a8dda Mon Sep 17 00:00:00 2001 From: jfv Date: Wed, 2 Apr 2008 22:00:36 +0000 Subject: [PATCH] This update primarily addresses the ability to have both the em and the igb driver static in the kernel. But it also reflects some other bug fixes in my development stream at Intel. PR 122373 is also fixed in this code. --- sys/conf/files | 24 +- sys/dev/em/e1000_80003es2lan.c | 257 +++++++------- sys/dev/em/e1000_82540.c | 166 +++++---- sys/dev/em/e1000_82541.c | 296 ++++++++-------- sys/dev/em/e1000_82542.c | 140 +++++--- sys/dev/em/e1000_82543.c | 208 ++++++------ sys/dev/em/e1000_82571.c | 329 ++++++++---------- sys/dev/em/e1000_82571.h | 15 +- sys/dev/em/e1000_api.c | 259 +++++++------- sys/dev/em/e1000_api.h | 10 +- sys/dev/em/e1000_defines.h | 28 +- sys/dev/em/e1000_hw.h | 71 ++-- sys/dev/em/e1000_ich8lan.c | 445 ++++++++++-------------- sys/dev/em/e1000_ich8lan.h | 12 +- sys/dev/em/e1000_mac.c | 179 ++++++++-- sys/dev/em/e1000_mac.h | 16 +- sys/dev/em/e1000_manage.c | 21 +- sys/dev/em/e1000_nvm.c | 127 ++++--- sys/dev/em/e1000_nvm.h | 16 +- sys/dev/em/e1000_osdep.c | 101 ++++++ sys/dev/em/e1000_osdep.h | 78 +++-- sys/dev/em/e1000_phy.c | 601 +++++++++++++++------------------ sys/dev/em/e1000_phy.h | 21 +- sys/dev/em/if_em.c | 298 +++++++--------- sys/dev/em/if_em.h | 3 - sys/dev/igb/e1000_mac.c | 6 +- sys/dev/igb/e1000_osdep.c | 101 ++++++ sys/dev/igb/if_igb.c | 238 ++++++------- sys/modules/em/Makefile | 2 +- sys/modules/igb/Makefile | 2 +- 30 files changed, 2089 insertions(+), 1981 deletions(-) create mode 100644 sys/dev/em/e1000_osdep.c create mode 100644 sys/dev/igb/e1000_osdep.c diff --git a/sys/conf/files b/sys/conf/files index acc024cf2e97..b010b35aab93 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 c0159da9a2f9..a17b861335ff 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; + 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; - 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.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 @@ STATIC s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw) * * 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 @@ STATIC s32 e1000_acquire_nvm_80003es2lan(struct e1000_hw *hw) * 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 @@ STATIC s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, * 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 @@ STATIC s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw, * 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 @@ STATIC s32 e1000_get_cfg_done_80003es2lan(struct e1000_hw *hw) * 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 @@ STATIC s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) * 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 @@ STATIC s32 e1000_get_cable_length_80003es2lan(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_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 @@ STATIC s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed, * 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 @@ STATIC s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw) * 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 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw) * 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 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw) * 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 c3c5bf5c92f7..05980751f737 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 @@ STATIC s32 e1000_init_phy_params_82540(struct e1000_hw *hw) * * 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 @@ STATIC s32 e1000_setup_copper_link_82540(struct e1000_hw *hw) * 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 @@ static s32 e1000_set_phy_mode_82540(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_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 d7b2956423ad..4a43b32f231c 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 @@ STATIC s32 e1000_init_phy_params_82541(struct e1000_hw *hw) * * 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 @@ STATIC s32 e1000_init_nvm_params_82541(struct e1000_hw *hw) * * 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 @@ STATIC s32 e1000_get_link_up_info_82541(struct e1000_hw *hw, u16 *speed, * 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 @@ STATIC s32 e1000_phy_hw_reset_82541(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_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 @@ STATIC s32 e1000_setup_copper_link_82541(struct e1000_hw *hw) * 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 @@ static s32 e1000_config_dsp_after_link_change_82541(struct e1000_hw *hw, * 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 @@ STATIC s32 e1000_get_cable_length_igp_82541(struct e1000_hw *hw) * 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 @@ STATIC s32 e1000_set_d3_lplu_state_82541(struct e1000_hw *hw, bool active) * 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 @@ STATIC s32 e1000_setup_led_82541(struct e1000_hw *hw) * 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 @@ void e1000_init_script_state_82541(struct e1000_hw *hw, bool state) * 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 04f27f60bbb1..0f762021c326 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 @@ STATIC s32 e1000_setup_link_82542(struct e1000_hw *hw) * 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); @@ -424,6 +423,41 @@ STATIC s32 e1000_led_off_82542(struct e1000_hw *hw) return E1000_SUCCESS; } +/** + * 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 5a4fdbcdae3d..1312a8f87626 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 @@ STATIC s32 e1000_init_phy_params_82543(struct e1000_hw *hw) * * 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 @@ void e1000_tbi_adjust_stats_82543(struct e1000_hw *hw, * * 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 @@ STATIC s32 e1000_read_phy_reg_82543(struct e1000_hw *hw, u32 offset, u16 *data) * * 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 @@ STATIC s32 e1000_phy_force_speed_duplex_82543(struct e1000_hw *hw) **/ 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 @@ static s32 e1000_polarity_reversal_workaround_82543(struct e1000_hw *hw) * 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 @@ STATIC s32 e1000_init_hw_82543(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_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 @@ STATIC s32 e1000_setup_link_82543(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_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 @@ STATIC s32 e1000_setup_copper_link_82543(struct e1000_hw *hw) * 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 @@ STATIC s32 e1000_setup_fiber_link_82543(struct e1000_hw *hw) * - 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 @@ STATIC s32 e1000_check_for_copper_link_82543(struct e1000_hw *hw) * 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 @@ STATIC s32 e1000_check_for_fiber_link_82543(struct e1000_hw *hw) 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 @@ static s32 e1000_config_mac_to_phy_82543(struct e1000_hw *hw) * 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 8d9d32aba2bb..7a2e2093bdb8 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 @@ STATIC s32 e1000_init_phy_params_82571(struct e1000_hw *hw) * * 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 @@ STATIC s32 e1000_acquire_nvm_82571(struct e1000_hw *hw) * * 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 @@ STATIC s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw) * 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 @@ static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, * * 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 @@ STATIC s32 e1000_get_cfg_done_82571(struct e1000_hw *hw) * 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 @@ STATIC s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) * 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 @@ STATIC s32 e1000_reset_hw_82571(struct e1000_hw *hw) * * 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 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) * 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 @@ STATIC s32 e1000_setup_copper_link_82571(struct e1000_hw *hw) * 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 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw) * 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 186c4cdcdf34..e6469ea57603 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 57e0b3e3b9b8..ead54d6f7143 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 @@ s32 e1000_setup_init_funcs(struct e1000_hw *hw, bool init_device) **/ 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 2423b965ed66..921b194a595b 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 a40fa4b26aa1..516db57dfe50 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 11ae79b30be9..ebc20bf53296 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 *); + s32 (*write_reg)(struct e1000_hw *, u32, u16); + void (*power_up)(struct e1000_hw *); + void (*power_down)(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 *); +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 29b80e97cdb2..149d66b051d5 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; + 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->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 @@ STATIC s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw) * 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 @@ STATIC s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw) * 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 @@ STATIC s32 e1000_acquire_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 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 @@ STATIC s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw) * 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 @@ STATIC s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw) * 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 @@ static s32 e1000_get_phy_info_ife_ich8lan(struct e1000_hw *hw) * 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 @@ STATIC s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, * 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 @@ STATIC s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, * * 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; @@ -1281,30 +1240,6 @@ STATIC s32 e1000_read_flash_word_ich8lan(struct e1000_hw *hw, u32 offset, return ret_val; } -/** - * 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 @@ -1397,7 +1332,7 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, * * 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 @@ STATIC s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, * 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 @@ STATIC s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw) * 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 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, * * 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 @@ static s32 e1000_retry_write_flash_byte_ich8lan(struct e1000_hw *hw, * 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 @@ STATIC s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank) * 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 @@ STATIC s32 e1000_valid_led_default_ich8lan(struct e1000_hw *hw, u16 *data) * 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 @@ static void e1000_initialize_hw_bits_ich8lan(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_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 @@ STATIC s32 e1000_setup_link_ich8lan(struct e1000_hw *hw) * 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 @@ STATIC s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw) * 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 @@ void e1000_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) * '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 32102eefdaa0..caa23a091d6f 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 511a81657456..fa50d81125af 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,13 +29,138 @@ 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 @@ s32 e1000_check_for_serdes_link_generic(struct e1000_hw *hw) **/ 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 @@ s32 e1000_force_mac_fc_generic(struct e1000_hw *hw) 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 8e98628da2a8..59927647fd9d 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 fea53840c0d0..db47d73d360e 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 @@ s32 e1000_mng_enable_host_if_generic(struct e1000_hw * hw) * 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 6ea278a7ba21..a44b1958d36d 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,12 +29,75 @@ 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 @@ -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 33aced1a9095..d0ab33c614e3 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 000000000000..60be8674e1a3 --- /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 75648507570f..8a63950ac875 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. + 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. -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$ */ +******************************************************************************/ +/*$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 cd048951357a..af0f663a88d4 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 }; @@ -61,6 +56,77 @@ static const u16 e1000_igp_2_cable_length_table[] = (sizeof(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 @@ s32 e1000_get_phy_id(struct e1000_hw *hw) **/ 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 @@ s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data) **/ 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 @@ s32 e1000_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data) **/ 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 @@ s32 e1000_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data) **/ 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 @@ s32 e1000_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data) **/ 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 @@ s32 e1000_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data) 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 @@ s32 e1000_read_kmrn_reg_generic(struct e1000_hw *hw, u32 offset, u16 *data) 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 @@ s32 e1000_get_phy_info_igp(struct e1000_hw *hw) **/ 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 @@ s32 e1000_phy_sw_reset_generic(struct e1000_hw *hw) 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 @@ s32 e1000_phy_hw_reset_generic(struct e1000_hw *hw) 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 c4b72fe60556..16d3d70b981a 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 c5f412cfd80f..584b4be9e53d 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. + 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. -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$ */ +******************************************************************************/ +/*$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; - 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; + /* 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; + } - 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 @@ em_rxeof(struct adapter *adapter, int count) 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); @@ -4556,84 +4577,6 @@ em_is_valid_ether_addr(u8 *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, 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 */ @@ -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 bd5bf623c92e..9a3b0b4bd872 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 bdf4fd868022..fa50d81125af 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 000000000000..60be8674e1a3 --- /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 1f878bf4f85c..59243eee5591 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; - 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; - } + /* 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; + } + + /* 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 @@ igb_rxeof(struct rx_ring *rxr, int count) } 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 4d831f4de6fc..6fe050bff709 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 25475500a9b9..ceb440eb32ea 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