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

Merge branch 'mv88e6xxx-ATU-occupancy-as-devlink-resource'



Andrew Lunn says:

====================
mv88e6xxx ATU occupancy as devlink resource

This patchset add generic support to DSA for devlink resources. The
Marvell switch Address Translation Unit occupancy is then exported as
a resource. In order to do this, the number of ATU entries is added to
the per switch info structure. Helpers are added, and then the
resource itself is then added.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 2ee6ad1d e0c69ca7
Loading
Loading
Loading
Loading
+211 −4
Original line number Diff line number Diff line
@@ -2720,9 +2720,179 @@ static void mv88e6xxx_teardown_devlink_params(struct dsa_switch *ds)
				      ARRAY_SIZE(mv88e6xxx_devlink_params));
}

enum mv88e6xxx_devlink_resource_id {
	MV88E6XXX_RESOURCE_ID_ATU,
	MV88E6XXX_RESOURCE_ID_ATU_BIN_0,
	MV88E6XXX_RESOURCE_ID_ATU_BIN_1,
	MV88E6XXX_RESOURCE_ID_ATU_BIN_2,
	MV88E6XXX_RESOURCE_ID_ATU_BIN_3,
};

static u64 mv88e6xxx_devlink_atu_bin_get(struct mv88e6xxx_chip *chip,
					 u16 bin)
{
	u16 occupancy = 0;
	int err;

	mv88e6xxx_reg_lock(chip);

	err = mv88e6xxx_g2_atu_stats_set(chip, MV88E6XXX_G2_ATU_STATS_MODE_ALL,
					 bin);
	if (err) {
		dev_err(chip->dev, "failed to set ATU stats kind/bin\n");
		goto unlock;
	}

	err = mv88e6xxx_g1_atu_get_next(chip, 0);
	if (err) {
		dev_err(chip->dev, "failed to perform ATU get next\n");
		goto unlock;
	}

	err = mv88e6xxx_g2_atu_stats_get(chip, &occupancy);
	if (err) {
		dev_err(chip->dev, "failed to get ATU stats\n");
		goto unlock;
	}

unlock:
	mv88e6xxx_reg_unlock(chip);

	return occupancy;
}

static u64 mv88e6xxx_devlink_atu_bin_0_get(void *priv)
{
	struct mv88e6xxx_chip *chip = priv;

	return mv88e6xxx_devlink_atu_bin_get(chip,
					     MV88E6XXX_G2_ATU_STATS_BIN_0);
}

static u64 mv88e6xxx_devlink_atu_bin_1_get(void *priv)
{
	struct mv88e6xxx_chip *chip = priv;

	return mv88e6xxx_devlink_atu_bin_get(chip,
					     MV88E6XXX_G2_ATU_STATS_BIN_1);
}

static u64 mv88e6xxx_devlink_atu_bin_2_get(void *priv)
{
	struct mv88e6xxx_chip *chip = priv;

	return mv88e6xxx_devlink_atu_bin_get(chip,
					     MV88E6XXX_G2_ATU_STATS_BIN_2);
}

static u64 mv88e6xxx_devlink_atu_bin_3_get(void *priv)
{
	struct mv88e6xxx_chip *chip = priv;

	return mv88e6xxx_devlink_atu_bin_get(chip,
					     MV88E6XXX_G2_ATU_STATS_BIN_3);
}

static u64 mv88e6xxx_devlink_atu_get(void *priv)
{
	return mv88e6xxx_devlink_atu_bin_0_get(priv) +
		mv88e6xxx_devlink_atu_bin_1_get(priv) +
		mv88e6xxx_devlink_atu_bin_2_get(priv) +
		mv88e6xxx_devlink_atu_bin_3_get(priv);
}

