Loading...
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2019 Intel Corporation */
3
4#include "igc.h"
5#include "igc_hw.h"
6#include "igc_tsn.h"
7
8static bool is_any_launchtime(struct igc_adapter *adapter)
9{
10 int i;
11
12 for (i = 0; i < adapter->num_tx_queues; i++) {
13 struct igc_ring *ring = adapter->tx_ring[i];
14
15 if (ring->launchtime_enable)
16 return true;
17 }
18
19 return false;
20}
21
22static bool is_cbs_enabled(struct igc_adapter *adapter)
23{
24 int i;
25
26 for (i = 0; i < adapter->num_tx_queues; i++) {
27 struct igc_ring *ring = adapter->tx_ring[i];
28
29 if (ring->cbs_enable)
30 return true;
31 }
32
33 return false;
34}
35
36static unsigned int igc_tsn_new_flags(struct igc_adapter *adapter)
37{
38 unsigned int new_flags = adapter->flags & ~IGC_FLAG_TSN_ANY_ENABLED;
39
40 if (adapter->taprio_offload_enable)
41 new_flags |= IGC_FLAG_TSN_QBV_ENABLED;
42
43 if (is_any_launchtime(adapter))
44 new_flags |= IGC_FLAG_TSN_QBV_ENABLED;
45
46 if (is_cbs_enabled(adapter))
47 new_flags |= IGC_FLAG_TSN_QAV_ENABLED;
48
49 if (adapter->strict_priority_enable)
50 new_flags |= IGC_FLAG_TSN_LEGACY_ENABLED;
51
52 return new_flags;
53}
54
55static bool igc_tsn_is_tx_mode_in_tsn(struct igc_adapter *adapter)
56{
57 struct igc_hw *hw = &adapter->hw;
58
59 return !!(rd32(IGC_TQAVCTRL) & IGC_TQAVCTRL_TRANSMIT_MODE_TSN);
60}
61
62void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter)
63{
64 struct igc_hw *hw = &adapter->hw;
65 u16 txoffset;
66
67 if (!igc_tsn_is_tx_mode_in_tsn(adapter))
68 return;
69
70 switch (adapter->link_speed) {
71 case SPEED_10:
72 txoffset = IGC_TXOFFSET_SPEED_10;
73 break;
74 case SPEED_100:
75 txoffset = IGC_TXOFFSET_SPEED_100;
76 break;
77 case SPEED_1000:
78 txoffset = IGC_TXOFFSET_SPEED_1000;
79 break;
80 case SPEED_2500:
81 txoffset = IGC_TXOFFSET_SPEED_2500;
82 break;
83 default:
84 txoffset = 0;
85 break;
86 }
87
88 wr32(IGC_GTXOFFSET, txoffset);
89}
90
91static void igc_tsn_restore_retx_default(struct igc_adapter *adapter)
92{
93 struct igc_hw *hw = &adapter->hw;
94 u32 retxctl;
95
96 retxctl = rd32(IGC_RETX_CTL) & IGC_RETX_CTL_WATERMARK_MASK;
97 wr32(IGC_RETX_CTL, retxctl);
98}
99
100bool igc_tsn_is_taprio_activated_by_user(struct igc_adapter *adapter)
101{
102 struct igc_hw *hw = &adapter->hw;
103
104 return (rd32(IGC_BASET_H) || rd32(IGC_BASET_L)) &&
105 adapter->taprio_offload_enable;
106}
107
108static void igc_tsn_tx_arb(struct igc_adapter *adapter, u16 *queue_per_tc)
109{
110 struct igc_hw *hw = &adapter->hw;
111 u32 txarb;
112
113 txarb = rd32(IGC_TXARB);
114
115 txarb &= ~(IGC_TXARB_TXQ_PRIO_0_MASK |
116 IGC_TXARB_TXQ_PRIO_1_MASK |
117 IGC_TXARB_TXQ_PRIO_2_MASK |
118 IGC_TXARB_TXQ_PRIO_3_MASK);
119
120 txarb |= IGC_TXARB_TXQ_PRIO_0(queue_per_tc[3]);
121 txarb |= IGC_TXARB_TXQ_PRIO_1(queue_per_tc[2]);
122 txarb |= IGC_TXARB_TXQ_PRIO_2(queue_per_tc[1]);
123 txarb |= IGC_TXARB_TXQ_PRIO_3(queue_per_tc[0]);
124
125 wr32(IGC_TXARB, txarb);
126}
127
128/* Returns the TSN specific registers to their default values after
129 * the adapter is reset.
130 */
131static int igc_tsn_disable_offload(struct igc_adapter *adapter)
132{
133 u16 queue_per_tc[4] = { 3, 2, 1, 0 };
134 struct igc_hw *hw = &adapter->hw;
135 u32 tqavctrl;
136 int i;
137
138 wr32(IGC_GTXOFFSET, 0);
139 wr32(IGC_TXPBS, I225_TXPBSIZE_DEFAULT);
140 wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_DEFAULT);
141
142 if (igc_is_device_id_i226(hw))
143 igc_tsn_restore_retx_default(adapter);
144
145 tqavctrl = rd32(IGC_TQAVCTRL);
146 tqavctrl &= ~(IGC_TQAVCTRL_TRANSMIT_MODE_TSN |
147 IGC_TQAVCTRL_ENHANCED_QAV | IGC_TQAVCTRL_FUTSCDDIS);
148
149 wr32(IGC_TQAVCTRL, tqavctrl);
150
151 for (i = 0; i < adapter->num_tx_queues; i++) {
152 wr32(IGC_TXQCTL(i), 0);
153 wr32(IGC_STQT(i), 0);
154 wr32(IGC_ENDQT(i), NSEC_PER_SEC);
155 }
156
157 wr32(IGC_QBVCYCLET_S, 0);
158 wr32(IGC_QBVCYCLET, NSEC_PER_SEC);
159
160 /* Reset mqprio TC configuration. */
161 netdev_reset_tc(adapter->netdev);
162
163 /* Restore the default Tx arbitration: Priority 0 has the highest
164 * priority and is assigned to queue 0 and so on and so forth.
165 */
166 igc_tsn_tx_arb(adapter, queue_per_tc);
167
168 adapter->flags &= ~IGC_FLAG_TSN_QBV_ENABLED;
169 adapter->flags &= ~IGC_FLAG_TSN_LEGACY_ENABLED;
170
171 return 0;
172}
173
174/* To partially fix i226 HW errata, reduce MAC internal buffering from 192 Bytes
175 * to 88 Bytes by setting RETX_CTL register using the recommendation from:
176 * a) Ethernet Controller I225/I226 Specification Update Rev 2.1
177 * Item 9: TSN: Packet Transmission Might Cross the Qbv Window
178 * b) I225/6 SW User Manual Rev 1.2.4: Section 8.11.5 Retry Buffer Control
179 */
180static void igc_tsn_set_retx_qbvfullthreshold(struct igc_adapter *adapter)
181{
182 struct igc_hw *hw = &adapter->hw;
183 u32 retxctl, watermark;
184
185 retxctl = rd32(IGC_RETX_CTL);
186 watermark = retxctl & IGC_RETX_CTL_WATERMARK_MASK;
187 /* Set QBVFULLTH value using watermark and set QBVFULLEN */
188 retxctl |= (watermark << IGC_RETX_CTL_QBVFULLTH_SHIFT) |
189 IGC_RETX_CTL_QBVFULLEN;
190 wr32(IGC_RETX_CTL, retxctl);
191}
192
193static int igc_tsn_enable_offload(struct igc_adapter *adapter)
194{
195 struct igc_hw *hw = &adapter->hw;
196 u32 tqavctrl, baset_l, baset_h;
197 u32 sec, nsec, cycle;
198 ktime_t base_time, systim;
199 int i;
200
201 wr32(IGC_TSAUXC, 0);
202 wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_TSN);
203 wr32(IGC_TXPBS, IGC_TXPBSIZE_TSN);
204
205 if (igc_is_device_id_i226(hw))
206 igc_tsn_set_retx_qbvfullthreshold(adapter);
207
208 if (adapter->strict_priority_enable) {
209 int err;
210
211 err = netdev_set_num_tc(adapter->netdev, adapter->num_tc);
212 if (err)
213 return err;
214
215 for (i = 0; i < adapter->num_tc; i++) {
216 err = netdev_set_tc_queue(adapter->netdev, i, 1,
217 adapter->queue_per_tc[i]);
218 if (err)
219 return err;
220 }
221
222 /* In case the card is configured with less than four queues. */
223 for (; i < IGC_MAX_TX_QUEUES; i++)
224 adapter->queue_per_tc[i] = i;
225
226 /* Configure queue priorities according to the user provided
227 * mapping.
228 */
229 igc_tsn_tx_arb(adapter, adapter->queue_per_tc);
230
231 /* Enable legacy TSN mode which will do strict priority without
232 * any other TSN features.
233 */
234 tqavctrl = rd32(IGC_TQAVCTRL);
235 tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN;
236 tqavctrl &= ~IGC_TQAVCTRL_ENHANCED_QAV;
237 wr32(IGC_TQAVCTRL, tqavctrl);
238
239 return 0;
240 }
241
242 for (i = 0; i < adapter->num_tx_queues; i++) {
243 struct igc_ring *ring = adapter->tx_ring[i];
244 u32 txqctl = 0;
245 u16 cbs_value;
246 u32 tqavcc;
247
248 wr32(IGC_STQT(i), ring->start_time);
249 wr32(IGC_ENDQT(i), ring->end_time);
250
251 if (adapter->taprio_offload_enable) {
252 /* If taprio_offload_enable is set we are in "taprio"
253 * mode and we need to be strict about the
254 * cycles: only transmit a packet if it can be
255 * completed during that cycle.
256 *
257 * If taprio_offload_enable is NOT true when
258 * enabling TSN offload, the cycle should have
259 * no external effects, but is only used internally
260 * to adapt the base time register after a second
261 * has passed.
262 *
263 * Enabling strict mode in this case would
264 * unnecessarily prevent the transmission of
265 * certain packets (i.e. at the boundary of a
266 * second) and thus interfere with the launchtime
267 * feature that promises transmission at a
268 * certain point in time.
269 */
270 txqctl |= IGC_TXQCTL_STRICT_CYCLE |
271 IGC_TXQCTL_STRICT_END;
272 }
273
274 if (ring->launchtime_enable)
275 txqctl |= IGC_TXQCTL_QUEUE_MODE_LAUNCHT;
276
277 /* Skip configuring CBS for Q2 and Q3 */
278 if (i > 1)
279 goto skip_cbs;
280
281 if (ring->cbs_enable) {
282 if (i == 0)
283 txqctl |= IGC_TXQCTL_QAV_SEL_CBS0;
284 else
285 txqctl |= IGC_TXQCTL_QAV_SEL_CBS1;
286
287 /* According to i225 datasheet section 7.5.2.7, we
288 * should set the 'idleSlope' field from TQAVCC
289 * register following the equation:
290 *
291 * value = link-speed 0x7736 * BW * 0.2
292 * ---------- * ----------------- (E1)
293 * 100Mbps 2.5
294 *
295 * Note that 'link-speed' is in Mbps.
296 *
297 * 'BW' is the percentage bandwidth out of full
298 * link speed which can be found with the
299 * following equation. Note that idleSlope here
300 * is the parameter from this function
301 * which is in kbps.
302 *
303 * BW = idleSlope
304 * ----------------- (E2)
305 * link-speed * 1000
306 *
307 * That said, we can come up with a generic
308 * equation to calculate the value we should set
309 * it TQAVCC register by replacing 'BW' in E1 by E2.
310 * The resulting equation is:
311 *
312 * value = link-speed * 0x7736 * idleSlope * 0.2
313 * ------------------------------------- (E3)
314 * 100 * 2.5 * link-speed * 1000
315 *
316 * 'link-speed' is present in both sides of the
317 * fraction so it is canceled out. The final
318 * equation is the following:
319 *
320 * value = idleSlope * 61036
321 * ----------------- (E4)
322 * 2500000
323 *
324 * NOTE: For i225, given the above, we can see
325 * that idleslope is represented in
326 * 40.959433 kbps units by the value at
327 * the TQAVCC register (2.5Gbps / 61036),
328 * which reduces the granularity for
329 * idleslope increments.
330 *
331 * In i225 controller, the sendSlope and loCredit
332 * parameters from CBS are not configurable
333 * by software so we don't do any
334 * 'controller configuration' in respect to
335 * these parameters.
336 */
337 cbs_value = DIV_ROUND_UP_ULL(ring->idleslope
338 * 61036ULL, 2500000);
339
340 tqavcc = rd32(IGC_TQAVCC(i));
341 tqavcc &= ~IGC_TQAVCC_IDLESLOPE_MASK;
342 tqavcc |= cbs_value | IGC_TQAVCC_KEEP_CREDITS;
343 wr32(IGC_TQAVCC(i), tqavcc);
344
345 wr32(IGC_TQAVHC(i),
346 0x80000000 + ring->hicredit * 0x7736);
347 } else {
348 /* Disable any CBS for the queue */
349 txqctl &= ~(IGC_TXQCTL_QAV_SEL_MASK);
350
351 /* Set idleSlope to zero. */
352 tqavcc = rd32(IGC_TQAVCC(i));
353 tqavcc &= ~(IGC_TQAVCC_IDLESLOPE_MASK |
354 IGC_TQAVCC_KEEP_CREDITS);
355 wr32(IGC_TQAVCC(i), tqavcc);
356
357 /* Set hiCredit to zero. */
358 wr32(IGC_TQAVHC(i), 0);
359 }
360skip_cbs:
361 wr32(IGC_TXQCTL(i), txqctl);
362 }
363
364 tqavctrl = rd32(IGC_TQAVCTRL) & ~IGC_TQAVCTRL_FUTSCDDIS;
365
366 tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV;
367
368 adapter->qbv_count++;
369
370 cycle = adapter->cycle_time;
371 base_time = adapter->base_time;
372
373 nsec = rd32(IGC_SYSTIML);
374 sec = rd32(IGC_SYSTIMH);
375
376 systim = ktime_set(sec, nsec);
377 if (ktime_compare(systim, base_time) > 0) {
378 s64 n = div64_s64(ktime_sub_ns(systim, base_time), cycle);
379
380 base_time = ktime_add_ns(base_time, (n + 1) * cycle);
381 } else {
382 if (igc_is_device_id_i226(hw)) {
383 ktime_t adjust_time, expires_time;
384
385 /* According to datasheet section 7.5.2.9.3.3, FutScdDis bit
386 * has to be configured before the cycle time and base time.
387 * Tx won't hang if a GCL is already running,
388 * so in this case we don't need to set FutScdDis.
389 */
390 if (!(rd32(IGC_BASET_H) || rd32(IGC_BASET_L)))
391 tqavctrl |= IGC_TQAVCTRL_FUTSCDDIS;
392
393 nsec = rd32(IGC_SYSTIML);
394 sec = rd32(IGC_SYSTIMH);
395 systim = ktime_set(sec, nsec);
396
397 adjust_time = adapter->base_time;
398 expires_time = ktime_sub_ns(adjust_time, systim);
399 hrtimer_start(&adapter->hrtimer, expires_time, HRTIMER_MODE_REL);
400 }
401 }
402
403 wr32(IGC_TQAVCTRL, tqavctrl);
404
405 wr32(IGC_QBVCYCLET_S, cycle);
406 wr32(IGC_QBVCYCLET, cycle);
407
408 baset_h = div_s64_rem(base_time, NSEC_PER_SEC, &baset_l);
409 wr32(IGC_BASET_H, baset_h);
410
411 /* In i226, Future base time is only supported when FutScdDis bit
412 * is enabled and only active for re-configuration.
413 * In this case, initialize the base time with zero to create
414 * "re-configuration" scenario then only set the desired base time.
415 */
416 if (tqavctrl & IGC_TQAVCTRL_FUTSCDDIS)
417 wr32(IGC_BASET_L, 0);
418 wr32(IGC_BASET_L, baset_l);
419
420 return 0;
421}
422
423int igc_tsn_reset(struct igc_adapter *adapter)
424{
425 unsigned int new_flags;
426 int err = 0;
427
428 new_flags = igc_tsn_new_flags(adapter);
429
430 if (!(new_flags & IGC_FLAG_TSN_ANY_ENABLED))
431 return igc_tsn_disable_offload(adapter);
432
433 err = igc_tsn_enable_offload(adapter);
434 if (err < 0)
435 return err;
436
437 adapter->flags = new_flags;
438
439 return err;
440}
441
442static bool igc_tsn_will_tx_mode_change(struct igc_adapter *adapter)
443{
444 bool any_tsn_enabled = !!(igc_tsn_new_flags(adapter) &
445 IGC_FLAG_TSN_ANY_ENABLED);
446
447 return (any_tsn_enabled && !igc_tsn_is_tx_mode_in_tsn(adapter)) ||
448 (!any_tsn_enabled && igc_tsn_is_tx_mode_in_tsn(adapter));
449}
450
451int igc_tsn_offload_apply(struct igc_adapter *adapter)
452{
453 /* Per I225/6 HW Design Section 7.5.2.1 guideline, if tx mode change
454 * from legacy->tsn or tsn->legacy, then reset adapter is needed.
455 */
456 if (netif_running(adapter->netdev) &&
457 igc_tsn_will_tx_mode_change(adapter)) {
458 schedule_work(&adapter->reset_task);
459 return 0;
460 }
461
462 igc_tsn_reset(adapter);
463
464 return 0;
465}
1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2019 Intel Corporation */
3
4#include "igc.h"
5#include "igc_hw.h"
6#include "igc_tsn.h"
7
8static bool is_any_launchtime(struct igc_adapter *adapter)
9{
10 int i;
11
12 for (i = 0; i < adapter->num_tx_queues; i++) {
13 struct igc_ring *ring = adapter->tx_ring[i];
14
15 if (ring->launchtime_enable)
16 return true;
17 }
18
19 return false;
20}
21
22static bool is_cbs_enabled(struct igc_adapter *adapter)
23{
24 int i;
25
26 for (i = 0; i < adapter->num_tx_queues; i++) {
27 struct igc_ring *ring = adapter->tx_ring[i];
28
29 if (ring->cbs_enable)
30 return true;
31 }
32
33 return false;
34}
35
36static unsigned int igc_tsn_new_flags(struct igc_adapter *adapter)
37{
38 unsigned int new_flags = adapter->flags & ~IGC_FLAG_TSN_ANY_ENABLED;
39
40 if (adapter->taprio_offload_enable)
41 new_flags |= IGC_FLAG_TSN_QBV_ENABLED;
42
43 if (is_any_launchtime(adapter))
44 new_flags |= IGC_FLAG_TSN_QBV_ENABLED;
45
46 if (is_cbs_enabled(adapter))
47 new_flags |= IGC_FLAG_TSN_QAV_ENABLED;
48
49 return new_flags;
50}
51
52void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter)
53{
54 struct igc_hw *hw = &adapter->hw;
55 u16 txoffset;
56
57 if (!is_any_launchtime(adapter))
58 return;
59
60 switch (adapter->link_speed) {
61 case SPEED_10:
62 txoffset = IGC_TXOFFSET_SPEED_10;
63 break;
64 case SPEED_100:
65 txoffset = IGC_TXOFFSET_SPEED_100;
66 break;
67 case SPEED_1000:
68 txoffset = IGC_TXOFFSET_SPEED_1000;
69 break;
70 case SPEED_2500:
71 txoffset = IGC_TXOFFSET_SPEED_2500;
72 break;
73 default:
74 txoffset = 0;
75 break;
76 }
77
78 wr32(IGC_GTXOFFSET, txoffset);
79}
80
81/* Returns the TSN specific registers to their default values after
82 * the adapter is reset.
83 */
84static int igc_tsn_disable_offload(struct igc_adapter *adapter)
85{
86 struct igc_hw *hw = &adapter->hw;
87 u32 tqavctrl;
88 int i;
89
90 wr32(IGC_GTXOFFSET, 0);
91 wr32(IGC_TXPBS, I225_TXPBSIZE_DEFAULT);
92 wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_DEFAULT);
93
94 tqavctrl = rd32(IGC_TQAVCTRL);
95 tqavctrl &= ~(IGC_TQAVCTRL_TRANSMIT_MODE_TSN |
96 IGC_TQAVCTRL_ENHANCED_QAV | IGC_TQAVCTRL_FUTSCDDIS);
97
98 wr32(IGC_TQAVCTRL, tqavctrl);
99
100 for (i = 0; i < adapter->num_tx_queues; i++) {
101 wr32(IGC_TXQCTL(i), 0);
102 wr32(IGC_STQT(i), 0);
103 wr32(IGC_ENDQT(i), NSEC_PER_SEC);
104 }
105
106 wr32(IGC_QBVCYCLET_S, 0);
107 wr32(IGC_QBVCYCLET, NSEC_PER_SEC);
108
109 adapter->flags &= ~IGC_FLAG_TSN_QBV_ENABLED;
110
111 return 0;
112}
113
114static int igc_tsn_enable_offload(struct igc_adapter *adapter)
115{
116 struct igc_hw *hw = &adapter->hw;
117 u32 tqavctrl, baset_l, baset_h;
118 u32 sec, nsec, cycle;
119 ktime_t base_time, systim;
120 int i;
121
122 wr32(IGC_TSAUXC, 0);
123 wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_TSN);
124 wr32(IGC_TXPBS, IGC_TXPBSIZE_TSN);
125
126 for (i = 0; i < adapter->num_tx_queues; i++) {
127 struct igc_ring *ring = adapter->tx_ring[i];
128 u32 txqctl = 0;
129 u16 cbs_value;
130 u32 tqavcc;
131
132 wr32(IGC_STQT(i), ring->start_time);
133 wr32(IGC_ENDQT(i), ring->end_time);
134
135 if (adapter->taprio_offload_enable) {
136 /* If taprio_offload_enable is set we are in "taprio"
137 * mode and we need to be strict about the
138 * cycles: only transmit a packet if it can be
139 * completed during that cycle.
140 *
141 * If taprio_offload_enable is NOT true when
142 * enabling TSN offload, the cycle should have
143 * no external effects, but is only used internally
144 * to adapt the base time register after a second
145 * has passed.
146 *
147 * Enabling strict mode in this case would
148 * unnecessarily prevent the transmission of
149 * certain packets (i.e. at the boundary of a
150 * second) and thus interfere with the launchtime
151 * feature that promises transmission at a
152 * certain point in time.
153 */
154 txqctl |= IGC_TXQCTL_STRICT_CYCLE |
155 IGC_TXQCTL_STRICT_END;
156 }
157
158 if (ring->launchtime_enable)
159 txqctl |= IGC_TXQCTL_QUEUE_MODE_LAUNCHT;
160
161 /* Skip configuring CBS for Q2 and Q3 */
162 if (i > 1)
163 goto skip_cbs;
164
165 if (ring->cbs_enable) {
166 if (i == 0)
167 txqctl |= IGC_TXQCTL_QAV_SEL_CBS0;
168 else
169 txqctl |= IGC_TXQCTL_QAV_SEL_CBS1;
170
171 /* According to i225 datasheet section 7.5.2.7, we
172 * should set the 'idleSlope' field from TQAVCC
173 * register following the equation:
174 *
175 * value = link-speed 0x7736 * BW * 0.2
176 * ---------- * ----------------- (E1)
177 * 100Mbps 2.5
178 *
179 * Note that 'link-speed' is in Mbps.
180 *
181 * 'BW' is the percentage bandwidth out of full
182 * link speed which can be found with the
183 * following equation. Note that idleSlope here
184 * is the parameter from this function
185 * which is in kbps.
186 *
187 * BW = idleSlope
188 * ----------------- (E2)
189 * link-speed * 1000
190 *
191 * That said, we can come up with a generic
192 * equation to calculate the value we should set
193 * it TQAVCC register by replacing 'BW' in E1 by E2.
194 * The resulting equation is:
195 *
196 * value = link-speed * 0x7736 * idleSlope * 0.2
197 * ------------------------------------- (E3)
198 * 100 * 2.5 * link-speed * 1000
199 *
200 * 'link-speed' is present in both sides of the
201 * fraction so it is canceled out. The final
202 * equation is the following:
203 *
204 * value = idleSlope * 61036
205 * ----------------- (E4)
206 * 2500000
207 *
208 * NOTE: For i225, given the above, we can see
209 * that idleslope is represented in
210 * 40.959433 kbps units by the value at
211 * the TQAVCC register (2.5Gbps / 61036),
212 * which reduces the granularity for
213 * idleslope increments.
214 *
215 * In i225 controller, the sendSlope and loCredit
216 * parameters from CBS are not configurable
217 * by software so we don't do any
218 * 'controller configuration' in respect to
219 * these parameters.
220 */
221 cbs_value = DIV_ROUND_UP_ULL(ring->idleslope
222 * 61036ULL, 2500000);
223
224 tqavcc = rd32(IGC_TQAVCC(i));
225 tqavcc &= ~IGC_TQAVCC_IDLESLOPE_MASK;
226 tqavcc |= cbs_value | IGC_TQAVCC_KEEP_CREDITS;
227 wr32(IGC_TQAVCC(i), tqavcc);
228
229 wr32(IGC_TQAVHC(i),
230 0x80000000 + ring->hicredit * 0x7736);
231 } else {
232 /* Disable any CBS for the queue */
233 txqctl &= ~(IGC_TXQCTL_QAV_SEL_MASK);
234
235 /* Set idleSlope to zero. */
236 tqavcc = rd32(IGC_TQAVCC(i));
237 tqavcc &= ~(IGC_TQAVCC_IDLESLOPE_MASK |
238 IGC_TQAVCC_KEEP_CREDITS);
239 wr32(IGC_TQAVCC(i), tqavcc);
240
241 /* Set hiCredit to zero. */
242 wr32(IGC_TQAVHC(i), 0);
243 }
244skip_cbs:
245 wr32(IGC_TXQCTL(i), txqctl);
246 }
247
248 tqavctrl = rd32(IGC_TQAVCTRL) & ~IGC_TQAVCTRL_FUTSCDDIS;
249
250 tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV;
251
252 adapter->qbv_count++;
253
254 cycle = adapter->cycle_time;
255 base_time = adapter->base_time;
256
257 nsec = rd32(IGC_SYSTIML);
258 sec = rd32(IGC_SYSTIMH);
259
260 systim = ktime_set(sec, nsec);
261 if (ktime_compare(systim, base_time) > 0) {
262 s64 n = div64_s64(ktime_sub_ns(systim, base_time), cycle);
263
264 base_time = ktime_add_ns(base_time, (n + 1) * cycle);
265
266 /* Increase the counter if scheduling into the past while
267 * Gate Control List (GCL) is running.
268 */
269 if ((rd32(IGC_BASET_H) || rd32(IGC_BASET_L)) &&
270 (adapter->tc_setup_type == TC_SETUP_QDISC_TAPRIO) &&
271 (adapter->qbv_count > 1))
272 adapter->qbv_config_change_errors++;
273 } else {
274 if (igc_is_device_id_i226(hw)) {
275 ktime_t adjust_time, expires_time;
276
277 /* According to datasheet section 7.5.2.9.3.3, FutScdDis bit
278 * has to be configured before the cycle time and base time.
279 * Tx won't hang if a GCL is already running,
280 * so in this case we don't need to set FutScdDis.
281 */
282 if (!(rd32(IGC_BASET_H) || rd32(IGC_BASET_L)))
283 tqavctrl |= IGC_TQAVCTRL_FUTSCDDIS;
284
285 nsec = rd32(IGC_SYSTIML);
286 sec = rd32(IGC_SYSTIMH);
287 systim = ktime_set(sec, nsec);
288
289 adjust_time = adapter->base_time;
290 expires_time = ktime_sub_ns(adjust_time, systim);
291 hrtimer_start(&adapter->hrtimer, expires_time, HRTIMER_MODE_REL);
292 }
293 }
294
295 wr32(IGC_TQAVCTRL, tqavctrl);
296
297 wr32(IGC_QBVCYCLET_S, cycle);
298 wr32(IGC_QBVCYCLET, cycle);
299
300 baset_h = div_s64_rem(base_time, NSEC_PER_SEC, &baset_l);
301 wr32(IGC_BASET_H, baset_h);
302
303 /* In i226, Future base time is only supported when FutScdDis bit
304 * is enabled and only active for re-configuration.
305 * In this case, initialize the base time with zero to create
306 * "re-configuration" scenario then only set the desired base time.
307 */
308 if (tqavctrl & IGC_TQAVCTRL_FUTSCDDIS)
309 wr32(IGC_BASET_L, 0);
310 wr32(IGC_BASET_L, baset_l);
311
312 return 0;
313}
314
315int igc_tsn_reset(struct igc_adapter *adapter)
316{
317 unsigned int new_flags;
318 int err = 0;
319
320 new_flags = igc_tsn_new_flags(adapter);
321
322 if (!(new_flags & IGC_FLAG_TSN_ANY_ENABLED))
323 return igc_tsn_disable_offload(adapter);
324
325 err = igc_tsn_enable_offload(adapter);
326 if (err < 0)
327 return err;
328
329 adapter->flags = new_flags;
330
331 return err;
332}
333
334int igc_tsn_offload_apply(struct igc_adapter *adapter)
335{
336 struct igc_hw *hw = &adapter->hw;
337
338 /* Per I225/6 HW Design Section 7.5.2.1, transmit mode
339 * cannot be changed dynamically. Require reset the adapter.
340 */
341 if (netif_running(adapter->netdev) &&
342 (igc_is_device_id_i225(hw) || !adapter->qbv_count)) {
343 schedule_work(&adapter->reset_task);
344 return 0;
345 }
346
347 igc_tsn_reset(adapter);
348
349 return 0;
350}