diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile index 24e6145d4eae..be661832cef8 100644 --- a/drivers/net/ethernet/stmicro/stmmac/Makefile +++ b/drivers/net/ethernet/stmicro/stmmac/Makefile @@ -19,7 +19,8 @@ obj-$(CONFIG_DWMAC_MEDIATEK) += dwmac-mediatek.o obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o dwmac-meson8b.o obj-$(CONFIG_DWMAC_OXNAS) += dwmac-oxnas.o obj-$(CONFIG_DWMAC_QCOM_ETHQOS) += dwmac-qcom-ethqos.o -obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rk.o +obj-$(CONFIG_DWMAC_ROCKCHIP) += dwmac-rockchip.o +dwmac-rockchip-objs := dwmac-rk.o dwmac-rk-tool.o obj-$(CONFIG_DWMAC_SOCFPGA) += dwmac-altr-socfpga.o obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk-tool.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk-tool.c index c05ae3100fa8..d45eb0c43cee 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk-tool.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk-tool.c @@ -969,17 +969,17 @@ static int dwmac_rk_alloc_dma_desc_resources(struct stmmac_priv *priv, int ret = -ENOMEM; /* desc dma map */ - lb_priv->dma_rx = dma_zalloc_coherent(priv->device, - sizeof(struct dma_desc), - &lb_priv->dma_rx_phy, - GFP_KERNEL); + lb_priv->dma_rx = dma_alloc_coherent(priv->device, + sizeof(struct dma_desc), + &lb_priv->dma_rx_phy, + GFP_KERNEL); if (!lb_priv->dma_rx) return ret; - lb_priv->dma_tx = dma_zalloc_coherent(priv->device, - sizeof(struct dma_desc), - &lb_priv->dma_tx_phy, - GFP_KERNEL); + lb_priv->dma_tx = dma_alloc_coherent(priv->device, + sizeof(struct dma_desc), + &lb_priv->dma_tx_phy, + GFP_KERNEL); if (!lb_priv->dma_tx) { dma_free_coherent(priv->device, sizeof(struct dma_desc), @@ -1150,7 +1150,7 @@ static int dwmac_rk_init(struct net_device *dev, writel((mode & ~DMA_CONTROL_OSF), priv->ioaddr + DMA_CONTROL); } - stmmac_enable_dma_irq(priv, priv->ioaddr, 0); + stmmac_enable_dma_irq(priv, priv->ioaddr, 0, 1, 1); if (priv->hw->pcs) stmmac_pcs_ctrl_ane(priv, priv->hw, 1, priv->hw->ps, 0); @@ -1167,7 +1167,7 @@ static void dwmac_rk_release(struct net_device *dev, { struct stmmac_priv *priv = netdev_priv(dev); - stmmac_disable_dma_irq(priv, priv->ioaddr, 0); + stmmac_disable_dma_irq(priv, priv->ioaddr, 0, 0, 0); /* Release and free the Rx/Tx resources */ dwmac_rk_free_dma_desc_resources(priv, lb_priv); @@ -1216,7 +1216,9 @@ static int dwmac_rk_loopback_run(struct stmmac_priv *priv, /* wait for phy and controller ready */ usleep_range(100000, 200000); - dwmac_rk_init(ndev, lb_priv); + ret = dwmac_rk_init(ndev, lb_priv); + if (ret) + goto exit_init; dwmac_rk_set_loopback(priv, lb_priv->type, lb_priv->speed, true); if (lb_priv->scan) { @@ -1240,6 +1242,7 @@ out: dwmac_rk_release(ndev, lb_priv); dwmac_rk_set_loopback(priv, lb_priv->type, lb_priv->speed, false); +exit_init: if (ndev_up) ndev->netdev_ops->ndo_open(ndev); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c index 62ef5f315f87..a38daea86479 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c @@ -24,6 +24,7 @@ #include #include #include "stmmac_platform.h" +#include "dwmac-rk-tool.h" struct rk_priv_data; struct rk_gmac_ops { @@ -1560,6 +1561,40 @@ static void rk_fix_speed(void *priv, unsigned int speed) } } +void dwmac_rk_set_rgmii_delayline(struct stmmac_priv *priv, + int tx_delay, int rx_delay) +{ + struct rk_priv_data *bsp_priv = priv->plat->bsp_priv; + + if (bsp_priv->ops->set_to_rgmii) { + bsp_priv->ops->set_to_rgmii(bsp_priv, tx_delay, rx_delay); + bsp_priv->tx_delay = tx_delay; + bsp_priv->rx_delay = rx_delay; + } +} +EXPORT_SYMBOL(dwmac_rk_set_rgmii_delayline); + +void dwmac_rk_get_rgmii_delayline(struct stmmac_priv *priv, + int *tx_delay, int *rx_delay) +{ + struct rk_priv_data *bsp_priv = priv->plat->bsp_priv; + + if (!bsp_priv->ops->set_to_rgmii) + return; + + *tx_delay = bsp_priv->tx_delay; + *rx_delay = bsp_priv->rx_delay; +} +EXPORT_SYMBOL(dwmac_rk_get_rgmii_delayline); + +int dwmac_rk_get_phy_interface(struct stmmac_priv *priv) +{ + struct rk_priv_data *bsp_priv = priv->plat->bsp_priv; + + return bsp_priv->phy_iface; +} +EXPORT_SYMBOL(dwmac_rk_get_phy_interface); + static void rk_get_eth_addr(void *priv, unsigned char *addr) { int ret; @@ -1634,6 +1669,10 @@ static int rk_gmac_probe(struct platform_device *pdev) if (ret) goto err_gmac_powerdown; + ret = dwmac_rk_create_loopback_sysfs(&pdev->dev); + if (ret) + goto err_gmac_powerdown; + return 0; err_gmac_powerdown: @@ -1650,6 +1689,7 @@ static int rk_gmac_remove(struct platform_device *pdev) int ret = stmmac_dvr_remove(&pdev->dev); rk_gmac_powerdown(bsp_priv); + dwmac_rk_remove_loopback_sysfs(&pdev->dev); return ret; } diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 85f3cde5ffd0..1c6c9d146be2 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -512,10 +512,68 @@ phy_has_fixups_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RO(phy_has_fixups); +static ssize_t +phy_registers_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct phy_device *phydev = to_phy_device(dev); + int index; + + for (index = 0; index < 32; index++) + sprintf(buf, "%s%2d: 0x%x\n", buf, index, + phy_read(phydev, index)); + + return strlen(buf); +} + +static ssize_t +phy_registers_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct phy_device *phydev = to_phy_device(dev); + int index = 0, val = 0; + char tmp[32]; + char *data; + + if (count >= sizeof(tmp)) + goto out; + + memset(tmp, 0, sizeof(tmp)); + memcpy(tmp, buf, count); + + data = tmp; + data = strstr(data, " "); + if (!data) + goto out; + *data = 0; + data++; + + if (kstrtoint(tmp, 0, &index) || index >= 32) + goto out; + + if (kstrtoint(data, 0, &val) || val > 0xffff) + goto out; + + pr_info("Set Ethernet PHY register %d to 0x%x\n", (int)index, (int)val); + + phy_write(phydev, index, val); + + return count; + +out: + pr_err("wrong register value input\n"); + pr_err("usage: \n"); + + return count; +} + +static DEVICE_ATTR_RW(phy_registers); + static struct attribute *phy_dev_attrs[] = { &dev_attr_phy_id.attr, &dev_attr_phy_interface.attr, &dev_attr_phy_has_fixups.attr, + &dev_attr_phy_registers.attr, NULL, }; ATTRIBUTE_GROUPS(phy_dev);