Commit e19de30d authored by Daniel Golle's avatar Daniel Golle Committed by David S. Miller

net: dsa: mt7530: add support for in-band link status

Read link status from SGMII PCS for in-band managed 2500Base-X and
1000Base-X connection on a MAC port of the MT7531. This is needed to
get the SFP cage working which is connected to SGMII interface of
port 5 of the MT7531 switch IC on the Bananapi BPi-R3 board.
While at it also handle an_complete for both the autoneg and the
non-autoneg codepath.
Signed-off-by: default avatarDaniel Golle <daniel@makrotopia.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 793cc3c7
......@@ -2699,9 +2699,6 @@ mt7531_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
case PHY_INTERFACE_MODE_NA:
case PHY_INTERFACE_MODE_1000BASEX:
case PHY_INTERFACE_MODE_2500BASEX:
if (phylink_autoneg_inband(mode))
return -EINVAL;
return mt7531_sgmii_setup_mode_force(priv, port, interface);
default:
return -EINVAL;
......@@ -2777,13 +2774,6 @@ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
return;
}
if (phylink_autoneg_inband(mode) &&
state->interface != PHY_INTERFACE_MODE_SGMII) {
dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
__func__);
return;
}
mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
mcr_new = mcr_cur;
mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
......@@ -2922,6 +2912,9 @@ static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
MAC_10 | MAC_100 | MAC_1000FD;
if ((priv->id == ID_MT7531) && mt753x_is_mac_port(port))
config->mac_capabilities |= MAC_2500FD;
/* This driver does not make use of the speed, duplex, pause or the
* advertisement in its mac_config, so it is safe to mark this driver
* as non-legacy.
......@@ -2987,6 +2980,7 @@ mt7531_sgmii_pcs_get_state_an(struct mt7530_priv *priv, int port,
status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
state->link = !!(status & MT7531_SGMII_LINK_STATUS);
state->an_complete = !!(status & MT7531_SGMII_AN_COMPLETE);
if (state->interface == PHY_INTERFACE_MODE_SGMII &&
(status & MT7531_SGMII_AN_ENABLE)) {
val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port));
......@@ -3017,16 +3011,44 @@ mt7531_sgmii_pcs_get_state_an(struct mt7530_priv *priv, int port,
return 0;
}
static void
mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port,
struct phylink_link_state *state)
{
unsigned int val;
val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
state->link = !!(val & MT7531_SGMII_LINK_STATUS);
if (!state->link)
return;
state->an_complete = state->link;
if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
state->speed = SPEED_2500;
else
state->speed = SPEED_1000;
state->duplex = DUPLEX_FULL;
state->pause = MLO_PAUSE_NONE;
}
static void mt7531_pcs_get_state(struct phylink_pcs *pcs,
struct phylink_link_state *state)
{
struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
int port = pcs_to_mt753x_pcs(pcs)->port;
if (state->interface == PHY_INTERFACE_MODE_SGMII)
if (state->interface == PHY_INTERFACE_MODE_SGMII) {
mt7531_sgmii_pcs_get_state_an(priv, port, state);
else
state->link = false;
return;
} else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) ||
(state->interface == PHY_INTERFACE_MODE_2500BASEX)) {
mt7531_sgmii_pcs_get_state_inband(priv, port, state);
return;
}
state->link = false;
}
static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
......@@ -3067,6 +3089,8 @@ mt753x_setup(struct dsa_switch *ds)
priv->pcs[i].pcs.ops = priv->info->pcs_ops;
priv->pcs[i].priv = priv;
priv->pcs[i].port = i;
if (mt753x_is_mac_port(i))
priv->pcs[i].pcs.poll = 1;
}
ret = priv->info->sw_setup(ds);
......
......@@ -373,6 +373,7 @@ enum mt7530_vlan_port_acc_frm {
#define MT7531_SGMII_LINK_STATUS BIT(18)
#define MT7531_SGMII_AN_ENABLE BIT(12)
#define MT7531_SGMII_AN_RESTART BIT(9)
#define MT7531_SGMII_AN_COMPLETE BIT(21)
/* Register for SGMII PCS_SPPED_ABILITY */
#define MT7531_PCS_SPEED_ABILITY(p) MT7531_SGMII_REG(p, 0x08)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment