netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/2] mv88e6xxx: Allow config of ATU hash algorithm
@ 2019-10-04  1:35 Andrew Lunn
  2019-10-04  1:35 ` [PATCH net-next 1/2] net: dsa: Add support for devlink device parameters Andrew Lunn
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Andrew Lunn @ 2019-10-04  1:35 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Vivien Didelot, Florian Fainelli, Andrew Lunn

The Marvell switches allow the hash algorithm for MAC addresses in the
address translation unit to be configured. Add support to the DSA core
to allow DSA drivers to make use of devlink parameters, and allow the
ATU hash to be get/set via such a parameter.

Andrew Lunn (2):
  net: dsa: Add support for devlink device parameters
  net: dsa: mv88e6xxx: Add devlink param for ATU hash algorithm.

 drivers/net/dsa/mv88e6xxx/chip.c        | 136 +++++++++++++++++++++++-
 drivers/net/dsa/mv88e6xxx/chip.h        |   4 +
 drivers/net/dsa/mv88e6xxx/global1.h     |   3 +
 drivers/net/dsa/mv88e6xxx/global1_atu.c |  30 ++++++
 include/net/dsa.h                       |  23 ++++
 net/dsa/dsa.c                           |  48 +++++++++
 net/dsa/dsa2.c                          |   7 +-
 7 files changed, 249 insertions(+), 2 deletions(-)

-- 
2.23.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH net-next 1/2] net: dsa: Add support for devlink device parameters
  2019-10-04  1:35 [PATCH net-next 0/2] mv88e6xxx: Allow config of ATU hash algorithm Andrew Lunn
@ 2019-10-04  1:35 ` Andrew Lunn
  2019-10-04  1:35 ` [PATCH net-next 2/2] net: dsa: mv88e6xxx: Add devlink param for ATU hash algorithm Andrew Lunn
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 8+ messages in thread
From: Andrew Lunn @ 2019-10-04  1:35 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Vivien Didelot, Florian Fainelli, Andrew Lunn

Add plumbing to allow DSA drivers to register parameters with devlink.

To keep with the abstraction, the DSA drivers pass the ds structure to
these helpers, and the DSA core then translates that to the devlink
structure associated to the device.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 include/net/dsa.h | 23 +++++++++++++++++++++++
 net/dsa/dsa.c     | 48 +++++++++++++++++++++++++++++++++++++++++++++++
 net/dsa/dsa2.c    |  7 ++++++-
 3 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/include/net/dsa.h b/include/net/dsa.h
index 8c3ea0530f65..6623f4428930 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -541,6 +541,29 @@ struct dsa_switch_ops {
 	 */
 	netdev_tx_t (*port_deferred_xmit)(struct dsa_switch *ds, int port,
 					  struct sk_buff *skb);
+	/* Devlink parameters */
+	int	(*devlink_param_get)(struct dsa_switch *ds, u32 id,
+				     struct devlink_param_gset_ctx *ctx);
+	int	(*devlink_param_set)(struct dsa_switch *ds, u32 id,
+				     struct devlink_param_gset_ctx *ctx);
+};
+
+#define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes)		\
+	DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes,		\
+			     dsa_dl_param_get,	dsa_dl_param_set, NULL)
+
+int dsa_dl_param_get(struct devlink *dl, u32 id,
+		     struct devlink_param_gset_ctx *ctx);
+int dsa_dl_param_set(struct devlink *dl, u32 id,
+		     struct devlink_param_gset_ctx *ctx);
+int dsa_devlink_params_register(struct dsa_switch *ds,
+				const struct devlink_param *params,
+				size_t params_count);
+void dsa_devlink_params_unregister(struct dsa_switch *ds,
+				   const struct devlink_param *params,
+				   size_t params_count);
+struct dsa_devlink_priv {
+	struct dsa_switch *ds;
 };
 
 struct dsa_switch_driver {
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
index 43120a3fb06f..ea7678650d8c 100644
--- a/net/dsa/dsa.c
+++ b/net/dsa/dsa.c
@@ -329,6 +329,54 @@ int call_dsa_notifiers(unsigned long val, struct net_device *dev,
 }
 EXPORT_SYMBOL_GPL(call_dsa_notifiers);
 
+int dsa_dl_param_get(struct devlink *dl, u32 id,
+		     struct devlink_param_gset_ctx *ctx)
+{
+	struct dsa_devlink_priv *dl_priv;
+	struct dsa_switch *ds;
+
+	dl_priv = devlink_priv(dl);
+	ds = dl_priv->ds;
+
+	if (!ds->ops->devlink_param_get)
+		return -EOPNOTSUPP;
+
+	return ds->ops->devlink_param_get(ds, id, ctx);
+}
+EXPORT_SYMBOL_GPL(dsa_dl_param_get);
+
+int dsa_dl_param_set(struct devlink *dl, u32 id,
+		     struct devlink_param_gset_ctx *ctx)
+{
+	struct dsa_devlink_priv *dl_priv;
+	struct dsa_switch *ds;
+
+	dl_priv = devlink_priv(dl);
+	ds = dl_priv->ds;
+
+	if (!ds->ops->devlink_param_set)
+		return -EOPNOTSUPP;
+
+	return ds->ops->devlink_param_set(ds, id, ctx);
+}
+EXPORT_SYMBOL_GPL(dsa_dl_param_set);
+
+int dsa_devlink_params_register(struct dsa_switch *ds,
+				const struct devlink_param *params,
+				size_t params_count)
+{
+	return devlink_params_register(ds->devlink, params, params_count);
+}
+EXPORT_SYMBOL_GPL(dsa_devlink_params_register);
+
+void dsa_devlink_params_unregister(struct dsa_switch *ds,
+				   const struct devlink_param *params,
+				   size_t params_count)
+{
+	devlink_params_unregister(ds->devlink, params, params_count);
+}
+EXPORT_SYMBOL_GPL(dsa_devlink_params_unregister);
+
 static int __init dsa_init_module(void)
 {
 	int rc;
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
index 73002022c9d8..d74cc82fb44a 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -367,6 +367,7 @@ static void dsa_port_teardown(struct dsa_port *dp)
 
 static int dsa_switch_setup(struct dsa_switch *ds)
 {
+	struct dsa_devlink_priv *dl_priv;
 	int err = 0;
 
 	/* Initialize ds->phys_mii_mask before registering the slave MDIO bus
@@ -379,9 +380,11 @@ static int dsa_switch_setup(struct dsa_switch *ds)
 	/* Add the switch to devlink before calling setup, so that setup can
 	 * add dpipe tables
 	 */
-	ds->devlink = devlink_alloc(&dsa_devlink_ops, 0);
+	ds->devlink = devlink_alloc(&dsa_devlink_ops, sizeof(*devlink_priv));
 	if (!ds->devlink)
 		return -ENOMEM;
+	dl_priv = devlink_priv(ds->devlink);
+	dl_priv->ds = ds;
 
 	err = devlink_register(ds->devlink, ds->dev);
 	if (err)
@@ -395,6 +398,8 @@ static int dsa_switch_setup(struct dsa_switch *ds)
 	if (err < 0)
 		goto unregister_notifier;
 
+	devlink_params_publish(ds->devlink);
+
 	if (!ds->slave_mii_bus && ds->ops->phy_read) {
 		ds->slave_mii_bus = devm_mdiobus_alloc(ds->dev);
 		if (!ds->slave_mii_bus) {
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH net-next 2/2] net: dsa: mv88e6xxx: Add devlink param for ATU hash algorithm.
  2019-10-04  1:35 [PATCH net-next 0/2] mv88e6xxx: Allow config of ATU hash algorithm Andrew Lunn
  2019-10-04  1:35 ` [PATCH net-next 1/2] net: dsa: Add support for devlink device parameters Andrew Lunn
