Commit 8fbaced2 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files
Tony Nguyen says:

====================
Intel Wired LAN Driver Updates 2023-03-07 (igc)

This series contains updates to igc driver only.

Muhammad adds tracking and reporting of QBV config errors.

Tan Tee adds support for configuring max SDU for each Tx queue.

Sasha removes check for alternate media as only one media type is
supported.

* '1GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue:
  igc: Clean up and optimize watchdog task
  igc: offload queue max SDU from tc-taprio
  igc: Add qbv_config_change_errors counter
====================

Link: https://lore.kernel.org/r/20230307221332.3997881-1-anthony.l.nguyen@intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents fd9c31f8 6cc1b2fd
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -99,6 +99,7 @@ struct igc_ring {

	u32 start_time;
	u32 end_time;
	u32 max_sdu;

	/* CBS parameters */
	bool cbs_enable;                /* indicates if CBS is enabled */
@@ -185,6 +186,7 @@ struct igc_adapter {
	ktime_t base_time;
	ktime_t cycle_time;
	bool qbv_enable;
	u32 qbv_config_change_errors;

	/* OS defined structs */
	struct pci_dev *pdev;
@@ -292,8 +294,6 @@ extern char igc_driver_name[];
#define IGC_FLAG_PTP			BIT(8)
#define IGC_FLAG_WOL_SUPPORTED		BIT(8)
#define IGC_FLAG_NEED_LINK_UPDATE	BIT(9)
#define IGC_FLAG_MEDIA_RESET		BIT(10)
#define IGC_FLAG_MAS_ENABLE		BIT(12)
#define IGC_FLAG_HAS_MSIX		BIT(13)
#define IGC_FLAG_EEE			BIT(14)
#define IGC_FLAG_VLAN_PROMISC		BIT(15)
+1 −0
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ static const struct igc_stats igc_gstrings_stats[] = {
	IGC_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared),
	IGC_STAT("tx_lpi_counter", stats.tlpic),
	IGC_STAT("rx_lpi_counter", stats.rlpic),
	IGC_STAT("qbv_config_change_errors", qbv_config_change_errors),
};

#define IGC_NETDEV_STAT(_net_stat) { \
+1 −0
Original line number Diff line number Diff line
@@ -273,6 +273,7 @@ struct igc_hw_stats {
	u64 o2bspc;
	u64 b2ospc;
	u64 b2ogprc;
	u64 txdrop;
};

struct net_device *igc_get_hw_dev(struct igc_hw *hw);
+30 −21
Original line number Diff line number Diff line
@@ -1500,6 +1500,7 @@ static int igc_tso(struct igc_ring *tx_ring,
static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
				       struct igc_ring *tx_ring)
{
	struct igc_adapter *adapter = netdev_priv(tx_ring->netdev);
	bool first_flag = false, insert_empty = false;
	u16 count = TXD_USE_COUNT(skb_headlen(skb));
	__be16 protocol = vlan_get_protocol(skb);
@@ -1562,9 +1563,19 @@ static netdev_tx_t igc_xmit_frame_ring(struct sk_buff *skb,
	first->bytecount = skb->len;
	first->gso_segs = 1;

	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
		struct igc_adapter *adapter = netdev_priv(tx_ring->netdev);
	if (tx_ring->max_sdu > 0) {
		u32 max_sdu = 0;

		max_sdu = tx_ring->max_sdu +
			  (skb_vlan_tagged(first->skb) ? VLAN_HLEN : 0);

		if (first->bytecount > max_sdu) {
			adapter->stats.txdrop++;
			goto out_drop;
		}
	}

	if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP)) {
		/* FIXME: add support for retrieving timestamps from
		 * the other timer registers before skipping the
		 * timestamping request.
@@ -4919,7 +4930,8 @@ void igc_update_stats(struct igc_adapter *adapter)
	net_stats->tx_window_errors = adapter->stats.latecol;
	net_stats->tx_carrier_errors = adapter->stats.tncrs;

	/* Tx Dropped needs to be maintained elsewhere */
	/* Tx Dropped */
	net_stats->tx_dropped = adapter->stats.txdrop;

	/* Management Stats */
	adapter->stats.mgptc += rd32(IGC_MGTPTC);
@@ -5565,25 +5577,8 @@ static void igc_watchdog_task(struct work_struct *work)
				mod_timer(&adapter->phy_info_timer,
					  round_jiffies(jiffies + 2 * HZ));

			/* link is down, time to check for alternate media */
			if (adapter->flags & IGC_FLAG_MAS_ENABLE) {
				if (adapter->flags & IGC_FLAG_MEDIA_RESET) {
					schedule_work(&adapter->reset_task);
					/* return immediately */
					return;
				}
			}
			pm_schedule_suspend(netdev->dev.parent,
					    MSEC_PER_SEC * 5);

		/* also check for alternate media here */
		} else if (!netif_carrier_ok(netdev) &&
			   (adapter->flags & IGC_FLAG_MAS_ENABLE)) {
			if (adapter->flags & IGC_FLAG_MEDIA_RESET) {
				schedule_work(&adapter->reset_task);
				/* return immediately */
				return;
			}
		}
	}

