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); } } }
static void bfa_fcs_port_ns_plogi_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 fc_logi_s *plogi_resp; */ struct fc_els_cmd_s *els_cmd; struct fc_ls_rjt_s *ls_rjt; 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); port->stats.ns_plogi_rsp_err++; bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); return; } els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); switch (els_cmd->els_code) { case FC_ELS_ACC: if (rsp_len < sizeof(struct fc_logi_s)) { bfa_trc(port->fcs, rsp_len); port->stats.ns_plogi_acc_err++; bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); break; } port->stats.ns_plogi_accepts++; bfa_sm_send_event(ns, NSSM_EVENT_RSP_OK); break; case FC_ELS_LS_RJT: ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); bfa_trc(port->fcs, ls_rjt->reason_code); bfa_trc(port->fcs, ls_rjt->reason_code_expl); port->stats.ns_rejects++; bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); break; default: port->stats.ns_plogi_unknown_rsp++; bfa_trc(port->fcs, els_cmd->els_code); bfa_sm_send_event(ns, NSSM_EVENT_RSP_ERROR); } }
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); }
void bfa_fcs_port_loop_plogi_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_s *port = (struct bfa_fcs_port_s *) cbarg; struct fc_logi_s *plogi_resp; struct fc_els_cmd_s *els_cmd; bfa_trc(port->fcs, req_status); if (req_status != BFA_STATUS_OK) { bfa_trc(port->fcs, req_status); return; } els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); plogi_resp = (struct fc_logi_s *) els_cmd; if (els_cmd->els_code == FC_ELS_ACC) { bfa_fcs_rport_start(port, rsp_fchs, plogi_resp); } else { bfa_trc(port->fcs, plogi_resp->els_cmd.els_code); bfa_assert(0); } }
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); }
void bfa_fcs_port_loop_adisc_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_s *port = (struct bfa_fcs_port_s *) cbarg; struct bfa_fcs_rport_s *rport; struct fc_adisc_s *adisc_resp; struct fc_els_cmd_s *els_cmd; u32 pid = rsp_fchs->s_id; bfa_trc(port->fcs, req_status); if (req_status != BFA_STATUS_OK) { bfa_fcxp_free(fcxp); return; } els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); adisc_resp = (struct fc_adisc_s *) els_cmd; if (els_cmd->els_code == FC_ELS_ACC) { } else { bfa_trc(port->fcs, adisc_resp->els_cmd.els_code); rport = bfa_fcs_port_get_rport_by_pid(port, pid); if (rport) { list_del(&rport->qe); bfa_fcs_rport_delete(rport); } } return; }
/** * Called by fcxp to notify the Plogi response */ static void bfa_fcs_port_loop_plogi_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_s *port = (struct bfa_fcs_port_s *) cbarg; struct fc_logi_s *plogi_resp; struct fc_els_cmd_s *els_cmd; bfa_trc(port->fcs, req_status); /* * Sanity Checks */ if (req_status != BFA_STATUS_OK) { bfa_trc(port->fcs, req_status); /* * @todo * This could mean that the device with this APLA does not * exist on the loop. */ return; } els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); plogi_resp = (struct fc_logi_s *) els_cmd; if (els_cmd->els_code == FC_ELS_ACC) { bfa_fcs_rport_start(port, rsp_fchs, plogi_resp); } else { bfa_trc(port->fcs, plogi_resp->els_cmd.els_code); bfa_assert(0); } }
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); } }
static void bfa_fcs_itnim_prli_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_itnim_s *itnim = (struct bfa_fcs_itnim_s *) cbarg; struct fc_els_cmd_s *els_cmd; struct fc_prli_s *prli_resp; struct fc_ls_rjt_s *ls_rjt; struct fc_prli_params_s *sparams; bfa_trc(itnim->fcs, req_status); /* * Sanity Checks */ if (req_status != BFA_STATUS_OK) { itnim->stats.prli_rsp_err++; bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_ERROR); return; } els_cmd = (struct fc_els_cmd_s *) BFA_FCXP_RSP_PLD(fcxp); if (els_cmd->els_code == FC_ELS_ACC) { prli_resp = (struct fc_prli_s *) els_cmd; if (fc_prli_rsp_parse(prli_resp, rsp_len) != FC_PARSE_OK) { bfa_trc(itnim->fcs, rsp_len); /* * Check if this r-port is also in Initiator mode. * If so, we need to set this ITN as a no-op. */ if (prli_resp->parampage.servparams.initiator) { bfa_trc(itnim->fcs, prli_resp->parampage.type); itnim->rport->scsi_function = BFA_RPORT_INITIATOR; itnim->stats.prli_rsp_acc++; itnim->stats.initiator++; bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_OK); return; } itnim->stats.prli_rsp_parse_err++; return; } itnim->rport->scsi_function = BFA_RPORT_TARGET; sparams = &prli_resp->parampage.servparams; itnim->seq_rec = sparams->retry; itnim->rec_support = sparams->rec_support; itnim->task_retry_id = sparams->task_retry_id; itnim->conf_comp = sparams->confirm; itnim->stats.prli_rsp_acc++; bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_OK); } else { ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp); bfa_trc(itnim->fcs, ls_rjt->reason_code); bfa_trc(itnim->fcs, ls_rjt->reason_code_expl); itnim->stats.prli_rsp_rjt++; if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP) { bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_NOT_SUPP); return; } bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_RSP_ERROR); } }
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); }