aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/bfa/bfa_fcs_rport.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/bfa/bfa_fcs_rport.c')
-rw-r--r--drivers/scsi/bfa/bfa_fcs_rport.c3126
1 files changed, 3126 insertions, 0 deletions
diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c
new file mode 100644
index 00000000000..635f0cd8871
--- /dev/null
+++ b/drivers/scsi/bfa/bfa_fcs_rport.c
@@ -0,0 +1,3126 @@
+/*
+ * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
+ * All rights reserved
+ * www.brocade.com
+ *
+ * Linux driver for Brocade Fibre Channel Host Bus Adapter.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License (GPL) Version 2 as
+ * published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+/**
+ * rport.c Remote port implementation.
+ */
+
+#include "bfa_fcs.h"
+#include "bfa_fcbuild.h"
+#include "bfad_drv.h"
+
+BFA_TRC_FILE(FCS, RPORT);
+
+static u32
+bfa_fcs_rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000;
+ /* In millisecs */
+/*
+ * forward declarations
+ */
+static struct bfa_fcs_rport_s *bfa_fcs_rport_alloc(
+ struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid);
+static void bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport);
+static void bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport);
+static void bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport);
+static void bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport);
+static void bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport,
+ struct fc_logi_s *plogi);
+static void bfa_fcs_rport_timeout(void *arg);
+static void bfa_fcs_rport_send_plogi(void *rport_cbarg,
+ struct bfa_fcxp_s *fcxp_alloced);
+static void bfa_fcs_rport_send_plogiacc(void *rport_cbarg,
+ struct bfa_fcxp_s *fcxp_alloced);
+static void bfa_fcs_rport_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);
+static void bfa_fcs_rport_send_adisc(void *rport_cbarg,
+ struct bfa_fcxp_s *fcxp_alloced);
+static void bfa_fcs_rport_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);
+static void bfa_fcs_rport_send_nsdisc(void *rport_cbarg,
+ struct bfa_fcxp_s *fcxp_alloced);
+static void bfa_fcs_rport_gidpn_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);
+static void bfa_fcs_rport_gpnid_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);
+static void bfa_fcs_rport_send_logo(void *rport_cbarg,
+ struct bfa_fcxp_s *fcxp_alloced);
+static void bfa_fcs_rport_send_logo_acc(void *rport_cbarg);
+static void bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
+ struct fchs_s *rx_fchs, u16 len);
+static void bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport,
+ struct fchs_s *rx_fchs, u8 reason_code,
+ u8 reason_code_expl);
+static void bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
+ struct fchs_s *rx_fchs, u16 len);
+static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport);
+/**
+ * fcs_rport_sm FCS rport state machine events
+ */
+
+enum rport_event {
+ RPSM_EVENT_PLOGI_SEND = 1, /* new rport; start with PLOGI */
+ RPSM_EVENT_PLOGI_RCVD = 2, /* Inbound PLOGI from remote port */
+ RPSM_EVENT_PLOGI_COMP = 3, /* PLOGI completed to rport */
+ RPSM_EVENT_LOGO_RCVD = 4, /* LOGO from remote device */
+ RPSM_EVENT_LOGO_IMP = 5, /* implicit logo for SLER */
+ RPSM_EVENT_FCXP_SENT = 6, /* Frame from has been sent */
+ RPSM_EVENT_DELETE = 7, /* RPORT delete request */
+ RPSM_EVENT_SCN = 8, /* state change notification */
+ RPSM_EVENT_ACCEPTED = 9, /* Good response from remote device */
+ RPSM_EVENT_FAILED = 10, /* Request to rport failed. */
+ RPSM_EVENT_TIMEOUT = 11, /* Rport SM timeout event */
+ RPSM_EVENT_HCB_ONLINE = 12, /* BFA rport online callback */
+ RPSM_EVENT_HCB_OFFLINE = 13, /* BFA rport offline callback */
+ RPSM_EVENT_FC4_OFFLINE = 14, /* FC-4 offline complete */
+ RPSM_EVENT_ADDRESS_CHANGE = 15, /* Rport's PID has changed */
+ RPSM_EVENT_ADDRESS_DISC = 16, /* Need to Discover rport's PID */
+ RPSM_EVENT_PRLO_RCVD = 17, /* PRLO from remote device */
+ RPSM_EVENT_PLOGI_RETRY = 18, /* Retry PLOGI continously */
+};
+
+static void bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+static void bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
+ enum rport_event event);
+
+static struct bfa_sm_table_s rport_sm_table[] = {
+ {BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT},
+ {BFA_SM(bfa_fcs_rport_sm_plogi_sending), BFA_RPORT_PLOGI},
+ {BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE},
+ {BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY},
+ {BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI},
+ {BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE},
+ {BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE},
+ {BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY},
+ {BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY},
+ {BFA_SM(bfa_fcs_rport_sm_adisc_sending), BFA_RPORT_ADISC},
+ {BFA_SM(bfa_fcs_rport_sm_adisc), BFA_RPORT_ADISC},
+ {BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV},
+ {BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO},
+ {BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE},
+ {BFA_SM(bfa_fcs_rport_sm_hcb_offline), BFA_RPORT_OFFLINE},
+ {BFA_SM(bfa_fcs_rport_sm_hcb_logorcv), BFA_RPORT_LOGORCV},
+ {BFA_SM(bfa_fcs_rport_sm_hcb_logosend), BFA_RPORT_LOGO},
+ {BFA_SM(bfa_fcs_rport_sm_logo_sending), BFA_RPORT_LOGO},
+ {BFA_SM(bfa_fcs_rport_sm_offline), BFA_RPORT_OFFLINE},
+ {BFA_SM(bfa_fcs_rport_sm_nsdisc_sending), BFA_RPORT_NSDISC},
+ {BFA_SM(bfa_fcs_rport_sm_nsdisc_retry), BFA_RPORT_NSDISC},
+ {BFA_SM(bfa_fcs_rport_sm_nsdisc_sent), BFA_RPORT_NSDISC},
+};
+
+/**
+ * Beginning state.
+ */
+static void
+bfa_fcs_rport_sm_uninit(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_PLOGI_SEND:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
+ rport->plogi_retries = 0;
+ bfa_fcs_rport_send_plogi(rport, NULL);
+ break;
+
+ case RPSM_EVENT_PLOGI_RCVD:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
+ bfa_fcs_rport_send_plogiacc(rport, NULL);
+ break;
+
+ case RPSM_EVENT_PLOGI_COMP:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
+ bfa_fcs_rport_hal_online(rport);
+ break;
+
+ case RPSM_EVENT_ADDRESS_CHANGE:
+ case RPSM_EVENT_ADDRESS_DISC:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
+ rport->ns_retries = 0;
+ bfa_fcs_rport_send_nsdisc(rport, NULL);
+ break;
+ default:
+ bfa_sm_fault(rport->fcs, event);
+ }
+}
+
+/**
+ * PLOGI is being sent.
+ */
+static void
+bfa_fcs_rport_sm_plogi_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_plogi);
+ break;
+
+ case RPSM_EVENT_DELETE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
+ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
+ bfa_fcs_rport_free(rport);
+ 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;
+
+ case RPSM_EVENT_ADDRESS_CHANGE:
+ case RPSM_EVENT_SCN:
+ /* query the NS */
+ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
+ rport->ns_retries = 0;
+ bfa_fcs_rport_send_nsdisc(rport, NULL);
+ break;
+
+ case RPSM_EVENT_LOGO_IMP:
+ rport->pid = 0;
+ 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;
+
+
+ default:
+ bfa_sm_fault(rport->fcs, event);
+ }
+}
+
+/**
+ * PLOGI is being sent.
+ */
+static void
+bfa_fcs_rport_sm_plogiacc_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_hal_online);
+ bfa_fcs_rport_hal_online(rport);
+ break;
+
+ case RPSM_EVENT_DELETE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
+ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
+ bfa_fcs_rport_free(rport);
+ break;
+
+ case RPSM_EVENT_PLOGI_RCVD:
+ case RPSM_EVENT_SCN:
+ /**
+ * Ignore, SCN is possibly online notification.
+ */
+ break;
+
+ case RPSM_EVENT_ADDRESS_CHANGE:
+ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
+ rport->ns_retries = 0;
+ bfa_fcs_rport_send_nsdisc(rport, NULL);
+ break;
+
+ case RPSM_EVENT_LOGO_IMP:
+ rport->pid = 0;
+ 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_HCB_OFFLINE:
+ /**
+ * Ignore BFA callback, on a PLOGI receive we call bfa offline.
+ */
+ break;
+
+ default:
+ bfa_sm_fault(rport->fcs, event);
+ }
+}
+
+/**
+ * PLOGI is sent.
+ */
+static void
+bfa_fcs_rport_sm_plogi_retry(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_TIMEOUT:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
+ bfa_fcs_rport_send_plogi(rport, NULL);
+ break;
+
+ case RPSM_EVENT_DELETE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
+ bfa_timer_stop(&rport->timer);
+ bfa_fcs_rport_free(rport);
+ break;
+
+ case RPSM_EVENT_PRLO_RCVD:
+ case RPSM_EVENT_LOGO_RCVD:
+ break;
+
+ case RPSM_EVENT_PLOGI_RCVD:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
+ bfa_timer_stop(&rport->timer);
+ bfa_fcs_rport_send_plogiacc(rport, NULL);
+ break;
+
+ case RPSM_EVENT_ADDRESS_CHANGE:
+ case RPSM_EVENT_SCN:
+ bfa_timer_stop(&rport->timer);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
+ rport->ns_retries = 0;
+ bfa_fcs_rport_send_nsdisc(rport, NULL);
+ break;
+
+ case RPSM_EVENT_LOGO_IMP:
+ rport->pid = 0;
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
+ bfa_timer_stop(&rport->timer);
+ bfa_timer_start(rport->fcs->bfa, &rport->timer,
+ bfa_fcs_rport_timeout, rport,
+ bfa_fcs_rport_del_timeout);
+ break;
+
+ case RPSM_EVENT_PLOGI_COMP:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
+ bfa_timer_stop(&rport->timer);
+ bfa_fcs_rport_hal_online(rport);
+ break;
+
+ default:
+ bfa_sm_fault(rport->fcs, event);
+ }
+}
+
+/**
+ * PLOGI is sent.
+ */
+static void
+bfa_fcs_rport_sm_plogi(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_hal_online);
+ rport->plogi_retries = 0;
+ bfa_fcs_rport_hal_online(rport);
+ break;
+
+ case RPSM_EVENT_LOGO_RCVD:
+ bfa_fcs_rport_send_logo_acc(rport);
+ /*
+ * !! fall through !!
+ */
+ case RPSM_EVENT_PRLO_RCVD:
+ if (rport->prlo == BFA_TRUE)
+ bfa_fcs_rport_send_prlo_acc(rport);
+
+ bfa_fcxp_discard(rport->fcxp);
+ /*
+ * !! fall through !!
+ */
+ case RPSM_EVENT_FAILED:
+ if (rport->plogi_retries < BFA_FCS_RPORT_MAX_RETRIES) {
+ rport->plogi_retries++;
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
+ bfa_timer_start(rport->fcs->bfa, &rport->timer,
+ bfa_fcs_rport_timeout, rport,
+ BFA_FCS_RETRY_TIMEOUT);
+ } else {
+ bfa_stats(rport->port, rport_del_max_plogi_retry);
+ 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_PLOGI_RETRY:
+ rport->plogi_retries = 0;
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
+ bfa_timer_start(rport->fcs->bfa, &rport->timer,
+ bfa_fcs_rport_timeout, rport,
+ (FC_RA_TOV * 1000));
+ break;
+
+ case RPSM_EVENT_LOGO_IMP:
+ rport->pid = 0;
+ 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_ADDRESS_CHANGE:
+ case RPSM_EVENT_SCN:
+ bfa_fcxp_discard(rport->fcxp);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
+ rport->ns_retries = 0;
+ bfa_fcs_rport_send_nsdisc(rport, NULL);
+ 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_DELETE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
+ bfa_fcxp_discard(rport->fcxp);
+ bfa_fcs_rport_free(rport);
+ break;
+
+ case RPSM_EVENT_PLOGI_COMP:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
+ bfa_fcxp_discard(rport->fcxp);
+ bfa_fcs_rport_hal_online(rport);
+ break;
+
+ default:
+ bfa_sm_fault(rport->fcs, event);
+ }
+}
+
+/**
+ * PLOGI is complete. Awaiting BFA rport online callback. FC-4s
+ * are offline.
+ */
+static void
+bfa_fcs_rport_sm_hal_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_HCB_ONLINE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
+ bfa_fcs_rport_online_action(rport);
+ break;
+
+ case RPSM_EVENT_PRLO_RCVD:
+ break;
+
+ case RPSM_EVENT_LOGO_RCVD:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
+ bfa_rport_offline(rport->bfa_rport);
+ break;
+
+ case RPSM_EVENT_LOGO_IMP:
+ case RPSM_EVENT_ADDRESS_CHANGE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
+ bfa_rport_offline(rport->bfa_rport);
+ break;
+
+ case RPSM_EVENT_PLOGI_RCVD:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
+ bfa_rport_offline(rport->bfa_rport);
+ bfa_fcs_rport_send_plogiacc(rport, NULL);
+ break;
+
+ case RPSM_EVENT_DELETE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
+ bfa_rport_offline(rport->bfa_rport);
+ break;
+
+ case RPSM_EVENT_SCN:
+ /**
+ * @todo
+ * Ignore SCN - PLOGI just completed, FC-4 login should detect
+ * device failures.
+ */
+ break;
+
+ default:
+ bfa_sm_fault(rport->fcs, event);
+ }
+}
+
+/**
+ * Rport is ONLINE. FC-4s active.
+ */
+static void
+bfa_fcs_rport_sm_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_SCN:
+ if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
+ bfa_sm_set_state(rport,
+ bfa_fcs_rport_sm_nsquery_sending);
+ rport->ns_retries = 0;
+ bfa_fcs_rport_send_nsdisc(rport, NULL);
+ } else {
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
+ bfa_fcs_rport_send_adisc(rport, NULL);
+ }
+ break;
+
+ case RPSM_EVENT_PLOGI_RCVD:
+ case RPSM_EVENT_LOGO_IMP:
+ case RPSM_EVENT_ADDRESS_CHANGE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
+ bfa_fcs_rport_offline_action(rport);
+ break;
+
+ case RPSM_EVENT_DELETE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
+ bfa_fcs_rport_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_offline_action(rport);
+ break;
+
+ 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.
+ */
+static void
+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_offline_action(rport);
+ break;
+
+ case RPSM_EVENT_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_offline_action(rport);
+ break;
+
+ case RPSM_EVENT_LOGO_IMP:
+ rport->pid = 0;
+ 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:
+ 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_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.
+ */
+static void
+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_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_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_offline_action(rport);
+ break;
+
+ case RPSM_EVENT_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_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_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.
+ */
+static void
+bfa_fcs_rport_sm_adisc_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);
+ 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_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_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_offline_action(rport);
+ break;
+
+ case RPSM_EVENT_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_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.
+ */
+static void
+bfa_fcs_rport_sm_adisc(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);
+ /*
+ * !!! fall through !!!
+ */
+
+ case RPSM_EVENT_FAILED:
+ case RPSM_EVENT_ADDRESS_CHANGE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
+ bfa_fcs_rport_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_offline_action(rport);
+ break;
+
+ case RPSM_EVENT_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_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_offline_action(rport);
+ break;
+
+ default:
+ bfa_sm_fault(rport->fcs, event);
+ }
+}
+
+/**
+ * Rport has sent LOGO. Awaiting FC-4 offline completion callback.
+ */
+static void
+bfa_fcs_rport_sm_fc4_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_FC4_OFFLINE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
+ bfa_rport_offline(rport->bfa_rport);
+ break;
+
+ case RPSM_EVENT_DELETE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
+ break;
+
+ 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.
+ */
+static void
+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_rport_offline(rport->bfa_rport);
+ break;
+
+ default:
+ bfa_sm_fault(rport->fcs, event);
+ }
+}
+
+/**
+ * Rport is going offline. Awaiting FC-4 offline completion callback.
+ */
+static void
+bfa_fcs_rport_sm_fc4_offline(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_offline);
+ bfa_rport_offline(rport->bfa_rport);
+ break;
+
+ case RPSM_EVENT_SCN:
+ case RPSM_EVENT_LOGO_IMP:
+ case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
+ 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;
+
+ default:
+ bfa_sm_fault(rport->fcs, event);
+ }
+}
+
+/**
+ * Rport is offline. FC-4s are offline. Awaiting BFA rport offline
+ * callback.
+ */
+static void
+bfa_fcs_rport_sm_hcb_offline(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 (bfa_fcs_lport_is_online(rport->port)) {
+ 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 {
+ bfa_sm_set_state(rport,
+ bfa_fcs_rport_sm_plogi_sending);
+ rport->plogi_retries = 0;
+ bfa_fcs_rport_send_plogi(rport, NULL);
+ }
+ } else {
+ 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_uninit);
+ bfa_fcs_rport_free(rport);
+ break;
+
+ case RPSM_EVENT_SCN:
+ case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
+ /**
+ * 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.
+ */
+static void
+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))) {
+ bfa_sm_set_state(rport,
+ bfa_fcs_rport_sm_nsdisc_sending);
+ rport->ns_retries = 0;
+ bfa_fcs_rport_send_nsdisc(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_hcb_logosend);
+ break;
+
+ case RPSM_EVENT_LOGO_IMP:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
+ break;
+
+ 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.
+ */
+static void
+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:
+ case RPSM_EVENT_PRLO_RCVD:
+ 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.
+ */
+static void
+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:
+ case RPSM_EVENT_ADDRESS_CHANGE:
+ break;
+
+ case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
+ bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
+ bfa_fcs_rport_free(rport);
+ break;
+
+ default:
+ bfa_sm_fault(rport->fcs, event);
+ }
+}
+
+/**
+ * Rport is offline. FC-4s are offline. BFA rport is offline.
+ * Timer active to delete stale rport.
+ */
+static void
+bfa_fcs_rport_sm_offline(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_TIMEOUT:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
+ bfa_fcs_rport_free(rport);
+ break;
+
+ case RPSM_EVENT_SCN:
+ case RPSM_EVENT_ADDRESS_CHANGE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
+ bfa_timer_stop(&rport->timer);
+ rport->ns_retries = 0;
+ bfa_fcs_rport_send_nsdisc(rport, NULL);
+ break;
+
+ case RPSM_EVENT_DELETE:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
+ bfa_timer_stop(&rport->timer);
+ bfa_fcs_rport_free(rport);
+ break;
+
+ case RPSM_EVENT_PLOGI_RCVD:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
+ bfa_timer_stop(&rport->timer);
+ bfa_fcs_rport_send_plogiacc(rport, NULL);
+ break;
+
+ case RPSM_EVENT_LOGO_RCVD:
+ case RPSM_EVENT_PRLO_RCVD:
+ case RPSM_EVENT_LOGO_IMP:
+ break;
+
+ case RPSM_EVENT_PLOGI_COMP:
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
+ bfa_timer_stop(&rport->timer);
+ bfa_fcs_rport_hal_online(rport);
+ break;
+
+ case RPSM_EVENT_PLOGI_SEND:
+ bfa_timer_stop(&rport->timer);
+ bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
+ rport->plogi_retries = 0;
+ bfa_fcs_rport_send_plogi(rport, NULL);
+ break;
+
+ default:
+ bfa_sm_fault(rport->fcs, event);
+ }
+}
+
+/**
+ * Rport address has changed. Nameserver discovery request is being sent.
+ */
+static void
+bfa_fcs_rport_sm_nsdisc_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_nsdisc_sent);
+ break;
+
+ case