lkml.org 
[lkml]   [2022]   [Jan]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[RFC PATCH v7 14/16] net: dsa: qca8k: cache lo and hi for mdio write
Date
From Documentation, we can cache lo and hi the same way we do with the
page. This massively reduce the mdio write as 3/4 of the time as we only
require to write the lo or hi part for a mdio write.

Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
drivers/net/dsa/qca8k.c | 60 ++++++++++++++++++++++++++++++++---------
drivers/net/dsa/qca8k.h | 5 ++++
2 files changed, 53 insertions(+), 12 deletions(-)

diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index c2f5414033d8..2a43fb9aeef2 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -88,6 +88,42 @@ qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page)
*page = regaddr & 0x3ff;
}

+static int
+qca8k_set_lo(struct mii_bus *bus, int phy_id, u32 regnum,
+ u16 lo, u16 *cached_lo)
+{
+ int ret;
+
+ if (lo == *cached_lo)
+ return 0;
+
+ ret = bus->write(bus, phy_id, regnum, lo);
+ if (ret < 0)
+ dev_err_ratelimited(&bus->dev,
+ "failed to write qca8k 32bit lo register\n");
+
+ *cached_lo = lo;
+ return 0;
+}
+
+static int
+qca8k_set_hi(struct mii_bus *bus, int phy_id, u32 regnum,
+ u16 hi, u16 *cached_hi)
+{
+ int ret;
+
+ if (hi == *cached_hi)
+ return 0;
+
+ ret = bus->write(bus, phy_id, regnum, hi);
+ if (ret < 0)
+ dev_err_ratelimited(&bus->dev,
+ "failed to write qca8k 32bit hi register\n");
+
+ *cached_hi = hi;
+ return 0;
+}
+
static int
qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
{
@@ -111,7 +147,8 @@ qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum, u32 *val)
}

static void
-qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
+qca8k_mii_write32(struct mii_bus *bus, struct qca8k_mdio_cache *cache,
+ int phy_id, u32 regnum, u32 val)
{
u16 lo, hi;
int ret;
@@ -119,12 +156,9 @@ qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val)
lo = val & 0xffff;
hi = (u16)(val >> 16);

- ret = bus->write(bus, phy_id, regnum, lo);
+ ret = qca8k_set_lo(bus, phy_id, regnum, lo, &cache->lo);
if (ret >= 0)
- ret = bus->write(bus, phy_id, regnum + 1, hi);
- if (ret < 0)
- dev_err_ratelimited(&bus->dev,
- "failed to write qca8k 32bit register\n");
+ ret = qca8k_set_hi(bus, phy_id, regnum + 1, hi, &cache->hi);
}

static int
@@ -384,7 +418,7 @@ qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val)
if (ret < 0)
goto exit;

- qca8k_mii_write32(bus, 0x10 | r2, r1, val);
+ qca8k_mii_write32(bus, mdio_cache, 0x10 | r2, r1, val);

exit:
mutex_unlock(&bus->mdio_lock);
@@ -421,7 +455,7 @@ qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_

val &= ~mask;
val |= write_val;
- qca8k_mii_write32(bus, 0x10 | r2, r1, val);
+ qca8k_mii_write32(bus, mdio_cache, 0x10 | r2, r1, val);

exit:
mutex_unlock(&bus->mdio_lock);
@@ -1072,14 +1106,14 @@ qca8k_mdio_write(struct mii_bus *bus, struct qca8k_mdio_cache *cache,
if (ret)
goto exit;

- qca8k_mii_write32(bus, 0x10 | r2, r1, val);
+ qca8k_mii_write32(bus, cache, 0x10 | r2, r1, val);

ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
QCA8K_MDIO_MASTER_BUSY);

exit:
/* even if the busy_wait timeouts try to clear the MASTER_EN */
- qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
+ qca8k_mii_write32(bus, cache, 0x10 | r2, r1, 0);

mutex_unlock(&bus->mdio_lock);

@@ -1109,7 +1143,7 @@ qca8k_mdio_read(struct mii_bus *bus, struct qca8k_mdio_cache *cache,
if (ret)
goto exit;

- qca8k_mii_write32(bus, 0x10 | r2, r1, val);
+ qca8k_mii_write32(bus, cache, 0x10 | r2, r1, val);

ret = qca8k_mdio_busy_wait(bus, QCA8K_MDIO_MASTER_CTRL,
QCA8K_MDIO_MASTER_BUSY);
@@ -1120,7 +1154,7 @@ qca8k_mdio_read(struct mii_bus *bus, struct qca8k_mdio_cache *cache,

exit:
/* even if the busy_wait timeouts try to clear the MASTER_EN */
- qca8k_mii_write32(bus, 0x10 | r2, r1, 0);
+ qca8k_mii_write32(bus, cache, 0x10 | r2, r1, 0);

mutex_unlock(&bus->mdio_lock);

@@ -3007,6 +3041,8 @@ qca8k_sw_probe(struct mdio_device *mdiodev)
}

priv->mdio_cache.page = 0xffff;
+ priv->mdio_cache.lo = 0xffff;
+ priv->mdio_cache.hi = 0xffff;

/* Check the detected switch id */
ret = qca8k_read_switch_id(priv);
diff --git a/drivers/net/dsa/qca8k.h b/drivers/net/dsa/qca8k.h
index 77ffdc7b5aaa..9ecd4d221906 100644
--- a/drivers/net/dsa/qca8k.h
+++ b/drivers/net/dsa/qca8k.h
@@ -369,6 +369,11 @@ struct qca8k_mdio_cache {
* mdio writes
*/
u16 page;
+/* lo and hi can also be cached and from Documentation we can skip one
+ * extra mdio write if lo or hi is didn't change.
+ */
+ u16 lo;
+ u16 hi;
};

struct qca8k_priv {
--
2.33.1
\
 
 \ /
  Last update: 2022-01-23 02:39    [W:0.323 / U:0.004 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site