ralink: add support for mt7621 switch counters
authorblogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Thu, 18 Jun 2015 20:24:49 +0000 (20:24 +0000)
committerblogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Thu, 18 Jun 2015 20:24:49 +0000 (20:24 +0000)
Signed-off-by: Cristian Morales Vega <cristian@samknows.com>
Backport of r46050

git-svn-id: svn://svn.openwrt.org/openwrt/branches/chaos_calmer@46060 3c298f89-4303-0410-b956-a3cf2f4a3e73

target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c

index 1352b25..51e16f2 100644 (file)
@@ -63,6 +63,107 @@ enum {
 
 #define REG_HWTRAP             0x7804
 
+#define MIB_DESC(_s , _o, _n)   \
+       {                       \
+               .size = (_s),   \
+               .offset = (_o), \
+               .name = (_n),   \
+       }
+
+struct mt7xxx_mib_desc {
+       unsigned int size;
+       unsigned int offset;
+       const char *name;
+};
+
+#define MT7621_MIB_COUNTER_BASE        0x4000
+#define MT7621_MIB_COUNTER_PORT_OFFSET 0x100
+#define MT7621_STATS_TDPC      0x00
+#define MT7621_STATS_TCRC      0x04
+#define MT7621_STATS_TUPC      0x08
+#define MT7621_STATS_TMPC      0x0C
+#define MT7621_STATS_TBPC      0x10
+#define MT7621_STATS_TCEC      0x14
+#define MT7621_STATS_TSCEC     0x18
+#define MT7621_STATS_TMCEC     0x1C
+#define MT7621_STATS_TDEC      0x20
+#define MT7621_STATS_TLCEC     0x24
+#define MT7621_STATS_TXCEC     0x28
+#define MT7621_STATS_TPPC      0x2C
+#define MT7621_STATS_TL64PC    0x30
+#define MT7621_STATS_TL65PC    0x34
+#define MT7621_STATS_TL128PC   0x38
+#define MT7621_STATS_TL256PC   0x3C
+#define MT7621_STATS_TL512PC   0x40
+#define MT7621_STATS_TL1024PC  0x44
+#define MT7621_STATS_TOC       0x48
+#define MT7621_STATS_RDPC      0x60
+#define MT7621_STATS_RFPC      0x64
+#define MT7621_STATS_RUPC      0x68
+#define MT7621_STATS_RMPC      0x6C
+#define MT7621_STATS_RBPC      0x70
+#define MT7621_STATS_RAEPC     0x74
+#define MT7621_STATS_RCEPC     0x78
+#define MT7621_STATS_RUSPC     0x7C
+#define MT7621_STATS_RFEPC     0x80
+#define MT7621_STATS_ROSPC     0x84
+#define MT7621_STATS_RJEPC     0x88
+#define MT7621_STATS_RPPC      0x8C
+#define MT7621_STATS_RL64PC    0x90
+#define MT7621_STATS_RL65PC    0x94
+#define MT7621_STATS_RL128PC   0x98
+#define MT7621_STATS_RL256PC   0x9C
+#define MT7621_STATS_RL512PC   0xA0
+#define MT7621_STATS_RL1024PC  0xA4
+#define MT7621_STATS_ROC       0xA8
+#define MT7621_STATS_RDPC_CTRL 0xB0
+#define MT7621_STATS_RDPC_ING  0xB4
+#define MT7621_STATS_RDPC_ARL  0xB8
+
+static const struct mt7xxx_mib_desc mt7621_mibs[] = {
+       MIB_DESC(1, MT7621_STATS_TDPC, "TxDrop"),
+       MIB_DESC(1, MT7621_STATS_TCRC, "TxCRC"),
+       MIB_DESC(1, MT7621_STATS_TUPC, "TxUni"),
+       MIB_DESC(1, MT7621_STATS_TMPC, "TxMulti"),
+       MIB_DESC(1, MT7621_STATS_TBPC, "TxBroad"),
+       MIB_DESC(1, MT7621_STATS_TCEC, "TxCollision"),
+       MIB_DESC(1, MT7621_STATS_TSCEC, "TxSingleCol"),
+       MIB_DESC(1, MT7621_STATS_TMCEC, "TxMultiCol"),
+       MIB_DESC(1, MT7621_STATS_TDEC, "TxDefer"),
+       MIB_DESC(1, MT7621_STATS_TLCEC, "TxLateCol"),
+       MIB_DESC(1, MT7621_STATS_TXCEC, "TxExcCol"),
+       MIB_DESC(1, MT7621_STATS_TPPC, "TxPause"),
+       MIB_DESC(1, MT7621_STATS_TL64PC, "Tx64Byte"),
+       MIB_DESC(1, MT7621_STATS_TL65PC, "Tx65Byte"),
+       MIB_DESC(1, MT7621_STATS_TL128PC, "Tx128Byte"),
+       MIB_DESC(1, MT7621_STATS_TL256PC, "Tx256Byte"),
+       MIB_DESC(1, MT7621_STATS_TL512PC, "Tx512Byte"),
+       MIB_DESC(1, MT7621_STATS_TL1024PC, "Tx1024Byte"),
+       MIB_DESC(2, MT7621_STATS_TOC, "TxByte"),
+       MIB_DESC(1, MT7621_STATS_RDPC, "RxDrop"),
+       MIB_DESC(1, MT7621_STATS_RFPC, "RxFiltered"),
+       MIB_DESC(1, MT7621_STATS_RUPC, "RxUni"),
+       MIB_DESC(1, MT7621_STATS_RMPC, "RxMulti"),
+       MIB_DESC(1, MT7621_STATS_RBPC, "RxBroad"),
+       MIB_DESC(1, MT7621_STATS_RAEPC, "RxAlignErr"),
+       MIB_DESC(1, MT7621_STATS_RCEPC, "RxCRC"),
+       MIB_DESC(1, MT7621_STATS_RUSPC, "RxUnderSize"),
+       MIB_DESC(1, MT7621_STATS_RFEPC, "RxFragment"),
+       MIB_DESC(1, MT7621_STATS_ROSPC, "RxOverSize"),
+       MIB_DESC(1, MT7621_STATS_RJEPC, "RxJabber"),
+       MIB_DESC(1, MT7621_STATS_RPPC, "RxPause"),
+       MIB_DESC(1, MT7621_STATS_RL64PC, "Rx64Byte"),
+       MIB_DESC(1, MT7621_STATS_RL65PC, "Rx65Byte"),
+       MIB_DESC(1, MT7621_STATS_RL128PC, "Rx128Byte"),
+       MIB_DESC(1, MT7621_STATS_RL256PC, "Rx256Byte"),
+       MIB_DESC(1, MT7621_STATS_RL512PC, "Rx512Byte"),
+       MIB_DESC(1, MT7621_STATS_RL1024PC, "Rx1024Byte"),
+       MIB_DESC(2, MT7621_STATS_ROC, "RxByte"),
+       MIB_DESC(1, MT7621_STATS_RDPC_CTRL, "RxCtrlDrop"),
+       MIB_DESC(1, MT7621_STATS_RDPC_ING, "RxIngDrop"),
+       MIB_DESC(1, MT7621_STATS_RDPC_ARL, "RxARLDrop")
+};
+
 enum {
        /* Global attributes. */
        MT7530_ATTR_ENABLE_VLAN,
@@ -500,6 +601,63 @@ static const struct switch_attr mt7530_global[] = {
        },
 };
 
+static u64 get_mib_counter(struct mt7530_priv *priv, int i, int port)
+{
+       unsigned int port_base;
+       u64 t;
+
+       port_base = MT7621_MIB_COUNTER_BASE +
+                   MT7621_MIB_COUNTER_PORT_OFFSET * port;
+
+       t = mt7530_r32(priv, port_base + mt7621_mibs[i].offset);
+       if (mt7621_mibs[i].size == 2) {
+               u64 hi;
+
+               hi = mt7530_r32(priv, port_base + mt7621_mibs[i].offset + 4);
+               t |= hi << 32;
+       }
+
+       return t;
+}
+
+static int mt7621_sw_get_port_mib(struct switch_dev *dev,
+                                 const struct switch_attr *attr,
+                                 struct switch_val *val)
+{
+       static char buf[4096];
+       struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
+       int i, len = 0;
+
+       if (val->port_vlan >= MT7530_NUM_PORTS)
+               return -EINVAL;
+
+       len += snprintf(buf + len, sizeof(buf) - len,
+                       "Port %d MIB counters\n", val->port_vlan);
+
+       for (i = 0; i < sizeof(mt7621_mibs) / sizeof(*mt7621_mibs); ++i) {
+               u64 counter;
+               len += snprintf(buf + len, sizeof(buf) - len,
+                               "%-11s: ", mt7621_mibs[i].name);
+               counter = get_mib_counter(priv, i, val->port_vlan);
+               len += snprintf(buf + len, sizeof(buf) - len, "%llu\n",
+                               counter);
+       }
+
+       val->value.s = buf;
+       val->len = len;
+       return 0;
+}
+
+static const struct switch_attr mt7621_port[] = {
+       {
+               .type = SWITCH_TYPE_STRING,
+               .name = "mib",
+               .description = "Get MIB counters for port",
+               .get = mt7621_sw_get_port_mib,
+               .set = NULL,
+       },
+};
+
 static const struct switch_attr mt7530_port[] = {
 };
 
@@ -514,6 +672,28 @@ static const struct switch_attr mt7530_vlan[] = {
        },
 };
 
