2
0

778-v6.3-02-net-dsa-qca8k-convert-to-regmap-read-write-API.patch 7.5 KB

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