@ 2019-10-04  1:35 ` Andrew Lunn
  2019-10-04 14:47   ` Vivien Didelot
  2019-10-04  2:14 ` [PATCH net-next 0/2] mv88e6xxx: Allow config of " Jakub Kicinski
  2019-10-04  8:44 ` Vladimir Oltean
  3 siblings, 1 reply; 8+ messages in thread
From: Andrew Lunn @ 2019-10-04  1:35 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Vivien Didelot, Florian Fainelli, Andrew Lunn

Some of the marvell switches have bits controlling the hash algorithm
the ATU uses for MAC addresses. In some industrial settings, where all
the devices are from the same manufacture, and hence use the same OUI,
the default hashing algorithm is not optimal. Allow the other
algorithms to be selected via devlink.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
 drivers/net/dsa/mv88e6xxx/chip.c        | 136 +++++++++++++++++++++++-
 drivers/net/dsa/mv88e6xxx/chip.h        |   4 +
 drivers/net/dsa/mv88e6xxx/global1.h     |   3 +
 drivers/net/dsa/mv88e6xxx/global1_atu.c |  30 ++++++
 4 files changed, 172 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 6787d560e9e3..ebadcdba03df 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1370,6 +1370,22 @@ static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid)
 	return mv88e6xxx_g1_atu_flush(chip, *fid, true);
 }
 
