Skip to content

Commit 64433e5

Browse files
edersondisouzaanguy11
authored andcommitted
igc: Enable internal i225 PPS
The i225 device can produce one interrupt on the full second, much like i210 - from where this patch is inspired. This patch sets up the full second interruption on the i225 and when receiving it, it sends a PPS event to PTP (Precision Time Protocol) kernel subsystem. The PTP subsystem exposes the PPS events via ioctl and sysfs, and one can use the `testptp` tool (tools/testing/selftests/ptp) to check that the events are being generated. Signed-off-by: Ederson de Souza <[email protected]> Tested-by: Dvora Fuxbrumer <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 1d3cb90 commit 64433e5

File tree

3 files changed

+37
-1
lines changed

3 files changed

+37
-1
lines changed

drivers/net/ethernet/intel/igc/igc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ struct igc_adapter {
223223
char fw_version[32];
224224

225225
struct bpf_prog *xdp_prog;
226+
227+
bool pps_sys_wrap_on;
226228
};
227229

228230
void igc_up(struct igc_adapter *adapter);

drivers/net/ethernet/intel/igc/igc_main.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4251,9 +4251,17 @@ igc_features_check(struct sk_buff *skb, struct net_device *dev,
42514251
static void igc_tsync_interrupt(struct igc_adapter *adapter)
42524252
{
42534253
struct igc_hw *hw = &adapter->hw;
4254+
struct ptp_clock_event event;
42544255
u32 tsicr = rd32(IGC_TSICR);
42554256
u32 ack = 0;
42564257

4258+
if (tsicr & IGC_TSICR_SYS_WRAP) {
4259+
event.type = PTP_CLOCK_PPS;
4260+
if (adapter->ptp_caps.pps)
4261+
ptp_clock_event(adapter->ptp_clock, &event);
4262+
ack |= IGC_TSICR_SYS_WRAP;
4263+
}
4264+
42574265
if (tsicr & IGC_TSICR_TXTS) {
42584266
/* retrieve hardware timestamp */
42594267
schedule_work(&adapter->ptp_tx_work);

drivers/net/ethernet/intel/igc/igc_ptp.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,29 @@ static int igc_ptp_settime_i225(struct ptp_clock_info *ptp,
123123
static int igc_ptp_feature_enable_i225(struct ptp_clock_info *ptp,
124124
struct ptp_clock_request *rq, int on)
125125
{
126+
struct igc_adapter *igc =
127+
container_of(ptp, struct igc_adapter, ptp_caps);
128+
struct igc_hw *hw = &igc->hw;
129+
unsigned long flags;
130+
u32 tsim;
131+
132+
switch (rq->type) {
133+
case PTP_CLK_REQ_PPS:
134+
spin_lock_irqsave(&igc->tmreg_lock, flags);
135+
tsim = rd32(IGC_TSIM);
136+
if (on)
137+
tsim |= IGC_TSICR_SYS_WRAP;
138+
else
139+
tsim &= ~IGC_TSICR_SYS_WRAP;
140+
igc->pps_sys_wrap_on = on;
141+
wr32(IGC_TSIM, tsim);
142+
spin_unlock_irqrestore(&igc->tmreg_lock, flags);
143+
return 0;
144+
145+
default:
146+
break;
147+
}
148+
126149
return -EOPNOTSUPP;
127150
}
128151

@@ -497,6 +520,7 @@ void igc_ptp_init(struct igc_adapter *adapter)
497520
adapter->ptp_caps.gettimex64 = igc_ptp_gettimex64_i225;
498521
adapter->ptp_caps.settime64 = igc_ptp_settime_i225;
499522
adapter->ptp_caps.enable = igc_ptp_feature_enable_i225;
523+
adapter->ptp_caps.pps = 1;
500524
break;
501525
default:
502526
adapter->ptp_clock = NULL;
@@ -598,7 +622,9 @@ void igc_ptp_reset(struct igc_adapter *adapter)
598622
case igc_i225:
599623
wr32(IGC_TSAUXC, 0x0);
600624
wr32(IGC_TSSDP, 0x0);
601-
wr32(IGC_TSIM, IGC_TSICR_INTERRUPTS);
625+
wr32(IGC_TSIM,
626+
IGC_TSICR_INTERRUPTS |
627+
(adapter->pps_sys_wrap_on ? IGC_TSICR_SYS_WRAP : 0));
602628
wr32(IGC_IMS, IGC_IMS_TS);
603629
break;
604630
default:

0 commit comments

Comments
 (0)