mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 03:15:31 +09:00
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:
@@ -19,7 +19,8 @@ obj-$(CONFIG_DWMAC_MEDIATEK) += dwmac-mediatek.o
|
|||||||
obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o dwmac-meson8b.o
|
obj-$(CONFIG_DWMAC_MESON) += dwmac-meson.o dwmac-meson8b.o
|
||||||
obj-$(CONFIG_DWMAC_OXNAS) += dwmac-oxnas.o
|
obj-$(CONFIG_DWMAC_OXNAS) += dwmac-oxnas.o
|
||||||
obj-$(CONFIG_DWMAC_QCOM_ETHQOS) += dwmac-qcom-ethqos.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_SOCFPGA) += dwmac-altr-socfpga.o
|
||||||
obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
|
obj-$(CONFIG_DWMAC_STI) += dwmac-sti.o
|
||||||
obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o
|
obj-$(CONFIG_DWMAC_STM32) += dwmac-stm32.o
|
||||||
|
|||||||
@@ -969,17 +969,17 @@ static int dwmac_rk_alloc_dma_desc_resources(struct stmmac_priv *priv,
|
|||||||
int ret = -ENOMEM;
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
/* desc dma map */
|
/* desc dma map */
|
||||||
lb_priv->dma_rx = dma_zalloc_coherent(priv->device,
|
lb_priv->dma_rx = dma_alloc_coherent(priv->device,
|
||||||
sizeof(struct dma_desc),
|
sizeof(struct dma_desc),
|
||||||
&lb_priv->dma_rx_phy,
|
&lb_priv->dma_rx_phy,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!lb_priv->dma_rx)
|
if (!lb_priv->dma_rx)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
lb_priv->dma_tx = dma_zalloc_coherent(priv->device,
|
lb_priv->dma_tx = dma_alloc_coherent(priv->device,
|
||||||
sizeof(struct dma_desc),
|
sizeof(struct dma_desc),
|
||||||
&lb_priv->dma_tx_phy,
|
&lb_priv->dma_tx_phy,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!lb_priv->dma_tx) {
|
if (!lb_priv->dma_tx) {
|
||||||
dma_free_coherent(priv->device,
|
dma_free_coherent(priv->device,
|
||||||
sizeof(struct dma_desc),
|
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);
|
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)
|
if (priv->hw->pcs)
|
||||||
stmmac_pcs_ctrl_ane(priv, priv->hw, 1, priv->hw->ps, 0);
|
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);
|
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 */
|
/* Release and free the Rx/Tx resources */
|
||||||
dwmac_rk_free_dma_desc_resources(priv, lb_priv);
|
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 */
|
/* wait for phy and controller ready */
|
||||||
usleep_range(100000, 200000);
|
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);
|
dwmac_rk_set_loopback(priv, lb_priv->type, lb_priv->speed, true);
|
||||||
|
|
||||||
if (lb_priv->scan) {
|
if (lb_priv->scan) {
|
||||||
@@ -1240,6 +1242,7 @@ out:
|
|||||||
dwmac_rk_release(ndev, lb_priv);
|
dwmac_rk_release(ndev, lb_priv);
|
||||||
dwmac_rk_set_loopback(priv, lb_priv->type, lb_priv->speed, false);
|
dwmac_rk_set_loopback(priv, lb_priv->type, lb_priv->speed, false);
|
||||||
|
|
||||||
|
exit_init:
|
||||||
if (ndev_up)
|
if (ndev_up)
|
||||||
ndev->netdev_ops->ndo_open(ndev);
|
ndev->netdev_ops->ndo_open(ndev);
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include <linux/pm_runtime.h>
|
#include <linux/pm_runtime.h>
|
||||||
#include <linux/soc/rockchip/rk_vendor_storage.h>
|
#include <linux/soc/rockchip/rk_vendor_storage.h>
|
||||||
#include "stmmac_platform.h"
|
#include "stmmac_platform.h"
|
||||||
|
#include "dwmac-rk-tool.h"
|
||||||
|
|
||||||
struct rk_priv_data;
|
struct rk_priv_data;
|
||||||
struct rk_gmac_ops {
|
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)
|
static void rk_get_eth_addr(void *priv, unsigned char *addr)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -1634,6 +1669,10 @@ static int rk_gmac_probe(struct platform_device *pdev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto err_gmac_powerdown;
|
goto err_gmac_powerdown;
|
||||||
|
|
||||||
|
ret = dwmac_rk_create_loopback_sysfs(&pdev->dev);
|
||||||
|
if (ret)
|
||||||
|
goto err_gmac_powerdown;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_gmac_powerdown:
|
err_gmac_powerdown:
|
||||||
@@ -1650,6 +1689,7 @@ static int rk_gmac_remove(struct platform_device *pdev)
|
|||||||
int ret = stmmac_dvr_remove(&pdev->dev);
|
int ret = stmmac_dvr_remove(&pdev->dev);
|
||||||
|
|
||||||
rk_gmac_powerdown(bsp_priv);
|
rk_gmac_powerdown(bsp_priv);
|
||||||
|
dwmac_rk_remove_loopback_sysfs(&pdev->dev);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -512,10 +512,68 @@ phy_has_fixups_show(struct device *dev, struct device_attribute *attr,
|
|||||||
}
|
}
|
||||||
static DEVICE_ATTR_RO(phy_has_fixups);
|
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[] = {
|
static struct attribute *phy_dev_attrs[] = {
|
||||||
&dev_attr_phy_id.attr,
|
&dev_attr_phy_id.attr,
|
||||||
&dev_attr_phy_interface.attr,
|
&dev_attr_phy_interface.attr,
|
||||||
&dev_attr_phy_has_fixups.attr,
|
&dev_attr_phy_has_fixups.attr,
|
||||||
|
&dev_attr_phy_registers.attr,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
ATTRIBUTE_GROUPS(phy_dev);
|
ATTRIBUTE_GROUPS(phy_dev);
|
||||||
|
|||||||
Reference in New Issue
Block a user