net: ftmac100: add mii read and write callbacks
Register mii_bus with read and write callbacks to allow the 'mii' command to work. Use a timeout of 10 ms to wait for the R/W operations to complete. Signed-off-by: Sergei Antonov <saproj@gmail.com> Reviewed-by: Rick Chen <rick@andestech.com> Tested-by: Rick Chen <rick@andestech.com>
This commit is contained in:
@@ -413,6 +413,7 @@ config FSL_FM_10GEC_REGULAR_NOTATION
|
|||||||
|
|
||||||
config FTMAC100
|
config FTMAC100
|
||||||
bool "Ftmac100 Ethernet Support"
|
bool "Ftmac100 Ethernet Support"
|
||||||
|
select MII
|
||||||
help
|
help
|
||||||
This MAC is present in Andestech SoCs.
|
This MAC is present in Andestech SoCs.
|
||||||
|
|
||||||
|
@@ -12,9 +12,13 @@
|
|||||||
#include <env.h>
|
#include <env.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
|
#include <phy.h>
|
||||||
|
#include <miiphy.h>
|
||||||
|
#include <dm/device_compat.h>
|
||||||
#include <asm/global_data.h>
|
#include <asm/global_data.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
|
#include <linux/iopoll.h>
|
||||||
|
|
||||||
#include "ftmac100.h"
|
#include "ftmac100.h"
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
@@ -23,12 +27,16 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||||||
|
|
||||||
#define ETH_ZLEN 60
|
#define ETH_ZLEN 60
|
||||||
|
|
||||||
|
/* Timeout for a mdio read/write operation */
|
||||||
|
#define FTMAC100_MDIO_TIMEOUT_USEC 10000
|
||||||
|
|
||||||
struct ftmac100_data {
|
struct ftmac100_data {
|
||||||
struct ftmac100_txdes txdes[1];
|
struct ftmac100_txdes txdes[1];
|
||||||
struct ftmac100_rxdes rxdes[PKTBUFSRX];
|
struct ftmac100_rxdes rxdes[PKTBUFSRX];
|
||||||
int rx_index;
|
int rx_index;
|
||||||
const char *name;
|
const char *name;
|
||||||
struct ftmac100 *ftmac100;
|
struct ftmac100 *ftmac100;
|
||||||
|
struct mii_dev *bus;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -322,10 +330,104 @@ static int ftmac100_of_to_plat(struct udevice *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct mii_bus functions
|
||||||
|
*/
|
||||||
|
static int ftmac100_mdio_read(struct mii_dev *bus, int addr, int devad,
|
||||||
|
int reg)
|
||||||
|
{
|
||||||
|
struct ftmac100_data *priv = bus->priv;
|
||||||
|
struct ftmac100 *ftmac100 = priv->ftmac100;
|
||||||
|
int phycr = FTMAC100_PHYCR_PHYAD(addr) |
|
||||||
|
FTMAC100_PHYCR_REGAD(reg) |
|
||||||
|
FTMAC100_PHYCR_MIIRD;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
writel(phycr, &ftmac100->phycr);
|
||||||
|
|
||||||
|
ret = readl_poll_timeout(&ftmac100->phycr, phycr,
|
||||||
|
!(phycr & FTMAC100_PHYCR_MIIRD),
|
||||||
|
FTMAC100_MDIO_TIMEOUT_USEC);
|
||||||
|
if (ret)
|
||||||
|
pr_err("%s: mdio read failed (addr=0x%x reg=0x%x)\n",
|
||||||
|
bus->name, addr, reg);
|
||||||
|
else
|
||||||
|
ret = phycr & FTMAC100_PHYCR_MIIRDATA;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ftmac100_mdio_write(struct mii_dev *bus, int addr, int devad,
|
||||||
|
int reg, u16 value)
|
||||||
|
{
|
||||||
|
struct ftmac100_data *priv = bus->priv;
|
||||||
|
struct ftmac100 *ftmac100 = priv->ftmac100;
|
||||||
|
int phycr = FTMAC100_PHYCR_PHYAD(addr) |
|
||||||
|
FTMAC100_PHYCR_REGAD(reg) |
|
||||||
|
FTMAC100_PHYCR_MIIWR;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
writel(value, &ftmac100->phywdata);
|
||||||
|
writel(phycr, &ftmac100->phycr);
|
||||||
|
|
||||||
|
ret = readl_poll_timeout(&ftmac100->phycr, phycr,
|
||||||
|
!(phycr & FTMAC100_PHYCR_MIIWR),
|
||||||
|
FTMAC100_MDIO_TIMEOUT_USEC);
|
||||||
|
if (ret)
|
||||||
|
pr_err("%s: mdio write failed (addr=0x%x reg=0x%x)\n",
|
||||||
|
bus->name, addr, reg);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ftmac100_mdio_init(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct ftmac100_data *priv = dev_get_priv(dev);
|
||||||
|
struct mii_dev *bus;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
bus = mdio_alloc();
|
||||||
|
if (!bus)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
bus->read = ftmac100_mdio_read;
|
||||||
|
bus->write = ftmac100_mdio_write;
|
||||||
|
bus->priv = priv;
|
||||||
|
|
||||||
|
ret = mdio_register_seq(bus, dev_seq(dev));
|
||||||
|
if (ret) {
|
||||||
|
mdio_free(bus);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->bus = bus;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ftmac100_probe(struct udevice *dev)
|
static int ftmac100_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct ftmac100_data *priv = dev_get_priv(dev);
|
struct ftmac100_data *priv = dev_get_priv(dev);
|
||||||
priv->name = dev->name;
|
priv->name = dev->name;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
ret = ftmac100_mdio_init(dev);
|
||||||
|
if (ret) {
|
||||||
|
dev_err(dev, "Failed to initialize mdiobus: %d\n", ret);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ftmac100_remove(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct ftmac100_data *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
mdio_unregister(priv->bus);
|
||||||
|
mdio_free(priv->bus);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,6 +456,7 @@ U_BOOT_DRIVER(ftmac100) = {
|
|||||||
.bind = ftmac100_bind,
|
.bind = ftmac100_bind,
|
||||||
.of_to_plat = ftmac100_of_to_plat,
|
.of_to_plat = ftmac100_of_to_plat,
|
||||||
.probe = ftmac100_probe,
|
.probe = ftmac100_probe,
|
||||||
|
.remove = ftmac100_remove,
|
||||||
.ops = &ftmac100_ops,
|
.ops = &ftmac100_ops,
|
||||||
.priv_auto = sizeof(struct ftmac100_data),
|
.priv_auto = sizeof(struct ftmac100_data),
|
||||||
.plat_auto = sizeof(struct eth_pdata),
|
.plat_auto = sizeof(struct eth_pdata),
|
||||||
|
@@ -92,6 +92,15 @@ struct ftmac100 {
|
|||||||
#define FTMAC100_MACCR_RX_MULTIPKT (1 << 16)
|
#define FTMAC100_MACCR_RX_MULTIPKT (1 << 16)
|
||||||
#define FTMAC100_MACCR_RX_BROADPKT (1 << 17)
|
#define FTMAC100_MACCR_RX_BROADPKT (1 << 17)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PHY control register
|
||||||
|
*/
|
||||||
|
#define FTMAC100_PHYCR_MIIRDATA 0xffff
|
||||||
|
#define FTMAC100_PHYCR_PHYAD(x) (((x) & 0x1f) << 16)
|
||||||
|
#define FTMAC100_PHYCR_REGAD(x) (((x) & 0x1f) << 21)
|
||||||
|
#define FTMAC100_PHYCR_MIIWR BIT(27)
|
||||||
|
#define FTMAC100_PHYCR_MIIRD BIT(26)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Transmit descriptor, aligned to 16 bytes
|
* Transmit descriptor, aligned to 16 bytes
|
||||||
*/
|
*/
|
||||||
|
Reference in New Issue
Block a user