mirror of
https://git.openwrt.org/openwrt/openwrt.git
synced 2026-03-14 23:09:45 +01:00
realtek: pcs: configure auto-negotiation on all SoCs
RTL83xx uses the BMCR and ADVERTISE registers like RTL93xx to configure in-band auto-negotiation. Split out the common parts as a new generic implementation and use it for RTL83xx. RTL93xx retains its own variant of set_autoneg to support XSGMII, but calls into the generic version for all other modes. Tested 1000Base-X auto-negotiation on HPE 1920-8G (RTL8380). Also tested HPE 1920-24G (RTL8382) and HPE-1920-48G (RTL8393) to make sure this does not affect PHY ports. Signed-off-by: Jan Hoffmann <jan@3e8.eu> Link: https://github.com/openwrt/openwrt/pull/21934 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
parent
2e5b44a989
commit
a517d94c9f
1 changed files with 48 additions and 34 deletions
|
|
@ -444,6 +444,46 @@ static int rtpcs_sds_determine_hw_mode(struct rtpcs_serdes *sds,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Generic auto-negotiation config */
|
||||
|
||||
static int rtpcs_generic_sds_set_autoneg(struct rtpcs_serdes *sds, unsigned int neg_mode,
|
||||
const unsigned long *advertising)
|
||||
{
|
||||
u16 bmcr, adv;
|
||||
bool changed = 0;
|
||||
int ret;
|
||||
|
||||
if ((sds->hw_mode == RTPCS_SDS_MODE_1000BASEX) ||
|
||||
(sds->hw_mode == RTPCS_SDS_MODE_2500BASEX)) {
|
||||
adv = ADVERTISE_1000XFULL;
|
||||
if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
|
||||
advertising))
|
||||
adv |= ADVERTISE_1000XPAUSE;
|
||||
if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
|
||||
advertising))
|
||||
adv |= ADVERTISE_1000XPSE_ASYM;
|
||||
|
||||
ret = rtpcs_sds_modify_changed(sds, 0x2, MII_ADVERTISE,
|
||||
0xffff, adv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
changed = ret;
|
||||
}
|
||||
|
||||
bmcr = neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED ? BMCR_ANENABLE : 0;
|
||||
|
||||
ret = rtpcs_sds_modify(sds, 0x2, MII_BMCR, BMCR_ANENABLE, bmcr);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
static void rtpcs_generic_sds_restart_autoneg(struct rtpcs_serdes *sds)
|
||||
{
|
||||
rtpcs_sds_modify(sds, 0x2, MII_BMCR, BMCR_ANRESTART, BMCR_ANRESTART);
|
||||
}
|
||||
|
||||
/* Variant-specific functions */
|
||||
|
||||
/* RTL838X */
|
||||
|
|
@ -968,9 +1008,7 @@ static int rtpcs_839x_setup_serdes(struct rtpcs_serdes *sds,
|
|||
static int rtpcs_93xx_sds_set_autoneg(struct rtpcs_serdes *sds, unsigned int neg_mode,
|
||||
const unsigned long *advertising)
|
||||
{
|
||||
u16 bmcr, adv, en_val;
|
||||
bool changed = 0;
|
||||
int ret;
|
||||
u16 en_val;
|
||||
|
||||
switch (sds->hw_mode) {
|
||||
case RTPCS_SDS_MODE_XSGMII: /* XSG N-way state */
|
||||
|
|
@ -978,38 +1016,10 @@ static int rtpcs_93xx_sds_set_autoneg(struct rtpcs_serdes *sds, unsigned int neg
|
|||
|
||||
return rtpcs_sds_xsg_write_bits(sds, 0x0, 0x2, 9, 8, en_val);
|
||||
default:
|
||||
if ((sds->hw_mode == RTPCS_SDS_MODE_1000BASEX) ||
|
||||
(sds->hw_mode == RTPCS_SDS_MODE_2500BASEX)) {
|
||||
adv = ADVERTISE_1000XFULL;
|
||||
if (linkmode_test_bit(ETHTOOL_LINK_MODE_Pause_BIT,
|
||||
advertising))
|
||||
adv |= ADVERTISE_1000XPAUSE;
|
||||
if (linkmode_test_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
|
||||
advertising))
|
||||
adv |= ADVERTISE_1000XPSE_ASYM;
|
||||
|
||||
ret = rtpcs_sds_modify_changed(sds, 0x2, MII_ADVERTISE,
|
||||
0xffff, adv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
changed = ret;
|
||||
}
|
||||
|
||||
bmcr = neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED ? BMCR_ANENABLE : 0;
|
||||
|
||||
ret = rtpcs_sds_modify(sds, 0x2, MII_BMCR, BMCR_ANENABLE, bmcr);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return changed;
|
||||
return rtpcs_generic_sds_set_autoneg(sds, neg_mode, advertising);
|
||||
}
|
||||
}
|
||||
|
||||
static void rtpcs_93xx_sds_restart_autoneg(struct rtpcs_serdes *sds)
|
||||
{
|
||||
rtpcs_sds_modify(sds, 0x2, MII_BMCR, BMCR_ANRESTART, BMCR_ANRESTART);
|
||||
}
|
||||
|
||||
static int rtpcs_93xx_init_serdes_common(struct rtpcs_ctrl *ctrl)
|
||||
{
|
||||
u32 model_info = 0;
|
||||
|
|
@ -3980,6 +3990,8 @@ static const struct phylink_pcs_ops rtpcs_838x_pcs_ops = {
|
|||
static const struct rtpcs_serdes_ops rtpcs_838x_sds_ops = {
|
||||
.read = rtpcs_generic_sds_op_read,
|
||||
.write = rtpcs_generic_sds_op_write,
|
||||
.set_autoneg = rtpcs_generic_sds_set_autoneg,
|
||||
.restart_autoneg = rtpcs_generic_sds_restart_autoneg,
|
||||
};
|
||||
|
||||
static const struct rtpcs_config rtpcs_838x_cfg = {
|
||||
|
|
@ -4006,6 +4018,8 @@ static const struct phylink_pcs_ops rtpcs_839x_pcs_ops = {
|
|||
static const struct rtpcs_serdes_ops rtpcs_839x_sds_ops = {
|
||||
.read = rtpcs_generic_sds_op_read,
|
||||
.write = rtpcs_generic_sds_op_write,
|
||||
.set_autoneg = rtpcs_generic_sds_set_autoneg,
|
||||
.restart_autoneg = rtpcs_generic_sds_restart_autoneg,
|
||||
};
|
||||
|
||||
static const struct rtpcs_config rtpcs_839x_cfg = {
|
||||
|
|
@ -4034,7 +4048,7 @@ static const struct rtpcs_serdes_ops rtpcs_930x_sds_ops = {
|
|||
.write = rtpcs_930x_sds_op_write,
|
||||
.xsg_write = rtpcs_930x_sds_op_xsg_write,
|
||||
.set_autoneg = rtpcs_93xx_sds_set_autoneg,
|
||||
.restart_autoneg = rtpcs_93xx_sds_restart_autoneg,
|
||||
.restart_autoneg = rtpcs_generic_sds_restart_autoneg,
|
||||
};
|
||||
|
||||
static const struct rtpcs_config rtpcs_930x_cfg = {
|
||||
|
|
@ -4063,7 +4077,7 @@ static const struct rtpcs_serdes_ops rtpcs_931x_sds_ops = {
|
|||
.write = rtpcs_generic_sds_op_write,
|
||||
.xsg_write = rtpcs_931x_sds_op_xsg_write,
|
||||
.set_autoneg = rtpcs_93xx_sds_set_autoneg,
|
||||
.restart_autoneg = rtpcs_93xx_sds_restart_autoneg,
|
||||
.restart_autoneg = rtpcs_generic_sds_restart_autoneg,
|
||||
};
|
||||
|
||||
static const struct rtpcs_config rtpcs_931x_cfg = {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue