2
0

780-v6.6-01-net-dsa-qca8k-make-learning-configurable-and-keep-of.patch 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. From 23cfc7172e5297d0bee49ac6f6f8248d1cf0820d Mon Sep 17 00:00:00 2001
  2. From: Christian Marangi <[email protected]>
  3. Date: Sun, 30 Jul 2023 09:41:10 +0200
  4. Subject: [PATCH 1/4] net: dsa: qca8k: make learning configurable and keep off
  5. if standalone
  6. Address learning should initially be turned off by the driver for port
  7. operation in standalone mode, then the DSA core handles changes to it
  8. via ds->ops->port_bridge_flags().
  9. Currently this is not the case for qca8k where learning is enabled
  10. unconditionally in qca8k_setup for every user port.
  11. Handle ports configured in standalone mode by making the learning
  12. configurable and not enabling it by default.
  13. Implement .port_pre_bridge_flags and .port_bridge_flags dsa ops to
  14. enable learning for bridge that request it and tweak
  15. .port_stp_state_set to correctly disable learning when port is
  16. configured in standalone mode.
  17. Signed-off-by: Christian Marangi <[email protected]>
  18. Reviewed-by: Vladimir Oltean <[email protected]>
  19. Reviewed-by: Florian Fainelli <[email protected]>
  20. Link: https://lore.kernel.org/r/[email protected]
  21. Signed-off-by: Paolo Abeni <[email protected]>
  22. ---
  23. drivers/net/dsa/qca/qca8k-8xxx.c | 7 +++--
  24. drivers/net/dsa/qca/qca8k-common.c | 48 ++++++++++++++++++++++++++++++
  25. drivers/net/dsa/qca/qca8k.h | 6 ++++
  26. 3 files changed, 58 insertions(+), 3 deletions(-)
  27. --- a/drivers/net/dsa/qca/qca8k-8xxx.c
  28. +++ b/drivers/net/dsa/qca/qca8k-8xxx.c
  29. @@ -1894,9 +1894,8 @@ qca8k_setup(struct dsa_switch *ds)
  30. if (ret)
  31. return ret;
  32. - /* Enable ARP Auto-learning by default */
  33. - ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
  34. - QCA8K_PORT_LOOKUP_LEARN);
  35. + ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
  36. + QCA8K_PORT_LOOKUP_LEARN);
  37. if (ret)
  38. return ret;
  39. @@ -2002,6 +2001,8 @@ static const struct dsa_switch_ops qca8k
  40. .port_change_mtu = qca8k_port_change_mtu,
  41. .port_max_mtu = qca8k_port_max_mtu,
  42. .port_stp_state_set = qca8k_port_stp_state_set,
  43. + .port_pre_bridge_flags = qca8k_port_pre_bridge_flags,
  44. + .port_bridge_flags = qca8k_port_bridge_flags,
  45. .port_bridge_join = qca8k_port_bridge_join,
  46. .port_bridge_leave = qca8k_port_bridge_leave,
  47. .port_fast_age = qca8k_port_fast_age,
  48. --- a/drivers/net/dsa/qca/qca8k-common.c
  49. +++ b/drivers/net/dsa/qca/qca8k-common.c
  50. @@ -565,9 +565,26 @@ int qca8k_get_mac_eee(struct dsa_switch
  51. return 0;
  52. }
  53. +static int qca8k_port_configure_learning(struct dsa_switch *ds, int port,
  54. + bool learning)
  55. +{
  56. + struct qca8k_priv *priv = ds->priv;
  57. +
  58. + if (learning)
  59. + return regmap_set_bits(priv->regmap,
  60. + QCA8K_PORT_LOOKUP_CTRL(port),
  61. + QCA8K_PORT_LOOKUP_LEARN);
  62. + else
  63. + return regmap_clear_bits(priv->regmap,
  64. + QCA8K_PORT_LOOKUP_CTRL(port),
  65. + QCA8K_PORT_LOOKUP_LEARN);
  66. +}
  67. +
  68. void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
  69. {
  70. + struct dsa_port *dp = dsa_to_port(ds, port);
  71. struct qca8k_priv *priv = ds->priv;
  72. + bool learning = false;
  73. u32 stp_state;
  74. switch (state) {
  75. @@ -582,8 +599,11 @@ void qca8k_port_stp_state_set(struct dsa
  76. break;
  77. case BR_STATE_LEARNING:
  78. stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING;
  79. + learning = dp->learning;
  80. break;
  81. case BR_STATE_FORWARDING:
  82. + learning = dp->learning;
  83. + fallthrough;
  84. default:
  85. stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD;
  86. break;
  87. @@ -591,6 +611,34 @@ void qca8k_port_stp_state_set(struct dsa
  88. qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
  89. QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
  90. +
  91. + qca8k_port_configure_learning(ds, port, learning);
  92. +}
  93. +
  94. +int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
  95. + struct switchdev_brport_flags flags,
  96. + struct netlink_ext_ack *extack)
  97. +{
  98. + if (flags.mask & ~BR_LEARNING)
  99. + return -EINVAL;
  100. +
  101. + return 0;
  102. +}
  103. +
  104. +int qca8k_port_bridge_flags(struct dsa_switch *ds, int port,
  105. + struct switchdev_brport_flags flags,
  106. + struct netlink_ext_ack *extack)
  107. +{
  108. + int ret;
  109. +
  110. + if (flags.mask & BR_LEARNING) {
  111. + ret = qca8k_port_configure_learning(ds, port,
  112. + flags.val & BR_LEARNING);
  113. + if (ret)
  114. + return ret;
  115. + }
  116. +
  117. + return 0;
  118. }
  119. int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
  120. --- a/drivers/net/dsa/qca/qca8k.h
  121. +++ b/drivers/net/dsa/qca/qca8k.h
  122. @@ -448,6 +448,12 @@ int qca8k_get_mac_eee(struct dsa_switch
  123. /* Common bridge function */
  124. void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);
  125. +int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
  126. + struct switchdev_brport_flags flags,
  127. + struct netlink_ext_ack *extack);
  128. +int qca8k_port_bridge_flags(struct dsa_switch *ds, int port,
  129. + struct switchdev_brport_flags flags,
  130. + struct netlink_ext_ack *extack);
  131. int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
  132. struct dsa_bridge bridge,
  133. bool *tx_fwd_offload,