[openwrt/openwrt] ipq806x: dwmac: fix GMACs connected via SGMII fixed-link

LEDE Commits lede-commits at lists.infradead.org
Sat May 8 09:45:59 PDT 2021


ynezz pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/d62825dd77b3990b8ff2cf341ff3a8b16f4883d1

commit d62825dd77b3990b8ff2cf341ff3a8b16f4883d1
Author: Mark Mentovai <mark at moxienet.com>
AuthorDate: Sat May 8 11:00:55 2021 -0400

    ipq806x: dwmac: fix GMACs connected via SGMII fixed-link
    
    fa731838c524 cleared the forced speed in the QSGMII PCS_ALL_CH_CTL
    register during probe, but this is only correct for GMACs that are not
    configured with fixed-link. This prevented GMACs configured with both
    phy-mode = "sgmii" and fixed-link from working properly, as discussed at
    https://github.com/openwrt/openwrt/pull/3954#issuecomment-834625090 and
    the comments that follow. Notably, this prevented all communication
    between gmac2 and the switch on the Netgear R7800.
    
    The correct behavior is to set the QSGMII PCS_ALL_CH_CTL register by
    considering the gmac's fixed-link child, setting the speed as directed by
    fixed-link if present, and otherwise clearing it as was done previously.
    
    Fixes: fa731838c524 ("ipq806x: dwmac: clear forced speed during probe")
    Signed-off-by: Mark Mentovai <mark at moxienet.com>
    Tested-by: Hannu Nyman <hannu.nyman at iki.fi>
    Run-tested: ipq806x/ubnt,unifi-ac-hd, ipq806x/netgear,r7800
    Cc: Petr Štetiar <ynezz at true.cz>
    Cc: Ansuel Smith <ansuelsmth at gmail.com>
    Tested-by:  Ansuel Smith <ansuelsmth at gmail.com>
---
 .../100-dwmac-ipq806x-qsgmii-pcs-all-ch-ctl.patch  | 62 +++++++++++++++++++---
 1 file changed, 56 insertions(+), 6 deletions(-)

diff --git a/target/linux/ipq806x/patches-5.4/100-dwmac-ipq806x-qsgmii-pcs-all-ch-ctl.patch b/target/linux/ipq806x/patches-5.4/100-dwmac-ipq806x-qsgmii-pcs-all-ch-ctl.patch
index 6cdbf4d3dc..3c497ead6a 100644
--- a/target/linux/ipq806x/patches-5.4/100-dwmac-ipq806x-qsgmii-pcs-all-ch-ctl.patch
+++ b/target/linux/ipq806x/patches-5.4/100-dwmac-ipq806x-qsgmii-pcs-all-ch-ctl.patch
@@ -18,16 +18,66 @@
  #define QSGMII_PCS_CAL_LCKDT_CTL		0x120
  #define QSGMII_PCS_CAL_LCKDT_CTL_RST		BIT(19)
  
-@@ -345,6 +356,12 @@ static int ipq806x_gmac_probe(struct pla
+@@ -241,6 +252,36 @@ static void ipq806x_gmac_fix_mac_speed(v
+ 	ipq806x_gmac_set_speed(gmac, speed);
+ }
+ 
++static int
++ipq806x_gmac_get_qsgmii_pcs_speed_val(struct platform_device *pdev) {
++	struct device_node *fixed_link_node;
++	int rv;
++	int fixed_link_speed;
++
++	if (!of_phy_is_fixed_link(pdev->dev.of_node))
++		return 0;
++
++	fixed_link_node = of_get_child_by_name(pdev->dev.of_node, "fixed-link");
++	if (!fixed_link_node)
++		return -1;
++
++	rv = of_property_read_u32(fixed_link_node, "speed", &fixed_link_speed);
++	of_node_put(fixed_link_node);
++	if (rv)
++		return -1;
++
++	switch (fixed_link_speed) {
++	case SPEED_1000:
++		return QSGMII_PCS_CH_SPEED_FORCE | QSGMII_PCS_CH_SPEED_1000;
++	case SPEED_100:
++		return QSGMII_PCS_CH_SPEED_FORCE | QSGMII_PCS_CH_SPEED_100;
++	case SPEED_10:
++		return QSGMII_PCS_CH_SPEED_FORCE | QSGMII_PCS_CH_SPEED_10;
++	}
++
++	return -1;
++}
++
+ static int ipq806x_gmac_probe(struct platform_device *pdev)
+ {
+ 	struct plat_stmmacenet_data *plat_dat;
+@@ -249,6 +290,7 @@ static int ipq806x_gmac_probe(struct pla
+ 	struct ipq806x_gmac *gmac;
+ 	int val;
+ 	int err;
++	int qsgmii_pcs_speed;
+ 
+ 	val = stmmac_get_platform_resources(pdev, &stmmac_res);
+ 	if (val)
+@@ -345,6 +387,17 @@ static int ipq806x_gmac_probe(struct pla
  			     0x1ul << QSGMII_PHY_RX_INPUT_EQU_OFFSET |
  			     0x2ul << QSGMII_PHY_CDR_PI_SLEW_OFFSET |
  			     0xCul << QSGMII_PHY_TX_DRV_AMP_OFFSET);
 +
-+		regmap_update_bits(gmac->qsgmii_csr,
-+				   QSGMII_PCS_ALL_CH_CTL,
-+				   QSGMII_PCS_CH_SPEED_MASK <<
-+				    QSGMII_PCS_CH_SPEED_SHIFT(gmac->id),
-+				   0);
++		qsgmii_pcs_speed = ipq806x_gmac_get_qsgmii_pcs_speed_val(pdev);
++		if (qsgmii_pcs_speed != -1) {
++			regmap_update_bits(
++			    gmac->qsgmii_csr,
++			    QSGMII_PCS_ALL_CH_CTL,
++			    QSGMII_PCS_CH_SPEED_MASK <<
++				QSGMII_PCS_CH_SPEED_SHIFT(gmac->id),
++			    qsgmii_pcs_speed <<
++				QSGMII_PCS_CH_SPEED_SHIFT(gmac->id));
++		}
  	}
  
  	plat_dat->has_gmac = true;



More information about the lede-commits mailing list