With the new addition of the USXGMII link partner ability constants we
can now introduce a phylink helper that decodes the USXGMII word and
populates the appropriate fields in the phylink_link_state structure
based on them.

Signed-off-by: Ioana Ciornei <ioana.cior...@nxp.com>
Reviewed-by: Russell King <rmk+ker...@armlinux.org.uk>
---
Changes in v5:
- none

 drivers/net/phy/phylink.c | 43 +++++++++++++++++++++++++++++++++++++++
 include/linux/phylink.h   |  3 +++
 2 files changed, 46 insertions(+)

diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 32b4bd6a5b55..d7810c908bb3 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -2318,6 +2318,49 @@ static void phylink_decode_sgmii_word(struct 
phylink_link_state *state,
                state->duplex = DUPLEX_HALF;
 }
 
+/**
+ * phylink_decode_usxgmii_word() - decode the USXGMII word from a MAC PCS
+ * @state: a pointer to a struct phylink_link_state.
+ * @lpa: a 16 bit value which stores the USXGMII auto-negotiation word
+ *
+ * Helper for MAC PCS supporting the USXGMII protocol and the auto-negotiation
+ * code word.  Decode the USXGMII code word and populate the corresponding 
fields
+ * (speed, duplex) into the phylink_link_state structure.
+ */
+void phylink_decode_usxgmii_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;
+       case MDIO_USXGMII_2500:
+               state->speed = SPEED_2500;
+               break;
+       case MDIO_USXGMII_5000:
+               state->speed = SPEED_5000;
+               break;
+       case MDIO_USXGMII_10G:
+               state->speed = SPEED_10000;
+               break;
+       default:
+               state->link = false;
+               return;
+       }
+
+       if (lpa & MDIO_USXGMII_FULL_DUPLEX)
+               state->duplex = DUPLEX_FULL;
+       else
+               state->duplex = DUPLEX_HALF;
+}
+EXPORT_SYMBOL_GPL(phylink_decode_usxgmii_word);
+
 /**
  * phylink_mii_c22_pcs_get_state() - read the MAC PCS state
  * @pcs: a pointer to a &struct mdio_device.
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index c36fb41a7d90..d81a714cfbbd 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -490,4 +490,7 @@ void phylink_mii_c22_pcs_an_restart(struct mdio_device 
*pcs);
 
 void phylink_mii_c45_pcs_get_state(struct mdio_device *pcs,
                                   struct phylink_link_state *state);
+
+void phylink_decode_usxgmii_word(struct phylink_link_state *state,
+                                uint16_t lpa);
 #endif
-- 
2.25.1

Reply via email to