aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9054-amd-xgbe-Fix-Tx_Timestamp_Timeout-error-while-runnin.patch
blob: a21353727f9b8f8c70dc337e5414d745199dbb13 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
From 6f213873c2c360853b6d39774c3c0e3fdcf66261 Mon Sep 17 00:00:00 2001
From: Devang Vyas <devangnayanbhai.vyas@amd.com>
Date: Mon, 20 Jun 2022 18:46:38 +0530
Subject: [PATCH 54/57] amd-xgbe: Fix Tx_Timestamp_Timeout error while running
 ptp4l application

This patch fixes the Tx timestamp timeout error observed while running ptp4l
application because of which PTP synchronization is not achieved. This patch
schedules PTP packet queue when PTP in-progress flag is set and poll for the
XGMAC TXTSC bit to be set. This work thread reads Tx Timestamp registers
when timestamp is captured, convert the value to HW timestamp and pass it to
the network stack.

Signed-off-by: Devang Vyas <devangnayanbhai.vyas@amd.com>
Change-Id: I8d331b1c9bd1eaef36149a323ea789b538cc2cc0
---
 drivers/net/ethernet/amd/xgbe/xgbe-common.h |  2 +
 drivers/net/ethernet/amd/xgbe/xgbe-dev.c    |  7 ++-
 drivers/net/ethernet/amd/xgbe/xgbe-drv.c    | 48 ++++++++++-----------
 3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
index 0b8b1e97d2f9..449f5be26930 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
@@ -333,6 +333,8 @@
 #define MAC_TXSNR			0x0d30
 #define MAC_TXSSR			0x0d34
 
+#define MAC_TXSNR_MASK			GENMASK(30, 0)
+
 #define MAC_QTFCR_INC			4
 #define MAC_MACA_INC			4
 #define MAC_HTR_INC			4
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index e5cc96bc70ad..0252d80f6834 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -1576,15 +1576,14 @@ static u64 xgbe_get_tx_tstamp(struct xgbe_prv_data *pdata)
 
 	if (pdata->vdata->tx_tstamp_workaround) {
 		tx_snr = XGMAC_IOREAD(pdata, MAC_TXSNR);
+		tx_snr = tx_snr & MAC_TXSNR_MASK;
 		tx_ssr = XGMAC_IOREAD(pdata, MAC_TXSSR);
 	} else {
-		tx_ssr = XGMAC_IOREAD(pdata, MAC_TXSSR);
 		tx_snr = XGMAC_IOREAD(pdata, MAC_TXSNR);
+		tx_snr = tx_snr & MAC_TXSNR_MASK;
+		tx_ssr = XGMAC_IOREAD(pdata, MAC_TXSSR);
 	}
 
-	if (XGMAC_GET_BITS(tx_snr, MAC_TXSNR, TXTSSTSMIS))
-		return 0;
-
 	nsec = tx_ssr;
 	nsec *= NSEC_PER_SEC;
 	nsec += tx_snr;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index caea72cddb89..3ed9ff7fdaff 100755
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -479,7 +479,7 @@ static void xgbe_isr_task(struct tasklet_struct *t)
 	struct xgbe_hw_if *hw_if = &pdata->hw_if;
 	struct xgbe_channel *channel;
 	unsigned int dma_isr, dma_ch_isr;
-	unsigned int mac_isr, mac_tssr, mac_mdioisr;
+	unsigned int mac_isr, mac_mdioisr;
 	unsigned int i;
 
 	/* The DMA interrupt status register also reports MAC and MTL
@@ -548,21 +548,6 @@ static void xgbe_isr_task(struct tasklet_struct *t)
 		if (XGMAC_GET_BITS(mac_isr, MAC_ISR, MMCRXIS))
 			hw_if->rx_mmc_int(pdata);
 
-		if (XGMAC_GET_BITS(mac_isr, MAC_ISR, TSIS)) {
-			mac_tssr = XGMAC_IOREAD(pdata, MAC_TSSR);
-
-			netif_dbg(pdata, intr, pdata->netdev,
-				  "MAC_TSSR=%#010x\n", mac_tssr);
-
-			if (XGMAC_GET_BITS(mac_tssr, MAC_TSSR, TXTSC)) {
-				/* Read Tx Timestamp to clear interrupt */
-				pdata->tx_tstamp =
-					hw_if->get_tx_tstamp(pdata);
-				queue_work(pdata->dev_workqueue,
-					   &pdata->tx_tstamp_work);
-			}
-		}
-
 		if (XGMAC_GET_BITS(mac_isr, MAC_ISR, SMI)) {
 			mac_mdioisr = XGMAC_IOREAD(pdata, MAC_MDIOISR);
 
@@ -1470,25 +1455,35 @@ static void xgbe_tx_tstamp(struct work_struct *work)
 						   struct xgbe_prv_data,
 						   tx_tstamp_work);
 	struct skb_shared_hwtstamps hwtstamps;
+	struct sk_buff *skb = pdata->tx_tstamp_skb;
 	u64 nsec;
 	unsigned long flags;
+	u32 value;
 
-	spin_lock_irqsave(&pdata->tstamp_lock, flags);
-	if (!pdata->tx_tstamp_skb)
-		goto unlock;
+	if (readl_poll_timeout_atomic(pdata->xgmac_regs + MAC_TSSR,
+				value, value & (1 << MAC_TSSR_TXTSC_INDEX), 100, 10000)) {
+                dev_kfree_skb_any(pdata->tx_tstamp_skb);
+                pdata->tx_tstamp_skb = NULL;
+		return;
+	}
 
-	if (pdata->tx_tstamp) {
-		nsec = timecounter_cyc2time(&pdata->tstamp_tc,
-					    pdata->tx_tstamp);
+	pdata->tx_tstamp = pdata->hw_if.get_tx_tstamp(pdata);
 
-		memset(&hwtstamps, 0, sizeof(hwtstamps));
-		hwtstamps.hwtstamp = ns_to_ktime(nsec);
-		skb_tstamp_tx(pdata->tx_tstamp_skb, &hwtstamps);
+	spin_lock_irqsave(&pdata->tstamp_lock, flags);
+	if (!pdata->tx_tstamp_skb) {
+		dev_kfree_skb_any(pdata->tx_tstamp_skb);
+		pdata->tx_tstamp_skb = NULL;
+		goto unlock;
 	}
 
-	dev_kfree_skb_any(pdata->tx_tstamp_skb);
+	nsec = timecounter_cyc2time(&pdata->tstamp_tc,
+			pdata->tx_tstamp);
 
+	memset(&hwtstamps, 0, sizeof(hwtstamps));
+	hwtstamps.hwtstamp = ns_to_ktime(nsec);
 	pdata->tx_tstamp_skb = NULL;
+	skb_tstamp_tx(skb, &hwtstamps);
+	dev_kfree_skb_any(skb);
 
 unlock:
 	spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
@@ -1653,6 +1648,7 @@ static void xgbe_prep_tx_tstamp(struct xgbe_prv_data *pdata,
 		} else {
 			pdata->tx_tstamp_skb = skb_get(skb);
 			skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+			queue_work(pdata->dev_workqueue, &pdata->tx_tstamp_work);
 		}
 		spin_unlock_irqrestore(&pdata->tstamp_lock, flags);
 	}
-- 
2.37.3