Jelajahi Sumber

net: dsa: mv88e6xxx: Allow the SERDES interfaces to have statistics

When gettting the number of statistics, the strings and the actual
statistics, call the SERDES ops if implemented. This means the stats
code needs to return the number of strings/stats they have placed into
the data, so that the SERDES strings/stats can follow on.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Andrew Lunn 7 tahun lalu
induk
melakukan
436fe17d27
2 mengubah file dengan 62 tambahan dan 27 penghapusan
  1. 52 24
      drivers/net/dsa/mv88e6xxx/chip.c
  2. 10 3
      drivers/net/dsa/mv88e6xxx/chip.h

+ 52 - 24
drivers/net/dsa/mv88e6xxx/chip.c

@@ -689,8 +689,8 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip,
 	return value;
 	return value;
 }
 }
 
 
-static void mv88e6xxx_stats_get_strings(struct mv88e6xxx_chip *chip,
-					uint8_t *data, int types)
+static int mv88e6xxx_stats_get_strings(struct mv88e6xxx_chip *chip,
+				       uint8_t *data, int types)
 {
 {
 	struct mv88e6xxx_hw_stat *stat;
 	struct mv88e6xxx_hw_stat *stat;
 	int i, j;
 	int i, j;
@@ -703,31 +703,39 @@ static void mv88e6xxx_stats_get_strings(struct mv88e6xxx_chip *chip,
 			j++;
 			j++;
 		}
 		}
 	}
 	}
+
+	return j;
 }
 }
 
 
-static void mv88e6095_stats_get_strings(struct mv88e6xxx_chip *chip,
-					uint8_t *data)
+static int mv88e6095_stats_get_strings(struct mv88e6xxx_chip *chip,
+				       uint8_t *data)
 {
 {
-	mv88e6xxx_stats_get_strings(chip, data,
-				    STATS_TYPE_BANK0 | STATS_TYPE_PORT);
+	return mv88e6xxx_stats_get_strings(chip, data,
+					   STATS_TYPE_BANK0 | STATS_TYPE_PORT);
 }
 }
 
 
-static void mv88e6320_stats_get_strings(struct mv88e6xxx_chip *chip,
-					uint8_t *data)
+static int mv88e6320_stats_get_strings(struct mv88e6xxx_chip *chip,
+				       uint8_t *data)
 {
 {
-	mv88e6xxx_stats_get_strings(chip, data,
-				    STATS_TYPE_BANK0 | STATS_TYPE_BANK1);
+	return mv88e6xxx_stats_get_strings(chip, data,
+					   STATS_TYPE_BANK0 | STATS_TYPE_BANK1);
 }
 }
 
 
 static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
 static void mv88e6xxx_get_strings(struct dsa_switch *ds, int port,
 				  uint8_t *data)
 				  uint8_t *data)
 {
 {
 	struct mv88e6xxx_chip *chip = ds->priv;
 	struct mv88e6xxx_chip *chip = ds->priv;
+	int count = 0;
 
 
 	mutex_lock(&chip->reg_lock);
 	mutex_lock(&chip->reg_lock);
 
 
 	if (chip->info->ops->stats_get_strings)
 	if (chip->info->ops->stats_get_strings)
-		chip->info->ops->stats_get_strings(chip, data);
+		count = chip->info->ops->stats_get_strings(chip, data);
+
+	if (chip->info->ops->serdes_get_strings) {
+		data += count * ETH_GSTRING_LEN;
+		chip->info->ops->serdes_get_strings(chip, port, data);
+	}
 
 
 	mutex_unlock(&chip->reg_lock);
 	mutex_unlock(&chip->reg_lock);
 }
 }
@@ -761,19 +769,31 @@ static int mv88e6320_stats_get_sset_count(struct mv88e6xxx_chip *chip)
 static int mv88e6xxx_get_sset_count(struct dsa_switch *ds, int port)
 static int mv88e6xxx_get_sset_count(struct dsa_switch *ds, int port)
 {
 {
 	struct mv88e6xxx_chip *chip = ds->priv;
 	struct mv88e6xxx_chip *chip = ds->priv;
-	int ret = 0;
+	int serdes_count = 0;
+	int count = 0;
 
 
 	mutex_lock(&chip->reg_lock);
 	mutex_lock(&chip->reg_lock);
 	if (chip->info->ops->stats_get_sset_count)
 	if (chip->info->ops->stats_get_sset_count)
-		ret = chip->info->ops->stats_get_sset_count(chip);
+		count = chip->info->ops->stats_get_sset_count(chip);
+	if (count < 0)
+		goto out;
+
+	if (chip->info->ops->serdes_get_sset_count)
+		serdes_count = chip->info->ops->serdes_get_sset_count(chip,
+								      port);
+	if (serdes_count < 0)
+		count = serdes_count;
+	else
+		count += serdes_count;
+out:
 	mutex_unlock(&chip->reg_lock);
 	mutex_unlock(&chip->reg_lock);
 
 
-	return ret;
+	return count;
 }
 }
 
 
