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
is_any_launchtime(struct igc_adapter * adapter)8 static 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
is_cbs_enabled(struct igc_adapter * adapter)22 static 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
igc_tsn_new_flags(struct igc_adapter * adapter)36 static 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
igc_tsn_is_tx_mode_in_tsn(struct igc_adapter * adapter)52 static bool igc_tsn_is_tx_mode_in_tsn(struct igc_adapter *adapter)
53 {
54 struct igc_hw *hw = &adapter->hw;
55
56 return !!(rd32(IGC_TQAVCTRL) & IGC_TQAVCTRL_TRANSMIT_MODE_TSN);
57 }
58
igc_tsn_adjust_txtime_offset(struct igc_adapter * adapter)59 void igc_tsn_adjust_txtime_offset(struct igc_adapter *adapter)
60 {
61 struct igc_hw *hw = &adapter->hw;
62 u16 txoffset;
63
64 if (!igc_tsn_is_tx_mode_in_tsn(adapter))
65 return;
66
67 switch (adapter->link_speed) {
68 case SPEED_10:
69 txoffset = IGC_TXOFFSET_SPEED_10;
70 break;
71 case SPEED_100:
72 txoffset = IGC_TXOFFSET_SPEED_100;
73 break;
74 case SPEED_1000:
75 txoffset = IGC_TXOFFSET_SPEED_1000;
76 break;
77 case SPEED_2500:
78 txoffset = IGC_TXOFFSET_SPEED_2500;
79 break;
80 default:
81 txoffset = 0;
82 break;
83 }
84
85 wr32(IGC_GTXOFFSET, txoffset);
86 }
87
igc_tsn_restore_retx_default(struct igc_adapter * adapter)88 static void igc_tsn_restore_retx_default(struct igc_adapter *adapter)
89 {
90 struct igc_hw *hw = &adapter->hw;
91 u32 retxctl;
92
93 retxctl = rd32(IGC_RETX_CTL) & IGC_RETX_CTL_WATERMARK_MASK;
94 wr32(IGC_RETX_CTL, retxctl);
95 }
96
igc_tsn_is_taprio_activated_by_user(struct igc_adapter * adapter)97 bool igc_tsn_is_taprio_activated_by_user(struct igc_adapter *adapter)
98 {
99 struct igc_hw *hw = &adapter->hw;
100
101 return (rd32(IGC_BASET_H) || rd32(IGC_BASET_L)) &&
102 adapter->taprio_offload_enable;
103 }
104
105 /* Returns the TSN specific registers to their default values after
106 * the adapter is reset.
107 */
igc_tsn_disable_offload(struct igc_adapter * adapter)108 static int igc_tsn_disable_offload(struct igc_adapter *adapter)
109 {
110 struct igc_hw *hw = &adapter->hw;
111 u32 tqavctrl;
112 int i;
113
114 wr32(IGC_GTXOFFSET, 0);
115 wr32(IGC_TXPBS, I225_TXPBSIZE_DEFAULT);
116 wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_DEFAULT);
117
118 if (igc_is_device_id_i226(hw))
119 igc_tsn_restore_retx_default(adapter);
120
121 tqavctrl = rd32(IGC_TQAVCTRL);
122 tqavctrl &= ~(IGC_TQAVCTRL_TRANSMIT_MODE_TSN |
123 IGC_TQAVCTRL_ENHANCED_QAV | IGC_TQAVCTRL_FUTSCDDIS);
124
125 wr32(IGC_TQAVCTRL, tqavctrl);
126
127 for (i = 0; i < adapter->num_tx_queues; i++) {
128 wr32(IGC_TXQCTL(i), 0);
129 wr32(IGC_STQT(i), 0);
130 wr32(IGC_ENDQT(i), NSEC_PER_SEC);
131 }
132
133 wr32(IGC_QBVCYCLET_S, 0);
134 wr32(IGC_QBVCYCLET, NSEC_PER_SEC);
135
136 adapter->flags &= ~IGC_FLAG_TSN_QBV_ENABLED;
137
138 return 0;
139 }
140
141 /* To partially fix i226 HW errata, reduce MAC internal buffering from 192 Bytes
142 * to 88 Bytes by setting RETX_CTL register using the recommendation from:
143 * a) Ethernet Controller I225/I226 Specification Update Rev 2.1
144 * Item 9: TSN: Packet Transmission Might Cross the Qbv Window
145 * b) I225/6 SW User Manual Rev 1.2.4: Section 8.11.5 Retry Buffer Control
146 */
igc_tsn_set_retx_qbvfullthreshold(struct igc_adapter * adapter)147 static void igc_tsn_set_retx_qbvfullthreshold(struct igc_adapter *adapter)
148 {
149 struct igc_hw *hw = &adapter->hw;
150 u32 retxctl, watermark;
151
152 retxctl = rd32(IGC_RETX_CTL);
153 watermark = retxctl & IGC_RETX_CTL_WATERMARK_MASK;
154 /* Set QBVFULLTH value using watermark and set QBVFULLEN */
155 retxctl |= (watermark << IGC_RETX_CTL_QBVFULLTH_SHIFT) |
156 IGC_RETX_CTL_QBVFULLEN;
157 wr32(IGC_RETX_CTL, retxctl);
158 }
159
igc_tsn_enable_offload(struct igc_adapter * adapter)160 static int igc_tsn_enable_offload(struct igc_adapter *adapter)
161 {
162 struct igc_hw *hw = &adapter->hw;
163 u32 tqavctrl, baset_l, baset_h;
164 u32 sec, nsec, cycle;
165 ktime_t base_time, systim;
166 int i;
167
168 wr32(IGC_TSAUXC, 0);
169 wr32(IGC_DTXMXPKTSZ, IGC_DTXMXPKTSZ_TSN);
170 wr32(IGC_TXPBS, IGC_TXPBSIZE_TSN);
171
172 if (igc_is_device_id_i226(hw))
173 igc_tsn_set_retx_qbvfullthreshold(adapter);
174
175 for (i = 0; i < adapter->num_tx_queues; i++) {
176 struct igc_ring *ring = adapter->tx_ring[i];
177 u32 txqctl = 0;
178 u16 cbs_value;
179 u32 tqavcc;
180
181 wr32(IGC_STQT(i), ring->start_time);
182 wr32(IGC_ENDQT(i), ring->end_time);
183
184 if (adapter->taprio_offload_enable) {
185 /* If taprio_offload_enable is set we are in "taprio"
186 * mode and we need to be strict about the
187 * cycles: only transmit a packet if it can be
188 * completed during that cycle.
189 *
190 * If taprio_offload_enable is NOT true when
191 * enabling TSN offload, the cycle should have
192 * no external effects, but is only used internally
193 * to adapt the base time register after a second
194 * has passed.
195 *
196 * Enabling strict mode in this case would
197 * unnecessarily prevent the transmission of
198 * certain packets (i.e. at the boundary of a
199 * second) and thus interfere with the launchtime
200 * feature that promises transmission at a
201 * certain point in time.
202 */
203 txqctl |= IGC_TXQCTL_STRICT_CYCLE |
204 IGC_TXQCTL_STRICT_END;
205 }
206
207 if (ring->launchtime_enable)
208 txqctl |= IGC_TXQCTL_QUEUE_MODE_LAUNCHT;
209
210 /* Skip configuring CBS for Q2 and Q3 */
211 if (i > 1)
212 goto skip_cbs;
213
214 if (ring->cbs_enable) {
215 if (i == 0)
216 txqctl |= IGC_TXQCTL_QAV_SEL_CBS0;
217 else
218 txqctl |= IGC_TXQCTL_QAV_SEL_CBS1;
219
220 /* According to i225 datasheet section 7.5.2.7, we
221 * should set the 'idleSlope' field from TQAVCC
222 * register following the equation:
223 *
224 * value = link-speed 0x7736 * BW * 0.2
225 * ---------- * ----------------- (E1)
226 * 100Mbps 2.5
227 *
228 * Note that 'link-speed' is in Mbps.
229 *
230 * 'BW' is the percentage bandwidth out of full
231 * link speed which can be found with the
232 * following equation. Note that idleSlope here
233 * is the parameter from this function
234 * which is in kbps.
235 *
236 * BW = idleSlope
237 * ----------------- (E2)
238 * link-speed * 1000
239 *
240 * That said, we can come up with a generic
241 * equation to calculate the value we should set
242 * it TQAVCC register by replacing 'BW' in E1 by E2.
243 * The resulting equation is:
244 *
245 * value = link-speed * 0x7736 * idleSlope * 0.2
246 * ------------------------------------- (E3)
247 * 100 * 2.5 * link-speed * 1000
248 *
249 * 'link-speed' is present in both sides of the
250 * fraction so it is canceled out. The final
251 * equation is the following:
252 *
253 * value = idleSlope * 61036
254 * ----------------- (E4)
255 * 2500000
256 *
257 * NOTE: For i225, given the above, we can see
258 * that idleslope is represented in
259 * 40.959433 kbps units by the value at
260 * the TQAVCC register (2.5Gbps / 61036),
261 * which reduces the granularity for
262 * idleslope increments.
263 *
264 * In i225 controller, the sendSlope and loCredit
265 * parameters from CBS are not configurable
266 * by software so we don't do any
267 * 'controller configuration' in respect to
268 * these parameters.
269 */
270 cbs_value = DIV_ROUND_UP_ULL(ring->idleslope
271 * 61036ULL, 2500000);
272
273 tqavcc = rd32(IGC_TQAVCC(i));
274 tqavcc &= ~IGC_TQAVCC_IDLESLOPE_MASK;
275 tqavcc |= cbs_value | IGC_TQAVCC_KEEP_CREDITS;
276 wr32(IGC_TQAVCC(i), tqavcc);
277
278 wr32(IGC_TQAVHC(i),
279 0x80000000 + ring->hicredit * 0x7736);
280 } else {
281 /* Disable any CBS for the queue */
282 txqctl &= ~(IGC_TXQCTL_QAV_SEL_MASK);
283
284 /* Set idleSlope to zero. */
285 tqavcc = rd32(IGC_TQAVCC(i));
286 tqavcc &= ~(IGC_TQAVCC_IDLESLOPE_MASK |
287 IGC_TQAVCC_KEEP_CREDITS);
288 wr32(IGC_TQAVCC(i), tqavcc);
289
290 /* Set hiCredit to zero. */
291 wr32(IGC_TQAVHC(i), 0);
292 }
293 skip_cbs:
294 wr32(IGC_TXQCTL(i), txqctl);
295 }
296
297 tqavctrl = rd32(IGC_TQAVCTRL) & ~IGC_TQAVCTRL_FUTSCDDIS;
298
299 tqavctrl |= IGC_TQAVCTRL_TRANSMIT_MODE_TSN | IGC_TQAVCTRL_ENHANCED_QAV;
300
301 adapter->qbv_count++;
302
303 cycle = adapter->cycle_time;
304 base_time = adapter->base_time;
305
306 nsec = rd32(IGC_SYSTIML);
307 sec = rd32(IGC_SYSTIMH);
308
309 systim = ktime_set(sec, nsec);
310 if (ktime_compare(systim, base_time) > 0) {
311 s64 n = div64_s64(ktime_sub_ns(systim, base_time), cycle);
312
313 base_time = ktime_add_ns(base_time, (n + 1) * cycle);
314 } else {
315 if (igc_is_device_id_i226(hw)) {
316 ktime_t adjust_time, expires_time;
317
318 /* According to datasheet section 7.5.2.9.3.3, FutScdDis bit
319 * has to be configured before the cycle time and base time.
320 * Tx won't hang if a GCL is already running,
321 * so in this case we don't need to set FutScdDis.
322 */
323 if (!(rd32(IGC_BASET_H) || rd32(IGC_BASET_L)))
324 tqavctrl |= IGC_TQAVCTRL_FUTSCDDIS;
325
326 nsec = rd32(IGC_SYSTIML);
327 sec = rd32(IGC_SYSTIMH);
328 systim = ktime_set(sec, nsec);
329
330 adjust_time = adapter->base_time;
331 expires_time = ktime_sub_ns(adjust_time, systim);
332 hrtimer_start(&adapter->hrtimer, expires_time, HRTIMER_MODE_REL);
333 }
334 }
335
336 wr32(IGC_TQAVCTRL, tqavctrl);
337
338 wr32(IGC_QBVCYCLET_S, cycle);
339 wr32(IGC_QBVCYCLET, cycle);
340
341 baset_h = div_s64_rem(base_time, NSEC_PER_SEC, &baset_l);
342 wr32(IGC_BASET_H, baset_h);
343
344 /* In i226, Future base time is only supported when FutScdDis bit
345 * is enabled and only active for re-configuration.
346 * In this case, initialize the base time with zero to create
347 * "re-configuration" scenario then only set the desired base time.
348 */
349 if (tqavctrl & IGC_TQAVCTRL_FUTSCDDIS)
350 wr32(IGC_BASET_L, 0);
351 wr32(IGC_BASET_L, baset_l);
352
353 return 0;
354 }
355
igc_tsn_reset(struct igc_adapter * adapter)356 int igc_tsn_reset(struct igc_adapter *adapter)
357 {
358 unsigned int new_flags;
359 int err = 0;
360
361 new_flags = igc_tsn_new_flags(adapter);
362
363 if (!(new_flags & IGC_FLAG_TSN_ANY_ENABLED))
364 return igc_tsn_disable_offload(adapter);
365
366 err = igc_tsn_enable_offload(adapter);
367 if (err < 0)
368 return err;
369
370 adapter->flags = new_flags;
371
372 return err;
373 }
374
igc_tsn_will_tx_mode_change(struct igc_adapter * adapter)375 static bool igc_tsn_will_tx_mode_change(struct igc_adapter *adapter)
376 {
377 bool any_tsn_enabled = !!(igc_tsn_new_flags(adapter) &
378 IGC_FLAG_TSN_ANY_ENABLED);
379
380 return (any_tsn_enabled && !igc_tsn_is_tx_mode_in_tsn(adapter)) ||
381 (!any_tsn_enabled && igc_tsn_is_tx_mode_in_tsn(adapter));
382 }
383
igc_tsn_offload_apply(struct igc_adapter * adapter)384 int igc_tsn_offload_apply(struct igc_adapter *adapter)
385 {
386 /* Per I225/6 HW Design Section 7.5.2.1 guideline, if tx mode change
387 * from legacy->tsn or tsn->legacy, then reset adapter is needed.
388 */
389 if (netif_running(adapter->netdev) &&
390 igc_tsn_will_tx_mode_change(adapter)) {
391 schedule_work(&adapter->reset_task);
392 return 0;
393 }
394
395 igc_tsn_reset(adapter);
396
397 return 0;
398 }
399