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

Commit d8ef0347 authored by David S. Miller's avatar David S. Miller
Browse files


Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2016-02-17

This series contains updates to i40e/i40evf only (again).

Jesse moves sync_vsi_filters() up in the service_task because it may need
to request a reset, and we do not want to wait another round of service
task time.  Refactored the enable_icr0() in order to allow it to be
decided by the caller whether the CLEARPBA (clear pending events) bit will
be set while re-enabling the interrupt.  Also provides the "Don't Give Up"
patch, where the driver will keep polling trying to allocate receive buffers
until it succeeds.  This should keep all receive queues running even in
the face of memory pressure.  Cleans up the debugging helpers by putting
everything in hex to be consistent.

Neerav updates the DCB firmware version related checkes specific to X710
and XL710 only since the checks are not required for X722 devices.

Shannon adds the use of the new shared MAC filter bit for multicast and
broadcast filters in order to make better use of the filters available
from the device.  Added a parameter to allow the driver to set the
enable/disable of statistics gathering in the hardware switch.  Also the
L2 cloud filtering parameter is removed since it was never used.

Anjali refactors the force_wb and WB_ON_ITR functionality since
Force-WriteBack functionality in X710/XL710 devices has been moved out of
the clean routine and into the service task, so we need to make sure
WriteBack-On-ITR is separated out since it is still called from clean.

Catherine changes the VF driver string to reflect all the products that
are supported.

Mitch refactors the packet split receive code to properly use half-pages
for receives.  Also changes the use of bitwise operators to logical
operators on clean_complete variable, while making a witty reference to
Mr. Spock.  Cleans up (i.e. removes) the hsplit field in the ring
structure and use the existing macro to detect packet split enablement,
which allows debugfs dumps of the VSI to properly show which recevie
routine is in use.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2bc6b4f4 c24215c0
Loading
Loading
Loading
Loading
+21 −2
Original line number Diff line number Diff line
/*******************************************************************************
 *
 * Intel Ethernet Controller XL710 Family Linux Driver
 * Copyright(c) 2013 - 2015 Intel Corporation.
 * Copyright(c) 2013 - 2016 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
@@ -138,6 +138,19 @@
/* default to trying for four seconds */
#define I40E_TRY_LINK_TIMEOUT (4 * HZ)

/**
 * i40e_is_mac_710 - Return true if MAC is X710/XL710
 * @hw: ptr to the hardware info
 **/
static inline bool i40e_is_mac_710(struct i40e_hw *hw)
{
	if ((hw->mac.type == I40E_MAC_X710) ||
	    (hw->mac.type == I40E_MAC_XL710))
		return true;

	return false;
}

