Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Patrick McHardy and committed by
David S. Miller
db0ce50d 2a887191

+31 -16
+31 -16
drivers/net/e1000/e1000_main.c
··· 126 126 struct e1000_tx_ring *tx_ring); 127 127 static void e1000_clean_rx_ring(struct e1000_adapter *adapter, 128 128 struct e1000_rx_ring *rx_ring); 129 - static void e1000_set_multi(struct net_device *netdev); 129 + static void e1000_set_rx_mode(struct net_device *netdev); 130 130 static void e1000_update_phy_info(unsigned long data); 131 131 static void e1000_watchdog(unsigned long data); 132 132 static void e1000_82547_tx_fifo_stall(unsigned long data); ··· 487 487 struct net_device *netdev = adapter->netdev; 488 488 int i; 489 489 490 - e1000_set_multi(netdev); 490 + e1000_set_rx_mode(netdev); 491 491 492 492 e1000_restore_vlan(adapter); 493 493 e1000_init_manageability(adapter); ··· 900 900 netdev->stop = &e1000_close; 901 901 netdev->hard_start_xmit = &e1000_xmit_frame; 902 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 904 netdev->set_mac_address = &e1000_set_mac; 905 905 netdev->change_mtu = &e1000_change_mtu; 906 906 netdev->do_ioctl = &e1000_ioctl; ··· 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 2387 * @netdev: network interface device structure 2388 2388 * 2389 - * The set_multi entry point is called whenever the multicast address 2390 - * list or the network interface flags are updated. This routine is 2391 - * responsible for configuring the hardware for proper multicast, 2389 + * The set_rx_mode entry point is called whenever the unicast or multicast 2390 + * address lists or the network interface flags are updated. This routine is 2391 + * responsible for configuring the hardware for proper unicast, multicast, 2392 2392 * promiscuous mode, and all-multi behavior. 2393 2393 **/ 2394 2394 2395 2395 static void 2396 - e1000_set_multi(struct net_device *netdev) 2396 + e1000_set_rx_mode(struct net_device *netdev) 2397 2397 { 2398 2398 struct e1000_adapter *adapter = netdev_priv(netdev); 2399 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 2402 uint32_t rctl; 2402 2403 uint32_t hash_value; 2403 2404 int i, rar_entries = E1000_RAR_ENTRIES; ··· 2421 2420 rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); 2422 2421 } else if (netdev->flags & IFF_ALLMULTI) { 2423 2422 rctl |= E1000_RCTL_MPE; 2424 - rctl &= ~E1000_RCTL_UPE; 2425 2423 } else { 2426 - rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE); 2424 + rctl &= ~E1000_RCTL_MPE; 2425 + } 2426 + 2427 + uc_ptr = NULL; 2428 + if (netdev->uc_count > rar_entries - 1) { 2429 + rctl |= E1000_RCTL_UPE; 2430 + } else if (!(netdev->flags & IFF_PROMISC)) { 2431 + rctl &= ~E1000_RCTL_UPE; 2432 + uc_ptr = netdev->uc_list; 2427 2433 } 2428 2434 2429 2435 E1000_WRITE_REG(hw, RCTL, rctl); ··· 2440 2432 if (hw->mac_type == e1000_82542_rev2_0) 2441 2433 e1000_enter_82542_rst(adapter); 2442 2434 2443 - /* load the first 14 multicast address into the exact filters 1-14 2435 + /* load the first 14 addresses into the exact filters 1-14. Unicast 2436 + * addresses take precedence to avoid disabling unicast filtering 2437 + * when possible. 2438 + * 2444 2439 * RAR 0 is used for the station MAC adddress 2445 2440 * if there are not 14 addresses, go ahead and clear the filters 2446 2441 * -- with 82571 controllers only 0-13 entries are filled here ··· 2451 2440 mc_ptr = netdev->mc_list; 2452 2441 2453 2442 for (i = 1; i < rar_entries; i++) { 2454 - if (mc_ptr) { 2455 - e1000_rar_set(hw, mc_ptr->dmi_addr, i); 2443 + if (uc_ptr) { 2444 + e1000_rar_set(hw, uc_ptr->da_addr, i); 2445 + uc_ptr = uc_ptr->next; 2446 + } else if (mc_ptr) { 2447 + e1000_rar_set(hw, mc_ptr->da_addr, i); 2456 2448 mc_ptr = mc_ptr->next; 2457 2449 } else { 2458 2450 E1000_WRITE_REG_ARRAY(hw, RA, i << 1, 0); ··· 2464 2450 E1000_WRITE_FLUSH(hw); 2465 2451 } 2466 2452 } 2453 + WARN_ON(uc_ptr != NULL); 2467 2454 2468 2455 /* clear the old settings from the multicast hash table */ 2469 2456 ··· 2476 2461 /* load any remaining addresses into the hash table */ 2477 2462 2478 2463 for (; mc_ptr; mc_ptr = mc_ptr->next) { 2479 - hash_value = e1000_hash_mc_addr(hw, mc_ptr->dmi_addr); 2464 + hash_value = e1000_hash_mc_addr(hw, mc_ptr->da_addr); 2480 2465 e1000_mta_set(hw, hash_value); 2481 2466 } 2482 2467 ··· 5085 5070 5086 5071 if (wufc) { 5087 5072 e1000_setup_rctl(adapter); 5088 - e1000_set_multi(netdev); 5073 + e1000_set_rx_mode(netdev); 5089 5074 5090 5075 /* turn on all-multi mode if wake on multicast is enabled */ 5091 5076 if (wufc & E1000_WUFC_MC) {