1 From f23eb497c891985126a065f950bc61e9c404bb12 Mon Sep 17 00:00:00 2001
2 From: Lei Wei <quic_leiwei@quicinc.com>
3 Date: Wed, 6 Mar 2024 17:40:52 +0800
4 Subject: [PATCH 12/50] net: pcs: Add 10GBASER interface mode support to IPQ
7 10GBASER mode is used when PCS connects with a 10G SFP module.
9 Change-Id: Ifc3c3bb23811807a9b34e88771aab2c830c2327c
10 Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
12 drivers/net/pcs/pcs-qcom-ipq-uniphy.c | 48 +++++++++++++++++++++++++++
13 1 file changed, 48 insertions(+)
15 diff --git a/drivers/net/pcs/pcs-qcom-ipq-uniphy.c b/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
16 index 837de629d0b2..68a1715531ef 100644
17 --- a/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
18 +++ b/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
20 FIELD_PREP(GENMASK(9, 2), \
21 FIELD_GET(XPCS_INDIRECT_ADDR_L, reg)))
23 +#define XPCS_10GBASER_STS 0x30020
24 +#define XPCS_10GBASER_LINK_STS BIT(12)
26 #define XPCS_DIG_CTRL 0x38000
27 #define XPCS_USXG_ADPT_RESET BIT(10)
28 #define XPCS_USXG_EN BIT(9)
29 @@ -320,6 +323,23 @@ static void ipq_unipcs_get_state_usxgmii(struct ipq_uniphy_pcs *qunipcs,
30 state->duplex = DUPLEX_HALF;
33 +static void ipq_unipcs_get_state_10gbaser(struct ipq_uniphy_pcs *qunipcs,
34 + struct phylink_link_state *state)
38 + val = ipq_unipcs_reg_read32(qunipcs, XPCS_10GBASER_STS);
40 + state->link = !!(val & XPCS_10GBASER_LINK_STS);
45 + state->speed = SPEED_10000;
46 + state->duplex = DUPLEX_FULL;
47 + state->pause |= MLO_PAUSE_TXRX_MASK;
50 static int ipq_unipcs_config_mode(struct ipq_uniphy_pcs *qunipcs,
51 phy_interface_t interface)
53 @@ -354,6 +374,7 @@ static int ipq_unipcs_config_mode(struct ipq_uniphy_pcs *qunipcs,
56 case PHY_INTERFACE_MODE_USXGMII:
57 + case PHY_INTERFACE_MODE_10GBASER:
59 ipq_unipcs_reg_modify32(qunipcs, PCS_MODE_CTRL,
61 @@ -461,6 +482,25 @@ static int ipq_unipcs_config_usxgmii(struct ipq_uniphy_pcs *qunipcs,
65 +static int ipq_unipcs_config_10gbaser(struct ipq_uniphy_pcs *qunipcs,
66 + phy_interface_t interface)
70 + if (qunipcs->interface != interface) {
71 + ret = ipq_unipcs_config_mode(qunipcs, interface);
76 + reset_control_deassert(qunipcs->reset[XPCS_RESET]);
78 + qunipcs->interface = interface;
84 static unsigned long ipq_unipcs_clock_rate_get_gmii(int speed)
86 unsigned long rate = 0;
87 @@ -527,6 +567,7 @@ ipq_unipcs_link_up_clock_rate_set(struct ipq_uniphy_pcs_ch *qunipcs_ch,
88 rate = ipq_unipcs_clock_rate_get_gmii(speed);
90 case PHY_INTERFACE_MODE_USXGMII:
91 + case PHY_INTERFACE_MODE_10GBASER:
92 rate = ipq_unipcs_clock_rate_get_xgmii(speed);
95 @@ -644,6 +685,9 @@ static void ipq_unipcs_get_state(struct phylink_pcs *pcs,
96 case PHY_INTERFACE_MODE_USXGMII:
97 ipq_unipcs_get_state_usxgmii(qunipcs, state);
99 + case PHY_INTERFACE_MODE_10GBASER:
100 + ipq_unipcs_get_state_10gbaser(qunipcs, state);
105 @@ -675,6 +719,8 @@ static int ipq_unipcs_config(struct phylink_pcs *pcs,
106 case PHY_INTERFACE_MODE_USXGMII:
107 return ipq_unipcs_config_usxgmii(qunipcs,
108 neg_mode, interface);
109 + case PHY_INTERFACE_MODE_10GBASER:
110 + return ipq_unipcs_config_10gbaser(qunipcs, interface);
112 dev_err(qunipcs->dev,
113 "interface %s not supported\n", phy_modes(interface));
114 @@ -705,6 +751,8 @@ static void ipq_unipcs_link_up(struct phylink_pcs *pcs,
115 case PHY_INTERFACE_MODE_USXGMII:
116 ipq_unipcs_link_up_config_usxgmii(qunipcs, speed);
118 + case PHY_INTERFACE_MODE_10GBASER:
121 dev_err(qunipcs->dev,
122 "interface %s not supported\n", phy_modes(interface));