aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2009-09-03 10:48:56 -0400
committerDavid S. Miller <davem@davemloft.net>2009-09-03 23:01:45 -0400
commitff41f8dcc63b4d027ed314ae909df53746c40632 (patch)
treef3465a5e04b48150fad1b4b24eff51e7772f2bef /drivers
parent55f9d6786de2f9cf37db50dbe8ae16f887f3ad7f (diff)
igb: add support for set_rx_mode netdevice operation
This patch adds support for the set_rx_mode netdevice operation so that igb can better support multiple unicast 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')
-rw-r--r--drivers/net/igb/igb_main.c73
1 files changed, 48 insertions, 25 deletions
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index 7a054d99bff1..95089a8feeec 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -94,7 +94,7 @@ static void igb_clean_all_tx_rings(struct igb_adapter *);
94static void igb_clean_all_rx_rings(struct igb_adapter *); 94static void igb_clean_all_rx_rings(struct igb_adapter *);
95static void igb_clean_tx_ring(struct igb_ring *); 95static void igb_clean_tx_ring(struct igb_ring *);
96static void igb_clean_rx_ring(struct igb_ring *); 96static void igb_clean_rx_ring(struct igb_ring *);
97static void igb_set_multi(struct net_device *); 97static void igb_set_rx_mode(struct net_device *);
98static void igb_update_phy_info(unsigned long); 98static void igb_update_phy_info(unsigned long);
99static void igb_watchdog(unsigned long); 99static void igb_watchdog(unsigned long);
100static void igb_watchdog_task(struct work_struct *); 100static void igb_watchdog_task(struct work_struct *);
@@ -928,7 +928,7 @@ static void igb_configure(struct igb_adapter *adapter)
928 int i; 928 int i;
929 929
930 igb_get_hw_control(adapter); 930 igb_get_hw_control(adapter);
931 igb_set_multi(netdev); 931 igb_set_rx_mode(netdev);
932 932
933 igb_restore_vlan(adapter); 933 igb_restore_vlan(adapter);
934 934
@@ -1169,7 +1169,8 @@ static const struct net_device_ops igb_netdev_ops = {
1169 .ndo_stop = igb_close, 1169 .ndo_stop = igb_close,
1170 .ndo_start_xmit = igb_xmit_frame_adv, 1170 .ndo_start_xmit = igb_xmit_frame_adv,
1171 .ndo_get_stats = igb_get_stats, 1171 .ndo_get_stats = igb_get_stats,
1172 .ndo_set_multicast_list = igb_set_multi, 1172 .ndo_set_rx_mode = igb_set_rx_mode,
1173 .ndo_set_multicast_list = igb_set_rx_mode,
1173 .ndo_set_mac_address = igb_set_mac, 1174 .ndo_set_mac_address = igb_set_mac,
1174 .ndo_change_mtu = igb_change_mtu, 1175 .ndo_change_mtu = igb_change_mtu,
1175 .ndo_do_ioctl = igb_ioctl, 1176 .ndo_do_ioctl = igb_ioctl,
@@ -2519,48 +2520,70 @@ static int igb_set_mac(struct net_device *netdev, void *p)
2519 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); 2520 memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
2520 memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len); 2521 memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
2521 2522
2522 hw->mac.ops.rar_set(hw, hw->mac.addr, 0); 2523 igb_rar_set(hw, hw->mac.addr, 0);
2523
2524 igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0); 2524 igb_set_rah_pool(hw, adapter->vfs_allocated_count, 0);
2525 2525
2526 return 0; 2526 return 0;
2527} 2527}
2528 2528
2529/** 2529/**
2530 * igb_set_multi - Multicast and Promiscuous mode set 2530 * igb_set_rx_mode - Secondary Unicast, Multicast and Promiscuous mode set
2531 * @netdev: network interface device structure 2531 * @netdev: network interface device structure
2532 * 2532 *
2533 * The set_multi entry point is called whenever the multicast address 2533 * The set_rx_mode entry point is called whenever the unicast or multicast
2534 * list or the network interface flags are updated. This routine is 2534 * address lists or the network interface flags are updated. This routine is
2535 * responsible for configuring the hardware for proper multicast, 2535 * responsible for configuring the hardware for proper unicast, multicast,
2536 * promiscuous mode, and all-multi behavior. 2536 * promiscuous mode, and all-multi behavior.
2537 **/ 2537 **/
2538static void igb_set_multi(struct net_device *netdev) 2538static void igb_set_rx_mode(struct net_device *netdev)
2539{ 2539{
2540 struct igb_adapter *adapter = netdev_priv(netdev); 2540 struct igb_adapter *adapter = netdev_priv(netdev);
2541 struct e1000_hw *hw = &adapter->hw; 2541 struct e1000_hw *hw = &adapter->hw;
2542 struct dev_mc_list *mc_ptr; 2542 unsigned int rar_entries = hw->mac.rar_entry_count -
2543 (adapter->vfs_allocated_count + 1);
2544 struct dev_mc_list *mc_ptr = netdev->mc_list;
2543 u8 *mta_list = NULL; 2545 u8 *mta_list = NULL;
2544 u32 rctl; 2546 u32 rctl;
2545 int i; 2547 int i;
2546 2548
2547 /* Check for Promiscuous and All Multicast modes */ 2549 /* Check for Promiscuous and All Multicast modes */
2548
2549 rctl = rd32(E1000_RCTL); 2550 rctl = rd32(E1000_RCTL);
2550 2551
2551 if (netdev->flags & IFF_PROMISC) { 2552 if (netdev->flags & IFF_PROMISC) {
2552 rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE); 2553 rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
2553 rctl &= ~E1000_RCTL_VFE; 2554 rctl &= ~E1000_RCTL_VFE;
2554 } else { 2555 } else {
2555 if (netdev->flags & IFF_ALLMULTI) { 2556 if (netdev->flags & IFF_ALLMULTI)
2556 rctl |= E1000_RCTL_MPE; 2557 rctl |= E1000_RCTL_MPE;
2558 else
2559 rctl &= ~E1000_RCTL_MPE;
2560
2561 if (netdev->uc.count > rar_entries)
2562 rctl |= E1000_RCTL_UPE;
2563 else
2557 rctl &= ~E1000_RCTL_UPE; 2564 rctl &= ~E1000_RCTL_UPE;
2558 } else
2559 rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
2560 rctl |= E1000_RCTL_VFE; 2565 rctl |= E1000_RCTL_VFE;
2561 } 2566 }
2562 wr32(E1000_RCTL, rctl); 2567 wr32(E1000_RCTL, rctl);
2563 2568
2569 if (netdev->uc.count && rar_entries) {
2570 struct netdev_hw_addr *ha;
2571 list_for_each_entry(ha, &netdev->uc.list, list) {
2572 if (!rar_entries)
2573 break;
2574 igb_rar_set(hw, ha->addr, rar_entries);
2575 igb_set_rah_pool(hw, adapter->vfs_allocated_count,
2576 rar_entries);
2577 rar_entries--;
2578 }
2579 }
2580 /* write the addresses in reverse order to avoid write combining */
2581 for (; rar_entries > 0 ; rar_entries--) {
2582 wr32(E1000_RAH(rar_entries), 0);
2583 wr32(E1000_RAL(rar_entries), 0);
2584 }
2585 wrfl();
2586
2564 if (!netdev->mc_count) { 2587 if (!netdev->mc_count) {
2565 /* nothing to program, so clear mc list */ 2588 /* nothing to program, so clear mc list */
2566 igb_update_mc_addr_list(hw, NULL, 0); 2589 igb_update_mc_addr_list(hw, NULL, 0);
@@ -2576,8 +2599,6 @@ static void igb_set_multi(struct net_device *netdev)
2576 } 2599 }
2577 2600
2578 /* The shared function expects a packed array of only addresses. */ 2601 /* The shared function expects a packed array of only addresses. */
2579 mc_ptr = netdev->mc_list;
2580
2581 for (i = 0; i < netdev->mc_count; i++) { 2602 for (i = 0; i < netdev->mc_count; i++) {
2582 if (!mc_ptr) 2603 if (!mc_ptr)
2583 break; 2604 break;
@@ -3938,7 +3959,7 @@ static int igb_set_vf_multicasts(struct igb_adapter *adapter,
3938 vf_data->vf_mc_hashes[i] = hash_list[i];; 3959 vf_data->vf_mc_hashes[i] = hash_list[i];;
3939 3960
3940 /* Flush and reset the mta with the new values */ 3961 /* Flush and reset the mta with the new values */
3941 igb_set_multi(adapter->netdev); 3962 igb_set_rx_mode(adapter->netdev);
3942 3963
3943 return 0; 3964 return 0;
3944} 3965}
@@ -4072,13 +4093,14 @@ static inline void igb_vf_reset_event(struct igb_adapter *adapter, u32 vf)
4072 adapter->vf_data[vf].num_vf_mc_hashes = 0; 4093 adapter->vf_data[vf].num_vf_mc_hashes = 0;
4073 4094
4074 /* Flush and reset the mta with the new values */ 4095 /* Flush and reset the mta with the new values */
4075 igb_set_multi(adapter->netdev); 4096 igb_set_rx_mode(adapter->netdev);
4076} 4097}
4077 4098
4078static inline void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf) 4099static inline void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
4079{ 4100{
4080 struct e1000_hw *hw = &adapter->hw; 4101 struct e1000_hw *hw = &adapter->hw;
4081 unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses; 4102 unsigned char *vf_mac = adapter->vf_data[vf].vf_mac_addresses;
4103 int rar_entry = hw->mac.rar_entry_count - (vf + 1);
4082 u32 reg, msgbuf[3]; 4104 u32 reg, msgbuf[3];
4083 u8 *addr = (u8 *)(&msgbuf[1]); 4105 u8 *addr = (u8 *)(&msgbuf[1]);
4084 4106
@@ -4086,8 +4108,8 @@ static inline void igb_vf_reset_msg(struct igb_adapter *adapter, u32 vf)
4086 igb_vf_reset_event(adapter, vf); 4108 igb_vf_reset_event(adapter, vf);
4087 4109
4088 /* set vf mac address */ 4110 /* set vf mac address */
4089 igb_rar_set(hw, vf_mac, vf + 1); 4111 igb_rar_set(hw, vf_mac, rar_entry);
4090 igb_set_rah_pool(hw, vf, vf + 1); 4112 igb_set_rah_pool(hw, vf, rar_entry);
4091 4113
4092 /* enable transmit and receive for vf */ 4114 /* enable transmit and receive for vf */
4093 reg = rd32(E1000_VFTE); 4115 reg = rd32(E1000_VFTE);
@@ -5228,7 +5250,7 @@ static int __igb_shutdown(struct pci_dev *pdev, bool *enable_wake)
5228 5250
5229 if (wufc) { 5251 if (wufc) {
5230 igb_setup_rctl(adapter); 5252 igb_setup_rctl(adapter);
5231 igb_set_multi(netdev); 5253 igb_set_rx_mode(netdev);
5232 5254
5233 /* turn on all-multi mode if wake on multicast is enabled */ 5255 /* turn on all-multi mode if wake on multicast is enabled */
5234 if (wufc & E1000_WUFC_MC) { 5256 if (wufc & E1000_WUFC_MC) {
@@ -5482,12 +5504,13 @@ static int igb_set_vf_mac(struct igb_adapter *adapter,
5482 int vf, unsigned char *mac_addr) 5504 int vf, unsigned char *mac_addr)
5483{ 5505{
5484 struct e1000_hw *hw = &adapter->hw; 5506 struct e1000_hw *hw = &adapter->hw;
5485 int rar_entry = vf + 1; /* VF MAC addresses start at entry 1 */ 5507 /* VF MAC addresses start at end of receive addresses and moves
5486 5508 * torwards the first, as a result a collision should not be possible */
5487 igb_rar_set(hw, mac_addr, rar_entry); 5509 int rar_entry = hw->mac.rar_entry_count - (vf + 1);
5488 5510
5489 memcpy(adapter->vf_data[vf].vf_mac_addresses, mac_addr, ETH_ALEN); 5511 memcpy(adapter->vf_data[vf].vf_mac_addresses, mac_addr, ETH_ALEN);
5490 5512
5513 igb_rar_set(hw, mac_addr, rar_entry);
5491 igb_set_rah_pool(hw, vf, rar_entry); 5514 igb_set_rah_pool(hw, vf, rar_entry);
5492 5515
5493 return 0; 5516 return 0;