aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tg3.c
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2010-04-12 02:58:27 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-13 05:25:44 -0400
commitd2757fc4076118e13180e91f02c3c52659be3d9d (patch)
tree2862b2b319d58cfa581d86855e80525d966aac6b /drivers/net/tg3.c
parenta977dbe8445b8a81d6127c4aa9112a2c29a1a008 (diff)
tg3: Optimize rx double copy test
On a PCIX bus, the 5701 has a bug which requires the driver to double copy all rx packets. The rx code uses the rx_offset device member as a flag to determine if this workaround should take effect. The following patch will modify the rx_offset member such that this test will become less clear. The patch starts by integrating the workaround check into the packet length check. It rounds out the implementation by relaxing the workaround restrictions if the platform has efficient unaligned accesses. Signed-off-by: Matt Carlson <mcarlson@broadcom.com> Reviewed-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r--drivers/net/tg3.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 3e893231fef3..57914050b098 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -144,6 +144,24 @@
144 144
145#define TG3_RSS_MIN_NUM_MSIX_VECS 2 145#define TG3_RSS_MIN_NUM_MSIX_VECS 2
146 146
147/* Due to a hardware bug, the 5701 can only DMA to memory addresses
148 * that are at least dword aligned when used in PCIX mode. The driver
149 * works around this bug by double copying the packet. This workaround
150 * is built into the normal double copy length check for efficiency.
151 *
152 * However, the double copy is only necessary on those architectures
153 * where unaligned memory accesses are inefficient. For those architectures
154 * where unaligned memory accesses incur little penalty, we can reintegrate
155 * the 5701 in the normal rx path. Doing so saves a device structure
156 * dereference by hardcoding the double copy threshold in place.
157 */
158#define TG3_RX_COPY_THRESHOLD 256
159#if NET_IP_ALIGN == 0 || defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
160 #define TG3_RX_COPY_THRESH(tp) TG3_RX_COPY_THRESHOLD
161#else
162 #define TG3_RX_COPY_THRESH(tp) ((tp)->rx_copy_thresh)
163#endif
164
147/* minimum number of free TX descriptors required to wake up TX process */ 165/* minimum number of free TX descriptors required to wake up TX process */
148#define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4) 166#define TG3_TX_WAKEUP_THRESH(tnapi) ((tnapi)->tx_pending / 4)
149 167
@@ -4639,12 +4657,7 @@ static int tg3_rx(struct tg3_napi *tnapi, int budget)
4639 len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4657 len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) -
4640 ETH_FCS_LEN; 4658 ETH_FCS_LEN;
4641 4659
4642 if (len > RX_COPY_THRESHOLD && 4660 if (len > TG3_RX_COPY_THRESH(tp)) {
4643 tp->rx_offset == NET_IP_ALIGN) {
4644 /* rx_offset will likely not equal NET_IP_ALIGN
4645 * if this is a 5701 card running in PCI-X mode
4646 * [see tg3_get_invariants()]
4647 */
4648 int skb_size; 4661 int skb_size;
4649 4662
4650 skb_size = tg3_alloc_rx_skb(tp, tpr, opaque_key, 4663 skb_size = tg3_alloc_rx_skb(tp, tpr, opaque_key,
@@ -13469,9 +13482,14 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
13469 tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES; 13482 tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES;
13470 13483
13471 tp->rx_offset = NET_IP_ALIGN; 13484 tp->rx_offset = NET_IP_ALIGN;
13485 tp->rx_copy_thresh = TG3_RX_COPY_THRESHOLD;
13472 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 && 13486 if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701 &&
13473 (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) 13487 (tp->tg3_flags & TG3_FLAG_PCIX_MODE) != 0) {
13474 tp->rx_offset = 0; 13488 tp->rx_offset = 0;
13489#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
13490 tp->rx_copy_thresh = ~0;
13491#endif
13492 }
13475 13493
13476 tp->rx_std_max_post = TG3_RX_RING_SIZE; 13494 tp->rx_std_max_post = TG3_RX_RING_SIZE;
13477 13495