|
@@ -340,62 +340,34 @@ static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
|
|
|
* @hw: pointer to the HW structure
|
|
|
* @mc_addr_list: array of multicast addresses to program
|
|
|
* @mc_addr_count: number of multicast addresses to program
|
|
|
- * @rar_used_count: the first RAR register free to program
|
|
|
- * @rar_count: total number of supported Receive Address Registers
|
|
|
*
|
|
|
- * Updates the Receive Address Registers and Multicast Table Array.
|
|
|
+ * Updates entire Multicast Table Array.
|
|
|
* The caller must have a packed mc_addr_list of multicast addresses.
|
|
|
- * The parameter rar_count will usually be hw->mac.rar_entry_count
|
|
|
- * unless there are workarounds that change this.
|
|
|
**/
|
|
|
void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
|
|
|
- u8 *mc_addr_list, u32 mc_addr_count,
|
|
|
- u32 rar_used_count, u32 rar_count)
|
|
|
+ u8 *mc_addr_list, u32 mc_addr_count)
|
|
|
{
|
|
|
- u32 i;
|
|
|
- u32 *mcarray = kzalloc(hw->mac.mta_reg_count * sizeof(u32), GFP_ATOMIC);
|
|
|
+ u32 hash_value, hash_bit, hash_reg;
|
|
|
+ int i;
|
|
|
|
|
|
- if (!mcarray) {
|
|
|
- printk(KERN_ERR "multicast array memory allocation failed\n");
|
|
|
- return;
|
|
|
- }
|
|
|
+ /* clear mta_shadow */
|
|
|
+ memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
|
|
|
|
|
|
- /*
|
|
|
- * Load the first set of multicast addresses into the exact
|
|
|
- * filters (RAR). If there are not enough to fill the RAR
|
|
|
- * array, clear the filters.
|
|
|
- */
|
|
|
- for (i = rar_used_count; i < rar_count; i++) {
|
|
|
- if (mc_addr_count) {
|
|
|
- e1000e_rar_set(hw, mc_addr_list, i);
|
|
|
- mc_addr_count--;
|
|
|
- mc_addr_list += ETH_ALEN;
|
|
|
- } else {
|
|
|
- E1000_WRITE_REG_ARRAY(hw, E1000_RA, i << 1, 0);
|
|
|
- e1e_flush();
|
|
|
- E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1) + 1, 0);
|
|
|
- e1e_flush();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* Load any remaining multicast addresses into the hash table. */
|
|
|
- for (; mc_addr_count > 0; mc_addr_count--) {
|
|
|
- u32 hash_value, hash_reg, hash_bit, mta;
|
|
|
+ /* update mta_shadow from mc_addr_list */
|
|
|
+ for (i = 0; (u32) i < mc_addr_count; i++) {
|
|
|
hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
|
|
|
- e_dbg("Hash value = 0x%03X\n", hash_value);
|
|
|
+
|
|
|
hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
|
|
|
hash_bit = hash_value & 0x1F;
|
|
|
- mta = (1 << hash_bit);
|
|
|
- mcarray[hash_reg] |= mta;
|
|
|
- mc_addr_list += ETH_ALEN;
|
|
|
- }
|
|
|
|
|
|
- /* write the hash table completely */
|
|
|
- for (i = 0; i < hw->mac.mta_reg_count; i++)
|
|
|
- E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, mcarray[i]);
|
|
|
+ hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
|
|
|
+ mc_addr_list += (ETH_ALEN);
|
|
|
+ }
|
|
|
|
|
|
+ /* replace the entire MTA table */
|
|
|
+ for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
|
|
|
+ E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]);
|
|
|
e1e_flush();
|
|
|
- kfree(mcarray);
|
|
|
}
|
|
|
|
|
|
/**
|