Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/e1000/e1000_82571.c
Show First 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | |||||
static bool e1000_check_mng_mode_82574(struct e1000_hw *hw); | static bool e1000_check_mng_mode_82574(struct e1000_hw *hw); | ||||
static s32 e1000_led_on_82574(struct e1000_hw *hw); | static s32 e1000_led_on_82574(struct e1000_hw *hw); | ||||
static s32 e1000_setup_link_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_copper_link_82571(struct e1000_hw *hw); | ||||
static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw); | static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw); | ||||
static s32 e1000_setup_fiber_serdes_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 s32 e1000_valid_led_default_82571(struct e1000_hw *hw, u16 *data); | ||||
static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw); | 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_fix_nvm_checksum_82571(struct e1000_hw *hw); | ||||
static s32 e1000_get_phy_id_82571(struct e1000_hw *hw); | static s32 e1000_get_phy_id_82571(struct e1000_hw *hw); | ||||
static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); | |||||
static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw); | |||||
static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw); | static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw); | ||||
static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw); | static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw); | ||||
static s32 e1000_set_d0_lplu_state_82574(struct e1000_hw *hw, | static s32 e1000_set_d0_lplu_state_82574(struct e1000_hw *hw, | ||||
bool active); | bool active); | ||||
static s32 e1000_set_d3_lplu_state_82574(struct e1000_hw *hw, | static s32 e1000_set_d3_lplu_state_82574(struct e1000_hw *hw, | ||||
bool active); | bool active); | ||||
static void e1000_initialize_hw_bits_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, | static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset, | ||||
Show All 34 Lines | case e1000_82572: | ||||
phy->type = e1000_phy_igp_2; | phy->type = e1000_phy_igp_2; | ||||
phy->ops.get_cfg_done = e1000_get_cfg_done_82571; | phy->ops.get_cfg_done = e1000_get_cfg_done_82571; | ||||
phy->ops.get_info = e1000_get_phy_info_igp; | phy->ops.get_info = e1000_get_phy_info_igp; | ||||
phy->ops.check_polarity = e1000_check_polarity_igp; | phy->ops.check_polarity = e1000_check_polarity_igp; | ||||
phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_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.get_cable_length = e1000_get_cable_length_igp_2; | ||||
phy->ops.read_reg = e1000_read_phy_reg_igp; | phy->ops.read_reg = e1000_read_phy_reg_igp; | ||||
phy->ops.write_reg = e1000_write_phy_reg_igp; | phy->ops.write_reg = e1000_write_phy_reg_igp; | ||||
phy->ops.acquire = e1000_get_hw_semaphore_82571; | phy->ops.acquire = e1000_get_hw_semaphore; | ||||
phy->ops.release = e1000_put_hw_semaphore_82571; | phy->ops.release = e1000_put_hw_semaphore; | ||||
break; | break; | ||||
case e1000_82573: | case e1000_82573: | ||||
phy->type = e1000_phy_m88; | phy->type = e1000_phy_m88; | ||||
phy->ops.get_cfg_done = e1000_get_cfg_done_generic; | phy->ops.get_cfg_done = e1000_get_cfg_done_generic; | ||||
phy->ops.get_info = e1000_get_phy_info_m88; | phy->ops.get_info = e1000_get_phy_info_m88; | ||||
phy->ops.check_polarity = e1000_check_polarity_m88; | phy->ops.check_polarity = e1000_check_polarity_m88; | ||||
phy->ops.commit = e1000_phy_sw_reset_generic; | phy->ops.commit = e1000_phy_sw_reset_generic; | ||||
phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; | phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; | ||||
phy->ops.get_cable_length = e1000_get_cable_length_m88; | phy->ops.get_cable_length = e1000_get_cable_length_m88; | ||||
phy->ops.read_reg = e1000_read_phy_reg_m88; | phy->ops.read_reg = e1000_read_phy_reg_m88; | ||||
phy->ops.write_reg = e1000_write_phy_reg_m88; | phy->ops.write_reg = e1000_write_phy_reg_m88; | ||||
phy->ops.acquire = e1000_get_hw_semaphore_82571; | phy->ops.acquire = e1000_get_hw_semaphore; | ||||
phy->ops.release = e1000_put_hw_semaphore_82571; | phy->ops.release = e1000_put_hw_semaphore; | ||||
break; | break; | ||||
case e1000_82574: | case e1000_82574: | ||||
case e1000_82583: | case e1000_82583: | ||||
E1000_MUTEX_INIT(&hw->dev_spec._82571.swflag_mutex); | |||||
phy->type = e1000_phy_bm; | phy->type = e1000_phy_bm; | ||||
phy->ops.get_cfg_done = e1000_get_cfg_done_generic; | phy->ops.get_cfg_done = e1000_get_cfg_done_generic; | ||||
phy->ops.get_info = e1000_get_phy_info_m88; | phy->ops.get_info = e1000_get_phy_info_m88; | ||||
phy->ops.check_polarity = e1000_check_polarity_m88; | phy->ops.check_polarity = e1000_check_polarity_m88; | ||||
phy->ops.commit = e1000_phy_sw_reset_generic; | phy->ops.commit = e1000_phy_sw_reset_generic; | ||||
phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; | phy->ops.force_speed_duplex = e1000_phy_force_speed_duplex_m88; | ||||
phy->ops.get_cable_length = e1000_get_cable_length_m88; | phy->ops.get_cable_length = e1000_get_cable_length_m88; | ||||
▲ Show 20 Lines • Show All 346 Lines • ▼ Show 20 Lines | default: | ||||
return -E1000_ERR_PHY; | return -E1000_ERR_PHY; | ||||
break; | break; | ||||
} | } | ||||
return E1000_SUCCESS; | return E1000_SUCCESS; | ||||
} | } | ||||
/** | /** | ||||
* e1000_get_hw_semaphore_82571 - Acquire hardware semaphore | * e1000_get_hw_semaphore_82574 - Acquire hardware semaphore | ||||
* @hw: pointer to the HW structure | * @hw: pointer to the HW structure | ||||
* | * | ||||
* Acquire the HW semaphore to access the PHY or NVM | |||||
**/ | |||||
static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw) | |||||
{ | |||||
u32 swsm; | |||||
s32 sw_timeout = hw->nvm.word_size + 1; | |||||
s32 fw_timeout = hw->nvm.word_size + 1; | |||||
s32 i = 0; | |||||
DEBUGFUNC("e1000_get_hw_semaphore_82571"); | |||||
/* If we have timedout 3 times on trying to acquire | |||||
* the inter-port SMBI semaphore, there is old code | |||||
* operating on the other port, and it is not | |||||
* releasing SMBI. Modify the number of times that | |||||
* we try for the semaphore to interwork with this | |||||
* older code. | |||||
*/ | |||||
if (hw->dev_spec._82571.smb_counter > 2) | |||||
sw_timeout = 1; | |||||
/* Get the SW semaphore */ | |||||
while (i < sw_timeout) { | |||||
swsm = E1000_READ_REG(hw, E1000_SWSM); | |||||
if (!(swsm & E1000_SWSM_SMBI)) | |||||
break; | |||||
usec_delay(50); | |||||
i++; | |||||
} | |||||
if (i == sw_timeout) { | |||||
DEBUGOUT("Driver can't access device - SMBI bit is set.\n"); | |||||
hw->dev_spec._82571.smb_counter++; | |||||
} | |||||
/* Get the FW semaphore. */ | |||||
for (i = 0; i < fw_timeout; i++) { | |||||
swsm = E1000_READ_REG(hw, E1000_SWSM); | |||||
E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI); | |||||
/* Semaphore acquired if bit latched */ | |||||
if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI) | |||||
break; | |||||
usec_delay(50); | |||||
} | |||||
if (i == fw_timeout) { | |||||
/* Release semaphores */ | |||||
e1000_put_hw_semaphore_82571(hw); | |||||
DEBUGOUT("Driver can't access the NVM\n"); | |||||
return -E1000_ERR_NVM; | |||||
} | |||||
return E1000_SUCCESS; | |||||
} | |||||
/** | |||||
* e1000_put_hw_semaphore_82571 - Release hardware semaphore | |||||
* @hw: pointer to the HW structure | |||||
* | |||||
* Release hardware semaphore used to access the PHY or NVM | |||||
**/ | |||||
static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw) | |||||
{ | |||||
u32 swsm; | |||||
DEBUGFUNC("e1000_put_hw_semaphore_generic"); | |||||
swsm = E1000_READ_REG(hw, E1000_SWSM); | |||||
swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); | |||||
E1000_WRITE_REG(hw, E1000_SWSM, swsm); | |||||
} | |||||
/** | |||||
* e1000_get_hw_semaphore_82573 - Acquire hardware semaphore | |||||
* @hw: pointer to the HW structure | |||||
* | |||||
* Acquire the HW semaphore during reset. | * Acquire the HW semaphore during reset. | ||||
* | * | ||||
**/ | **/ | ||||
static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw) | static s32 | ||||
e1000_get_hw_semaphore_82574(struct e1000_hw *hw) | |||||
{ | { | ||||
u32 extcnf_ctrl; | u32 extcnf_ctrl; | ||||
s32 i = 0; | s32 i = 0; | ||||
/* XXX assert that mutex is held */ | |||||
DEBUGFUNC("e1000_get_hw_semaphore_82573"); | DEBUGFUNC("e1000_get_hw_semaphore_82573"); | ||||
ASSERT_CTX_LOCK_HELD(hw); | |||||
extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); | extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); | ||||
do { | do { | ||||
extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; | extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; | ||||
E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); | E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); | ||||
extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); | extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); | ||||
if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) | if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP) | ||||
break; | break; | ||||
msec_delay(2); | msec_delay(2); | ||||
i++; | i++; | ||||
} while (i < MDIO_OWNERSHIP_TIMEOUT); | } while (i < MDIO_OWNERSHIP_TIMEOUT); | ||||
if (i == MDIO_OWNERSHIP_TIMEOUT) { | if (i == MDIO_OWNERSHIP_TIMEOUT) { | ||||
/* Release semaphores */ | /* Release semaphores */ | ||||
e1000_put_hw_semaphore_82573(hw); | e1000_put_hw_semaphore_82574(hw); | ||||
DEBUGOUT("Driver can't access the PHY\n"); | DEBUGOUT("Driver can't access the PHY\n"); | ||||
return -E1000_ERR_PHY; | return -E1000_ERR_PHY; | ||||
} | } | ||||
return E1000_SUCCESS; | return E1000_SUCCESS; | ||||
} | } | ||||
/** | /** | ||||
* e1000_put_hw_semaphore_82573 - Release hardware semaphore | * e1000_put_hw_semaphore_82574 - Release hardware semaphore | ||||
* @hw: pointer to the HW structure | * @hw: pointer to the HW structure | ||||
* | * | ||||
* Release hardware semaphore used during reset. | * Release hardware semaphore used during reset. | ||||
* | * | ||||
**/ | **/ | ||||
static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw) | static void | ||||
e1000_put_hw_semaphore_82574(struct e1000_hw *hw) | |||||
{ | { | ||||
u32 extcnf_ctrl; | u32 extcnf_ctrl; | ||||
DEBUGFUNC("e1000_put_hw_semaphore_82573"); | DEBUGFUNC("e1000_put_hw_semaphore_82574"); | ||||
extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); | extcnf_ctrl = E1000_READ_REG(hw, E1000_EXTCNF_CTRL); | ||||
extcnf_ctrl &= ~E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; | extcnf_ctrl &= ~E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP; | ||||
E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); | E1000_WRITE_REG(hw, E1000_EXTCNF_CTRL, extcnf_ctrl); | ||||
} | } | ||||
/** | /** | ||||
* e1000_get_hw_semaphore_82574 - Acquire hardware semaphore | |||||
* @hw: pointer to the HW structure | |||||
* | |||||
* Acquire the HW semaphore to access the PHY or NVM. | |||||
* | |||||
**/ | |||||
static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw) | |||||
{ | |||||
s32 ret_val; | |||||
DEBUGFUNC("e1000_get_hw_semaphore_82574"); | |||||
E1000_MUTEX_LOCK(&hw->dev_spec._82571.swflag_mutex); | |||||
ret_val = e1000_get_hw_semaphore_82573(hw); | |||||
if (ret_val) | |||||
E1000_MUTEX_UNLOCK(&hw->dev_spec._82571.swflag_mutex); | |||||
return ret_val; | |||||
} | |||||
/** | |||||
* e1000_put_hw_semaphore_82574 - Release hardware semaphore | |||||
* @hw: pointer to the HW structure | |||||
* | |||||
* Release hardware semaphore used to access the PHY or NVM | |||||
* | |||||
**/ | |||||
static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw) | |||||
{ | |||||
DEBUGFUNC("e1000_put_hw_semaphore_82574"); | |||||
e1000_put_hw_semaphore_82573(hw); | |||||
E1000_MUTEX_UNLOCK(&hw->dev_spec._82571.swflag_mutex); | |||||
} | |||||
/** | |||||
* e1000_set_d0_lplu_state_82574 - Set Low Power Linkup D0 state | * e1000_set_d0_lplu_state_82574 - Set Low Power Linkup D0 state | ||||
* @hw: pointer to the HW structure | * @hw: pointer to the HW structure | ||||
* @active: TRUE to enable LPLU, FALSE to disable | * @active: TRUE to enable LPLU, FALSE to disable | ||||
* | * | ||||
* Sets the LPLU D0 state according to the active flag. | * Sets the LPLU D0 state according to the active flag. | ||||
* LPLU will not be activated unless the | * LPLU will not be activated unless the | ||||
* device autonegotiation advertisement meets standards of | * device autonegotiation advertisement meets standards of | ||||
* either 10 or 10/100 or 10/100/1000 at all duplexes. | * either 10 or 10/100 or 10/100/1000 at all duplexes. | ||||
▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | |||||
* hardware semaphore. | * 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; | s32 ret_val; | ||||
DEBUGFUNC("e1000_acquire_nvm_82571"); | DEBUGFUNC("e1000_acquire_nvm_82571"); | ||||
ret_val = e1000_get_hw_semaphore_82571(hw); | ret_val = e1000_get_hw_semaphore(hw); | ||||
if (ret_val) | if (ret_val) | ||||
return ret_val; | return ret_val; | ||||
switch (hw->mac.type) { | switch (hw->mac.type) { | ||||
case e1000_82573: | case e1000_82573: | ||||
break; | break; | ||||
default: | default: | ||||
ret_val = e1000_acquire_nvm_generic(hw); | ret_val = e1000_acquire_nvm_generic(hw); | ||||
break; | break; | ||||
} | } | ||||
if (ret_val) | if (ret_val) | ||||
e1000_put_hw_semaphore_82571(hw); | e1000_put_hw_semaphore(hw); | ||||
return ret_val; | return ret_val; | ||||
} | } | ||||
/** | /** | ||||
* e1000_release_nvm_82571 - Release exclusive access to EEPROM | * e1000_release_nvm_82571 - Release exclusive access to EEPROM | ||||
* @hw: pointer to the HW structure | * @hw: pointer to the HW structure | ||||
* | * | ||||
* Stop any current commands to the EEPROM and clear the EEPROM request bit. | * 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"); | DEBUGFUNC("e1000_release_nvm_82571"); | ||||
e1000_release_nvm_generic(hw); | e1000_release_nvm_generic(hw); | ||||
e1000_put_hw_semaphore_82571(hw); | e1000_put_hw_semaphore(hw); | ||||
} | } | ||||
/** | /** | ||||
* e1000_write_nvm_82571 - Write to EEPROM using appropriate interface | * e1000_write_nvm_82571 - Write to EEPROM using appropriate interface | ||||
* @hw: pointer to the HW structure | * @hw: pointer to the HW structure | ||||
* @offset: offset within the EEPROM to be written to | * @offset: offset within the EEPROM to be written to | ||||
* @words: number of words to write | * @words: number of words to write | ||||
* @data: 16 bit word(s) to be written to the EEPROM | * @data: 16 bit word(s) to be written to the EEPROM | ||||
▲ Show 20 Lines • Show All 300 Lines • ▼ Show 20 Lines | static s32 e1000_reset_hw_82571(struct e1000_hw *hw) | ||||
msec_delay(10); | msec_delay(10); | ||||
/* Must acquire the MDIO ownership before MAC reset. | /* Must acquire the MDIO ownership before MAC reset. | ||||
* Ownership defaults to firmware after a reset. | * Ownership defaults to firmware after a reset. | ||||
*/ | */ | ||||
switch (hw->mac.type) { | switch (hw->mac.type) { | ||||
case e1000_82573: | case e1000_82573: | ||||
ret_val = e1000_get_hw_semaphore_82573(hw); | |||||
break; | |||||
case e1000_82574: | case e1000_82574: | ||||
case e1000_82583: | case e1000_82583: | ||||
ret_val = e1000_get_hw_semaphore_82574(hw); | ret_val = e1000_get_hw_semaphore_82574(hw); | ||||
break; | break; | ||||
default: | default: | ||||
break; | break; | ||||
} | } | ||||
ctrl = E1000_READ_REG(hw, E1000_CTRL); | ctrl = E1000_READ_REG(hw, E1000_CTRL); | ||||
DEBUGOUT("Issuing a global reset to MAC\n"); | DEBUGOUT("Issuing a global reset to MAC\n"); | ||||
E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST); | E1000_WRITE_REG(hw, E1000_CTRL, ctrl | E1000_CTRL_RST); | ||||
/* Must release MDIO ownership and mutex after MAC reset. */ | /* Must release MDIO ownership and mutex after MAC reset. */ | ||||
switch (hw->mac.type) { | switch (hw->mac.type) { | ||||
case e1000_82573: | case e1000_82573: | ||||
/* Release mutex only if the hw semaphore is acquired */ | |||||
if (!ret_val) | |||||
e1000_put_hw_semaphore_82573(hw); | |||||
break; | |||||
case e1000_82574: | case e1000_82574: | ||||
case e1000_82583: | case e1000_82583: | ||||
/* Release mutex only if the hw semaphore is acquired */ | /* Release mutex only if the hw semaphore is acquired */ | ||||
if (!ret_val) | if (!ret_val) | ||||
e1000_put_hw_semaphore_82574(hw); | e1000_put_hw_semaphore_82574(hw); | ||||
break; | break; | ||||
default: | default: | ||||
panic("unknown mac type %x\n", hw->mac.type); | |||||
break; | break; | ||||
} | } | ||||
if (hw->nvm.type == e1000_nvm_flash_hw) { | if (hw->nvm.type == e1000_nvm_flash_hw) { | ||||
usec_delay(10); | usec_delay(10); | ||||
ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); | ctrl_ext = E1000_READ_REG(hw, E1000_CTRL_EXT); | ||||
ctrl_ext |= E1000_CTRL_EXT_EE_RST; | ctrl_ext |= E1000_CTRL_EXT_EE_RST; | ||||
E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); | E1000_WRITE_REG(hw, E1000_CTRL_EXT, ctrl_ext); | ||||
▲ Show 20 Lines • Show All 900 Lines • Show Last 20 Lines |