diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 3cd345ba44209df6dd873a3eeec97ef9fce0e8c8..6e3600b51ee4fcafd2c9d81e7657bbb94662b7fb 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -1018,8 +1018,8 @@ static inline void velocity_give_many_rx_descs(struct velocity_info *vptr) wmb(); - unusable = vptr->rd_filled | 0x0003; - dirty = vptr->rd_dirty - unusable + 1; + unusable = vptr->rd_filled & 0x0003; + dirty = vptr->rd_dirty - unusable; for (avail = vptr->rd_filled & 0xfffc; avail; avail--) { dirty = (dirty > 0) ? dirty - 1 : vptr->options.numrx - 1; vptr->rd_ring[dirty].rdesc0.owner = OWNED_BY_NIC; @@ -1232,15 +1232,17 @@ static int velocity_rx_srv(struct velocity_info *vptr, int status) int rd_curr = vptr->rd_curr; int works = 0; - while (1) { + do { struct rx_desc *rd = vptr->rd_ring + rd_curr; - if (!vptr->rd_info[rd_curr].skb || (works++ > 15)) + if (!vptr->rd_info[rd_curr].skb) break; if (rd->rdesc0.owner == OWNED_BY_NIC) break; + rmb(); + /* * Don't drop CE or RL error frame although RXOK is off */ @@ -1263,14 +1265,15 @@ static int velocity_rx_srv(struct velocity_info *vptr, int status) rd_curr++; if (rd_curr >= vptr->options.numrx) rd_curr = 0; - } + } while (++works <= 15); - if (velocity_rx_refill(vptr) < 0) { + vptr->rd_curr = rd_curr; + + if (works > 0 && velocity_rx_refill(vptr) < 0) { VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR "%s: rx buf allocation failure\n", vptr->dev->name); } - vptr->rd_curr = rd_curr; VAR_USED(stats); return works; }