aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e/lib.c
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2010-01-12 21:05:38 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-13 23:31:57 -0500
commitab8932f3e8e07df92d6ce3fa41f5af0dda865429 (patch)
treeadfd802b04591e62b4743790ea8308f24f46d3e4 /drivers/net/e1000e/lib.c
parentf4d2dd4cd4d001f5dc20fc76c780c0c20c000c23 (diff)
e1000e: genericize the update multicast address list
Make updating the multicast address list generic for all families and enforce the requirement to update the entire multicast table array all at once instead of piecemeal which causes problems on some parts. Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/e1000e/lib.c')
-rw-r--r--drivers/net/e1000e/lib.c58
1 files changed, 15 insertions, 43 deletions
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 5f6b17148d34..2425ed11d5cc 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -340,62 +340,34 @@ static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
340 * @hw: pointer to the HW structure 340 * @hw: pointer to the HW structure
341 * @mc_addr_list: array of multicast addresses to program 341 * @mc_addr_list: array of multicast addresses to program
342 * @mc_addr_count: number of multicast addresses to program 342 * @mc_addr_count: number of multicast addresses to program
343 * @rar_used_count: the first RAR register free to program
344 * @rar_count: total number of supported Receive Address Registers
345 * 343 *
346 * Updates the Receive Address Registers and Multicast Table Array. 344 * Updates entire Multicast Table Array.
347 * The caller must have a packed mc_addr_list of multicast addresses. 345 * The caller must have a packed mc_addr_list of multicast addresses.
348 * The parameter rar_count will usually be hw->mac.rar_entry_count
349 * unless there are workarounds that change this.
350 **/ 346 **/
351void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw, 347void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
352 u8 *mc_addr_list, u32 mc_addr_count, 348 u8 *mc_addr_list, u32 mc_addr_count)
353 u32 rar_used_count, u32 rar_count)
354{ 349{
355 u32 i; 350 u32 hash_value, hash_bit, hash_reg;
356 u32 *mcarray = kzalloc(hw->mac.mta_reg_count * sizeof(u32), GFP_ATOMIC); 351 int i;
357 352
358 if (!mcarray) { 353 /* clear mta_shadow */
359 printk(KERN_ERR "multicast array memory allocation failed\n"); 354 memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
360 return;
361 }
362 355
363 /* 356 /* update mta_shadow from mc_addr_list */
364 * Load the first set of multicast addresses into the exact 357 for (i = 0; (u32) i < mc_addr_count; i++) {
365 * filters (RAR). If there are not enough to fill the RAR
366 * array, clear the filters.
367 */
368 for (i = rar_used_count; i < rar_count; i++) {
369 if (mc_addr_count) {
370 e1000e_rar_set(hw, mc_addr_list, i);
371 mc_addr_count--;
372 mc_addr_list += ETH_ALEN;
373 } else {
374 E1000_WRITE_REG_ARRAY(hw, E1000_RA, i << 1, 0);
375 e1e_flush();
376 E1000_WRITE_REG_ARRAY(hw, E1000_RA, (i << 1) + 1, 0);
377 e1e_flush();
378 }
379 }
380
381 /* Load any remaining multicast addresses into the hash table. */
382 for (; mc_addr_count > 0; mc_addr_count--) {
383 u32 hash_value, hash_reg, hash_bit, mta;
384 hash_value = e1000_hash_mc_addr(hw, mc_addr_list); 358 hash_value = e1000_hash_mc_addr(hw, mc_addr_list);
385 e_dbg("Hash value = 0x%03X\n", hash_value); 359
386 hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1); 360 hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
387 hash_bit = hash_value & 0x1F; 361 hash_bit = hash_value & 0x1F;
388 mta = (1 << hash_bit);
389 mcarray[hash_reg] |= mta;
390 mc_addr_list += ETH_ALEN;
391 }
392 362
393 /* write the hash table completely */ 363 hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
394 for (i = 0; i < hw->mac.mta_reg_count; i++) 364 mc_addr_list += (ETH_ALEN);
395 E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, mcarray[i]); 365 }
396 366
367 /* replace the entire MTA table */
368 for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
369 E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]);
397 e1e_flush(); 370 e1e_flush();
398 kfree(mcarray);
399} 371}
400 372
401/** 373/**