1319 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2019 Intel Corporation */3 4#include "igc.h"5 6#include <linux/module.h>7#include <linux/device.h>8#include <linux/pci.h>9#include <linux/ptp_classify.h>10#include <linux/clocksource.h>11#include <linux/ktime.h>12#include <linux/delay.h>13#include <linux/iopoll.h>14#include <net/xdp_sock_drv.h>15 16#define INCVALUE_MASK 0x7fffffff17#define ISGN 0x8000000018 19#define IGC_PTP_TX_TIMEOUT (HZ * 15)20 21#define IGC_PTM_STAT_SLEEP 222#define IGC_PTM_STAT_TIMEOUT 10023 24/* SYSTIM read access for I225 */25void igc_ptp_read(struct igc_adapter *adapter, struct timespec64 *ts)26{27 struct igc_hw *hw = &adapter->hw;28 u32 sec, nsec;29 30 /* The timestamp is latched when SYSTIML is read. */31 nsec = rd32(IGC_SYSTIML);32 sec = rd32(IGC_SYSTIMH);33 34 ts->tv_sec = sec;35 ts->tv_nsec = nsec;36}37 38static void igc_ptp_write_i225(struct igc_adapter *adapter,39 const struct timespec64 *ts)40{41 struct igc_hw *hw = &adapter->hw;42 43 wr32(IGC_SYSTIML, ts->tv_nsec);44 wr32(IGC_SYSTIMH, ts->tv_sec);45}46 47static int igc_ptp_adjfine_i225(struct ptp_clock_info *ptp, long scaled_ppm)48{49 struct igc_adapter *igc = container_of(ptp, struct igc_adapter,50 ptp_caps);51 struct igc_hw *hw = &igc->hw;52 int neg_adj = 0;53 u64 rate;54 u32 inca;55 56 if (scaled_ppm < 0) {57 neg_adj = 1;58 scaled_ppm = -scaled_ppm;59 }60 rate = scaled_ppm;61 rate <<= 14;62 rate = div_u64(rate, 78125);63 64 inca = rate & INCVALUE_MASK;65 if (neg_adj)66 inca |= ISGN;67 68 wr32(IGC_TIMINCA, inca);69 70 return 0;71}72 73static int igc_ptp_adjtime_i225(struct ptp_clock_info *ptp, s64 delta)74{75 struct igc_adapter *igc = container_of(ptp, struct igc_adapter,76 ptp_caps);77 struct timespec64 now, then = ns_to_timespec64(delta);78 unsigned long flags;79 80 spin_lock_irqsave(&igc->tmreg_lock, flags);81 82 igc_ptp_read(igc, &now);83 now = timespec64_add(now, then);84 igc_ptp_write_i225(igc, (const struct timespec64 *)&now);85 86 spin_unlock_irqrestore(&igc->tmreg_lock, flags);87 88 return 0;89}90 91static int igc_ptp_gettimex64_i225(struct ptp_clock_info *ptp,92 struct timespec64 *ts,93 struct ptp_system_timestamp *sts)94{95 struct igc_adapter *igc = container_of(ptp, struct igc_adapter,96 ptp_caps);97 struct igc_hw *hw = &igc->hw;98 unsigned long flags;99 100 spin_lock_irqsave(&igc->tmreg_lock, flags);101 102 ptp_read_system_prets(sts);103 ts->tv_nsec = rd32(IGC_SYSTIML);104 ts->tv_sec = rd32(IGC_SYSTIMH);105 ptp_read_system_postts(sts);106 107 spin_unlock_irqrestore(&igc->tmreg_lock, flags);108 109 return 0;110}111 112static int igc_ptp_settime_i225(struct ptp_clock_info *ptp,113 const struct timespec64 *ts)114{115 struct igc_adapter *igc = container_of(ptp, struct igc_adapter,116 ptp_caps);117 unsigned long flags;118 119 spin_lock_irqsave(&igc->tmreg_lock, flags);120 121 igc_ptp_write_i225(igc, ts);122 123 spin_unlock_irqrestore(&igc->tmreg_lock, flags);124 125 return 0;126}127 128static void igc_pin_direction(int pin, int input, u32 *ctrl, u32 *ctrl_ext)129{130 u32 *ptr = pin < 2 ? ctrl : ctrl_ext;131 static const u32 mask[IGC_N_SDP] = {132 IGC_CTRL_SDP0_DIR,133 IGC_CTRL_SDP1_DIR,134 IGC_CTRL_EXT_SDP2_DIR,135 IGC_CTRL_EXT_SDP3_DIR,136 };137 138 if (input)139 *ptr &= ~mask[pin];140 else141 *ptr |= mask[pin];142}143 144static void igc_pin_perout(struct igc_adapter *igc, int chan, int pin, int freq)145{146 static const u32 igc_aux0_sel_sdp[IGC_N_SDP] = {147 IGC_AUX0_SEL_SDP0, IGC_AUX0_SEL_SDP1, IGC_AUX0_SEL_SDP2, IGC_AUX0_SEL_SDP3,148 };149 static const u32 igc_aux1_sel_sdp[IGC_N_SDP] = {150 IGC_AUX1_SEL_SDP0, IGC_AUX1_SEL_SDP1, IGC_AUX1_SEL_SDP2, IGC_AUX1_SEL_SDP3,151 };152 static const u32 igc_ts_sdp_en[IGC_N_SDP] = {153 IGC_TS_SDP0_EN, IGC_TS_SDP1_EN, IGC_TS_SDP2_EN, IGC_TS_SDP3_EN,154 };155 static const u32 igc_ts_sdp_sel_tt0[IGC_N_SDP] = {156 IGC_TS_SDP0_SEL_TT0, IGC_TS_SDP1_SEL_TT0,157 IGC_TS_SDP2_SEL_TT0, IGC_TS_SDP3_SEL_TT0,158 };159 static const u32 igc_ts_sdp_sel_tt1[IGC_N_SDP] = {160 IGC_TS_SDP0_SEL_TT1, IGC_TS_SDP1_SEL_TT1,161 IGC_TS_SDP2_SEL_TT1, IGC_TS_SDP3_SEL_TT1,162 };163 static const u32 igc_ts_sdp_sel_fc0[IGC_N_SDP] = {164 IGC_TS_SDP0_SEL_FC0, IGC_TS_SDP1_SEL_FC0,165 IGC_TS_SDP2_SEL_FC0, IGC_TS_SDP3_SEL_FC0,166 };167 static const u32 igc_ts_sdp_sel_fc1[IGC_N_SDP] = {168 IGC_TS_SDP0_SEL_FC1, IGC_TS_SDP1_SEL_FC1,169 IGC_TS_SDP2_SEL_FC1, IGC_TS_SDP3_SEL_FC1,170 };171 static const u32 igc_ts_sdp_sel_clr[IGC_N_SDP] = {172 IGC_TS_SDP0_SEL_FC1, IGC_TS_SDP1_SEL_FC1,173 IGC_TS_SDP2_SEL_FC1, IGC_TS_SDP3_SEL_FC1,174 };175 struct igc_hw *hw = &igc->hw;176 u32 ctrl, ctrl_ext, tssdp = 0;177 178 ctrl = rd32(IGC_CTRL);179 ctrl_ext = rd32(IGC_CTRL_EXT);180 tssdp = rd32(IGC_TSSDP);181 182 igc_pin_direction(pin, 0, &ctrl, &ctrl_ext);183 184 /* Make sure this pin is not enabled as an input. */185 if ((tssdp & IGC_AUX0_SEL_SDP3) == igc_aux0_sel_sdp[pin])186 tssdp &= ~IGC_AUX0_TS_SDP_EN;187 188 if ((tssdp & IGC_AUX1_SEL_SDP3) == igc_aux1_sel_sdp[pin])189 tssdp &= ~IGC_AUX1_TS_SDP_EN;190 191 tssdp &= ~igc_ts_sdp_sel_clr[pin];192 if (freq) {193 if (chan == 1)194 tssdp |= igc_ts_sdp_sel_fc1[pin];195 else196 tssdp |= igc_ts_sdp_sel_fc0[pin];197 } else {198 if (chan == 1)199 tssdp |= igc_ts_sdp_sel_tt1[pin];200 else201 tssdp |= igc_ts_sdp_sel_tt0[pin];202 }203 tssdp |= igc_ts_sdp_en[pin];204 205 wr32(IGC_TSSDP, tssdp);206 wr32(IGC_CTRL, ctrl);207 wr32(IGC_CTRL_EXT, ctrl_ext);208}209 210static void igc_pin_extts(struct igc_adapter *igc, int chan, int pin)211{212 static const u32 igc_aux0_sel_sdp[IGC_N_SDP] = {213 IGC_AUX0_SEL_SDP0, IGC_AUX0_SEL_SDP1, IGC_AUX0_SEL_SDP2, IGC_AUX0_SEL_SDP3,214 };215 static const u32 igc_aux1_sel_sdp[IGC_N_SDP] = {216 IGC_AUX1_SEL_SDP0, IGC_AUX1_SEL_SDP1, IGC_AUX1_SEL_SDP2, IGC_AUX1_SEL_SDP3,217 };218 static const u32 igc_ts_sdp_en[IGC_N_SDP] = {219 IGC_TS_SDP0_EN, IGC_TS_SDP1_EN, IGC_TS_SDP2_EN, IGC_TS_SDP3_EN,220 };221 struct igc_hw *hw = &igc->hw;222 u32 ctrl, ctrl_ext, tssdp = 0;223 224 ctrl = rd32(IGC_CTRL);225 ctrl_ext = rd32(IGC_CTRL_EXT);226 tssdp = rd32(IGC_TSSDP);227 228 igc_pin_direction(pin, 1, &ctrl, &ctrl_ext);229 230 /* Make sure this pin is not enabled as an output. */231 tssdp &= ~igc_ts_sdp_en[pin];232 233 if (chan == 1) {234 tssdp &= ~IGC_AUX1_SEL_SDP3;235 tssdp |= igc_aux1_sel_sdp[pin] | IGC_AUX1_TS_SDP_EN;236 } else {237 tssdp &= ~IGC_AUX0_SEL_SDP3;238 tssdp |= igc_aux0_sel_sdp[pin] | IGC_AUX0_TS_SDP_EN;239 }240 241 wr32(IGC_TSSDP, tssdp);242 wr32(IGC_CTRL, ctrl);243 wr32(IGC_CTRL_EXT, ctrl_ext);244}245 246static int igc_ptp_feature_enable_i225(struct ptp_clock_info *ptp,247 struct ptp_clock_request *rq, int on)248{249 struct igc_adapter *igc =250 container_of(ptp, struct igc_adapter, ptp_caps);251 struct igc_hw *hw = &igc->hw;252 unsigned long flags;253 struct timespec64 ts;254 int use_freq = 0, pin = -1;255 u32 tsim, tsauxc, tsauxc_mask, tsim_mask, trgttiml, trgttimh, freqout;256 s64 ns;257 258 switch (rq->type) {259 case PTP_CLK_REQ_EXTTS:260 /* Reject requests with unsupported flags */261 if (rq->extts.flags & ~(PTP_ENABLE_FEATURE |262 PTP_RISING_EDGE |263 PTP_FALLING_EDGE |264 PTP_STRICT_FLAGS))265 return -EOPNOTSUPP;266 267 /* Reject requests failing to enable both edges. */268 if ((rq->extts.flags & PTP_STRICT_FLAGS) &&269 (rq->extts.flags & PTP_ENABLE_FEATURE) &&270 (rq->extts.flags & PTP_EXTTS_EDGES) != PTP_EXTTS_EDGES)271 return -EOPNOTSUPP;272 273 if (on) {274 pin = ptp_find_pin(igc->ptp_clock, PTP_PF_EXTTS,275 rq->extts.index);276 if (pin < 0)277 return -EBUSY;278 }279 if (rq->extts.index == 1) {280 tsauxc_mask = IGC_TSAUXC_EN_TS1;281 tsim_mask = IGC_TSICR_AUTT1;282 } else {283 tsauxc_mask = IGC_TSAUXC_EN_TS0;284 tsim_mask = IGC_TSICR_AUTT0;285 }286 spin_lock_irqsave(&igc->tmreg_lock, flags);287 tsauxc = rd32(IGC_TSAUXC);288 tsim = rd32(IGC_TSIM);289 if (on) {290 igc_pin_extts(igc, rq->extts.index, pin);291 tsauxc |= tsauxc_mask;292 tsim |= tsim_mask;293 } else {294 tsauxc &= ~tsauxc_mask;295 tsim &= ~tsim_mask;296 }297 wr32(IGC_TSAUXC, tsauxc);298 wr32(IGC_TSIM, tsim);299 spin_unlock_irqrestore(&igc->tmreg_lock, flags);300 return 0;301 302 case PTP_CLK_REQ_PEROUT:303 /* Reject requests with unsupported flags */304 if (rq->perout.flags)305 return -EOPNOTSUPP;306 307 if (on) {308 pin = ptp_find_pin(igc->ptp_clock, PTP_PF_PEROUT,309 rq->perout.index);310 if (pin < 0)311 return -EBUSY;312 }313 ts.tv_sec = rq->perout.period.sec;314 ts.tv_nsec = rq->perout.period.nsec;315 ns = timespec64_to_ns(&ts);316 ns = ns >> 1;317 if (on && (ns <= 70000000LL || ns == 125000000LL ||318 ns == 250000000LL || ns == 500000000LL)) {319 if (ns < 8LL)320 return -EINVAL;321 use_freq = 1;322 }323 ts = ns_to_timespec64(ns);324 if (rq->perout.index == 1) {325 if (use_freq) {326 tsauxc_mask = IGC_TSAUXC_EN_CLK1 | IGC_TSAUXC_ST1;327 tsim_mask = 0;328 } else {329 tsauxc_mask = IGC_TSAUXC_EN_TT1;330 tsim_mask = IGC_TSICR_TT1;331 }332 trgttiml = IGC_TRGTTIML1;333 trgttimh = IGC_TRGTTIMH1;334 freqout = IGC_FREQOUT1;335 } else {336 if (use_freq) {337 tsauxc_mask = IGC_TSAUXC_EN_CLK0 | IGC_TSAUXC_ST0;338 tsim_mask = 0;339 } else {340 tsauxc_mask = IGC_TSAUXC_EN_TT0;341 tsim_mask = IGC_TSICR_TT0;342 }343 trgttiml = IGC_TRGTTIML0;344 trgttimh = IGC_TRGTTIMH0;345 freqout = IGC_FREQOUT0;346 }347 spin_lock_irqsave(&igc->tmreg_lock, flags);348 tsauxc = rd32(IGC_TSAUXC);349 tsim = rd32(IGC_TSIM);350 if (rq->perout.index == 1) {351 tsauxc &= ~(IGC_TSAUXC_EN_TT1 | IGC_TSAUXC_EN_CLK1 |352 IGC_TSAUXC_ST1);353 tsim &= ~IGC_TSICR_TT1;354 } else {355 tsauxc &= ~(IGC_TSAUXC_EN_TT0 | IGC_TSAUXC_EN_CLK0 |356 IGC_TSAUXC_ST0);357 tsim &= ~IGC_TSICR_TT0;358 }359 if (on) {360 struct timespec64 safe_start;361 int i = rq->perout.index;362 363 igc_pin_perout(igc, i, pin, use_freq);364 igc_ptp_read(igc, &safe_start);365 366 /* PPS output start time is triggered by Target time(TT)367 * register. Programming any past time value into TT368 * register will cause PPS to never start. Need to make369 * sure we program the TT register a time ahead in370 * future. There isn't a stringent need to fire PPS out371 * right away. Adding +2 seconds should take care of372 * corner cases. Let's say if the SYSTIML is close to373 * wrap up and the timer keeps ticking as we program the374 * register, adding +2seconds is safe bet.375 */376 safe_start.tv_sec += 2;377 378 if (rq->perout.start.sec < safe_start.tv_sec)379 igc->perout[i].start.tv_sec = safe_start.tv_sec;380 else381 igc->perout[i].start.tv_sec = rq->perout.start.sec;382 igc->perout[i].start.tv_nsec = rq->perout.start.nsec;383 igc->perout[i].period.tv_sec = ts.tv_sec;384 igc->perout[i].period.tv_nsec = ts.tv_nsec;385 wr32(trgttimh, (u32)igc->perout[i].start.tv_sec);386 /* For now, always select timer 0 as source. */387 wr32(trgttiml, (u32)(igc->perout[i].start.tv_nsec |388 IGC_TT_IO_TIMER_SEL_SYSTIM0));389 if (use_freq)390 wr32(freqout, ns);391 tsauxc |= tsauxc_mask;392 tsim |= tsim_mask;393 }394 wr32(IGC_TSAUXC, tsauxc);395 wr32(IGC_TSIM, tsim);396 spin_unlock_irqrestore(&igc->tmreg_lock, flags);397 return 0;398 399 case PTP_CLK_REQ_PPS:400 spin_lock_irqsave(&igc->tmreg_lock, flags);401 tsim = rd32(IGC_TSIM);402 if (on)403 tsim |= IGC_TSICR_SYS_WRAP;404 else405 tsim &= ~IGC_TSICR_SYS_WRAP;406 igc->pps_sys_wrap_on = on;407 wr32(IGC_TSIM, tsim);408 spin_unlock_irqrestore(&igc->tmreg_lock, flags);409 return 0;410 411 default:412 break;413 }414 415 return -EOPNOTSUPP;416}417 418static int igc_ptp_verify_pin(struct ptp_clock_info *ptp, unsigned int pin,419 enum ptp_pin_function func, unsigned int chan)420{421 switch (func) {422 case PTP_PF_NONE:423 case PTP_PF_EXTTS:424 case PTP_PF_PEROUT:425 break;426 case PTP_PF_PHYSYNC:427 return -1;428 }429 return 0;430}431 432/**433 * igc_ptp_systim_to_hwtstamp - convert system time value to HW timestamp434 * @adapter: board private structure435 * @hwtstamps: timestamp structure to update436 * @systim: unsigned 64bit system time value437 *438 * We need to convert the system time value stored in the RX/TXSTMP registers439 * into a hwtstamp which can be used by the upper level timestamping functions.440 *441 * Returns 0 on success.442 **/443static int igc_ptp_systim_to_hwtstamp(struct igc_adapter *adapter,444 struct skb_shared_hwtstamps *hwtstamps,445 u64 systim)446{447 switch (adapter->hw.mac.type) {448 case igc_i225:449 memset(hwtstamps, 0, sizeof(*hwtstamps));450 /* Upper 32 bits contain s, lower 32 bits contain ns. */451 hwtstamps->hwtstamp = ktime_set(systim >> 32,452 systim & 0xFFFFFFFF);453 break;454 default:455 return -EINVAL;456 }457 return 0;458}459 460/**461 * igc_ptp_rx_pktstamp - Retrieve timestamp from Rx packet buffer462 * @adapter: Pointer to adapter the packet buffer belongs to463 * @buf: Pointer to start of timestamp in HW format (2 32-bit words)464 *465 * This function retrieves and converts the timestamp stored at @buf466 * to ktime_t, adjusting for hardware latencies.467 *468 * Returns timestamp value.469 */470ktime_t igc_ptp_rx_pktstamp(struct igc_adapter *adapter, __le32 *buf)471{472 ktime_t timestamp;473 u32 secs, nsecs;474 int adjust;475 476 nsecs = le32_to_cpu(buf[0]);477 secs = le32_to_cpu(buf[1]);478 479 timestamp = ktime_set(secs, nsecs);480 481 /* Adjust timestamp for the RX latency based on link speed */482 switch (adapter->link_speed) {483 case SPEED_10:484 adjust = IGC_I225_RX_LATENCY_10;485 break;486 case SPEED_100:487 adjust = IGC_I225_RX_LATENCY_100;488 break;489 case SPEED_1000:490 adjust = IGC_I225_RX_LATENCY_1000;491 break;492 case SPEED_2500:493 adjust = IGC_I225_RX_LATENCY_2500;494 break;495 default:496 adjust = 0;497 netdev_warn_once(adapter->netdev, "Imprecise timestamp\n");498 break;499 }500 501 return ktime_sub_ns(timestamp, adjust);502}503 504static void igc_ptp_disable_rx_timestamp(struct igc_adapter *adapter)505{506 struct igc_hw *hw = &adapter->hw;507 u32 val;508 int i;509 510 wr32(IGC_TSYNCRXCTL, 0);511 512 for (i = 0; i < adapter->num_rx_queues; i++) {513 val = rd32(IGC_SRRCTL(i));514 val &= ~IGC_SRRCTL_TIMESTAMP;515 wr32(IGC_SRRCTL(i), val);516 }517 518 val = rd32(IGC_RXPBS);519 val &= ~IGC_RXPBS_CFG_TS_EN;520 wr32(IGC_RXPBS, val);521}522 523static void igc_ptp_enable_rx_timestamp(struct igc_adapter *adapter)524{525 struct igc_hw *hw = &adapter->hw;526 u32 val;527 int i;528 529 val = rd32(IGC_RXPBS);530 val |= IGC_RXPBS_CFG_TS_EN;531 wr32(IGC_RXPBS, val);532 533 for (i = 0; i < adapter->num_rx_queues; i++) {534 val = rd32(IGC_SRRCTL(i));535 /* Enable retrieving timestamps from timer 0, the536 * "adjustable clock" and timer 1 the "free running537 * clock".538 */539 val |= IGC_SRRCTL_TIMER1SEL(1) | IGC_SRRCTL_TIMER0SEL(0) |540 IGC_SRRCTL_TIMESTAMP;541 wr32(IGC_SRRCTL(i), val);542 }543 544 val = IGC_TSYNCRXCTL_ENABLED | IGC_TSYNCRXCTL_TYPE_ALL |545 IGC_TSYNCRXCTL_RXSYNSIG;546 wr32(IGC_TSYNCRXCTL, val);547}548 549static void igc_ptp_free_tx_buffer(struct igc_adapter *adapter,550 struct igc_tx_timestamp_request *tstamp)551{552 if (tstamp->buffer_type == IGC_TX_BUFFER_TYPE_XSK) {553 /* Release the transmit completion */554 tstamp->xsk_tx_buffer->xsk_pending_ts = false;555 556 /* Note: tstamp->skb and tstamp->xsk_tx_buffer are in union.557 * By setting tstamp->xsk_tx_buffer to NULL, tstamp->skb will558 * become NULL as well.559 */560 tstamp->xsk_tx_buffer = NULL;561 tstamp->buffer_type = 0;562 563 /* Trigger txrx interrupt for transmit completion */564 igc_xsk_wakeup(adapter->netdev, tstamp->xsk_queue_index, 0);565 566 return;567 }568 569 dev_kfree_skb_any(tstamp->skb);570 tstamp->skb = NULL;571}572 573static void igc_ptp_clear_tx_tstamp(struct igc_adapter *adapter)574{575 unsigned long flags;576 int i;577 578 spin_lock_irqsave(&adapter->ptp_tx_lock, flags);579 580 for (i = 0; i < IGC_MAX_TX_TSTAMP_REGS; i++) {581 struct igc_tx_timestamp_request *tstamp = &adapter->tx_tstamp[i];582 583 if (tstamp->skb)584 igc_ptp_free_tx_buffer(adapter, tstamp);585 }586 587 spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags);588}589 590static void igc_ptp_disable_tx_timestamp(struct igc_adapter *adapter)591{592 struct igc_hw *hw = &adapter->hw;593 int i;594 595 /* Clear the flags first to avoid new packets to be enqueued596 * for TX timestamping.597 */598 for (i = 0; i < adapter->num_tx_queues; i++) {599 struct igc_ring *tx_ring = adapter->tx_ring[i];600 601 clear_bit(IGC_RING_FLAG_TX_HWTSTAMP, &tx_ring->flags);602 }603 604 /* Now we can clean the pending TX timestamp requests. */605 igc_ptp_clear_tx_tstamp(adapter);606 607 wr32(IGC_TSYNCTXCTL, 0);608}609 610static void igc_ptp_enable_tx_timestamp(struct igc_adapter *adapter)611{612 struct igc_hw *hw = &adapter->hw;613 int i;614 615 wr32(IGC_TSYNCTXCTL, IGC_TSYNCTXCTL_ENABLED | IGC_TSYNCTXCTL_TXSYNSIG);616 617 /* Read TXSTMP registers to discard any timestamp previously stored. */618 rd32(IGC_TXSTMPL);619 rd32(IGC_TXSTMPH);620 621 /* The hardware is ready to accept TX timestamp requests,622 * notify the transmit path.623 */624 for (i = 0; i < adapter->num_tx_queues; i++) {625 struct igc_ring *tx_ring = adapter->tx_ring[i];626 627 set_bit(IGC_RING_FLAG_TX_HWTSTAMP, &tx_ring->flags);628 }629 630}631 632/**633 * igc_ptp_set_timestamp_mode - setup hardware for timestamping634 * @adapter: networking device structure635 * @config: hwtstamp configuration636 *637 * Return: 0 in case of success, negative errno code otherwise.638 */639static int igc_ptp_set_timestamp_mode(struct igc_adapter *adapter,640 struct hwtstamp_config *config)641{642 switch (config->tx_type) {643 case HWTSTAMP_TX_OFF:644 igc_ptp_disable_tx_timestamp(adapter);645 break;646 case HWTSTAMP_TX_ON:647 igc_ptp_enable_tx_timestamp(adapter);648 break;649 default:650 return -ERANGE;651 }652 653 switch (config->rx_filter) {654 case HWTSTAMP_FILTER_NONE:655 igc_ptp_disable_rx_timestamp(adapter);656 break;657 case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:658 case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:659 case HWTSTAMP_FILTER_PTP_V2_EVENT:660 case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:661 case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:662 case HWTSTAMP_FILTER_PTP_V2_SYNC:663 case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:664 case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:665 case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:666 case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:667 case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:668 case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:669 case HWTSTAMP_FILTER_NTP_ALL:670 case HWTSTAMP_FILTER_ALL:671 igc_ptp_enable_rx_timestamp(adapter);672 config->rx_filter = HWTSTAMP_FILTER_ALL;673 break;674 default:675 return -ERANGE;676 }677 678 return 0;679}680 681/* Requires adapter->ptp_tx_lock held by caller. */682static void igc_ptp_tx_timeout(struct igc_adapter *adapter,683 struct igc_tx_timestamp_request *tstamp)684{685 if (tstamp->skb)686 igc_ptp_free_tx_buffer(adapter, tstamp);687 688 adapter->tx_hwtstamp_timeouts++;689 690 netdev_warn(adapter->netdev, "Tx timestamp timeout\n");691}692 693void igc_ptp_tx_hang(struct igc_adapter *adapter)694{695 struct igc_tx_timestamp_request *tstamp;696 struct igc_hw *hw = &adapter->hw;697 unsigned long flags;698 bool found = false;699 int i;700 701 spin_lock_irqsave(&adapter->ptp_tx_lock, flags);702 703 for (i = 0; i < IGC_MAX_TX_TSTAMP_REGS; i++) {704 tstamp = &adapter->tx_tstamp[i];705 706 if (!tstamp->skb)707 continue;708 709 if (time_is_after_jiffies(tstamp->start + IGC_PTP_TX_TIMEOUT))710 continue;711 712 igc_ptp_tx_timeout(adapter, tstamp);713 found = true;714 }715 716 if (found) {717 /* Reading the high register of the first set of timestamp registers718 * clears all the equivalent bits in the TSYNCTXCTL register.719 */720 rd32(IGC_TXSTMPH_0);721 }722 723 spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags);724}725 726static void igc_ptp_tx_reg_to_stamp(struct igc_adapter *adapter,727 struct igc_tx_timestamp_request *tstamp, u64 regval)728{729 struct skb_shared_hwtstamps shhwtstamps;730 struct sk_buff *skb;731 int adjust = 0;732 733 skb = tstamp->skb;734 if (!skb)735 return;736 737 if (igc_ptp_systim_to_hwtstamp(adapter, &shhwtstamps, regval))738 return;739 740 switch (adapter->link_speed) {741 case SPEED_10:742 adjust = IGC_I225_TX_LATENCY_10;743 break;744 case SPEED_100:745 adjust = IGC_I225_TX_LATENCY_100;746 break;747 case SPEED_1000:748 adjust = IGC_I225_TX_LATENCY_1000;749 break;750 case SPEED_2500:751 adjust = IGC_I225_TX_LATENCY_2500;752 break;753 }754 755 shhwtstamps.hwtstamp =756 ktime_add_ns(shhwtstamps.hwtstamp, adjust);757 758 /* Copy the tx hardware timestamp into xdp metadata or skb */759 if (tstamp->buffer_type == IGC_TX_BUFFER_TYPE_XSK) {760 struct xsk_buff_pool *xsk_pool;761 762 xsk_pool = adapter->tx_ring[tstamp->xsk_queue_index]->xsk_pool;763 if (xsk_pool && xp_tx_metadata_enabled(xsk_pool)) {764 xsk_tx_metadata_complete(&tstamp->xsk_meta,765 &igc_xsk_tx_metadata_ops,766 &shhwtstamps.hwtstamp);767 }768 } else {769 skb_tstamp_tx(skb, &shhwtstamps);770 }771 772 igc_ptp_free_tx_buffer(adapter, tstamp);773}774 775/**776 * igc_ptp_tx_hwtstamp - utility function which checks for TX time stamp777 * @adapter: Board private structure778 *779 * Check against the ready mask for which of the timestamp register780 * sets are ready to be retrieved, then retrieve that and notify the781 * rest of the stack.782 *783 * Context: Expects adapter->ptp_tx_lock to be held by caller.784 */785static void igc_ptp_tx_hwtstamp(struct igc_adapter *adapter)786{787 struct igc_hw *hw = &adapter->hw;788 u64 regval;789 u32 mask;790 int i;791 792 mask = rd32(IGC_TSYNCTXCTL) & IGC_TSYNCTXCTL_TXTT_ANY;793 if (mask & IGC_TSYNCTXCTL_TXTT_0) {794 regval = rd32(IGC_TXSTMPL);795 regval |= (u64)rd32(IGC_TXSTMPH) << 32;796 } else {797 /* There's a bug in the hardware that could cause798 * missing interrupts for TX timestamping. The issue799 * is that for new interrupts to be triggered, the800 * IGC_TXSTMPH_0 register must be read.801 *802 * To avoid discarding a valid timestamp that just803 * happened at the "wrong" time, we need to confirm804 * that there was no timestamp captured, we do that by805 * assuming that no two timestamps in sequence have806 * the same nanosecond value.807 *808 * So, we read the "low" register, read the "high"809 * register (to latch a new timestamp) and read the810 * "low" register again, if "old" and "new" versions811 * of the "low" register are different, a valid812 * timestamp was captured, we can read the "high"813 * register again.814 */815 u32 txstmpl_old, txstmpl_new;816 817 txstmpl_old = rd32(IGC_TXSTMPL);818 rd32(IGC_TXSTMPH);819 txstmpl_new = rd32(IGC_TXSTMPL);820 821 if (txstmpl_old == txstmpl_new)822 goto done;823 824 regval = txstmpl_new;825 regval |= (u64)rd32(IGC_TXSTMPH) << 32;826 }827 828 igc_ptp_tx_reg_to_stamp(adapter, &adapter->tx_tstamp[0], regval);829 830done:831 /* Now that the problematic first register was handled, we can832 * use retrieve the timestamps from the other registers833 * (starting from '1') with less complications.834 */835 for (i = 1; i < IGC_MAX_TX_TSTAMP_REGS; i++) {836 struct igc_tx_timestamp_request *tstamp = &adapter->tx_tstamp[i];837 838 if (!(tstamp->mask & mask))839 continue;840 841 regval = rd32(tstamp->regl);842 regval |= (u64)rd32(tstamp->regh) << 32;843 844 igc_ptp_tx_reg_to_stamp(adapter, tstamp, regval);845 }846}847 848/**849 * igc_ptp_tx_tstamp_event850 * @adapter: board private structure851 *852 * Called when a TX timestamp interrupt happens to retrieve the853 * timestamp and send it up to the socket.854 */855void igc_ptp_tx_tstamp_event(struct igc_adapter *adapter)856{857 unsigned long flags;858 859 spin_lock_irqsave(&adapter->ptp_tx_lock, flags);860 861 igc_ptp_tx_hwtstamp(adapter);862 863 spin_unlock_irqrestore(&adapter->ptp_tx_lock, flags);864}865 866/**867 * igc_ptp_set_ts_config - set hardware time stamping config868 * @netdev: network interface device structure869 * @ifr: interface request data870 *871 **/872int igc_ptp_set_ts_config(struct net_device *netdev, struct ifreq *ifr)873{874 struct igc_adapter *adapter = netdev_priv(netdev);875 struct hwtstamp_config config;876 int err;877 878 if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))879 return -EFAULT;880 881 err = igc_ptp_set_timestamp_mode(adapter, &config);882 if (err)883 return err;884 885 /* save these settings for future reference */886 memcpy(&adapter->tstamp_config, &config,887 sizeof(adapter->tstamp_config));888 889 return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ?890 -EFAULT : 0;891}892 893/**894 * igc_ptp_get_ts_config - get hardware time stamping config895 * @netdev: network interface device structure896 * @ifr: interface request data897 *898 * Get the hwtstamp_config settings to return to the user. Rather than attempt899 * to deconstruct the settings from the registers, just return a shadow copy900 * of the last known settings.901 **/902int igc_ptp_get_ts_config(struct net_device *netdev, struct ifreq *ifr)903{904 struct igc_adapter *adapter = netdev_priv(netdev);905 struct hwtstamp_config *config = &adapter->tstamp_config;906 907 return copy_to_user(ifr->ifr_data, config, sizeof(*config)) ?908 -EFAULT : 0;909}910 911/* The two conditions below must be met for cross timestamping via912 * PCIe PTM:913 *914 * 1. We have an way to convert the timestamps in the PTM messages915 * to something related to the system clocks (right now, only916 * X86 systems with support for the Always Running Timer allow that);917 *918 * 2. We have PTM enabled in the path from the device to the PCIe root port.919 */920static bool igc_is_crosststamp_supported(struct igc_adapter *adapter)921{922 if (!IS_ENABLED(CONFIG_X86_TSC))923 return false;924 925 /* FIXME: it was noticed that enabling support for PCIe PTM in926 * some i225-V models could cause lockups when bringing the927 * interface up/down. There should be no downsides to928 * disabling crosstimestamping support for i225-V, as it929 * doesn't have any PTP support. That way we gain some time930 * while root causing the issue.931 */932 if (adapter->pdev->device == IGC_DEV_ID_I225_V)933 return false;934 935 return pcie_ptm_enabled(adapter->pdev);936}937 938static struct system_counterval_t igc_device_tstamp_to_system(u64 tstamp)939{940#if IS_ENABLED(CONFIG_X86_TSC) && !defined(CONFIG_UML)941 return (struct system_counterval_t) {942 .cs_id = CSID_X86_ART,943 .cycles = tstamp,944 .use_nsecs = true,945 };946#else947 return (struct system_counterval_t) { };948#endif949}950 951static void igc_ptm_log_error(struct igc_adapter *adapter, u32 ptm_stat)952{953 struct net_device *netdev = adapter->netdev;954 955 switch (ptm_stat) {956 case IGC_PTM_STAT_RET_ERR:957 netdev_err(netdev, "PTM Error: Root port timeout\n");958 break;959 case IGC_PTM_STAT_BAD_PTM_RES:960 netdev_err(netdev, "PTM Error: Bad response, PTM Response Data expected\n");961 break;962 case IGC_PTM_STAT_T4M1_OVFL:963 netdev_err(netdev, "PTM Error: T4 minus T1 overflow\n");964 break;965 case IGC_PTM_STAT_ADJUST_1ST:966 netdev_err(netdev, "PTM Error: 1588 timer adjusted during first PTM cycle\n");967 break;968 case IGC_PTM_STAT_ADJUST_CYC:969 netdev_err(netdev, "PTM Error: 1588 timer adjusted during non-first PTM cycle\n");970 break;971 default:972 netdev_err(netdev, "PTM Error: Unknown error (%#x)\n", ptm_stat);973 break;974 }975}976 977static int igc_phc_get_syncdevicetime(ktime_t *device,978 struct system_counterval_t *system,979 void *ctx)980{981 u32 stat, t2_curr_h, t2_curr_l, ctrl;982 struct igc_adapter *adapter = ctx;983 struct igc_hw *hw = &adapter->hw;984 int err, count = 100;985 ktime_t t1, t2_curr;986 987 /* Get a snapshot of system clocks to use as historic value. */988 ktime_get_snapshot(&adapter->snapshot);989 990 do {991 /* Doing this in a loop because in the event of a992 * badly timed (ha!) system clock adjustment, we may993 * get PTM errors from the PCI root, but these errors994 * are transitory. Repeating the process returns valid995 * data eventually.996 */997 998 /* To "manually" start the PTM cycle we need to clear and999 * then set again the TRIG bit.1000 */1001 ctrl = rd32(IGC_PTM_CTRL);1002 ctrl &= ~IGC_PTM_CTRL_TRIG;1003 wr32(IGC_PTM_CTRL, ctrl);1004 ctrl |= IGC_PTM_CTRL_TRIG;1005 wr32(IGC_PTM_CTRL, ctrl);1006 1007 /* The cycle only starts "for real" when software notifies1008 * that it has read the registers, this is done by setting1009 * VALID bit.1010 */1011 wr32(IGC_PTM_STAT, IGC_PTM_STAT_VALID);1012 1013 err = readx_poll_timeout(rd32, IGC_PTM_STAT, stat,1014 stat, IGC_PTM_STAT_SLEEP,1015 IGC_PTM_STAT_TIMEOUT);1016 if (err < 0) {1017 netdev_err(adapter->netdev, "Timeout reading IGC_PTM_STAT register\n");1018 return err;1019 }1020 1021 if ((stat & IGC_PTM_STAT_VALID) == IGC_PTM_STAT_VALID)1022 break;1023 1024 if (stat & ~IGC_PTM_STAT_VALID) {1025 /* An error occurred, log it. */1026 igc_ptm_log_error(adapter, stat);1027 /* The STAT register is write-1-to-clear (W1C),1028 * so write the previous error status to clear it.1029 */1030 wr32(IGC_PTM_STAT, stat);1031 continue;1032 }1033 } while (--count);1034 1035 if (!count) {1036 netdev_err(adapter->netdev, "Exceeded number of tries for PTM cycle\n");1037 return -ETIMEDOUT;1038 }1039 1040 t1 = ktime_set(rd32(IGC_PTM_T1_TIM0_H), rd32(IGC_PTM_T1_TIM0_L));1041 1042 t2_curr_l = rd32(IGC_PTM_CURR_T2_L);1043 t2_curr_h = rd32(IGC_PTM_CURR_T2_H);1044 1045 /* FIXME: When the register that tells the endianness of the1046 * PTM registers are implemented, check them here and add the1047 * appropriate conversion.1048 */1049 t2_curr_h = swab32(t2_curr_h);1050 1051 t2_curr = ((s64)t2_curr_h << 32 | t2_curr_l);1052 1053 *device = t1;1054 *system = igc_device_tstamp_to_system(t2_curr);1055 1056 return 0;1057}1058 1059static int igc_ptp_getcrosststamp(struct ptp_clock_info *ptp,1060 struct system_device_crosststamp *cts)1061{1062 struct igc_adapter *adapter = container_of(ptp, struct igc_adapter,1063 ptp_caps);1064 1065 return get_device_system_crosststamp(igc_phc_get_syncdevicetime,1066 adapter, &adapter->snapshot, cts);1067}1068 1069static int igc_ptp_getcyclesx64(struct ptp_clock_info *ptp,1070 struct timespec64 *ts,1071 struct ptp_system_timestamp *sts)1072{1073 struct igc_adapter *igc = container_of(ptp, struct igc_adapter, ptp_caps);1074 struct igc_hw *hw = &igc->hw;1075 unsigned long flags;1076 1077 spin_lock_irqsave(&igc->free_timer_lock, flags);1078 1079 ptp_read_system_prets(sts);1080 ts->tv_nsec = rd32(IGC_SYSTIML_1);1081 ts->tv_sec = rd32(IGC_SYSTIMH_1);1082 ptp_read_system_postts(sts);1083 1084 spin_unlock_irqrestore(&igc->free_timer_lock, flags);1085 1086 return 0;1087}1088 1089/**1090 * igc_ptp_init - Initialize PTP functionality1091 * @adapter: Board private structure1092 *1093 * This function is called at device probe to initialize the PTP1094 * functionality.1095 */1096void igc_ptp_init(struct igc_adapter *adapter)1097{1098 struct net_device *netdev = adapter->netdev;1099 struct igc_tx_timestamp_request *tstamp;1100 struct igc_hw *hw = &adapter->hw;1101 int i;1102 1103 tstamp = &adapter->tx_tstamp[0];1104 tstamp->mask = IGC_TSYNCTXCTL_TXTT_0;1105 tstamp->regl = IGC_TXSTMPL_0;1106 tstamp->regh = IGC_TXSTMPH_0;1107 tstamp->flags = 0;1108 1109 tstamp = &adapter->tx_tstamp[1];1110 tstamp->mask = IGC_TSYNCTXCTL_TXTT_1;1111 tstamp->regl = IGC_TXSTMPL_1;1112 tstamp->regh = IGC_TXSTMPH_1;1113 tstamp->flags = IGC_TX_FLAGS_TSTAMP_1;1114 1115 tstamp = &adapter->tx_tstamp[2];1116 tstamp->mask = IGC_TSYNCTXCTL_TXTT_2;1117 tstamp->regl = IGC_TXSTMPL_2;1118 tstamp->regh = IGC_TXSTMPH_2;1119 tstamp->flags = IGC_TX_FLAGS_TSTAMP_2;1120 1121 tstamp = &adapter->tx_tstamp[3];1122 tstamp->mask = IGC_TSYNCTXCTL_TXTT_3;1123 tstamp->regl = IGC_TXSTMPL_3;1124 tstamp->regh = IGC_TXSTMPH_3;1125 tstamp->flags = IGC_TX_FLAGS_TSTAMP_3;1126 1127 switch (hw->mac.type) {1128 case igc_i225:1129 for (i = 0; i < IGC_N_SDP; i++) {1130 struct ptp_pin_desc *ppd = &adapter->sdp_config[i];1131 1132 snprintf(ppd->name, sizeof(ppd->name), "SDP%d", i);1133 ppd->index = i;1134 ppd->func = PTP_PF_NONE;1135 }1136 snprintf(adapter->ptp_caps.name, 16, "%pm", netdev->dev_addr);1137 adapter->ptp_caps.owner = THIS_MODULE;1138 adapter->ptp_caps.max_adj = 62499999;1139 adapter->ptp_caps.adjfine = igc_ptp_adjfine_i225;1140 adapter->ptp_caps.adjtime = igc_ptp_adjtime_i225;1141 adapter->ptp_caps.gettimex64 = igc_ptp_gettimex64_i225;1142 adapter->ptp_caps.getcyclesx64 = igc_ptp_getcyclesx64;1143 adapter->ptp_caps.settime64 = igc_ptp_settime_i225;1144 adapter->ptp_caps.enable = igc_ptp_feature_enable_i225;1145 adapter->ptp_caps.pps = 1;1146 adapter->ptp_caps.pin_config = adapter->sdp_config;1147 adapter->ptp_caps.n_ext_ts = IGC_N_EXTTS;1148 adapter->ptp_caps.n_per_out = IGC_N_PEROUT;1149 adapter->ptp_caps.n_pins = IGC_N_SDP;1150 adapter->ptp_caps.verify = igc_ptp_verify_pin;1151 1152 if (!igc_is_crosststamp_supported(adapter))1153 break;1154 1155 adapter->ptp_caps.getcrosststamp = igc_ptp_getcrosststamp;1156 break;1157 default:1158 adapter->ptp_clock = NULL;1159 return;1160 }1161 1162 spin_lock_init(&adapter->ptp_tx_lock);1163 spin_lock_init(&adapter->free_timer_lock);1164 spin_lock_init(&adapter->tmreg_lock);1165 1166 adapter->tstamp_config.rx_filter = HWTSTAMP_FILTER_NONE;1167 adapter->tstamp_config.tx_type = HWTSTAMP_TX_OFF;1168 1169 adapter->prev_ptp_time = ktime_to_timespec64(ktime_get_real());1170 adapter->ptp_reset_start = ktime_get();1171 1172 adapter->ptp_clock = ptp_clock_register(&adapter->ptp_caps,1173 &adapter->pdev->dev);1174 if (IS_ERR(adapter->ptp_clock)) {1175 adapter->ptp_clock = NULL;1176 netdev_err(netdev, "ptp_clock_register failed\n");1177 } else if (adapter->ptp_clock) {1178 netdev_info(netdev, "PHC added\n");1179 adapter->ptp_flags |= IGC_PTP_ENABLED;1180 }1181}1182 1183static void igc_ptp_time_save(struct igc_adapter *adapter)1184{1185 igc_ptp_read(adapter, &adapter->prev_ptp_time);1186 adapter->ptp_reset_start = ktime_get();1187}1188 1189static void igc_ptp_time_restore(struct igc_adapter *adapter)1190{1191 struct timespec64 ts = adapter->prev_ptp_time;1192 ktime_t delta;1193 1194 delta = ktime_sub(ktime_get(), adapter->ptp_reset_start);1195 1196 timespec64_add_ns(&ts, ktime_to_ns(delta));1197 1198 igc_ptp_write_i225(adapter, &ts);1199}1200 1201static void igc_ptm_stop(struct igc_adapter *adapter)1202{1203 struct igc_hw *hw = &adapter->hw;1204 u32 ctrl;1205 1206 ctrl = rd32(IGC_PTM_CTRL);1207 ctrl &= ~IGC_PTM_CTRL_EN;1208 1209 wr32(IGC_PTM_CTRL, ctrl);1210}1211 1212/**1213 * igc_ptp_suspend - Disable PTP work items and prepare for suspend1214 * @adapter: Board private structure1215 *1216 * This function stops the overflow check work and PTP Tx timestamp work, and1217 * will prepare the device for OS suspend.1218 */1219void igc_ptp_suspend(struct igc_adapter *adapter)1220{1221 if (!(adapter->ptp_flags & IGC_PTP_ENABLED))1222 return;1223 1224 igc_ptp_clear_tx_tstamp(adapter);1225 1226 if (pci_device_is_present(adapter->pdev)) {1227 igc_ptp_time_save(adapter);1228 igc_ptm_stop(adapter);1229 }1230}1231 1232/**1233 * igc_ptp_stop - Disable PTP device and stop the overflow check.1234 * @adapter: Board private structure.1235 *1236 * This function stops the PTP support and cancels the delayed work.1237 **/1238void igc_ptp_stop(struct igc_adapter *adapter)1239{1240 igc_ptp_suspend(adapter);1241 1242 if (adapter->ptp_clock) {1243 ptp_clock_unregister(adapter->ptp_clock);1244 netdev_info(adapter->netdev, "PHC removed\n");1245 adapter->ptp_flags &= ~IGC_PTP_ENABLED;1246 }1247}1248 1249/**1250 * igc_ptp_reset - Re-enable the adapter for PTP following a reset.1251 * @adapter: Board private structure.1252 *1253 * This function handles the reset work required to re-enable the PTP device.1254 **/1255void igc_ptp_reset(struct igc_adapter *adapter)1256{1257 struct igc_hw *hw = &adapter->hw;1258 u32 cycle_ctrl, ctrl;1259 unsigned long flags;1260 u32 timadj;1261 1262 /* reset the tstamp_config */1263 igc_ptp_set_timestamp_mode(adapter, &adapter->tstamp_config);1264 1265 spin_lock_irqsave(&adapter->tmreg_lock, flags);1266 1267 switch (adapter->hw.mac.type) {1268 case igc_i225:1269 timadj = rd32(IGC_TIMADJ);1270 timadj |= IGC_TIMADJ_ADJUST_METH;1271 wr32(IGC_TIMADJ, timadj);1272 1273 wr32(IGC_TSAUXC, 0x0);1274 wr32(IGC_TSSDP, 0x0);1275 wr32(IGC_TSIM,1276 IGC_TSICR_INTERRUPTS |1277 (adapter->pps_sys_wrap_on ? IGC_TSICR_SYS_WRAP : 0));1278 wr32(IGC_IMS, IGC_IMS_TS);1279 1280 if (!igc_is_crosststamp_supported(adapter))1281 break;1282 1283 wr32(IGC_PCIE_DIG_DELAY, IGC_PCIE_DIG_DELAY_DEFAULT);1284 wr32(IGC_PCIE_PHY_DELAY, IGC_PCIE_PHY_DELAY_DEFAULT);1285 1286 cycle_ctrl = IGC_PTM_CYCLE_CTRL_CYC_TIME(IGC_PTM_CYC_TIME_DEFAULT);1287 1288 wr32(IGC_PTM_CYCLE_CTRL, cycle_ctrl);1289 1290 ctrl = IGC_PTM_CTRL_EN |1291 IGC_PTM_CTRL_START_NOW |1292 IGC_PTM_CTRL_SHRT_CYC(IGC_PTM_SHORT_CYC_DEFAULT) |1293 IGC_PTM_CTRL_PTM_TO(IGC_PTM_TIMEOUT_DEFAULT) |1294 IGC_PTM_CTRL_TRIG;1295 1296 wr32(IGC_PTM_CTRL, ctrl);1297 1298 /* Force the first cycle to run. */1299 wr32(IGC_PTM_STAT, IGC_PTM_STAT_VALID);1300 1301 break;1302 default:1303 /* No work to do. */1304 goto out;1305 }1306 1307 /* Re-initialize the timer. */1308 if (hw->mac.type == igc_i225) {1309 igc_ptp_time_restore(adapter);1310 } else {1311 timecounter_init(&adapter->tc, &adapter->cc,1312 ktime_to_ns(ktime_get_real()));1313 }1314out:1315 spin_unlock_irqrestore(&adapter->tmreg_lock, flags);1316 1317 wrfl();1318}1319