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>
This commit is contained in:
parent
916444df30
commit
98942d7053
@ -505,6 +505,9 @@ extern const struct e1000_info e1000_es2_info;
|
|||||||
void e1000e_ptp_init(struct e1000_adapter *adapter);
|
void e1000e_ptp_init(struct e1000_adapter *adapter);
|
||||||
void e1000e_ptp_remove(struct e1000_adapter *adapter);
|
void e1000e_ptp_remove(struct e1000_adapter *adapter);
|
||||||
|
|
||||||
|
u64 e1000e_read_systim(struct e1000_adapter *adapter,
|
||||||
|
struct ptp_system_timestamp *sts);
|
||||||
|
|
||||||
static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw)
|
static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw)
|
||||||
{
|
{
|
||||||
return hw->phy.ops.reset(hw);
|
return hw->phy.ops.reset(hw);
|
||||||
|
@ -4319,13 +4319,16 @@ void e1000e_reinit_locked(struct e1000_adapter *adapter)
|
|||||||
/**
|
/**
|
||||||
* e1000e_sanitize_systim - sanitize raw cycle counter reads
|
* e1000e_sanitize_systim - sanitize raw cycle counter reads
|
||||||
* @hw: pointer to the HW structure
|
* @hw: pointer to the HW structure
|
||||||
* @systim: time value read, sanitized and returned
|
* @systim: PHC time value read, sanitized and returned
|
||||||
|
* @sts: structure to hold system time before and after reading SYSTIML,
|
||||||
|
* may be NULL
|
||||||
*
|
*
|
||||||
* Errata for 82574/82583 possible bad bits read from SYSTIMH/L:
|
* Errata for 82574/82583 possible bad bits read from SYSTIMH/L:
|
||||||
* check to see that the time is incrementing at a reasonable
|
* check to see that the time is incrementing at a reasonable
|
||||||
* rate and is a multiple of incvalue.
|
* rate and is a multiple of incvalue.
|
||||||
**/
|
**/
|
||||||
static u64 e1000e_sanitize_systim(struct e1000_hw *hw, u64 systim)
|
static u64 e1000e_sanitize_systim(struct e1000_hw *hw, u64 systim,
|
||||||
|
struct ptp_system_timestamp *sts)
|
||||||
{
|
{
|
||||||
u64 time_delta, rem, temp;
|
u64 time_delta, rem, temp;
|
||||||
u64 systim_next;
|
u64 systim_next;
|
||||||
@ -4335,7 +4338,9 @@ static u64 e1000e_sanitize_systim(struct e1000_hw *hw, u64 systim)
|
|||||||
incvalue = er32(TIMINCA) & E1000_TIMINCA_INCVALUE_MASK;
|
incvalue = er32(TIMINCA) & E1000_TIMINCA_INCVALUE_MASK;
|
||||||
for (i = 0; i < E1000_MAX_82574_SYSTIM_REREADS; i++) {
|
for (i = 0; i < E1000_MAX_82574_SYSTIM_REREADS; i++) {
|
||||||
/* latch SYSTIMH on read of SYSTIML */
|
/* latch SYSTIMH on read of SYSTIML */
|
||||||
|
ptp_read_system_prets(sts);
|
||||||
systim_next = (u64)er32(SYSTIML);
|
systim_next = (u64)er32(SYSTIML);
|
||||||
|
ptp_read_system_postts(sts);
|
||||||
systim_next |= (u64)er32(SYSTIMH) << 32;
|
systim_next |= (u64)er32(SYSTIMH) << 32;
|
||||||
|
|
||||||
time_delta = systim_next - systim;
|
time_delta = systim_next - systim;
|
||||||
@ -4353,15 +4358,16 @@ static u64 e1000e_sanitize_systim(struct e1000_hw *hw, u64 systim)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* e1000e_cyclecounter_read - read raw cycle counter (used by time counter)
|
* e1000e_read_systim - read SYSTIM register
|
||||||
* @cc: cyclecounter structure
|
* @adapter: board private structure
|
||||||
|
* @sts: structure which will contain system time before and after reading
|
||||||
|
* SYSTIML, may be NULL
|
||||||
**/
|
**/
|
||||||
static u64 e1000e_cyclecounter_read(const struct cyclecounter *cc)
|
u64 e1000e_read_systim(struct e1000_adapter *adapter,
|
||||||
|
struct ptp_system_timestamp *sts)
|
||||||
{
|
{
|
||||||
struct e1000_adapter *adapter = container_of(cc, struct e1000_adapter,
|
|
||||||
cc);
|
|
||||||
struct e1000_hw *hw = &adapter->hw;
|
struct e1000_hw *hw = &adapter->hw;
|
||||||
u32 systimel, systimeh;
|
u32 systimel, systimel_2, systimeh;
|
||||||
u64 systim;
|
u64 systim;
|
||||||
/* SYSTIMH latching upon SYSTIML read does not work well.
|
/* SYSTIMH latching upon SYSTIML read does not work well.
|
||||||
* This means that if SYSTIML overflows after we read it but before
|
* This means that if SYSTIML overflows after we read it but before
|
||||||
@ -4369,11 +4375,15 @@ static u64 e1000e_cyclecounter_read(const struct cyclecounter *cc)
|
|||||||
* will experience a huge non linear increment in the systime value
|
* will experience a huge non linear increment in the systime value
|
||||||
* to fix that we test for overflow and if true, we re-read systime.
|
* to fix that we test for overflow and if true, we re-read systime.
|
||||||
*/
|
*/
|
||||||
|
ptp_read_system_prets(sts);
|
||||||
systimel = er32(SYSTIML);
|
systimel = er32(SYSTIML);
|
||||||
|
ptp_read_system_postts(sts);
|
||||||
systimeh = er32(SYSTIMH);
|
systimeh = er32(SYSTIMH);
|
||||||
/* Is systimel is so large that overflow is possible? */
|
/* Is systimel is so large that overflow is possible? */
|
||||||
if (systimel >= (u32)0xffffffff - E1000_TIMINCA_INCVALUE_MASK) {
|
if (systimel >= (u32)0xffffffff - E1000_TIMINCA_INCVALUE_MASK) {
|
||||||
u32 systimel_2 = er32(SYSTIML);
|
ptp_read_system_prets(sts);
|
||||||
|
systimel_2 = er32(SYSTIML);
|
||||||
|
ptp_read_system_postts(sts);
|
||||||
if (systimel > systimel_2) {
|
if (systimel > systimel_2) {
|
||||||
/* There was an overflow, read again SYSTIMH, and use
|
/* There was an overflow, read again SYSTIMH, and use
|
||||||
* systimel_2
|
* systimel_2
|
||||||
@ -4386,11 +4396,23 @@ static u64 e1000e_cyclecounter_read(const struct cyclecounter *cc)
|
|||||||
systim |= (u64)systimeh << 32;
|
systim |= (u64)systimeh << 32;
|
||||||
|
|
||||||
if (adapter->flags2 & FLAG2_CHECK_SYSTIM_OVERFLOW)
|
if (adapter->flags2 & FLAG2_CHECK_SYSTIM_OVERFLOW)
|
||||||
systim = e1000e_sanitize_systim(hw, systim);
|
systim = e1000e_sanitize_systim(hw, systim, sts);
|
||||||
|
|
||||||
return systim;
|
return systim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* e1000e_cyclecounter_read - read raw cycle counter (used by time counter)
|
||||||
|
* @cc: cyclecounter structure
|
||||||
|
**/
|
||||||
|
static u64 e1000e_cyclecounter_read(const struct cyclecounter *cc)
|
||||||
|
{
|
||||||
|
struct e1000_adapter *adapter = container_of(cc, struct e1000_adapter,
|
||||||
|
cc);
|
||||||
|
|
||||||
|
return e1000e_read_systim(adapter, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* e1000_sw_init - Initialize general software structures (struct e1000_adapter)
|
* e1000_sw_init - Initialize general software structures (struct e1000_adapter)
|
||||||
* @adapter: board private structure to initialize
|
* @adapter: board private structure to initialize
|
||||||
|
@ -161,14 +161,18 @@ static int e1000e_phc_getcrosststamp(struct ptp_clock_info *ptp,
|
|||||||
#endif/*CONFIG_E1000E_HWTS*/
|
#endif/*CONFIG_E1000E_HWTS*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* e1000e_phc_gettime - Reads the current time from the hardware clock
|
* e1000e_phc_gettimex - Reads the current time from the hardware clock and
|
||||||
|
* system clock
|
||||||
* @ptp: ptp clock structure
|
* @ptp: ptp clock structure
|
||||||
* @ts: timespec structure to hold the current time value
|
* @ts: timespec structure to hold the current PHC time
|
||||||
|
* @sts: structure to hold the current system time
|
||||||
*
|
*
|
||||||
* Read the timecounter and return the correct value in ns after converting
|
* Read the timecounter and return the correct value in ns after converting
|
||||||
* it into a struct timespec.
|
* it into a struct timespec.
|
||||||
**/
|
**/
|
||||||
static int e1000e_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
|
static int e1000e_phc_gettimex(struct ptp_clock_info *ptp,
|
||||||
|
struct timespec64 *ts,
|
||||||
|
struct ptp_system_timestamp *sts)
|
||||||
{
|
{
|
||||||
struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
|
struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
|
||||||
ptp_clock_info);
|
ptp_clock_info);
|
||||||
@ -177,8 +181,8 @@ static int e1000e_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts)
|
|||||||
|
|
||||||
spin_lock_irqsave(&adapter->systim_lock, flags);
|
spin_lock_irqsave(&adapter->systim_lock, flags);
|
||||||
|
|
||||||
/* Use timecounter_cyc2time() to allow non-monotonic SYSTIM readings */
|
/* NOTE: Non-monotonic SYSTIM readings may be returned */
|
||||||
cycles = adapter->cc.read(&adapter->cc);
|
cycles = e1000e_read_systim(adapter, sts);
|
||||||
ns = timecounter_cyc2time(&adapter->tc, cycles);
|
ns = timecounter_cyc2time(&adapter->tc, cycles);
|
||||||
|
|
||||||
spin_unlock_irqrestore(&adapter->systim_lock, flags);
|
spin_unlock_irqrestore(&adapter->systim_lock, flags);
|
||||||
@ -258,7 +262,7 @@ static const struct ptp_clock_info e1000e_ptp_clock_info = {
|
|||||||
.pps = 0,
|
.pps = 0,
|
||||||
.adjfreq = e1000e_phc_adjfreq,
|
.adjfreq = e1000e_phc_adjfreq,
|
||||||
.adjtime = e1000e_phc_adjtime,
|
.adjtime = e1000e_phc_adjtime,
|
||||||
.gettime64 = e1000e_phc_gettime,
|
.gettimex64 = e1000e_phc_gettimex,
|
||||||
.settime64 = e1000e_phc_settime,
|
.settime64 = e1000e_phc_settime,
|
||||||
.enable = e1000e_phc_enable,
|
.enable = e1000e_phc_enable,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user