Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/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: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Dec 17, 2013
2 parents bc4d0f6 + 6dbbbfb commit e437931
Show file tree
Hide file tree
Showing 8 changed files with 469 additions and 90 deletions.
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions drivers/net/ethernet/intel/i40e/i40e_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/i40e/i40e_diag.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
146 changes: 128 additions & 18 deletions drivers/net/ethernet/intel/i40e/i40e_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
ecmd->supported = SUPPORTED_10000baseT_Full;
ecmd->advertising = ADVERTISED_10000baseT_Full;
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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;

Expand All @@ -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");
Expand All @@ -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");
}
Expand Down Expand Up @@ -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,
Expand All @@ -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,
};

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/i40e/i40e_hmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Loading

0 comments on commit e437931

Please sign in to comment.