+static int mv88e6xxx_atu_get_hash(struct mv88e6xxx_chip *chip)
+{
+	if (chip->info->ops->atu_get_hash)
+		return chip->info->ops->atu_get_hash(chip);
+
+	return -EOPNOTSUPP;
+}
+
+static int mv88e6xxx_atu_set_hash(struct mv88e6xxx_chip *chip, u8 hash)
+{
+	if (chip->info->ops->atu_set_hash)
+		return chip->info->ops->atu_set_hash(chip, hash);
+
+	return -EOPNOTSUPP;
+}
+
 static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
 					u16 vid_begin, u16 vid_end)
 {
@@ -2641,6 +2657,83 @@ static int mv88e6390_setup_errata(struct mv88e6xxx_chip *chip)
 	return mv88e6xxx_software_reset(chip);
 }
 
+enum mv88e6xxx_devlink_param_id {
+	MV88E6XXX_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
+	MV88E6XXX_DEVLINK_PARAM_ID_ATU_HASH,
+};
+
+static int mv88e6xxx_devlink_param_get(struct dsa_switch *ds, u32 id,
+				       struct devlink_param_gset_ctx *ctx)
+{
+	struct mv88e6xxx_chip *chip = ds->priv;
+	int err = 0;
+	int hash;
+
+	mv88e6xxx_reg_lock(chip);
+
+	switch (id) {
+	case MV88E6XXX_DEVLINK_PARAM_ID_ATU_HASH:
+		hash = mv88e6xxx_atu_get_hash(chip);
+		if (hash < 0) {
+			err = hash;
+			break;
+		}
+
+		ctx->val.vu8 = hash;
+		break;
+	default:
+		err = -EOPNOTSUPP;
+	}
+
+	mv88e6xxx_reg_unlock(chip);
+
+	return err;
+}
+
+static int mv88e6xxx_devlink_param_set(struct dsa_switch *ds, u32 id,
+				       struct devlink_param_gset_ctx *ctx)
+{
+	struct mv88e6xxx_chip *chip = ds->priv;
+	int err;
+
+	mv88e6xxx_reg_lock(chip);
+
+	switch (id) {
+	case MV88E6XXX_DEVLINK_PARAM_ID_ATU_HASH:
+		err = mv88e6xxx_atu_set_hash(chip, ctx->val.vu8);
+		break;
+	default:
+		err = -EOPNOTSUPP;
+	}
+
+	mv88e6xxx_reg_unlock(chip);
+
+	return err;
+}
+
+static const struct devlink_param mv88e6xxx_devlink_params[] = {
+	DSA_DEVLINK_PARAM_DRIVER(MV88E6XXX_DEVLINK_PARAM_ID_ATU_HASH,
+				 "ATU_hash", DEVLINK_PARAM_TYPE_U8,
+				 BIT(DEVLINK_PARAM_CMODE_RUNTIME)),
+};
+
+static int mv88e6xxx_setup_devlink_params(struct dsa_switch *ds)
+{
+	return dsa_devlink_params_register(ds, mv88e6xxx_devlink_params,
+					   ARRAY_SIZE(mv88e6xxx_devlink_params));
+}
+
+static void mv88e6xxx_teardown_devlink_params(struct dsa_switch *ds)
+{
+	dsa_devlink_params_unregister(ds, mv88e6xxx_devlink_params,
+				      ARRAY_SIZE(mv88e6xxx_devlink_params));
+}
+
+static void mv88e6xxx_teardown(struct dsa_switch *ds)
+{
+	mv88e6xxx_teardown_devlink_params(ds);
+}
+
 static int mv88e6xxx_setup(struct dsa_switch *ds)
 {
 	struct mv88e6xxx_chip *chip = ds->priv;
@@ -2757,7 +2850,11 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
 unlock:
 	mv88e6xxx_reg_unlock(chip);
 
-	return err;
+	/* Has to be called without holding the register lock, since
+	 * it takes the devlink lock, and we later take the locks in
+	 * the reverse order when getting/setting parameters.
+	 */
+	return mv88e6xxx_setup_devlink_params(ds);
 }
 
 static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
