Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a77f9a28 authored by David S. Miller's avatar David S. Miller
Browse files
Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates 2014-09-04

This series contains updates to i40e, i40evf, ixgbe and ixgbevf.

Catherine adds dual speed module support to i40e.  Updates i40e to allow
the user to change link settings when the link is down.

Serey renames i40e_ndo_set_vf_spoofck() to i40e_ndo_set_vf_spookchk()
to be more consistent with what is defined in netdev and removes a
unnecessary variable assignment.

Jesse makes a malicious driver detection warning only print if extended
driver string is enabled for i40e.  Fixes a panic under traffic load when
resetting or if/whenever there was a Tx-timeout because we were enabling
the Tx queue to early.

Anjali fixes an issue when PF reset fails, where we were trying to restart
the admin queue which has not been setup at that point.  This resolves an
occasional kernel panic when PF reset fails for some reason.

Ethan Zhao replaces the use of a local i40e_vfs_are_assigned() with the
global kernel pci_vfs_assigned() for i40e.

Alex cleans up the FDB handling for ixgbe.  This change makes it so that
the behavior for FDB handling is consistent between both the SR-IOV and
non-SR-IOV cases.  The main change is that we perform bounds checking on
the number of SR-IOV addresses regardless of if SR-IOV is enabled or not
as we can only support a certain number of addresses in the hardware.

Emil extends the pending Tx work check to the VF interfaces, where the
driver initiates a reset of the interface on link loss with pending Tx
work in order to clear the rings.  Introduces a delay for 82599 VFs of
at least 500 usecs to make sure the VFLINKS value is correct, since this
bit tends to flap when a DA or SFP+ cable is disconnected.

Jacob adds code comments in ixgbe to make it more obvious that we are
resetting features based on the fact that we do not have MSI-X enabled,
and cannot use the previous settings.  Also resolves a kernel NULL
pointer dereference by limiting the combined total of MACVLAN and
SR-IOV VFs, since the hardware has a limited number of pools available
(64).  Previously, no checks were in place to limit the number of
accelerated MACVLAN devices based on the number of pools, which would
be ok since there was already a limit for these well below the number of
available pools.  However, SR-IOV uses the very same pools, therefore
we need to ensure that the total number of pools does not exceed the
number of pools available in the hardware.

v2:
 - clean up code comment in patch 5 by replacing "an" with "auto
   negotiation" based on feedback from Sergei Shtylyov
 - removed un-necessary parenthesis around function call in patch 8
   based on feedback from Sergei Shtylyov
====================
parents c2b32e58 aac2f1bf
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -145,6 +145,7 @@ enum i40e_state_t {
	__I40E_BAD_EEPROM,
	__I40E_DOWN_REQUESTED,
	__I40E_FD_FLUSH_REQUESTED,
	__I40E_RESET_FAILED,
};

