aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2010-06-20 23:06:53 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-25 01:13:14 -0400
commit5b98c1bfcfc745604985e6a50ef7481c39a9fcea (patch)
tree229ee3aebc005882769cac7139d02779b5880a25 /drivers/net/sfc
parent565b7b2d2e632b5792879c0c9cccdd9eecd31195 (diff)
sfc: Implement ethtool register dump operation
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Acked-by: Jeff Garzik <jgarzik@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r--drivers/net/sfc/ethtool.c16
-rw-r--r--drivers/net/sfc/io.h7
-rw-r--r--drivers/net/sfc/nic.c266
-rw-r--r--drivers/net/sfc/nic.h3
4 files changed, 292 insertions, 0 deletions
diff --git a/drivers/net/sfc/ethtool.c b/drivers/net/sfc/ethtool.c
index 22026bfbc4c1..81b7f39ca5fb 100644
--- a/drivers/net/sfc/ethtool.c
+++ b/drivers/net/sfc/ethtool.c
@@ -242,6 +242,20 @@ static void efx_ethtool_get_drvinfo(struct net_device *net_dev,
242 strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info)); 242 strlcpy(info->bus_info, pci_name(efx->pci_dev), sizeof(info->bus_info));
243} 243}
244 244
245static int efx_ethtool_get_regs_len(struct net_device *net_dev)
246{
247 return efx_nic_get_regs_len(netdev_priv(net_dev));
248}
249
250static void efx_ethtool_get_regs(struct net_device *net_dev,
251 struct ethtool_regs *regs, void *buf)
252{
253 struct efx_nic *efx = netdev_priv(net_dev);
254
255 regs->version = efx->type->revision;
256 efx_nic_get_regs(efx, buf);
257}
258
245/** 259/**
246 * efx_fill_test - fill in an individual self-test entry 260 * efx_fill_test - fill in an individual self-test entry
247 * @test_index: Index of the test 261 * @test_index: Index of the test
@@ -834,6 +848,8 @@ const struct ethtool_ops efx_ethtool_ops = {
834 .get_settings = efx_ethtool_get_settings, 848 .get_settings = efx_ethtool_get_settings,
835 .set_settings = efx_ethtool_set_settings, 849 .set_settings = efx_ethtool_set_settings,
836 .get_drvinfo = efx_ethtool_get_drvinfo, 850 .get_drvinfo = efx_ethtool_get_drvinfo,
851 .get_regs_len = efx_ethtool_get_regs_len,
852 .get_regs = efx_ethtool_get_regs,
837 .nway_reset = efx_ethtool_nway_reset, 853 .nway_reset = efx_ethtool_nway_reset,
838 .get_link = efx_ethtool_get_link, 854 .get_link = efx_ethtool_get_link,
839 .get_eeprom_len = efx_ethtool_get_eeprom_len, 855 .get_eeprom_len = efx_ethtool_get_eeprom_len,
diff --git a/drivers/net/sfc/io.h b/drivers/net/sfc/io.h
index b89177c27f4a..4317574c772d 100644
--- a/drivers/net/sfc/io.h
+++ b/drivers/net/sfc/io.h
@@ -211,6 +211,13 @@ static inline void efx_writed_table(struct efx_nic *efx, efx_dword_t *value,
211 efx_writed(efx, value, reg + index * sizeof(efx_oword_t)); 211 efx_writed(efx, value, reg + index * sizeof(efx_oword_t));
212} 212}
213 213
214/* Read from a dword register forming part of a table */
215static inline void efx_readd_table(struct efx_nic *efx, efx_dword_t *value,
216 unsigned int reg, unsigned int index)
217{
218 efx_readd(efx, value, reg + index * sizeof(efx_dword_t));
219}
220
214/* Page-mapped register block size */ 221/* Page-mapped register block size */
215#define EFX_PAGE_BLOCK_SIZE 0x2000 222#define EFX_PAGE_BLOCK_SIZE 0x2000
216 223
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c
index 0ee6fd367e6f..67235f1c2550 100644
--- a/drivers/net/sfc/nic.c
+++ b/drivers/net/sfc/nic.c
@@ -1627,3 +1627,269 @@ void efx_nic_init_common(struct efx_nic *efx)
1627 EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1); 1627 EFX_SET_OWORD_FIELD(temp, FRF_BZ_TX_FLUSH_MIN_LEN_EN, 1);
1628 efx_writeo(efx, &temp, FR_AZ_TX_RESERVED); 1628 efx_writeo(efx, &temp, FR_AZ_TX_RESERVED);
1629} 1629}
1630
1631/* Register dump */
1632
1633#define REGISTER_REVISION_A 1
1634#define REGISTER_REVISION_B 2
1635#define REGISTER_REVISION_C 3
1636#define REGISTER_REVISION_Z 3 /* latest revision */
1637
1638struct efx_nic_reg {
1639 u32 offset:24;
1640 u32 min_revision:2, max_revision:2;
1641};
1642
1643#define REGISTER(name, min_rev, max_rev) { \
1644 FR_ ## min_rev ## max_rev ## _ ## name, \
1645 REGISTER_REVISION_ ## min_rev, REGISTER_REVISION_ ## max_rev \
1646}
1647#define REGISTER_AA(name) REGISTER(name, A, A)
1648#define REGISTER_AB(name) REGISTER(name, A, B)
1649#define REGISTER_AZ(name) REGISTER(name, A, Z)
1650#define REGISTER_BB(name) REGISTER(name, B, B)
1651#define REGISTER_BZ(name) REGISTER(name, B, Z)
1652#define REGISTER_CZ(name) REGISTER(name, C, Z)
1653
1654static const struct efx_nic_reg efx_nic_regs[] = {
1655 REGISTER_AZ(ADR_REGION),
1656 REGISTER_AZ(INT_EN_KER),
1657 REGISTER_BZ(INT_EN_CHAR),
1658 REGISTER_AZ(INT_ADR_KER),
1659 REGISTER_BZ(INT_ADR_CHAR),
1660 /* INT_ACK_KER is WO */
1661 /* INT_ISR0 is RC */
1662 REGISTER_AZ(HW_INIT),
1663 REGISTER_CZ(USR_EV_CFG),
1664 REGISTER_AB(EE_SPI_HCMD),
1665 REGISTER_AB(EE_SPI_HADR),
1666 REGISTER_AB(EE_SPI_HDATA),
1667 REGISTER_AB(EE_BASE_PAGE),
1668 REGISTER_AB(EE_VPD_CFG0),
1669 /* EE_VPD_SW_CNTL and EE_VPD_SW_DATA are not used */
1670 /* PMBX_DBG_IADDR and PBMX_DBG_IDATA are indirect */
1671 /* PCIE_CORE_INDIRECT is indirect */
1672 REGISTER_AB(NIC_STAT),
1673 REGISTER_AB(GPIO_CTL),
1674 REGISTER_AB(GLB_CTL),
1675 /* FATAL_INTR_KER and FATAL_INTR_CHAR are partly RC */
1676 REGISTER_BZ(DP_CTRL),
1677 REGISTER_AZ(MEM_STAT),
1678 REGISTER_AZ(CS_DEBUG),
1679 REGISTER_AZ(ALTERA_BUILD),
1680 REGISTER_AZ(CSR_SPARE),
1681 REGISTER_AB(PCIE_SD_CTL0123),
1682 REGISTER_AB(PCIE_SD_CTL45),
1683 REGISTER_AB(PCIE_PCS_CTL_STAT),
1684 /* DEBUG_DATA_OUT is not used */
1685 /* DRV_EV is WO */
1686 REGISTER_AZ(EVQ_CTL),
1687 REGISTER_AZ(EVQ_CNT1),
1688 REGISTER_AZ(EVQ_CNT2),
1689 REGISTER_AZ(BUF_TBL_CFG),
1690 REGISTER_AZ(SRM_RX_DC_CFG),
1691 REGISTER_AZ(SRM_TX_DC_CFG),
1692 REGISTER_AZ(SRM_CFG),
1693 /* BUF_TBL_UPD is WO */
1694 REGISTER_AZ(SRM_UPD_EVQ),
1695 REGISTER_AZ(SRAM_PARITY),
1696 REGISTER_AZ(RX_CFG),
1697 REGISTER_BZ(RX_FILTER_CTL),
1698 /* RX_FLUSH_DESCQ is WO */
1699 REGISTER_AZ(RX_DC_CFG),
1700 REGISTER_AZ(RX_DC_PF_WM),
1701 REGISTER_BZ(RX_RSS_TKEY),
1702 /* RX_NODESC_DROP is RC */
1703 REGISTER_AA(RX_SELF_RST),
1704 /* RX_DEBUG, RX_PUSH_DROP are not used */
1705 REGISTER_CZ(RX_RSS_IPV6_REG1),
1706 REGISTER_CZ(RX_RSS_IPV6_REG2),
1707 REGISTER_CZ(RX_RSS_IPV6_REG3),
1708 /* TX_FLUSH_DESCQ is WO */
1709 REGISTER_AZ(TX_DC_CFG),
1710 REGISTER_AA(TX_CHKSM_CFG),
1711 REGISTER_AZ(TX_CFG),
1712 /* TX_PUSH_DROP is not used */
1713 REGISTER_AZ(TX_RESERVED),
1714 REGISTER_BZ(TX_PACE),
1715 /* TX_PACE_DROP_QID is RC */
1716 REGISTER_BB(TX_VLAN),
1717 REGISTER_BZ(TX_IPFIL_PORTEN),
1718 REGISTER_AB(MD_TXD),
1719 REGISTER_AB(MD_RXD),
1720 REGISTER_AB(MD_CS),
1721 REGISTER_AB(MD_PHY_ADR),
1722 REGISTER_AB(MD_ID),
1723 /* MD_STAT is RC */
1724 REGISTER_AB(MAC_STAT_DMA),
1725 REGISTER_AB(MAC_CTRL),
1726 REGISTER_BB(GEN_MODE),
1727 REGISTER_AB(MAC_MC_HASH_REG0),
1728 REGISTER_AB(MAC_MC_HASH_REG1),
1729 REGISTER_AB(GM_CFG1),
1730 REGISTER_AB(GM_CFG2),
1731 /* GM_IPG and GM_HD are not used */
1732 REGISTER_AB(GM_MAX_FLEN),
1733 /* GM_TEST is not used */
1734 REGISTER_AB(GM_ADR1),
1735 REGISTER_AB(GM_ADR2),
1736 REGISTER_AB(GMF_CFG0),
1737 REGISTER_AB(GMF_CFG1),
1738 REGISTER_AB(GMF_CFG2),
1739 REGISTER_AB(GMF_CFG3),
1740 REGISTER_AB(GMF_CFG4),
1741 REGISTER_AB(GMF_CFG5),
1742 REGISTER_BB(TX_SRC_MAC_CTL),
1743 REGISTER_AB(XM_ADR_LO),
1744 REGISTER_AB(XM_ADR_HI),
1745 REGISTER_AB(XM_GLB_CFG),
1746 REGISTER_AB(XM_TX_CFG),
1747 REGISTER_AB(XM_RX_CFG),
1748 REGISTER_AB(XM_MGT_INT_MASK),
1749 REGISTER_AB(XM_FC),
1750 REGISTER_AB(XM_PAUSE_TIME),
1751 REGISTER_AB(XM_TX_PARAM),
1752 REGISTER_AB(XM_RX_PARAM),
1753 /* XM_MGT_INT_MSK (note no 'A') is RC */
1754 REGISTER_AB(XX_PWR_RST),
1755 REGISTER_AB(XX_SD_CTL),
1756 REGISTER_AB(XX_TXDRV_CTL),
1757 /* XX_PRBS_CTL, XX_PRBS_CHK and XX_PRBS_ERR are not used */
1758 /* XX_CORE_STAT is partly RC */
1759};
1760
1761struct efx_nic_reg_table {
1762 u32 offset:24;
1763 u32 min_revision:2, max_revision:2;
1764 u32 step:6, rows:21;
1765};
1766
1767#define REGISTER_TABLE_DIMENSIONS(_, offset, min_rev, max_rev, step, rows) { \
1768 offset, \
1769 REGISTER_REVISION_ ## min_rev, REGISTER_REVISION_ ## max_rev, \
1770 step, rows \
1771}
1772#define REGISTER_TABLE(name, min_rev, max_rev) \
1773 REGISTER_TABLE_DIMENSIONS( \
1774 name, FR_ ## min_rev ## max_rev ## _ ## name, \
1775 min_rev, max_rev, \
1776 FR_ ## min_rev ## max_rev ## _ ## name ## _STEP, \
1777 FR_ ## min_rev ## max_rev ## _ ## name ## _ROWS)
1778#define REGISTER_TABLE_AA(name) REGISTER_TABLE(name, A, A)
1779#define REGISTER_TABLE_AZ(name) REGISTER_TABLE(name, A, Z)
1780#define REGISTER_TABLE_BB(name) REGISTER_TABLE(name, B, B)
1781#define REGISTER_TABLE_BZ(name) REGISTER_TABLE(name, B, Z)
1782#define REGISTER_TABLE_BB_CZ(name) \
1783 REGISTER_TABLE_DIMENSIONS(name, FR_BZ_ ## name, B, B, \
1784 FR_BZ_ ## name ## _STEP, \
1785 FR_BB_ ## name ## _ROWS), \
1786 REGISTER_TABLE_DIMENSIONS(name, FR_BZ_ ## name, C, Z, \
1787 FR_BZ_ ## name ## _STEP, \
1788 FR_CZ_ ## name ## _ROWS)
1789#define REGISTER_TABLE_CZ(name) REGISTER_TABLE(name, C, Z)
1790
1791static const struct efx_nic_reg_table efx_nic_reg_tables[] = {
1792 /* DRIVER is not used */
1793 /* EVQ_RPTR, TIMER_COMMAND, USR_EV and {RX,TX}_DESC_UPD are WO */
1794 REGISTER_TABLE_BB(TX_IPFIL_TBL),
1795 REGISTER_TABLE_BB(TX_SRC_MAC_TBL),
1796 REGISTER_TABLE_AA(RX_DESC_PTR_TBL_KER),
1797 REGISTER_TABLE_BB_CZ(RX_DESC_PTR_TBL),
1798 REGISTER_TABLE_AA(TX_DESC_PTR_TBL_KER),
1799 REGISTER_TABLE_BB_CZ(TX_DESC_PTR_TBL),
1800 REGISTER_TABLE_AA(EVQ_PTR_TBL_KER),
1801 REGISTER_TABLE_BB_CZ(EVQ_PTR_TBL),
1802 /* The register buffer is allocated with slab, so we can't
1803 * reasonably read all of the buffer table (up to 8MB!).
1804 * However this driver will only use a few entries. Reading
1805 * 1K entries allows for some expansion of queue count and
1806 * size before we need to change the version. */
1807 REGISTER_TABLE_DIMENSIONS(BUF_FULL_TBL_KER, FR_AA_BUF_FULL_TBL_KER,
1808 A, A, 8, 1024),
1809 REGISTER_TABLE_DIMENSIONS(BUF_FULL_TBL, FR_BZ_BUF_FULL_TBL,
1810 B, Z, 8, 1024),
1811 /* RX_FILTER_TBL{0,1} is huge and not used by this driver */
1812 REGISTER_TABLE_CZ(RX_MAC_FILTER_TBL0),
1813 REGISTER_TABLE_BB_CZ(TIMER_TBL),
1814 REGISTER_TABLE_BB_CZ(TX_PACE_TBL),
1815 REGISTER_TABLE_BZ(RX_INDIRECTION_TBL),
1816 /* TX_FILTER_TBL0 is huge and not used by this driver */
1817 REGISTER_TABLE_CZ(TX_MAC_FILTER_TBL0),
1818 REGISTER_TABLE_CZ(MC_TREG_SMEM),
1819 /* MSIX_PBA_TABLE is not mapped */
1820 /* SRM_DBG is not mapped (and is redundant with BUF_FLL_TBL) */
1821};
1822
1823size_t efx_nic_get_regs_len(struct efx_nic *efx)
1824{
1825 const struct efx_nic_reg *reg;
1826 const struct efx_nic_reg_table *table;
1827 size_t len = 0;
1828
1829 for (reg = efx_nic_regs;
1830 reg < efx_nic_regs + ARRAY_SIZE(efx_nic_regs);
1831 reg++)
1832 if (efx->type->revision >= reg->min_revision &&
1833 efx->type->revision <= reg->max_revision)
1834 len += sizeof(efx_oword_t);
1835
1836 for (table = efx_nic_reg_tables;
1837 table < efx_nic_reg_tables + ARRAY_SIZE(efx_nic_reg_tables);
1838 table++)
1839 if (efx->type->revision >= table->min_revision &&
1840 efx->type->revision <= table->max_revision)
1841 len += table->rows * min_t(size_t, table->step, 16);
1842
1843 return len;
1844}
1845
1846void efx_nic_get_regs(struct efx_nic *efx, void *buf)
1847{
1848 const struct efx_nic_reg *reg;
1849 const struct efx_nic_reg_table *table;
1850
1851 for (reg = efx_nic_regs;
1852 reg < efx_nic_regs + ARRAY_SIZE(efx_nic_regs);
1853 reg++) {
1854 if (efx->type->revision >= reg->min_revision &&
1855 efx->type->revision <= reg->max_revision) {
1856 efx_reado(efx, (efx_oword_t *)buf, reg->offset);
1857 buf += sizeof(efx_oword_t);
1858 }
1859 }
1860
1861 for (table = efx_nic_reg_tables;
1862 table < efx_nic_reg_tables + ARRAY_SIZE(efx_nic_reg_tables);
1863 table++) {
1864 size_t size, i;
1865
1866 if (!(efx->type->revision >= table->min_revision &&
1867 efx->type->revision <= table->max_revision))
1868 continue;
1869
1870 size = min_t(size_t, table->step, 16);
1871
1872 for (i = 0; i < table->rows; i++) {
1873 switch (table->step) {
1874 case 4: /* 32-bit register or SRAM */
1875 efx_readd_table(efx, buf, table->offset, i);
1876 break;
1877 case 8: /* 64-bit SRAM */
1878 efx_sram_readq(efx,
1879 efx->membase + table->offset,
1880 buf, i);
1881 break;
1882 case 16: /* 128-bit register */
1883 efx_reado_table(efx, buf, table->offset, i);
1884 break;
1885 case 32: /* 128-bit register, interleaved */
1886 efx_reado_table(efx, buf, table->offset, 2 * i);
1887 break;
1888 default:
1889 WARN_ON(1);
1890 return;
1891 }
1892 buf += size;
1893 }
1894 }
1895}
diff --git a/drivers/net/sfc/nic.h b/drivers/net/sfc/nic.h
index 95770e15115d..534461ffece8 100644
--- a/drivers/net/sfc/nic.h
+++ b/drivers/net/sfc/nic.h
@@ -222,6 +222,9 @@ extern int efx_nic_test_registers(struct efx_nic *efx,
222 const struct efx_nic_register_test *regs, 222 const struct efx_nic_register_test *regs,
223 size_t n_regs); 223 size_t n_regs);
224 224
225extern size_t efx_nic_get_regs_len(struct efx_nic *efx);
226extern void efx_nic_get_regs(struct efx_nic *efx, void *buf);
227
225/************************************************************************** 228/**************************************************************************
226 * 229 *
227 * Falcon MAC stats 230 * Falcon MAC stats