@@ -3117,6 +3214,8 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.phylink_validate = mv88e6185_phylink_validate,
@@ -3246,6 +3345,8 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.avb_ops = &mv88e6165_avb_ops,
@@ -3280,6 +3381,8 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.avb_ops = &mv88e6165_avb_ops,
@@ -3322,6 +3425,8 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.phylink_validate = mv88e6185_phylink_validate,
@@ -3366,6 +3471,8 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6352_g1_rmu_disable,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.serdes_get_lane = mv88e6352_serdes_get_lane,
@@ -3409,6 +3516,8 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.phylink_validate = mv88e6185_phylink_validate,
@@ -3453,6 +3562,8 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6352_g1_rmu_disable,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.serdes_get_lane = mv88e6352_serdes_get_lane,
@@ -3538,6 +3649,8 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6390_g1_rmu_disable,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6390_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
 	.serdes_power = mv88e6390_serdes_power,
@@ -3587,6 +3700,8 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6390_g1_rmu_disable,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6390_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
 	.serdes_power = mv88e6390_serdes_power,
@@ -3635,6 +3750,8 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6390_g1_rmu_disable,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6390_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
 	.serdes_power = mv88e6390_serdes_power,
@@ -3686,6 +3803,8 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6352_g1_rmu_disable,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.serdes_get_lane = mv88e6352_serdes_get_lane,
@@ -3777,6 +3896,8 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6390_g1_rmu_disable,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6390_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
 	.serdes_power = mv88e6390_serdes_power,
@@ -3963,6 +4084,8 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.phylink_validate = mv88e6185_phylink_validate,
@@ -4003,6 +4126,8 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
 	.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.avb_ops = &mv88e6352_avb_ops,
@@ -4049,6 +4174,8 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6352_g1_rmu_disable,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6352_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
 	.serdes_get_lane = mv88e6352_serdes_get_lane,
@@ -4105,6 +4232,8 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6390_g1_rmu_disable,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6390_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
 	.serdes_power = mv88e6390_serdes_power,
@@ -4158,6 +4287,8 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
 	.pot_clear = mv88e6xxx_g2_pot_clear,
 	.reset = mv88e6352_g1_reset,
 	.rmu_disable = mv88e6390_g1_rmu_disable,
+	.atu_get_hash = mv88e6165_g1_atu_get_hash,
+	.atu_set_hash = mv88e6165_g1_atu_set_hash,
 	.vtu_getnext = mv88e6390_g1_vtu_getnext,
 	.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
 	.serdes_power = mv88e6390_serdes_power,
