aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <ben.hutchings@codethink.co.uk>2015-02-26 15:34:35 -0500
committerDavid S. Miller <davem@davemloft.net>2015-03-04 15:40:54 -0500
commit6b4b4fead3421f00953c8ce89af95ba9a1f39086 (patch)
treebffc95eba469f567745b5b50464104207c0f2f47
parent3365711df024f60d2e1e0ba9b40b6e965ab83bf6 (diff)
sh_eth: Implement ethtool register dump operations
There are many different sets of registers implemented by the different versions of this controller, and we can only expect this to get more complicated in future. Limit how much ethtool needs to know by including an explicit bitmap of which registers are included in the dump, allowing room for future growth in the number of possible registers. As I don't have datasheets for all of these, I've only included registers that are: - defined in all 5 register type arrays, or - used by the driver, or - documented in the datasheet I have Add one new capability flag so we can tell whether the RTRATE register is implemented. Delete the TSU_ADRL0 and TSU_ADR{H,L}31 definitions, as they weren't used and the address table is already assumed to be contiguous. Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.c197
-rw-r--r--drivers/net/ethernet/renesas/sh_eth.h9
2 files changed, 195 insertions, 11 deletions
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
index 64e72ebdf8c5..5d9e3a77a1eb 100644
--- a/drivers/net/ethernet/renesas/sh_eth.c
+++ b/drivers/net/ethernet/renesas/sh_eth.c
@@ -137,9 +137,6 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
137 [TSU_POST3] = 0x0078, 137 [TSU_POST3] = 0x0078,
138 [TSU_POST4] = 0x007c, 138 [TSU_POST4] = 0x007c,
139 [TSU_ADRH0] = 0x0100, 139 [TSU_ADRH0] = 0x0100,
140 [TSU_ADRL0] = 0x0104,
141 [TSU_ADRH31] = 0x01f8,
142 [TSU_ADRL31] = 0x01fc,
143 140
144 [TXNLCR0] = 0x0080, 141 [TXNLCR0] = 0x0080,
145 [TXALCR0] = 0x0084, 142 [TXALCR0] = 0x0084,
@@ -206,9 +203,6 @@ static const u16 sh_eth_offset_fast_rz[SH_ETH_MAX_REGISTER_OFFSET] = {
206 [TSU_ADSBSY] = 0x0060, 203 [TSU_ADSBSY] = 0x0060,
207 [TSU_TEN] = 0x0064, 204 [TSU_TEN] = 0x0064,
208 [TSU_ADRH0] = 0x0100, 205 [TSU_ADRH0] = 0x0100,
209 [TSU_ADRL0] = 0x0104,
210 [TSU_ADRH31] = 0x01f8,
211 [TSU_ADRL31] = 0x01fc,
212 206
213 [TXNLCR0] = 0x0080, 207 [TXNLCR0] = 0x0080,
214 [TXALCR0] = 0x0084, 208 [TXALCR0] = 0x0084,
@@ -405,8 +399,6 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
405 [FWALCR1] = 0x00b4, 399 [FWALCR1] = 0x00b4,
406 400
407 [TSU_ADRH0] = 0x0100, 401 [TSU_ADRH0] = 0x0100,
408 [TSU_ADRL0] = 0x0104,
409 [TSU_ADRL31] = 0x01fc,
410}; 402};
411 403
412static void sh_eth_rcv_snd_disable(struct net_device *ndev); 404static void sh_eth_rcv_snd_disable(struct net_device *ndev);
@@ -601,6 +593,7 @@ static struct sh_eth_cpu_data sh7757_data = {
601 .no_ade = 1, 593 .no_ade = 1,
602 .rpadir = 1, 594 .rpadir = 1,
603 .rpadir_value = 2 << 16, 595 .rpadir_value = 2 << 16,
596 .rtrate = 1,
604}; 597};
605 598
606#define SH_GIGA_ETH_BASE 0xfee00000UL 599#define SH_GIGA_ETH_BASE 0xfee00000UL
@@ -1945,6 +1938,192 @@ error_exit:
1945 return ret; 1938 return ret;
1946} 1939}
1947 1940
1941/* If it is ever necessary to increase SH_ETH_REG_DUMP_MAX_REGS, the
1942 * version must be bumped as well. Just adding registers up to that
1943 * limit is fine, as long as the existing register indices don't
1944 * change.
1945 */
1946#define SH_ETH_REG_DUMP_VERSION 1
1947#define SH_ETH_REG_DUMP_MAX_REGS 256
1948
1949static size_t __sh_eth_get_regs(struct net_device *ndev, u32 *buf)
1950{
1951 struct sh_eth_private *mdp = netdev_priv(ndev);
1952 struct sh_eth_cpu_data *cd = mdp->cd;
1953 u32 *valid_map;
1954 size_t len;
1955
1956 BUILD_BUG_ON(SH_ETH_MAX_REGISTER_OFFSET > SH_ETH_REG_DUMP_MAX_REGS);
1957
1958 /* Dump starts with a bitmap that tells ethtool which
1959 * registers are defined for this chip.
1960 */
1961 len = DIV_ROUND_UP(SH_ETH_REG_DUMP_MAX_REGS, 32);
1962 if (buf) {
1963 valid_map = buf;
1964 buf += len;
1965 } else {
1966 valid_map = NULL;
1967 }
1968
1969 /* Add a register to the dump, if it has a defined offset.
1970 * This automatically skips most undefined registers, but for
1971 * some it is also necessary to check a capability flag in
1972 * struct sh_eth_cpu_data.
1973 */
1974#define mark_reg_valid(reg) valid_map[reg / 32] |= 1U << (reg % 32)
1975#define add_reg_from(reg, read_expr) do { \
1976 if (mdp->reg_offset[reg] != SH_ETH_OFFSET_INVALID) { \
1977 if (buf) { \
1978 mark_reg_valid(reg); \
1979 *buf++ = read_expr; \
1980 } \
1981 ++len; \
1982 } \
1983 } while (0)
1984#define add_reg(reg) add_reg_from(reg, sh_eth_read(ndev, reg))
1985#define add_tsu_reg(reg) add_reg_from(reg, sh_eth_tsu_read(mdp, reg))
1986
1987 add_reg(EDSR);
1988 add_reg(EDMR);
1989 add_reg(EDTRR);
1990 add_reg(EDRRR);
1991 add_reg(EESR);
1992 add_reg(EESIPR);
1993 add_reg(TDLAR);
1994 add_reg(TDFAR);
1995 add_reg(TDFXR);
1996 add_reg(TDFFR);
1997 add_reg(RDLAR);
1998 add_reg(RDFAR);
1999 add_reg(RDFXR);
2000 add_reg(RDFFR);
2001 add_reg(TRSCER);
2002 add_reg(RMFCR);
2003 add_reg(TFTR);
2004 add_reg(FDR);
2005 add_reg(RMCR);
2006 add_reg(TFUCR);
2007 add_reg(RFOCR);
2008 if (cd->rmiimode)
2009 add_reg(RMIIMODE);
2010 add_reg(FCFTR);
2011 if (cd->rpadir)
2012 add_reg(RPADIR);
2013 if (!cd->no_trimd)
2014 add_reg(TRIMD);
2015 add_reg(ECMR);
2016 add_reg(ECSR);
2017 add_reg(ECSIPR);
2018 add_reg(PIR);
2019 if (!cd->no_psr)
2020 add_reg(PSR);
2021 add_reg(RDMLR);
2022 add_reg(RFLR);
2023 add_reg(IPGR);
2024 if (cd->apr)
2025 add_reg(APR);
2026 if (cd->mpr)
2027 add_reg(MPR);
2028 add_reg(RFCR);
2029 add_reg(RFCF);
2030 if (cd->tpauser)
2031 add_reg(TPAUSER);
2032 add_reg(TPAUSECR);
2033 add_reg(GECMR);
2034 if (cd->bculr)
2035 add_reg(BCULR);
2036 add_reg(MAHR);
2037 add_reg(MALR);
2038 add_reg(TROCR);
2039 add_reg(CDCR);
2040 add_reg(LCCR);
2041 add_reg(CNDCR);
2042 add_reg(CEFCR);
2043 add_reg(FRECR);
2044 add_reg(TSFRCR);
2045 add_reg(TLFRCR);
2046 add_reg(CERCR);
2047 add_reg(CEECR);
2048 add_reg(MAFCR);
2049 if (cd->rtrate)
2050 add_reg(RTRATE);
2051 if (cd->hw_crc)
2052 add_reg(CSMR);
2053 if (cd->select_mii)
2054 add_reg(RMII_MII);
2055 add_reg(ARSTR);
2056 if (cd->tsu) {
2057 add_tsu_reg(TSU_CTRST);
2058 add_tsu_reg(TSU_FWEN0);
2059 add_tsu_reg(TSU_FWEN1);
2060 add_tsu_reg(TSU_FCM);
2061 add_tsu_reg(TSU_BSYSL0);
2062 add_tsu_reg(TSU_BSYSL1);
2063 add_tsu_reg(TSU_PRISL0);
2064 add_tsu_reg(TSU_PRISL1);
2065 add_tsu_reg(TSU_FWSL0);
2066 add_tsu_reg(TSU_FWSL1);
2067 add_tsu_reg(TSU_FWSLC);
2068 add_tsu_reg(TSU_QTAG0);
2069 add_tsu_reg(TSU_QTAG1);
2070 add_tsu_reg(TSU_QTAGM0);
2071 add_tsu_reg(TSU_QTAGM1);
2072 add_tsu_reg(TSU_FWSR);
2073 add_tsu_reg(TSU_FWINMK);
2074 add_tsu_reg(TSU_ADQT0);
2075 add_tsu_reg(TSU_ADQT1);
2076 add_tsu_reg(TSU_VTAG0);
2077 add_tsu_reg(TSU_VTAG1);
2078 add_tsu_reg(TSU_ADSBSY);
2079 add_tsu_reg(TSU_TEN);
2080 add_tsu_reg(TSU_POST1);
2081 add_tsu_reg(TSU_POST2);
2082 add_tsu_reg(TSU_POST3);
2083 add_tsu_reg(TSU_POST4);
2084 if (mdp->reg_offset[TSU_ADRH0] != SH_ETH_OFFSET_INVALID) {
2085 /* This is the start of a table, not just a single
2086 * register.
2087 */
2088 if (buf) {
2089 unsigned int i;
2090
2091 mark_reg_valid(TSU_ADRH0);
2092 for (i = 0; i < SH_ETH_TSU_CAM_ENTRIES * 2; i++)
2093 *buf++ = ioread32(
2094 mdp->tsu_addr +
2095 mdp->reg_offset[TSU_ADRH0] +
2096 i * 4);
2097 }
2098 len += SH_ETH_TSU_CAM_ENTRIES * 2;
2099 }
2100 }
2101
2102#undef mark_reg_valid
2103#undef add_reg_from
2104#undef add_reg
2105#undef add_tsu_reg
2106
2107 return len * 4;
2108}
2109
2110static int sh_eth_get_regs_len(struct net_device *ndev)
2111{
2112 return __sh_eth_get_regs(ndev, NULL);
2113}
2114
2115static void sh_eth_get_regs(struct net_device *ndev, struct ethtool_regs *regs,
2116 void *buf)
2117{
2118 struct sh_eth_private *mdp = netdev_priv(ndev);
2119
2120 regs->version = SH_ETH_REG_DUMP_VERSION;
2121
2122 pm_runtime_get_sync(&mdp->pdev->dev);
2123 __sh_eth_get_regs(ndev, buf);
2124 pm_runtime_put_sync(&mdp->pdev->dev);
2125}
2126
1948static int sh_eth_nway_reset(struct net_device *ndev) 2127static int sh_eth_nway_reset(struct net_device *ndev)
1949{ 2128{
1950 struct sh_eth_private *mdp = netdev_priv(ndev); 2129 struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -2090,6 +2269,8 @@ static int sh_eth_set_ringparam(struct net_device *ndev,
2090static const struct ethtool_ops sh_eth_ethtool_ops = { 2269static const struct ethtool_ops sh_eth_ethtool_ops = {
2091 .get_settings = sh_eth_get_settings, 2270 .get_settings = sh_eth_get_settings,
2092 .set_settings = sh_eth_set_settings, 2271 .set_settings = sh_eth_set_settings,
2272 .get_regs_len = sh_eth_get_regs_len,
2273 .get_regs = sh_eth_get_regs,
2093 .nway_reset = sh_eth_nway_reset, 2274 .nway_reset = sh_eth_nway_reset,
2094 .get_msglevel = sh_eth_get_msglevel, 2275 .get_msglevel = sh_eth_get_msglevel,
2095 .set_msglevel = sh_eth_set_msglevel, 2276 .set_msglevel = sh_eth_set_msglevel,
diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
index 33a360c4fd10..06dbbe5201cb 100644
--- a/drivers/net/ethernet/renesas/sh_eth.h
+++ b/drivers/net/ethernet/renesas/sh_eth.h
@@ -32,6 +32,10 @@
32#define SH_ETH_TSU_CAM_ENTRIES 32 32#define SH_ETH_TSU_CAM_ENTRIES 32
33 33
34enum { 34enum {
35 /* IMPORTANT: To keep ethtool register dump working, add new
36 * register names immediately before SH_ETH_MAX_REGISTER_OFFSET.
37 */
38
35 /* E-DMAC registers */ 39 /* E-DMAC registers */
36 EDSR = 0, 40 EDSR = 0,
37 EDMR, 41 EDMR,
@@ -131,9 +135,7 @@ enum {
131 TSU_POST3, 135 TSU_POST3,
132 TSU_POST4, 136 TSU_POST4,
133 TSU_ADRH0, 137 TSU_ADRH0,
134 TSU_ADRL0, 138 /* TSU_ADR{H,L}{0..31} are assumed to be contiguous */
135 TSU_ADRH31,
136 TSU_ADRL31,
137 139
138 TXNLCR0, 140 TXNLCR0,
139 TXALCR0, 141 TXALCR0,
@@ -491,6 +493,7 @@ struct sh_eth_cpu_data {
491 unsigned select_mii:1; /* EtherC have RMII_MII (MII select register) */ 493 unsigned select_mii:1; /* EtherC have RMII_MII (MII select register) */
492 unsigned shift_rd0:1; /* shift Rx descriptor word 0 right by 16 */ 494 unsigned shift_rd0:1; /* shift Rx descriptor word 0 right by 16 */
493 unsigned rmiimode:1; /* EtherC has RMIIMODE register */ 495 unsigned rmiimode:1; /* EtherC has RMIIMODE register */
496 unsigned rtrate:1; /* EtherC has RTRATE register */
494}; 497};
495 498
496struct sh_eth_private { 499struct sh_eth_private {