mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-22 23:12:32 +00:00
a62b1544d1
Backport various QCA8K fixes patch merged upstream. Refresh any changed patches due to backports. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
262 lines
7.5 KiB
Diff
262 lines
7.5 KiB
Diff
From c766e077d927e1775902c18827205ea2ade3a35d Mon Sep 17 00:00:00 2001
|
|
From: Christian Marangi <ansuelsmth@gmail.com>
|
|
Date: Wed, 25 Jan 2023 21:35:17 +0100
|
|
Subject: [PATCH] net: dsa: qca8k: convert to regmap read/write API
|
|
|
|
Convert qca8k to regmap read/write bulk API. The mgmt eth can write up
|
|
to 32 bytes of data at times. Currently we use a custom function to do
|
|
it but regmap now supports declaration of read/write bulk even without a
|
|
bus.
|
|
|
|
Drop the custom function and rework the regmap function to this new
|
|
implementation.
|
|
|
|
Rework the qca8k_fdb_read/write function to use the new
|
|
regmap_bulk_read/write as the old qca8k_bulk_read/write are now dropped.
|
|
|
|
Cc: Mark Brown <broonie@kernel.org>
|
|
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
---
|
|
drivers/net/dsa/qca/qca8k-8xxx.c | 92 ++++++++++++++++++++++++------
|
|
drivers/net/dsa/qca/qca8k-common.c | 47 ++-------------
|
|
drivers/net/dsa/qca/qca8k.h | 3 -
|
|
3 files changed, 77 insertions(+), 65 deletions(-)
|
|
|
|
--- a/drivers/net/dsa/qca/qca8k-8xxx.c
|
|
+++ b/drivers/net/dsa/qca/qca8k-8xxx.c
|
|
@@ -425,16 +425,12 @@ qca8k_regmap_update_bits_eth(struct qca8
|
|
}
|
|
|
|
static int
|
|
-qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
|
|
+qca8k_read_mii(struct qca8k_priv *priv, uint32_t reg, uint32_t *val)
|
|
{
|
|
- struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
|
|
struct mii_bus *bus = priv->bus;
|
|
u16 r1, r2, page;
|
|
int ret;
|
|
|
|
- if (!qca8k_read_eth(priv, reg, val, sizeof(*val)))
|
|
- return 0;
|
|
-
|
|
qca8k_split_addr(reg, &r1, &r2, &page);
|
|
|
|
mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
|
@@ -451,16 +447,12 @@ exit:
|
|
}
|
|
|
|
static int
|
|
-qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val)
|
|
+qca8k_write_mii(struct qca8k_priv *priv, uint32_t reg, uint32_t val)
|
|
{
|
|
- struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
|
|
struct mii_bus *bus = priv->bus;
|
|
u16 r1, r2, page;
|
|
int ret;
|
|
|
|
- if (!qca8k_write_eth(priv, reg, &val, sizeof(val)))
|
|
- return 0;
|
|
-
|
|
qca8k_split_addr(reg, &r1, &r2, &page);
|
|
|
|
mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
|
@@ -477,17 +469,14 @@ exit:
|
|
}
|
|
|
|
static int
|
|
-qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val)
|
|
+qca8k_regmap_update_bits_mii(struct qca8k_priv *priv, uint32_t reg,
|
|
+ uint32_t mask, uint32_t write_val)
|
|
{
|
|
- struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
|
|
struct mii_bus *bus = priv->bus;
|
|
u16 r1, r2, page;
|
|
u32 val;
|
|
int ret;
|
|
|
|
- if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val))
|
|
- return 0;
|
|
-
|
|
qca8k_split_addr(reg, &r1, &r2, &page);
|
|
|
|
mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
|
|
@@ -510,17 +499,84 @@ exit:
|
|
return ret;
|
|
}
|
|
|
|
+static int
|
|
+qca8k_bulk_read(void *ctx, const void *reg_buf, size_t reg_len,
|
|
+ void *val_buf, size_t val_len)
|
|
+{
|
|
+ int i, count = val_len / sizeof(u32), ret;
|
|
+ u32 reg = *(u32 *)reg_buf & U16_MAX;
|
|
+ struct qca8k_priv *priv = ctx;
|
|
+
|
|
+ if (priv->mgmt_master &&
|
|
+ !qca8k_read_eth(priv, reg, val_buf, val_len))
|
|
+ return 0;
|
|
+
|
|
+ /* loop count times and increment reg of 4 */
|
|
+ for (i = 0; i < count; i++, reg += sizeof(u32)) {
|
|
+ ret = qca8k_read_mii(priv, reg, val_buf + i);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int
|
|
+qca8k_bulk_gather_write(void *ctx, const void *reg_buf, size_t reg_len,
|
|
+ const void *val_buf, size_t val_len)
|
|
+{
|
|
+ int i, count = val_len / sizeof(u32), ret;
|
|
+ u32 reg = *(u32 *)reg_buf & U16_MAX;
|
|
+ struct qca8k_priv *priv = ctx;
|
|
+ u32 *val = (u32 *)val_buf;
|
|
+
|
|
+ if (priv->mgmt_master &&
|
|
+ !qca8k_write_eth(priv, reg, val, val_len))
|
|
+ return 0;
|
|
+
|
|
+ /* loop count times, increment reg of 4 and increment val ptr to
|
|
+ * the next value
|
|
+ */
|
|
+ for (i = 0; i < count; i++, reg += sizeof(u32), val++) {
|
|
+ ret = qca8k_write_mii(priv, reg, *val);
|
|
+ if (ret < 0)
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int
|
|
+qca8k_bulk_write(void *ctx, const void *data, size_t bytes)
|
|
+{
|
|
+ return qca8k_bulk_gather_write(ctx, data, sizeof(u16), data + sizeof(u16),
|
|
+ bytes - sizeof(u16));
|
|
+}
|
|
+
|
|
+static int
|
|
+qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val)
|
|
+{
|
|
+ struct qca8k_priv *priv = ctx;
|
|
+
|
|
+ if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val))
|
|
+ return 0;
|
|
+
|
|
+ return qca8k_regmap_update_bits_mii(priv, reg, mask, write_val);
|
|
+}
|
|
+
|
|
static struct regmap_config qca8k_regmap_config = {
|
|
.reg_bits = 16,
|
|
.val_bits = 32,
|
|
.reg_stride = 4,
|
|
.max_register = 0x16ac, /* end MIB - Port6 range */
|
|
- .reg_read = qca8k_regmap_read,
|
|
- .reg_write = qca8k_regmap_write,
|
|
+ .read = qca8k_bulk_read,
|
|
+ .write = qca8k_bulk_write,
|
|
.reg_update_bits = qca8k_regmap_update_bits,
|
|
.rd_table = &qca8k_readable_table,
|
|
.disable_locking = true, /* Locking is handled by qca8k read/write */
|
|
.cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */
|
|
+ .max_raw_read = 32, /* mgmt eth can read/write up to 8 registers at time */
|
|
+ .max_raw_write = 32,
|
|
};
|
|
|
|
static int
|
|
@@ -2091,8 +2147,6 @@ static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
|
|
|
|
static const struct qca8k_info_ops qca8xxx_ops = {
|
|
.autocast_mib = qca8k_get_ethtool_stats_eth,
|
|
- .read_eth = qca8k_read_eth,
|
|
- .write_eth = qca8k_write_eth,
|
|
};
|
|
|
|
static const struct qca8k_match_data qca8327 = {
|
|
--- a/drivers/net/dsa/qca/qca8k-common.c
|
|
+++ b/drivers/net/dsa/qca/qca8k-common.c
|
|
@@ -101,45 +101,6 @@ const struct regmap_access_table qca8k_r
|
|
.n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges),
|
|
};
|
|
|
|
-/* TODO: remove these extra ops when we can support regmap bulk read/write */
|
|
-static int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
|
|
-{
|
|
- int i, count = len / sizeof(u32), ret;
|
|
-
|
|
- if (priv->mgmt_master && priv->info->ops->read_eth &&
|
|
- !priv->info->ops->read_eth(priv, reg, val, len))
|
|
- return 0;
|
|
-
|
|
- for (i = 0; i < count; i++) {
|
|
- ret = regmap_read(priv->regmap, reg + (i * 4), val + i);
|
|
- if (ret < 0)
|
|
- return ret;
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
-/* TODO: remove these extra ops when we can support regmap bulk read/write */
|
|
-static int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
|
|
-{
|
|
- int i, count = len / sizeof(u32), ret;
|
|
- u32 tmp;
|
|
-
|
|
- if (priv->mgmt_master && priv->info->ops->write_eth &&
|
|
- !priv->info->ops->write_eth(priv, reg, val, len))
|
|
- return 0;
|
|
-
|
|
- for (i = 0; i < count; i++) {
|
|
- tmp = val[i];
|
|
-
|
|
- ret = regmap_write(priv->regmap, reg + (i * 4), tmp);
|
|
- if (ret < 0)
|
|
- return ret;
|
|
- }
|
|
-
|
|
- return 0;
|
|
-}
|
|
-
|
|
static int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
|
|
{
|
|
u32 val;
|
|
@@ -154,8 +115,8 @@ static int qca8k_fdb_read(struct qca8k_p
|
|
int ret;
|
|
|
|
/* load the ARL table into an array */
|
|
- ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg,
|
|
- QCA8K_ATU_TABLE_SIZE * sizeof(u32));
|
|
+ ret = regmap_bulk_read(priv->regmap, QCA8K_REG_ATU_DATA0, reg,
|
|
+ QCA8K_ATU_TABLE_SIZE);
|
|
if (ret)
|
|
return ret;
|
|
|
|
@@ -196,8 +157,8 @@ static void qca8k_fdb_write(struct qca8k
|
|
reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]);
|
|
|
|
/* load the array into the ARL table */
|
|
- qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg,
|
|
- QCA8K_ATU_TABLE_SIZE * sizeof(u32));
|
|
+ regmap_bulk_write(priv->regmap, QCA8K_REG_ATU_DATA0, reg,
|
|
+ QCA8K_ATU_TABLE_SIZE);
|
|
}
|
|
|
|
static int qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd,
|
|
--- a/drivers/net/dsa/qca/qca8k.h
|
|
+++ b/drivers/net/dsa/qca/qca8k.h
|
|
@@ -330,9 +330,6 @@ struct qca8k_priv;
|
|
|
|
struct qca8k_info_ops {
|
|
int (*autocast_mib)(struct dsa_switch *ds, int port, u64 *data);
|
|
- /* TODO: remove these extra ops when we can support regmap bulk read/write */
|
|
- int (*read_eth)(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
|
|
- int (*write_eth)(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
|
|
};
|
|
|
|
struct qca8k_match_data {
|