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:
Sergei Antonov
2023-02-03 22:09:04 +03:00
committed by Tom Rini
parent 9628c3e8b1
commit add396d667
3 changed files with 113 additions and 0 deletions

View File

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

View File

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

View File

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