793-02-v6.11-net-dsa-qca8k-factor-out-bridge-join-leave-logic.patch 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. From 412e1775f413c944b8c51bdadb675be957d83dc8 Mon Sep 17 00:00:00 2001
  2. Message-ID: <412e1775f413c944b8c51bdadb675be957d83dc8.1728674648.git.mschiffer@universe-factory.net>
  3. In-Reply-To: <e85d3e6fea05c8ae21a40809a3c6b7adc97411c7.1728674648.git.mschiffer@universe-factory.net>
  4. References: <e85d3e6fea05c8ae21a40809a3c6b7adc97411c7.1728674648.git.mschiffer@universe-factory.net>
  5. From: Matthias Schiffer <[email protected]>
  6. Date: Thu, 20 Jun 2024 19:25:49 +0200
  7. Subject: [PATCH] net: dsa: qca8k: factor out bridge join/leave logic
  8. Most of the logic in qca8k_port_bridge_join() and qca8k_port_bridge_leave()
  9. is the same. Refactor to reduce duplication and prepare for reusing the
  10. code for implementing bridge port isolation.
  11. dsa_port_offloads_bridge_dev() is used instead of
  12. dsa_port_offloads_bridge(), passing the bridge in as a struct netdevice *,
  13. as we won't have a struct dsa_bridge in qca8k_port_bridge_flags().
  14. The error handling is changed slightly in the bridge leave case,
  15. returning early and emitting an error message when a regmap access fails.
  16. This shouldn't matter in practice, as there isn't much we can do if
  17. communication with the switch breaks down in the middle of reconfiguration.
  18. Signed-off-by: Matthias Schiffer <[email protected]>
  19. Reviewed-by: Wojciech Drewek <[email protected]>
  20. Signed-off-by: David S. Miller <[email protected]>
  21. ---
  22. drivers/net/dsa/qca/qca8k-common.c | 101 ++++++++++++++---------------
  23. 1 file changed, 50 insertions(+), 51 deletions(-)
  24. --- a/drivers/net/dsa/qca/qca8k-common.c
  25. +++ b/drivers/net/dsa/qca/qca8k-common.c
  26. @@ -615,6 +615,49 @@ void qca8k_port_stp_state_set(struct dsa
  27. qca8k_port_configure_learning(ds, port, learning);
  28. }
  29. +static int qca8k_update_port_member(struct qca8k_priv *priv, int port,
  30. + const struct net_device *bridge_dev,
  31. + bool join)
  32. +{
  33. + struct dsa_port *dp = dsa_to_port(priv->ds, port), *other_dp;
  34. + u32 port_mask = BIT(dp->cpu_dp->index);
  35. + int i, ret;
  36. +
  37. + for (i = 0; i < QCA8K_NUM_PORTS; i++) {
  38. + if (i == port)
  39. + continue;
  40. + if (dsa_is_cpu_port(priv->ds, i))
  41. + continue;
  42. +
  43. + other_dp = dsa_to_port(priv->ds, i);
  44. + if (!dsa_port_offloads_bridge_dev(other_dp, bridge_dev))
  45. + continue;
  46. +
  47. + /* Add/remove this port to/from the portvlan mask of the other
  48. + * ports in the bridge
  49. + */
  50. + if (join) {
  51. + port_mask |= BIT(i);
  52. + ret = regmap_set_bits(priv->regmap,
  53. + QCA8K_PORT_LOOKUP_CTRL(i),
  54. + BIT(port));
  55. + } else {
  56. + ret = regmap_clear_bits(priv->regmap,
  57. + QCA8K_PORT_LOOKUP_CTRL(i),
  58. + BIT(port));
  59. + }
  60. +
  61. + if (ret)
  62. + return ret;
  63. + }
  64. +
  65. + /* Add/remove all other ports to/from this port's portvlan mask */
  66. + ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
  67. + QCA8K_PORT_LOOKUP_MEMBER, port_mask);
  68. +
  69. + return ret;
  70. +}
  71. +
  72. int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
  73. struct switchdev_brport_flags flags,
  74. struct netlink_ext_ack *extack)
  75. @@ -647,65 +690,21 @@ int qca8k_port_bridge_join(struct dsa_sw
  76. struct netlink_ext_ack *extack)
  77. {
  78. struct qca8k_priv *priv = ds->priv;
  79. - int port_mask, cpu_port;
  80. - int i, ret;
  81. -
  82. - cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
  83. - port_mask = BIT(cpu_port);
  84. - for (i = 0; i < QCA8K_NUM_PORTS; i++) {
  85. - if (i == port)
  86. - continue;
  87. - if (dsa_is_cpu_port(ds, i))
  88. - continue;
  89. - if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge))
  90. - continue;
  91. - /* Add this port to the portvlan mask of the other ports
  92. - * in the bridge
  93. - */
  94. - ret = regmap_set_bits(priv->regmap,
  95. - QCA8K_PORT_LOOKUP_CTRL(i),
  96. - BIT(port));
  97. - if (ret)
  98. - return ret;
  99. - port_mask |= BIT(i);
  100. - }
  101. -
  102. - /* Add all other ports to this ports portvlan mask */
  103. - ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
  104. - QCA8K_PORT_LOOKUP_MEMBER, port_mask);
  105. -
  106. - return ret;
  107. + return qca8k_update_port_member(priv, port, bridge.dev, true);
  108. }
  109. void qca8k_port_bridge_leave(struct dsa_switch *ds, int port,
  110. struct dsa_bridge bridge)
  111. {
  112. struct qca8k_priv *priv = ds->priv;
  113. - int cpu_port, i;
  114. -
  115. - cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
  116. -
  117. - for (i = 0; i < QCA8K_NUM_PORTS; i++) {
  118. - if (i == port)
  119. - continue;
  120. - if (dsa_is_cpu_port(ds, i))
  121. - continue;
  122. - if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge))
  123. - continue;
  124. - /* Remove this port to the portvlan mask of the other ports
  125. - * in the bridge
  126. - */
  127. - regmap_clear_bits(priv->regmap,
  128. - QCA8K_PORT_LOOKUP_CTRL(i),
  129. - BIT(port));
  130. - }
  131. + int err;
  132. - /* Set the cpu port to be the only one in the portvlan mask of
  133. - * this port
  134. - */
  135. - qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
  136. - QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
  137. + err = qca8k_update_port_member(priv, port, bridge.dev, false);
  138. + if (err)
  139. + dev_err(priv->dev,
  140. + "Failed to update switch config for bridge leave: %d\n",
  141. + err);
  142. }
  143. void qca8k_port_fast_age(struct dsa_switch *ds, int port)