Skip to content

Commit

Permalink
net: pcs: add 2500BASEX support for Intel mGbE controller
Browse files Browse the repository at this point in the history
XPCS IP supports 2500BASEX as PHY interface. It is configured as
autonegotiation disable to cater for PHYs that does not supports 2500BASEX
autonegotiation.

v2: Add supported link speed masking.
v3: Restructure to introduce xpcs_config_2500basex() used to configure the
    xpcs for 2.5G speeds. Added 2500BASEX specific information for
    configuration.
v4: Fix indentation error

Signed-off-by: Voon Weifeng <weifeng.voon@intel.com>
Signed-off-by: Michael Sit Wei Hong <michael.wei.hong.sit@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Voon Weifeng authored and David S. Miller committed Jun 8, 2021
1 parent 597a68c commit f27abde
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
56 changes: 56 additions & 0 deletions drivers/net/pcs/pcs-xpcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,12 @@

/* Clause 37 Defines */
/* VR MII MMD registers offsets */
#define DW_VR_MII_MMD_CTRL 0x0000
#define DW_VR_MII_DIG_CTRL1 0x8000
#define DW_VR_MII_AN_CTRL 0x8001
#define DW_VR_MII_AN_INTR_STS 0x8002
/* Enable 2.5G Mode */
#define DW_VR_MII_DIG_CTRL1_2G5_EN BIT(2)
/* EEE Mode Control Register */
#define DW_VR_MII_EEE_MCTRL0 0x8006
#define DW_VR_MII_EEE_MCTRL1 0x800b
Expand All @@ -86,6 +89,11 @@
#define DW_VR_MII_C37_ANSGM_SP_1000 0x2
#define DW_VR_MII_C37_ANSGM_SP_LNKSTS BIT(4)

/* SR MII MMD Control defines */
#define AN_CL37_EN BIT(12) /* Enable Clause 37 auto-nego */
#define SGMII_SPEED_SS13 BIT(13) /* SGMII speed along with SS6 */
#define SGMII_SPEED_SS6 BIT(6) /* SGMII speed along with SS13 */

/* VR MII EEE Control 0 defines */
#define DW_VR_MII_EEE_LTX_EN BIT(0) /* LPI Tx Enable */
#define DW_VR_MII_EEE_LRX_EN BIT(1) /* LPI Rx Enable */
Expand Down Expand Up @@ -161,6 +169,14 @@ static const int xpcs_sgmii_features[] = {
__ETHTOOL_LINK_MODE_MASK_NBITS,
};

static const int xpcs_2500basex_features[] = {
ETHTOOL_LINK_MODE_Asym_Pause_BIT,
ETHTOOL_LINK_MODE_Autoneg_BIT,
ETHTOOL_LINK_MODE_2500baseX_Full_BIT,
ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
__ETHTOOL_LINK_MODE_MASK_NBITS,
};

static const phy_interface_t xpcs_usxgmii_interfaces[] = {
PHY_INTERFACE_MODE_USXGMII,
};
Expand All @@ -177,11 +193,17 @@ static const phy_interface_t xpcs_sgmii_interfaces[] = {
PHY_INTERFACE_MODE_SGMII,
};

static const phy_interface_t xpcs_2500basex_interfaces[] = {
PHY_INTERFACE_MODE_2500BASEX,
PHY_INTERFACE_MODE_MAX,
};

enum {
DW_XPCS_USXGMII,
DW_XPCS_10GKR,
DW_XPCS_XLGMII,
DW_XPCS_SGMII,
DW_XPCS_2500BASEX,
DW_XPCS_INTERFACE_MAX,
};

Expand Down Expand Up @@ -306,6 +328,7 @@ static int xpcs_soft_reset(struct mdio_xpcs_args *xpcs,
dev = MDIO_MMD_PCS;
break;
case DW_AN_C37_SGMII:
case DW_2500BASEX:
dev = MDIO_MMD_VEND2;
break;
default:
Expand Down Expand Up @@ -804,6 +827,28 @@ static int xpcs_config_aneg_c37_sgmii(struct mdio_xpcs_args *xpcs)
return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
}

static int xpcs_config_2500basex(struct mdio_xpcs_args *xpcs)
{
int ret;

ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1);
if (ret < 0)
return ret;
ret |= DW_VR_MII_DIG_CTRL1_2G5_EN;
ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW;
ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret);
if (ret < 0)
return ret;

ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL);
if (ret < 0)
return ret;
ret &= ~AN_CL37_EN;
ret |= SGMII_SPEED_SS6;
ret &= ~SGMII_SPEED_SS13;
return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, ret);
}

static int xpcs_do_config(struct mdio_xpcs_args *xpcs,
phy_interface_t interface, unsigned int mode)
{
Expand All @@ -827,6 +872,11 @@ static int xpcs_do_config(struct mdio_xpcs_args *xpcs,
if (ret)
return ret;
break;
case DW_2500BASEX:
ret = xpcs_config_2500basex(xpcs);
if (ret)
return ret;
break;
default:
return -1;
}
Expand Down Expand Up @@ -1023,6 +1073,12 @@ static const struct xpcs_compat synopsys_xpcs_compat[DW_XPCS_INTERFACE_MAX] = {
.num_interfaces = ARRAY_SIZE(xpcs_sgmii_interfaces),
.an_mode = DW_AN_C37_SGMII,
},
[DW_XPCS_2500BASEX] = {
.supported = xpcs_2500basex_features,
.interface = xpcs_2500basex_interfaces,
.num_interfaces = ARRAY_SIZE(xpcs_2500basex_features),
.an_mode = DW_2500BASEX,
},
};

static const struct xpcs_id xpcs_id_list[] = {
Expand Down
1 change: 1 addition & 0 deletions include/linux/pcs/pcs-xpcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
/* AN mode */
#define DW_AN_C73 1
#define DW_AN_C37_SGMII 2
#define DW_2500BASEX 3

struct xpcs_id;

Expand Down

0 comments on commit f27abde

Please sign in to comment.