summaryrefslogtreecommitdiffstats
path: root/drivers/net/bfin_mac.c
diff options
context:
space:
mode:
authorSonic Zhang <sonic.zhang@analog.com>2010-05-10 07:39:08 +0200
committerDavid S. Miller <davem@davemloft.net>2010-05-18 02:20:58 +0200
commitf6e1e4f3e511589dd0c47d42b870501659e7195f (patch)
tree0574a664c6cf76b7b9b0c0b795f0c6b8d2351391 /drivers/net/bfin_mac.c
parentnetdev: bfin_mac: handler RX status errors (diff)
downloadlinux-f6e1e4f3e511589dd0c47d42b870501659e7195f.tar.xz
linux-f6e1e4f3e511589dd0c47d42b870501659e7195f.zip
netdev: bfin_mac: invalid data cache only once for each new rx skb buffer
The skb buffer isn't actually used until we finish transferring and pass it up to higher layers, so only invalidate the range once before we start receiving actual data. This also avoids the problem with data invalidating on Blackfin systems -- there is no invalidate-only, just invalidate+flush. So when running in writeback mode, there is the small (but not uncommon) possibility of the flush overwriting valid DMA-ed data from the cache. Signed-off-by: Sonic Zhang <sonic.zhang@analog.com> Signed-off-by: Mike Frysinger <vapier@gentoo.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bfin_mac.c')
-rw-r--r--drivers/net/bfin_mac.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 16f2a37c733d..2b364ba6b62e 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -203,6 +203,11 @@ static int desc_list_init(void)
goto init_error;
}
skb_reserve(new_skb, NET_IP_ALIGN);
+ /* Invidate the data cache of skb->data range when it is write back
+ * cache. It will prevent overwritting the new data from DMA
+ */
+ blackfin_dcache_invalidate_range((unsigned long)new_skb->head,
+ (unsigned long)new_skb->end);
r->skb = new_skb;
/*
@@ -1011,19 +1016,17 @@ static void bfin_mac_rx(struct net_device *dev)
}
/* reserve 2 bytes for RXDWA padding */
skb_reserve(new_skb, NET_IP_ALIGN);
- current_rx_ptr->skb = new_skb;
- current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2;
-
/* Invidate the data cache of skb->data range when it is write back
* cache. It will prevent overwritting the new data from DMA
*/
blackfin_dcache_invalidate_range((unsigned long)new_skb->head,
(unsigned long)new_skb->end);
+ current_rx_ptr->skb = new_skb;
+ current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2;
+
len = (unsigned short)((current_rx_ptr->status.status_word) & RX_FRLEN);
skb_put(skb, len);
- blackfin_dcache_invalidate_range((unsigned long)skb->head,
- (unsigned long)skb->tail);
skb->protocol = eth_type_trans(skb, dev);