/** * Query Fabric for FC4-Types Devices. * * TBD : Need to use a local (FCS private) response buffer, since the response * can be larger than 2K. */ static void bfa_fcs_port_ns_send_gid_ft(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) { struct bfa_fcs_port_ns_s *ns = ns_cbarg; struct bfa_fcs_port_s *port = ns->port; struct fchs_s fchs; int len; struct bfa_fcxp_s *fcxp; bfa_trc(port->fcs, port->pid); fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); if (!fcxp) { port->stats.ns_gidft_alloc_wait++; bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, bfa_fcs_port_ns_send_gid_ft, ns); return; } ns->fcxp = fcxp; /* * This query is only initiated for FCP initiator mode. */ len = fc_gid_ft_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), ns->port->pid, FC_TYPE_FCP); bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_gid_ft_response, (void *)ns, bfa_fcxp_get_maxrsp(port->fcs->bfa), FC_RA_TOV); port->stats.ns_gidft_sent++; bfa_sm_send_event(ns, NSSM_EVENT_GIDFT_SENT); }
/** * Register FC4-Types * TBD, Need to retrieve this from the OS driver, in case IPFC is enabled ? */ static void bfa_fcs_port_ns_send_rft_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) { struct bfa_fcs_port_ns_s *ns = ns_cbarg; struct bfa_fcs_port_s *port = ns->port; struct fchs_s fchs; int len; struct bfa_fcxp_s *fcxp; bfa_trc(port->fcs, port->port_cfg.pwwn); fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); if (!fcxp) { port->stats.ns_rftid_alloc_wait++; bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, bfa_fcs_port_ns_send_rft_id, ns); return; } ns->fcxp = fcxp; len = fc_rftid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), bfa_fcs_port_get_fcid(port), 0, port->port_cfg.roles); bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rft_id_response, (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV); port->stats.ns_rftid_sent++; bfa_sm_send_event(ns, NSSM_EVENT_RFTID_SENT); }
static void bfa_fcs_port_ns_send_plogi(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) { struct bfa_fcs_port_ns_s *ns = ns_cbarg; struct bfa_fcs_port_s *port = ns->port; struct fchs_s fchs; int len; struct bfa_fcxp_s *fcxp; bfa_trc(port->fcs, port->pid); fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); if (!fcxp) { port->stats.ns_plogi_alloc_wait++; bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, bfa_fcs_port_ns_send_plogi, ns); return; } ns->fcxp = fcxp; len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), bfa_os_hton3b(FC_NAME_SERVER), bfa_fcs_port_get_fcid(port), 0, port->port_cfg.pwwn, port->port_cfg.nwwn, bfa_pport_get_maxfrsize(port->fcs->bfa)); bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_plogi_response, (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV); port->stats.ns_plogi_sent++; bfa_sm_send_event(ns, NSSM_EVENT_PLOGI_SENT); }
static void bfa_fcs_itnim_send_prli(void *itnim_cbarg, struct bfa_fcxp_s *fcxp_alloced) { struct bfa_fcs_itnim_s *itnim = itnim_cbarg; struct bfa_fcs_rport_s *rport = itnim->rport; struct bfa_fcs_lport_s *port = rport->port; struct fchs_s fchs; struct bfa_fcxp_s *fcxp; int len; bfa_trc(itnim->fcs, itnim->rport->pwwn); fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE); if (!fcxp) { itnim->stats.fcxp_alloc_wait++; bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &itnim->fcxp_wqe, bfa_fcs_itnim_send_prli, itnim, BFA_TRUE); return; } itnim->fcxp = fcxp; len = fc_prli_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), itnim->rport->pid, bfa_fcs_lport_get_fcid(port), 0); bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id, port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, bfa_fcs_itnim_prli_response, (void *)itnim, FC_MAX_PDUSZ, FC_ELS_TOV); itnim->stats.prli_sent++; bfa_sm_send_event(itnim, BFA_FCS_ITNIM_SM_FRMSENT); }
static void bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced) { struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg; struct bfa_fcs_rport_s *rport = rpf->rport; struct bfa_fcs_port_s *port = rport->port; struct fchs_s fchs; int len; struct bfa_fcxp_s *fcxp; bfa_trc(rport->fcs, rport->pwwn); fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); if (!fcxp) { bfa_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe, bfa_fcs_rpf_send_rpsc2, rpf); return; } rpf->fcxp = fcxp; len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid, bfa_fcs_port_get_fcid(port), &rport->pid, 1); bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response, rpf, FC_MAX_PDUSZ, FC_RA_TOV); rport->stats.rpsc_sent++; bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT); }
static void bfa_fcs_port_ms_send_gfn(void *ms_cbarg, struct bfa_fcxp_s *fcxp_alloced) { struct bfa_fcs_port_ms_s *ms = ms_cbarg; struct bfa_fcs_port_s *port = ms->port; struct fchs_s fchs; int len; struct bfa_fcxp_s *fcxp; bfa_trc(port->fcs, port->pid); fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); if (!fcxp) { bfa_fcxp_alloc_wait(port->fcs->bfa, &ms->fcxp_wqe, bfa_fcs_port_ms_send_gfn, ms); return; } ms->fcxp = fcxp; len = fc_gfn_req_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), bfa_fcs_port_get_fcid(port), bfa_lps_get_peer_nwwn(port->fabric->lps)); bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, bfa_fcs_port_ms_gfn_response, (void *)ms, FC_MAX_PDUSZ, FC_FCCT_TOV); bfa_sm_send_event(ms, MSSM_EVENT_FCXP_SENT); }
/** * Register FC4-Features : Should be done after RFT_ID */ static void bfa_fcs_port_ns_send_rff_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) { struct bfa_fcs_port_ns_s *ns = ns_cbarg; struct bfa_fcs_port_s *port = ns->port; struct fchs_s fchs; int len; struct bfa_fcxp_s *fcxp; u8 fc4_ftrs = 0; bfa_trc(port->fcs, port->port_cfg.pwwn); fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); if (!fcxp) { port->stats.ns_rffid_alloc_wait++; bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, bfa_fcs_port_ns_send_rff_id, ns); return; } ns->fcxp = fcxp; if (BFA_FCS_VPORT_IS_INITIATOR_MODE(ns->port)) { fc4_ftrs = FC_GS_FCP_FC4_FEATURE_INITIATOR; } else if (BFA_FCS_VPORT_IS_TARGET_MODE(ns->port)) { fc4_ftrs = FC_GS_FCP_FC4_FEATURE_TARGET; } len = fc_rffid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), bfa_fcs_port_get_fcid(port), 0, FC_TYPE_FCP, fc4_ftrs); bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rff_id_response, (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV); port->stats.ns_rffid_sent++; bfa_sm_send_event(ns, NSSM_EVENT_RFFID_SENT); }
/** * RPRT : Register Port */ static void bfa_fcs_port_fdmi_send_rprt(void *fdmi_cbarg, struct bfa_fcxp_s *fcxp_alloced) { struct bfa_fcs_port_fdmi_s *fdmi = fdmi_cbarg; struct bfa_fcs_port_s *port = fdmi->ms->port; struct fchs_s fchs; u16 len, attr_len; struct bfa_fcxp_s *fcxp; u8 *pyld; bfa_trc(port->fcs, port->port_cfg.pwwn); fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); if (!fcxp) { bfa_fcxp_alloc_wait(port->fcs->bfa, &fdmi->fcxp_wqe, bfa_fcs_port_fdmi_send_rprt, fdmi); return; } fdmi->fcxp = fcxp; pyld = bfa_fcxp_get_reqbuf(fcxp); bfa_os_memset(pyld, 0, FC_MAX_PDUSZ); len = fc_fdmi_reqhdr_build(&fchs, pyld, bfa_fcs_port_get_fcid(port), FDMI_RPRT); attr_len = bfa_fcs_port_fdmi_build_rprt_pyld(fdmi, (u8 *) ((struct ct_hdr_s *) pyld + 1)); bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, FC_CLASS_3, len + attr_len, &fchs, bfa_fcs_port_fdmi_rprt_response, (void *)fdmi, FC_MAX_PDUSZ, FC_FCCT_TOV); bfa_sm_send_event(fdmi, FDMISM_EVENT_RPRT_SENT); }
/** * Register the symbolic port name. */ static void bfa_fcs_port_ns_send_rspn_id(void *ns_cbarg, struct bfa_fcxp_s *fcxp_alloced) { struct bfa_fcs_port_ns_s *ns = ns_cbarg; struct bfa_fcs_port_s *port = ns->port; struct fchs_s fchs; int len; struct bfa_fcxp_s *fcxp; u8 symbl[256]; u8 *psymbl = &symbl[0]; bfa_os_memset(symbl, 0, sizeof(symbl)); bfa_trc(port->fcs, port->port_cfg.pwwn); fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs); if (!fcxp) { port->stats.ns_rspnid_alloc_wait++; bfa_fcxp_alloc_wait(port->fcs->bfa, &ns->fcxp_wqe, bfa_fcs_port_ns_send_rspn_id, ns); return; } ns->fcxp = fcxp; /* * for V-Port, form a Port Symbolic Name */ if (port->vport) { /**For Vports, * we append the vport's port symbolic name to that of the base port. */ strncpy((char *)psymbl, (char *) &(bfa_fcs_port_get_psym_name (bfa_fcs_get_base_port(port->fcs))), strlen((char *) &bfa_fcs_port_get_psym_name(bfa_fcs_get_base_port (port->fcs)))); /* * Ensure we have a null terminating string. */ ((char *) psymbl)[strlen((char *) &bfa_fcs_port_get_psym_name (bfa_fcs_get_base_port(port->fcs)))] = 0; strncat((char *)psymbl, (char *)&(bfa_fcs_port_get_psym_name(port)), strlen((char *)&bfa_fcs_port_get_psym_name(port))); } else { psymbl = (u8 *) &(bfa_fcs_port_get_psym_name(port)); } len = fc_rspnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), bfa_fcs_port_get_fcid(port), 0, psymbl); bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs, bfa_fcs_port_ns_rspn_id_response, (void *)ns, FC_MAX_PDUSZ, FC_RA_TOV); port->stats.ns_rspnid_sent++; bfa_sm_send_event(ns, NSSM_EVENT_RSPNID_SENT); }