@@ -4933,6 +5064,7 @@ static int mv88e6xxx_port_egress_floods(struct dsa_switch *ds, int port,
 static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
 	.get_tag_protocol	= mv88e6xxx_get_tag_protocol,
 	.setup			= mv88e6xxx_setup,
+	.teardown		= mv88e6xxx_teardown,
 	.phylink_validate	= mv88e6xxx_validate,
 	.phylink_mac_link_state	= mv88e6xxx_link_state,
 	.phylink_mac_config	= mv88e6xxx_mac_config,
@@ -4975,6 +5107,8 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
 	.port_txtstamp		= mv88e6xxx_port_txtstamp,
 	.port_rxtstamp		= mv88e6xxx_port_rxtstamp,
 	.get_ts_info		= mv88e6xxx_get_ts_info,
+	.devlink_param_get	= mv88e6xxx_devlink_param_get,
+	.devlink_param_set	= mv88e6xxx_devlink_param_set,
 };
 
 static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index e9b1a1ac9a8e..2d8042d38366 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -497,6 +497,10 @@ struct mv88e6xxx_ops {
 	int (*serdes_get_stats)(struct mv88e6xxx_chip *chip,  int port,
 				uint64_t *data);
 
+	/* Address Translation Unit operations */
+	int (*atu_get_hash)(struct mv88e6xxx_chip *chip);
+	int (*atu_set_hash)(struct mv88e6xxx_chip *chip, u8 hash);
+
 	/* VLAN Translation Unit operations */
 	int (*vtu_getnext)(struct mv88e6xxx_chip *chip,
 			   struct mv88e6xxx_vtu_entry *entry);
diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h
index 0870fcc8bfc8..a2a9e0a78dd7 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.h
+++ b/drivers/net/dsa/mv88e6xxx/global1.h
@@ -109,6 +109,7 @@
 /* Offset 0x0A: ATU Control Register */
 #define MV88E6XXX_G1_ATU_CTL		0x0a
 #define MV88E6XXX_G1_ATU_CTL_LEARN2ALL	0x0008
+#define MV88E6161_G1_ATU_CTL_HASH_MASK	0x3
 
 /* Offset 0x0B: ATU Operation Register */
 #define MV88E6XXX_G1_ATU_OP				0x0b
@@ -318,6 +319,8 @@ int mv88e6xxx_g1_atu_remove(struct mv88e6xxx_chip *chip, u16 fid, int port,
 			    bool all);
 int mv88e6xxx_g1_atu_prob_irq_setup(struct mv88e6xxx_chip *chip);
 void mv88e6xxx_g1_atu_prob_irq_free(struct mv88e6xxx_chip *chip);
+int mv88e6165_g1_atu_get_hash(struct mv88e6xxx_chip *chip);
+int mv88e6165_g1_atu_set_hash(struct mv88e6xxx_chip *chip, u8 hash);
 
 int mv88e6185_g1_vtu_getnext(struct mv88e6xxx_chip *chip,
 			     struct mv88e6xxx_vtu_entry *entry);
diff --git a/drivers/net/dsa/mv88e6xxx/global1_atu.c b/drivers/net/dsa/mv88e6xxx/global1_atu.c
index 792a96ef418f..11496612e915 100644
--- a/drivers/net/dsa/mv88e6xxx/global1_atu.c
+++ b/drivers/net/dsa/mv88e6xxx/global1_atu.c
@@ -73,6 +73,36 @@ int mv88e6xxx_g1_atu_set_age_time(struct mv88e6xxx_chip *chip,
 	return 0;
 }
 
+int mv88e6165_g1_atu_get_hash(struct mv88e6xxx_chip *chip)
+{
+	int err;
+	u16 val;
+
+	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_CTL, &val);
+	if (err)
+		return err;
+
+	return val & MV88E6161_G1_ATU_CTL_HASH_MASK;
+}
+
+int mv88e6165_g1_atu_set_hash(struct mv88e6xxx_chip *chip, u8 hash)
+{
+	int err;
+	u16 val;
+
+	if (hash & ~MV88E6161_G1_ATU_CTL_HASH_MASK)
+		return -EINVAL;
+
+	err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_ATU_CTL, &val);
+	if (err)
+		return err;
+
+	val &= ~MV88E6161_G1_ATU_CTL_HASH_MASK;
+	val |= hash;
+
+	return mv88e6xxx_g1_write(chip, MV88E6XXX_G1_ATU_CTL, val);
+}
+
 /* Offset 0x0B: ATU Operation Register */
 
 static int mv88e6xxx_g1_atu_op_wait(struct mv88e6xxx_chip *chip)
-- 
2.23.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next 0/2] mv88e6xxx: Allow config of ATU hash algorithm
  2019-10-04  1:35 [PATCH net-next 0/2] mv88e6xxx: Allow config of ATU hash algorithm Andrew Lunn
  2019-10-04  1:35 ` [PATCH net-next 1/2] net: dsa: Add support for devlink device parameters Andrew Lunn
  2019-10-04  1:35 ` [PATCH net-next 2/2] net: dsa: mv88e6xxx: Add devlink param for ATU hash algorithm Andrew Lunn
