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; 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; }
static irqreturn_t fnic_isr_msix_wq(int irq, void *data) { struct fnic *fnic = data; unsigned long wq_work_done = 0; wq_work_done = fnic_wq_cmpl_handler(fnic, -1); vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ], wq_work_done, 1 /* unmask intr */, 1 /* reset intr timer */); return IRQ_HANDLED; }
static int fnic_cleanup(struct fnic *fnic) { unsigned int i; int err; vnic_dev_disable(fnic->vdev); for (i = 0; i < fnic->intr_count; i++) vnic_intr_mask(&fnic->intr[i]); for (i = 0; i < fnic->rq_count; i++) { err = vnic_rq_disable(&fnic->rq[i]); if (err) return err; } for (i = 0; i < fnic->raw_wq_count; i++) { err = vnic_wq_disable(&fnic->wq[i]); if (err) return err; } for (i = 0; i < fnic->wq_copy_count; i++) { err = vnic_wq_copy_disable(&fnic->wq_copy[i]); if (err) return err; } /* Clean up completed IOs and FCS frames */ fnic_wq_copy_cmpl_handler(fnic, -1); fnic_wq_cmpl_handler(fnic, -1); fnic_rq_cmpl_handler(fnic, -1); /* Clean up the IOs and FCS frames that have not completed */ for (i = 0; i < fnic->raw_wq_count; i++) vnic_wq_clean(&fnic->wq[i], fnic_free_wq_buf); for (i = 0; i < fnic->rq_count; i++) vnic_rq_clean(&fnic->rq[i], fnic_free_rq_buf); for (i = 0; i < fnic->wq_copy_count; i++) vnic_wq_copy_clean(&fnic->wq_copy[i], fnic_wq_copy_cleanup_handler); for (i = 0; i < fnic->cq_count; i++) vnic_cq_clean(&fnic->cq[i]); for (i = 0; i < fnic->intr_count; i++) vnic_intr_clean(&fnic->intr[i]); mempool_destroy(fnic->io_req_pool); for (i = 0; i < FNIC_SGL_NUM_CACHES; i++) mempool_destroy(fnic->io_sgl_pool[i]); return 0; }
static irqreturn_t fnic_isr_msix_wq(int irq, void *data) { struct fnic *fnic = data; unsigned long wq_work_done = 0; fnic->fnic_stats.misc_stats.last_isr_time = jiffies; atomic64_inc(&fnic->fnic_stats.misc_stats.isr_count); wq_work_done = fnic_wq_cmpl_handler(fnic, -1); vnic_intr_return_credits(&fnic->intr[FNIC_MSIX_WQ], wq_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 int fnic_cleanup(struct fnic *fnic) { unsigned int i; int err; unsigned long flags; struct fc_frame *flogi = NULL; struct fc_frame *flogi_resp = NULL; vnic_dev_disable(fnic->vdev); for (i = 0; i < fnic->intr_count; i++) vnic_intr_mask(&fnic->intr[i]); for (i = 0; i < fnic->rq_count; i++) { err = vnic_rq_disable(&fnic->rq[i]); if (err) return err; } for (i = 0; i < fnic->raw_wq_count; i++) { err = vnic_wq_disable(&fnic->wq[i]); if (err) return err; } for (i = 0; i < fnic->wq_copy_count; i++) { err = vnic_wq_copy_disable(&fnic->wq_copy[i]); if (err) return err; } /* Clean up completed IOs and FCS frames */ fnic_wq_copy_cmpl_handler(fnic, -1); fnic_wq_cmpl_handler(fnic, -1); fnic_rq_cmpl_handler(fnic, -1); /* Clean up the IOs and FCS frames that have not completed */ for (i = 0; i < fnic->raw_wq_count; i++) vnic_wq_clean(&fnic->wq[i], fnic_free_wq_buf); for (i = 0; i < fnic->rq_count; i++) vnic_rq_clean(&fnic->rq[i], fnic_free_rq_buf); for (i = 0; i < fnic->wq_copy_count; i++) vnic_wq_copy_clean(&fnic->wq_copy[i], fnic_wq_copy_cleanup_handler); for (i = 0; i < fnic->cq_count; i++) vnic_cq_clean(&fnic->cq[i]); for (i = 0; i < fnic->intr_count; i++) vnic_intr_clean(&fnic->intr[i]); /* * Remove cached flogi and flogi resp frames if any * These frames are not in any queue, and therefore queue * cleanup does not clean them. So clean them explicitly */ spin_lock_irqsave(&fnic->fnic_lock, flags); flogi = fnic->flogi; fnic->flogi = NULL; flogi_resp = fnic->flogi_resp; fnic->flogi_resp = NULL; spin_unlock_irqrestore(&fnic->fnic_lock, flags); if (flogi) dev_kfree_skb(fp_skb(flogi)); if (flogi_resp) dev_kfree_skb(fp_skb(flogi_resp)); mempool_destroy(fnic->io_req_pool); for (i = 0; i < FNIC_SGL_NUM_CACHES; i++) mempool_destroy(fnic->io_sgl_pool[i]); return 0; }
static int fnic_cleanup(struct fnic *fnic) { unsigned int i; int err; unsigned long flags; struct fc_frame *flogi = NULL; struct fc_frame *flogi_resp = NULL; vnic_dev_disable(fnic->vdev); for (i = 0; i < fnic->intr_count; i++) vnic_intr_mask(&fnic->intr[i]); for (i = 0; i < fnic->rq_count; i++) { err = vnic_rq_disable(&fnic->rq[i]); if (err) return err; } for (i = 0; i < fnic->raw_wq_count; i++) { err = vnic_wq_disable(&fnic->wq[i]); if (err) return err; } for (i = 0; i < fnic->wq_copy_count; i++) { err = vnic_wq_copy_disable(&fnic->wq_copy[i]); if (err) return err; } fnic_wq_copy_cmpl_handler(fnic, -1); fnic_wq_cmpl_handler(fnic, -1); fnic_rq_cmpl_handler(fnic, -1); for (i = 0; i < fnic->raw_wq_count; i++) vnic_wq_clean(&fnic->wq[i], fnic_free_wq_buf); for (i = 0; i < fnic->rq_count; i++) vnic_rq_clean(&fnic->rq[i], fnic_free_rq_buf); for (i = 0; i < fnic->wq_copy_count; i++) vnic_wq_copy_clean(&fnic->wq_copy[i], fnic_wq_copy_cleanup_handler); for (i = 0; i < fnic->cq_count; i++) vnic_cq_clean(&fnic->cq[i]); for (i = 0; i < fnic->intr_count; i++) vnic_intr_clean(&fnic->intr[i]); spin_lock_irqsave(&fnic->fnic_lock, flags); flogi = fnic->flogi; fnic->flogi = NULL; flogi_resp = fnic->flogi_resp; fnic->flogi_resp = NULL; spin_unlock_irqrestore(&fnic->fnic_lock, flags); if (flogi) dev_kfree_skb(fp_skb(flogi)); if (flogi_resp) dev_kfree_skb(fp_skb(flogi_resp)); mempool_destroy(fnic->io_req_pool); for (i = 0; i < FNIC_SGL_NUM_CACHES; i++) mempool_destroy(fnic->io_sgl_pool[i]); return 0; }