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

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates

This series contains updates to i40e only (again).

Jesse provides a fix for when tx_rings structure is NULL and we do not want
to panic. Then refactors the flow control set up and disables L2 flow control
by default.  Provides some trivial fixes as well as prevent compiler warnings.
Then to align to similar behaviour in ixgbe, use the total number of CPUs in
the system to suggest the number of transmit and receive queue pairs.

Shannon provides a i40e ethtool fix to get some more reasonable information
reports back out to the ethtool.  In addition, fixes PF reset after offline
test, where it reorders the test to put the register test last as it is the
only one that needs a reset, and we wait to trigger the reset until after we
clear the testing bit.  Lastly provides basic support for handling suspend
and resume for now, later on Wake-On-LAN support will be added.

Anjali provides changes to tell the stack about our actual number of queues
in order for RFS/RPS/XFS to work correctly.  Then provides several patches to
implement dynamically changing the queue count for the main VSI.  Adds
basic support for get/set channels for RSS so that the number of receive and
transmit queue pair can be changed via ethtool.  Cleans up the use of
rtnl_lock in the reset patch since it runs from a work time.

Neerav Parikh cleans up the VF interface to remove FCoE code as this
feature will not be supported on VF interfaces.

v2:
  - submitted patch 1 to net (since it was a fix needed for net), so dropped
    from this series (this patch will get added to net-next when Dave syncs
    his trees)
  - Dropped patches 4 & 11 from previous submission because of feedback
    received from Ben Hutchings and Sergei Shtylyov.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents bc4d0f61 6dbbbfb2
