Commit b0a8d1a0 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by David S. Miller

net: ezchip: fix address space confusion in nps_enet.c

The nps_enet driver happily mixes virtual, physical and __iomem
addresses, which are all different depending on the architecture
and configuration.  That causes a warning when building the code
on ARM with LPAE mode enabled:

drivers/net/ethernet/ezchip/nps_enet.c: In function 'nps_enet_send_frame':
drivers/net/ethernet/ezchip/nps_enet.c:370:13: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]

but will also fail to work for other reasons.

In this patch, I'm trying to change the code to use only normal
kernel pointers, which I assume is what the author actually meant:

* For reading or writing a 32-bit word that may be unaligned when
  an SKB contains unaligned data, I'm using get_unaligned/put_unaligned()
  rather than memcpy_fromio/toio.

* For converting a u8 pointer to a u32 pointer, I use a cast rather
  than the incorrect virt_to_phys.

* For copying a couple of bytes from one place to another while respecting
  alignment, I use memcpy instead of memcpy_toio.
Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8cde3e44
...@@ -48,21 +48,15 @@ static void nps_enet_read_rx_fifo(struct net_device *ndev, ...@@ -48,21 +48,15 @@ static void nps_enet_read_rx_fifo(struct net_device *ndev,
*reg = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF); *reg = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF);
else { /* !dst_is_aligned */ else { /* !dst_is_aligned */
for (i = 0; i < len; i++, reg++) { for (i = 0; i < len; i++, reg++) {
u32 buf = u32 buf = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF);
nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF); put_unaligned(buf, reg);
/* to accommodate word-unaligned address of "reg"
* we have to do memcpy_toio() instead of simple "=".
*/
memcpy_toio((void __iomem *)reg, &buf, sizeof(buf));
} }
} }
/* copy last bytes (if any) */ /* copy last bytes (if any) */
if (last) { if (last) {
u32 buf = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF); u32 buf = nps_enet_reg_get(priv, NPS_ENET_REG_RX_BUF);
memcpy((u8*)reg, &buf, last);
memcpy_toio((void __iomem *)reg, &buf, last);
} }
} }
...@@ -367,7 +361,7 @@ static void nps_enet_send_frame(struct net_device *ndev, ...@@ -367,7 +361,7 @@ static void nps_enet_send_frame(struct net_device *ndev,
struct nps_enet_tx_ctl tx_ctrl; struct nps_enet_tx_ctl tx_ctrl;
short length = skb->len; short length = skb->len;
u32 i, len = DIV_ROUND_UP(length, sizeof(u32)); u32 i, len = DIV_ROUND_UP(length, sizeof(u32));
u32 *src = (u32 *)virt_to_phys(skb->data); u32 *src = (void *)skb->data;
bool src_is_aligned = IS_ALIGNED((unsigned long)src, sizeof(u32)); bool src_is_aligned = IS_ALIGNED((unsigned long)src, sizeof(u32));
tx_ctrl.value = 0; tx_ctrl.value = 0;
...@@ -375,17 +369,11 @@ static void nps_enet_send_frame(struct net_device *ndev, ...@@ -375,17 +369,11 @@ static void nps_enet_send_frame(struct net_device *ndev,
if (src_is_aligned) if (src_is_aligned)
for (i = 0; i < len; i++, src++) for (i = 0; i < len; i++, src++)
nps_enet_reg_set(priv, NPS_ENET_REG_TX_BUF, *src); nps_enet_reg_set(priv, NPS_ENET_REG_TX_BUF, *src);
else { /* !src_is_aligned */ else /* !src_is_aligned */
for (i = 0; i < len; i++, src++) { for (i = 0; i < len; i++, src++)
u32 buf; nps_enet_reg_set(priv, NPS_ENET_REG_TX_BUF,
get_unaligned(src));
/* to accommodate word-unaligned address of "src"
* we have to do memcpy_fromio() instead of simple "="
*/
memcpy_fromio(&buf, (void __iomem *)src, sizeof(buf));
nps_enet_reg_set(priv, NPS_ENET_REG_TX_BUF, buf);
}
}
/* Write the length of the Frame */ /* Write the length of the Frame */
tx_ctrl.nt = length; tx_ctrl.nt = length;
......
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