summaryrefslogtreecommitdiffstats
path: root/src/drivers/net/jme.c
diff options
context:
space:
mode:
authorGuo-Fu Tseng2010-06-04 16:23:15 +0200
committerMichael Brown2010-06-13 19:10:39 +0200
commit1798e04ebbb4f86ef1b1ba1432f835482b1543b2 (patch)
treef709e15fe56678784b34bcc6b6298d0f05ccc47b /src/drivers/net/jme.c
parent[ethernet] Move Ethernet MAC address checking routines to ethernet.h (diff)
downloadipxe-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.c20
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--) {