aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2010-06-15 05:25:48 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-15 17:23:35 -0400
commit2850062af1e00b3aab9f2ae486eda3e61d4aaeb9 (patch)
treef6cad36ae3980db7e03e9c9645e8c6eda7e21e3e /drivers/net/ixgbe
parent16fb62b6b4d57339a0ec931b3fb8c8d0ca6414e8 (diff)
ixgbe: update set_rx_mode to fix issues w/ macvlan
This change corrects issues where macvlan was not correctly triggering promiscuous mode on ixgbe due to the filters not being correctly set. It also corrects the fact that VF rar filters were being overwritten when the PF was reset. CC: Shirley Ma <xma@us.ibm.com> Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Tested-by: Emil Tantilov <emil.s.tantilov@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/ixgbe')
-rw-r--r--drivers/net/ixgbe/ixgbe.h1
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c88
-rw-r--r--drivers/net/ixgbe/ixgbe_sriov.c16
3 files changed, 79 insertions, 26 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 9270089eb282..9e15eb93860e 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -110,7 +110,6 @@ struct vf_data_storage {
110 u16 vlans_enabled; 110 u16 vlans_enabled;
111 bool clear_to_send; 111 bool clear_to_send;
112 bool pf_set_mac; 112 bool pf_set_mac;
113 int rar;
114 u16 pf_vlan; /* When set, guest VLAN config not allowed. */ 113 u16 pf_vlan; /* When set, guest VLAN config not allowed. */
115 u16 pf_qos; 114 u16 pf_qos;
116}; 115};
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 9cca737e4885..ebc4b04fdef2 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -2992,6 +2992,48 @@ static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
2992} 2992}
2993 2993
2994/** 2994/**
2995 * ixgbe_write_uc_addr_list - write unicast addresses to RAR table
2996 * @netdev: network interface device structure
2997 *
2998 * Writes unicast address list to the RAR table.
2999 * Returns: -ENOMEM on failure/insufficient address space
3000 * 0 on no addresses written
3001 * X on writing X addresses to the RAR table
3002 **/
3003static int ixgbe_write_uc_addr_list(struct net_device *netdev)
3004{
3005 struct ixgbe_adapter *adapter = netdev_priv(netdev);
3006 struct ixgbe_hw *hw = &adapter->hw;
3007 unsigned int vfn = adapter->num_vfs;
3008 unsigned int rar_entries = hw->mac.num_rar_entries - (vfn + 1);
3009 int count = 0;
3010
3011 /* return ENOMEM indicating insufficient memory for addresses */
3012 if (netdev_uc_count(netdev) > rar_entries)
3013 return -ENOMEM;
3014
3015 if (!netdev_uc_empty(netdev) && rar_entries) {
3016 struct netdev_hw_addr *ha;
3017 /* return error if we do not support writing to RAR table */
3018 if (!hw->mac.ops.set_rar)
3019 return -ENOMEM;
3020
3021 netdev_for_each_uc_addr(ha, netdev) {
3022 if (!rar_entries)
3023 break;
3024 hw->mac.ops.set_rar(hw, rar_entries--, ha->addr,
3025 vfn, IXGBE_RAH_AV);
3026 count++;
3027 }
3028 }
3029 /* write the addresses in reverse order to avoid write combining */
3030 for (; rar_entries > 0 ; rar_entries--)
3031 hw->mac.ops.clear_rar(hw, rar_entries);
3032
3033 return count;
3034}
3035
3036/**
2995 * ixgbe_set_rx_mode - Unicast, Multicast and Promiscuous mode set 3037 * ixgbe_set_rx_mode - Unicast, Multicast and Promiscuous mode set
2996 * @netdev: network interface device structure 3038 * @netdev: network interface device structure
2997 * 3039 *
@@ -3004,38 +3046,58 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
3004{ 3046{
3005 struct ixgbe_adapter *adapter = netdev_priv(netdev); 3047 struct ixgbe_adapter *adapter = netdev_priv(netdev);
3006 struct ixgbe_hw *hw = &adapter->hw; 3048 struct ixgbe_hw *hw = &adapter->hw;
3007 u32 fctrl; 3049 u32 fctrl, vmolr = IXGBE_VMOLR_BAM | IXGBE_VMOLR_AUPE;
3050 int count;
3008 3051
3009 /* Check for Promiscuous and All Multicast modes */ 3052 /* Check for Promiscuous and All Multicast modes */
3010 3053
3011 fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL); 3054 fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
3012 3055
3056 /* clear the bits we are changing the status of */
3057 fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
3058
3013 if (netdev->flags & IFF_PROMISC) { 3059 if (netdev->flags & IFF_PROMISC) {
3014 hw->addr_ctrl.user_set_promisc = true; 3060 hw->addr_ctrl.user_set_promisc = true;
3015 fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); 3061 fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
3062 vmolr |= (IXGBE_VMOLR_ROPE | IXGBE_VMOLR_MPE);
3016 /* don't hardware filter vlans in promisc mode */ 3063 /* don't hardware filter vlans in promisc mode */
3017 ixgbe_vlan_filter_disable(adapter); 3064 ixgbe_vlan_filter_disable(adapter);
3018 } else { 3065 } else {
3019 if (netdev->flags & IFF_ALLMULTI) { 3066 if (netdev->flags & IFF_ALLMULTI) {
3020 fctrl |= IXGBE_FCTRL_MPE; 3067 fctrl |= IXGBE_FCTRL_MPE;
3021 fctrl &= ~IXGBE_FCTRL_UPE; 3068 vmolr |= IXGBE_VMOLR_MPE;
3022 } else if (!hw->addr_ctrl.uc_set_promisc) { 3069 } else {
3023 fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); 3070 /*
3071 * Write addresses to the MTA, if the attempt fails
3072 * then we should just turn on promiscous mode so
3073 * that we can at least receive multicast traffic
3074 */
3075 hw->mac.ops.update_mc_addr_list(hw, netdev);
3076 vmolr |= IXGBE_VMOLR_ROMPE;
3024 } 3077 }
3025 ixgbe_vlan_filter_enable(adapter); 3078 ixgbe_vlan_filter_enable(adapter);
3026 hw->addr_ctrl.user_set_promisc = false; 3079 hw->addr_ctrl.user_set_promisc = false;
3080 /*
3081 * Write addresses to available RAR registers, if there is not
3082 * sufficient space to store all the addresses then enable
3083 * unicast promiscous mode
3084 */
3085 count = ixgbe_write_uc_addr_list(netdev);
3086 if (count < 0) {
3087 fctrl |= IXGBE_FCTRL_UPE;
3088 vmolr |= IXGBE_VMOLR_ROPE;
3089 }
3027 } 3090 }
3028 3091
3029 IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); 3092 if (adapter->num_vfs) {
3030
3031 /* reprogram secondary unicast list */
3032 hw->mac.ops.update_uc_addr_list(hw, netdev);
3033
3034 /* reprogram multicast list */
3035 hw->mac.ops.update_mc_addr_list(hw, netdev);
3036
3037 if (adapter->num_vfs)
3038 ixgbe_restore_vf_multicasts(adapter); 3093 ixgbe_restore_vf_multicasts(adapter);
3094 vmolr |= IXGBE_READ_REG(hw, IXGBE_VMOLR(adapter->num_vfs)) &
3095 ~(IXGBE_VMOLR_MPE | IXGBE_VMOLR_ROMPE |
3096 IXGBE_VMOLR_ROPE);
3097 IXGBE_WRITE_REG(hw, IXGBE_VMOLR(adapter->num_vfs), vmolr);
3098 }
3099
3100 IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
3039} 3101}
3040 3102
3041static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter) 3103static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c
index 66f6e62b8cb0..6e6dee04ff61 100644
--- a/drivers/net/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ixgbe/ixgbe_sriov.c
@@ -137,6 +137,7 @@ static void ixgbe_set_vmvir(struct ixgbe_adapter *adapter, u32 vid, u32 vf)
137inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) 137inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
138{ 138{
139 struct ixgbe_hw *hw = &adapter->hw; 139 struct ixgbe_hw *hw = &adapter->hw;
140 int rar_entry = hw->mac.num_rar_entries - (vf + 1);
140 141
141 /* reset offloads to defaults */ 142 /* reset offloads to defaults */
142 if (adapter->vfinfo[vf].pf_vlan) { 143 if (adapter->vfinfo[vf].pf_vlan) {
@@ -158,26 +159,17 @@ inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
158 /* Flush and reset the mta with the new values */ 159 /* Flush and reset the mta with the new values */
159 ixgbe_set_rx_mode(adapter->netdev); 160 ixgbe_set_rx_mode(adapter->netdev);
160 161
161 if (adapter->vfinfo[vf].rar > 0) { 162 hw->mac.ops.clear_rar(hw, rar_entry);
162 adapter->hw.mac.ops.clear_rar(&adapter->hw,
163 adapter->vfinfo[vf].rar);
164 adapter->vfinfo[vf].rar = -1;
165 }
166} 163}
167 164
168int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, 165int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
169 int vf, unsigned char *mac_addr) 166 int vf, unsigned char *mac_addr)
170{ 167{
171 struct ixgbe_hw *hw = &adapter->hw; 168 struct ixgbe_hw *hw = &adapter->hw;
172 169 int rar_entry = hw->mac.num_rar_entries - (vf + 1);
173 adapter->vfinfo[vf].rar = hw->mac.ops.set_rar(hw, vf + 1, mac_addr,
174 vf, IXGBE_RAH_AV);
175 if (adapter->vfinfo[vf].rar < 0) {
176 e_err("Could not set MAC Filter for VF %d\n", vf);
177 return -1;
178 }
179 170
180 memcpy(adapter->vfinfo[vf].vf_mac_addresses, mac_addr, 6); 171 memcpy(adapter->vfinfo[vf].vf_mac_addresses, mac_addr, 6);
172 hw->mac.ops.set_rar(hw, rar_entry, mac_addr, vf, IXGBE_RAH_AV);
181 173
182 return 0; 174 return 0;
183} 175}