summaryrefslogtreecommitdiff
path: root/scripts/package-build/linux-kernel/patches/kernel/0003-Kernel-T8914-add-support-for-2.5G-pluggables-on-BCM5.patch
blob: 35539c6d00ef9586df24a55ee8e8f1781a8b9ed8 (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
From 95190cc11737b35b62e92de37d7761370909d1b1 Mon Sep 17 00:00:00 2001
From: Christian Breunig <christian@breunig.cc>
Date: Thu, 25 Jun 2026 17:06:39 +0200
Subject: [PATCH] Kernel: T8914: add support for 2.5G pluggables on BCM57810S

Add the well-known JAMESMTL kernel module patch for bnx2x to advertise 2.5Gbit/s
capabilities on Broadcom NetXtreme2-X cards with BCM57810S chipset.

This is useful for ISP GPON access networks that use 2.5Gbit/s pluggables and
need the NIC to negotiate beyond 1000baseT/Full, avoiding the 940Mbit/s
practical cap on overprovisioned 1G services.

References:
* https://hack-gpon.org/broadcom-57810s/
* https://github.com/JAMESMTL/snippets/blob/dceb2fee74d80c66d/bnx2x/patches/bnx2x_warpcore_8727_2_5g_sgmii_txfault.patch
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x.h   |  1 +
 .../net/ethernet/broadcom/bnx2x/bnx2x_link.c  | 54 +++++++++++++++++--
 .../net/ethernet/broadcom/bnx2x/bnx2x_main.c  |  6 +++
 .../net/ethernet/broadcom/bnx2x/bnx2x_reg.h   |  3 +-
 4 files changed, 58 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 9580ab83d387..e22a832936c3 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1593,6 +1593,7 @@ struct bnx2x {
 	uint			num_ethernet_queues;
 	uint			num_cnic_queues;
 	int			disable_tpa;
+	int			mask_tx_fault;
 
 	u32			rx_mode;
 #define BNX2X_RX_MODE_NONE		0
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
index ea310057fe3a..3fa0cf96da84 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
@@ -151,6 +151,7 @@ typedef int (*read_sfp_module_eeprom_func_p)(struct bnx2x_phy *phy,
 
 #define SFP_EEPROM_CON_TYPE_ADDR		0x2
 	#define SFP_EEPROM_CON_TYPE_VAL_UNKNOWN	0x0
+	#define SFP_EEPROM_CON_TYPE_VAL_SC	0x1
 	#define SFP_EEPROM_CON_TYPE_VAL_LC	0x7
 	#define SFP_EEPROM_CON_TYPE_VAL_COPPER	0x21
 	#define SFP_EEPROM_CON_TYPE_VAL_RJ45	0x22
@@ -4210,6 +4211,16 @@ static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
 					 0x1000);
 		DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n");
 	} else {
+		/* Note that 2.5G works only when used with 1G advertisment */
+		if (fiber_mode && (phy->req_line_speed == SPEED_2500) &&
+			(phy->speed_cap_mask &
+			 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
+			  PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))) {
+			bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
+				MDIO_WC_REG_SERDESDIGITAL_MISC1,
+					0x6010);
+		}
+
 		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
 				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
 		val16 &= 0xcebf;
@@ -4220,6 +4231,7 @@ static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
 			val16 |= 0x2000;
 			break;
 		case SPEED_1000:
+		case SPEED_2500:
 			val16 |= 0x0040;
 			break;
 		default:
@@ -8174,6 +8186,7 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
 		break;
 	}
 	case SFP_EEPROM_CON_TYPE_VAL_UNKNOWN:
+	case SFP_EEPROM_CON_TYPE_VAL_SC:
 	case SFP_EEPROM_CON_TYPE_VAL_LC:
 	case SFP_EEPROM_CON_TYPE_VAL_RJ45:
 		check_limiting_mode = 1;
