d444553452ce95db2de64a6ab7baf294520b0c3c
[openwrt/staging/linusw.git] /
1 From 8bca458990dd8c6d001b2fb52063aa18e8ca7444 Mon Sep 17 00:00:00 2001
2 From: Christian 'Ansuel' Marangi <ansuelsmth@gmail.com>
3 Date: Tue, 14 Jun 2022 13:22:28 +0200
4 Subject: [PATCH 2/2] net: ethernet: stmmac: reset force speed bit for ipq806x
5
6 Some bootloader may set the force speed regs even if the actual
7 interface should use autonegotiation between PCS and PHY.
8 This cause the complete malfuction of the interface.
9
10 To fix this correctly reset the force speed regs if a fixed-link is not
11 defined in the DTS. With a fixed-link node correctly configure the
12 forced speed regs to handle any misconfiguration by the bootloader.
13
14 Reported-by: Mark Mentovai <mark@moxienet.com>
15 Co-developed-by: Mark Mentovai <mark@moxienet.com>
16 Signed-off-by: Mark Mentovai <mark@moxienet.com>
17 Signed-off-by: Christian 'Ansuel' Marangi <ansuelsmth@gmail.com>
18 Link: https://lore.kernel.org/r/20220614112228.1998-2-ansuelsmth@gmail.com
19 Signed-off-by: Paolo Abeni <pabeni@redhat.com>
20 ---
21 .../ethernet/stmicro/stmmac/dwmac-ipq806x.c | 64 +++++++++++++++++++
22 1 file changed, 64 insertions(+)
23
24 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
25 +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
26 @@ -66,6 +66,17 @@
27 #define NSS_COMMON_CLK_DIV_SGMII_100 4
28 #define NSS_COMMON_CLK_DIV_SGMII_10 49
29
30 +#define QSGMII_PCS_ALL_CH_CTL 0x80
31 +#define QSGMII_PCS_CH_SPEED_FORCE BIT(1)
32 +#define QSGMII_PCS_CH_SPEED_10 0x0
33 +#define QSGMII_PCS_CH_SPEED_100 BIT(2)
34 +#define QSGMII_PCS_CH_SPEED_1000 BIT(3)
35 +#define QSGMII_PCS_CH_SPEED_MASK (QSGMII_PCS_CH_SPEED_FORCE | \
36 + QSGMII_PCS_CH_SPEED_10 | \
37 + QSGMII_PCS_CH_SPEED_100 | \
38 + QSGMII_PCS_CH_SPEED_1000)
39 +#define QSGMII_PCS_CH_SPEED_SHIFT(x) ((x) * 4)
40 +
41 #define QSGMII_PCS_CAL_LCKDT_CTL 0x120
42 #define QSGMII_PCS_CAL_LCKDT_CTL_RST BIT(19)
43
44 @@ -253,6 +264,55 @@ static void ipq806x_gmac_fix_mac_speed(v
45 ipq806x_gmac_set_speed(gmac, speed);
46 }
47
48 +static int
49 +ipq806x_gmac_configure_qsgmii_pcs_speed(struct ipq806x_gmac *gmac)
50 +{
51 + struct platform_device *pdev = gmac->pdev;
52 + struct device *dev = &pdev->dev;
53 + struct device_node *dn;
54 + int link_speed;
55 + int val = 0;
56 + int ret;
57 +
58 + /* Some bootloader may apply wrong configuration and cause
59 + * not functioning port. If fixed link is not set,
60 + * reset the force speed bit.
61 + */
62 + if (!of_phy_is_fixed_link(pdev->dev.of_node))
63 + goto write;
64 +
65 + dn = of_get_child_by_name(pdev->dev.of_node, "fixed-link");
66 + ret = of_property_read_u32(dn, "speed", &link_speed);
67 + of_node_put(dn);
68 + if (ret) {
69 + dev_err(dev, "found fixed-link node with no speed");
70 + return ret;
71 + }
72 +
73 + val = QSGMII_PCS_CH_SPEED_FORCE;
74 +
75 + switch (link_speed) {
76 + case SPEED_1000:
77 + val |= QSGMII_PCS_CH_SPEED_1000;
78 + break;
79 + case SPEED_100:
80 + val |= QSGMII_PCS_CH_SPEED_100;
81 + break;
82 + case SPEED_10:
83 + val |= QSGMII_PCS_CH_SPEED_10;
84 + break;
85 + }
86 +
87 +write:
88 + regmap_update_bits(gmac->qsgmii_csr, QSGMII_PCS_ALL_CH_CTL,
89 + QSGMII_PCS_CH_SPEED_MASK <<
90 + QSGMII_PCS_CH_SPEED_SHIFT(gmac->id),
91 + val <<
92 + QSGMII_PCS_CH_SPEED_SHIFT(gmac->id));
93 +
94 + return 0;
95 +}
96 +
97 static const struct soc_device_attribute ipq806x_gmac_soc_v1[] = {
98 {
99 .revision = "1.*",
100 @@ -400,6 +460,10 @@ static int ipq806x_gmac_probe(struct pla
101 err = ipq806x_gmac_configure_qsgmii_params(gmac);
102 if (err)
103 goto err_remove_config_dt;
104 +
105 + err = ipq806x_gmac_configure_qsgmii_pcs_speed(gmac);
106 + if (err)
107 + goto err_remove_config_dt;
108 }
109
110 plat_dat->has_gmac = true;