diff options
Diffstat (limited to 'drivers/net/e1000e/ich8lan.c')
| -rw-r--r-- | drivers/net/e1000e/ich8lan.c | 94 | 
1 files changed, 43 insertions, 51 deletions
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index d56c7473144a..99df2abf82a9 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -338,10 +338,7 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)  {  	struct e1000_nvm_info *nvm = &hw->nvm;  	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; -	union ich8_hws_flash_status hsfsts; -	u32 gfpreg; -	u32 sector_base_addr; -	u32 sector_end_addr; +	u32 gfpreg, sector_base_addr, sector_end_addr;  	u16 i;  	/* Can't read flash registers if the register set isn't mapped. */ @@ -375,20 +372,6 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)  	/* Adjust to word count */  	nvm->flash_bank_size /= sizeof(u16); -	/* -	 * Make sure the flash bank size does not overwrite the 4k -	 * sector ranges. We may have 64k allotted to us but we only care -	 * about the first 2 4k sectors. Therefore, if we have anything less -	 * than 64k set in the HSFSTS register, we will reduce the bank size -	 * down to 4k and let the rest remain unused. If berasesz == 3, then -	 * we are working in 64k mode. Otherwise we are not. -	 */ -	if (nvm->flash_bank_size > E1000_ICH8_SHADOW_RAM_WORDS) { -		hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); -		if (hsfsts.hsf_status.berasesz != 3) -			nvm->flash_bank_size = E1000_ICH8_SHADOW_RAM_WORDS; -	} -  	nvm->word_size = E1000_ICH8_SHADOW_RAM_WORDS;  	/* Clear shadow ram */ @@ -594,8 +577,8 @@ static DEFINE_MUTEX(nvm_mutex);   **/  static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)  { -	u32 extcnf_ctrl; -	u32 timeout = PHY_CFG_TIMEOUT; +	u32 extcnf_ctrl, timeout = PHY_CFG_TIMEOUT; +	s32 ret_val = 0;  	might_sleep(); @@ -603,28 +586,46 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)  	while (timeout) {  		extcnf_ctrl = er32(EXTCNF_CTRL); +		if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)) +			break; -		if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)) { -			extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; -			ew32(EXTCNF_CTRL, extcnf_ctrl); +		mdelay(1); +		timeout--; +	} + +	if (!timeout) { +		hw_dbg(hw, "SW/FW/HW has locked the resource for too long.\n"); +		ret_val = -E1000_ERR_CONFIG; +		goto out; +	} + +	timeout = PHY_CFG_TIMEOUT * 2; + +	extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; +	ew32(EXTCNF_CTRL, extcnf_ctrl); + +	while (timeout) { +		extcnf_ctrl = er32(EXTCNF_CTRL); +		if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG) +			break; -			extcnf_ctrl = er32(EXTCNF_CTRL); -			if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG) -				break; -		}  		mdelay(1);  		timeout--;  	}  	if (!timeout) { -		hw_dbg(hw, "FW or HW has locked the resource for too long.\n"); +		hw_dbg(hw, "Failed to acquire the semaphore.\n");  		extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;  		ew32(EXTCNF_CTRL, extcnf_ctrl); -		mutex_unlock(&nvm_mutex); -		return -E1000_ERR_CONFIG; +		ret_val = -E1000_ERR_CONFIG; +		goto out;  	} -	return 0; +out: +	if (ret_val) +		mutex_unlock(&nvm_mutex); + +	return ret_val;  }  /** @@ -1306,7 +1307,7 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,  	struct e1000_nvm_info *nvm = &hw->nvm;  	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan;  	u32 act_offset; -	s32 ret_val; +	s32 ret_val = 0;  	u32 bank = 0;  	u16 i, word; @@ -1321,12 +1322,15 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,  		goto out;  	ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank); -	if (ret_val) -		goto release; +	if (ret_val) { +		hw_dbg(hw, "Could not detect valid bank, assuming bank 0\n"); +		bank = 0; +	}  	act_offset = (bank) ? nvm->flash_bank_size : 0;  	act_offset += offset; +	ret_val = 0;  	for (i = 0; i < words; i++) {  		if ((dev_spec->shadow_ram) &&  		    (dev_spec->shadow_ram[offset+i].modified)) { @@ -1341,7 +1345,6 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,  		}  	} -release:  	e1000_release_swflag_ich8lan(hw);  out: @@ -1592,7 +1595,6 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,  {  	struct e1000_nvm_info *nvm = &hw->nvm;  	struct e1000_dev_spec_ich8lan *dev_spec = &hw->dev_spec.ich8lan; -	s32 ret_val;  	u16 i;  	if ((offset >= nvm->word_size) || (words > nvm->word_size - offset) || @@ -1601,17 +1603,11 @@ static s32 e1000_write_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,  		return -E1000_ERR_NVM;  	} -	ret_val = e1000_acquire_swflag_ich8lan(hw); -	if (ret_val) -		return ret_val; -  	for (i = 0; i < words; i++) {  		dev_spec->shadow_ram[offset+i].modified = 1;  		dev_spec->shadow_ram[offset+i].value = data[i];  	} -	e1000_release_swflag_ich8lan(hw); -  	return 0;  } @@ -1652,8 +1648,8 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)  	 */  	ret_val =  e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);  	if (ret_val) { -		e1000_release_swflag_ich8lan(hw); -		goto out; +		hw_dbg(hw, "Could not detect valid bank, assuming bank 0\n"); +		bank = 0;  	}  	if (bank == 0) { @@ -2039,12 +2035,8 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)  		iteration = 1;  		break;  	case 2: -		if (hw->mac.type == e1000_ich9lan) { -			sector_size = ICH_FLASH_SEG_SIZE_8K; -			iteration = flash_bank_size / ICH_FLASH_SEG_SIZE_8K; -		} else { -			return -E1000_ERR_NVM; -		} +		sector_size = ICH_FLASH_SEG_SIZE_8K; +		iteration = 1;  		break;  	case 3:  		sector_size = ICH_FLASH_SEG_SIZE_64K; @@ -2056,7 +2048,7 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)  	/* Start with the base address, then add the sector offset. */  	flash_linear_addr = hw->nvm.flash_base_addr; -	flash_linear_addr += (bank) ? (sector_size * iteration) : 0; +	flash_linear_addr += (bank) ? flash_bank_size : 0;  	for (j = 0; j < iteration ; j++) {  		do {  | 
