The RTL8110SB in the Thecus n2100 clears the lower half of TxDescStartAddr when the upper half of that register is written to with a zero, so we need to write to the lower and upper halves the other way round. (Note that only PCI MEM transactions seem to have this problem, writing to the same registers in IO space doesn't give the same problem.) Also disable error interrupts, as the 8110SB consistently gets a PCI parity error interrupt shortly after bringing the interface up, and the error recovery logic that subsequently runs causes the chip to stop working at all. Index: linux-2.6.18-rc4/drivers/net/r8169.c =================================================================== --- linux-2.6.18-rc4.orig/drivers/net/r8169.c +++ linux-2.6.18-rc4/drivers/net/r8169.c @@ -484,7 +484,7 @@ static int rtl8169_poll(struct net_devic #endif static const u16 rtl8169_intr_mask = - SYSErr | LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK; + LinkChg | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK; static const u16 rtl8169_napi_event = RxOK | RxOverflow | RxFIFOOver | TxOK | TxErr; static const unsigned int rtl8169_rx_config = @@ -1825,8 +1825,8 @@ rtl8169_hw_start(struct net_device *dev) */ RTL_W16(IntrMitigate, 0x0000); - RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_32BIT_MASK)); RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32)); + RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr & DMA_32BIT_MASK)); RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK)); RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32)); RTL_W8(Cfg9346, Cfg9346_Lock); @@ -2527,10 +2527,12 @@ rtl8169_interrupt(int irq, void *dev_ins if (!(status & rtl8169_intr_mask)) break; +#if 0 if (unlikely(status & SYSErr)) { rtl8169_pcierr_interrupt(dev); break; } +#endif if (status & LinkChg) rtl8169_check_link_status(dev, tp, ioaddr);