static int mv88e6xxx_setup_devlink_resources(struct dsa_switch *ds)
{
	struct devlink_resource_size_params size_params;
	struct mv88e6xxx_chip *chip = ds->priv;
	int err;

	devlink_resource_size_params_init(&size_params,
					  mv88e6xxx_num_macs(chip),
					  mv88e6xxx_num_macs(chip),
					  1, DEVLINK_RESOURCE_UNIT_ENTRY);

	err = dsa_devlink_resource_register(ds, "ATU",
					    mv88e6xxx_num_macs(chip),
					    MV88E6XXX_RESOURCE_ID_ATU,
					    DEVLINK_RESOURCE_ID_PARENT_TOP,
					    &size_params);
	if (err)
		goto out;

	devlink_resource_size_params_init(&size_params,
					  mv88e6xxx_num_macs(chip) / 4,
					  mv88e6xxx_num_macs(chip) / 4,
					  1, DEVLINK_RESOURCE_UNIT_ENTRY);

	err = dsa_devlink_resource_register(ds, "ATU_bin_0",
					    mv88e6xxx_num_macs(chip) / 4,
					    MV88E6XXX_RESOURCE_ID_ATU_BIN_0,
					    MV88E6XXX_RESOURCE_ID_ATU,
					    &size_params);
	if (err)
		goto out;

	err = dsa_devlink_resource_register(ds, "ATU_bin_1",
					    mv88e6xxx_num_macs(chip) / 4,
					    MV88E6XXX_RESOURCE_ID_ATU_BIN_1,
					    MV88E6XXX_RESOURCE_ID_ATU,
					    &size_params);
	if (err)
		goto out;

	err = dsa_devlink_resource_register(ds, "ATU_bin_2",
					    mv88e6xxx_num_macs(chip) / 4,
					    MV88E6XXX_RESOURCE_ID_ATU_BIN_2,
					    MV88E6XXX_RESOURCE_ID_ATU,
					    &size_params);
	if (err)
		goto out;

	err = dsa_devlink_resource_register(ds, "ATU_bin_3",
					    mv88e6xxx_num_macs(chip) / 4,
					    MV88E6XXX_RESOURCE_ID_ATU_BIN_3,
					    MV88E6XXX_RESOURCE_ID_ATU,
					    &size_params);
	if (err)
		goto out;

	dsa_devlink_resource_occ_get_register(ds,
					      MV88E6XXX_RESOURCE_ID_ATU,
					      mv88e6xxx_devlink_atu_get,
					      chip);

	dsa_devlink_resource_occ_get_register(ds,
					      MV88E6XXX_RESOURCE_ID_ATU_BIN_0,
					      mv88e6xxx_devlink_atu_bin_0_get,
					      chip);

	dsa_devlink_resource_occ_get_register(ds,
					      MV88E6XXX_RESOURCE_ID_ATU_BIN_1,
					      mv88e6xxx_devlink_atu_bin_1_get,
					      chip);

	dsa_devlink_resource_occ_get_register(ds,
					      MV88E6XXX_RESOURCE_ID_ATU_BIN_2,
					      mv88e6xxx_devlink_atu_bin_2_get,
					      chip);

	dsa_devlink_resource_occ_get_register(ds,
					      MV88E6XXX_RESOURCE_ID_ATU_BIN_3,
					      mv88e6xxx_devlink_atu_bin_3_get,
					      chip);

	return 0;

out:
	dsa_devlink_resources_unregister(ds);
	return err;
}

static void mv88e6xxx_teardown(struct dsa_switch *ds)
{
	mv88e6xxx_teardown_devlink_params(ds);
	dsa_devlink_resources_unregister(ds);
}

static int mv88e6xxx_setup(struct dsa_switch *ds)
@@ -2841,11 +3011,23 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
unlock:
	mv88e6xxx_reg_unlock(chip);

	/* 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.
	if (err)
		return err;

	/* Have to be called without holding the register lock, since
	 * they take the devlink lock, and we later take the locks in
	 * the reverse order when getting/setting parameters or
	 * resource occupancy.
	 */
	return mv88e6xxx_setup_devlink_params(ds);
	err = mv88e6xxx_setup_devlink_resources(ds);
	if (err)
		return err;

	err = mv88e6xxx_setup_devlink_params(ds);
	if (err)
		dsa_devlink_resources_unregister(ds);

	return err;
}

static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
@@ -4299,6 +4481,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6097,
		.name = "Marvell 88E6085",
		.num_databases = 4096,
		.num_macs = 8192,
		.num_ports = 10,
		.num_internal_phys = 5,
		.max_vid = 4095,
@@ -4321,6 +4504,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6095,
		.name = "Marvell 88E6095/88E6095F",
		.num_databases = 256,
		.num_macs = 8192,
		.num_ports = 11,
		.num_internal_phys = 0,
		.max_vid = 4095,
