diff options
Diffstat (limited to 'drivers/net/ethernet/intel/igb/e1000_mac.c')
| -rw-r--r-- | drivers/net/ethernet/intel/igb/e1000_mac.c | 27 | 
1 files changed, 27 insertions, 0 deletions
| diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.c b/drivers/net/ethernet/intel/igb/e1000_mac.c index fd8eb2f9ab9d..e63ee3cca5ea 100644 --- a/drivers/net/ethernet/intel/igb/e1000_mac.c +++ b/drivers/net/ethernet/intel/igb/e1000_mac.c @@ -484,6 +484,31 @@ static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)  }  /** + * igb_i21x_hw_doublecheck - double checks potential HW issue in i21X + * @hw: pointer to the HW structure + * + * Checks if multicast array is wrote correctly + * If not then rewrites again to register + **/ +static void igb_i21x_hw_doublecheck(struct e1000_hw *hw) +{ +	bool is_failed; +	int i; + +	do { +		is_failed = false; +		for (i = hw->mac.mta_reg_count - 1; i >= 0; i--) { +			if (array_rd32(E1000_MTA, i) != hw->mac.mta_shadow[i]) { +				is_failed = true; +				array_wr32(E1000_MTA, i, hw->mac.mta_shadow[i]); +				wrfl(); +				break; +			} +		} +	} while (is_failed); +} + +/**   *  igb_update_mc_addr_list - Update Multicast addresses   *  @hw: pointer to the HW structure   *  @mc_addr_list: array of multicast addresses to program @@ -516,6 +541,8 @@ void igb_update_mc_addr_list(struct e1000_hw *hw,  	for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)  		array_wr32(E1000_MTA, i, hw->mac.mta_shadow[i]);  	wrfl(); +	if (hw->mac.type == e1000_i210 || hw->mac.type == e1000_i211) +		igb_i21x_hw_doublecheck(hw);  }  /** | 