enum i40e_interrupt_policy {
+2 −0
Original line number Diff line number Diff line
@@ -752,6 +752,8 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
	switch (hw->phy.link_info.phy_type) {
	case I40E_PHY_TYPE_10GBASE_SR:
	case I40E_PHY_TYPE_10GBASE_LR:
	case I40E_PHY_TYPE_1000BASE_SX:
	case I40E_PHY_TYPE_1000BASE_LX:
	case I40E_PHY_TYPE_40GBASE_SR4:
	case I40E_PHY_TYPE_40GBASE_LR4:
		media = I40E_MEDIA_TYPE_FIBER;
+31 −24
Original line number Diff line number Diff line
@@ -313,7 +313,10 @@ static int i40e_get_settings(struct net_device *netdev,
		break;
	case I40E_PHY_TYPE_10GBASE_SR:
	case I40E_PHY_TYPE_10GBASE_LR:
	case I40E_PHY_TYPE_1000BASE_SX:
	case I40E_PHY_TYPE_1000BASE_LX:
		ecmd->supported = SUPPORTED_10000baseT_Full;
		ecmd->supported |= SUPPORTED_1000baseT_Full;
		break;
	case I40E_PHY_TYPE_10GBASE_CR1_CU:
	case I40E_PHY_TYPE_10GBASE_CR1:
@@ -352,7 +355,8 @@ static int i40e_get_settings(struct net_device *netdev,
		break;
	default:
		/* if we got here and link is up something bad is afoot */
		WARN_ON(link_up);
		netdev_info(netdev, "WARNING: Link is up but PHY type 0x%x is not recognized.\n",
			    hw_link_info->phy_type);
	}

no_valid_phy_type:
@@ -462,7 +466,8 @@ static int i40e_set_settings(struct net_device *netdev,

	if (hw->phy.media_type != I40E_MEDIA_TYPE_BASET &&
	    hw->phy.media_type != I40E_MEDIA_TYPE_FIBER &&
	    hw->phy.media_type != I40E_MEDIA_TYPE_BACKPLANE)
	    hw->phy.media_type != I40E_MEDIA_TYPE_BACKPLANE &&
	    hw->phy.link_info.link_info & I40E_AQ_LINK_UP)
		return -EOPNOTSUPP;

	/* get our own copy of the bits to check against */
@@ -493,11 +498,10 @@ static int i40e_set_settings(struct net_device *netdev,
	if (status)
		return -EAGAIN;

	/* Copy link_speed and abilities to config in case they are not
	/* Copy abilities to config in case autoneg is not
	 * set below
	 */
	memset(&config, 0, sizeof(struct i40e_aq_set_phy_config));
	config.link_speed = abilities.link_speed;
	config.abilities = abilities.abilities;

	/* Check autoneg */
@@ -534,42 +538,38 @@ static int i40e_set_settings(struct net_device *netdev,
		return -EINVAL;

	if (advertise & ADVERTISED_100baseT_Full)
		if (!(abilities.link_speed & I40E_LINK_SPEED_100MB)) {
		config.link_speed |= I40E_LINK_SPEED_100MB;
			change = true;
		}
	if (advertise & ADVERTISED_1000baseT_Full ||
	    advertise & ADVERTISED_1000baseKX_Full)
		if (!(abilities.link_speed & I40E_LINK_SPEED_1GB)) {
		config.link_speed |= I40E_LINK_SPEED_1GB;
			change = true;
		}
	if (advertise & ADVERTISED_10000baseT_Full ||
	    advertise & ADVERTISED_10000baseKX4_Full ||
	    advertise & ADVERTISED_10000baseKR_Full)
		if (!(abilities.link_speed & I40E_LINK_SPEED_10GB)) {
		config.link_speed |= I40E_LINK_SPEED_10GB;
			change = true;
		}
	if (advertise & ADVERTISED_40000baseKR4_Full ||
	    advertise & ADVERTISED_40000baseCR4_Full ||
	    advertise & ADVERTISED_40000baseSR4_Full ||
	    advertise & ADVERTISED_40000baseLR4_Full)
		if (!(abilities.link_speed & I40E_LINK_SPEED_40GB)) {
		config.link_speed |= I40E_LINK_SPEED_40GB;
			change = true;
		}

	if (change) {
	if (change || (abilities.link_speed != config.link_speed)) {
		/* copy over the rest of the abilities */
		config.phy_type = abilities.phy_type;
		config.eee_capability = abilities.eee_capability;
		config.eeer = abilities.eeer_val;
		config.low_power_ctrl = abilities.d3_lpan;

		/* If link is up set link and an so changes take effect */
		if (hw->phy.link_info.link_info & I40E_AQ_LINK_UP)
		/* set link and auto negotiation so changes take effect */
		config.abilities |= I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
		/* If link is up put link down */
		if (hw->phy.link_info.link_info & I40E_AQ_LINK_UP) {
			/* Tell the OS link is going down, the link will go
			 * back up when fw says it is ready asynchronously
			 */
			netdev_info(netdev, "PHY settings change requested, NIC Link is going down.\n");
			netif_carrier_off(netdev);
			netif_tx_stop_all_queues(netdev);
		}

		/* make the aq call */
		status = i40e_aq_set_phy_config(hw, &config, NULL);
@@ -686,6 +686,13 @@ static int i40e_set_pauseparam(struct net_device *netdev,
	else
		 return -EINVAL;

	/* Tell the OS link is going down, the link will go back up when fw
	 * says it is ready asynchronously
	 */
	netdev_info(netdev, "Flow control settings change requested, NIC Link is going down.\n");
	netif_carrier_off(netdev);
	netif_tx_stop_all_queues(netdev);

	/* Set the fc mode and only restart an if link is up*/
	status = i40e_set_fc(hw, &aq_failures, link_up);

+25 −20
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ static const char i40e_driver_string[] =

#define DRV_VERSION_MAJOR 1
#define DRV_VERSION_MINOR 0
#define DRV_VERSION_BUILD 4
#define DRV_VERSION_BUILD 11
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
	     __stringify(DRV_VERSION_MINOR) "." \
	     __stringify(DRV_VERSION_BUILD)    DRV_KERN
@@ -5289,7 +5289,7 @@ static void i40e_fdir_reinit_subtask(struct i40e_pf *pf)
 **/
static void i40e_vsi_link_event(struct i40e_vsi *vsi, bool link_up)
{
	if (!vsi)
	if (!vsi || test_bit(__I40E_DOWN, &vsi->state))
		return;

	switch (vsi->type) {
@@ -5568,6 +5568,10 @@ static void i40e_clean_adminq_subtask(struct i40e_pf *pf)
	u32 oldval;
	u32 val;

	/* Do not run clean AQ when PF reset fails */
	if (test_bit(__I40E_RESET_FAILED, &pf->state))
		return;

	/* check for error indications */
	val = rd32(&pf->hw, pf->hw.aq.arq.len);
	oldval = val;
@@ -5973,19 +5977,20 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
	ret = i40e_pf_reset(hw);
	if (ret) {
		dev_info(&pf->pdev->dev, "PF reset failed, %d\n", ret);
		goto end_core_reset;
		set_bit(__I40E_RESET_FAILED, &pf->state);
		goto clear_recovery;
	}
	pf->pfr_count++;

	if (test_bit(__I40E_DOWN, &pf->state))
		goto end_core_reset;
		goto clear_recovery;
	dev_dbg(&pf->pdev->dev, "Rebuilding internal switch\n");

	/* rebuild the basics for the AdminQ, HMC, and initial HW switch */
	ret = i40e_init_adminq(&pf->hw);
	if (ret) {
		dev_info(&pf->pdev->dev, "Rebuild AdminQ failed, %d\n", ret);
		goto end_core_reset;
		goto clear_recovery;
	}

	/* re-verify the eeprom if we just had an EMP reset */
@@ -6103,6 +6108,8 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
	i40e_send_version(pf);

end_core_reset:
	clear_bit(__I40E_RESET_FAILED, &pf->state);
clear_recovery:
	clear_bit(__I40E_RESET_RECOVERY_PENDING, &pf->state);
}

@@ -6148,8 +6155,8 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf)
				I40E_GL_MDET_TX_EVENT_SHIFT;
		u8 queue = (reg & I40E_GL_MDET_TX_QUEUE_MASK) >>
				I40E_GL_MDET_TX_QUEUE_SHIFT;
		dev_info(&pf->pdev->dev,
			 "Malicious Driver Detection event 0x%02x on TX queue %d pf number 0x%02x vf number 0x%02x\n",
		if (netif_msg_tx_err(pf))
			dev_info(&pf->pdev->dev, "Malicious Driver Detection event 0x%02x on TX queue %d pf number 0x%02x vf number 0x%02x\n",
				 event, queue, pf_num, vf_num);
		wr32(hw, I40E_GL_MDET_TX, 0xffffffff);
		mdd_detected = true;
@@ -6162,8 +6169,8 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf)
				I40E_GL_MDET_RX_EVENT_SHIFT;
		u8 queue = (reg & I40E_GL_MDET_RX_QUEUE_MASK) >>
				I40E_GL_MDET_RX_QUEUE_SHIFT;
		dev_info(&pf->pdev->dev,
			 "Malicious Driver Detection event 0x%02x on RX queue %d of function 0x%02x\n",
		if (netif_msg_rx_err(pf))
			dev_info(&pf->pdev->dev, "Malicious Driver Detection event 0x%02x on RX queue %d of function 0x%02x\n",
				 event, queue, func);
		wr32(hw, I40E_GL_MDET_RX, 0xffffffff);
		mdd_detected = true;
@@ -6173,17 +6180,13 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf)
		reg = rd32(hw, I40E_PF_MDET_TX);
		if (reg & I40E_PF_MDET_TX_VALID_MASK) {
			wr32(hw, I40E_PF_MDET_TX, 0xFFFF);
			dev_info(&pf->pdev->dev,
				 "MDD TX event is for this function 0x%08x, requesting PF reset.\n",
				 reg);
			dev_info(&pf->pdev->dev, "TX driver issue detected, PF reset issued\n");
			pf_mdd_detected = true;
		}
		reg = rd32(hw, I40E_PF_MDET_RX);
		if (reg & I40E_PF_MDET_RX_VALID_MASK) {
			wr32(hw, I40E_PF_MDET_RX, 0xFFFF);
			dev_info(&pf->pdev->dev,
				 "MDD RX event is for this function 0x%08x, requesting PF reset.\n",
				 reg);
			dev_info(&pf->pdev->dev, "RX driver issue detected, PF reset issued\n");
			pf_mdd_detected = true;
		}
		/* Queue belongs to the PF, initiate a reset */
@@ -6200,14 +6203,16 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf)
		if (reg & I40E_VP_MDET_TX_VALID_MASK) {
			wr32(hw, I40E_VP_MDET_TX(i), 0xFFFF);
			vf->num_mdd_events++;
			dev_info(&pf->pdev->dev, "MDD TX event on VF %d\n", i);
			dev_info(&pf->pdev->dev, "TX driver issue detected on VF %d\n",
				 i);
		}

		reg = rd32(hw, I40E_VP_MDET_RX(i));
		if (reg & I40E_VP_MDET_RX_VALID_MASK) {
			wr32(hw, I40E_VP_MDET_RX(i), 0xFFFF);
			vf->num_mdd_events++;
			dev_info(&pf->pdev->dev, "MDD RX event on VF %d\n", i);
			dev_info(&pf->pdev->dev, "RX driver issue detected on VF %d\n",
				 i);
		}

		if (vf->num_mdd_events > I40E_DEFAULT_NUM_MDD_EVENTS_ALLOWED) {
@@ -7469,7 +7474,7 @@ static const struct net_device_ops i40e_netdev_ops = {
	.ndo_set_vf_rate	= i40e_ndo_set_vf_bw,
	.ndo_get_vf_config	= i40e_ndo_get_vf_config,
	.ndo_set_vf_link_state	= i40e_ndo_set_vf_link_state,
	.ndo_set_vf_spoofchk	= i40e_ndo_set_vf_spoofck,
	.ndo_set_vf_spoofchk	= i40e_ndo_set_vf_spoofchk,
#ifdef CONFIG_I40E_VXLAN
	.ndo_add_vxlan_port	= i40e_add_vxlan_port,
	.ndo_del_vxlan_port	= i40e_del_vxlan_port,
+3 −33
Original line number Diff line number Diff line
@@ -707,35 +707,6 @@ void i40e_reset_vf(struct i40e_vf *vf, bool flr)
	wr32(hw, I40E_VFGEN_RSTAT1(vf->vf_id), I40E_VFR_VFACTIVE);
	i40e_flush(hw);
}

/**
 * i40e_vfs_are_assigned
 * @pf: pointer to the pf structure
 *
 * Determine if any VFs are assigned to VMs
 **/
static bool i40e_vfs_are_assigned(struct i40e_pf *pf)
{
	struct pci_dev *pdev = pf->pdev;
	struct pci_dev *vfdev;

	/* loop through all the VFs to see if we own any that are assigned */
	vfdev = pci_get_device(PCI_VENDOR_ID_INTEL, I40E_DEV_ID_VF , NULL);
	while (vfdev) {
		/* if we don't own it we don't care */
		if (vfdev->is_virtfn && pci_physfn(vfdev) == pdev) {
			/* if it is assigned we cannot release it */
			if (vfdev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)
				return true;
		}

		vfdev = pci_get_device(PCI_VENDOR_ID_INTEL,
				       I40E_DEV_ID_VF,
				       vfdev);
	}

	return false;
}
#ifdef CONFIG_PCI_IOV

/**
@@ -843,7 +814,7 @@ void i40e_free_vfs(struct i40e_pf *pf)
	 * assigned. Setting the number of VFs to 0 through sysfs is caught
	 * before this function ever gets called.
	 */
	if (!i40e_vfs_are_assigned(pf)) {
	if (!pci_vfs_assigned(pf->pdev)) {
		pci_disable_sriov(pf->pdev);
		/* Acknowledge VFLR for all VFS. Without this, VFs will fail to
		 * work correctly when SR-IOV gets re-enabled.
@@ -980,7 +951,7 @@ int i40e_pci_sriov_configure(struct pci_dev *pdev, int num_vfs)
	if (num_vfs)
		return i40e_pci_sriov_enable(pdev, num_vfs);

	if (!i40e_vfs_are_assigned(pf)) {
	if (!pci_vfs_assigned(pf->pdev)) {
		i40e_free_vfs(pf);
	} else {
		dev_warn(&pdev->dev, "Unable to free VFs because some are assigned to VMs.\n");
@@ -2098,7 +2069,6 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
	/* Force the VF driver stop so it has to reload with new MAC address */
	i40e_vc_disable_vf(pf, vf);
	dev_info(&pf->pdev->dev, "Reload the VF driver to make this change effective.\n");
	ret = 0;

error_param:
	return ret;
@@ -2423,7 +2393,7 @@ int i40e_ndo_set_vf_link_state(struct net_device *netdev, int vf_id, int link)
 *
 * Enable or disable VF spoof checking
 **/
int i40e_ndo_set_vf_spoofck(struct net_device *netdev, int vf_id, bool enable)
int i40e_ndo_set_vf_spoofchk(struct net_device *netdev, int vf_id, bool enable)
{
	struct i40e_netdev_priv *np = netdev_priv(netdev);
	struct i40e_vsi *vsi = np->vsi;
Loading