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


Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates 2020-01-17

This series contains updates to igc, i40e, fm10k and ice drivers.

Sasha fixes a typo in a code comment that referred to silicon that is
not supported in the igc driver.  Cleaned up a defined that was not
being used.  Added support for another i225 SKU which does not have an
NVM.  Added support for TCP segmentation offload (TSO) into igc.  Added
support for PHY power management control to provide a reliable and
accurate indication of PHY reset completion.

Jake adds support for the new txqueue parameter to the transmit timeout
function in fm10k which reduces the code complexity when determining
which transmit queue is stuck.

Julio Faracco makes the similar changes that Jake did for fm10k, for
i40e and ice drivers.  Added support for the new txqueue parameter in
the transmit timeout functions for i40e and ice.

Colin Ian King cleans up a redundant initialization of a local variable.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 56f200c7 102d412a
Loading
Loading
Loading
Loading
+10 −7
Original line number Diff line number Diff line
@@ -696,21 +696,24 @@ static netdev_tx_t fm10k_xmit_frame(struct sk_buff *skb, struct net_device *dev)
/**
 * fm10k_tx_timeout - Respond to a Tx Hang
 * @netdev: network interface device structure
 * @txqueue: the index of the Tx queue that timed out
 **/
static void fm10k_tx_timeout(struct net_device *netdev, unsigned int txqueue)
{
	struct fm10k_intfc *interface = netdev_priv(netdev);
	struct fm10k_ring *tx_ring;
	bool real_tx_hang = false;
	int i;

#define TX_TIMEO_LIMIT 16000
	for (i = 0; i < interface->num_tx_queues; i++) {
		struct fm10k_ring *tx_ring = interface->tx_ring[i];
	if (txqueue >= interface->num_tx_queues) {
		WARN(1, "invalid Tx queue index %d", txqueue);
		return;
	}

	tx_ring = interface->tx_ring[txqueue];
	if (check_for_tx_hang(tx_ring) && fm10k_check_tx_hang(tx_ring))
		real_tx_hang = true;
	}

#define TX_TIMEO_LIMIT 16000
	if (real_tx_hang) {
		fm10k_tx_timeout_reset(interface);
	} else {
+11 −30
Original line number Diff line number Diff line
@@ -307,40 +307,21 @@ static void i40e_tx_timeout(struct net_device *netdev, unsigned int txqueue)
	struct i40e_vsi *vsi = np->vsi;
	struct i40e_pf *pf = vsi->back;
	struct i40e_ring *tx_ring = NULL;
	unsigned int i, hung_queue = 0;
	unsigned int i;
	u32 head, val;

	pf->tx_timeout_count++;

	/* find the stopped queue the same way the stack does */
	for (i = 0; i < netdev->num_tx_queues; i++) {
		struct netdev_queue *q;
		unsigned long trans_start;

		q = netdev_get_tx_queue(netdev, i);
		trans_start = q->trans_start;
		if (netif_xmit_stopped(q) &&
		    time_after(jiffies,
			       (trans_start + netdev->watchdog_timeo))) {
			hung_queue = i;
			break;
		}
	}

	if (i == netdev->num_tx_queues) {
		netdev_info(netdev, "tx_timeout: no netdev hung queue found\n");
	} else {
		/* now that we have an index, find the tx_ring struct */
	/* with txqueue index, find the tx_ring struct */
	for (i = 0; i < vsi->num_queue_pairs; i++) {
		if (vsi->tx_rings[i] && vsi->tx_rings[i]->desc) {
				if (hung_queue ==
			if (txqueue ==
			    vsi->tx_rings[i]->queue_index) {
				tx_ring = vsi->tx_rings[i];
				break;
			}
		}
	}
	}

	if (time_after(jiffies, (pf->tx_timeout_last_recovery + HZ*20)))
		pf->tx_timeout_recovery_level = 1;  /* reset after some time */
@@ -363,14 +344,14 @@ static void i40e_tx_timeout(struct net_device *netdev, unsigned int txqueue)
			val = rd32(&pf->hw, I40E_PFINT_DYN_CTL0);

		netdev_info(netdev, "tx_timeout: VSI_seid: %d, Q %d, NTC: 0x%x, HWB: 0x%x, NTU: 0x%x, TAIL: 0x%x, INT: 0x%x\n",
			    vsi->seid, hung_queue, tx_ring->next_to_clean,
			    vsi->seid, txqueue, tx_ring->next_to_clean,
			    head, tx_ring->next_to_use,
			    readl(tx_ring->tail), val);
	}

	pf->tx_timeout_last_recovery = jiffies;
	netdev_info(netdev, "tx_timeout recovery level %d, hung_queue %d\n",
		    pf->tx_timeout_recovery_level, hung_queue);
	netdev_info(netdev, "tx_timeout recovery level %d, txqueue %d\n",
		    pf->tx_timeout_recovery_level, txqueue);

	switch (pf->tx_timeout_recovery_level) {
	case 1:
+11 −30
Original line number Diff line number Diff line
@@ -5086,33 +5086,14 @@ static void ice_tx_timeout(struct net_device *netdev, unsigned int txqueue)
	struct ice_ring *tx_ring = NULL;
	struct ice_vsi *vsi = np->vsi;
	struct ice_pf *pf = vsi->back;
	int hung_queue = -1;
	u32 i;

	pf->tx_timeout_count++;

	/* find the stopped queue the same way dev_watchdog() does */
	for (i = 0; i < netdev->num_tx_queues; i++) {
		unsigned long trans_start;
		struct netdev_queue *q;

		q = netdev_get_tx_queue(netdev, i);
		trans_start = q->trans_start;
		if (netif_xmit_stopped(q) &&
		    time_after(jiffies,
			       trans_start + netdev->watchdog_timeo)) {
			hung_queue = i;
			break;
		}
	}

	if (i == netdev->num_tx_queues)
		netdev_info(netdev, "tx_timeout: no netdev hung queue found\n");
	else
	/* now that we have an index, find the tx_ring struct */
	for (i = 0; i < vsi->num_txq; i++)
		if (vsi->tx_rings[i] && vsi->tx_rings[i]->desc)
				if (hung_queue == vsi->tx_rings[i]->q_index) {
			if (txqueue == vsi->tx_rings[i]->q_index) {
				tx_ring = vsi->tx_rings[i];
				break;
			}
@@ -5130,19 +5111,19 @@ static void ice_tx_timeout(struct net_device *netdev, unsigned int txqueue)
		struct ice_hw *hw = &pf->hw;
		u32 head, val = 0;

		head = (rd32(hw, QTX_COMM_HEAD(vsi->txq_map[hung_queue])) &
		head = (rd32(hw, QTX_COMM_HEAD(vsi->txq_map[txqueue])) &
			QTX_COMM_HEAD_HEAD_M) >> QTX_COMM_HEAD_HEAD_S;
		/* Read interrupt register */
		val = rd32(hw, GLINT_DYN_CTL(tx_ring->q_vector->reg_idx));

		netdev_info(netdev, "tx_timeout: VSI_num: %d, Q %d, NTC: 0x%x, HW_HEAD: 0x%x, NTU: 0x%x, INT: 0x%x\n",
			    vsi->vsi_num, hung_queue, tx_ring->next_to_clean,
			    vsi->vsi_num, txqueue, tx_ring->next_to_clean,
			    head, tx_ring->next_to_use, val);
	}

	pf->tx_timeout_last_recovery = jiffies;
	netdev_info(netdev, "tx_timeout recovery level %d, hung_queue %d\n",
		    pf->tx_timeout_recovery_level, hung_queue);
	netdev_info(netdev, "tx_timeout recovery level %d, txqueue %d\n",
		    pf->tx_timeout_recovery_level, txqueue);

	switch (pf->tx_timeout_recovery_level) {
	case 1:
+1 −1
Original line number Diff line number Diff line
@@ -1020,8 +1020,8 @@ bool ice_clean_tx_irq_zc(struct ice_ring *xdp_ring, int budget)
	s16 ntc = xdp_ring->next_to_clean;
	struct ice_tx_desc *tx_desc;
	struct ice_tx_buf *tx_buf;
	bool xmit_done = true;
	u32 xsk_frames = 0;
	bool xmit_done;

	tx_desc = ICE_TX_DESC(xdp_ring, ntc);
	tx_buf = &xdp_ring->tx_buf[ntc];
+1 −0
Original line number Diff line number Diff line
@@ -212,6 +212,7 @@ static s32 igc_get_invariants_base(struct igc_hw *hw)
	case IGC_DEV_ID_I225_I:
	case IGC_DEV_ID_I220_V:
	case IGC_DEV_ID_I225_K:
	case IGC_DEV_ID_I225_BLANK_NVM:
		mac->type = igc_i225;
		break;
	default:
Loading