xref: /openbmc/linux/drivers/scsi/bfa/bfa_fcs_rport.c (revision 61ba4394)
1a36c61f9SKrishna Gudipati /*
2a36c61f9SKrishna Gudipati  * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
3a36c61f9SKrishna Gudipati  * All rights reserved
4a36c61f9SKrishna Gudipati  * www.brocade.com
5a36c61f9SKrishna Gudipati  *
6a36c61f9SKrishna Gudipati  * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7a36c61f9SKrishna Gudipati  *
8a36c61f9SKrishna Gudipati  * This program is free software; you can redistribute it and/or modify it
9a36c61f9SKrishna Gudipati  * under the terms of the GNU General Public License (GPL) Version 2 as
10a36c61f9SKrishna Gudipati  * published by the Free Software Foundation
11a36c61f9SKrishna Gudipati  *
12a36c61f9SKrishna Gudipati  * This program is distributed in the hope that it will be useful, but
13a36c61f9SKrishna Gudipati  * WITHOUT ANY WARRANTY; without even the implied warranty of
14a36c61f9SKrishna Gudipati  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15a36c61f9SKrishna Gudipati  * General Public License for more details.
16a36c61f9SKrishna Gudipati  */
17a36c61f9SKrishna Gudipati 
185fbe25c7SJing Huang /*
19a36c61f9SKrishna Gudipati  *  rport.c Remote port implementation.
20a36c61f9SKrishna Gudipati  */
21a36c61f9SKrishna Gudipati 
22f16a1750SMaggie Zhang #include "bfad_drv.h"
237826f304SKrishna Gudipati #include "bfad_im.h"
24a36c61f9SKrishna Gudipati #include "bfa_fcs.h"
25a36c61f9SKrishna Gudipati #include "bfa_fcbuild.h"
26a36c61f9SKrishna Gudipati 
27a36c61f9SKrishna Gudipati BFA_TRC_FILE(FCS, RPORT);
28a36c61f9SKrishna Gudipati 
29a36c61f9SKrishna Gudipati static u32
30a36c61f9SKrishna Gudipati bfa_fcs_rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000;
31a36c61f9SKrishna Gudipati 	 /* In millisecs */
32a36c61f9SKrishna Gudipati /*
3361ba4394SKrishna Gudipati  * bfa_fcs_rport_max_logins is max count of bfa_fcs_rports
3461ba4394SKrishna Gudipati  * whereas DEF_CFG_NUM_RPORTS is max count of bfa_rports
3561ba4394SKrishna Gudipati  */
3661ba4394SKrishna Gudipati static u32 bfa_fcs_rport_max_logins = BFA_FCS_MAX_RPORT_LOGINS;
3761ba4394SKrishna Gudipati 
3861ba4394SKrishna Gudipati /*
39a36c61f9SKrishna Gudipati  * forward declarations
40a36c61f9SKrishna Gudipati  */
41a36c61f9SKrishna Gudipati static struct bfa_fcs_rport_s *bfa_fcs_rport_alloc(
42a36c61f9SKrishna Gudipati 		struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid);
43a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport);
44a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport);
4561ba4394SKrishna Gudipati static void	bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport);
4661ba4394SKrishna Gudipati static void	bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport);
4761ba4394SKrishna Gudipati static void	bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport);
4861ba4394SKrishna Gudipati static void	bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport);
49a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport,
50a36c61f9SKrishna Gudipati 					struct fc_logi_s *plogi);
51a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_timeout(void *arg);
52a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_plogi(void *rport_cbarg,
53a36c61f9SKrishna Gudipati 					 struct bfa_fcxp_s *fcxp_alloced);
54a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_plogiacc(void *rport_cbarg,
55a36c61f9SKrishna Gudipati 					struct bfa_fcxp_s *fcxp_alloced);
56a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_plogi_response(void *fcsarg,
57a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp, void *cbarg,
58a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
59a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs);
60a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_adisc(void *rport_cbarg,
61a36c61f9SKrishna Gudipati 					 struct bfa_fcxp_s *fcxp_alloced);
62a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_adisc_response(void *fcsarg,
63a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp, void *cbarg,
64a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
65a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs);
66a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_nsdisc(void *rport_cbarg,
67a36c61f9SKrishna Gudipati 					 struct bfa_fcxp_s *fcxp_alloced);
68a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_gidpn_response(void *fcsarg,
69a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp, void *cbarg,
70a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
71a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs);
72a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_gpnid_response(void *fcsarg,
73a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp, void *cbarg,
74a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
75a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs);
76a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_logo(void *rport_cbarg,
77a36c61f9SKrishna Gudipati 					struct bfa_fcxp_s *fcxp_alloced);
78a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_logo_acc(void *rport_cbarg);
79a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
80a36c61f9SKrishna Gudipati 					struct fchs_s *rx_fchs, u16 len);
81a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport,
82a36c61f9SKrishna Gudipati 				struct fchs_s *rx_fchs, u8 reason_code,
83a36c61f9SKrishna Gudipati 					  u8 reason_code_expl);
84a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
85a36c61f9SKrishna Gudipati 				struct fchs_s *rx_fchs, u16 len);
86a36c61f9SKrishna Gudipati static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport);
8761ba4394SKrishna Gudipati static void	bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport);
88a36c61f9SKrishna Gudipati 
89a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport,
90a36c61f9SKrishna Gudipati 					enum rport_event event);
91a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
92a36c61f9SKrishna Gudipati 						enum rport_event event);
93a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
94a36c61f9SKrishna Gudipati 						  enum rport_event event);
95a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
96a36c61f9SKrishna Gudipati 						enum rport_event event);
97a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport,
98a36c61f9SKrishna Gudipati 					enum rport_event event);
9961ba4394SKrishna Gudipati static void	bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport,
10061ba4394SKrishna Gudipati 					enum rport_event event);
101a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
102a36c61f9SKrishna Gudipati 						enum rport_event event);
103a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport,
104a36c61f9SKrishna Gudipati 					enum rport_event event);
105a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
106a36c61f9SKrishna Gudipati 						 enum rport_event event);
107a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport,
108a36c61f9SKrishna Gudipati 					 enum rport_event event);
109a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
110a36c61f9SKrishna Gudipati 						enum rport_event event);
111a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport,
112a36c61f9SKrishna Gudipati 					enum rport_event event);
113a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
114a36c61f9SKrishna Gudipati 						enum rport_event event);
115a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
116a36c61f9SKrishna Gudipati 						enum rport_event event);
117a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
118a36c61f9SKrishna Gudipati 						enum rport_event event);
119a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
120a36c61f9SKrishna Gudipati 						enum rport_event event);
121a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
122a36c61f9SKrishna Gudipati 						enum rport_event event);
123a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
124a36c61f9SKrishna Gudipati 						enum rport_event event);
125a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
126a36c61f9SKrishna Gudipati 						enum rport_event event);
127a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport,
128a36c61f9SKrishna Gudipati 					 enum rport_event event);
129a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
130a36c61f9SKrishna Gudipati 						enum rport_event event);
131a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
132a36c61f9SKrishna Gudipati 						enum rport_event event);
133a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
134a36c61f9SKrishna Gudipati 						enum rport_event event);
135a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
136a36c61f9SKrishna Gudipati 						enum rport_event event);
13761ba4394SKrishna Gudipati static void	bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s *rport,
13861ba4394SKrishna Gudipati 						enum rport_event event);
13961ba4394SKrishna Gudipati static void	bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s *rport,
14061ba4394SKrishna Gudipati 						enum rport_event event);
141a36c61f9SKrishna Gudipati 
142a36c61f9SKrishna Gudipati static struct bfa_sm_table_s rport_sm_table[] = {
143a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT},
144a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_plogi_sending), BFA_RPORT_PLOGI},
145a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE},
146a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY},
147a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI},
14861ba4394SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_fc4_fcs_online), BFA_RPORT_ONLINE},
149a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE},
150a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE},
151a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY},
152a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY},
153a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_adisc_sending), BFA_RPORT_ADISC},
154a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_adisc), BFA_RPORT_ADISC},
155a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV},
156a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO},
157a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE},
158a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_hcb_offline), BFA_RPORT_OFFLINE},
159a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_hcb_logorcv), BFA_RPORT_LOGORCV},
160a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_hcb_logosend), BFA_RPORT_LOGO},
161a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_logo_sending), BFA_RPORT_LOGO},
162a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_offline), BFA_RPORT_OFFLINE},
163a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsdisc_sending), BFA_RPORT_NSDISC},
164a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsdisc_retry), BFA_RPORT_NSDISC},
165a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsdisc_sent), BFA_RPORT_NSDISC},
166a36c61f9SKrishna Gudipati };
167a36c61f9SKrishna Gudipati 
1685fbe25c7SJing Huang /*
169a36c61f9SKrishna Gudipati  *		Beginning state.
170a36c61f9SKrishna Gudipati  */
171a36c61f9SKrishna Gudipati static void
172a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event)
173a36c61f9SKrishna Gudipati {
174a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
175a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
176a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
177a36c61f9SKrishna Gudipati 
178a36c61f9SKrishna Gudipati 	switch (event) {
179a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_SEND:
180a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
181a36c61f9SKrishna Gudipati 		rport->plogi_retries = 0;
182a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogi(rport, NULL);
183a36c61f9SKrishna Gudipati 		break;
184a36c61f9SKrishna Gudipati 
185a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
18661ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
18761ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
188a36c61f9SKrishna Gudipati 		break;
189a36c61f9SKrishna Gudipati 
190a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
191a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
192a36c61f9SKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
193a36c61f9SKrishna Gudipati 		break;
194a36c61f9SKrishna Gudipati 
195a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
196a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_DISC:
197a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
198a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
199a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
200a36c61f9SKrishna Gudipati 		break;
201a36c61f9SKrishna Gudipati 	default:
202a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
203a36c61f9SKrishna Gudipati 	}
204a36c61f9SKrishna Gudipati }
205a36c61f9SKrishna Gudipati 
2065fbe25c7SJing Huang /*
207a36c61f9SKrishna Gudipati  *		PLOGI is being sent.
208a36c61f9SKrishna Gudipati  */
209a36c61f9SKrishna Gudipati static void
210a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
211a36c61f9SKrishna Gudipati 	 enum rport_event event)
212a36c61f9SKrishna Gudipati {
213a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
214a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
215a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
216a36c61f9SKrishna Gudipati 
217a36c61f9SKrishna Gudipati 	switch (event) {
218a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
219a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi);
220a36c61f9SKrishna Gudipati 		break;
221a36c61f9SKrishna Gudipati 
222a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
223a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
224a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
225a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
226a36c61f9SKrishna Gudipati 		break;
227a36c61f9SKrishna Gudipati 
228a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
229a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
230a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
231a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
232a36c61f9SKrishna Gudipati 		break;
233a36c61f9SKrishna Gudipati 
234a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
235a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
236a36c61f9SKrishna Gudipati 		/* query the NS */
237a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
238a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
239a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
240a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
241a36c61f9SKrishna Gudipati 		break;
242a36c61f9SKrishna Gudipati 
243a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
244a36c61f9SKrishna Gudipati 		rport->pid = 0;
245a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
246a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
247a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
248a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
249a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
250a36c61f9SKrishna Gudipati 		break;
251a36c61f9SKrishna Gudipati 
252a36c61f9SKrishna Gudipati 
253a36c61f9SKrishna Gudipati 	default:
254a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
255a36c61f9SKrishna Gudipati 	}
256a36c61f9SKrishna Gudipati }
257a36c61f9SKrishna Gudipati 
2585fbe25c7SJing Huang /*
259a36c61f9SKrishna Gudipati  *		PLOGI is being sent.
260a36c61f9SKrishna Gudipati  */
261a36c61f9SKrishna Gudipati static void
262a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
263a36c61f9SKrishna Gudipati 	 enum rport_event event)
264a36c61f9SKrishna Gudipati {
265a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
266a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
267a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
268a36c61f9SKrishna Gudipati 
269a36c61f9SKrishna Gudipati 	switch (event) {
270a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
27161ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
27261ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
273a36c61f9SKrishna Gudipati 		break;
274a36c61f9SKrishna Gudipati 
275a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
276a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
277a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
278a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
279a36c61f9SKrishna Gudipati 		break;
280a36c61f9SKrishna Gudipati 
281a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
282d7be54ccSKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
283a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
2845fbe25c7SJing Huang 		/*
285a36c61f9SKrishna Gudipati 		 * Ignore, SCN is possibly online notification.
286a36c61f9SKrishna Gudipati 		 */
287a36c61f9SKrishna Gudipati 		break;
288a36c61f9SKrishna Gudipati 
289a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
290a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
291a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
292a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
293a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
294a36c61f9SKrishna Gudipati 		break;
295a36c61f9SKrishna Gudipati 
296a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
297a36c61f9SKrishna Gudipati 		rport->pid = 0;
298a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
299a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
300a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
301a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
302a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
303a36c61f9SKrishna Gudipati 		break;
304a36c61f9SKrishna Gudipati 
305a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
3065fbe25c7SJing Huang 		/*
307a36c61f9SKrishna Gudipati 		 * Ignore BFA callback, on a PLOGI receive we call bfa offline.
308a36c61f9SKrishna Gudipati 		 */
309a36c61f9SKrishna Gudipati 		break;
310a36c61f9SKrishna Gudipati 
311a36c61f9SKrishna Gudipati 	default:
312a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
313a36c61f9SKrishna Gudipati 	}
314a36c61f9SKrishna Gudipati }
315a36c61f9SKrishna Gudipati 
3165fbe25c7SJing Huang /*
317a36c61f9SKrishna Gudipati  *		PLOGI is sent.
318a36c61f9SKrishna Gudipati  */
319a36c61f9SKrishna Gudipati static void
320a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
321a36c61f9SKrishna Gudipati 			enum rport_event event)
322a36c61f9SKrishna Gudipati {
323a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
324a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
325a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
326a36c61f9SKrishna Gudipati 
327a36c61f9SKrishna Gudipati 	switch (event) {
328a36c61f9SKrishna Gudipati 	case RPSM_EVENT_TIMEOUT:
329a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
330a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogi(rport, NULL);
331a36c61f9SKrishna Gudipati 		break;
332a36c61f9SKrishna Gudipati 
333a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
334a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
335a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
336a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
337a36c61f9SKrishna Gudipati 		break;
338a36c61f9SKrishna Gudipati 
339a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
340a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
341a36c61f9SKrishna Gudipati 		break;
342a36c61f9SKrishna Gudipati 
343a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
344a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
345a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
346a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
347a36c61f9SKrishna Gudipati 		break;
348a36c61f9SKrishna Gudipati 
349a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
350a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
351a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
352a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
353a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
354a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
355a36c61f9SKrishna Gudipati 		break;
356a36c61f9SKrishna Gudipati 
357a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
358a36c61f9SKrishna Gudipati 		rport->pid = 0;
359a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
360a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
361a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
362a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
363a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
364a36c61f9SKrishna Gudipati 		break;
365a36c61f9SKrishna Gudipati 
366a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
36761ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
368a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
36961ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
370a36c61f9SKrishna Gudipati 		break;
371a36c61f9SKrishna Gudipati 
372a36c61f9SKrishna Gudipati 	default:
373a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
374a36c61f9SKrishna Gudipati 	}
375a36c61f9SKrishna Gudipati }
376a36c61f9SKrishna Gudipati 
3775fbe25c7SJing Huang /*
378a36c61f9SKrishna Gudipati  *		PLOGI is sent.
379a36c61f9SKrishna Gudipati  */
380a36c61f9SKrishna Gudipati static void
381a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
382a36c61f9SKrishna Gudipati {
383a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
384a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
385a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
386a36c61f9SKrishna Gudipati 
387a36c61f9SKrishna Gudipati 	switch (event) {
388a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ACCEPTED:
38961ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
390a36c61f9SKrishna Gudipati 		rport->plogi_retries = 0;
39161ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
392a36c61f9SKrishna Gudipati 		break;
393a36c61f9SKrishna Gudipati 
394a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
395a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
396a36c61f9SKrishna Gudipati 		/*
397a36c61f9SKrishna Gudipati 		 * !! fall through !!
398a36c61f9SKrishna Gudipati 		 */
399a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
400a36c61f9SKrishna Gudipati 		if (rport->prlo == BFA_TRUE)
401a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
402a36c61f9SKrishna Gudipati 
403a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
404a36c61f9SKrishna Gudipati 		/*
405a36c61f9SKrishna Gudipati 		 * !! fall through !!
406a36c61f9SKrishna Gudipati 		 */
407a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FAILED:
408a36c61f9SKrishna Gudipati 		if (rport->plogi_retries < BFA_FCS_RPORT_MAX_RETRIES) {
409a36c61f9SKrishna Gudipati 			rport->plogi_retries++;
410a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
411a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
412a36c61f9SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
413a36c61f9SKrishna Gudipati 					BFA_FCS_RETRY_TIMEOUT);
414a36c61f9SKrishna Gudipati 		} else {
415a36c61f9SKrishna Gudipati 			bfa_stats(rport->port, rport_del_max_plogi_retry);
416ee1a4a42SKrishna Gudipati 			rport->old_pid = rport->pid;
417a36c61f9SKrishna Gudipati 			rport->pid = 0;
418a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
419a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
420a36c61f9SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
421a36c61f9SKrishna Gudipati 					bfa_fcs_rport_del_timeout);
422a36c61f9SKrishna Gudipati 		}
423a36c61f9SKrishna Gudipati 		break;
424a36c61f9SKrishna Gudipati 
425a36c61f9SKrishna Gudipati 	case	RPSM_EVENT_PLOGI_RETRY:
426a36c61f9SKrishna Gudipati 		rport->plogi_retries = 0;
427a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
428a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
429a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
430a36c61f9SKrishna Gudipati 				(FC_RA_TOV * 1000));
431a36c61f9SKrishna Gudipati 		break;
432a36c61f9SKrishna Gudipati 
433a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
434a36c61f9SKrishna Gudipati 		rport->pid = 0;
435a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
436a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
437a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
438a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
439a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
440a36c61f9SKrishna Gudipati 		break;
441a36c61f9SKrishna Gudipati 
442a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
443a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
444a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
445a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
446a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
447a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
448a36c61f9SKrishna Gudipati 		break;
449a36c61f9SKrishna Gudipati 
450a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
451a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
452a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
453a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
454a36c61f9SKrishna Gudipati 		break;
455a36c61f9SKrishna Gudipati 
456a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
457a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
458a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
459a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
460a36c61f9SKrishna Gudipati 		break;
461a36c61f9SKrishna Gudipati 
462a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
46361ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
464a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
46561ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
466a36c61f9SKrishna Gudipati 		break;
467a36c61f9SKrishna Gudipati 
468a36c61f9SKrishna Gudipati 	default:
469a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
470a36c61f9SKrishna Gudipati 	}
471a36c61f9SKrishna Gudipati }
472a36c61f9SKrishna Gudipati 
4735fbe25c7SJing Huang /*
47461ba4394SKrishna Gudipati  * PLOGI is done. Await bfa_fcs_itnim to ascertain the scsi function
47561ba4394SKrishna Gudipati  */
47661ba4394SKrishna Gudipati static void
47761ba4394SKrishna Gudipati bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport,
47861ba4394SKrishna Gudipati 				enum rport_event event)
47961ba4394SKrishna Gudipati {
48061ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
48161ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
48261ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, event);
48361ba4394SKrishna Gudipati 
48461ba4394SKrishna Gudipati 	switch (event) {
48561ba4394SKrishna Gudipati 	case RPSM_EVENT_FC4_FCS_ONLINE:
48661ba4394SKrishna Gudipati 		if (rport->scsi_function == BFA_RPORT_INITIATOR) {
48761ba4394SKrishna Gudipati 			if (!BFA_FCS_PID_IS_WKA(rport->pid))
48861ba4394SKrishna Gudipati 				bfa_fcs_rpf_rport_online(rport);
48961ba4394SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
49061ba4394SKrishna Gudipati 			break;
49161ba4394SKrishna Gudipati 		}
49261ba4394SKrishna Gudipati 
49361ba4394SKrishna Gudipati 		if (!rport->bfa_rport)
49461ba4394SKrishna Gudipati 			rport->bfa_rport =
49561ba4394SKrishna Gudipati 				bfa_rport_create(rport->fcs->bfa, rport);
49661ba4394SKrishna Gudipati 
49761ba4394SKrishna Gudipati 		if (rport->bfa_rport) {
49861ba4394SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
49961ba4394SKrishna Gudipati 			bfa_fcs_rport_hal_online(rport);
50061ba4394SKrishna Gudipati 		} else {
50161ba4394SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
50261ba4394SKrishna Gudipati 			bfa_fcs_rport_fcs_offline_action(rport);
50361ba4394SKrishna Gudipati 		}
50461ba4394SKrishna Gudipati 		break;
50561ba4394SKrishna Gudipati 
50661ba4394SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
50761ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
50861ba4394SKrishna Gudipati 		rport->plogi_pending = BFA_TRUE;
50961ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
51061ba4394SKrishna Gudipati 		break;
51161ba4394SKrishna Gudipati 
51261ba4394SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
51361ba4394SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
51461ba4394SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
51561ba4394SKrishna Gudipati 	case RPSM_EVENT_SCN:
51661ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
51761ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
51861ba4394SKrishna Gudipati 		break;
51961ba4394SKrishna Gudipati 
52061ba4394SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
52161ba4394SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
52261ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
52361ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
52461ba4394SKrishna Gudipati 		break;
52561ba4394SKrishna Gudipati 
52661ba4394SKrishna Gudipati 	case RPSM_EVENT_DELETE:
52761ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
52861ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
52961ba4394SKrishna Gudipati 		break;
53061ba4394SKrishna Gudipati 
53161ba4394SKrishna Gudipati 	default:
53261ba4394SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
53361ba4394SKrishna Gudipati 		break;
53461ba4394SKrishna Gudipati 	}
53561ba4394SKrishna Gudipati }
53661ba4394SKrishna Gudipati 
53761ba4394SKrishna Gudipati /*
538a36c61f9SKrishna Gudipati  *		PLOGI is complete. Awaiting BFA rport online callback. FC-4s
539a36c61f9SKrishna Gudipati  *		are offline.
540a36c61f9SKrishna Gudipati  */
541a36c61f9SKrishna Gudipati static void
542a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
543a36c61f9SKrishna Gudipati 			enum rport_event event)
544a36c61f9SKrishna Gudipati {
545a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
546a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
547a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
548a36c61f9SKrishna Gudipati 
549a36c61f9SKrishna Gudipati 	switch (event) {
550a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_ONLINE:
551a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
55261ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_online_action(rport);
553a36c61f9SKrishna Gudipati 		break;
554a36c61f9SKrishna Gudipati 
555d7be54ccSKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
556a36c61f9SKrishna Gudipati 		break;
557a36c61f9SKrishna Gudipati 
55861ba4394SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
559a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
56061ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
56161ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
562a36c61f9SKrishna Gudipati 		break;
563a36c61f9SKrishna Gudipati 
56461ba4394SKrishna Gudipati 	case RPSM_EVENT_SCN:
565a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
566a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
56761ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
56861ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
569a36c61f9SKrishna Gudipati 		break;
570a36c61f9SKrishna Gudipati 
571a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
572d7be54ccSKrishna Gudipati 		rport->plogi_pending = BFA_TRUE;
57361ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
57461ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
575a36c61f9SKrishna Gudipati 		break;
576a36c61f9SKrishna Gudipati 
577a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
57861ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
57961ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
580a36c61f9SKrishna Gudipati 		break;
581a36c61f9SKrishna Gudipati 
582a36c61f9SKrishna Gudipati 	default:
583a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
584a36c61f9SKrishna Gudipati 	}
585a36c61f9SKrishna Gudipati }
586a36c61f9SKrishna Gudipati 
5875fbe25c7SJing Huang /*
588a36c61f9SKrishna Gudipati  *		Rport is ONLINE. FC-4s active.
589a36c61f9SKrishna Gudipati  */
590a36c61f9SKrishna Gudipati static void
591a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
592a36c61f9SKrishna Gudipati {
593a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
594a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
595a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
596a36c61f9SKrishna Gudipati 
597a36c61f9SKrishna Gudipati 	switch (event) {
598a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
599a36c61f9SKrishna Gudipati 		if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
600a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
601a36c61f9SKrishna Gudipati 					 bfa_fcs_rport_sm_nsquery_sending);
602a36c61f9SKrishna Gudipati 			rport->ns_retries = 0;
603a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
604a36c61f9SKrishna Gudipati 		} else {
605a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
606a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_adisc(rport, NULL);
607a36c61f9SKrishna Gudipati 		}
608a36c61f9SKrishna Gudipati 		break;
609a36c61f9SKrishna Gudipati 
610a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
611a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
612a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
613a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
61461ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
615a36c61f9SKrishna Gudipati 		break;
616a36c61f9SKrishna Gudipati 
617a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
618a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
61961ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
620a36c61f9SKrishna Gudipati 		break;
621a36c61f9SKrishna Gudipati 
622a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
623a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
624a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
62561ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
626a36c61f9SKrishna Gudipati 		break;
627a36c61f9SKrishna Gudipati 
628a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
629a36c61f9SKrishna Gudipati 		break;
630a36c61f9SKrishna Gudipati 
631a36c61f9SKrishna Gudipati 	default:
632a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
633a36c61f9SKrishna Gudipati 	}
634a36c61f9SKrishna Gudipati }
635a36c61f9SKrishna Gudipati 
6365fbe25c7SJing Huang /*
637a36c61f9SKrishna Gudipati  *		An SCN event is received in ONLINE state. NS query is being sent
638a36c61f9SKrishna Gudipati  *		prior to ADISC authentication with rport. FC-4s are paused.
639a36c61f9SKrishna Gudipati  */
640a36c61f9SKrishna Gudipati static void
641a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
642a36c61f9SKrishna Gudipati 	 enum rport_event event)
643a36c61f9SKrishna Gudipati {
644a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
645a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
646a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
647a36c61f9SKrishna Gudipati 
648a36c61f9SKrishna Gudipati 	switch (event) {
649a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
650a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsquery);
651a36c61f9SKrishna Gudipati 		break;
652a36c61f9SKrishna Gudipati 
653a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
654a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
655a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
65661ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
657a36c61f9SKrishna Gudipati 		break;
658a36c61f9SKrishna Gudipati 
659a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
6605fbe25c7SJing Huang 		/*
661a36c61f9SKrishna Gudipati 		 * ignore SCN, wait for response to query itself
662a36c61f9SKrishna Gudipati 		 */
663a36c61f9SKrishna Gudipati 		break;
664a36c61f9SKrishna Gudipati 
665a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
666a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
667a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
668a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
66961ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
670a36c61f9SKrishna Gudipati 		break;
671a36c61f9SKrishna Gudipati 
672a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
673a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
674a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
675a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
676a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
677a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
67861ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
679a36c61f9SKrishna Gudipati 		break;
680a36c61f9SKrishna Gudipati 
681a36c61f9SKrishna Gudipati 	default:
682a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
683a36c61f9SKrishna Gudipati 	}
684a36c61f9SKrishna Gudipati }
685a36c61f9SKrishna Gudipati 
6865fbe25c7SJing Huang /*
687a36c61f9SKrishna Gudipati  *	An SCN event is received in ONLINE state. NS query is sent to rport.
688a36c61f9SKrishna Gudipati  *	FC-4s are paused.
689a36c61f9SKrishna Gudipati  */
690a36c61f9SKrishna Gudipati static void
691a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
692a36c61f9SKrishna Gudipati {
693a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
694a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
695a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
696a36c61f9SKrishna Gudipati 
697a36c61f9SKrishna Gudipati 	switch (event) {
698a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ACCEPTED:
699a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
700a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_adisc(rport, NULL);
701a36c61f9SKrishna Gudipati 		break;
702a36c61f9SKrishna Gudipati 
703a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FAILED:
704a36c61f9SKrishna Gudipati 		rport->ns_retries++;
705a36c61f9SKrishna Gudipati 		if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
706a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
707a36c61f9SKrishna Gudipati 					 bfa_fcs_rport_sm_nsquery_sending);
708a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
709a36c61f9SKrishna Gudipati 		} else {
710a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
71161ba4394SKrishna Gudipati 			bfa_fcs_rport_hal_offline_action(rport);
712a36c61f9SKrishna Gudipati 		}
713a36c61f9SKrishna Gudipati 		break;
714a36c61f9SKrishna Gudipati 
715a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
716a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
717a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
71861ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
719a36c61f9SKrishna Gudipati 		break;
720a36c61f9SKrishna Gudipati 
721a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
722a36c61f9SKrishna Gudipati 		break;
723a36c61f9SKrishna Gudipati 
724a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
725a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
726a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
727a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
72861ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
729a36c61f9SKrishna Gudipati 		break;
730a36c61f9SKrishna Gudipati 
731a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
732a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
733a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
734a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
735a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
736a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
73761ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
738a36c61f9SKrishna Gudipati 		break;
739a36c61f9SKrishna Gudipati 
740a36c61f9SKrishna Gudipati 	default:
741a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
742a36c61f9SKrishna Gudipati 	}
743a36c61f9SKrishna Gudipati }
744a36c61f9SKrishna Gudipati 
7455fbe25c7SJing Huang /*
746a36c61f9SKrishna Gudipati  *	An SCN event is received in ONLINE state. ADISC is being sent for
747a36c61f9SKrishna Gudipati  *	authenticating with rport. FC-4s are paused.
748a36c61f9SKrishna Gudipati  */
749a36c61f9SKrishna Gudipati static void
750a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
751a36c61f9SKrishna Gudipati 	 enum rport_event event)
752a36c61f9SKrishna Gudipati {
753a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
754a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
755a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
756a36c61f9SKrishna Gudipati 
757a36c61f9SKrishna Gudipati 	switch (event) {
758a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
759a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc);
760a36c61f9SKrishna Gudipati 		break;
761a36c61f9SKrishna Gudipati 
762a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
763a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
764a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
76561ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
766a36c61f9SKrishna Gudipati 		break;
767a36c61f9SKrishna Gudipati 
768a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
769a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
770a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
771a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
77261ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
773a36c61f9SKrishna Gudipati 		break;
774a36c61f9SKrishna Gudipati 
775a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
776a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
777a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
778a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
77961ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
780a36c61f9SKrishna Gudipati 		break;
781a36c61f9SKrishna Gudipati 
782a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
783a36c61f9SKrishna Gudipati 		break;
784a36c61f9SKrishna Gudipati 
785a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
786a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
787a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
78861ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
789a36c61f9SKrishna Gudipati 		break;
790a36c61f9SKrishna Gudipati 
791a36c61f9SKrishna Gudipati 	default:
792a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
793a36c61f9SKrishna Gudipati 	}
794a36c61f9SKrishna Gudipati }
795a36c61f9SKrishna Gudipati 
7965fbe25c7SJing Huang /*
797a36c61f9SKrishna Gudipati  *		An SCN event is received in ONLINE state. ADISC is to rport.
798a36c61f9SKrishna Gudipati  *		FC-4s are paused.
799a36c61f9SKrishna Gudipati  */
800a36c61f9SKrishna Gudipati static void
801a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
802a36c61f9SKrishna Gudipati {
803a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
804a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
805a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
806a36c61f9SKrishna Gudipati 
807a36c61f9SKrishna Gudipati 	switch (event) {
808a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ACCEPTED:
809a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
810a36c61f9SKrishna Gudipati 		break;
811a36c61f9SKrishna Gudipati 
812a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
8135fbe25c7SJing Huang 		/*
814a36c61f9SKrishna Gudipati 		 * Too complex to cleanup FC-4 & rport and then acc to PLOGI.
815a36c61f9SKrishna Gudipati 		 * At least go offline when a PLOGI is received.
816a36c61f9SKrishna Gudipati 		 */
817a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
818a36c61f9SKrishna Gudipati 		/*
819a36c61f9SKrishna Gudipati 		 * !!! fall through !!!
820a36c61f9SKrishna Gudipati 		 */
821a36c61f9SKrishna Gudipati 
822a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FAILED:
823a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
824a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
82561ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
826a36c61f9SKrishna Gudipati 		break;
827a36c61f9SKrishna Gudipati 
828a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
829a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
830a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
83161ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
832a36c61f9SKrishna Gudipati 		break;
833a36c61f9SKrishna Gudipati 
834a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
8355fbe25c7SJing Huang 		/*
836a36c61f9SKrishna Gudipati 		 * already processing RSCN
837a36c61f9SKrishna Gudipati 		 */
838a36c61f9SKrishna Gudipati 		break;
839a36c61f9SKrishna Gudipati 
840a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
841a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
842a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
84361ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
844a36c61f9SKrishna Gudipati 		break;
845a36c61f9SKrishna Gudipati 
846a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
847a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
848a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
849a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
85061ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
851a36c61f9SKrishna Gudipati 		break;
852a36c61f9SKrishna Gudipati 
853a36c61f9SKrishna Gudipati 	default:
854a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
855a36c61f9SKrishna Gudipati 	}
856a36c61f9SKrishna Gudipati }
857a36c61f9SKrishna Gudipati 
8585fbe25c7SJing Huang /*
859a36c61f9SKrishna Gudipati  *		Rport has sent LOGO. Awaiting FC-4 offline completion callback.
860a36c61f9SKrishna Gudipati  */
861a36c61f9SKrishna Gudipati static void
862a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
863a36c61f9SKrishna Gudipati 			enum rport_event event)
864a36c61f9SKrishna Gudipati {
865a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
866a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
867a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
868a36c61f9SKrishna Gudipati 
869a36c61f9SKrishna Gudipati 	switch (event) {
870a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FC4_OFFLINE:
871a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
87261ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline(rport);
873a36c61f9SKrishna Gudipati 		break;
874a36c61f9SKrishna Gudipati 
875a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
87661ba4394SKrishna Gudipati 		if (rport->pid && (rport->prlo == BFA_TRUE))
87761ba4394SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
87861ba4394SKrishna Gudipati 		if (rport->pid && (rport->prlo == BFA_FALSE))
87961ba4394SKrishna Gudipati 			bfa_fcs_rport_send_logo_acc(rport);
88061ba4394SKrishna Gudipati 
88161ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete);
882a36c61f9SKrishna Gudipati 		break;
883a36c61f9SKrishna Gudipati 
88461ba4394SKrishna Gudipati 	case RPSM_EVENT_HCB_ONLINE:
885a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
886a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
887a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
888a36c61f9SKrishna Gudipati 		break;
889a36c61f9SKrishna Gudipati 
890a36c61f9SKrishna Gudipati 	default:
891a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
892a36c61f9SKrishna Gudipati 	}
893a36c61f9SKrishna Gudipati }
894a36c61f9SKrishna Gudipati 
8955fbe25c7SJing Huang /*
896a36c61f9SKrishna Gudipati  *		LOGO needs to be sent to rport. Awaiting FC-4 offline completion
897a36c61f9SKrishna Gudipati  *		callback.
898a36c61f9SKrishna Gudipati  */
899a36c61f9SKrishna Gudipati static void
900a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
901a36c61f9SKrishna Gudipati 	 enum rport_event event)
902a36c61f9SKrishna Gudipati {
903a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
904a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
905a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
906a36c61f9SKrishna Gudipati 
907a36c61f9SKrishna Gudipati 	switch (event) {
908a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FC4_OFFLINE:
909a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
91061ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline(rport);
91161ba4394SKrishna Gudipati 		break;
91261ba4394SKrishna Gudipati 
91361ba4394SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
91461ba4394SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
91561ba4394SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
91661ba4394SKrishna Gudipati 		if (rport->prlo == BFA_TRUE)
91761ba4394SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
91861ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete);
91961ba4394SKrishna Gudipati 		break;
92061ba4394SKrishna Gudipati 
92161ba4394SKrishna Gudipati 	case RPSM_EVENT_HCB_ONLINE:
92261ba4394SKrishna Gudipati 	case RPSM_EVENT_DELETE:
92361ba4394SKrishna Gudipati 		/* Rport is being deleted */
924a36c61f9SKrishna Gudipati 		break;
925a36c61f9SKrishna Gudipati 
926a36c61f9SKrishna Gudipati 	default:
927a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
928a36c61f9SKrishna Gudipati 	}
929a36c61f9SKrishna Gudipati }
930a36c61f9SKrishna Gudipati 
9315fbe25c7SJing Huang /*
932a36c61f9SKrishna Gudipati  *	Rport is going offline. Awaiting FC-4 offline completion callback.
933a36c61f9SKrishna Gudipati  */
934a36c61f9SKrishna Gudipati static void
935a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
936a36c61f9SKrishna Gudipati 			enum rport_event event)
937a36c61f9SKrishna Gudipati {
938a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
939a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
940a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
941a36c61f9SKrishna Gudipati 
942a36c61f9SKrishna Gudipati 	switch (event) {
943a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FC4_OFFLINE:
944a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
94561ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline(rport);
946a36c61f9SKrishna Gudipati 		break;
947a36c61f9SKrishna Gudipati 
94861ba4394SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
94961ba4394SKrishna Gudipati 		/*
95061ba4394SKrishna Gudipati 		 * Rport is going offline. Just ack the logo
95161ba4394SKrishna Gudipati 		 */
95261ba4394SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
95361ba4394SKrishna Gudipati 		break;
95461ba4394SKrishna Gudipati 
95561ba4394SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
95661ba4394SKrishna Gudipati 		bfa_fcs_rport_send_prlo_acc(rport);
95761ba4394SKrishna Gudipati 		break;
95861ba4394SKrishna Gudipati 
95961ba4394SKrishna Gudipati 	case RPSM_EVENT_HCB_ONLINE:
960a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
961a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
962a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
9635fbe25c7SJing Huang 		/*
964a36c61f9SKrishna Gudipati 		 * rport is already going offline.
965a36c61f9SKrishna Gudipati 		 * SCN - ignore and wait till transitioning to offline state
966a36c61f9SKrishna Gudipati 		 */
967a36c61f9SKrishna Gudipati 		break;
968a36c61f9SKrishna Gudipati 
969a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
970a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
971a36c61f9SKrishna Gudipati 		break;
972a36c61f9SKrishna Gudipati 
973a36c61f9SKrishna Gudipati 	default:
974a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
975a36c61f9SKrishna Gudipati 	}
976a36c61f9SKrishna Gudipati }
977a36c61f9SKrishna Gudipati 
9785fbe25c7SJing Huang /*
979a36c61f9SKrishna Gudipati  *		Rport is offline. FC-4s are offline. Awaiting BFA rport offline
980a36c61f9SKrishna Gudipati  *		callback.
981a36c61f9SKrishna Gudipati  */
982a36c61f9SKrishna Gudipati static void
983a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
984a36c61f9SKrishna Gudipati 				enum rport_event event)
985a36c61f9SKrishna Gudipati {
986a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
987a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
988a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
989a36c61f9SKrishna Gudipati 
990a36c61f9SKrishna Gudipati 	switch (event) {
991a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
992d7be54ccSKrishna Gudipati 		if (bfa_fcs_lport_is_online(rport->port) &&
993d7be54ccSKrishna Gudipati 		    (rport->plogi_pending)) {
994d7be54ccSKrishna Gudipati 			rport->plogi_pending = BFA_FALSE;
995d7be54ccSKrishna Gudipati 			bfa_sm_set_state(rport,
996d7be54ccSKrishna Gudipati 				bfa_fcs_rport_sm_plogiacc_sending);
997d7be54ccSKrishna Gudipati 			bfa_fcs_rport_send_plogiacc(rport, NULL);
998d7be54ccSKrishna Gudipati 			break;
999d7be54ccSKrishna Gudipati 		}
1000d7be54ccSKrishna Gudipati 		/*
1001d7be54ccSKrishna Gudipati 		 * !! fall through !!
1002d7be54ccSKrishna Gudipati 		 */
1003d7be54ccSKrishna Gudipati 
1004a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
100561ba4394SKrishna Gudipati 		if (!bfa_fcs_lport_is_online(rport->port)) {
100661ba4394SKrishna Gudipati 			rport->pid = 0;
100761ba4394SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
100861ba4394SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
100961ba4394SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
101061ba4394SKrishna Gudipati 					bfa_fcs_rport_del_timeout);
101161ba4394SKrishna Gudipati 			break;
101261ba4394SKrishna Gudipati 		}
1013a36c61f9SKrishna Gudipati 		if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
1014a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
1015a36c61f9SKrishna Gudipati 				bfa_fcs_rport_sm_nsdisc_sending);
1016a36c61f9SKrishna Gudipati 			rport->ns_retries = 0;
1017a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
1018a36c61f9SKrishna Gudipati 		} else {
101961ba4394SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1020a36c61f9SKrishna Gudipati 			rport->plogi_retries = 0;
1021a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_plogi(rport, NULL);
1022a36c61f9SKrishna Gudipati 		}
1023a36c61f9SKrishna Gudipati 		break;
1024a36c61f9SKrishna Gudipati 
1025a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
1026a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1027a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1028a36c61f9SKrishna Gudipati 		break;
1029a36c61f9SKrishna Gudipati 
1030a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
1031a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1032a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1033d7be54ccSKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
1034d7be54ccSKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
10355fbe25c7SJing Huang 		/*
1036a36c61f9SKrishna Gudipati 		 * Ignore, already offline.
1037a36c61f9SKrishna Gudipati 		 */
1038a36c61f9SKrishna Gudipati 		break;
1039a36c61f9SKrishna Gudipati 
1040a36c61f9SKrishna Gudipati 	default:
1041a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1042a36c61f9SKrishna Gudipati 	}
1043a36c61f9SKrishna Gudipati }
1044a36c61f9SKrishna Gudipati 
10455fbe25c7SJing Huang /*
1046a36c61f9SKrishna Gudipati  *		Rport is offline. FC-4s are offline. Awaiting BFA rport offline
1047a36c61f9SKrishna Gudipati  *		callback to send LOGO accept.
1048a36c61f9SKrishna Gudipati  */
1049a36c61f9SKrishna Gudipati static void
1050a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
1051a36c61f9SKrishna Gudipati 			enum rport_event event)
1052a36c61f9SKrishna Gudipati {
1053a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1054a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1055a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1056a36c61f9SKrishna Gudipati 
1057a36c61f9SKrishna Gudipati 	switch (event) {
1058a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
1059a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1060a36c61f9SKrishna Gudipati 		if (rport->pid && (rport->prlo == BFA_TRUE))
1061a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
1062a36c61f9SKrishna Gudipati 		if (rport->pid && (rport->prlo == BFA_FALSE))
1063a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_logo_acc(rport);
1064a36c61f9SKrishna Gudipati 		/*
1065a36c61f9SKrishna Gudipati 		 * If the lport is online and if the rport is not a well
1066a36c61f9SKrishna Gudipati 		 * known address port,
1067a36c61f9SKrishna Gudipati 		 * we try to re-discover the r-port.
1068a36c61f9SKrishna Gudipati 		 */
1069a36c61f9SKrishna Gudipati 		if (bfa_fcs_lport_is_online(rport->port) &&
1070a36c61f9SKrishna Gudipati 			(!BFA_FCS_PID_IS_WKA(rport->pid))) {
1071d7be54ccSKrishna Gudipati 			if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
1072a36c61f9SKrishna Gudipati 				bfa_sm_set_state(rport,
1073a36c61f9SKrishna Gudipati 					bfa_fcs_rport_sm_nsdisc_sending);
1074a36c61f9SKrishna Gudipati 				rport->ns_retries = 0;
1075a36c61f9SKrishna Gudipati 				bfa_fcs_rport_send_nsdisc(rport, NULL);
1076a36c61f9SKrishna Gudipati 			} else {
1077d7be54ccSKrishna Gudipati 				/* For N2N  Direct Attach, try to re-login */
1078d7be54ccSKrishna Gudipati 				bfa_sm_set_state(rport,
1079d7be54ccSKrishna Gudipati 					bfa_fcs_rport_sm_plogi_sending);
1080d7be54ccSKrishna Gudipati 				rport->plogi_retries = 0;
1081d7be54ccSKrishna Gudipati 				bfa_fcs_rport_send_plogi(rport, NULL);
1082d7be54ccSKrishna Gudipati 			}
1083d7be54ccSKrishna Gudipati 		} else {
1084a36c61f9SKrishna Gudipati 			/*
1085a36c61f9SKrishna Gudipati 			 * if it is not a well known address, reset the
1086a36c61f9SKrishna Gudipati 			 * pid to 0.
1087a36c61f9SKrishna Gudipati 			 */
1088a36c61f9SKrishna Gudipati 			if (!BFA_FCS_PID_IS_WKA(rport->pid))
1089a36c61f9SKrishna Gudipati 				rport->pid = 0;
1090a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1091a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
1092a36c61f9SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
1093a36c61f9SKrishna Gudipati 					bfa_fcs_rport_del_timeout);
1094a36c61f9SKrishna Gudipati 		}
1095a36c61f9SKrishna Gudipati 		break;
1096a36c61f9SKrishna Gudipati 
1097a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
109861ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
109961ba4394SKrishna Gudipati 		if (rport->pid && (rport->prlo == BFA_TRUE))
110061ba4394SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
110161ba4394SKrishna Gudipati 		if (rport->pid && (rport->prlo == BFA_FALSE))
110261ba4394SKrishna Gudipati 			bfa_fcs_rport_send_logo_acc(rport);
1103a36c61f9SKrishna Gudipati 		break;
1104a36c61f9SKrishna Gudipati 
1105a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
1106a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
1107a36c61f9SKrishna Gudipati 		break;
1108a36c61f9SKrishna Gudipati 
1109a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1110a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
11115fbe25c7SJing Huang 		/*
1112a36c61f9SKrishna Gudipati 		 * Ignore - already processing a LOGO.
1113a36c61f9SKrishna Gudipati 		 */
1114a36c61f9SKrishna Gudipati 		break;
1115a36c61f9SKrishna Gudipati 
1116a36c61f9SKrishna Gudipati 	default:
1117a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1118a36c61f9SKrishna Gudipati 	}
1119a36c61f9SKrishna Gudipati }
1120a36c61f9SKrishna Gudipati 
11215fbe25c7SJing Huang /*
1122a36c61f9SKrishna Gudipati  *		Rport is being deleted. FC-4s are offline.
1123a36c61f9SKrishna Gudipati  *  Awaiting BFA rport offline
1124a36c61f9SKrishna Gudipati  *		callback to send LOGO.
1125a36c61f9SKrishna Gudipati  */
1126a36c61f9SKrishna Gudipati static void
1127a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
1128a36c61f9SKrishna Gudipati 		 enum rport_event event)
1129a36c61f9SKrishna Gudipati {
1130a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1131a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1132a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1133a36c61f9SKrishna Gudipati 
1134a36c61f9SKrishna Gudipati 	switch (event) {
1135a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
1136a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_logo_sending);
1137a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_logo(rport, NULL);
1138a36c61f9SKrishna Gudipati 		break;
1139a36c61f9SKrishna Gudipati 
1140a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
114161ba4394SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
1142a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
114361ba4394SKrishna Gudipati 		if (rport->prlo == BFA_TRUE)
114461ba4394SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
114561ba4394SKrishna Gudipati 
114661ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
114761ba4394SKrishna Gudipati 		break;
114861ba4394SKrishna Gudipati 
1149a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1150a36c61f9SKrishna Gudipati 		break;
1151a36c61f9SKrishna Gudipati 
1152a36c61f9SKrishna Gudipati 	default:
1153a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1154a36c61f9SKrishna Gudipati 	}
1155a36c61f9SKrishna Gudipati }
1156a36c61f9SKrishna Gudipati 
11575fbe25c7SJing Huang /*
1158a36c61f9SKrishna Gudipati  *		Rport is being deleted. FC-4s are offline. LOGO is being sent.
1159a36c61f9SKrishna Gudipati  */
1160a36c61f9SKrishna Gudipati static void
1161a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
1162a36c61f9SKrishna Gudipati 	 enum rport_event event)
1163a36c61f9SKrishna Gudipati {
1164a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1165a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1166a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1167a36c61f9SKrishna Gudipati 
1168a36c61f9SKrishna Gudipati 	switch (event) {
1169a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
1170a36c61f9SKrishna Gudipati 		/* Once LOGO is sent, we donot wait for the response */
1171a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1172a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1173a36c61f9SKrishna Gudipati 		break;
1174a36c61f9SKrishna Gudipati 
1175a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
1176a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1177a36c61f9SKrishna Gudipati 		break;
1178a36c61f9SKrishna Gudipati 
1179a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
118061ba4394SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
1181a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
118261ba4394SKrishna Gudipati 		if (rport->prlo == BFA_TRUE)
118361ba4394SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
118461ba4394SKrishna Gudipati 
1185a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1186a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1187a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1188a36c61f9SKrishna Gudipati 		break;
1189a36c61f9SKrishna Gudipati 
1190a36c61f9SKrishna Gudipati 	default:
1191a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1192a36c61f9SKrishna Gudipati 	}
1193a36c61f9SKrishna Gudipati }
1194a36c61f9SKrishna Gudipati 
11955fbe25c7SJing Huang /*
1196a36c61f9SKrishna Gudipati  *		Rport is offline. FC-4s are offline. BFA rport is offline.
1197a36c61f9SKrishna Gudipati  *		Timer active to delete stale rport.
1198a36c61f9SKrishna Gudipati  */
1199a36c61f9SKrishna Gudipati static void
1200a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
1201a36c61f9SKrishna Gudipati {
1202a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1203a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1204a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1205a36c61f9SKrishna Gudipati 
1206a36c61f9SKrishna Gudipati 	switch (event) {
1207a36c61f9SKrishna Gudipati 	case RPSM_EVENT_TIMEOUT:
1208a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1209a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1210a36c61f9SKrishna Gudipati 		break;
1211a36c61f9SKrishna Gudipati 
1212a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
1213a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1214a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1215a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1216a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
1217a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
1218a36c61f9SKrishna Gudipati 		break;
1219a36c61f9SKrishna Gudipati 
1220a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
1221a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1222a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1223a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1224a36c61f9SKrishna Gudipati 		break;
1225a36c61f9SKrishna Gudipati 
1226a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
1227a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1228a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1229a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
1230a36c61f9SKrishna Gudipati 		break;
1231a36c61f9SKrishna Gudipati 
1232a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1233a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1234a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
1235a36c61f9SKrishna Gudipati 		break;
1236a36c61f9SKrishna Gudipati 
1237a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
123861ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1239a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
124061ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
1241a36c61f9SKrishna Gudipati 		break;
1242a36c61f9SKrishna Gudipati 
1243a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_SEND:
1244a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1245a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1246a36c61f9SKrishna Gudipati 		rport->plogi_retries = 0;
1247a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogi(rport, NULL);
1248a36c61f9SKrishna Gudipati 		break;
1249a36c61f9SKrishna Gudipati 
1250a36c61f9SKrishna Gudipati 	default:
1251a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1252a36c61f9SKrishna Gudipati 	}
1253a36c61f9SKrishna Gudipati }
1254a36c61f9SKrishna Gudipati 
12555fbe25c7SJing Huang /*
1256a36c61f9SKrishna Gudipati  *	Rport address has changed. Nameserver discovery request is being sent.
1257a36c61f9SKrishna Gudipati  */
1258a36c61f9SKrishna Gudipati static void
1259a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
1260a36c61f9SKrishna Gudipati 	 enum rport_event event)
1261a36c61f9SKrishna Gudipati {
1262a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1263a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1264a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1265a36c61f9SKrishna Gudipati 
1266a36c61f9SKrishna Gudipati 	switch (event) {
1267a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
1268a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sent);
1269a36c61f9SKrishna Gudipati 		break;
1270a36c61f9SKrishna Gudipati 
1271a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
1272a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1273a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1274a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1275a36c61f9SKrishna Gudipati 		break;
1276a36c61f9SKrishna Gudipati 
1277a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
1278a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1279a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1280a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
1281a36c61f9SKrishna Gudipati 		break;
1282a36c61f9SKrishna Gudipati 
1283a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
1284a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1285a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1286a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_SEND:
1287a36c61f9SKrishna Gudipati 		break;
1288a36c61f9SKrishna Gudipati 
1289a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1290a36c61f9SKrishna Gudipati 		rport->ns_retries = 0; /* reset the retry count */
1291a36c61f9SKrishna Gudipati 		break;
1292a36c61f9SKrishna Gudipati 
1293a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
1294a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1295a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1296a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
1297a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
1298a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
1299a36c61f9SKrishna Gudipati 		break;
1300a36c61f9SKrishna Gudipati 
1301a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
130261ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1303a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
130461ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
1305a36c61f9SKrishna Gudipati 		break;
1306a36c61f9SKrishna Gudipati 
1307a36c61f9SKrishna Gudipati 	default:
1308a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1309a36c61f9SKrishna Gudipati 	}
1310a36c61f9SKrishna Gudipati }
1311a36c61f9SKrishna Gudipati 
13125fbe25c7SJing Huang /*
1313a36c61f9SKrishna Gudipati  *		Nameserver discovery failed. Waiting for timeout to retry.
1314a36c61f9SKrishna Gudipati  */
1315a36c61f9SKrishna Gudipati static void
1316a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
1317a36c61f9SKrishna Gudipati 	 enum rport_event event)
1318a36c61f9SKrishna Gudipati {
1319a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1320a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1321a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1322a36c61f9SKrishna Gudipati 
1323a36c61f9SKrishna Gudipati 	switch (event) {
1324a36c61f9SKrishna Gudipati 	case RPSM_EVENT_TIMEOUT:
1325a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1326a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
1327a36c61f9SKrishna Gudipati 		break;
1328a36c61f9SKrishna Gudipati 
1329a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
1330a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1331a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1332a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1333a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
1334a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
1335a36c61f9SKrishna Gudipati 		break;
1336a36c61f9SKrishna Gudipati 
1337a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
1338a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1339a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1340a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1341a36c61f9SKrishna Gudipati 		break;
1342a36c61f9SKrishna Gudipati 
1343a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
1344a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1345a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1346a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
1347a36c61f9SKrishna Gudipati 		break;
1348a36c61f9SKrishna Gudipati 
1349a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
1350a36c61f9SKrishna Gudipati 		rport->pid = 0;
1351a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1352a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1353a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
1354a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
1355a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
1356a36c61f9SKrishna Gudipati 		break;
1357a36c61f9SKrishna Gudipati 
1358a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1359a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
1360a36c61f9SKrishna Gudipati 		break;
1361a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1362a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_prlo_acc(rport);
1363a36c61f9SKrishna Gudipati 		break;
1364a36c61f9SKrishna Gudipati 
1365a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
136661ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1367a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
136861ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
1369a36c61f9SKrishna Gudipati 		break;
1370a36c61f9SKrishna Gudipati 
1371a36c61f9SKrishna Gudipati 	default:
1372a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1373a36c61f9SKrishna Gudipati 	}
1374a36c61f9SKrishna Gudipati }
1375a36c61f9SKrishna Gudipati 
13765fbe25c7SJing Huang /*
1377a36c61f9SKrishna Gudipati  *		Rport address has changed. Nameserver discovery request is sent.
1378a36c61f9SKrishna Gudipati  */
1379a36c61f9SKrishna Gudipati static void
1380a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
1381a36c61f9SKrishna Gudipati 			enum rport_event event)
1382a36c61f9SKrishna Gudipati {
1383a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1384a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1385a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1386a36c61f9SKrishna Gudipati 
1387a36c61f9SKrishna Gudipati 	switch (event) {
1388a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ACCEPTED:
1389a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1390a36c61f9SKrishna Gudipati 		if (rport->pid) {
1391a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1392a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_plogi(rport, NULL);
1393a36c61f9SKrishna Gudipati 		} else {
1394a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
1395a36c61f9SKrishna Gudipati 				 bfa_fcs_rport_sm_nsdisc_sending);
1396a36c61f9SKrishna Gudipati 			rport->ns_retries = 0;
1397a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
1398a36c61f9SKrishna Gudipati 		}
1399a36c61f9SKrishna Gudipati 		break;
1400a36c61f9SKrishna Gudipati 
1401a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FAILED:
1402a36c61f9SKrishna Gudipati 		rport->ns_retries++;
1403a36c61f9SKrishna Gudipati 		if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
1404a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
1405a36c61f9SKrishna Gudipati 				 bfa_fcs_rport_sm_nsdisc_sending);
1406a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
1407a36c61f9SKrishna Gudipati 		} else {
1408ee1a4a42SKrishna Gudipati 			rport->old_pid = rport->pid;
1409a36c61f9SKrishna Gudipati 			rport->pid = 0;
1410a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1411a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
1412a36c61f9SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
1413a36c61f9SKrishna Gudipati 					bfa_fcs_rport_del_timeout);
1414a36c61f9SKrishna Gudipati 		};
1415a36c61f9SKrishna Gudipati 		break;
1416a36c61f9SKrishna Gudipati 
1417a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
1418a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1419a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
1420a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1421a36c61f9SKrishna Gudipati 		break;
1422a36c61f9SKrishna Gudipati 
1423a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
1424a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1425a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
1426a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
1427a36c61f9SKrishna Gudipati 		break;
1428a36c61f9SKrishna Gudipati 
1429a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
1430a36c61f9SKrishna Gudipati 		rport->pid = 0;
1431a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1432a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
1433a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
1434a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
1435a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
1436a36c61f9SKrishna Gudipati 		break;
1437a36c61f9SKrishna Gudipati 
1438a36c61f9SKrishna Gudipati 
1439a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1440a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_prlo_acc(rport);
1441a36c61f9SKrishna Gudipati 		break;
1442a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
14435fbe25c7SJing Huang 		/*
1444a36c61f9SKrishna Gudipati 		 * ignore, wait for NS query response
1445a36c61f9SKrishna Gudipati 		 */
1446a36c61f9SKrishna Gudipati 		break;
1447a36c61f9SKrishna Gudipati 
1448a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
14495fbe25c7SJing Huang 		/*
1450a36c61f9SKrishna Gudipati 		 * Not logged-in yet. Accept LOGO.
1451a36c61f9SKrishna Gudipati 		 */
1452a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
1453a36c61f9SKrishna Gudipati 		break;
1454a36c61f9SKrishna Gudipati 
1455a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
145661ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1457a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
145861ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
1459a36c61f9SKrishna Gudipati 		break;
1460a36c61f9SKrishna Gudipati 
1461a36c61f9SKrishna Gudipati 	default:
1462a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1463a36c61f9SKrishna Gudipati 	}
1464a36c61f9SKrishna Gudipati }
1465a36c61f9SKrishna Gudipati 
146661ba4394SKrishna Gudipati /*
146761ba4394SKrishna Gudipati  * Rport needs to be deleted
146861ba4394SKrishna Gudipati  * waiting for ITNIM clean up to finish
146961ba4394SKrishna Gudipati  */
147061ba4394SKrishna Gudipati static void
147161ba4394SKrishna Gudipati bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s *rport,
147261ba4394SKrishna Gudipati 				enum rport_event event)
147361ba4394SKrishna Gudipati {
147461ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
147561ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
147661ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1477a36c61f9SKrishna Gudipati 
147861ba4394SKrishna Gudipati 	switch (event) {
147961ba4394SKrishna Gudipati 	case RPSM_EVENT_FC4_OFFLINE:
148061ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
148161ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline(rport);
148261ba4394SKrishna Gudipati 		break;
148361ba4394SKrishna Gudipati 
148461ba4394SKrishna Gudipati 	case RPSM_EVENT_DELETE:
148561ba4394SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
148661ba4394SKrishna Gudipati 		/* Ignore these events */
148761ba4394SKrishna Gudipati 		break;
148861ba4394SKrishna Gudipati 
148961ba4394SKrishna Gudipati 	default:
149061ba4394SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
149161ba4394SKrishna Gudipati 		break;
149261ba4394SKrishna Gudipati 	}
149361ba4394SKrishna Gudipati }
149461ba4394SKrishna Gudipati 
149561ba4394SKrishna Gudipati /*
149661ba4394SKrishna Gudipati  * RPort needs to be deleted
149761ba4394SKrishna Gudipati  * waiting for BFA/FW to finish current processing
149861ba4394SKrishna Gudipati  */
149961ba4394SKrishna Gudipati static void
150061ba4394SKrishna Gudipati bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s *rport,
150161ba4394SKrishna Gudipati 				enum rport_event event)
150261ba4394SKrishna Gudipati {
150361ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
150461ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
150561ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, event);
150661ba4394SKrishna Gudipati 
150761ba4394SKrishna Gudipati 	switch (event) {
150861ba4394SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
150961ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
151061ba4394SKrishna Gudipati 		bfa_fcs_rport_free(rport);
151161ba4394SKrishna Gudipati 		break;
151261ba4394SKrishna Gudipati 
151361ba4394SKrishna Gudipati 	case RPSM_EVENT_DELETE:
151461ba4394SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
151561ba4394SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
151661ba4394SKrishna Gudipati 		/* Ignore these events */
151761ba4394SKrishna Gudipati 		break;
151861ba4394SKrishna Gudipati 
151961ba4394SKrishna Gudipati 	default:
152061ba4394SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
152161ba4394SKrishna Gudipati 	}
152261ba4394SKrishna Gudipati }
1523a36c61f9SKrishna Gudipati 
15245fbe25c7SJing Huang /*
1525a36c61f9SKrishna Gudipati  *  fcs_rport_private FCS RPORT provate functions
1526a36c61f9SKrishna Gudipati  */
1527a36c61f9SKrishna Gudipati 
1528a36c61f9SKrishna Gudipati static void
1529a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1530a36c61f9SKrishna Gudipati {
1531a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1532a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1533a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1534a36c61f9SKrishna Gudipati 	int		len;
1535a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1536a36c61f9SKrishna Gudipati 
1537a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1538a36c61f9SKrishna Gudipati 
1539c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
1540c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1541a36c61f9SKrishna Gudipati 	if (!fcxp) {
1542a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1543c3f1b123SKrishna Gudipati 				bfa_fcs_rport_send_plogi, rport, BFA_TRUE);
1544a36c61f9SKrishna Gudipati 		return;
1545a36c61f9SKrishna Gudipati 	}
1546a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1547a36c61f9SKrishna Gudipati 
1548a36c61f9SKrishna Gudipati 	len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1549a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0,
1550a36c61f9SKrishna Gudipati 				port->port_cfg.pwwn, port->port_cfg.nwwn,
1551be540a99SKrishna Gudipati 				bfa_fcport_get_maxfrsize(port->fcs->bfa),
1552be540a99SKrishna Gudipati 				bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
1553a36c61f9SKrishna Gudipati 
1554a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1555a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response,
1556a36c61f9SKrishna Gudipati 			(void *)rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1557a36c61f9SKrishna Gudipati 
1558a36c61f9SKrishna Gudipati 	rport->stats.plogis++;
1559a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1560a36c61f9SKrishna Gudipati }
1561a36c61f9SKrishna Gudipati 
1562a36c61f9SKrishna Gudipati static void
1563a36c61f9SKrishna Gudipati bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1564a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
1565a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs)
1566a36c61f9SKrishna Gudipati {
1567a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1568a36c61f9SKrishna Gudipati 	struct fc_logi_s	*plogi_rsp;
1569a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s	*ls_rjt;
1570a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *twin;
1571a36c61f9SKrishna Gudipati 	struct list_head	*qe;
1572a36c61f9SKrishna Gudipati 
1573a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1574a36c61f9SKrishna Gudipati 
1575a36c61f9SKrishna Gudipati 	/*
1576a36c61f9SKrishna Gudipati 	 * Sanity Checks
1577a36c61f9SKrishna Gudipati 	 */
1578a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
1579a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, req_status);
1580a36c61f9SKrishna Gudipati 		rport->stats.plogi_failed++;
1581a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1582a36c61f9SKrishna Gudipati 		return;
1583a36c61f9SKrishna Gudipati 	}
1584a36c61f9SKrishna Gudipati 
1585a36c61f9SKrishna Gudipati 	plogi_rsp = (struct fc_logi_s *) BFA_FCXP_RSP_PLD(fcxp);
1586a36c61f9SKrishna Gudipati 
15875fbe25c7SJing Huang 	/*
1588a36c61f9SKrishna Gudipati 	 * Check for failure first.
1589a36c61f9SKrishna Gudipati 	 */
1590a36c61f9SKrishna Gudipati 	if (plogi_rsp->els_cmd.els_code != FC_ELS_ACC) {
1591a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
1592a36c61f9SKrishna Gudipati 
1593a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, ls_rjt->reason_code);
1594a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1595a36c61f9SKrishna Gudipati 
1596a36c61f9SKrishna Gudipati 		if ((ls_rjt->reason_code == FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD) &&
1597a36c61f9SKrishna Gudipati 		 (ls_rjt->reason_code_expl == FC_LS_RJT_EXP_INSUFF_RES)) {
1598a36c61f9SKrishna Gudipati 			rport->stats.rjt_insuff_res++;
1599a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RETRY);
1600a36c61f9SKrishna Gudipati 			return;
1601a36c61f9SKrishna Gudipati 		}
1602a36c61f9SKrishna Gudipati 
1603a36c61f9SKrishna Gudipati 		rport->stats.plogi_rejects++;
1604a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1605a36c61f9SKrishna Gudipati 		return;
1606a36c61f9SKrishna Gudipati 	}
1607a36c61f9SKrishna Gudipati 
16085fbe25c7SJing Huang 	/*
1609a36c61f9SKrishna Gudipati 	 * PLOGI is complete. Make sure this device is not one of the known
1610a36c61f9SKrishna Gudipati 	 * device with a new FC port address.
1611a36c61f9SKrishna Gudipati 	 */
1612a36c61f9SKrishna Gudipati 	list_for_each(qe, &rport->port->rport_q) {
1613a36c61f9SKrishna Gudipati 		twin = (struct bfa_fcs_rport_s *) qe;
1614a36c61f9SKrishna Gudipati 		if (twin == rport)
1615a36c61f9SKrishna Gudipati 			continue;
1616a36c61f9SKrishna Gudipati 		if (!rport->pwwn && (plogi_rsp->port_name == twin->pwwn)) {
1617a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs, twin->pid);
1618a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs, rport->pid);
1619a36c61f9SKrishna Gudipati 
1620a36c61f9SKrishna Gudipati 			/* Update plogi stats in twin */
1621a36c61f9SKrishna Gudipati 			twin->stats.plogis  += rport->stats.plogis;
1622a36c61f9SKrishna Gudipati 			twin->stats.plogi_rejects  +=
1623a36c61f9SKrishna Gudipati 				 rport->stats.plogi_rejects;
1624a36c61f9SKrishna Gudipati 			twin->stats.plogi_timeouts  +=
1625a36c61f9SKrishna Gudipati 				 rport->stats.plogi_timeouts;
1626a36c61f9SKrishna Gudipati 			twin->stats.plogi_failed +=
1627a36c61f9SKrishna Gudipati 				 rport->stats.plogi_failed;
1628a36c61f9SKrishna Gudipati 			twin->stats.plogi_rcvd	  += rport->stats.plogi_rcvd;
1629a36c61f9SKrishna Gudipati 			twin->stats.plogi_accs++;
1630a36c61f9SKrishna Gudipati 
1631f7f73812SMaggie Zhang 			bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
1632a36c61f9SKrishna Gudipati 
1633a36c61f9SKrishna Gudipati 			bfa_fcs_rport_update(twin, plogi_rsp);
1634a36c61f9SKrishna Gudipati 			twin->pid = rsp_fchs->s_id;
1635a36c61f9SKrishna Gudipati 			bfa_sm_send_event(twin, RPSM_EVENT_PLOGI_COMP);
1636a36c61f9SKrishna Gudipati 			return;
1637a36c61f9SKrishna Gudipati 		}
1638a36c61f9SKrishna Gudipati 	}
1639a36c61f9SKrishna Gudipati 
16405fbe25c7SJing Huang 	/*
1641a36c61f9SKrishna Gudipati 	 * Normal login path -- no evil twins.
1642a36c61f9SKrishna Gudipati 	 */
1643a36c61f9SKrishna Gudipati 	rport->stats.plogi_accs++;
1644a36c61f9SKrishna Gudipati 	bfa_fcs_rport_update(rport, plogi_rsp);
1645a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1646a36c61f9SKrishna Gudipati }
1647a36c61f9SKrishna Gudipati 
1648a36c61f9SKrishna Gudipati static void
1649a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1650a36c61f9SKrishna Gudipati {
1651a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1652a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1653a36c61f9SKrishna Gudipati 	struct fchs_s		fchs;
1654a36c61f9SKrishna Gudipati 	int		len;
1655a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1656a36c61f9SKrishna Gudipati 
1657a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1658a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->reply_oxid);
1659a36c61f9SKrishna Gudipati 
1660c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
1661c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
1662a36c61f9SKrishna Gudipati 	if (!fcxp) {
1663a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1664c3f1b123SKrishna Gudipati 				bfa_fcs_rport_send_plogiacc, rport, BFA_FALSE);
1665a36c61f9SKrishna Gudipati 		return;
1666a36c61f9SKrishna Gudipati 	}
1667a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1668a36c61f9SKrishna Gudipati 
1669a36c61f9SKrishna Gudipati 	len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1670a36c61f9SKrishna Gudipati 				 rport->pid, bfa_fcs_lport_get_fcid(port),
1671a36c61f9SKrishna Gudipati 				 rport->reply_oxid, port->port_cfg.pwwn,
1672a36c61f9SKrishna Gudipati 				 port->port_cfg.nwwn,
1673be540a99SKrishna Gudipati 				 bfa_fcport_get_maxfrsize(port->fcs->bfa),
1674be540a99SKrishna Gudipati 				 bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
1675a36c61f9SKrishna Gudipati 
1676a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1677a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1678a36c61f9SKrishna Gudipati 
1679a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1680a36c61f9SKrishna Gudipati }
1681a36c61f9SKrishna Gudipati 
1682a36c61f9SKrishna Gudipati static void
1683a36c61f9SKrishna Gudipati bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1684a36c61f9SKrishna Gudipati {
1685a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1686a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1687a36c61f9SKrishna Gudipati 	struct fchs_s		fchs;
1688a36c61f9SKrishna Gudipati 	int		len;
1689a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1690a36c61f9SKrishna Gudipati 
1691a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1692a36c61f9SKrishna Gudipati 
1693c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
1694c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1695a36c61f9SKrishna Gudipati 	if (!fcxp) {
1696a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1697c3f1b123SKrishna Gudipati 				bfa_fcs_rport_send_adisc, rport, BFA_TRUE);
1698a36c61f9SKrishna Gudipati 		return;
1699a36c61f9SKrishna Gudipati 	}
1700a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1701a36c61f9SKrishna Gudipati 
1702a36c61f9SKrishna Gudipati 	len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1703a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0,
1704a36c61f9SKrishna Gudipati 				port->port_cfg.pwwn, port->port_cfg.nwwn);
1705a36c61f9SKrishna Gudipati 
1706a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1707a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, bfa_fcs_rport_adisc_response,
1708a36c61f9SKrishna Gudipati 			rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1709a36c61f9SKrishna Gudipati 
1710a36c61f9SKrishna Gudipati 	rport->stats.adisc_sent++;
1711a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1712a36c61f9SKrishna Gudipati }
1713a36c61f9SKrishna Gudipati 
1714a36c61f9SKrishna Gudipati static void
1715a36c61f9SKrishna Gudipati bfa_fcs_rport_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1716a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
1717a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs)
1718a36c61f9SKrishna Gudipati {
1719a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1720a36c61f9SKrishna Gudipati 	void		*pld = bfa_fcxp_get_rspbuf(fcxp);
1721a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s	*ls_rjt;
1722a36c61f9SKrishna Gudipati 
1723a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
1724a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, req_status);
1725a36c61f9SKrishna Gudipati 		rport->stats.adisc_failed++;
1726a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1727a36c61f9SKrishna Gudipati 		return;
1728a36c61f9SKrishna Gudipati 	}
1729a36c61f9SKrishna Gudipati 
1730a36c61f9SKrishna Gudipati 	if (fc_adisc_rsp_parse((struct fc_adisc_s *)pld, rsp_len, rport->pwwn,
1731a36c61f9SKrishna Gudipati 				rport->nwwn)  == FC_PARSE_OK) {
1732a36c61f9SKrishna Gudipati 		rport->stats.adisc_accs++;
1733a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1734a36c61f9SKrishna Gudipati 		return;
1735a36c61f9SKrishna Gudipati 	}
1736a36c61f9SKrishna Gudipati 
1737a36c61f9SKrishna Gudipati 	rport->stats.adisc_rejects++;
1738a36c61f9SKrishna Gudipati 	ls_rjt = pld;
1739a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, ls_rjt->els_cmd.els_code);
1740a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, ls_rjt->reason_code);
1741a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1742a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1743a36c61f9SKrishna Gudipati }
1744a36c61f9SKrishna Gudipati 
1745a36c61f9SKrishna Gudipati static void
1746a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1747a36c61f9SKrishna Gudipati {
1748a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1749a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1750a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1751a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1752a36c61f9SKrishna Gudipati 	int		len;
1753a36c61f9SKrishna Gudipati 	bfa_cb_fcxp_send_t cbfn;
1754a36c61f9SKrishna Gudipati 
1755a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1756a36c61f9SKrishna Gudipati 
1757c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
1758c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1759a36c61f9SKrishna Gudipati 	if (!fcxp) {
1760a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1761c3f1b123SKrishna Gudipati 				bfa_fcs_rport_send_nsdisc, rport, BFA_TRUE);
1762a36c61f9SKrishna Gudipati 		return;
1763a36c61f9SKrishna Gudipati 	}
1764a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1765a36c61f9SKrishna Gudipati 
1766a36c61f9SKrishna Gudipati 	if (rport->pwwn) {
1767a36c61f9SKrishna Gudipati 		len = fc_gidpn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1768a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0, rport->pwwn);
1769a36c61f9SKrishna Gudipati 		cbfn = bfa_fcs_rport_gidpn_response;
1770a36c61f9SKrishna Gudipati 	} else {
1771a36c61f9SKrishna Gudipati 		len = fc_gpnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1772a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0, rport->pid);
1773a36c61f9SKrishna Gudipati 		cbfn = bfa_fcs_rport_gpnid_response;
1774a36c61f9SKrishna Gudipati 	}
1775a36c61f9SKrishna Gudipati 
1776a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1777a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, cbfn,
1778a36c61f9SKrishna Gudipati 			(void *)rport, FC_MAX_PDUSZ, FC_FCCT_TOV);
1779a36c61f9SKrishna Gudipati 
1780a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1781a36c61f9SKrishna Gudipati }
1782a36c61f9SKrishna Gudipati 
1783a36c61f9SKrishna Gudipati static void
1784a36c61f9SKrishna Gudipati bfa_fcs_rport_gidpn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1785a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
1786a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs)
1787a36c61f9SKrishna Gudipati {
1788a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1789a36c61f9SKrishna Gudipati 	struct ct_hdr_s	*cthdr;
1790a36c61f9SKrishna Gudipati 	struct fcgs_gidpn_resp_s	*gidpn_rsp;
1791a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s	*twin;
1792a36c61f9SKrishna Gudipati 	struct list_head	*qe;
1793a36c61f9SKrishna Gudipati 
1794a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1795a36c61f9SKrishna Gudipati 
1796a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1797ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
1798a36c61f9SKrishna Gudipati 
1799a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1800a36c61f9SKrishna Gudipati 		/* Check if the pid is the same as before. */
1801a36c61f9SKrishna Gudipati 		gidpn_rsp = (struct fcgs_gidpn_resp_s *) (cthdr + 1);
1802a36c61f9SKrishna Gudipati 
1803a36c61f9SKrishna Gudipati 		if (gidpn_rsp->dap == rport->pid) {
1804a36c61f9SKrishna Gudipati 			/* Device is online  */
1805a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1806a36c61f9SKrishna Gudipati 		} else {
1807a36c61f9SKrishna Gudipati 			/*
1808a36c61f9SKrishna Gudipati 			 * Device's PID has changed. We need to cleanup
1809a36c61f9SKrishna Gudipati 			 * and re-login. If there is another device with
1810a36c61f9SKrishna Gudipati 			 * the the newly discovered pid, send an scn notice
1811a36c61f9SKrishna Gudipati 			 * so that its new pid can be discovered.
1812a36c61f9SKrishna Gudipati 			 */
1813a36c61f9SKrishna Gudipati 			list_for_each(qe, &rport->port->rport_q) {
1814a36c61f9SKrishna Gudipati 				twin = (struct bfa_fcs_rport_s *) qe;
1815a36c61f9SKrishna Gudipati 				if (twin == rport)
1816a36c61f9SKrishna Gudipati 					continue;
1817a36c61f9SKrishna Gudipati 				if (gidpn_rsp->dap == twin->pid) {
1818a36c61f9SKrishna Gudipati 					bfa_trc(rport->fcs, twin->pid);
1819a36c61f9SKrishna Gudipati 					bfa_trc(rport->fcs, rport->pid);
1820a36c61f9SKrishna Gudipati 
1821a36c61f9SKrishna Gudipati 					twin->pid = 0;
1822a36c61f9SKrishna Gudipati 					bfa_sm_send_event(twin,
1823a36c61f9SKrishna Gudipati 					 RPSM_EVENT_ADDRESS_CHANGE);
1824a36c61f9SKrishna Gudipati 				}
1825a36c61f9SKrishna Gudipati 			}
1826a36c61f9SKrishna Gudipati 			rport->pid = gidpn_rsp->dap;
1827a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_CHANGE);
1828a36c61f9SKrishna Gudipati 		}
1829a36c61f9SKrishna Gudipati 		return;
1830a36c61f9SKrishna Gudipati 	}
1831a36c61f9SKrishna Gudipati 
1832a36c61f9SKrishna Gudipati 	/*
1833a36c61f9SKrishna Gudipati 	 * Reject Response
1834a36c61f9SKrishna Gudipati 	 */
1835a36c61f9SKrishna Gudipati 	switch (cthdr->reason_code) {
1836a36c61f9SKrishna Gudipati 	case CT_RSN_LOGICAL_BUSY:
1837a36c61f9SKrishna Gudipati 		/*
1838a36c61f9SKrishna Gudipati 		 * Need to retry
1839a36c61f9SKrishna Gudipati 		 */
1840a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
1841a36c61f9SKrishna Gudipati 		break;
1842a36c61f9SKrishna Gudipati 
1843a36c61f9SKrishna Gudipati 	case CT_RSN_UNABLE_TO_PERF:
1844a36c61f9SKrishna Gudipati 		/*
1845a36c61f9SKrishna Gudipati 		 * device doesn't exist : Start timer to cleanup this later.
1846a36c61f9SKrishna Gudipati 		 */
1847a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1848a36c61f9SKrishna Gudipati 		break;
1849a36c61f9SKrishna Gudipati 
1850a36c61f9SKrishna Gudipati 	default:
1851a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1852a36c61f9SKrishna Gudipati 		break;
1853a36c61f9SKrishna Gudipati 	}
1854a36c61f9SKrishna Gudipati }
1855a36c61f9SKrishna Gudipati 
1856a36c61f9SKrishna Gudipati static void
1857a36c61f9SKrishna Gudipati bfa_fcs_rport_gpnid_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1858a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
1859a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs)
1860a36c61f9SKrishna Gudipati {
1861a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1862a36c61f9SKrishna Gudipati 	struct ct_hdr_s	*cthdr;
1863a36c61f9SKrishna Gudipati 
1864a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1865a36c61f9SKrishna Gudipati 
1866a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1867ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
1868a36c61f9SKrishna Gudipati 
1869a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1870a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1871a36c61f9SKrishna Gudipati 		return;
1872a36c61f9SKrishna Gudipati 	}
1873a36c61f9SKrishna Gudipati 
1874a36c61f9SKrishna Gudipati 	/*
1875a36c61f9SKrishna Gudipati 	 * Reject Response
1876a36c61f9SKrishna Gudipati 	 */
1877a36c61f9SKrishna Gudipati 	switch (cthdr->reason_code) {
1878a36c61f9SKrishna Gudipati 	case CT_RSN_LOGICAL_BUSY:
1879a36c61f9SKrishna Gudipati 		/*
1880a36c61f9SKrishna Gudipati 		 * Need to retry
1881a36c61f9SKrishna Gudipati 		 */
1882a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
1883a36c61f9SKrishna Gudipati 		break;
1884a36c61f9SKrishna Gudipati 
1885a36c61f9SKrishna Gudipati 	case CT_RSN_UNABLE_TO_PERF:
1886a36c61f9SKrishna Gudipati 		/*
1887a36c61f9SKrishna Gudipati 		 * device doesn't exist : Start timer to cleanup this later.
1888a36c61f9SKrishna Gudipati 		 */
1889a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1890a36c61f9SKrishna Gudipati 		break;
1891a36c61f9SKrishna Gudipati 
1892a36c61f9SKrishna Gudipati 	default:
1893a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1894a36c61f9SKrishna Gudipati 		break;
1895a36c61f9SKrishna Gudipati 	}
1896a36c61f9SKrishna Gudipati }
1897a36c61f9SKrishna Gudipati 
18985fbe25c7SJing Huang /*
1899a36c61f9SKrishna Gudipati  *	Called to send a logout to the rport.
1900a36c61f9SKrishna Gudipati  */
1901a36c61f9SKrishna Gudipati static void
1902a36c61f9SKrishna Gudipati bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1903a36c61f9SKrishna Gudipati {
1904a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1905a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port;
1906a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1907a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1908a36c61f9SKrishna Gudipati 	u16	len;
1909a36c61f9SKrishna Gudipati 
1910a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1911a36c61f9SKrishna Gudipati 
1912a36c61f9SKrishna Gudipati 	port = rport->port;
1913a36c61f9SKrishna Gudipati 
1914c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
1915c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
1916a36c61f9SKrishna Gudipati 	if (!fcxp) {
1917a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1918c3f1b123SKrishna Gudipati 				bfa_fcs_rport_send_logo, rport, BFA_FALSE);
1919a36c61f9SKrishna Gudipati 		return;
1920a36c61f9SKrishna Gudipati 	}
1921a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1922a36c61f9SKrishna Gudipati 
1923a36c61f9SKrishna Gudipati 	len = fc_logo_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1924a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0,
1925a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_pwwn(port));
1926a36c61f9SKrishna Gudipati 
1927a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1928a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL,
1929a36c61f9SKrishna Gudipati 			rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1930a36c61f9SKrishna Gudipati 
1931a36c61f9SKrishna Gudipati 	rport->stats.logos++;
1932a36c61f9SKrishna Gudipati 	bfa_fcxp_discard(rport->fcxp);
1933a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1934a36c61f9SKrishna Gudipati }
1935a36c61f9SKrishna Gudipati 
19365fbe25c7SJing Huang /*
1937a36c61f9SKrishna Gudipati  *	Send ACC for a LOGO received.
1938a36c61f9SKrishna Gudipati  */
1939a36c61f9SKrishna Gudipati static void
1940a36c61f9SKrishna Gudipati bfa_fcs_rport_send_logo_acc(void *rport_cbarg)
1941a36c61f9SKrishna Gudipati {
1942a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1943a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port;
1944a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1945a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1946a36c61f9SKrishna Gudipati 	u16	len;
1947a36c61f9SKrishna Gudipati 
1948a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1949a36c61f9SKrishna Gudipati 
1950a36c61f9SKrishna Gudipati 	port = rport->port;
1951a36c61f9SKrishna Gudipati 
1952c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
1953a36c61f9SKrishna Gudipati 	if (!fcxp)
1954a36c61f9SKrishna Gudipati 		return;
1955a36c61f9SKrishna Gudipati 
1956a36c61f9SKrishna Gudipati 	rport->stats.logo_rcvd++;
1957a36c61f9SKrishna Gudipati 	len = fc_logo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1958a36c61f9SKrishna Gudipati 				rport->pid, bfa_fcs_lport_get_fcid(port),
1959a36c61f9SKrishna Gudipati 				rport->reply_oxid);
1960a36c61f9SKrishna Gudipati 
1961a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1962a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1963a36c61f9SKrishna Gudipati }
1964a36c61f9SKrishna Gudipati 
19655fbe25c7SJing Huang /*
1966a36c61f9SKrishna Gudipati  *	brief
1967a36c61f9SKrishna Gudipati  *	This routine will be called by bfa_timer on timer timeouts.
1968a36c61f9SKrishna Gudipati  *
1969a36c61f9SKrishna Gudipati  *	param[in]	rport			- pointer to bfa_fcs_lport_ns_t.
1970a36c61f9SKrishna Gudipati  *	param[out]	rport_status	- pointer to return vport status in
1971a36c61f9SKrishna Gudipati  *
1972a36c61f9SKrishna Gudipati  *	return
1973a36c61f9SKrishna Gudipati  *		void
1974a36c61f9SKrishna Gudipati  *
1975a36c61f9SKrishna Gudipati  *	Special Considerations:
1976a36c61f9SKrishna Gudipati  *
1977a36c61f9SKrishna Gudipati  *	note
1978a36c61f9SKrishna Gudipati  */
1979a36c61f9SKrishna Gudipati static void
1980a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout(void *arg)
1981a36c61f9SKrishna Gudipati {
1982a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) arg;
1983a36c61f9SKrishna Gudipati 
1984a36c61f9SKrishna Gudipati 	rport->stats.plogi_timeouts++;
1985a36c61f9SKrishna Gudipati 	bfa_stats(rport->port, rport_plogi_timeouts);
1986a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
1987a36c61f9SKrishna Gudipati }
1988a36c61f9SKrishna Gudipati 
1989a36c61f9SKrishna Gudipati static void
1990a36c61f9SKrishna Gudipati bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
1991a36c61f9SKrishna Gudipati 			struct fchs_s *rx_fchs, u16 len)
1992a36c61f9SKrishna Gudipati {
1993a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1994a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1995a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1996a36c61f9SKrishna Gudipati 	struct fc_prli_s	*prli;
1997a36c61f9SKrishna Gudipati 
1998a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
1999a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
2000a36c61f9SKrishna Gudipati 
2001a36c61f9SKrishna Gudipati 	rport->stats.prli_rcvd++;
2002a36c61f9SKrishna Gudipati 
2003a36c61f9SKrishna Gudipati 	/*
2004a36c61f9SKrishna Gudipati 	 * We are in Initiator Mode
2005a36c61f9SKrishna Gudipati 	 */
2006a36c61f9SKrishna Gudipati 	prli = (struct fc_prli_s *) (rx_fchs + 1);
2007a36c61f9SKrishna Gudipati 
2008a36c61f9SKrishna Gudipati 	if (prli->parampage.servparams.target) {
2009a36c61f9SKrishna Gudipati 		/*
2010a36c61f9SKrishna Gudipati 		 * PRLI from a target ?
2011a36c61f9SKrishna Gudipati 		 * Send the Acc.
2012a36c61f9SKrishna Gudipati 		 * PRLI sent by us will be used to transition the IT nexus,
2013a36c61f9SKrishna Gudipati 		 * once the response is received from the target.
2014a36c61f9SKrishna Gudipati 		 */
2015a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, rx_fchs->s_id);
2016a36c61f9SKrishna Gudipati 		rport->scsi_function = BFA_RPORT_TARGET;
2017a36c61f9SKrishna Gudipati 	} else {
2018a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, prli->parampage.type);
2019a36c61f9SKrishna Gudipati 		rport->scsi_function = BFA_RPORT_INITIATOR;
2020a36c61f9SKrishna Gudipati 		bfa_fcs_itnim_is_initiator(rport->itnim);
2021a36c61f9SKrishna Gudipati 	}
2022a36c61f9SKrishna Gudipati 
2023c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2024a36c61f9SKrishna Gudipati 	if (!fcxp)
2025a36c61f9SKrishna Gudipati 		return;
2026a36c61f9SKrishna Gudipati 
2027a36c61f9SKrishna Gudipati 	len = fc_prli_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2028a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2029a36c61f9SKrishna Gudipati 				rx_fchs->ox_id, port->port_cfg.roles);
2030a36c61f9SKrishna Gudipati 
2031a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2032a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
2033a36c61f9SKrishna Gudipati }
2034a36c61f9SKrishna Gudipati 
2035a36c61f9SKrishna Gudipati static void
2036a36c61f9SKrishna Gudipati bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport,
2037a36c61f9SKrishna Gudipati 			struct fchs_s *rx_fchs, u16 len)
2038a36c61f9SKrishna Gudipati {
2039a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2040a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2041a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2042a36c61f9SKrishna Gudipati 	struct fc_rpsc_speed_info_s speeds;
2043a36c61f9SKrishna Gudipati 	struct bfa_port_attr_s pport_attr;
2044a36c61f9SKrishna Gudipati 
2045a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
2046a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
2047a36c61f9SKrishna Gudipati 
2048a36c61f9SKrishna Gudipati 	rport->stats.rpsc_rcvd++;
2049a36c61f9SKrishna Gudipati 	speeds.port_speed_cap =
2050a36c61f9SKrishna Gudipati 		RPSC_SPEED_CAP_1G | RPSC_SPEED_CAP_2G | RPSC_SPEED_CAP_4G |
2051a36c61f9SKrishna Gudipati 		RPSC_SPEED_CAP_8G;
2052a36c61f9SKrishna Gudipati 
2053a36c61f9SKrishna Gudipati 	/*
2054a36c61f9SKrishna Gudipati 	 * get curent speed from pport attributes from BFA
2055a36c61f9SKrishna Gudipati 	 */
2056a36c61f9SKrishna Gudipati 	bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
2057a36c61f9SKrishna Gudipati 
2058a36c61f9SKrishna Gudipati 	speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
2059a36c61f9SKrishna Gudipati 
2060c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2061a36c61f9SKrishna Gudipati 	if (!fcxp)
2062a36c61f9SKrishna Gudipati 		return;
2063a36c61f9SKrishna Gudipati 
2064a36c61f9SKrishna Gudipati 	len = fc_rpsc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2065a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2066a36c61f9SKrishna Gudipati 				rx_fchs->ox_id, &speeds);
2067a36c61f9SKrishna Gudipati 
2068a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2069a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
2070a36c61f9SKrishna Gudipati }
2071a36c61f9SKrishna Gudipati 
2072a36c61f9SKrishna Gudipati static void
2073a36c61f9SKrishna Gudipati bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
2074a36c61f9SKrishna Gudipati 			struct fchs_s *rx_fchs, u16 len)
2075a36c61f9SKrishna Gudipati {
2076a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2077a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2078a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2079a36c61f9SKrishna Gudipati 	struct fc_adisc_s	*adisc;
2080a36c61f9SKrishna Gudipati 
2081a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
2082a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
2083a36c61f9SKrishna Gudipati 
2084a36c61f9SKrishna Gudipati 	rport->stats.adisc_rcvd++;
2085a36c61f9SKrishna Gudipati 
2086a36c61f9SKrishna Gudipati 	adisc = (struct fc_adisc_s *) (rx_fchs + 1);
2087a36c61f9SKrishna Gudipati 
2088a36c61f9SKrishna Gudipati 	/*
2089a36c61f9SKrishna Gudipati 	 * Accept if the itnim for this rport is online.
2090a36c61f9SKrishna Gudipati 	 * Else reject the ADISC.
2091a36c61f9SKrishna Gudipati 	 */
2092a36c61f9SKrishna Gudipati 	if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) {
2093a36c61f9SKrishna Gudipati 
2094c3f1b123SKrishna Gudipati 		fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2095a36c61f9SKrishna Gudipati 		if (!fcxp)
2096a36c61f9SKrishna Gudipati 			return;
2097a36c61f9SKrishna Gudipati 
2098a36c61f9SKrishna Gudipati 		len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2099a36c61f9SKrishna Gudipati 			 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2100a36c61f9SKrishna Gudipati 			 rx_fchs->ox_id, port->port_cfg.pwwn,
2101a36c61f9SKrishna Gudipati 			 port->port_cfg.nwwn);
2102a36c61f9SKrishna Gudipati 
2103a36c61f9SKrishna Gudipati 		bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
2104a36c61f9SKrishna Gudipati 				BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
2105a36c61f9SKrishna Gudipati 				FC_MAX_PDUSZ, 0);
2106a36c61f9SKrishna Gudipati 	} else {
2107a36c61f9SKrishna Gudipati 		rport->stats.adisc_rejected++;
2108a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_ls_rjt(rport, rx_fchs,
2109a36c61f9SKrishna Gudipati 					  FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD,
2110a36c61f9SKrishna Gudipati 					  FC_LS_RJT_EXP_LOGIN_REQUIRED);
2111a36c61f9SKrishna Gudipati 	}
2112a36c61f9SKrishna Gudipati }
2113a36c61f9SKrishna Gudipati 
2114a36c61f9SKrishna Gudipati static void
2115a36c61f9SKrishna Gudipati bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport)
2116a36c61f9SKrishna Gudipati {
2117a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2118a36c61f9SKrishna Gudipati 	struct bfa_rport_info_s rport_info;
2119a36c61f9SKrishna Gudipati 
2120a36c61f9SKrishna Gudipati 	rport_info.pid = rport->pid;
2121a36c61f9SKrishna Gudipati 	rport_info.local_pid = port->pid;
2122a36c61f9SKrishna Gudipati 	rport_info.lp_tag = port->lp_tag;
2123a36c61f9SKrishna Gudipati 	rport_info.vf_id = port->fabric->vf_id;
2124a36c61f9SKrishna Gudipati 	rport_info.vf_en = port->fabric->is_vf;
2125a36c61f9SKrishna Gudipati 	rport_info.fc_class = rport->fc_cos;
2126a36c61f9SKrishna Gudipati 	rport_info.cisc = rport->cisc;
2127a36c61f9SKrishna Gudipati 	rport_info.max_frmsz = rport->maxfrsize;
2128a36c61f9SKrishna Gudipati 	bfa_rport_online(rport->bfa_rport, &rport_info);
2129a36c61f9SKrishna Gudipati }
2130a36c61f9SKrishna Gudipati 
213161ba4394SKrishna Gudipati static void
213261ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport)
213361ba4394SKrishna Gudipati {
213461ba4394SKrishna Gudipati 	if (rport->bfa_rport)
213561ba4394SKrishna Gudipati 		bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
213661ba4394SKrishna Gudipati 	else
213761ba4394SKrishna Gudipati 		bfa_cb_rport_offline(rport);
213861ba4394SKrishna Gudipati }
213961ba4394SKrishna Gudipati 
2140a36c61f9SKrishna Gudipati static struct bfa_fcs_rport_s *
2141a36c61f9SKrishna Gudipati bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
2142a36c61f9SKrishna Gudipati {
2143a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs = port->fcs;
2144a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2145a36c61f9SKrishna Gudipati 	struct bfad_rport_s	*rport_drv;
2146a36c61f9SKrishna Gudipati 
21475fbe25c7SJing Huang 	/*
2148a36c61f9SKrishna Gudipati 	 * allocate rport
2149a36c61f9SKrishna Gudipati 	 */
215061ba4394SKrishna Gudipati 	if (fcs->num_rport_logins >= bfa_fcs_rport_max_logins) {
215161ba4394SKrishna Gudipati 		bfa_trc(fcs, rpid);
215261ba4394SKrishna Gudipati 		return NULL;
215361ba4394SKrishna Gudipati 	}
215461ba4394SKrishna Gudipati 
2155a36c61f9SKrishna Gudipati 	if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv)
2156a36c61f9SKrishna Gudipati 		!= BFA_STATUS_OK) {
2157a36c61f9SKrishna Gudipati 		bfa_trc(fcs, rpid);
2158a36c61f9SKrishna Gudipati 		return NULL;
2159a36c61f9SKrishna Gudipati 	}
2160a36c61f9SKrishna Gudipati 
2161a36c61f9SKrishna Gudipati 	/*
2162a36c61f9SKrishna Gudipati 	 * Initialize r-port
2163a36c61f9SKrishna Gudipati 	 */
2164a36c61f9SKrishna Gudipati 	rport->port = port;
2165a36c61f9SKrishna Gudipati 	rport->fcs = fcs;
2166a36c61f9SKrishna Gudipati 	rport->rp_drv = rport_drv;
2167a36c61f9SKrishna Gudipati 	rport->pid = rpid;
2168a36c61f9SKrishna Gudipati 	rport->pwwn = pwwn;
2169ee1a4a42SKrishna Gudipati 	rport->old_pid = 0;
2170a36c61f9SKrishna Gudipati 
217161ba4394SKrishna Gudipati 	rport->bfa_rport = NULL;
2172a36c61f9SKrishna Gudipati 
21735fbe25c7SJing Huang 	/*
2174a36c61f9SKrishna Gudipati 	 * allocate FC-4s
2175a36c61f9SKrishna Gudipati 	 */
2176d4b671c5SJing Huang 	WARN_ON(!bfa_fcs_lport_is_initiator(port));
2177a36c61f9SKrishna Gudipati 
2178a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_is_initiator(port)) {
2179a36c61f9SKrishna Gudipati 		rport->itnim = bfa_fcs_itnim_create(rport);
2180a36c61f9SKrishna Gudipati 		if (!rport->itnim) {
2181a36c61f9SKrishna Gudipati 			bfa_trc(fcs, rpid);
2182a36c61f9SKrishna Gudipati 			kfree(rport_drv);
2183a36c61f9SKrishna Gudipati 			return NULL;
2184a36c61f9SKrishna Gudipati 		}
2185a36c61f9SKrishna Gudipati 	}
2186a36c61f9SKrishna Gudipati 
2187a36c61f9SKrishna Gudipati 	bfa_fcs_lport_add_rport(port, rport);
218861ba4394SKrishna Gudipati 	fcs->num_rport_logins++;
2189a36c61f9SKrishna Gudipati 
2190a36c61f9SKrishna Gudipati 	bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
2191a36c61f9SKrishna Gudipati 
2192a36c61f9SKrishna Gudipati 	/* Initialize the Rport Features(RPF) Sub Module  */
2193a36c61f9SKrishna Gudipati 	if (!BFA_FCS_PID_IS_WKA(rport->pid))
2194a36c61f9SKrishna Gudipati 		bfa_fcs_rpf_init(rport);
2195a36c61f9SKrishna Gudipati 
2196a36c61f9SKrishna Gudipati 	return rport;
2197a36c61f9SKrishna Gudipati }
2198a36c61f9SKrishna Gudipati 
2199a36c61f9SKrishna Gudipati 
2200a36c61f9SKrishna Gudipati static void
2201a36c61f9SKrishna Gudipati bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
2202a36c61f9SKrishna Gudipati {
2203a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
220461ba4394SKrishna Gudipati 	struct bfa_fcs_s *fcs = port->fcs;
2205a36c61f9SKrishna Gudipati 
22065fbe25c7SJing Huang 	/*
2207a36c61f9SKrishna Gudipati 	 * - delete FC-4s
2208a36c61f9SKrishna Gudipati 	 * - delete BFA rport
2209a36c61f9SKrishna Gudipati 	 * - remove from queue of rports
2210a36c61f9SKrishna Gudipati 	 */
221161ba4394SKrishna Gudipati 	rport->plogi_pending = BFA_FALSE;
221261ba4394SKrishna Gudipati 
2213a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_is_initiator(port)) {
2214a36c61f9SKrishna Gudipati 		bfa_fcs_itnim_delete(rport->itnim);
2215a36c61f9SKrishna Gudipati 		if (rport->pid != 0 && !BFA_FCS_PID_IS_WKA(rport->pid))
2216a36c61f9SKrishna Gudipati 			bfa_fcs_rpf_rport_offline(rport);
2217a36c61f9SKrishna Gudipati 	}
2218a36c61f9SKrishna Gudipati 
221961ba4394SKrishna Gudipati 	if (rport->bfa_rport) {
2220f7f73812SMaggie Zhang 		bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_DELETE);
222161ba4394SKrishna Gudipati 		rport->bfa_rport = NULL;
222261ba4394SKrishna Gudipati 	}
222361ba4394SKrishna Gudipati 
2224a36c61f9SKrishna Gudipati 	bfa_fcs_lport_del_rport(port, rport);
222561ba4394SKrishna Gudipati 	fcs->num_rport_logins--;
2226a36c61f9SKrishna Gudipati 	kfree(rport->rp_drv);
2227a36c61f9SKrishna Gudipati }
2228a36c61f9SKrishna Gudipati 
2229a36c61f9SKrishna Gudipati static void
22307826f304SKrishna Gudipati bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport,
22317826f304SKrishna Gudipati 			enum bfa_rport_aen_event event,
22327826f304SKrishna Gudipati 			struct bfa_rport_aen_data_s *data)
22337826f304SKrishna Gudipati {
22347826f304SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
22357826f304SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
22367826f304SKrishna Gudipati 	struct bfa_aen_entry_s  *aen_entry;
22377826f304SKrishna Gudipati 
22387826f304SKrishna Gudipati 	bfad_get_aen_entry(bfad, aen_entry);
22397826f304SKrishna Gudipati 	if (!aen_entry)
22407826f304SKrishna Gudipati 		return;
22417826f304SKrishna Gudipati 
22427826f304SKrishna Gudipati 	if (event == BFA_RPORT_AEN_QOS_PRIO)
22437826f304SKrishna Gudipati 		aen_entry->aen_data.rport.priv.qos = data->priv.qos;
22447826f304SKrishna Gudipati 	else if (event == BFA_RPORT_AEN_QOS_FLOWID)
22457826f304SKrishna Gudipati 		aen_entry->aen_data.rport.priv.qos = data->priv.qos;
22467826f304SKrishna Gudipati 
22477826f304SKrishna Gudipati 	aen_entry->aen_data.rport.vf_id = rport->port->fabric->vf_id;
22487826f304SKrishna Gudipati 	aen_entry->aen_data.rport.ppwwn = bfa_fcs_lport_get_pwwn(
22497826f304SKrishna Gudipati 					bfa_fcs_get_base_port(rport->fcs));
22507826f304SKrishna Gudipati 	aen_entry->aen_data.rport.lpwwn = bfa_fcs_lport_get_pwwn(rport->port);
22517826f304SKrishna Gudipati 	aen_entry->aen_data.rport.rpwwn = rport->pwwn;
22527826f304SKrishna Gudipati 
22537826f304SKrishna Gudipati 	/* Send the AEN notification */
22547826f304SKrishna Gudipati 	bfad_im_post_vendor_event(aen_entry, bfad, ++rport->fcs->fcs_aen_seq,
22557826f304SKrishna Gudipati 				  BFA_AEN_CAT_RPORT, event);
22567826f304SKrishna Gudipati }
22577826f304SKrishna Gudipati 
22587826f304SKrishna Gudipati static void
225961ba4394SKrishna Gudipati bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport)
226061ba4394SKrishna Gudipati {
226161ba4394SKrishna Gudipati 	if ((!rport->pid) || (!rport->pwwn)) {
226261ba4394SKrishna Gudipati 		bfa_trc(rport->fcs, rport->pid);
226361ba4394SKrishna Gudipati 		bfa_sm_fault(rport->fcs, rport->pid);
226461ba4394SKrishna Gudipati 	}
226561ba4394SKrishna Gudipati 
226661ba4394SKrishna Gudipati 	bfa_sm_send_event(rport->itnim, BFA_FCS_ITNIM_SM_FCS_ONLINE);
226761ba4394SKrishna Gudipati }
226861ba4394SKrishna Gudipati 
226961ba4394SKrishna Gudipati static void
227061ba4394SKrishna Gudipati bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport)
2271a36c61f9SKrishna Gudipati {
2272a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2273a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2274a36c61f9SKrishna Gudipati 	char	lpwwn_buf[BFA_STRING_32];
2275a36c61f9SKrishna Gudipati 	char	rpwwn_buf[BFA_STRING_32];
2276a36c61f9SKrishna Gudipati 
2277a36c61f9SKrishna Gudipati 	rport->stats.onlines++;
2278a36c61f9SKrishna Gudipati 
2279d7be54ccSKrishna Gudipati 	if ((!rport->pid) || (!rport->pwwn)) {
2280d7be54ccSKrishna Gudipati 		bfa_trc(rport->fcs, rport->pid);
2281d7be54ccSKrishna Gudipati 		bfa_sm_fault(rport->fcs, rport->pid);
2282d7be54ccSKrishna Gudipati 	}
2283d7be54ccSKrishna Gudipati 
2284a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_is_initiator(port)) {
228561ba4394SKrishna Gudipati 		bfa_fcs_itnim_brp_online(rport->itnim);
2286a36c61f9SKrishna Gudipati 		if (!BFA_FCS_PID_IS_WKA(rport->pid))
2287a36c61f9SKrishna Gudipati 			bfa_fcs_rpf_rport_online(rport);
2288a36c61f9SKrishna Gudipati 	};
2289a36c61f9SKrishna Gudipati 
2290a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2291a36c61f9SKrishna Gudipati 	wwn2str(rpwwn_buf, rport->pwwn);
22927826f304SKrishna Gudipati 	if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
229388166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2294a36c61f9SKrishna Gudipati 		"Remote port (WWN = %s) online for logical port (WWN = %s)\n",
2295a36c61f9SKrishna Gudipati 		rpwwn_buf, lpwwn_buf);
22967826f304SKrishna Gudipati 		bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_ONLINE, NULL);
22977826f304SKrishna Gudipati 	}
2298a36c61f9SKrishna Gudipati }
2299a36c61f9SKrishna Gudipati 
2300a36c61f9SKrishna Gudipati static void
230161ba4394SKrishna Gudipati bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport)
230261ba4394SKrishna Gudipati {
230361ba4394SKrishna Gudipati 	if (!BFA_FCS_PID_IS_WKA(rport->pid))
230461ba4394SKrishna Gudipati 		bfa_fcs_rpf_rport_offline(rport);
230561ba4394SKrishna Gudipati 
230661ba4394SKrishna Gudipati 	bfa_fcs_itnim_rport_offline(rport->itnim);
230761ba4394SKrishna Gudipati }
230861ba4394SKrishna Gudipati 
230961ba4394SKrishna Gudipati static void
231061ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport)
2311a36c61f9SKrishna Gudipati {
2312a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2313a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2314a36c61f9SKrishna Gudipati 	char	lpwwn_buf[BFA_STRING_32];
2315a36c61f9SKrishna Gudipati 	char	rpwwn_buf[BFA_STRING_32];
2316a36c61f9SKrishna Gudipati 
231761ba4394SKrishna Gudipati 	if (!rport->bfa_rport) {
231861ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
231961ba4394SKrishna Gudipati 		return;
232061ba4394SKrishna Gudipati 	}
232161ba4394SKrishna Gudipati 
2322a36c61f9SKrishna Gudipati 	rport->stats.offlines++;
2323a36c61f9SKrishna Gudipati 
2324a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2325a36c61f9SKrishna Gudipati 	wwn2str(rpwwn_buf, rport->pwwn);
2326a36c61f9SKrishna Gudipati 	if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
23277826f304SKrishna Gudipati 		if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE) {
232888166242SJing Huang 			BFA_LOG(KERN_ERR, bfad, bfa_log_level,
2329a36c61f9SKrishna Gudipati 				"Remote port (WWN = %s) connectivity lost for "
2330a36c61f9SKrishna Gudipati 				"logical port (WWN = %s)\n",
2331a36c61f9SKrishna Gudipati 				rpwwn_buf, lpwwn_buf);
23327826f304SKrishna Gudipati 			bfa_fcs_rport_aen_post(rport,
23337826f304SKrishna Gudipati 				BFA_RPORT_AEN_DISCONNECT, NULL);
23347826f304SKrishna Gudipati 		} else {
233588166242SJing Huang 			BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2336a36c61f9SKrishna Gudipati 				"Remote port (WWN = %s) offlined by "
2337a36c61f9SKrishna Gudipati 				"logical port (WWN = %s)\n",
2338a36c61f9SKrishna Gudipati 				rpwwn_buf, lpwwn_buf);
23397826f304SKrishna Gudipati 			bfa_fcs_rport_aen_post(rport,
23407826f304SKrishna Gudipati 				BFA_RPORT_AEN_OFFLINE, NULL);
23417826f304SKrishna Gudipati 		}
2342a36c61f9SKrishna Gudipati 	}
2343a36c61f9SKrishna Gudipati 
2344a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_is_initiator(port)) {
2345a36c61f9SKrishna Gudipati 		bfa_fcs_itnim_rport_offline(rport->itnim);
2346a36c61f9SKrishna Gudipati 		if (!BFA_FCS_PID_IS_WKA(rport->pid))
2347a36c61f9SKrishna Gudipati 			bfa_fcs_rpf_rport_offline(rport);
2348a36c61f9SKrishna Gudipati 	}
2349a36c61f9SKrishna Gudipati }
2350a36c61f9SKrishna Gudipati 
23515fbe25c7SJing Huang /*
2352a36c61f9SKrishna Gudipati  * Update rport parameters from PLOGI or PLOGI accept.
2353a36c61f9SKrishna Gudipati  */
2354a36c61f9SKrishna Gudipati static void
2355a36c61f9SKrishna Gudipati bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
2356a36c61f9SKrishna Gudipati {
2357a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = rport->port;
2358a36c61f9SKrishna Gudipati 
23595fbe25c7SJing Huang 	/*
2360a36c61f9SKrishna Gudipati 	 * - port name
2361a36c61f9SKrishna Gudipati 	 * - node name
2362a36c61f9SKrishna Gudipati 	 */
2363a36c61f9SKrishna Gudipati 	rport->pwwn = plogi->port_name;
2364a36c61f9SKrishna Gudipati 	rport->nwwn = plogi->node_name;
2365a36c61f9SKrishna Gudipati 
23665fbe25c7SJing Huang 	/*
2367a36c61f9SKrishna Gudipati 	 * - class of service
2368a36c61f9SKrishna Gudipati 	 */
2369a36c61f9SKrishna Gudipati 	rport->fc_cos = 0;
2370a36c61f9SKrishna Gudipati 	if (plogi->class3.class_valid)
2371a36c61f9SKrishna Gudipati 		rport->fc_cos = FC_CLASS_3;
2372a36c61f9SKrishna Gudipati 
2373a36c61f9SKrishna Gudipati 	if (plogi->class2.class_valid)
2374a36c61f9SKrishna Gudipati 		rport->fc_cos |= FC_CLASS_2;
2375a36c61f9SKrishna Gudipati 
23765fbe25c7SJing Huang 	/*
2377a36c61f9SKrishna Gudipati 	 * - CISC
2378a36c61f9SKrishna Gudipati 	 * - MAX receive frame size
2379a36c61f9SKrishna Gudipati 	 */
2380a36c61f9SKrishna Gudipati 	rport->cisc = plogi->csp.cisc;
2381bd5a0260SKrishna Gudipati 	if (be16_to_cpu(plogi->class3.rxsz) < be16_to_cpu(plogi->csp.rxsz))
2382ba816ea8SJing Huang 		rport->maxfrsize = be16_to_cpu(plogi->class3.rxsz);
2383bd5a0260SKrishna Gudipati 	else
2384bd5a0260SKrishna Gudipati 		rport->maxfrsize = be16_to_cpu(plogi->csp.rxsz);
2385a36c61f9SKrishna Gudipati 
2386ba816ea8SJing Huang 	bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
2387a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->fabric->bb_credit);
23885fbe25c7SJing Huang 	/*
2389a36c61f9SKrishna Gudipati 	 * Direct Attach P2P mode :
2390a36c61f9SKrishna Gudipati 	 * This is to handle a bug (233476) in IBM targets in Direct Attach
2391a36c61f9SKrishna Gudipati 	 *  Mode. Basically, in FLOGI Accept the target would have
2392a36c61f9SKrishna Gudipati 	 * erroneously set the BB Credit to the value used in the FLOGI
2393a36c61f9SKrishna Gudipati 	 * sent by the HBA. It uses the correct value (its own BB credit)
2394a36c61f9SKrishna Gudipati 	 * in PLOGI.
2395a36c61f9SKrishna Gudipati 	 */
2396a36c61f9SKrishna Gudipati 	if ((!bfa_fcs_fabric_is_switched(port->fabric))	 &&
2397ba816ea8SJing Huang 		(be16_to_cpu(plogi->csp.bbcred) < port->fabric->bb_credit)) {
2398a36c61f9SKrishna Gudipati 
2399ba816ea8SJing Huang 		bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
2400a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, port->fabric->bb_credit);
2401a36c61f9SKrishna Gudipati 
2402ba816ea8SJing Huang 		port->fabric->bb_credit = be16_to_cpu(plogi->csp.bbcred);
2403a36c61f9SKrishna Gudipati 		bfa_fcport_set_tx_bbcredit(port->fcs->bfa,
2404be540a99SKrishna Gudipati 					  port->fabric->bb_credit, 0);
2405a36c61f9SKrishna Gudipati 	}
2406a36c61f9SKrishna Gudipati 
2407a36c61f9SKrishna Gudipati }
2408a36c61f9SKrishna Gudipati 
24095fbe25c7SJing Huang /*
2410a36c61f9SKrishna Gudipati  *	Called to handle LOGO received from an existing remote port.
2411a36c61f9SKrishna Gudipati  */
2412a36c61f9SKrishna Gudipati static void
2413a36c61f9SKrishna Gudipati bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs)
2414a36c61f9SKrishna Gudipati {
2415a36c61f9SKrishna Gudipati 	rport->reply_oxid = fchs->ox_id;
2416a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->reply_oxid);
2417a36c61f9SKrishna Gudipati 
2418a36c61f9SKrishna Gudipati 	rport->prlo = BFA_FALSE;
2419a36c61f9SKrishna Gudipati 	rport->stats.logo_rcvd++;
2420a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD);
2421a36c61f9SKrishna Gudipati }
2422a36c61f9SKrishna Gudipati 
2423a36c61f9SKrishna Gudipati 
2424a36c61f9SKrishna Gudipati 
24255fbe25c7SJing Huang /*
2426a36c61f9SKrishna Gudipati  *  fcs_rport_public FCS rport public interfaces
2427a36c61f9SKrishna Gudipati  */
2428a36c61f9SKrishna Gudipati 
24295fbe25c7SJing Huang /*
2430a36c61f9SKrishna Gudipati  *	Called by bport/vport to create a remote port instance for a discovered
2431a36c61f9SKrishna Gudipati  *	remote device.
2432a36c61f9SKrishna Gudipati  *
2433a36c61f9SKrishna Gudipati  * @param[in] port	- base port or vport
2434a36c61f9SKrishna Gudipati  * @param[in] rpid	- remote port ID
2435a36c61f9SKrishna Gudipati  *
2436a36c61f9SKrishna Gudipati  * @return None
2437a36c61f9SKrishna Gudipati  */
2438a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *
2439a36c61f9SKrishna Gudipati bfa_fcs_rport_create(struct bfa_fcs_lport_s *port, u32 rpid)
2440a36c61f9SKrishna Gudipati {
2441a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2442a36c61f9SKrishna Gudipati 
2443a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rpid);
2444a36c61f9SKrishna Gudipati 	rport = bfa_fcs_rport_alloc(port, WWN_NULL, rpid);
2445a36c61f9SKrishna Gudipati 	if (!rport)
2446a36c61f9SKrishna Gudipati 		return NULL;
2447a36c61f9SKrishna Gudipati 
2448a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
2449a36c61f9SKrishna Gudipati 	return rport;
2450a36c61f9SKrishna Gudipati }
2451a36c61f9SKrishna Gudipati 
24525fbe25c7SJing Huang /*
2453a36c61f9SKrishna Gudipati  * Called to create a rport for which only the wwn is known.
2454a36c61f9SKrishna Gudipati  *
2455a36c61f9SKrishna Gudipati  * @param[in] port	- base port
2456a36c61f9SKrishna Gudipati  * @param[in] rpwwn	- remote port wwn
2457a36c61f9SKrishna Gudipati  *
2458a36c61f9SKrishna Gudipati  * @return None
2459a36c61f9SKrishna Gudipati  */
2460a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *
2461a36c61f9SKrishna Gudipati bfa_fcs_rport_create_by_wwn(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
2462a36c61f9SKrishna Gudipati {
2463a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2464a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rpwwn);
2465a36c61f9SKrishna Gudipati 	rport = bfa_fcs_rport_alloc(port, rpwwn, 0);
2466a36c61f9SKrishna Gudipati 	if (!rport)
2467a36c61f9SKrishna Gudipati 		return NULL;
2468a36c61f9SKrishna Gudipati 
2469a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_DISC);
2470a36c61f9SKrishna Gudipati 	return rport;
2471a36c61f9SKrishna Gudipati }
24725fbe25c7SJing Huang /*
2473a36c61f9SKrishna Gudipati  * Called by bport in private loop topology to indicate that a
2474a36c61f9SKrishna Gudipati  * rport has been discovered and plogi has been completed.
2475a36c61f9SKrishna Gudipati  *
2476a36c61f9SKrishna Gudipati  * @param[in] port	- base port or vport
2477a36c61f9SKrishna Gudipati  * @param[in] rpid	- remote port ID
2478a36c61f9SKrishna Gudipati  */
2479a36c61f9SKrishna Gudipati void
2480a36c61f9SKrishna Gudipati bfa_fcs_rport_start(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
2481a36c61f9SKrishna Gudipati 	 struct fc_logi_s *plogi)
2482a36c61f9SKrishna Gudipati {
2483a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2484a36c61f9SKrishna Gudipati 
2485a36c61f9SKrishna Gudipati 	rport = bfa_fcs_rport_alloc(port, WWN_NULL, fchs->s_id);
2486a36c61f9SKrishna Gudipati 	if (!rport)
2487a36c61f9SKrishna Gudipati 		return;
2488a36c61f9SKrishna Gudipati 
2489a36c61f9SKrishna Gudipati 	bfa_fcs_rport_update(rport, plogi);
2490a36c61f9SKrishna Gudipati 
2491a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_COMP);
2492a36c61f9SKrishna Gudipati }
2493a36c61f9SKrishna Gudipati 
24945fbe25c7SJing Huang /*
2495a36c61f9SKrishna Gudipati  *	Called by bport/vport to handle PLOGI received from a new remote port.
2496a36c61f9SKrishna Gudipati  *	If an existing rport does a plogi, it will be handled separately.
2497a36c61f9SKrishna Gudipati  */
2498a36c61f9SKrishna Gudipati void
2499a36c61f9SKrishna Gudipati bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
2500a36c61f9SKrishna Gudipati 				struct fc_logi_s *plogi)
2501a36c61f9SKrishna Gudipati {
2502a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2503a36c61f9SKrishna Gudipati 
2504a36c61f9SKrishna Gudipati 	rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id);
2505a36c61f9SKrishna Gudipati 	if (!rport)
2506a36c61f9SKrishna Gudipati 		return;
2507a36c61f9SKrishna Gudipati 
2508a36c61f9SKrishna Gudipati 	bfa_fcs_rport_update(rport, plogi);
2509a36c61f9SKrishna Gudipati 
2510a36c61f9SKrishna Gudipati 	rport->reply_oxid = fchs->ox_id;
2511a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->reply_oxid);
2512a36c61f9SKrishna Gudipati 
2513a36c61f9SKrishna Gudipati 	rport->stats.plogi_rcvd++;
2514a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2515a36c61f9SKrishna Gudipati }
2516a36c61f9SKrishna Gudipati 
25175fbe25c7SJing Huang /*
2518a36c61f9SKrishna Gudipati  *	Called by bport/vport to handle PLOGI received from an existing
2519a36c61f9SKrishna Gudipati  *	 remote port.
2520a36c61f9SKrishna Gudipati  */
2521a36c61f9SKrishna Gudipati void
2522a36c61f9SKrishna Gudipati bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2523a36c61f9SKrishna Gudipati 			struct fc_logi_s *plogi)
2524a36c61f9SKrishna Gudipati {
25255fbe25c7SJing Huang 	/*
2526a36c61f9SKrishna Gudipati 	 * @todo Handle P2P and initiator-initiator.
2527a36c61f9SKrishna Gudipati 	 */
2528a36c61f9SKrishna Gudipati 
2529a36c61f9SKrishna Gudipati 	bfa_fcs_rport_update(rport, plogi);
2530a36c61f9SKrishna Gudipati 
2531a36c61f9SKrishna Gudipati 	rport->reply_oxid = rx_fchs->ox_id;
2532a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->reply_oxid);
2533a36c61f9SKrishna Gudipati 
2534d7be54ccSKrishna Gudipati 	rport->pid = rx_fchs->s_id;
2535d7be54ccSKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2536d7be54ccSKrishna Gudipati 
2537a36c61f9SKrishna Gudipati 	rport->stats.plogi_rcvd++;
2538a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2539a36c61f9SKrishna Gudipati }
2540a36c61f9SKrishna Gudipati 
2541a36c61f9SKrishna Gudipati 
25425fbe25c7SJing Huang /*
2543a36c61f9SKrishna Gudipati  *	Called by bport/vport to notify SCN for the remote port
2544a36c61f9SKrishna Gudipati  */
2545a36c61f9SKrishna Gudipati void
2546a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
2547a36c61f9SKrishna Gudipati {
2548a36c61f9SKrishna Gudipati 	rport->stats.rscns++;
2549a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_SCN);
2550a36c61f9SKrishna Gudipati }
2551a36c61f9SKrishna Gudipati 
25525fbe25c7SJing Huang /*
2553a36c61f9SKrishna Gudipati  *	brief
2554a36c61f9SKrishna Gudipati  *	This routine BFA callback for bfa_rport_online() call.
2555a36c61f9SKrishna Gudipati  *
2556a36c61f9SKrishna Gudipati  *	param[in]	cb_arg	-  rport struct.
2557a36c61f9SKrishna Gudipati  *
2558a36c61f9SKrishna Gudipati  *	return
2559a36c61f9SKrishna Gudipati  *		void
2560a36c61f9SKrishna Gudipati  *
2561a36c61f9SKrishna Gudipati  *	Special Considerations:
2562a36c61f9SKrishna Gudipati  *
2563a36c61f9SKrishna Gudipati  *	note
2564a36c61f9SKrishna Gudipati  */
2565a36c61f9SKrishna Gudipati void
2566a36c61f9SKrishna Gudipati bfa_cb_rport_online(void *cbarg)
2567a36c61f9SKrishna Gudipati {
2568a36c61f9SKrishna Gudipati 
2569a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2570a36c61f9SKrishna Gudipati 
2571a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2572a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_HCB_ONLINE);
2573a36c61f9SKrishna Gudipati }
2574a36c61f9SKrishna Gudipati 
25755fbe25c7SJing Huang /*
2576a36c61f9SKrishna Gudipati  *	brief
2577a36c61f9SKrishna Gudipati  *	This routine BFA callback for bfa_rport_offline() call.
2578a36c61f9SKrishna Gudipati  *
2579a36c61f9SKrishna Gudipati  *	param[in]	rport	-
2580a36c61f9SKrishna Gudipati  *
2581a36c61f9SKrishna Gudipati  *	return
2582a36c61f9SKrishna Gudipati  *		void
2583a36c61f9SKrishna Gudipati  *
2584a36c61f9SKrishna Gudipati  *	Special Considerations:
2585a36c61f9SKrishna Gudipati  *
2586a36c61f9SKrishna Gudipati  *	note
2587a36c61f9SKrishna Gudipati  */
2588a36c61f9SKrishna Gudipati void
2589a36c61f9SKrishna Gudipati bfa_cb_rport_offline(void *cbarg)
2590a36c61f9SKrishna Gudipati {
2591a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2592a36c61f9SKrishna Gudipati 
2593a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2594a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_HCB_OFFLINE);
2595a36c61f9SKrishna Gudipati }
2596a36c61f9SKrishna Gudipati 
25975fbe25c7SJing Huang /*
2598a36c61f9SKrishna Gudipati  *	brief
2599a36c61f9SKrishna Gudipati  *	This routine is a static BFA callback when there is a QoS flow_id
2600a36c61f9SKrishna Gudipati  *	change notification
2601a36c61f9SKrishna Gudipati  *
2602a36c61f9SKrishna Gudipati  *	param[in]	rport	-
2603a36c61f9SKrishna Gudipati  *
2604a36c61f9SKrishna Gudipati  *	return
2605a36c61f9SKrishna Gudipati  *		void
2606a36c61f9SKrishna Gudipati  *
2607a36c61f9SKrishna Gudipati  *	Special Considerations:
2608a36c61f9SKrishna Gudipati  *
2609a36c61f9SKrishna Gudipati  *	note
2610a36c61f9SKrishna Gudipati  */
2611a36c61f9SKrishna Gudipati void
2612a36c61f9SKrishna Gudipati bfa_cb_rport_qos_scn_flowid(void *cbarg,
2613a36c61f9SKrishna Gudipati 		struct bfa_rport_qos_attr_s old_qos_attr,
2614a36c61f9SKrishna Gudipati 		struct bfa_rport_qos_attr_s new_qos_attr)
2615a36c61f9SKrishna Gudipati {
2616a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
26177826f304SKrishna Gudipati 	struct bfa_rport_aen_data_s aen_data;
2618a36c61f9SKrishna Gudipati 
2619a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
26207826f304SKrishna Gudipati 	aen_data.priv.qos = new_qos_attr;
26217826f304SKrishna Gudipati 	bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data);
2622a36c61f9SKrishna Gudipati }
2623a36c61f9SKrishna Gudipati 
26245fbe25c7SJing Huang /*
2625a36c61f9SKrishna Gudipati  *	brief
2626a36c61f9SKrishna Gudipati  *	This routine is a static BFA callback when there is a QoS priority
2627a36c61f9SKrishna Gudipati  *	change notification
2628a36c61f9SKrishna Gudipati  *
2629a36c61f9SKrishna Gudipati  *	param[in]	rport	-
2630a36c61f9SKrishna Gudipati  *
2631a36c61f9SKrishna Gudipati  *	return
2632a36c61f9SKrishna Gudipati  *		void
2633a36c61f9SKrishna Gudipati  *
2634a36c61f9SKrishna Gudipati  *	Special Considerations:
2635a36c61f9SKrishna Gudipati  *
2636a36c61f9SKrishna Gudipati  *	note
2637a36c61f9SKrishna Gudipati  */
2638a36c61f9SKrishna Gudipati void
2639a36c61f9SKrishna Gudipati bfa_cb_rport_qos_scn_prio(void *cbarg,
2640a36c61f9SKrishna Gudipati 		struct bfa_rport_qos_attr_s old_qos_attr,
2641a36c61f9SKrishna Gudipati 		struct bfa_rport_qos_attr_s new_qos_attr)
2642a36c61f9SKrishna Gudipati {
2643a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
26447826f304SKrishna Gudipati 	struct bfa_rport_aen_data_s aen_data;
2645a36c61f9SKrishna Gudipati 
2646a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
26477826f304SKrishna Gudipati 	aen_data.priv.qos = new_qos_attr;
26487826f304SKrishna Gudipati 	bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_PRIO, &aen_data);
2649a36c61f9SKrishna Gudipati }
2650a36c61f9SKrishna Gudipati 
26515fbe25c7SJing Huang /*
2652a36c61f9SKrishna Gudipati  *		Called to process any unsolicted frames from this remote port
2653a36c61f9SKrishna Gudipati  */
2654a36c61f9SKrishna Gudipati void
2655a36c61f9SKrishna Gudipati bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport,
2656a36c61f9SKrishna Gudipati 			struct fchs_s *fchs, u16 len)
2657a36c61f9SKrishna Gudipati {
2658a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2659a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s	*els_cmd;
2660a36c61f9SKrishna Gudipati 
2661a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, fchs->s_id);
2662a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, fchs->d_id);
2663a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, fchs->type);
2664a36c61f9SKrishna Gudipati 
2665a36c61f9SKrishna Gudipati 	if (fchs->type != FC_TYPE_ELS)
2666a36c61f9SKrishna Gudipati 		return;
2667a36c61f9SKrishna Gudipati 
2668a36c61f9SKrishna Gudipati 	els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
2669a36c61f9SKrishna Gudipati 
2670a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, els_cmd->els_code);
2671a36c61f9SKrishna Gudipati 
2672a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
2673a36c61f9SKrishna Gudipati 	case FC_ELS_LOGO:
2674a36c61f9SKrishna Gudipati 		bfa_stats(port, plogi_rcvd);
2675a36c61f9SKrishna Gudipati 		bfa_fcs_rport_process_logo(rport, fchs);
2676a36c61f9SKrishna Gudipati 		break;
2677a36c61f9SKrishna Gudipati 
2678a36c61f9SKrishna Gudipati 	case FC_ELS_ADISC:
2679a36c61f9SKrishna Gudipati 		bfa_stats(port, adisc_rcvd);
2680a36c61f9SKrishna Gudipati 		bfa_fcs_rport_process_adisc(rport, fchs, len);
2681a36c61f9SKrishna Gudipati 		break;
2682a36c61f9SKrishna Gudipati 
2683a36c61f9SKrishna Gudipati 	case FC_ELS_PRLO:
2684a36c61f9SKrishna Gudipati 		bfa_stats(port, prlo_rcvd);
2685a36c61f9SKrishna Gudipati 		if (bfa_fcs_lport_is_initiator(port))
2686a36c61f9SKrishna Gudipati 			bfa_fcs_fcpim_uf_recv(rport->itnim, fchs, len);
2687a36c61f9SKrishna Gudipati 		break;
2688a36c61f9SKrishna Gudipati 
2689a36c61f9SKrishna Gudipati 	case FC_ELS_PRLI:
2690a36c61f9SKrishna Gudipati 		bfa_stats(port, prli_rcvd);
2691a36c61f9SKrishna Gudipati 		bfa_fcs_rport_process_prli(rport, fchs, len);
2692a36c61f9SKrishna Gudipati 		break;
2693a36c61f9SKrishna Gudipati 
2694a36c61f9SKrishna Gudipati 	case FC_ELS_RPSC:
2695a36c61f9SKrishna Gudipati 		bfa_stats(port, rpsc_rcvd);
2696a36c61f9SKrishna Gudipati 		bfa_fcs_rport_process_rpsc(rport, fchs, len);
2697a36c61f9SKrishna Gudipati 		break;
2698a36c61f9SKrishna Gudipati 
2699a36c61f9SKrishna Gudipati 	default:
2700a36c61f9SKrishna Gudipati 		bfa_stats(port, un_handled_els_rcvd);
2701a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_ls_rjt(rport, fchs,
2702a36c61f9SKrishna Gudipati 					  FC_LS_RJT_RSN_CMD_NOT_SUPP,
2703a36c61f9SKrishna Gudipati 					  FC_LS_RJT_EXP_NO_ADDL_INFO);
2704a36c61f9SKrishna Gudipati 		break;
2705a36c61f9SKrishna Gudipati 	}
2706a36c61f9SKrishna Gudipati }
2707a36c61f9SKrishna Gudipati 
2708a36c61f9SKrishna Gudipati /* send best case  acc to prlo */
2709a36c61f9SKrishna Gudipati static void
2710a36c61f9SKrishna Gudipati bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport)
2711a36c61f9SKrishna Gudipati {
2712a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2713a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2714a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2715a36c61f9SKrishna Gudipati 	int		len;
2716a36c61f9SKrishna Gudipati 
2717a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2718a36c61f9SKrishna Gudipati 
2719c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2720a36c61f9SKrishna Gudipati 	if (!fcxp)
2721a36c61f9SKrishna Gudipati 		return;
2722a36c61f9SKrishna Gudipati 	len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2723a36c61f9SKrishna Gudipati 			rport->pid, bfa_fcs_lport_get_fcid(port),
2724a36c61f9SKrishna Gudipati 			rport->reply_oxid, 0);
2725a36c61f9SKrishna Gudipati 
2726a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id,
2727a36c61f9SKrishna Gudipati 		port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs,
2728a36c61f9SKrishna Gudipati 		NULL, NULL, FC_MAX_PDUSZ, 0);
2729a36c61f9SKrishna Gudipati }
2730a36c61f9SKrishna Gudipati 
2731a36c61f9SKrishna Gudipati /*
2732a36c61f9SKrishna Gudipati  * Send a LS reject
2733a36c61f9SKrishna Gudipati  */
2734a36c61f9SKrishna Gudipati static void
2735a36c61f9SKrishna Gudipati bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2736a36c61f9SKrishna Gudipati 			  u8 reason_code, u8 reason_code_expl)
2737a36c61f9SKrishna Gudipati {
2738a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2739a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2740a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2741a36c61f9SKrishna Gudipati 	int		len;
2742a36c61f9SKrishna Gudipati 
2743a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rx_fchs->s_id);
2744a36c61f9SKrishna Gudipati 
2745c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(rport->fcs, BFA_FALSE);
2746a36c61f9SKrishna Gudipati 	if (!fcxp)
2747a36c61f9SKrishna Gudipati 		return;
2748a36c61f9SKrishna Gudipati 
2749a36c61f9SKrishna Gudipati 	len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2750a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2751a36c61f9SKrishna Gudipati 				rx_fchs->ox_id, reason_code, reason_code_expl);
2752a36c61f9SKrishna Gudipati 
2753a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
2754a36c61f9SKrishna Gudipati 			BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
2755a36c61f9SKrishna Gudipati 			FC_MAX_PDUSZ, 0);
2756a36c61f9SKrishna Gudipati }
2757a36c61f9SKrishna Gudipati 
27585fbe25c7SJing Huang /*
2759a36c61f9SKrishna Gudipati  * Return state of rport.
2760a36c61f9SKrishna Gudipati  */
2761a36c61f9SKrishna Gudipati int
2762a36c61f9SKrishna Gudipati bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport)
2763a36c61f9SKrishna Gudipati {
2764a36c61f9SKrishna Gudipati 	return bfa_sm_to_state(rport_sm_table, rport->sm);
2765a36c61f9SKrishna Gudipati }
2766a36c61f9SKrishna Gudipati 
2767f7f73812SMaggie Zhang 
27685fbe25c7SJing Huang /*
2769a36c61f9SKrishna Gudipati  *	brief
2770a36c61f9SKrishna Gudipati  *		 Called by the Driver to set rport delete/ageout timeout
2771a36c61f9SKrishna Gudipati  *
2772a36c61f9SKrishna Gudipati  *	param[in]		rport timeout value in seconds.
2773a36c61f9SKrishna Gudipati  *
2774a36c61f9SKrishna Gudipati  *	return None
2775a36c61f9SKrishna Gudipati  */
2776a36c61f9SKrishna Gudipati void
2777a36c61f9SKrishna Gudipati bfa_fcs_rport_set_del_timeout(u8 rport_tmo)
2778a36c61f9SKrishna Gudipati {
2779a36c61f9SKrishna Gudipati 	/* convert to Millisecs */
2780a36c61f9SKrishna Gudipati 	if (rport_tmo > 0)
2781a36c61f9SKrishna Gudipati 		bfa_fcs_rport_del_timeout = rport_tmo * 1000;
2782a36c61f9SKrishna Gudipati }
2783a36c61f9SKrishna Gudipati void
278450444a34SMaggie bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, __be16 ox_id)
2785a36c61f9SKrishna Gudipati {
2786a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2787a36c61f9SKrishna Gudipati 
2788a36c61f9SKrishna Gudipati 	rport->prlo = BFA_TRUE;
2789a36c61f9SKrishna Gudipati 	rport->reply_oxid = ox_id;
2790a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PRLO_RCVD);
2791a36c61f9SKrishna Gudipati }
2792a36c61f9SKrishna Gudipati 
279361ba4394SKrishna Gudipati /*
279461ba4394SKrishna Gudipati  * Called by BFAD to set the max limit on number of bfa_fcs_rport allocation
279561ba4394SKrishna Gudipati  * which limits number of concurrent logins to remote ports
279661ba4394SKrishna Gudipati  */
279761ba4394SKrishna Gudipati void
279861ba4394SKrishna Gudipati bfa_fcs_rport_set_max_logins(u32 max_logins)
279961ba4394SKrishna Gudipati {
280061ba4394SKrishna Gudipati 	if (max_logins > 0)
280161ba4394SKrishna Gudipati 		bfa_fcs_rport_max_logins = max_logins;
280261ba4394SKrishna Gudipati }
280361ba4394SKrishna Gudipati 
280460138066SKrishna Gudipati void
280560138066SKrishna Gudipati bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
280660138066SKrishna Gudipati 		struct bfa_rport_attr_s *rport_attr)
280760138066SKrishna Gudipati {
280860138066SKrishna Gudipati 	struct bfa_rport_qos_attr_s qos_attr;
280960138066SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
281060138066SKrishna Gudipati 	bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed;
2811a36c61f9SKrishna Gudipati 
281260138066SKrishna Gudipati 	memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
281360138066SKrishna Gudipati 	memset(&qos_attr, 0, sizeof(struct bfa_rport_qos_attr_s));
281460138066SKrishna Gudipati 
281560138066SKrishna Gudipati 	rport_attr->pid = rport->pid;
281660138066SKrishna Gudipati 	rport_attr->pwwn = rport->pwwn;
281760138066SKrishna Gudipati 	rport_attr->nwwn = rport->nwwn;
281860138066SKrishna Gudipati 	rport_attr->cos_supported = rport->fc_cos;
281960138066SKrishna Gudipati 	rport_attr->df_sz = rport->maxfrsize;
282060138066SKrishna Gudipati 	rport_attr->state = bfa_fcs_rport_get_state(rport);
282160138066SKrishna Gudipati 	rport_attr->fc_cos = rport->fc_cos;
282260138066SKrishna Gudipati 	rport_attr->cisc = rport->cisc;
282360138066SKrishna Gudipati 	rport_attr->scsi_function = rport->scsi_function;
282460138066SKrishna Gudipati 	rport_attr->curr_speed  = rport->rpf.rpsc_speed;
282560138066SKrishna Gudipati 	rport_attr->assigned_speed  = rport->rpf.assigned_speed;
282660138066SKrishna Gudipati 
282761ba4394SKrishna Gudipati 	if (rport->bfa_rport) {
282860138066SKrishna Gudipati 		qos_attr.qos_priority = rport->bfa_rport->qos_attr.qos_priority;
282960138066SKrishna Gudipati 		qos_attr.qos_flow_id =
283060138066SKrishna Gudipati 			cpu_to_be32(rport->bfa_rport->qos_attr.qos_flow_id);
283161ba4394SKrishna Gudipati 	}
283260138066SKrishna Gudipati 	rport_attr->qos_attr = qos_attr;
283360138066SKrishna Gudipati 
283460138066SKrishna Gudipati 	rport_attr->trl_enforced = BFA_FALSE;
283560138066SKrishna Gudipati 	if (bfa_fcport_is_ratelim(port->fcs->bfa) &&
283660138066SKrishna Gudipati 	    (rport->scsi_function == BFA_RPORT_TARGET)) {
283760138066SKrishna Gudipati 		if (rport_speed == BFA_PORT_SPEED_UNKNOWN)
283860138066SKrishna Gudipati 			rport_speed =
283960138066SKrishna Gudipati 				bfa_fcport_get_ratelim_speed(rport->fcs->bfa);
284060138066SKrishna Gudipati 
284160138066SKrishna Gudipati 		if (rport_speed < bfa_fcs_lport_get_rport_max_speed(port))
284260138066SKrishna Gudipati 			rport_attr->trl_enforced = BFA_TRUE;
284360138066SKrishna Gudipati 	}
284460138066SKrishna Gudipati }
2845a36c61f9SKrishna Gudipati 
28465fbe25c7SJing Huang /*
2847a36c61f9SKrishna Gudipati  * Remote port implementation.
2848a36c61f9SKrishna Gudipati  */
2849a36c61f9SKrishna Gudipati 
28505fbe25c7SJing Huang /*
2851a36c61f9SKrishna Gudipati  *  fcs_rport_api FCS rport API.
2852a36c61f9SKrishna Gudipati  */
2853a36c61f9SKrishna Gudipati 
2854a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *
2855a36c61f9SKrishna Gudipati bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
2856a36c61f9SKrishna Gudipati {
2857a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2858a36c61f9SKrishna Gudipati 
2859a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn);
2860a36c61f9SKrishna Gudipati 	if (rport == NULL) {
2861a36c61f9SKrishna Gudipati 		/*
2862a36c61f9SKrishna Gudipati 		 * TBD Error handling
2863a36c61f9SKrishna Gudipati 		 */
2864a36c61f9SKrishna Gudipati 	}
2865a36c61f9SKrishna Gudipati 
2866a36c61f9SKrishna Gudipati 	return rport;
2867a36c61f9SKrishna Gudipati }
2868a36c61f9SKrishna Gudipati 
2869a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *
2870a36c61f9SKrishna Gudipati bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t rnwwn)
2871a36c61f9SKrishna Gudipati {
2872a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2873a36c61f9SKrishna Gudipati 
2874a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_nwwn(port, rnwwn);
2875a36c61f9SKrishna Gudipati 	if (rport == NULL) {
2876a36c61f9SKrishna Gudipati 		/*
2877a36c61f9SKrishna Gudipati 		 * TBD Error handling
2878a36c61f9SKrishna Gudipati 		 */
2879a36c61f9SKrishna Gudipati 	}
2880a36c61f9SKrishna Gudipati 
2881a36c61f9SKrishna Gudipati 	return rport;
2882a36c61f9SKrishna Gudipati }
2883a36c61f9SKrishna Gudipati 
2884a36c61f9SKrishna Gudipati /*
2885a36c61f9SKrishna Gudipati  * Remote port features (RPF) implementation.
2886a36c61f9SKrishna Gudipati  */
2887a36c61f9SKrishna Gudipati 
2888a36c61f9SKrishna Gudipati #define BFA_FCS_RPF_RETRIES	(3)
2889a36c61f9SKrishna Gudipati #define BFA_FCS_RPF_RETRY_TIMEOUT  (1000) /* 1 sec (In millisecs) */
2890a36c61f9SKrishna Gudipati 
2891a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_send_rpsc2(void *rport_cbarg,
2892a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp_alloced);
2893a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_rpsc2_response(void *fcsarg,
2894a36c61f9SKrishna Gudipati 			struct bfa_fcxp_s *fcxp,
2895a36c61f9SKrishna Gudipati 			void *cbarg,
2896a36c61f9SKrishna Gudipati 			bfa_status_t req_status,
2897a36c61f9SKrishna Gudipati 			u32 rsp_len,
2898a36c61f9SKrishna Gudipati 			u32 resid_len,
2899a36c61f9SKrishna Gudipati 			struct fchs_s *rsp_fchs);
2900a36c61f9SKrishna Gudipati 
2901a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_timeout(void *arg);
2902a36c61f9SKrishna Gudipati 
29035fbe25c7SJing Huang /*
2904a36c61f9SKrishna Gudipati  *  fcs_rport_ftrs_sm FCS rport state machine events
2905a36c61f9SKrishna Gudipati  */
2906a36c61f9SKrishna Gudipati 
2907a36c61f9SKrishna Gudipati enum rpf_event {
2908a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPORT_OFFLINE  = 1, /* Rport offline		*/
2909a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPORT_ONLINE   = 2,	/* Rport online			*/
2910a36c61f9SKrishna Gudipati 	RPFSM_EVENT_FCXP_SENT      = 3,	/* Frame from has been sent	*/
2911a36c61f9SKrishna Gudipati 	RPFSM_EVENT_TIMEOUT	   = 4, /* Rport SM timeout event	*/
2912a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPSC_COMP      = 5,
2913a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPSC_FAIL      = 6,
2914a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPSC_ERROR     = 7,
2915a36c61f9SKrishna Gudipati };
2916a36c61f9SKrishna Gudipati 
2917a36c61f9SKrishna Gudipati static void	bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf,
2918a36c61f9SKrishna Gudipati 					enum rpf_event event);
2919a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf,
2920a36c61f9SKrishna Gudipati 				       enum rpf_event event);
2921a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf,
2922a36c61f9SKrishna Gudipati 				       enum rpf_event event);
2923a36c61f9SKrishna Gudipati static void	bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf,
2924a36c61f9SKrishna Gudipati 					enum rpf_event event);
2925a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf,
2926a36c61f9SKrishna Gudipati 					enum rpf_event event);
2927a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf,
2928a36c61f9SKrishna Gudipati 					enum rpf_event event);
2929a36c61f9SKrishna Gudipati 
2930a36c61f9SKrishna Gudipati static void
2931a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2932a36c61f9SKrishna Gudipati {
2933a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2934a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = &rport->fcs->fabric;
2935a36c61f9SKrishna Gudipati 
2936a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2937a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2938a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
2939a36c61f9SKrishna Gudipati 
2940a36c61f9SKrishna Gudipati 	switch (event) {
2941a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_ONLINE:
2942a36c61f9SKrishna Gudipati 		/* Send RPSC2 to a Brocade fabric only. */
2943a36c61f9SKrishna Gudipati 		if ((!BFA_FCS_PID_IS_WKA(rport->pid)) &&
2944f7f73812SMaggie Zhang 			((rport->port->fabric->lps->brcd_switch) ||
2945a36c61f9SKrishna Gudipati 			(bfa_fcs_fabric_get_switch_oui(fabric) ==
2946a36c61f9SKrishna Gudipati 						BFA_FCS_BRCD_SWITCH_OUI))) {
2947a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
2948a36c61f9SKrishna Gudipati 			rpf->rpsc_retries = 0;
2949a36c61f9SKrishna Gudipati 			bfa_fcs_rpf_send_rpsc2(rpf, NULL);
2950a36c61f9SKrishna Gudipati 		}
2951a36c61f9SKrishna Gudipati 		break;
2952a36c61f9SKrishna Gudipati 
2953a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
2954a36c61f9SKrishna Gudipati 		break;
2955a36c61f9SKrishna Gudipati 
2956a36c61f9SKrishna Gudipati 	default:
2957a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
2958a36c61f9SKrishna Gudipati 	}
2959a36c61f9SKrishna Gudipati }
2960a36c61f9SKrishna Gudipati 
2961a36c61f9SKrishna Gudipati static void
2962a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2963a36c61f9SKrishna Gudipati {
2964a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2965a36c61f9SKrishna Gudipati 
2966a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
2967a36c61f9SKrishna Gudipati 
2968a36c61f9SKrishna Gudipati 	switch (event) {
2969a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_FCXP_SENT:
2970a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc);
2971a36c61f9SKrishna Gudipati 		break;
2972a36c61f9SKrishna Gudipati 
2973a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
2974a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
2975a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe);
2976a36c61f9SKrishna Gudipati 		rpf->rpsc_retries = 0;
2977a36c61f9SKrishna Gudipati 		break;
2978a36c61f9SKrishna Gudipati 
2979a36c61f9SKrishna Gudipati 	default:
2980a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
2981a36c61f9SKrishna Gudipati 	}
2982a36c61f9SKrishna Gudipati }
2983a36c61f9SKrishna Gudipati 
2984a36c61f9SKrishna Gudipati static void
2985a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2986a36c61f9SKrishna Gudipati {
2987a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2988a36c61f9SKrishna Gudipati 
2989a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2990a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
2991a36c61f9SKrishna Gudipati 
2992a36c61f9SKrishna Gudipati 	switch (event) {
2993a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPSC_COMP:
2994a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
2995a36c61f9SKrishna Gudipati 		/* Update speed info in f/w via BFA */
2996a36c61f9SKrishna Gudipati 		if (rpf->rpsc_speed != BFA_PORT_SPEED_UNKNOWN)
2997a36c61f9SKrishna Gudipati 			bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed);
2998a36c61f9SKrishna Gudipati 		else if (rpf->assigned_speed != BFA_PORT_SPEED_UNKNOWN)
2999a36c61f9SKrishna Gudipati 			bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed);
3000a36c61f9SKrishna Gudipati 		break;
3001a36c61f9SKrishna Gudipati 
3002a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPSC_FAIL:
3003a36c61f9SKrishna Gudipati 		/* RPSC not supported by rport */
3004a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
3005a36c61f9SKrishna Gudipati 		break;
3006a36c61f9SKrishna Gudipati 
3007a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPSC_ERROR:
3008a36c61f9SKrishna Gudipati 		/* need to retry...delayed a bit. */
3009a36c61f9SKrishna Gudipati 		if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) {
3010a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rpf->timer,
3011a36c61f9SKrishna Gudipati 				    bfa_fcs_rpf_timeout, rpf,
3012a36c61f9SKrishna Gudipati 				    BFA_FCS_RPF_RETRY_TIMEOUT);
3013a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry);
3014a36c61f9SKrishna Gudipati 		} else {
3015a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
3016a36c61f9SKrishna Gudipati 		}
3017a36c61f9SKrishna Gudipati 		break;
3018a36c61f9SKrishna Gudipati 
3019a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
3020a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3021a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rpf->fcxp);
3022a36c61f9SKrishna Gudipati 		rpf->rpsc_retries = 0;
3023a36c61f9SKrishna Gudipati 		break;
3024a36c61f9SKrishna Gudipati 
3025a36c61f9SKrishna Gudipati 	default:
3026a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
3027a36c61f9SKrishna Gudipati 	}
3028a36c61f9SKrishna Gudipati }
3029a36c61f9SKrishna Gudipati 
3030a36c61f9SKrishna Gudipati static void
3031a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3032a36c61f9SKrishna Gudipati {
3033a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3034a36c61f9SKrishna Gudipati 
3035a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3036a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
3037a36c61f9SKrishna Gudipati 
3038a36c61f9SKrishna Gudipati 	switch (event) {
3039a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_TIMEOUT:
3040a36c61f9SKrishna Gudipati 		/* re-send the RPSC */
3041a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
3042a36c61f9SKrishna Gudipati 		bfa_fcs_rpf_send_rpsc2(rpf, NULL);
3043a36c61f9SKrishna Gudipati 		break;
3044a36c61f9SKrishna Gudipati 
3045a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
3046a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rpf->timer);
3047a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3048a36c61f9SKrishna Gudipati 		rpf->rpsc_retries = 0;
3049a36c61f9SKrishna Gudipati 		break;
3050a36c61f9SKrishna Gudipati 
3051a36c61f9SKrishna Gudipati 	default:
3052a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
3053a36c61f9SKrishna Gudipati 	}
3054a36c61f9SKrishna Gudipati }
3055a36c61f9SKrishna Gudipati 
3056a36c61f9SKrishna Gudipati static void
3057a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3058a36c61f9SKrishna Gudipati {
3059a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3060a36c61f9SKrishna Gudipati 
3061a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
3062a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3063a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
3064a36c61f9SKrishna Gudipati 
3065a36c61f9SKrishna Gudipati 	switch (event) {
3066a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
3067a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3068a36c61f9SKrishna Gudipati 		rpf->rpsc_retries = 0;
3069a36c61f9SKrishna Gudipati 		break;
3070a36c61f9SKrishna Gudipati 
3071a36c61f9SKrishna Gudipati 	default:
3072a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
3073a36c61f9SKrishna Gudipati 	}
3074a36c61f9SKrishna Gudipati }
3075a36c61f9SKrishna Gudipati 
3076a36c61f9SKrishna Gudipati static void
3077a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3078a36c61f9SKrishna Gudipati {
3079a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3080a36c61f9SKrishna Gudipati 
3081a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
3082a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3083a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
3084a36c61f9SKrishna Gudipati 
3085a36c61f9SKrishna Gudipati 	switch (event) {
3086a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_ONLINE:
3087a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
3088a36c61f9SKrishna Gudipati 		bfa_fcs_rpf_send_rpsc2(rpf, NULL);
3089a36c61f9SKrishna Gudipati 		break;
3090a36c61f9SKrishna Gudipati 
3091a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
3092a36c61f9SKrishna Gudipati 		break;
3093a36c61f9SKrishna Gudipati 
3094a36c61f9SKrishna Gudipati 	default:
3095a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
3096a36c61f9SKrishna Gudipati 	}
3097a36c61f9SKrishna Gudipati }
30985fbe25c7SJing Huang /*
3099a36c61f9SKrishna Gudipati  * Called when Rport is created.
3100a36c61f9SKrishna Gudipati  */
3101a36c61f9SKrishna Gudipati void
3102a36c61f9SKrishna Gudipati bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport)
3103a36c61f9SKrishna Gudipati {
3104a36c61f9SKrishna Gudipati 	struct bfa_fcs_rpf_s *rpf = &rport->rpf;
3105a36c61f9SKrishna Gudipati 
3106a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3107a36c61f9SKrishna Gudipati 	rpf->rport = rport;
3108a36c61f9SKrishna Gudipati 
3109a36c61f9SKrishna Gudipati 	bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit);
3110a36c61f9SKrishna Gudipati }
3111a36c61f9SKrishna Gudipati 
31125fbe25c7SJing Huang /*
3113a36c61f9SKrishna Gudipati  * Called when Rport becomes online
3114a36c61f9SKrishna Gudipati  */
3115a36c61f9SKrishna Gudipati void
3116a36c61f9SKrishna Gudipati bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport)
3117a36c61f9SKrishna Gudipati {
3118a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3119a36c61f9SKrishna Gudipati 
3120a36c61f9SKrishna Gudipati 	if (__fcs_min_cfg(rport->port->fcs))
3121a36c61f9SKrishna Gudipati 		return;
3122a36c61f9SKrishna Gudipati 
3123a36c61f9SKrishna Gudipati 	if (bfa_fcs_fabric_is_switched(rport->port->fabric))
3124a36c61f9SKrishna Gudipati 		bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE);
3125a36c61f9SKrishna Gudipati }
3126a36c61f9SKrishna Gudipati 
31275fbe25c7SJing Huang /*
3128a36c61f9SKrishna Gudipati  * Called when Rport becomes offline
3129a36c61f9SKrishna Gudipati  */
3130a36c61f9SKrishna Gudipati void
3131a36c61f9SKrishna Gudipati bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport)
3132a36c61f9SKrishna Gudipati {
3133a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3134a36c61f9SKrishna Gudipati 
3135a36c61f9SKrishna Gudipati 	if (__fcs_min_cfg(rport->port->fcs))
3136a36c61f9SKrishna Gudipati 		return;
3137a36c61f9SKrishna Gudipati 
3138a36c61f9SKrishna Gudipati 	rport->rpf.rpsc_speed = 0;
3139a36c61f9SKrishna Gudipati 	bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE);
3140a36c61f9SKrishna Gudipati }
3141a36c61f9SKrishna Gudipati 
3142a36c61f9SKrishna Gudipati static void
3143a36c61f9SKrishna Gudipati bfa_fcs_rpf_timeout(void *arg)
3144a36c61f9SKrishna Gudipati {
3145a36c61f9SKrishna Gudipati 	struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg;
3146a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3147a36c61f9SKrishna Gudipati 
3148a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3149a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rpf, RPFSM_EVENT_TIMEOUT);
3150a36c61f9SKrishna Gudipati }
3151a36c61f9SKrishna Gudipati 
3152a36c61f9SKrishna Gudipati static void
3153a36c61f9SKrishna Gudipati bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3154a36c61f9SKrishna Gudipati {
3155a36c61f9SKrishna Gudipati 	struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg;
3156a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3157a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
3158a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
3159a36c61f9SKrishna Gudipati 	int		len;
3160a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
3161a36c61f9SKrishna Gudipati 
3162a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
3163a36c61f9SKrishna Gudipati 
3164c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
3165c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3166a36c61f9SKrishna Gudipati 	if (!fcxp) {
3167a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe,
3168c3f1b123SKrishna Gudipati 				bfa_fcs_rpf_send_rpsc2, rpf, BFA_TRUE);
3169a36c61f9SKrishna Gudipati 		return;
3170a36c61f9SKrishna Gudipati 	}
3171a36c61f9SKrishna Gudipati 	rpf->fcxp = fcxp;
3172a36c61f9SKrishna Gudipati 
3173a36c61f9SKrishna Gudipati 	len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
3174a36c61f9SKrishna Gudipati 			    bfa_fcs_lport_get_fcid(port), &rport->pid, 1);
3175a36c61f9SKrishna Gudipati 
3176a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3177a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response,
3178a36c61f9SKrishna Gudipati 			  rpf, FC_MAX_PDUSZ, FC_ELS_TOV);
3179a36c61f9SKrishna Gudipati 	rport->stats.rpsc_sent++;
3180a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT);
3181a36c61f9SKrishna Gudipati 
3182a36c61f9SKrishna Gudipati }
3183a36c61f9SKrishna Gudipati 
3184a36c61f9SKrishna Gudipati static void
3185a36c61f9SKrishna Gudipati bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
3186a36c61f9SKrishna Gudipati 			    bfa_status_t req_status, u32 rsp_len,
3187a36c61f9SKrishna Gudipati 			    u32 resid_len, struct fchs_s *rsp_fchs)
3188a36c61f9SKrishna Gudipati {
3189a36c61f9SKrishna Gudipati 	struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg;
3190a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3191a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s *ls_rjt;
3192a36c61f9SKrishna Gudipati 	struct fc_rpsc2_acc_s *rpsc2_acc;
3193a36c61f9SKrishna Gudipati 	u16	num_ents;
3194a36c61f9SKrishna Gudipati 
3195a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, req_status);
3196a36c61f9SKrishna Gudipati 
3197a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
3198a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, req_status);
3199a36c61f9SKrishna Gudipati 		if (req_status == BFA_STATUS_ETIMER)
3200a36c61f9SKrishna Gudipati 			rport->stats.rpsc_failed++;
3201a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3202a36c61f9SKrishna Gudipati 		return;
3203a36c61f9SKrishna Gudipati 	}
3204a36c61f9SKrishna Gudipati 
3205a36c61f9SKrishna Gudipati 	rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp);
3206a36c61f9SKrishna Gudipati 	if (rpsc2_acc->els_cmd == FC_ELS_ACC) {
3207a36c61f9SKrishna Gudipati 		rport->stats.rpsc_accs++;
3208ba816ea8SJing Huang 		num_ents = be16_to_cpu(rpsc2_acc->num_pids);
3209a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, num_ents);
3210a36c61f9SKrishna Gudipati 		if (num_ents > 0) {
3211d4b671c5SJing Huang 			WARN_ON(rpsc2_acc->port_info[0].pid == rport->pid);
3212a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs,
3213ba816ea8SJing Huang 				be16_to_cpu(rpsc2_acc->port_info[0].pid));
3214a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs,
3215ba816ea8SJing Huang 				be16_to_cpu(rpsc2_acc->port_info[0].speed));
3216a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs,
3217ba816ea8SJing Huang 				be16_to_cpu(rpsc2_acc->port_info[0].index));
3218a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs,
3219a36c61f9SKrishna Gudipati 				rpsc2_acc->port_info[0].type);
3220a36c61f9SKrishna Gudipati 
3221a36c61f9SKrishna Gudipati 			if (rpsc2_acc->port_info[0].speed == 0) {
3222a36c61f9SKrishna Gudipati 				bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3223a36c61f9SKrishna Gudipati 				return;
3224a36c61f9SKrishna Gudipati 			}
3225a36c61f9SKrishna Gudipati 
3226a36c61f9SKrishna Gudipati 			rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed(
3227ba816ea8SJing Huang 				be16_to_cpu(rpsc2_acc->port_info[0].speed));
3228a36c61f9SKrishna Gudipati 
3229a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP);
3230a36c61f9SKrishna Gudipati 		}
3231a36c61f9SKrishna Gudipati 	} else {
3232a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3233a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, ls_rjt->reason_code);
3234a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
3235a36c61f9SKrishna Gudipati 		rport->stats.rpsc_rejects++;
3236a36c61f9SKrishna Gudipati 		if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP)
3237a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL);
3238a36c61f9SKrishna Gudipati 		else
3239a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3240a36c61f9SKrishna Gudipati 	}
3241a36c61f9SKrishna Gudipati }
3242