-static void mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
-				      uint64_t *data, int types,
-				      u16 bank1_select, u16 histogram)
+static int mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
+				     uint64_t *data, int types,
+				     u16 bank1_select, u16 histogram)
 {
 {
 	struct mv88e6xxx_hw_stat *stat;
 	struct mv88e6xxx_hw_stat *stat;
 	int i, j;
 	int i, j;
@@ -790,18 +810,19 @@ static void mv88e6xxx_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
 			j++;
 			j++;
 		}
 		}
 	}
 	}
+	return j;
 }
 }
 
 
-static void mv88e6095_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
-				      uint64_t *data)
+static int mv88e6095_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
+				     uint64_t *data)
 {
 {
 	return mv88e6xxx_stats_get_stats(chip, port, data,
 	return mv88e6xxx_stats_get_stats(chip, port, data,
 					 STATS_TYPE_BANK0 | STATS_TYPE_PORT,
 					 STATS_TYPE_BANK0 | STATS_TYPE_PORT,
 					 0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
 					 0, MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
 }
 }
 
 
-static void mv88e6320_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
-				      uint64_t *data)
+static int mv88e6320_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
+				     uint64_t *data)
 {
 {
 	return mv88e6xxx_stats_get_stats(chip, port, data,
 	return mv88e6xxx_stats_get_stats(chip, port, data,
 					 STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
 					 STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
@@ -809,8 +830,8 @@ static void mv88e6320_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
 					 MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
 					 MV88E6XXX_G1_STATS_OP_HIST_RX_TX);
 }
 }
 
 
-static void mv88e6390_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
-				      uint64_t *data)
+static int mv88e6390_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
+				     uint64_t *data)
 {
 {
 	return mv88e6xxx_stats_get_stats(chip, port, data,
 	return mv88e6xxx_stats_get_stats(chip, port, data,
 					 STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
 					 STATS_TYPE_BANK0 | STATS_TYPE_BANK1,
@@ -821,8 +842,15 @@ static void mv88e6390_stats_get_stats(struct mv88e6xxx_chip *chip, int port,
 static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port,
 static void mv88e6xxx_get_stats(struct mv88e6xxx_chip *chip, int port,
 				uint64_t *data)
 				uint64_t *data)
 {
 {
+	int count = 0;
+
 	if (chip->info->ops->stats_get_stats)
 	if (chip->info->ops->stats_get_stats)
-		chip->info->ops->stats_get_stats(chip, port, data);
+		count = chip->info->ops->stats_get_stats(chip, port, data);
+
+	if (chip->info->ops->serdes_get_stats) {
+		data += count;
+		chip->info->ops->serdes_get_stats(chip, port, data);
+	}
 }
 }
 
 
 static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,
 static void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, int port,

+ 10 - 3
drivers/net/dsa/mv88e6xxx/chip.h

@@ -386,9 +386,9 @@ struct mv88e6xxx_ops {
 
 
 	/* Return the number of strings describing statistics */
 	/* Return the number of strings describing statistics */
 	int (*stats_get_sset_count)(struct mv88e6xxx_chip *chip);
 	int (*stats_get_sset_count)(struct mv88e6xxx_chip *chip);
-	void (*stats_get_strings)(struct mv88e6xxx_chip *chip,  uint8_t *data);
-	void (*stats_get_stats)(struct mv88e6xxx_chip *chip,  int port,
-				uint64_t *data);
+	int (*stats_get_strings)(struct mv88e6xxx_chip *chip,  uint8_t *data);
+	int (*stats_get_stats)(struct mv88e6xxx_chip *chip,  int port,
+			       uint64_t *data);
 	int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port);
 	int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port);
 	int (*set_egress_port)(struct mv88e6xxx_chip *chip, int port);
 	int (*set_egress_port)(struct mv88e6xxx_chip *chip, int port);
 	const struct mv88e6xxx_irq_ops *watchdog_ops;
 	const struct mv88e6xxx_irq_ops *watchdog_ops;
@@ -398,6 +398,13 @@ struct mv88e6xxx_ops {
 	/* Power on/off a SERDES interface */
 	/* Power on/off a SERDES interface */
 	int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, bool on);
 	int (*serdes_power)(struct mv88e6xxx_chip *chip, int port, bool on);
 
 
+	/* Statistics from the SERDES interface */
+	int (*serdes_get_sset_count)(struct mv88e6xxx_chip *chip, int port);
+	void (*serdes_get_strings)(struct mv88e6xxx_chip *chip,  int port,
+				   uint8_t *data);
+	void (*serdes_get_stats)(struct mv88e6xxx_chip *chip,  int port,
+				 uint64_t *data);
+
 	/* VLAN Translation Unit operations */
 	/* VLAN Translation Unit operations */
 	int (*vtu_getnext)(struct mv88e6xxx_chip *chip,
 	int (*vtu_getnext)(struct mv88e6xxx_chip *chip,
 			   struct mv88e6xxx_vtu_entry *entry);
 			   struct mv88e6xxx_vtu_entry *entry);