return 0;
}
-static void qeth_queue_input_buffer(struct qeth_card *card, int index)
+static unsigned int qeth_rx_refill_queue(struct qeth_card *card,
+ unsigned int count)
{
struct qeth_qdio_q *queue = card->qdio.in_q;
struct list_head *lh;
- int count;
int i;
int rc;
int newcount = 0;
- count = (index < queue->next_buf_to_init)?
- card->qdio.in_buf_pool.buf_count -
- (queue->next_buf_to_init - index) :
- card->qdio.in_buf_pool.buf_count -
- (queue->next_buf_to_init + QDIO_MAX_BUFFERS_PER_Q - index);
/* only requeue at a certain threshold to avoid SIGAs */
if (count >= QETH_IN_BUF_REQUEUE_THRESHOLD(card)) {
for (i = queue->next_buf_to_init;
i++;
if (i == card->qdio.in_buf_pool.buf_count) {
QETH_CARD_TEXT(card, 2, "qsarbw");
- card->reclaim_index = index;
schedule_delayed_work(
&card->buffer_reclaim_work,
QETH_RECLAIM_WORK_TIME);
}
- return;
+ return 0;
}
/*
}
queue->next_buf_to_init = QDIO_BUFNR(queue->next_buf_to_init +
count);
+ return count;
}
+
+ return 0;
}
static void qeth_buffer_reclaim_work(struct work_struct *work)
struct qeth_card *card = container_of(work, struct qeth_card,
buffer_reclaim_work.work);
- QETH_CARD_TEXT_(card, 2, "brw:%x", card->reclaim_index);
- qeth_queue_input_buffer(card, card->reclaim_index);
+ local_bh_disable();
+ napi_schedule(&card->napi);
+ /* kick-start the NAPI softirq: */
+ local_bh_enable();
}
static void qeth_handle_send_error(struct qeth_card *card,
static unsigned int qeth_rx_poll(struct qeth_card *card, int budget)
{
+ struct qeth_rx *ctx = &card->rx;
unsigned int work_done = 0;
while (budget > 0) {
QETH_CARD_STAT_INC(card, rx_bufs);
qeth_put_buffer_pool_entry(card, buffer->pool_entry);
buffer->pool_entry = NULL;
- qeth_queue_input_buffer(card, card->rx.b_index);
card->rx.b_count--;
+ ctx->bufs_refill++;
+ ctx->bufs_refill -= qeth_rx_refill_queue(card,
+ ctx->bufs_refill);
/* Step forward to next buffer: */
card->rx.b_index = QDIO_BUFNR(card->rx.b_index + 1);
if (card->options.cq == QETH_CQ_ENABLED)
qeth_cq_poll(card);
- /* Exhausted the RX budget. Keep IRQ disabled, we get called again. */
- if (budget && work_done >= budget)
- return work_done;
+ if (budget) {
+ struct qeth_rx *ctx = &card->rx;
+
+ /* Process any substantial refill backlog: */
+ ctx->bufs_refill -= qeth_rx_refill_queue(card, ctx->bufs_refill);
+
+ /* Exhausted the RX budget. Keep IRQ disabled, we get called again. */
+ if (work_done >= budget)
+ return work_done;
+ }
if (napi_complete_done(napi, work_done) &&
qdio_start_irq(CARD_DDEV(card)))
}
napi_disable(&card->napi);
+ cancel_delayed_work_sync(&card->buffer_reclaim_work);
qdio_stop_irq(CARD_DDEV(card));
return 0;