public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
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 v2 3/3] net: ftmac100: add mii read and write callbacks
Date: Thu, 19 Jan 2023 22:51:16 +0300	[thread overview]
Message-ID: <20230119195116.246711-3-saproj@gmail.com> (raw)
In-Reply-To: <20230119195116.246711-1-saproj@gmail.com>

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

v1 -> v2:
* fix a typo in the description
* add a dependency from MII to Kconfig
* rebase to the current master

 drivers/net/Kconfig    |   1 +
 drivers/net/ftmac100.c | 103 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/ftmac100.h |   9 ++++
 3 files changed, 113 insertions(+)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 7873538cc2df..017931956990 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -406,6 +406,7 @@ config FSL_FM_10GEC_REGULAR_NOTATION
 
 config FTMAC100
 	bool "Ftmac100 Ethernet Support"
+	select MII
 	help
 	  This MAC is present in Andestech SoCs.
 
diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c
index cc88ea17ffe7..1cf109b278cc 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"
 #include <dm.h>
@@ -23,12 +27,16 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #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;
 };
 
 /*
@@ -322,10 +330,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;
 }
 
@@ -354,6 +456,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


  parent reply	other threads:[~2023-01-19 19:52 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-19 19:51 [PATCH v2 1/3] net: ftmac100: change driver name from nds32_mac to ftmac100 Sergei Antonov
2023-01-19 19:51 ` [PATCH v2 2/3] net: ftmac100: simplify priv->iobase casting Sergei Antonov
2023-02-02 22:05   ` Tom Rini
2023-02-03 19:09     ` Sergei Antonov
2023-01-19 19:51 ` Sergei Antonov [this message]
2023-02-04  0:30   ` [PATCH v2 3/3] net: ftmac100: add mii read and write callbacks 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=20230119195116.246711-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