Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ixgbe: convert .adjfreq to .adjfine

Convert the ixgbe PTP frequency adjustment implementations from .adjfreq to
.adjfine. This allows using the scaled parts per million adjustment from
the PTP core and results in a more precise adjustment for small
corrections.

To avoid overflow, use mul_u64_u64_div_u64 to perform the calculation. On
X86 platforms, this will use instructions that perform the operations with
128bit intermediate values. For other architectures, the implementation
will limit the loss of precision as much as possible.

This change slightly improves the precision of frequency adjustments for
all ixgbe based devices, and gets us one driver closer to being able to
remove the older .adjfreq implementation from the kernel.

Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Gurucharan <gurucharanx.g@intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>

authored by

Jacob Keller and committed by
Tony Nguyen
5a554232 ccd3bf98

+40 -33
+40 -33
drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
··· 113 113 * the sign bit. This register enables software to calculate frequency 114 114 * adjustments and apply them directly to the clock rate. 115 115 * 116 - * The math for converting ppb into TIMINCA values is fairly straightforward. 117 - * TIMINCA value = ( Base_Frequency * ppb ) / 1000000000ULL 116 + * The math for converting scaled_ppm into TIMINCA values is fairly 117 + * straightforward. 118 118 * 119 - * This assumes that ppb is never high enough to create a value bigger than 120 - * TIMINCA's 31 bits can store. This is ensured by the stack. Calculating this 121 - * value is also simple. 119 + * TIMINCA value = ( Base_Frequency * scaled_ppm ) / 1000000ULL << 16 120 + * 121 + * To avoid overflow, we simply use mul_u64_u64_div_u64. 122 + * 123 + * This assumes that scaled_ppm is never high enough to create a value bigger 124 + * than TIMINCA's 31 bits can store. This is ensured by the stack, and is 125 + * measured in parts per billion. Calculating this value is also simple. 122 126 * Max ppb = ( Max Adjustment / Base Frequency ) / 1000000000ULL 123 127 * 124 128 * For the X550, the Max adjustment is +/- 0.5 ns, and the base frequency is ··· 437 433 } 438 434 439 435 /** 440 - * ixgbe_ptp_adjfreq_82599 436 + * ixgbe_ptp_adjfine_82599 441 437 * @ptp: the ptp clock structure 442 - * @ppb: parts per billion adjustment from base 438 + * @scaled_ppm: scaled parts per million adjustment from base 443 439 * 444 - * adjust the frequency of the ptp cycle counter by the 445 - * indicated ppb from the base frequency. 440 + * Adjust the frequency of the ptp cycle counter by the 441 + * indicated scaled_ppm from the base frequency. 442 + * 443 + * Scaled parts per million is ppm with a 16-bit binary fractional field. 446 444 */ 447 - static int ixgbe_ptp_adjfreq_82599(struct ptp_clock_info *ptp, s32 ppb) 445 + static int ixgbe_ptp_adjfine_82599(struct ptp_clock_info *ptp, long scaled_ppm) 448 446 { 449 447 struct ixgbe_adapter *adapter = 450 448 container_of(ptp, struct ixgbe_adapter, ptp_caps); 451 449 struct ixgbe_hw *hw = &adapter->hw; 452 - u64 freq, incval; 453 - u32 diff; 450 + u64 incval, diff; 454 451 int neg_adj = 0; 455 452 456 - if (ppb < 0) { 453 + if (scaled_ppm < 0) { 457 454 neg_adj = 1; 458 - ppb = -ppb; 455 + scaled_ppm = -scaled_ppm; 459 456 } 460 457 461 458 smp_mb(); 462 459 incval = READ_ONCE(adapter->base_incval); 463 460 464 - freq = incval; 465 - freq *= ppb; 466 - diff = div_u64(freq, 1000000000ULL); 461 + diff = mul_u64_u64_div_u64(incval, scaled_ppm, 462 + 1000000ULL << 16); 467 463 468 464 incval = neg_adj ? (incval - diff) : (incval + diff); 469 465 470 466 switch (hw->mac.type) { 471 467 case ixgbe_mac_X540: 472 468 if (incval > 0xFFFFFFFFULL) 473 - e_dev_warn("PTP ppb adjusted SYSTIME rate overflowed!\n"); 469 + e_dev_warn("PTP scaled_ppm adjusted SYSTIME rate overflowed!\n"); 474 470 IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, (u32)incval); 475 471 break; 476 472 case ixgbe_mac_82599EB: 477 473 if (incval > 0x00FFFFFFULL) 478 - e_dev_warn("PTP ppb adjusted SYSTIME rate overflowed!\n"); 474 + e_dev_warn("PTP scaled_ppm adjusted SYSTIME rate overflowed!\n"); 479 475 IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, 480 476 BIT(IXGBE_INCPER_SHIFT_82599) | 481 477 ((u32)incval & 0x00FFFFFFUL)); ··· 488 484 } 489 485 490 486 /** 491 - * ixgbe_ptp_adjfreq_X550 487 + * ixgbe_ptp_adjfine_X550 492 488 * @ptp: the ptp clock structure 493 - * @ppb: parts per billion adjustment from base 489 + * @scaled_ppm: scaled parts per million adjustment from base 494 490 * 495 - * adjust the frequency of the SYSTIME registers by the indicated ppb from base 496 - * frequency 491 + * Adjust the frequency of the SYSTIME registers by the indicated scaled_ppm 492 + * from base frequency. 493 + * 494 + * Scaled parts per million is ppm with a 16-bit binary fractional field. 497 495 */ 498 - static int ixgbe_ptp_adjfreq_X550(struct ptp_clock_info *ptp, s32 ppb) 496 + static int ixgbe_ptp_adjfine_X550(struct ptp_clock_info *ptp, long scaled_ppm) 499 497 { 500 498 struct ixgbe_adapter *adapter = 501 499 container_of(ptp, struct ixgbe_adapter, ptp_caps); 502 500 struct ixgbe_hw *hw = &adapter->hw; 503 501 int neg_adj = 0; 504 - u64 rate = IXGBE_X550_BASE_PERIOD; 502 + u64 rate; 505 503 u32 inca; 506 504 507 - if (ppb < 0) { 505 + if (scaled_ppm < 0) { 508 506 neg_adj = 1; 509 - ppb = -ppb; 507 + scaled_ppm = -scaled_ppm; 510 508 } 511 - rate *= ppb; 512 - rate = div_u64(rate, 1000000000ULL); 509 + 510 + rate = mul_u64_u64_div_u64(IXGBE_X550_BASE_PERIOD, scaled_ppm, 511 + 1000000ULL << 16); 513 512 514 513 /* warn if rate is too large */ 515 514 if (rate >= INCVALUE_MASK) 516 - e_dev_warn("PTP ppb adjusted SYSTIME rate overflowed!\n"); 515 + e_dev_warn("PTP scaled_ppm adjusted SYSTIME rate overflowed!\n"); 517 516 518 517 inca = rate & INCVALUE_MASK; 519 518 if (neg_adj) ··· 1362 1355 adapter->ptp_caps.n_ext_ts = 0; 1363 1356 adapter->ptp_caps.n_per_out = 0; 1364 1357 adapter->ptp_caps.pps = 1; 1365 - adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_82599; 1358 + adapter->ptp_caps.adjfine = ixgbe_ptp_adjfine_82599; 1366 1359 adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; 1367 1360 adapter->ptp_caps.gettimex64 = ixgbe_ptp_gettimex; 1368 1361 adapter->ptp_caps.settime64 = ixgbe_ptp_settime; ··· 1379 1372 adapter->ptp_caps.n_ext_ts = 0; 1380 1373 adapter->ptp_caps.n_per_out = 0; 1381 1374 adapter->ptp_caps.pps = 0; 1382 - adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_82599; 1375 + adapter->ptp_caps.adjfine = ixgbe_ptp_adjfine_82599; 1383 1376 adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; 1384 1377 adapter->ptp_caps.gettimex64 = ixgbe_ptp_gettimex; 1385 1378 adapter->ptp_caps.settime64 = ixgbe_ptp_settime; ··· 1395 1388 adapter->ptp_caps.n_ext_ts = 0; 1396 1389 adapter->ptp_caps.n_per_out = 0; 1397 1390 adapter->ptp_caps.pps = 1; 1398 - adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_X550; 1391 + adapter->ptp_caps.adjfine = ixgbe_ptp_adjfine_X550; 1399 1392 adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; 1400 1393 adapter->ptp_caps.gettimex64 = ixgbe_ptp_gettimex; 1401 1394 adapter->ptp_caps.settime64 = ixgbe_ptp_settime;