aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2008-01-10 19:14:12 -0500
committerJeff Garzik <jeff@garzik.org>2008-01-12 17:49:10 -0500
commit86c6887e6fea0b395dc939174ac80ad0ae88288c (patch)
treea4159ed0ca36c44ce6738c1302cd038149f5f411 /drivers/net
parentdfd9a421bed2325059fae04f810769b648fa1302 (diff)
sky2: large memory workaround.
This patch might fix problems with 4G or more of memory. It stops the driver from doing a small optimization for Tx and Rx, and instead always sets the high-page on tx/rx descriptors. Fixes-bug: http://bugzilla.kernel.org/show_bug.cgi?id=9725 Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/sky2.c24
-rw-r--r--drivers/net/sky2.h4
2 files changed, 10 insertions, 18 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 52ec89b82f64..bc15940ce1bc 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -944,7 +944,6 @@ static void tx_init(struct sky2_port *sky2)
944 le = get_tx_le(sky2); 944 le = get_tx_le(sky2);
945 le->addr = 0; 945 le->addr = 0;
946 le->opcode = OP_ADDR64 | HW_OWNER; 946 le->opcode = OP_ADDR64 | HW_OWNER;
947 sky2->tx_addr64 = 0;
948} 947}
949 948
950static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2, 949static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2,
@@ -978,13 +977,11 @@ static void sky2_rx_add(struct sky2_port *sky2, u8 op,
978 dma_addr_t map, unsigned len) 977 dma_addr_t map, unsigned len)
979{ 978{
980 struct sky2_rx_le *le; 979 struct sky2_rx_le *le;
981 u32 hi = upper_32_bits(map);
982 980
983 if (sky2->rx_addr64 != hi) { 981 if (sizeof(dma_addr_t) > sizeof(u32)) {
984 le = sky2_next_rx(sky2); 982 le = sky2_next_rx(sky2);
985 le->addr = cpu_to_le32(hi); 983 le->addr = cpu_to_le32(upper_32_bits(map));
986 le->opcode = OP_ADDR64 | HW_OWNER; 984 le->opcode = OP_ADDR64 | HW_OWNER;
987 sky2->rx_addr64 = upper_32_bits(map + len);
988 } 985 }
989 986
990 le = sky2_next_rx(sky2); 987 le = sky2_next_rx(sky2);
@@ -1480,7 +1477,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1480 struct tx_ring_info *re; 1477 struct tx_ring_info *re;
1481 unsigned i, len; 1478 unsigned i, len;
1482 dma_addr_t mapping; 1479 dma_addr_t mapping;
1483 u32 addr64;
1484 u16 mss; 1480 u16 mss;
1485 u8 ctrl; 1481 u8 ctrl;
1486 1482
@@ -1493,15 +1489,12 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1493 1489
1494 len = skb_headlen(skb); 1490 len = skb_headlen(skb);
1495 mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE); 1491 mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
1496 addr64 = upper_32_bits(mapping);
1497 1492
1498 /* Send high bits if changed or crosses boundary */ 1493 /* Send high bits if needed */
1499 if (addr64 != sky2->tx_addr64 || 1494 if (sizeof(dma_addr_t) > sizeof(u32)) {
1500 upper_32_bits(mapping + len) != sky2->tx_addr64) {
1501 le = get_tx_le(sky2); 1495 le = get_tx_le(sky2);
1502 le->addr = cpu_to_le32(addr64); 1496 le->addr = cpu_to_le32(upper_32_bits(mapping));
1503 le->opcode = OP_ADDR64 | HW_OWNER; 1497 le->opcode = OP_ADDR64 | HW_OWNER;
1504 sky2->tx_addr64 = upper_32_bits(mapping + len);
1505 } 1498 }
1506 1499
1507 /* Check for TCP Segmentation Offload */ 1500 /* Check for TCP Segmentation Offload */
@@ -1582,13 +1575,12 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1582 1575
1583 mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset, 1576 mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
1584 frag->size, PCI_DMA_TODEVICE); 1577 frag->size, PCI_DMA_TODEVICE);
1585 addr64 = upper_32_bits(mapping); 1578
1586 if (addr64 != sky2->tx_addr64) { 1579 if (sizeof(dma_addr_t) > sizeof(u32)) {
1587 le = get_tx_le(sky2); 1580 le = get_tx_le(sky2);
1588 le->addr = cpu_to_le32(addr64); 1581 le->addr = cpu_to_le32(upper_32_bits(mapping));
1589 le->ctrl = 0; 1582 le->ctrl = 0;
1590 le->opcode = OP_ADDR64 | HW_OWNER; 1583 le->opcode = OP_ADDR64 | HW_OWNER;
1591 sky2->tx_addr64 = addr64;
1592 } 1584 }
1593 1585
1594 le = get_tx_le(sky2); 1586 le = get_tx_le(sky2);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index bc646a47edd2..ffe9b8a50a1b 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -1991,14 +1991,14 @@ struct sky2_port {
1991 u16 tx_cons; /* next le to check */ 1991 u16 tx_cons; /* next le to check */
1992 u16 tx_prod; /* next le to use */ 1992 u16 tx_prod; /* next le to use */
1993 u16 tx_next; /* debug only */ 1993 u16 tx_next; /* debug only */
1994 u32 tx_addr64; 1994
1995 u16 tx_pending; 1995 u16 tx_pending;
1996 u16 tx_last_mss; 1996 u16 tx_last_mss;
1997 u32 tx_tcpsum; 1997 u32 tx_tcpsum;
1998 1998
1999 struct rx_ring_info *rx_ring ____cacheline_aligned_in_smp; 1999 struct rx_ring_info *rx_ring ____cacheline_aligned_in_smp;
2000 struct sky2_rx_le *rx_le; 2000 struct sky2_rx_le *rx_le;
2001 u32 rx_addr64; 2001
2002 u16 rx_next; /* next re to check */ 2002 u16 rx_next; /* next re to check */
2003 u16 rx_put; /* next le index to use */ 2003 u16 rx_put; /* next le index to use */
2004 u16 rx_pending; 2004 u16 rx_pending;