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

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


Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2019-06-14

This series contains updates to i40e only.

Aleksandr adds stub functions for Energy Efficient Ethernet (EEE) to
currently report that it is not supported in i40e.  Fixed up the Link
Layer Detection Protocol (LLDP) code to ensure we do not set the LLDP
flag too early before we ensure that we have a successful start.  This
also will prevent needles restarting of the device if LLDP did not
change its state with an unsuccessful start.

Piotr bumps up the amount of VLANs that an untrusted VF can implement,
from 8 VLANs to 16.  Adds checks to the Virtual Embedded Bridge (VEB)
and channel arrays so access does not exceed the boundary and ensure the
index is below the maximum.  Fixed an issue in the driver where we were
not checking the response from the LLDP flag and were returned success
no matter what the value of the response was.

Mitch fixes a variable counter, which can be negative in value so make
it an integer instead of an unsigned-integer.

Doug improves the admin queue log granularity by making it possible to
log only the admin queue descriptors without the entire admin queue
message buffers.

Sergey fixes up the virtchnl code by removing duplicate checks, ensure
the variable type is correct when comparing integers, enhance error and
warning messages to include useful information.

Adam fixes a potential kernel panic when the i40e driver was being bound
to a non-i40e port by adding a check on the BAR size to ensure it is
large enough by reading the highest register.

Jake fixes a statistics error in the "transmit errors" stat, which was
being calculated twice.

Gustavo A. R. Silva adds a fall-through code comment to help with
compiler checks.

v2: Fixed the return values wrapped in parenthesis in patch 8 and
    cleaned up the commit message in patch 12 so the Gustavo does
    not repeat himself.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f48d2cce 514af5f0
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -675,7 +675,7 @@ static u16 i40e_clean_asq(struct i40e_hw *hw)
	desc = I40E_ADMINQ_DESC(*asq, ntc);
	details = I40E_ADMINQ_DETAILS(*asq, ntc);
	while (rd32(hw, hw->aq.asq.head) != ntc) {
		i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
		i40e_debug(hw, I40E_DEBUG_AQ_COMMAND,
			   "ntc %d head %d.\n", ntc, rd32(hw, hw->aq.asq.head));

		if (details->callback) {
@@ -835,7 +835,7 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
	}

	/* bump the tail */
	i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: desc and buffer:\n");
	i40e_debug(hw, I40E_DEBUG_AQ_COMMAND, "AQTX: desc and buffer:\n");
	i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc_on_ring,
		      buff, buff_size);
	(hw->aq.asq.next_to_use)++;
@@ -886,7 +886,7 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
		hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval;
	}

	i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
	i40e_debug(hw, I40E_DEBUG_AQ_COMMAND,
		   "AQTX: desc and buffer writeback:\n");
	i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff, buff_size);

@@ -995,7 +995,7 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
		memcpy(e->msg_buf, hw->aq.arq.r.arq_bi[desc_idx].va,
		       e->msg_len);

	i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQRX: desc and buffer:\n");
	i40e_debug(hw, I40E_DEBUG_AQ_COMMAND, "AQRX: desc and buffer:\n");
	i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf,
		      hw->aq.arq_buf_size);

