Skip to content

Commit 98942d7

Browse files
mlichvardavem330
authored andcommitted
e1000e: extend PTP gettime function to read system clock
This adds support for the PTP_SYS_OFFSET_EXTENDED ioctl. Cc: Richard Cochran <richardcochran@gmail.com> Cc: Jacob Keller <jacob.e.keller@intel.com> Cc: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com> Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 916444d commit 98942d7

File tree

3 files changed

+45
-16
lines changed

3 files changed

+45
-16
lines changed

drivers/net/ethernet/intel/e1000e/e1000.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,9 @@ extern const struct e1000_info e1000_es2_info;
505505
void e1000e_ptp_init(struct e1000_adapter *adapter);
506506
void e1000e_ptp_remove(struct e1000_adapter *adapter);
507507

508+
u64 e1000e_read_systim(struct e1000_adapter *adapter,
509+
struct ptp_system_timestamp *sts);
510+
508511
static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw)
509512
{
510513
return hw->phy.ops.reset(hw);

drivers/net/ethernet/intel/e1000e/netdev.c

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4319,13 +4319,16 @@ void e1000e_reinit_locked(struct e1000_adapter *adapter)
43194319
/**
43204320
* e1000e_sanitize_systim - sanitize raw cycle counter reads
43214321
* @hw: pointer to the HW structure
4322-
* @systim: time value read, sanitized and returned
4322+
* @systim: PHC time value read, sanitized and returned
4323+
* @sts: structure to hold system time before and after reading SYSTIML,
4324+
* may be NULL
43234325
*
43244326
* Errata for 82574/82583 possible bad bits read from SYSTIMH/L:
43254327
* check to see that the time is incrementing at a reasonable
43264328
* rate and is a multiple of incvalue.
43274329
**/
4328-
static u64 e1000e_sanitize_systim(struct e1000_hw *hw, u64 systim)
4330+
static u64 e1000e_sanitize_systim(struct e1000_hw *hw, u64 systim,
4331+
struct ptp_system_timestamp *sts)
43294332
{
43304333
u64 time_delta, rem, temp;
43314334
u64 systim_next;
@@ -4335,7 +4338,9 @@ static u64 e1000e_sanitize_systim(struct e1000_hw *hw, u64 systim)
43354338
incvalue = er32(TIMINCA) & E1000_TIMINCA_INCVALUE_MASK;
43364339
for (i = 0; i < E1000_MAX_82574_SYSTIM_REREADS; i++) {
43374340
/* latch SYSTIMH on read of SYSTIML */
4341+
ptp_read_system_prets(sts);
43384342
systim_next = (u64)er32(SYSTIML);
4343+
ptp_read_system_postts(sts);
43394344
systim_next |= (u64)er32(SYSTIMH) << 32;
43404345

43414346
time_delta = systim_next - systim;
@@ -4353,27 +4358,32 @@ static u64 e1000e_sanitize_systim(struct e1000_hw *hw, u64 systim)
43534358
}
43544359

43554360
/**
4356-
* e1000e_cyclecounter_read - read raw cycle counter (used by time counter)
4357-
* @cc: cyclecounter structure
4361+
* e1000e_read_systim - read SYSTIM register
4362+
* @adapter: board private structure
4363+
* @sts: structure which will contain system time before and after reading
4364+
* SYSTIML, may be NULL
43584365
**/
4359-
static u64 e1000e_cyclecounter_read(const struct cyclecounter *cc)
4366+
u64 e1000e_read_systim(struct e1000_adapter *adapter,
4367+
struct ptp_system_timestamp *sts)
43604368
{
4361-
struct e1000_adapter *adapter = container_of(cc, struct e1000_adapter,
4362-
cc);
43634369
struct e1000_hw *hw = &adapter->hw;
4364-
u32 systimel, systimeh;
4370+
u32 systimel, systimel_2, systimeh;
43654371
u64 systim;
43664372
/* SYSTIMH latching upon SYSTIML read does not work well.
43674373
* This means that if SYSTIML overflows after we read it but before
43684374
* we read SYSTIMH, the value of SYSTIMH has been incremented and we
43694375
* will experience a huge non linear increment in the systime value
43704376
* to fix that we test for overflow and if true, we re-read systime.
43714377
*/
4378+
ptp_read_system_prets(sts);
43724379
systimel = er32(SYSTIML);
4380+
ptp_read_system_postts(sts);
43734381
systimeh = er32(SYSTIMH);
43744382
/* Is systimel is so large that overflow is possible? */
43754383
if (systimel >= (u32)0xffffffff - E1000_TIMINCA_INCVALUE_MASK) {
4376-
u32 systimel_2 = er32(SYSTIML);
4384+
ptp_read_system_prets(sts);
4385+
systimel_2 = er32(SYSTIML);
4386+
ptp_read_system_postts(sts);
43774387
if (systimel > systimel_2) {
43784388
/* There was an overflow, read again SYSTIMH, and use
43794389
* systimel_2
@@ -4386,11 +4396,23 @@ static u64 e1000e_cyclecounter_read(const struct cyclecounter *cc)
43864396
systim |= (u64)systimeh << 32;
43874397

43884398
if (adapter->flags2 & FLAG2_CHECK_SYSTIM_OVERFLOW)
4389-
systim = e1000e_sanitize_systim(hw, systim);
4399+
systim = e1000e_sanitize_systim(hw, systim, sts);
43904400

43914401
return systim;
43924402
}
43934403

4404+
/**
4405+
* e1000e_cyclecounter_read - read raw cycle counter (used by time counter)
4406+
* @cc: cyclecounter structure
4407+
**/
4408+
static u64 e1000e_cyclecounter_read(const struct cyclecounter *cc)
4409+
{
4410+
struct e1000_adapter *adapter = container_of(cc, struct e1000_adapter,
4411+
cc);
4412+
4413+
return e1000e_read_systim(adapter, NULL);
4414+
}
4415+
43944416
/**
43954417
* e1000_sw_init - Initialize general software structures (struct e1000_adapter)
43964418
* @adapter: board private structure to initialize

drivers/net/ethernet/intel/e1000e/ptp.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -161,14 +161,18 @@ static int e1000e_phc_getcrosststamp(struct ptp_clock_info *ptp,
161161
#endif/*CONFIG_E1000E_HWTS*/
162162

163163
/**
164-
* e1000e_phc_gettime - Reads the current time from the hardware clock
164+
* e1000e_phc_gettimex - Reads the current time from the hardware clock and
165+
* system clock
165166
* @ptp: ptp clock structure
166-
* @ts: timespec structure to hold the current time value
167+
* @ts: timespec structure to hold the current PHC time
168+
* @sts: structure to hold the current system time
167169
*
168170
* Read the timecounter and return the correct value in ns after converting
169171
* it into a struct timespec.
170172
**/
171-
static int e1000e_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
173+
static int e1000e_phc_gettimex(struct ptp_clock_info *ptp,
174+
struct timespec64 *ts,
175+
struct ptp_system_timestamp *sts)
172176
{
173177
struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
174178
ptp_clock_info);
@@ -177,8 +181,8 @@ static int e1000e_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
177181

178182
spin_lock_irqsave(&adapter->systim_lock, flags);
179183

180-
/* Use timecounter_cyc2time() to allow non-monotonic SYSTIM readings */
181-
cycles = adapter->cc.read(&adapter->cc);
184+
/* NOTE: Non-monotonic SYSTIM readings may be returned */
185+
cycles = e1000e_read_systim(adapter, sts);
182186
ns = timecounter_cyc2time(&adapter->tc, cycles);
183187

184188
spin_unlock_irqrestore(&adapter->systim_lock, flags);
@@ -258,7 +262,7 @@ static const struct ptp_clock_info e1000e_ptp_clock_info = {
258262
.pps = 0,
259263
.adjfreq = e1000e_phc_adjfreq,
260264
.adjtime = e1000e_phc_adjtime,
261-
.gettime64 = e1000e_phc_gettime,
265+
.gettimex64 = e1000e_phc_gettimex,
262266
.settime64 = e1000e_phc_settime,
263267
.enable = e1000e_phc_enable,
264268
};

0 commit comments

Comments
 (0)