aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-5.15/9044-amd-xgbe-RX-Adaptation-support-for-V3000.patch
blob: a4f4a06eb64ad00b883c4479d3212d32560b644d (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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
From f820ae13017b4926cfadd644bfd2f1f31476d284 Mon Sep 17 00:00:00 2001
From: Raju Rangoju <Raju.Rangoju@amd.com>
Date: Mon, 11 Apr 2022 19:01:46 +0530
Subject: [PATCH 44/48] amd-xgbe: RX-Adaptation support for V3000

Change-Id: I2329b9414374ab335bc768c1b319ae1c0a55cefc
Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com>
Signed-off-by: rgaridap <Ramesh.Garidapuri@amd.com>
---
 drivers/net/ethernet/amd/xgbe/xgbe-common.h |  38 +++++
 drivers/net/ethernet/amd/xgbe/xgbe-pci.c    |   1 +
 drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c | 155 +++++++++++++++++++-
 drivers/net/ethernet/amd/xgbe/xgbe.h        |   5 +
 4 files changed, 191 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-common.h b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
index 466273b22f0a..0b8b1e97d2f9 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-common.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-common.h
@@ -1285,6 +1285,24 @@
 #define MDIO_PMA_RX_CTRL1		0x8051
 #endif
 
+#ifndef	MDIO_PMA_RX_LSTS
+#define	MDIO_PMA_RX_LSTS		0x018020
+#endif
+
+#ifndef	MDIO_PMA_RX_EQ_CTRL4
+//#define	MDIO_PMA_RX_EQ_CTRL4		0x003C
+#define	MDIO_PMA_RX_EQ_CTRL4		0x0001805C
+#endif
+
+#ifndef MDIO_PMA_MP_MISC_STS
+#define MDIO_PMA_MP_MISC_STS            0x0078
+#endif
+
+#ifndef	MDIO_PMA_PHY_RX_EQ_CEU
+//#define	MDIO_PMA_PHY_RX_EQ_CEU		0x800E
+#define	MDIO_PMA_PHY_RX_EQ_CEU		0x1800E
+#endif
+
 #ifndef MDIO_PCS_DIG_CTRL
 #define MDIO_PCS_DIG_CTRL		0x8000
 #endif
@@ -1395,6 +1413,26 @@
 #define XGBE_PMA_RX_RST_0_RESET_ON	0x10
 #define XGBE_PMA_RX_RST_0_RESET_OFF	0x00
 
+#define	XGBE_PMA_RX_SIG_DET_0_MASK	BIT(4)
+#define	XGBE_PMA_RX_SIG_DET_0_ENABLE	BIT(4)
+#define	XGBE_PMA_RX_SIG_DET_0_DISABLE	0x0000
+
+#define	XGBE_PMA_RX_VALID_0_MASK	BIT(12)
+#define	XGBE_PMA_RX_VALID_0_ENABLE	BIT(12)
+#define	XGBE_PMA_RX_VALID_0_DISABLE	0x0000
+
+#define	XGBE_PMA_RX_AD_REQ_MASK		BIT(12)
+#define	XGBE_PMA_RX_AD_REQ_ENABLE	BIT(12)
+#define	XGBE_PMA_RX_AD_REQ_DISABLE	0x0000
+
+#define XGBE_PMA_RX_ADPT_ACK_MASK       BIT(12)
+#define XGBE_PMA_RX_ADPT_ACK            BIT(12)
+
+#define	XGBE_PMA_CFF_UPDTM1_VLD		BIT(8)
+#define XGBE_PMA_CFF_UPDT0_VLD		BIT(9)
+#define XGBE_PMA_CFF_UPDT1_VLD		BIT(10)
+#define XGBE_PMA_CFF_UPDT_MASK		(XGBE_PMA_CFF_UPDTM1_VLD | XGBE_PMA_CFF_UPDT0_VLD | XGBE_PMA_CFF_UPDT1_VLD)
+
 #define XGBE_PMA_PLL_CTRL_MASK		BIT(15)
 #define XGBE_PMA_PLL_CTRL_ENABLE	BIT(15)
 #define XGBE_PMA_PLL_CTRL_DISABLE	0x0000
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
index 4da4924e7254..0f2ac86ff904 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-pci.c
@@ -288,6 +288,7 @@ static int xgbe_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
 		/* Yellow Carp devices do not need rrc */
 		pdata->vdata->enable_rrc = 0;
+		pdata->vdata->is_yc = 1;
 		dev_dbg(dev, "Disabling the RRC on Yellow carp devices\n");
 	} else {
 		pdata->xpcs_window_def_reg = PCS_V2_WINDOW_DEF;
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
index b66dae94bd54..f0cb4acbf231 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-phy-v2.c
@@ -387,6 +387,10 @@ struct xgbe_phy_data {
 static DEFINE_MUTEX(xgbe_phy_comm_lock);
 
 static enum xgbe_an_mode xgbe_phy_an_mode(struct xgbe_prv_data *pdata);
+static void xgbe_phy_rrc(struct xgbe_prv_data *pdata);
+static void xgbe_phy_set_mode(struct xgbe_prv_data *pdata, enum xgbe_mode mode);
+static void xgbe_phy_kr_mode(struct xgbe_prv_data *pdata);
+static void xgbe_phy_sfi_mode(struct xgbe_prv_data *pdata);
 
 static int xgbe_phy_i2c_xfer(struct xgbe_prv_data *pdata,
 			     struct xgbe_i2c_op *i2c_op)
@@ -2096,15 +2100,97 @@ static void xgbe_phy_pll_ctrl(struct xgbe_prv_data *pdata, bool enable)
 	 }
 }
 
