Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c)  2019 Intel Corporation */
  3
  4#include "igc.h"
  5#include "igc_tsn.h"
  6
  7static bool is_any_launchtime(struct igc_adapter *adapter)
  8{
  9	int i;
 10
 11	for (i = 0; i < adapter->num_tx_queues; i++) {
 12		struct igc_ring *ring = adapter->tx_ring[i];
 13
 14		if (ring->launchtime_enable)
 15			return true;
 16	}
 17
 18	return false;
 19}
 20
 21/* Returns the TSN specific registers to their default values after
 22 * TSN offloading is disabled.
 23 */
 24static int igc_tsn_disable_offload(struct igc_adapter *adapter)
 25{
 26	struct igc_hw *hw = &adapter->hw;
 27	u32 tqavctrl;
 28	int i;
 29
 30	if (!(adapter->flags & IGC_FLAG_TSN_QBV_ENABLED))
 31		return 0;
 32
 33	adapter->cycle_time = 0;
 34
 35	wr32(IGC_TXPBS, I225_TXPBSIZE_DEFAULT);
 36	wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_DEFAULT);
 37
 38	tqavctrl = rd32(IGC_TQAVCTRL);
 39	tqavctrl &= ~(IGC_TQAVCTRL_TRANSMIT_MODE_TSN |
 40		      IGC_TQAVCTRL_ENHANCED_QAV);
 41	wr32(IGC_TQAVCTRL, tqavctrl);
 42
 43	for (i = 0; i < adapter->num_tx_queues; i++) {
 44		struct igc_ring *ring = adapter->tx_ring[i];
 45
 46		ring->start_time = 0;
 47		ring->end_time = 0;
 48		ring->launchtime_enable = false;
 49
 50		wr32(IGC_TXQCTL(i), 0);
 51		wr32(IGC_STQT(i), 0);
 52		wr32(IGC_ENDQT(i), NSEC_PER_SEC);
 53	}
 54
 55	wr32(IGC_QBVCYCLET_S, NSEC_PER_SEC);
 56	wr32(IGC_QBVCYCLET, NSEC_PER_SEC);
 57
 58	adapter->flags &= ~IGC_FLAG_TSN_QBV_ENABLED;
 59
 60	return 0;
 61}
 62
 63static int igc_tsn_enable_offload(struct igc_adapter *adapter)
 64{
 65	struct igc_hw *hw = &adapter->hw;
 66	u32 tqavctrl, baset_l, baset_h;
 67	u32 sec, nsec, cycle;
 68	ktime_t base_time, systim;
 69	int i;
 70
 71	if (adapter->flags & IGC_FLAG_TSN_QBV_ENABLED)
 72		return 0;
 73
 74	cycle = adapter->cycle_time;
 75	base_time = adapter->base_time;
 76
 77	wr32(IGC_TSAUXC, 0);
 78	wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_TSN);
 79	wr32(IGC_TXPBS, IGC_TXPBSIZE_TSN);
 80
 81	tqavctrl = rd32(IGC_TQAVCTRL);
 82	tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV;
 83	wr32(IGC_TQAVCTRL, tqavctrl);
 84
 85	wr32(IGC_QBVCYCLET_S, cycle);
 86	wr32(IGC_QBVCYCLET, cycle);
 87
 88	for (i = 0; i < adapter->num_tx_queues; i++) {
 89		struct igc_ring *ring = adapter->tx_ring[i];
 90		u32 txqctl = 0;
 91
 92		wr32(IGC_STQT(i), ring->start_time);
 93		wr32(IGC_ENDQT(i), ring->end_time);
 94
 95		if (adapter->base_time) {
 96			/* If we have a base_time we are in "taprio"
 97			 * mode and we need to be strict about the
 98			 * cycles: only transmit a packet if it can be
 99			 * completed during that cycle.
100			 */
101			txqctl |= IGC_TXQCTL_STRICT_CYCLE |
102				IGC_TXQCTL_STRICT_END;
103		}
104
105		if (ring->launchtime_enable)
106			txqctl |= IGC_TXQCTL_QUEUE_MODE_LAUNCHT;
107
108		wr32(IGC_TXQCTL(i), txqctl);
109	}
110
111	nsec = rd32(IGC_SYSTIML);
112	sec = rd32(IGC_SYSTIMH);
113
114	systim = ktime_set(sec, nsec);
115
116	if (ktime_compare(systim, base_time) > 0) {
117		s64 n;
118
119		n = div64_s64(ktime_sub_ns(systim, base_time), cycle);
120		base_time = ktime_add_ns(base_time, (n + 1) * cycle);
121	}
122
123	baset_h = div_s64_rem(base_time, NSEC_PER_SEC, &baset_l);
124
125	wr32(IGC_BASET_H, baset_h);
126	wr32(IGC_BASET_L, baset_l);
127
128	adapter->flags |= IGC_FLAG_TSN_QBV_ENABLED;
129
130	return 0;
131}
132
133int igc_tsn_offload_apply(struct igc_adapter *adapter)
134{
135	bool is_any_enabled = adapter->base_time || is_any_launchtime(adapter);
136
137	if (!(adapter->flags & IGC_FLAG_TSN_QBV_ENABLED) && !is_any_enabled)
138		return 0;
139
140	if (!is_any_enabled) {
141		int err = igc_tsn_disable_offload(adapter);
142
143		if (err < 0)
144			return err;
145
146		/* The BASET registers aren't cleared when writing
147		 * into them, force a reset if the interface is
148		 * running.
149		 */
150		if (netif_running(adapter->netdev))
151			schedule_work(&adapter->reset_task);
152
153		return 0;
154	}
155
156	return igc_tsn_enable_offload(adapter);
157}