Skip to content

Commit b3edf28

Browse files
authored
Merge pull request vyos#1227 from c-po/bnx2-patch
Kernel: T8914: add support for 2.5G pluggables on BCM57810S
2 parents b284c29 + 33efe03 commit b3edf28

1 file changed

Lines changed: 239 additions & 0 deletions

File tree

Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
From 95190cc11737b35b62e92de37d7761370909d1b1 Mon Sep 17 00:00:00 2001
2+
From: Christian Breunig <christian@breunig.cc>
3+
Date: Thu, 25 Jun 2026 17:06:39 +0200
4+
Subject: [PATCH] Kernel: T8914: add support for 2.5G pluggables on BCM57810S
5+
6+
Add the well-known JAMESMTL kernel module patch for bnx2x to advertise 2.5Gbit/s
7+
capabilities on Broadcom NetXtreme2-X cards with BCM57810S chipset.
8+
9+
This is useful for ISP GPON access networks that use 2.5Gbit/s pluggables and
10+
need the NIC to negotiate beyond 1000baseT/Full, avoiding the 940Mbit/s
11+
practical cap on overprovisioned 1G services.
12+
13+
References:
14+
* https://hack-gpon.org/broadcom-57810s/
15+
* https://github.com/JAMESMTL/snippets/blob/dceb2fee74d80c66d/bnx2x/patches/bnx2x_warpcore_8727_2_5g_sgmii_txfault.patch
16+
---
17+
drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 1 +
18+
.../net/ethernet/broadcom/bnx2x/bnx2x_link.c | 54 +++++++++++++++++--
19+
.../net/ethernet/broadcom/bnx2x/bnx2x_main.c | 6 +++
20+
.../net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 3 +-
21+
4 files changed, 58 insertions(+), 6 deletions(-)
22+
23+
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
24+
index 9580ab83d387..e22a832936c3 100644
25+
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
26+
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
27+
@@ -1593,6 +1593,7 @@ struct bnx2x {
28+
uint num_ethernet_queues;
29+
uint num_cnic_queues;
30+
int disable_tpa;
31+
+ int mask_tx_fault;
32+
33+
u32 rx_mode;
34+
#define BNX2X_RX_MODE_NONE 0
35+
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
36+
index ea310057fe3a..3fa0cf96da84 100644
37+
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
38+
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
39+
@@ -151,6 +151,7 @@ typedef int (*read_sfp_module_eeprom_func_p)(struct bnx2x_phy *phy,
40+
41+
#define SFP_EEPROM_CON_TYPE_ADDR 0x2
42+
#define SFP_EEPROM_CON_TYPE_VAL_UNKNOWN 0x0
43+
+ #define SFP_EEPROM_CON_TYPE_VAL_SC 0x1
44+
#define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
45+
#define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
46+
#define SFP_EEPROM_CON_TYPE_VAL_RJ45 0x22
47+
@@ -4210,6 +4211,16 @@ static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
48+
0x1000);
49+
DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n");
50+
} else {
51+
+ /* Note that 2.5G works only when used with 1G advertisment */
52+
+ if (fiber_mode && (phy->req_line_speed == SPEED_2500) &&
53+
+ (phy->speed_cap_mask &
54+
+ (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
55+
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))) {
56+
+ bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
57+
+ MDIO_WC_REG_SERDESDIGITAL_MISC1,
58+
+ 0x6010);
59+
+ }
60+
+
61+
bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
62+
MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
63+
val16 &= 0xcebf;
64+
@@ -4220,6 +4231,7 @@ static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
65+
val16 |= 0x2000;
66+
break;
67+
case SPEED_1000:
68+
+ case SPEED_2500:
69+
val16 |= 0x0040;
70+
break;
71+
default:
72+
@@ -8174,6 +8186,7 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
73+
break;
74+
}
75+
case SFP_EEPROM_CON_TYPE_VAL_UNKNOWN:
76+
+ case SFP_EEPROM_CON_TYPE_VAL_SC:
77+
case SFP_EEPROM_CON_TYPE_VAL_LC:
78+
case SFP_EEPROM_CON_TYPE_VAL_RJ45:
79+
check_limiting_mode = 1;
80+
@@ -8184,7 +8197,8 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
81+
(val[SFP_EEPROM_1G_COMP_CODE_ADDR] != 0)) {
82+
DP(NETIF_MSG_LINK, "1G SFP module detected\n");
83+
phy->media_type = ETH_PHY_SFP_1G_FIBER;
84+
- if (phy->req_line_speed != SPEED_1000) {
85+
+ if ((phy->req_line_speed != SPEED_1000) &&
86+
+ (phy->req_line_speed != SPEED_2500)) {
87+
u8 gport = params->port;
88+
phy->req_line_speed = SPEED_1000;
89+
if (!CHIP_IS_E1x(bp)) {
90+
@@ -9238,6 +9252,7 @@ static void bnx2x_8727_config_speed(struct bnx2x_phy *phy,
91+
u16 tmp1, val;
92+
/* Set option 1G speed */
93+
if ((phy->req_line_speed == SPEED_1000) ||
94+
+ (phy->req_line_speed == SPEED_2500) ||
95+
(phy->media_type == ETH_PHY_SFP_1G_FIBER)) {
96+
DP(NETIF_MSG_LINK, "Setting 1G force\n");
97+
bnx2x_cl45_write(bp, phy,
98+
@@ -9247,6 +9262,22 @@ static void bnx2x_8727_config_speed(struct bnx2x_phy *phy,
99+
bnx2x_cl45_read(bp, phy,
100+
MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
101+
DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
102+
+ if ((phy->req_line_speed == SPEED_2500) &&
103+
+ (phy->speed_cap_mask &
104+
+ (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
105+
+ PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))) {
106+
+ bnx2x_cl45_read_and_write(bp, phy,
107+
+ MDIO_AN_DEVAD,
108+
+ MDIO_AN_REG_8727_MISC_CTRL2,
109+
+ ~(1<<5));
110+
+ bnx2x_cl45_write(bp, phy,
111+
+ MDIO_AN_DEVAD,
112+
+ MDIO_AN_REG_8727_MISC_CTRL1, 0x0010);
113+
+ } else {
114+
+ bnx2x_cl45_write(bp, phy,
115+
+ MDIO_AN_DEVAD,
116+
+ MDIO_AN_REG_8727_MISC_CTRL1, 0x001C);
117+
+ }
118+
/* Power down the XAUI until link is up in case of dual-media
119+
* and 1G
120+
*/
121+
@@ -9268,7 +9299,7 @@ static void bnx2x_8727_config_speed(struct bnx2x_phy *phy,
122+
123+
DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
124+
bnx2x_cl45_write(bp, phy,
125+
- MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
126+
+ MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL2, 0);
127+
bnx2x_cl45_write(bp, phy,
128+
MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
129+
} else {
130+
@@ -9276,8 +9307,11 @@ static void bnx2x_8727_config_speed(struct bnx2x_phy *phy,
131+
* registers although it is default
132+
*/
133+
bnx2x_cl45_write(bp, phy,
134+
- MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
135+
+ MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL2,
136+
0x0020);
137+
+ bnx2x_cl45_write(bp, phy,
138+
+ MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL1,
139+
+ 0x001C);
140+
bnx2x_cl45_write(bp, phy,
141+
MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
142+
bnx2x_cl45_write(bp, phy,
143+
@@ -9567,6 +9601,11 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
144+
vars->line_speed = SPEED_10000;
145+
DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
146+
params->port);
147+
+ } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
148+
+ link_up = 1;
149+
+ vars->line_speed = SPEED_2500;
150+
+ DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
151+
+ params->port);
152+
} else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
153+
link_up = 1;
154+
vars->line_speed = SPEED_1000;
155+
@@ -9598,7 +9637,8 @@ static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
156+
}
157+
158+
if ((DUAL_MEDIA(params)) &&
159+
- (phy->req_line_speed == SPEED_1000)) {
160+
+ ((phy->req_line_speed == SPEED_1000) ||
161+
+ (phy->req_line_speed == SPEED_2500))) {
162+
bnx2x_cl45_read(bp, phy,
163+
MDIO_PMA_DEVAD,
164+
MDIO_PMA_REG_8727_PCS_GP, &val1);
165+
@@ -11722,6 +11762,7 @@ static const struct bnx2x_phy phy_warpcore = {
166+
SUPPORTED_100baseT_Full |
167+
SUPPORTED_1000baseT_Full |
168+
SUPPORTED_1000baseKX_Full |
169+
+ SUPPORTED_2500baseX_Full |
170+
SUPPORTED_10000baseT_Full |
171+
SUPPORTED_10000baseKR_Full |
172+
SUPPORTED_20000baseKR2_Full |
173+
@@ -11908,6 +11949,7 @@ static const struct bnx2x_phy phy_8727 = {
174+
.tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
175+
.mdio_ctrl = 0,
176+
.supported = (SUPPORTED_10000baseT_Full |
177+
+ SUPPORTED_2500baseX_Full |
178+
SUPPORTED_1000baseT_Full |
179+
SUPPORTED_FIBRE |
180+
SUPPORTED_Pause |
181+
@@ -12255,6 +12297,7 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
182+
break;
183+
case PORT_HW_CFG_NET_SERDES_IF_SFI:
184+
phy->supported &= (SUPPORTED_1000baseT_Full |
185+
+ SUPPORTED_2500baseX_Full |
186+
SUPPORTED_10000baseT_Full |
187+
SUPPORTED_FIBRE |
188+
SUPPORTED_Pause |
189+
@@ -13939,7 +13982,8 @@ void bnx2x_period_func(struct link_params *params, struct link_vars *vars)
190+
& PORT_HW_CFG_NET_SERDES_IF_MASK) ==
191+
PORT_HW_CFG_NET_SERDES_IF_SFI) {
192+
if (bnx2x_is_sfp_module_plugged(phy, params)) {
193+
- bnx2x_sfp_tx_fault_detection(phy, params, vars);
194+
+ if(!((params->port + 1) & bp->mask_tx_fault))
195+
+ bnx2x_sfp_tx_fault_detection(phy, params, vars);
196+
} else if (vars->link_status &
197+
LINK_STATUS_SFP_TX_FAULT) {
198+
/* Clean trail, interrupt corrects the leds */
199+
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
200+
index 8e6eec828d48..767d4cd238e9 100644
201+
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
202+
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
203+
@@ -112,6 +112,10 @@ static int disable_tpa;
204+
module_param(disable_tpa, int, 0444);
205+
MODULE_PARM_DESC(disable_tpa, " Disable the TPA (LRO) feature");
206+
207+
+static int mask_tx_fault;
208+
+module_param(mask_tx_fault, int, 0444);
209+
+MODULE_PARM_DESC(mask_tx_fault, " Mask SFP TX fault detection");
210+
+
211+
static int int_mode;
212+
module_param(int_mode, int, 0444);
213+
MODULE_PARM_DESC(int_mode, " Force interrupt mode other than MSI-X "
214+
@@ -12343,6 +12347,8 @@ static int bnx2x_init_bp(struct bnx2x *bp)
215+
if (BP_NOMCP(bp) && (func == 0))
216+
dev_err(&bp->pdev->dev, "MCP disabled, must load devices in order!\n");
217+
218+
+ bp->mask_tx_fault = mask_tx_fault;
219+
+
220+
bp->disable_tpa = disable_tpa;
221+
bp->disable_tpa |= !!IS_MF_STORAGE_ONLY(bp);
222+
/* Reduce memory usage in kdump environment by disabling TPA */
223+
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
224+
index a018f251d198..b030b1cf9f93 100644
225+
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
226+
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
227+
@@ -7171,7 +7171,8 @@ Theotherbitsarereservedandshouldbezero*/
228+
#define MDIO_PMA_REG_8727_PCS_GP 0xc842
229+
#define MDIO_PMA_REG_8727_OPT_CFG_REG 0xc8e4
230+
231+
-#define MDIO_AN_REG_8727_MISC_CTRL 0x8309
232+
+#define MDIO_AN_REG_8727_MISC_CTRL1 0x8308
233+
+#define MDIO_AN_REG_8727_MISC_CTRL2 0x8309
234+
235+
#define MDIO_PMA_REG_8073_CHIP_REV 0xc801
236+
#define MDIO_PMA_REG_8073_SPEED_LINK_STATUS 0xc820
237+
--
238+
2.39.5
239+

0 commit comments

Comments
 (0)