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>
This commit is contained in:
commit
c314c7ba40
|
@ -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_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_client_update_msix_info(struct i40e_pf *pf);
|
||||
int i40e_vf_client_capable(struct i40e_pf *pf, u32 vf_id);
|
||||
/**
|
||||
* 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)
|
|||
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
|
||||
* @pf: pointer to the board struct
|
||||
|
@ -328,9 +339,6 @@ static void i40e_client_add_instance(struct i40e_pf *pf)
|
|||
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,
|
||||
struct netdev_hw_addr, list);
|
||||
if (mac)
|
||||
|
@ -340,6 +348,8 @@ static void i40e_client_add_instance(struct i40e_pf *pf)
|
|||
|
||||
cdev->client = registered_client;
|
||||
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)
|
|||
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 200
|
||||
/**
|
||||
|
@ -1284,14 +1307,14 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw)
|
|||
if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK))
|
||||
break;
|
||||
reg2 = rd32(hw, I40E_GLGEN_RSTAT);
|
||||
if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) {
|
||||
hw_dbg(hw, "Core reset upcoming. Skipping PF reset request.\n");
|
||||
hw_dbg(hw, "I40E_GLGEN_RSTAT = 0x%x\n", reg2);
|
||||
return I40E_ERR_NOT_READY;
|
||||
}
|
||||
if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK)
|
||||
break;
|
||||
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");
|
||||
return I40E_ERR_RESET_FAILED;
|
||||
}
|
||||
|
@ -2415,6 +2438,7 @@ i40e_status i40e_aq_get_switch_config(struct i40e_hw *hw,
|
|||
* i40e_aq_set_switch_config
|
||||
* @hw: pointer to the hardware structure
|
||||
* @flags: bit flag values to set
|
||||
* @mode: cloud filter mode
|
||||
* @valid_flags: which bit flags to set
|
||||
* @mode: cloud filter mode
|
||||
* @cmd_details: pointer to command details structure or NULL
|
||||
|
@ -5552,7 +5576,7 @@ i40e_aq_add_cloud_filters(struct i40e_hw *hw, u16 seid,
|
|||
* function.
|
||||
*
|
||||
**/
|
||||
i40e_status
|
||||
enum i40e_status_code
|
||||
i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
|
||||
struct i40e_aqc_cloud_filters_element_bb *filters,
|
||||
u8 filter_count)
|
||||
|
@ -5646,7 +5670,7 @@ i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 seid,
|
|||
* function.
|
||||
*
|
||||
**/
|
||||
i40e_status
|
||||
enum i40e_status_code
|
||||
i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
|
||||
struct i40e_aqc_cloud_filters_element_bb *filters,
|
||||
u8 filter_count)
|
||||
|
|
|
@ -859,7 +859,9 @@ static int i40e_set_link_ksettings(struct net_device *netdev,
|
|||
if (hw->device_id == I40E_DEV_ID_KX_B ||
|
||||
hw->device_id == I40E_DEV_ID_KX_C ||
|
||||
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");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
@ -870,16 +872,6 @@ static int i40e_set_link_ksettings(struct net_device *netdev,
|
|||
/* save autoneg out of ksettings */
|
||||
autoneg = copy_ks.base.autoneg;
|
||||
|
||||
memset(&safe_ks, 0, sizeof(safe_ks));
|
||||
/* Get link modes supported by hardware and check against modes
|
||||
* 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,
|
||||
safe_ks.link_modes.supported,
|
||||
__ETHTOOL_LINK_MODE_MASK_NBITS))
|
||||
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;
|
||||
|
@ -887,6 +879,14 @@ static int i40e_set_link_ksettings(struct net_device *netdev,
|
|||
copy_ks.base.link_mode_masks_nwords;
|
||||
i40e_get_link_ksettings(netdev, &safe_ks);
|
||||
|
||||
/* Get link modes supported by hardware and check against modes
|
||||
* requested by the user. Return an error if unsupported mode was set.
|
||||
*/
|
||||
if (!bitmap_subset(copy_ks.link_modes.advertising,
|
||||
safe_ks.link_modes.supported,
|
||||
__ETHTOOL_LINK_MODE_MASK_NBITS))
|
||||
return -EINVAL;
|
||||
|
||||
/* set autoneg back to what it currently is */
|
||||
copy_ks.base.autoneg = safe_ks.base.autoneg;
|
||||
|
||||
|
|
|
@ -10594,6 +10594,9 @@ static int i40e_restore_interrupt_scheme(struct i40e_pf *pf)
|
|||
if (err)
|
||||
goto err_unwind;
|
||||
|
||||
if (pf->flags & I40E_FLAG_IWARP_ENABLED)
|
||||
i40e_client_update_msix_info(pf);
|
||||
|
||||
return 0;
|
||||
|
||||
err_unwind:
|
||||
|
@ -14344,6 +14347,11 @@ static int __maybe_unused i40e_suspend(struct device *dev)
|
|||
del_timer_sync(&pf->service_timer);
|
||||
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))
|
||||
i40e_enable_mc_magic_wake(pf);
|
||||
|
||||
|
|
|
@ -287,7 +287,7 @@ i40e_status i40e_aq_query_switch_comp_bw_config(struct i40e_hw *hw,
|
|||
struct i40e_asq_cmd_details *cmd_details);
|
||||
i40e_status i40e_aq_resume_port_tx(struct i40e_hw *hw,
|
||||
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,
|
||||
struct i40e_aqc_cloud_filters_element_bb *filters,
|
||||
u8 filter_count);
|
||||
|
@ -299,7 +299,7 @@ enum i40e_status_code
|
|||
i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 vsi,
|
||||
struct i40e_aqc_cloud_filters_element_data *filters,
|
||||
u8 filter_count);
|
||||
i40e_status
|
||||
enum i40e_status_code
|
||||
i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid,
|
||||
struct i40e_aqc_cloud_filters_element_bb *filters,
|
||||
u8 filter_count);
|
||||
|
|
|
@ -280,13 +280,10 @@ struct i40evf_adapter {
|
|||
|
||||
u32 flags;
|
||||
#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_RESET_PENDING BIT(4)
|
||||
#define I40EVF_FLAG_RESET_NEEDED BIT(5)
|
||||
#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_SERVICE_CLIENT_REQUESTED BIT(9)
|
||||
#define I40EVF_FLAG_CLIENT_NEEDS_OPEN BIT(10)
|
||||
|
|
|
@ -2791,14 +2791,7 @@ static int i40evf_configure_clsflower(struct i40evf_adapter *adapter,
|
|||
{
|
||||
int tc = tc_classid_to_hwtc(adapter->netdev, cls_flower->classid);
|
||||
struct i40evf_cloud_filter *filter = NULL;
|
||||
int err = 0, count = 50;
|
||||
|
||||
while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
|
||||
&adapter->crit_section)) {
|
||||
udelay(1);
|
||||
if (--count == 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
int err = -EINVAL, count = 50;
|
||||
|
||||
if (tc < 0) {
|
||||
dev_err(&adapter->pdev->dev, "Invalid traffic class\n");
|
||||
|
@ -2806,10 +2799,16 @@ static int i40evf_configure_clsflower(struct i40evf_adapter *adapter,
|
|||
}
|
||||
|
||||
filter = kzalloc(sizeof(*filter), GFP_KERNEL);
|
||||
if (!filter) {
|
||||
err = -ENOMEM;
|
||||
goto clearout;
|
||||
if (!filter)
|
||||
return -ENOMEM;
|
||||
|
||||
while (test_and_set_bit(__I40EVF_IN_CRITICAL_TASK,
|
||||
&adapter->crit_section)) {
|
||||
if (--count == 0)
|
||||
goto err;
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
filter->cookie = cls_flower->cookie;
|
||||
|
||||
/* set the mask to all zeroes to begin with */
|
||||
|
@ -2834,7 +2833,7 @@ static int i40evf_configure_clsflower(struct i40evf_adapter *adapter,
|
|||
err:
|
||||
if (err)
|
||||
kfree(filter);
|
||||
clearout:
|
||||
|
||||
clear_bit(__I40EVF_IN_CRITICAL_TASK, &adapter->crit_section);
|
||||
return err;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue