Bug 9725
Summary: | sky2 fails to work on Gigabyte GA-965G-DS3 with 4 GB RAM | ||
---|---|---|---|
Product: | Drivers | Reporter: | Volker Schlecht (vschlecht) |
Component: | Network | Assignee: | Stephen Hemminger (stephen) |
Status: | RESOLVED CODE_FIX | ||
Severity: | normal | CC: | stephen, vschlecht |
Priority: | P1 | ||
Hardware: | All | ||
OS: | Linux | ||
Kernel Version: | 2.6.23.13 | Subsystem: | |
Regression: | --- | Bisected commit-id: |
Description
Volker Schlecht
2008-01-10 14:31:57 UTC
The attached patch by Stephen Hemminger fixes the problem. The driver has performed flawlessly for days now. -- Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> --- Patch against 2.6.23.13 --- a/drivers/net/sky2.c 2008-01-06 11:22:12.000000000 -0800 +++ b/drivers/net/sky2.c 2008-01-06 11:23:54.000000000 -0800 @@ -922,7 +922,6 @@ static void tx_init(struct sky2_port *sk le = get_tx_le(sky2); le->addr = 0; le->opcode = OP_ADDR64 | HW_OWNER; - sky2->tx_addr64 = 0; } static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2, @@ -956,13 +955,11 @@ static void sky2_rx_add(struct sky2_port dma_addr_t map, unsigned len) { struct sky2_rx_le *le; - u32 hi = upper_32_bits(map); - if (sky2->rx_addr64 != hi) { + if (sizeof(dma_addr_t) > sizeof(u32)) { le = sky2_next_rx(sky2); - le->addr = cpu_to_le32(hi); + le->addr = cpu_to_le32(upper_32_bits(map)); le->opcode = OP_ADDR64 | HW_OWNER; - sky2->rx_addr64 = upper_32_bits(map + len); } le = sky2_next_rx(sky2); @@ -1460,7 +1457,6 @@ static int sky2_xmit_frame(struct sk_buf struct tx_ring_info *re; unsigned i, len; dma_addr_t mapping; - u32 addr64; u16 mss; u8 ctrl; @@ -1473,15 +1469,12 @@ static int sky2_xmit_frame(struct sk_buf len = skb_headlen(skb); mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE); - addr64 = upper_32_bits(mapping); - /* Send high bits if changed or crosses boundary */ - if (addr64 != sky2->tx_addr64 || - upper_32_bits(mapping + len) != sky2->tx_addr64) { + /* Send high bits if needed */ + if (sizeof(dma_addr_t) > sizeof(u32)) { le = get_tx_le(sky2); - le->addr = cpu_to_le32(addr64); + le->addr = cpu_to_le32(upper_32_bits(mapping)); le->opcode = OP_ADDR64 | HW_OWNER; - sky2->tx_addr64 = upper_32_bits(mapping + len); } /* Check for TCP Segmentation Offload */ @@ -1562,13 +1555,12 @@ static int sky2_xmit_frame(struct sk_buf mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset, frag->size, PCI_DMA_TODEVICE); - addr64 = upper_32_bits(mapping); - if (addr64 != sky2->tx_addr64) { + + if (sizeof(dma_addr_t) > sizeof(u32)) { le = get_tx_le(sky2); - le->addr = cpu_to_le32(addr64); + le->addr = cpu_to_le32(upper_32_bits(mapping)); le->ctrl = 0; le->opcode = OP_ADDR64 | HW_OWNER; - sky2->tx_addr64 = addr64; } le = get_tx_le(sky2); --- a/drivers/net/sky2.h 2008-01-06 11:22:12.000000000 -0800 +++ b/drivers/net/sky2.h 2008-01-06 11:22:18.000000000 -0800 @@ -2009,14 +2009,14 @@ struct sky2_port { u16 tx_cons; /* next le to check */ u16 tx_prod; /* next le to use */ u16 tx_next; /* debug only */ - u32 tx_addr64; + u16 tx_pending; u16 tx_last_mss; u32 tx_tcpsum; struct rx_ring_info *rx_ring ____cacheline_aligned_in_smp; struct sky2_rx_le *rx_le; - u32 rx_addr64; + u16 rx_next; /* next re to check */ u16 rx_put; /* next le index to use */ u16 rx_pending; Fix is in 2.6.24-rc8 |