net: phylink: use a dedicated helper to parse usgmii control word
authorMaxime Chevallier <maxime.chevallier@bootlin.com>
Fri, 9 Jun 2023 08:03:05 +0000 (10:03 +0200)
committerJakub Kicinski <kuba@kernel.org>
Mon, 12 Jun 2023 23:51:20 +0000 (16:51 -0700)
Q-USGMII is a derivative of USGMII, that uses a specific formatting for
the control word. The layout is close to the USXGMII control word, but
doesn't support speeds over 1Gbps. Use a dedicated decoding logic for
the USGMII control word, re-using USXGMII definitions but only considering
10/100/1000Mbps speeds

Fixes: 5e61fe157a27 ("net: phy: Introduce QUSGMII PHY mode")
Signed-off-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/phy/phylink.c

index 809e6d5216dc119b96cd3b38c3cbfee1efe742fe..5efdeb59f4b2972131b79453692591da481b8baa 100644 (file)
@@ -3298,6 +3298,41 @@ void phylink_decode_usxgmii_word(struct phylink_link_state *state,
 }
 EXPORT_SYMBOL_GPL(phylink_decode_usxgmii_word);
 
+/**
+ * phylink_decode_usgmii_word() - decode the USGMII word from a MAC PCS
+ * @state: a pointer to a struct phylink_link_state.
+ * @lpa: a 16 bit value which stores the USGMII auto-negotiation word
+ *
+ * Helper for MAC PCS supporting the USGMII protocol and the auto-negotiation
+ * code word.  Decode the USGMII code word and populate the corresponding fields
+ * (speed, duplex) into the phylink_link_state structure. The structure for this
+ * word is the same as the USXGMII word, except it only supports speeds up to
+ * 1Gbps.
+ */
+static void phylink_decode_usgmii_word(struct phylink_link_state *state,
+                                      uint16_t lpa)
+{
+       switch (lpa & MDIO_USXGMII_SPD_MASK) {
+       case MDIO_USXGMII_10:
+               state->speed = SPEED_10;
+               break;
+       case MDIO_USXGMII_100:
+               state->speed = SPEED_100;
+               break;
+       case MDIO_USXGMII_1000:
+               state->speed = SPEED_1000;
+               break;
+       default:
+               state->link = false;
+               return;
+       }
+
+       if (lpa & MDIO_USXGMII_FULL_DUPLEX)
+               state->duplex = DUPLEX_FULL;
+       else
+               state->duplex = DUPLEX_HALF;
+}
+
 /**
  * phylink_mii_c22_pcs_decode_state() - Decode MAC PCS state from MII registers
  * @state: a pointer to a &struct phylink_link_state.
@@ -3335,9 +3370,11 @@ void phylink_mii_c22_pcs_decode_state(struct phylink_link_state *state,
 
        case PHY_INTERFACE_MODE_SGMII:
        case PHY_INTERFACE_MODE_QSGMII:
-       case PHY_INTERFACE_MODE_QUSGMII:
                phylink_decode_sgmii_word(state, lpa);
                break;
+       case PHY_INTERFACE_MODE_QUSGMII:
+               phylink_decode_usgmii_word(state, lpa);
+               break;
 
        default:
                state->link = false;