From: Sergei Antonov <saproj@gmail.com>
To: u-boot@lists.denx.de, joe.hershberger@ni.com, rfried.dev@gmail.com
Cc: bmeng.cn@gmail.com, Sergei Antonov <saproj@gmail.com>
Subject: [PATCH 3/3] net: ftmac100: add mii read and write callbacks
Date: Wed, 28 Dec 2022 14:54:23 +0300 [thread overview]
Message-ID: <20221228115423.1035149-3-saproj@gmail.com> (raw)
In-Reply-To: <20221228115423.1035149-1-saproj@gmail.com>
Register mii_bus with read and write callbacks tp 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>
---
drivers/net/ftmac100.c | 103 +++++++++++++++++++++++++++++++++++++++++
drivers/net/ftmac100.h | 9 ++++
2 files changed, 112 insertions(+)
diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c
index bb39e837bbe7..10395c94f9d1 100644
--- a/drivers/net/ftmac100.c
+++ b/drivers/net/ftmac100.c
@@ -12,9 +12,13 @@
#include <env.h>
#include <malloc.h>
#include <net.h>
+#include <phy.h>
+#include <miiphy.h>
+#include <dm/device_compat.h>
#include <asm/global_data.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/iopoll.h>
#include "ftmac100.h"
#ifdef CONFIG_DM_ETH
@@ -23,12 +27,16 @@ DECLARE_GLOBAL_DATA_PTR;
#endif
#define ETH_ZLEN 60
+/* Timeout for a mdio read/write operation */
+#define FTMAC100_MDIO_TIMEOUT_USEC 10000
+
struct ftmac100_data {
struct ftmac100_txdes txdes[1];
struct ftmac100_rxdes rxdes[PKTBUFSRX];
int rx_index;
const char *name;
struct ftmac100 *ftmac100;
+ struct mii_dev *bus;
};
/*
@@ -408,10 +416,104 @@ static int ftmac100_of_to_plat(struct udevice *dev)
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)
{
struct ftmac100_data *priv = dev_get_priv(dev);
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;
}
@@ -440,6 +542,7 @@ U_BOOT_DRIVER(ftmac100) = {
.bind = ftmac100_bind,
.of_to_plat = ftmac100_of_to_plat,
.probe = ftmac100_probe,
+ .remove = ftmac100_remove,
.ops = &ftmac100_ops,
.priv_auto = sizeof(struct ftmac100_data),
.plat_auto = sizeof(struct eth_pdata),
diff --git a/drivers/net/ftmac100.h b/drivers/net/ftmac100.h
index 75a49f628a69..21d339f835bf 100644
--- a/drivers/net/ftmac100.h
+++ b/drivers/net/ftmac100.h
@@ -92,6 +92,15 @@ struct ftmac100 {
#define FTMAC100_MACCR_RX_MULTIPKT (1 << 16)
#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
*/
--
2.34.1
next prev parent reply other threads:[~2022-12-28 11:55 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-28 11:54 [PATCH 1/3] net: ftmac100: change driver name from nds32_mac to ftmac100 Sergei Antonov
2022-12-28 11:54 ` [PATCH 2/3] net: ftmac100: simplify priv->iobase casting Sergei Antonov
2023-01-10 17:12 ` Ramon Fried
2022-12-28 11:54 ` Sergei Antonov [this message]
2023-01-10 17:13 ` [PATCH 3/3] net: ftmac100: add mii read and write callbacks Ramon Fried
2023-01-19 19:55 ` Sergei Antonov
2023-02-04 0:30 ` Ramon Fried
2023-01-10 17:11 ` [PATCH 1/3] net: ftmac100: change driver name from nds32_mac to ftmac100 Ramon Fried
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221228115423.1035149-3-saproj@gmail.com \
--to=saproj@gmail.com \
--cc=bmeng.cn@gmail.com \
--cc=joe.hershberger@ni.com \
--cc=rfried.dev@gmail.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox