Commit 3365711d authored by Ben Hutchings's avatar Ben Hutchings Committed by David S. Miller

sh_eth: WARN on access to a register not implemented in a particular chip

Currently we may silently read/write a register at offset 0.  Change
this to WARN and then ignore the write or read-back all-ones.
Signed-off-by: default avatarBen Hutchings <ben.hutchings@codethink.co.uk>
Acked-by: default avatarSergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 25b77ad7
...@@ -52,7 +52,12 @@ ...@@ -52,7 +52,12 @@
NETIF_MSG_RX_ERR| \ NETIF_MSG_RX_ERR| \
NETIF_MSG_TX_ERR) NETIF_MSG_TX_ERR)
#define SH_ETH_OFFSET_DEFAULTS \
[0 ... SH_ETH_MAX_REGISTER_OFFSET - 1] = SH_ETH_OFFSET_INVALID
static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = { static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
SH_ETH_OFFSET_DEFAULTS,
[EDSR] = 0x0000, [EDSR] = 0x0000,
[EDMR] = 0x0400, [EDMR] = 0x0400,
[EDTRR] = 0x0408, [EDTRR] = 0x0408,
...@@ -151,6 +156,8 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = { ...@@ -151,6 +156,8 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
}; };
static const u16 sh_eth_offset_fast_rz[SH_ETH_MAX_REGISTER_OFFSET] = { static const u16 sh_eth_offset_fast_rz[SH_ETH_MAX_REGISTER_OFFSET] = {
SH_ETH_OFFSET_DEFAULTS,
[EDSR] = 0x0000, [EDSR] = 0x0000,
[EDMR] = 0x0400, [EDMR] = 0x0400,
[EDTRR] = 0x0408, [EDTRR] = 0x0408,
...@@ -210,6 +217,8 @@ static const u16 sh_eth_offset_fast_rz[SH_ETH_MAX_REGISTER_OFFSET] = { ...@@ -210,6 +217,8 @@ static const u16 sh_eth_offset_fast_rz[SH_ETH_MAX_REGISTER_OFFSET] = {
}; };
static const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = { static const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = {
SH_ETH_OFFSET_DEFAULTS,
[ECMR] = 0x0300, [ECMR] = 0x0300,
[RFLR] = 0x0308, [RFLR] = 0x0308,
[ECSR] = 0x0310, [ECSR] = 0x0310,
...@@ -256,6 +265,8 @@ static const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = { ...@@ -256,6 +265,8 @@ static const u16 sh_eth_offset_fast_rcar[SH_ETH_MAX_REGISTER_OFFSET] = {
}; };
static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = { static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {
SH_ETH_OFFSET_DEFAULTS,
[ECMR] = 0x0100, [ECMR] = 0x0100,
[RFLR] = 0x0108, [RFLR] = 0x0108,
[ECSR] = 0x0110, [ECSR] = 0x0110,
...@@ -308,6 +319,8 @@ static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = { ...@@ -308,6 +319,8 @@ static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {
}; };
static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = { static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
SH_ETH_OFFSET_DEFAULTS,
[EDMR] = 0x0000, [EDMR] = 0x0000,
[EDTRR] = 0x0004, [EDTRR] = 0x0004,
[EDRRR] = 0x0008, [EDRRR] = 0x0008,
...@@ -1544,7 +1557,8 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota) ...@@ -1544,7 +1557,8 @@ static int sh_eth_rx(struct net_device *ndev, u32 intr_status, int *quota)
/* If we don't need to check status, don't. -KDU */ /* If we don't need to check status, don't. -KDU */
if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) { if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R)) {
/* fix the values for the next receiving if RDE is set */ /* fix the values for the next receiving if RDE is set */
if (intr_status & EESR_RDE && mdp->reg_offset[RDFAR] != 0) { if (intr_status & EESR_RDE &&
mdp->reg_offset[RDFAR] != SH_ETH_OFFSET_INVALID) {
u32 count = (sh_eth_read(ndev, RDFAR) - u32 count = (sh_eth_read(ndev, RDFAR) -
sh_eth_read(ndev, RDLAR)) >> 4; sh_eth_read(ndev, RDLAR)) >> 4;
......
...@@ -543,19 +543,29 @@ static inline void sh_eth_soft_swap(char *src, int len) ...@@ -543,19 +543,29 @@ static inline void sh_eth_soft_swap(char *src, int len)
#endif #endif
} }
#define SH_ETH_OFFSET_INVALID ((u16) ~0)
static inline void sh_eth_write(struct net_device *ndev, u32 data, static inline void sh_eth_write(struct net_device *ndev, u32 data,
int enum_index) int enum_index)
{ {
struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_private *mdp = netdev_priv(ndev);
u16 offset = mdp->reg_offset[enum_index];
if (WARN_ON(offset == SH_ETH_OFFSET_INVALID))
return;
iowrite32(data, mdp->addr + mdp->reg_offset[enum_index]); iowrite32(data, mdp->addr + offset);
} }
static inline u32 sh_eth_read(struct net_device *ndev, int enum_index) static inline u32 sh_eth_read(struct net_device *ndev, int enum_index)
{ {
struct sh_eth_private *mdp = netdev_priv(ndev); struct sh_eth_private *mdp = netdev_priv(ndev);
u16 offset = mdp->reg_offset[enum_index];
if (WARN_ON(offset == SH_ETH_OFFSET_INVALID))
return ~0U;
return ioread32(mdp->addr + mdp->reg_offset[enum_index]); return ioread32(mdp->addr + offset);
} }
static inline void *sh_eth_tsu_get_offset(struct sh_eth_private *mdp, static inline void *sh_eth_tsu_get_offset(struct sh_eth_private *mdp,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment