Changeset View
Changeset View
Standalone View
Standalone View
head/sys/dev/e1000/e1000_mac.c
Show First 20 Lines • Show All 2,186 Lines • ▼ Show 20 Lines | |||||
* e1000_get_hw_semaphore - Acquire hardware semaphore | * e1000_get_hw_semaphore - 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 | * Acquire the HW semaphore to access the PHY or NVM | ||||
**/ | **/ | ||||
s32 e1000_get_hw_semaphore(struct e1000_hw *hw) | s32 e1000_get_hw_semaphore(struct e1000_hw *hw) | ||||
{ | { | ||||
u32 swsm; | u32 swsm; | ||||
s32 timeout = hw->nvm.word_size + 1; | s32 fw_timeout = hw->nvm.word_size + 1; | ||||
s32 sw_timeout = hw->nvm.word_size + 1; | |||||
s32 i = 0; | s32 i = 0; | ||||
DEBUGFUNC("e1000_get_hw_semaphore"); | DEBUGFUNC("e1000_get_hw_semaphore"); | ||||
#ifdef notyet | |||||
/* _82571 */ | /* _82571 */ | ||||
/* If we have timedout 3 times on trying to acquire | /* If we have timedout 3 times on trying to acquire | ||||
* the inter-port SMBI semaphore, there is old code | * the inter-port SMBI semaphore, there is old code | ||||
* operating on the other port, and it is not | * operating on the other port, and it is not | ||||
* releasing SMBI. Modify the number of times that | * releasing SMBI. Modify the number of times that | ||||
* we try for the semaphore to interwork with this | * we try for the semaphore to interwork with this | ||||
* older code. | * older code. | ||||
*/ | */ | ||||
if (hw->dev_spec._82571.smb_counter > 2) | if (hw->dev_spec._82571.smb_counter > 2) | ||||
sw_timeout = 1; | sw_timeout = 1; | ||||
#endif | |||||
/* Get the SW semaphore */ | /* Get the SW semaphore */ | ||||
while (i < timeout) { | while (i < sw_timeout) { | ||||
swsm = E1000_READ_REG(hw, E1000_SWSM); | swsm = E1000_READ_REG(hw, E1000_SWSM); | ||||
if (!(swsm & E1000_SWSM_SMBI)) | if (!(swsm & E1000_SWSM_SMBI)) | ||||
break; | break; | ||||
usec_delay(50); | usec_delay(50); | ||||
i++; | i++; | ||||
} | } | ||||
if (i == timeout) { | if (i == sw_timeout) { | ||||
#ifdef notyet | DEBUGOUT("Driver can't access device - SMBI bit is set.\n"); | ||||
/* | hw->dev_spec._82571.smb_counter++; | ||||
* XXX This sounds more like a driver bug whereby we either | } | ||||
* recursed accidentally or missed clearing it previously | |||||
*/ | |||||
/* In rare circumstances, the SW semaphore may already be held | /* In rare circumstances, the SW semaphore may already be held | ||||
* unintentionally. Clear the semaphore once before giving up. | * unintentionally. Clear the semaphore once before giving up. | ||||
*/ | */ | ||||
if (hw->dev_spec._82575.clear_semaphore_once) { | if (hw->dev_spec._82575.clear_semaphore_once) { | ||||
hw->dev_spec._82575.clear_semaphore_once = FALSE; | hw->dev_spec._82575.clear_semaphore_once = FALSE; | ||||
e1000_put_hw_semaphore_generic(hw); | e1000_put_hw_semaphore(hw); | ||||
for (i = 0; i < timeout; i++) { | for (i = 0; i < fw_timeout; i++) { | ||||
swsm = E1000_READ_REG(hw, E1000_SWSM); | swsm = E1000_READ_REG(hw, E1000_SWSM); | ||||
if (!(swsm & E1000_SWSM_SMBI)) | if (!(swsm & E1000_SWSM_SMBI)) | ||||
break; | break; | ||||
usec_delay(50); | usec_delay(50); | ||||
} | } | ||||
} | } | ||||
#endif | |||||
DEBUGOUT("Driver can't access device - SMBI bit is set.\n"); | |||||
return -E1000_ERR_NVM; | |||||
} | |||||
/* Get the FW semaphore. */ | /* Get the FW semaphore. */ | ||||
for (i = 0; i < timeout; i++) { | for (i = 0; i < fw_timeout; i++) { | ||||
swsm = E1000_READ_REG(hw, E1000_SWSM); | swsm = E1000_READ_REG(hw, E1000_SWSM); | ||||
E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI); | E1000_WRITE_REG(hw, E1000_SWSM, swsm | E1000_SWSM_SWESMBI); | ||||
/* Semaphore acquired if bit latched */ | /* Semaphore acquired if bit latched */ | ||||
if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI) | if (E1000_READ_REG(hw, E1000_SWSM) & E1000_SWSM_SWESMBI) | ||||
break; | break; | ||||
usec_delay(50); | usec_delay(50); | ||||
} | } | ||||
if (i == timeout) { | if (i == fw_timeout) { | ||||
/* Release semaphores */ | /* Release semaphores */ | ||||
e1000_put_hw_semaphore(hw); | e1000_put_hw_semaphore(hw); | ||||
DEBUGOUT("Driver can't access the NVM\n"); | DEBUGOUT("Driver can't access the NVM\n"); | ||||
return -E1000_ERR_NVM; | return -E1000_ERR_NVM; | ||||
} | } | ||||
return E1000_SUCCESS; | return E1000_SUCCESS; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 99 Lines • Show Last 20 Lines |