+static const struct switch_dev_ops mt7621_ops = {
+       .attr_global = {
+               .attr = mt7530_global,
+               .n_attr = ARRAY_SIZE(mt7530_global),
+       },
+       .attr_port = {
+               .attr = mt7621_port,
+               .n_attr = ARRAY_SIZE(mt7621_port),
+       },
+       .attr_vlan = {
+               .attr = mt7530_vlan,
+               .n_attr = ARRAY_SIZE(mt7530_vlan),
+       },
+       .get_vlan_ports = mt7530_get_vlan_ports,
+       .set_vlan_ports = mt7530_set_vlan_ports,
+       .get_port_pvid = mt7530_get_port_pvid,
+       .set_port_pvid = mt7530_set_port_pvid,
+       .get_port_link = mt7530_get_port_link,
+       .apply_config = mt7530_apply_config,
+       .reset_switch = mt7530_reset_switch,
+};
+
 static const struct switch_dev_ops mt7530_ops = {
        .attr_global = {
                .attr = mt7530_global,
@@ -556,6 +736,9 @@ mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus, int vl
        if (bus) {
                swdev->alias = "mt7530";
                swdev->name = "mt7530";
+       } else if (IS_ENABLED(CONFIG_SOC_MT7621)) {
+               swdev->alias = "mt7621";
+               swdev->name = "mt7621";
        } else {
                swdev->alias = "mt7620";
                swdev->name = "mt7620";
@@ -563,7 +746,10 @@ mt7530_probe(struct device *dev, void __iomem *base, struct mii_bus *bus, int vl
        swdev->cpu_port = MT7530_CPU_PORT;
        swdev->ports = MT7530_NUM_PORTS;
        swdev->vlans = MT7530_NUM_VLANS;
-       swdev->ops = &mt7530_ops;
+       if (IS_ENABLED(CONFIG_SOC_MT7621))
+               swdev->ops = &mt7621_ops;
+       else
+               swdev->ops = &mt7530_ops;
 
        ret = register_switch(swdev, NULL);
        if (ret) {