Commit c314c7ba authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents e3c72f3d 12d80bca
...@@ -1041,6 +1041,7 @@ void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi); ...@@ -1041,6 +1041,7 @@ void i40e_notify_client_of_l2_param_changes(struct i40e_vsi *vsi);
void i40e_notify_client_of_netdev_close(struct i40e_vsi *vsi, bool reset); void i40e_notify_client_of_netdev_close(struct i40e_vsi *vsi, bool reset);
void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs); void i40e_notify_client_of_vf_enable(struct i40e_pf *pf, u32 num_vfs);
void i40e_notify_client_of_vf_reset(struct i40e_pf *pf, u32 vf_id); void i40e_notify_client_of_vf_reset(struct i40e_pf *pf, u32 vf_id);
void i40e_client_update_msix_info(struct i40e_pf *pf);
int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id); int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id);
/** /**
* i40e_irq_dynamic_enable - Enable default interrupt generation settings * i40e_irq_dynamic_enable - Enable default interrupt generation settings
......
...@@ -287,6 +287,17 @@ int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id) ...@@ -287,6 +287,17 @@ int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id)
return capable; return capable;
} }
void i40e_client_update_msix_info(struct i40e_pf *pf)
{
struct i40e_client_instance *cdev = pf->cinst;
if (!cdev || !cdev->client)
return;
cdev->lan_info.msix_count = pf->num_iwarp_msix;
cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector];
}
/** /**
* i40e_client_add_instance - add a client instance struct to the instance list * i40e_client_add_instance - add a client instance struct to the instance list
* @pf: pointer to the board struct * @pf: pointer to the board struct
...@@ -328,9 +339,6 @@ static void i40e_client_add_instance(struct i40e_pf *pf) ...@@ -328,9 +339,6 @@ static void i40e_client_add_instance(struct i40e_pf *pf)
return; return;
} }
cdev->lan_info.msix_count = pf->num_iwarp_msix;
cdev->lan_info.msix_entries = &pf->msix_entries[pf->iwarp_base_vector];
mac = list_first_entry(&cdev->lan_info.netdev->dev_addrs.list, mac = list_first_entry(&cdev->lan_info.netdev->dev_addrs.list,
struct netdev_hw_addr, list); struct netdev_hw_addr, list);
if (mac) if (mac)
...@@ -340,6 +348,8 @@ static void i40e_client_add_instance(struct i40e_pf *pf) ...@@ -340,6 +348,8 @@ static void i40e_client_add_instance(struct i40e_pf *pf)
cdev->client = registered_client; cdev->client = registered_client;
pf->cinst = cdev; pf->cinst = cdev;
i40e_client_update_msix_info(pf);
} }
/** /**
......
...@@ -1208,6 +1208,29 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw) ...@@ -1208,6 +1208,29 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
return media; return media;
} }
/**
* i40e_poll_globr - Poll for Global Reset completion
* @hw: pointer to the hardware structure
* @retry_limit: how many times to retry before failure
**/
static i40e_status i40e_poll_globr(struct i40e_hw *hw,
u32 retry_limit)
{
u32 cnt, reg = 0;
for (cnt = 0; cnt < retry_limit; cnt++) {
reg = rd32(hw, I40E_GLGEN_RSTAT);
if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK))
return 0;
msleep(100);
}
hw_dbg(hw, "Global reset failed.\n");
hw_dbg(hw, "I40E_GLGEN_RSTAT = 0x%x\n", reg);
return I40E_ERR_RESET_FAILED;
}
#define I40E_PF_RESET_WAIT_COUNT_A0 200 #define I40E_PF_RESET_WAIT_COUNT_A0 200
#define I40E_PF_RESET_WAIT_COUNT 200 #define I40E_PF_RESET_WAIT_COUNT 200
/** /**
...@@ -1284,14 +1307,14 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw) ...@@ -1284,14 +1307,14 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw)
if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK)) if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK))
break; break;
reg2 = rd32(hw, I40E_GLGEN_RSTAT); reg2 = rd32(hw, I40E_GLGEN_RSTAT);
if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) { if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK)
hw_dbg(hw, "Core reset upcoming. Skipping PF reset request.\n"); break;
hw_dbg(hw, "I40E_GLGEN_RSTAT = 0x%x\n", reg2);
return I40E_ERR_NOT_READY;
}
usleep_range(1000, 2000); usleep_range(1000, 2000);
} }
if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) { if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) {
if (i40e_poll_globr(hw, grst_del))
return I40E_ERR_RESET_FAILED;
} else if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) {
hw_dbg(hw, "PF reset polling failed to complete.\n"); hw_dbg(hw, "PF reset polling failed to complete.\n");
return I40E_ERR_RESET_FAILED; return I40E_ERR_RESET_FAILED;
} }
...@@ -2415,6 +2438,7 @@ i40e_status i40e_aq_get_switch_config(struct i40e_hw *hw, ...@@ -2415,6 +2438,7 @@ i40e_status i40e_aq_get_switch_config(struct i40e_hw *hw,
* i40e_aq_set_switch_config * i40e_aq_set_switch_config
* @hw: pointer to the hardware structure * @hw: pointer to the hardware structure
* @flags: bit flag values to set * @flags: bit flag values to set
* @mode: cloud filter mode
* @valid_flags: which bit flags to set * @valid_flags: which bit flags to set
* @mode: cloud filter mode * @mode: cloud filter mode
* @cmd_details: pointer to command details structure or NULL * @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,7 +5576,7 @@ i40e_aq_add_cloud_filters(struct i40e_hw *hw, u16 seid,
* function. * function.
* *
**/ **/
i40e_status enum i40e_status_code
i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid, i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
struct i40e_aqc_cloud_filters_element_bb *filters, struct i40e_aqc_cloud_filters_element_bb *filters,
u8 filter_count) u8 filter_count)
...@@ -5646,7 +5670,7 @@ i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 seid, ...@@ -5646,7 +5670,7 @@ i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 seid,
* function. * function.
* *
**/ **/
i40e_status enum i40e_status_code
i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid, i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
struct i40e_aqc_cloud_filters_element_bb *filters, struct i40e_aqc_cloud_filters_element_bb *filters,
u8 filter_count) u8 filter_count)
......
...@@ -859,7 +859,9 @@ static int i40e_set_link_ksettings(struct net_device *netdev, ...@@ -859,7 +859,9 @@ static int i40e_set_link_ksettings(struct net_device *netdev,
if (hw->device_id == I40E_DEV_ID_KX_B || if (hw->device_id == I40E_DEV_ID_KX_B ||
hw->device_id == I40E_DEV_ID_KX_C || hw->device_id == I40E_DEV_ID_KX_C ||
hw->device_id == I40E_DEV_ID_20G_KR2 || hw->device_id == I40E_DEV_ID_20G_KR2 ||
hw->device_id == I40E_DEV_ID_20G_KR2_A) { hw->device_id == I40E_DEV_ID_20G_KR2_A ||
hw->device_id == I40E_DEV_ID_25G_B ||
hw->device_id == I40E_DEV_ID_KX_X722) {
netdev_info(netdev, "Changing settings is not supported on backplane.\n"); netdev_info(netdev, "Changing settings is not supported on backplane.\n");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
...@@ -870,23 +872,21 @@ static int i40e_set_link_ksettings(struct net_device *netdev, ...@@ -870,23 +872,21 @@ static int i40e_set_link_ksettings(struct net_device *netdev,
/* save autoneg out of ksettings */ /* save autoneg out of ksettings */
autoneg = copy_ks.base.autoneg; autoneg = copy_ks.base.autoneg;
memset(&safe_ks, 0, sizeof(safe_ks)); /* get our own copy of the bits to check against */
memset(&safe_ks, 0, sizeof(struct ethtool_link_ksettings));
safe_ks.base.cmd = copy_ks.base.cmd;
safe_ks.base.link_mode_masks_nwords =
copy_ks.base.link_mode_masks_nwords;
i40e_get_link_ksettings(netdev, &safe_ks);
/* Get link modes supported by hardware and check against modes /* Get link modes supported by hardware and check against modes
* requested by the user. Return an error if unsupported mode was set. * requested by the user. Return an error if unsupported mode was set.
*/ */
i40e_phy_type_to_ethtool(pf, &safe_ks);
if (!bitmap_subset(copy_ks.link_modes.advertising, if (!bitmap_subset(copy_ks.link_modes.advertising,
safe_ks.link_modes.supported, safe_ks.link_modes.supported,
__ETHTOOL_LINK_MODE_MASK_NBITS)) __ETHTOOL_LINK_MODE_MASK_NBITS))
return -EINVAL; return -EINVAL;
/* get our own copy of the bits to check against */
memset(&safe_ks, 0, sizeof(struct ethtool_link_ksettings));
safe_ks.base.cmd = copy_ks.base.cmd;
safe_ks.base.link_mode_masks_nwords =
copy_ks.base.link_mode_masks_nwords;
i40e_get_link_ksettings(netdev, &safe_ks);
/* set autoneg back to what it currently is */ /* set autoneg back to what it currently is */
copy_ks.base.autoneg = safe_ks.base.autoneg; copy_ks.base.autoneg = safe_ks.base.autoneg;
......
...@@ -10594,6 +10594,9 @@ static int i40e_restore_interrupt_scheme(struct i40e_pf *pf) ...@@ -10594,6 +10594,9 @@ static int i40e_restore_interrupt_scheme(struct i40e_pf *pf)
if (err) if (err)
goto err_unwind; goto err_unwind;
if (pf->flags & I40E_FLAG_IWARP_ENABLED)
i40e_client_update_msix_info(pf);
return 0; return 0;
err_unwind: err_unwind:
...@@ -14344,6 +14347,11 @@ static int __maybe_unused i40e_suspend(struct device *dev) ...@@ -14344,6 +14347,11 @@ static int __maybe_unused i40e_suspend(struct device *dev)
del_timer_sync(&pf->service_timer); del_timer_sync(&pf->service_timer);
cancel_work_sync(&pf->service_task); cancel_work_sync(&pf->service_task);
/* Client close must be called explicitly here because the timer
* has been stopped.
*/
i40e_notify_client_of_netdev_close(pf->vsi[pf->lan_vsi], false);
if (pf->wol_en && (pf->hw_features & I40E_HW_WOL_MC_MAGIC_PKT_WAKE)) if (pf->wol_en && (pf->hw_features & I40E_HW_WOL_MC_MAGIC_PKT_WAKE))
i40e_enable_mc_magic_wake(pf); i40e_enable_mc_magic_wake(pf);
......
...@@ -287,7 +287,7 @@ i40e_status i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw, ...@@ -287,7 +287,7 @@ i40e_status i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
struct i40e_asq_cmd_details *cmd_details); struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_resume_port_tx(struct i40e_hw *hw, i40e_status i40e_aq_resume_port_tx(struct i40e_hw *hw,
struct i40e_asq_cmd_details *cmd_details); struct i40e_asq_cmd_details *cmd_details);
i40e_status enum i40e_status_code
i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid, i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
struct i40e_aqc_cloud_filters_element_bb *filters, struct i40e_aqc_cloud_filters_element_bb *filters,
u8 filter_count); u8 filter_count);
...@@ -299,7 +299,7 @@ enum i40e_status_code ...@@ -299,7 +299,7 @@ enum i40e_status_code
i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 vsi, i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 vsi,
struct i40e_aqc_cloud_filters_element_data *filters, struct i40e_aqc_cloud_filters_element_data *filters,
u8 filter_count); u8 filter_count);
i40e_status enum i40e_status_code
i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid, i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
struct i40e_aqc_cloud_filters_element_bb *filters, struct i40e_aqc_cloud_filters_element_bb *filters,
u8 filter_count); u8 filter_count);
......
...@@ -280,13 +280,10 @@ struct i40evf_adapter { ...@@ -280,13 +280,10 @@ struct i40evf_adapter {
u32 flags; u32 flags;
#define I40EVF_FLAG_RX_CSUM_ENABLED BIT(0) #define I40EVF_FLAG_RX_CSUM_ENABLED BIT(0)
#define I40EVF_FLAG_IMIR_ENABLED BIT(1)
#define I40EVF_FLAG_MQ_CAPABLE BIT(2)
#define I40EVF_FLAG_PF_COMMS_FAILED BIT(3) #define I40EVF_FLAG_PF_COMMS_FAILED BIT(3)
#define I40EVF_FLAG_RESET_PENDING BIT(4) #define I40EVF_FLAG_RESET_PENDING BIT(4)
#define I40EVF_FLAG_RESET_NEEDED BIT(5) #define I40EVF_FLAG_RESET_NEEDED BIT(5)
#define I40EVF_FLAG_WB_ON_ITR_CAPABLE BIT(6) #define I40EVF_FLAG_WB_ON_ITR_CAPABLE BIT(6)
#define I40EVF_FLAG_OUTER_UDP_CSUM_CAPABLE BIT(7)
#define I40EVF_FLAG_ADDR_SET_BY_PF BIT(8) #define I40EVF_FLAG_ADDR_SET_BY_PF BIT(8)
#define I40EVF_FLAG_SERVICE_CLIENT_REQUESTED BIT(9) #define I40EVF_FLAG_SERVICE_CLIENT_REQUESTED BIT(9)
#define I40EVF_FLAG_CLIENT_NEEDS_OPEN BIT(10) #define I40EVF_FLAG_CLIENT_NEEDS_OPEN BIT(10)
......
...@@ -2791,14 +2791,7 @@ static int i40evf_configure_clsflower(struct i40evf_adapter *adapter, ...@@ -2791,14 +2791,7 @@ static int i40evf_configure_clsflower(struct i40evf_adapter *adapter,
{ {
int tc = tc_classid_to_hwtc(adapter->netdev, cls_flower->classid); int tc = tc_classid_to_hwtc(adapter->netdev, cls_flower->classid);
struct i40evf_cloud_filter *filter = NULL; struct i40evf_cloud_filter *filter = NULL;
int err = 0, count = 50; int err = -EINVAL, count = 50;
while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
&adapter->crit_section)) {
udelay(1);
if (--count == 0)
return -EINVAL;
}
if (tc < 0) { if (tc < 0) {
dev_err(&adapter->pdev->dev, "Invalid traffic class\n"); dev_err(&adapter->pdev->dev, "Invalid traffic class\n");
...@@ -2806,10 +2799,16 @@ static int i40evf_configure_clsflower(struct i40evf_adapter *adapter, ...@@ -2806,10 +2799,16 @@ static int i40evf_configure_clsflower(struct i40evf_adapter *adapter,
} }
filter = kzalloc(sizeof(*filter), GFP_KERNEL); filter = kzalloc(sizeof(*filter), GFP_KERNEL);
if (!filter) { if (!filter)
err = -ENOMEM; return -ENOMEM;
goto clearout;
while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
&adapter->crit_section)) {
if (--count == 0)
goto err;
udelay(1);
} }
filter->cookie = cls_flower->cookie; filter->cookie = cls_flower->cookie;
/* set the mask to all zeroes to begin with */ /* set the mask to all zeroes to begin with */
...@@ -2834,7 +2833,7 @@ static int i40evf_configure_clsflower(struct i40evf_adapter *adapter, ...@@ -2834,7 +2833,7 @@ static int i40evf_configure_clsflower(struct i40evf_adapter *adapter,
err: err:
if (err) if (err)
kfree(filter); kfree(filter);
clearout:
clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section); clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment