Brown paper bag time: the Rx descriptors are contiguous and EORbit only marks the last descriptor in the array. OWNbit implicitly marks the end of the Rx descriptors segment which is owned by the nic. drivers/net/r8169.c | 20 ++++++-------------- 1 files changed, 6 insertions(+), 14 deletions(-) diff -puN drivers/net/r8169.c~r8169-dma-api-rx-buffers-ahum drivers/net/r8169.c --- linux-2.6.0-test11/drivers/net/r8169.c~r8169-dma-api-rx-buffers-ahum 2003-12-02 00:22:41.000000000 +0100 +++ linux-2.6.0-test11-fr/drivers/net/r8169.c 2003-12-02 00:22:41.000000000 +0100 @@ -283,6 +283,8 @@ enum _DescStatusBit { LSbit = 0x10000000, }; +#define RsvdMask 0x3fffc000 + struct TxDesc { u32 status; u32 vlan_tag; @@ -1121,7 +1123,7 @@ rtl8169_hw_start(struct net_device *dev) static inline void rtl8169_make_unusable_by_asic(struct RxDesc *desc) { desc->buf_addr = 0xdeadbeef; - desc->status = EORbit; + desc->status &= ~(OWNbit | RsvdMask); } static void rtl8169_free_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, @@ -1141,7 +1143,7 @@ static inline void rtl8169_return_to_asi static inline void rtl8169_give_to_asic(struct RxDesc *desc, dma_addr_t mapping) { desc->buf_addr = mapping; - desc->status = OWNbit + RX_BUF_SIZE; + desc->status |= OWNbit + RX_BUF_SIZE; } static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct net_device *dev, @@ -1209,11 +1211,6 @@ static inline void rtl8169_mark_as_last_ desc->status |= EORbit; } -static inline void rtl8169_unmark_as_last_descriptor(struct RxDesc *desc) -{ - desc->status &= ~EORbit; -} - static int rtl8169_init_ring(struct net_device *dev) { struct rtl8169_private *tp = dev->priv; @@ -1460,14 +1457,9 @@ rtl8169_rx_interrupt(struct net_device * } delta = rtl8169_rx_fill(tp, dev, tp->dirty_rx, tp->cur_rx); - if (delta > 0) { - u32 old_last = (tp->dirty_rx - 1) % NUM_RX_DESC; - + if (delta > 0) tp->dirty_rx += delta; - rtl8169_mark_as_last_descriptor(tp->RxDescArray + - (tp->dirty_rx - 1)%NUM_RX_DESC); - rtl8169_unmark_as_last_descriptor(tp->RxDescArray + old_last); - } else if (delta < 0) + else if (delta < 0) printk(KERN_INFO "%s: no Rx buffer allocated\n", dev->name); /* _