@@ -4341,6 +4525,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6097,
		.name = "Marvell 88E6097/88E6097F",
		.num_databases = 4096,
		.num_macs = 8192,
		.num_ports = 11,
		.num_internal_phys = 8,
		.max_vid = 4095,
@@ -4363,6 +4548,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6165,
		.name = "Marvell 88E6123",
		.num_databases = 4096,
		.num_macs = 1024,
		.num_ports = 3,
		.num_internal_phys = 5,
		.max_vid = 4095,
@@ -4385,6 +4571,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6185,
		.name = "Marvell 88E6131",
		.num_databases = 256,
		.num_macs = 8192,
		.num_ports = 8,
		.num_internal_phys = 0,
		.max_vid = 4095,
@@ -4405,6 +4592,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6341,
		.name = "Marvell 88E6141",
		.num_databases = 4096,
		.num_macs = 2048,
		.num_ports = 6,
		.num_internal_phys = 5,
		.num_gpio = 11,
@@ -4428,6 +4616,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6165,
		.name = "Marvell 88E6161",
		.num_databases = 4096,
		.num_macs = 1024,
		.num_ports = 6,
		.num_internal_phys = 5,
		.max_vid = 4095,
@@ -4451,6 +4640,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6165,
		.name = "Marvell 88E6165",
		.num_databases = 4096,
		.num_macs = 8192,
		.num_ports = 6,
		.num_internal_phys = 0,
		.max_vid = 4095,
@@ -4474,6 +4664,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6351,
		.name = "Marvell 88E6171",
		.num_databases = 4096,
		.num_macs = 8192,
		.num_ports = 7,
		.num_internal_phys = 5,
		.max_vid = 4095,
@@ -4496,6 +4687,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6352,
		.name = "Marvell 88E6172",
		.num_databases = 4096,
		.num_macs = 8192,
		.num_ports = 7,
		.num_internal_phys = 5,
		.num_gpio = 15,
@@ -4519,6 +4711,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6351,
		.name = "Marvell 88E6175",
		.num_databases = 4096,
		.num_macs = 8192,
		.num_ports = 7,
		.num_internal_phys = 5,
		.max_vid = 4095,
@@ -4541,6 +4734,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6352,
		.name = "Marvell 88E6176",
		.num_databases = 4096,
		.num_macs = 8192,
		.num_ports = 7,
		.num_internal_phys = 5,
		.num_gpio = 15,
@@ -4564,6 +4758,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6185,
		.name = "Marvell 88E6185",
		.num_databases = 256,
		.num_macs = 8192,
		.num_ports = 10,
		.num_internal_phys = 0,
		.max_vid = 4095,
@@ -4584,6 +4779,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6390,
		.name = "Marvell 88E6190",
		.num_databases = 4096,
		.num_macs = 16384,
		.num_ports = 11,	/* 10 + Z80 */
		.num_internal_phys = 9,
		.num_gpio = 16,
@@ -4607,6 +4803,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6390,
		.name = "Marvell 88E6190X",
		.num_databases = 4096,
		.num_macs = 16384,
		.num_ports = 11,	/* 10 + Z80 */
		.num_internal_phys = 9,
		.num_gpio = 16,
@@ -4630,6 +4827,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6390,
		.name = "Marvell 88E6191",
		.num_databases = 4096,
		.num_macs = 16384,
		.num_ports = 11,	/* 10 + Z80 */
		.num_internal_phys = 9,
		.max_vid = 8191,
@@ -4680,6 +4878,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6352,
		.name = "Marvell 88E6240",
		.num_databases = 4096,
		.num_macs = 8192,
		.num_ports = 7,
		.num_internal_phys = 5,
		.num_gpio = 15,
@@ -4750,6 +4949,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6320,
		.name = "Marvell 88E6320",
		.num_databases = 4096,
		.num_macs = 8192,
		.num_ports = 7,
		.num_internal_phys = 5,
		.num_gpio = 15,
@@ -4774,6 +4974,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6320,
		.name = "Marvell 88E6321",
		.num_databases = 4096,
		.num_macs = 8192,
		.num_ports = 7,
		.num_internal_phys = 5,
		.num_gpio = 15,
