Commit eb8b7077 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mv88e6xxx-Allow-config-of-ATU-hash-algorithm'



Andrew Lunn says:

====================
mv88e6xxx: Allow config of ATU hash algorithm

v2:

Pass a pointer for where the hash should be stored, return a plain
errno, or 0.

Document the parameter.

v3:

Document type of parameter, and valid range
Add break statements to default clause of switch
Directly use ctx->val.vu8

v4:

Consistently use devlink, not a mix of devlink and dl.
Fix allocation of devlink priv
Remove upper case from parameter name
Make mask 16 bit wide.

v5:
Back to using the parameter name ATU_hash

v6:
Rebase net-next/master
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ebdcebcb 23e8b470
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
ATU_hash		[DEVICE, DRIVER-SPECIFIC]
			Select one of four possible hashing algorithms for
			MAC addresses in the Address Translation Unit.
			A value of 3 seems to work better than the default of
			1 when many MAC addresses have the same OUI.
			Configuration mode: runtime
			Type: u8. 0-3 valid.
+1 −0
Original line number Diff line number Diff line
@@ -9744,6 +9744,7 @@ S: Maintained
F:	drivers/net/dsa/mv88e6xxx/
F:	include/linux/platform_data/mv88e6xxx.h
F:	Documentation/devicetree/bindings/net/dsa/marvell.txt
F:	Documentation/networking/devlink-params-mv88e6xxx.txt
MARVELL ARMADA DRM SUPPORT
M:	Russell King <linux@armlinux.org.uk>
+130 −1
Original line number Diff line number Diff line
@@ -1378,6 +1378,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, u8 *hash)
{
	if (chip->info->ops->atu_get_hash)
		return chip->info->ops->atu_get_hash(chip, hash);

	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)
{
@@ -2637,6 +2653,78 @@ 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;

	mv88e6xxx_reg_lock(chip);

	switch (id) {
	case MV88E6XXX_DEVLINK_PARAM_ID_ATU_HASH:
		err = mv88e6xxx_atu_get_hash(chip, &ctx->val.vu8);
		break;
	default:
		err = -EOPNOTSUPP;
		break;
	}

	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;
		break;
	}

	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;
@@ -2753,7 +2841,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)
@@ -3113,6 +3205,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,
@@ -3242,6 +3336,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,
@@ -3276,6 +3372,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,
@@ -3318,6 +3416,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,
@@ -3362,6 +3462,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,
@@ -3405,6 +3507,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,
@@ -3449,6 +3553,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,
@@ -3534,6 +3640,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,
@@ -3583,6 +3691,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,
@@ -3631,6 +3741,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,
@@ -3682,6 +3794,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,
@@ -3773,6 +3887,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,
@@ -3959,6 +4075,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,
@@ -3999,6 +4117,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,
@@ -4045,6 +4165,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,
@@ -4101,6 +4223,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,
@@ -4154,6 +4278,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,
@@ -4929,6 +5055,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,
@@ -4971,6 +5098,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)
+4 −0
Original line number Diff line number Diff line
@@ -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, u8 *hash);
	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);
+3 −0
Original line number Diff line number Diff line
@@ -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	0x0003

/* 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, u8 *hash);
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);
Loading