drivers: net: cpsw: add support to dump ALE table via ethtool register dump
authorMugunthan V N <mugunthanvnm@ti.com>
Tue, 22 Jul 2014 17:55:07 +0000 (23:25 +0530)
committerDavid S. Miller <davem@davemloft.net>
Wed, 23 Jul 2014 02:58:25 +0000 (19:58 -0700)
Add support to view addresses added by the driver and learnt by the
hardware from ALE table via ethtool register dump interface.

Signed-off-by: Mugunthan V N <mugunthanvnm@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/ti/cpsw.c
drivers/net/ethernet/ti/cpsw_ale.c
drivers/net/ethernet/ti/cpsw_ale.h

index ae6379af5b4dac5bab01b8e9aa7d61699d258f15..60f925df15e26feaea2ae1d3cc8de80795a363eb 100644 (file)
@@ -1675,14 +1675,34 @@ static const struct net_device_ops cpsw_netdev_ops = {
        .ndo_vlan_rx_kill_vid   = cpsw_ndo_vlan_rx_kill_vid,
 };
 
+static int cpsw_get_regs_len(struct net_device *ndev)
+{
+       struct cpsw_priv *priv = netdev_priv(ndev);
+
+       return priv->data.ale_entries * ALE_ENTRY_WORDS * sizeof(u32);
+}
+
+static void cpsw_get_regs(struct net_device *ndev,
+                         struct ethtool_regs *regs, void *p)
+{
+       struct cpsw_priv *priv = netdev_priv(ndev);
+       u32 *reg = p;
+
+       /* update CPSW IP version */
+       regs->version = priv->version;
+
+       cpsw_ale_dump(priv->ale, reg);
+}
+
 static void cpsw_get_drvinfo(struct net_device *ndev,
                             struct ethtool_drvinfo *info)
 {
        struct cpsw_priv *priv = netdev_priv(ndev);
 
-       strlcpy(info->driver, "TI CPSW Driver v1.0", sizeof(info->driver));
+       strlcpy(info->driver, "cpsw", sizeof(info->driver));
        strlcpy(info->version, "1.0", sizeof(info->version));
        strlcpy(info->bus_info, priv->pdev->name, sizeof(info->bus_info));
+       info->regdump_len = cpsw_get_regs_len(ndev);
 }
 
 static u32 cpsw_get_msglevel(struct net_device *ndev)
@@ -1790,6 +1810,8 @@ static const struct ethtool_ops cpsw_ethtool_ops = {
        .get_ethtool_stats      = cpsw_get_ethtool_stats,
        .get_wol        = cpsw_get_wol,
        .set_wol        = cpsw_set_wol,
+       .get_regs_len   = cpsw_get_regs_len,
+       .get_regs       = cpsw_get_regs,
 };
 
 static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv,
index 7f893069c4187caab2e8071775f1d0756eb5a17a..0579b2243bb6d7fdfb20e27b761fbdf1d33b00b6 100644 (file)
@@ -25,8 +25,6 @@
 #include "cpsw_ale.h"
 
 #define BITMASK(bits)          (BIT(bits) - 1)
-#define ALE_ENTRY_BITS         68
-#define ALE_ENTRY_WORDS        DIV_ROUND_UP(ALE_ENTRY_BITS, 32)
 
 #define ALE_VERSION_MAJOR(rev) ((rev >> 8) & 0xff)
 #define ALE_VERSION_MINOR(rev) (rev & 0xff)
@@ -763,3 +761,13 @@ int cpsw_ale_destroy(struct cpsw_ale *ale)
        kfree(ale);
        return 0;
 }
+
+void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data)
+{
+       int i;
+
+       for (i = 0; i < ale->params.ale_entries; i++) {
+               cpsw_ale_read(ale, i, data);
+               data += ALE_ENTRY_WORDS;
+       }
+}
index de409c33b2502556366c2843ba8901f361bae87d..31cf43cab42ee7ba70b6948593bc93cf28c5a6e7 100644 (file)
@@ -80,6 +80,9 @@ enum cpsw_ale_port_state {
 #define ALE_MCAST_FWD_LEARN            2
 #define ALE_MCAST_FWD_2                        3
 
+#define ALE_ENTRY_BITS         68
+#define ALE_ENTRY_WORDS        DIV_ROUND_UP(ALE_ENTRY_BITS, 32)
+
 struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params);
 int cpsw_ale_destroy(struct cpsw_ale *ale);
 
@@ -104,5 +107,6 @@ int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port);
 int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control);
 int cpsw_ale_control_set(struct cpsw_ale *ale, int port,
                         int control, int value);
+void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data);
 
 #endif