@ 2019-10-04  2:14 ` Jakub Kicinski
  2019-10-04 12:47   ` Andrew Lunn
  2019-10-04  8:44 ` Vladimir Oltean
  3 siblings, 1 reply; 8+ messages in thread
From: Jakub Kicinski @ 2019-10-04  2:14 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: David Miller, netdev, Vivien Didelot, Florian Fainelli

On Fri,  4 Oct 2019 03:35:21 +0200, Andrew Lunn wrote:
> The Marvell switches allow the hash algorithm for MAC addresses in the
> address translation unit to be configured. Add support to the DSA core
> to allow DSA drivers to make use of devlink parameters, and allow the
> ATU hash to be get/set via such a parameter.
> 
> Andrew Lunn (2):
>   net: dsa: Add support for devlink device parameters
>   net: dsa: mv88e6xxx: Add devlink param for ATU hash algorithm.
> 
>  drivers/net/dsa/mv88e6xxx/chip.c        | 136 +++++++++++++++++++++++-
>  drivers/net/dsa/mv88e6xxx/chip.h        |   4 +
>  drivers/net/dsa/mv88e6xxx/global1.h     |   3 +
>  drivers/net/dsa/mv88e6xxx/global1_atu.c |  30 ++++++
>  include/net/dsa.h                       |  23 ++++
>  net/dsa/dsa.c                           |  48 +++++++++
>  net/dsa/dsa2.c                          |   7 +-
>  7 files changed, 249 insertions(+), 2 deletions(-)

We try to make sure devlink parameters are documented under
Documentation/networking/devlink-params-$drv. Could you add 
a simple doc for mv88e6xxx with a short description?

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next 0/2] mv88e6xxx: Allow config of ATU hash algorithm
  2019-10-04  1:35 [PATCH net-next 0/2] mv88e6xxx: Allow config of ATU hash algorithm Andrew Lunn
                   ` (2 preceding siblings ...)
  2019-10-04  2:14 ` [PATCH net-next 0/2] mv88e6xxx: Allow config of " Jakub Kicinski
@ 2019-10-04  8:44 ` Vladimir Oltean
  2019-10-04 13:00   ` Andrew Lunn
  3 siblings, 1 reply; 8+ messages in thread
From: Vladimir Oltean @ 2019-10-04  8:44 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: David Miller, netdev, Vivien Didelot, Florian Fainelli

Hi Andrew,

On Fri, 4 Oct 2019 at 10:55, Andrew Lunn <andrew@lunn.ch> wrote:
>
> The Marvell switches allow the hash algorithm for MAC addresses in the
> address translation unit to be configured. Add support to the DSA core
> to allow DSA drivers to make use of devlink parameters, and allow the
> ATU hash to be get/set via such a parameter.
>

What is the hash algorithm used by mv88e6xxx? In sja1105 it is simply
crc32 over the {DMAC, VLAN} key, with a configurable polynomial
(stored in Koopman notation, but that is maybe irrelevant).
Are you really changing the algorithm, but only the hashing function's seed?
If the sja1105 is in any way similar to mv88e6xxx, maybe it would make
sense to devise a more generic devlink attribute?
Also, I believe the hashing function is only relevant if the ATU's CAM
is set- (not fully-) associative. Then it would make sense to maybe
let the user know what the total number of FDB entries and buckets is?
I am not clear even after looking at the mv88e6xxx_g1_atu_* functions.
How would they know they need to change the hash function, and what to
change it to?

> Andrew Lunn (2):
>   net: dsa: Add support for devlink device parameters
>   net: dsa: mv88e6xxx: Add devlink param for ATU hash algorithm.
>
>  drivers/net/dsa/mv88e6xxx/chip.c        | 136 +++++++++++++++++++++++-
>  drivers/net/dsa/mv88e6xxx/chip.h        |   4 +
>  drivers/net/dsa/mv88e6xxx/global1.h     |   3 +
>  drivers/net/dsa/mv88e6xxx/global1_atu.c |  30 ++++++
>  include/net/dsa.h                       |  23 ++++
>  net/dsa/dsa.c                           |  48 +++++++++
>  net/dsa/dsa2.c                          |   7 +-
>  7 files changed, 249 insertions(+), 2 deletions(-)
>
> --
> 2.23.0
>

Regards,
-Vladimir

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next 0/2] mv88e6xxx: Allow config of ATU hash algorithm
  2019-10-04  2:14 ` [PATCH net-next 0/2] mv88e6xxx: Allow config of " Jakub Kicinski
