static int enic_poll(struct napi_struct *napi, int budget) { struct enic *enic = container_of(napi, struct enic, napi); struct net_device *netdev = enic->netdev; unsigned int rq_work_to_do = budget; unsigned int wq_work_to_do = -1; /* no limit */ unsigned int work_done, rq_work_done, wq_work_done; /* Service RQ (first) and WQ */ rq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_RQ], rq_work_to_do, enic_rq_service, NULL); wq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_WQ], wq_work_to_do, enic_wq_service, NULL); /* Accumulate intr event credits for this polling * cycle. An intr event is the completion of a * a WQ or RQ packet. */ work_done = rq_work_done + wq_work_done; if (work_done > 0) vnic_intr_return_credits(&enic->intr[ENIC_INTX_WQ_RQ], work_done, 0 /* don't unmask intr */, 0 /* don't reset intr timer */); if (rq_work_done > 0) { /* Replenish RQ */ vnic_rq_fill(&enic->rq[0], enic_rq_alloc_buf); } else { /* If no work done, flush all LROs and exit polling */ if (netdev->features & NETIF_F_LRO) lro_flush_all(&enic->lro_mgr); netif_rx_complete(napi); vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]); } return rq_work_done; }
static irqreturn_t fnic_isr_msix_wq_copy(int irq, void *data) { struct fnic *fnic = data; unsigned long wq_copy_work_done = 0; fnic->fnic_stats.misc_stats.last_isr_time = jiffies; atomic64_inc(&fnic->fnic_stats.misc_stats.isr_count); wq_copy_work_done = fnic_wq_copy_cmpl_handler(fnic, -1); vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ_COPY], wq_copy_work_done, 1 /* unmask intr */, 1 /* reset intr timer */); return IRQ_HANDLED; }
static irqreturn_t fnic_isr_msi(int irq, void *data) { struct fnic *fnic = data; unsigned long work_done = 0; work_done += fnic_wq_copy_cmpl_handler(fnic, -1); work_done += fnic_wq_cmpl_handler(fnic, -1); work_done += fnic_rq_cmpl_handler(fnic, -1); vnic_intr_return_credits(&fnic->intr[0], work_done, 1 /* unmask intr */, 1 /* reset intr timer */); return IRQ_HANDLED; }
static irqreturn_t enic_isr_msix_wq(int irq, void *data) { struct enic *enic = data; unsigned int wq_work_to_do = -1; unsigned int wq_work_done; wq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_WQ], wq_work_to_do, enic_wq_service, NULL); vnic_intr_return_credits(&enic->intr[ENIC_MSIX_WQ], wq_work_done, 1 , 1 ); return IRQ_HANDLED; }
static irqreturn_t enic_isr_msix_wq(int irq, void *data) { struct enic *enic = data; unsigned int wq_work_to_do = -1; /* no limit */ unsigned int wq_work_done; wq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_WQ], wq_work_to_do, enic_wq_service, NULL); vnic_intr_return_credits(&enic->intr[ENIC_MSIX_WQ], wq_work_done, 1 /* unmask intr */, 1 /* reset intr timer */); return IRQ_HANDLED; }
static int enic_poll(struct napi_struct *napi, int budget) { struct enic *enic = container_of(napi, struct enic, napi); struct net_device *netdev = enic->netdev; unsigned int rq_work_to_do = budget; unsigned int wq_work_to_do = -1; unsigned int work_done, rq_work_done, wq_work_done; rq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_RQ], rq_work_to_do, enic_rq_service, NULL); wq_work_done = vnic_cq_service(&enic->cq[ENIC_CQ_WQ], wq_work_to_do, enic_wq_service, NULL); work_done = rq_work_done + wq_work_done; if (work_done > 0) vnic_intr_return_credits(&enic->intr[ENIC_INTX_WQ_RQ], work_done, 0 , 0 ); if (rq_work_done > 0) { vnic_rq_fill(&enic->rq[0], enic->rq_alloc_buf); } else { if (netdev->features & NETIF_F_LRO) lro_flush_all(&enic->lro_mgr); napi_complete(napi); vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]); } return rq_work_done; }
static irqreturn_t fnic_isr_legacy(int irq, void *data) { struct fnic *fnic = data; u32 pba; unsigned long work_done = 0; pba = vnic_intr_legacy_pba(fnic->legacy_pba); if (!pba) return IRQ_NONE; fnic->fnic_stats.misc_stats.last_isr_time = jiffies; atomic64_inc(&fnic->fnic_stats.misc_stats.isr_count); if (pba & (1 << FNIC_INTX_NOTIFY)) { vnic_intr_return_all_credits(&fnic->intr[FNIC_INTX_NOTIFY]); fnic_handle_link_event(fnic); } if (pba & (1 << FNIC_INTX_ERR)) { vnic_intr_return_all_credits(&fnic->intr[FNIC_INTX_ERR]); fnic_log_q_error(fnic); } if (pba & (1 << FNIC_INTX_WQ_RQ_COPYWQ)) { work_done += fnic_wq_copy_cmpl_handler(fnic, -1); work_done += fnic_wq_cmpl_handler(fnic, -1); work_done += fnic_rq_cmpl_handler(fnic, -1); vnic_intr_return_credits(&fnic->intr[FNIC_INTX_WQ_RQ_COPYWQ], work_done, 1 /* unmask intr */, 1 /* reset intr timer */); } return IRQ_HANDLED; }