diff options
author | David S. Miller <davem@davemloft.net> | 2018-03-19 15:12:03 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-03-19 15:12:03 -0400 |
commit | c314c7ba40389876a3a4534cdef4adde56174a09 (patch) | |
tree | e703d38c8451ce06aa5e97db1398e029e311e9ed | |
parent | e3c72f3d37e4745dc3a6ae69f5fc2bd4c31ca4eb (diff) | |
parent | 12d80bca0bb7178bc85a32e19795ff249a5903ad (diff) |
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue
Jeff Kirsher says:
====================
40GbE Intel Wired LAN Driver Updates 2018-03-19
This series contains updates to i40e and i40evf only.
Alex fixes a potential deadlock in the configure_clsflower function in
i40evf, where we exit with the "IN_CRITICAL_TASK" bit set while
notifying the PF of flower filters.
Jan fixed an issue where it was possible to set a mode that is not
allowed which resulted in link being down, so fixed the parity between
i40e_set_link_ksettings() and i40e_get_link_ksettings().
Patryk fixes a bug where a backplane device was allowing the setting of
link settings, which is not allowed.
Shiraz fixes a crash when entering S3 because the client interface was
freeing the MSIx vectors while they are still in use.
Jake fixes up a function header comment to document a newly added
parameter. Also cleaned up flags that were never used.
Doug fixes the incorrect return type for i40e_aq_add_cloud_filters().
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_client.c | 16 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_common.c | 40 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 20 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_main.c | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40e/i40e_prototype.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40evf/i40evf.h | 3 | ||||
-rw-r--r-- | drivers/net/ethernet/intel/i40evf/i40evf_main.c | 23 |
8 files changed, 77 insertions, 38 deletions
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h index 36d9401a6258..271ab1a861b7 100644 --- a/drivers/net/ethernet/intel/i40e/i40e.h +++ b/drivers/net/ethernet/intel/i40e/i40e.h | |||
@@ -1041,6 +1041,7 @@ void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi); | |||
1041 | void i40e_notify_client_of_netdev_close(struct i40e_vsi *vsi, bool reset); | 1041 | void i40e_notify_client_of_netdev_close(struct i40e_vsi *vsi, bool reset); |
1042 | void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs); | 1042 | void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs); |
1043 | void i40e_notify_client_of_vf_reset(struct i40e_pf *pf, u32 vf_id); | 1043 | void i40e_notify_client_of_vf_reset(struct i40e_pf *pf, u32 vf_id); |
1044 | void i40e_client_update_msix_info(struct i40e_pf *pf); | ||
1044 | int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id); | 1045 | int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id); |
1045 | /** | 1046 | /** |
1046 | * i40e_irq_dynamic_enable - Enable default interrupt generation settings | 1047 | * i40e_irq_dynamic_enable - Enable default interrupt generation settings |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_client.c b/drivers/net/ethernet/intel/i40e/i40e_client.c index 0de9610c1d8d..704695a61645 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_client.c +++ b/drivers/net/ethernet/intel/i40e/i40e_client.c | |||
@@ -287,6 +287,17 @@ out: | |||
287 | return capable; | 287 | return capable; |
288 | } | 288 | } |
289 | 289 | ||
290 | void i40e_client_update_msix_info(struct i40e_pf *pf) | ||
291 | { | ||
292 | struct i40e_client_instance *cdev = pf->cinst; | ||
293 | |||
294 | if (!cdev || !cdev->client) | ||
295 | return; | ||
296 | |||
297 | cdev->lan_info.msix_count = pf->num_iwarp_msix; | ||
298 | cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector]; | ||
299 | } | ||
300 | |||
290 | /** | 301 | /** |
291 | * i40e_client_add_instance - add a client instance struct to the instance list | 302 | * i40e_client_add_instance - add a client instance struct to the instance list |
292 | * @pf: pointer to the board struct | 303 | * @pf: pointer to the board struct |
@@ -328,9 +339,6 @@ static void i40e_client_add_instance(struct i40e_pf *pf) | |||
328 | return; | 339 | return; |
329 | } | 340 | } |
330 | 341 | ||
331 | cdev->lan_info.msix_count = pf->num_iwarp_msix; | ||
332 | cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector]; | ||
333 | |||
334 | mac = list_first_entry(&cdev->lan_info.netdev->dev_addrs.list, | 342 | mac = list_first_entry(&cdev->lan_info.netdev->dev_addrs.list, |
335 | struct netdev_hw_addr, list); | 343 | struct netdev_hw_addr, list); |
336 | if (mac) | 344 | if (mac) |
@@ -340,6 +348,8 @@ static void i40e_client_add_instance(struct i40e_pf *pf) | |||
340 | 348 | ||
341 | cdev->client = registered_client; | 349 | cdev->client = registered_client; |
342 | pf->cinst = cdev; | 350 | pf->cinst = cdev; |
351 | |||
352 | i40e_client_update_msix_info(pf); | ||
343 | } | 353 | } |
344 | 354 | ||
345 | /** | 355 | /** |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c index 242c4c789e8d..4fa31d87d9d2 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_common.c +++ b/drivers/net/ethernet/intel/i40e/i40e_common.c | |||
@@ -1208,6 +1208,29 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw) | |||
1208 | return media; | 1208 | return media; |
1209 | } | 1209 | } |
1210 | 1210 | ||
1211 | /** | ||
1212 | * i40e_poll_globr - Poll for Global Reset completion | ||
1213 | * @hw: pointer to the hardware structure | ||
1214 | * @retry_limit: how many times to retry before failure | ||
1215 | **/ | ||
1216 | static i40e_status i40e_poll_globr(struct i40e_hw *hw, | ||
1217 | u32 retry_limit) | ||
1218 | { | ||
1219 | u32 cnt, reg = 0; | ||
1220 | |||
1221 | for (cnt = 0; cnt < retry_limit; cnt++) { | ||
1222 | reg = rd32(hw, I40E_GLGEN_RSTAT); | ||
1223 | if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK)) | ||
1224 | return 0; | ||
1225 | msleep(100); | ||
1226 | } | ||
1227 | |||
1228 | hw_dbg(hw, "Global reset failed.\n"); | ||
1229 | hw_dbg(hw, "I40E_GLGEN_RSTAT = 0x%x\n", reg); | ||
1230 | |||
1231 | return I40E_ERR_RESET_FAILED; | ||
1232 | } | ||
1233 | |||
1211 | #define I40E_PF_RESET_WAIT_COUNT_A0 200 | 1234 | #define I40E_PF_RESET_WAIT_COUNT_A0 200 |
1212 | #define I40E_PF_RESET_WAIT_COUNT 200 | 1235 | #define I40E_PF_RESET_WAIT_COUNT 200 |
1213 | /** | 1236 | /** |
@@ -1284,14 +1307,14 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw) | |||
1284 | if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK)) | 1307 | if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK)) |
1285 | break; | 1308 | break; |
1286 | reg2 = rd32(hw, I40E_GLGEN_RSTAT); | 1309 | reg2 = rd32(hw, I40E_GLGEN_RSTAT); |
1287 | if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) { | 1310 | if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) |
1288 | hw_dbg(hw, "Core reset upcoming. Skipping PF reset request.\n"); | 1311 | break; |
1289 | hw_dbg(hw, "I40E_GLGEN_RSTAT = 0x%x\n", reg2); | ||
1290 | return I40E_ERR_NOT_READY; | ||
1291 | } | ||
1292 | usleep_range(1000, 2000); | 1312 | usleep_range(1000, 2000); |
1293 | } | 1313 | } |
1294 | if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) { | 1314 | if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) { |
1315 | if (i40e_poll_globr(hw, grst_del)) | ||
1316 | return I40E_ERR_RESET_FAILED; | ||
1317 | } else if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) { | ||
1295 | hw_dbg(hw, "PF reset polling failed to complete.\n"); | 1318 | hw_dbg(hw, "PF reset polling failed to complete.\n"); |
1296 | return I40E_ERR_RESET_FAILED; | 1319 | return I40E_ERR_RESET_FAILED; |
1297 | } | 1320 | } |
@@ -2415,6 +2438,7 @@ i40e_status i40e_aq_get_switch_config(struct i40e_hw *hw, | |||
2415 | * i40e_aq_set_switch_config | 2438 | * i40e_aq_set_switch_config |
2416 | * @hw: pointer to the hardware structure | 2439 | * @hw: pointer to the hardware structure |
2417 | * @flags: bit flag values to set | 2440 | * @flags: bit flag values to set |
2441 | * @mode: cloud filter mode | ||
2418 | * @valid_flags: which bit flags to set | 2442 | * @valid_flags: which bit flags to set |
2419 | * @mode: cloud filter mode | 2443 | * @mode: cloud filter mode |
2420 | * @cmd_details: pointer to command details structure or NULL | 2444 | * @cmd_details: pointer to command details structure or NULL |
@@ -5552,7 +5576,7 @@ i40e_aq_add_cloud_filters(struct i40e_hw *hw, u16 seid, | |||
5552 | * function. | 5576 | * function. |
5553 | * | 5577 | * |
5554 | **/ | 5578 | **/ |
5555 | i40e_status | 5579 | enum i40e_status_code |
5556 | i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid, | 5580 | i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid, |
5557 | struct i40e_aqc_cloud_filters_element_bb *filters, | 5581 | struct i40e_aqc_cloud_filters_element_bb *filters, |
5558 | u8 filter_count) | 5582 | u8 filter_count) |
@@ -5646,7 +5670,7 @@ i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 seid, | |||
5646 | * function. | 5670 | * function. |
5647 | * | 5671 | * |
5648 | **/ | 5672 | **/ |
5649 | i40e_status | 5673 | enum i40e_status_code |
5650 | i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid, | 5674 | i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid, |
5651 | struct i40e_aqc_cloud_filters_element_bb *filters, | 5675 | struct i40e_aqc_cloud_filters_element_bb *filters, |
5652 | u8 filter_count) | 5676 | u8 filter_count) |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c index 89807e32a898..0c7e7de595d3 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c | |||
@@ -859,7 +859,9 @@ static int i40e_set_link_ksettings(struct net_device *netdev, | |||
859 | if (hw->device_id == I40E_DEV_ID_KX_B || | 859 | if (hw->device_id == I40E_DEV_ID_KX_B || |
860 | hw->device_id == I40E_DEV_ID_KX_C || | 860 | hw->device_id == I40E_DEV_ID_KX_C || |
861 | hw->device_id == I40E_DEV_ID_20G_KR2 || | 861 | hw->device_id == I40E_DEV_ID_20G_KR2 || |
862 | hw->device_id == I40E_DEV_ID_20G_KR2_A) { | 862 | hw->device_id == I40E_DEV_ID_20G_KR2_A || |
863 | hw->device_id == I40E_DEV_ID_25G_B || | ||
864 | hw->device_id == I40E_DEV_ID_KX_X722) { | ||
863 | netdev_info(netdev, "Changing settings is not supported on backplane.\n"); | 865 | netdev_info(netdev, "Changing settings is not supported on backplane.\n"); |
864 | return -EOPNOTSUPP; | 866 | return -EOPNOTSUPP; |
865 | } | 867 | } |
@@ -870,23 +872,21 @@ static int i40e_set_link_ksettings(struct net_device *netdev, | |||
870 | /* save autoneg out of ksettings */ | 872 | /* save autoneg out of ksettings */ |
871 | autoneg = copy_ks.base.autoneg; | 873 | autoneg = copy_ks.base.autoneg; |
872 | 874 | ||
873 | memset(&safe_ks, 0, sizeof(safe_ks)); | 875 | /* get our own copy of the bits to check against */ |
876 | memset(&safe_ks, 0, sizeof(struct ethtool_link_ksettings)); | ||
877 | safe_ks.base.cmd = copy_ks.base.cmd; | ||
878 | safe_ks.base.link_mode_masks_nwords = | ||
879 | copy_ks.base.link_mode_masks_nwords; | ||
880 | i40e_get_link_ksettings(netdev, &safe_ks); | ||
881 | |||
874 | /* Get link modes supported by hardware and check against modes | 882 | /* Get link modes supported by hardware and check against modes |
875 | * requested by the user. Return an error if unsupported mode was set. | 883 | * requested by the user. Return an error if unsupported mode was set. |
876 | */ | 884 | */ |
877 | i40e_phy_type_to_ethtool(pf, &safe_ks); | ||
878 | if (!bitmap_subset(copy_ks.link_modes.advertising, | 885 | if (!bitmap_subset(copy_ks.link_modes.advertising, |
879 | safe_ks.link_modes.supported, | 886 | safe_ks.link_modes.supported, |
880 | __ETHTOOL_LINK_MODE_MASK_NBITS)) | 887 | __ETHTOOL_LINK_MODE_MASK_NBITS)) |
881 | return -EINVAL; | 888 | return -EINVAL; |
882 | 889 | ||
883 | /* get our own copy of the bits to check against */ | ||
884 | memset(&safe_ks, 0, sizeof(struct ethtool_link_ksettings)); | ||
885 | safe_ks.base.cmd = copy_ks.base.cmd; | ||
886 | safe_ks.base.link_mode_masks_nwords = | ||
887 | copy_ks.base.link_mode_masks_nwords; | ||
888 | i40e_get_link_ksettings(netdev, &safe_ks); | ||
889 | |||
890 | /* set autoneg back to what it currently is */ | 890 | /* set autoneg back to what it currently is */ |
891 | copy_ks.base.autoneg = safe_ks.base.autoneg; | 891 | copy_ks.base.autoneg = safe_ks.base.autoneg; |
892 | 892 | ||
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index b78c06a1f82c..4a4401c61089 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c | |||
@@ -10594,6 +10594,9 @@ static int i40e_restore_interrupt_scheme(struct i40e_pf *pf) | |||
10594 | if (err) | 10594 | if (err) |
10595 | goto err_unwind; | 10595 | goto err_unwind; |
10596 | 10596 | ||
10597 | if (pf->flags & I40E_FLAG_IWARP_ENABLED) | ||
10598 | i40e_client_update_msix_info(pf); | ||
10599 | |||
10597 | return 0; | 10600 | return 0; |
10598 | 10601 | ||
10599 | err_unwind: | 10602 | err_unwind: |
@@ -14344,6 +14347,11 @@ static int __maybe_unused i40e_suspend(struct device *dev) | |||
14344 | del_timer_sync(&pf->service_timer); | 14347 | del_timer_sync(&pf->service_timer); |
14345 | cancel_work_sync(&pf->service_task); | 14348 | cancel_work_sync(&pf->service_task); |
14346 | 14349 | ||
14350 | /* Client close must be called explicitly here because the timer | ||
14351 | * has been stopped. | ||
14352 | */ | ||
14353 | i40e_notify_client_of_netdev_close(pf->vsi[pf->lan_vsi], false); | ||
14354 | |||
14347 | if (pf->wol_en && (pf->hw_features & I40E_HW_WOL_MC_MAGIC_PKT_WAKE)) | 14355 | if (pf->wol_en && (pf->hw_features & I40E_HW_WOL_MC_MAGIC_PKT_WAKE)) |
14348 | i40e_enable_mc_magic_wake(pf); | 14356 | i40e_enable_mc_magic_wake(pf); |
14349 | 14357 | ||
diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h index 83798b7841b9..eabb636f6a19 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h +++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h | |||
@@ -287,7 +287,7 @@ i40e_status i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw, | |||
287 | struct i40e_asq_cmd_details *cmd_details); | 287 | struct i40e_asq_cmd_details *cmd_details); |
288 | i40e_status i40e_aq_resume_port_tx(struct i40e_hw *hw, | 288 | i40e_status i40e_aq_resume_port_tx(struct i40e_hw *hw, |
289 | struct i40e_asq_cmd_details *cmd_details); | 289 | struct i40e_asq_cmd_details *cmd_details); |
290 | i40e_status | 290 | enum i40e_status_code |
291 | i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid, | 291 | i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid, |
292 | struct i40e_aqc_cloud_filters_element_bb *filters, | 292 | struct i40e_aqc_cloud_filters_element_bb *filters, |
293 | u8 filter_count); | 293 | u8 filter_count); |
@@ -299,7 +299,7 @@ enum i40e_status_code | |||
299 | i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 vsi, | 299 | i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 vsi, |
300 | struct i40e_aqc_cloud_filters_element_data *filters, | 300 | struct i40e_aqc_cloud_filters_element_data *filters, |
301 | u8 filter_count); | 301 | u8 filter_count); |
302 | i40e_status | 302 | enum i40e_status_code |
303 | i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid, | 303 | i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid, |
304 | struct i40e_aqc_cloud_filters_element_bb *filters, | 304 | struct i40e_aqc_cloud_filters_element_bb *filters, |
305 | u8 filter_count); | 305 | u8 filter_count); |
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf.h b/drivers/net/ethernet/intel/i40evf/i40evf.h index e46555ad7122..279dced87e47 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf.h +++ b/drivers/net/ethernet/intel/i40evf/i40evf.h | |||
@@ -280,13 +280,10 @@ struct i40evf_adapter { | |||
280 | 280 | ||
281 | u32 flags; | 281 | u32 flags; |
282 | #define I40EVF_FLAG_RX_CSUM_ENABLED BIT(0) | 282 | #define I40EVF_FLAG_RX_CSUM_ENABLED BIT(0) |
283 | #define I40EVF_FLAG_IMIR_ENABLED BIT(1) | ||
284 | #define I40EVF_FLAG_MQ_CAPABLE BIT(2) | ||
285 | #define I40EVF_FLAG_PF_COMMS_FAILED BIT(3) | 283 | #define I40EVF_FLAG_PF_COMMS_FAILED BIT(3) |
286 | #define I40EVF_FLAG_RESET_PENDING BIT(4) | 284 | #define I40EVF_FLAG_RESET_PENDING BIT(4) |
287 | #define I40EVF_FLAG_RESET_NEEDED BIT(5) | 285 | #define I40EVF_FLAG_RESET_NEEDED BIT(5) |
288 | #define I40EVF_FLAG_WB_ON_ITR_CAPABLE BIT(6) | 286 | #define I40EVF_FLAG_WB_ON_ITR_CAPABLE BIT(6) |
289 | #define I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE BIT(7) | ||
290 | #define I40EVF_FLAG_ADDR_SET_BY_PF BIT(8) | 287 | #define I40EVF_FLAG_ADDR_SET_BY_PF BIT(8) |
291 | #define I40EVF_FLAG_SERVICE_CLIENT_REQUESTED BIT(9) | 288 | #define I40EVF_FLAG_SERVICE_CLIENT_REQUESTED BIT(9) |
292 | #define I40EVF_FLAG_CLIENT_NEEDS_OPEN BIT(10) | 289 | #define I40EVF_FLAG_CLIENT_NEEDS_OPEN BIT(10) |
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c index 486cf491b000..7e7cd80abaf4 100644 --- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c +++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c | |||
@@ -2791,14 +2791,7 @@ static int i40evf_configure_clsflower(struct i40evf_adapter *adapter, | |||
2791 | { | 2791 | { |
2792 | int tc = tc_classid_to_hwtc(adapter->netdev, cls_flower->classid); | 2792 | int tc = tc_classid_to_hwtc(adapter->netdev, cls_flower->classid); |
2793 | struct i40evf_cloud_filter *filter = NULL; | 2793 | struct i40evf_cloud_filter *filter = NULL; |
2794 | int err = 0, count = 50; | 2794 | int err = -EINVAL, count = 50; |
2795 | |||
2796 | while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK, | ||
2797 | &adapter->crit_section)) { | ||
2798 | udelay(1); | ||
2799 | if (--count == 0) | ||
2800 | return -EINVAL; | ||
2801 | } | ||
2802 | 2795 | ||
2803 | if (tc < 0) { | 2796 | if (tc < 0) { |
2804 | dev_err(&adapter->pdev->dev, "Invalid traffic class\n"); | 2797 | dev_err(&adapter->pdev->dev, "Invalid traffic class\n"); |
@@ -2806,10 +2799,16 @@ static int i40evf_configure_clsflower(struct i40evf_adapter *adapter, | |||
2806 | } | 2799 | } |
2807 | 2800 | ||
2808 | filter = kzalloc(sizeof(*filter), GFP_KERNEL); | 2801 | filter = kzalloc(sizeof(*filter), GFP_KERNEL); |
2809 | if (!filter) { | 2802 | if (!filter) |
2810 | err = -ENOMEM; | 2803 | return -ENOMEM; |
2811 | goto clearout; | 2804 | |
2805 | while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK, | ||
2806 | &adapter->crit_section)) { | ||
2807 | if (--count == 0) | ||
2808 | goto err; | ||
2809 | udelay(1); | ||
2812 | } | 2810 | } |
2811 | |||
2813 | filter->cookie = cls_flower->cookie; | 2812 | filter->cookie = cls_flower->cookie; |
2814 | 2813 | ||
2815 | /* set the mask to all zeroes to begin with */ | 2814 | /* set the mask to all zeroes to begin with */ |
@@ -2834,7 +2833,7 @@ static int i40evf_configure_clsflower(struct i40evf_adapter *adapter, | |||
2834 | err: | 2833 | err: |
2835 | if (err) | 2834 | if (err) |
2836 | kfree(filter); | 2835 | kfree(filter); |
2837 | clearout: | 2836 | |
2838 | clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section); | 2837 | clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section); |
2839 | return err; | 2838 | return err; |
2840 | } | 2839 | } |