123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- From c766e077d927e1775902c18827205ea2ade3a35d Mon Sep 17 00:00:00 2001
- From: Christian Marangi <[email protected]>
- 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 <[email protected]>
- Signed-off-by: Christian Marangi <[email protected]>
- Signed-off-by: David S. Miller <[email protected]>
- ---
- 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
- @@ -2102,8 +2158,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 {
|