@ 2019-10-04 12:47   ` Andrew Lunn
  0 siblings, 0 replies; 8+ messages in thread
From: Andrew Lunn @ 2019-10-04 12:47 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: David Miller, netdev, Vivien Didelot, Florian Fainelli

On Thu, Oct 03, 2019 at 07:14:55PM -0700, Jakub Kicinski wrote:
> On Fri,  4 Oct 2019 03:35:21 +0200, Andrew Lunn wrote:
> > The Marvell switches allow the hash algorithm for MAC addresses in the
> > address translation unit to be configured. Add support to the DSA core
> > to allow DSA drivers to make use of devlink parameters, and allow the
> > ATU hash to be get/set via such a parameter.
> > 
> > Andrew Lunn (2):
> >   net: dsa: Add support for devlink device parameters
> >   net: dsa: mv88e6xxx: Add devlink param for ATU hash algorithm.
> > 
> >  drivers/net/dsa/mv88e6xxx/chip.c        | 136 +++++++++++++++++++++++-
> >  drivers/net/dsa/mv88e6xxx/chip.h        |   4 +
> >  drivers/net/dsa/mv88e6xxx/global1.h     |   3 +
> >  drivers/net/dsa/mv88e6xxx/global1_atu.c |  30 ++++++
> >  include/net/dsa.h                       |  23 ++++
> >  net/dsa/dsa.c                           |  48 +++++++++
> >  net/dsa/dsa2.c                          |   7 +-
> >  7 files changed, 249 insertions(+), 2 deletions(-)
> 
> We try to make sure devlink parameters are documented under
> Documentation/networking/devlink-params-$drv. Could you add 
> a simple doc for mv88e6xxx with a short description?

Jakub

Sure, no problem.

I don't know what the hash algorithms actually are, we have just
played around and found that in some settings, a different value
helps. So the documentation will be limited.

	Andrew

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next 0/2] mv88e6xxx: Allow config of ATU hash algorithm
  2019-10-04  8:44 ` Vladimir Oltean
@ 2019-10-04 13:00   ` Andrew Lunn
  0 siblings, 0 replies; 8+ messages in thread
From: Andrew Lunn @ 2019-10-04 13:00 UTC (permalink / raw)
  To: Vladimir Oltean; +Cc: David Miller, netdev, Vivien Didelot, Florian Fainelli

On Fri, Oct 04, 2019 at 11:44:02AM +0300, Vladimir Oltean wrote:
> Hi Andrew,
> 
> On Fri, 4 Oct 2019 at 10:55, Andrew Lunn <andrew@lunn.ch> wrote:
> >
> > The Marvell switches allow the hash algorithm for MAC addresses in the
> > address translation unit to be configured. Add support to the DSA core
> > to allow DSA drivers to make use of devlink parameters, and allow the
> > ATU hash to be get/set via such a parameter.
> >
> 
> What is the hash algorithm used by mv88e6xxx? In sja1105 it is simply
> crc32 over the {DMAC, VLAN} key, with a configurable polynomial
> (stored in Koopman notation, but that is maybe irrelevant).
> Are you really changing the algorithm, but only the hashing function's seed?
> If the sja1105 is in any way similar to mv88e6xxx, maybe it would make
> sense to devise a more generic devlink attribute?
> Also, I believe the hashing function is only relevant if the ATU's CAM
> is set- (not fully-) associative. Then it would make sense to maybe
> let the user know what the total number of FDB entries and buckets is?
> I am not clear even after looking at the mv88e6xxx_g1_atu_* functions.
> How would they know they need to change the hash function, and what to
> change it to?

Hi Vladimir

I have a second patchset which gives you an idea of the fill level. It
is documented that there are 4 buckets, and you can get the number of
buckets which are used at each level. The patch will also give the
total number of ATU entries.

The datasheet does not specify how the hashing is performed, just that
there are 4 possible configurations. We founds that the default
configuration does not work too well when all the equipment is from
one vendor, so the OUI is the same. By changing the algorithm we got a
better spread. Maybe it is giving more weight to the lower bits of the
MAC address?

Given the level of undocumented black magic, i don't know if we can do
a more generic configuration.

  Andrew

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH net-next 2/2] net: dsa: mv88e6xxx: Add devlink param for ATU hash algorithm.
  2019-10-04  1:35 ` [PATCH net-next 2/2] net: dsa: mv88e6xxx: Add devlink param for ATU hash algorithm Andrew Lunn