@@ -6048,12 +6043,14 @@ static int igc_tsn_clear_schedule(struct igc_adapter *adapter)

	adapter->base_time = 0;
	adapter->cycle_time = NSEC_PER_SEC;
	adapter->qbv_config_change_errors = 0;

	for (i = 0; i < adapter->num_tx_queues; i++) {
		struct igc_ring *ring = adapter->tx_ring[i];

		ring->start_time = 0;
		ring->end_time = NSEC_PER_SEC;
		ring->max_sdu = 0;
	}

	return 0;
@@ -6137,6 +6134,16 @@ static int igc_save_qbv_schedule(struct igc_adapter *adapter,
		}
	}

	for (i = 0; i < adapter->num_tx_queues; i++) {
		struct igc_ring *ring = adapter->tx_ring[i];
		struct net_device *dev = adapter->netdev;

		if (qopt->max_sdu[i])
			ring->max_sdu = qopt->max_sdu[i] + dev->hard_header_len;
		else
			ring->max_sdu = 0;
	}

	return 0;
}

@@ -6235,8 +6242,10 @@ static int igc_tc_query_caps(struct igc_adapter *adapter,

		caps->broken_mqprio = true;

		if (hw->mac.type == igc_i225)
		if (hw->mac.type == igc_i225) {
			caps->supports_queue_max_sdu = true;
			caps->gate_mask_per_txq = true;
		}

		return 0;
	}
+12 −0
Original line number Diff line number Diff line
@@ -114,6 +114,7 @@ static int igc_tsn_disable_offload(struct igc_adapter *adapter)
static int igc_tsn_enable_offload(struct igc_adapter *adapter)
{
	struct igc_hw *hw = &adapter->hw;
	bool tsn_mode_reconfig = false;
	u32 tqavctrl, baset_l, baset_h;
	u32 sec, nsec, cycle;
	ktime_t base_time, systim;
@@ -226,6 +227,10 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter)
	}

	tqavctrl = rd32(IGC_TQAVCTRL) & ~IGC_TQAVCTRL_FUTSCDDIS;

	if (tqavctrl & IGC_TQAVCTRL_TRANSMIT_MODE_TSN)
		tsn_mode_reconfig = true;

	tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV;

	cycle = adapter->cycle_time;
@@ -239,6 +244,13 @@ static int igc_tsn_enable_offload(struct igc_adapter *adapter)
		s64 n = div64_s64(ktime_sub_ns(systim, base_time), cycle);

		base_time = ktime_add_ns(base_time, (n + 1) * cycle);

		/* Increase the counter if scheduling into the past while
		 * Gate Control List (GCL) is running.
		 */
		if ((rd32(IGC_BASET_H) || rd32(IGC_BASET_L)) &&
		    tsn_mode_reconfig)
			adapter->qbv_config_change_errors++;
	} else {
		/* According to datasheet section 7.5.2.9.3.3, FutScdDis bit
		 * has to be configured before the cycle time and base time.