File Index
Files and directories
Sign in
FILE

xgbe-hwtstamp.c

File preview with syntax highlighting.

linux-6.19.14/drivers/net/ethernet/amd/xgbe/xgbe-hwtstamp.c C
  1// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause)
  2/*
  3 * Copyright (c) 2014-2025, Advanced Micro Devices, Inc.
  4 * Copyright (c) 2014, Synopsys, Inc.
  5 * All rights reserved
  6 *
  7 * Author: Raju Rangoju <Raju.Rangoju@amd.com>
  8 */
  9
 10#include "xgbe.h"
 11#include "xgbe-common.h"
 12
 13void xgbe_update_tstamp_time(struct xgbe_prv_data *pdata,
 14			     unsigned int sec, unsigned int nsec)
 15{
 16	int count;
 17
 18	/* Set the time values and tell the device */
 19	XGMAC_IOWRITE(pdata, MAC_STSUR, sec);
 20	XGMAC_IOWRITE(pdata, MAC_STNUR, nsec);
 21
 22	/* issue command to update the system time value */
 23	XGMAC_IOWRITE(pdata, MAC_TSCR,
 24		      XGMAC_IOREAD(pdata, MAC_TSCR) |
 25		      (1 << MAC_TSCR_TSUPDT_INDEX));
 26
 27	/* Wait for the time adjust/update to complete */
 28	count = 10000;
 29	while (--count && XGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSUPDT))
 30		udelay(5);
 31
 32	if (count < 0)
 33		netdev_err(pdata->netdev,
 34			   "timed out updating system timestamp\n");
 35}
 36
 37void xgbe_update_tstamp_addend(struct xgbe_prv_data *pdata,
 38			       unsigned int addend)
 39{
 40	unsigned int count = 10000;
 41
 42	/* Set the addend register value and tell the device */
 43	XGMAC_IOWRITE(pdata, MAC_TSAR, addend);
 44	XGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSADDREG, 1);
 45
 46	/* Wait for addend update to complete */
 47	while (--count && XGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSADDREG))
 48		udelay(5);
 49
 50	if (!count)
 51		netdev_err(pdata->netdev,
 52			   "timed out updating timestamp addend register\n");
 53}
 54
 55void xgbe_set_tstamp_time(struct xgbe_prv_data *pdata, unsigned int sec,
 56			  unsigned int nsec)
 57{
 58	unsigned int count = 10000;
 59
 60	/* Set the time values and tell the device */
 61	XGMAC_IOWRITE(pdata, MAC_STSUR, sec);
 62	XGMAC_IOWRITE(pdata, MAC_STNUR, nsec);
 63	XGMAC_IOWRITE_BITS(pdata, MAC_TSCR, TSINIT, 1);
 64
 65	/* Wait for time update to complete */
 66	while (--count && XGMAC_IOREAD_BITS(pdata, MAC_TSCR, TSINIT))
 67		udelay(5);
 68
 69	if (!count)
 70		netdev_err(pdata->netdev, "timed out initializing timestamp\n");
 71}
 72
 73u64 xgbe_get_tstamp_time(struct xgbe_prv_data *pdata)
 74{
 75	u64 nsec;
 76
 77	nsec = XGMAC_IOREAD(pdata, MAC_STSR);
 78	nsec *= NSEC_PER_SEC;
 79	nsec += XGMAC_IOREAD(pdata, MAC_STNR);
 80
 81	return nsec;
 82}
 83
 84u64 xgbe_get_tx_tstamp(struct xgbe_prv_data *pdata)
 85{
 86	unsigned int tx_snr, tx_ssr;
 87	u64 nsec;
 88
 89	if (pdata->vdata->tx_tstamp_workaround) {
 90		tx_snr = XGMAC_IOREAD(pdata, MAC_TXSNR);
 91		tx_ssr = XGMAC_IOREAD(pdata, MAC_TXSSR);
 92	} else {
 93		tx_ssr = XGMAC_IOREAD(pdata, MAC_TXSSR);
 94		tx_snr = XGMAC_IOREAD(pdata, MAC_TXSNR);
 95	}
 96
 97	if (XGMAC_GET_BITS(tx_snr, MAC_TXSNR, TXTSSTSMIS))
 98		return 0;
 99
100	nsec = tx_ssr;
101	nsec *= NSEC_PER_SEC;
102	nsec += tx_snr;
103
104	return nsec;
105}
106
107void xgbe_get_rx_tstamp(struct xgbe_packet_data *packet,
108			struct xgbe_ring_desc *rdesc)
109{
110	u64 nsec;
111
112	if (XGMAC_GET_BITS_LE(rdesc->desc3, RX_CONTEXT_DESC3, TSA) &&
113	    !XGMAC_GET_BITS_LE(rdesc->desc3, RX_CONTEXT_DESC3, TSD)) {
114		nsec = le32_to_cpu(rdesc->desc1);
115		nsec *= NSEC_PER_SEC;
116		nsec += le32_to_cpu(rdesc->desc0);
117		if (nsec != 0xffffffffffffffffULL) {
118			packet->rx_tstamp = nsec;
119			XGMAC_SET_BITS(packet->attributes, RX_PACKET_ATTRIBUTES,
120				       RX_TSTAMP, 1);
121		}
122	}
123}
124
125void xgbe_config_tstamp(struct xgbe_prv_data *pdata, unsigned int mac_tscr)
126{
127	unsigned int value = 0;
128
129	value = XGMAC_IOREAD(pdata, MAC_TSCR);
130	value |= mac_tscr;
131	XGMAC_IOWRITE(pdata, MAC_TSCR, value);
132}
133
134void xgbe_tx_tstamp(struct work_struct *work)
135{
136	struct xgbe_prv_data *pdata = container_of(work,
137						   struct xgbe_prv_data,
138						   tx_tstamp_work);
139	struct skb_shared_hwtstamps hwtstamps;
140	unsigned long flags;
141
142	spin_lock_irqsave(&pdata->tstamp_lock, flags);
143	if (!pdata->tx_tstamp_skb)
144		goto unlock;
145
146	if (pdata->tx_tstamp) {
147		memset(&hwtstamps, 0, sizeof(hwtstamps));
148		hwtstamps.hwtstamp = ns_to_ktime(pdata->tx_tstamp);
149		skb_tstamp_tx(pdata->tx_tstamp_skb, &hwtstamps);
150	}
151
152	dev_kfree_skb_any(pdata->tx_tstamp_skb);
153
154	pdata->tx_tstamp_skb = NULL;
155
156unlock:
157	spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
158}
159
160int xgbe_get_hwtstamp_settings(struct net_device *netdev,
161			       struct kernel_hwtstamp_config *config)
162{
163	struct xgbe_prv_data *pdata = netdev_priv(netdev);
164
165	*config = pdata->tstamp_config;
166
167	return 0;
168}
169
170int xgbe_set_hwtstamp_settings(struct net_device *netdev,
171			       struct kernel_hwtstamp_config *config,
172			       struct netlink_ext_ack *extack)
173{
174	struct xgbe_prv_data *pdata = netdev_priv(netdev);
175	unsigned int mac_tscr = 0;
176
177	switch (config->tx_type) {
178	case HWTSTAMP_TX_OFF:
179		break;
180
181	case HWTSTAMP_TX_ON:
182		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
183		break;
184
185	default:
186		return -ERANGE;
187	}
188
189	switch (config->rx_filter) {
190	case HWTSTAMP_FILTER_NONE:
191		break;
192
193	case HWTSTAMP_FILTER_NTP_ALL:
194	case HWTSTAMP_FILTER_ALL:
195		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENALL, 1);
196		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
197		break;
198
199		/* PTP v2, UDP, any kind of event packet */
200	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
201		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
202		fallthrough;    /* to PTP v1, UDP, any kind of event packet */
203	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
204		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
205		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
206		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, SNAPTYPSEL, 1);
207		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
208		break;
209		/* PTP v2, UDP, Sync packet */
210	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
211		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
212		fallthrough;    /* to PTP v1, UDP, Sync packet */
213	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
214		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
215		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
216		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
217		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
218		break;
219
220		/* PTP v2, UDP, Delay_req packet */
221	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
222		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
223		fallthrough;    /* to PTP v1, UDP, Delay_req packet */
224	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
225		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
226		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
227		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
228		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSMSTRENA, 1);
229		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
230		break;
231
232		/* 802.AS1, Ethernet, any kind of event packet */
233	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
234		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, AV8021ASMEN, 1);
235		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, SNAPTYPSEL, 1);
236		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
237		break;
238
239		/* 802.AS1, Ethernet, Sync packet */
240	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
241		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, AV8021ASMEN, 1);
242		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
243		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
244		break;
245
246		/* 802.AS1, Ethernet, Delay_req packet */
247	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
248		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, AV8021ASMEN, 1);
249		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSMSTRENA, 1);
250		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
251		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
252		break;
253
254		/* PTP v2/802.AS1, any layer, any kind of event packet */
255	case HWTSTAMP_FILTER_PTP_V2_EVENT:
256		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
257		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1);
258		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
259		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
260		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, SNAPTYPSEL, 1);
261		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
262		break;
263
264		/* PTP v2/802.AS1, any layer, Sync packet */
265	case HWTSTAMP_FILTER_PTP_V2_SYNC:
266		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
267		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1);
268		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
269		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
270		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
271		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
272		break;
273
274		/* PTP v2/802.AS1, any layer, Delay_req packet */
275	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
276		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSVER2ENA, 1);
277		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPENA, 1);
278		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV4ENA, 1);
279		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSIPV6ENA, 1);
280		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSMSTRENA, 1);
281		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSEVNTENA, 1);
282		XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
283		break;
284
285	default:
286		return -ERANGE;
287	}
288
289	xgbe_config_tstamp(pdata, mac_tscr);
290
291	pdata->tstamp_config = *config;
292
293	return 0;
294}
295
296void xgbe_prep_tx_tstamp(struct xgbe_prv_data *pdata,
297			 struct sk_buff *skb,
298			 struct xgbe_packet_data *packet)
299{
300	unsigned long flags;
301
302	if (XGMAC_GET_BITS(packet->attributes, TX_PACKET_ATTRIBUTES, PTP)) {
303		spin_lock_irqsave(&pdata->tstamp_lock, flags);
304		if (pdata->tx_tstamp_skb) {
305			/* Another timestamp in progress, ignore this one */
306			XGMAC_SET_BITS(packet->attributes,
307				       TX_PACKET_ATTRIBUTES, PTP, 0);
308		} else {
309			pdata->tx_tstamp_skb = skb_get(skb);
310			skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
311		}
312		spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
313	}
314
315	skb_tx_timestamp(skb);
316}
317
318int xgbe_init_ptp(struct xgbe_prv_data *pdata)
319{
320	unsigned int mac_tscr = 0;
321	struct timespec64 now;
322	u64 dividend;
323
324	/* Register Settings to be done based on the link speed. */
325	switch (pdata->phy.speed) {
326	case SPEED_1000:
327		XGMAC_IOWRITE(pdata, MAC_TICNR, MAC_TICNR_1G_INITVAL);
328		XGMAC_IOWRITE(pdata, MAC_TECNR, MAC_TECNR_1G_INITVAL);
329		break;
330	case SPEED_2500:
331	case SPEED_10000:
332		XGMAC_IOWRITE_BITS(pdata, MAC_TICSNR, TSICSNS,
333				   MAC_TICSNR_10G_INITVAL);
334		XGMAC_IOWRITE(pdata, MAC_TECNR, MAC_TECNR_10G_INITVAL);
335		XGMAC_IOWRITE_BITS(pdata, MAC_TECSNR, TSECSNS,
336				   MAC_TECSNR_10G_INITVAL);
337		break;
338	case SPEED_UNKNOWN:
339	default:
340		break;
341	}
342
343	/* Enable IEEE1588 PTP clock. */
344	XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSENA, 1);
345
346	/* Overwrite earlier timestamps */
347	XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TXTSSTSM, 1);
348
349	/* Set one nano-second accuracy */
350	XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSCTRLSSR, 1);
351
352	/* Set fine timestamp update */
353	XGMAC_SET_BITS(mac_tscr, MAC_TSCR, TSCFUPDT, 1);
354
355	xgbe_config_tstamp(pdata, mac_tscr);
356
357	/* Exit if timestamping is not enabled */
358	if (!XGMAC_GET_BITS(mac_tscr, MAC_TSCR, TSENA))
359		return -EOPNOTSUPP;
360
361	if (pdata->vdata->tstamp_ptp_clock_freq) {
362		/* Initialize time registers based on
363		 * 125MHz PTP Clock Frequency
364		 */
365		XGMAC_IOWRITE_BITS(pdata, MAC_SSIR, SSINC,
366				   XGBE_V2_TSTAMP_SSINC);
367		XGMAC_IOWRITE_BITS(pdata, MAC_SSIR, SNSINC,
368				   XGBE_V2_TSTAMP_SNSINC);
369	} else {
370		/* Initialize time registers based on
371		 * 50MHz PTP Clock Frequency
372		 */
373		XGMAC_IOWRITE_BITS(pdata, MAC_SSIR, SSINC, XGBE_TSTAMP_SSINC);
374		XGMAC_IOWRITE_BITS(pdata, MAC_SSIR, SNSINC, XGBE_TSTAMP_SNSINC);
375	}
376
377	/* Calculate the addend:
378	 *   addend = 2^32 / (PTP ref clock / (PTP clock based on SSINC))
379	 *          = (2^32 * (PTP clock based on SSINC)) / PTP ref clock
380	 */
381	if (pdata->vdata->tstamp_ptp_clock_freq)
382		dividend = XGBE_V2_PTP_ACT_CLK_FREQ;
383	else
384		dividend = XGBE_PTP_ACT_CLK_FREQ;
385
386	dividend = (u64)(dividend << 32);
387	pdata->tstamp_addend = div_u64(dividend, pdata->ptpclk_rate);
388
389	xgbe_update_tstamp_addend(pdata, pdata->tstamp_addend);
390
391	dma_wmb();
392	/* initialize system time */
393	ktime_get_real_ts64(&now);
394
395	/* lower 32 bits of tv_sec are safe until y2106 */
396	xgbe_set_tstamp_time(pdata, (u32)now.tv_sec, now.tv_nsec);
397
398	return 0;
399}
~/ Read-only file preview.