aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2009-07-23 14:08:54 -0400
committerDavid S. Miller <davem@davemloft.net>2009-07-26 12:46:52 -0400
commit28fc06f58b1fe567bb86c7d0e3d93137e5c0126e (patch)
tree8f579894d96f4d9aea951f8985f0cd8e5fb6b16c /drivers/net
parent009bc06e5311b48c77b7708d9e226ae0f110373a (diff)
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')
-rw-r--r--drivers/net/igb/e1000_82575.c59
-rw-r--r--drivers/net/igb/e1000_82575.h1
-rw-r--r--drivers/net/igb/e1000_hw.h4
-rw-r--r--drivers/net/igb/e1000_mac.c35
-rw-r--r--drivers/net/igb/e1000_mac.h2
-rw-r--r--drivers/net/igb/igb_main.c44
6 files changed, 56 insertions, 89 deletions
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index c4506bf1fca2..5d2c2fbf926b 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -798,65 +798,6 @@ static void igb_init_rx_addrs_82575(struct e1000_hw *hw, u16 rar_count)
798} 798}
799 799
800/** 800/**
801 * igb_update_mc_addr_list - Update Multicast addresses
802 * @hw: pointer to the HW structure
803 * @mc_addr_list: array of multicast addresses to program
804 * @mc_addr_count: number of multicast addresses to program
805 * @rar_used_count: the first RAR register free to program
806 * @rar_count: total number of supported Receive Address Registers
807 *
808 * Updates the Receive Address Registers and Multicast Table Array.
809 * The caller must have a packed mc_addr_list of multicast addresses.
810 * The parameter rar_count will usually be hw->mac.rar_entry_count
811 * unless there are workarounds that change this.
812 **/
813void igb_update_mc_addr_list(struct e1000_hw *hw,
814 u8 *mc_addr_list, u32 mc_addr_count,
815 u32 rar_used_count, u32 rar_count)
816{
817 u32 hash_value;
818 u32 i;
819 u8 addr[6] = {0,0,0,0,0,0};
820 /*
821 * This function is essentially the same as that of
822 * igb_update_mc_addr_list_generic. However it also takes care
823 * of the special case where the register offset of the
824 * second set of RARs begins elsewhere. This is implicitly taken care by
825 * function e1000_rar_set_generic.
826 */
827
828 /*
829 * Load the first set of multicast addresses into the exact
830 * filters (RAR). If there are not enough to fill the RAR
831 * array, clear the filters.
832 */
833 for (i = rar_used_count; i < rar_count; i++) {
834 if (mc_addr_count) {
835 igb_rar_set(hw, mc_addr_list, i);
836 mc_addr_count--;
837 mc_addr_list += ETH_ALEN;
838 } else {
839 igb_rar_set(hw, addr, i);
840 }
841 }
842
843 /* Clear the old settings from the MTA */
844 hw_dbg("Clearing MTA\n");
845 for (i = 0; i < hw->mac.mta_reg_count; i++) {
846 array_wr32(E1000_MTA, i, 0);
847 wrfl();
848 }
849
850 /* Load any remaining multicast addresses into the hash table. */
851 for (; mc_addr_count > 0; mc_addr_count--) {
852 hash_value = igb_hash_mc_addr(hw, mc_addr_list);
853 hw_dbg("Hash value = 0x%03X\n", hash_value);
854 igb_mta_set(hw, hash_value);
855 mc_addr_list += ETH_ALEN;
856 }
857}
858
859/**
860 * igb_shutdown_fiber_serdes_link_82575 - Remove link during power down 801 * igb_shutdown_fiber_serdes_link_82575 - Remove link during power down
861 * @hw: pointer to the HW structure 802 * @hw: pointer to the HW structure
862 * 803 *
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index b674417ae06d..8a1e6597061f 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -28,7 +28,6 @@
28#ifndef _E1000_82575_H_ 28#ifndef _E1000_82575_H_
29#define _E1000_82575_H_ 29#define _E1000_82575_H_
30 30
31void igb_update_mc_addr_list(struct e1000_hw*, u8*, u32, u32, u32);
32extern void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw); 31extern void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
33extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw); 32extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
34 33
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index eb41f3b8234f..83f9b4f6d5e1 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -338,6 +338,10 @@ struct e1000_mac_info {
338 u16 ifs_ratio; 338 u16 ifs_ratio;
339 u16 ifs_step_size; 339 u16 ifs_step_size;
340 u16 mta_reg_count; 340 u16 mta_reg_count;
341
342 /* Maximum size of the MTA register table in all supported adapters */
343 #define MAX_MTA_REG 128
344 u32 mta_shadow[MAX_MTA_REG];
341 u16 rar_entry_count; 345 u16 rar_entry_count;
342 346
343 u8 forced_speed_duplex; 347 u8 forced_speed_duplex;
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)
261} 261}
262 262
263/** 263/**
264 * igb_update_mc_addr_list - Update Multicast addresses
265 * @hw: pointer to the HW structure
266 * @mc_addr_list: array of multicast addresses to program
267 * @mc_addr_count: number of multicast addresses to program
268 *
269 * Updates entire Multicast Table Array.
270 * The caller must have a packed mc_addr_list of multicast addresses.
271 **/
272void igb_update_mc_addr_list(struct e1000_hw *hw,
273 u8 *mc_addr_list, u32 mc_addr_count)
274{
275 u32 hash_value, hash_bit, hash_reg;
276 int i;
277
278 /* clear mta_shadow */
279 memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
280
281 /* update mta_shadow from mc_addr_list */
282 for (i = 0; (u32) i < mc_addr_count; i++) {
283 hash_value = igb_hash_mc_addr(hw, mc_addr_list);
284
285 hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
286 hash_bit = hash_value & 0x1F;
287
288 hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
289 mc_addr_list += (ETH_ALEN);
290 }
291
292 /* replace the entire MTA table */
293 for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
294 array_wr32(E1000_MTA, i, hw->mac.mta_shadow[i]);
295 wrfl();
296}
297
298/**
264 * igb_hash_mc_addr - Generate a multicast hash value 299 * igb_hash_mc_addr - Generate a multicast hash value
265 * @hw: pointer to the HW structure 300 * @hw: pointer to the HW structure
266 * @mc_addr: pointer to a multicast address 301 * @mc_addr: pointer to a multicast address
diff --git a/drivers/net/igb/e1000_mac.h b/drivers/net/igb/e1000_mac.h
index 1d690b4c9ae4..f9ebfb3f234c 100644
--- a/drivers/net/igb/e1000_mac.h
+++ b/drivers/net/igb/e1000_mac.h
@@ -51,6 +51,8 @@ s32 igb_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
51 u16 *duplex); 51 u16 *duplex);
52s32 igb_id_led_init(struct e1000_hw *hw); 52s32 igb_id_led_init(struct e1000_hw *hw);
53s32 igb_led_off(struct e1000_hw *hw); 53s32 igb_led_off(struct e1000_hw *hw);
54void igb_update_mc_addr_list(struct e1000_hw *hw,
55 u8 *mc_addr_list, u32 mc_addr_count);
54s32 igb_setup_link(struct e1000_hw *hw); 56s32 igb_setup_link(struct e1000_hw *hw);
55s32 igb_validate_mdi_setting(struct e1000_hw *hw); 57s32 igb_validate_mdi_setting(struct e1000_hw *hw);
56s32 igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg, 58s32 igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 2cb546078c52..e4f4526e5be1 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -127,7 +127,7 @@ static void igb_restore_vlan(struct igb_adapter *);
127static void igb_ping_all_vfs(struct igb_adapter *); 127static void igb_ping_all_vfs(struct igb_adapter *);
128static void igb_msg_task(struct igb_adapter *); 128static void igb_msg_task(struct igb_adapter *);
129static int igb_rcv_msg_from_vf(struct igb_adapter *, u32); 129static int igb_rcv_msg_from_vf(struct igb_adapter *, u32);
130static void igb_set_mc_list_pools(struct igb_adapter *, int, u16); 130static inline void igb_set_rah_pool(struct e1000_hw *, int , int);
131static void igb_vmm_control(struct igb_adapter *); 131static void igb_vmm_control(struct igb_adapter *);
132static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *); 132static int igb_set_vf_mac(struct igb_adapter *adapter, int, unsigned char *);
133static void igb_restore_vf_multicasts(struct igb_adapter *adapter); 133static void igb_restore_vf_multicasts(struct igb_adapter *adapter);
@@ -2535,7 +2535,6 @@ static void igb_set_multi(struct net_device *netdev)
2535{ 2535{
2536 struct igb_adapter *adapter = netdev_priv(netdev); 2536 struct igb_adapter *adapter = netdev_priv(netdev);
2537 struct e1000_hw *hw = &adapter->hw; 2537 struct e1000_hw *hw = &adapter->hw;
2538 struct e1000_mac_info *mac = &hw->mac;
2539 struct dev_mc_list *mc_ptr; 2538 struct dev_mc_list *mc_ptr;
2540 u8 *mta_list = NULL; 2539 u8 *mta_list = NULL;
2541 u32 rctl; 2540 u32 rctl;
@@ -2558,13 +2557,18 @@ static void igb_set_multi(struct net_device *netdev)
2558 } 2557 }
2559 wr32(E1000_RCTL, rctl); 2558 wr32(E1000_RCTL, rctl);
2560 2559
2561 if (netdev->mc_count) { 2560 if (!netdev->mc_count) {
2562 mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC); 2561 /* nothing to program, so clear mc list */
2563 if (!mta_list) { 2562 igb_update_mc_addr_list(hw, NULL, 0);
2564 dev_err(&adapter->pdev->dev, 2563 igb_restore_vf_multicasts(adapter);
2565 "failed to allocate multicast filter list\n"); 2564 return;
2566 return; 2565 }
2567 } 2566
2567 mta_list = kzalloc(netdev->mc_count * 6, GFP_ATOMIC);
2568 if (!mta_list) {
2569 dev_err(&adapter->pdev->dev,
2570 "failed to allocate multicast filter list\n");
2571 return;
2568 } 2572 }
2569 2573
2570 /* The shared function expects a packed array of only addresses. */ 2574 /* The shared function expects a packed array of only addresses. */
@@ -2576,14 +2580,9 @@ static void igb_set_multi(struct net_device *netdev)
2576 memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN); 2580 memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
2577 mc_ptr = mc_ptr->next; 2581 mc_ptr = mc_ptr->next;
2578 } 2582 }
2579 igb_update_mc_addr_list(hw, mta_list, i, 2583 igb_update_mc_addr_list(hw, mta_list, i);
2580 adapter->vfs_allocated_count + 1,
2581 mac->rar_entry_count);
2582
2583 igb_set_mc_list_pools(adapter, i, mac->rar_entry_count);
2584 igb_restore_vf_multicasts(adapter);
2585
2586 kfree(mta_list); 2584 kfree(mta_list);
2585 igb_restore_vf_multicasts(adapter);
2587} 2586}
2588 2587
2589/* Need to wait a few seconds after link up to get diagnostic information from 2588/* Need to wait a few seconds after link up to get diagnostic information from
@@ -5468,19 +5467,6 @@ static void igb_io_resume(struct pci_dev *pdev)
5468 igb_get_hw_control(adapter); 5467 igb_get_hw_control(adapter);
5469} 5468}
5470 5469
5471static void igb_set_mc_list_pools(struct igb_adapter *adapter,
5472 int entry_count, u16 total_rar_filters)
5473{
5474 struct e1000_hw *hw = &adapter->hw;
5475 int i = adapter->vfs_allocated_count + 1;
5476
5477 if ((i + entry_count) < total_rar_filters)
5478 total_rar_filters = i + entry_count;
5479
5480 for (; i < total_rar_filters; i++)
5481 igb_set_rah_pool(hw, adapter->vfs_allocated_count, i);
5482}
5483
5484static int igb_set_vf_mac(struct igb_adapter *adapter, 5470static int igb_set_vf_mac(struct igb_adapter *adapter,
5485 int vf, unsigned char *mac_addr) 5471 int vf, unsigned char *mac_addr)
5486{ 5472{