From 07f9bb8eb006e9664d651089a1f422d045e093e3 Mon Sep 17 00:00:00 2001 From: Lei Wei Date: Tue, 9 Apr 2024 01:07:22 +0800 Subject: [PATCH] net: pcs: Add 1000BASEX interface mode support to IPQ UNIPHY PCS driver 1000BASEX is used when PCS connects with a 1G SFP module. Change-Id: Ied7298de3c1ecba74e6457a07fdd6b3ceab79728 Signed-off-by: Lei Wei Signed-off-by: Alexandru Gagniuc --- drivers/net/pcs/pcs-qcom-ipq9574.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) --- a/drivers/net/pcs/pcs-qcom-ipq9574.c +++ b/drivers/net/pcs/pcs-qcom-ipq9574.c @@ -31,6 +31,9 @@ #define PCS_MODE_PSGMII FIELD_PREP(PCS_MODE_SEL_MASK, 0x2) #define PCS_MODE_SGMII_PLUS FIELD_PREP(PCS_MODE_SEL_MASK, 0x8) #define PCS_MODE_XPCS FIELD_PREP(PCS_MODE_SEL_MASK, 0x10) +#define PCS_MODE_SGMII_CTRL_MASK GENMASK(6, 4) +#define PCS_MODE_SGMII_CTRL_1000BASEX FIELD_PREP(PCS_MODE_SGMII_CTRL_MASK, \ + 0x0) #define PCS_MII_CTRL(x) (0x480 + 0x18 * (x)) #define PCS_MII_ADPT_RESET BIT(11) @@ -283,7 +286,7 @@ static int ipq_pcs_config_mode(struct ip phy_interface_t interface) { unsigned long rate = 125000000; - unsigned int val; + unsigned int val, mask = PCS_MODE_SEL_MASK; int ret; /* Assert XPCS reset */ @@ -297,6 +300,10 @@ static int ipq_pcs_config_mode(struct ip case PHY_INTERFACE_MODE_QSGMII: val = PCS_MODE_QSGMII; break; + case PHY_INTERFACE_MODE_1000BASEX: + mask |= PCS_MODE_SGMII_CTRL_MASK; + val = PCS_MODE_SGMII | PCS_MODE_SGMII_CTRL_1000BASEX; + break; case PHY_INTERFACE_MODE_2500BASEX: val = PCS_MODE_SGMII_PLUS; rate = 312500000; @@ -316,7 +323,7 @@ static int ipq_pcs_config_mode(struct ip } ret = regmap_update_bits(qpcs->regmap, PCS_MODE_CTRL, - PCS_MODE_SEL_MASK, val); + mask, val); if (ret) return ret; @@ -523,6 +530,7 @@ ipq_unipcs_link_up_clock_rate_set(struct case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_QSGMII: case PHY_INTERFACE_MODE_PSGMII: + case PHY_INTERFACE_MODE_1000BASEX: rate = ipq_unipcs_clock_rate_get_gmii(speed); break; case PHY_INTERFACE_MODE_2500BASEX: @@ -657,6 +665,7 @@ static int ipq_pcs_validate(struct phyli case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_QSGMII: case PHY_INTERFACE_MODE_10GBASER: + case PHY_INTERFACE_MODE_1000BASEX: return 0; case PHY_INTERFACE_MODE_2500BASEX: /* In-band autoneg is not supported for 2500BASEX */ @@ -731,6 +740,10 @@ static void ipq_pcs_get_state(struct phy case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_QSGMII: case PHY_INTERFACE_MODE_PSGMII: + case PHY_INTERFACE_MODE_1000BASEX: + /* SGMII and 1000BASEX in-band autoneg word format are decoded + * by PCS hardware and both placed to the same status register. + */ ipq_pcs_get_state_sgmii(qpcs, index, state); break; case PHY_INTERFACE_MODE_2500BASEX: @@ -768,6 +781,7 @@ static int ipq_pcs_config(struct phylink case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_QSGMII: case PHY_INTERFACE_MODE_PSGMII: + case PHY_INTERFACE_MODE_1000BASEX: return ipq_pcs_config_sgmii(qpcs, index, neg_mode, interface); case PHY_INTERFACE_MODE_2500BASEX: return ipq_unipcs_config_2500basex(qpcs, interface); @@ -800,6 +814,7 @@ static void ipq_pcs_link_up(struct phyli case PHY_INTERFACE_MODE_SGMII: case PHY_INTERFACE_MODE_QSGMII: case PHY_INTERFACE_MODE_PSGMII: + case PHY_INTERFACE_MODE_1000BASEX: ret = ipq_pcs_link_up_config_sgmii(qpcs, index, neg_mode, speed); break;