+static void xgbe_phy_rx_adaptation(struct xgbe_prv_data *pdata)
+{
+	/*
+	 * step 1: Check for RX_VALID && LF_SIGDET
+	if (yes) {
+		step 2: force PCS to send RX_ADAPT Req to PHY
+		and then,
+		step 3: wait for RX_ADAPT ACK from the PHY
+		if (Yes) {
+			step4: Check for Block lock
+			if (yes)
+				return;
+			else
+				step 5: do mode set
+		} else
+			do mode set
+	} else
+		issue rrc
+	*/
+
+	int reg;
+	pdata->count = 0;
+
+rx_adapt_reinit:
+	reg = XMDIO_READ_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_LSTS,
+			      (XGBE_PMA_RX_SIG_DET_0_MASK | XGBE_PMA_RX_VALID_0_MASK));
+	netif_dbg(pdata, link, pdata->netdev, "%s MDIO_PMA_RX_LSTS reg 0x%x\n", __func__, reg);
+
+	 /* step 1: Check for RX_VALID && LF_SIGDET */
+	if ((reg & XGBE_PMA_RX_VALID_0_MASK) && (reg & XGBE_PMA_RX_SIG_DET_0_MASK)) {
+		reg = XMDIO_READ_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_EQ_CTRL4, 0xffffffff);
+		netif_dbg(pdata, link, pdata->netdev, "%s MDIO_PMA_RX_EQ_CTRL4 current data 0x%x\n",
+				__func__, reg);
+
+		/* step 2: force PCS to send RX_ADAPT Req to PHY */
+		XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_EQ_CTRL4,
+				 XGBE_PMA_RX_AD_REQ_MASK, XGBE_PMA_RX_AD_REQ_ENABLE);
+
+		msleep(200);
+
+		/* step 3: wait for RX_ADAPT ACK from the PHY */
+		reg = XMDIO_READ_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_PHY_RX_EQ_CEU, 0xffffffff /*XGBE_PMA_CFF_UPDT_MASK*/);
+
+		/* Clear the RX_AD_REQ bit */
+		XMDIO_WRITE_BITS(pdata, MDIO_MMD_PMAPMD, MDIO_PMA_RX_EQ_CTRL4,
+				XGBE_PMA_RX_AD_REQ_MASK, XGBE_PMA_RX_AD_REQ_DISABLE);
+
+		netif_dbg(pdata, link, pdata->netdev, "%s MDIO_PMA_PHY_RX_EQ_CEU ACK is %s\n",
+				__func__, ((reg & XGBE_PMA_CFF_UPDT_MASK) == XGBE_PMA_CFF_UPDT_MASK) ? "SET" : "NOT_SET");
+
+		if ((reg & XGBE_PMA_CFF_UPDT_MASK) == XGBE_PMA_CFF_UPDT_MASK)
+		{
+			/*step 4: Check for Block lock */
+
+			/* Link status is latched low, so read once to clear
+			 * and then read again to get current state
+			 */
+			reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
+			reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
+			if (reg & MDIO_STAT1_LSTATUS) {
+				/* If the block lock is found, declare the link up */
+				netif_dbg(pdata, link, pdata->netdev, "%s block_lock done\n", __func__);
+				pdata->rx_adapt_done = 1;
+				pdata->mode_set = 0;
+				return;
+			} else {
+				struct xgbe_phy_data *phy_data = pdata->phy_data;
+				xgbe_phy_set_mode(pdata, phy_data->cur_mode);
+			}
+		} else {
+			struct xgbe_phy_data *phy_data = pdata->phy_data;
+			xgbe_phy_set_mode(pdata, phy_data->cur_mode);
+		}
+	} else {
+		netif_dbg(pdata, link, pdata->netdev, "%s either RX_VALID or LF_SIGDET is not set, issuing rrc\n",__func__);
+		xgbe_phy_rrc(pdata);
+		if (pdata->count++ >= 5)
+			return;
+		goto rx_adapt_reinit;
+	}
+}
+
 static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata,
 					unsigned int cmd, unsigned int sub_cmd)
 {
 	unsigned int s0 = 0;
 	unsigned int wait;
+	struct xgbe_phy_data *phy_data = pdata->phy_data;
 
 	/* Disable PLL re-initialization during FW command processing */
 	xgbe_phy_pll_ctrl(pdata, false);
-
 	/* Log if a previous command did not complete */
 	if (XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS)) {
 		netif_dbg(pdata, link, pdata->netdev,
@@ -2125,7 +2211,7 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata,
 	wait = XGBE_RATECHANGE_COUNT;
 	while (wait--) {
 		if (!XP_IOREAD_BITS(pdata, XP_DRIVER_INT_RO, STATUS))
-			goto reenable_pll;
+			goto do_rx_adaptation;
 
 		usleep_range(1000, 2000);
 	}
@@ -2135,10 +2221,19 @@ static void xgbe_phy_perform_ratechange(struct xgbe_prv_data *pdata,
 
 	/* Reset on error */
 	xgbe_phy_rx_reset(pdata);
+	goto reenable_pll;
+
+do_rx_adaptation:
+	dev_dbg(pdata->dev, "%s  en_rx_adap %d sfp_cable %d\n", __func__, pdata->en_rx_adap, phy_data->sfp_cable);
+	if (pdata->en_rx_adap && (((cmd == 4) || (cmd == 3)) && (sub_cmd == 1))) {
+		netif_dbg(pdata, link, pdata->netdev, "%s Enabling RX adaptation\n", __func__);
+		pdata->mode_set = 1;
+		xgbe_phy_rx_adaptation(pdata);
+	}
 
 reenable_pll:
 	/* Enable PLL re-initialization, not needed for phy_poweroff (0,0) */
-	if (cmd != 0)
+	if ((cmd != 0) || (cmd != 5))
 		xgbe_phy_pll_ctrl(pdata, true);
 }
 
@@ -2171,6 +2266,8 @@ static void xgbe_phy_sfi_mode(struct xgbe_prv_data *pdata)
 	/* 10G/SFI */
 	if (phy_data->sfp_cable != XGBE_SFP_CABLE_PASSIVE) {
 		xgbe_phy_perform_ratechange(pdata, 3, 0);
+	} else if ((phy_data->sfp_cable == XGBE_SFP_CABLE_PASSIVE) && (pdata->en_rx_adap)) {
+		xgbe_phy_perform_ratechange(pdata, 3, 1);
 	} else {
 		if (phy_data->sfp_cable_len <= 1)
 			xgbe_phy_perform_ratechange(pdata, 3, 1);
@@ -2178,8 +2275,8 @@ static void xgbe_phy_sfi_mode(struct xgbe_prv_data *pdata)
 			xgbe_phy_perform_ratechange(pdata, 3, 2);
 		else
 			xgbe_phy_perform_ratechange(pdata, 3, 3);
-	}
 
+	}
 	phy_data->cur_mode = XGBE_MODE_SFI;
 
 	netif_dbg(pdata, link, pdata->netdev, "10GbE SFI mode set\n");
@@ -2234,7 +2331,10 @@ static void xgbe_phy_kr_mode(struct xgbe_prv_data *pdata)
 	xgbe_phy_set_redrv_mode(pdata);
 
 	/* 10G/KR */
-	xgbe_phy_perform_ratechange(pdata, 4, 0);
+	if (pdata->en_rx_adap) {
+		xgbe_phy_perform_ratechange(pdata, 4, 1);
+	} else
+		xgbe_phy_perform_ratechange(pdata, 4, 0);
 
 	phy_data->cur_mode = XGBE_MODE_KR;
 
@@ -2751,7 +2851,24 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
 	 */
 	reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
 	reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
-	if (reg & MDIO_STAT1_LSTATUS)
+
+	if (pdata->en_rx_adap) {
+		if (reg & MDIO_STAT1_LSTATUS) {
+			if (pdata->rx_adapt_done)
+				return 1;
+			else
+				xgbe_phy_rx_adaptation(pdata);
+		} else {
+			if (pdata->mode_set)
+				xgbe_phy_rx_adaptation(pdata);
+			else {
+				pdata->mode_set = 0;
+				pdata->rx_adapt_done = 0;
+				xgbe_phy_set_mode(pdata, phy_data->cur_mode);
+			}
+		}
+
+	} else if (reg & MDIO_STAT1_LSTATUS)
 		return 1;
 
 	if (pdata->phy.autoneg == AUTONEG_ENABLE &&
@@ -3351,7 +3468,22 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
 	/* Backplane support */
 	case XGBE_PORT_MODE_BACKPLANE:
 		XGBE_SET_SUP(lks, Autoneg);
-		fallthrough;
+		XGBE_SET_SUP(lks, Pause);
+		XGBE_SET_SUP(lks, Asym_Pause);
+		XGBE_SET_SUP(lks, Backplane);
+		if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000) {
+			XGBE_SET_SUP(lks, 1000baseKX_Full);
+			phy_data->start_mode = XGBE_MODE_KX_1000;
+		}
+		if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) {
+			XGBE_SET_SUP(lks, 10000baseKR_Full);
+			if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE)
+				XGBE_SET_SUP(lks, 10000baseR_FEC);
+			phy_data->start_mode = XGBE_MODE_KR;
+		}
+
+		phy_data->phydev_mode = XGBE_MDIO_MODE_NONE;
+		break;
 	case XGBE_PORT_MODE_BACKPLANE_NO_AUTONEG:
 		XGBE_SET_SUP(lks, Pause);
 		XGBE_SET_SUP(lks, Asym_Pause);
