summaryrefslogtreecommitdiff
path: root/drivers/net/dsa/qca8k.c
diff options
context:
space:
mode:
authorJonathan McDowell <noodles@earth.li>2020-06-20 11:31:05 +0100
committerDavid S. Miller <davem@davemloft.net>2020-06-22 15:54:34 -0700
commitf6dadd559886f8cc12d68e98ad77d1da08bfe978 (patch)
tree3143fa5160dcf04ad08b42ecd2b9c26672ba5515 /drivers/net/dsa/qca8k.c
parentb3591c2a366167b5ae985dc3c88a55db3d770cb8 (diff)
net: dsa: qca8k: Improve SGMII interface handling
This patch improves the handling of the SGMII interface on the QCA8K devices. Previously the driver did no configuration of the port, even if it was selected. We now configure it up in the appropriate PHY/MAC/Base-X mode depending on what phylink tells us we are connected to and ensure it is enabled. Tested with a device where the CPU connection is RGMII (i.e. the common current use case) + one where the CPU connection is SGMII. I don't have any devices where the SGMII interface is brought out to something other than the CPU. Signed-off-by: Jonathan McDowell <noodles@earth.li> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/qca8k.c')
-rw-r--r--drivers/net/dsa/qca8k.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index 63b84789f16b1..11d1c290d90f6 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -673,6 +673,9 @@ qca8k_setup(struct dsa_switch *ds)
/* Flush the FDB table */
qca8k_fdb_flush(priv);
+ /* We don't have interrupts for link changes, so we need to poll */
+ ds->pcs_poll = true;
+
return 0;
}
@@ -681,7 +684,7 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
const struct phylink_link_state *state)
{
struct qca8k_priv *priv = ds->priv;
- u32 reg;
+ u32 reg, val;
switch (port) {
case 0: /* 1st CPU port */
@@ -740,6 +743,34 @@ qca8k_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
case PHY_INTERFACE_MODE_1000BASEX:
/* Enable SGMII on the port */
qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN);
+
+ /* Enable/disable SerDes auto-negotiation as necessary */
+ val = qca8k_read(priv, QCA8K_REG_PWS);
+ if (phylink_autoneg_inband(mode))
+ val &= ~QCA8K_PWS_SERDES_AEN_DIS;
+ else
+ val |= QCA8K_PWS_SERDES_AEN_DIS;
+ qca8k_write(priv, QCA8K_REG_PWS, val);
+
+ /* Configure the SGMII parameters */
+ val = qca8k_read(priv, QCA8K_REG_SGMII_CTRL);
+
+ val |= QCA8K_SGMII_EN_PLL | QCA8K_SGMII_EN_RX |
+ QCA8K_SGMII_EN_TX | QCA8K_SGMII_EN_SD;
+
+ if (dsa_is_cpu_port(ds, port)) {
+ /* CPU port, we're talking to the CPU MAC, be a PHY */
+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
+ val |= QCA8K_SGMII_MODE_CTRL_PHY;
+ } else if (state->interface == PHY_INTERFACE_MODE_SGMII) {
+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
+ val |= QCA8K_SGMII_MODE_CTRL_MAC;
+ } else if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
+ val &= ~QCA8K_SGMII_MODE_CTRL_MASK;
+ val |= QCA8K_SGMII_MODE_CTRL_BASEX;
+ }
+
+ qca8k_write(priv, QCA8K_REG_SGMII_CTRL, val);
break;
default:
dev_err(ds->dev, "xMII mode %s not supported for port %d\n",