diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2012-05-11 04:33:06 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2012-07-21 19:03:25 -0400 |
commit | 1c55ed768bb8b6aee0e1c88e963a429a3c14be07 (patch) | |
tree | 42f8c602fa09c548ae8ca36e966f9e4c13abb891 | |
parent | 9297127b9cdd8d30c829ef5fd28b7cc0323a7bcd (diff) |
ixgbevf: Add lock around mailbox ops to prevent simultaneous access
This change adds a spinlock around the mailbox accesses to prevent
simultaneous access to the mailboxes.
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 41 |
2 files changed, 41 insertions, 2 deletions
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h index e167d1bb6dea..66858b529f13 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf.h | |||
@@ -249,6 +249,8 @@ struct ixgbevf_adapter { | |||
249 | bool link_up; | 249 | bool link_up; |
250 | 250 | ||
251 | struct work_struct watchdog_task; | 251 | struct work_struct watchdog_task; |
252 | |||
253 | spinlock_t mbx_lock; | ||
252 | }; | 254 | }; |
253 | 255 | ||
254 | enum ixbgevf_state_t { | 256 | enum ixbgevf_state_t { |
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index 2dc78d7e297a..7cb678d2d2a2 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | |||
@@ -1120,9 +1120,14 @@ static int ixgbevf_vlan_rx_add_vid(struct net_device *netdev, u16 vid) | |||
1120 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); | 1120 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); |
1121 | struct ixgbe_hw *hw = &adapter->hw; | 1121 | struct ixgbe_hw *hw = &adapter->hw; |
1122 | 1122 | ||
1123 | spin_lock(&adapter->mbx_lock); | ||
1124 | |||
1123 | /* add VID to filter table */ | 1125 | /* add VID to filter table */ |
1124 | if (hw->mac.ops.set_vfta) | 1126 | if (hw->mac.ops.set_vfta) |
1125 | hw->mac.ops.set_vfta(hw, vid, 0, true); | 1127 | hw->mac.ops.set_vfta(hw, vid, 0, true); |
1128 | |||
1129 | spin_unlock(&adapter->mbx_lock); | ||
1130 | |||
1126 | set_bit(vid, adapter->active_vlans); | 1131 | set_bit(vid, adapter->active_vlans); |
1127 | 1132 | ||
1128 | return 0; | 1133 | return 0; |
@@ -1133,9 +1138,14 @@ static int ixgbevf_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) | |||
1133 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); | 1138 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); |
1134 | struct ixgbe_hw *hw = &adapter->hw; | 1139 | struct ixgbe_hw *hw = &adapter->hw; |
1135 | 1140 | ||
1141 | spin_lock(&adapter->mbx_lock); | ||
1142 | |||
1136 | /* remove VID from filter table */ | 1143 | /* remove VID from filter table */ |
1137 | if (hw->mac.ops.set_vfta) | 1144 | if (hw->mac.ops.set_vfta) |
1138 | hw->mac.ops.set_vfta(hw, vid, 0, false); | 1145 | hw->mac.ops.set_vfta(hw, vid, 0, false); |
1146 | |||
1147 | spin_unlock(&adapter->mbx_lock); | ||
1148 | |||
1139 | clear_bit(vid, adapter->active_vlans); | 1149 | clear_bit(vid, adapter->active_vlans); |
1140 | 1150 | ||
1141 | return 0; | 1151 | return 0; |
@@ -1190,11 +1200,15 @@ static void ixgbevf_set_rx_mode(struct net_device *netdev) | |||
1190 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); | 1200 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); |
1191 | struct ixgbe_hw *hw = &adapter->hw; | 1201 | struct ixgbe_hw *hw = &adapter->hw; |
1192 | 1202 | ||
1203 | spin_lock(&adapter->mbx_lock); | ||
1204 | |||
1193 | /* reprogram multicast list */ | 1205 | /* reprogram multicast list */ |
1194 | if (hw->mac.ops.update_mc_addr_list) | 1206 | if (hw->mac.ops.update_mc_addr_list) |
1195 | hw->mac.ops.update_mc_addr_list(hw, netdev); | 1207 | hw->mac.ops.update_mc_addr_list(hw, netdev); |
1196 | 1208 | ||
1197 | ixgbevf_write_uc_addr_list(netdev); | 1209 | ixgbevf_write_uc_addr_list(netdev); |
1210 | |||
1211 | spin_unlock(&adapter->mbx_lock); | ||
1198 | } | 1212 | } |
1199 | 1213 | ||
1200 | static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter) | 1214 | static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter) |
@@ -1339,6 +1353,8 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter) | |||
1339 | 1353 | ||
1340 | ixgbevf_configure_msix(adapter); | 1354 | ixgbevf_configure_msix(adapter); |
1341 | 1355 | ||
1356 | spin_lock(&adapter->mbx_lock); | ||
1357 | |||
1342 | if (hw->mac.ops.set_rar) { | 1358 | if (hw->mac.ops.set_rar) { |
1343 | if (is_valid_ether_addr(hw->mac.addr)) | 1359 | if (is_valid_ether_addr(hw->mac.addr)) |
1344 | hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0); | 1360 | hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0); |
@@ -1350,6 +1366,8 @@ static void ixgbevf_up_complete(struct ixgbevf_adapter *adapter) | |||
1350 | msg[1] = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; | 1366 | msg[1] = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; |
1351 | hw->mbx.ops.write_posted(hw, msg, 2); | 1367 | hw->mbx.ops.write_posted(hw, msg, 2); |
1352 | 1368 | ||
1369 | spin_unlock(&adapter->mbx_lock); | ||
1370 | |||
1353 | clear_bit(__IXGBEVF_DOWN, &adapter->state); | 1371 | clear_bit(__IXGBEVF_DOWN, &adapter->state); |
1354 | ixgbevf_napi_enable_all(adapter); | 1372 | ixgbevf_napi_enable_all(adapter); |
1355 | 1373 | ||
@@ -1562,11 +1580,15 @@ void ixgbevf_reset(struct ixgbevf_adapter *adapter) | |||
1562 | struct ixgbe_hw *hw = &adapter->hw; | 1580 | struct ixgbe_hw *hw = &adapter->hw; |
1563 | struct net_device *netdev = adapter->netdev; | 1581 | struct net_device *netdev = adapter->netdev; |
1564 | 1582 | ||
1583 | spin_lock(&adapter->mbx_lock); | ||
1584 | |||
1565 | if (hw->mac.ops.reset_hw(hw)) | 1585 | if (hw->mac.ops.reset_hw(hw)) |
1566 | hw_dbg(hw, "PF still resetting\n"); | 1586 | hw_dbg(hw, "PF still resetting\n"); |
1567 | else | 1587 | else |
1568 | hw->mac.ops.init_hw(hw); | 1588 | hw->mac.ops.init_hw(hw); |
1569 | 1589 | ||
1590 | spin_unlock(&adapter->mbx_lock); | ||
1591 | |||
1570 | if (is_valid_ether_addr(adapter->hw.mac.addr)) { | 1592 | if (is_valid_ether_addr(adapter->hw.mac.addr)) { |
1571 | memcpy(netdev->dev_addr, adapter->hw.mac.addr, | 1593 | memcpy(netdev->dev_addr, adapter->hw.mac.addr, |
1572 | netdev->addr_len); | 1594 | netdev->addr_len); |
@@ -1893,6 +1915,9 @@ static int __devinit ixgbevf_sw_init(struct ixgbevf_adapter *adapter) | |||
1893 | adapter->netdev->addr_len); | 1915 | adapter->netdev->addr_len); |
1894 | } | 1916 | } |
1895 | 1917 | ||
1918 | /* lock to protect mailbox accesses */ | ||
1919 | spin_lock_init(&adapter->mbx_lock); | ||
1920 | |||
1896 | /* Enable dynamic interrupt throttling rates */ | 1921 | /* Enable dynamic interrupt throttling rates */ |
1897 | adapter->rx_itr_setting = 1; | 1922 | adapter->rx_itr_setting = 1; |
1898 | adapter->tx_itr_setting = 1; | 1923 | adapter->tx_itr_setting = 1; |
@@ -2032,8 +2057,16 @@ static void ixgbevf_watchdog_task(struct work_struct *work) | |||
2032 | * no LSC interrupt | 2057 | * no LSC interrupt |
2033 | */ | 2058 | */ |
2034 | if (hw->mac.ops.check_link) { | 2059 | if (hw->mac.ops.check_link) { |
2035 | if ((hw->mac.ops.check_link(hw, &link_speed, | 2060 | s32 need_reset; |
2036 | &link_up, false)) != 0) { | 2061 | |
2062 | spin_lock(&adapter->mbx_lock); | ||
2063 | |||
2064 | need_reset = hw->mac.ops.check_link(hw, &link_speed, | ||
2065 | &link_up, false); | ||
2066 | |||
2067 | spin_unlock(&adapter->mbx_lock); | ||
2068 | |||
2069 | if (need_reset) { | ||
2037 | adapter->link_up = link_up; | 2070 | adapter->link_up = link_up; |
2038 | adapter->link_speed = link_speed; | 2071 | adapter->link_speed = link_speed; |
2039 | netif_carrier_off(netdev); | 2072 | netif_carrier_off(netdev); |
@@ -2813,9 +2846,13 @@ static int ixgbevf_set_mac(struct net_device *netdev, void *p) | |||
2813 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | 2846 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); |
2814 | memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len); | 2847 | memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len); |
2815 | 2848 | ||
2849 | spin_lock(&adapter->mbx_lock); | ||
2850 | |||
2816 | if (hw->mac.ops.set_rar) | 2851 | if (hw->mac.ops.set_rar) |
2817 | hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0); | 2852 | hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0); |
2818 | 2853 | ||
2854 | spin_unlock(&adapter->mbx_lock); | ||
2855 | |||
2819 | return 0; | 2856 | return 0; |
2820 | } | 2857 | } |
2821 | 2858 | ||