static void bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, struct bfa_pcidev_s *pcidev) { struct bfa_iocfc_s *iocfc = &bfa->iocfc; bfa->bfad = bfad; iocfc->bfa = bfa; iocfc->action = BFA_IOCFC_ACT_NONE; bfa_os_assign(iocfc->cfg, *cfg); if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT) { iocfc->hwif.hw_reginit = bfa_hwct_reginit; iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack; iocfc->hwif.hw_msix_init = bfa_hwct_msix_init; iocfc->hwif.hw_msix_install = bfa_hwct_msix_install; iocfc->hwif.hw_msix_uninstall = bfa_hwct_msix_uninstall; iocfc->hwif.hw_isr_mode_set = bfa_hwct_isr_mode_set; iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs; } else { iocfc->hwif.hw_reginit = bfa_hwcb_reginit; iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack; iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init; iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install; iocfc->hwif.hw_msix_uninstall = bfa_hwcb_msix_uninstall; iocfc->hwif.hw_isr_mode_set = bfa_hwcb_isr_mode_set; iocfc->hwif.hw_msix_getvecs = bfa_hwcb_msix_getvecs; } iocfc->hwif.hw_reginit(bfa); bfa->msix.nvecs = 0; }
u16 fc_rnid_acc_build(struct fchs_s *fchs, struct fc_rnid_acc_s *rnid_acc, u32 d_id, u32 s_id, u16 ox_id, u32 data_format, struct fc_rnid_common_id_data_s *common_id_data, struct fc_rnid_general_topology_data_s *gen_topo_data) { memset(rnid_acc, 0, sizeof(struct fc_rnid_acc_s)); fc_els_rsp_build(fchs, d_id, s_id, ox_id); rnid_acc->els_cmd.els_code = FC_ELS_ACC; rnid_acc->node_id_data_format = data_format; rnid_acc->common_id_data_length = sizeof(struct fc_rnid_common_id_data_s); rnid_acc->common_id_data = *common_id_data; if (data_format == RNID_NODEID_DATA_FORMAT_DISCOVERY) { rnid_acc->specific_id_data_length = sizeof(struct fc_rnid_general_topology_data_s); bfa_os_assign(rnid_acc->gen_topology_data, *gen_topo_data); return sizeof(struct fc_rnid_acc_s); } else { return sizeof(struct fc_rnid_acc_s) - sizeof(struct fc_rnid_general_topology_data_s); } }
static void bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport) { struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event; fcport->speed = pevent->link_state.speed; fcport->topology = pevent->link_state.topology; if (fcport->topology == BFA_PPORT_TOPOLOGY_LOOP) fcport->myalpa = pevent->link_state.tl.loop_info.myalpa; /* QoS Details */ bfa_os_assign(fcport->qos_attr, pevent->link_state.qos_attr); bfa_os_assign(fcport->qos_vc_attr, pevent->link_state.qos_vc_attr); bfa_trc(fcport->bfa, fcport->speed); bfa_trc(fcport->bfa, fcport->topology); }
static void bfa_iocfc_init_mem(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg, struct bfa_pcidev_s *pcidev) { struct bfa_iocfc_s *iocfc = &bfa->iocfc; bfa->bfad = bfad; iocfc->bfa = bfa; iocfc->action = BFA_IOCFC_ACT_NONE; bfa_os_assign(iocfc->cfg, *cfg); /** * Initialize chip specific handlers. */ if (bfa_asic_id_ct(bfa_ioc_devid(&bfa->ioc))) { iocfc->hwif.hw_reginit = bfa_hwct_reginit; iocfc->hwif.hw_reqq_ack = bfa_hwct_reqq_ack; iocfc->hwif.hw_rspq_ack = bfa_hwct_rspq_ack; iocfc->hwif.hw_msix_init = bfa_hwct_msix_init; iocfc->hwif.hw_msix_install = bfa_hwct_msix_install; iocfc->hwif.hw_msix_uninstall = bfa_hwct_msix_uninstall; iocfc->hwif.hw_isr_mode_set = bfa_hwct_isr_mode_set; iocfc->hwif.hw_msix_getvecs = bfa_hwct_msix_getvecs; iocfc->hwif.hw_msix_get_rme_range = bfa_hwct_msix_get_rme_range; } else { iocfc->hwif.hw_reginit = bfa_hwcb_reginit; iocfc->hwif.hw_reqq_ack = bfa_hwcb_reqq_ack; iocfc->hwif.hw_rspq_ack = bfa_hwcb_rspq_ack; iocfc->hwif.hw_msix_init = bfa_hwcb_msix_init; iocfc->hwif.hw_msix_install = bfa_hwcb_msix_install; iocfc->hwif.hw_msix_uninstall = bfa_hwcb_msix_uninstall; iocfc->hwif.hw_isr_mode_set = bfa_hwcb_isr_mode_set; iocfc->hwif.hw_msix_getvecs = bfa_hwcb_msix_getvecs; iocfc->hwif.hw_msix_get_rme_range = bfa_hwcb_msix_get_rme_range; } iocfc->hwif.hw_reginit(bfa); bfa->msix.nvecs = 0; }
/** * Send I/O request to firmware. */ static bfa_boolean_t bfa_ioim_send_ioreq(struct bfa_ioim_s *ioim) { struct bfa_itnim_s *itnim = ioim->itnim; struct bfi_ioim_req_s *m; static struct fcp_cmnd_s cmnd_z0 = { 0 }; struct bfi_sge_s *sge; u32 pgdlen = 0; u64 addr; struct scatterlist *sg; struct scsi_cmnd *cmnd = (struct scsi_cmnd *) ioim->dio; /** * check for room in queue to send request now */ m = bfa_reqq_next(ioim->bfa, ioim->reqq); if (!m) { bfa_reqq_wait(ioim->bfa, ioim->reqq, &ioim->iosp->reqq_wait); return BFA_FALSE; } /** * build i/o request message next */ m->io_tag = bfa_os_htons(ioim->iotag); m->rport_hdl = ioim->itnim->rport->fw_handle; m->io_timeout = bfa_cb_ioim_get_timeout(ioim->dio); /** * build inline IO SG element here */ sge = &m->sges[0]; if (ioim->nsges) { sg = (struct scatterlist *)scsi_sglist(cmnd); addr = bfa_os_sgaddr(sg_dma_address(sg)); sge->sga = *(union bfi_addr_u *) &addr; pgdlen = sg_dma_len(sg); sge->sg_len = pgdlen; sge->flags = (ioim->nsges > BFI_SGE_INLINE) ? BFI_SGE_DATA_CPL : BFI_SGE_DATA_LAST; bfa_sge_to_be(sge); sge++; } if (ioim->nsges > BFI_SGE_INLINE) { sge->sga = ioim->sgpg->sgpg_pa; } else { sge->sga.a32.addr_lo = 0; sge->sga.a32.addr_hi = 0; } sge->sg_len = pgdlen; sge->flags = BFI_SGE_PGDLEN; bfa_sge_to_be(sge); /** * set up I/O command parameters */ bfa_os_assign(m->cmnd, cmnd_z0); m->cmnd.lun = bfa_cb_ioim_get_lun(ioim->dio); m->cmnd.iodir = bfa_cb_ioim_get_iodir(ioim->dio); bfa_os_assign(m->cmnd.cdb, *(struct scsi_cdb_s *)bfa_cb_ioim_get_cdb(ioim->dio)); m->cmnd.fcp_dl = bfa_os_htonl(bfa_cb_ioim_get_size(ioim->dio)); /** * set up I/O message header */ switch (m->cmnd.iodir) { case FCP_IODIR_READ: bfi_h2i_set(m->mh, BFI_MC_IOIM_READ, 0, bfa_lpuid(ioim->bfa)); bfa_stats(itnim, input_reqs); break; case FCP_IODIR_WRITE: bfi_h2i_set(m->mh, BFI_MC_IOIM_WRITE, 0, bfa_lpuid(ioim->bfa)); bfa_stats(itnim, output_reqs); break; case FCP_IODIR_RW: bfa_stats(itnim, input_reqs); bfa_stats(itnim, output_reqs); default: bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_lpuid(ioim->bfa)); } if (itnim->seq_rec || (bfa_cb_ioim_get_size(ioim->dio) & (sizeof(u32) - 1))) bfi_h2i_set(m->mh, BFI_MC_IOIM_IO, 0, bfa_lpuid(ioim->bfa)); #ifdef IOIM_ADVANCED m->cmnd.crn = bfa_cb_ioim_get_crn(ioim->dio); m->cmnd.priority = bfa_cb_ioim_get_priority(ioim->dio); m->cmnd.taskattr = bfa_cb_ioim_get_taskattr(ioim->dio); /** * Handle large CDB (>16 bytes). */ m->cmnd.addl_cdb_len = (bfa_cb_ioim_get_cdblen(ioim->dio) - FCP_CMND_CDB_LEN) / sizeof(u32); if (m->cmnd.addl_cdb_len) { bfa_os_memcpy(&m->cmnd.cdb + 1, (struct scsi_cdb_s *) bfa_cb_ioim_get_cdb(ioim->dio) + 1, m->cmnd.addl_cdb_len * sizeof(u32)); fcp_cmnd_fcpdl(&m->cmnd) = bfa_os_htonl(bfa_cb_ioim_get_size(ioim->dio)); } #endif /** * queue I/O message to firmware */ bfa_reqq_produce(ioim->bfa, ioim->reqq); return BFA_TRUE; }
void bfa_ioim_isr(struct bfa_s *bfa, struct bfi_msg_s *m) { struct bfa_fcpim_mod_s *fcpim = BFA_FCPIM_MOD(bfa); struct bfi_ioim_rsp_s *rsp = (struct bfi_ioim_rsp_s *) m; struct bfa_ioim_s *ioim; u16 iotag; enum bfa_ioim_event evt = BFA_IOIM_SM_COMP; iotag = bfa_os_ntohs(rsp->io_tag); ioim = BFA_IOIM_FROM_TAG(fcpim, iotag); bfa_assert(ioim->iotag == iotag); bfa_trc(ioim->bfa, ioim->iotag); bfa_trc(ioim->bfa, rsp->io_status); bfa_trc(ioim->bfa, rsp->reuse_io_tag); if (bfa_sm_cmp_state(ioim, bfa_ioim_sm_active)) bfa_os_assign(ioim->iosp->comp_rspmsg, *m); switch (rsp->io_status) { case BFI_IOIM_STS_OK: bfa_fcpim_stats(fcpim, iocomp_ok); if (rsp->reuse_io_tag == 0) evt = BFA_IOIM_SM_DONE; else evt = BFA_IOIM_SM_COMP; break; case BFI_IOIM_STS_TIMEDOUT: case BFI_IOIM_STS_ABORTED: rsp->io_status = BFI_IOIM_STS_ABORTED; bfa_fcpim_stats(fcpim, iocomp_aborted); if (rsp->reuse_io_tag == 0) evt = BFA_IOIM_SM_DONE; else evt = BFA_IOIM_SM_COMP; break; case BFI_IOIM_STS_PROTO_ERR: bfa_fcpim_stats(fcpim, iocom_proto_err); bfa_assert(rsp->reuse_io_tag); evt = BFA_IOIM_SM_COMP; break; case BFI_IOIM_STS_SQER_NEEDED: bfa_fcpim_stats(fcpim, iocom_sqer_needed); bfa_assert(rsp->reuse_io_tag == 0); evt = BFA_IOIM_SM_SQRETRY; break; case BFI_IOIM_STS_RES_FREE: bfa_fcpim_stats(fcpim, iocom_res_free); evt = BFA_IOIM_SM_FREE; break; case BFI_IOIM_STS_HOST_ABORTED: bfa_fcpim_stats(fcpim, iocom_hostabrts); if (rsp->abort_tag != ioim->abort_tag) { bfa_trc(ioim->bfa, rsp->abort_tag); bfa_trc(ioim->bfa, ioim->abort_tag); return; } if (rsp->reuse_io_tag) evt = BFA_IOIM_SM_ABORT_COMP; else evt = BFA_IOIM_SM_ABORT_DONE; break; case BFI_IOIM_STS_UTAG: bfa_fcpim_stats(fcpim, iocom_utags); evt = BFA_IOIM_SM_COMP_UTAG; break; default: bfa_assert(0); } bfa_sm_send_event(ioim, evt); }