AR8216: remove redundant port number in MIB header line
[openwrt.git] / target / linux / generic / files / drivers / net / phy / ar8216.c
index 9065915..a1b9841 100644 (file)
@@ -1317,6 +1317,31 @@ unlock:
        return ret;
 }
 
+static void
+ar8xxx_byte_to_str(char *buf, int len, u64 byte)
+{
+       unsigned long b;
+       const char *unit;
+
+       if (byte >= 0x40000000) { /* 1 GiB */
+               b = byte * 10 / 0x40000000;
+               unit = "GiB";
+       } else if (byte >= 0x100000) { /* 1 MiB */
+               b = byte * 10 / 0x100000;
+               unit = "MiB";
+       } else if (byte >= 0x400) { /* 1 KiB */
+               b = byte * 10 / 0x400;
+               unit = "KiB";
+       } else {
+               b = byte;
+               unit = "Byte";
+       }
+       if (strcmp(unit, "Byte"))
+               snprintf(buf, len, "%lu.%lu %s", b / 10, b % 10, unit);
+       else
+               snprintf(buf, len, "%lu %s", b, unit);
+}
+
 int
 ar8xxx_sw_get_port_mib(struct switch_dev *dev,
                       const struct switch_attr *attr,
@@ -1324,11 +1349,14 @@ ar8xxx_sw_get_port_mib(struct switch_dev *dev,
 {
        struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
        const struct ar8xxx_chip *chip = priv->chip;
-       u64 *mib_stats;
+       u64 *mib_stats, mib_data;
        int port;
        int ret;
        char *buf = priv->buf;
+       char buf1[64];
+       const char *mib_name;
        int i, len = 0;
+       bool mib_stats_empty = true;
 
        if (!ar8xxx_has_mib_counters(priv))
                return -EOPNOTSUPP;
@@ -1345,15 +1373,28 @@ ar8xxx_sw_get_port_mib(struct switch_dev *dev,
        ar8xxx_mib_fetch_port_stat(priv, port, false);
 
        len += snprintf(buf + len, sizeof(priv->buf) - len,
-                       "Port %d MIB counters\n",
-                       port);
+                       "MIB counters\n");
 
        mib_stats = &priv->mib_stats[port * chip->num_mibs];
-       for (i = 0; i < chip->num_mibs; i++)
+       for (i = 0; i < chip->num_mibs; i++) {
+               mib_name = chip->mib_decs[i].name;
+               mib_data = mib_stats[i];
                len += snprintf(buf + len, sizeof(priv->buf) - len,
-                               "%-12s: %llu\n",
-                               chip->mib_decs[i].name,
-                               mib_stats[i]);
+                               "%-12s: %llu\n", mib_name, mib_data);
+               if ((!strcmp(mib_name, "TxByte") ||
+                   !strcmp(mib_name, "RxGoodByte")) &&
+                   mib_data >= 1024) {
+                       ar8xxx_byte_to_str(buf1, sizeof(buf1), mib_data);
+                       --len; /* discard newline at the end of buf */
+                       len += snprintf(buf + len, sizeof(priv->buf) - len,
+                                       " (%s)\n", buf1);
+               }
+               if (mib_stats_empty && mib_data)
+                       mib_stats_empty = false;
+       }
+
+       if (mib_stats_empty)
+               len = snprintf(buf, sizeof(priv->buf), "No MIB data");
 
        val->value.s = buf;
        val->len = len;
@@ -1436,6 +1477,40 @@ ar8xxx_sw_get_arl_table(struct switch_dev *dev,
        return 0;
 }
 
+int
+ar8xxx_sw_set_flush_arl_table(struct switch_dev *dev,
+                             const struct switch_attr *attr,
+                             struct switch_val *val)
+{
+       struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
+       int ret;
+
+       mutex_lock(&priv->reg_mutex);
+       ret = priv->chip->atu_flush(priv);
+       mutex_unlock(&priv->reg_mutex);
+
+       return ret;
+}
+
+int
+ar8xxx_sw_set_flush_port_arl_table(struct switch_dev *dev,
+                                  const struct switch_attr *attr,
+                                  struct switch_val *val)
+{
+       struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
+       int port, ret;
+
+       port = val->port_vlan;
+       if (port >= dev->ports)
+               return -EINVAL;
+
+       mutex_lock(&priv->reg_mutex);
+       ret = priv->chip->atu_flush_port(priv, port);
+       mutex_unlock(&priv->reg_mutex);
+
+       return ret;
+}
+
 static const struct switch_attr ar8xxx_sw_attr_globals[] = {
        {
                .type = SWITCH_TYPE_INT,
@@ -1490,9 +1565,15 @@ static const struct switch_attr ar8xxx_sw_attr_globals[] = {
                .set = NULL,
                .get = ar8xxx_sw_get_arl_table,
        },
+       {
+               .type = SWITCH_TYPE_NOVAL,
+               .name = "flush_arl_table",
+               .description = "Flush ARL table",
+               .set = ar8xxx_sw_set_flush_arl_table,
+       },
 };
 
-const struct switch_attr ar8xxx_sw_attr_port[2] = {
+const struct switch_attr ar8xxx_sw_attr_port[] = {
        {
                .type = SWITCH_TYPE_NOVAL,
                .name = "reset_mib",
@@ -1506,6 +1587,12 @@ const struct switch_attr ar8xxx_sw_attr_port[2] = {
                .set = NULL,
                .get = ar8xxx_sw_get_port_mib,
        },
+       {
+               .type = SWITCH_TYPE_NOVAL,
+               .name = "flush_arl_table",
+               .description = "Flush port's ARL table entries",
+               .set = ar8xxx_sw_set_flush_port_arl_table,
+       },
 };
 
 const struct switch_attr ar8xxx_sw_attr_vlan[1] = {