summaryrefslogtreecommitdiffstats
path: root/drivers/net/igb/e1000_mac.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2009-07-23 20:08:54 +0200
committerDavid S. Miller <davem@davemloft.net>2009-07-26 18:46:52 +0200
commit28fc06f58b1fe567bb86c7d0e3d93137e5c0126e (patch)
tree8f579894d96f4d9aea951f8985f0cd8e5fb6b16c /drivers/net/igb/e1000_mac.c
parentigb: add completion timeout workaround for 82575/82576 (diff)
downloadlinux-28fc06f58b1fe567bb86c7d0e3d93137e5c0126e.tar.xz
linux-28fc06f58b1fe567bb86c7d0e3d93137e5c0126e.zip
igb: move all multicast addresses into multicast table array
This patch moves all of the multicast addresses out of the free Receive address registers and instead programs them all into the multicast table array. As a result the multicast filtering may not be as precise, but it also greatly reduces the overhead for multicast addresses. Signed-off-by: Alexander Duyck <alexander.h.duyck@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/igb/e1000_mac.c')
-rw-r--r--drivers/net/igb/e1000_mac.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 60343b58364d..46e27e98254a 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -261,6 +261,41 @@ void igb_mta_set(struct e1000_hw *hw, u32 hash_value)
}
/**
+ * igb_update_mc_addr_list - Update Multicast addresses
+ * @hw: pointer to the HW structure
+ * @mc_addr_list: array of multicast addresses to program
+ * @mc_addr_count: number of multicast addresses to program
+ *
+ * Updates entire Multicast Table Array.
+ * The caller must have a packed mc_addr_list of multicast addresses.
+ **/
+void igb_update_mc_addr_list(struct e1000_hw *hw,
+ u8 *mc_addr_list, u32 mc_addr_count)
+{
+ u32 hash_value, hash_bit, hash_reg;
+ int i;
+
+ /* clear mta_shadow */
+ memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
+
+ /* update mta_shadow from mc_addr_list */
+ for (i = 0; (u32) i < mc_addr_count; i++) {
+ hash_value = igb_hash_mc_addr(hw, mc_addr_list);
+
+ hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
+ hash_bit = hash_value & 0x1F;
+
+ 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--)
+ array_wr32(E1000_MTA, i, hw->mac.mta_shadow[i]);
+ wrfl();
+}
+
+/**
* igb_hash_mc_addr - Generate a multicast hash value
* @hw: pointer to the HW structure
* @mc_addr: pointer to a multicast address