hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
....@@ -72,13 +72,13 @@
7272 #define IXGBE_INCPER_SHIFT_82599 24
7373
7474 #define IXGBE_OVERFLOW_PERIOD (HZ * 30)
75
-#define IXGBE_PTP_TX_TIMEOUT (HZ * 15)
75
+#define IXGBE_PTP_TX_TIMEOUT (HZ)
7676
77
-/* half of a one second clock period, for use with PPS signal. We have to use
78
- * this instead of something pre-defined like IXGBE_PTP_PPS_HALF_SECOND, in
79
- * order to force at least 64bits of precision for shifting
77
+/* We use our own definitions instead of NSEC_PER_SEC because we want to mark
78
+ * the value as a ULL to force precision when bit shifting.
8079 */
81
-#define IXGBE_PTP_PPS_HALF_SECOND 500000000ULL
80
+#define NS_PER_SEC 1000000000ULL
81
+#define NS_PER_HALF_SEC 500000000ULL
8282
8383 /* In contrast, the X550 controller has two registers, SYSTIMEH and SYSTIMEL
8484 * which contain measurements of seconds and nanoseconds respectively. This
....@@ -141,23 +141,26 @@
141141 #define MAX_TIMADJ 0x7FFFFFFF
142142
143143 /**
144
- * ixgbe_ptp_setup_sdp_x540
144
+ * ixgbe_ptp_setup_sdp_X540
145145 * @adapter: private adapter structure
146146 *
147147 * this function enables or disables the clock out feature on SDP0 for
148
- * the X540 device. It will create a 1second periodic output that can
148
+ * the X540 device. It will create a 1 second periodic output that can
149149 * be used as the PPS (via an interrupt).
150150 *
151
- * It calculates when the systime will be on an exact second, and then
152
- * aligns the start of the PPS signal to that value. The shift is
153
- * necessary because it can change based on the link speed.
151
+ * It calculates when the system time will be on an exact second, and then
152
+ * aligns the start of the PPS signal to that value.
153
+ *
154
+ * This works by using the cycle counter shift and mult values in reverse, and
155
+ * assumes that the values we're shifting will not overflow.
154156 */
155
-static void ixgbe_ptp_setup_sdp_x540(struct ixgbe_adapter *adapter)
157
+static void ixgbe_ptp_setup_sdp_X540(struct ixgbe_adapter *adapter)
156158 {
159
+ struct cyclecounter *cc = &adapter->hw_cc;
157160 struct ixgbe_hw *hw = &adapter->hw;
158
- int shift = adapter->hw_cc.shift;
159161 u32 esdp, tsauxc, clktiml, clktimh, trgttiml, trgttimh, rem;
160
- u64 ns = 0, clock_edge = 0;
162
+ u64 ns = 0, clock_edge = 0, clock_period;
163
+ unsigned long flags;
161164
162165 /* disable the pin first */
163166 IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0);
....@@ -177,26 +180,33 @@
177180 /* enable the Clock Out feature on SDP0, and allow
178181 * interrupts to occur when the pin changes
179182 */
180
- tsauxc = IXGBE_TSAUXC_EN_CLK |
181
- IXGBE_TSAUXC_SYNCLK |
182
- IXGBE_TSAUXC_SDP0_INT;
183
+ tsauxc = (IXGBE_TSAUXC_EN_CLK |
184
+ IXGBE_TSAUXC_SYNCLK |
185
+ IXGBE_TSAUXC_SDP0_INT);
183186
184
- /* clock period (or pulse length) */
185
- clktiml = (u32)(IXGBE_PTP_PPS_HALF_SECOND << shift);
186
- clktimh = (u32)((IXGBE_PTP_PPS_HALF_SECOND << shift) >> 32);
187
-
188
- /* Account for the cyclecounter wrap-around value by
189
- * using the converted ns value of the current time to
190
- * check for when the next aligned second would occur.
187
+ /* Determine the clock time period to use. This assumes that the
188
+ * cycle counter shift is small enough to avoid overflow.
191189 */
192
- clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIML);
193
- clock_edge |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32;
194
- ns = timecounter_cyc2time(&adapter->hw_tc, clock_edge);
190
+ clock_period = div_u64((NS_PER_HALF_SEC << cc->shift), cc->mult);
191
+ clktiml = (u32)(clock_period);
192
+ clktimh = (u32)(clock_period >> 32);
195193
196
- div_u64_rem(ns, IXGBE_PTP_PPS_HALF_SECOND, &rem);
197
- clock_edge += ((IXGBE_PTP_PPS_HALF_SECOND - (u64)rem) << shift);
194
+ /* Read the current clock time, and save the cycle counter value */
195
+ spin_lock_irqsave(&adapter->tmreg_lock, flags);
196
+ ns = timecounter_read(&adapter->hw_tc);
197
+ clock_edge = adapter->hw_tc.cycle_last;
198
+ spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
198199
199
- /* specify the initial clock start time */
200
+ /* Figure out how many seconds to add in order to round up */
201
+ div_u64_rem(ns, NS_PER_SEC, &rem);
202
+
203
+ /* Figure out how many nanoseconds to add to round the clock edge up
204
+ * to the next full second
205
+ */
206
+ rem = (NS_PER_SEC - rem);
207
+
208
+ /* Adjust the clock edge to align with the next full second. */
209
+ clock_edge += div_u64(((u64)rem << cc->shift), cc->mult);
200210 trgttiml = (u32)clock_edge;
201211 trgttimh = (u32)(clock_edge >> 32);
202212
....@@ -212,8 +222,100 @@
212222 }
213223
214224 /**
225
+ * ixgbe_ptp_setup_sdp_X550
226
+ * @adapter: private adapter structure
227
+ *
228
+ * Enable or disable a clock output signal on SDP 0 for X550 hardware.
229
+ *
230
+ * Use the target time feature to align the output signal on the next full
231
+ * second.
232
+ *
233
+ * This works by using the cycle counter shift and mult values in reverse, and
234
+ * assumes that the values we're shifting will not overflow.
235
+ */
236
+static void ixgbe_ptp_setup_sdp_X550(struct ixgbe_adapter *adapter)
237
+{
238
+ u32 esdp, tsauxc, freqout, trgttiml, trgttimh, rem, tssdp;
239
+ struct cyclecounter *cc = &adapter->hw_cc;
240
+ struct ixgbe_hw *hw = &adapter->hw;
241
+ u64 ns = 0, clock_edge = 0;
242
+ struct timespec64 ts;
243
+ unsigned long flags;
244
+
245
+ /* disable the pin first */
246
+ IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0);
247
+ IXGBE_WRITE_FLUSH(hw);
248
+
249
+ if (!(adapter->flags2 & IXGBE_FLAG2_PTP_PPS_ENABLED))
250
+ return;
251
+
252
+ esdp = IXGBE_READ_REG(hw, IXGBE_ESDP);
253
+
254
+ /* enable the SDP0 pin as output, and connected to the
255
+ * native function for Timesync (ClockOut)
256
+ */
257
+ esdp |= IXGBE_ESDP_SDP0_DIR |
258
+ IXGBE_ESDP_SDP0_NATIVE;
259
+
260
+ /* enable the Clock Out feature on SDP0, and use Target Time 0 to
261
+ * enable generation of interrupts on the clock change.
262
+ */
263
+#define IXGBE_TSAUXC_DIS_TS_CLEAR 0x40000000
264
+ tsauxc = (IXGBE_TSAUXC_EN_CLK | IXGBE_TSAUXC_ST0 |
265
+ IXGBE_TSAUXC_EN_TT0 | IXGBE_TSAUXC_SDP0_INT |
266
+ IXGBE_TSAUXC_DIS_TS_CLEAR);
267
+
268
+ tssdp = (IXGBE_TSSDP_TS_SDP0_EN |
269
+ IXGBE_TSSDP_TS_SDP0_CLK0);
270
+
271
+ /* Determine the clock time period to use. This assumes that the
272
+ * cycle counter shift is small enough to avoid overflowing a 32bit
273
+ * value.
274
+ */
275
+ freqout = div_u64(NS_PER_HALF_SEC << cc->shift, cc->mult);
276
+
277
+ /* Read the current clock time, and save the cycle counter value */
278
+ spin_lock_irqsave(&adapter->tmreg_lock, flags);
279
+ ns = timecounter_read(&adapter->hw_tc);
280
+ clock_edge = adapter->hw_tc.cycle_last;
281
+ spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
282
+
283
+ /* Figure out how far past the next second we are */
284
+ div_u64_rem(ns, NS_PER_SEC, &rem);
285
+
286
+ /* Figure out how many nanoseconds to add to round the clock edge up
287
+ * to the next full second
288
+ */
289
+ rem = (NS_PER_SEC - rem);
290
+
291
+ /* Adjust the clock edge to align with the next full second. */
292
+ clock_edge += div_u64(((u64)rem << cc->shift), cc->mult);
293
+
294
+ /* X550 hardware stores the time in 32bits of 'billions of cycles' and
295
+ * 32bits of 'cycles'. There's no guarantee that cycles represents
296
+ * nanoseconds. However, we can use the math from a timespec64 to
297
+ * convert into the hardware representation.
298
+ *
299
+ * See ixgbe_ptp_read_X550() for more details.
300
+ */
301
+ ts = ns_to_timespec64(clock_edge);
302
+ trgttiml = (u32)ts.tv_nsec;
303
+ trgttimh = (u32)ts.tv_sec;
304
+
305
+ IXGBE_WRITE_REG(hw, IXGBE_FREQOUT0, freqout);
306
+ IXGBE_WRITE_REG(hw, IXGBE_TRGTTIML0, trgttiml);
307
+ IXGBE_WRITE_REG(hw, IXGBE_TRGTTIMH0, trgttimh);
308
+
309
+ IXGBE_WRITE_REG(hw, IXGBE_ESDP, esdp);
310
+ IXGBE_WRITE_REG(hw, IXGBE_TSSDP, tssdp);
311
+ IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, tsauxc);
312
+
313
+ IXGBE_WRITE_FLUSH(hw);
314
+}
315
+
316
+/**
215317 * ixgbe_ptp_read_X550 - read cycle counter value
216
- * @hw_cc: cyclecounter structure
318
+ * @cc: cyclecounter structure
217319 *
218320 * This function reads SYSTIME registers. It is called by the cyclecounter
219321 * structure to convert from internal representation into nanoseconds. We need
....@@ -221,10 +323,10 @@
221323 * result of SYSTIME is 32bits of "billions of cycles" and 32 bits of
222324 * "cycles", rather than seconds and nanoseconds.
223325 */
224
-static u64 ixgbe_ptp_read_X550(const struct cyclecounter *hw_cc)
326
+static u64 ixgbe_ptp_read_X550(const struct cyclecounter *cc)
225327 {
226328 struct ixgbe_adapter *adapter =
227
- container_of(hw_cc, struct ixgbe_adapter, hw_cc);
329
+ container_of(cc, struct ixgbe_adapter, hw_cc);
228330 struct ixgbe_hw *hw = &adapter->hw;
229331 struct timespec64 ts;
230332
....@@ -443,22 +545,52 @@
443545 }
444546
445547 /**
446
- * ixgbe_ptp_gettime
548
+ * ixgbe_ptp_gettimex
447549 * @ptp: the ptp clock structure
448
- * @ts: timespec structure to hold the current time value
550
+ * @ts: timespec to hold the PHC timestamp
551
+ * @sts: structure to hold the system time before and after reading the PHC
449552 *
450553 * read the timecounter and return the correct value on ns,
451554 * after converting it into a struct timespec.
452555 */
453
-static int ixgbe_ptp_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
556
+static int ixgbe_ptp_gettimex(struct ptp_clock_info *ptp,
557
+ struct timespec64 *ts,
558
+ struct ptp_system_timestamp *sts)
454559 {
455560 struct ixgbe_adapter *adapter =
456561 container_of(ptp, struct ixgbe_adapter, ptp_caps);
562
+ struct ixgbe_hw *hw = &adapter->hw;
457563 unsigned long flags;
458
- u64 ns;
564
+ u64 ns, stamp;
459565
460566 spin_lock_irqsave(&adapter->tmreg_lock, flags);
461
- ns = timecounter_read(&adapter->hw_tc);
567
+
568
+ switch (adapter->hw.mac.type) {
569
+ case ixgbe_mac_X550:
570
+ case ixgbe_mac_X550EM_x:
571
+ case ixgbe_mac_x550em_a:
572
+ /* Upper 32 bits represent billions of cycles, lower 32 bits
573
+ * represent cycles. However, we use timespec64_to_ns for the
574
+ * correct math even though the units haven't been corrected
575
+ * yet.
576
+ */
577
+ ptp_read_system_prets(sts);
578
+ IXGBE_READ_REG(hw, IXGBE_SYSTIMR);
579
+ ptp_read_system_postts(sts);
580
+ ts->tv_nsec = IXGBE_READ_REG(hw, IXGBE_SYSTIML);
581
+ ts->tv_sec = IXGBE_READ_REG(hw, IXGBE_SYSTIMH);
582
+ stamp = timespec64_to_ns(ts);
583
+ break;
584
+ default:
585
+ ptp_read_system_prets(sts);
586
+ stamp = IXGBE_READ_REG(hw, IXGBE_SYSTIML);
587
+ ptp_read_system_postts(sts);
588
+ stamp |= (u64)IXGBE_READ_REG(hw, IXGBE_SYSTIMH) << 32;
589
+ break;
590
+ }
591
+
592
+ ns = timecounter_cyc2time(&adapter->hw_tc, stamp);
593
+
462594 spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
463595
464596 *ts = ns_to_timespec64(ns);
....@@ -567,10 +699,14 @@
567699 {
568700 bool timeout = time_is_before_jiffies(adapter->last_overflow_check +
569701 IXGBE_OVERFLOW_PERIOD);
570
- struct timespec64 ts;
702
+ unsigned long flags;
571703
572704 if (timeout) {
573
- ixgbe_ptp_gettime(&adapter->ptp_caps, &ts);
705
+ /* Update the timecounter */
706
+ spin_lock_irqsave(&adapter->tmreg_lock, flags);
707
+ timecounter_read(&adapter->hw_tc);
708
+ spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
709
+
574710 adapter->last_overflow_check = jiffies;
575711 }
576712 }
....@@ -804,6 +940,15 @@
804940 ixgbe_ptp_convert_to_hwtstamp(adapter, skb_hwtstamps(skb), regval);
805941 }
806942
943
+/**
944
+ * ixgbe_ptp_get_ts_config - get current hardware timestamping configuration
945
+ * @adapter: pointer to adapter structure
946
+ * @ifr: ioctl data
947
+ *
948
+ * This function returns the current timestamping settings. Rather than
949
+ * attempt to deconstruct registers to fill in the values, simply keep a copy
950
+ * of the old settings around, and return a copy when requested.
951
+ */
807952 int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
808953 {
809954 struct hwtstamp_config *config = &adapter->tstamp_config;
....@@ -906,7 +1051,7 @@
9061051 adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED;
9071052 break;
9081053 }
909
- /* fall through */
1054
+ fallthrough;
9101055 default:
9111056 /*
9121057 * register RXMTRL must be set in order to do V1 packets,
....@@ -1066,7 +1211,6 @@
10661211 struct cyclecounter cc;
10671212 unsigned long flags;
10681213 u32 incval = 0;
1069
- u32 tsauxc = 0;
10701214 u32 fuse0 = 0;
10711215
10721216 /* For some of the boards below this mask is technically incorrect.
....@@ -1097,22 +1241,10 @@
10971241 cc.mult = 3;
10981242 cc.shift = 2;
10991243 }
1100
- /* fallthrough */
1244
+ fallthrough;
11011245 case ixgbe_mac_x550em_a:
11021246 case ixgbe_mac_X550:
11031247 cc.read = ixgbe_ptp_read_X550;
1104
-
1105
- /* enable SYSTIME counter */
1106
- IXGBE_WRITE_REG(hw, IXGBE_SYSTIMR, 0);
1107
- IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0);
1108
- IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0);
1109
- tsauxc = IXGBE_READ_REG(hw, IXGBE_TSAUXC);
1110
- IXGBE_WRITE_REG(hw, IXGBE_TSAUXC,
1111
- tsauxc & ~IXGBE_TSAUXC_DISABLE_SYSTIME);
1112
- IXGBE_WRITE_REG(hw, IXGBE_TSIM, IXGBE_TSIM_TXTS);
1113
- IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_TIMESYNC);
1114
-
1115
- IXGBE_WRITE_FLUSH(hw);
11161248 break;
11171249 case ixgbe_mac_X540:
11181250 cc.read = ixgbe_ptp_read_82599;
....@@ -1145,6 +1277,50 @@
11451277 }
11461278
11471279 /**
1280
+ * ixgbe_ptp_init_systime - Initialize SYSTIME registers
1281
+ * @adapter: the ixgbe private board structure
1282
+ *
1283
+ * Initialize and start the SYSTIME registers.
1284
+ */
1285
+static void ixgbe_ptp_init_systime(struct ixgbe_adapter *adapter)
1286
+{
1287
+ struct ixgbe_hw *hw = &adapter->hw;
1288
+ u32 tsauxc;
1289
+
1290
+ switch (hw->mac.type) {
1291
+ case ixgbe_mac_X550EM_x:
1292
+ case ixgbe_mac_x550em_a:
1293
+ case ixgbe_mac_X550:
1294
+ tsauxc = IXGBE_READ_REG(hw, IXGBE_TSAUXC);
1295
+
1296
+ /* Reset SYSTIME registers to 0 */
1297
+ IXGBE_WRITE_REG(hw, IXGBE_SYSTIMR, 0);
1298
+ IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0);
1299
+ IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0);
1300
+
1301
+ /* Reset interrupt settings */
1302
+ IXGBE_WRITE_REG(hw, IXGBE_TSIM, IXGBE_TSIM_TXTS);
1303
+ IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_TIMESYNC);
1304
+
1305
+ /* Activate the SYSTIME counter */
1306
+ IXGBE_WRITE_REG(hw, IXGBE_TSAUXC,
1307
+ tsauxc & ~IXGBE_TSAUXC_DISABLE_SYSTIME);
1308
+ break;
1309
+ case ixgbe_mac_X540:
1310
+ case ixgbe_mac_82599EB:
1311
+ /* Reset SYSTIME registers to 0 */
1312
+ IXGBE_WRITE_REG(hw, IXGBE_SYSTIML, 0);
1313
+ IXGBE_WRITE_REG(hw, IXGBE_SYSTIMH, 0);
1314
+ break;
1315
+ default:
1316
+ /* Other devices aren't supported */
1317
+ return;
1318
+ };
1319
+
1320
+ IXGBE_WRITE_FLUSH(hw);
1321
+}
1322
+
1323
+/**
11481324 * ixgbe_ptp_reset
11491325 * @adapter: the ixgbe private board structure
11501326 *
....@@ -1169,6 +1345,8 @@
11691345 return;
11701346
11711347 ixgbe_ptp_start_cyclecounter(adapter);
1348
+
1349
+ ixgbe_ptp_init_systime(adapter);
11721350
11731351 spin_lock_irqsave(&adapter->tmreg_lock, flags);
11741352 timecounter_init(&adapter->hw_tc, &adapter->hw_cc,
....@@ -1216,10 +1394,10 @@
12161394 adapter->ptp_caps.pps = 1;
12171395 adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_82599;
12181396 adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime;
1219
- adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime;
1397
+ adapter->ptp_caps.gettimex64 = ixgbe_ptp_gettimex;
12201398 adapter->ptp_caps.settime64 = ixgbe_ptp_settime;
12211399 adapter->ptp_caps.enable = ixgbe_ptp_feature_enable;
1222
- adapter->ptp_setup_sdp = ixgbe_ptp_setup_sdp_x540;
1400
+ adapter->ptp_setup_sdp = ixgbe_ptp_setup_sdp_X540;
12231401 break;
12241402 case ixgbe_mac_82599EB:
12251403 snprintf(adapter->ptp_caps.name,
....@@ -1233,7 +1411,7 @@
12331411 adapter->ptp_caps.pps = 0;
12341412 adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_82599;
12351413 adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime;
1236
- adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime;
1414
+ adapter->ptp_caps.gettimex64 = ixgbe_ptp_gettimex;
12371415 adapter->ptp_caps.settime64 = ixgbe_ptp_settime;
12381416 adapter->ptp_caps.enable = ixgbe_ptp_feature_enable;
12391417 break;
....@@ -1246,13 +1424,13 @@
12461424 adapter->ptp_caps.n_alarm = 0;
12471425 adapter->ptp_caps.n_ext_ts = 0;
12481426 adapter->ptp_caps.n_per_out = 0;
1249
- adapter->ptp_caps.pps = 0;
1427
+ adapter->ptp_caps.pps = 1;
12501428 adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_X550;
12511429 adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime;
1252
- adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime;
1430
+ adapter->ptp_caps.gettimex64 = ixgbe_ptp_gettimex;
12531431 adapter->ptp_caps.settime64 = ixgbe_ptp_settime;
12541432 adapter->ptp_caps.enable = ixgbe_ptp_feature_enable;
1255
- adapter->ptp_setup_sdp = NULL;
1433
+ adapter->ptp_setup_sdp = ixgbe_ptp_setup_sdp_X550;
12561434 break;
12571435 default:
12581436 adapter->ptp_clock = NULL;