- add support for 2500baseX_Full in addition to 1000baseT_Full.
  For 2.5Gbps speed, HSGMII mode shall be enabled in the serdes.
- add the possibility to support SC connectors on SFP (GPON are mostly SC)
- change the initialisation time from 60ms to 1800ms (for xPON-Based SFP)

This has been tested with GPON's ONU SFP but requires a specific
firmware configuration described in the documentation.

Signed-off-by: Julien Aube <julien_d...@jaube.fr>
---
 doc/guides/nics/bnx2x.rst |  4 ++++
 drivers/net/bnx2x/elink.c | 19 +++++++++++++++++--
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/doc/guides/nics/bnx2x.rst b/doc/guides/nics/bnx2x.rst
index 788a6dac08..f19784db2c 100644
--- a/doc/guides/nics/bnx2x.rst
+++ b/doc/guides/nics/bnx2x.rst
@@ -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
 ------------------------------
 
diff --git a/drivers/net/bnx2x/elink.c b/drivers/net/bnx2x/elink.c
index 43fbf04ece..2c81f85b96 100644
--- a/drivers/net/bnx2x/elink.c
+++ b/drivers/net/bnx2x/elink.c
@@ -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,15 @@ 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 advertisement */
+               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 +5089,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 +9149,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 +9163,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 +9337,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 +12627,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 +13170,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 |
-- 
2.30.2

Reply via email to