generic: provide get_port_stats() on ar8xxx switches
authorThibaut VARENE <hacks@slashdirt.org>
Fri, 4 Aug 2017 10:28:23 +0000 (12:28 +0200)
committerJohn Crispin <john@phrozen.org>
Fri, 1 Sep 2017 07:30:35 +0000 (09:30 +0200)
This patch provides a generic switch_dev_ops 'get_port_stats()' callback by
taping into the relevant port MIB counters.

The implementation uses a generic callback that select the correct MIB counter
index based on chip version.

This callback is used by swconfig_leds led trigger to blink LEDs with port
network traffic.

Signed-off-by: Thibaut VARENE <hacks@slashdirt.org>
target/linux/generic/files/drivers/net/phy/ar8216.c
target/linux/generic/files/drivers/net/phy/ar8216.h
target/linux/generic/files/drivers/net/phy/ar8327.c

index 37877d513af7c161f3b47ec1d2a1cf623b24eb13..7f3d5115ab0979081731ee1a2369250c12a90e36 100644 (file)
@@ -49,6 +49,12 @@ extern const struct ar8xxx_chip ar8337_chip;
                .name = (_n),   \
        }
 
+#define AR8216_MIB_RXB_ID      14      /* RxGoodByte */
+#define AR8216_MIB_TXB_ID      29      /* TxByte */
+
+#define AR8236_MIB_RXB_ID      15      /* RxGoodByte */
+#define AR8236_MIB_TXB_ID      31      /* TxByte */
+
 static const struct ar8xxx_mib_desc ar8216_mibs[] = {
        MIB_DESC(1, AR8216_STATS_RXBROAD, "RxBroad"),
        MIB_DESC(1, AR8216_STATS_RXPAUSE, "RxPause"),
@@ -1581,6 +1587,56 @@ ar8xxx_sw_set_flush_port_arl_table(struct switch_dev *dev,
        return ret;
 }
 
+int
+ar8xxx_sw_get_port_stats(struct switch_dev *dev, int port,
+                       struct switch_port_stats *stats)
+{
+       struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
+       u64 *mib_stats;
+       int ret;
+       int mib_txb_id, mib_rxb_id;
+
+       if (!ar8xxx_has_mib_counters(priv))
+               return -EOPNOTSUPP;
+
+       if (port >= dev->ports)
+               return -EINVAL;
+
+       switch (priv->chip_ver) {
+               case AR8XXX_VER_AR8216:
+                       mib_txb_id = AR8216_MIB_TXB_ID;
+                       mib_rxb_id = AR8216_MIB_RXB_ID;
+                       break;
+               case AR8XXX_VER_AR8236:
+               case AR8XXX_VER_AR8316:
+               case AR8XXX_VER_AR8327:
+               case AR8XXX_VER_AR8337:
+                       mib_txb_id = AR8236_MIB_TXB_ID;
+                       mib_rxb_id = AR8236_MIB_RXB_ID;
+                       break;
+               default:
+                       return -EOPNOTSUPP;
+       }
+
+       mutex_lock(&priv->mib_lock);
+       ret = ar8xxx_mib_capture(priv);
+       if (ret)
+               goto unlock;
+
+       ar8xxx_mib_fetch_port_stat(priv, port, false);
+
+       mib_stats = &priv->mib_stats[port * priv->chip->num_mibs];
+
+       stats->tx_bytes = mib_stats[mib_txb_id];
+       stats->rx_bytes = mib_stats[mib_rxb_id];
+
+       ret = 0;
+
+unlock:
+       mutex_unlock(&priv->mib_lock);
+       return ret;
+}
+
 static const struct switch_attr ar8xxx_sw_attr_globals[] = {
        {
                .type = SWITCH_TYPE_INT,
@@ -1696,6 +1752,7 @@ static const struct switch_dev_ops ar8xxx_sw_ops = {
        .apply_config = ar8xxx_sw_hw_apply,
        .reset_switch = ar8xxx_sw_reset_switch,
        .get_port_link = ar8xxx_sw_get_port_link,
+       .get_port_stats = ar8xxx_sw_get_port_stats,
 };
 
 static const struct ar8xxx_chip ar8216_chip = {
index d9508b9ff83c4c3d75978ae86546705660661a7f..321eeb79231fbf8a50296c01feb5208d9eacc5a1 100644 (file)
@@ -566,6 +566,9 @@ ar8xxx_sw_set_flush_port_arl_table(struct switch_dev *dev,
                                   const struct switch_attr *attr,
                                   struct switch_val *val);
 int
+ar8xxx_sw_get_port_stats(struct switch_dev *dev, int port,
+                       struct switch_port_stats *stats);
+int
 ar8216_wait_bit(struct ar8xxx_priv *priv, int reg, u32 mask, u32 val);
 
 static inline struct ar8xxx_priv *
index 24a13c6418cd392a23c7a84db1266003c86b0306..bae9744736c6d6002d5413a4e00dd2db4fcaa8a8 100644 (file)
@@ -1411,6 +1411,7 @@ static const struct switch_dev_ops ar8327_sw_ops = {
        .apply_config = ar8327_sw_hw_apply,
        .reset_switch = ar8xxx_sw_reset_switch,
        .get_port_link = ar8xxx_sw_get_port_link,
+       .get_port_stats = ar8xxx_sw_get_port_stats,
 };
 
 const struct ar8xxx_chip ar8327_chip = {