@ 2019-10-04 14:47   ` Vivien Didelot
  0 siblings, 0 replies; 8+ messages in thread
From: Vivien Didelot @ 2019-10-04 14:47 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: David Miller, netdev, Florian Fainelli, Andrew Lunn

Hi Andrew,

On Fri,  4 Oct 2019 03:35:23 +0200, Andrew Lunn <andrew@lunn.ch> wrote:
> Some of the marvell switches have bits controlling the hash algorithm
> the ATU uses for MAC addresses. In some industrial settings, where all
> the devices are from the same manufacture, and hence use the same OUI,
> the default hashing algorithm is not optimal. Allow the other
> algorithms to be selected via devlink.
> 
> Signed-off-by: Andrew Lunn <andrew@lunn.ch>
> ---
>  drivers/net/dsa/mv88e6xxx/chip.c        | 136 +++++++++++++++++++++++-
>  drivers/net/dsa/mv88e6xxx/chip.h        |   4 +
>  drivers/net/dsa/mv88e6xxx/global1.h     |   3 +
>  drivers/net/dsa/mv88e6xxx/global1_atu.c |  30 ++++++
>  4 files changed, 172 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
> index 6787d560e9e3..ebadcdba03df 100644
> --- a/drivers/net/dsa/mv88e6xxx/chip.c
> +++ b/drivers/net/dsa/mv88e6xxx/chip.c
> @@ -1370,6 +1370,22 @@ static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid)
>  	return mv88e6xxx_g1_atu_flush(chip, *fid, true);
>  }
>  
> +static int mv88e6xxx_atu_get_hash(struct mv88e6xxx_chip *chip)
> +{
> +	if (chip->info->ops->atu_get_hash)
> +		return chip->info->ops->atu_get_hash(chip);
> +
> +	return -EOPNOTSUPP;
> +}
> +
> +static int mv88e6xxx_atu_set_hash(struct mv88e6xxx_chip *chip, u8 hash)
> +{
> +	if (chip->info->ops->atu_set_hash)
> +		return chip->info->ops->atu_set_hash(chip, hash);
> +
> +	return -EOPNOTSUPP;
> +}
> +
>  static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
>  					u16 vid_begin, u16 vid_end)
>  {
> @@ -2641,6 +2657,83 @@ static int mv88e6390_setup_errata(struct mv88e6xxx_chip *chip)
>  	return mv88e6xxx_software_reset(chip);
>  }
>  
> +enum mv88e6xxx_devlink_param_id {
> +	MV88E6XXX_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
> +	MV88E6XXX_DEVLINK_PARAM_ID_ATU_HASH,
> +};
> +
> +static int mv88e6xxx_devlink_param_get(struct dsa_switch *ds, u32 id,
> +				       struct devlink_param_gset_ctx *ctx)
> +{
> +	struct mv88e6xxx_chip *chip = ds->priv;
> +	int err = 0;
> +	int hash;
> +
> +	mv88e6xxx_reg_lock(chip);
> +
> +	switch (id) {
> +	case MV88E6XXX_DEVLINK_PARAM_ID_ATU_HASH:
> +		hash = mv88e6xxx_atu_get_hash(chip);
> +		if (hash < 0) {
> +			err = hash;
> +			break;
> +		}

Could you please keep the common construct used in the driver for
functions which may fail, that is to say using a pointer to the correct
type and only returning error codes, so that we end up with something
like this:

    u8 hash;
    int err;

    err = mv88e6xxx_atu_get_hash(chip, &hash);
    if (err)
        ...


Thanks,

	Vivien

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2019-10-04 14:47 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-04  1:35 [PATCH net-next 0/2] mv88e6xxx: Allow config of ATU hash algorithm Andrew Lunn
2019-10-04  1:35 ` [PATCH net-next 1/2] net: dsa: Add support for devlink device parameters Andrew Lunn
2019-10-04  1:35 ` [PATCH net-next 2/2] net: dsa: mv88e6xxx: Add devlink param for ATU hash algorithm Andrew Lunn
2019-10-04 14:47   ` Vivien Didelot
2019-10-04  2:14 ` [PATCH net-next 0/2] mv88e6xxx: Allow config of " Jakub Kicinski
2019-10-04 12:47   ` Andrew Lunn
2019-10-04  8:44 ` Vladimir Oltean
2019-10-04 13:00   ` Andrew Lunn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).