@@ -149,18 +149,14 @@ enum ptp_packet_state {
149
149
/* Maximum parts-per-billion adjustment that is acceptable */
150
150
#define MAX_PPB 1000000
151
151
152
- /* Number of bits required to hold the above */
153
- #define MAX_PPB_BITS 20
154
-
155
- /* Number of extra bits allowed when calculating fractional ns.
156
- * EXTRA_BITS + MC_CMD_PTP_IN_ADJUST_BITS + MAX_PPB_BITS should
157
- * be less than 63.
158
- */
159
- #define PPB_EXTRA_BITS 2
160
-
161
152
/* Precalculate scale word to avoid long long division at runtime */
162
- #define PPB_SCALE_WORD ((1LL << (PPB_EXTRA_BITS + MC_CMD_PTP_IN_ADJUST_BITS +\
163
- MAX_PPB_BITS)) / 1000000000LL)
153
+ /* This is equivalent to 2^66 / 10^9. */
154
+ #define PPB_SCALE_WORD ((1LL << (57)) / 1953125LL)
155
+
156
+ /* How much to shift down after scaling to convert to FP40 */
157
+ #define PPB_SHIFT_FP40 26
158
+ /* ... and FP44. */
159
+ #define PPB_SHIFT_FP44 22
164
160
165
161
#define PTP_SYNC_ATTEMPTS 4
166
162
@@ -261,6 +257,8 @@ struct efx_ptp_timeset {
261
257
* @evt_code: Last event code
262
258
* @start: Address at which MC indicates ready for synchronisation
263
259
* @host_time_pps: Host time at last PPS
260
+ * @adjfreq_ppb_shift: Shift required to convert scaled parts-per-billion
261
+ * frequency adjustment into a fixed point fractional nanosecond format.
264
262
* @current_adjfreq: Current ppb adjustment.
265
263
* @phc_clock: Pointer to registered phc device (if primary function)
266
264
* @phc_clock_info: Registration structure for phc device
@@ -310,6 +308,7 @@ struct efx_ptp_data {
310
308
unsigned int sync_event_minor_shift ;
311
309
} nic_time ;
312
310
unsigned int min_synchronisation_ns ;
311
+ unsigned int capabilities ;
313
312
struct {
314
313
s32 ptp_tx ;
315
314
s32 ptp_rx ;
@@ -323,6 +322,7 @@ struct efx_ptp_data {
323
322
int evt_code ;
324
323
struct efx_buffer start ;
325
324
struct pps_event_time host_time_pps ;
325
+ unsigned int adjfreq_ppb_shift ;
326
326
s64 current_adjfreq ;
327
327
struct ptp_clock * phc_clock ;
328
328
struct ptp_clock_info phc_clock_info ;
@@ -676,6 +676,22 @@ static int efx_ptp_get_attributes(struct efx_nic *efx)
676
676
else
677
677
ptp -> min_synchronisation_ns = DEFAULT_MIN_SYNCHRONISATION_NS ;
678
678
679
+ if (rc == 0 &&
680
+ out_len >= MC_CMD_PTP_OUT_GET_ATTRIBUTES_LEN )
681
+ ptp -> capabilities = MCDI_DWORD (outbuf ,
682
+ PTP_OUT_GET_ATTRIBUTES_CAPABILITIES );
683
+ else
684
+ ptp -> capabilities = 0 ;
685
+
686
+ /* Set up the shift for conversion between frequency
687
+ * adjustments in parts-per-billion and the fixed-point
688
+ * fractional ns format that the adapter uses.
689
+ */
690
+ if (ptp -> capabilities & (1 << MC_CMD_PTP_OUT_GET_ATTRIBUTES_FP44_FREQ_ADJ_LBN ))
691
+ ptp -> adjfreq_ppb_shift = PPB_SHIFT_FP44 ;
692
+ else
693
+ ptp -> adjfreq_ppb_shift = PPB_SHIFT_FP40 ;
694
+
679
695
return 0 ;
680
696
}
681
697
@@ -2027,9 +2043,10 @@ static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta)
2027
2043
else if (delta < - MAX_PPB )
2028
2044
delta = - MAX_PPB ;
2029
2045
2030
- /* Convert ppb to fixed point ns. */
2031
- adjustment_ns = (((s64 )delta * PPB_SCALE_WORD ) >>
2032
- (PPB_EXTRA_BITS + MAX_PPB_BITS ));
2046
+ /* Convert ppb to fixed point ns taking care to round correctly. */
2047
+ adjustment_ns = ((s64 )delta * PPB_SCALE_WORD +
2048
+ (1 << (ptp_data -> adjfreq_ppb_shift - 1 ))) >>
2049
+ ptp_data -> adjfreq_ppb_shift ;
2033
2050
2034
2051
MCDI_SET_DWORD (inadj , PTP_IN_OP , MC_CMD_PTP_OP_ADJUST );
2035
2052
MCDI_SET_DWORD (inadj , PTP_IN_PERIPH_ID , 0 );
0 commit comments