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/next-queue

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates 2015-04-14

This series contains updates to i40e and i40evf.

Mitch provides a fix for i40e, where VFs were gone and the associated
VSI's had been removed and the rings were not stopped, which in some
circumstances cased memory corruption or DMAR errors.  So stop all the
rings associated with each VF before releasing its resources.  Also
cleaned up a poorly indented piece of code.  Fixes VF link state, where
VF devices were assuming link is up unless told otherwise, which means
that VFs instantiated on a PF with no link, would report the wrong state.

Anjali adds support to add Flow director Sideband rules for a VF from it's
PF.  Fixes a recently discovered hardware issue, where after a VFLR
hardware might be indicating to us a reset completion little too early, so
wait another 10 msec for cache to be cleaned up.

Jesse enables the user to dump the internal hardware state for better
debugging by allowing a bash script to acquire information about the
internal hardware state.  The data output to the kernel log is collected
by the script and can then be sent to Intel.  Also fixed a possible
failure path to allocate memory that was found by smatch.  Cleaned up
unused local variables.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Apr 15, 2015
2 parents 074975d + 2aea6dc commit 6b9107d
Show file tree
Hide file tree
Showing 13 changed files with 304 additions and 163 deletions.
65 changes: 65 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -2397,6 +2397,7 @@ i40e_status i40e_aq_erase_nvm(struct i40e_hw *hw, u8 module_pointer,
#define I40E_DEV_FUNC_CAP_LED 0x61
#define I40E_DEV_FUNC_CAP_SDP 0x62
#define I40E_DEV_FUNC_CAP_MDIO 0x63
#define I40E_DEV_FUNC_CAP_WR_CSR_PROT 0x64

/**
* i40e_parse_discover_capabilities
Expand Down Expand Up @@ -2541,11 +2542,18 @@ static void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
p->fd_filters_guaranteed = number;
p->fd_filters_best_effort = logical_id;
break;
case I40E_DEV_FUNC_CAP_WR_CSR_PROT:
p->wr_csr_prot = (u64)number;
p->wr_csr_prot |= (u64)logical_id << 32;
break;
default:
break;
}
}

if (p->fcoe)
i40e_debug(hw, I40E_DEBUG_ALL, "device is FCoE capable\n");

/* Software override ensuring FCoE is disabled if npar or mfp
* mode because it is not supported in these modes.
*/
Expand Down Expand Up @@ -3502,6 +3510,63 @@ void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status)
}
}

/**
* i40e_aq_debug_dump
* @hw: pointer to the hardware structure
* @cluster_id: specific cluster to dump
* @table_id: table id within cluster
* @start_index: index of line in the block to read
* @buff_size: dump buffer size
* @buff: dump buffer
* @ret_buff_size: actual buffer size returned
* @ret_next_table: next block to read
* @ret_next_index: next index to read
*
* Dump internal FW/HW data for debug purposes.
*
**/
i40e_status i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
u8 table_id, u32 start_index, u16 buff_size,
void *buff, u16 *ret_buff_size,
u8 *ret_next_table, u32 *ret_next_index,
struct i40e_asq_cmd_details *cmd_details)
{
struct i40e_aq_desc desc;
struct i40e_aqc_debug_dump_internals *cmd =
(struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
struct i40e_aqc_debug_dump_internals *resp =
(struct i40e_aqc_debug_dump_internals *)&desc.params.raw;
i40e_status status;

if (buff_size == 0 || !buff)
return I40E_ERR_PARAM;

i40e_fill_default_direct_cmd_desc(&desc,
i40e_aqc_opc_debug_dump_internals);
/* Indirect Command */
desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_BUF);
if (buff_size > I40E_AQ_LARGE_BUF)
desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);

cmd->cluster_id = cluster_id;
cmd->table_id = table_id;
cmd->idx = cpu_to_le32(start_index);

desc.datalen = cpu_to_le16(buff_size);

status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details);
if (!status) {
if (ret_buff_size)
*ret_buff_size = le16_to_cpu(desc.datalen);
if (ret_next_table)
*ret_next_table = resp->table_id;
if (ret_next_index)
*ret_next_index = le32_to_cpu(resp->idx);
}

return status;
}

