/** * Update BFA configuration from firmware configuration. */ static void bfa_iocfc_cfgrsp(struct bfa_s *bfa) { struct bfa_iocfc_s *iocfc = &bfa->iocfc; struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp; struct bfa_iocfc_fwcfg_s *fwcfg = &cfgrsp->fwcfg; fwcfg->num_cqs = fwcfg->num_cqs; fwcfg->num_ioim_reqs = bfa_os_ntohs(fwcfg->num_ioim_reqs); fwcfg->num_tskim_reqs = bfa_os_ntohs(fwcfg->num_tskim_reqs); fwcfg->num_fcxp_reqs = bfa_os_ntohs(fwcfg->num_fcxp_reqs); fwcfg->num_uf_bufs = bfa_os_ntohs(fwcfg->num_uf_bufs); fwcfg->num_rports = bfa_os_ntohs(fwcfg->num_rports); iocfc->cfgdone = BFA_TRUE; /** * Configuration is complete - initialize/start submodules */ bfa_fcport_init(bfa); if (iocfc->action == BFA_IOCFC_ACT_INIT) bfa_cb_queue(bfa, &iocfc->init_hcb_qe, bfa_iocfc_init_cb, bfa); else bfa_iocfc_start_submod(bfa); }
void bfa_pport_qos_get_vc_attr(struct bfa_s *bfa, struct bfa_qos_vc_attr_s *qos_vc_attr) { struct bfa_pport_s *pport = BFA_PORT_MOD(bfa); struct bfa_qos_vc_attr_s *bfa_vc_attr = &pport->qos_vc_attr; u32 i = 0; qos_vc_attr->total_vc_count = bfa_os_ntohs(bfa_vc_attr->total_vc_count); qos_vc_attr->shared_credit = bfa_os_ntohs(bfa_vc_attr->shared_credit); qos_vc_attr->elp_opmode_flags = bfa_os_ntohl(bfa_vc_attr->elp_opmode_flags); /* * Individual VC info */ while (i < qos_vc_attr->total_vc_count) { qos_vc_attr->vc_info[i].vc_credit = bfa_vc_attr->vc_info[i].vc_credit; qos_vc_attr->vc_info[i].borrow_credit = bfa_vc_attr->vc_info[i].borrow_credit; qos_vc_attr->vc_info[i].priority = bfa_vc_attr->vc_info[i].priority; ++i; } }
static void bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, bfa_status_t req_status, u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs) { struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg; struct bfa_fcs_rport_s *rport = rpf->rport; struct fc_ls_rjt_s *ls_rjt; struct fc_rpsc2_acc_s *rpsc2_acc; u16 num_ents; bfa_trc(rport->fcs, req_status); if (req_status != BFA_STATUS_OK) { bfa_trc(rport->fcs, req_status); if (req_status == BFA_STATUS_ETIMER) rport->stats.rpsc_failed++; bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); return; } rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp); if (rpsc2_acc->els_cmd == FC_ELS_ACC) { rport->stats.rpsc_accs++; num_ents = bfa_os_ntohs(rpsc2_acc->num_pids); bfa_trc(rport->fcs, num_ents); if (num_ents > 0) { bfa_assert(rpsc2_acc->port_info[0].pid != rport->pid); bfa_trc(rport->fcs, bfa_os_ntohs(rpsc2_acc->port_info[0].pid)); bfa_trc(rport->fcs, bfa_os_ntohs(rpsc2_acc->port_info[0].speed)); bfa_trc(rport->fcs, bfa_os_ntohs(rpsc2_acc->port_info[0].index)); bfa_trc(rport->fcs, rpsc2_acc->port_info[0].type); if (rpsc2_acc->port_info[0].speed == 0) { bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); return; } rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed( bfa_os_ntohs(rpsc2_acc->port_info[0].speed)); bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP); } } else { ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); bfa_trc(rport->fcs, ls_rjt->reason_code); bfa_trc(rport->fcs, ls_rjt->reason_code_expl); rport->stats.rpsc_rejects++; if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP) { bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL); } else { bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR); } } }
enum fc_parse_status fc_plogi_parse(struct fchs_s *fchs) { struct fc_logi_s *plogi = (struct fc_logi_s *) (fchs + 1); if (plogi->class3.class_valid != 1) return FC_PARSE_FAILURE; if ((bfa_os_ntohs(plogi->class3.rxsz) < FC_MIN_PDUSZ) || (bfa_os_ntohs(plogi->class3.rxsz) > FC_MAX_PDUSZ) || (plogi->class3.rxsz == 0)) return FC_PARSE_FAILURE; return FC_PARSE_OK; }
enum fc_parse_status fc_plogi_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name) { struct fc_els_cmd_s *els_cmd = (struct fc_els_cmd_s *) (fchs + 1); struct fc_logi_s *plogi; struct fc_ls_rjt_s *ls_rjt; switch (els_cmd->els_code) { case FC_ELS_LS_RJT: ls_rjt = (struct fc_ls_rjt_s *) (fchs + 1); if (ls_rjt->reason_code == FC_LS_RJT_RSN_LOGICAL_BUSY) return FC_PARSE_BUSY; else return FC_PARSE_FAILURE; case FC_ELS_ACC: plogi = (struct fc_logi_s *) (fchs + 1); if (len < sizeof(struct fc_logi_s)) return FC_PARSE_FAILURE; if (!wwn_is_equal(plogi->port_name, port_name)) return FC_PARSE_FAILURE; if (!plogi->class3.class_valid) return FC_PARSE_FAILURE; if (bfa_os_ntohs(plogi->class3.rxsz) < (FC_MIN_PDUSZ)) return FC_PARSE_FAILURE; return FC_PARSE_OK; default: return FC_PARSE_FAILURE; } }
u16 fc_tprlo_rsp_parse(struct fchs_s *fchs, int len) { struct fc_tprlo_acc_s *tprlo = (struct fc_tprlo_acc_s *) (fchs + 1); int num_pages = 0; int page = 0; len = len; if (tprlo->command != FC_ELS_ACC) return FC_PARSE_ACC_INVAL; num_pages = (bfa_os_ntohs(tprlo->payload_len) - 4) / 16; for (page = 0; page < num_pages; page++) { if (tprlo->tprlo_acc_params[page].type != FC_TYPE_FCP) return FC_PARSE_NOT_FCP; if (tprlo->tprlo_acc_params[page].opa_valid != 0) return FC_PARSE_OPAFLAG_INVAL; if (tprlo->tprlo_acc_params[page].rpa_valid != 0) return FC_PARSE_RPAFLAG_INVAL; if (tprlo->tprlo_acc_params[page].orig_process_assc != 0) return FC_PARSE_OPA_INVAL; if (tprlo->tprlo_acc_params[page].resp_process_assc != 0) return FC_PARSE_RPA_INVAL; } return FC_PARSE_OK; }
u16 fc_tprlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id, int num_pages, enum fc_tprlo_type tprlo_type, u32 tpr_id) { struct fc_tprlo_s *tprlo = (struct fc_tprlo_s *) (fchs + 1); int page; fc_els_req_build(fchs, d_id, s_id, ox_id); memset(tprlo, 0, (num_pages * 16) + 4); tprlo->command = FC_ELS_TPRLO; tprlo->page_len = 0x10; tprlo->payload_len = bfa_os_htons((num_pages * 16) + 4); for (page = 0; page < num_pages; page++) { tprlo->tprlo_params[page].type = FC_TYPE_FCP; tprlo->tprlo_params[page].opa_valid = 0; tprlo->tprlo_params[page].rpa_valid = 0; tprlo->tprlo_params[page].orig_process_assc = 0; tprlo->tprlo_params[page].resp_process_assc = 0; if (tprlo_type == FC_GLOBAL_LOGO) { tprlo->tprlo_params[page].global_process_logout = 1; } else if (tprlo_type == FC_TPR_LOGO) { tprlo->tprlo_params[page].tpo_nport_valid = 1; tprlo->tprlo_params[page].tpo_nport_id = (tpr_id); } } return bfa_os_ntohs(tprlo->payload_len); }
u16 fc_prlo_rsp_parse(struct fchs_s *fchs, int len) { struct fc_prlo_acc_s *prlo = (struct fc_prlo_acc_s *) (fchs + 1); int num_pages = 0; int page = 0; len = len; if (prlo->command != FC_ELS_ACC) return FC_PARSE_FAILURE; num_pages = ((bfa_os_ntohs(prlo->payload_len)) - 4) / 16; for (page = 0; page < num_pages; page++) { if (prlo->prlo_acc_params[page].type != FC_TYPE_FCP) return FC_PARSE_FAILURE; if (prlo->prlo_acc_params[page].opa_valid != 0) return FC_PARSE_FAILURE; if (prlo->prlo_acc_params[page].rpa_valid != 0) return FC_PARSE_FAILURE; if (prlo->prlo_acc_params[page].orig_process_assc != 0) return FC_PARSE_FAILURE; if (prlo->prlo_acc_params[page].resp_process_assc != 0) return FC_PARSE_FAILURE; } return FC_PARSE_OK; }
static void bfa_fcs_port_fdmi_rprt_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, bfa_status_t req_status, u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs) { struct bfa_fcs_port_fdmi_s *fdmi = (struct bfa_fcs_port_fdmi_s *)cbarg; struct bfa_fcs_port_s *port = fdmi->ms->port; struct ct_hdr_s *cthdr = NULL; bfa_trc(port->fcs, port->port_cfg.pwwn); /* * Sanity Checks */ if (req_status != BFA_STATUS_OK) { bfa_trc(port->fcs, req_status); bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); return; } cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_OK); return; } bfa_trc(port->fcs, cthdr->reason_code); bfa_trc(port->fcs, cthdr->exp_code); bfa_sm_send_event(fdmi, FDMISM_EVENT_RSP_ERROR); }
int fc_logout_params_pages(struct fchs_s *fc_frame, u8 els_code) { int num_pages = 0; struct fc_prlo_s *prlo; struct fc_tprlo_s *tprlo; if (els_code == FC_ELS_PRLO) { prlo = (struct fc_prlo_s *) (fc_frame + 1); num_pages = (bfa_os_ntohs(prlo->payload_len) - 4) / 16; } else { tprlo = (struct fc_tprlo_s *) (fc_frame + 1); num_pages = (bfa_os_ntohs(tprlo->payload_len) - 4) / 16; } return num_pages; }
void bfa_iocfc_get_attr(struct bfa_s *bfa, struct bfa_iocfc_attr_s *attr) { struct bfa_iocfc_s *iocfc = &bfa->iocfc; attr->intr_attr.coalesce = iocfc->cfginfo->intr_attr.coalesce; attr->intr_attr.delay = iocfc->cfginfo->intr_attr.delay ? bfa_os_ntohs(iocfc->cfginfo->intr_attr.delay) : bfa_os_ntohs(iocfc->cfgrsp->intr_attr.delay); attr->intr_attr.latency = iocfc->cfginfo->intr_attr.latency ? bfa_os_ntohs(iocfc->cfginfo->intr_attr.latency) : bfa_os_ntohs(iocfc->cfgrsp->intr_attr.latency); attr->config = iocfc->cfg; }
static void bfa_iocfc_cfgrsp(struct bfa_s *bfa) { struct bfa_iocfc_s *iocfc = &bfa->iocfc; struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp; struct bfa_iocfc_fwcfg_s *fwcfg = &cfgrsp->fwcfg; struct bfi_iocfc_cfg_s *cfginfo = iocfc->cfginfo; fwcfg->num_cqs = fwcfg->num_cqs; fwcfg->num_ioim_reqs = bfa_os_ntohs(fwcfg->num_ioim_reqs); fwcfg->num_tskim_reqs = bfa_os_ntohs(fwcfg->num_tskim_reqs); fwcfg->num_fcxp_reqs = bfa_os_ntohs(fwcfg->num_fcxp_reqs); fwcfg->num_uf_bufs = bfa_os_ntohs(fwcfg->num_uf_bufs); fwcfg->num_rports = bfa_os_ntohs(fwcfg->num_rports); cfginfo->intr_attr.coalesce = cfgrsp->intr_attr.coalesce; cfginfo->intr_attr.delay = bfa_os_ntohs(cfgrsp->intr_attr.delay); cfginfo->intr_attr.latency = bfa_os_ntohs(cfgrsp->intr_attr.latency); iocfc->cfgdone = BFA_TRUE; if (iocfc->action == BFA_IOCFC_ACT_INIT) bfa_cb_queue(bfa, &iocfc->init_hcb_qe, bfa_iocfc_init_cb, bfa); else bfa_iocfc_start_submod(bfa); }
u16 fc_ct_rsp_parse(struct ct_hdr_s *cthdr) { if (bfa_os_ntohs(cthdr->cmd_rsp_code) != CT_RSP_ACCEPT) { if (cthdr->reason_code == CT_RSN_LOGICAL_BUSY) return FC_PARSE_BUSY; else return FC_PARSE_FAILURE; } return FC_PARSE_OK; }
void bfa_ioim_good_comp_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; iotag = bfa_os_ntohs(rsp->io_tag); ioim = BFA_IOIM_FROM_TAG(fcpim, iotag); bfa_assert(ioim->iotag == iotag); bfa_trc_fp(ioim->bfa, ioim->iotag); bfa_sm_send_event(ioim, BFA_IOIM_SM_COMP_GOOD); }
static void bfa_fcs_port_ns_rff_id_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, bfa_status_t req_status, u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs) { struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg; struct bfa_fcs_port_s *port = ns->port; struct ct_hdr_s *cthdr = NULL; bfa_trc(port->fcs, port->port_cfg.pwwn); /* * Sanity Checks */ if (req_status != BFA_STATUS_OK) { bfa_trc(port->fcs, req_status); port->stats.ns_rffid_rsp_err++; bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); return; } cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { port->stats.ns_rffid_accepts++; bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); return; } port->stats.ns_rffid_rejects++; bfa_trc(port->fcs, cthdr->reason_code); bfa_trc(port->fcs, cthdr->exp_code); if (cthdr->reason_code == CT_RSN_NOT_SUPP) { /* * if this command is not supported, we don't retry */ bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); } else { bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); } }
static void bfa_fcs_port_ms_gfn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, bfa_status_t req_status, u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs) { struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg; struct bfa_fcs_port_s *port = ms->port; struct ct_hdr_s *cthdr = NULL; wwn_t *gfn_resp; bfa_trc(port->fcs, req_status); bfa_trc(port->fcs, port->port_cfg.pwwn); /* * Sanity Checks */ if (req_status != BFA_STATUS_OK) { bfa_trc(port->fcs, req_status); bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); return; } cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { gfn_resp = (wwn_t *) (cthdr + 1); /* * check if it has actually changed */ if ((memcmp ((void *)&bfa_fcs_port_get_fabric_name(port), gfn_resp, sizeof(wwn_t)) != 0)) bfa_fcs_fabric_set_fabric_name(port->fabric, *gfn_resp); bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); return; } bfa_trc(port->fcs, cthdr->reason_code); bfa_trc(port->fcs, cthdr->exp_code); bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); }
enum fc_parse_status fc_pdisc_parse(struct fchs_s *fchs, wwn_t node_name, wwn_t port_name) { struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); if (pdisc->class3.class_valid != 1) return FC_PARSE_FAILURE; if ((bfa_os_ntohs(pdisc->class3.rxsz) < (FC_MIN_PDUSZ - sizeof(struct fchs_s))) || (pdisc->class3.rxsz == 0)) return FC_PARSE_FAILURE; if (!wwn_is_equal(pdisc->port_name, port_name)) return FC_PARSE_FAILURE; if (!wwn_is_equal(pdisc->node_name, node_name)) return FC_PARSE_FAILURE; return FC_PARSE_OK; }
u16 fc_pdisc_rsp_parse(struct fchs_s *fchs, int len, wwn_t port_name) { struct fc_logi_s *pdisc = (struct fc_logi_s *) (fchs + 1); if (len < sizeof(struct fc_logi_s)) return FC_PARSE_LEN_INVAL; if (pdisc->els_cmd.els_code != FC_ELS_ACC) return FC_PARSE_ACC_INVAL; if (!wwn_is_equal(pdisc->port_name, port_name)) return FC_PARSE_PWWN_NOT_EQUAL; if (!pdisc->class3.class_valid) return FC_PARSE_NWWN_NOT_EQUAL; if (bfa_os_ntohs(pdisc->class3.rxsz) < (FC_MIN_PDUSZ)) return FC_PARSE_RXSZ_INVAL; return FC_PARSE_OK; }
u16 fc_prlo_build(struct fchs_s *fchs, u32 d_id, u32 s_id, u16 ox_id, int num_pages) { struct fc_prlo_s *prlo = (struct fc_prlo_s *) (fchs + 1); int page; fc_els_req_build(fchs, d_id, s_id, ox_id); memset(prlo, 0, (num_pages * 16) + 4); prlo->command = FC_ELS_PRLO; prlo->page_len = 0x10; prlo->payload_len = bfa_os_htons((num_pages * 16) + 4); for (page = 0; page < num_pages; page++) { prlo->prlo_params[page].type = FC_TYPE_FCP; prlo->prlo_params[page].opa_valid = 0; prlo->prlo_params[page].rpa_valid = 0; prlo->prlo_params[page].orig_process_assc = 0; prlo->prlo_params[page].resp_process_assc = 0; } return bfa_os_ntohs(prlo->payload_len); }
u16 fc_prlo_acc_build(struct fchs_s *fchs, struct fc_prlo_acc_s *prlo_acc, u32 d_id, u32 s_id, u16 ox_id, int num_pages) { int page; fc_els_rsp_build(fchs, d_id, s_id, ox_id); memset(prlo_acc, 0, (num_pages * 16) + 4); prlo_acc->command = FC_ELS_ACC; prlo_acc->page_len = 0x10; prlo_acc->payload_len = bfa_os_htons((num_pages * 16) + 4); for (page = 0; page < num_pages; page++) { prlo_acc->prlo_acc_params[page].opa_valid = 0; prlo_acc->prlo_acc_params[page].rpa_valid = 0; prlo_acc->prlo_acc_params[page].fc4type_csp = FC_TYPE_FCP; prlo_acc->prlo_acc_params[page].orig_process_assc = 0; prlo_acc->prlo_acc_params[page].resp_process_assc = 0; } return bfa_os_ntohs(prlo_acc->payload_len); }
static void bfa_fcs_port_ns_gid_ft_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, bfa_status_t req_status, u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs) { struct bfa_fcs_port_ns_s *ns = (struct bfa_fcs_port_ns_s *)cbarg; struct bfa_fcs_port_s *port = ns->port; struct ct_hdr_s *cthdr = NULL; u32 n_pids; bfa_trc(port->fcs, port->port_cfg.pwwn); /* * Sanity Checks */ if (req_status != BFA_STATUS_OK) { bfa_trc(port->fcs, req_status); port->stats.ns_gidft_rsp_err++; bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); return; } if (resid_len != 0) { /* * TBD : we will need to allocate a larger buffer & retry the * command */ bfa_trc(port->fcs, rsp_len); bfa_trc(port->fcs, resid_len); return; } cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); switch (cthdr->cmd_rsp_code) { case CT_RSP_ACCEPT: port->stats.ns_gidft_accepts++; n_pids = (fc_get_ctresp_pyld_len(rsp_len) / sizeof(u32)); bfa_trc(port->fcs, n_pids); bfa_fcs_port_ns_process_gidft_pids(port, (u32 *) (cthdr + 1), n_pids); bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); break; case CT_RSP_REJECT: /* * Check the reason code & explanation. * There may not have been any FC4 devices in the fabric */ port->stats.ns_gidft_rejects++; bfa_trc(port->fcs, cthdr->reason_code); bfa_trc(port->fcs, cthdr->exp_code); if ((cthdr->reason_code == CT_RSN_UNABLE_TO_PERF) && (cthdr->exp_code == CT_NS_EXP_FT_NOT_REG)) { bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); } else { /* * for all other errors, retry */ bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); } break; default: port->stats.ns_gidft_unknown_rsp++; bfa_trc(port->fcs, cthdr->cmd_rsp_code); bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); } }
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); }
static void bfa_fcs_port_ms_gmal_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg, bfa_status_t req_status, u32 rsp_len, u32 resid_len, struct fchs_s *rsp_fchs) { struct bfa_fcs_port_ms_s *ms = (struct bfa_fcs_port_ms_s *)cbarg; struct bfa_fcs_port_s *port = ms->port; struct ct_hdr_s *cthdr = NULL; struct fcgs_gmal_resp_s *gmal_resp; struct fc_gmal_entry_s *gmal_entry; u32 num_entries; u8 *rsp_str; bfa_trc(port->fcs, req_status); bfa_trc(port->fcs, port->port_cfg.pwwn); /* * Sanity Checks */ if (req_status != BFA_STATUS_OK) { bfa_trc(port->fcs, req_status); bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); return; } cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp); cthdr->cmd_rsp_code = bfa_os_ntohs(cthdr->cmd_rsp_code); if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { gmal_resp = (struct fcgs_gmal_resp_s *)(cthdr + 1); num_entries = bfa_os_ntohl(gmal_resp->ms_len); if (num_entries == 0) { bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); return; } /* * The response could contain multiple Entries. * Entries for SNMP interface, etc. * We look for the entry with a telnet prefix. * First "http://" entry refers to IP addr */ gmal_entry = (struct fc_gmal_entry_s *)gmal_resp->ms_ma; while (num_entries > 0) { if (strncmp (gmal_entry->prefix, CT_GMAL_RESP_PREFIX_HTTP, sizeof(gmal_entry->prefix)) == 0) { /* * if the IP address is terminating with a '/', * remove it. *Byte 0 consists of the length * of the string. */ rsp_str = &(gmal_entry->prefix[0]); if (rsp_str[gmal_entry->len - 1] == '/') rsp_str[gmal_entry->len - 1] = 0; /* * copy IP Address to fabric */ strncpy(bfa_fcs_port_get_fabric_ipaddr(port), gmal_entry->ip_addr, BFA_FCS_FABRIC_IPADDR_SZ); break; } else { --num_entries; ++gmal_entry; } } bfa_sm_send_event(ms, MSSM_EVENT_RSP_OK); return; } bfa_trc(port->fcs, cthdr->reason_code); bfa_trc(port->fcs, cthdr->exp_code); bfa_sm_send_event(ms, MSSM_EVENT_RSP_ERROR); }