ipq806x: dwmac: clear forced speed during probe
On a Ubiquiti UniFi AC HD (ubnt,unifi-ac-hd, UAP-AC-HD, UAP301), a
forced speed on gmac1 is set in the QSGMII PCS_ALL_CH_CTL register,
presumably by the bootloader (4.3.28), preventing the interface from
being usable. The QSDK NSS GMAC driver takes care to clear the forced
speed in nss_gmac_qsgmii_dev_init
(https://source.codeaurora.org/quic/qsdk/oss/lklm/nss-gmac/tree/ipq806x/nss_gmac_init.c?h=nss
at d5bb14925861).
gmac1 is connected to the port on the device labeled SECONDARY, and is
currently eth0 but will be switched to eth1 by a subsequent patch. By
clearing the QSGMII PCS forced speed during dwmac initialization when
SGMII is in use, this port becomes usable.
This patch is upstreamable, and will be sent upstream after successful
testing in OpenWrt.
Signed-off-by: Mark Mentovai <mark@moxienet.com>
Build-tested: ipq806x/ubnt,unifi-ac-hd
Run-tested: ipq806x/ubnt,unifi-ac-hd
2021-04-12 15:59:18 +00:00
|
|
|
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
|
|
|
|
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-ipq806x.c
|
|
|
|
@@ -64,6 +64,17 @@
|
|
|
|
#define NSS_COMMON_CLK_DIV_SGMII_100 4
|
|
|
|
#define NSS_COMMON_CLK_DIV_SGMII_10 49
|
|
|
|
|
|
|
|
+#define QSGMII_PCS_ALL_CH_CTL 0x80
|
|
|
|
+#define QSGMII_PCS_CH_SPEED_FORCE 0x2
|
|
|
|
+#define QSGMII_PCS_CH_SPEED_10 0x0
|
|
|
|
+#define QSGMII_PCS_CH_SPEED_100 0x4
|
|
|
|
+#define QSGMII_PCS_CH_SPEED_1000 0x8
|
|
|
|
+#define QSGMII_PCS_CH_SPEED_MASK (QSGMII_PCS_CH_SPEED_FORCE | \
|
|
|
|
+ QSGMII_PCS_CH_SPEED_10 | \
|
|
|
|
+ QSGMII_PCS_CH_SPEED_100 | \
|
|
|
|
+ QSGMII_PCS_CH_SPEED_1000)
|
|
|
|
+#define QSGMII_PCS_CH_SPEED_SHIFT(x) (x * 4)
|
|
|
|
+
|
|
|
|
#define QSGMII_PCS_CAL_LCKDT_CTL 0x120
|
|
|
|
#define QSGMII_PCS_CAL_LCKDT_CTL_RST BIT(19)
|
|
|
|
|
2021-05-08 15:00:55 +00:00
|
|
|
@@ -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
|
ipq806x: dwmac: clear forced speed during probe
On a Ubiquiti UniFi AC HD (ubnt,unifi-ac-hd, UAP-AC-HD, UAP301), a
forced speed on gmac1 is set in the QSGMII PCS_ALL_CH_CTL register,
presumably by the bootloader (4.3.28), preventing the interface from
being usable. The QSDK NSS GMAC driver takes care to clear the forced
speed in nss_gmac_qsgmii_dev_init
(https://source.codeaurora.org/quic/qsdk/oss/lklm/nss-gmac/tree/ipq806x/nss_gmac_init.c?h=nss
at d5bb14925861).
gmac1 is connected to the port on the device labeled SECONDARY, and is
currently eth0 but will be switched to eth1 by a subsequent patch. By
clearing the QSGMII PCS forced speed during dwmac initialization when
SGMII is in use, this port becomes usable.
This patch is upstreamable, and will be sent upstream after successful
testing in OpenWrt.
Signed-off-by: Mark Mentovai <mark@moxienet.com>
Build-tested: ipq806x/ubnt,unifi-ac-hd
Run-tested: ipq806x/ubnt,unifi-ac-hd
2021-04-12 15:59:18 +00:00
|
|
|
0x1ul << QSGMII_PHY_RX_INPUT_EQU_OFFSET |
|
|
|
|
0x2ul << QSGMII_PHY_CDR_PI_SLEW_OFFSET |
|
|
|
|
0xCul << QSGMII_PHY_TX_DRV_AMP_OFFSET);
|
|
|
|
+
|
2021-05-08 15:00:55 +00:00
|
|
|
+ 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));
|
|
|
|
+ }
|
ipq806x: dwmac: clear forced speed during probe
On a Ubiquiti UniFi AC HD (ubnt,unifi-ac-hd, UAP-AC-HD, UAP301), a
forced speed on gmac1 is set in the QSGMII PCS_ALL_CH_CTL register,
presumably by the bootloader (4.3.28), preventing the interface from
being usable. The QSDK NSS GMAC driver takes care to clear the forced
speed in nss_gmac_qsgmii_dev_init
(https://source.codeaurora.org/quic/qsdk/oss/lklm/nss-gmac/tree/ipq806x/nss_gmac_init.c?h=nss
at d5bb14925861).
gmac1 is connected to the port on the device labeled SECONDARY, and is
currently eth0 but will be switched to eth1 by a subsequent patch. By
clearing the QSGMII PCS forced speed during dwmac initialization when
SGMII is in use, this port becomes usable.
This patch is upstreamable, and will be sent upstream after successful
testing in OpenWrt.
Signed-off-by: Mark Mentovai <mark@moxienet.com>
Build-tested: ipq806x/ubnt,unifi-ac-hd
Run-tested: ipq806x/ubnt,unifi-ac-hd
2021-04-12 15:59:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
plat_dat->has_gmac = true;
|