void bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr) { struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s)); attr->nwwn = fcport->nwwn; attr->pwwn = fcport->pwwn; bfa_os_memcpy(&attr->pport_cfg, &fcport->cfg, sizeof(struct bfa_pport_cfg_s)); /* speed attributes */ attr->pport_cfg.speed = fcport->cfg.speed; attr->speed_supported = fcport->speed_sup; attr->speed = fcport->speed; attr->cos_supported = FC_CLASS_3; /* topology attributes */ attr->pport_cfg.topology = fcport->cfg.topology; attr->topology = fcport->topology; /* beacon attributes */ attr->beacon = fcport->beacon; attr->link_e2e_beacon = fcport->link_e2e_beacon; attr->plog_enabled = bfa_plog_get_setting(fcport->bfa->plog); attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa); attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa); attr->port_state = bfa_sm_to_state(hal_pport_sm_table, fcport->sm); if (bfa_ioc_is_disabled(&fcport->bfa->ioc)) attr->port_state = BFA_PPORT_ST_IOCDIS; else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc)) attr->port_state = BFA_PPORT_ST_FWMISMATCH; }
void bfa_fcs_port_get_stats(struct bfa_fcs_port_s *fcs_port, struct bfa_port_stats_s *port_stats) { bfa_os_memcpy(port_stats, &fcs_port->stats, sizeof(struct bfa_port_stats_s)); return; }
static void fc_bls_rsp_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id) { bfa_os_memcpy(fchs, &fc_bls_rsp_tmpl, sizeof(struct fchs_s)); fchs->d_id = d_id; fchs->s_id = s_id; fchs->ox_id = ox_id; }
void fc_els_req_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id) { bfa_os_memcpy(fchs, &fc_els_req_tmpl, sizeof(struct fchs_s)); fchs->d_id = (d_id); fchs->s_id = (s_id); fchs->ox_id = bfa_os_htons(ox_id); }
u16 fc_abts_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id) { bfa_os_memcpy(fchs, &fc_bls_req_tmpl, sizeof(struct fchs_s)); fchs->cat_info = FC_CAT_ABTS; fchs->d_id = (d_id); fchs->s_id = (s_id); fchs->ox_id = bfa_os_htons(ox_id); return sizeof(struct fchs_s); }
void bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_pport_attr_s *attr) { struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa); struct bfa_iocfc_s *iocfc = &bfa->iocfc; struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp; bfa_os_memset(attr, 0, sizeof(struct bfa_pport_attr_s)); attr->nwwn = fcport->nwwn; attr->pwwn = fcport->pwwn; attr->factorypwwn = bfa_ioc_get_mfg_pwwn(&bfa->ioc); attr->factorynwwn = bfa_ioc_get_mfg_nwwn(&bfa->ioc); bfa_os_memcpy(&attr->pport_cfg, &fcport->cfg, sizeof(struct bfa_pport_cfg_s)); /* * speed attributes */ attr->pport_cfg.speed = fcport->cfg.speed; attr->speed_supported = fcport->speed_sup; attr->speed = fcport->speed; attr->cos_supported = FC_CLASS_3; /* * topology attributes */ attr->pport_cfg.topology = fcport->cfg.topology; attr->topology = fcport->topology; /* * beacon attributes */ attr->beacon = fcport->beacon; attr->link_e2e_beacon = fcport->link_e2e_beacon; attr->plog_enabled = bfa_plog_get_setting(fcport->bfa->plog); attr->pport_cfg.path_tov = bfa_fcpim_path_tov_get(bfa); attr->pport_cfg.q_depth = bfa_fcpim_qdepth_get(bfa); /* PBC Disabled State */ if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED) attr->port_state = BFA_PPORT_ST_PREBOOT_DISABLED; else { attr->port_state = bfa_sm_to_state( hal_pport_sm_table, fcport->sm); if (bfa_ioc_is_disabled(&fcport->bfa->ioc)) attr->port_state = BFA_PPORT_ST_IOCDIS; else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc)) attr->port_state = BFA_PPORT_ST_FWMISMATCH; } }
static u16 fc_plogi_x_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size, u8 els_code) { struct fc_logi_s *plogi = (struct fc_logi_s *) (pld); bfa_os_memcpy(plogi, &plogi_tmpl, sizeof(struct fc_logi_s)); plogi->els_cmd.els_code = els_code; if (els_code == FC_ELS_PLOGI) fc_els_req_build(fchs, d_id, s_id, ox_id); else fc_els_rsp_build(fchs, d_id, s_id, ox_id); plogi->csp.rxsz = plogi->class3.rxsz = bfa_os_htons(pdu_size); bfa_os_memcpy(&plogi->port_name, &port_name, sizeof(wwn_t)); bfa_os_memcpy(&plogi->node_name, &node_name, sizeof(wwn_t)); return sizeof(struct fc_logi_s); }
u16 fc_ba_acc_build(struct fchs_s *fchs, struct fc_ba_acc_s *ba_acc, u32 d_id, u32 s_id, u16 ox_id, u16 rx_id) { fc_bls_rsp_build(fchs, d_id, s_id, ox_id); bfa_os_memcpy(ba_acc, &ba_acc_tmpl, sizeof(struct fc_ba_acc_s)); fchs->rx_id = rx_id; ba_acc->ox_id = fchs->ox_id; ba_acc->rx_id = fchs->rx_id; return sizeof(struct fc_ba_acc_s); }
u16 fc_rrq_build(struct fchs_s *fchs, struct fc_rrq_s *rrq, u32 d_id, u32 s_id, u16 ox_id, u16 rrq_oxid) { fc_els_req_build(fchs, d_id, s_id, ox_id); /* * build rrq payload */ bfa_os_memcpy(rrq, &rrq_tmpl, sizeof(struct fc_rrq_s)); rrq->s_id = (s_id); rrq->ox_id = bfa_os_htons(rrq_oxid); rrq->rx_id = FC_RXID_ANY; return sizeof(struct fc_rrq_s); }
bfa_status_t bfa_fcs_itnim_stats_get(struct bfa_fcs_port_s *port, wwn_t rpwwn, struct bfa_itnim_stats_s *stats) { struct bfa_fcs_itnim_s *itnim = NULL; bfa_assert(port != NULL); itnim = bfa_fcs_itnim_lookup(port, rpwwn); if (itnim == NULL) return BFA_STATUS_NO_FCPIM_NEXUS; bfa_os_memcpy(stats, &itnim->stats, sizeof(struct bfa_itnim_stats_s)); return BFA_STATUS_OK; }
u16 fc_pdisc_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size) { struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); bfa_os_memcpy(pdisc, &plogi_tmpl, sizeof(struct fc_logi_s)); pdisc->els_cmd.els_code = FC_ELS_PDISC; fc_els_req_build(fchs, d_id, s_id, ox_id); pdisc->csp.rxsz = pdisc->class3.rxsz = bfa_os_htons(pdu_size); pdisc->port_name = port_name; pdisc->node_name = node_name; return sizeof(struct fc_logi_s); }
u16 fc_prli_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, u16 ox_id) { struct fc_prli_s *prli = (struct fc_prli_s *) (pld); fc_els_req_build(fchs, d_id, s_id, ox_id); bfa_os_memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s)); prli->command = FC_ELS_PRLI; prli->parampage.servparams.initiator = 1; prli->parampage.servparams.retry = 1; prli->parampage.servparams.rec_support = 1; prli->parampage.servparams.task_retry_id = 0; prli->parampage.servparams.confirm = 1; return sizeof(struct fc_prli_s); }
u16 fc_fdisc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size) { u32 d_id = bfa_os_hton3b(FC_FABRIC_PORT); bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); flogi->els_cmd.els_code = FC_ELS_FDISC; fc_els_req_build(fchs, d_id, s_id, ox_id); flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size); flogi->port_name = port_name; flogi->node_name = node_name; return sizeof(struct fc_logi_s); }
u16 fc_flogi_acc_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size, u16 local_bb_credits) { u32 d_id = 0; bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); fc_els_rsp_build(fchs, d_id, s_id, ox_id); flogi->els_cmd.els_code = FC_ELS_ACC; flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size); flogi->port_name = port_name; flogi->node_name = node_name; flogi->csp.bbcred = bfa_os_htons(local_bb_credits); return sizeof(struct fc_logi_s); }
u16 fc_prli_acc_build(struct fchs_s *fchs, void *pld, u32 d_id, u32 s_id, u16 ox_id, enum bfa_port_role role) { struct fc_prli_s *prli = (struct fc_prli_s *) (pld); fc_els_rsp_build(fchs, d_id, s_id, ox_id); bfa_os_memcpy(prli, &prli_tmpl, sizeof(struct fc_prli_s)); prli->command = FC_ELS_ACC; if ((role & BFA_PORT_ROLE_FCP_TM) == BFA_PORT_ROLE_FCP_TM) prli->parampage.servparams.target = 1; else prli->parampage.servparams.initiator = 1; prli->parampage.rspcode = FC_PRLI_ACC_XQTD; return sizeof(struct fc_prli_s); }
u16 fc_flogi_build(struct fchs_s *fchs, struct fc_logi_s *flogi, u32 s_id, u16 ox_id, wwn_t port_name, wwn_t node_name, u16 pdu_size, u8 set_npiv, u8 set_auth, u16 local_bb_credits) { u32 d_id = bfa_os_hton3b(FC_FABRIC_PORT); u32 *vvl_info; bfa_os_memcpy(flogi, &plogi_tmpl, sizeof(struct fc_logi_s)); flogi->els_cmd.els_code = FC_ELS_FLOGI; fc_els_req_build(fchs, d_id, s_id, ox_id); flogi->csp.rxsz = flogi->class3.rxsz = bfa_os_htons(pdu_size); flogi->port_name = port_name; flogi->node_name = node_name; /* * Set the NPIV Capability Bit ( word 1, bit 31) of Common * Service Parameters. */ flogi->csp.ciro = set_npiv; /* set AUTH capability */ flogi->csp.security = set_auth; flogi->csp.bbcred = bfa_os_htons(local_bb_credits); /* Set brcd token in VVL */ vvl_info = (u32 *)&flogi->vvl[0]; /* set the flag to indicate the presence of VVL */ flogi->csp.npiv_supp = 1; /* @todo. field name is not correct */ vvl_info[0] = bfa_os_htonl(FLOGI_VVL_BRCD); return sizeof(struct fc_logi_s); }
/** * 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; }