aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--target/linux/generic/files/drivers/net/phy/ar8216.c57
-rw-r--r--target/linux/generic/files/drivers/net/phy/ar8216.h3
-rw-r--r--target/linux/generic/files/drivers/net/phy/ar8327.c1
3 files changed, 61 insertions, 0 deletions
diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c b/target/linux/generic/files/drivers/net/phy/ar8216.c
index 37877d513a..7f3d5115ab 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8216.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8216.c
@@ -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 = {
diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.h b/target/linux/generic/files/drivers/net/phy/ar8216.h
index d9508b9ff8..321eeb7923 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8216.h
+++ b/target/linux/generic/files/drivers/net/phy/ar8216.h
@@ -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 *
diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.c b/target/linux/generic/files/drivers/net/phy/ar8327.c
index 24a13c6418..bae9744736 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8327.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8327.c
@@ -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 = {