aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-11-13 23:54:59 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:03:51 -0500
commitdb0ce50d3792e993a1b24f16fb70153eccf38f33 (patch)
tree09ca5eab32a90f4f3877c5060eedf5ee5720fad6 /drivers/net
parent2a88719197bde746006c18ebe8f3576c87991419 (diff)
[E1000]: Secondary unicast address support
Add support for configuring secondary unicast addresses. Unicast addresses take precendece over multicast addresses when filling the exact address filters to avoid going to promiscous mode. When more unicast addresses are present than filter slots, unicast filtering is disabled and all slots can be used for multicast addresses. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/e1000/e1000_main.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 40dbe4cfe556..ade483e6e6d0 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -126,7 +126,7 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
126 struct e1000_tx_ring *tx_ring); 126 struct e1000_tx_ring *tx_ring);
127static void e1000_clean_rx_ring(struct e1000_adapter *adapter, 127static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
128 struct e1000_rx_ring *rx_ring); 128 struct e1000_rx_ring *rx_ring);
129static void e1000_set_multi(struct net_device *netdev); 129static void e1000_set_rx_mode(struct net_device *netdev);
130static void e1000_update_phy_info(unsigned long data); 130static void e1000_update_phy_info(unsigned long data);
131static void e1000_watchdog(unsigned long data); 131static void e1000_watchdog(unsigned long data);
132static void e1000_82547_tx_fifo_stall(unsigned long data); 132static void e1000_82547_tx_fifo_stall(unsigned long data);
@@ -487,7 +487,7 @@ static void e1000_configure(struct e1000_adapter *adapter)
487 struct net_device *netdev = adapter->netdev; 487 struct net_device *netdev = adapter->netdev;
488 int i; 488 int i;
489 489
490 e1000_set_multi(netdev); 490 e1000_set_rx_mode(netdev);
491 491
492 e1000_restore_vlan(adapter); 492 e1000_restore_vlan(adapter);
493 e1000_init_manageability(adapter); 493 e1000_init_manageability(adapter);
@@ -900,7 +900,7 @@ e1000_probe(struct pci_dev *pdev,
900 netdev->stop = &e1000_close; 900 netdev->stop = &e1000_close;
901 netdev->hard_start_xmit = &e1000_xmit_frame; 901 netdev->hard_start_xmit = &e1000_xmit_frame;
902 netdev->get_stats = &e1000_get_stats; 902 netdev->get_stats = &e1000_get_stats;
903 netdev->set_multicast_list = &e1000_set_multi; 903 netdev->set_rx_mode = &e1000_set_rx_mode;
904 netdev->set_mac_address = &e1000_set_mac; 904 netdev->set_mac_address = &e1000_set_mac;
905 netdev->change_mtu = &e1000_change_mtu; 905 netdev->change_mtu = &e1000_change_mtu;
906 netdev->do_ioctl = &e1000_ioctl; 906 netdev->do_ioctl = &e1000_ioctl;
@@ -2383,21 +2383,22 @@ e1000_set_mac(struct net_device *netdev, void *p)
2383} 2383}
2384 2384
2385/** 2385/**
2386 * e1000_set_multi - Multicast and Promiscuous mode set 2386 * e1000_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
2387 * @netdev: network interface device structure 2387 * @netdev: network interface device structure
2388 * 2388 *
2389 * The set_multi entry point is called whenever the multicast address 2389 * The set_rx_mode entry point is called whenever the unicast or multicast
2390 * list or the network interface flags are updated. This routine is 2390 * address lists or the network interface flags are updated. This routine is
2391 * responsible for configuring the hardware for proper multicast, 2391 * responsible for configuring the hardware for proper unicast, multicast,
2392 * promiscuous mode, and all-multi behavior. 2392 * promiscuous mode, and all-multi behavior.
2393 **/ 2393 **/
2394 2394
2395static void 2395static void
2396e1000_set_multi(struct net_device *netdev) 2396e1000_set_rx_mode(struct net_device *netdev)
2397{ 2397{
2398 struct e1000_adapter *adapter = netdev_priv(netdev); 2398 struct e1000_adapter *adapter = netdev_priv(netdev);
2399 struct e1000_hw *hw = &adapter->hw; 2399 struct e1000_hw *hw = &adapter->hw;
2400 struct dev_mc_list *mc_ptr; 2400 struct dev_addr_list *uc_ptr;
2401 struct dev_addr_list *mc_ptr;
2401 uint32_t rctl; 2402 uint32_t rctl;
2402 uint32_t hash_value; 2403 uint32_t hash_value;
2403 int i, rar_entries = E1000_RAR_ENTRIES; 2404 int i, rar_entries = E1000_RAR_ENTRIES;
@@ -2420,9 +2421,16 @@ e1000_set_multi(struct net_device *netdev)
2420 rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); 2421 rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
2421 } else if (netdev->flags & IFF_ALLMULTI) { 2422 } else if (netdev->flags & IFF_ALLMULTI) {
2422 rctl |= E1000_RCTL_MPE; 2423 rctl |= E1000_RCTL_MPE;
2423 rctl &= ~E1000_RCTL_UPE;
2424 } else { 2424 } else {
2425 rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE); 2425 rctl &= ~E1000_RCTL_MPE;
2426 }
2427
2428 uc_ptr = NULL;
2429 if (netdev->uc_count > rar_entries - 1) {
2430 rctl |= E1000_RCTL_UPE;
2431 } else if (!(netdev->flags & IFF_PROMISC)) {
2432 rctl &= ~E1000_RCTL_UPE;
2433 uc_ptr = netdev->uc_list;
2426 } 2434 }
2427 2435
2428 E1000_WRITE_REG(hw, RCTL, rctl); 2436 E1000_WRITE_REG(hw, RCTL, rctl);
@@ -2432,7 +2440,10 @@ e1000_set_multi(struct net_device *netdev)
2432 if (hw->mac_type == e1000_82542_rev2_0) 2440 if (hw->mac_type == e1000_82542_rev2_0)
2433 e1000_enter_82542_rst(adapter); 2441 e1000_enter_82542_rst(adapter);
2434 2442
2435 /* load the first 14 multicast address into the exact filters 1-14 2443 /* load the first 14 addresses into the exact filters 1-14. Unicast
2444 * addresses take precedence to avoid disabling unicast filtering
2445 * when possible.
2446 *
2436 * RAR 0 is used for the station MAC adddress 2447 * RAR 0 is used for the station MAC adddress
2437 * if there are not 14 addresses, go ahead and clear the filters 2448 * if there are not 14 addresses, go ahead and clear the filters
2438 * -- with 82571 controllers only 0-13 entries are filled here 2449 * -- with 82571 controllers only 0-13 entries are filled here
@@ -2440,8 +2451,11 @@ e1000_set_multi(struct net_device *netdev)
2440 mc_ptr = netdev->mc_list; 2451 mc_ptr = netdev->mc_list;
2441 2452
2442 for (i = 1; i < rar_entries; i++) { 2453 for (i = 1; i < rar_entries; i++) {
2443 if (mc_ptr) { 2454 if (uc_ptr) {
2444 e1000_rar_set(hw, mc_ptr->dmi_addr, i); 2455 e1000_rar_set(hw, uc_ptr->da_addr, i);
2456 uc_ptr = uc_ptr->next;
2457 } else if (mc_ptr) {
2458 e1000_rar_set(hw, mc_ptr->da_addr, i);
2445 mc_ptr = mc_ptr->next; 2459 mc_ptr = mc_ptr->next;
2446 } else { 2460 } else {
2447 E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0); 2461 E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0);
@@ -2450,6 +2464,7 @@ e1000_set_multi(struct net_device *netdev)
2450 E1000_WRITE_FLUSH(hw); 2464 E1000_WRITE_FLUSH(hw);
2451 } 2465 }
2452 } 2466 }
2467 WARN_ON(uc_ptr != NULL);
2453 2468
2454 /* clear the old settings from the multicast hash table */ 2469 /* clear the old settings from the multicast hash table */
2455 2470
@@ -2461,7 +2476,7 @@ e1000_set_multi(struct net_device *netdev)
2461 /* load any remaining addresses into the hash table */ 2476 /* load any remaining addresses into the hash table */
2462 2477
2463 for (; mc_ptr; mc_ptr = mc_ptr->next) { 2478 for (; mc_ptr; mc_ptr = mc_ptr->next) {
2464 hash_value = e1000_hash_mc_addr(hw, mc_ptr->dmi_addr); 2479 hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr);
2465 e1000_mta_set(hw, hash_value); 2480 e1000_mta_set(hw, hash_value);
2466 } 2481 }
2467 2482
@@ -5070,7 +5085,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
5070 5085
5071 if (wufc) { 5086 if (wufc) {
5072 e1000_setup_rctl(adapter); 5087 e1000_setup_rctl(adapter);
5073 e1000_set_multi(netdev); 5088 e1000_set_rx_mode(netdev);
5074 5089
5075 /* turn on all-multi mode if wake on multicast is enabled */ 5090 /* turn on all-multi mode if wake on multicast is enabled */
5076 if (wufc & E1000_WUFC_MC) { 5091 if (wufc & E1000_WUFC_MC) {