@@ -8184,7 +8197,8 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
 		    (val[SFP_EEPROM_1G_COMP_CODE_ADDR] != 0)) {
 			DP(NETIF_MSG_LINK, "1G SFP module detected\n");
 			phy->media_type = ETH_PHY_SFP_1G_FIBER;
-			if (phy->req_line_speed != SPEED_1000) {
+			if ((phy->req_line_speed != SPEED_1000) &&
+				(phy->req_line_speed != SPEED_2500)) {
 				u8 gport = params->port;
 				phy->req_line_speed = SPEED_1000;
 				if (!CHIP_IS_E1x(bp)) {
@@ -9238,6 +9252,7 @@ static void bnx2x_8727_config_speed(struct bnx2x_phy *phy,
 	u16 tmp1, val;
 	/* Set option 1G speed */
 	if ((phy->req_line_speed == SPEED_1000) ||
+		(phy->req_line_speed == SPEED_2500) ||
 	    (phy->media_type == ETH_PHY_SFP_1G_FIBER)) {
 		DP(NETIF_MSG_LINK, "Setting 1G force\n");
 		bnx2x_cl45_write(bp, phy,
@@ -9247,6 +9262,22 @@ static void bnx2x_8727_config_speed(struct bnx2x_phy *phy,
 		bnx2x_cl45_read(bp, phy,
 				MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
 		DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
+		if ((phy->req_line_speed == SPEED_2500) &&
+			(phy->speed_cap_mask &
+			(PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
+			 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))) {
+			bnx2x_cl45_read_and_write(bp, phy,
+					MDIO_AN_DEVAD,
+					MDIO_AN_REG_8727_MISC_CTRL2,
+					~(1<<5));
+			bnx2x_cl45_write(bp, phy,
+					MDIO_AN_DEVAD,
+					MDIO_AN_REG_8727_MISC_CTRL1, 0x0010);
+		} else {
+			bnx2x_cl45_write(bp, phy,
+					MDIO_AN_DEVAD,
+					MDIO_AN_REG_8727_MISC_CTRL1, 0x001C);
+		}
 		/* Power down the XAUI until link is up in case of dual-media
 		 * and 1G
 		 */
@@ -9268,7 +9299,7 @@ static void bnx2x_8727_config_speed(struct bnx2x_phy *phy,
 
 		DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
 		bnx2x_cl45_write(bp, phy,
-				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
+				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL2, 0);
 		bnx2x_cl45_write(bp, phy,
 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
 	} else {
@@ -9276,8 +9307,11 @@ static void bnx2x_8727_config_speed(struct bnx2x_phy *phy,
 		 * registers although it is default
 		 */
 		bnx2x_cl45_write(bp, phy,
-				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
+				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL2,
 				 0x0020);
+		bnx2x_cl45_write(bp, phy,
+				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL1,
+				 0x001C);
 		bnx2x_cl45_write(bp, phy,
 				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
 		bnx2x_cl45_write(bp, phy,
@@ -9567,6 +9601,11 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
 		vars->line_speed = SPEED_10000;
 		DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
 			   params->port);
+	} else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
+		link_up = 1;
+		vars->line_speed = SPEED_2500;
+		DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
+			   params->port);
 	} else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
 		link_up = 1;
 		vars->line_speed = SPEED_1000;
@@ -9598,7 +9637,8 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
 	}
 
 	if ((DUAL_MEDIA(params)) &&
-	    (phy->req_line_speed == SPEED_1000)) {
+	    ((phy->req_line_speed == SPEED_1000) ||
+	     (phy->req_line_speed == SPEED_2500))) {
 		bnx2x_cl45_read(bp, phy,
 				MDIO_PMA_DEVAD,
 				MDIO_PMA_REG_8727_PCS_GP, &val1);
@@ -11722,6 +11762,7 @@ static const struct bnx2x_phy phy_warpcore = {
 			   SUPPORTED_100baseT_Full |
 			   SUPPORTED_1000baseT_Full |
 			   SUPPORTED_1000baseKX_Full |
+			   SUPPORTED_2500baseX_Full |
 			   SUPPORTED_10000baseT_Full |
 			   SUPPORTED_10000baseKR_Full |
 			   SUPPORTED_20000baseKR2_Full |
@@ -11908,6 +11949,7 @@ static const struct bnx2x_phy phy_8727 = {
 	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
 	.mdio_ctrl	= 0,
 	.supported	= (SUPPORTED_10000baseT_Full |
+			   SUPPORTED_2500baseX_Full |
 			   SUPPORTED_1000baseT_Full |
 			   SUPPORTED_FIBRE |
 			   SUPPORTED_Pause |
@@ -12255,6 +12297,7 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
 			break;
 		case PORT_HW_CFG_NET_SERDES_IF_SFI:
 			phy->supported &= (SUPPORTED_1000baseT_Full |
+					   SUPPORTED_2500baseX_Full |
 					   SUPPORTED_10000baseT_Full |
 					   SUPPORTED_FIBRE |
 					   SUPPORTED_Pause |
@@ -13939,7 +13982,8 @@ void bnx2x_period_func(struct link_params *params, struct link_vars *vars)
 		    & PORT_HW_CFG_NET_SERDES_IF_MASK) ==
 		    PORT_HW_CFG_NET_SERDES_IF_SFI) {
 			if (bnx2x_is_sfp_module_plugged(phy, params)) {
-				bnx2x_sfp_tx_fault_detection(phy, params, vars);
+				if(!((params->port + 1) & bp->mask_tx_fault))
+					bnx2x_sfp_tx_fault_detection(phy, params, vars);
 			} else if (vars->link_status &
 				LINK_STATUS_SFP_TX_FAULT) {
 				/* Clean trail, interrupt corrects the leds */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 8e6eec828d48..767d4cd238e9 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -112,6 +112,10 @@ static int disable_tpa;
 module_param(disable_tpa, int, 0444);
 MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature");
 
+static int mask_tx_fault;
+module_param(mask_tx_fault, int, 0444);
+MODULE_PARM_DESC(mask_tx_fault, " Mask SFP TX fault detection");
+
 static int int_mode;
 module_param(int_mode, int, 0444);
 MODULE_PARM_DESC(int_mode, " Force interrupt mode other than MSI-X "
@@ -12343,6 +12347,8 @@ static int bnx2x_init_bp(struct bnx2x *bp)
 	if (BP_NOMCP(bp) && (func == 0))
 		dev_err(&bp->pdev->dev, "MCP disabled, must load devices in order!\n");
 
+	bp->mask_tx_fault = mask_tx_fault;
+
 	bp->disable_tpa = disable_tpa;
 	bp->disable_tpa |= !!IS_MF_STORAGE_ONLY(bp);
 	/* Reduce memory usage in kdump environment by disabling TPA */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
index a018f251d198..b030b1cf9f93 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
@@ -7171,7 +7171,8 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_PMA_REG_8727_PCS_GP		0xc842
 #define MDIO_PMA_REG_8727_OPT_CFG_REG		0xc8e4
 
-#define MDIO_AN_REG_8727_MISC_CTRL		0x8309
+#define MDIO_AN_REG_8727_MISC_CTRL1		0x8308
+#define MDIO_AN_REG_8727_MISC_CTRL2		0x8309
 
 #define MDIO_PMA_REG_8073_CHIP_REV			0xc801
 #define MDIO_PMA_REG_8073_SPEED_LINK_STATUS		0xc820
-- 
2.39.5