Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drivers: net: cpsw: add support to dump ALE table via ethtool register dump

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>

authored by

Mugunthan V N and committed by
David S. Miller
52c4f0ec 63502b8d

+37 -3
+23 -1
drivers/net/ethernet/ti/cpsw.c
··· 1675 1675 .ndo_vlan_rx_kill_vid = cpsw_ndo_vlan_rx_kill_vid, 1676 1676 }; 1677 1677 1678 + static int cpsw_get_regs_len(struct net_device *ndev) 1679 + { 1680 + struct cpsw_priv *priv = netdev_priv(ndev); 1681 + 1682 + return priv->data.ale_entries * ALE_ENTRY_WORDS * sizeof(u32); 1683 + } 1684 + 1685 + static void cpsw_get_regs(struct net_device *ndev, 1686 + struct ethtool_regs *regs, void *p) 1687 + { 1688 + struct cpsw_priv *priv = netdev_priv(ndev); 1689 + u32 *reg = p; 1690 + 1691 + /* update CPSW IP version */ 1692 + regs->version = priv->version; 1693 + 1694 + cpsw_ale_dump(priv->ale, reg); 1695 + } 1696 + 1678 1697 static void cpsw_get_drvinfo(struct net_device *ndev, 1679 1698 struct ethtool_drvinfo *info) 1680 1699 { 1681 1700 struct cpsw_priv *priv = netdev_priv(ndev); 1682 1701 1683 - strlcpy(info->driver, "TI CPSW Driver v1.0", sizeof(info->driver)); 1702 + strlcpy(info->driver, "cpsw", sizeof(info->driver)); 1684 1703 strlcpy(info->version, "1.0", sizeof(info->version)); 1685 1704 strlcpy(info->bus_info, priv->pdev->name, sizeof(info->bus_info)); 1705 + info->regdump_len = cpsw_get_regs_len(ndev); 1686 1706 } 1687 1707 1688 1708 static u32 cpsw_get_msglevel(struct net_device *ndev) ··· 1810 1790 .get_ethtool_stats = cpsw_get_ethtool_stats, 1811 1791 .get_wol = cpsw_get_wol, 1812 1792 .set_wol = cpsw_set_wol, 1793 + .get_regs_len = cpsw_get_regs_len, 1794 + .get_regs = cpsw_get_regs, 1813 1795 }; 1814 1796 1815 1797 static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv,
+10 -2
drivers/net/ethernet/ti/cpsw_ale.c
··· 25 25 #include "cpsw_ale.h" 26 26 27 27 #define BITMASK(bits) (BIT(bits) - 1) 28 - #define ALE_ENTRY_BITS 68 29 - #define ALE_ENTRY_WORDS DIV_ROUND_UP(ALE_ENTRY_BITS, 32) 30 28 31 29 #define ALE_VERSION_MAJOR(rev) ((rev >> 8) & 0xff) 32 30 #define ALE_VERSION_MINOR(rev) (rev & 0xff) ··· 760 762 cpsw_ale_control_set(ale, 0, ALE_ENABLE, 0); 761 763 kfree(ale); 762 764 return 0; 765 + } 766 + 767 + void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data) 768 + { 769 + int i; 770 + 771 + for (i = 0; i < ale->params.ale_entries; i++) { 772 + cpsw_ale_read(ale, i, data); 773 + data += ALE_ENTRY_WORDS; 774 + } 763 775 }
+4
drivers/net/ethernet/ti/cpsw_ale.h
··· 80 80 #define ALE_MCAST_FWD_LEARN 2 81 81 #define ALE_MCAST_FWD_2 3 82 82 83 + #define ALE_ENTRY_BITS 68 84 + #define ALE_ENTRY_WORDS DIV_ROUND_UP(ALE_ENTRY_BITS, 32) 85 + 83 86 struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params); 84 87 int cpsw_ale_destroy(struct cpsw_ale *ale); 85 88 ··· 107 104 int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control); 108 105 int cpsw_ale_control_set(struct cpsw_ale *ale, int port, 109 106 int control, int value); 107 + void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data); 110 108 111 109 #endif