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 <and...@lunn.ch>
Tested-by: Florian Fainelli <f.faine...@gmail.com>
---
 drivers/net/dsa/mv88e6xxx/chip.c | 76 +++++++++++++++++++++++++++-------------
 drivers/net/dsa/mv88e6xxx/chip.h | 13 +++++--
 2 files changed, 62 insertions(+), 27 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 27ca0fcb1040..243d274aace5 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -689,8 +689,8 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct 
mv88e6xxx_chip *chip,
        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;
        int i, j;
@@ -703,31 +703,39 @@ static void mv88e6xxx_stats_get_strings(struct 
mv88e6xxx_chip *chip,
                        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,
                                  uint8_t *data)
 {
        struct mv88e6xxx_chip *chip = ds->priv;
+       int count = 0;
 
        mutex_lock(&chip->reg_lock);
 
        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);
 }
@@ -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)
 {
        struct mv88e6xxx_chip *chip = ds->priv;
-       int ret = 0;
+       int serdes_count = 0;
+       int count = 0;
 
        mutex_lock(&chip->reg_lock);
        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);
 
-       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;
        int i, j;
@@ -790,18 +810,19 @@ static void mv88e6xxx_stats_get_stats(struct 
mv88e6xxx_chip *chip, int port,
                        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,
                                         STATS_TYPE_BANK0 | STATS_TYPE_PORT,
                                         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,
                                         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);
 }
 
-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,
                                         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,
                                uint64_t *data)
 {
+       int count = 0;
+
        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,
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index d6a1391dc268..e1ed1b7ca319 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -386,9 +386,9 @@ struct mv88e6xxx_ops {
 
        /* Return the number of strings describing statistics */
        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_egress_port)(struct mv88e6xxx_chip *chip, int port);
        const struct mv88e6xxx_irq_ops *watchdog_ops;
@@ -398,6 +398,13 @@ struct mv88e6xxx_ops {
        /* Power on/off a SERDES interface */
        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 */
        int (*vtu_getnext)(struct mv88e6xxx_chip *chip,
                           struct mv88e6xxx_vtu_entry *entry);
-- 
2.16.2

Reply via email to