/**
* i40e_read_bw_from_alt_ram
* @hw: pointer to the hardware structure
Expand Down
6 changes: 2 additions & 4 deletions drivers/net/ethernet/intel/i40e/i40e_dcb.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ static void i40e_cee_to_dcb_v1_config(
{
u16 status, tlv_status = le16_to_cpu(cee_cfg->tlv_status);
u16 app_prio = le16_to_cpu(cee_cfg->oper_app_prio);
u8 i, tc, err, sync, oper;
u8 i, tc, err;

/* CEE PG data to ETS config */
dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
Expand Down Expand Up @@ -456,9 +456,7 @@ static void i40e_cee_to_dcb_v1_config(
status = (tlv_status & I40E_AQC_CEE_APP_STATUS_MASK) >>
I40E_AQC_CEE_APP_STATUS_SHIFT;
err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
/* Add APPs if Error is False and Oper/Sync is True */
/* Add APPs if Error is False */
if (!err) {
/* CEE operating configuration supports FCoE/iSCSI/FIP only */
dcbcfg->numapps = I40E_CEE_OPER_MAX_APPS;
Expand Down
45 changes: 45 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1388,6 +1388,50 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
r_cfg->app[i].selector,
r_cfg->app[i].protocolid);
}
} else if (strncmp(&cmd_buf[5], "debug fwdata", 12) == 0) {
int cluster_id, table_id;
int index, ret;
u16 buff_len = 4096;
u32 next_index;
u8 next_table;
u8 *buff;
u16 rlen;

cnt = sscanf(&cmd_buf[18], "%i %i %i",
&cluster_id, &table_id, &index);
if (cnt != 3) {
dev_info(&pf->pdev->dev,
"dump debug fwdata <cluster_id> <table_id> <index>\n");
goto command_write_done;
}

dev_info(&pf->pdev->dev,
"AQ debug dump fwdata params %x %x %x %x\n",
cluster_id, table_id, index, buff_len);
buff = kzalloc(buff_len, GFP_KERNEL);
if (!buff)
goto command_write_done;

ret = i40e_aq_debug_dump(&pf->hw, cluster_id, table_id,
index, buff_len, buff, &rlen,
&next_table, &next_index,
NULL);
if (ret) {
dev_info(&pf->pdev->dev,
"debug dump fwdata AQ Failed %d 0x%x\n",
ret, pf->hw.aq.asq_last_status);
kfree(buff);
buff = NULL;
goto command_write_done;
}
dev_info(&pf->pdev->dev,
"AQ debug dump fwdata rlen=0x%x next_table=0x%x next_index=0x%x\n",
rlen, next_table, next_index);
print_hex_dump(KERN_INFO, "AQ buffer WB: ",
DUMP_PREFIX_OFFSET, 16, 1,
buff, rlen, true);
kfree(buff);
buff = NULL;
} else {
dev_info(&pf->pdev->dev,
"dump desc tx <vsi_seid> <ring_id> [<desc_n>], dump desc rx <vsi_seid> <ring_id> [<desc_n>],\n");
Expand Down Expand Up @@ -1903,6 +1947,7 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
dev_info(&pf->pdev->dev, " dump desc rx <vsi_seid> <ring_id> [<desc_n>]\n");
dev_info(&pf->pdev->dev, " dump desc aq\n");
dev_info(&pf->pdev->dev, " dump reset stats\n");
dev_info(&pf->pdev->dev, " dump debug fwdata <cluster_id> <table_id> <index>\n");
dev_info(&pf->pdev->dev, " msg_enable [level]\n");
dev_info(&pf->pdev->dev, " read <reg>\n");
dev_info(&pf->pdev->dev, " write <reg> <value>\n");
Expand Down
29 changes: 27 additions & 2 deletions drivers/net/ethernet/intel/i40e/i40e_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,7 @@ static void i40e_get_settings_link_up(struct i40e_hw *hw,
/* Set speed and duplex */
switch (link_speed) {
case I40E_LINK_SPEED_40GB:
/* need a SPEED_40000 in ethtool.h */
ethtool_cmd_speed_set(ecmd, 40000);
ethtool_cmd_speed_set(ecmd, SPEED_40000);
break;
case I40E_LINK_SPEED_20GB:
ethtool_cmd_speed_set(ecmd, SPEED_20000);
Expand Down Expand Up @@ -1914,6 +1913,16 @@ static int i40e_get_ethtool_fdir_entry(struct i40e_pf *pf,
else
fsp->ring_cookie = rule->q_index;

if (rule->dest_vsi != pf->vsi[pf->lan_vsi]->id) {
struct i40e_vsi *vsi;

vsi = i40e_find_vsi_from_id(pf, rule->dest_vsi);
if (vsi && vsi->type == I40E_VSI_SRIOV) {
fsp->h_ext.data[1] = htonl(vsi->vf_id);
fsp->m_ext.data[1] = htonl(0x1);
}
}

return 0;
}

Expand Down Expand Up @@ -2207,6 +2216,7 @@ static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi,
struct i40e_fdir_filter *input;
struct i40e_pf *pf;
int ret = -EINVAL;
u16 vf_id;

if (!vsi)
return -EINVAL;
Expand Down Expand Up @@ -2267,7 +2277,22 @@ static int i40e_add_fdir_ethtool(struct i40e_vsi *vsi,
input->dst_ip[0] = fsp->h_u.tcp_ip4_spec.ip4src;
input->src_ip[0] = fsp->h_u.tcp_ip4_spec.ip4dst;

if (ntohl(fsp->m_ext.data[1])) {
if (ntohl(fsp->h_ext.data[1]) >= pf->num_alloc_vfs) {
netif_info(pf, drv, vsi->netdev, "Invalid VF id\n");
goto free_input;
}
vf_id = ntohl(fsp->h_ext.data[1]);
/* Find vsi id from vf id and override dest vsi */
input->dest_vsi = pf->vf[vf_id].lan_vsi_id;
if (input->q_index >= pf->vf[vf_id].num_queue_pairs) {
netif_info(pf, drv, vsi->netdev, "Invalid queue id\n");
goto free_input;
}
}

ret = i40e_add_del_fdir(vsi, input, true);
free_input:
if (ret)
kfree(input);
else
Expand Down
16 changes: 12 additions & 4 deletions drivers/net/ethernet/intel/i40e/i40e_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static const char i40e_driver_string[] =

#define DRV_VERSION_MAJOR 1
#define DRV_VERSION_MINOR 3
#define DRV_VERSION_BUILD 1
#define DRV_VERSION_BUILD 2
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
__stringify(DRV_VERSION_MINOR) "." \
__stringify(DRV_VERSION_BUILD) DRV_KERN
Expand Down Expand Up @@ -7301,7 +7301,7 @@ static int i40e_vsi_alloc_q_vectors(struct i40e_vsi *vsi)
* i40e_init_interrupt_scheme - Determine proper interrupt scheme
* @pf: board private structure to initialize
**/
static void i40e_init_interrupt_scheme(struct i40e_pf *pf)
static int i40e_init_interrupt_scheme(struct i40e_pf *pf)
{
int vectors = 0;
ssize_t size;
Expand Down Expand Up @@ -7343,11 +7343,17 @@ static void i40e_init_interrupt_scheme(struct i40e_pf *pf)
/* set up vector assignment tracking */
size = sizeof(struct i40e_lump_tracking) + (sizeof(u16) * vectors);
pf->irq_pile = kzalloc(size, GFP_KERNEL);
if (!pf->irq_pile) {
dev_err(&pf->pdev->dev, "error allocating irq_pile memory\n");
return -ENOMEM;
}
pf->irq_pile->num_entries = vectors;
pf->irq_pile->search_hint = 0;

/* track first vector for misc interrupts */
/* track first vector for misc interrupts, ignore return */
(void)i40e_get_lump(pf, pf->irq_pile, 1, I40E_PILE_VALID_BIT - 1);

return 0;
}

/**
Expand Down Expand Up @@ -9827,7 +9833,9 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)

/* set up the main switch operations */
i40e_determine_queue_usage(pf);
i40e_init_interrupt_scheme(pf);
err = i40e_init_interrupt_scheme(pf);
if (err)
goto err_switch_setup;

/* The number of VSIs reported by the FW is the minimum guaranteed
* to us; HW supports far more and we share the remaining pool with
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/ethernet/intel/i40e/i40e_nvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -821,13 +821,12 @@ static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
int *errno)
{
enum i40e_nvmupd_cmd upd_cmd;
u8 transaction, module;
u8 transaction;

/* anything that doesn't match a recognized case is an error */
upd_cmd = I40E_NVMUPD_INVALID;

transaction = i40e_nvmupd_get_transaction(cmd->config);
module = i40e_nvmupd_get_module(cmd->config);

/* limits on data size */
if ((cmd->data_size < 1) ||
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_prototype.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,4 +303,9 @@ i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
u16 vsi_seid, u16 queue, bool is_add,
struct i40e_control_filter_stats *stats,
struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
u8 table_id, u32 start_index, u16 buff_size,
void *buff, u16 *ret_buff_size,
u8 *ret_next_table, u32 *ret_next_index,
struct i40e_asq_cmd_details *cmd_details);
#endif /* _I40E_PROTOTYPE_H_ */
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/i40e/i40e_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ struct i40e_hw_capabilities {
u8 rx_buf_chain_len;
u32 enabled_tcmap;
u32 maxtc;
u64 wr_csr_prot;
};

struct i40e_mac_info {
Expand Down
Loading

0 comments on commit 6b9107d

Please sign in to comment.