+21 −19
Original line number Diff line number Diff line
@@ -281,37 +281,40 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
		   void *buffer, u16 buf_len)
{
	struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc;
	u32 effective_mask = hw->debug_mask & mask;
	char prefix[27];
	u16 len;
	u8 *buf = (u8 *)buffer;

	if ((!(mask & hw->debug_mask)) || (desc == NULL))
	if (!effective_mask || !desc)
		return;

	len = le16_to_cpu(aq_desc->datalen);

	i40e_debug(hw, mask,
	i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR,
		   "AQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n",
		   le16_to_cpu(aq_desc->opcode),
		   le16_to_cpu(aq_desc->flags),
		   le16_to_cpu(aq_desc->datalen),
		   le16_to_cpu(aq_desc->retval));
	i40e_debug(hw, mask, "\tcookie (h,l) 0x%08X 0x%08X\n",
	i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR,
		   "\tcookie (h,l) 0x%08X 0x%08X\n",
		   le32_to_cpu(aq_desc->cookie_high),
		   le32_to_cpu(aq_desc->cookie_low));
	i40e_debug(hw, mask, "\tparam (0,1)  0x%08X 0x%08X\n",
	i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR,
		   "\tparam (0,1)  0x%08X 0x%08X\n",
		   le32_to_cpu(aq_desc->params.internal.param0),
		   le32_to_cpu(aq_desc->params.internal.param1));
	i40e_debug(hw, mask, "\taddr (h,l)   0x%08X 0x%08X\n",
	i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR,
		   "\taddr (h,l)   0x%08X 0x%08X\n",
		   le32_to_cpu(aq_desc->params.external.addr_high),
		   le32_to_cpu(aq_desc->params.external.addr_low));

	if ((buffer != NULL) && (aq_desc->datalen != 0)) {
	if (buffer && buf_len != 0 && len != 0 &&
	    (effective_mask & I40E_DEBUG_AQ_DESC_BUFFER)) {
		i40e_debug(hw, mask, "AQ CMD Buffer:\n");
		if (buf_len < len)
			len = buf_len;
		/* write the full 16-byte chunks */
		if (hw->debug_mask & mask) {
			char prefix[27];

		snprintf(prefix, sizeof(prefix),
			 "i40e %02x:%02x.%x: \t0x",
@@ -323,7 +326,6 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
			       16, 1, buf, len, false);
	}
}
}

/**
 * i40e_check_asq_alive
+60 −22
Original line number Diff line number Diff line
@@ -4852,9 +4852,12 @@ static u32 i40e_get_priv_flags(struct net_device *dev)
static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
{
	struct i40e_netdev_priv *np = netdev_priv(dev);
	u64 orig_flags, new_flags, changed_flags;
	enum i40e_admin_queue_err adq_err;
	struct i40e_vsi *vsi = np->vsi;
	struct i40e_pf *pf = vsi->back;
	u64 orig_flags, new_flags, changed_flags;
	bool is_reset_needed;
	i40e_status status;
	u32 i, j;

	orig_flags = READ_ONCE(pf->flags);
@@ -4898,6 +4901,10 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
flags_complete:
	changed_flags = orig_flags ^ new_flags;

	is_reset_needed = !!(changed_flags & (I40E_FLAG_VEB_STATS_ENABLED |
		I40E_FLAG_LEGACY_RX | I40E_FLAG_SOURCE_PRUNING_DISABLED |
		I40E_FLAG_DISABLE_FW_LLDP));

	/* Before we finalize any flag changes, we need to perform some
	 * checks to ensure that the changes are supported and safe.
	 */
@@ -4932,13 +4939,6 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
		return -EOPNOTSUPP;
	}

	/* Now that we've checked to ensure that the new flags are valid, load
	 * them into place. Since we only modify flags either (a) during
	 * initialization or (b) while holding the RTNL lock, we don't need
	 * anything fancy here.
	 */
	pf->flags = new_flags;

	/* Process any additional changes needed as a result of flag changes.
	 * The changed_flags value reflects the list of bits that were
	 * changed in the code above.
@@ -4946,7 +4946,7 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)

	/* Flush current ATR settings if ATR was disabled */
	if ((changed_flags & I40E_FLAG_FD_ATR_ENABLED) &&
	    !(pf->flags & I40E_FLAG_FD_ATR_ENABLED)) {
	    !(new_flags & I40E_FLAG_FD_ATR_ENABLED)) {
		set_bit(__I40E_FD_ATR_AUTO_DISABLED, pf->state);
		set_bit(__I40E_FD_FLUSH_REQUESTED, pf->state);
	}
