xref: /openbmc/linux/drivers/scsi/bfa/bfa_fcs_rport.c (revision 889d0d42)
1a36c61f9SKrishna Gudipati /*
2889d0d42SAnil Gurumurthy  * Copyright (c) 2005-2014 Brocade Communications Systems, Inc.
3889d0d42SAnil Gurumurthy  * Copyright (c) 2014- QLogic Corporation.
4a36c61f9SKrishna Gudipati  * All rights reserved
5889d0d42SAnil Gurumurthy  * www.qlogic.com
6a36c61f9SKrishna Gudipati  *
7a36c61f9SKrishna Gudipati  * Linux driver for Brocade Fibre Channel Host Bus Adapter.
8a36c61f9SKrishna Gudipati  *
9a36c61f9SKrishna Gudipati  * This program is free software; you can redistribute it and/or modify it
10a36c61f9SKrishna Gudipati  * under the terms of the GNU General Public License (GPL) Version 2 as
11a36c61f9SKrishna Gudipati  * published by the Free Software Foundation
12a36c61f9SKrishna Gudipati  *
13a36c61f9SKrishna Gudipati  * This program is distributed in the hope that it will be useful, but
14a36c61f9SKrishna Gudipati  * WITHOUT ANY WARRANTY; without even the implied warranty of
15a36c61f9SKrishna Gudipati  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16a36c61f9SKrishna Gudipati  * General Public License for more details.
17a36c61f9SKrishna Gudipati  */
18a36c61f9SKrishna Gudipati 
195fbe25c7SJing Huang /*
20a36c61f9SKrishna Gudipati  *  rport.c Remote port implementation.
21a36c61f9SKrishna Gudipati  */
22a36c61f9SKrishna Gudipati 
23f16a1750SMaggie Zhang #include "bfad_drv.h"
247826f304SKrishna Gudipati #include "bfad_im.h"
25a36c61f9SKrishna Gudipati #include "bfa_fcs.h"
26a36c61f9SKrishna Gudipati #include "bfa_fcbuild.h"
27a36c61f9SKrishna Gudipati 
28a36c61f9SKrishna Gudipati BFA_TRC_FILE(FCS, RPORT);
29a36c61f9SKrishna Gudipati 
30a36c61f9SKrishna Gudipati static u32
31a36c61f9SKrishna Gudipati bfa_fcs_rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000;
32a36c61f9SKrishna Gudipati 	 /* In millisecs */
33a36c61f9SKrishna Gudipati /*
3461ba4394SKrishna Gudipati  * bfa_fcs_rport_max_logins is max count of bfa_fcs_rports
3561ba4394SKrishna Gudipati  * whereas DEF_CFG_NUM_RPORTS is max count of bfa_rports
3661ba4394SKrishna Gudipati  */
3761ba4394SKrishna Gudipati static u32 bfa_fcs_rport_max_logins = BFA_FCS_MAX_RPORT_LOGINS;
3861ba4394SKrishna Gudipati 
3961ba4394SKrishna Gudipati /*
40a36c61f9SKrishna Gudipati  * forward declarations
41a36c61f9SKrishna Gudipati  */
42a36c61f9SKrishna Gudipati static struct bfa_fcs_rport_s *bfa_fcs_rport_alloc(
43a36c61f9SKrishna Gudipati 		struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid);
44a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport);
45a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport);
4661ba4394SKrishna Gudipati static void	bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport);
4761ba4394SKrishna Gudipati static void	bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport);
4861ba4394SKrishna Gudipati static void	bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport);
4961ba4394SKrishna Gudipati static void	bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport);
50a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport,
51a36c61f9SKrishna Gudipati 					struct fc_logi_s *plogi);
52a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_timeout(void *arg);
53a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_plogi(void *rport_cbarg,
54a36c61f9SKrishna Gudipati 					 struct bfa_fcxp_s *fcxp_alloced);
55a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_plogiacc(void *rport_cbarg,
56a36c61f9SKrishna Gudipati 					struct bfa_fcxp_s *fcxp_alloced);
57a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_plogi_response(void *fcsarg,
58a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp, void *cbarg,
59a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
60a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs);
61a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_adisc(void *rport_cbarg,
62a36c61f9SKrishna Gudipati 					 struct bfa_fcxp_s *fcxp_alloced);
63a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_adisc_response(void *fcsarg,
64a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp, void *cbarg,
65a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
66a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs);
67a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_nsdisc(void *rport_cbarg,
68a36c61f9SKrishna Gudipati 					 struct bfa_fcxp_s *fcxp_alloced);
69a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_gidpn_response(void *fcsarg,
70a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp, void *cbarg,
71a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
72a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs);
73a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_gpnid_response(void *fcsarg,
74a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp, void *cbarg,
75a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
76a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs);
77a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_logo(void *rport_cbarg,
78a36c61f9SKrishna Gudipati 					struct bfa_fcxp_s *fcxp_alloced);
79a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_logo_acc(void *rport_cbarg);
80a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
81a36c61f9SKrishna Gudipati 					struct fchs_s *rx_fchs, u16 len);
82a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport,
83a36c61f9SKrishna Gudipati 				struct fchs_s *rx_fchs, u8 reason_code,
84a36c61f9SKrishna Gudipati 					  u8 reason_code_expl);
85a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
86a36c61f9SKrishna Gudipati 				struct fchs_s *rx_fchs, u16 len);
87a36c61f9SKrishna Gudipati static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport);
8861ba4394SKrishna Gudipati static void	bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport);
89a36c61f9SKrishna Gudipati 
90a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport,
91a36c61f9SKrishna Gudipati 					enum rport_event event);
92a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
93a36c61f9SKrishna Gudipati 						enum rport_event event);
94a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
95a36c61f9SKrishna Gudipati 						  enum rport_event event);
96a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
97a36c61f9SKrishna Gudipati 						enum rport_event event);
98a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport,
99a36c61f9SKrishna Gudipati 					enum rport_event event);
10061ba4394SKrishna Gudipati static void	bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport,
10161ba4394SKrishna Gudipati 					enum rport_event event);
102a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
103a36c61f9SKrishna Gudipati 						enum rport_event event);
104a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport,
105a36c61f9SKrishna Gudipati 					enum rport_event event);
106a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
107a36c61f9SKrishna Gudipati 						 enum rport_event event);
108a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport,
109a36c61f9SKrishna Gudipati 					 enum rport_event event);
110bc0e2c2aSKrishna Gudipati static void	bfa_fcs_rport_sm_adisc_online_sending(
111bc0e2c2aSKrishna Gudipati 			struct bfa_fcs_rport_s *rport, enum rport_event event);
112bc0e2c2aSKrishna Gudipati static void	bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport,
113a36c61f9SKrishna Gudipati 					enum rport_event event);
114bc0e2c2aSKrishna Gudipati static void	bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s
115bc0e2c2aSKrishna Gudipati 					*rport, enum rport_event event);
116bc0e2c2aSKrishna Gudipati static void	bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport,
117a36c61f9SKrishna Gudipati 					enum rport_event event);
118a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
119a36c61f9SKrishna Gudipati 						enum rport_event event);
120a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
121a36c61f9SKrishna Gudipati 						enum rport_event event);
122a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
123a36c61f9SKrishna Gudipati 						enum rport_event event);
124a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
125a36c61f9SKrishna Gudipati 						enum rport_event event);
126a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
127a36c61f9SKrishna Gudipati 						enum rport_event event);
128a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
129a36c61f9SKrishna Gudipati 						enum rport_event event);
130a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
131a36c61f9SKrishna Gudipati 						enum rport_event event);
132a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport,
133a36c61f9SKrishna Gudipati 					 enum rport_event event);
134a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
135a36c61f9SKrishna Gudipati 						enum rport_event event);
136a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
137a36c61f9SKrishna Gudipati 						enum rport_event event);
138a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
139a36c61f9SKrishna Gudipati 						enum rport_event event);
140a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
141a36c61f9SKrishna Gudipati 						enum rport_event event);
14261ba4394SKrishna Gudipati static void	bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s *rport,
14361ba4394SKrishna Gudipati 						enum rport_event event);
14461ba4394SKrishna Gudipati static void	bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s *rport,
14561ba4394SKrishna Gudipati 						enum rport_event event);
146a36c61f9SKrishna Gudipati 
147a36c61f9SKrishna Gudipati static struct bfa_sm_table_s rport_sm_table[] = {
148a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT},
149a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_plogi_sending), BFA_RPORT_PLOGI},
150a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE},
151a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY},
152a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI},
15361ba4394SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_fc4_fcs_online), BFA_RPORT_ONLINE},
154a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE},
155a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE},
156a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY},
157a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY},
158bc0e2c2aSKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_adisc_online_sending), BFA_RPORT_ADISC},
159bc0e2c2aSKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_adisc_online), BFA_RPORT_ADISC},
160bc0e2c2aSKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_adisc_offline_sending), BFA_RPORT_ADISC},
161bc0e2c2aSKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_adisc_offline), BFA_RPORT_ADISC},
162a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV},
163a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO},
164a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE},
165a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_hcb_offline), BFA_RPORT_OFFLINE},
166a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_hcb_logorcv), BFA_RPORT_LOGORCV},
167a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_hcb_logosend), BFA_RPORT_LOGO},
168a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_logo_sending), BFA_RPORT_LOGO},
169a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_offline), BFA_RPORT_OFFLINE},
170a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsdisc_sending), BFA_RPORT_NSDISC},
171a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsdisc_retry), BFA_RPORT_NSDISC},
172a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsdisc_sent), BFA_RPORT_NSDISC},
173a36c61f9SKrishna Gudipati };
174a36c61f9SKrishna Gudipati 
1755fbe25c7SJing Huang /*
176a36c61f9SKrishna Gudipati  *		Beginning state.
177a36c61f9SKrishna Gudipati  */
178a36c61f9SKrishna Gudipati static void
179a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event)
180a36c61f9SKrishna Gudipati {
181a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
182a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
183a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
184a36c61f9SKrishna Gudipati 
185a36c61f9SKrishna Gudipati 	switch (event) {
186a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_SEND:
187a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
188a36c61f9SKrishna Gudipati 		rport->plogi_retries = 0;
189a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogi(rport, NULL);
190a36c61f9SKrishna Gudipati 		break;
191a36c61f9SKrishna Gudipati 
192a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
19307cdc046SVijay Mohan Guvva 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
19407cdc046SVijay Mohan Guvva 		bfa_fcs_rport_send_plogiacc(rport, NULL);
195a36c61f9SKrishna Gudipati 		break;
196a36c61f9SKrishna Gudipati 
197a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
198a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
199a36c61f9SKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
200a36c61f9SKrishna Gudipati 		break;
201a36c61f9SKrishna Gudipati 
202a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
203a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_DISC:
204a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
205a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
206a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
207a36c61f9SKrishna Gudipati 		break;
208a36c61f9SKrishna Gudipati 	default:
209a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
210a36c61f9SKrishna Gudipati 	}
211a36c61f9SKrishna Gudipati }
212a36c61f9SKrishna Gudipati 
2135fbe25c7SJing Huang /*
214a36c61f9SKrishna Gudipati  *		PLOGI is being sent.
215a36c61f9SKrishna Gudipati  */
216a36c61f9SKrishna Gudipati static void
217a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
218a36c61f9SKrishna Gudipati 	 enum rport_event event)
219a36c61f9SKrishna Gudipati {
220a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
221a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
222a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
223a36c61f9SKrishna Gudipati 
224a36c61f9SKrishna Gudipati 	switch (event) {
225a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
226a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi);
227a36c61f9SKrishna Gudipati 		break;
228a36c61f9SKrishna Gudipati 
229a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
230a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
231a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
232a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
233a36c61f9SKrishna Gudipati 		break;
234a36c61f9SKrishna Gudipati 
235a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
236a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
237a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
238a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
239a36c61f9SKrishna Gudipati 		break;
240a36c61f9SKrishna Gudipati 
241bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_OFFLINE:
242bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
243bc0e2c2aSKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
244bc0e2c2aSKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
245bc0e2c2aSKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
246bc0e2c2aSKrishna Gudipati 				bfa_fcs_rport_del_timeout);
247bc0e2c2aSKrishna Gudipati 		break;
248a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
249bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
250a36c61f9SKrishna Gudipati 		/* query the NS */
251a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
252bc0e2c2aSKrishna Gudipati 		WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
253bc0e2c2aSKrishna Gudipati 					BFA_PORT_TOPOLOGY_LOOP));
254a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
255a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
256a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
257a36c61f9SKrishna Gudipati 		break;
258a36c61f9SKrishna Gudipati 
259a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
260a36c61f9SKrishna Gudipati 		rport->pid = 0;
261a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
262a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
263a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
264a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
265a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
266a36c61f9SKrishna Gudipati 		break;
267a36c61f9SKrishna Gudipati 
268a36c61f9SKrishna Gudipati 
269a36c61f9SKrishna Gudipati 	default:
270a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
271a36c61f9SKrishna Gudipati 	}
272a36c61f9SKrishna Gudipati }
273a36c61f9SKrishna Gudipati 
2745fbe25c7SJing Huang /*
275a36c61f9SKrishna Gudipati  *		PLOGI is being sent.
276a36c61f9SKrishna Gudipati  */
277a36c61f9SKrishna Gudipati static void
278a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
279a36c61f9SKrishna Gudipati 	 enum rport_event event)
280a36c61f9SKrishna Gudipati {
281a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
282a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
283a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
284a36c61f9SKrishna Gudipati 
285a36c61f9SKrishna Gudipati 	switch (event) {
286a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
28761ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
28861ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
289a36c61f9SKrishna Gudipati 		break;
290a36c61f9SKrishna Gudipati 
291a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
292a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
293a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
294a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
295a36c61f9SKrishna Gudipati 		break;
296a36c61f9SKrishna Gudipati 
297a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
298d7be54ccSKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
299bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
3005fbe25c7SJing Huang 		/*
301a36c61f9SKrishna Gudipati 		 * Ignore, SCN is possibly online notification.
302a36c61f9SKrishna Gudipati 		 */
303a36c61f9SKrishna Gudipati 		break;
304a36c61f9SKrishna Gudipati 
305bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_OFFLINE:
306bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
307bc0e2c2aSKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
308bc0e2c2aSKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
309bc0e2c2aSKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
310bc0e2c2aSKrishna Gudipati 				bfa_fcs_rport_del_timeout);
311bc0e2c2aSKrishna Gudipati 		break;
312bc0e2c2aSKrishna Gudipati 
313a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
314a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
315a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
316a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
317a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
318a36c61f9SKrishna Gudipati 		break;
319a36c61f9SKrishna Gudipati 
320a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
321a36c61f9SKrishna Gudipati 		rport->pid = 0;
322a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
323a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
324a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
325a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
326a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
327a36c61f9SKrishna Gudipati 		break;
328a36c61f9SKrishna Gudipati 
329a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
3305fbe25c7SJing Huang 		/*
331a36c61f9SKrishna Gudipati 		 * Ignore BFA callback, on a PLOGI receive we call bfa offline.
332a36c61f9SKrishna Gudipati 		 */
333a36c61f9SKrishna Gudipati 		break;
334a36c61f9SKrishna Gudipati 
335a36c61f9SKrishna Gudipati 	default:
336a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
337a36c61f9SKrishna Gudipati 	}
338a36c61f9SKrishna Gudipati }
339a36c61f9SKrishna Gudipati 
3405fbe25c7SJing Huang /*
341a36c61f9SKrishna Gudipati  *		PLOGI is sent.
342a36c61f9SKrishna Gudipati  */
343a36c61f9SKrishna Gudipati static void
344a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
345a36c61f9SKrishna Gudipati 			enum rport_event event)
346a36c61f9SKrishna Gudipati {
347a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
348a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
349a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
350a36c61f9SKrishna Gudipati 
351a36c61f9SKrishna Gudipati 	switch (event) {
352a36c61f9SKrishna Gudipati 	case RPSM_EVENT_TIMEOUT:
353a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
354a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogi(rport, NULL);
355a36c61f9SKrishna Gudipati 		break;
356a36c61f9SKrishna Gudipati 
357a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
358a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
359a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
360a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
361a36c61f9SKrishna Gudipati 		break;
362a36c61f9SKrishna Gudipati 
363a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
364a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
365a36c61f9SKrishna Gudipati 		break;
366a36c61f9SKrishna Gudipati 
367a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
368a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
369a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
370a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
371a36c61f9SKrishna Gudipati 		break;
372a36c61f9SKrishna Gudipati 
373bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_OFFLINE:
374bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
375a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
376bc0e2c2aSKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
377bc0e2c2aSKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
378bc0e2c2aSKrishna Gudipati 				bfa_fcs_rport_del_timeout);
379bc0e2c2aSKrishna Gudipati 		break;
380bc0e2c2aSKrishna Gudipati 
381bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
382bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
383bc0e2c2aSKrishna Gudipati 		bfa_timer_stop(&rport->timer);
384bc0e2c2aSKrishna Gudipati 		WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
385bc0e2c2aSKrishna Gudipati 					BFA_PORT_TOPOLOGY_LOOP));
386a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
387a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
388a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
389a36c61f9SKrishna Gudipati 		break;
390a36c61f9SKrishna Gudipati 
391a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
392a36c61f9SKrishna Gudipati 		rport->pid = 0;
393a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
394a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
395a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
396a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
397a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
398a36c61f9SKrishna Gudipati 		break;
399a36c61f9SKrishna Gudipati 
400a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
40161ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
402a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
40361ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
404a36c61f9SKrishna Gudipati 		break;
405a36c61f9SKrishna Gudipati 
406a36c61f9SKrishna Gudipati 	default:
407a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
408a36c61f9SKrishna Gudipati 	}
409a36c61f9SKrishna Gudipati }
410a36c61f9SKrishna Gudipati 
4115fbe25c7SJing Huang /*
412a36c61f9SKrishna Gudipati  *		PLOGI is sent.
413a36c61f9SKrishna Gudipati  */
414a36c61f9SKrishna Gudipati static void
415a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
416a36c61f9SKrishna Gudipati {
417a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
418a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
419a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
420a36c61f9SKrishna Gudipati 
421a36c61f9SKrishna Gudipati 	switch (event) {
422a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ACCEPTED:
42361ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
424a36c61f9SKrishna Gudipati 		rport->plogi_retries = 0;
42561ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
426a36c61f9SKrishna Gudipati 		break;
427a36c61f9SKrishna Gudipati 
428a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
429a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
430a36c61f9SKrishna Gudipati 		/*
431a36c61f9SKrishna Gudipati 		 * !! fall through !!
432a36c61f9SKrishna Gudipati 		 */
433a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
434a36c61f9SKrishna Gudipati 		if (rport->prlo == BFA_TRUE)
435a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
436a36c61f9SKrishna Gudipati 
437a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
438a36c61f9SKrishna Gudipati 		/*
439a36c61f9SKrishna Gudipati 		 * !! fall through !!
440a36c61f9SKrishna Gudipati 		 */
441a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FAILED:
442a36c61f9SKrishna Gudipati 		if (rport->plogi_retries < BFA_FCS_RPORT_MAX_RETRIES) {
443a36c61f9SKrishna Gudipati 			rport->plogi_retries++;
444a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
445a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
446a36c61f9SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
447a36c61f9SKrishna Gudipati 					BFA_FCS_RETRY_TIMEOUT);
448a36c61f9SKrishna Gudipati 		} else {
449a36c61f9SKrishna Gudipati 			bfa_stats(rport->port, rport_del_max_plogi_retry);
450ee1a4a42SKrishna Gudipati 			rport->old_pid = rport->pid;
451a36c61f9SKrishna Gudipati 			rport->pid = 0;
452a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
453a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
454a36c61f9SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
455a36c61f9SKrishna Gudipati 					bfa_fcs_rport_del_timeout);
456a36c61f9SKrishna Gudipati 		}
457a36c61f9SKrishna Gudipati 		break;
458a36c61f9SKrishna Gudipati 
459bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_ONLINE:
460bc0e2c2aSKrishna Gudipati 		break;
461bc0e2c2aSKrishna Gudipati 
462bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_OFFLINE:
463bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
464bc0e2c2aSKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
465bc0e2c2aSKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
466bc0e2c2aSKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
467bc0e2c2aSKrishna Gudipati 				bfa_fcs_rport_del_timeout);
468bc0e2c2aSKrishna Gudipati 		break;
469bc0e2c2aSKrishna Gudipati 
470a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RETRY:
471a36c61f9SKrishna Gudipati 		rport->plogi_retries = 0;
472a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
473a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
474a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
475a36c61f9SKrishna Gudipati 				(FC_RA_TOV * 1000));
476a36c61f9SKrishna Gudipati 		break;
477a36c61f9SKrishna Gudipati 
478a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
479a36c61f9SKrishna Gudipati 		rport->pid = 0;
480a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
481a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
482a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
483a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
484a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
485a36c61f9SKrishna Gudipati 		break;
486a36c61f9SKrishna Gudipati 
487a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
488bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
489a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
490bc0e2c2aSKrishna Gudipati 		WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
491bc0e2c2aSKrishna Gudipati 					BFA_PORT_TOPOLOGY_LOOP));
492a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
493a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
494a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
495a36c61f9SKrishna Gudipati 		break;
496a36c61f9SKrishna Gudipati 
497a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
498a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
499a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
500a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
501a36c61f9SKrishna Gudipati 		break;
502a36c61f9SKrishna Gudipati 
503a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
504a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
505a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
506a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
507a36c61f9SKrishna Gudipati 		break;
508a36c61f9SKrishna Gudipati 
509a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
51061ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
511a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
51261ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
513a36c61f9SKrishna Gudipati 		break;
514a36c61f9SKrishna Gudipati 
515a36c61f9SKrishna Gudipati 	default:
516a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
517a36c61f9SKrishna Gudipati 	}
518a36c61f9SKrishna Gudipati }
519a36c61f9SKrishna Gudipati 
5205fbe25c7SJing Huang /*
52161ba4394SKrishna Gudipati  * PLOGI is done. Await bfa_fcs_itnim to ascertain the scsi function
52261ba4394SKrishna Gudipati  */
52361ba4394SKrishna Gudipati static void
52461ba4394SKrishna Gudipati bfa_fcs_rport_sm_fc4_fcs_online(struct bfa_fcs_rport_s *rport,
52561ba4394SKrishna Gudipati 				enum rport_event event)
52661ba4394SKrishna Gudipati {
52761ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
52861ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
52961ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, event);
53061ba4394SKrishna Gudipati 
53161ba4394SKrishna Gudipati 	switch (event) {
53261ba4394SKrishna Gudipati 	case RPSM_EVENT_FC4_FCS_ONLINE:
53361ba4394SKrishna Gudipati 		if (rport->scsi_function == BFA_RPORT_INITIATOR) {
53461ba4394SKrishna Gudipati 			if (!BFA_FCS_PID_IS_WKA(rport->pid))
53561ba4394SKrishna Gudipati 				bfa_fcs_rpf_rport_online(rport);
53661ba4394SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
53761ba4394SKrishna Gudipati 			break;
53861ba4394SKrishna Gudipati 		}
53961ba4394SKrishna Gudipati 
54061ba4394SKrishna Gudipati 		if (!rport->bfa_rport)
54161ba4394SKrishna Gudipati 			rport->bfa_rport =
54261ba4394SKrishna Gudipati 				bfa_rport_create(rport->fcs->bfa, rport);
54361ba4394SKrishna Gudipati 
54461ba4394SKrishna Gudipati 		if (rport->bfa_rport) {
54561ba4394SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
54661ba4394SKrishna Gudipati 			bfa_fcs_rport_hal_online(rport);
54761ba4394SKrishna Gudipati 		} else {
54861ba4394SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
54961ba4394SKrishna Gudipati 			bfa_fcs_rport_fcs_offline_action(rport);
55061ba4394SKrishna Gudipati 		}
55161ba4394SKrishna Gudipati 		break;
55261ba4394SKrishna Gudipati 
55361ba4394SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
55461ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
55561ba4394SKrishna Gudipati 		rport->plogi_pending = BFA_TRUE;
55661ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
55761ba4394SKrishna Gudipati 		break;
55861ba4394SKrishna Gudipati 
55961ba4394SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
56061ba4394SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
56161ba4394SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
562bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
563bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_OFFLINE:
56461ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
56561ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
56661ba4394SKrishna Gudipati 		break;
56761ba4394SKrishna Gudipati 
56861ba4394SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
56961ba4394SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
57061ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
57161ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
57261ba4394SKrishna Gudipati 		break;
57361ba4394SKrishna Gudipati 
57461ba4394SKrishna Gudipati 	case RPSM_EVENT_DELETE:
57561ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
57661ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
57761ba4394SKrishna Gudipati 		break;
57861ba4394SKrishna Gudipati 
57961ba4394SKrishna Gudipati 	default:
58061ba4394SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
58161ba4394SKrishna Gudipati 		break;
58261ba4394SKrishna Gudipati 	}
58361ba4394SKrishna Gudipati }
58461ba4394SKrishna Gudipati 
58561ba4394SKrishna Gudipati /*
586a36c61f9SKrishna Gudipati  *		PLOGI is complete. Awaiting BFA rport online callback. FC-4s
587a36c61f9SKrishna Gudipati  *		are offline.
588a36c61f9SKrishna Gudipati  */
589a36c61f9SKrishna Gudipati static void
590a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
591a36c61f9SKrishna Gudipati 			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_HCB_ONLINE:
599a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
60061ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_online_action(rport);
601a36c61f9SKrishna Gudipati 		break;
602a36c61f9SKrishna Gudipati 
603d7be54ccSKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
604a36c61f9SKrishna Gudipati 		break;
605a36c61f9SKrishna Gudipati 
60661ba4394SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
607a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
60861ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
60961ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
610a36c61f9SKrishna Gudipati 		break;
611a36c61f9SKrishna Gudipati 
612bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
613a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
614a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
615bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_OFFLINE:
61661ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
61761ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
618a36c61f9SKrishna Gudipati 		break;
619a36c61f9SKrishna Gudipati 
620a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
621d7be54ccSKrishna Gudipati 		rport->plogi_pending = BFA_TRUE;
62261ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
62361ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
624a36c61f9SKrishna Gudipati 		break;
625a36c61f9SKrishna Gudipati 
626a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
62761ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
62861ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
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  *		Rport is ONLINE. FC-4s active.
638a36c61f9SKrishna Gudipati  */
639a36c61f9SKrishna Gudipati static void
640a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
641a36c61f9SKrishna Gudipati {
642a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
643a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
644a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
645a36c61f9SKrishna Gudipati 
646a36c61f9SKrishna Gudipati 	switch (event) {
647bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
648a36c61f9SKrishna Gudipati 		if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
649a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
650a36c61f9SKrishna Gudipati 					 bfa_fcs_rport_sm_nsquery_sending);
651a36c61f9SKrishna Gudipati 			rport->ns_retries = 0;
652a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
653a36c61f9SKrishna Gudipati 		} else {
654bc0e2c2aSKrishna Gudipati 			bfa_sm_set_state(rport,
655bc0e2c2aSKrishna Gudipati 				bfa_fcs_rport_sm_adisc_online_sending);
656a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_adisc(rport, NULL);
657a36c61f9SKrishna Gudipati 		}
658a36c61f9SKrishna Gudipati 		break;
659a36c61f9SKrishna Gudipati 
660a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
661a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
662a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
663bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_OFFLINE:
664a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
66561ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
666a36c61f9SKrishna Gudipati 		break;
667a36c61f9SKrishna Gudipati 
668a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
669a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
67061ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
671a36c61f9SKrishna Gudipati 		break;
672a36c61f9SKrishna Gudipati 
673a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
674a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
675a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
67661ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
677a36c61f9SKrishna Gudipati 		break;
678a36c61f9SKrishna Gudipati 
679bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_ONLINE:
680a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
681a36c61f9SKrishna Gudipati 		break;
682a36c61f9SKrishna Gudipati 
683a36c61f9SKrishna Gudipati 	default:
684a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
685a36c61f9SKrishna Gudipati 	}
686a36c61f9SKrishna Gudipati }
687a36c61f9SKrishna Gudipati 
6885fbe25c7SJing Huang /*
689a36c61f9SKrishna Gudipati  *		An SCN event is received in ONLINE state. NS query is being sent
690a36c61f9SKrishna Gudipati  *		prior to ADISC authentication with rport. FC-4s are paused.
691a36c61f9SKrishna Gudipati  */
692a36c61f9SKrishna Gudipati static void
693a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
694a36c61f9SKrishna Gudipati 	 enum rport_event event)
695a36c61f9SKrishna Gudipati {
696a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
697a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
698a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
699a36c61f9SKrishna Gudipati 
700a36c61f9SKrishna Gudipati 	switch (event) {
701a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
702a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsquery);
703a36c61f9SKrishna Gudipati 		break;
704a36c61f9SKrishna Gudipati 
705a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
706a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
707a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
70861ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
709a36c61f9SKrishna Gudipati 		break;
710a36c61f9SKrishna Gudipati 
711bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
7125fbe25c7SJing Huang 		/*
713a36c61f9SKrishna Gudipati 		 * ignore SCN, wait for response to query itself
714a36c61f9SKrishna Gudipati 		 */
715a36c61f9SKrishna Gudipati 		break;
716a36c61f9SKrishna Gudipati 
717a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
718a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
719a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
720a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
72161ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
722a36c61f9SKrishna Gudipati 		break;
723a36c61f9SKrishna Gudipati 
724a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
725a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
726a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
727a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
728a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
729a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
73061ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
731a36c61f9SKrishna Gudipati 		break;
732a36c61f9SKrishna Gudipati 
733a36c61f9SKrishna Gudipati 	default:
734a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
735a36c61f9SKrishna Gudipati 	}
736a36c61f9SKrishna Gudipati }
737a36c61f9SKrishna Gudipati 
7385fbe25c7SJing Huang /*
739a36c61f9SKrishna Gudipati  *	An SCN event is received in ONLINE state. NS query is sent to rport.
740a36c61f9SKrishna Gudipati  *	FC-4s are paused.
741a36c61f9SKrishna Gudipati  */
742a36c61f9SKrishna Gudipati static void
743a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
744a36c61f9SKrishna Gudipati {
745a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
746a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
747a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
748a36c61f9SKrishna Gudipati 
749a36c61f9SKrishna Gudipati 	switch (event) {
750a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ACCEPTED:
751bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online_sending);
752a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_adisc(rport, NULL);
753a36c61f9SKrishna Gudipati 		break;
754a36c61f9SKrishna Gudipati 
755a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FAILED:
756a36c61f9SKrishna Gudipati 		rport->ns_retries++;
757a36c61f9SKrishna Gudipati 		if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
758a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
759a36c61f9SKrishna Gudipati 					 bfa_fcs_rport_sm_nsquery_sending);
760a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
761a36c61f9SKrishna Gudipati 		} else {
762a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
76361ba4394SKrishna Gudipati 			bfa_fcs_rport_hal_offline_action(rport);
764a36c61f9SKrishna Gudipati 		}
765a36c61f9SKrishna Gudipati 		break;
766a36c61f9SKrishna Gudipati 
767a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
768a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
769a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
77061ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
771a36c61f9SKrishna Gudipati 		break;
772a36c61f9SKrishna Gudipati 
773bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
774a36c61f9SKrishna Gudipati 		break;
775a36c61f9SKrishna Gudipati 
776a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
777a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
778a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
779a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
78061ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
781a36c61f9SKrishna Gudipati 		break;
782a36c61f9SKrishna Gudipati 
783a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
784a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
785a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
786a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
787a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
788a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
78961ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
790a36c61f9SKrishna Gudipati 		break;
791a36c61f9SKrishna Gudipati 
792a36c61f9SKrishna Gudipati 	default:
793a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
794a36c61f9SKrishna Gudipati 	}
795a36c61f9SKrishna Gudipati }
796a36c61f9SKrishna Gudipati 
7975fbe25c7SJing Huang /*
798a36c61f9SKrishna Gudipati  *	An SCN event is received in ONLINE state. ADISC is being sent for
799a36c61f9SKrishna Gudipati  *	authenticating with rport. FC-4s are paused.
800a36c61f9SKrishna Gudipati  */
801a36c61f9SKrishna Gudipati static void
802bc0e2c2aSKrishna Gudipati bfa_fcs_rport_sm_adisc_online_sending(struct bfa_fcs_rport_s *rport,
803a36c61f9SKrishna Gudipati 	 enum rport_event event)
804a36c61f9SKrishna Gudipati {
805a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
806a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
807a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
808a36c61f9SKrishna Gudipati 
809a36c61f9SKrishna Gudipati 	switch (event) {
810a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
811bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_online);
812a36c61f9SKrishna Gudipati 		break;
813a36c61f9SKrishna Gudipati 
814a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
815a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
816a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
81761ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
818a36c61f9SKrishna Gudipati 		break;
819a36c61f9SKrishna Gudipati 
820a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
821a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
822a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
823a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
82461ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
825a36c61f9SKrishna Gudipati 		break;
826a36c61f9SKrishna Gudipati 
827a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
828a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
829a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
830a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
83161ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
832a36c61f9SKrishna Gudipati 		break;
833a36c61f9SKrishna Gudipati 
834bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
835a36c61f9SKrishna Gudipati 		break;
836a36c61f9SKrishna Gudipati 
837a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
838a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
839a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
84061ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
841a36c61f9SKrishna Gudipati 		break;
842a36c61f9SKrishna Gudipati 
843a36c61f9SKrishna Gudipati 	default:
844a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
845a36c61f9SKrishna Gudipati 	}
846a36c61f9SKrishna Gudipati }
847a36c61f9SKrishna Gudipati 
8485fbe25c7SJing Huang /*
849a36c61f9SKrishna Gudipati  *		An SCN event is received in ONLINE state. ADISC is to rport.
850a36c61f9SKrishna Gudipati  *		FC-4s are paused.
851a36c61f9SKrishna Gudipati  */
852a36c61f9SKrishna Gudipati static void
853bc0e2c2aSKrishna Gudipati bfa_fcs_rport_sm_adisc_online(struct bfa_fcs_rport_s *rport,
854bc0e2c2aSKrishna Gudipati 				enum rport_event event)
855a36c61f9SKrishna Gudipati {
856a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
857a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
858a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
859a36c61f9SKrishna Gudipati 
860a36c61f9SKrishna Gudipati 	switch (event) {
861a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ACCEPTED:
862a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
863a36c61f9SKrishna Gudipati 		break;
864a36c61f9SKrishna Gudipati 
865a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
8665fbe25c7SJing Huang 		/*
867a36c61f9SKrishna Gudipati 		 * Too complex to cleanup FC-4 & rport and then acc to PLOGI.
868a36c61f9SKrishna Gudipati 		 * At least go offline when a PLOGI is received.
869a36c61f9SKrishna Gudipati 		 */
870a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
871a36c61f9SKrishna Gudipati 		/*
872a36c61f9SKrishna Gudipati 		 * !!! fall through !!!
873a36c61f9SKrishna Gudipati 		 */
874a36c61f9SKrishna Gudipati 
875a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FAILED:
876a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
877a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
87861ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
879a36c61f9SKrishna Gudipati 		break;
880a36c61f9SKrishna Gudipati 
881a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
882a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
883a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
88461ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
885a36c61f9SKrishna Gudipati 		break;
886a36c61f9SKrishna Gudipati 
887bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
8885fbe25c7SJing Huang 		/*
889a36c61f9SKrishna Gudipati 		 * already processing RSCN
890a36c61f9SKrishna Gudipati 		 */
891a36c61f9SKrishna Gudipati 		break;
892a36c61f9SKrishna Gudipati 
893a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
894a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
895a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
89661ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
897a36c61f9SKrishna Gudipati 		break;
898a36c61f9SKrishna Gudipati 
899a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
900a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
901a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
902a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
90361ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline_action(rport);
904a36c61f9SKrishna Gudipati 		break;
905a36c61f9SKrishna Gudipati 
906a36c61f9SKrishna Gudipati 	default:
907a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
908a36c61f9SKrishna Gudipati 	}
909a36c61f9SKrishna Gudipati }
910a36c61f9SKrishna Gudipati 
9115fbe25c7SJing Huang /*
912bc0e2c2aSKrishna Gudipati  * ADISC is being sent for authenticating with rport
913bc0e2c2aSKrishna Gudipati  * Already did offline actions.
914bc0e2c2aSKrishna Gudipati  */
915bc0e2c2aSKrishna Gudipati static void
916bc0e2c2aSKrishna Gudipati bfa_fcs_rport_sm_adisc_offline_sending(struct bfa_fcs_rport_s *rport,
917bc0e2c2aSKrishna Gudipati 	enum rport_event event)
918bc0e2c2aSKrishna Gudipati {
919bc0e2c2aSKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
920bc0e2c2aSKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
921bc0e2c2aSKrishna Gudipati 	bfa_trc(rport->fcs, event);
922bc0e2c2aSKrishna Gudipati 
923bc0e2c2aSKrishna Gudipati 	switch (event) {
924bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
925bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_offline);
926bc0e2c2aSKrishna Gudipati 		break;
927bc0e2c2aSKrishna Gudipati 
928bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_DELETE:
929bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_OFFLINE:
930bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
931bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
932bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
933bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
934bc0e2c2aSKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa,
935bc0e2c2aSKrishna Gudipati 			&rport->fcxp_wqe);
936bc0e2c2aSKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
937bc0e2c2aSKrishna Gudipati 			bfa_fcs_rport_timeout, rport,
938bc0e2c2aSKrishna Gudipati 			bfa_fcs_rport_del_timeout);
939bc0e2c2aSKrishna Gudipati 		break;
940bc0e2c2aSKrishna Gudipati 
941bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
942bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
943bc0e2c2aSKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
944bc0e2c2aSKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
945bc0e2c2aSKrishna Gudipati 		break;
946bc0e2c2aSKrishna Gudipati 
947bc0e2c2aSKrishna Gudipati 	default:
948bc0e2c2aSKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
949bc0e2c2aSKrishna Gudipati 	}
950bc0e2c2aSKrishna Gudipati }
951bc0e2c2aSKrishna Gudipati 
952bc0e2c2aSKrishna Gudipati /*
953bc0e2c2aSKrishna Gudipati  * ADISC to rport
954bc0e2c2aSKrishna Gudipati  * Already did offline actions
955bc0e2c2aSKrishna Gudipati  */
956bc0e2c2aSKrishna Gudipati static void
957bc0e2c2aSKrishna Gudipati bfa_fcs_rport_sm_adisc_offline(struct bfa_fcs_rport_s *rport,
958bc0e2c2aSKrishna Gudipati 			enum rport_event event)
959bc0e2c2aSKrishna Gudipati {
960bc0e2c2aSKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
961bc0e2c2aSKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
962bc0e2c2aSKrishna Gudipati 	bfa_trc(rport->fcs, event);
963bc0e2c2aSKrishna Gudipati 
964bc0e2c2aSKrishna Gudipati 	switch (event) {
965bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_ACCEPTED:
966bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
967bc0e2c2aSKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
968bc0e2c2aSKrishna Gudipati 		break;
969bc0e2c2aSKrishna Gudipati 
970bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
971bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
972bc0e2c2aSKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
973bc0e2c2aSKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
974bc0e2c2aSKrishna Gudipati 		break;
975bc0e2c2aSKrishna Gudipati 
976bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAILED:
977bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
978bc0e2c2aSKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
979bc0e2c2aSKrishna Gudipati 			bfa_fcs_rport_timeout, rport,
980bc0e2c2aSKrishna Gudipati 			bfa_fcs_rport_del_timeout);
981bc0e2c2aSKrishna Gudipati 		break;
982bc0e2c2aSKrishna Gudipati 
983bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_DELETE:
984bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_OFFLINE:
985bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
986bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
987bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
988bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
989bc0e2c2aSKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
990bc0e2c2aSKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
991bc0e2c2aSKrishna Gudipati 			bfa_fcs_rport_timeout, rport,
992bc0e2c2aSKrishna Gudipati 			bfa_fcs_rport_del_timeout);
993bc0e2c2aSKrishna Gudipati 		break;
994bc0e2c2aSKrishna Gudipati 
995bc0e2c2aSKrishna Gudipati 	default:
996bc0e2c2aSKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
997bc0e2c2aSKrishna Gudipati 	}
998bc0e2c2aSKrishna Gudipati }
999bc0e2c2aSKrishna Gudipati 
1000bc0e2c2aSKrishna Gudipati /*
1001a36c61f9SKrishna Gudipati  * Rport has sent LOGO. Awaiting FC-4 offline completion callback.
1002a36c61f9SKrishna Gudipati  */
1003a36c61f9SKrishna Gudipati static void
1004a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
1005a36c61f9SKrishna Gudipati 			enum rport_event event)
1006a36c61f9SKrishna Gudipati {
1007a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1008a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1009a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1010a36c61f9SKrishna Gudipati 
1011a36c61f9SKrishna Gudipati 	switch (event) {
1012a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FC4_OFFLINE:
1013a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
101461ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline(rport);
1015a36c61f9SKrishna Gudipati 		break;
1016a36c61f9SKrishna Gudipati 
1017a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
101861ba4394SKrishna Gudipati 		if (rport->pid && (rport->prlo == BFA_TRUE))
101961ba4394SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
102061ba4394SKrishna Gudipati 		if (rport->pid && (rport->prlo == BFA_FALSE))
102161ba4394SKrishna Gudipati 			bfa_fcs_rport_send_logo_acc(rport);
102261ba4394SKrishna Gudipati 
102361ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete);
1024a36c61f9SKrishna Gudipati 		break;
1025a36c61f9SKrishna Gudipati 
1026bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_ONLINE:
1027bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_OFFLINE:
102861ba4394SKrishna Gudipati 	case RPSM_EVENT_HCB_ONLINE:
1029a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1030a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1031a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1032a36c61f9SKrishna Gudipati 		break;
1033a36c61f9SKrishna Gudipati 
1034a36c61f9SKrishna Gudipati 	default:
1035a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1036a36c61f9SKrishna Gudipati 	}
1037a36c61f9SKrishna Gudipati }
1038a36c61f9SKrishna Gudipati 
10395fbe25c7SJing Huang /*
1040a36c61f9SKrishna Gudipati  *		LOGO needs to be sent to rport. Awaiting FC-4 offline completion
1041a36c61f9SKrishna Gudipati  *		callback.
1042a36c61f9SKrishna Gudipati  */
1043a36c61f9SKrishna Gudipati static void
1044a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
1045a36c61f9SKrishna Gudipati 	 enum rport_event event)
1046a36c61f9SKrishna Gudipati {
1047a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1048a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1049a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1050a36c61f9SKrishna Gudipati 
1051a36c61f9SKrishna Gudipati 	switch (event) {
1052a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FC4_OFFLINE:
1053a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
105461ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline(rport);
105561ba4394SKrishna Gudipati 		break;
105661ba4394SKrishna Gudipati 
105761ba4394SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
105861ba4394SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
105961ba4394SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
106061ba4394SKrishna Gudipati 		if (rport->prlo == BFA_TRUE)
106161ba4394SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
106261ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_off_delete);
106361ba4394SKrishna Gudipati 		break;
106461ba4394SKrishna Gudipati 
106561ba4394SKrishna Gudipati 	case RPSM_EVENT_HCB_ONLINE:
106661ba4394SKrishna Gudipati 	case RPSM_EVENT_DELETE:
106761ba4394SKrishna Gudipati 		/* Rport is being deleted */
1068a36c61f9SKrishna Gudipati 		break;
1069a36c61f9SKrishna Gudipati 
1070a36c61f9SKrishna Gudipati 	default:
1071a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1072a36c61f9SKrishna Gudipati 	}
1073a36c61f9SKrishna Gudipati }
1074a36c61f9SKrishna Gudipati 
10755fbe25c7SJing Huang /*
1076a36c61f9SKrishna Gudipati  *	Rport is going offline. Awaiting FC-4 offline completion callback.
1077a36c61f9SKrishna Gudipati  */
1078a36c61f9SKrishna Gudipati static void
1079a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
1080a36c61f9SKrishna Gudipati 			enum rport_event event)
1081a36c61f9SKrishna Gudipati {
1082a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1083a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1084a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1085a36c61f9SKrishna Gudipati 
1086a36c61f9SKrishna Gudipati 	switch (event) {
1087a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FC4_OFFLINE:
1088a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
108961ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline(rport);
1090a36c61f9SKrishna Gudipati 		break;
1091a36c61f9SKrishna Gudipati 
1092bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_ONLINE:
1093bc0e2c2aSKrishna Gudipati 		break;
109461ba4394SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
109561ba4394SKrishna Gudipati 		/*
109661ba4394SKrishna Gudipati 		 * Rport is going offline. Just ack the logo
109761ba4394SKrishna Gudipati 		 */
109861ba4394SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
109961ba4394SKrishna Gudipati 		break;
110061ba4394SKrishna Gudipati 
110161ba4394SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
110261ba4394SKrishna Gudipati 		bfa_fcs_rport_send_prlo_acc(rport);
110361ba4394SKrishna Gudipati 		break;
110461ba4394SKrishna Gudipati 
1105bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_OFFLINE:
110661ba4394SKrishna Gudipati 	case RPSM_EVENT_HCB_ONLINE:
1107bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
1108a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
1109a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
11105fbe25c7SJing Huang 		/*
1111a36c61f9SKrishna Gudipati 		 * rport is already going offline.
1112a36c61f9SKrishna Gudipati 		 * SCN - ignore and wait till transitioning to offline state
1113a36c61f9SKrishna Gudipati 		 */
1114a36c61f9SKrishna Gudipati 		break;
1115a36c61f9SKrishna Gudipati 
1116a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
1117a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
1118a36c61f9SKrishna Gudipati 		break;
1119a36c61f9SKrishna Gudipati 
1120a36c61f9SKrishna Gudipati 	default:
1121a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1122a36c61f9SKrishna Gudipati 	}
1123a36c61f9SKrishna Gudipati }
1124a36c61f9SKrishna Gudipati 
11255fbe25c7SJing Huang /*
1126a36c61f9SKrishna Gudipati  *		Rport is offline. FC-4s are offline. Awaiting BFA rport offline
1127a36c61f9SKrishna Gudipati  *		callback.
1128a36c61f9SKrishna Gudipati  */
1129a36c61f9SKrishna Gudipati static void
1130a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
1131a36c61f9SKrishna Gudipati 				enum rport_event event)
1132a36c61f9SKrishna Gudipati {
1133a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1134a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1135a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1136a36c61f9SKrishna Gudipati 
1137a36c61f9SKrishna Gudipati 	switch (event) {
1138a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
1139d7be54ccSKrishna Gudipati 		if (bfa_fcs_lport_is_online(rport->port) &&
1140d7be54ccSKrishna Gudipati 		    (rport->plogi_pending)) {
1141d7be54ccSKrishna Gudipati 			rport->plogi_pending = BFA_FALSE;
1142d7be54ccSKrishna Gudipati 			bfa_sm_set_state(rport,
1143d7be54ccSKrishna Gudipati 				bfa_fcs_rport_sm_plogiacc_sending);
1144d7be54ccSKrishna Gudipati 			bfa_fcs_rport_send_plogiacc(rport, NULL);
1145d7be54ccSKrishna Gudipati 			break;
1146d7be54ccSKrishna Gudipati 		}
1147d7be54ccSKrishna Gudipati 		/*
1148d7be54ccSKrishna Gudipati 		 * !! fall through !!
1149d7be54ccSKrishna Gudipati 		 */
1150d7be54ccSKrishna Gudipati 
1151a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
115261ba4394SKrishna Gudipati 		if (!bfa_fcs_lport_is_online(rport->port)) {
115361ba4394SKrishna Gudipati 			rport->pid = 0;
115461ba4394SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
115561ba4394SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
115661ba4394SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
115761ba4394SKrishna Gudipati 					bfa_fcs_rport_del_timeout);
115861ba4394SKrishna Gudipati 			break;
115961ba4394SKrishna Gudipati 		}
1160a36c61f9SKrishna Gudipati 		if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
1161a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
1162a36c61f9SKrishna Gudipati 				bfa_fcs_rport_sm_nsdisc_sending);
1163a36c61f9SKrishna Gudipati 			rport->ns_retries = 0;
1164a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
1165bc0e2c2aSKrishna Gudipati 		} else if (bfa_fcport_get_topology(rport->port->fcs->bfa) ==
1166bc0e2c2aSKrishna Gudipati 					BFA_PORT_TOPOLOGY_LOOP) {
1167bc0e2c2aSKrishna Gudipati 			if (rport->scn_online) {
1168bc0e2c2aSKrishna Gudipati 				bfa_sm_set_state(rport,
1169bc0e2c2aSKrishna Gudipati 					bfa_fcs_rport_sm_adisc_offline_sending);
1170bc0e2c2aSKrishna Gudipati 				bfa_fcs_rport_send_adisc(rport, NULL);
1171bc0e2c2aSKrishna Gudipati 			} else {
1172bc0e2c2aSKrishna Gudipati 				bfa_sm_set_state(rport,
1173bc0e2c2aSKrishna Gudipati 					bfa_fcs_rport_sm_offline);
1174bc0e2c2aSKrishna Gudipati 				bfa_timer_start(rport->fcs->bfa, &rport->timer,
1175bc0e2c2aSKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
1176bc0e2c2aSKrishna Gudipati 					bfa_fcs_rport_del_timeout);
1177bc0e2c2aSKrishna Gudipati 			}
1178a36c61f9SKrishna Gudipati 		} else {
117961ba4394SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1180a36c61f9SKrishna Gudipati 			rport->plogi_retries = 0;
1181a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_plogi(rport, NULL);
1182a36c61f9SKrishna Gudipati 		}
1183a36c61f9SKrishna Gudipati 		break;
1184a36c61f9SKrishna Gudipati 
1185a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
1186a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1187a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1188a36c61f9SKrishna Gudipati 		break;
1189a36c61f9SKrishna Gudipati 
1190bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_ONLINE:
1191bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_OFFLINE:
1192bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
1193a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1194a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1195d7be54ccSKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
1196d7be54ccSKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
11975fbe25c7SJing Huang 		/*
1198a36c61f9SKrishna Gudipati 		 * Ignore, already offline.
1199a36c61f9SKrishna Gudipati 		 */
1200a36c61f9SKrishna Gudipati 		break;
1201a36c61f9SKrishna Gudipati 
1202a36c61f9SKrishna Gudipati 	default:
1203a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1204a36c61f9SKrishna Gudipati 	}
1205a36c61f9SKrishna Gudipati }
1206a36c61f9SKrishna Gudipati 
12075fbe25c7SJing Huang /*
1208a36c61f9SKrishna Gudipati  *		Rport is offline. FC-4s are offline. Awaiting BFA rport offline
1209a36c61f9SKrishna Gudipati  *		callback to send LOGO accept.
1210a36c61f9SKrishna Gudipati  */
1211a36c61f9SKrishna Gudipati static void
1212a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
1213a36c61f9SKrishna Gudipati 			enum rport_event event)
1214a36c61f9SKrishna Gudipati {
1215a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1216a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1217a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1218a36c61f9SKrishna Gudipati 
1219a36c61f9SKrishna Gudipati 	switch (event) {
1220a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
1221a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1222a36c61f9SKrishna Gudipati 		if (rport->pid && (rport->prlo == BFA_TRUE))
1223a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
1224a36c61f9SKrishna Gudipati 		if (rport->pid && (rport->prlo == BFA_FALSE))
1225a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_logo_acc(rport);
1226a36c61f9SKrishna Gudipati 		/*
1227a36c61f9SKrishna Gudipati 		 * If the lport is online and if the rport is not a well
1228a36c61f9SKrishna Gudipati 		 * known address port,
1229a36c61f9SKrishna Gudipati 		 * we try to re-discover the r-port.
1230a36c61f9SKrishna Gudipati 		 */
1231a36c61f9SKrishna Gudipati 		if (bfa_fcs_lport_is_online(rport->port) &&
1232a36c61f9SKrishna Gudipati 			(!BFA_FCS_PID_IS_WKA(rport->pid))) {
1233d7be54ccSKrishna Gudipati 			if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
1234a36c61f9SKrishna Gudipati 				bfa_sm_set_state(rport,
1235a36c61f9SKrishna Gudipati 					bfa_fcs_rport_sm_nsdisc_sending);
1236a36c61f9SKrishna Gudipati 				rport->ns_retries = 0;
1237a36c61f9SKrishna Gudipati 				bfa_fcs_rport_send_nsdisc(rport, NULL);
1238a36c61f9SKrishna Gudipati 			} else {
1239d7be54ccSKrishna Gudipati 				/* For N2N  Direct Attach, try to re-login */
1240d7be54ccSKrishna Gudipati 				bfa_sm_set_state(rport,
1241d7be54ccSKrishna Gudipati 					bfa_fcs_rport_sm_plogi_sending);
1242d7be54ccSKrishna Gudipati 				rport->plogi_retries = 0;
1243d7be54ccSKrishna Gudipati 				bfa_fcs_rport_send_plogi(rport, NULL);
1244d7be54ccSKrishna Gudipati 			}
1245d7be54ccSKrishna Gudipati 		} else {
1246a36c61f9SKrishna Gudipati 			/*
1247a36c61f9SKrishna Gudipati 			 * if it is not a well known address, reset the
1248a36c61f9SKrishna Gudipati 			 * pid to 0.
1249a36c61f9SKrishna Gudipati 			 */
1250a36c61f9SKrishna Gudipati 			if (!BFA_FCS_PID_IS_WKA(rport->pid))
1251a36c61f9SKrishna Gudipati 				rport->pid = 0;
1252a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1253a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
1254a36c61f9SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
1255a36c61f9SKrishna Gudipati 					bfa_fcs_rport_del_timeout);
1256a36c61f9SKrishna Gudipati 		}
1257a36c61f9SKrishna Gudipati 		break;
1258a36c61f9SKrishna Gudipati 
1259a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
126061ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
126161ba4394SKrishna Gudipati 		if (rport->pid && (rport->prlo == BFA_TRUE))
126261ba4394SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
126361ba4394SKrishna Gudipati 		if (rport->pid && (rport->prlo == BFA_FALSE))
126461ba4394SKrishna Gudipati 			bfa_fcs_rport_send_logo_acc(rport);
1265a36c61f9SKrishna Gudipati 		break;
1266a36c61f9SKrishna Gudipati 
1267a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
1268a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
1269a36c61f9SKrishna Gudipati 		break;
1270a36c61f9SKrishna Gudipati 
1271bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_ONLINE:
1272bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_OFFLINE:
1273a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1274a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
12755fbe25c7SJing Huang 		/*
1276a36c61f9SKrishna Gudipati 		 * Ignore - already processing a LOGO.
1277a36c61f9SKrishna Gudipati 		 */
1278a36c61f9SKrishna Gudipati 		break;
1279a36c61f9SKrishna Gudipati 
1280a36c61f9SKrishna Gudipati 	default:
1281a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1282a36c61f9SKrishna Gudipati 	}
1283a36c61f9SKrishna Gudipati }
1284a36c61f9SKrishna Gudipati 
12855fbe25c7SJing Huang /*
1286a36c61f9SKrishna Gudipati  *		Rport is being deleted. FC-4s are offline.
1287a36c61f9SKrishna Gudipati  *  Awaiting BFA rport offline
1288a36c61f9SKrishna Gudipati  *		callback to send LOGO.
1289a36c61f9SKrishna Gudipati  */
1290a36c61f9SKrishna Gudipati static void
1291a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
1292a36c61f9SKrishna Gudipati 		 enum rport_event event)
1293a36c61f9SKrishna Gudipati {
1294a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1295a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1296a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1297a36c61f9SKrishna Gudipati 
1298a36c61f9SKrishna Gudipati 	switch (event) {
1299a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
1300a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_logo_sending);
1301a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_logo(rport, NULL);
1302a36c61f9SKrishna Gudipati 		break;
1303a36c61f9SKrishna Gudipati 
1304a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
130561ba4394SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
1306a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
130761ba4394SKrishna Gudipati 		if (rport->prlo == BFA_TRUE)
130861ba4394SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
130961ba4394SKrishna Gudipati 
131061ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
131161ba4394SKrishna Gudipati 		break;
131261ba4394SKrishna Gudipati 
1313bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_ONLINE:
1314bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_OFFLINE:
1315a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1316a36c61f9SKrishna Gudipati 		break;
1317a36c61f9SKrishna Gudipati 
1318a36c61f9SKrishna Gudipati 	default:
1319a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1320a36c61f9SKrishna Gudipati 	}
1321a36c61f9SKrishna Gudipati }
1322a36c61f9SKrishna Gudipati 
13235fbe25c7SJing Huang /*
1324a36c61f9SKrishna Gudipati  *		Rport is being deleted. FC-4s are offline. LOGO is being sent.
1325a36c61f9SKrishna Gudipati  */
1326a36c61f9SKrishna Gudipati static void
1327a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
1328a36c61f9SKrishna Gudipati 	 enum rport_event event)
1329a36c61f9SKrishna Gudipati {
1330a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1331a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1332a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1333a36c61f9SKrishna Gudipati 
1334a36c61f9SKrishna Gudipati 	switch (event) {
1335a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
1336a36c61f9SKrishna Gudipati 		/* Once LOGO is sent, we donot wait for the response */
1337a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1338a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1339a36c61f9SKrishna Gudipati 		break;
1340a36c61f9SKrishna Gudipati 
1341bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_ONLINE:
1342bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_OFFLINE:
1343bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
1344a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1345a36c61f9SKrishna Gudipati 		break;
1346a36c61f9SKrishna Gudipati 
1347a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
134861ba4394SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
1349a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
135061ba4394SKrishna Gudipati 		if (rport->prlo == BFA_TRUE)
135161ba4394SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
135261ba4394SKrishna Gudipati 
1353a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1354a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1355a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1356a36c61f9SKrishna Gudipati 		break;
1357a36c61f9SKrishna Gudipati 
1358a36c61f9SKrishna Gudipati 	default:
1359a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1360a36c61f9SKrishna Gudipati 	}
1361a36c61f9SKrishna Gudipati }
1362a36c61f9SKrishna Gudipati 
13635fbe25c7SJing Huang /*
1364a36c61f9SKrishna Gudipati  *		Rport is offline. FC-4s are offline. BFA rport is offline.
1365a36c61f9SKrishna Gudipati  *		Timer active to delete stale rport.
1366a36c61f9SKrishna Gudipati  */
1367a36c61f9SKrishna Gudipati static void
1368a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
1369a36c61f9SKrishna Gudipati {
1370a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1371a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1372a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1373a36c61f9SKrishna Gudipati 
1374a36c61f9SKrishna Gudipati 	switch (event) {
1375a36c61f9SKrishna Gudipati 	case RPSM_EVENT_TIMEOUT:
1376a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1377a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1378a36c61f9SKrishna Gudipati 		break;
1379a36c61f9SKrishna Gudipati 
1380bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
1381a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1382a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1383bc0e2c2aSKrishna Gudipati 		WARN_ON(!(bfa_fcport_get_topology(rport->port->fcs->bfa) !=
1384bc0e2c2aSKrishna Gudipati 					BFA_PORT_TOPOLOGY_LOOP));
1385bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1386a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
1387a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
1388a36c61f9SKrishna Gudipati 		break;
1389a36c61f9SKrishna Gudipati 
1390a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
1391a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1392a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1393a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1394a36c61f9SKrishna Gudipati 		break;
1395a36c61f9SKrishna Gudipati 
1396a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
1397a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1398a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1399a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
1400a36c61f9SKrishna Gudipati 		break;
1401a36c61f9SKrishna Gudipati 
1402a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1403a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1404a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
1405bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_OFFLINE:
1406a36c61f9SKrishna Gudipati 		break;
1407a36c61f9SKrishna Gudipati 
1408a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
140961ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1410a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
141161ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
1412a36c61f9SKrishna Gudipati 		break;
1413a36c61f9SKrishna Gudipati 
1414bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_SCN_ONLINE:
1415bc0e2c2aSKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1416bc0e2c2aSKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1417bc0e2c2aSKrishna Gudipati 		bfa_fcs_rport_send_plogi(rport, NULL);
1418bc0e2c2aSKrishna Gudipati 		break;
1419bc0e2c2aSKrishna Gudipati 
1420a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_SEND:
1421a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1422a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1423a36c61f9SKrishna Gudipati 		rport->plogi_retries = 0;
1424a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogi(rport, NULL);
1425a36c61f9SKrishna Gudipati 		break;
1426a36c61f9SKrishna Gudipati 
1427a36c61f9SKrishna Gudipati 	default:
1428a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1429a36c61f9SKrishna Gudipati 	}
1430a36c61f9SKrishna Gudipati }
1431a36c61f9SKrishna Gudipati 
14325fbe25c7SJing Huang /*
1433a36c61f9SKrishna Gudipati  *	Rport address has changed. Nameserver discovery request is being sent.
1434a36c61f9SKrishna Gudipati  */
1435a36c61f9SKrishna Gudipati static void
1436a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
1437a36c61f9SKrishna Gudipati 	 enum rport_event event)
1438a36c61f9SKrishna Gudipati {
1439a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1440a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1441a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1442a36c61f9SKrishna Gudipati 
1443a36c61f9SKrishna Gudipati 	switch (event) {
1444a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
1445a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sent);
1446a36c61f9SKrishna Gudipati 		break;
1447a36c61f9SKrishna Gudipati 
1448a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
1449a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1450a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1451a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1452a36c61f9SKrishna Gudipati 		break;
1453a36c61f9SKrishna Gudipati 
1454a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
1455a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1456a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1457a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
1458a36c61f9SKrishna Gudipati 		break;
1459a36c61f9SKrishna Gudipati 
1460bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
1461a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1462a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1463a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_SEND:
1464a36c61f9SKrishna Gudipati 		break;
1465a36c61f9SKrishna Gudipati 
1466a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1467a36c61f9SKrishna Gudipati 		rport->ns_retries = 0; /* reset the retry count */
1468a36c61f9SKrishna Gudipati 		break;
1469a36c61f9SKrishna Gudipati 
1470a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
1471a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1472a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1473a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
1474a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
1475a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
1476a36c61f9SKrishna Gudipati 		break;
1477a36c61f9SKrishna Gudipati 
1478a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
147961ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1480a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
148161ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
1482a36c61f9SKrishna Gudipati 		break;
1483a36c61f9SKrishna Gudipati 
1484a36c61f9SKrishna Gudipati 	default:
1485a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1486a36c61f9SKrishna Gudipati 	}
1487a36c61f9SKrishna Gudipati }
1488a36c61f9SKrishna Gudipati 
14895fbe25c7SJing Huang /*
1490a36c61f9SKrishna Gudipati  *		Nameserver discovery failed. Waiting for timeout to retry.
1491a36c61f9SKrishna Gudipati  */
1492a36c61f9SKrishna Gudipati static void
1493a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
1494a36c61f9SKrishna Gudipati 	 enum rport_event event)
1495a36c61f9SKrishna Gudipati {
1496a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1497a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1498a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1499a36c61f9SKrishna Gudipati 
1500a36c61f9SKrishna Gudipati 	switch (event) {
1501a36c61f9SKrishna Gudipati 	case RPSM_EVENT_TIMEOUT:
1502a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1503a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
1504a36c61f9SKrishna Gudipati 		break;
1505a36c61f9SKrishna Gudipati 
1506bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
1507a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1508a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1509a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1510a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
1511a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
1512a36c61f9SKrishna Gudipati 		break;
1513a36c61f9SKrishna Gudipati 
1514a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
1515a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1516a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1517a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1518a36c61f9SKrishna Gudipati 		break;
1519a36c61f9SKrishna Gudipati 
1520a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
1521a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1522a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1523a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
1524a36c61f9SKrishna Gudipati 		break;
1525a36c61f9SKrishna Gudipati 
1526a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
1527a36c61f9SKrishna Gudipati 		rport->pid = 0;
1528a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1529a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1530a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
1531a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
1532a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
1533a36c61f9SKrishna Gudipati 		break;
1534a36c61f9SKrishna Gudipati 
1535a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1536a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
1537a36c61f9SKrishna Gudipati 		break;
1538a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1539a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_prlo_acc(rport);
1540a36c61f9SKrishna Gudipati 		break;
1541a36c61f9SKrishna Gudipati 
1542a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
154361ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1544a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
154561ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
1546a36c61f9SKrishna Gudipati 		break;
1547a36c61f9SKrishna Gudipati 
1548a36c61f9SKrishna Gudipati 	default:
1549a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1550a36c61f9SKrishna Gudipati 	}
1551a36c61f9SKrishna Gudipati }
1552a36c61f9SKrishna Gudipati 
15535fbe25c7SJing Huang /*
1554a36c61f9SKrishna Gudipati  *		Rport address has changed. Nameserver discovery request is sent.
1555a36c61f9SKrishna Gudipati  */
1556a36c61f9SKrishna Gudipati static void
1557a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
1558a36c61f9SKrishna Gudipati 			enum rport_event event)
1559a36c61f9SKrishna Gudipati {
1560a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1561a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1562a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1563a36c61f9SKrishna Gudipati 
1564a36c61f9SKrishna Gudipati 	switch (event) {
1565a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ACCEPTED:
1566a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1567a36c61f9SKrishna Gudipati 		if (rport->pid) {
1568a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1569a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_plogi(rport, NULL);
1570a36c61f9SKrishna Gudipati 		} else {
1571a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
1572a36c61f9SKrishna Gudipati 				 bfa_fcs_rport_sm_nsdisc_sending);
1573a36c61f9SKrishna Gudipati 			rport->ns_retries = 0;
1574a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
1575a36c61f9SKrishna Gudipati 		}
1576a36c61f9SKrishna Gudipati 		break;
1577a36c61f9SKrishna Gudipati 
1578a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FAILED:
1579a36c61f9SKrishna Gudipati 		rport->ns_retries++;
1580a36c61f9SKrishna Gudipati 		if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
1581a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
1582a36c61f9SKrishna Gudipati 				 bfa_fcs_rport_sm_nsdisc_sending);
1583a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
1584a36c61f9SKrishna Gudipati 		} else {
1585ee1a4a42SKrishna Gudipati 			rport->old_pid = rport->pid;
1586a36c61f9SKrishna Gudipati 			rport->pid = 0;
1587a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1588a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
1589a36c61f9SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
1590a36c61f9SKrishna Gudipati 					bfa_fcs_rport_del_timeout);
1591a36c61f9SKrishna Gudipati 		};
1592a36c61f9SKrishna Gudipati 		break;
1593a36c61f9SKrishna Gudipati 
1594a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
1595a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1596a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
1597a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1598a36c61f9SKrishna Gudipati 		break;
1599a36c61f9SKrishna Gudipati 
1600a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
1601a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1602a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
1603a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
1604a36c61f9SKrishna Gudipati 		break;
1605a36c61f9SKrishna Gudipati 
1606a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
1607a36c61f9SKrishna Gudipati 		rport->pid = 0;
1608a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1609a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
1610a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
1611a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
1612a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
1613a36c61f9SKrishna Gudipati 		break;
1614a36c61f9SKrishna Gudipati 
1615a36c61f9SKrishna Gudipati 
1616a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1617a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_prlo_acc(rport);
1618a36c61f9SKrishna Gudipati 		break;
1619bc0e2c2aSKrishna Gudipati 	case RPSM_EVENT_FAB_SCN:
16205fbe25c7SJing Huang 		/*
1621a36c61f9SKrishna Gudipati 		 * ignore, wait for NS query response
1622a36c61f9SKrishna Gudipati 		 */
1623a36c61f9SKrishna Gudipati 		break;
1624a36c61f9SKrishna Gudipati 
1625a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
16265fbe25c7SJing Huang 		/*
1627a36c61f9SKrishna Gudipati 		 * Not logged-in yet. Accept LOGO.
1628a36c61f9SKrishna Gudipati 		 */
1629a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
1630a36c61f9SKrishna Gudipati 		break;
1631a36c61f9SKrishna Gudipati 
1632a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
163361ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_fcs_online);
1634a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
163561ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_online_action(rport);
1636a36c61f9SKrishna Gudipati 		break;
1637a36c61f9SKrishna Gudipati 
1638a36c61f9SKrishna Gudipati 	default:
1639a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1640a36c61f9SKrishna Gudipati 	}
1641a36c61f9SKrishna Gudipati }
1642a36c61f9SKrishna Gudipati 
164361ba4394SKrishna Gudipati /*
164461ba4394SKrishna Gudipati  * Rport needs to be deleted
164561ba4394SKrishna Gudipati  * waiting for ITNIM clean up to finish
164661ba4394SKrishna Gudipati  */
164761ba4394SKrishna Gudipati static void
164861ba4394SKrishna Gudipati bfa_fcs_rport_sm_fc4_off_delete(struct bfa_fcs_rport_s *rport,
164961ba4394SKrishna Gudipati 				enum rport_event event)
165061ba4394SKrishna Gudipati {
165161ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
165261ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
165361ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1654a36c61f9SKrishna Gudipati 
165561ba4394SKrishna Gudipati 	switch (event) {
165661ba4394SKrishna Gudipati 	case RPSM_EVENT_FC4_OFFLINE:
165761ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_delete_pending);
165861ba4394SKrishna Gudipati 		bfa_fcs_rport_hal_offline(rport);
165961ba4394SKrishna Gudipati 		break;
166061ba4394SKrishna Gudipati 
166161ba4394SKrishna Gudipati 	case RPSM_EVENT_DELETE:
166261ba4394SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
166361ba4394SKrishna Gudipati 		/* Ignore these events */
166461ba4394SKrishna Gudipati 		break;
166561ba4394SKrishna Gudipati 
166661ba4394SKrishna Gudipati 	default:
166761ba4394SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
166861ba4394SKrishna Gudipati 		break;
166961ba4394SKrishna Gudipati 	}
167061ba4394SKrishna Gudipati }
167161ba4394SKrishna Gudipati 
167261ba4394SKrishna Gudipati /*
167361ba4394SKrishna Gudipati  * RPort needs to be deleted
167461ba4394SKrishna Gudipati  * waiting for BFA/FW to finish current processing
167561ba4394SKrishna Gudipati  */
167661ba4394SKrishna Gudipati static void
167761ba4394SKrishna Gudipati bfa_fcs_rport_sm_delete_pending(struct bfa_fcs_rport_s *rport,
167861ba4394SKrishna Gudipati 				enum rport_event event)
167961ba4394SKrishna Gudipati {
168061ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
168161ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
168261ba4394SKrishna Gudipati 	bfa_trc(rport->fcs, event);
168361ba4394SKrishna Gudipati 
168461ba4394SKrishna Gudipati 	switch (event) {
168561ba4394SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
168661ba4394SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
168761ba4394SKrishna Gudipati 		bfa_fcs_rport_free(rport);
168861ba4394SKrishna Gudipati 		break;
168961ba4394SKrishna Gudipati 
169061ba4394SKrishna Gudipati 	case RPSM_EVENT_DELETE:
169161ba4394SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
169261ba4394SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
169361ba4394SKrishna Gudipati 		/* Ignore these events */
169461ba4394SKrishna Gudipati 		break;
169561ba4394SKrishna Gudipati 
169661ba4394SKrishna Gudipati 	default:
169761ba4394SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
169861ba4394SKrishna Gudipati 	}
169961ba4394SKrishna Gudipati }
1700a36c61f9SKrishna Gudipati 
17015fbe25c7SJing Huang /*
1702a36c61f9SKrishna Gudipati  *  fcs_rport_private FCS RPORT provate functions
1703a36c61f9SKrishna Gudipati  */
1704a36c61f9SKrishna Gudipati 
1705a36c61f9SKrishna Gudipati static void
1706a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1707a36c61f9SKrishna Gudipati {
1708a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1709a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1710a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1711a36c61f9SKrishna Gudipati 	int		len;
1712a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1713a36c61f9SKrishna Gudipati 
1714a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1715a36c61f9SKrishna Gudipati 
1716c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
1717c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1718a36c61f9SKrishna Gudipati 	if (!fcxp) {
1719a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1720c3f1b123SKrishna Gudipati 				bfa_fcs_rport_send_plogi, rport, BFA_TRUE);
1721a36c61f9SKrishna Gudipati 		return;
1722a36c61f9SKrishna Gudipati 	}
1723a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1724a36c61f9SKrishna Gudipati 
1725a36c61f9SKrishna Gudipati 	len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1726a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0,
1727a36c61f9SKrishna Gudipati 				port->port_cfg.pwwn, port->port_cfg.nwwn,
1728be540a99SKrishna Gudipati 				bfa_fcport_get_maxfrsize(port->fcs->bfa),
1729be540a99SKrishna Gudipati 				bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
1730a36c61f9SKrishna Gudipati 
1731a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1732a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response,
1733a36c61f9SKrishna Gudipati 			(void *)rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1734a36c61f9SKrishna Gudipati 
1735a36c61f9SKrishna Gudipati 	rport->stats.plogis++;
1736a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1737a36c61f9SKrishna Gudipati }
1738a36c61f9SKrishna Gudipati 
1739a36c61f9SKrishna Gudipati static void
1740a36c61f9SKrishna Gudipati bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1741a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
1742a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs)
1743a36c61f9SKrishna Gudipati {
1744a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1745a36c61f9SKrishna Gudipati 	struct fc_logi_s	*plogi_rsp;
1746a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s	*ls_rjt;
1747a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *twin;
1748a36c61f9SKrishna Gudipati 	struct list_head	*qe;
1749a36c61f9SKrishna Gudipati 
1750a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1751a36c61f9SKrishna Gudipati 
1752a36c61f9SKrishna Gudipati 	/*
1753a36c61f9SKrishna Gudipati 	 * Sanity Checks
1754a36c61f9SKrishna Gudipati 	 */
1755a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
1756a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, req_status);
1757a36c61f9SKrishna Gudipati 		rport->stats.plogi_failed++;
1758a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1759a36c61f9SKrishna Gudipati 		return;
1760a36c61f9SKrishna Gudipati 	}
1761a36c61f9SKrishna Gudipati 
1762a36c61f9SKrishna Gudipati 	plogi_rsp = (struct fc_logi_s *) BFA_FCXP_RSP_PLD(fcxp);
1763a36c61f9SKrishna Gudipati 
17645fbe25c7SJing Huang 	/*
1765a36c61f9SKrishna Gudipati 	 * Check for failure first.
1766a36c61f9SKrishna Gudipati 	 */
1767a36c61f9SKrishna Gudipati 	if (plogi_rsp->els_cmd.els_code != FC_ELS_ACC) {
1768a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
1769a36c61f9SKrishna Gudipati 
1770a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, ls_rjt->reason_code);
1771a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1772a36c61f9SKrishna Gudipati 
1773a36c61f9SKrishna Gudipati 		if ((ls_rjt->reason_code == FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD) &&
1774a36c61f9SKrishna Gudipati 		 (ls_rjt->reason_code_expl == FC_LS_RJT_EXP_INSUFF_RES)) {
1775a36c61f9SKrishna Gudipati 			rport->stats.rjt_insuff_res++;
1776a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RETRY);
1777a36c61f9SKrishna Gudipati 			return;
1778a36c61f9SKrishna Gudipati 		}
1779a36c61f9SKrishna Gudipati 
1780a36c61f9SKrishna Gudipati 		rport->stats.plogi_rejects++;
1781a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1782a36c61f9SKrishna Gudipati 		return;
1783a36c61f9SKrishna Gudipati 	}
1784a36c61f9SKrishna Gudipati 
17855fbe25c7SJing Huang 	/*
1786a36c61f9SKrishna Gudipati 	 * PLOGI is complete. Make sure this device is not one of the known
1787a36c61f9SKrishna Gudipati 	 * device with a new FC port address.
1788a36c61f9SKrishna Gudipati 	 */
1789a36c61f9SKrishna Gudipati 	list_for_each(qe, &rport->port->rport_q) {
1790a36c61f9SKrishna Gudipati 		twin = (struct bfa_fcs_rport_s *) qe;
1791a36c61f9SKrishna Gudipati 		if (twin == rport)
1792a36c61f9SKrishna Gudipati 			continue;
1793a36c61f9SKrishna Gudipati 		if (!rport->pwwn && (plogi_rsp->port_name == twin->pwwn)) {
1794a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs, twin->pid);
1795a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs, rport->pid);
1796a36c61f9SKrishna Gudipati 
1797a36c61f9SKrishna Gudipati 			/* Update plogi stats in twin */
1798a36c61f9SKrishna Gudipati 			twin->stats.plogis  += rport->stats.plogis;
1799a36c61f9SKrishna Gudipati 			twin->stats.plogi_rejects  +=
1800a36c61f9SKrishna Gudipati 				 rport->stats.plogi_rejects;
1801a36c61f9SKrishna Gudipati 			twin->stats.plogi_timeouts  +=
1802a36c61f9SKrishna Gudipati 				 rport->stats.plogi_timeouts;
1803a36c61f9SKrishna Gudipati 			twin->stats.plogi_failed +=
1804a36c61f9SKrishna Gudipati 				 rport->stats.plogi_failed;
1805a36c61f9SKrishna Gudipati 			twin->stats.plogi_rcvd	  += rport->stats.plogi_rcvd;
1806a36c61f9SKrishna Gudipati 			twin->stats.plogi_accs++;
1807a36c61f9SKrishna Gudipati 
1808f7f73812SMaggie Zhang 			bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
1809a36c61f9SKrishna Gudipati 
1810a36c61f9SKrishna Gudipati 			bfa_fcs_rport_update(twin, plogi_rsp);
1811a36c61f9SKrishna Gudipati 			twin->pid = rsp_fchs->s_id;
1812a36c61f9SKrishna Gudipati 			bfa_sm_send_event(twin, RPSM_EVENT_PLOGI_COMP);
1813a36c61f9SKrishna Gudipati 			return;
1814a36c61f9SKrishna Gudipati 		}
1815a36c61f9SKrishna Gudipati 	}
1816a36c61f9SKrishna Gudipati 
18175fbe25c7SJing Huang 	/*
1818a36c61f9SKrishna Gudipati 	 * Normal login path -- no evil twins.
1819a36c61f9SKrishna Gudipati 	 */
1820a36c61f9SKrishna Gudipati 	rport->stats.plogi_accs++;
1821a36c61f9SKrishna Gudipati 	bfa_fcs_rport_update(rport, plogi_rsp);
1822a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1823a36c61f9SKrishna Gudipati }
1824a36c61f9SKrishna Gudipati 
1825a36c61f9SKrishna Gudipati static void
1826a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1827a36c61f9SKrishna Gudipati {
1828a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1829a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1830a36c61f9SKrishna Gudipati 	struct fchs_s		fchs;
1831a36c61f9SKrishna Gudipati 	int		len;
1832a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1833a36c61f9SKrishna Gudipati 
1834a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1835a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->reply_oxid);
1836a36c61f9SKrishna Gudipati 
1837c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
1838c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
1839a36c61f9SKrishna Gudipati 	if (!fcxp) {
1840a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1841c3f1b123SKrishna Gudipati 				bfa_fcs_rport_send_plogiacc, rport, BFA_FALSE);
1842a36c61f9SKrishna Gudipati 		return;
1843a36c61f9SKrishna Gudipati 	}
1844a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1845a36c61f9SKrishna Gudipati 
1846a36c61f9SKrishna Gudipati 	len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1847a36c61f9SKrishna Gudipati 				 rport->pid, bfa_fcs_lport_get_fcid(port),
1848a36c61f9SKrishna Gudipati 				 rport->reply_oxid, port->port_cfg.pwwn,
1849a36c61f9SKrishna Gudipati 				 port->port_cfg.nwwn,
1850be540a99SKrishna Gudipati 				 bfa_fcport_get_maxfrsize(port->fcs->bfa),
1851be540a99SKrishna Gudipati 				 bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
1852a36c61f9SKrishna Gudipati 
1853a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1854a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1855a36c61f9SKrishna Gudipati 
1856a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1857a36c61f9SKrishna Gudipati }
1858a36c61f9SKrishna Gudipati 
1859a36c61f9SKrishna Gudipati static void
1860a36c61f9SKrishna Gudipati bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1861a36c61f9SKrishna Gudipati {
1862a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1863a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1864a36c61f9SKrishna Gudipati 	struct fchs_s		fchs;
1865a36c61f9SKrishna Gudipati 	int		len;
1866a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1867a36c61f9SKrishna Gudipati 
1868a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1869a36c61f9SKrishna Gudipati 
1870c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
1871c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1872a36c61f9SKrishna Gudipati 	if (!fcxp) {
1873a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1874c3f1b123SKrishna Gudipati 				bfa_fcs_rport_send_adisc, rport, BFA_TRUE);
1875a36c61f9SKrishna Gudipati 		return;
1876a36c61f9SKrishna Gudipati 	}
1877a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1878a36c61f9SKrishna Gudipati 
1879a36c61f9SKrishna Gudipati 	len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1880a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0,
1881a36c61f9SKrishna Gudipati 				port->port_cfg.pwwn, port->port_cfg.nwwn);
1882a36c61f9SKrishna Gudipati 
1883a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1884a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, bfa_fcs_rport_adisc_response,
1885a36c61f9SKrishna Gudipati 			rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1886a36c61f9SKrishna Gudipati 
1887a36c61f9SKrishna Gudipati 	rport->stats.adisc_sent++;
1888a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1889a36c61f9SKrishna Gudipati }
1890a36c61f9SKrishna Gudipati 
1891a36c61f9SKrishna Gudipati static void
1892a36c61f9SKrishna Gudipati bfa_fcs_rport_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1893a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
1894a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs)
1895a36c61f9SKrishna Gudipati {
1896a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1897a36c61f9SKrishna Gudipati 	void		*pld = bfa_fcxp_get_rspbuf(fcxp);
1898a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s	*ls_rjt;
1899a36c61f9SKrishna Gudipati 
1900a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
1901a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, req_status);
1902a36c61f9SKrishna Gudipati 		rport->stats.adisc_failed++;
1903a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1904a36c61f9SKrishna Gudipati 		return;
1905a36c61f9SKrishna Gudipati 	}
1906a36c61f9SKrishna Gudipati 
1907a36c61f9SKrishna Gudipati 	if (fc_adisc_rsp_parse((struct fc_adisc_s *)pld, rsp_len, rport->pwwn,
1908a36c61f9SKrishna Gudipati 				rport->nwwn)  == FC_PARSE_OK) {
1909a36c61f9SKrishna Gudipati 		rport->stats.adisc_accs++;
1910a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1911a36c61f9SKrishna Gudipati 		return;
1912a36c61f9SKrishna Gudipati 	}
1913a36c61f9SKrishna Gudipati 
1914a36c61f9SKrishna Gudipati 	rport->stats.adisc_rejects++;
1915a36c61f9SKrishna Gudipati 	ls_rjt = pld;
1916a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, ls_rjt->els_cmd.els_code);
1917a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, ls_rjt->reason_code);
1918a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1919a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1920a36c61f9SKrishna Gudipati }
1921a36c61f9SKrishna Gudipati 
1922a36c61f9SKrishna Gudipati static void
1923a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1924a36c61f9SKrishna Gudipati {
1925a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1926a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1927a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1928a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1929a36c61f9SKrishna Gudipati 	int		len;
1930a36c61f9SKrishna Gudipati 	bfa_cb_fcxp_send_t cbfn;
1931a36c61f9SKrishna Gudipati 
1932a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1933a36c61f9SKrishna Gudipati 
1934c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
1935c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
1936a36c61f9SKrishna Gudipati 	if (!fcxp) {
1937a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1938c3f1b123SKrishna Gudipati 				bfa_fcs_rport_send_nsdisc, rport, BFA_TRUE);
1939a36c61f9SKrishna Gudipati 		return;
1940a36c61f9SKrishna Gudipati 	}
1941a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1942a36c61f9SKrishna Gudipati 
1943a36c61f9SKrishna Gudipati 	if (rport->pwwn) {
1944a36c61f9SKrishna Gudipati 		len = fc_gidpn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1945a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0, rport->pwwn);
1946a36c61f9SKrishna Gudipati 		cbfn = bfa_fcs_rport_gidpn_response;
1947a36c61f9SKrishna Gudipati 	} else {
1948a36c61f9SKrishna Gudipati 		len = fc_gpnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1949a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0, rport->pid);
1950a36c61f9SKrishna Gudipati 		cbfn = bfa_fcs_rport_gpnid_response;
1951a36c61f9SKrishna Gudipati 	}
1952a36c61f9SKrishna Gudipati 
1953a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1954a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, cbfn,
1955a36c61f9SKrishna Gudipati 			(void *)rport, FC_MAX_PDUSZ, FC_FCCT_TOV);
1956a36c61f9SKrishna Gudipati 
1957a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1958a36c61f9SKrishna Gudipati }
1959a36c61f9SKrishna Gudipati 
1960a36c61f9SKrishna Gudipati static void
1961a36c61f9SKrishna Gudipati bfa_fcs_rport_gidpn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1962a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
1963a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs)
1964a36c61f9SKrishna Gudipati {
1965a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1966a36c61f9SKrishna Gudipati 	struct ct_hdr_s	*cthdr;
1967a36c61f9SKrishna Gudipati 	struct fcgs_gidpn_resp_s	*gidpn_rsp;
1968a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s	*twin;
1969a36c61f9SKrishna Gudipati 	struct list_head	*qe;
1970a36c61f9SKrishna Gudipati 
1971a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1972a36c61f9SKrishna Gudipati 
1973a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1974ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
1975a36c61f9SKrishna Gudipati 
1976a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1977a36c61f9SKrishna Gudipati 		/* Check if the pid is the same as before. */
1978a36c61f9SKrishna Gudipati 		gidpn_rsp = (struct fcgs_gidpn_resp_s *) (cthdr + 1);
1979a36c61f9SKrishna Gudipati 
1980a36c61f9SKrishna Gudipati 		if (gidpn_rsp->dap == rport->pid) {
1981a36c61f9SKrishna Gudipati 			/* Device is online  */
1982a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1983a36c61f9SKrishna Gudipati 		} else {
1984a36c61f9SKrishna Gudipati 			/*
1985a36c61f9SKrishna Gudipati 			 * Device's PID has changed. We need to cleanup
1986a36c61f9SKrishna Gudipati 			 * and re-login. If there is another device with
1987a36c61f9SKrishna Gudipati 			 * the the newly discovered pid, send an scn notice
1988a36c61f9SKrishna Gudipati 			 * so that its new pid can be discovered.
1989a36c61f9SKrishna Gudipati 			 */
1990a36c61f9SKrishna Gudipati 			list_for_each(qe, &rport->port->rport_q) {
1991a36c61f9SKrishna Gudipati 				twin = (struct bfa_fcs_rport_s *) qe;
1992a36c61f9SKrishna Gudipati 				if (twin == rport)
1993a36c61f9SKrishna Gudipati 					continue;
1994a36c61f9SKrishna Gudipati 				if (gidpn_rsp->dap == twin->pid) {
1995a36c61f9SKrishna Gudipati 					bfa_trc(rport->fcs, twin->pid);
1996a36c61f9SKrishna Gudipati 					bfa_trc(rport->fcs, rport->pid);
1997a36c61f9SKrishna Gudipati 
1998a36c61f9SKrishna Gudipati 					twin->pid = 0;
1999a36c61f9SKrishna Gudipati 					bfa_sm_send_event(twin,
2000a36c61f9SKrishna Gudipati 					 RPSM_EVENT_ADDRESS_CHANGE);
2001a36c61f9SKrishna Gudipati 				}
2002a36c61f9SKrishna Gudipati 			}
2003a36c61f9SKrishna Gudipati 			rport->pid = gidpn_rsp->dap;
2004a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_CHANGE);
2005a36c61f9SKrishna Gudipati 		}
2006a36c61f9SKrishna Gudipati 		return;
2007a36c61f9SKrishna Gudipati 	}
2008a36c61f9SKrishna Gudipati 
2009a36c61f9SKrishna Gudipati 	/*
2010a36c61f9SKrishna Gudipati 	 * Reject Response
2011a36c61f9SKrishna Gudipati 	 */
2012a36c61f9SKrishna Gudipati 	switch (cthdr->reason_code) {
2013a36c61f9SKrishna Gudipati 	case CT_RSN_LOGICAL_BUSY:
2014a36c61f9SKrishna Gudipati 		/*
2015a36c61f9SKrishna Gudipati 		 * Need to retry
2016a36c61f9SKrishna Gudipati 		 */
2017a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
2018a36c61f9SKrishna Gudipati 		break;
2019a36c61f9SKrishna Gudipati 
2020a36c61f9SKrishna Gudipati 	case CT_RSN_UNABLE_TO_PERF:
2021a36c61f9SKrishna Gudipati 		/*
2022a36c61f9SKrishna Gudipati 		 * device doesn't exist : Start timer to cleanup this later.
2023a36c61f9SKrishna Gudipati 		 */
2024a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
2025a36c61f9SKrishna Gudipati 		break;
2026a36c61f9SKrishna Gudipati 
2027a36c61f9SKrishna Gudipati 	default:
2028a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
2029a36c61f9SKrishna Gudipati 		break;
2030a36c61f9SKrishna Gudipati 	}
2031a36c61f9SKrishna Gudipati }
2032a36c61f9SKrishna Gudipati 
2033a36c61f9SKrishna Gudipati static void
2034a36c61f9SKrishna Gudipati bfa_fcs_rport_gpnid_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
2035a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
2036a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs)
2037a36c61f9SKrishna Gudipati {
2038a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2039a36c61f9SKrishna Gudipati 	struct ct_hdr_s	*cthdr;
2040a36c61f9SKrishna Gudipati 
2041a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2042a36c61f9SKrishna Gudipati 
2043a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
2044ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
2045a36c61f9SKrishna Gudipati 
2046a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
2047a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
2048a36c61f9SKrishna Gudipati 		return;
2049a36c61f9SKrishna Gudipati 	}
2050a36c61f9SKrishna Gudipati 
2051a36c61f9SKrishna Gudipati 	/*
2052a36c61f9SKrishna Gudipati 	 * Reject Response
2053a36c61f9SKrishna Gudipati 	 */
2054a36c61f9SKrishna Gudipati 	switch (cthdr->reason_code) {
2055a36c61f9SKrishna Gudipati 	case CT_RSN_LOGICAL_BUSY:
2056a36c61f9SKrishna Gudipati 		/*
2057a36c61f9SKrishna Gudipati 		 * Need to retry
2058a36c61f9SKrishna Gudipati 		 */
2059a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
2060a36c61f9SKrishna Gudipati 		break;
2061a36c61f9SKrishna Gudipati 
2062a36c61f9SKrishna Gudipati 	case CT_RSN_UNABLE_TO_PERF:
2063a36c61f9SKrishna Gudipati 		/*
2064a36c61f9SKrishna Gudipati 		 * device doesn't exist : Start timer to cleanup this later.
2065a36c61f9SKrishna Gudipati 		 */
2066a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
2067a36c61f9SKrishna Gudipati 		break;
2068a36c61f9SKrishna Gudipati 
2069a36c61f9SKrishna Gudipati 	default:
2070a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
2071a36c61f9SKrishna Gudipati 		break;
2072a36c61f9SKrishna Gudipati 	}
2073a36c61f9SKrishna Gudipati }
2074a36c61f9SKrishna Gudipati 
20755fbe25c7SJing Huang /*
2076a36c61f9SKrishna Gudipati  *	Called to send a logout to the rport.
2077a36c61f9SKrishna Gudipati  */
2078a36c61f9SKrishna Gudipati static void
2079a36c61f9SKrishna Gudipati bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2080a36c61f9SKrishna Gudipati {
2081a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
2082a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port;
2083a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2084a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2085a36c61f9SKrishna Gudipati 	u16	len;
2086a36c61f9SKrishna Gudipati 
2087a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2088a36c61f9SKrishna Gudipati 
2089a36c61f9SKrishna Gudipati 	port = rport->port;
2090a36c61f9SKrishna Gudipati 
2091c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
2092c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2093a36c61f9SKrishna Gudipati 	if (!fcxp) {
2094a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
2095c3f1b123SKrishna Gudipati 				bfa_fcs_rport_send_logo, rport, BFA_FALSE);
2096a36c61f9SKrishna Gudipati 		return;
2097a36c61f9SKrishna Gudipati 	}
2098a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
2099a36c61f9SKrishna Gudipati 
2100a36c61f9SKrishna Gudipati 	len = fc_logo_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
2101a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0,
2102a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_pwwn(port));
2103a36c61f9SKrishna Gudipati 
2104a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2105a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL,
2106a36c61f9SKrishna Gudipati 			rport, FC_MAX_PDUSZ, FC_ELS_TOV);
2107a36c61f9SKrishna Gudipati 
2108a36c61f9SKrishna Gudipati 	rport->stats.logos++;
2109a36c61f9SKrishna Gudipati 	bfa_fcxp_discard(rport->fcxp);
2110a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
2111a36c61f9SKrishna Gudipati }
2112a36c61f9SKrishna Gudipati 
21135fbe25c7SJing Huang /*
2114a36c61f9SKrishna Gudipati  *	Send ACC for a LOGO received.
2115a36c61f9SKrishna Gudipati  */
2116a36c61f9SKrishna Gudipati static void
2117a36c61f9SKrishna Gudipati bfa_fcs_rport_send_logo_acc(void *rport_cbarg)
2118a36c61f9SKrishna Gudipati {
2119a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
2120a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port;
2121a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2122a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2123a36c61f9SKrishna Gudipati 	u16	len;
2124a36c61f9SKrishna Gudipati 
2125a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2126a36c61f9SKrishna Gudipati 
2127a36c61f9SKrishna Gudipati 	port = rport->port;
2128a36c61f9SKrishna Gudipati 
2129c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2130a36c61f9SKrishna Gudipati 	if (!fcxp)
2131a36c61f9SKrishna Gudipati 		return;
2132a36c61f9SKrishna Gudipati 
2133a36c61f9SKrishna Gudipati 	rport->stats.logo_rcvd++;
2134a36c61f9SKrishna Gudipati 	len = fc_logo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2135a36c61f9SKrishna Gudipati 				rport->pid, bfa_fcs_lport_get_fcid(port),
2136a36c61f9SKrishna Gudipati 				rport->reply_oxid);
2137a36c61f9SKrishna Gudipati 
2138a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2139a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
2140a36c61f9SKrishna Gudipati }
2141a36c61f9SKrishna Gudipati 
21425fbe25c7SJing Huang /*
2143a36c61f9SKrishna Gudipati  *	brief
2144a36c61f9SKrishna Gudipati  *	This routine will be called by bfa_timer on timer timeouts.
2145a36c61f9SKrishna Gudipati  *
2146a36c61f9SKrishna Gudipati  *	param[in]	rport			- pointer to bfa_fcs_lport_ns_t.
2147a36c61f9SKrishna Gudipati  *	param[out]	rport_status	- pointer to return vport status in
2148a36c61f9SKrishna Gudipati  *
2149a36c61f9SKrishna Gudipati  *	return
2150a36c61f9SKrishna Gudipati  *		void
2151a36c61f9SKrishna Gudipati  *
2152a36c61f9SKrishna Gudipati  *	Special Considerations:
2153a36c61f9SKrishna Gudipati  *
2154a36c61f9SKrishna Gudipati  *	note
2155a36c61f9SKrishna Gudipati  */
2156a36c61f9SKrishna Gudipati static void
2157a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout(void *arg)
2158a36c61f9SKrishna Gudipati {
2159a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) arg;
2160a36c61f9SKrishna Gudipati 
2161a36c61f9SKrishna Gudipati 	rport->stats.plogi_timeouts++;
2162a36c61f9SKrishna Gudipati 	bfa_stats(rport->port, rport_plogi_timeouts);
2163a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
2164a36c61f9SKrishna Gudipati }
2165a36c61f9SKrishna Gudipati 
2166a36c61f9SKrishna Gudipati static void
2167a36c61f9SKrishna Gudipati bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
2168a36c61f9SKrishna Gudipati 			struct fchs_s *rx_fchs, u16 len)
2169a36c61f9SKrishna Gudipati {
2170a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2171a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2172a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2173a36c61f9SKrishna Gudipati 	struct fc_prli_s	*prli;
2174a36c61f9SKrishna Gudipati 
2175a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
2176a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
2177a36c61f9SKrishna Gudipati 
2178a36c61f9SKrishna Gudipati 	rport->stats.prli_rcvd++;
2179a36c61f9SKrishna Gudipati 
2180a36c61f9SKrishna Gudipati 	/*
2181a36c61f9SKrishna Gudipati 	 * We are in Initiator Mode
2182a36c61f9SKrishna Gudipati 	 */
2183a36c61f9SKrishna Gudipati 	prli = (struct fc_prli_s *) (rx_fchs + 1);
2184a36c61f9SKrishna Gudipati 
2185a36c61f9SKrishna Gudipati 	if (prli->parampage.servparams.target) {
2186a36c61f9SKrishna Gudipati 		/*
2187a36c61f9SKrishna Gudipati 		 * PRLI from a target ?
2188a36c61f9SKrishna Gudipati 		 * Send the Acc.
2189a36c61f9SKrishna Gudipati 		 * PRLI sent by us will be used to transition the IT nexus,
2190a36c61f9SKrishna Gudipati 		 * once the response is received from the target.
2191a36c61f9SKrishna Gudipati 		 */
2192a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, rx_fchs->s_id);
2193a36c61f9SKrishna Gudipati 		rport->scsi_function = BFA_RPORT_TARGET;
2194a36c61f9SKrishna Gudipati 	} else {
2195a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, prli->parampage.type);
2196a36c61f9SKrishna Gudipati 		rport->scsi_function = BFA_RPORT_INITIATOR;
2197a36c61f9SKrishna Gudipati 		bfa_fcs_itnim_is_initiator(rport->itnim);
2198a36c61f9SKrishna Gudipati 	}
2199a36c61f9SKrishna Gudipati 
2200c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2201a36c61f9SKrishna Gudipati 	if (!fcxp)
2202a36c61f9SKrishna Gudipati 		return;
2203a36c61f9SKrishna Gudipati 
2204a36c61f9SKrishna Gudipati 	len = fc_prli_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2205a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2206a36c61f9SKrishna Gudipati 				rx_fchs->ox_id, port->port_cfg.roles);
2207a36c61f9SKrishna Gudipati 
2208a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2209a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
2210a36c61f9SKrishna Gudipati }
2211a36c61f9SKrishna Gudipati 
2212a36c61f9SKrishna Gudipati static void
2213a36c61f9SKrishna Gudipati bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport,
2214a36c61f9SKrishna Gudipati 			struct fchs_s *rx_fchs, u16 len)
2215a36c61f9SKrishna Gudipati {
2216a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2217a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2218a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2219a36c61f9SKrishna Gudipati 	struct fc_rpsc_speed_info_s speeds;
2220a36c61f9SKrishna Gudipati 	struct bfa_port_attr_s pport_attr;
2221a36c61f9SKrishna Gudipati 
2222a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
2223a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
2224a36c61f9SKrishna Gudipati 
2225a36c61f9SKrishna Gudipati 	rport->stats.rpsc_rcvd++;
2226a36c61f9SKrishna Gudipati 	speeds.port_speed_cap =
2227a36c61f9SKrishna Gudipati 		RPSC_SPEED_CAP_1G | RPSC_SPEED_CAP_2G | RPSC_SPEED_CAP_4G |
2228a36c61f9SKrishna Gudipati 		RPSC_SPEED_CAP_8G;
2229a36c61f9SKrishna Gudipati 
2230a36c61f9SKrishna Gudipati 	/*
2231a36c61f9SKrishna Gudipati 	 * get curent speed from pport attributes from BFA
2232a36c61f9SKrishna Gudipati 	 */
2233a36c61f9SKrishna Gudipati 	bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
2234a36c61f9SKrishna Gudipati 
2235a36c61f9SKrishna Gudipati 	speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
2236a36c61f9SKrishna Gudipati 
2237c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2238a36c61f9SKrishna Gudipati 	if (!fcxp)
2239a36c61f9SKrishna Gudipati 		return;
2240a36c61f9SKrishna Gudipati 
2241a36c61f9SKrishna Gudipati 	len = fc_rpsc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2242a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2243a36c61f9SKrishna Gudipati 				rx_fchs->ox_id, &speeds);
2244a36c61f9SKrishna Gudipati 
2245a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2246a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
2247a36c61f9SKrishna Gudipati }
2248a36c61f9SKrishna Gudipati 
2249a36c61f9SKrishna Gudipati static void
2250a36c61f9SKrishna Gudipati bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
2251a36c61f9SKrishna Gudipati 			struct fchs_s *rx_fchs, u16 len)
2252a36c61f9SKrishna Gudipati {
2253a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2254a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2255a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2256a36c61f9SKrishna Gudipati 	struct fc_adisc_s	*adisc;
2257a36c61f9SKrishna Gudipati 
2258a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
2259a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
2260a36c61f9SKrishna Gudipati 
2261a36c61f9SKrishna Gudipati 	rport->stats.adisc_rcvd++;
2262a36c61f9SKrishna Gudipati 
2263a36c61f9SKrishna Gudipati 	adisc = (struct fc_adisc_s *) (rx_fchs + 1);
2264a36c61f9SKrishna Gudipati 
2265a36c61f9SKrishna Gudipati 	/*
2266a36c61f9SKrishna Gudipati 	 * Accept if the itnim for this rport is online.
2267a36c61f9SKrishna Gudipati 	 * Else reject the ADISC.
2268a36c61f9SKrishna Gudipati 	 */
2269a36c61f9SKrishna Gudipati 	if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) {
2270a36c61f9SKrishna Gudipati 
2271c3f1b123SKrishna Gudipati 		fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2272a36c61f9SKrishna Gudipati 		if (!fcxp)
2273a36c61f9SKrishna Gudipati 			return;
2274a36c61f9SKrishna Gudipati 
2275a36c61f9SKrishna Gudipati 		len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2276a36c61f9SKrishna Gudipati 			 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2277a36c61f9SKrishna Gudipati 			 rx_fchs->ox_id, port->port_cfg.pwwn,
2278a36c61f9SKrishna Gudipati 			 port->port_cfg.nwwn);
2279a36c61f9SKrishna Gudipati 
2280a36c61f9SKrishna Gudipati 		bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
2281a36c61f9SKrishna Gudipati 				BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
2282a36c61f9SKrishna Gudipati 				FC_MAX_PDUSZ, 0);
2283a36c61f9SKrishna Gudipati 	} else {
2284a36c61f9SKrishna Gudipati 		rport->stats.adisc_rejected++;
2285a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_ls_rjt(rport, rx_fchs,
2286a36c61f9SKrishna Gudipati 					  FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD,
2287a36c61f9SKrishna Gudipati 					  FC_LS_RJT_EXP_LOGIN_REQUIRED);
2288a36c61f9SKrishna Gudipati 	}
2289a36c61f9SKrishna Gudipati }
2290a36c61f9SKrishna Gudipati 
2291a36c61f9SKrishna Gudipati static void
2292a36c61f9SKrishna Gudipati bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport)
2293a36c61f9SKrishna Gudipati {
2294a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2295a36c61f9SKrishna Gudipati 	struct bfa_rport_info_s rport_info;
2296a36c61f9SKrishna Gudipati 
2297a36c61f9SKrishna Gudipati 	rport_info.pid = rport->pid;
2298a36c61f9SKrishna Gudipati 	rport_info.local_pid = port->pid;
2299a36c61f9SKrishna Gudipati 	rport_info.lp_tag = port->lp_tag;
2300a36c61f9SKrishna Gudipati 	rport_info.vf_id = port->fabric->vf_id;
2301a36c61f9SKrishna Gudipati 	rport_info.vf_en = port->fabric->is_vf;
2302a36c61f9SKrishna Gudipati 	rport_info.fc_class = rport->fc_cos;
2303a36c61f9SKrishna Gudipati 	rport_info.cisc = rport->cisc;
2304a36c61f9SKrishna Gudipati 	rport_info.max_frmsz = rport->maxfrsize;
2305a36c61f9SKrishna Gudipati 	bfa_rport_online(rport->bfa_rport, &rport_info);
2306a36c61f9SKrishna Gudipati }
2307a36c61f9SKrishna Gudipati 
230861ba4394SKrishna Gudipati static void
230961ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline(struct bfa_fcs_rport_s *rport)
231061ba4394SKrishna Gudipati {
231161ba4394SKrishna Gudipati 	if (rport->bfa_rport)
231261ba4394SKrishna Gudipati 		bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
231361ba4394SKrishna Gudipati 	else
231461ba4394SKrishna Gudipati 		bfa_cb_rport_offline(rport);
231561ba4394SKrishna Gudipati }
231661ba4394SKrishna Gudipati 
2317a36c61f9SKrishna Gudipati static struct bfa_fcs_rport_s *
2318a36c61f9SKrishna Gudipati bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
2319a36c61f9SKrishna Gudipati {
2320a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs = port->fcs;
2321a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2322a36c61f9SKrishna Gudipati 	struct bfad_rport_s	*rport_drv;
2323a36c61f9SKrishna Gudipati 
23245fbe25c7SJing Huang 	/*
2325a36c61f9SKrishna Gudipati 	 * allocate rport
2326a36c61f9SKrishna Gudipati 	 */
232761ba4394SKrishna Gudipati 	if (fcs->num_rport_logins >= bfa_fcs_rport_max_logins) {
232861ba4394SKrishna Gudipati 		bfa_trc(fcs, rpid);
232961ba4394SKrishna Gudipati 		return NULL;
233061ba4394SKrishna Gudipati 	}
233161ba4394SKrishna Gudipati 
2332a36c61f9SKrishna Gudipati 	if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv)
2333a36c61f9SKrishna Gudipati 		!= BFA_STATUS_OK) {
2334a36c61f9SKrishna Gudipati 		bfa_trc(fcs, rpid);
2335a36c61f9SKrishna Gudipati 		return NULL;
2336a36c61f9SKrishna Gudipati 	}
2337a36c61f9SKrishna Gudipati 
2338a36c61f9SKrishna Gudipati 	/*
2339a36c61f9SKrishna Gudipati 	 * Initialize r-port
2340a36c61f9SKrishna Gudipati 	 */
2341a36c61f9SKrishna Gudipati 	rport->port = port;
2342a36c61f9SKrishna Gudipati 	rport->fcs = fcs;
2343a36c61f9SKrishna Gudipati 	rport->rp_drv = rport_drv;
2344a36c61f9SKrishna Gudipati 	rport->pid = rpid;
2345a36c61f9SKrishna Gudipati 	rport->pwwn = pwwn;
2346ee1a4a42SKrishna Gudipati 	rport->old_pid = 0;
2347a36c61f9SKrishna Gudipati 
234861ba4394SKrishna Gudipati 	rport->bfa_rport = NULL;
2349a36c61f9SKrishna Gudipati 
23505fbe25c7SJing Huang 	/*
2351a36c61f9SKrishna Gudipati 	 * allocate FC-4s
2352a36c61f9SKrishna Gudipati 	 */
2353d4b671c5SJing Huang 	WARN_ON(!bfa_fcs_lport_is_initiator(port));
2354a36c61f9SKrishna Gudipati 
2355a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_is_initiator(port)) {
2356a36c61f9SKrishna Gudipati 		rport->itnim = bfa_fcs_itnim_create(rport);
2357a36c61f9SKrishna Gudipati 		if (!rport->itnim) {
2358a36c61f9SKrishna Gudipati 			bfa_trc(fcs, rpid);
2359a36c61f9SKrishna Gudipati 			kfree(rport_drv);
2360a36c61f9SKrishna Gudipati 			return NULL;
2361a36c61f9SKrishna Gudipati 		}
2362a36c61f9SKrishna Gudipati 	}
2363a36c61f9SKrishna Gudipati 
2364a36c61f9SKrishna Gudipati 	bfa_fcs_lport_add_rport(port, rport);
236561ba4394SKrishna Gudipati 	fcs->num_rport_logins++;
2366a36c61f9SKrishna Gudipati 
2367a36c61f9SKrishna Gudipati 	bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
2368a36c61f9SKrishna Gudipati 
2369a36c61f9SKrishna Gudipati 	/* Initialize the Rport Features(RPF) Sub Module  */
2370a36c61f9SKrishna Gudipati 	if (!BFA_FCS_PID_IS_WKA(rport->pid))
2371a36c61f9SKrishna Gudipati 		bfa_fcs_rpf_init(rport);
2372a36c61f9SKrishna Gudipati 
2373a36c61f9SKrishna Gudipati 	return rport;
2374a36c61f9SKrishna Gudipati }
2375a36c61f9SKrishna Gudipati 
2376a36c61f9SKrishna Gudipati 
2377a36c61f9SKrishna Gudipati static void
2378a36c61f9SKrishna Gudipati bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
2379a36c61f9SKrishna Gudipati {
2380a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
238161ba4394SKrishna Gudipati 	struct bfa_fcs_s *fcs = port->fcs;
2382a36c61f9SKrishna Gudipati 
23835fbe25c7SJing Huang 	/*
2384a36c61f9SKrishna Gudipati 	 * - delete FC-4s
2385a36c61f9SKrishna Gudipati 	 * - delete BFA rport
2386a36c61f9SKrishna Gudipati 	 * - remove from queue of rports
2387a36c61f9SKrishna Gudipati 	 */
238861ba4394SKrishna Gudipati 	rport->plogi_pending = BFA_FALSE;
238961ba4394SKrishna Gudipati 
2390a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_is_initiator(port)) {
2391a36c61f9SKrishna Gudipati 		bfa_fcs_itnim_delete(rport->itnim);
2392a36c61f9SKrishna Gudipati 		if (rport->pid != 0 && !BFA_FCS_PID_IS_WKA(rport->pid))
2393a36c61f9SKrishna Gudipati 			bfa_fcs_rpf_rport_offline(rport);
2394a36c61f9SKrishna Gudipati 	}
2395a36c61f9SKrishna Gudipati 
239661ba4394SKrishna Gudipati 	if (rport->bfa_rport) {
2397f7f73812SMaggie Zhang 		bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_DELETE);
239861ba4394SKrishna Gudipati 		rport->bfa_rport = NULL;
239961ba4394SKrishna Gudipati 	}
240061ba4394SKrishna Gudipati 
2401a36c61f9SKrishna Gudipati 	bfa_fcs_lport_del_rport(port, rport);
240261ba4394SKrishna Gudipati 	fcs->num_rport_logins--;
2403a36c61f9SKrishna Gudipati 	kfree(rport->rp_drv);
2404a36c61f9SKrishna Gudipati }
2405a36c61f9SKrishna Gudipati 
2406a36c61f9SKrishna Gudipati static void
24077826f304SKrishna Gudipati bfa_fcs_rport_aen_post(struct bfa_fcs_rport_s *rport,
24087826f304SKrishna Gudipati 			enum bfa_rport_aen_event event,
24097826f304SKrishna Gudipati 			struct bfa_rport_aen_data_s *data)
24107826f304SKrishna Gudipati {
24117826f304SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
24127826f304SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
24137826f304SKrishna Gudipati 	struct bfa_aen_entry_s  *aen_entry;
24147826f304SKrishna Gudipati 
24157826f304SKrishna Gudipati 	bfad_get_aen_entry(bfad, aen_entry);
24167826f304SKrishna Gudipati 	if (!aen_entry)
24177826f304SKrishna Gudipati 		return;
24187826f304SKrishna Gudipati 
24197826f304SKrishna Gudipati 	if (event == BFA_RPORT_AEN_QOS_PRIO)
24207826f304SKrishna Gudipati 		aen_entry->aen_data.rport.priv.qos = data->priv.qos;
24217826f304SKrishna Gudipati 	else if (event == BFA_RPORT_AEN_QOS_FLOWID)
24227826f304SKrishna Gudipati 		aen_entry->aen_data.rport.priv.qos = data->priv.qos;
24237826f304SKrishna Gudipati 
24247826f304SKrishna Gudipati 	aen_entry->aen_data.rport.vf_id = rport->port->fabric->vf_id;
24257826f304SKrishna Gudipati 	aen_entry->aen_data.rport.ppwwn = bfa_fcs_lport_get_pwwn(
24267826f304SKrishna Gudipati 					bfa_fcs_get_base_port(rport->fcs));
24277826f304SKrishna Gudipati 	aen_entry->aen_data.rport.lpwwn = bfa_fcs_lport_get_pwwn(rport->port);
24287826f304SKrishna Gudipati 	aen_entry->aen_data.rport.rpwwn = rport->pwwn;
24297826f304SKrishna Gudipati 
24307826f304SKrishna Gudipati 	/* Send the AEN notification */
24317826f304SKrishna Gudipati 	bfad_im_post_vendor_event(aen_entry, bfad, ++rport->fcs->fcs_aen_seq,
24327826f304SKrishna Gudipati 				  BFA_AEN_CAT_RPORT, event);
24337826f304SKrishna Gudipati }
24347826f304SKrishna Gudipati 
24357826f304SKrishna Gudipati static void
243661ba4394SKrishna Gudipati bfa_fcs_rport_fcs_online_action(struct bfa_fcs_rport_s *rport)
243761ba4394SKrishna Gudipati {
243861ba4394SKrishna Gudipati 	if ((!rport->pid) || (!rport->pwwn)) {
243961ba4394SKrishna Gudipati 		bfa_trc(rport->fcs, rport->pid);
244061ba4394SKrishna Gudipati 		bfa_sm_fault(rport->fcs, rport->pid);
244161ba4394SKrishna Gudipati 	}
244261ba4394SKrishna Gudipati 
244361ba4394SKrishna Gudipati 	bfa_sm_send_event(rport->itnim, BFA_FCS_ITNIM_SM_FCS_ONLINE);
244461ba4394SKrishna Gudipati }
244561ba4394SKrishna Gudipati 
244661ba4394SKrishna Gudipati static void
244761ba4394SKrishna Gudipati bfa_fcs_rport_hal_online_action(struct bfa_fcs_rport_s *rport)
2448a36c61f9SKrishna Gudipati {
2449a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2450a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2451a36c61f9SKrishna Gudipati 	char	lpwwn_buf[BFA_STRING_32];
2452a36c61f9SKrishna Gudipati 	char	rpwwn_buf[BFA_STRING_32];
2453a36c61f9SKrishna Gudipati 
2454a36c61f9SKrishna Gudipati 	rport->stats.onlines++;
2455a36c61f9SKrishna Gudipati 
2456d7be54ccSKrishna Gudipati 	if ((!rport->pid) || (!rport->pwwn)) {
2457d7be54ccSKrishna Gudipati 		bfa_trc(rport->fcs, rport->pid);
2458d7be54ccSKrishna Gudipati 		bfa_sm_fault(rport->fcs, rport->pid);
2459d7be54ccSKrishna Gudipati 	}
2460d7be54ccSKrishna Gudipati 
2461a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_is_initiator(port)) {
246261ba4394SKrishna Gudipati 		bfa_fcs_itnim_brp_online(rport->itnim);
2463a36c61f9SKrishna Gudipati 		if (!BFA_FCS_PID_IS_WKA(rport->pid))
2464a36c61f9SKrishna Gudipati 			bfa_fcs_rpf_rport_online(rport);
2465a36c61f9SKrishna Gudipati 	};
2466a36c61f9SKrishna Gudipati 
2467a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2468a36c61f9SKrishna Gudipati 	wwn2str(rpwwn_buf, rport->pwwn);
24697826f304SKrishna Gudipati 	if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
247088166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2471a36c61f9SKrishna Gudipati 		"Remote port (WWN = %s) online for logical port (WWN = %s)\n",
2472a36c61f9SKrishna Gudipati 		rpwwn_buf, lpwwn_buf);
24737826f304SKrishna Gudipati 		bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_ONLINE, NULL);
24747826f304SKrishna Gudipati 	}
2475a36c61f9SKrishna Gudipati }
2476a36c61f9SKrishna Gudipati 
2477a36c61f9SKrishna Gudipati static void
247861ba4394SKrishna Gudipati bfa_fcs_rport_fcs_offline_action(struct bfa_fcs_rport_s *rport)
247961ba4394SKrishna Gudipati {
248061ba4394SKrishna Gudipati 	if (!BFA_FCS_PID_IS_WKA(rport->pid))
248161ba4394SKrishna Gudipati 		bfa_fcs_rpf_rport_offline(rport);
248261ba4394SKrishna Gudipati 
248361ba4394SKrishna Gudipati 	bfa_fcs_itnim_rport_offline(rport->itnim);
248461ba4394SKrishna Gudipati }
248561ba4394SKrishna Gudipati 
248661ba4394SKrishna Gudipati static void
248761ba4394SKrishna Gudipati bfa_fcs_rport_hal_offline_action(struct bfa_fcs_rport_s *rport)
2488a36c61f9SKrishna Gudipati {
2489a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2490a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2491a36c61f9SKrishna Gudipati 	char	lpwwn_buf[BFA_STRING_32];
2492a36c61f9SKrishna Gudipati 	char	rpwwn_buf[BFA_STRING_32];
2493a36c61f9SKrishna Gudipati 
249461ba4394SKrishna Gudipati 	if (!rport->bfa_rport) {
249561ba4394SKrishna Gudipati 		bfa_fcs_rport_fcs_offline_action(rport);
249661ba4394SKrishna Gudipati 		return;
249761ba4394SKrishna Gudipati 	}
249861ba4394SKrishna Gudipati 
2499a36c61f9SKrishna Gudipati 	rport->stats.offlines++;
2500a36c61f9SKrishna Gudipati 
2501a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2502a36c61f9SKrishna Gudipati 	wwn2str(rpwwn_buf, rport->pwwn);
2503a36c61f9SKrishna Gudipati 	if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
25047826f304SKrishna Gudipati 		if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE) {
250588166242SJing Huang 			BFA_LOG(KERN_ERR, bfad, bfa_log_level,
2506a36c61f9SKrishna Gudipati 				"Remote port (WWN = %s) connectivity lost for "
2507a36c61f9SKrishna Gudipati 				"logical port (WWN = %s)\n",
2508a36c61f9SKrishna Gudipati 				rpwwn_buf, lpwwn_buf);
25097826f304SKrishna Gudipati 			bfa_fcs_rport_aen_post(rport,
25107826f304SKrishna Gudipati 				BFA_RPORT_AEN_DISCONNECT, NULL);
25117826f304SKrishna Gudipati 		} else {
251288166242SJing Huang 			BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2513a36c61f9SKrishna Gudipati 				"Remote port (WWN = %s) offlined by "
2514a36c61f9SKrishna Gudipati 				"logical port (WWN = %s)\n",
2515a36c61f9SKrishna Gudipati 				rpwwn_buf, lpwwn_buf);
25167826f304SKrishna Gudipati 			bfa_fcs_rport_aen_post(rport,
25177826f304SKrishna Gudipati 				BFA_RPORT_AEN_OFFLINE, NULL);
25187826f304SKrishna Gudipati 		}
2519a36c61f9SKrishna Gudipati 	}
2520a36c61f9SKrishna Gudipati 
2521a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_is_initiator(port)) {
2522a36c61f9SKrishna Gudipati 		bfa_fcs_itnim_rport_offline(rport->itnim);
2523a36c61f9SKrishna Gudipati 		if (!BFA_FCS_PID_IS_WKA(rport->pid))
2524a36c61f9SKrishna Gudipati 			bfa_fcs_rpf_rport_offline(rport);
2525a36c61f9SKrishna Gudipati 	}
2526a36c61f9SKrishna Gudipati }
2527a36c61f9SKrishna Gudipati 
25285fbe25c7SJing Huang /*
2529a36c61f9SKrishna Gudipati  * Update rport parameters from PLOGI or PLOGI accept.
2530a36c61f9SKrishna Gudipati  */
2531a36c61f9SKrishna Gudipati static void
2532a36c61f9SKrishna Gudipati bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
2533a36c61f9SKrishna Gudipati {
2534a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = rport->port;
2535a36c61f9SKrishna Gudipati 
25365fbe25c7SJing Huang 	/*
2537a36c61f9SKrishna Gudipati 	 * - port name
2538a36c61f9SKrishna Gudipati 	 * - node name
2539a36c61f9SKrishna Gudipati 	 */
2540a36c61f9SKrishna Gudipati 	rport->pwwn = plogi->port_name;
2541a36c61f9SKrishna Gudipati 	rport->nwwn = plogi->node_name;
2542a36c61f9SKrishna Gudipati 
25435fbe25c7SJing Huang 	/*
2544a36c61f9SKrishna Gudipati 	 * - class of service
2545a36c61f9SKrishna Gudipati 	 */
2546a36c61f9SKrishna Gudipati 	rport->fc_cos = 0;
2547a36c61f9SKrishna Gudipati 	if (plogi->class3.class_valid)
2548a36c61f9SKrishna Gudipati 		rport->fc_cos = FC_CLASS_3;
2549a36c61f9SKrishna Gudipati 
2550a36c61f9SKrishna Gudipati 	if (plogi->class2.class_valid)
2551a36c61f9SKrishna Gudipati 		rport->fc_cos |= FC_CLASS_2;
2552a36c61f9SKrishna Gudipati 
25535fbe25c7SJing Huang 	/*
2554a36c61f9SKrishna Gudipati 	 * - CISC
2555a36c61f9SKrishna Gudipati 	 * - MAX receive frame size
2556a36c61f9SKrishna Gudipati 	 */
2557a36c61f9SKrishna Gudipati 	rport->cisc = plogi->csp.cisc;
2558bd5a0260SKrishna Gudipati 	if (be16_to_cpu(plogi->class3.rxsz) < be16_to_cpu(plogi->csp.rxsz))
2559ba816ea8SJing Huang 		rport->maxfrsize = be16_to_cpu(plogi->class3.rxsz);
2560bd5a0260SKrishna Gudipati 	else
2561bd5a0260SKrishna Gudipati 		rport->maxfrsize = be16_to_cpu(plogi->csp.rxsz);
2562a36c61f9SKrishna Gudipati 
2563ba816ea8SJing Huang 	bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
2564a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->fabric->bb_credit);
25655fbe25c7SJing Huang 	/*
2566a36c61f9SKrishna Gudipati 	 * Direct Attach P2P mode :
2567a36c61f9SKrishna Gudipati 	 * This is to handle a bug (233476) in IBM targets in Direct Attach
2568a36c61f9SKrishna Gudipati 	 *  Mode. Basically, in FLOGI Accept the target would have
2569a36c61f9SKrishna Gudipati 	 * erroneously set the BB Credit to the value used in the FLOGI
2570a36c61f9SKrishna Gudipati 	 * sent by the HBA. It uses the correct value (its own BB credit)
2571a36c61f9SKrishna Gudipati 	 * in PLOGI.
2572a36c61f9SKrishna Gudipati 	 */
2573a36c61f9SKrishna Gudipati 	if ((!bfa_fcs_fabric_is_switched(port->fabric))	 &&
2574ba816ea8SJing Huang 		(be16_to_cpu(plogi->csp.bbcred) < port->fabric->bb_credit)) {
2575a36c61f9SKrishna Gudipati 
2576ba816ea8SJing Huang 		bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
2577a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, port->fabric->bb_credit);
2578a36c61f9SKrishna Gudipati 
2579ba816ea8SJing Huang 		port->fabric->bb_credit = be16_to_cpu(plogi->csp.bbcred);
2580a36c61f9SKrishna Gudipati 		bfa_fcport_set_tx_bbcredit(port->fcs->bfa,
2581bbe37a67SVijaya Mohan Guvva 					  port->fabric->bb_credit);
2582a36c61f9SKrishna Gudipati 	}
2583a36c61f9SKrishna Gudipati 
2584a36c61f9SKrishna Gudipati }
2585a36c61f9SKrishna Gudipati 
25865fbe25c7SJing Huang /*
2587a36c61f9SKrishna Gudipati  *	Called to handle LOGO received from an existing remote port.
2588a36c61f9SKrishna Gudipati  */
2589a36c61f9SKrishna Gudipati static void
2590a36c61f9SKrishna Gudipati bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs)
2591a36c61f9SKrishna Gudipati {
2592a36c61f9SKrishna Gudipati 	rport->reply_oxid = fchs->ox_id;
2593a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->reply_oxid);
2594a36c61f9SKrishna Gudipati 
2595a36c61f9SKrishna Gudipati 	rport->prlo = BFA_FALSE;
2596a36c61f9SKrishna Gudipati 	rport->stats.logo_rcvd++;
2597a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD);
2598a36c61f9SKrishna Gudipati }
2599a36c61f9SKrishna Gudipati 
2600a36c61f9SKrishna Gudipati 
2601a36c61f9SKrishna Gudipati 
26025fbe25c7SJing Huang /*
2603a36c61f9SKrishna Gudipati  *  fcs_rport_public FCS rport public interfaces
2604a36c61f9SKrishna Gudipati  */
2605a36c61f9SKrishna Gudipati 
26065fbe25c7SJing Huang /*
2607a36c61f9SKrishna Gudipati  *	Called by bport/vport to create a remote port instance for a discovered
2608a36c61f9SKrishna Gudipati  *	remote device.
2609a36c61f9SKrishna Gudipati  *
2610a36c61f9SKrishna Gudipati  * @param[in] port	- base port or vport
2611a36c61f9SKrishna Gudipati  * @param[in] rpid	- remote port ID
2612a36c61f9SKrishna Gudipati  *
2613a36c61f9SKrishna Gudipati  * @return None
2614a36c61f9SKrishna Gudipati  */
2615a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *
2616a36c61f9SKrishna Gudipati bfa_fcs_rport_create(struct bfa_fcs_lport_s *port, u32 rpid)
2617a36c61f9SKrishna Gudipati {
2618a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2619a36c61f9SKrishna Gudipati 
2620a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rpid);
2621a36c61f9SKrishna Gudipati 	rport = bfa_fcs_rport_alloc(port, WWN_NULL, rpid);
2622a36c61f9SKrishna Gudipati 	if (!rport)
2623a36c61f9SKrishna Gudipati 		return NULL;
2624a36c61f9SKrishna Gudipati 
2625a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
2626a36c61f9SKrishna Gudipati 	return rport;
2627a36c61f9SKrishna Gudipati }
2628a36c61f9SKrishna Gudipati 
26295fbe25c7SJing Huang /*
2630a36c61f9SKrishna Gudipati  * Called to create a rport for which only the wwn is known.
2631a36c61f9SKrishna Gudipati  *
2632a36c61f9SKrishna Gudipati  * @param[in] port	- base port
2633a36c61f9SKrishna Gudipati  * @param[in] rpwwn	- remote port wwn
2634a36c61f9SKrishna Gudipati  *
2635a36c61f9SKrishna Gudipati  * @return None
2636a36c61f9SKrishna Gudipati  */
2637a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *
2638a36c61f9SKrishna Gudipati bfa_fcs_rport_create_by_wwn(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
2639a36c61f9SKrishna Gudipati {
2640a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2641a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rpwwn);
2642a36c61f9SKrishna Gudipati 	rport = bfa_fcs_rport_alloc(port, rpwwn, 0);
2643a36c61f9SKrishna Gudipati 	if (!rport)
2644a36c61f9SKrishna Gudipati 		return NULL;
2645a36c61f9SKrishna Gudipati 
2646a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_DISC);
2647a36c61f9SKrishna Gudipati 	return rport;
2648a36c61f9SKrishna Gudipati }
26495fbe25c7SJing Huang /*
2650a36c61f9SKrishna Gudipati  * Called by bport in private loop topology to indicate that a
2651a36c61f9SKrishna Gudipati  * rport has been discovered and plogi has been completed.
2652a36c61f9SKrishna Gudipati  *
2653a36c61f9SKrishna Gudipati  * @param[in] port	- base port or vport
2654a36c61f9SKrishna Gudipati  * @param[in] rpid	- remote port ID
2655a36c61f9SKrishna Gudipati  */
2656a36c61f9SKrishna Gudipati void
2657a36c61f9SKrishna Gudipati bfa_fcs_rport_start(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
2658a36c61f9SKrishna Gudipati 	 struct fc_logi_s *plogi)
2659a36c61f9SKrishna Gudipati {
2660a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2661a36c61f9SKrishna Gudipati 
2662a36c61f9SKrishna Gudipati 	rport = bfa_fcs_rport_alloc(port, WWN_NULL, fchs->s_id);
2663a36c61f9SKrishna Gudipati 	if (!rport)
2664a36c61f9SKrishna Gudipati 		return;
2665a36c61f9SKrishna Gudipati 
2666a36c61f9SKrishna Gudipati 	bfa_fcs_rport_update(rport, plogi);
2667a36c61f9SKrishna Gudipati 
2668a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_COMP);
2669a36c61f9SKrishna Gudipati }
2670a36c61f9SKrishna Gudipati 
26715fbe25c7SJing Huang /*
2672a36c61f9SKrishna Gudipati  *	Called by bport/vport to handle PLOGI received from a new remote port.
2673a36c61f9SKrishna Gudipati  *	If an existing rport does a plogi, it will be handled separately.
2674a36c61f9SKrishna Gudipati  */
2675a36c61f9SKrishna Gudipati void
2676a36c61f9SKrishna Gudipati bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
2677a36c61f9SKrishna Gudipati 				struct fc_logi_s *plogi)
2678a36c61f9SKrishna Gudipati {
2679a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2680a36c61f9SKrishna Gudipati 
2681a36c61f9SKrishna Gudipati 	rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id);
2682a36c61f9SKrishna Gudipati 	if (!rport)
2683a36c61f9SKrishna Gudipati 		return;
2684a36c61f9SKrishna Gudipati 
2685a36c61f9SKrishna Gudipati 	bfa_fcs_rport_update(rport, plogi);
2686a36c61f9SKrishna Gudipati 
2687a36c61f9SKrishna Gudipati 	rport->reply_oxid = fchs->ox_id;
2688a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->reply_oxid);
2689a36c61f9SKrishna Gudipati 
2690a36c61f9SKrishna Gudipati 	rport->stats.plogi_rcvd++;
2691a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2692a36c61f9SKrishna Gudipati }
2693a36c61f9SKrishna Gudipati 
26945fbe25c7SJing Huang /*
2695a36c61f9SKrishna Gudipati  *	Called by bport/vport to handle PLOGI received from an existing
2696a36c61f9SKrishna Gudipati  *	 remote port.
2697a36c61f9SKrishna Gudipati  */
2698a36c61f9SKrishna Gudipati void
2699a36c61f9SKrishna Gudipati bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2700a36c61f9SKrishna Gudipati 			struct fc_logi_s *plogi)
2701a36c61f9SKrishna Gudipati {
27025fbe25c7SJing Huang 	/*
2703a36c61f9SKrishna Gudipati 	 * @todo Handle P2P and initiator-initiator.
2704a36c61f9SKrishna Gudipati 	 */
2705a36c61f9SKrishna Gudipati 
2706a36c61f9SKrishna Gudipati 	bfa_fcs_rport_update(rport, plogi);
2707a36c61f9SKrishna Gudipati 
2708a36c61f9SKrishna Gudipati 	rport->reply_oxid = rx_fchs->ox_id;
2709a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->reply_oxid);
2710a36c61f9SKrishna Gudipati 
2711d7be54ccSKrishna Gudipati 	rport->pid = rx_fchs->s_id;
2712d7be54ccSKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2713d7be54ccSKrishna Gudipati 
2714a36c61f9SKrishna Gudipati 	rport->stats.plogi_rcvd++;
2715a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2716a36c61f9SKrishna Gudipati }
2717a36c61f9SKrishna Gudipati 
2718a36c61f9SKrishna Gudipati 
27195fbe25c7SJing Huang /*
2720a36c61f9SKrishna Gudipati  *	Called by bport/vport to notify SCN for the remote port
2721a36c61f9SKrishna Gudipati  */
2722a36c61f9SKrishna Gudipati void
2723a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
2724a36c61f9SKrishna Gudipati {
2725a36c61f9SKrishna Gudipati 	rport->stats.rscns++;
2726bc0e2c2aSKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FAB_SCN);
2727a36c61f9SKrishna Gudipati }
2728a36c61f9SKrishna Gudipati 
27295fbe25c7SJing Huang /*
2730a36c61f9SKrishna Gudipati  *	brief
2731a36c61f9SKrishna Gudipati  *	This routine BFA callback for bfa_rport_online() call.
2732a36c61f9SKrishna Gudipati  *
2733a36c61f9SKrishna Gudipati  *	param[in]	cb_arg	-  rport struct.
2734a36c61f9SKrishna Gudipati  *
2735a36c61f9SKrishna Gudipati  *	return
2736a36c61f9SKrishna Gudipati  *		void
2737a36c61f9SKrishna Gudipati  *
2738a36c61f9SKrishna Gudipati  *	Special Considerations:
2739a36c61f9SKrishna Gudipati  *
2740a36c61f9SKrishna Gudipati  *	note
2741a36c61f9SKrishna Gudipati  */
2742a36c61f9SKrishna Gudipati void
2743a36c61f9SKrishna Gudipati bfa_cb_rport_online(void *cbarg)
2744a36c61f9SKrishna Gudipati {
2745a36c61f9SKrishna Gudipati 
2746a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2747a36c61f9SKrishna Gudipati 
2748a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2749a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_HCB_ONLINE);
2750a36c61f9SKrishna Gudipati }
2751a36c61f9SKrishna Gudipati 
27525fbe25c7SJing Huang /*
2753a36c61f9SKrishna Gudipati  *	brief
2754a36c61f9SKrishna Gudipati  *	This routine BFA callback for bfa_rport_offline() call.
2755a36c61f9SKrishna Gudipati  *
2756a36c61f9SKrishna Gudipati  *	param[in]	rport	-
2757a36c61f9SKrishna Gudipati  *
2758a36c61f9SKrishna Gudipati  *	return
2759a36c61f9SKrishna Gudipati  *		void
2760a36c61f9SKrishna Gudipati  *
2761a36c61f9SKrishna Gudipati  *	Special Considerations:
2762a36c61f9SKrishna Gudipati  *
2763a36c61f9SKrishna Gudipati  *	note
2764a36c61f9SKrishna Gudipati  */
2765a36c61f9SKrishna Gudipati void
2766a36c61f9SKrishna Gudipati bfa_cb_rport_offline(void *cbarg)
2767a36c61f9SKrishna Gudipati {
2768a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2769a36c61f9SKrishna Gudipati 
2770a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2771a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_HCB_OFFLINE);
2772a36c61f9SKrishna Gudipati }
2773a36c61f9SKrishna Gudipati 
27745fbe25c7SJing Huang /*
2775a36c61f9SKrishna Gudipati  *	brief
2776a36c61f9SKrishna Gudipati  *	This routine is a static BFA callback when there is a QoS flow_id
2777a36c61f9SKrishna Gudipati  *	change notification
2778a36c61f9SKrishna Gudipati  *
2779a36c61f9SKrishna Gudipati  *	param[in]	rport	-
2780a36c61f9SKrishna Gudipati  *
2781a36c61f9SKrishna Gudipati  *	return
2782a36c61f9SKrishna Gudipati  *		void
2783a36c61f9SKrishna Gudipati  *
2784a36c61f9SKrishna Gudipati  *	Special Considerations:
2785a36c61f9SKrishna Gudipati  *
2786a36c61f9SKrishna Gudipati  *	note
2787a36c61f9SKrishna Gudipati  */
2788a36c61f9SKrishna Gudipati void
2789a36c61f9SKrishna Gudipati bfa_cb_rport_qos_scn_flowid(void *cbarg,
2790a36c61f9SKrishna Gudipati 		struct bfa_rport_qos_attr_s old_qos_attr,
2791a36c61f9SKrishna Gudipati 		struct bfa_rport_qos_attr_s new_qos_attr)
2792a36c61f9SKrishna Gudipati {
2793a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
27947826f304SKrishna Gudipati 	struct bfa_rport_aen_data_s aen_data;
2795a36c61f9SKrishna Gudipati 
2796a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
27977826f304SKrishna Gudipati 	aen_data.priv.qos = new_qos_attr;
27987826f304SKrishna Gudipati 	bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_FLOWID, &aen_data);
2799a36c61f9SKrishna Gudipati }
2800a36c61f9SKrishna Gudipati 
2801bc0e2c2aSKrishna Gudipati void
2802bc0e2c2aSKrishna Gudipati bfa_cb_rport_scn_online(struct bfa_s *bfa)
2803bc0e2c2aSKrishna Gudipati {
2804bc0e2c2aSKrishna Gudipati 	struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs;
2805bc0e2c2aSKrishna Gudipati 	struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs);
2806bc0e2c2aSKrishna Gudipati 	struct bfa_fcs_rport_s *rp;
2807bc0e2c2aSKrishna Gudipati 	struct list_head *qe;
2808bc0e2c2aSKrishna Gudipati 
2809bc0e2c2aSKrishna Gudipati 	list_for_each(qe, &port->rport_q) {
2810bc0e2c2aSKrishna Gudipati 		rp = (struct bfa_fcs_rport_s *) qe;
2811bc0e2c2aSKrishna Gudipati 		bfa_sm_send_event(rp, RPSM_EVENT_SCN_ONLINE);
2812bc0e2c2aSKrishna Gudipati 		rp->scn_online = BFA_TRUE;
2813bc0e2c2aSKrishna Gudipati 	}
2814bc0e2c2aSKrishna Gudipati 
2815bc0e2c2aSKrishna Gudipati 	if (bfa_fcs_lport_is_online(port))
2816bc0e2c2aSKrishna Gudipati 		bfa_fcs_lport_lip_scn_online(port);
2817bc0e2c2aSKrishna Gudipati }
2818bc0e2c2aSKrishna Gudipati 
2819bc0e2c2aSKrishna Gudipati void
2820bc0e2c2aSKrishna Gudipati bfa_cb_rport_scn_no_dev(void *rport)
2821bc0e2c2aSKrishna Gudipati {
2822bc0e2c2aSKrishna Gudipati 	struct bfa_fcs_rport_s *rp = rport;
2823bc0e2c2aSKrishna Gudipati 
2824bc0e2c2aSKrishna Gudipati 	bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE);
2825bc0e2c2aSKrishna Gudipati 	rp->scn_online = BFA_FALSE;
2826bc0e2c2aSKrishna Gudipati }
2827bc0e2c2aSKrishna Gudipati 
2828bc0e2c2aSKrishna Gudipati void
2829bc0e2c2aSKrishna Gudipati bfa_cb_rport_scn_offline(struct bfa_s *bfa)
2830bc0e2c2aSKrishna Gudipati {
2831bc0e2c2aSKrishna Gudipati 	struct bfa_fcs_s *fcs = &((struct bfad_s *)bfa->bfad)->bfa_fcs;
2832bc0e2c2aSKrishna Gudipati 	struct bfa_fcs_lport_s *port = bfa_fcs_get_base_port(fcs);
2833bc0e2c2aSKrishna Gudipati 	struct bfa_fcs_rport_s *rp;
2834bc0e2c2aSKrishna Gudipati 	struct list_head *qe;
2835bc0e2c2aSKrishna Gudipati 
2836bc0e2c2aSKrishna Gudipati 	list_for_each(qe, &port->rport_q) {
2837bc0e2c2aSKrishna Gudipati 		rp = (struct bfa_fcs_rport_s *) qe;
2838bc0e2c2aSKrishna Gudipati 		bfa_sm_send_event(rp, RPSM_EVENT_SCN_OFFLINE);
2839bc0e2c2aSKrishna Gudipati 		rp->scn_online = BFA_FALSE;
2840bc0e2c2aSKrishna Gudipati 	}
2841bc0e2c2aSKrishna Gudipati }
2842bc0e2c2aSKrishna Gudipati 
28435fbe25c7SJing Huang /*
2844a36c61f9SKrishna Gudipati  *	brief
2845a36c61f9SKrishna Gudipati  *	This routine is a static BFA callback when there is a QoS priority
2846a36c61f9SKrishna Gudipati  *	change notification
2847a36c61f9SKrishna Gudipati  *
2848a36c61f9SKrishna Gudipati  *	param[in]	rport	-
2849a36c61f9SKrishna Gudipati  *
2850a36c61f9SKrishna Gudipati  *	return
2851a36c61f9SKrishna Gudipati  *		void
2852a36c61f9SKrishna Gudipati  *
2853a36c61f9SKrishna Gudipati  *	Special Considerations:
2854a36c61f9SKrishna Gudipati  *
2855a36c61f9SKrishna Gudipati  *	note
2856a36c61f9SKrishna Gudipati  */
2857a36c61f9SKrishna Gudipati void
2858a36c61f9SKrishna Gudipati bfa_cb_rport_qos_scn_prio(void *cbarg,
2859a36c61f9SKrishna Gudipati 		struct bfa_rport_qos_attr_s old_qos_attr,
2860a36c61f9SKrishna Gudipati 		struct bfa_rport_qos_attr_s new_qos_attr)
2861a36c61f9SKrishna Gudipati {
2862a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
28637826f304SKrishna Gudipati 	struct bfa_rport_aen_data_s aen_data;
2864a36c61f9SKrishna Gudipati 
2865a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
28667826f304SKrishna Gudipati 	aen_data.priv.qos = new_qos_attr;
28677826f304SKrishna Gudipati 	bfa_fcs_rport_aen_post(rport, BFA_RPORT_AEN_QOS_PRIO, &aen_data);
2868a36c61f9SKrishna Gudipati }
2869a36c61f9SKrishna Gudipati 
28705fbe25c7SJing Huang /*
2871a36c61f9SKrishna Gudipati  *		Called to process any unsolicted frames from this remote port
2872a36c61f9SKrishna Gudipati  */
2873a36c61f9SKrishna Gudipati void
2874a36c61f9SKrishna Gudipati bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport,
2875a36c61f9SKrishna Gudipati 			struct fchs_s *fchs, u16 len)
2876a36c61f9SKrishna Gudipati {
2877a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2878a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s	*els_cmd;
2879a36c61f9SKrishna Gudipati 
2880a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, fchs->s_id);
2881a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, fchs->d_id);
2882a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, fchs->type);
2883a36c61f9SKrishna Gudipati 
2884a36c61f9SKrishna Gudipati 	if (fchs->type != FC_TYPE_ELS)
2885a36c61f9SKrishna Gudipati 		return;
2886a36c61f9SKrishna Gudipati 
2887a36c61f9SKrishna Gudipati 	els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
2888a36c61f9SKrishna Gudipati 
2889a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, els_cmd->els_code);
2890a36c61f9SKrishna Gudipati 
2891a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
2892a36c61f9SKrishna Gudipati 	case FC_ELS_LOGO:
2893a36c61f9SKrishna Gudipati 		bfa_stats(port, plogi_rcvd);
2894a36c61f9SKrishna Gudipati 		bfa_fcs_rport_process_logo(rport, fchs);
2895a36c61f9SKrishna Gudipati 		break;
2896a36c61f9SKrishna Gudipati 
2897a36c61f9SKrishna Gudipati 	case FC_ELS_ADISC:
2898a36c61f9SKrishna Gudipati 		bfa_stats(port, adisc_rcvd);
2899a36c61f9SKrishna Gudipati 		bfa_fcs_rport_process_adisc(rport, fchs, len);
2900a36c61f9SKrishna Gudipati 		break;
2901a36c61f9SKrishna Gudipati 
2902a36c61f9SKrishna Gudipati 	case FC_ELS_PRLO:
2903a36c61f9SKrishna Gudipati 		bfa_stats(port, prlo_rcvd);
2904a36c61f9SKrishna Gudipati 		if (bfa_fcs_lport_is_initiator(port))
2905a36c61f9SKrishna Gudipati 			bfa_fcs_fcpim_uf_recv(rport->itnim, fchs, len);
2906a36c61f9SKrishna Gudipati 		break;
2907a36c61f9SKrishna Gudipati 
2908a36c61f9SKrishna Gudipati 	case FC_ELS_PRLI:
2909a36c61f9SKrishna Gudipati 		bfa_stats(port, prli_rcvd);
2910a36c61f9SKrishna Gudipati 		bfa_fcs_rport_process_prli(rport, fchs, len);
2911a36c61f9SKrishna Gudipati 		break;
2912a36c61f9SKrishna Gudipati 
2913a36c61f9SKrishna Gudipati 	case FC_ELS_RPSC:
2914a36c61f9SKrishna Gudipati 		bfa_stats(port, rpsc_rcvd);
2915a36c61f9SKrishna Gudipati 		bfa_fcs_rport_process_rpsc(rport, fchs, len);
2916a36c61f9SKrishna Gudipati 		break;
2917a36c61f9SKrishna Gudipati 
2918a36c61f9SKrishna Gudipati 	default:
2919a36c61f9SKrishna Gudipati 		bfa_stats(port, un_handled_els_rcvd);
2920a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_ls_rjt(rport, fchs,
2921a36c61f9SKrishna Gudipati 					  FC_LS_RJT_RSN_CMD_NOT_SUPP,
2922a36c61f9SKrishna Gudipati 					  FC_LS_RJT_EXP_NO_ADDL_INFO);
2923a36c61f9SKrishna Gudipati 		break;
2924a36c61f9SKrishna Gudipati 	}
2925a36c61f9SKrishna Gudipati }
2926a36c61f9SKrishna Gudipati 
2927a36c61f9SKrishna Gudipati /* send best case  acc to prlo */
2928a36c61f9SKrishna Gudipati static void
2929a36c61f9SKrishna Gudipati bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport)
2930a36c61f9SKrishna Gudipati {
2931a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2932a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2933a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2934a36c61f9SKrishna Gudipati 	int		len;
2935a36c61f9SKrishna Gudipati 
2936a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2937a36c61f9SKrishna Gudipati 
2938c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs, BFA_FALSE);
2939a36c61f9SKrishna Gudipati 	if (!fcxp)
2940a36c61f9SKrishna Gudipati 		return;
2941a36c61f9SKrishna Gudipati 	len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2942a36c61f9SKrishna Gudipati 			rport->pid, bfa_fcs_lport_get_fcid(port),
2943a36c61f9SKrishna Gudipati 			rport->reply_oxid, 0);
2944a36c61f9SKrishna Gudipati 
2945a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id,
2946a36c61f9SKrishna Gudipati 		port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs,
2947a36c61f9SKrishna Gudipati 		NULL, NULL, FC_MAX_PDUSZ, 0);
2948a36c61f9SKrishna Gudipati }
2949a36c61f9SKrishna Gudipati 
2950a36c61f9SKrishna Gudipati /*
2951a36c61f9SKrishna Gudipati  * Send a LS reject
2952a36c61f9SKrishna Gudipati  */
2953a36c61f9SKrishna Gudipati static void
2954a36c61f9SKrishna Gudipati bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2955a36c61f9SKrishna Gudipati 			  u8 reason_code, u8 reason_code_expl)
2956a36c61f9SKrishna Gudipati {
2957a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2958a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2959a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2960a36c61f9SKrishna Gudipati 	int		len;
2961a36c61f9SKrishna Gudipati 
2962a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rx_fchs->s_id);
2963a36c61f9SKrishna Gudipati 
2964c3f1b123SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(rport->fcs, BFA_FALSE);
2965a36c61f9SKrishna Gudipati 	if (!fcxp)
2966a36c61f9SKrishna Gudipati 		return;
2967a36c61f9SKrishna Gudipati 
2968a36c61f9SKrishna Gudipati 	len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2969a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2970a36c61f9SKrishna Gudipati 				rx_fchs->ox_id, reason_code, reason_code_expl);
2971a36c61f9SKrishna Gudipati 
2972a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
2973a36c61f9SKrishna Gudipati 			BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
2974a36c61f9SKrishna Gudipati 			FC_MAX_PDUSZ, 0);
2975a36c61f9SKrishna Gudipati }
2976a36c61f9SKrishna Gudipati 
29775fbe25c7SJing Huang /*
2978a36c61f9SKrishna Gudipati  * Return state of rport.
2979a36c61f9SKrishna Gudipati  */
2980a36c61f9SKrishna Gudipati int
2981a36c61f9SKrishna Gudipati bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport)
2982a36c61f9SKrishna Gudipati {
2983a36c61f9SKrishna Gudipati 	return bfa_sm_to_state(rport_sm_table, rport->sm);
2984a36c61f9SKrishna Gudipati }
2985a36c61f9SKrishna Gudipati 
2986f7f73812SMaggie Zhang 
29875fbe25c7SJing Huang /*
2988a36c61f9SKrishna Gudipati  *	brief
2989a36c61f9SKrishna Gudipati  *		 Called by the Driver to set rport delete/ageout timeout
2990a36c61f9SKrishna Gudipati  *
2991a36c61f9SKrishna Gudipati  *	param[in]		rport timeout value in seconds.
2992a36c61f9SKrishna Gudipati  *
2993a36c61f9SKrishna Gudipati  *	return None
2994a36c61f9SKrishna Gudipati  */
2995a36c61f9SKrishna Gudipati void
2996a36c61f9SKrishna Gudipati bfa_fcs_rport_set_del_timeout(u8 rport_tmo)
2997a36c61f9SKrishna Gudipati {
2998a36c61f9SKrishna Gudipati 	/* convert to Millisecs */
2999a36c61f9SKrishna Gudipati 	if (rport_tmo > 0)
3000a36c61f9SKrishna Gudipati 		bfa_fcs_rport_del_timeout = rport_tmo * 1000;
3001a36c61f9SKrishna Gudipati }
3002a36c61f9SKrishna Gudipati void
300350444a34SMaggie bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, __be16 ox_id)
3004a36c61f9SKrishna Gudipati {
3005a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3006a36c61f9SKrishna Gudipati 
3007a36c61f9SKrishna Gudipati 	rport->prlo = BFA_TRUE;
3008a36c61f9SKrishna Gudipati 	rport->reply_oxid = ox_id;
3009a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PRLO_RCVD);
3010a36c61f9SKrishna Gudipati }
3011a36c61f9SKrishna Gudipati 
301261ba4394SKrishna Gudipati /*
301361ba4394SKrishna Gudipati  * Called by BFAD to set the max limit on number of bfa_fcs_rport allocation
301461ba4394SKrishna Gudipati  * which limits number of concurrent logins to remote ports
301561ba4394SKrishna Gudipati  */
301661ba4394SKrishna Gudipati void
301761ba4394SKrishna Gudipati bfa_fcs_rport_set_max_logins(u32 max_logins)
301861ba4394SKrishna Gudipati {
301961ba4394SKrishna Gudipati 	if (max_logins > 0)
302061ba4394SKrishna Gudipati 		bfa_fcs_rport_max_logins = max_logins;
302161ba4394SKrishna Gudipati }
302261ba4394SKrishna Gudipati 
302360138066SKrishna Gudipati void
302460138066SKrishna Gudipati bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
302560138066SKrishna Gudipati 		struct bfa_rport_attr_s *rport_attr)
302660138066SKrishna Gudipati {
302760138066SKrishna Gudipati 	struct bfa_rport_qos_attr_s qos_attr;
302860138066SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
302960138066SKrishna Gudipati 	bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed;
30307ace27aeSKrishna Gudipati 	struct bfa_port_attr_s port_attr;
30317ace27aeSKrishna Gudipati 
30327ace27aeSKrishna Gudipati 	bfa_fcport_get_attr(rport->fcs->bfa, &port_attr);
3033a36c61f9SKrishna Gudipati 
303460138066SKrishna Gudipati 	memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
303560138066SKrishna Gudipati 	memset(&qos_attr, 0, sizeof(struct bfa_rport_qos_attr_s));
303660138066SKrishna Gudipati 
303760138066SKrishna Gudipati 	rport_attr->pid = rport->pid;
303860138066SKrishna Gudipati 	rport_attr->pwwn = rport->pwwn;
303960138066SKrishna Gudipati 	rport_attr->nwwn = rport->nwwn;
304060138066SKrishna Gudipati 	rport_attr->cos_supported = rport->fc_cos;
304160138066SKrishna Gudipati 	rport_attr->df_sz = rport->maxfrsize;
304260138066SKrishna Gudipati 	rport_attr->state = bfa_fcs_rport_get_state(rport);
304360138066SKrishna Gudipati 	rport_attr->fc_cos = rport->fc_cos;
304460138066SKrishna Gudipati 	rport_attr->cisc = rport->cisc;
304560138066SKrishna Gudipati 	rport_attr->scsi_function = rport->scsi_function;
304660138066SKrishna Gudipati 	rport_attr->curr_speed  = rport->rpf.rpsc_speed;
304760138066SKrishna Gudipati 	rport_attr->assigned_speed  = rport->rpf.assigned_speed;
304860138066SKrishna Gudipati 
304961ba4394SKrishna Gudipati 	if (rport->bfa_rport) {
305060138066SKrishna Gudipati 		qos_attr.qos_priority = rport->bfa_rport->qos_attr.qos_priority;
305160138066SKrishna Gudipati 		qos_attr.qos_flow_id =
305260138066SKrishna Gudipati 			cpu_to_be32(rport->bfa_rport->qos_attr.qos_flow_id);
305361ba4394SKrishna Gudipati 	}
305460138066SKrishna Gudipati 	rport_attr->qos_attr = qos_attr;
305560138066SKrishna Gudipati 
305660138066SKrishna Gudipati 	rport_attr->trl_enforced = BFA_FALSE;
305760138066SKrishna Gudipati 	if (bfa_fcport_is_ratelim(port->fcs->bfa) &&
305860138066SKrishna Gudipati 	    (rport->scsi_function == BFA_RPORT_TARGET)) {
305960138066SKrishna Gudipati 		if (rport_speed == BFA_PORT_SPEED_UNKNOWN)
306060138066SKrishna Gudipati 			rport_speed =
306160138066SKrishna Gudipati 				bfa_fcport_get_ratelim_speed(rport->fcs->bfa);
306260138066SKrishna Gudipati 
30637ace27aeSKrishna Gudipati 		if ((bfa_fcs_lport_get_rport_max_speed(port) !=
30647ace27aeSKrishna Gudipati 		    BFA_PORT_SPEED_UNKNOWN) && (rport_speed < port_attr.speed))
306560138066SKrishna Gudipati 			rport_attr->trl_enforced = BFA_TRUE;
306660138066SKrishna Gudipati 	}
306760138066SKrishna Gudipati }
3068a36c61f9SKrishna Gudipati 
30695fbe25c7SJing Huang /*
3070a36c61f9SKrishna Gudipati  * Remote port implementation.
3071a36c61f9SKrishna Gudipati  */
3072a36c61f9SKrishna Gudipati 
30735fbe25c7SJing Huang /*
3074a36c61f9SKrishna Gudipati  *  fcs_rport_api FCS rport API.
3075a36c61f9SKrishna Gudipati  */
3076a36c61f9SKrishna Gudipati 
3077a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *
3078a36c61f9SKrishna Gudipati bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
3079a36c61f9SKrishna Gudipati {
3080a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
3081a36c61f9SKrishna Gudipati 
3082a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn);
3083a36c61f9SKrishna Gudipati 	if (rport == NULL) {
3084a36c61f9SKrishna Gudipati 		/*
3085a36c61f9SKrishna Gudipati 		 * TBD Error handling
3086a36c61f9SKrishna Gudipati 		 */
3087a36c61f9SKrishna Gudipati 	}
3088a36c61f9SKrishna Gudipati 
3089a36c61f9SKrishna Gudipati 	return rport;
3090a36c61f9SKrishna Gudipati }
3091a36c61f9SKrishna Gudipati 
3092a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *
3093a36c61f9SKrishna Gudipati bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t rnwwn)
3094a36c61f9SKrishna Gudipati {
3095a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
3096a36c61f9SKrishna Gudipati 
3097a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_nwwn(port, rnwwn);
3098a36c61f9SKrishna Gudipati 	if (rport == NULL) {
3099a36c61f9SKrishna Gudipati 		/*
3100a36c61f9SKrishna Gudipati 		 * TBD Error handling
3101a36c61f9SKrishna Gudipati 		 */
3102a36c61f9SKrishna Gudipati 	}
3103a36c61f9SKrishna Gudipati 
3104a36c61f9SKrishna Gudipati 	return rport;
3105a36c61f9SKrishna Gudipati }
3106a36c61f9SKrishna Gudipati 
3107a36c61f9SKrishna Gudipati /*
3108a36c61f9SKrishna Gudipati  * Remote port features (RPF) implementation.
3109a36c61f9SKrishna Gudipati  */
3110a36c61f9SKrishna Gudipati 
3111a36c61f9SKrishna Gudipati #define BFA_FCS_RPF_RETRIES	(3)
3112a36c61f9SKrishna Gudipati #define BFA_FCS_RPF_RETRY_TIMEOUT  (1000) /* 1 sec (In millisecs) */
3113a36c61f9SKrishna Gudipati 
3114a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_send_rpsc2(void *rport_cbarg,
3115a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp_alloced);
3116a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_rpsc2_response(void *fcsarg,
3117a36c61f9SKrishna Gudipati 			struct bfa_fcxp_s *fcxp,
3118a36c61f9SKrishna Gudipati 			void *cbarg,
3119a36c61f9SKrishna Gudipati 			bfa_status_t req_status,
3120a36c61f9SKrishna Gudipati 			u32 rsp_len,
3121a36c61f9SKrishna Gudipati 			u32 resid_len,
3122a36c61f9SKrishna Gudipati 			struct fchs_s *rsp_fchs);
3123a36c61f9SKrishna Gudipati 
3124a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_timeout(void *arg);
3125a36c61f9SKrishna Gudipati 
31265fbe25c7SJing Huang /*
3127a36c61f9SKrishna Gudipati  *  fcs_rport_ftrs_sm FCS rport state machine events
3128a36c61f9SKrishna Gudipati  */
3129a36c61f9SKrishna Gudipati 
3130a36c61f9SKrishna Gudipati enum rpf_event {
3131a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPORT_OFFLINE  = 1, /* Rport offline		*/
3132a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPORT_ONLINE   = 2,	/* Rport online			*/
3133a36c61f9SKrishna Gudipati 	RPFSM_EVENT_FCXP_SENT      = 3,	/* Frame from has been sent	*/
3134a36c61f9SKrishna Gudipati 	RPFSM_EVENT_TIMEOUT	   = 4, /* Rport SM timeout event	*/
3135a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPSC_COMP      = 5,
3136a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPSC_FAIL      = 6,
3137a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPSC_ERROR     = 7,
3138a36c61f9SKrishna Gudipati };
3139a36c61f9SKrishna Gudipati 
3140a36c61f9SKrishna Gudipati static void	bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf,
3141a36c61f9SKrishna Gudipati 					enum rpf_event event);
3142a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf,
3143a36c61f9SKrishna Gudipati 				       enum rpf_event event);
3144a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf,
3145a36c61f9SKrishna Gudipati 				       enum rpf_event event);
3146a36c61f9SKrishna Gudipati static void	bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf,
3147a36c61f9SKrishna Gudipati 					enum rpf_event event);
3148a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf,
3149a36c61f9SKrishna Gudipati 					enum rpf_event event);
3150a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf,
3151a36c61f9SKrishna Gudipati 					enum rpf_event event);
3152a36c61f9SKrishna Gudipati 
3153a36c61f9SKrishna Gudipati static void
3154a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3155a36c61f9SKrishna Gudipati {
3156a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3157a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = &rport->fcs->fabric;
3158a36c61f9SKrishna Gudipati 
3159a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
3160a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3161a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
3162a36c61f9SKrishna Gudipati 
3163a36c61f9SKrishna Gudipati 	switch (event) {
3164a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_ONLINE:
3165a36c61f9SKrishna Gudipati 		/* Send RPSC2 to a Brocade fabric only. */
3166a36c61f9SKrishna Gudipati 		if ((!BFA_FCS_PID_IS_WKA(rport->pid)) &&
3167f7f73812SMaggie Zhang 			((rport->port->fabric->lps->brcd_switch) ||
3168a36c61f9SKrishna Gudipati 			(bfa_fcs_fabric_get_switch_oui(fabric) ==
3169a36c61f9SKrishna Gudipati 						BFA_FCS_BRCD_SWITCH_OUI))) {
3170a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
3171a36c61f9SKrishna Gudipati 			rpf->rpsc_retries = 0;
3172a36c61f9SKrishna Gudipati 			bfa_fcs_rpf_send_rpsc2(rpf, NULL);
3173a36c61f9SKrishna Gudipati 		}
3174a36c61f9SKrishna Gudipati 		break;
3175a36c61f9SKrishna Gudipati 
3176a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
3177a36c61f9SKrishna Gudipati 		break;
3178a36c61f9SKrishna Gudipati 
3179a36c61f9SKrishna Gudipati 	default:
3180a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
3181a36c61f9SKrishna Gudipati 	}
3182a36c61f9SKrishna Gudipati }
3183a36c61f9SKrishna Gudipati 
3184a36c61f9SKrishna Gudipati static void
3185a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3186a36c61f9SKrishna Gudipati {
3187a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3188a36c61f9SKrishna Gudipati 
3189a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
3190a36c61f9SKrishna Gudipati 
3191a36c61f9SKrishna Gudipati 	switch (event) {
3192a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_FCXP_SENT:
3193a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc);
3194a36c61f9SKrishna Gudipati 		break;
3195a36c61f9SKrishna Gudipati 
3196a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
3197a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3198a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe);
3199a36c61f9SKrishna Gudipati 		rpf->rpsc_retries = 0;
3200a36c61f9SKrishna Gudipati 		break;
3201a36c61f9SKrishna Gudipati 
3202a36c61f9SKrishna Gudipati 	default:
3203a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
3204a36c61f9SKrishna Gudipati 	}
3205a36c61f9SKrishna Gudipati }
3206a36c61f9SKrishna Gudipati 
3207a36c61f9SKrishna Gudipati static void
3208a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3209a36c61f9SKrishna Gudipati {
3210a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3211a36c61f9SKrishna Gudipati 
3212a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3213a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
3214a36c61f9SKrishna Gudipati 
3215a36c61f9SKrishna Gudipati 	switch (event) {
3216a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPSC_COMP:
3217a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
3218a36c61f9SKrishna Gudipati 		/* Update speed info in f/w via BFA */
3219a36c61f9SKrishna Gudipati 		if (rpf->rpsc_speed != BFA_PORT_SPEED_UNKNOWN)
3220a36c61f9SKrishna Gudipati 			bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed);
3221a36c61f9SKrishna Gudipati 		else if (rpf->assigned_speed != BFA_PORT_SPEED_UNKNOWN)
3222a36c61f9SKrishna Gudipati 			bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed);
3223a36c61f9SKrishna Gudipati 		break;
3224a36c61f9SKrishna Gudipati 
3225a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPSC_FAIL:
3226a36c61f9SKrishna Gudipati 		/* RPSC not supported by rport */
3227a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
3228a36c61f9SKrishna Gudipati 		break;
3229a36c61f9SKrishna Gudipati 
3230a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPSC_ERROR:
3231a36c61f9SKrishna Gudipati 		/* need to retry...delayed a bit. */
3232a36c61f9SKrishna Gudipati 		if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) {
3233a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rpf->timer,
3234a36c61f9SKrishna Gudipati 				    bfa_fcs_rpf_timeout, rpf,
3235a36c61f9SKrishna Gudipati 				    BFA_FCS_RPF_RETRY_TIMEOUT);
3236a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry);
3237a36c61f9SKrishna Gudipati 		} else {
3238a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
3239a36c61f9SKrishna Gudipati 		}
3240a36c61f9SKrishna Gudipati 		break;
3241a36c61f9SKrishna Gudipati 
3242a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
3243a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3244a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rpf->fcxp);
3245a36c61f9SKrishna Gudipati 		rpf->rpsc_retries = 0;
3246a36c61f9SKrishna Gudipati 		break;
3247a36c61f9SKrishna Gudipati 
3248a36c61f9SKrishna Gudipati 	default:
3249a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
3250a36c61f9SKrishna Gudipati 	}
3251a36c61f9SKrishna Gudipati }
3252a36c61f9SKrishna Gudipati 
3253a36c61f9SKrishna Gudipati static void
3254a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3255a36c61f9SKrishna Gudipati {
3256a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3257a36c61f9SKrishna Gudipati 
3258a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3259a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
3260a36c61f9SKrishna Gudipati 
3261a36c61f9SKrishna Gudipati 	switch (event) {
3262a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_TIMEOUT:
3263a36c61f9SKrishna Gudipati 		/* re-send the RPSC */
3264a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
3265a36c61f9SKrishna Gudipati 		bfa_fcs_rpf_send_rpsc2(rpf, NULL);
3266a36c61f9SKrishna Gudipati 		break;
3267a36c61f9SKrishna Gudipati 
3268a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
3269a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rpf->timer);
3270a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3271a36c61f9SKrishna Gudipati 		rpf->rpsc_retries = 0;
3272a36c61f9SKrishna Gudipati 		break;
3273a36c61f9SKrishna Gudipati 
3274a36c61f9SKrishna Gudipati 	default:
3275a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
3276a36c61f9SKrishna Gudipati 	}
3277a36c61f9SKrishna Gudipati }
3278a36c61f9SKrishna Gudipati 
3279a36c61f9SKrishna Gudipati static void
3280a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3281a36c61f9SKrishna Gudipati {
3282a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3283a36c61f9SKrishna Gudipati 
3284a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
3285a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3286a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
3287a36c61f9SKrishna Gudipati 
3288a36c61f9SKrishna Gudipati 	switch (event) {
3289a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
3290a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
3291a36c61f9SKrishna Gudipati 		rpf->rpsc_retries = 0;
3292a36c61f9SKrishna Gudipati 		break;
3293a36c61f9SKrishna Gudipati 
3294a36c61f9SKrishna Gudipati 	default:
3295a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
3296a36c61f9SKrishna Gudipati 	}
3297a36c61f9SKrishna Gudipati }
3298a36c61f9SKrishna Gudipati 
3299a36c61f9SKrishna Gudipati static void
3300a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
3301a36c61f9SKrishna Gudipati {
3302a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3303a36c61f9SKrishna Gudipati 
3304a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
3305a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3306a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
3307a36c61f9SKrishna Gudipati 
3308a36c61f9SKrishna Gudipati 	switch (event) {
3309a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_ONLINE:
3310a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
3311a36c61f9SKrishna Gudipati 		bfa_fcs_rpf_send_rpsc2(rpf, NULL);
3312a36c61f9SKrishna Gudipati 		break;
3313a36c61f9SKrishna Gudipati 
3314a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
3315a36c61f9SKrishna Gudipati 		break;
3316a36c61f9SKrishna Gudipati 
3317a36c61f9SKrishna Gudipati 	default:
3318a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
3319a36c61f9SKrishna Gudipati 	}
3320a36c61f9SKrishna Gudipati }
33215fbe25c7SJing Huang /*
3322a36c61f9SKrishna Gudipati  * Called when Rport is created.
3323a36c61f9SKrishna Gudipati  */
3324a36c61f9SKrishna Gudipati void
3325a36c61f9SKrishna Gudipati bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport)
3326a36c61f9SKrishna Gudipati {
3327a36c61f9SKrishna Gudipati 	struct bfa_fcs_rpf_s *rpf = &rport->rpf;
3328a36c61f9SKrishna Gudipati 
3329a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3330a36c61f9SKrishna Gudipati 	rpf->rport = rport;
3331a36c61f9SKrishna Gudipati 
3332a36c61f9SKrishna Gudipati 	bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit);
3333a36c61f9SKrishna Gudipati }
3334a36c61f9SKrishna Gudipati 
33355fbe25c7SJing Huang /*
3336a36c61f9SKrishna Gudipati  * Called when Rport becomes online
3337a36c61f9SKrishna Gudipati  */
3338a36c61f9SKrishna Gudipati void
3339a36c61f9SKrishna Gudipati bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport)
3340a36c61f9SKrishna Gudipati {
3341a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3342a36c61f9SKrishna Gudipati 
3343a36c61f9SKrishna Gudipati 	if (__fcs_min_cfg(rport->port->fcs))
3344a36c61f9SKrishna Gudipati 		return;
3345a36c61f9SKrishna Gudipati 
3346a36c61f9SKrishna Gudipati 	if (bfa_fcs_fabric_is_switched(rport->port->fabric))
3347a36c61f9SKrishna Gudipati 		bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE);
3348a36c61f9SKrishna Gudipati }
3349a36c61f9SKrishna Gudipati 
33505fbe25c7SJing Huang /*
3351a36c61f9SKrishna Gudipati  * Called when Rport becomes offline
3352a36c61f9SKrishna Gudipati  */
3353a36c61f9SKrishna Gudipati void
3354a36c61f9SKrishna Gudipati bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport)
3355a36c61f9SKrishna Gudipati {
3356a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3357a36c61f9SKrishna Gudipati 
3358a36c61f9SKrishna Gudipati 	if (__fcs_min_cfg(rport->port->fcs))
3359a36c61f9SKrishna Gudipati 		return;
3360a36c61f9SKrishna Gudipati 
3361a36c61f9SKrishna Gudipati 	rport->rpf.rpsc_speed = 0;
3362a36c61f9SKrishna Gudipati 	bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE);
3363a36c61f9SKrishna Gudipati }
3364a36c61f9SKrishna Gudipati 
3365a36c61f9SKrishna Gudipati static void
3366a36c61f9SKrishna Gudipati bfa_fcs_rpf_timeout(void *arg)
3367a36c61f9SKrishna Gudipati {
3368a36c61f9SKrishna Gudipati 	struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg;
3369a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3370a36c61f9SKrishna Gudipati 
3371a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3372a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rpf, RPFSM_EVENT_TIMEOUT);
3373a36c61f9SKrishna Gudipati }
3374a36c61f9SKrishna Gudipati 
3375a36c61f9SKrishna Gudipati static void
3376a36c61f9SKrishna Gudipati bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3377a36c61f9SKrishna Gudipati {
3378a36c61f9SKrishna Gudipati 	struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg;
3379a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3380a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
3381a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
3382a36c61f9SKrishna Gudipati 	int		len;
3383a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
3384a36c61f9SKrishna Gudipati 
3385a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
3386a36c61f9SKrishna Gudipati 
3387c3f1b123SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced :
3388c3f1b123SKrishna Gudipati 	       bfa_fcs_fcxp_alloc(port->fcs, BFA_TRUE);
3389a36c61f9SKrishna Gudipati 	if (!fcxp) {
3390a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe,
3391c3f1b123SKrishna Gudipati 				bfa_fcs_rpf_send_rpsc2, rpf, BFA_TRUE);
3392a36c61f9SKrishna Gudipati 		return;
3393a36c61f9SKrishna Gudipati 	}
3394a36c61f9SKrishna Gudipati 	rpf->fcxp = fcxp;
3395a36c61f9SKrishna Gudipati 
3396a36c61f9SKrishna Gudipati 	len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
3397a36c61f9SKrishna Gudipati 			    bfa_fcs_lport_get_fcid(port), &rport->pid, 1);
3398a36c61f9SKrishna Gudipati 
3399a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3400a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response,
3401a36c61f9SKrishna Gudipati 			  rpf, FC_MAX_PDUSZ, FC_ELS_TOV);
3402a36c61f9SKrishna Gudipati 	rport->stats.rpsc_sent++;
3403a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT);
3404a36c61f9SKrishna Gudipati 
3405a36c61f9SKrishna Gudipati }
3406a36c61f9SKrishna Gudipati 
3407a36c61f9SKrishna Gudipati static void
3408a36c61f9SKrishna Gudipati bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
3409a36c61f9SKrishna Gudipati 			    bfa_status_t req_status, u32 rsp_len,
3410a36c61f9SKrishna Gudipati 			    u32 resid_len, struct fchs_s *rsp_fchs)
3411a36c61f9SKrishna Gudipati {
3412a36c61f9SKrishna Gudipati 	struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg;
3413a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3414a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s *ls_rjt;
3415a36c61f9SKrishna Gudipati 	struct fc_rpsc2_acc_s *rpsc2_acc;
3416a36c61f9SKrishna Gudipati 	u16	num_ents;
3417a36c61f9SKrishna Gudipati 
3418a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, req_status);
3419a36c61f9SKrishna Gudipati 
3420a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
3421a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, req_status);
3422a36c61f9SKrishna Gudipati 		if (req_status == BFA_STATUS_ETIMER)
3423a36c61f9SKrishna Gudipati 			rport->stats.rpsc_failed++;
3424a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3425a36c61f9SKrishna Gudipati 		return;
3426a36c61f9SKrishna Gudipati 	}
3427a36c61f9SKrishna Gudipati 
3428a36c61f9SKrishna Gudipati 	rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp);
3429a36c61f9SKrishna Gudipati 	if (rpsc2_acc->els_cmd == FC_ELS_ACC) {
3430a36c61f9SKrishna Gudipati 		rport->stats.rpsc_accs++;
3431ba816ea8SJing Huang 		num_ents = be16_to_cpu(rpsc2_acc->num_pids);
3432a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, num_ents);
3433a36c61f9SKrishna Gudipati 		if (num_ents > 0) {
343436ec9712SVijaya Mohan Guvva 			WARN_ON(be32_to_cpu(rpsc2_acc->port_info[0].pid) !=
343536ec9712SVijaya Mohan Guvva 						bfa_ntoh3b(rport->pid));
3436a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs,
343736ec9712SVijaya Mohan Guvva 				be32_to_cpu(rpsc2_acc->port_info[0].pid));
3438a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs,
3439ba816ea8SJing Huang 				be16_to_cpu(rpsc2_acc->port_info[0].speed));
3440a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs,
3441ba816ea8SJing Huang 				be16_to_cpu(rpsc2_acc->port_info[0].index));
3442a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs,
3443a36c61f9SKrishna Gudipati 				rpsc2_acc->port_info[0].type);
3444a36c61f9SKrishna Gudipati 
3445a36c61f9SKrishna Gudipati 			if (rpsc2_acc->port_info[0].speed == 0) {
3446a36c61f9SKrishna Gudipati 				bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3447a36c61f9SKrishna Gudipati 				return;
3448a36c61f9SKrishna Gudipati 			}
3449a36c61f9SKrishna Gudipati 
3450a36c61f9SKrishna Gudipati 			rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed(
3451ba816ea8SJing Huang 				be16_to_cpu(rpsc2_acc->port_info[0].speed));
3452a36c61f9SKrishna Gudipati 
3453a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP);
3454a36c61f9SKrishna Gudipati 		}
3455a36c61f9SKrishna Gudipati 	} else {
3456a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3457a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, ls_rjt->reason_code);
3458a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
3459a36c61f9SKrishna Gudipati 		rport->stats.rpsc_rejects++;
3460a36c61f9SKrishna Gudipati 		if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP)
3461a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL);
3462a36c61f9SKrishna Gudipati 		else
3463a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3464a36c61f9SKrishna Gudipati 	}
3465a36c61f9SKrishna Gudipati }
3466