735-v5.14-06-net-dsa-qca8k-handle-error-with-qca8k_write-operatio.patch 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. From d7805757c75c76e9518fc1023a29f0c4eed5b581 Mon Sep 17 00:00:00 2001
  2. From: Ansuel Smith <[email protected]>
  3. Date: Fri, 14 May 2021 22:59:56 +0200
  4. Subject: [PATCH] net: dsa: qca8k: handle error with qca8k_write operation
  5. qca8k_write can fail. Rework any user to handle error values and
  6. correctly return.
  7. Signed-off-by: Ansuel Smith <[email protected]>
  8. Reviewed-by: Andrew Lunn <[email protected]>
  9. Signed-off-by: David S. Miller <[email protected]>
  10. ---
  11. drivers/net/dsa/qca8k.c | 102 ++++++++++++++++++++++++++--------------
  12. 1 file changed, 67 insertions(+), 35 deletions(-)
  13. --- a/drivers/net/dsa/qca8k.c
  14. +++ b/drivers/net/dsa/qca8k.c
  15. @@ -168,7 +168,7 @@ exit:
  16. return val;
  17. }
  18. -static void
  19. +static int
  20. qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
  21. {
  22. struct mii_bus *bus = priv->bus;
  23. @@ -187,6 +187,7 @@ qca8k_write(struct qca8k_priv *priv, u32
  24. exit:
  25. mutex_unlock(&bus->mdio_lock);
  26. + return ret;
  27. }
  28. static u32
  29. @@ -247,9 +248,7 @@ qca8k_regmap_write(void *ctx, uint32_t r
  30. {
  31. struct qca8k_priv *priv = (struct qca8k_priv *)ctx;
  32. - qca8k_write(priv, reg, val);
  33. -
  34. - return 0;
  35. + return qca8k_write(priv, reg, val);
  36. }
  37. static const struct regmap_range qca8k_readable_ranges[] = {
  38. @@ -367,6 +366,7 @@ static int
  39. qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port)
  40. {
  41. u32 reg;
  42. + int ret;
  43. /* Set the command and FDB index */
  44. reg = QCA8K_ATU_FUNC_BUSY;
  45. @@ -377,7 +377,9 @@ qca8k_fdb_access(struct qca8k_priv *priv
  46. }
  47. /* Write the function register triggering the table access */
  48. - qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg);
  49. + ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg);
  50. + if (ret)
  51. + return ret;
  52. /* wait for completion */
  53. if (qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY))
  54. @@ -447,6 +449,7 @@ static int
  55. qca8k_vlan_access(struct qca8k_priv *priv, enum qca8k_vlan_cmd cmd, u16 vid)
  56. {
  57. u32 reg;
  58. + int ret;
  59. /* Set the command and VLAN index */
  60. reg = QCA8K_VTU_FUNC1_BUSY;
  61. @@ -454,7 +457,9 @@ qca8k_vlan_access(struct qca8k_priv *pri
  62. reg |= vid << QCA8K_VTU_FUNC1_VID_S;
  63. /* Write the function register triggering the table access */
  64. - qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
  65. + ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
  66. + if (ret)
  67. + return ret;
  68. /* wait for completion */
  69. if (qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY))
  70. @@ -502,7 +507,9 @@ qca8k_vlan_add(struct qca8k_priv *priv,
  71. reg |= QCA8K_VTU_FUNC0_EG_MODE_TAG <<
  72. QCA8K_VTU_FUNC0_EG_MODE_S(port);
  73. - qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
  74. + ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
  75. + if (ret)
  76. + return ret;
  77. ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
  78. out:
  79. @@ -545,7 +552,9 @@ qca8k_vlan_del(struct qca8k_priv *priv,
  80. if (del) {
  81. ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
  82. } else {
  83. - qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
  84. + ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
  85. + if (ret)
  86. + return ret;
  87. ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
  88. }
  89. @@ -555,15 +564,20 @@ out:
  90. return ret;
  91. }
  92. -static void
  93. +static int
  94. qca8k_mib_init(struct qca8k_priv *priv)
  95. {
  96. + int ret;
  97. +
  98. mutex_lock(&priv->reg_mutex);
  99. qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY);
  100. qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
  101. qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
  102. - qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
  103. +
  104. + ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
  105. +
  106. mutex_unlock(&priv->reg_mutex);
  107. + return ret;
  108. }
  109. static void
  110. @@ -600,6 +614,7 @@ static int
  111. qca8k_mdio_write(struct qca8k_priv *priv, int port, u32 regnum, u16 data)
  112. {
  113. u32 phy, val;
  114. + int ret;
  115. if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
  116. return -EINVAL;
  117. @@ -613,7 +628,9 @@ qca8k_mdio_write(struct qca8k_priv *priv
  118. QCA8K_MDIO_MASTER_REG_ADDR(regnum) |
  119. QCA8K_MDIO_MASTER_DATA(data);
  120. - qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
  121. + ret = qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
  122. + if (ret)
  123. + return ret;
  124. return qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
  125. QCA8K_MDIO_MASTER_BUSY);
  126. @@ -623,6 +640,7 @@ static int
  127. qca8k_mdio_read(struct qca8k_priv *priv, int port, u32 regnum)
  128. {
  129. u32 phy, val;
  130. + int ret;
  131. if (regnum >= QCA8K_MDIO_MASTER_MAX_REG)
  132. return -EINVAL;
  133. @@ -635,7 +653,9 @@ qca8k_mdio_read(struct qca8k_priv *priv,
  134. QCA8K_MDIO_MASTER_READ | QCA8K_MDIO_MASTER_PHY_ADDR(phy) |
  135. QCA8K_MDIO_MASTER_REG_ADDR(regnum);
  136. - qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
  137. + ret = qca8k_write(priv, QCA8K_MDIO_MASTER_CTRL, val);
  138. + if (ret)
  139. + return ret;
  140. if (qca8k_busy_wait(priv, QCA8K_MDIO_MASTER_CTRL,
  141. QCA8K_MDIO_MASTER_BUSY))
  142. @@ -766,12 +786,18 @@ qca8k_setup(struct dsa_switch *ds)
  143. QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN);
  144. /* Enable MIB counters */
  145. - qca8k_mib_init(priv);
  146. + ret = qca8k_mib_init(priv);
  147. + if (ret)
  148. + dev_warn(priv->dev, "mib init failed");
  149. /* Enable QCA header mode on the cpu port */
  150. - qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT),
  151. - QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
  152. - QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
  153. + ret = qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT),
  154. + QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S |
  155. + QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S);
  156. + if (ret) {
  157. + dev_err(priv->dev, "failed enabling QCA header mode");
  158. + return ret;
  159. + }
  160. /* Disable forwarding by default on all ports */
  161. for (i = 0; i < QCA8K_NUM_PORTS; i++)
  162. @@ -783,11 +809,13 @@ qca8k_setup(struct dsa_switch *ds)
  163. qca8k_port_set_status(priv, i, 0);
  164. /* Forward all unknown frames to CPU port for Linux processing */
  165. - qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
  166. - BIT(0) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
  167. - BIT(0) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
  168. - BIT(0) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
  169. - BIT(0) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
  170. + ret = qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1,
  171. + BIT(0) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S |
  172. + BIT(0) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S |
  173. + BIT(0) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S |
  174. + BIT(0) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S);
  175. + if (ret)
  176. + return ret;
  177. /* Setup connection between CPU port & user ports */
  178. for (i = 0; i < QCA8K_NUM_PORTS; i++) {
  179. @@ -815,16 +843,20 @@ qca8k_setup(struct dsa_switch *ds)
  180. qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i),
  181. 0xfff << shift,
  182. QCA8K_PORT_VID_DEF << shift);
  183. - qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
  184. - QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
  185. - QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
  186. + ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i),
  187. + QCA8K_PORT_VLAN_CVID(QCA8K_PORT_VID_DEF) |
  188. + QCA8K_PORT_VLAN_SVID(QCA8K_PORT_VID_DEF));
  189. + if (ret)
  190. + return ret;
  191. }
  192. }
  193. /* Setup our port MTUs to match power on defaults */
  194. for (i = 0; i < QCA8K_NUM_PORTS; i++)
  195. priv->port_mtu[i] = ETH_FRAME_LEN + ETH_FCS_LEN;
  196. - qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
  197. + ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, ETH_FRAME_LEN + ETH_FCS_LEN);
  198. + if (ret)
  199. + dev_warn(priv->dev, "failed setting MTU settings");
  200. /* Flush the FDB table */
  201. qca8k_fdb_flush(priv);
  202. @@ -1140,8 +1172,8 @@ qca8k_set_mac_eee(struct dsa_switch *ds,
  203. {
  204. struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
  205. u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
  206. - int ret = 0;
  207. u32 reg;
  208. + int ret;
  209. mutex_lock(&priv->reg_mutex);
  210. reg = qca8k_read(priv, QCA8K_REG_EEE_CTRL);
  211. @@ -1154,7 +1186,7 @@ qca8k_set_mac_eee(struct dsa_switch *ds,
  212. reg |= lpi_en;
  213. else
  214. reg &= ~lpi_en;
  215. - qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
  216. + ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
  217. exit:
  218. mutex_unlock(&priv->reg_mutex);
  219. @@ -1284,9 +1316,7 @@ qca8k_port_change_mtu(struct dsa_switch
  220. mtu = priv->port_mtu[i];
  221. /* Include L2 header / FCS length */
  222. - qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
  223. -
  224. - return 0;
  225. + return qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, mtu + ETH_HLEN + ETH_FCS_LEN);
  226. }
  227. static int