1 /*******************************************************************************
3 Intel PRO/1000 Linux driver
4 Copyright(c) 1999 - 2013 Intel Corporation.
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
23 Linux NICS <linux.nics@intel.com>
24 e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
25 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *******************************************************************************/
29 /* PTP 1588 Hardware Clock (PHC)
30 * Derived from PTP Hardware Clock driver for Intel 82576 and 82580 (igb)
31 * Copyright (C) 2011 Richard Cochran <richardcochran@gmail.com>
37 * e1000e_phc_adjfreq - adjust the frequency of the hardware clock
38 * @ptp: ptp clock structure
39 * @delta: Desired frequency change in parts per billion
41 * Adjust the frequency of the PHC cycle counter by the indicated delta from
44 static int e1000e_phc_adjfreq(struct ptp_clock_info
*ptp
, s32 delta
)
46 struct e1000_adapter
*adapter
= container_of(ptp
, struct e1000_adapter
,
48 struct e1000_hw
*hw
= &adapter
->hw
;
51 u32 timinca
, incvalue
;
54 if ((delta
> ptp
->max_adj
) || (delta
<= -1000000000))
62 /* Get the System Time Register SYSTIM base frequency */
63 ret_val
= e1000e_get_base_timinca(adapter
, &timinca
);
67 incvalue
= timinca
& E1000_TIMINCA_INCVALUE_MASK
;
69 adjustment
= incvalue
;
71 adjustment
= div_u64(adjustment
, 1000000000);
73 incvalue
= neg_adj
? (incvalue
- adjustment
) : (incvalue
+ adjustment
);
75 timinca
&= ~E1000_TIMINCA_INCVALUE_MASK
;
78 ew32(TIMINCA
, timinca
);
84 * e1000e_phc_adjtime - Shift the time of the hardware clock
85 * @ptp: ptp clock structure
86 * @delta: Desired change in nanoseconds
88 * Adjust the timer by resetting the timecounter structure.
90 static int e1000e_phc_adjtime(struct ptp_clock_info
*ptp
, s64 delta
)
92 struct e1000_adapter
*adapter
= container_of(ptp
, struct e1000_adapter
,
97 spin_lock_irqsave(&adapter
->systim_lock
, flags
);
98 now
= timecounter_read(&adapter
->tc
);
100 timecounter_init(&adapter
->tc
, &adapter
->cc
, now
);
101 spin_unlock_irqrestore(&adapter
->systim_lock
, flags
);
107 * e1000e_phc_gettime - Reads the current time from the hardware clock
108 * @ptp: ptp clock structure
109 * @ts: timespec structure to hold the current time value
111 * Read the timecounter and return the correct value in ns after converting
112 * it into a struct timespec.
114 static int e1000e_phc_gettime(struct ptp_clock_info
*ptp
, struct timespec
*ts
)
116 struct e1000_adapter
*adapter
= container_of(ptp
, struct e1000_adapter
,
122 spin_lock_irqsave(&adapter
->systim_lock
, flags
);
123 ns
= timecounter_read(&adapter
->tc
);
124 spin_unlock_irqrestore(&adapter
->systim_lock
, flags
);
126 ts
->tv_sec
= div_u64_rem(ns
, NSEC_PER_SEC
, &remainder
);
127 ts
->tv_nsec
= remainder
;
133 * e1000e_phc_settime - Set the current time on the hardware clock
134 * @ptp: ptp clock structure
135 * @ts: timespec containing the new time for the cycle counter
137 * Reset the timecounter to use a new base value instead of the kernel
140 static int e1000e_phc_settime(struct ptp_clock_info
*ptp
,
141 const struct timespec
*ts
)
143 struct e1000_adapter
*adapter
= container_of(ptp
, struct e1000_adapter
,
148 ns
= timespec_to_ns(ts
);
150 /* reset the timecounter */
151 spin_lock_irqsave(&adapter
->systim_lock
, flags
);
152 timecounter_init(&adapter
->tc
, &adapter
->cc
, ns
);
153 spin_unlock_irqrestore(&adapter
->systim_lock
, flags
);
159 * e1000e_phc_enable - enable or disable an ancillary feature
160 * @ptp: ptp clock structure
161 * @request: Desired resource to enable or disable
162 * @on: Caller passes one to enable or zero to disable
164 * Enable (or disable) ancillary features of the PHC subsystem.
165 * Currently, no ancillary features are supported.
167 static int e1000e_phc_enable(struct ptp_clock_info __always_unused
*ptp
,
168 struct ptp_clock_request __always_unused
*request
,
169 int __always_unused on
)
174 static void e1000e_systim_overflow_work(struct work_struct
*work
)
176 struct e1000_adapter
*adapter
= container_of(work
, struct e1000_adapter
,
177 systim_overflow_work
.work
);
178 struct e1000_hw
*hw
= &adapter
->hw
;
181 adapter
->ptp_clock_info
.gettime(&adapter
->ptp_clock_info
, &ts
);
183 e_dbg("SYSTIM overflow check at %ld.%09lu\n", ts
.tv_sec
, ts
.tv_nsec
);
185 schedule_delayed_work(&adapter
->systim_overflow_work
,
186 E1000_SYSTIM_OVERFLOW_PERIOD
);
189 static const struct ptp_clock_info e1000e_ptp_clock_info
= {
190 .owner
= THIS_MODULE
,
195 .adjfreq
= e1000e_phc_adjfreq
,
196 .adjtime
= e1000e_phc_adjtime
,
197 .gettime
= e1000e_phc_gettime
,
198 .settime
= e1000e_phc_settime
,
199 .enable
= e1000e_phc_enable
,
203 * e1000e_ptp_init - initialize PTP for devices which support it
204 * @adapter: board private structure
206 * This function performs the required steps for enabling PTP support.
207 * If PTP support has already been loaded it simply calls the cyclecounter
208 * init routine and exits.
210 void e1000e_ptp_init(struct e1000_adapter
*adapter
)
212 struct e1000_hw
*hw
= &adapter
->hw
;
214 adapter
->ptp_clock
= NULL
;
216 if (!(adapter
->flags
& FLAG_HAS_HW_TIMESTAMP
))
219 adapter
->ptp_clock_info
= e1000e_ptp_clock_info
;
221 snprintf(adapter
->ptp_clock_info
.name
,
222 sizeof(adapter
->ptp_clock_info
.name
), "%pm",
223 adapter
->netdev
->perm_addr
);
225 switch (hw
->mac
.type
) {
228 if ((hw
->mac
.type
!= e1000_pch_lpt
) ||
229 (er32(TSYNCRXCTL
) & E1000_TSYNCRXCTL_SYSCFI
)) {
230 adapter
->ptp_clock_info
.max_adj
= 24000000 - 1;
236 adapter
->ptp_clock_info
.max_adj
= 600000000 - 1;
242 INIT_DELAYED_WORK(&adapter
->systim_overflow_work
,
243 e1000e_systim_overflow_work
);
245 schedule_delayed_work(&adapter
->systim_overflow_work
,
246 E1000_SYSTIM_OVERFLOW_PERIOD
);
248 adapter
->ptp_clock
= ptp_clock_register(&adapter
->ptp_clock_info
,
249 &adapter
->pdev
->dev
);
250 if (IS_ERR(adapter
->ptp_clock
)) {
251 adapter
->ptp_clock
= NULL
;
252 e_err("ptp_clock_register failed\n");
254 e_info("registered PHC clock\n");
259 * e1000e_ptp_remove - disable PTP device and stop the overflow check
260 * @adapter: board private structure
262 * Stop the PTP support, and cancel the delayed work.
264 void e1000e_ptp_remove(struct e1000_adapter
*adapter
)
266 if (!(adapter
->flags
& FLAG_HAS_HW_TIMESTAMP
))
269 cancel_delayed_work_sync(&adapter
->systim_overflow_work
);
271 if (adapter
->ptp_clock
) {
272 ptp_clock_unregister(adapter
->ptp_clock
);
273 adapter
->ptp_clock
= NULL
;
274 e_info("removed PHC\n");