net: phy: add sysfs node for reading PHY's registers

Change-Id: I76468dd235a39b6f79699b1cc931c2c7bb7bdbc5
Signed-off-by: Roger Chen <roger.chen@rock-chips.com>
Signed-off-by: David Wu <david.wu@rock-chips.com>
This commit is contained in:
Roger Chen
2016-04-06 18:07:56 +08:00
committed by Tao Huang
parent c80c57be7f
commit ea074eb627
4 changed files with 114 additions and 12 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -24,6 +24,7 @@
#include <linux/pm_runtime.h>
#include <linux/soc/rockchip/rk_vendor_storage.h>
#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;
}

View File

@@ -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: <reg index> <value>\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);