[Intel-wired-lan] [PATCH next-queue v1 1/2] igc: Enable internal i225 PPS

Paul Menzel pmenzel at molgen.mpg.de
Tue Feb 16 09:38:04 UTC 2021


Dear Ederson,


Am 12.02.21 um 02:42 schrieb Ederson de Souza:
> The i225 device can produce one interrupt on the full second. This patch

Please reference the spec.

> allows using this interrupt to generate an internal PPS event for
> adjusting the kernel system time.

How can this be tested?

A more elaborate description of the implementation would be useful in 
commit messages.

> Signed-off-by: Ederson de Souza <ederson.desouza at intel.com>
> ---
>   drivers/net/ethernet/intel/igc/igc.h      |  2 ++
>   drivers/net/ethernet/intel/igc/igc_main.c |  8 +++++++
>   drivers/net/ethernet/intel/igc/igc_ptp.c  | 28 ++++++++++++++++++++++-
>   3 files changed, 37 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/intel/igc/igc.h b/drivers/net/ethernet/intel/igc/igc.h
> index 415cfea27718..fa81cec80711 100644
> --- a/drivers/net/ethernet/intel/igc/igc.h
> +++ b/drivers/net/ethernet/intel/igc/igc.h
> @@ -224,6 +224,8 @@ struct igc_adapter {
>   	char fw_version[32];
>   
>   	struct bpf_prog *xdp_prog;
> +
> +	bool pps_sys_wrap_on;
>   };
>   
>   void igc_up(struct igc_adapter *adapter);
> diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c
> index c363f7fd1aaa..5e3b6ac00b3a 100644
> --- a/drivers/net/ethernet/intel/igc/igc_main.c
> +++ b/drivers/net/ethernet/intel/igc/igc_main.c
> @@ -4599,9 +4599,17 @@ igc_features_check(struct sk_buff *skb, struct net_device *dev,
>   static void igc_tsync_interrupt(struct igc_adapter *adapter)
>   {
>   	struct igc_hw *hw = &adapter->hw;
> +	struct ptp_clock_event event;
>   	u32 tsicr = rd32(IGC_TSICR);
>   	u32 ack = 0;
>   
> +	if (tsicr & IGC_TSICR_SYS_WRAP) {
> +		event.type = PTP_CLOCK_PPS;
> +		if (adapter->ptp_caps.pps)
> +			ptp_clock_event(adapter->ptp_clock, &event);
> +		ack |= IGC_TSICR_SYS_WRAP;
> +	}
> +
>   	if (tsicr & IGC_TSICR_TXTS) {
>   		/* retrieve hardware timestamp */
>   		schedule_work(&adapter->ptp_tx_work);
> diff --git a/drivers/net/ethernet/intel/igc/igc_ptp.c b/drivers/net/ethernet/intel/igc/igc_ptp.c
> index 7301a7b3fadc..868cd51909e9 100644
> --- a/drivers/net/ethernet/intel/igc/igc_ptp.c
> +++ b/drivers/net/ethernet/intel/igc/igc_ptp.c
> @@ -123,6 +123,29 @@ static int igc_ptp_settime_i225(struct ptp_clock_info *ptp,
>   static int igc_ptp_feature_enable_i225(struct ptp_clock_info *ptp,
>   				       struct ptp_clock_request *rq, int on)
>   {
> +	struct igc_adapter *igc =
> +		container_of(ptp, struct igc_adapter, ptp_caps);
> +	struct igc_hw *hw = &igc->hw;
> +	unsigned long flags;
> +	u32 tsim;
> +
> +	switch (rq->type) {
> +	case PTP_CLK_REQ_PPS:
> +		spin_lock_irqsave(&igc->tmreg_lock, flags);
> +		tsim = rd32(IGC_TSIM);
> +		if (on)
> +			tsim |= IGC_TSICR_SYS_WRAP;
> +		else
> +			tsim &= ~IGC_TSICR_SYS_WRAP;
> +		igc->pps_sys_wrap_on = !!on;
> +		wr32(IGC_TSIM, tsim);
> +		spin_unlock_irqrestore(&igc->tmreg_lock, flags);
> +		return 0;
> +
> +	default:
> +		break;
> +	}
> +
>   	return -EOPNOTSUPP;
>   }
>   
> @@ -497,6 +520,7 @@ void igc_ptp_init(struct igc_adapter *adapter)
>   		adapter->ptp_caps.gettimex64 = igc_ptp_gettimex64_i225;
>   		adapter->ptp_caps.settime64 = igc_ptp_settime_i225;
>   		adapter->ptp_caps.enable = igc_ptp_feature_enable_i225;
> +		adapter->ptp_caps.pps = 1;
>   		break;
>   	default:
>   		adapter->ptp_clock = NULL;
> @@ -598,7 +622,9 @@ void igc_ptp_reset(struct igc_adapter *adapter)
>   	case igc_i225:
>   		wr32(IGC_TSAUXC, 0x0);
>   		wr32(IGC_TSSDP, 0x0);
> -		wr32(IGC_TSIM, IGC_TSICR_INTERRUPTS);
> +		wr32(IGC_TSIM,
> +		     IGC_TSICR_INTERRUPTS |
> +		     (adapter->pps_sys_wrap_on ? IGC_TSICR_SYS_WRAP : 0));
>   		wr32(IGC_IMS, IGC_IMS_TS);
>   		break;
>   	default:

Otherwise, this looks good.

Reviewed-by: Paul Menzel <pmenzel at molgen.mpg.de>


Kind regards,

Paul


More information about the Intel-wired-lan mailing list