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 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 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 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 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 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 (!is_any_launchtime(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 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 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 */ 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 */ 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 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 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 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 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