cyberchallenge-modem/buildroot/board/tiesse/tgr/kernel-patches/1008-imx8mm-clear-stats.patch

236 lines
7.8 KiB
Diff
Raw Normal View History

Index: include/uapi/linux/ethtool.h
===================================================================
--- include/uapi/linux/ethtool.h
+++ linux-imx/include/uapi/linux/ethtool.h
@@ -1377,6 +1377,7 @@ enum ethtool_fec_config_bits {
#define ETHTOOL_PHY_STUNABLE 0x0000004f /* Set PHY tunable configuration */
#define ETHTOOL_GFECPARAM 0x00000050 /* Get FEC settings */
#define ETHTOOL_SFECPARAM 0x00000051 /* Set FEC settings */
+#define ETHTOOL_CSTATS 0x00000052 /* Clear statistics */
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
Index: net/core/ethtool.c
===================================================================
--- net/core/ethtool.c
+++ linux-imx/net/core/ethtool.c
@@ -1938,6 +1938,15 @@ static int ethtool_get_stats(struct net_
return ret;
}
+static int ethtool_clear_stats(struct net_device *dev)
+{
+ if (!dev->ethtool_ops->clear_ethtool_stats)
+ return -EOPNOTSUPP;
+
+ dev->ethtool_ops->clear_ethtool_stats(dev);
+ return 0;
+}
+
static int ethtool_get_phy_stats(struct net_device *dev, void __user *useraddr)
{
struct ethtool_stats stats;
@@ -2577,6 +2586,7 @@ int dev_ethtool(struct net *net, struct
case ETHTOOL_GSSET_INFO:
case ETHTOOL_GSTRINGS:
case ETHTOOL_GSTATS:
+ case ETHTOOL_CSTATS:
case ETHTOOL_GPHYSTATS:
case ETHTOOL_GTSO:
case ETHTOOL_GPERMADDR:
@@ -2688,6 +2698,9 @@ int dev_ethtool(struct net *net, struct
case ETHTOOL_GSTATS:
rc = ethtool_get_stats(dev, useraddr);
break;
+ case ETHTOOL_CSTATS:
+ rc = ethtool_clear_stats(dev);
+ break;
case ETHTOOL_GPERMADDR:
rc = ethtool_get_perm_addr(dev, useraddr);
break;
Index: include/linux/ethtool.h
===================================================================
--- include/linux/ethtool.h
+++ linux-imx/include/linux/ethtool.h
@@ -347,6 +347,7 @@ struct ethtool_ops {
int (*set_phys_id)(struct net_device *, enum ethtool_phys_id_state);
void (*get_ethtool_stats)(struct net_device *,
struct ethtool_stats *, u64 *);
+ void (*clear_ethtool_stats)(struct net_device *);
int (*begin)(struct net_device *);
void (*complete)(struct net_device *);
u32 (*get_priv_flags)(struct net_device *);
Index: net/dsa/slave.c
===================================================================
--- net/dsa/slave.c
+++ linux-imx/net/dsa/slave.c
@@ -1019,6 +1019,30 @@ static int dsa_slave_set_rxnfc(struct ne
return ds->ops->set_rxnfc(ds, p->dp->index, nfc);
}
+static void dsa_slave_clear_ethtool_stats(struct net_device *dev)
+{
+ struct dsa_slave_priv *p = netdev_priv(dev);
+ struct dsa_switch *ds = p->dp->ds;
+ struct pcpu_sw_netstats *s;
+ unsigned int start;
+ int i;
+
+ memset(&dev->stats, 0, sizeof(struct net_device_stats));
+ for_each_possible_cpu(i) {
+ s = per_cpu_ptr(p->stats64, i);
+ do {
+ start = u64_stats_fetch_begin_irq(&s->syncp);
+ s->tx_packets = 0L;
+ s->tx_bytes = 0L;
+ s->rx_packets = 0L;
+ s->rx_bytes = 0L;
+ } while (u64_stats_fetch_retry_irq(&s->syncp, start));
+ }
+
+ if (ds->ops->clear_ethtool_stats)
+ ds->ops->clear_ethtool_stats(ds, p->dp->index);
+}
+
static const struct ethtool_ops dsa_slave_ethtool_ops = {
.get_drvinfo = dsa_slave_get_drvinfo,
.get_regs_len = dsa_slave_get_regs_len,
@@ -1039,6 +1063,7 @@ static const struct ethtool_ops dsa_slav
.set_link_ksettings = dsa_slave_set_link_ksettings,
.get_rxnfc = dsa_slave_get_rxnfc,
.set_rxnfc = dsa_slave_set_rxnfc,
+ .clear_ethtool_stats = dsa_slave_clear_ethtool_stats,
};
static const struct net_device_ops dsa_slave_netdev_ops = {
Index: drivers/net/dsa/mv88e6xxx/chip.h
===================================================================
--- drivers/net/dsa/mv88e6xxx/chip.h
+++ linux-imx/drivers/net/dsa/mv88e6xxx/chip.h
@@ -330,6 +330,7 @@ struct mv88e6xxx_ops {
void (*stats_get_strings)(struct mv88e6xxx_chip *chip, uint8_t *data);
void (*stats_get_stats)(struct mv88e6xxx_chip *chip, int port,
uint64_t *data);
+ void (*stats_clear_stats)(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);
const struct mv88e6xxx_irq_ops *watchdog_ops;
Index: include/net/dsa.h
===================================================================
--- include/net/dsa.h
+++ linux-imx/include/net/dsa.h
@@ -320,6 +320,7 @@ struct dsa_switch_ops {
void (*get_ethtool_stats)(struct dsa_switch *ds,
int port, uint64_t *data);
int (*get_sset_count)(struct dsa_switch *ds);
+ void (*clear_ethtool_stats)(struct dsa_switch *ds, int port);
/*
* ethtool Wake-on-LAN
Index: drivers/net/dsa/mv88e6xxx/chip.c
===================================================================
--- drivers/net/dsa/mv88e6xxx/chip.c
+++ linux-imx/drivers/net/dsa/mv88e6xxx/chip.c
@@ -648,6 +648,46 @@ static void mv88e6xxx_get_ethtool_stats(
mutex_unlock(&chip->reg_lock);
}
+static void mv88e6xxx_stats_clear_stats(struct mv88e6xxx_chip *chip, int port)
+{
+ u16 histogram = 0;
+ int err;
+
+ err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STATS_OP, &histogram);
+ if (err)
+ return;
+
+ histogram &= 0xC00;
+ /* Clear the statistics counters for given port */
+ err = mv88e6xxx_g1_write(chip, MV88E6XXX_G1_STATS_OP,
+ MV88E6XXX_G1_STATS_OP_BUSY |
+ MV88E6XXX_G1_STATS_OP_FLUSH_PORT |
+ (port +1) << 5 |
+ histogram);
+}
+
+static void mv88e6250_stats_clear_stats(struct mv88e6xxx_chip *chip, int port)
+{
+ mv88e6xxx_stats_clear_stats(chip, port);
+}
+
+static void mv88e6xxx_clear_stats(struct mv88e6xxx_chip *chip, int port)
+{
+ if (chip->info->ops->stats_clear_stats)
+ chip->info->ops->stats_clear_stats(chip, port);
+}
+
+static void mv88e6xxx_clear_ethtool_stats(struct dsa_switch *ds, int port)
+{
+ struct mv88e6xxx_chip *chip = ds->priv;
+
+ mutex_lock(&chip->reg_lock);
+
+ mv88e6xxx_clear_stats(chip, port);
+
+ mutex_unlock(&chip->reg_lock);
+}
+
static int mv88e6xxx_stats_set_histogram(struct mv88e6xxx_chip *chip)
{
if (chip->info->ops->stats_set_histogram)
@@ -2801,6 +2841,7 @@ static const struct mv88e6xxx_ops mv88e6
.stats_get_sset_count = mv88e6250_stats_get_sset_count,
.stats_get_strings = mv88e6250_stats_get_strings,
.stats_get_stats = mv88e6250_stats_get_stats,
+ .stats_clear_stats = mv88e6250_stats_clear_stats,
.set_cpu_port = mv88e6095_g1_set_cpu_port,
.set_egress_port = mv88e6095_g1_set_egress_port,
.watchdog_ops = &mv88e6250_watchdog_ops,
@@ -3837,6 +3878,7 @@ static const struct dsa_switch_ops mv88e
.adjust_link = mv88e6xxx_adjust_link,
.get_strings = mv88e6xxx_get_strings,
.get_ethtool_stats = mv88e6xxx_get_ethtool_stats,
+ .clear_ethtool_stats = mv88e6xxx_clear_ethtool_stats,
.get_sset_count = mv88e6xxx_get_sset_count,
.port_enable = mv88e6xxx_port_enable,
.port_disable = mv88e6xxx_port_disable,
Index: net/8021q/vlan_dev.c
===================================================================
--- net/8021q/vlan_dev.c
+++ linux-imx/net/8021q/vlan_dev.c
@@ -681,6 +681,26 @@ static int vlan_ethtool_get_ts_info(stru
return 0;
}
+static void vlan_clear_ethtool_stats(struct net_device *dev)
+{
+ struct vlan_pcpu_stats *p;
+ unsigned int start;
+ int i;
+
+ memset(&dev->stats, 0, sizeof(struct net_device_stats));
+ for_each_possible_cpu(i) {
+ p = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, i);
+ do {
+ start = u64_stats_fetch_begin_irq(&p->syncp);
+ p->rx_packets = 0L;
+ p->rx_bytes = 0L;
+ p->rx_multicast = 0L;
+ p->tx_packets = 0L;
+ p->tx_bytes = 0L;
+ } while (u64_stats_fetch_retry_irq(&p->syncp, start));
+ }
+}
+
static void vlan_dev_get_stats64(struct net_device *dev,
struct rtnl_link_stats64 *stats)
{
@@ -771,6 +791,7 @@ static const struct ethtool_ops vlan_eth
.get_drvinfo = vlan_ethtool_get_drvinfo,
.get_link = ethtool_op_get_link,
.get_ts_info = vlan_ethtool_get_ts_info,
+ .clear_ethtool_stats = vlan_clear_ethtool_stats,
};
static const struct net_device_ops vlan_netdev_ops = {