diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2012-08-20 20:15:13 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2012-09-24 04:50:45 -0400 |
commit | 2ddc7fe1cd1b2e0502f12b89c60b6e1ca66837dd (patch) | |
tree | eb64e408e2b78e4c38c9503e490ed5dda3d5915f | |
parent | 5c60f81a2553213856b3bb80f18003e56a6a110d (diff) |
ixgbevf: Return error on failure to enable VLAN
With recent kernel changes we can now return errors on a failure to setup a
VLAN filter. This patch takes advantage of that opportunity so that we can
return either an EIO error in the case of a mailbox failure, or an EACCESS
error in the case of being denied access to the VLAN filter table by the
PF.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Robert Garrett <robertx.e.garrett@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 21 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/vf.c | 20 |
2 files changed, 34 insertions, 7 deletions
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 2ba15ae2335c..cf372ee49d0c 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | |||
@@ -1126,36 +1126,47 @@ static int ixgbevf_vlan_rx_add_vid(struct net_device *netdev, u16 vid) | |||
1126 | { | 1126 | { |
1127 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); | 1127 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); |
1128 | struct ixgbe_hw *hw = &adapter->hw; | 1128 | struct ixgbe_hw *hw = &adapter->hw; |
1129 | int err; | ||
1130 | |||
1131 | if (!hw->mac.ops.set_vfta) | ||
1132 | return -EOPNOTSUPP; | ||
1129 | 1133 | ||
1130 | spin_lock(&adapter->mbx_lock); | 1134 | spin_lock(&adapter->mbx_lock); |
1131 | 1135 | ||
1132 | /* add VID to filter table */ | 1136 | /* add VID to filter table */ |
1133 | if (hw->mac.ops.set_vfta) | 1137 | err = hw->mac.ops.set_vfta(hw, vid, 0, true); |
1134 | hw->mac.ops.set_vfta(hw, vid, 0, true); | ||
1135 | 1138 | ||
1136 | spin_unlock(&adapter->mbx_lock); | 1139 | spin_unlock(&adapter->mbx_lock); |
1137 | 1140 | ||
1141 | /* translate error return types so error makes sense */ | ||
1142 | if (err == IXGBE_ERR_MBX) | ||
1143 | return -EIO; | ||
1144 | |||
1145 | if (err == IXGBE_ERR_INVALID_ARGUMENT) | ||
1146 | return -EACCES; | ||
1147 | |||
1138 | set_bit(vid, adapter->active_vlans); | 1148 | set_bit(vid, adapter->active_vlans); |
1139 | 1149 | ||
1140 | return 0; | 1150 | return err; |
1141 | } | 1151 | } |
1142 | 1152 | ||
1143 | static int ixgbevf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) | 1153 | static int ixgbevf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) |
1144 | { | 1154 | { |
1145 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); | 1155 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); |
1146 | struct ixgbe_hw *hw = &adapter->hw; | 1156 | struct ixgbe_hw *hw = &adapter->hw; |
1157 | int err = -EOPNOTSUPP; | ||
1147 | 1158 | ||
1148 | spin_lock(&adapter->mbx_lock); | 1159 | spin_lock(&adapter->mbx_lock); |
1149 | 1160 | ||
1150 | /* remove VID from filter table */ | 1161 | /* remove VID from filter table */ |
1151 | if (hw->mac.ops.set_vfta) | 1162 | if (hw->mac.ops.set_vfta) |
1152 | hw->mac.ops.set_vfta(hw, vid, 0, false); | 1163 | err = hw->mac.ops.set_vfta(hw, vid, 0, false); |
1153 | 1164 | ||
1154 | spin_unlock(&adapter->mbx_lock); | 1165 | spin_unlock(&adapter->mbx_lock); |
1155 | 1166 | ||
1156 | clear_bit(vid, adapter->active_vlans); | 1167 | clear_bit(vid, adapter->active_vlans); |
1157 | 1168 | ||
1158 | return 0; | 1169 | return err; |
1159 | } | 1170 | } |
1160 | 1171 | ||
1161 | static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter) | 1172 | static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter) |
diff --git a/drivers/net/ethernet/intel/ixgbevf/vf.c b/drivers/net/ethernet/intel/ixgbevf/vf.c index a5e66c79f632..0c7447e6fcc8 100644 --- a/drivers/net/ethernet/intel/ixgbevf/vf.c +++ b/drivers/net/ethernet/intel/ixgbevf/vf.c | |||
@@ -349,16 +349,32 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw, | |||
349 | static s32 ixgbevf_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, | 349 | static s32 ixgbevf_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, |
350 | bool vlan_on) | 350 | bool vlan_on) |
351 | { | 351 | { |
352 | struct ixgbe_mbx_info *mbx = &hw->mbx; | ||
352 | u32 msgbuf[2]; | 353 | u32 msgbuf[2]; |
354 | s32 err; | ||
353 | 355 | ||
354 | msgbuf[0] = IXGBE_VF_SET_VLAN; | 356 | msgbuf[0] = IXGBE_VF_SET_VLAN; |
355 | msgbuf[1] = vlan; | 357 | msgbuf[1] = vlan; |
356 | /* Setting the 8 bit field MSG INFO to TRUE indicates "add" */ | 358 | /* Setting the 8 bit field MSG INFO to TRUE indicates "add" */ |
357 | msgbuf[0] |= vlan_on << IXGBE_VT_MSGINFO_SHIFT; | 359 | msgbuf[0] |= vlan_on << IXGBE_VT_MSGINFO_SHIFT; |
358 | 360 | ||
359 | ixgbevf_write_msg_read_ack(hw, msgbuf, 2); | 361 | err = mbx->ops.write_posted(hw, msgbuf, 2); |
362 | if (err) | ||
363 | goto mbx_err; | ||
360 | 364 | ||
361 | return 0; | 365 | err = mbx->ops.read_posted(hw, msgbuf, 2); |
366 | if (err) | ||
367 | goto mbx_err; | ||
368 | |||
369 | /* remove extra bits from the message */ | ||
370 | msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS; | ||
371 | msgbuf[0] &= ~(0xFF << IXGBE_VT_MSGINFO_SHIFT); | ||
372 | |||
373 | if (msgbuf[0] != (IXGBE_VF_SET_VLAN | IXGBE_VT_MSGTYPE_ACK)) | ||
374 | err = IXGBE_ERR_INVALID_ARGUMENT; | ||
375 | |||
376 | mbx_err: | ||
377 | return err; | ||
362 | } | 378 | } |
363 | 379 | ||
364 | /** | 380 | /** |