REG_RD(bp, BNX2_HC_COMMAND);
}
- if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)
+ if (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)
bnx2_tx_int(bp);
- if (bp->status_blk->status_rx_quick_consumer_index0 != bp->hw_rx_cons)
+ if (sblk->status_rx_quick_consumer_index0 != bp->hw_rx_cons)
work_done += bnx2_rx_int(bp, budget - work_done);
return work_done;
{
struct bnx2 *bp = container_of(napi, struct bnx2, napi);
int work_done = 0;
+ struct status_block *sblk = bp->status_blk;
while (1) {
work_done = bnx2_poll_work(bp, work_done, budget);
if (unlikely(work_done >= budget))
break;
+ /* bp->last_status_idx is used below to tell the hw how
+ * much work has been processed, so we must read it before
+ * checking for more work.
+ */
+ bp->last_status_idx = sblk->status_idx;
+ rmb();
if (likely(!bnx2_has_work(bp))) {
- bp->last_status_idx = bp->status_blk->status_idx;
- rmb();
-
netif_rx_complete(bp->dev, napi);
if (likely(bp->flags & USING_MSI_FLAG)) {
REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
bp->last_status_idx);
- return 0;
+ break;
}
REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |