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-03

This series contains updates to i40e and i40evf only.

Anjali provides a fix for verifying outer UDP receive checksum.  Also
adds helpful information to display when figuring out the cause of
HMC errors.

Mitch provides a fix to prevent a malicious or buggy VF driver from
sending an invalid index into the VSI array which could panic the host.
Cleans up the code where a function was moved, but the message did
not follow.  Adds protection to the VLAN filter list, same as the
MAC filter list, to protect from corruption if the watchdog happens
to run at the same time as a VLAN filter is being added/deleted.

Jesse changes several memcpy() statements to struct assignments which
are type safe and preferable.  Fixed a bug when skb allocation fails,
where we should not continue using the skb pointer.  Also fixed a void
function in FCoE which should not be returning anything.

Greg fixes both i40e and i40evf to set the Ethernet protocol correctly
when transmit VLAN offloads are disabled.

Shannon fixes up VLAN messages when ports are added or removed, which
were giving bogus index info.  Also aligned the message text style
with other messages in the driver.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Apr 3, 2015
2 parents e79d842 + 42d255c commit 5c5e0ad
Show file tree
Hide file tree
Showing 9 changed files with 202 additions and 135 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/i40e/i40e.h
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,7 @@ 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);
struct i40e_vsi *i40e_find_vsi_from_id(struct i40e_pf *pf, u16 id);
void i40e_update_stats(struct i40e_vsi *vsi);
void i40e_update_eth_stats(struct i40e_vsi *vsi);
struct rtnl_link_stats64 *i40e_get_vsi_stats_struct(struct i40e_vsi *vsi);
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_dcb_nl.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ void i40e_dcbnl_set_all(struct i40e_vsi *vsi)
if (!(pf->flags & I40E_FLAG_DCB_ENABLED))
return;

/* MFP mode but not an iSCSI PF so return */
if ((pf->flags & I40E_FLAG_MFP_ENABLED) && !(pf->hw.func_caps.iscsi))
return;

dcbxcfg = &hw->local_dcbx_config;

