/** * Called by fcs/port to notify transition to online state. */ void bfa_fcs_port_n2n_online(struct bfa_fcs_port_s *port) { struct bfa_fcs_port_n2n_s *n2n_port = &port->port_topo.pn2n; struct bfa_port_cfg_s *pcfg = &port->port_cfg; struct bfa_fcs_rport_s *rport; bfa_trc(port->fcs, pcfg->pwwn); /* * If our PWWN is > than that of the r-port, we have to initiate PLOGI * and assign an Address. if not, we need to wait for its PLOGI. * * If our PWWN is < than that of the remote port, it will send a PLOGI * with the PIDs assigned. The rport state machine take care of this * incoming PLOGI. */ if (memcmp ((void *)&pcfg->pwwn, (void *)&n2n_port->rem_port_wwn, sizeof(wwn_t)) > 0) { port->pid = N2N_LOCAL_PID; /** * First, check if we know the device by pwwn. */ rport = bfa_fcs_port_get_rport_by_pwwn(port, n2n_port->rem_port_wwn); if (rport) { bfa_trc(port->fcs, rport->pid); bfa_trc(port->fcs, rport->pwwn); rport->pid = N2N_REMOTE_PID; bfa_fcs_rport_online(rport); return; } /* * In n2n there can be only one rport. Delete the old one whose * pid should be zero, because it is offline. */ if (port->num_rports > 0) { rport = bfa_fcs_port_get_rport_by_pid(port, 0); bfa_assert(rport != NULL); if (rport) { bfa_trc(port->fcs, rport->pwwn); bfa_fcs_rport_delete(rport); } } bfa_fcs_rport_create(port, N2N_REMOTE_PID); } }
/* * Process the PID list in GID_FT response */ static void bfa_fcs_port_ns_process_gidft_pids(struct bfa_fcs_port_s *port, u32 *pid_buf, u32 n_pids) { struct fcgs_gidft_resp_s *gidft_entry; struct bfa_fcs_rport_s *rport; u32 ii; for (ii = 0; ii < n_pids; ii++) { gidft_entry = (struct fcgs_gidft_resp_s *) &pid_buf[ii]; if (gidft_entry->pid == port->pid) continue; /* * Check if this rport already exists */ rport = bfa_fcs_port_get_rport_by_pid(port, gidft_entry->pid); if (rport == NULL) { /* * this is a new device. create rport */ rport = bfa_fcs_rport_create(port, gidft_entry->pid); } else { /* * this rport already exists */ bfa_fcs_rport_scn(rport); } bfa_trc(port->fcs, gidft_entry->pid); /* * if the last entry bit is set, bail out. */ if (gidft_entry->last) return; } }
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; }