#include "mxl862xx-phylink.h"
void mxl862xx_phylink_get_caps(struct dsa_switch *ds, int port,
-@@ -19,8 +23,393 @@ void mxl862xx_phylink_get_caps(struct ds
+@@ -19,8 +23,410 @@ void mxl862xx_phylink_get_caps(struct ds
config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE | MAC_10 |
MAC_100 | MAC_1000 | MAC_2500FD;
+}
+
+static void mxl862xx_pcs_get_state(struct phylink_pcs *pcs,
++ unsigned int neg_mode,
+ struct phylink_link_state *state)
+{
+ struct mxl862xx_priv *priv = pcs_to_mxl862xx_pcs(pcs)->priv;
+ bmsr = BMSR_LSTATUS;
+ if (st.an_complete)
+ bmsr |= BMSR_ANEGCOMPLETE;
-+ phylink_mii_c22_pcs_decode_state(state, bmsr, lpa);
++ phylink_mii_c22_pcs_decode_state(state, neg_mode, bmsr, lpa);
+
+ /* Override speed/duplex with firmware's resolved values
+ * for downshift detection.
+
+ pcs->pcs.ops = &mxl862xx_pcs_ops;
+ pcs->pcs.poll = true;
++
++ /* Sub-ports only support QSGMII (quad mode with dedicated
++ * PHY_INTERFACE_MODE). Single-lane USXGMII is supported on main
++ * ports only; quad USXGMII is not yet supported as Linux lacks the
++ * infrastructure to signal TDM mode before AN.
++ */
++ __set_bit(PHY_INTERFACE_MODE_QSGMII, pcs->pcs.supported_interfaces);
++ if (port != 9 && port != 13)
++ return;
++
++ __set_bit(PHY_INTERFACE_MODE_SGMII, pcs->pcs.supported_interfaces);
++ __set_bit(PHY_INTERFACE_MODE_1000BASEX, pcs->pcs.supported_interfaces);
++ __set_bit(PHY_INTERFACE_MODE_2500BASEX, pcs->pcs.supported_interfaces);
++ __set_bit(PHY_INTERFACE_MODE_10GBASER, pcs->pcs.supported_interfaces);
++ __set_bit(PHY_INTERFACE_MODE_10GKR, pcs->pcs.supported_interfaces);
++ __set_bit(PHY_INTERFACE_MODE_USXGMII, pcs->pcs.supported_interfaces);
+}
+
+static struct phylink_pcs *
}
static void mxl862xx_phylink_mac_config(struct phylink_config *config,
-@@ -48,4 +437,5 @@ const struct phylink_mac_ops mxl862xx_ph
+@@ -48,4 +454,5 @@ const struct phylink_mac_ops mxl862xx_ph
.mac_config = mxl862xx_phylink_mac_config,
.mac_link_down = mxl862xx_phylink_mac_link_down,
.mac_link_up = mxl862xx_phylink_mac_link_up,
#define MXL862XX_XPCS_PCS_CONFIG (MXL862XX_XPCS_MAGIC + 0x1)
--- a/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
+++ b/drivers/net/dsa/mxl862xx/mxl862xx-phylink.c
-@@ -52,6 +52,155 @@ static struct mxl862xx_pcs *pcs_to_mxl86
+@@ -52,6 +52,156 @@ static struct mxl862xx_pcs *pcs_to_mxl86
return container_of(pcs, struct mxl862xx_pcs, pcs);
}
+}
+
+static void mxl862xx_legacy_pcs_get_state(struct phylink_pcs *pcs,
++ unsigned int neg_mode,
+ struct phylink_link_state *state)
+{
+ struct mxl862xx_priv *priv = pcs_to_mxl862xx_pcs(pcs)->priv;
static int mxl862xx_xpcs_port_id(int port)
{
return port >= 13;
-@@ -389,7 +538,10 @@ void mxl862xx_setup_pcs(struct mxl862xx_
+@@ -390,7 +540,10 @@ void mxl862xx_setup_pcs(struct mxl862xx_
pcs->priv = priv;
pcs->port = port;
+ else
+ pcs->pcs.ops = &mxl862xx_legacy_pcs_ops;
pcs->pcs.poll = true;
- }
-@@ -401,9 +553,6 @@ mxl862xx_phylink_mac_select_pcs(struct p
+ /* Sub-ports only support QSGMII (quad mode with dedicated
+@@ -418,9 +571,6 @@ mxl862xx_phylink_mac_select_pcs(struct p
struct mxl862xx_priv *priv = dp->ds->priv;
int port = dp->index;
switch (port) {
case 9 ... 16:
return &priv->serdes_ports[port - 9].pcs;
-@@ -534,7 +683,7 @@ void mxl862xx_serdes_get_stats(struct ds
+@@ -551,7 +701,7 @@ void mxl862xx_serdes_get_stats(struct ds
}
void mxl862xx_serdes_self_test(struct dsa_switch *ds, int port,