@@ -4955,7 +4955,7 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
		u16 sw_flags = 0, valid_flags = 0;
		int ret;

		if (!(pf->flags & I40E_FLAG_TRUE_PROMISC_SUPPORT))
		if (!(new_flags & I40E_FLAG_TRUE_PROMISC_SUPPORT))
			sw_flags = I40E_AQ_SET_SWITCH_CFG_PROMISC;
		valid_flags = I40E_AQ_SET_SWITCH_CFG_PROMISC;
		ret = i40e_aq_set_switch_config(&pf->hw, sw_flags, valid_flags,
@@ -4974,13 +4974,13 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
	    (changed_flags & I40E_FLAG_BASE_R_FEC)) {
		u8 fec_cfg = 0;

		if (pf->flags & I40E_FLAG_RS_FEC &&
		    pf->flags & I40E_FLAG_BASE_R_FEC) {
		if (new_flags & I40E_FLAG_RS_FEC &&
		    new_flags & I40E_FLAG_BASE_R_FEC) {
			fec_cfg = I40E_AQ_SET_FEC_AUTO;
		} else if (pf->flags & I40E_FLAG_RS_FEC) {
		} else if (new_flags & I40E_FLAG_RS_FEC) {
			fec_cfg = (I40E_AQ_SET_FEC_REQUEST_RS |
				   I40E_AQ_SET_FEC_ABILITY_RS);
		} else if (pf->flags & I40E_FLAG_BASE_R_FEC) {
		} else if (new_flags & I40E_FLAG_BASE_R_FEC) {
			fec_cfg = (I40E_AQ_SET_FEC_REQUEST_KR |
				   I40E_AQ_SET_FEC_ABILITY_KR);
		}
@@ -4988,14 +4988,14 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
			dev_warn(&pf->pdev->dev, "Cannot change FEC config\n");
	}

	if ((changed_flags & pf->flags &
	if ((changed_flags & new_flags &
	     I40E_FLAG_LINK_DOWN_ON_CLOSE_ENABLED) &&
	    (pf->flags & I40E_FLAG_MFP_ENABLED))
	    (new_flags & I40E_FLAG_MFP_ENABLED))
		dev_warn(&pf->pdev->dev,
			 "Turning on link-down-on-close flag may affect other partitions\n");

	if (changed_flags & I40E_FLAG_DISABLE_FW_LLDP) {
		if (pf->flags & I40E_FLAG_DISABLE_FW_LLDP) {
		if (new_flags & I40E_FLAG_DISABLE_FW_LLDP) {
			struct i40e_dcbx_config *dcbcfg;

			i40e_aq_stop_lldp(&pf->hw, true, false, NULL);
@@ -5013,17 +5013,43 @@ static int i40e_set_priv_flags(struct net_device *dev, u32 flags)
			dcbcfg->pfc.willing = 1;
			dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
		} else {
			i40e_aq_start_lldp(&pf->hw, false, NULL);
			status = i40e_aq_start_lldp(&pf->hw, false, NULL);
			if (status) {
				adq_err = pf->hw.aq.asq_last_status;
				switch (adq_err) {
				case I40E_AQ_RC_EEXIST:
					dev_warn(&pf->pdev->dev,
						 "FW LLDP agent is already running\n");
					is_reset_needed = false;
					break;
				case I40E_AQ_RC_EPERM:
					dev_warn(&pf->pdev->dev,
						 "Device configuration forbids SW from starting the LLDP agent.\n");
					return -EINVAL;
				default:
					dev_warn(&pf->pdev->dev,
						 "Starting FW LLDP agent failed: error: %s, %s\n",
						 i40e_stat_str(&pf->hw,
							       status),
						 i40e_aq_str(&pf->hw,
							     adq_err));
					return -EINVAL;
				}
			}
		}
	}

	/* Now that we've checked to ensure that the new flags are valid, load
	 * them into place. Since we only modify flags either (a) during
	 * initialization or (b) while holding the RTNL lock, we don't need
	 * anything fancy here.
	 */
	pf->flags = new_flags;

	/* Issue reset to cause things to take effect, as additional bits
	 * are added we will need to create a mask of bits requiring reset
	 */
	if (changed_flags & (I40E_FLAG_VEB_STATS_ENABLED |
			     I40E_FLAG_LEGACY_RX |
			     I40E_FLAG_SOURCE_PRUNING_DISABLED |
			     I40E_FLAG_DISABLE_FW_LLDP))
	if (is_reset_needed)
		i40e_do_reset(pf, BIT(__I40E_PF_RESET_REQUESTED), true);

	return 0;
@@ -5181,6 +5207,16 @@ static int i40e_get_module_eeprom(struct net_device *netdev,
	return 0;
}

static int i40e_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
{
	return -EOPNOTSUPP;
}

static int i40e_set_eee(struct net_device *netdev, struct ethtool_eee *edata)
{
	return -EOPNOTSUPP;
}

static const struct ethtool_ops i40e_ethtool_recovery_mode_ops = {
	.set_eeprom		= i40e_set_eeprom,
	.get_eeprom_len		= i40e_get_eeprom_len,
@@ -5208,6 +5244,8 @@ static const struct ethtool_ops i40e_ethtool_ops = {
	.set_rxnfc		= i40e_set_rxnfc,
	.self_test		= i40e_diag_test,
	.get_strings		= i40e_get_strings,
	.get_eee		= i40e_get_eee,
	.set_eee		= i40e_set_eee,
	.set_phys_id		= i40e_set_phys_id,
	.get_sset_count		= i40e_get_sset_count,
	.get_ethtool_stats	= i40e_get_ethtool_stats,
+18 −9
Original line number Diff line number Diff line
@@ -636,9 +636,6 @@ void i40e_update_eth_stats(struct i40e_vsi *vsi)
	i40e_stat_update32(hw, I40E_GLV_RUPP(stat_idx),
			   vsi->stat_offsets_loaded,
			   &oes->rx_unknown_protocol, &es->rx_unknown_protocol);
	i40e_stat_update32(hw, I40E_GLV_TEPC(stat_idx),
			   vsi->stat_offsets_loaded,
			   &oes->tx_errors, &es->tx_errors);

	i40e_stat_update48(hw, I40E_GLV_GORCH(stat_idx),
			   I40E_GLV_GORCL(stat_idx),
@@ -8570,7 +8567,7 @@ static void i40e_link_event(struct i40e_pf *pf)
	/* Notify the base of the switch tree connected to
	 * the link.  Floating VEBs are not notified.
	 */
	if (pf->lan_veb != I40E_NO_VEB && pf->veb[pf->lan_veb])
	if (pf->lan_veb < I40E_MAX_VEB && pf->veb[pf->lan_veb])
		i40e_veb_link_event(pf->veb[pf->lan_veb], new_link);
	else
		i40e_vsi_link_event(vsi, new_link);
@@ -12519,7 +12516,7 @@ int i40e_is_vsi_uplink_mode_veb(struct i40e_vsi *vsi)
	struct i40e_pf *pf = vsi->back;

	/* Uplink is not a bridge so default to VEB */
	if (vsi->veb_idx == I40E_NO_VEB)
	if (vsi->veb_idx >= I40E_MAX_VEB)
		return 1;

	veb = pf->veb[vsi->veb_idx];
@@ -13577,7 +13574,7 @@ static void i40e_setup_pf_switch_element(struct i40e_pf *pf,
		/* Main VEB? */
		if (uplink_seid != pf->mac_seid)
			break;
		if (pf->lan_veb == I40E_NO_VEB) {
		if (pf->lan_veb >= I40E_MAX_VEB) {
			int v;

			/* find existing or else empty VEB */
@@ -13587,13 +13584,15 @@ static void i40e_setup_pf_switch_element(struct i40e_pf *pf,
					break;
				}
			}
			if (pf->lan_veb == I40E_NO_VEB) {
			if (pf->lan_veb >= I40E_MAX_VEB) {
				v = i40e_veb_mem_alloc(pf);
				if (v < 0)
					break;
				pf->lan_veb = v;
			}
		}
		if (pf->lan_veb >= I40E_MAX_VEB)
			break;

		pf->veb[pf->lan_veb]->seid = seid;
		pf->veb[pf->lan_veb]->uplink_seid = pf->mac_seid;
@@ -13747,7 +13746,7 @@ static int i40e_setup_pf_switch(struct i40e_pf *pf, bool reinit)
		/* Set up the PF VSI associated with the PF's main VSI
		 * that is already in the HW switch
		 */
		if (pf->lan_veb != I40E_NO_VEB && pf->veb[pf->lan_veb])
		if (pf->lan_veb < I40E_MAX_VEB && pf->veb[pf->lan_veb])
			uplink_seid = pf->veb[pf->lan_veb]->seid;
		else
			uplink_seid = pf->mac_seid;
@@ -14203,7 +14202,17 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)

	pf->ioremap_len = min_t(int, pci_resource_len(pdev, 0),
				I40E_MAX_CSR_SPACE);

	/* We believe that the highest register to read is
	 * I40E_GLGEN_STAT_CLEAR, so we check if the BAR size
	 * is not less than that before mapping to prevent a
	 * kernel panic.
	 */
	if (pf->ioremap_len < I40E_GLGEN_STAT_CLEAR) {
		dev_err(&pdev->dev, "Cannot map registers, bar size 0x%X too small, aborting\n",
			pf->ioremap_len);
		err = -ENOMEM;
		goto err_ioremap;
	}
	hw->hw_addr = ioremap(pci_resource_start(pdev, 0), pf->ioremap_len);
	if (!hw->hw_addr) {
		err = -EIO;
+1 −1
Original line number Diff line number Diff line
@@ -774,7 +774,7 @@ void i40e_detect_recover_hung(struct i40e_vsi *vsi)
static bool i40e_clean_tx_irq(struct i40e_vsi *vsi,
			      struct i40e_ring *tx_ring, int napi_budget)
{
	u16 i = tx_ring->next_to_clean;
	int i = tx_ring->next_to_clean;
	struct i40e_tx_buffer *tx_buf;
	struct i40e_tx_desc *tx_head;
	struct i40e_tx_desc *tx_desc;
Loading