/* driver state flags */
enum i40e_state_t {
	__I40E_TESTING,
@@ -342,6 +355,9 @@ struct i40e_pf {
#define I40E_FLAG_NO_PCI_LINK_CHECK		BIT_ULL(42)
#define I40E_FLAG_100M_SGMII_CAPABLE		BIT_ULL(43)
#define I40E_FLAG_RESTART_AUTONEG		BIT_ULL(44)
#define I40E_FLAG_NO_DCB_SUPPORT		BIT_ULL(45)
#define I40E_FLAG_USE_SET_LLDP_MIB		BIT_ULL(46)
#define I40E_FLAG_STOP_FW_LLDP			BIT_ULL(47)
#define I40E_FLAG_PF_MAC			BIT_ULL(50)

	/* tracks features that get auto disabled by errors */
@@ -751,6 +767,9 @@ static inline void i40e_irq_dynamic_enable(struct i40e_vsi *vsi, int vector)
	struct i40e_hw *hw = &pf->hw;
	u32 val;

	/* definitely clear the PBA here, as this function is meant to
	 * clean out all previous interrupts AND enable the interrupt
	 */
	val = I40E_PFINT_DYN_CTLN_INTENA_MASK |
	      I40E_PFINT_DYN_CTLN_CLEARPBA_MASK |
	      (I40E_ITR_NONE << I40E_PFINT_DYN_CTLN_ITR_INDX_SHIFT);
@@ -759,7 +778,7 @@ static inline void i40e_irq_dynamic_enable(struct i40e_vsi *vsi, int vector)
}

void i40e_irq_dynamic_disable_icr0(struct i40e_pf *pf);
void i40e_irq_dynamic_enable_icr0(struct i40e_pf *pf);
void i40e_irq_dynamic_enable_icr0(struct i40e_pf *pf, bool clearpba);
#ifdef I40E_FCOE
struct rtnl_link_stats64 *i40e_get_netdev_stats_struct(
					     struct net_device *netdev,
+14 −7
Original line number Diff line number Diff line
/*******************************************************************************
 *
 * Intel Ethernet Controller XL710 Family Linux Driver
 * Copyright(c) 2013 - 2015 Intel Corporation.
 * Copyright(c) 2013 - 2016 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
@@ -2308,8 +2308,8 @@ i40e_status i40e_update_link_info(struct i40e_hw *hw)
 * @downlink_seid: the VSI SEID
 * @enabled_tc: bitmap of TCs to be enabled
 * @default_port: true for default port VSI, false for control port
 * @enable_l2_filtering: true to add L2 filter table rules to regular forwarding rules for cloud support
 * @veb_seid: pointer to where to put the resulting VEB SEID
 * @enable_stats: true to turn on VEB stats
 * @cmd_details: pointer to command details structure or NULL
 *
 * This asks the FW to add a VEB between the uplink and downlink
@@ -2317,8 +2317,8 @@ i40e_status i40e_update_link_info(struct i40e_hw *hw)
 **/
i40e_status i40e_aq_add_veb(struct i40e_hw *hw, u16 uplink_seid,
				u16 downlink_seid, u8 enabled_tc,
				bool default_port, bool enable_l2_filtering,
				u16 *veb_seid,
				bool default_port, u16 *veb_seid,
				bool enable_stats,
				struct i40e_asq_cmd_details *cmd_details)
{
	struct i40e_aq_desc desc;
@@ -2345,8 +2345,9 @@ i40e_status i40e_aq_add_veb(struct i40e_hw *hw, u16 uplink_seid,
	else
		veb_flags |= I40E_AQC_ADD_VEB_PORT_TYPE_DATA;

	if (enable_l2_filtering)
		veb_flags |= I40E_AQC_ADD_VEB_ENABLE_L2_FILTER;
	/* reverse logic here: set the bitflag to disable the stats */
	if (!enable_stats)
		veb_flags |= I40E_AQC_ADD_VEB_ENABLE_DISABLE_STATS;

	cmd->veb_flags = cpu_to_le16(veb_flags);

@@ -2435,6 +2436,7 @@ i40e_status i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
		(struct i40e_aqc_macvlan *)&desc.params.raw;
	i40e_status status;
	u16 buf_size;
	int i;

	if (count == 0 || !mv_list || !hw)
		return I40E_ERR_PARAM;
@@ -2448,6 +2450,11 @@ i40e_status i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid,
	cmd->seid[1] = 0;
	cmd->seid[2] = 0;

	for (i = 0; i < count; i++)
		if (is_multicast_ether_addr(mv_list[i].mac_addr))
			mv_list[i].flags |=
			       cpu_to_le16(I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC);

	desc.flags |= cpu_to_le16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD));
	if (buf_size > I40E_AQ_LARGE_BUF)
		desc.flags |= cpu_to_le16((u16)I40E_AQ_FLAG_LB);
+15 −10
Original line number Diff line number Diff line
/*******************************************************************************
 *
 * Intel Ethernet Controller XL710 Family Linux Driver
 * Copyright(c) 2013 - 2014 Intel Corporation.
 * Copyright(c) 2013 - 2016 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
@@ -521,7 +521,7 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
			 rx_ring->dtype);
		dev_info(&pf->pdev->dev,
			 "    rx_rings[%i]: hsplit = %d, next_to_use = %d, next_to_clean = %d, ring_active = %i\n",
			 i, rx_ring->hsplit,
			 i, ring_is_ps_enabled(rx_ring),
			 rx_ring->next_to_use,
			 rx_ring->next_to_clean,
			 rx_ring->ring_active);
@@ -535,6 +535,11 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
			 i,
			 rx_ring->rx_stats.alloc_page_failed,
			 rx_ring->rx_stats.alloc_buff_failed);
		dev_info(&pf->pdev->dev,
			 "    rx_rings[%i]: rx_stats: realloc_count = %lld, page_reuse_count = %lld\n",
			 i,
			 rx_ring->rx_stats.realloc_count,
			 rx_ring->rx_stats.page_reuse_count);
		dev_info(&pf->pdev->dev,
			 "    rx_rings[%i]: size = %i, dma = 0x%08lx\n",
			 i, rx_ring->size,
@@ -567,8 +572,8 @@ static void i40e_dbg_dump_vsi_seid(struct i40e_pf *pf, int seid)
			 "    tx_rings[%i]: dtype = %d\n",
			 i, tx_ring->dtype);
		dev_info(&pf->pdev->dev,
			 "    tx_rings[%i]: hsplit = %d, next_to_use = %d, next_to_clean = %d, ring_active = %i\n",
			 i, tx_ring->hsplit,
			 "    tx_rings[%i]: next_to_use = %d, next_to_clean = %d, ring_active = %i\n",
			 i,
			 tx_ring->next_to_use,
			 tx_ring->next_to_clean,
			 tx_ring->ring_active);
@@ -825,20 +830,20 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,
			if (!is_rx_ring) {
				txd = I40E_TX_DESC(ring, i);
				dev_info(&pf->pdev->dev,
					 "   d[%03i] = 0x%016llx 0x%016llx\n",
					 "   d[%03x] = 0x%016llx 0x%016llx\n",
					 i, txd->buffer_addr,
					 txd->cmd_type_offset_bsz);
			} else if (sizeof(union i40e_rx_desc) ==
				   sizeof(union i40e_16byte_rx_desc)) {
				rxd = I40E_RX_DESC(ring, i);
				dev_info(&pf->pdev->dev,
					 "   d[%03i] = 0x%016llx 0x%016llx\n",
					 "   d[%03x] = 0x%016llx 0x%016llx\n",
					 i, rxd->read.pkt_addr,
					 rxd->read.hdr_addr);
			} else {
				rxd = I40E_RX_DESC(ring, i);
				dev_info(&pf->pdev->dev,
					 "   d[%03i] = 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n",
					 "   d[%03x] = 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n",
					 i, rxd->read.pkt_addr,
					 rxd->read.hdr_addr,
					 rxd->read.rsvd1, rxd->read.rsvd2);
@@ -853,20 +858,20 @@ static void i40e_dbg_dump_desc(int cnt, int vsi_seid, int ring_id, int desc_n,
		if (!is_rx_ring) {
			txd = I40E_TX_DESC(ring, desc_n);
			dev_info(&pf->pdev->dev,
				 "vsi = %02i tx ring = %02i d[%03i] = 0x%016llx 0x%016llx\n",
				 "vsi = %02i tx ring = %02i d[%03x] = 0x%016llx 0x%016llx\n",
				 vsi_seid, ring_id, desc_n,
				 txd->buffer_addr, txd->cmd_type_offset_bsz);
		} else if (sizeof(union i40e_rx_desc) ==
			   sizeof(union i40e_16byte_rx_desc)) {
			rxd = I40E_RX_DESC(ring, desc_n);
			dev_info(&pf->pdev->dev,
				 "vsi = %02i rx ring = %02i d[%03i] = 0x%016llx 0x%016llx\n",
				 "vsi = %02i rx ring = %02i d[%03x] = 0x%016llx 0x%016llx\n",
				 vsi_seid, ring_id, desc_n,
				 rxd->read.pkt_addr, rxd->read.hdr_addr);
		} else {
			rxd = I40E_RX_DESC(ring, desc_n);
			dev_info(&pf->pdev->dev,
				 "vsi = %02i rx ring = %02i d[%03i] = 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n",
				 "vsi = %02i rx ring = %02i d[%03x] = 0x%016llx 0x%016llx 0x%016llx 0x%016llx\n",
				 vsi_seid, ring_id, desc_n,
				 rxd->read.pkt_addr, rxd->read.hdr_addr,
				 rxd->read.rsvd1, rxd->read.rsvd2);
+8 −3
Original line number Diff line number Diff line
/*******************************************************************************
 *
 * Intel Ethernet Controller XL710 Family Linux Driver
 * Copyright(c) 2013 - 2015 Intel Corporation.
 * Copyright(c) 2013 - 2016 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
@@ -2785,10 +2785,15 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
		pf->auto_disable_flags |= I40E_FLAG_FD_ATR_ENABLED;
	}

	if (flags & I40E_PRIV_FLAGS_VEB_STATS)
	if ((flags & I40E_PRIV_FLAGS_VEB_STATS) &&
	    !(pf->flags & I40E_FLAG_VEB_STATS_ENABLED)) {
		pf->flags |= I40E_FLAG_VEB_STATS_ENABLED;
	else
		reset_required = true;
	} else if (!(flags & I40E_PRIV_FLAGS_VEB_STATS) &&
		   (pf->flags & I40E_FLAG_VEB_STATS_ENABLED)) {
		pf->flags &= ~I40E_FLAG_VEB_STATS_ENABLED;
		reset_required = true;
	}

	if ((flags & I40E_PRIV_FLAGS_HW_ATR_EVICT) &&
	    (pf->flags & I40E_FLAG_HW_ATR_EVICT_CAPABLE))
+35 −16
Original line number Diff line number Diff line
/*******************************************************************************
 *
 * Intel Ethernet Controller XL710 Family Linux Driver
 * Copyright(c) 2013 - 2015 Intel Corporation.
 * Copyright(c) 2013 - 2016 Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
@@ -46,7 +46,7 @@ static const char i40e_driver_string[] =

#define DRV_VERSION_MAJOR 1
#define DRV_VERSION_MINOR 4
#define DRV_VERSION_BUILD 12
#define DRV_VERSION_BUILD 13
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
	     __stringify(DRV_VERSION_MINOR) "." \
	     __stringify(DRV_VERSION_BUILD)    DRV_KERN
@@ -2168,6 +2168,10 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
		}
	}
out:
	/* if something went wrong then set the changed flag so we try again */
	if (retval)
		vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED;

	clear_bit(__I40E_CONFIG_BUSY, &vsi->state);
	return retval;
}
@@ -3253,14 +3257,15 @@ void i40e_irq_dynamic_disable_icr0(struct i40e_pf *pf)
/**
 * i40e_irq_dynamic_enable_icr0 - Enable default interrupt generation for icr0
 * @pf: board private structure
 * @clearpba: true when all pending interrupt events should be cleared
 **/
void i40e_irq_dynamic_enable_icr0(struct i40e_pf *pf)
void i40e_irq_dynamic_enable_icr0(struct i40e_pf *pf, bool clearpba)
{
	struct i40e_hw *hw = &pf->hw;
	u32 val;

	val = I40E_PFINT_DYN_CTL0_INTENA_MASK   |
	      I40E_PFINT_DYN_CTL0_CLEARPBA_MASK |
	      (clearpba ? I40E_PFINT_DYN_CTL0_CLEARPBA_MASK : 0) |
	      (I40E_ITR_NONE << I40E_PFINT_DYN_CTL0_ITR_INDX_SHIFT);

	wr32(hw, I40E_PFINT_DYN_CTL0, val);
@@ -3392,7 +3397,7 @@ static int i40e_vsi_enable_irq(struct i40e_vsi *vsi)
		for (i = 0; i < vsi->num_q_vectors; i++)
			i40e_irq_dynamic_enable(vsi, i);
	} else {
		i40e_irq_dynamic_enable_icr0(pf);
		i40e_irq_dynamic_enable_icr0(pf, true);
	}

