diff options
Diffstat (limited to 'drivers/net/e1000/e1000_main.c')
-rw-r--r-- | drivers/net/e1000/e1000_main.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 93b861d032b5..a65023d772cb 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -2335,6 +2335,12 @@ static void e1000_set_rx_mode(struct net_device *netdev) | |||
2335 | int mta_reg_count = (hw->mac_type == e1000_ich8lan) ? | 2335 | int mta_reg_count = (hw->mac_type == e1000_ich8lan) ? |
2336 | E1000_NUM_MTA_REGISTERS_ICH8LAN : | 2336 | E1000_NUM_MTA_REGISTERS_ICH8LAN : |
2337 | E1000_NUM_MTA_REGISTERS; | 2337 | E1000_NUM_MTA_REGISTERS; |
2338 | u32 *mcarray = kcalloc(mta_reg_count, sizeof(u32), GFP_ATOMIC); | ||
2339 | |||
2340 | if (!mcarray) { | ||
2341 | DPRINTK(PROBE, ERR, "memory allocation failed\n"); | ||
2342 | return; | ||
2343 | } | ||
2338 | 2344 | ||
2339 | if (hw->mac_type == e1000_ich8lan) | 2345 | if (hw->mac_type == e1000_ich8lan) |
2340 | rar_entries = E1000_RAR_ENTRIES_ICH8LAN; | 2346 | rar_entries = E1000_RAR_ENTRIES_ICH8LAN; |
@@ -2401,22 +2407,34 @@ static void e1000_set_rx_mode(struct net_device *netdev) | |||
2401 | } | 2407 | } |
2402 | WARN_ON(uc_ptr != NULL); | 2408 | WARN_ON(uc_ptr != NULL); |
2403 | 2409 | ||
2404 | /* clear the old settings from the multicast hash table */ | ||
2405 | |||
2406 | for (i = 0; i < mta_reg_count; i++) { | ||
2407 | E1000_WRITE_REG_ARRAY(hw, MTA, i, 0); | ||
2408 | E1000_WRITE_FLUSH(); | ||
2409 | } | ||
2410 | |||
2411 | /* load any remaining addresses into the hash table */ | 2410 | /* load any remaining addresses into the hash table */ |
2412 | 2411 | ||
2413 | for (; mc_ptr; mc_ptr = mc_ptr->next) { | 2412 | for (; mc_ptr; mc_ptr = mc_ptr->next) { |
2413 | u32 hash_reg, hash_bit, mta; | ||
2414 | hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr); | 2414 | hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr); |
2415 | e1000_mta_set(hw, hash_value); | 2415 | hash_reg = (hash_value >> 5) & 0x7F; |
2416 | hash_bit = hash_value & 0x1F; | ||
2417 | mta = (1 << hash_bit); | ||
2418 | mcarray[hash_reg] |= mta; | ||
2416 | } | 2419 | } |
2417 | 2420 | ||
2421 | /* write the hash table completely, write from bottom to avoid | ||
2422 | * both stupid write combining chipsets, and flushing each write */ | ||
2423 | for (i = mta_reg_count - 1; i >= 0 ; i--) { | ||
2424 | /* | ||
2425 | * If we are on an 82544 has an errata where writing odd | ||
2426 | * offsets overwrites the previous even offset, but writing | ||
2427 | * backwards over the range solves the issue by always | ||
2428 | * writing the odd offset first | ||
2429 | */ | ||
2430 | E1000_WRITE_REG_ARRAY(hw, MTA, i, mcarray[i]); | ||
2431 | } | ||
2432 | E1000_WRITE_FLUSH(); | ||
2433 | |||
2418 | if (hw->mac_type == e1000_82542_rev2_0) | 2434 | if (hw->mac_type == e1000_82542_rev2_0) |
2419 | e1000_leave_82542_rst(adapter); | 2435 | e1000_leave_82542_rst(adapter); |
2436 | |||
2437 | kfree(mcarray); | ||
2420 | } | 2438 | } |
2421 | 2439 | ||
2422 | /* Need to wait a few seconds after link up to get diagnostic information from | 2440 | /* Need to wait a few seconds after link up to get diagnostic information from |