/* Set up all the App TLVs if DCBx is negotiated */
Expand Down Expand Up @@ -282,6 +286,10 @@ void i40e_dcbnl_flush_apps(struct i40e_pf *pf,
struct i40e_dcb_app_priority_table app;
int i;

/* MFP mode but not an iSCSI PF so return */
if ((pf->flags & I40E_FLAG_MFP_ENABLED) && !(pf->hw.func_caps.iscsi))
return;

for (i = 0; i < old_cfg->numapps; i++) {
app = old_cfg->app[i];
/* The APP is not available anymore delete it */
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/ethernet/intel/i40e/i40e_fcoe.c
Original file line number Diff line number Diff line change
Expand Up @@ -1306,8 +1306,7 @@ static void i40e_fcoe_tx_map(struct i40e_ring *tx_ring,
/* MACLEN is ether header length in words not bytes */
td_offset |= (maclen >> 1) << I40E_TX_DESC_LENGTH_MACLEN_SHIFT;

return i40e_tx_map(tx_ring, skb, first, tx_flags, hdr_len,
td_cmd, td_offset);
i40e_tx_map(tx_ring, skb, first, tx_flags, hdr_len, td_cmd, td_offset);
}

/**
Expand Down
82 changes: 50 additions & 32 deletions drivers/net/ethernet/intel/i40e/i40e_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ static const char i40e_driver_string[] =
#define DRV_KERN "-k"

#define DRV_VERSION_MAJOR 1
#define DRV_VERSION_MINOR 2
#define DRV_VERSION_BUILD 43
#define DRV_VERSION_MINOR 3
#define DRV_VERSION_BUILD 1
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
__stringify(DRV_VERSION_MINOR) "." \
__stringify(DRV_VERSION_BUILD) DRV_KERN
Expand Down Expand Up @@ -249,6 +249,22 @@ static int i40e_put_lump(struct i40e_lump_tracking *pile, u16 index, u16 id)
return count;
}

/**
* i40e_find_vsi_from_id - searches for the vsi with the given id
* @pf - the pf structure to search for the vsi
* @id - id of the vsi it is searching for
**/
struct i40e_vsi *i40e_find_vsi_from_id(struct i40e_pf *pf, u16 id)
{
int i;

for (i = 0; i < pf->num_alloc_vsi; i++)
if (pf->vsi[i] && (pf->vsi[i]->id == id))
return pf->vsi[i];

return NULL;
}

/**
* i40e_service_event_schedule - Schedule the service task to wake up
* @pf: board private structure
Expand Down Expand Up @@ -1969,7 +1985,7 @@ void i40e_vlan_stripping_enable(struct i40e_vsi *vsi)
I40E_AQ_VSI_PVLAN_EMOD_STR_BOTH;

ctxt.seid = vsi->seid;
memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
ctxt.info = vsi->info;
ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
if (ret) {
dev_info(&vsi->back->pdev->dev,
Expand Down Expand Up @@ -1998,7 +2014,7 @@ void i40e_vlan_stripping_disable(struct i40e_vsi *vsi)
I40E_AQ_VSI_PVLAN_EMOD_NOTHING;

ctxt.seid = vsi->seid;
memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
ctxt.info = vsi->info;
ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
if (ret) {
dev_info(&vsi->back->pdev->dev,
Expand Down Expand Up @@ -2282,7 +2298,7 @@ int i40e_vsi_add_pvid(struct i40e_vsi *vsi, u16 vid)
I40E_AQ_VSI_PVLAN_EMOD_STR;

ctxt.seid = vsi->seid;
memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
ctxt.info = vsi->info;
aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
if (aq_ret) {
dev_info(&vsi->back->pdev->dev,
Expand Down Expand Up @@ -3197,6 +3213,9 @@ static irqreturn_t i40e_intr(int irq, void *data)
if (icr0 & I40E_PFINT_ICR0_HMC_ERR_MASK) {
icr0 &= ~I40E_PFINT_ICR0_HMC_ERR_MASK;
dev_info(&pf->pdev->dev, "HMC error interrupt\n");
dev_info(&pf->pdev->dev, "HMC error info 0x%x, HMC error data 0x%x\n",
rd32(hw, I40E_PFHMC_ERRORINFO),
rd32(hw, I40E_PFHMC_ERRORDATA));
}

if (icr0 & I40E_PFINT_ICR0_TIMESYNC_MASK) {
Expand Down Expand Up @@ -4392,7 +4411,7 @@ static int i40e_vsi_config_tc(struct i40e_vsi *vsi, u8 enabled_tc)
ctxt.pf_num = vsi->back->hw.pf_id;
ctxt.vf_num = 0;
ctxt.uplink_seid = vsi->uplink_seid;
memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
ctxt.info = vsi->info;
i40e_vsi_setup_queue_map(vsi, &ctxt, enabled_tc, false);

/* Update the VSI after updating the VSI queue-mapping information */
Expand Down Expand Up @@ -5220,9 +5239,8 @@ static int i40e_handle_lldp_event(struct i40e_pf *pf,
goto exit;
}

memset(&tmp_dcbx_cfg, 0, sizeof(tmp_dcbx_cfg));
/* Store the old configuration */
memcpy(&tmp_dcbx_cfg, &hw->local_dcbx_config, sizeof(tmp_dcbx_cfg));
tmp_dcbx_cfg = hw->local_dcbx_config;

/* Reset the old DCBx configuration data */
memset(&hw->local_dcbx_config, 0, sizeof(hw->local_dcbx_config));
Expand Down Expand Up @@ -5782,11 +5800,9 @@ static void i40e_handle_link_event(struct i40e_pf *pf,
struct i40e_hw *hw = &pf->hw;
struct i40e_aqc_get_link_status *status =
(struct i40e_aqc_get_link_status *)&e->desc.params.raw;
struct i40e_link_status *hw_link_info = &hw->phy.link_info;

/* save off old link status information */
memcpy(&pf->hw.phy.link_info_old, hw_link_info,
sizeof(pf->hw.phy.link_info_old));
hw->phy.link_info_old = hw->phy.link_info;

/* Do a new status request to re-enable LSE reporting
* and load new status information into the hw struct
Expand Down Expand Up @@ -6608,7 +6624,6 @@ static void i40e_sync_vxlan_filters_subtask(struct i40e_pf *pf)
{
struct i40e_hw *hw = &pf->hw;
i40e_status ret;
u8 filter_index;
__be16 port;
int i;

Expand All @@ -6621,22 +6636,20 @@ static void i40e_sync_vxlan_filters_subtask(struct i40e_pf *pf)
if (pf->pending_vxlan_bitmap & (1 << i)) {
pf->pending_vxlan_bitmap &= ~(1 << i);
port = pf->vxlan_ports[i];
ret = port ?
i40e_aq_add_udp_tunnel(hw, ntohs(port),
if (port)
ret = i40e_aq_add_udp_tunnel(hw, ntohs(port),
I40E_AQC_TUNNEL_TYPE_VXLAN,
&filter_index, NULL)
: i40e_aq_del_udp_tunnel(hw, i, NULL);
NULL, NULL);
else
ret = i40e_aq_del_udp_tunnel(hw, i, NULL);

if (ret) {
dev_info(&pf->pdev->dev, "Failed to execute AQ command for %s port %d with index %d\n",
port ? "adding" : "deleting",
ntohs(port), port ? i : i);

dev_info(&pf->pdev->dev,
"%s vxlan port %d, index %d failed, err %d, aq_err %d\n",
port ? "add" : "delete",
ntohs(port), i, ret,
pf->hw.aq.asq_last_status);
pf->vxlan_ports[i] = 0;
} else {
dev_info(&pf->pdev->dev, "%s port %d with AQ command with index %d\n",
port ? "Added" : "Deleted",
ntohs(port), port ? i : filter_index);
}
}
}
Expand Down Expand Up @@ -7829,24 +7842,26 @@ static void i40e_add_vxlan_port(struct net_device *netdev,

/* Check if port already exists */
if (idx < I40E_MAX_PF_UDP_OFFLOAD_PORTS) {
netdev_info(netdev, "Port %d already offloaded\n", ntohs(port));
netdev_info(netdev, "vxlan port %d already offloaded\n",
ntohs(port));
return;
}

/* Now check if there is space to add the new port */
next_idx = i40e_get_vxlan_port_idx(pf, 0);

if (next_idx == I40E_MAX_PF_UDP_OFFLOAD_PORTS) {
netdev_info(netdev, "Maximum number of UDP ports reached, not adding port %d\n",
netdev_info(netdev, "maximum number of vxlan UDP ports reached, not adding port %d\n",
ntohs(port));
return;
}

/* New port: add it and mark its index in the bitmap */
pf->vxlan_ports[next_idx] = port;
pf->pending_vxlan_bitmap |= (1 << next_idx);

pf->flags |= I40E_FLAG_VXLAN_FILTER_SYNC;

dev_info(&pf->pdev->dev, "adding vxlan port %d\n", ntohs(port));
}

/**
Expand Down Expand Up @@ -7874,12 +7889,13 @@ static void i40e_del_vxlan_port(struct net_device *netdev,
* and make it pending
*/
pf->vxlan_ports[idx] = 0;

pf->pending_vxlan_bitmap |= (1 << idx);

pf->flags |= I40E_FLAG_VXLAN_FILTER_SYNC;

dev_info(&pf->pdev->dev, "deleting vxlan port %d\n",
ntohs(port));
} else {
netdev_warn(netdev, "Port %d was not found, not deleting\n",
netdev_warn(netdev, "vxlan port %d was not found, not deleting\n",
ntohs(port));
}
}
Expand Down Expand Up @@ -8269,7 +8285,7 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
ret, pf->hw.aq.asq_last_status);
return -ENOENT;
}
memcpy(&vsi->info, &ctxt.info, sizeof(ctxt.info));
vsi->info = ctxt.info;
vsi->info.valid_sections = 0;

