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

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


Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2017-08-27

This series contains updates to i40e and i40evf only.

Sudheer updates code comments and state variable so that adminq_subtask
will have accutate information whenever it gets scheduled.

Mariusz stores information about FEC modes, to be used to printing link
states information, so that we do not need to call admin queue when
reporting link status.  Adds VF support for controlling VLAN tag
stripping via ethtool.

Jake provides the majority of changes in this series, starting with
increasing the size of the prefix buffer so that it can hold enough
characters for every possible input, which prevents snprintf truncation.
Fixed other string truncation errors/warnings produced by GCC 7.x.
Removed an unnecessary workaround for resetting XPS.  Fixed an issue
where there is a mismatched affinity mask value, so initialize the value
to cpu_possible_mask and invert the logic for checking incorrect CPU vs
IRQ affinity so that the exceptional case is handled at the check.
Removed ULTRA latency mode due to several issues found and will be
looking at better solution for small packet workloads.

Akeem fixes an issue where the incorrect flag was being used to set
promiscuous mode for unicast, which was enabling promiscuous mode only
for multicast instead of unicast.

Carolyn fixes an issue where an error return value is set, but this
value can be overwritten before we actually do exit the function.  So
remove the error code assignment and add code comments for better
understanding on why we do not need to set and return the error.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents cde66f24 742c9875
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -328,9 +328,9 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
			len = buf_len;
		/* write the full 16-byte chunks */
		if (hw->debug_mask & mask) {
			char prefix[20];
			char prefix[27];

			snprintf(prefix, 20,
			snprintf(prefix, sizeof(prefix),
				 "i40e %02x:%02x.%x: \t0x",
				 hw->bus.bus_id,
				 hw->bus.device,
@@ -2529,6 +2529,10 @@ i40e_status i40e_update_link_info(struct i40e_hw *hw)
		if (status)
			return status;

		hw->phy.link_info.req_fec_info =
			abilities.fec_cfg_curr_mod_ext_info &
			(I40E_AQ_REQUEST_FEC_KR | I40E_AQ_REQUEST_FEC_RS);

		memcpy(hw->phy.link_info.module_type, &abilities.module_type,
		       sizeof(hw->phy.link_info.module_type));
	}
+37 −21
Original line number Diff line number Diff line
@@ -2874,22 +2874,15 @@ static void i40e_vsi_free_rx_resources(struct i40e_vsi *vsi)
static void i40e_config_xps_tx_ring(struct i40e_ring *ring)
{
	struct i40e_vsi *vsi = ring->vsi;
	cpumask_var_t mask;

	if (!ring->q_vector || !ring->netdev)
		return;

	/* Single TC mode enable XPS */
	if (vsi->tc_config.numtc <= 1) {
		if (!test_and_set_bit(__I40E_TX_XPS_INIT_DONE, &ring->state))
	if ((vsi->tc_config.numtc <= 1) &&
	    !test_and_set_bit(__I40E_TX_XPS_INIT_DONE, &ring->state)) {
		netif_set_xps_queue(ring->netdev,
					    &ring->q_vector->affinity_mask,
				    get_cpu_mask(ring->q_vector->v_idx),
				    ring->queue_index);
	} else if (alloc_cpumask_var(&mask, GFP_KERNEL)) {
		/* Disable XPS to allow selection based on TC */
		bitmap_zero(cpumask_bits(mask), nr_cpumask_bits);
		netif_set_xps_queue(ring->netdev, mask, ring->queue_index);
		free_cpumask_var(mask);
	}

	/* schedule our worker thread which will take care of
@@ -3513,8 +3506,10 @@ static int i40e_vsi_request_irq_msix(struct i40e_vsi *vsi, char *basename)
		q_vector->affinity_notify.notify = i40e_irq_affinity_notify;
		q_vector->affinity_notify.release = i40e_irq_affinity_release;
		irq_set_affinity_notifier(irq_num, &q_vector->affinity_notify);
		/* assign the mask for this irq */
		irq_set_affinity_hint(irq_num, &q_vector->affinity_mask);
		/* get_cpu_mask returns a static constant mask with
		 * a permanent lifetime so it's ok to use here.
		 */
		irq_set_affinity_hint(irq_num, get_cpu_mask(q_vector->v_idx));
	}

	vsi->irqs_ready = true;
@@ -4296,7 +4291,7 @@ static void i40e_vsi_free_irq(struct i40e_vsi *vsi)

			/* clear the affinity notifier in the IRQ descriptor */
			irq_set_affinity_notifier(irq_num, NULL);
			/* clear the affinity_mask in the IRQ descriptor */
			/* remove our suggested affinity mask for this IRQ */
			irq_set_affinity_hint(irq_num, NULL);
			synchronize_irq(irq_num);
			free_irq(irq_num, vsi->q_vectors[i]);
@@ -5354,6 +5349,7 @@ void i40e_print_link_message(struct i40e_vsi *vsi, bool isup)
	char *speed = "Unknown";
	char *fc = "Unknown";
	char *fec = "";
	char *req_fec = "";
	char *an = "";

	new_speed = vsi->back->hw.phy.link_info.link_speed;
@@ -5415,6 +5411,7 @@ void i40e_print_link_message(struct i40e_vsi *vsi, bool isup)
	}

	if (vsi->back->hw.phy.link_info.link_speed == I40E_LINK_SPEED_25GB) {
		req_fec = ", Requested FEC: None";
		fec = ", FEC: None";
		an = ", Autoneg: False";

@@ -5427,10 +5424,22 @@ void i40e_print_link_message(struct i40e_vsi *vsi, bool isup)
		else if (vsi->back->hw.phy.link_info.fec_info &
			 I40E_AQ_CONFIG_FEC_RS_ENA)
			fec = ", FEC: CL108 RS-FEC";

		/* 'CL108 RS-FEC' should be displayed when RS is requested, or
		 * both RS and FC are requested
		 */
		if (vsi->back->hw.phy.link_info.req_fec_info &
		    (I40E_AQ_REQUEST_FEC_KR | I40E_AQ_REQUEST_FEC_RS)) {
			if (vsi->back->hw.phy.link_info.req_fec_info &
			    I40E_AQ_REQUEST_FEC_RS)
				req_fec = ", Requested FEC: CL108 RS-FEC";
			else
				req_fec = ", Requested FEC: CL74 FC-FEC/BASE-R";
		}
	}

	netdev_info(vsi->netdev, "NIC Link is Up, %sbps Full Duplex%s%s, Flow Control: %s\n",
		    speed, fec, an, fc);
	netdev_info(vsi->netdev, "NIC Link is Up, %sbps Full Duplex%s%s%s, Flow Control: %s\n",
		    speed, req_fec, fec, an, fc);
}

/**
@@ -8228,7 +8237,7 @@ static int i40e_vsi_alloc_q_vector(struct i40e_vsi *vsi, int v_idx, int cpu)

	q_vector->vsi = vsi;
	q_vector->v_idx = v_idx;
	cpumask_set_cpu(cpu, &q_vector->affinity_mask);
	cpumask_copy(&q_vector->affinity_mask, cpu_possible_mask);

	if (vsi->netdev)
		netif_napi_add(vsi->netdev, &q_vector->napi,
@@ -9690,8 +9699,13 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
		i40e_add_mac_filter(vsi, mac_addr);
		spin_unlock_bh(&vsi->mac_filter_hash_lock);
	} else {
		/* relate the VSI_VMDQ name to the VSI_MAIN name */
		snprintf(netdev->name, IFNAMSIZ, "%sv%%d",
		/* Relate the VSI_VMDQ name to the VSI_MAIN name. Note that we
		 * are still limited by IFNAMSIZ, but we're adding 'v%d\0' to
		 * the end, which is 4 bytes long, so force truncation of the
		 * original name by IFNAMSIZ - 4
		 */
		snprintf(netdev->name, IFNAMSIZ, "%.*sv%%d",
			 IFNAMSIZ - 4,
			 pf->vsi[pf->lan_vsi]->netdev->name);
		random_ether_addr(mac_addr);

@@ -9865,13 +9879,15 @@ static int i40e_add_vsi(struct i40e_vsi *vsi)
			 */
			ret = i40e_vsi_config_tc(vsi, enabled_tc);
			if (ret) {
				/* Single TC condition is not fatal,
				 * message and continue
				 */
				dev_info(&pf->pdev->dev,
					 "failed to configure TCs for main VSI tc_map 0x%08x, err %s aq_err %s\n",
					 enabled_tc,
					 i40e_stat_str(&pf->hw, ret),
					 i40e_aq_str(&pf->hw,
						    pf->hw.aq.asq_last_status));
				ret = -ENOENT;
			}
		}
		break;
+8 −2
Original line number Diff line number Diff line
@@ -755,7 +755,11 @@ i40e_status i40e_nvmupd_command(struct i40e_hw *hw,

	/* Acquire lock to prevent race condition where adminq_task
	 * can execute after i40e_nvmupd_nvm_read/write but before state
	 * variables (nvm_wait_opcode, nvm_release_on_done) are updated
	 * variables (nvm_wait_opcode, nvm_release_on_done) are updated.
	 *
	 * During NVMUpdate, it is observed that lock could be held for
	 * ~5ms for most commands. However lock is held for ~60ms for
	 * NVMUPD_CSUM_LCB command.
	 */
	mutex_lock(&hw->aq.arq_mutex);
	switch (hw->nvmupd_state) {
@@ -778,7 +782,8 @@ i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
		 */
		if (cmd->offset == 0xffff) {
			i40e_nvmupd_check_wait_event(hw, hw->nvm_wait_opcode);
			return 0;
			status = 0;
			goto exit;
		}

		status = I40E_ERR_NOT_READY;
@@ -793,6 +798,7 @@ i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
		*perrno = -ESRCH;
		break;
	}
exit:
	mutex_unlock(&hw->aq.arq_mutex);
	return status;
}
+38 −40
Original line number Diff line number Diff line
@@ -959,19 +959,31 @@ void i40e_force_wb(struct i40e_vsi *vsi, struct i40e_q_vector *q_vector)
static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
{
	enum i40e_latency_range new_latency_range = rc->latency_range;
	struct i40e_q_vector *qv = rc->ring->q_vector;
	u32 new_itr = rc->itr;
	int bytes_per_int;
	int usecs;
	unsigned int usecs, estimated_usecs;

	if (rc->total_packets == 0 || !rc->itr)
		return false;

	usecs = (rc->itr << 1) * ITR_COUNTDOWN_START;
	bytes_per_int = rc->total_bytes / usecs;

	/* The calculations in this algorithm depend on interrupts actually
	 * firing at the ITR rate. This may not happen if the packet rate is
	 * really low, or if we've been napi polling. Check to make sure
	 * that's not the case before we continue.
	 */
	estimated_usecs = jiffies_to_usecs(jiffies - rc->last_itr_update);
	if (estimated_usecs > usecs) {
		new_latency_range = I40E_LOW_LATENCY;
		goto reset_latency;
	}

	/* simple throttlerate management
	 *   0-10MB/s   lowest (50000 ints/s)
	 *  10-20MB/s   low    (20000 ints/s)
	 *  20-1249MB/s bulk   (18000 ints/s)
	 *  > 40000 Rx packets per second (8000 ints/s)
	 *
	 * The math works out because the divisor is in 10^(-6) which
	 * turns the bytes/us input value into MB/s values, but
@@ -979,9 +991,6 @@ static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
	 * are in 2 usec increments in the ITR registers, and make sure
	 * to use the smoothed values that the countdown timer gives us.
	 */
	usecs = (rc->itr << 1) * ITR_COUNTDOWN_START;
	bytes_per_int = rc->total_bytes / usecs;

	switch (new_latency_range) {
	case I40E_LOWEST_LATENCY:
		if (bytes_per_int > 10)
@@ -994,24 +1003,13 @@ static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
			new_latency_range = I40E_LOWEST_LATENCY;
		break;
	case I40E_BULK_LATENCY:
	case I40E_ULTRA_LATENCY:
	default:
		if (bytes_per_int <= 20)
			new_latency_range = I40E_LOW_LATENCY;
		break;
	}

	/* this is to adjust RX more aggressively when streaming small
	 * packets.  The value of 40000 was picked as it is just beyond
	 * what the hardware can receive per second if in low latency
	 * mode.
	 */
#define RX_ULTRA_PACKET_RATE 40000

	if ((((rc->total_packets * 1000000) / usecs) > RX_ULTRA_PACKET_RATE) &&
	    (&qv->rx == rc))
		new_latency_range = I40E_ULTRA_LATENCY;

reset_latency:
	rc->latency_range = new_latency_range;

	switch (new_latency_range) {
@@ -1024,21 +1022,18 @@ static bool i40e_set_new_dynamic_itr(struct i40e_ring_container *rc)
	case I40E_BULK_LATENCY:
		new_itr = I40E_ITR_18K;
		break;
	case I40E_ULTRA_LATENCY:
		new_itr = I40E_ITR_8K;
		break;
	default:
		break;
	}

	rc->total_bytes = 0;
	rc->total_packets = 0;
	rc->last_itr_update = jiffies;

	if (new_itr != rc->itr) {
		rc->itr = new_itr;
		return true;
	}

	return false;
}

@@ -2243,6 +2238,12 @@ static inline void i40e_update_enable_itr(struct i40e_vsi *vsi,
	int idx = q_vector->v_idx;
	int rx_itr_setting, tx_itr_setting;

	/* If we don't have MSIX, then we only need to re-enable icr0 */
	if (!(vsi->back->flags & I40E_FLAG_MSIX_ENABLED)) {
		i40e_irq_dynamic_enable_icr0(vsi->back, false);
		return;
	}

	vector = (q_vector->v_idx + vsi->base_vector);

	/* avoid dynamic calculation if in countdown mode OR if
@@ -2363,7 +2364,6 @@ int i40e_napi_poll(struct napi_struct *napi, int budget)

	/* If work not completed, return budget and polling will return */
	if (!clean_complete) {
		const cpumask_t *aff_mask = &q_vector->affinity_mask;
		int cpu_id = smp_processor_id();

		/* It is possible that the interrupt affinity has changed but,
@@ -2373,8 +2373,16 @@ int i40e_napi_poll(struct napi_struct *napi, int budget)
		 * continue to poll, otherwise we must stop polling so the
		 * interrupt can move to the correct cpu.
		 */
		if (likely(cpumask_test_cpu(cpu_id, aff_mask) ||
			   !(vsi->back->flags & I40E_FLAG_MSIX_ENABLED))) {
		if (!cpumask_test_cpu(cpu_id, &q_vector->affinity_mask)) {
			/* Tell napi that we are done polling */
			napi_complete_done(napi, work_done);

			/* Force an interrupt */
			i40e_force_wb(vsi, q_vector);

			/* Return budget-1 so that polling stops */
			return budget - 1;
		}
tx_only:
		if (arm_wb) {
			q_vector->tx.ring[0].tx_stats.tx_force_wb++;
@@ -2382,7 +2390,6 @@ int i40e_napi_poll(struct napi_struct *napi, int budget)
		}
		return budget;
	}
	}

	if (vsi->back->flags & I40E_TXR_FLAGS_WB_ON_ITR)
		q_vector->arm_wb_state = false;
@@ -2390,15 +2397,6 @@ int i40e_napi_poll(struct napi_struct *napi, int budget)
	/* Work is done so exit the polling mode and re-enable the interrupt */
	napi_complete_done(napi, work_done);

	/* If we're prematurely stopping polling to fix the interrupt
	 * affinity we want to make sure polling starts back up so we
	 * issue a call to i40e_force_wb which triggers a SW interrupt.
	 */
	if (!clean_complete)
		i40e_force_wb(vsi, q_vector);
	else if (!(vsi->back->flags & I40E_FLAG_MSIX_ENABLED))
		i40e_irq_dynamic_enable_icr0(vsi->back, false);
	else
	i40e_update_enable_itr(vsi, q_vector);

	return min(work_done, budget - 1);
+1 −1
Original line number Diff line number Diff line
@@ -454,7 +454,6 @@ enum i40e_latency_range {
	I40E_LOWEST_LATENCY = 0,
	I40E_LOW_LATENCY = 1,
	I40E_BULK_LATENCY = 2,
	I40E_ULTRA_LATENCY = 3,
};

struct i40e_ring_container {
@@ -462,6 +461,7 @@ struct i40e_ring_container {
	struct i40e_ring *ring;
	unsigned int total_bytes;	/* total bytes processed this int */
	unsigned int total_packets;	/* total packets processed this int */
	unsigned long last_itr_update;	/* jiffies of last ITR update */
	u16 count;
	enum i40e_latency_range latency_range;
	u16 itr;
Loading