aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2011-07-27 10:20:51 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-28 01:39:31 -0400
commitd1a3b7377d3b6a01ec5f70adb32173b13233aabf (patch)
treead1d5204140560a8724a104bbc1dccbc0704307d
parente01ee14d499e5d09c0a9db0cac2545a018849e3d (diff)
tg3: Consolidate code that calls tg3_tx_set_bd()
This patch consolidates all code that populates tx BDs into a single routine. Setting tx BDs needs to be more carefully controlled to see if workarounds need to be applied. Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Reviewed-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/tg3.c79
1 files changed, 42 insertions, 37 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 90b68a229745..7f816a0ee421 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -5914,18 +5914,37 @@ static inline int tg3_40bit_overflow_test(struct tg3 *tp, dma_addr_t mapping,
5914#endif 5914#endif
5915} 5915}
5916 5916
5917static inline void tg3_tx_set_bd(struct tg3_napi *tnapi, u32 entry, 5917static inline void tg3_tx_set_bd(struct tg3_tx_buffer_desc *txbd,
5918 dma_addr_t mapping, u32 len, u32 flags, 5918 dma_addr_t mapping, u32 len, u32 flags,
5919 u32 mss, u32 vlan) 5919 u32 mss, u32 vlan)
5920{ 5920{
5921 struct tg3_tx_buffer_desc *txbd = &tnapi->tx_ring[entry];
5922
5923 txbd->addr_hi = ((u64) mapping >> 32); 5921 txbd->addr_hi = ((u64) mapping >> 32);
5924 txbd->addr_lo = ((u64) mapping & 0xffffffff); 5922 txbd->addr_lo = ((u64) mapping & 0xffffffff);
5925 txbd->len_flags = (len << TXD_LEN_SHIFT) | (flags & 0x0000ffff); 5923 txbd->len_flags = (len << TXD_LEN_SHIFT) | (flags & 0x0000ffff);
5926 txbd->vlan_tag = (mss << TXD_MSS_SHIFT) | (vlan << TXD_VLAN_TAG_SHIFT); 5924 txbd->vlan_tag = (mss << TXD_MSS_SHIFT) | (vlan << TXD_VLAN_TAG_SHIFT);
5927} 5925}
5928 5926
5927static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 entry,
5928 dma_addr_t map, u32 len, u32 flags,
5929 u32 mss, u32 vlan)
5930{
5931 struct tg3 *tp = tnapi->tp;
5932 bool hwbug = false;
5933
5934 if (tg3_flag(tp, SHORT_DMA_BUG) && len <= 8)
5935 hwbug = 1;
5936
5937 if (tg3_4g_overflow_test(map, len))
5938 hwbug = 1;
5939
5940 if (tg3_40bit_overflow_test(tp, map, len))
5941 hwbug = 1;
5942
5943 tg3_tx_set_bd(&tnapi->tx_ring[entry], map, len, flags, mss, vlan);
5944
5945 return hwbug;
5946}
5947
5929static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last) 5948static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last)
5930{ 5949{
5931 int i; 5950 int i;
@@ -5993,17 +6012,8 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
5993 PCI_DMA_TODEVICE); 6012 PCI_DMA_TODEVICE);
5994 /* Make sure the mapping succeeded */ 6013 /* Make sure the mapping succeeded */
5995 if (pci_dma_mapping_error(tp->pdev, new_addr)) { 6014 if (pci_dma_mapping_error(tp->pdev, new_addr)) {
5996 ret = -1;
5997 dev_kfree_skb(new_skb); 6015 dev_kfree_skb(new_skb);
5998
5999 /* Make sure new skb does not cross any 4G boundaries.
6000 * Drop the packet if it does.
6001 */
6002 } else if (tg3_4g_overflow_test(new_addr, new_skb->len)) {
6003 pci_unmap_single(tp->pdev, new_addr, new_skb->len,
6004 PCI_DMA_TODEVICE);
6005 ret = -1; 6016 ret = -1;
6006 dev_kfree_skb(new_skb);
6007 } else { 6017 } else {
6008 base_flags |= TXD_FLAG_END; 6018 base_flags |= TXD_FLAG_END;
6009 6019
@@ -6011,8 +6021,13 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
6011 dma_unmap_addr_set(&tnapi->tx_buffers[entry], 6021 dma_unmap_addr_set(&tnapi->tx_buffers[entry],
6012 mapping, new_addr); 6022 mapping, new_addr);
6013 6023
6014 tg3_tx_set_bd(tnapi, entry, new_addr, new_skb->len, 6024 if (tg3_tx_frag_set(tnapi, entry, new_addr,
6015 base_flags, mss, vlan); 6025 new_skb->len, base_flags,
6026 mss, vlan)) {
6027 tg3_tx_skb_unmap(tnapi, entry, 0);
6028 dev_kfree_skb(new_skb);
6029 ret = -1;
6030 }
6016 } 6031 }
6017 } 6032 }
6018 6033
@@ -6196,18 +6211,13 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
6196 6211
6197 would_hit_hwbug = 0; 6212 would_hit_hwbug = 0;
6198 6213
6199 if (tg3_4g_overflow_test(mapping, len))
6200 would_hit_hwbug = 1;
6201
6202 if (tg3_40bit_overflow_test(tp, mapping, len))
6203 would_hit_hwbug = 1;
6204
6205 if (tg3_flag(tp, 5701_DMA_BUG)) 6214 if (tg3_flag(tp, 5701_DMA_BUG))
6206 would_hit_hwbug = 1; 6215 would_hit_hwbug = 1;
6207 6216
6208 tg3_tx_set_bd(tnapi, entry, mapping, len, base_flags | 6217 if (tg3_tx_frag_set(tnapi, entry, mapping, len, base_flags |
6209 ((skb_shinfo(skb)->nr_frags == 0) ? TXD_FLAG_END : 0), 6218 ((skb_shinfo(skb)->nr_frags == 0) ? TXD_FLAG_END : 0),
6210 mss, vlan); 6219 mss, vlan))
6220 would_hit_hwbug = 1;
6211 6221
6212 entry = NEXT_TX(entry); 6222 entry = NEXT_TX(entry);
6213 6223
@@ -6236,20 +6246,11 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
6236 if (pci_dma_mapping_error(tp->pdev, mapping)) 6246 if (pci_dma_mapping_error(tp->pdev, mapping))
6237 goto dma_error; 6247 goto dma_error;
6238 6248
6239 if (tg3_flag(tp, SHORT_DMA_BUG) && 6249 if (tg3_tx_frag_set(tnapi, entry, mapping, len,
6240 len <= 8) 6250 base_flags | ((i == last) ? TXD_FLAG_END : 0),
6241 would_hit_hwbug = 1; 6251 tmp_mss, vlan))
6242
6243 if (tg3_4g_overflow_test(mapping, len))
6244 would_hit_hwbug = 1;
6245
6246 if (tg3_40bit_overflow_test(tp, mapping, len))
6247 would_hit_hwbug = 1; 6252 would_hit_hwbug = 1;
6248 6253
6249 tg3_tx_set_bd(tnapi, entry, mapping, len, base_flags |
6250 ((i == last) ? TXD_FLAG_END : 0),
6251 tmp_mss, vlan);
6252
6253 entry = NEXT_TX(entry); 6254 entry = NEXT_TX(entry);
6254 } 6255 }
6255 } 6256 }
@@ -11375,8 +11376,12 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, int loopback_mode)
11375 11376
11376 rx_start_idx = rnapi->hw_status->idx[0].rx_producer; 11377 rx_start_idx = rnapi->hw_status->idx[0].rx_producer;
11377 11378
11378 tg3_tx_set_bd(tnapi, tnapi->tx_prod, map, tx_len, 11379 if (tg3_tx_frag_set(tnapi, tnapi->tx_prod, map, tx_len,
11379 base_flags | TXD_FLAG_END, mss, 0); 11380 base_flags | TXD_FLAG_END, mss, 0)) {
11381 tnapi->tx_buffers[val].skb = NULL;
11382 dev_kfree_skb(skb);
11383 return -EIO;
11384 }
11380 11385
11381 tnapi->tx_prod++; 11386 tnapi->tx_prod++;
11382 11387