Latest working kernel version: none Earliest failing kernel version: none Distribution: Debian SID Hardware Environment: GA-965G-DS3 (revision 1.0. BIOS F9), 4 GB RAM Software Environment: not applicable Problem Description: sky2 fails to run on GA-965G-DS3 with 4 Gigabyte of RAM installed on 2.6.23 compiled for AMD64. Network operation is impossible even temporarily. (Reproducible also with kernel.org kernels 2.6.20.1. 2.6.22, 2.6.23.8 and 2.6.24-rc6) Counterchecks performed: sky2 works with these kernels if 1Gig is removed. sky2 also works with 4Gig, for i386 kernels.
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