0a631a09c1daa5a43e6e3aebf3262e093f3ba561
[openwrt/staging/jow.git] / target / linux / generic / backport-6.1 / 778-v6.3-02-net-dsa-qca8k-convert-to-regmap-read-write-API.patch
1 From c766e077d927e1775902c18827205ea2ade3a35d Mon Sep 17 00:00:00 2001
2 From: Christian Marangi <ansuelsmth@gmail.com>
3 Date: Wed, 25 Jan 2023 21:35:17 +0100
4 Subject: [PATCH] net: dsa: qca8k: convert to regmap read/write API
5
6 Convert qca8k to regmap read/write bulk API. The mgmt eth can write up
7 to 32 bytes of data at times. Currently we use a custom function to do
8 it but regmap now supports declaration of read/write bulk even without a
9 bus.
10
11 Drop the custom function and rework the regmap function to this new
12 implementation.
13
14 Rework the qca8k_fdb_read/write function to use the new
15 regmap_bulk_read/write as the old qca8k_bulk_read/write are now dropped.
16
17 Cc: Mark Brown <broonie@kernel.org>
18 Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
19 Signed-off-by: David S. Miller <davem@davemloft.net>
20 ---
21 drivers/net/dsa/qca/qca8k-8xxx.c | 92 ++++++++++++++++++++++++------
22 drivers/net/dsa/qca/qca8k-common.c | 47 ++-------------
23 drivers/net/dsa/qca/qca8k.h | 3 -
24 3 files changed, 77 insertions(+), 65 deletions(-)
25
26 --- a/drivers/net/dsa/qca/qca8k-8xxx.c
27 +++ b/drivers/net/dsa/qca/qca8k-8xxx.c
28 @@ -425,16 +425,12 @@ qca8k_regmap_update_bits_eth(struct qca8
29 }
30
31 static int
32 -qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val)
33 +qca8k_read_mii(struct qca8k_priv *priv, uint32_t reg, uint32_t *val)
34 {
35 - struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
36 struct mii_bus *bus = priv->bus;
37 u16 r1, r2, page;
38 int ret;
39
40 - if (!qca8k_read_eth(priv, reg, val, sizeof(*val)))
41 - return 0;
42 -
43 qca8k_split_addr(reg, &r1, &r2, &page);
44
45 mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
46 @@ -451,16 +447,12 @@ exit:
47 }
48
49 static int
50 -qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val)
51 +qca8k_write_mii(struct qca8k_priv *priv, uint32_t reg, uint32_t val)
52 {
53 - struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
54 struct mii_bus *bus = priv->bus;
55 u16 r1, r2, page;
56 int ret;
57
58 - if (!qca8k_write_eth(priv, reg, &val, sizeof(val)))
59 - return 0;
60 -
61 qca8k_split_addr(reg, &r1, &r2, &page);
62
63 mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
64 @@ -477,17 +469,14 @@ exit:
65 }
66
67 static int
68 -qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val)
69 +qca8k_regmap_update_bits_mii(struct qca8k_priv *priv, uint32_t reg,
70 + uint32_t mask, uint32_t write_val)
71 {
72 - struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
73 struct mii_bus *bus = priv->bus;
74 u16 r1, r2, page;
75 u32 val;
76 int ret;
77
78 - if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val))
79 - return 0;
80 -
81 qca8k_split_addr(reg, &r1, &r2, &page);
82
83 mutex_lock_nested(&bus->mdio_lock, MDIO_MUTEX_NESTED);
84 @@ -510,17 +499,84 @@ exit:
85 return ret;
86 }
87
88 +static int
89 +qca8k_bulk_read(void *ctx, const void *reg_buf, size_t reg_len,
90 + void *val_buf, size_t val_len)
91 +{
92 + int i, count = val_len / sizeof(u32), ret;
93 + u32 reg = *(u32 *)reg_buf & U16_MAX;
94 + struct qca8k_priv *priv = ctx;
95 +
96 + if (priv->mgmt_master &&
97 + !qca8k_read_eth(priv, reg, val_buf, val_len))
98 + return 0;
99 +
100 + /* loop count times and increment reg of 4 */
101 + for (i = 0; i < count; i++, reg += sizeof(u32)) {
102 + ret = qca8k_read_mii(priv, reg, val_buf + i);
103 + if (ret < 0)
104 + return ret;
105 + }
106 +
107 + return 0;
108 +}
109 +
110 +static int
111 +qca8k_bulk_gather_write(void *ctx, const void *reg_buf, size_t reg_len,
112 + const void *val_buf, size_t val_len)
113 +{
114 + int i, count = val_len / sizeof(u32), ret;
115 + u32 reg = *(u32 *)reg_buf & U16_MAX;
116 + struct qca8k_priv *priv = ctx;
117 + u32 *val = (u32 *)val_buf;
118 +
119 + if (priv->mgmt_master &&
120 + !qca8k_write_eth(priv, reg, val, val_len))
121 + return 0;
122 +
123 + /* loop count times, increment reg of 4 and increment val ptr to
124 + * the next value
125 + */
126 + for (i = 0; i < count; i++, reg += sizeof(u32), val++) {
127 + ret = qca8k_write_mii(priv, reg, *val);
128 + if (ret < 0)
129 + return ret;
130 + }
131 +
132 + return 0;
133 +}
134 +
135 +static int
136 +qca8k_bulk_write(void *ctx, const void *data, size_t bytes)
137 +{
138 + return qca8k_bulk_gather_write(ctx, data, sizeof(u16), data + sizeof(u16),
139 + bytes - sizeof(u16));
140 +}
141 +
142 +static int
143 +qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val)
144 +{
145 + struct qca8k_priv *priv = ctx;
146 +
147 + if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val))
148 + return 0;
149 +
150 + return qca8k_regmap_update_bits_mii(priv, reg, mask, write_val);
151 +}
152 +
153 static struct regmap_config qca8k_regmap_config = {
154 .reg_bits = 16,
155 .val_bits = 32,
156 .reg_stride = 4,
157 .max_register = 0x16ac, /* end MIB - Port6 range */
158 - .reg_read = qca8k_regmap_read,
159 - .reg_write = qca8k_regmap_write,
160 + .read = qca8k_bulk_read,
161 + .write = qca8k_bulk_write,
162 .reg_update_bits = qca8k_regmap_update_bits,
163 .rd_table = &qca8k_readable_table,
164 .disable_locking = true, /* Locking is handled by qca8k read/write */
165 .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */
166 + .max_raw_read = 32, /* mgmt eth can read/write up to 8 registers at time */
167 + .max_raw_write = 32,
168 };
169
170 static int
171 @@ -2102,8 +2158,6 @@ static SIMPLE_DEV_PM_OPS(qca8k_pm_ops,
172
173 static const struct qca8k_info_ops qca8xxx_ops = {
174 .autocast_mib = qca8k_get_ethtool_stats_eth,
175 - .read_eth = qca8k_read_eth,
176 - .write_eth = qca8k_write_eth,
177 };
178
179 static const struct qca8k_match_data qca8327 = {
180 --- a/drivers/net/dsa/qca/qca8k-common.c
181 +++ b/drivers/net/dsa/qca/qca8k-common.c
182 @@ -101,45 +101,6 @@ const struct regmap_access_table qca8k_r
183 .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges),
184 };
185
186 -/* TODO: remove these extra ops when we can support regmap bulk read/write */
187 -static int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
188 -{
189 - int i, count = len / sizeof(u32), ret;
190 -
191 - if (priv->mgmt_master && priv->info->ops->read_eth &&
192 - !priv->info->ops->read_eth(priv, reg, val, len))
193 - return 0;
194 -
195 - for (i = 0; i < count; i++) {
196 - ret = regmap_read(priv->regmap, reg + (i * 4), val + i);
197 - if (ret < 0)
198 - return ret;
199 - }
200 -
201 - return 0;
202 -}
203 -
204 -/* TODO: remove these extra ops when we can support regmap bulk read/write */
205 -static int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
206 -{
207 - int i, count = len / sizeof(u32), ret;
208 - u32 tmp;
209 -
210 - if (priv->mgmt_master && priv->info->ops->write_eth &&
211 - !priv->info->ops->write_eth(priv, reg, val, len))
212 - return 0;
213 -
214 - for (i = 0; i < count; i++) {
215 - tmp = val[i];
216 -
217 - ret = regmap_write(priv->regmap, reg + (i * 4), tmp);
218 - if (ret < 0)
219 - return ret;
220 - }
221 -
222 - return 0;
223 -}
224 -
225 static int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
226 {
227 u32 val;
228 @@ -154,8 +115,8 @@ static int qca8k_fdb_read(struct qca8k_p
229 int ret;
230
231 /* load the ARL table into an array */
232 - ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg,
233 - QCA8K_ATU_TABLE_SIZE * sizeof(u32));
234 + ret = regmap_bulk_read(priv->regmap, QCA8K_REG_ATU_DATA0, reg,
235 + QCA8K_ATU_TABLE_SIZE);
236 if (ret)
237 return ret;
238
239 @@ -196,8 +157,8 @@ static void qca8k_fdb_write(struct qca8k
240 reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]);
241
242 /* load the array into the ARL table */
243 - qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg,
244 - QCA8K_ATU_TABLE_SIZE * sizeof(u32));
245 + regmap_bulk_write(priv->regmap, QCA8K_REG_ATU_DATA0, reg,
246 + QCA8K_ATU_TABLE_SIZE);
247 }
248
249 static int qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd,
250 --- a/drivers/net/dsa/qca/qca8k.h
251 +++ b/drivers/net/dsa/qca/qca8k.h
252 @@ -330,9 +330,6 @@ struct qca8k_priv;
253
254 struct qca8k_info_ops {
255 int (*autocast_mib)(struct dsa_switch *ds, int port, u64 *data);
256 - /* TODO: remove these extra ops when we can support regmap bulk read/write */
257 - int (*read_eth)(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
258 - int (*write_eth)(struct qca8k_priv *priv, u32 reg, u32 *val, int len);
259 };
260
261 struct qca8k_match_data {