......@@ -133,6 +133,7 @@ enum i40e_state_t {
__I40E_GLOBAL_RESET_REQUESTED,
__I40E_EMP_RESET_REQUESTED,
__I40E_FILTER_OVERFLOW_PROMISC,
__I40E_SUSPENDED,
};
enum i40e_interrupt_policy {
......@@ -199,6 +200,7 @@ struct i40e_pf {
u16 num_tc_qps; /* num queue pairs per TC */
u16 num_lan_qps; /* num lan queues this pf has set up */
u16 num_lan_msix; /* num queue vectors for the base pf vsi */
int queues_left; /* queues left unclaimed */
u16 rss_size; /* num queues in the RSS array */
u16 rss_size_max; /* HW defined max RSS queues */
u16 fdir_pf_filter_count; /* num of guaranteed filters for this PF */
......@@ -501,6 +503,7 @@ int i40e_up(struct i40e_vsi *vsi);
void i40e_down(struct i40e_vsi *vsi);
extern const char i40e_driver_name[];
extern const char i40e_driver_version_str[];
void i40e_do_reset_safe(struct i40e_pf *pf, u32 reset_flags);
void i40e_do_reset(struct i40e_pf *pf, u32 reset_flags);
void i40e_update_stats(struct i40e_vsi *vsi);
void i40e_update_eth_stats(struct i40e_vsi *vsi);
......@@ -530,6 +533,7 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
int i40e_vsi_release(struct i40e_vsi *vsi);
struct i40e_vsi *i40e_vsi_lookup(struct i40e_pf *pf, enum i40e_vsi_type type,
struct i40e_vsi *start_vsi);
int i40e_reconfig_rss_queues(struct i40e_pf *pf, int queue_count);
struct i40e_veb *i40e_veb_setup(struct i40e_pf *pf, u16 flags, u16 uplink_seid,
u16 downlink_seid, u8 enabled_tc);
void i40e_veb_release(struct i40e_veb *veb);
......
......@@ -1462,19 +1462,19 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
}
} else if (strncmp(cmd_buf, "pfr", 3) == 0) {
dev_info(&pf->pdev->dev, "forcing PFR\n");
i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED));
i40e_do_reset_safe(pf, (1 << __I40E_PF_RESET_REQUESTED));
} else if (strncmp(cmd_buf, "corer", 5) == 0) {
dev_info(&pf->pdev->dev, "forcing CoreR\n");
i40e_do_reset(pf, (1 << __I40E_CORE_RESET_REQUESTED));
i40e_do_reset_safe(pf, (1 << __I40E_CORE_RESET_REQUESTED));
} else if (strncmp(cmd_buf, "globr", 5) == 0) {
dev_info(&pf->pdev->dev, "forcing GlobR\n");
i40e_do_reset(pf, (1 << __I40E_GLOBAL_RESET_REQUESTED));
i40e_do_reset_safe(pf, (1 << __I40E_GLOBAL_RESET_REQUESTED));
} else if (strncmp(cmd_buf, "empr", 4) == 0) {
dev_info(&pf->pdev->dev, "forcing EMPR\n");
i40e_do_reset(pf, (1 << __I40E_EMP_RESET_REQUESTED));
i40e_do_reset_safe(pf, (1 << __I40E_EMP_RESET_REQUESTED));
} else if (strncmp(cmd_buf, "read", 4) == 0) {
u32 address;
......
......@@ -119,7 +119,7 @@ i40e_status i40e_diag_eeprom_test(struct i40e_hw *hw)
/* read NVM control word and if NVM valid, validate EEPROM checksum*/
ret_code = i40e_read_nvm_word(hw, I40E_SR_NVM_CONTROL_WORD, &reg_val);
if ((!ret_code) &&
if (!ret_code &&
((reg_val & I40E_SR_CONTROL_WORD_1_MASK) ==
(0x01 << I40E_SR_CONTROL_WORD_1_SHIFT))) {
ret_code = i40e_validate_nvm_checksum(hw, NULL);
......
......@@ -193,32 +193,48 @@ static int i40e_get_settings(struct net_device *netdev,
ecmd->supported = SUPPORTED_10000baseKR_Full;
ecmd->advertising = ADVERTISED_10000baseKR_Full;
break;
case I40E_PHY_TYPE_10GBASE_T:
default:
if (i40e_is_40G_device(hw->device_id)) {
ecmd->supported = SUPPORTED_40000baseSR4_Full;
ecmd->advertising = ADVERTISED_40000baseSR4_Full;
} else {
ecmd->supported = SUPPORTED_10000baseT_Full;
ecmd->advertising = ADVERTISED_10000baseT_Full;
}
break;
}
/* for now just say autoneg all the time */
ecmd->supported |= SUPPORTED_Autoneg;
ecmd->advertising |= ADVERTISED_Autoneg;
ecmd->autoneg = ((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
AUTONEG_ENABLE : AUTONEG_DISABLE);
if (hw->phy.media_type == I40E_MEDIA_TYPE_BACKPLANE) {
switch (hw->phy.media_type) {
case I40E_MEDIA_TYPE_BACKPLANE:
ecmd->supported |= SUPPORTED_Backplane;
ecmd->advertising |= ADVERTISED_Backplane;
ecmd->port = PORT_NONE;
} else if (hw->phy.media_type == I40E_MEDIA_TYPE_BASET) {
break;
case I40E_MEDIA_TYPE_BASET:
ecmd->supported |= SUPPORTED_TP;
ecmd->advertising |= ADVERTISED_TP;
ecmd->port = PORT_TP;
} else if (hw->phy.media_type == I40E_MEDIA_TYPE_DA) {
break;
case I40E_MEDIA_TYPE_DA:
case I40E_MEDIA_TYPE_CX4:
ecmd->supported |= SUPPORTED_FIBRE;
ecmd->advertising |= ADVERTISED_FIBRE;
ecmd->port = PORT_DA;
} else {
break;
case I40E_MEDIA_TYPE_FIBER:
ecmd->supported |= SUPPORTED_FIBRE;
ecmd->advertising |= ADVERTISED_FIBRE;
ecmd->port = PORT_FIBRE;
break;
case I40E_MEDIA_TYPE_UNKNOWN:
default:
ecmd->port = PORT_OTHER;
break;
}
ecmd->transceiver = XCVR_EXTERNAL;
......@@ -260,12 +276,14 @@ static void i40e_get_pauseparam(struct net_device *netdev,
((hw_link_info->an_info & I40E_AQ_AN_COMPLETED) ?
AUTONEG_ENABLE : AUTONEG_DISABLE);
pause->rx_pause = 0;
pause->tx_pause = 0;
if (hw_link_info->an_info & I40E_AQ_LINK_PAUSE_RX)
if (hw->fc.current_mode == I40E_FC_RX_PAUSE) {
pause->rx_pause = 1;
} else if (hw->fc.current_mode == I40E_FC_TX_PAUSE) {
pause->tx_pause = 1;
} else if (hw->fc.current_mode == I40E_FC_FULL) {
pause->rx_pause = 1;
if (hw_link_info->an_info & I40E_AQ_LINK_PAUSE_TX)
pause->tx_pause = 1;
}
}
static u32 i40e_get_msglevel(struct net_device *netdev)
......@@ -732,7 +750,6 @@ static int i40e_reg_test(struct net_device *netdev, u64 *data)
netif_info(pf, hw, netdev, "register test\n");
*data = i40e_diag_reg_test(&pf->hw);
i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED));
return *data;
}
......@@ -780,20 +797,18 @@ static void i40e_diag_test(struct net_device *netdev,
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_pf *pf = np->vsi->back;
set_bit(__I40E_TESTING, &pf->state);
if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
/* Offline tests */
netif_info(pf, drv, netdev, "offline testing starting\n");
set_bit(__I40E_TESTING, &pf->state);
/* Link test performed before hardware reset
* so autoneg doesn't interfere with test result
*/
if (i40e_link_test(netdev, &data[I40E_ETH_TEST_LINK]))
eth_test->flags |= ETH_TEST_FL_FAILED;
if (i40e_reg_test(netdev, &data[I40E_ETH_TEST_REG]))
eth_test->flags |= ETH_TEST_FL_FAILED;
if (i40e_eeprom_test(netdev, &data[I40E_ETH_TEST_EEPROM]))
eth_test->flags |= ETH_TEST_FL_FAILED;
......@@ -803,6 +818,12 @@ static void i40e_diag_test(struct net_device *netdev,
if (i40e_loopback_test(netdev, &data[I40E_ETH_TEST_LOOPBACK]))
eth_test->flags |= ETH_TEST_FL_FAILED;
/* run reg test last, a reset is required after it */
if (i40e_reg_test(netdev, &data[I40E_ETH_TEST_REG]))
eth_test->flags |= ETH_TEST_FL_FAILED;
clear_bit(__I40E_TESTING, &pf->state);
i40e_do_reset(pf, (1 << __I40E_PF_RESET_REQUESTED));
} else {
/* Online tests */
netif_info(pf, drv, netdev, "online testing starting\n");
......@@ -816,7 +837,6 @@ static void i40e_diag_test(struct net_device *netdev,
data[I40E_ETH_TEST_INTR] = 0;
data[I40E_ETH_TEST_LOOPBACK] = 0;
}
clear_bit(__I40E_TESTING, &pf->state);
netif_info(pf, drv, netdev, "testing finished\n");
}
......@@ -1452,6 +1472,94 @@ static int i40e_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd)
return ret;
}
/**
* i40e_max_channels - get Max number of combined channels supported
* @vsi: vsi pointer
**/
static unsigned int i40e_max_channels(struct i40e_vsi *vsi)
{
/* TODO: This code assumes DCB and FD is disabled for now. */
return vsi->alloc_queue_pairs;
}
/**
* i40e_get_channels - Get the current channels enabled and max supported etc.
* @netdev: network interface device structure
* @ch: ethtool channels structure
*
* We don't support separate tx and rx queues as channels. The other count
* represents how many queues are being used for control. max_combined counts
* how many queue pairs we can support. They may not be mapped 1 to 1 with
* q_vectors since we support a lot more queue pairs than q_vectors.
**/
static void i40e_get_channels(struct net_device *dev,
struct ethtool_channels *ch)
{
struct i40e_netdev_priv *np = netdev_priv(dev);
struct i40e_vsi *vsi = np->vsi;
struct i40e_pf *pf = vsi->back;
/* report maximum channels */
ch->max_combined = i40e_max_channels(vsi);
/* report info for other vector */
ch->other_count = (pf->flags & I40E_FLAG_FDIR_ENABLED) ? 1 : 0;
ch->max_other = ch->other_count;
/* Note: This code assumes DCB is disabled for now. */
ch->combined_count = vsi->num_queue_pairs;
}
/**
* i40e_set_channels - Set the new channels count.
* @netdev: network interface device structure
* @ch: ethtool channels structure
*
* The new channels count may not be the same as requested by the user
* since it gets rounded down to a power of 2 value.
**/
static int i40e_set_channels(struct net_device *dev,
struct ethtool_channels *ch)
{
struct i40e_netdev_priv *np = netdev_priv(dev);
unsigned int count = ch->combined_count;
struct i40e_vsi *vsi = np->vsi;
struct i40e_pf *pf = vsi->back;
int new_count;
/* We do not support setting channels for any other VSI at present */
if (vsi->type != I40E_VSI_MAIN)
return -EINVAL;
/* verify they are not requesting separate vectors */
if (!count || ch->rx_count || ch->tx_count)
return -EINVAL;
/* verify other_count has not changed */
if (ch->other_count != ((pf->flags & I40E_FLAG_FDIR_ENABLED) ? 1 : 0))
return -EINVAL;
/* verify the number of channels does not exceed hardware limits */
if (count > i40e_max_channels(vsi))
return -EINVAL;
/* update feature limits from largest to smallest supported values */
/* TODO: Flow director limit, DCB etc */
/* cap RSS limit */
if (count > pf->rss_size_max)
count = pf->rss_size_max;
/* use rss_reconfig to rebuild with new queue count and update traffic
* class queue mapping
*/
new_count = i40e_reconfig_rss_queues(pf, count);
if (new_count > 1)
return 0;
else
return -EINVAL;
}
static const struct ethtool_ops i40e_ethtool_ops = {
.get_settings = i40e_get_settings,
.get_drvinfo = i40e_get_drvinfo,
......@@ -1476,6 +1584,8 @@ static const struct ethtool_ops i40e_ethtool_ops = {
.get_ethtool_stats = i40e_get_ethtool_stats,
.get_coalesce = i40e_get_coalesce,
.set_coalesce = i40e_set_coalesce,
.get_channels = i40e_get_channels,
.set_channels = i40e_set_channels,
.get_ts_info = i40e_get_ts_info,
};
......
......@@ -47,10 +47,10 @@ i40e_status i40e_add_sd_table_entry(struct i40e_hw *hw,
u64 direct_mode_sz)
{
enum i40e_memory_type mem_type __attribute__((unused));
i40e_status ret_code = 0;
struct i40e_hmc_sd_entry *sd_entry;
bool dma_mem_alloc_done = false;
struct i40e_dma_mem mem;
i40e_status ret_code;
u64 alloc_len;
if (NULL == hmc_info->sd_table.sd_entry) {
......
This diff is collapsed.
......@@ -49,6 +49,10 @@
#define I40E_VF_DEVICE_ID 0x154C
#define I40E_VF_HV_DEVICE_ID 0x1571
#define i40e_is_40G_device(d) ((d) == I40E_QSFP_A_DEVICE_ID || \
(d) == I40E_QSFP_B_DEVICE_ID || \
(d) == I40E_QSFP_C_DEVICE_ID)
#define I40E_FW_API_VERSION_MAJOR 0x0001
#define I40E_FW_API_VERSION_MINOR 0x0000
......
......@@ -521,6 +521,7 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
f = i40e_add_filter(vsi, vf->default_lan_addr.addr,
0, true, false);
}
if (!f) {
dev_err(&pf->pdev->dev, "Unable to add ucast filter\n");
ret = -ENOMEM;
......@@ -763,6 +764,7 @@ static void i40e_free_vf_res(struct i40e_vf *vf)
vf->lan_vsi_index = 0;
vf->lan_vsi_id = 0;
}
/* reset some of the state varibles keeping
* track of the resources
*/
......@@ -1776,30 +1778,6 @@ static int i40e_vc_remove_vlan_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
return i40e_vc_send_resp_to_vf(vf, I40E_VIRTCHNL_OP_DEL_VLAN, aq_ret);
}
/**
* i40e_vc_fcoe_msg
* @vf: pointer to the vf info
* @msg: pointer to the msg buffer
* @msglen: msg length
*
* called from the vf for the fcoe msgs
**/
static int i40e_vc_fcoe_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
{
i40e_status aq_ret = 0;
if (!test_bit(I40E_VF_STAT_ACTIVE, &vf->vf_states) ||
!test_bit(I40E_VF_STAT_FCOEENA, &vf->vf_states)) {
aq_ret = I40E_ERR_PARAM;
goto error_param;
}
aq_ret = I40E_ERR_NOT_IMPLEMENTED;
error_param:
/* send the response to the vf */
return i40e_vc_send_resp_to_vf(vf, I40E_VIRTCHNL_OP_FCOE, aq_ret);
}
/**
* i40e_vc_validate_vf_msg
* @vf: pointer to the vf info
......@@ -1973,9 +1951,6 @@ int i40e_vc_process_vf_msg(struct i40e_pf *pf, u16 vf_id, u32 v_opcode,
case I40E_VIRTCHNL_OP_GET_STATS:
ret = i40e_vc_get_stats_msg(vf, msg, msglen);
break;
case I40E_VIRTCHNL_OP_FCOE:
ret = i40e_vc_fcoe_msg(vf, msg, msglen);
break;
case I40E_VIRTCHNL_OP_UNKNOWN:
default:
dev_err(&pf->pdev->dev,
......
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