vsi->seid = ctxt.seid;
Expand Down Expand Up @@ -8403,7 +8419,7 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
ret = -ENOENT;
goto err;
}
memcpy(&vsi->info, &ctxt.info, sizeof(ctxt.info));
vsi->info = ctxt.info;
vsi->info.valid_sections = 0;
vsi->seid = ctxt.seid;
vsi->id = ctxt.vsi_number;
Expand Down Expand Up @@ -10210,6 +10226,8 @@ static int i40e_suspend(struct pci_dev *pdev, pm_message_t state)
set_bit(__I40E_DOWN, &pf->state);
del_timer_sync(&pf->service_timer);
cancel_work_sync(&pf->service_task);
i40e_fdir_teardown(pf);

rtnl_lock();
i40e_prep_for_reset(pf);
rtnl_unlock();
Expand Down
18 changes: 17 additions & 1 deletion drivers/net/ethernet/intel/i40e/i40e_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1565,8 +1565,11 @@ static int i40e_clean_rx_irq_ps(struct i40e_ring *rx_ring, int budget)
if (likely(!skb)) {
skb = netdev_alloc_skb_ip_align(rx_ring->netdev,
rx_ring->rx_hdr_len);
if (!skb)
if (!skb) {
rx_ring->rx_stats.alloc_buff_failed++;
break;
}

/* initialize queue mapping */
skb_record_rx_queue(skb, rx_ring->queue_index);
/* we are reusing so sync this buffer for CPU use */
Expand Down Expand Up @@ -2054,6 +2057,19 @@ static int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
__be16 protocol = skb->protocol;
u32 tx_flags = 0;

if (protocol == htons(ETH_P_8021Q) &&
!(tx_ring->netdev->features & NETIF_F_HW_VLAN_CTAG_TX)) {
/* When HW VLAN acceleration is turned off by the user the
* stack sets the protocol to 8021q so that the driver
* can take any steps required to support the SW only
* VLAN handling. In our case the driver doesn't need
* to take any further steps so just set the protocol
* to the encapsulated ethertype.
*/
skb->protocol = vlan_get_protocol(skb);
goto out;
}

/* if we have a HW VLAN tag being added, default to the HW one */
if (skb_vlan_tag_present(skb)) {
tx_flags |= skb_vlan_tag_get(skb) << I40E_TX_FLAGS_VLAN_SHIFT;
Expand Down
Loading

0 comments on commit 5c5e0ad

Please sign in to comment.