mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 04:13:31 +00:00

Refreshed patches for qualcommb/ipq95xx by running make target/linux/refresh after creating a .config containing: CONFIG_TARGET_qualcommbe=y CONFIG_TARGET_qualcommbe_ipq95xx=y CONFIG_TARGET_qualcommbe_ipq95xx_DEVICE_qcom_rdp433=y Signed-off-by: John Audia <therealgraysky@proton.me> Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
199 lines
5.9 KiB
Diff
199 lines
5.9 KiB
Diff
From fcd1c53b460aa39cfd15f842126af62b27a4fad5 Mon Sep 17 00:00:00 2001
|
|
From: Lei Wei <quic_leiwei@quicinc.com>
|
|
Date: Tue, 2 Apr 2024 18:28:42 +0800
|
|
Subject: [PATCH 13/50] net: pcs: Add 2500BASEX interface mode support to IPQ
|
|
UNIPHY PCS driver
|
|
|
|
2500BASEX mode is used when PCS connects with QCA8386 switch in a fixed
|
|
2500M link. It is also used when PCS connectes with QCA8081 PHY which
|
|
works at 2500M link speed. In addition, it can be also used when PCS
|
|
connects with a 2.5G SFP module.
|
|
|
|
Change-Id: I3fe61113c1b3685debc20659736a9488216a029d
|
|
Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
|
|
---
|
|
drivers/net/pcs/pcs-qcom-ipq-uniphy.c | 95 +++++++++++++++++++++++++++
|
|
1 file changed, 95 insertions(+)
|
|
|
|
--- a/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
|
|
+++ b/drivers/net/pcs/pcs-qcom-ipq-uniphy.c
|
|
@@ -25,6 +25,7 @@
|
|
#define PCS_MODE_SGMII FIELD_PREP(PCS_MODE_SEL_MASK, 0x4)
|
|
#define PCS_MODE_QSGMII FIELD_PREP(PCS_MODE_SEL_MASK, 0x1)
|
|
#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_AN_MODE BIT(0)
|
|
|
|
@@ -282,6 +283,24 @@ static void ipq_unipcs_get_state_sgmii(s
|
|
state->pause |= MLO_PAUSE_RX;
|
|
}
|
|
|
|
+static void ipq_unipcs_get_state_2500basex(struct ipq_uniphy_pcs *qunipcs,
|
|
+ int channel,
|
|
+ struct phylink_link_state *state)
|
|
+{
|
|
+ u32 val;
|
|
+
|
|
+ val = ipq_unipcs_reg_read32(qunipcs, PCS_CHANNEL_STS(channel));
|
|
+
|
|
+ state->link = !!(val & PCS_CHANNEL_LINK_STS);
|
|
+
|
|
+ if (!state->link)
|
|
+ return;
|
|
+
|
|
+ state->speed = SPEED_2500;
|
|
+ state->duplex = DUPLEX_FULL;
|
|
+ state->pause |= MLO_PAUSE_TXRX_MASK;
|
|
+}
|
|
+
|
|
static void ipq_unipcs_get_state_usxgmii(struct ipq_uniphy_pcs *qunipcs,
|
|
struct phylink_link_state *state)
|
|
{
|
|
@@ -373,6 +392,12 @@ static int ipq_unipcs_config_mode(struct
|
|
PCS_MODE_SEL_MASK | PCS_MODE_AN_MODE,
|
|
PCS_MODE_PSGMII);
|
|
break;
|
|
+ case PHY_INTERFACE_MODE_2500BASEX:
|
|
+ rate = 312500000;
|
|
+ ipq_unipcs_reg_modify32(qunipcs, PCS_MODE_CTRL,
|
|
+ PCS_MODE_SEL_MASK,
|
|
+ PCS_MODE_SGMII_PLUS);
|
|
+ break;
|
|
case PHY_INTERFACE_MODE_USXGMII:
|
|
case PHY_INTERFACE_MODE_10GBASER:
|
|
rate = 312500000;
|
|
@@ -450,6 +475,22 @@ err:
|
|
return ret;
|
|
}
|
|
|
|
+static int ipq_unipcs_config_2500basex(struct ipq_uniphy_pcs *qunipcs,
|
|
+ phy_interface_t interface)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ if (qunipcs->interface != interface) {
|
|
+ ret = ipq_unipcs_config_mode(qunipcs, interface);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ qunipcs->interface = interface;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int ipq_unipcs_config_usxgmii(struct ipq_uniphy_pcs *qunipcs,
|
|
unsigned int neg_mode,
|
|
phy_interface_t interface)
|
|
@@ -522,6 +563,21 @@ static unsigned long ipq_unipcs_clock_ra
|
|
return rate;
|
|
}
|
|
|
|
+static unsigned long ipq_unipcs_clock_rate_get_gmiiplus(int speed)
|
|
+{
|
|
+ unsigned long rate = 0;
|
|
+
|
|
+ switch (speed) {
|
|
+ case SPEED_2500:
|
|
+ rate = 312500000;
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ return rate;
|
|
+}
|
|
+
|
|
static unsigned long ipq_unipcs_clock_rate_get_xgmii(int speed)
|
|
{
|
|
unsigned long rate = 0;
|
|
@@ -566,6 +622,9 @@ ipq_unipcs_link_up_clock_rate_set(struct
|
|
case PHY_INTERFACE_MODE_PSGMII:
|
|
rate = ipq_unipcs_clock_rate_get_gmii(speed);
|
|
break;
|
|
+ case PHY_INTERFACE_MODE_2500BASEX:
|
|
+ rate = ipq_unipcs_clock_rate_get_gmiiplus(speed);
|
|
+ break;
|
|
case PHY_INTERFACE_MODE_USXGMII:
|
|
case PHY_INTERFACE_MODE_10GBASER:
|
|
rate = ipq_unipcs_clock_rate_get_xgmii(speed);
|
|
@@ -627,6 +686,21 @@ pcs_adapter_reset:
|
|
PCS_CHANNEL_ADPT_RESET);
|
|
}
|
|
|
|
+static void ipq_unipcs_link_up_config_2500basex(struct ipq_uniphy_pcs *qunipcs,
|
|
+ int channel,
|
|
+ int speed)
|
|
+{
|
|
+ /* 2500BASEX do not support autoneg and do not need to
|
|
+ * configure PCS speed, only reset PCS adapter here.
|
|
+ */
|
|
+ ipq_unipcs_reg_modify32(qunipcs, PCS_CHANNEL_CTRL(channel),
|
|
+ PCS_CHANNEL_ADPT_RESET,
|
|
+ 0);
|
|
+ ipq_unipcs_reg_modify32(qunipcs, PCS_CHANNEL_CTRL(channel),
|
|
+ PCS_CHANNEL_ADPT_RESET,
|
|
+ PCS_CHANNEL_ADPT_RESET);
|
|
+}
|
|
+
|
|
static void ipq_unipcs_link_up_config_usxgmii(struct ipq_uniphy_pcs *qunipcs,
|
|
int speed)
|
|
{
|
|
@@ -669,6 +743,17 @@ static void ipq_unipcs_link_up_config_us
|
|
XPCS_USXG_ADPT_RESET);
|
|
}
|
|
|
|
+static int ipq_unipcs_validate(struct phylink_pcs *pcs,
|
|
+ unsigned long *supported,
|
|
+ const struct phylink_link_state *state)
|
|
+{
|
|
+ /* In-band autoneg is not supported for 2500BASEX */
|
|
+ if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
|
|
+ phylink_clear(supported, Autoneg);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static void ipq_unipcs_get_state(struct phylink_pcs *pcs,
|
|
struct phylink_link_state *state)
|
|
{
|
|
@@ -682,6 +767,9 @@ static void ipq_unipcs_get_state(struct
|
|
case PHY_INTERFACE_MODE_PSGMII:
|
|
ipq_unipcs_get_state_sgmii(qunipcs, channel, state);
|
|
break;
|
|
+ case PHY_INTERFACE_MODE_2500BASEX:
|
|
+ ipq_unipcs_get_state_2500basex(qunipcs, channel, state);
|
|
+ break;
|
|
case PHY_INTERFACE_MODE_USXGMII:
|
|
ipq_unipcs_get_state_usxgmii(qunipcs, state);
|
|
break;
|
|
@@ -716,6 +804,8 @@ static int ipq_unipcs_config(struct phyl
|
|
case PHY_INTERFACE_MODE_PSGMII:
|
|
return ipq_unipcs_config_sgmii(qunipcs, channel,
|
|
neg_mode, interface);
|
|
+ case PHY_INTERFACE_MODE_2500BASEX:
|
|
+ return ipq_unipcs_config_2500basex(qunipcs, interface);
|
|
case PHY_INTERFACE_MODE_USXGMII:
|
|
return ipq_unipcs_config_usxgmii(qunipcs,
|
|
neg_mode, interface);
|
|
@@ -748,6 +838,10 @@ static void ipq_unipcs_link_up(struct ph
|
|
ipq_unipcs_link_up_config_sgmii(qunipcs, channel,
|
|
neg_mode, speed);
|
|
break;
|
|
+ case PHY_INTERFACE_MODE_2500BASEX:
|
|
+ ipq_unipcs_link_up_config_2500basex(qunipcs,
|
|
+ channel, speed);
|
|
+ break;
|
|
case PHY_INTERFACE_MODE_USXGMII:
|
|
ipq_unipcs_link_up_config_usxgmii(qunipcs, speed);
|
|
break;
|
|
@@ -761,6 +855,7 @@ static void ipq_unipcs_link_up(struct ph
|
|
}
|
|
|
|
static const struct phylink_pcs_ops ipq_unipcs_phylink_ops = {
|
|
+ .pcs_validate = ipq_unipcs_validate,
|
|
.pcs_get_state = ipq_unipcs_get_state,
|
|
.pcs_config = ipq_unipcs_config,
|
|
.pcs_link_up = ipq_unipcs_link_up,
|