Re: [PATCH v2 net-next 11/15] net: dsa: sja1105: add a new best_effort_vlan_filtering devlink parameter

2020-05-11 Thread Florian Fainelli



On 5/11/2020 6:53 AM, Vladimir Oltean wrote:
> From: Vladimir Oltean 
> 
> This devlink parameter enables the handling of DSA tags when enslaved to
> a bridge with vlan_filtering=1. There are very good reasons to want
> this, but there are also very good reasons for not enabling it by
> default. So a devlink param named best_effort_vlan_filtering, currently
> driver-specific and exported only by sja1105, is used to configure this.
> 
> In practice, this is perhaps the way that most users are going to use
> the switch in. It assumes that no more than 7 VLANs are needed per port.
> 
> Signed-off-by: Vladimir Oltean 

Reviewed-by: Florian Fainelli 
-- 
Florian


[PATCH v2 net-next 11/15] net: dsa: sja1105: add a new best_effort_vlan_filtering devlink parameter

2020-05-11 Thread Vladimir Oltean
From: Vladimir Oltean 

This devlink parameter enables the handling of DSA tags when enslaved to
a bridge with vlan_filtering=1. There are very good reasons to want
this, but there are also very good reasons for not enabling it by
default. So a devlink param named best_effort_vlan_filtering, currently
driver-specific and exported only by sja1105, is used to configure this.

In practice, this is perhaps the way that most users are going to use
the switch in. It assumes that no more than 7 VLANs are needed per port.

Signed-off-by: Vladimir Oltean 
---
Changes in v2:
- In sja1105_best_effort_vlan_filtering_set, get the vlan_filtering
  value of each port instead of just one time for port 0. Normally this
  shouldn't matter, but it avoids issues when port 0 is disabled in
  device tree.

 drivers/net/dsa/sja1105/sja1105.h  |   2 +
 drivers/net/dsa/sja1105/sja1105_main.c | 122 -
 2 files changed, 120 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dsa/sja1105/sja1105.h 
b/drivers/net/dsa/sja1105/sja1105.h
index a019ffae38f1..1dcaecab0912 100644
--- a/drivers/net/dsa/sja1105/sja1105.h
+++ b/drivers/net/dsa/sja1105/sja1105.h
@@ -194,6 +194,7 @@ struct sja1105_bridge_vlan {
 
 enum sja1105_vlan_state {
SJA1105_VLAN_UNAWARE,
+   SJA1105_VLAN_BEST_EFFORT,
SJA1105_VLAN_FILTERING_FULL,
 };
 
@@ -201,6 +202,7 @@ struct sja1105_private {
struct sja1105_static_config static_config;
bool rgmii_rx_delay[SJA1105_NUM_PORTS];
bool rgmii_tx_delay[SJA1105_NUM_PORTS];
+   bool best_effort_vlan_filtering;
const struct sja1105_info *info;
struct gpio_desc *reset_gpio;
struct spi_device *spidev;
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c 
b/drivers/net/dsa/sja1105/sja1105_main.c
index fe300cf94509..99139fcdc715 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -2132,6 +2132,7 @@ static int sja1105_vlan_filtering(struct dsa_switch *ds, 
int port, bool enabled)
enum sja1105_vlan_state state;
struct sja1105_table *table;
struct sja1105_rule *rule;
+   bool want_tagging;
u16 tpid, tpid2;
int rc;
 
@@ -2164,6 +2165,8 @@ static int sja1105_vlan_filtering(struct dsa_switch *ds, 
int port, bool enabled)
 
if (!enabled)
state = SJA1105_VLAN_UNAWARE;
+   else if (priv->best_effort_vlan_filtering)
+   state = SJA1105_VLAN_BEST_EFFORT;
else
state = SJA1105_VLAN_FILTERING_FULL;
 
@@ -2171,6 +2174,8 @@ static int sja1105_vlan_filtering(struct dsa_switch *ds, 
int port, bool enabled)
return 0;
 
priv->vlan_state = state;
+   want_tagging = (state == SJA1105_VLAN_UNAWARE ||
+   state == SJA1105_VLAN_BEST_EFFORT);
 
table = >static_config.tables[BLK_IDX_GENERAL_PARAMS];
general_params = table->entries;
@@ -2184,8 +2189,10 @@ static int sja1105_vlan_filtering(struct dsa_switch *ds, 
int port, bool enabled)
general_params->incl_srcpt1 = enabled;
general_params->incl_srcpt0 = enabled;
 
+   want_tagging = priv->best_effort_vlan_filtering || !enabled;
+
/* VLAN filtering => independent VLAN learning.
-* No VLAN filtering => shared VLAN learning.
+* No VLAN filtering (or best effort) => shared VLAN learning.
 *
 * In shared VLAN learning mode, untagged traffic still gets
 * pvid-tagged, and the FDB table gets populated with entries
@@ -2204,7 +2211,7 @@ static int sja1105_vlan_filtering(struct dsa_switch *ds, 
int port, bool enabled)
 */
table = >static_config.tables[BLK_IDX_L2_LOOKUP_PARAMS];
l2_lookup_params = table->entries;
-   l2_lookup_params->shared_learn = !enabled;
+   l2_lookup_params->shared_learn = want_tagging;
 
rc = sja1105_static_config_reload(priv, SJA1105_VLAN_FILTERING);
if (rc)
@@ -2212,9 +2219,10 @@ static int sja1105_vlan_filtering(struct dsa_switch *ds, 
int port, bool enabled)
 
/* Switch port identification based on 802.1Q is only passable
 * if we are not under a vlan_filtering bridge. So make sure
-* the two configurations are mutually exclusive.
+* the two configurations are mutually exclusive (of course, the
+* user may know better, i.e. best_effort_vlan_filtering).
 */
-   return sja1105_setup_8021q_tagging(ds, !enabled);
+   return sja1105_setup_8021q_tagging(ds, want_tagging);
 }
 
 bool sja1105_can_use_vlan_as_tags(struct dsa_switch *ds)
@@ -2305,6 +2313,105 @@ static int sja1105_vlan_del(struct dsa_switch *ds, int 
port,
return sja1105_build_vlan_table(priv, true);
 }
 
+static int sja1105_best_effort_vlan_filtering_get(struct sja1105_private *priv,
+ bool *be_vlan)
+{
+   *be_vlan = priv->best_effort_vlan_filtering;
+
+   return 0;
+}
+
+static int