static u32
bfa_fcs_rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000; /* In millisecs */ /* * bfa_fcs_rport_max_logins is max count of bfa_fcs_rports * whereas DEF_CFG_NUM_RPORTS is max count of bfa_rports
*/ static u32 bfa_fcs_rport_max_logins = BFA_FCS_MAX_RPORT_LOGINS;
struct bfa_fcs_rport_sm_table_s {
bfa_fcs_rport_sm_t sm; /* state machine function */ enum bfa_rport_state state; /* state machine encoding */ char *name; /* state name for display */
};
staticinlineenum bfa_rport_state
bfa_rport_sm_to_state(struct bfa_fcs_rport_sm_table_s *smt, bfa_fcs_rport_sm_t sm)
{ int i = 0;
while (smt[i].sm && smt[i].sm != sm)
i++; return smt[i].state;
}
case RPSM_EVENT_LOGO_RCVD:
bfa_fcs_rport_send_logo_acc(rport);
fallthrough; case RPSM_EVENT_PRLO_RCVD: if (rport->prlo == BFA_TRUE)
bfa_fcs_rport_send_prlo_acc(rport);
case RPSM_EVENT_PLOGI_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
rport->plogi_pending = BFA_TRUE;
bfa_fcs_rport_fcs_offline_action(rport); break;
case RPSM_EVENT_PLOGI_COMP: case RPSM_EVENT_LOGO_IMP: case RPSM_EVENT_ADDRESS_CHANGE: case RPSM_EVENT_FAB_SCN: case RPSM_EVENT_SCN_OFFLINE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
bfa_fcs_rport_fcs_offline_action(rport); break;
case RPSM_EVENT_LOGO_RCVD: case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
bfa_fcs_rport_fcs_offline_action(rport); break;
case RPSM_EVENT_DELETE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
bfa_fcs_rport_fcs_offline_action(rport); break;
switch (event) { case RPSM_EVENT_HCB_ONLINE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
bfa_fcs_rport_hal_online_action(rport); break;
case RPSM_EVENT_PLOGI_COMP: break;
case RPSM_EVENT_PRLO_RCVD: case RPSM_EVENT_LOGO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
bfa_fcs_rport_fcs_offline_action(rport); break;
case RPSM_EVENT_FAB_SCN: case RPSM_EVENT_LOGO_IMP: case RPSM_EVENT_ADDRESS_CHANGE: case RPSM_EVENT_SCN_OFFLINE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
bfa_fcs_rport_fcs_offline_action(rport); break;
case RPSM_EVENT_PLOGI_RCVD:
rport->plogi_pending = BFA_TRUE;
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
bfa_fcs_rport_fcs_offline_action(rport); break;
case RPSM_EVENT_DELETE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
bfa_fcs_rport_fcs_offline_action(rport); break;
case RPSM_EVENT_PLOGI_RCVD: case RPSM_EVENT_LOGO_IMP: case RPSM_EVENT_ADDRESS_CHANGE: case RPSM_EVENT_SCN_OFFLINE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
bfa_fcs_rport_hal_offline_action(rport); break;
case RPSM_EVENT_DELETE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
bfa_fcs_rport_hal_offline_action(rport); break;
case RPSM_EVENT_LOGO_RCVD: case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
bfa_fcs_rport_hal_offline_action(rport); break;
case RPSM_EVENT_SCN_ONLINE: case RPSM_EVENT_PLOGI_COMP: break;
default:
bfa_sm_fault(rport->fcs, event);
}
}
/* * An SCN event is received in ONLINE state. NS query is being sent * prior to ADISC authentication with rport. FC-4s are paused.
*/ staticvoid
bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport, enum rport_event event)
{
bfa_trc(rport->fcs, rport->pwwn);
bfa_trc(rport->fcs, rport->pid);
bfa_trc(rport->fcs, event);
switch (event) { case RPSM_EVENT_FCXP_SENT:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsquery); break;
case RPSM_EVENT_DELETE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
bfa_fcs_rport_hal_offline_action(rport); break;
case RPSM_EVENT_FAB_SCN: /* * ignore SCN, wait for response to query itself
*/ break;
case RPSM_EVENT_LOGO_RCVD: case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
bfa_fcs_rport_hal_offline_action(rport); break;
case RPSM_EVENT_LOGO_IMP: case RPSM_EVENT_PLOGI_RCVD: case RPSM_EVENT_ADDRESS_CHANGE: case RPSM_EVENT_PLOGI_COMP:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
bfa_fcs_rport_hal_offline_action(rport); break;
default:
bfa_sm_fault(rport->fcs, event);
}
}
/* * An SCN event is received in ONLINE state. NS query is sent to rport. * FC-4s are paused.
*/ staticvoid
bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
{
bfa_trc(rport->fcs, rport->pwwn);
bfa_trc(rport->fcs, rport->pid);
bfa_trc(rport->fcs, event);
switch (event) { case RPSM_EVENT_ACCEPTED:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online_sending);
bfa_fcs_rport_send_adisc(rport, NULL); break;
case RPSM_EVENT_FAILED:
rport->ns_retries++; if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
bfa_sm_set_state(rport,
bfa_fcs_rport_sm_nsquery_sending);
bfa_fcs_rport_send_nsdisc(rport, NULL);
} else {
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
bfa_fcs_rport_hal_offline_action(rport);
} break;
case RPSM_EVENT_DELETE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
bfa_fcxp_discard(rport->fcxp);
bfa_fcs_rport_hal_offline_action(rport); break;
case RPSM_EVENT_FAB_SCN: break;
case RPSM_EVENT_LOGO_RCVD: case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
bfa_fcxp_discard(rport->fcxp);
bfa_fcs_rport_hal_offline_action(rport); break;
case RPSM_EVENT_PLOGI_COMP: case RPSM_EVENT_ADDRESS_CHANGE: case RPSM_EVENT_PLOGI_RCVD: case RPSM_EVENT_LOGO_IMP:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
bfa_fcxp_discard(rport->fcxp);
bfa_fcs_rport_hal_offline_action(rport); break;
default:
bfa_sm_fault(rport->fcs, event);
}
}
/* * An SCN event is received in ONLINE state. ADISC is being sent for * authenticating with rport. FC-4s are paused.
*/ staticvoid
bfa_fcs_rport_sm_adisc_online_sending(struct bfa_fcs_rport_s *rport, enum rport_event event)
{
bfa_trc(rport->fcs, rport->pwwn);
bfa_trc(rport->fcs, rport->pid);
bfa_trc(rport->fcs, event);
switch (event) { case RPSM_EVENT_FCXP_SENT:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online); break;
case RPSM_EVENT_DELETE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
bfa_fcs_rport_hal_offline_action(rport); break;
case RPSM_EVENT_LOGO_IMP: case RPSM_EVENT_ADDRESS_CHANGE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
bfa_fcs_rport_hal_offline_action(rport); break;
case RPSM_EVENT_LOGO_RCVD: case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
bfa_fcs_rport_hal_offline_action(rport); break;
case RPSM_EVENT_FAB_SCN: break;
case RPSM_EVENT_PLOGI_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
bfa_fcs_rport_hal_offline_action(rport); break;
default:
bfa_sm_fault(rport->fcs, event);
}
}
/* * An SCN event is received in ONLINE state. ADISC is to rport. * FC-4s are paused.
*/ staticvoid
bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
{
bfa_trc(rport->fcs, rport->pwwn);
bfa_trc(rport->fcs, rport->pid);
bfa_trc(rport->fcs, event);
switch (event) { case RPSM_EVENT_ACCEPTED:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_online); break;
case RPSM_EVENT_PLOGI_RCVD: /* * Too complex to cleanup FC-4 & rport and then acc to PLOGI. * At least go offline when a PLOGI is received.
*/
bfa_fcxp_discard(rport->fcxp);
fallthrough;
case RPSM_EVENT_FAILED: case RPSM_EVENT_ADDRESS_CHANGE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
bfa_fcs_rport_hal_offline_action(rport); break;
case RPSM_EVENT_DELETE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
bfa_fcxp_discard(rport->fcxp);
bfa_fcs_rport_hal_offline_action(rport); break;
case RPSM_EVENT_FAB_SCN: /* * already processing RSCN
*/ break;
case RPSM_EVENT_LOGO_IMP:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
bfa_fcxp_discard(rport->fcxp);
bfa_fcs_rport_hal_offline_action(rport); break;
case RPSM_EVENT_LOGO_RCVD: case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
bfa_fcxp_discard(rport->fcxp);
bfa_fcs_rport_hal_offline_action(rport); break;
default:
bfa_sm_fault(rport->fcs, event);
}
}
/* * ADISC is being sent for authenticating with rport * Already did offline actions.
*/ staticvoid
bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s *rport, enum rport_event event)
{
bfa_trc(rport->fcs, rport->pwwn);
bfa_trc(rport->fcs, rport->pid);
bfa_trc(rport->fcs, event);
switch (event) { case RPSM_EVENT_FCXP_SENT:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_offline); break;
case RPSM_EVENT_DELETE: case RPSM_EVENT_SCN_OFFLINE: case RPSM_EVENT_LOGO_IMP: case RPSM_EVENT_LOGO_RCVD: case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
bfa_fcxp_walloc_cancel(rport->fcs->bfa,
&rport->fcxp_wqe);
bfa_timer_start(rport->fcs->bfa, &rport->timer,
bfa_fcs_rport_timeout, rport,
bfa_fcs_rport_del_timeout); break;
case RPSM_EVENT_PLOGI_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
bfa_fcs_rport_send_plogiacc(rport, NULL); break;
switch (event) { case RPSM_EVENT_ACCEPTED:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
bfa_fcs_rport_hal_online(rport); break;
case RPSM_EVENT_PLOGI_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
bfa_fcxp_discard(rport->fcxp);
bfa_fcs_rport_send_plogiacc(rport, NULL); break;
case RPSM_EVENT_FAILED:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
bfa_timer_start(rport->fcs->bfa, &rport->timer,
bfa_fcs_rport_timeout, rport,
bfa_fcs_rport_del_timeout); break;
case RPSM_EVENT_DELETE: case RPSM_EVENT_SCN_OFFLINE: case RPSM_EVENT_LOGO_IMP: case RPSM_EVENT_LOGO_RCVD: case RPSM_EVENT_PRLO_RCVD:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
bfa_fcxp_discard(rport->fcxp);
bfa_timer_start(rport->fcs->bfa, &rport->timer,
bfa_fcs_rport_timeout, rport,
bfa_fcs_rport_del_timeout); break;
case RPSM_EVENT_SCN_ONLINE: case RPSM_EVENT_SCN_OFFLINE: case RPSM_EVENT_HCB_ONLINE: case RPSM_EVENT_LOGO_RCVD: case RPSM_EVENT_PRLO_RCVD: case RPSM_EVENT_ADDRESS_CHANGE: break;
default:
bfa_sm_fault(rport->fcs, event);
}
}
/* * LOGO needs to be sent to rport. Awaiting FC-4 offline completion * callback.
*/ staticvoid
bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport, enum rport_event event)
{
bfa_trc(rport->fcs, rport->pwwn);
bfa_trc(rport->fcs, rport->pid);
bfa_trc(rport->fcs, event);
switch (event) { case RPSM_EVENT_FC4_OFFLINE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
bfa_fcs_rport_hal_offline(rport); break;
case RPSM_EVENT_LOGO_RCVD:
bfa_fcs_rport_send_logo_acc(rport);
fallthrough; case RPSM_EVENT_PRLO_RCVD: if (rport->prlo == BFA_TRUE)
bfa_fcs_rport_send_prlo_acc(rport);
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete); break;
case RPSM_EVENT_HCB_ONLINE: case RPSM_EVENT_DELETE: /* Rport is being deleted */ break;
switch (event) { case RPSM_EVENT_FC4_OFFLINE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
bfa_fcs_rport_hal_offline(rport); break;
case RPSM_EVENT_SCN_ONLINE: break; case RPSM_EVENT_LOGO_RCVD: /* * Rport is going offline. Just ack the logo
*/
bfa_fcs_rport_send_logo_acc(rport); break;
case RPSM_EVENT_PRLO_RCVD:
bfa_fcs_rport_send_prlo_acc(rport); break;
case RPSM_EVENT_SCN_OFFLINE: case RPSM_EVENT_HCB_ONLINE: case RPSM_EVENT_FAB_SCN: case RPSM_EVENT_LOGO_IMP: case RPSM_EVENT_ADDRESS_CHANGE: /* * rport is already going offline. * SCN - ignore and wait till transitioning to offline state
*/ break;
case RPSM_EVENT_DELETE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend); break;
case RPSM_EVENT_DELETE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
bfa_fcs_rport_free(rport); break;
case RPSM_EVENT_SCN_ONLINE: case RPSM_EVENT_SCN_OFFLINE: case RPSM_EVENT_FAB_SCN: case RPSM_EVENT_LOGO_RCVD: case RPSM_EVENT_PRLO_RCVD: case RPSM_EVENT_PLOGI_RCVD: case RPSM_EVENT_LOGO_IMP: /* * Ignore, already offline.
*/ break;
default:
bfa_sm_fault(rport->fcs, event);
}
}
/* * Rport is offline. FC-4s are offline. Awaiting BFA rport offline * callback to send LOGO accept.
*/ staticvoid
bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport, enum rport_event event)
{
bfa_trc(rport->fcs, rport->pwwn);
bfa_trc(rport->fcs, rport->pid);
bfa_trc(rport->fcs, event);
switch (event) { case RPSM_EVENT_HCB_OFFLINE: case RPSM_EVENT_ADDRESS_CHANGE: if (rport->pid && (rport->prlo == BFA_TRUE))
bfa_fcs_rport_send_prlo_acc(rport); if (rport->pid && (rport->prlo == BFA_FALSE))
bfa_fcs_rport_send_logo_acc(rport); /* * If the lport is online and if the rport is not a well * known address port, * we try to re-discover the r-port.
*/ if (bfa_fcs_lport_is_online(rport->port) &&
(!BFA_FCS_PID_IS_WKA(rport->pid))) { if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
bfa_sm_set_state(rport,
bfa_fcs_rport_sm_nsdisc_sending);
rport->ns_retries = 0;
bfa_fcs_rport_send_nsdisc(rport, NULL);
} else { /* For N2N Direct Attach, try to re-login */
bfa_sm_set_state(rport,
bfa_fcs_rport_sm_plogi_sending);
rport->plogi_retries = 0;
bfa_fcs_rport_send_plogi(rport, NULL);
}
} else { /* * if it is not a well known address, reset the * pid to 0.
*/ if (!BFA_FCS_PID_IS_WKA(rport->pid))
rport->pid = 0;
bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
bfa_timer_start(rport->fcs->bfa, &rport->timer,
bfa_fcs_rport_timeout, rport,
bfa_fcs_rport_del_timeout);
} break;
case RPSM_EVENT_DELETE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending); if (rport->pid && (rport->prlo == BFA_TRUE))
bfa_fcs_rport_send_prlo_acc(rport); if (rport->pid && (rport->prlo == BFA_FALSE))
bfa_fcs_rport_send_logo_acc(rport); break;
case RPSM_EVENT_LOGO_IMP:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline); break;
case RPSM_EVENT_SCN_ONLINE: case RPSM_EVENT_SCN_OFFLINE: case RPSM_EVENT_LOGO_RCVD: case RPSM_EVENT_PRLO_RCVD: /* * Ignore - already processing a LOGO.
*/ break;
default:
bfa_sm_fault(rport->fcs, event);
}
}
/* * Rport is being deleted. FC-4s are offline. * Awaiting BFA rport offline * callback to send LOGO.
*/ staticvoid
bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport, enum rport_event event)
{
bfa_trc(rport->fcs, rport->pwwn);
bfa_trc(rport->fcs, rport->pid);
bfa_trc(rport->fcs, event);
switch (event) { case RPSM_EVENT_HCB_OFFLINE:
bfa_sm_set_state(rport, bfa_fcs_rport_sm_logo_sending);
bfa_fcs_rport_send_logo(rport, NULL); break;
case RPSM_EVENT_LOGO_RCVD:
bfa_fcs_rport_send_logo_acc(rport);
fallthrough; case RPSM_EVENT_PRLO_RCVD: if (rport->prlo == BFA_TRUE)
bfa_fcs_rport_send_prlo_acc(rport);
case RPSM_EVENT_SCN_ONLINE: case RPSM_EVENT_SCN_OFFLINE: case RPSM_EVENT_ADDRESS_CHANGE: break;
default:
bfa_sm_fault(rport->fcs, event);
}
}
/* * Rport is being deleted. FC-4s are offline. LOGO is being sent.
*/ staticvoid
bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport, enum rport_event event)
{
bfa_trc(rport->fcs, rport->pwwn);
bfa_trc(rport->fcs, rport->pid);
bfa_trc(rport->fcs, event);
switch (event) { case RPSM_EVENT_FCXP_SENT: /* Once LOGO is sent, we donot wait for the response */
bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
bfa_fcs_rport_free(rport); break;
case RPSM_EVENT_SCN_ONLINE: case RPSM_EVENT_SCN_OFFLINE: case RPSM_EVENT_FAB_SCN: case RPSM_EVENT_ADDRESS_CHANGE: break;
case RPSM_EVENT_LOGO_RCVD:
bfa_fcs_rport_send_logo_acc(rport);
fallthrough; case RPSM_EVENT_PRLO_RCVD: if (rport->prlo == BFA_TRUE)
bfa_fcs_rport_send_prlo_acc(rport);
/* * PLOGI is complete. Make sure this device is not one of the known * device with a new FC port address.
*/
list_for_each(qe, &rport->port->rport_q) {
twin = (struct bfa_fcs_rport_s *) qe; if (twin == rport) continue; if (!rport->pwwn && (plogi_rsp->port_name == twin->pwwn)) {
bfa_trc(rport->fcs, twin->pid);
bfa_trc(rport->fcs, rport->pid);
if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) { /* Check if the pid is the same as before. */
gidpn_rsp = (struct fcgs_gidpn_resp_s *) (cthdr + 1);
if (gidpn_rsp->dap == rport->pid) { /* Device is online */
bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
} else { /* * Device's PID has changed. We need to cleanup * and re-login. If there is another device with * the the newly discovered pid, send an scn notice * so that its new pid can be discovered.
*/
list_for_each(qe, &rport->port->rport_q) {
twin = (struct bfa_fcs_rport_s *) qe; if (twin == rport) continue; if (gidpn_rsp->dap == twin->pid) {
bfa_trc(rport->fcs, twin->pid);
bfa_trc(rport->fcs, rport->pid);
/* * We are in Initiator Mode
*/
prli = (struct fc_prli_s *) (rx_fchs + 1);
if (prli->parampage.servparams.target) { /* * PRLI from a target ? * Send the Acc. * PRLI sent by us will be used to transition the IT nexus, * once the response is received from the target.
*/
bfa_trc(port->fcs, rx_fchs->s_id);
rport->scsi_function = BFA_RPORT_TARGET;
} else {
bfa_trc(rport->fcs, prli->parampage.type);
rport->scsi_function = BFA_RPORT_INITIATOR;
bfa_fcs_itnim_is_initiator(rport->itnim);
}
fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE); if (!fcxp) return;
len = fc_prli_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
rx_fchs->ox_id, port->port_cfg.roles);
if ((!rport->pid) || (!rport->pwwn)) {
bfa_trc(rport->fcs, rport->pid);
bfa_sm_fault(rport->fcs, rport->pid);
}
if (bfa_fcs_lport_is_initiator(port)) {
bfa_fcs_itnim_brp_online(rport->itnim); if (!BFA_FCS_PID_IS_WKA(rport->pid))
bfa_fcs_rpf_rport_online(rport);
}
wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
wwn2str(rpwwn_buf, rport->pwwn); if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Remote port (WWN = %s) online for logical port (WWN = %s)\n",
rpwwn_buf, lpwwn_buf);
bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_ONLINE, NULL);
}
}
staticvoid
bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport)
{ if (!BFA_FCS_PID_IS_WKA(rport->pid))
bfa_fcs_rpf_rport_offline(rport);
if (!rport->bfa_rport) {
bfa_fcs_rport_fcs_offline_action(rport); return;
}
rport->stats.offlines++;
wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
wwn2str(rpwwn_buf, rport->pwwn); if (!BFA_FCS_PID_IS_WKA(rport->pid)) { if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE) {
BFA_LOG(KERN_ERR, bfad, bfa_log_level, "Remote port (WWN = %s) connectivity lost for " "logical port (WWN = %s)\n",
rpwwn_buf, lpwwn_buf);
bfa_fcs_rport_aen_post(rport,
BFA_RPORT_AEN_DISCONNECT, NULL);
} else {
BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Remote port (WWN = %s) offlined by " "logical port (WWN = %s)\n",
rpwwn_buf, lpwwn_buf);
bfa_fcs_rport_aen_post(rport,
BFA_RPORT_AEN_OFFLINE, NULL);
}
}
if (bfa_fcs_lport_is_initiator(port)) {
bfa_fcs_itnim_rport_offline(rport->itnim); if (!BFA_FCS_PID_IS_WKA(rport->pid))
bfa_fcs_rpf_rport_offline(rport);
}
}
bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
bfa_trc(port->fcs, port->fabric->bb_credit); /* * Direct Attach P2P mode : * This is to handle a bug (233476) in IBM targets in Direct Attach * Mode. Basically, in FLOGI Accept the target would have * erroneously set the BB Credit to the value used in the FLOGI * sent by the HBA. It uses the correct value (its own BB credit) * in PLOGI.
*/ if ((!bfa_fcs_fabric_is_switched(port->fabric)) &&
(be16_to_cpu(plogi->csp.bbcred) < port->fabric->bb_credit)) {
/* * Called to handle LOGO received from an existing remote port.
*/ staticvoid
bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs)
{
rport->reply_oxid = fchs->ox_id;
bfa_trc(rport->fcs, rport->reply_oxid);
/* * fcs_rport_public FCS rport public interfaces
*/
/* * Called by bport/vport to create a remote port instance for a discovered * remote device. * * @param[in] port - base port or vport * @param[in] rpid - remote port ID * * @return None
*/ struct bfa_fcs_rport_s *
bfa_fcs_rport_create(struct bfa_fcs_lport_s *port, u32 rpid)
{ struct bfa_fcs_rport_s *rport;
/* * Called to create a rport for which only the wwn is known. * * @param[in] port - base port * @param[in] rpwwn - remote port wwn * * @return None
*/ struct bfa_fcs_rport_s *
bfa_fcs_rport_create_by_wwn(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
{ struct bfa_fcs_rport_s *rport;
bfa_trc(port->fcs, rpwwn);
rport = bfa_fcs_rport_alloc(port, rpwwn, 0); if (!rport) return NULL;
/* * Called by bport/vport to handle PLOGI received from a new remote port. * If an existing rport does a plogi, it will be handled separately.
*/ void
bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port, struct fchs_s *fchs, struct fc_logi_s *plogi)
{ struct bfa_fcs_rport_s *rport;
rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id); if (!rport) return;
/* * Called by bport/vport to handle PLOGI received from an existing * remote port.
*/ void
bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs, struct fc_logi_s *plogi)
{ /* * @todo Handle P2P and initiator-initiator.
*/
/* * Called by bport/vport to notify SCN for the remote port
*/ void
bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
{
rport->stats.rscns++;
bfa_sm_send_event(rport, RPSM_EVENT_FAB_SCN);
}
/* * Called to process any unsolicted frames from this remote port
*/ void
bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs, u16 len)
{ struct bfa_fcs_lport_s *port = rport->port; struct fc_els_cmd_s *els_cmd;
/* * Called by BFAD to set the max limit on number of bfa_fcs_rport allocation * which limits number of concurrent logins to remote ports
*/ void
bfa_fcs_rport_set_max_logins(u32 max_logins)
{ if (max_logins > 0)
bfa_fcs_rport_max_logins = max_logins;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.