.. | .. |
---|
72 | 72 | #define IXGBE_INCPER_SHIFT_82599 24 |
---|
73 | 73 | |
---|
74 | 74 | #define IXGBE_OVERFLOW_PERIOD (HZ * 30) |
---|
75 | | -#define IXGBE_PTP_TX_TIMEOUT (HZ * 15) |
---|
| 75 | +#define IXGBE_PTP_TX_TIMEOUT (HZ) |
---|
76 | 76 | |
---|
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. |
---|
80 | 79 | */ |
---|
81 | | -#define IXGBE_PTP_PPS_HALF_SECOND 500000000ULL |
---|
| 80 | +#define NS_PER_SEC 1000000000ULL |
---|
| 81 | +#define NS_PER_HALF_SEC 500000000ULL |
---|
82 | 82 | |
---|
83 | 83 | /* In contrast, the X550 controller has two registers, SYSTIMEH and SYSTIMEL |
---|
84 | 84 | * which contain measurements of seconds and nanoseconds respectively. This |
---|
.. | .. |
---|
141 | 141 | #define MAX_TIMADJ 0x7FFFFFFF |
---|
142 | 142 | |
---|
143 | 143 | /** |
---|
144 | | - * ixgbe_ptp_setup_sdp_x540 |
---|
| 144 | + * ixgbe_ptp_setup_sdp_X540 |
---|
145 | 145 | * @adapter: private adapter structure |
---|
146 | 146 | * |
---|
147 | 147 | * 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 |
---|
149 | 149 | * be used as the PPS (via an interrupt). |
---|
150 | 150 | * |
---|
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. |
---|
154 | 156 | */ |
---|
155 | | -static void ixgbe_ptp_setup_sdp_x540(struct ixgbe_adapter *adapter) |
---|
| 157 | +static void ixgbe_ptp_setup_sdp_X540(struct ixgbe_adapter *adapter) |
---|
156 | 158 | { |
---|
| 159 | + struct cyclecounter *cc = &adapter->hw_cc; |
---|
157 | 160 | struct ixgbe_hw *hw = &adapter->hw; |
---|
158 | | - int shift = adapter->hw_cc.shift; |
---|
159 | 161 | 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; |
---|
161 | 164 | |
---|
162 | 165 | /* disable the pin first */ |
---|
163 | 166 | IXGBE_WRITE_REG(hw, IXGBE_TSAUXC, 0x0); |
---|
.. | .. |
---|
177 | 180 | /* enable the Clock Out feature on SDP0, and allow |
---|
178 | 181 | * interrupts to occur when the pin changes |
---|
179 | 182 | */ |
---|
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); |
---|
183 | 186 | |
---|
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. |
---|
191 | 189 | */ |
---|
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); |
---|
195 | 193 | |
---|
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); |
---|
198 | 199 | |
---|
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); |
---|
200 | 210 | trgttiml = (u32)clock_edge; |
---|
201 | 211 | trgttimh = (u32)(clock_edge >> 32); |
---|
202 | 212 | |
---|
.. | .. |
---|
212 | 222 | } |
---|
213 | 223 | |
---|
214 | 224 | /** |
---|
| 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 | +/** |
---|
215 | 317 | * ixgbe_ptp_read_X550 - read cycle counter value |
---|
216 | | - * @hw_cc: cyclecounter structure |
---|
| 318 | + * @cc: cyclecounter structure |
---|
217 | 319 | * |
---|
218 | 320 | * This function reads SYSTIME registers. It is called by the cyclecounter |
---|
219 | 321 | * structure to convert from internal representation into nanoseconds. We need |
---|
.. | .. |
---|
221 | 323 | * result of SYSTIME is 32bits of "billions of cycles" and 32 bits of |
---|
222 | 324 | * "cycles", rather than seconds and nanoseconds. |
---|
223 | 325 | */ |
---|
224 | | -static u64 ixgbe_ptp_read_X550(const struct cyclecounter *hw_cc) |
---|
| 326 | +static u64 ixgbe_ptp_read_X550(const struct cyclecounter *cc) |
---|
225 | 327 | { |
---|
226 | 328 | struct ixgbe_adapter *adapter = |
---|
227 | | - container_of(hw_cc, struct ixgbe_adapter, hw_cc); |
---|
| 329 | + container_of(cc, struct ixgbe_adapter, hw_cc); |
---|
228 | 330 | struct ixgbe_hw *hw = &adapter->hw; |
---|
229 | 331 | struct timespec64 ts; |
---|
230 | 332 | |
---|
.. | .. |
---|
443 | 545 | } |
---|
444 | 546 | |
---|
445 | 547 | /** |
---|
446 | | - * ixgbe_ptp_gettime |
---|
| 548 | + * ixgbe_ptp_gettimex |
---|
447 | 549 | * @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 |
---|
449 | 552 | * |
---|
450 | 553 | * read the timecounter and return the correct value on ns, |
---|
451 | 554 | * after converting it into a struct timespec. |
---|
452 | 555 | */ |
---|
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) |
---|
454 | 559 | { |
---|
455 | 560 | struct ixgbe_adapter *adapter = |
---|
456 | 561 | container_of(ptp, struct ixgbe_adapter, ptp_caps); |
---|
| 562 | + struct ixgbe_hw *hw = &adapter->hw; |
---|
457 | 563 | unsigned long flags; |
---|
458 | | - u64 ns; |
---|
| 564 | + u64 ns, stamp; |
---|
459 | 565 | |
---|
460 | 566 | 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 | + |
---|
462 | 594 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); |
---|
463 | 595 | |
---|
464 | 596 | *ts = ns_to_timespec64(ns); |
---|
.. | .. |
---|
567 | 699 | { |
---|
568 | 700 | bool timeout = time_is_before_jiffies(adapter->last_overflow_check + |
---|
569 | 701 | IXGBE_OVERFLOW_PERIOD); |
---|
570 | | - struct timespec64 ts; |
---|
| 702 | + unsigned long flags; |
---|
571 | 703 | |
---|
572 | 704 | 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 | + |
---|
574 | 710 | adapter->last_overflow_check = jiffies; |
---|
575 | 711 | } |
---|
576 | 712 | } |
---|
.. | .. |
---|
804 | 940 | ixgbe_ptp_convert_to_hwtstamp(adapter, skb_hwtstamps(skb), regval); |
---|
805 | 941 | } |
---|
806 | 942 | |
---|
| 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 | + */ |
---|
807 | 952 | int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr) |
---|
808 | 953 | { |
---|
809 | 954 | struct hwtstamp_config *config = &adapter->tstamp_config; |
---|
.. | .. |
---|
906 | 1051 | adapter->flags |= IXGBE_FLAG_RX_HWTSTAMP_ENABLED; |
---|
907 | 1052 | break; |
---|
908 | 1053 | } |
---|
909 | | - /* fall through */ |
---|
| 1054 | + fallthrough; |
---|
910 | 1055 | default: |
---|
911 | 1056 | /* |
---|
912 | 1057 | * register RXMTRL must be set in order to do V1 packets, |
---|
.. | .. |
---|
1066 | 1211 | struct cyclecounter cc; |
---|
1067 | 1212 | unsigned long flags; |
---|
1068 | 1213 | u32 incval = 0; |
---|
1069 | | - u32 tsauxc = 0; |
---|
1070 | 1214 | u32 fuse0 = 0; |
---|
1071 | 1215 | |
---|
1072 | 1216 | /* For some of the boards below this mask is technically incorrect. |
---|
.. | .. |
---|
1097 | 1241 | cc.mult = 3; |
---|
1098 | 1242 | cc.shift = 2; |
---|
1099 | 1243 | } |
---|
1100 | | - /* fallthrough */ |
---|
| 1244 | + fallthrough; |
---|
1101 | 1245 | case ixgbe_mac_x550em_a: |
---|
1102 | 1246 | case ixgbe_mac_X550: |
---|
1103 | 1247 | 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); |
---|
1116 | 1248 | break; |
---|
1117 | 1249 | case ixgbe_mac_X540: |
---|
1118 | 1250 | cc.read = ixgbe_ptp_read_82599; |
---|
.. | .. |
---|
1145 | 1277 | } |
---|
1146 | 1278 | |
---|
1147 | 1279 | /** |
---|
| 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 | +/** |
---|
1148 | 1324 | * ixgbe_ptp_reset |
---|
1149 | 1325 | * @adapter: the ixgbe private board structure |
---|
1150 | 1326 | * |
---|
.. | .. |
---|
1169 | 1345 | return; |
---|
1170 | 1346 | |
---|
1171 | 1347 | ixgbe_ptp_start_cyclecounter(adapter); |
---|
| 1348 | + |
---|
| 1349 | + ixgbe_ptp_init_systime(adapter); |
---|
1172 | 1350 | |
---|
1173 | 1351 | spin_lock_irqsave(&adapter->tmreg_lock, flags); |
---|
1174 | 1352 | timecounter_init(&adapter->hw_tc, &adapter->hw_cc, |
---|
.. | .. |
---|
1216 | 1394 | adapter->ptp_caps.pps = 1; |
---|
1217 | 1395 | adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_82599; |
---|
1218 | 1396 | adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; |
---|
1219 | | - adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime; |
---|
| 1397 | + adapter->ptp_caps.gettimex64 = ixgbe_ptp_gettimex; |
---|
1220 | 1398 | adapter->ptp_caps.settime64 = ixgbe_ptp_settime; |
---|
1221 | 1399 | 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; |
---|
1223 | 1401 | break; |
---|
1224 | 1402 | case ixgbe_mac_82599EB: |
---|
1225 | 1403 | snprintf(adapter->ptp_caps.name, |
---|
.. | .. |
---|
1233 | 1411 | adapter->ptp_caps.pps = 0; |
---|
1234 | 1412 | adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_82599; |
---|
1235 | 1413 | adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; |
---|
1236 | | - adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime; |
---|
| 1414 | + adapter->ptp_caps.gettimex64 = ixgbe_ptp_gettimex; |
---|
1237 | 1415 | adapter->ptp_caps.settime64 = ixgbe_ptp_settime; |
---|
1238 | 1416 | adapter->ptp_caps.enable = ixgbe_ptp_feature_enable; |
---|
1239 | 1417 | break; |
---|
.. | .. |
---|
1246 | 1424 | adapter->ptp_caps.n_alarm = 0; |
---|
1247 | 1425 | adapter->ptp_caps.n_ext_ts = 0; |
---|
1248 | 1426 | adapter->ptp_caps.n_per_out = 0; |
---|
1249 | | - adapter->ptp_caps.pps = 0; |
---|
| 1427 | + adapter->ptp_caps.pps = 1; |
---|
1250 | 1428 | adapter->ptp_caps.adjfreq = ixgbe_ptp_adjfreq_X550; |
---|
1251 | 1429 | adapter->ptp_caps.adjtime = ixgbe_ptp_adjtime; |
---|
1252 | | - adapter->ptp_caps.gettime64 = ixgbe_ptp_gettime; |
---|
| 1430 | + adapter->ptp_caps.gettimex64 = ixgbe_ptp_gettimex; |
---|
1253 | 1431 | adapter->ptp_caps.settime64 = ixgbe_ptp_settime; |
---|
1254 | 1432 | adapter->ptp_caps.enable = ixgbe_ptp_feature_enable; |
---|
1255 | | - adapter->ptp_setup_sdp = NULL; |
---|
| 1433 | + adapter->ptp_setup_sdp = ixgbe_ptp_setup_sdp_X550; |
---|
1256 | 1434 | break; |
---|
1257 | 1435 | default: |
---|
1258 | 1436 | adapter->ptp_clock = NULL; |
---|