drivers/net/bnx2x : Add experimental 2.5Gbps support for BCM578xx.
Checks
Commit Message
From: Julien Aube <julien_dpdk@jaube.fr>
This has been tested with GPON's ONU SFP but requires a specific firmware configuration.
Signed-off-by: Julien Aube <julien_dpdk@jaube.fr>
---
doc/guides/nics/bnx2x.rst | 4 ++++
drivers/net/bnx2x/elink.c | 20 ++++++++++++++++++--
2 files changed, 22 insertions(+), 2 deletions(-)
@@ -22,6 +22,7 @@ BNX2X PMD has support for:
- Promiscuous mode
- Port hardware statistics
- SR-IOV VF
+- Experimental 2.5Gbps support
Non-supported Features
----------------------
@@ -72,6 +73,9 @@ Prerequisites
`linux-firmware git repository <https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/bnx2x/bnx2x-e2-7.13.11.0.fw>`_
to get the required firmware.
+- 2.5Gbps speed currently require that the firmware's nvm configuration number 7 / 35 (first port) and 36 (second port) are set to 0x70
+ for 1G/2.5G/10G support . This can be done for EFI or DOS using EDIAG tool from Broadcom.
+
Pre-Installation Configuration
------------------------------
@@ -867,6 +867,7 @@ typedef elink_status_t (*read_sfp_module_eeprom_func_p)(struct elink_phy *phy,
#define ELINK_SFP_EEPROM_CON_TYPE_ADDR 0x2
#define ELINK_SFP_EEPROM_CON_TYPE_VAL_UNKNOWN 0x0
+ #define ELINK_SFP_EEPROM_CON_TYPE_VAL_SC 0x1
#define ELINK_SFP_EEPROM_CON_TYPE_VAL_LC 0x7
#define ELINK_SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
#define ELINK_SFP_EEPROM_CON_TYPE_VAL_RJ45 0x22
@@ -5069,6 +5070,16 @@ static void elink_warpcore_set_sgmii_speed(struct elink_phy *phy,
0x1000);
ELINK_DEBUG_P0(sc, "set SGMII AUTONEG");
} 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))) {
+ elink_cl45_write(sc, phy, MDIO_WC_DEVAD,
+ MDIO_WC_REG_SERDESDIGITAL_MISC1,
+ 0x6010);
+ }
+
elink_cl45_read(sc, phy, MDIO_WC_DEVAD,
MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
val16 &= 0xcebf;
@@ -5079,6 +5090,7 @@ static void elink_warpcore_set_sgmii_speed(struct elink_phy *phy,
val16 |= 0x2000;
break;
case ELINK_SPEED_1000:
+ case ELINK_SPEED_2500:
val16 |= 0x0040;
break;
default:
@@ -9138,6 +9150,7 @@ static elink_status_t elink_get_edc_mode(struct elink_phy *phy,
break;
}
case ELINK_SFP_EEPROM_CON_TYPE_VAL_UNKNOWN:
+ case ELINK_SFP_EEPROM_CON_TYPE_VAL_SC:
case ELINK_SFP_EEPROM_CON_TYPE_VAL_LC:
case ELINK_SFP_EEPROM_CON_TYPE_VAL_RJ45:
check_limiting_mode = 1;
@@ -9151,7 +9164,8 @@ static elink_status_t elink_get_edc_mode(struct elink_phy *phy,
(val[ELINK_SFP_EEPROM_1G_COMP_CODE_ADDR] != 0)) {
ELINK_DEBUG_P0(sc, "1G SFP module detected");
phy->media_type = ELINK_ETH_PHY_SFP_1G_FIBER;
- if (phy->req_line_speed != ELINK_SPEED_1000) {
+ if ((phy->req_line_speed != ELINK_SPEED_1000) &&
+ (phy->req_line_speed != ELINK_SPEED_2500)) {
uint8_t gport = params->port;
phy->req_line_speed = ELINK_SPEED_1000;
if (!CHIP_IS_E1x(sc)) {
@@ -9324,7 +9338,7 @@ static elink_status_t elink_wait_for_sfp_module_initialized(
* some phys type ( e.g. JDSU )
*/
- for (timeout = 0; timeout < 60; timeout++) {
+ for (timeout = 0; timeout < 1800; timeout++) {
if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
rc = elink_warpcore_read_sfp_module_eeprom(
phy, params, ELINK_I2C_DEV_ADDR_A0, 1, 1, &val,
@@ -12614,6 +12628,7 @@ static const struct elink_phy phy_warpcore = {
ELINK_SUPPORTED_100baseT_Half |
ELINK_SUPPORTED_100baseT_Full |
ELINK_SUPPORTED_1000baseT_Full |
+ ELINK_SUPPORTED_2500baseX_Full |
ELINK_SUPPORTED_1000baseKX_Full |
ELINK_SUPPORTED_10000baseT_Full |
ELINK_SUPPORTED_10000baseKR_Full |
@@ -13156,6 +13171,7 @@ static elink_status_t elink_populate_int_phy(struct bnx2x_softc *sc,
break;
case PORT_HW_CFG_NET_SERDES_IF_SFI:
phy->supported &= (ELINK_SUPPORTED_1000baseT_Full |
+ ELINK_SUPPORTED_2500baseX_Full |
ELINK_SUPPORTED_10000baseT_Full |
ELINK_SUPPORTED_FIBRE |
ELINK_SUPPORTED_Pause |