diff options
author | Guo-Fu Tseng | 2010-06-04 16:23:15 +0200 |
---|---|---|
committer | Michael Brown | 2010-06-13 19:10:39 +0200 |
commit | 1798e04ebbb4f86ef1b1ba1432f835482b1543b2 (patch) | |
tree | f709e15fe56678784b34bcc6b6298d0f05ccc47b /src/drivers/net/jme.c | |
parent | [ethernet] Move Ethernet MAC address checking routines to ethernet.h (diff) | |
download | ipxe-1798e04ebbb4f86ef1b1ba1432f835482b1543b2.tar.gz ipxe-1798e04ebbb4f86ef1b1ba1432f835482b1543b2.tar.xz ipxe-1798e04ebbb4f86ef1b1ba1432f835482b1543b2.zip |
[jme] Fix refill behavior
After changing the driver to refill after feed, if any error occurs a
non-contiguous empty buffer will be introduced in the ring due to my
reuse-buffer-when-error implementation.
Reported-by: Marty Connor <mdc@etherboot.org>
Signed-off-by: Guo-Fu Tseng <cooldavid@cooldavid.org>
Signed-off-by: Stefan Hajnoczi <stefanha@gmail.com>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/net/jme.c')
-rw-r--r-- | src/drivers/net/jme.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/src/drivers/net/jme.c b/src/drivers/net/jme.c index 31208c2f..fae95914 100644 --- a/src/drivers/net/jme.c +++ b/src/drivers/net/jme.c @@ -590,17 +590,22 @@ jme_disable_rx_engine(struct jme_adapter *jme) } static void -jme_refill_rx_ring(struct jme_adapter *jme) +jme_refill_rx_ring(struct jme_adapter *jme, int curhole) { struct jme_ring *rxring = &jme->rxring; int i = rxring->next_to_fill; struct io_buffer **bufinf = rxring->bufinf; int mask = jme->rx_ring_mask; + int limit = jme->rx_ring_size; - while (!bufinf[i]) { - if (jme_make_new_rx_buf(bufinf + i)) - break; - jme_set_clean_rxdesc(jme, i); + while (limit--) { + if (!bufinf[i]) { + if (jme_make_new_rx_buf(bufinf + i)) + break; + jme_set_clean_rxdesc(jme, i); + } + if (i == curhole) + limit = 0; i = (i + 1) & mask; } rxring->next_to_fill = i; @@ -622,7 +627,7 @@ jme_alloc_and_feed_iob(struct jme_adapter *jme, int idx) netdev_rx(netdev, rxbi); rxring->bufinf[idx] = NULL; - jme_refill_rx_ring(jme); + jme_refill_rx_ring(jme, idx); } static void @@ -636,7 +641,8 @@ jme_process_receive(struct jme_adapter *jme) i = rxring->next_to_clean; rxdesc += i; - while (!(rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_OWN)) && + while (rxring->bufinf[i] && + !(rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_OWN)) && (rxdesc->descwb.desccnt & RXWBDCNT_WBCPL) && limit--) { |