@@ -3365,6 +3497,8 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
 			if (pdata->fec_ability & MDIO_PMA_10GBR_FECABLE_ABLE)
 				XGBE_SET_SUP(lks, 10000baseR_FEC);
 			phy_data->start_mode = XGBE_MODE_KR;
+			if (pdata->vdata->is_yc)
+				pdata->en_rx_adap = 1;
 		}
 
 		phy_data->phydev_mode = XGBE_MDIO_MODE_NONE;
@@ -3454,6 +3588,8 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
 		if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) {
 			XGBE_SET_SUP(lks, 10000baseT_Full);
 			phy_data->start_mode = XGBE_MODE_KR;
+			if (pdata->vdata->is_yc)
+				pdata->en_rx_adap = 1;
 		}
 
 		phy_data->phydev_mode = XGBE_MDIO_MODE_CL45;
@@ -3488,8 +3624,11 @@ static int xgbe_phy_init(struct xgbe_prv_data *pdata)
 			phy_data->start_mode = XGBE_MODE_SGMII_100;
 		if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_1000)
 			phy_data->start_mode = XGBE_MODE_SGMII_1000;
-		if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000)
+		if (phy_data->port_speeds & XGBE_PHY_PORT_SPEED_10000) {
 			phy_data->start_mode = XGBE_MODE_SFI;
+			if (pdata->vdata->is_yc)
+				pdata->en_rx_adap = 1;
+		}
 
 		phy_data->phydev_mode = XGBE_MDIO_MODE_CL22;
 
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index 8a5e0c68bc43..1ee48f3b9df5 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -1014,6 +1014,7 @@ struct xgbe_version_data {
 	unsigned int rx_desc_prefetch;
 	unsigned int an_cdr_workaround;
 	unsigned int enable_rrc;
+	unsigned int is_yc;
 };
 
 struct xgbe_prv_data {
@@ -1284,6 +1285,10 @@ struct xgbe_prv_data {
 
 	bool debugfs_an_cdr_workaround;
 	bool debugfs_an_cdr_track_early;
+	bool en_rx_adap;
+	int count;
+	bool rx_adapt_done;
+	bool mode_set;
 };
 
 /* Function prototypes*/
-- 
2.27.0