summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorQuentin Schulz <quentin.schulz@bootlin.com>2018-06-04 12:17:33 +0200
committerJoe Hershberger <joe.hershberger@ni.com>2018-06-13 13:54:17 -0500
commitc61221948c30710f2316b264f61efbf61c92a4aa (patch)
tree7ad2dd5ca585aae9a4b04d3e22d3c54b76d8fb8b /drivers/net
parent3cb51dad0dff5de5f4fff25639d2a88efead0691 (diff)
net: designware: set the PS bit when resetting DMA bus in MII configuration
On the SPEAr600 SoC, which has the dwmac1000 variant of the IP block, the DMA reset never succeeds when a MII PHY is used (no problem with a GMII PHY). The designware_eth_init() function sets the DMAMAC_SRST bit in the DMA_BUS_MODE register, and then polls until this bit clears. When a MII PHY is used, with the current driver, this bit never clears and the driver therefore doesn't work. The reason is that the PS bit of the GMAC_CONTROL register should be correctly configured for the DMA reset to work. When the PS bit is 0, it tells the MAC we have a GMII PHY, when the PS bit is 1, it tells the MAC we have a MII PHY. Doing a DMA reset clears all registers, so the PS bit is cleared as well. This makes the DMA reset work fine with a GMII PHY. However, with MII PHY, the PS bit should be set. We have identified this issue thanks to two SPEAr600 platform: - One equipped with a GMII PHY, with which the existing driver was working fine. - One equipped with a MII PHY, where the current driver fails because the DMA reset times out. Note: Taken from https://www.spinics.net/lists/netdev/msg432578.html Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com> Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/designware.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index cf125210d8..10a87096b7 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -280,6 +280,15 @@ int designware_eth_init(struct dw_eth_dev *priv, u8 *enetaddr)
writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode);
+ /*
+ * When a MII PHY is used, we must set the PS bit for the DMA
+ * reset to succeed.
+ */
+ if (priv->phydev->interface == PHY_INTERFACE_MODE_MII)
+ writel(readl(&mac_p->conf) | MII_PORTSELECT, &mac_p->conf);
+ else
+ writel(readl(&mac_p->conf) & ~MII_PORTSELECT, &mac_p->conf);
+
start = get_timer(0);
while (readl(&dma_p->busmode) & DMAMAC_SRST) {
if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT) {