	i40e_flush(&pf->hw);
@@ -3538,7 +3543,7 @@ static irqreturn_t i40e_intr(int irq, void *data)
	wr32(hw, I40E_PFINT_ICR0_ENA, ena_mask);
	if (!test_bit(__I40E_DOWN, &pf->state)) {
		i40e_service_event_schedule(pf);
		i40e_irq_dynamic_enable_icr0(pf);
		i40e_irq_dynamic_enable_icr0(pf, false);
	}

	return ret;
@@ -5008,8 +5013,7 @@ static int i40e_init_pf_dcb(struct i40e_pf *pf)
	int err = 0;

	/* Do not enable DCB for SW1 and SW2 images even if the FW is capable */
	if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
	    (pf->hw.aq.fw_maj_ver < 4))
	if (pf->flags & I40E_FLAG_NO_DCB_SUPPORT)
		goto out;

	/* Get the initial DCB configuration */
@@ -7113,6 +7117,7 @@ static void i40e_service_task(struct work_struct *work)
	}

	i40e_detect_recover_hung(pf);
	i40e_sync_filters_subtask(pf);
	i40e_reset_subtask(pf);
	i40e_handle_mdd_event(pf);
	i40e_vc_process_vflr_event(pf);
@@ -7854,7 +7859,7 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf)

	i40e_flush(hw);

	i40e_irq_dynamic_enable_icr0(pf);
	i40e_irq_dynamic_enable_icr0(pf, true);

	return err;
}
@@ -8420,11 +8425,25 @@ static int i40e_sw_init(struct i40e_pf *pf)
				 pf->hw.func_caps.fd_filters_best_effort;
	}

	if (((pf->hw.mac.type == I40E_MAC_X710) ||
	     (pf->hw.mac.type == I40E_MAC_XL710)) &&
	if (i40e_is_mac_710(&pf->hw) &&
	    (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 33)) ||
	    (pf->hw.aq.fw_maj_ver < 4)))
	    (pf->hw.aq.fw_maj_ver < 4))) {
		pf->flags |= I40E_FLAG_RESTART_AUTONEG;
		/* No DCB support  for FW < v4.33 */
		pf->flags |= I40E_FLAG_NO_DCB_SUPPORT;
	}

	/* Disable FW LLDP if FW < v4.3 */
	if (i40e_is_mac_710(&pf->hw) &&
	    (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 3)) ||
	    (pf->hw.aq.fw_maj_ver < 4)))
		pf->flags |= I40E_FLAG_STOP_FW_LLDP;

	/* Use the FW Set LLDP MIB API if FW > v4.40 */
	if (i40e_is_mac_710(&pf->hw) &&
	    (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver >= 40)) ||
	    (pf->hw.aq.fw_maj_ver >= 5)))
		pf->flags |= I40E_FLAG_USE_SET_LLDP_MIB;

	if (pf->hw.func_caps.vmdq) {
		pf->num_vmdq_vsis = I40E_DEFAULT_NUM_VMDQ_VSI;
@@ -8453,6 +8472,7 @@ static int i40e_sw_init(struct i40e_pf *pf)
			     I40E_FLAG_WB_ON_ITR_CAPABLE |
			     I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE |
			     I40E_FLAG_100M_SGMII_CAPABLE |
			     I40E_FLAG_USE_SET_LLDP_MIB |
			     I40E_FLAG_GENEVE_OFFLOAD_CAPABLE;
	} else if ((pf->hw.aq.api_maj_ver > 1) ||
		   ((pf->hw.aq.api_maj_ver == 1) &&
@@ -10050,13 +10070,13 @@ static int i40e_add_veb(struct i40e_veb *veb, struct i40e_vsi *vsi)
{
	struct i40e_pf *pf = veb->pf;
	bool is_default = veb->pf->cur_promisc;
	bool is_cloud = false;
	bool enable_stats = !!(pf->flags & I40E_FLAG_VEB_STATS_ENABLED);
	int ret;

	/* get a VEB from the hardware */
	ret = i40e_aq_add_veb(&pf->hw, veb->uplink_seid, vsi->seid,
			      veb->enabled_tc, is_default,
			      is_cloud, &veb->seid, NULL);
			      &veb->seid, enable_stats, NULL);
	if (ret) {
		dev_info(&pf->pdev->dev,
			 "couldn't add VEB, err %s aq_err %s\n",
@@ -10820,8 +10840,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
	 * Ignore error return codes because if it was already disabled via
	 * hardware settings this will fail
	 */
	if (((pf->hw.aq.fw_maj_ver == 4) && (pf->hw.aq.fw_min_ver < 3)) ||
	    (pf->hw.aq.fw_maj_ver < 4)) {
	if (pf->flags & I40E_FLAG_STOP_FW_LLDP) {
		dev_info(&pdev->dev, "Stopping firmware LLDP agent.\n");
		i40e_aq_stop_lldp(hw, true, NULL);
	}
Loading