@@ -4797,6 +4998,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6341,
		.name = "Marvell 88E6341",
		.num_databases = 4096,
		.num_macs = 2048,
		.num_internal_phys = 5,
		.num_ports = 6,
		.num_gpio = 11,
@@ -4821,6 +5023,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6351,
		.name = "Marvell 88E6350",
		.num_databases = 4096,
		.num_macs = 8192,
		.num_ports = 7,
		.num_internal_phys = 5,
		.max_vid = 4095,
@@ -4843,6 +5046,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6351,
		.name = "Marvell 88E6351",
		.num_databases = 4096,
		.num_macs = 8192,
		.num_ports = 7,
		.num_internal_phys = 5,
		.max_vid = 4095,
@@ -4865,6 +5069,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6352,
		.name = "Marvell 88E6352",
		.num_databases = 4096,
		.num_macs = 8192,
		.num_ports = 7,
		.num_internal_phys = 5,
		.num_gpio = 15,
@@ -4888,6 +5093,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6390,
		.name = "Marvell 88E6390",
		.num_databases = 4096,
		.num_macs = 16384,
		.num_ports = 11,	/* 10 + Z80 */
		.num_internal_phys = 9,
		.num_gpio = 16,
@@ -4911,6 +5117,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
		.family = MV88E6XXX_FAMILY_6390,
		.name = "Marvell 88E6390X",
		.num_databases = 4096,
		.num_macs = 16384,
		.num_ports = 11,	/* 10 + Z80 */
		.num_internal_phys = 9,
		.num_gpio = 16,
+6 −0
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@ struct mv88e6xxx_info {
	u16 prod_num;
	const char *name;
	unsigned int num_databases;
	unsigned int num_macs;
	unsigned int num_ports;
	unsigned int num_internal_phys;
	unsigned int num_gpio;
@@ -613,6 +614,11 @@ static inline unsigned int mv88e6xxx_num_databases(struct mv88e6xxx_chip *chip)
	return chip->info->num_databases;
}

static inline unsigned int mv88e6xxx_num_macs(struct  mv88e6xxx_chip *chip)
{
	return chip->info->num_macs;
}

static inline unsigned int mv88e6xxx_num_ports(struct mv88e6xxx_chip *chip)
{
	return chip->info->num_ports;
+1 −0
Original line number Diff line number Diff line
@@ -341,5 +341,6 @@ int mv88e6390_g1_vtu_loadpurge(struct mv88e6xxx_chip *chip,
int mv88e6xxx_g1_vtu_flush(struct mv88e6xxx_chip *chip);
int mv88e6xxx_g1_vtu_prob_irq_setup(struct mv88e6xxx_chip *chip);
void mv88e6xxx_g1_vtu_prob_irq_free(struct mv88e6xxx_chip *chip);
int mv88e6xxx_g1_atu_get_next(struct mv88e6xxx_chip *chip, u16 fid);

#endif /* _MV88E6XXX_GLOBAL1_H */
+5 −0
Original line number Diff line number Diff line
@@ -154,6 +154,11 @@ static int mv88e6xxx_g1_atu_op(struct mv88e6xxx_chip *chip, u16 fid, u16 op)
	return mv88e6xxx_g1_atu_op_wait(chip);
}

int mv88e6xxx_g1_atu_get_next(struct mv88e6xxx_chip *chip, u16 fid)
{
	return mv88e6xxx_g1_atu_op(chip, fid, MV88E6XXX_G1_ATU_OP_GET_NEXT_DB);
}

/* Offset 0x0C: ATU Data Register */

static int mv88e6xxx_g1_atu_data_read(struct mv88e6xxx_chip *chip,
+13 −0
Original line number Diff line number Diff line
@@ -280,6 +280,19 @@ int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr)
	return err;
}

/* Offset 0x0E: ATU Statistics */

int mv88e6xxx_g2_atu_stats_set(struct mv88e6xxx_chip *chip, u16 kind, u16 bin)
{
	return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_ATU_STATS,
				  kind | bin);
}

int mv88e6xxx_g2_atu_stats_get(struct mv88e6xxx_chip *chip, u16 *stats)
{
	return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_ATU_STATS, stats);
}

/* Offset 0x0F: Priority Override Table */

static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer,
Loading