xref: /openbmc/linux/drivers/scsi/bfa/bfa_fcs_rport.c (revision 60138066)
1a36c61f9SKrishna Gudipati /*
2a36c61f9SKrishna Gudipati  * Copyright (c) 2005-2010 Brocade Communications Systems, Inc.
3a36c61f9SKrishna Gudipati  * All rights reserved
4a36c61f9SKrishna Gudipati  * www.brocade.com
5a36c61f9SKrishna Gudipati  *
6a36c61f9SKrishna Gudipati  * Linux driver for Brocade Fibre Channel Host Bus Adapter.
7a36c61f9SKrishna Gudipati  *
8a36c61f9SKrishna Gudipati  * This program is free software; you can redistribute it and/or modify it
9a36c61f9SKrishna Gudipati  * under the terms of the GNU General Public License (GPL) Version 2 as
10a36c61f9SKrishna Gudipati  * published by the Free Software Foundation
11a36c61f9SKrishna Gudipati  *
12a36c61f9SKrishna Gudipati  * This program is distributed in the hope that it will be useful, but
13a36c61f9SKrishna Gudipati  * WITHOUT ANY WARRANTY; without even the implied warranty of
14a36c61f9SKrishna Gudipati  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15a36c61f9SKrishna Gudipati  * General Public License for more details.
16a36c61f9SKrishna Gudipati  */
17a36c61f9SKrishna Gudipati 
185fbe25c7SJing Huang /*
19a36c61f9SKrishna Gudipati  *  rport.c Remote port implementation.
20a36c61f9SKrishna Gudipati  */
21a36c61f9SKrishna Gudipati 
22f16a1750SMaggie Zhang #include "bfad_drv.h"
23a36c61f9SKrishna Gudipati #include "bfa_fcs.h"
24a36c61f9SKrishna Gudipati #include "bfa_fcbuild.h"
25a36c61f9SKrishna Gudipati 
26a36c61f9SKrishna Gudipati BFA_TRC_FILE(FCS, RPORT);
27a36c61f9SKrishna Gudipati 
28a36c61f9SKrishna Gudipati static u32
29a36c61f9SKrishna Gudipati bfa_fcs_rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT * 1000;
30a36c61f9SKrishna Gudipati 	 /* In millisecs */
31a36c61f9SKrishna Gudipati /*
32a36c61f9SKrishna Gudipati  * forward declarations
33a36c61f9SKrishna Gudipati  */
34a36c61f9SKrishna Gudipati static struct bfa_fcs_rport_s *bfa_fcs_rport_alloc(
35a36c61f9SKrishna Gudipati 		struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid);
36a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport);
37a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport);
38a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport);
39a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport);
40a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport,
41a36c61f9SKrishna Gudipati 					struct fc_logi_s *plogi);
42a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_timeout(void *arg);
43a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_plogi(void *rport_cbarg,
44a36c61f9SKrishna Gudipati 					 struct bfa_fcxp_s *fcxp_alloced);
45a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_plogiacc(void *rport_cbarg,
46a36c61f9SKrishna Gudipati 					struct bfa_fcxp_s *fcxp_alloced);
47a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_plogi_response(void *fcsarg,
48a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp, void *cbarg,
49a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
50a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs);
51a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_adisc(void *rport_cbarg,
52a36c61f9SKrishna Gudipati 					 struct bfa_fcxp_s *fcxp_alloced);
53a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_adisc_response(void *fcsarg,
54a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp, void *cbarg,
55a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
56a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs);
57a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_nsdisc(void *rport_cbarg,
58a36c61f9SKrishna Gudipati 					 struct bfa_fcxp_s *fcxp_alloced);
59a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_gidpn_response(void *fcsarg,
60a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp, void *cbarg,
61a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
62a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs);
63a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_gpnid_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_logo(void *rport_cbarg,
68a36c61f9SKrishna Gudipati 					struct bfa_fcxp_s *fcxp_alloced);
69a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_logo_acc(void *rport_cbarg);
70a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
71a36c61f9SKrishna Gudipati 					struct fchs_s *rx_fchs, u16 len);
72a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport,
73a36c61f9SKrishna Gudipati 				struct fchs_s *rx_fchs, u8 reason_code,
74a36c61f9SKrishna Gudipati 					  u8 reason_code_expl);
75a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
76a36c61f9SKrishna Gudipati 				struct fchs_s *rx_fchs, u16 len);
77a36c61f9SKrishna Gudipati static void bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport);
78a36c61f9SKrishna Gudipati 
79a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport,
80a36c61f9SKrishna Gudipati 					enum rport_event event);
81a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
82a36c61f9SKrishna Gudipati 						enum rport_event event);
83a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
84a36c61f9SKrishna Gudipati 						  enum rport_event event);
85a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
86a36c61f9SKrishna Gudipati 						enum rport_event event);
87a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport,
88a36c61f9SKrishna Gudipati 					enum rport_event event);
89a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
90a36c61f9SKrishna Gudipati 						enum rport_event event);
91a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport,
92a36c61f9SKrishna Gudipati 					enum rport_event event);
93a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
94a36c61f9SKrishna Gudipati 						 enum rport_event event);
95a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport,
96a36c61f9SKrishna Gudipati 					 enum rport_event event);
97a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
98a36c61f9SKrishna Gudipati 						enum rport_event event);
99a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport,
100a36c61f9SKrishna Gudipati 					enum rport_event event);
101a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
102a36c61f9SKrishna Gudipati 						enum rport_event event);
103a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
104a36c61f9SKrishna Gudipati 						enum rport_event event);
105a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
106a36c61f9SKrishna Gudipati 						enum rport_event event);
107a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
108a36c61f9SKrishna Gudipati 						enum rport_event event);
109a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
110a36c61f9SKrishna Gudipati 						enum rport_event event);
111a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
112a36c61f9SKrishna Gudipati 						enum rport_event event);
113a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
114a36c61f9SKrishna Gudipati 						enum rport_event event);
115a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport,
116a36c61f9SKrishna Gudipati 					 enum rport_event event);
117a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
118a36c61f9SKrishna Gudipati 						enum rport_event event);
119a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
120a36c61f9SKrishna Gudipati 						enum rport_event event);
121a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
122a36c61f9SKrishna Gudipati 						enum rport_event event);
123a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
124a36c61f9SKrishna Gudipati 						enum rport_event event);
125a36c61f9SKrishna Gudipati 
126a36c61f9SKrishna Gudipati static struct bfa_sm_table_s rport_sm_table[] = {
127a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT},
128a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_plogi_sending), BFA_RPORT_PLOGI},
129a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE},
130a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY},
131a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI},
132a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE},
133a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE},
134a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY},
135a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY},
136a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_adisc_sending), BFA_RPORT_ADISC},
137a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_adisc), BFA_RPORT_ADISC},
138a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV},
139a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO},
140a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE},
141a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_hcb_offline), BFA_RPORT_OFFLINE},
142a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_hcb_logorcv), BFA_RPORT_LOGORCV},
143a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_hcb_logosend), BFA_RPORT_LOGO},
144a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_logo_sending), BFA_RPORT_LOGO},
145a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_offline), BFA_RPORT_OFFLINE},
146a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsdisc_sending), BFA_RPORT_NSDISC},
147a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsdisc_retry), BFA_RPORT_NSDISC},
148a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsdisc_sent), BFA_RPORT_NSDISC},
149a36c61f9SKrishna Gudipati };
150a36c61f9SKrishna Gudipati 
1515fbe25c7SJing Huang /*
152a36c61f9SKrishna Gudipati  *		Beginning state.
153a36c61f9SKrishna Gudipati  */
154a36c61f9SKrishna Gudipati static void
155a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event)
156a36c61f9SKrishna Gudipati {
157a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
158a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
159a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
160a36c61f9SKrishna Gudipati 
161a36c61f9SKrishna Gudipati 	switch (event) {
162a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_SEND:
163a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
164a36c61f9SKrishna Gudipati 		rport->plogi_retries = 0;
165a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogi(rport, NULL);
166a36c61f9SKrishna Gudipati 		break;
167a36c61f9SKrishna Gudipati 
168a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
169a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
170a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
171a36c61f9SKrishna Gudipati 		break;
172a36c61f9SKrishna Gudipati 
173a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
174a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
175a36c61f9SKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
176a36c61f9SKrishna Gudipati 		break;
177a36c61f9SKrishna Gudipati 
178a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
179a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_DISC:
180a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
181a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
182a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
183a36c61f9SKrishna Gudipati 		break;
184a36c61f9SKrishna Gudipati 	default:
185a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
186a36c61f9SKrishna Gudipati 	}
187a36c61f9SKrishna Gudipati }
188a36c61f9SKrishna Gudipati 
1895fbe25c7SJing Huang /*
190a36c61f9SKrishna Gudipati  *		PLOGI is being sent.
191a36c61f9SKrishna Gudipati  */
192a36c61f9SKrishna Gudipati static void
193a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
194a36c61f9SKrishna Gudipati 	 enum rport_event event)
195a36c61f9SKrishna Gudipati {
196a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
197a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
198a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
199a36c61f9SKrishna Gudipati 
200a36c61f9SKrishna Gudipati 	switch (event) {
201a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
202a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi);
203a36c61f9SKrishna Gudipati 		break;
204a36c61f9SKrishna Gudipati 
205a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
206a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
207a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
208a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
209a36c61f9SKrishna Gudipati 		break;
210a36c61f9SKrishna Gudipati 
211a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
212a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
213a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
214a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
215a36c61f9SKrishna Gudipati 		break;
216a36c61f9SKrishna Gudipati 
217a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
218a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
219a36c61f9SKrishna Gudipati 		/* query the NS */
220a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
221a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
222a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
223a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
224a36c61f9SKrishna Gudipati 		break;
225a36c61f9SKrishna Gudipati 
226a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
227a36c61f9SKrishna Gudipati 		rport->pid = 0;
228a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
229a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
230a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
231a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
232a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
233a36c61f9SKrishna Gudipati 		break;
234a36c61f9SKrishna Gudipati 
235a36c61f9SKrishna Gudipati 
236a36c61f9SKrishna Gudipati 	default:
237a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
238a36c61f9SKrishna Gudipati 	}
239a36c61f9SKrishna Gudipati }
240a36c61f9SKrishna Gudipati 
2415fbe25c7SJing Huang /*
242a36c61f9SKrishna Gudipati  *		PLOGI is being sent.
243a36c61f9SKrishna Gudipati  */
244a36c61f9SKrishna Gudipati static void
245a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
246a36c61f9SKrishna Gudipati 	 enum rport_event event)
247a36c61f9SKrishna Gudipati {
248a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
249a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
250a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
251a36c61f9SKrishna Gudipati 
252a36c61f9SKrishna Gudipati 	switch (event) {
253a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
254a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
255a36c61f9SKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
256a36c61f9SKrishna Gudipati 		break;
257a36c61f9SKrishna Gudipati 
258a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
259a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
260a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
261a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
262a36c61f9SKrishna Gudipati 		break;
263a36c61f9SKrishna Gudipati 
264a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
265d7be54ccSKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
266a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
2675fbe25c7SJing Huang 		/*
268a36c61f9SKrishna Gudipati 		 * Ignore, SCN is possibly online notification.
269a36c61f9SKrishna Gudipati 		 */
270a36c61f9SKrishna Gudipati 		break;
271a36c61f9SKrishna Gudipati 
272a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
273a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
274a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
275a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
276a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
277a36c61f9SKrishna Gudipati 		break;
278a36c61f9SKrishna Gudipati 
279a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
280a36c61f9SKrishna Gudipati 		rport->pid = 0;
281a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
282a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
283a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
284a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
285a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
286a36c61f9SKrishna Gudipati 		break;
287a36c61f9SKrishna Gudipati 
288a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
2895fbe25c7SJing Huang 		/*
290a36c61f9SKrishna Gudipati 		 * Ignore BFA callback, on a PLOGI receive we call bfa offline.
291a36c61f9SKrishna Gudipati 		 */
292a36c61f9SKrishna Gudipati 		break;
293a36c61f9SKrishna Gudipati 
294a36c61f9SKrishna Gudipati 	default:
295a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
296a36c61f9SKrishna Gudipati 	}
297a36c61f9SKrishna Gudipati }
298a36c61f9SKrishna Gudipati 
2995fbe25c7SJing Huang /*
300a36c61f9SKrishna Gudipati  *		PLOGI is sent.
301a36c61f9SKrishna Gudipati  */
302a36c61f9SKrishna Gudipati static void
303a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
304a36c61f9SKrishna Gudipati 			enum rport_event event)
305a36c61f9SKrishna Gudipati {
306a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
307a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
308a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
309a36c61f9SKrishna Gudipati 
310a36c61f9SKrishna Gudipati 	switch (event) {
311a36c61f9SKrishna Gudipati 	case RPSM_EVENT_TIMEOUT:
312a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
313a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogi(rport, NULL);
314a36c61f9SKrishna Gudipati 		break;
315a36c61f9SKrishna Gudipati 
316a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
317a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
318a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
319a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
320a36c61f9SKrishna Gudipati 		break;
321a36c61f9SKrishna Gudipati 
322a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
323a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
324a36c61f9SKrishna Gudipati 		break;
325a36c61f9SKrishna Gudipati 
326a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
327a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
328a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
329a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
330a36c61f9SKrishna Gudipati 		break;
331a36c61f9SKrishna Gudipati 
332a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
333a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
334a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
335a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
336a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
337a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
338a36c61f9SKrishna Gudipati 		break;
339a36c61f9SKrishna Gudipati 
340a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
341a36c61f9SKrishna Gudipati 		rport->pid = 0;
342a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
343a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
344a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
345a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
346a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
347a36c61f9SKrishna Gudipati 		break;
348a36c61f9SKrishna Gudipati 
349a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
350a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
351a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
352a36c61f9SKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
353a36c61f9SKrishna Gudipati 		break;
354a36c61f9SKrishna Gudipati 
355a36c61f9SKrishna Gudipati 	default:
356a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
357a36c61f9SKrishna Gudipati 	}
358a36c61f9SKrishna Gudipati }
359a36c61f9SKrishna Gudipati 
3605fbe25c7SJing Huang /*
361a36c61f9SKrishna Gudipati  *		PLOGI is sent.
362a36c61f9SKrishna Gudipati  */
363a36c61f9SKrishna Gudipati static void
364a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
365a36c61f9SKrishna Gudipati {
366a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
367a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
368a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
369a36c61f9SKrishna Gudipati 
370a36c61f9SKrishna Gudipati 	switch (event) {
371a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ACCEPTED:
372a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
373a36c61f9SKrishna Gudipati 		rport->plogi_retries = 0;
374a36c61f9SKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
375a36c61f9SKrishna Gudipati 		break;
376a36c61f9SKrishna Gudipati 
377a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
378a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
379a36c61f9SKrishna Gudipati 		/*
380a36c61f9SKrishna Gudipati 		 * !! fall through !!
381a36c61f9SKrishna Gudipati 		 */
382a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
383a36c61f9SKrishna Gudipati 		if (rport->prlo == BFA_TRUE)
384a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
385a36c61f9SKrishna Gudipati 
386a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
387a36c61f9SKrishna Gudipati 		/*
388a36c61f9SKrishna Gudipati 		 * !! fall through !!
389a36c61f9SKrishna Gudipati 		 */
390a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FAILED:
391a36c61f9SKrishna Gudipati 		if (rport->plogi_retries < BFA_FCS_RPORT_MAX_RETRIES) {
392a36c61f9SKrishna Gudipati 			rport->plogi_retries++;
393a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
394a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
395a36c61f9SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
396a36c61f9SKrishna Gudipati 					BFA_FCS_RETRY_TIMEOUT);
397a36c61f9SKrishna Gudipati 		} else {
398a36c61f9SKrishna Gudipati 			bfa_stats(rport->port, rport_del_max_plogi_retry);
399a36c61f9SKrishna Gudipati 			rport->pid = 0;
400a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
401a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
402a36c61f9SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
403a36c61f9SKrishna Gudipati 					bfa_fcs_rport_del_timeout);
404a36c61f9SKrishna Gudipati 		}
405a36c61f9SKrishna Gudipati 		break;
406a36c61f9SKrishna Gudipati 
407a36c61f9SKrishna Gudipati 	case	RPSM_EVENT_PLOGI_RETRY:
408a36c61f9SKrishna Gudipati 		rport->plogi_retries = 0;
409a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
410a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
411a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
412a36c61f9SKrishna Gudipati 				(FC_RA_TOV * 1000));
413a36c61f9SKrishna Gudipati 		break;
414a36c61f9SKrishna Gudipati 
415a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
416a36c61f9SKrishna Gudipati 		rport->pid = 0;
417a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
418a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
419a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
420a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
421a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
422a36c61f9SKrishna Gudipati 		break;
423a36c61f9SKrishna Gudipati 
424a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
425a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
426a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
427a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
428a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
429a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
430a36c61f9SKrishna Gudipati 		break;
431a36c61f9SKrishna Gudipati 
432a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
433a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
434a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
435a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
436a36c61f9SKrishna Gudipati 		break;
437a36c61f9SKrishna Gudipati 
438a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
439a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
440a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
441a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
442a36c61f9SKrishna Gudipati 		break;
443a36c61f9SKrishna Gudipati 
444a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
445a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
446a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
447a36c61f9SKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
448a36c61f9SKrishna Gudipati 		break;
449a36c61f9SKrishna Gudipati 
450a36c61f9SKrishna Gudipati 	default:
451a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
452a36c61f9SKrishna Gudipati 	}
453a36c61f9SKrishna Gudipati }
454a36c61f9SKrishna Gudipati 
4555fbe25c7SJing Huang /*
456a36c61f9SKrishna Gudipati  *		PLOGI is complete. Awaiting BFA rport online callback. FC-4s
457a36c61f9SKrishna Gudipati  *		are offline.
458a36c61f9SKrishna Gudipati  */
459a36c61f9SKrishna Gudipati static void
460a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
461a36c61f9SKrishna Gudipati 			enum rport_event event)
462a36c61f9SKrishna Gudipati {
463a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
464a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
465a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
466a36c61f9SKrishna Gudipati 
467a36c61f9SKrishna Gudipati 	switch (event) {
468a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_ONLINE:
469a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
470a36c61f9SKrishna Gudipati 		bfa_fcs_rport_online_action(rport);
471a36c61f9SKrishna Gudipati 		break;
472a36c61f9SKrishna Gudipati 
473a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
474d7be54ccSKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
475a36c61f9SKrishna Gudipati 		break;
476a36c61f9SKrishna Gudipati 
477a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
478a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
479f7f73812SMaggie Zhang 		bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
480a36c61f9SKrishna Gudipati 		break;
481a36c61f9SKrishna Gudipati 
482a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
483a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
484a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
485f7f73812SMaggie Zhang 		bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
486a36c61f9SKrishna Gudipati 		break;
487a36c61f9SKrishna Gudipati 
488a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
489d7be54ccSKrishna Gudipati 		rport->plogi_pending = BFA_TRUE;
490d7be54ccSKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
491f7f73812SMaggie Zhang 		bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
492a36c61f9SKrishna Gudipati 		break;
493a36c61f9SKrishna Gudipati 
494a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
495a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
496f7f73812SMaggie Zhang 		bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
497a36c61f9SKrishna Gudipati 		break;
498a36c61f9SKrishna Gudipati 
499a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
5005fbe25c7SJing Huang 		/*
501a36c61f9SKrishna Gudipati 		 * @todo
502a36c61f9SKrishna Gudipati 		 * Ignore SCN - PLOGI just completed, FC-4 login should detect
503a36c61f9SKrishna Gudipati 		 * device failures.
504a36c61f9SKrishna Gudipati 		 */
505a36c61f9SKrishna Gudipati 		break;
506a36c61f9SKrishna Gudipati 
507a36c61f9SKrishna Gudipati 	default:
508a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
509a36c61f9SKrishna Gudipati 	}
510a36c61f9SKrishna Gudipati }
511a36c61f9SKrishna Gudipati 
5125fbe25c7SJing Huang /*
513a36c61f9SKrishna Gudipati  *		Rport is ONLINE. FC-4s active.
514a36c61f9SKrishna Gudipati  */
515a36c61f9SKrishna Gudipati static void
516a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
517a36c61f9SKrishna Gudipati {
518a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
519a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
520a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
521a36c61f9SKrishna Gudipati 
522a36c61f9SKrishna Gudipati 	switch (event) {
523a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
524a36c61f9SKrishna Gudipati 		if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
525a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
526a36c61f9SKrishna Gudipati 					 bfa_fcs_rport_sm_nsquery_sending);
527a36c61f9SKrishna Gudipati 			rport->ns_retries = 0;
528a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
529a36c61f9SKrishna Gudipati 		} else {
530a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
531a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_adisc(rport, NULL);
532a36c61f9SKrishna Gudipati 		}
533a36c61f9SKrishna Gudipati 		break;
534a36c61f9SKrishna Gudipati 
535a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
536a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
537a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
538a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
539a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
540a36c61f9SKrishna Gudipati 		break;
541a36c61f9SKrishna Gudipati 
542a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
543a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
544a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
545a36c61f9SKrishna Gudipati 		break;
546a36c61f9SKrishna Gudipati 
547a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
548a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
549a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
550a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
551a36c61f9SKrishna Gudipati 		break;
552a36c61f9SKrishna Gudipati 
553a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
554a36c61f9SKrishna Gudipati 		break;
555a36c61f9SKrishna Gudipati 
556a36c61f9SKrishna Gudipati 	default:
557a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
558a36c61f9SKrishna Gudipati 	}
559a36c61f9SKrishna Gudipati }
560a36c61f9SKrishna Gudipati 
5615fbe25c7SJing Huang /*
562a36c61f9SKrishna Gudipati  *		An SCN event is received in ONLINE state. NS query is being sent
563a36c61f9SKrishna Gudipati  *		prior to ADISC authentication with rport. FC-4s are paused.
564a36c61f9SKrishna Gudipati  */
565a36c61f9SKrishna Gudipati static void
566a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
567a36c61f9SKrishna Gudipati 	 enum rport_event event)
568a36c61f9SKrishna Gudipati {
569a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
570a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
571a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
572a36c61f9SKrishna Gudipati 
573a36c61f9SKrishna Gudipati 	switch (event) {
574a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
575a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsquery);
576a36c61f9SKrishna Gudipati 		break;
577a36c61f9SKrishna Gudipati 
578a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
579a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
580a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
581a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
582a36c61f9SKrishna Gudipati 		break;
583a36c61f9SKrishna Gudipati 
584a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
5855fbe25c7SJing Huang 		/*
586a36c61f9SKrishna Gudipati 		 * ignore SCN, wait for response to query itself
587a36c61f9SKrishna Gudipati 		 */
588a36c61f9SKrishna Gudipati 		break;
589a36c61f9SKrishna Gudipati 
590a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
591a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
592a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
593a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
594a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
595a36c61f9SKrishna Gudipati 		break;
596a36c61f9SKrishna Gudipati 
597a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
598a36c61f9SKrishna Gudipati 		rport->pid = 0;
599a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
600a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
601a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
602a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
603a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
604a36c61f9SKrishna Gudipati 		break;
605a36c61f9SKrishna Gudipati 
606a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
607a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
608a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
609a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
610a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
611a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
612a36c61f9SKrishna Gudipati 		break;
613a36c61f9SKrishna Gudipati 
614a36c61f9SKrishna Gudipati 	default:
615a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
616a36c61f9SKrishna Gudipati 	}
617a36c61f9SKrishna Gudipati }
618a36c61f9SKrishna Gudipati 
6195fbe25c7SJing Huang /*
620a36c61f9SKrishna Gudipati  *	An SCN event is received in ONLINE state. NS query is sent to rport.
621a36c61f9SKrishna Gudipati  *	FC-4s are paused.
622a36c61f9SKrishna Gudipati  */
623a36c61f9SKrishna Gudipati static void
624a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
625a36c61f9SKrishna Gudipati {
626a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
627a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
628a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
629a36c61f9SKrishna Gudipati 
630a36c61f9SKrishna Gudipati 	switch (event) {
631a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ACCEPTED:
632a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
633a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_adisc(rport, NULL);
634a36c61f9SKrishna Gudipati 		break;
635a36c61f9SKrishna Gudipati 
636a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FAILED:
637a36c61f9SKrishna Gudipati 		rport->ns_retries++;
638a36c61f9SKrishna Gudipati 		if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
639a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
640a36c61f9SKrishna Gudipati 					 bfa_fcs_rport_sm_nsquery_sending);
641a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
642a36c61f9SKrishna Gudipati 		} else {
643a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
644a36c61f9SKrishna Gudipati 			bfa_fcs_rport_offline_action(rport);
645a36c61f9SKrishna Gudipati 		}
646a36c61f9SKrishna Gudipati 		break;
647a36c61f9SKrishna Gudipati 
648a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
649a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
650a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
651a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
652a36c61f9SKrishna Gudipati 		break;
653a36c61f9SKrishna Gudipati 
654a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
655a36c61f9SKrishna Gudipati 		break;
656a36c61f9SKrishna Gudipati 
657a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
658a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
659a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
660a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
661a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
662a36c61f9SKrishna Gudipati 		break;
663a36c61f9SKrishna Gudipati 
664a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
665a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
666a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
667a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
668a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
669a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
670a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
671a36c61f9SKrishna Gudipati 		break;
672a36c61f9SKrishna Gudipati 
673a36c61f9SKrishna Gudipati 	default:
674a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
675a36c61f9SKrishna Gudipati 	}
676a36c61f9SKrishna Gudipati }
677a36c61f9SKrishna Gudipati 
6785fbe25c7SJing Huang /*
679a36c61f9SKrishna Gudipati  *	An SCN event is received in ONLINE state. ADISC is being sent for
680a36c61f9SKrishna Gudipati  *	authenticating with rport. FC-4s are paused.
681a36c61f9SKrishna Gudipati  */
682a36c61f9SKrishna Gudipati static void
683a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
684a36c61f9SKrishna Gudipati 	 enum rport_event event)
685a36c61f9SKrishna Gudipati {
686a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
687a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
688a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
689a36c61f9SKrishna Gudipati 
690a36c61f9SKrishna Gudipati 	switch (event) {
691a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
692a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc);
693a36c61f9SKrishna Gudipati 		break;
694a36c61f9SKrishna Gudipati 
695a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
696a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
697a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
698a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
699a36c61f9SKrishna Gudipati 		break;
700a36c61f9SKrishna Gudipati 
701a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
702a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
703a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
704a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
705a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
706a36c61f9SKrishna Gudipati 		break;
707a36c61f9SKrishna Gudipati 
708a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
709a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
710a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
711a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
712a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
713a36c61f9SKrishna Gudipati 		break;
714a36c61f9SKrishna Gudipati 
715a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
716a36c61f9SKrishna Gudipati 		break;
717a36c61f9SKrishna Gudipati 
718a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
719a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
720a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
721a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
722a36c61f9SKrishna Gudipati 		break;
723a36c61f9SKrishna Gudipati 
724a36c61f9SKrishna Gudipati 	default:
725a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
726a36c61f9SKrishna Gudipati 	}
727a36c61f9SKrishna Gudipati }
728a36c61f9SKrishna Gudipati 
7295fbe25c7SJing Huang /*
730a36c61f9SKrishna Gudipati  *		An SCN event is received in ONLINE state. ADISC is to rport.
731a36c61f9SKrishna Gudipati  *		FC-4s are paused.
732a36c61f9SKrishna Gudipati  */
733a36c61f9SKrishna Gudipati static void
734a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
735a36c61f9SKrishna Gudipati {
736a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
737a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
738a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
739a36c61f9SKrishna Gudipati 
740a36c61f9SKrishna Gudipati 	switch (event) {
741a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ACCEPTED:
742a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
743a36c61f9SKrishna Gudipati 		break;
744a36c61f9SKrishna Gudipati 
745a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
7465fbe25c7SJing Huang 		/*
747a36c61f9SKrishna Gudipati 		 * Too complex to cleanup FC-4 & rport and then acc to PLOGI.
748a36c61f9SKrishna Gudipati 		 * At least go offline when a PLOGI is received.
749a36c61f9SKrishna Gudipati 		 */
750a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
751a36c61f9SKrishna Gudipati 		/*
752a36c61f9SKrishna Gudipati 		 * !!! fall through !!!
753a36c61f9SKrishna Gudipati 		 */
754a36c61f9SKrishna Gudipati 
755a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FAILED:
756a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
757a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
758a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
759a36c61f9SKrishna Gudipati 		break;
760a36c61f9SKrishna Gudipati 
761a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
762a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
763a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
764a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
765a36c61f9SKrishna Gudipati 		break;
766a36c61f9SKrishna Gudipati 
767a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
7685fbe25c7SJing Huang 		/*
769a36c61f9SKrishna Gudipati 		 * already processing RSCN
770a36c61f9SKrishna Gudipati 		 */
771a36c61f9SKrishna Gudipati 		break;
772a36c61f9SKrishna Gudipati 
773a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
774a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
775a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
776a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
777a36c61f9SKrishna Gudipati 		break;
778a36c61f9SKrishna Gudipati 
779a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
780a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
781a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
782a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
783a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
784a36c61f9SKrishna Gudipati 		break;
785a36c61f9SKrishna Gudipati 
786a36c61f9SKrishna Gudipati 	default:
787a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
788a36c61f9SKrishna Gudipati 	}
789a36c61f9SKrishna Gudipati }
790a36c61f9SKrishna Gudipati 
7915fbe25c7SJing Huang /*
792a36c61f9SKrishna Gudipati  *		Rport has sent LOGO. Awaiting FC-4 offline completion callback.
793a36c61f9SKrishna Gudipati  */
794a36c61f9SKrishna Gudipati static void
795a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
796a36c61f9SKrishna Gudipati 			enum rport_event event)
797a36c61f9SKrishna Gudipati {
798a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
799a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
800a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
801a36c61f9SKrishna Gudipati 
802a36c61f9SKrishna Gudipati 	switch (event) {
803a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FC4_OFFLINE:
804a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
805f7f73812SMaggie Zhang 		bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
806a36c61f9SKrishna Gudipati 		break;
807a36c61f9SKrishna Gudipati 
808a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
809a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
810a36c61f9SKrishna Gudipati 		break;
811a36c61f9SKrishna Gudipati 
812a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
813a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
814a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
815a36c61f9SKrishna Gudipati 		break;
816a36c61f9SKrishna Gudipati 
817a36c61f9SKrishna Gudipati 	default:
818a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
819a36c61f9SKrishna Gudipati 	}
820a36c61f9SKrishna Gudipati }
821a36c61f9SKrishna Gudipati 
8225fbe25c7SJing Huang /*
823a36c61f9SKrishna Gudipati  *		LOGO needs to be sent to rport. Awaiting FC-4 offline completion
824a36c61f9SKrishna Gudipati  *		callback.
825a36c61f9SKrishna Gudipati  */
826a36c61f9SKrishna Gudipati static void
827a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
828a36c61f9SKrishna Gudipati 	 enum rport_event event)
829a36c61f9SKrishna Gudipati {
830a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
831a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
832a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
833a36c61f9SKrishna Gudipati 
834a36c61f9SKrishna Gudipati 	switch (event) {
835a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FC4_OFFLINE:
836a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
837f7f73812SMaggie Zhang 		bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
838a36c61f9SKrishna Gudipati 		break;
839a36c61f9SKrishna Gudipati 
840a36c61f9SKrishna Gudipati 	default:
841a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
842a36c61f9SKrishna Gudipati 	}
843a36c61f9SKrishna Gudipati }
844a36c61f9SKrishna Gudipati 
8455fbe25c7SJing Huang /*
846a36c61f9SKrishna Gudipati  *	Rport is going offline. Awaiting FC-4 offline completion callback.
847a36c61f9SKrishna Gudipati  */
848a36c61f9SKrishna Gudipati static void
849a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
850a36c61f9SKrishna Gudipati 			enum rport_event event)
851a36c61f9SKrishna Gudipati {
852a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
853a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
854a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
855a36c61f9SKrishna Gudipati 
856a36c61f9SKrishna Gudipati 	switch (event) {
857a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FC4_OFFLINE:
858a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
859f7f73812SMaggie Zhang 		bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_OFFLINE);
860a36c61f9SKrishna Gudipati 		break;
861a36c61f9SKrishna Gudipati 
862a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
863a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
864a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
865a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
866a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
8675fbe25c7SJing Huang 		/*
868a36c61f9SKrishna Gudipati 		 * rport is already going offline.
869a36c61f9SKrishna Gudipati 		 * SCN - ignore and wait till transitioning to offline state
870a36c61f9SKrishna Gudipati 		 */
871a36c61f9SKrishna Gudipati 		break;
872a36c61f9SKrishna Gudipati 
873a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
874a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
875a36c61f9SKrishna Gudipati 		break;
876a36c61f9SKrishna Gudipati 
877a36c61f9SKrishna Gudipati 	default:
878a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
879a36c61f9SKrishna Gudipati 	}
880a36c61f9SKrishna Gudipati }
881a36c61f9SKrishna Gudipati 
8825fbe25c7SJing Huang /*
883a36c61f9SKrishna Gudipati  *		Rport is offline. FC-4s are offline. Awaiting BFA rport offline
884a36c61f9SKrishna Gudipati  *		callback.
885a36c61f9SKrishna Gudipati  */
886a36c61f9SKrishna Gudipati static void
887a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
888a36c61f9SKrishna Gudipati 				enum rport_event event)
889a36c61f9SKrishna Gudipati {
890a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
891a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
892a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
893a36c61f9SKrishna Gudipati 
894a36c61f9SKrishna Gudipati 	switch (event) {
895a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
896d7be54ccSKrishna Gudipati 		if (bfa_fcs_lport_is_online(rport->port) &&
897d7be54ccSKrishna Gudipati 		    (rport->plogi_pending)) {
898d7be54ccSKrishna Gudipati 			rport->plogi_pending = BFA_FALSE;
899d7be54ccSKrishna Gudipati 			bfa_sm_set_state(rport,
900d7be54ccSKrishna Gudipati 				bfa_fcs_rport_sm_plogiacc_sending);
901d7be54ccSKrishna Gudipati 			bfa_fcs_rport_send_plogiacc(rport, NULL);
902d7be54ccSKrishna Gudipati 			break;
903d7be54ccSKrishna Gudipati 		}
904d7be54ccSKrishna Gudipati 		/*
905d7be54ccSKrishna Gudipati 		 * !! fall through !!
906d7be54ccSKrishna Gudipati 		 */
907d7be54ccSKrishna Gudipati 
908a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
909a36c61f9SKrishna Gudipati 		if (bfa_fcs_lport_is_online(rport->port)) {
910a36c61f9SKrishna Gudipati 			if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
911a36c61f9SKrishna Gudipati 				bfa_sm_set_state(rport,
912a36c61f9SKrishna Gudipati 					bfa_fcs_rport_sm_nsdisc_sending);
913a36c61f9SKrishna Gudipati 				rport->ns_retries = 0;
914a36c61f9SKrishna Gudipati 				bfa_fcs_rport_send_nsdisc(rport, NULL);
915a36c61f9SKrishna Gudipati 			} else {
916a36c61f9SKrishna Gudipati 				bfa_sm_set_state(rport,
917a36c61f9SKrishna Gudipati 					bfa_fcs_rport_sm_plogi_sending);
918a36c61f9SKrishna Gudipati 				rport->plogi_retries = 0;
919a36c61f9SKrishna Gudipati 				bfa_fcs_rport_send_plogi(rport, NULL);
920a36c61f9SKrishna Gudipati 			}
921a36c61f9SKrishna Gudipati 		} else {
922a36c61f9SKrishna Gudipati 			rport->pid = 0;
923a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
924a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
925a36c61f9SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
926a36c61f9SKrishna Gudipati 					bfa_fcs_rport_del_timeout);
927a36c61f9SKrishna Gudipati 		}
928a36c61f9SKrishna Gudipati 		break;
929a36c61f9SKrishna Gudipati 
930a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
931a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
932a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
933a36c61f9SKrishna Gudipati 		break;
934a36c61f9SKrishna Gudipati 
935a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
936a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
937a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
938d7be54ccSKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
939d7be54ccSKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
9405fbe25c7SJing Huang 		/*
941a36c61f9SKrishna Gudipati 		 * Ignore, already offline.
942a36c61f9SKrishna Gudipati 		 */
943a36c61f9SKrishna Gudipati 		break;
944a36c61f9SKrishna Gudipati 
945a36c61f9SKrishna Gudipati 	default:
946a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
947a36c61f9SKrishna Gudipati 	}
948a36c61f9SKrishna Gudipati }
949a36c61f9SKrishna Gudipati 
9505fbe25c7SJing Huang /*
951a36c61f9SKrishna Gudipati  *		Rport is offline. FC-4s are offline. Awaiting BFA rport offline
952a36c61f9SKrishna Gudipati  *		callback to send LOGO accept.
953a36c61f9SKrishna Gudipati  */
954a36c61f9SKrishna Gudipati static void
955a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
956a36c61f9SKrishna Gudipati 			enum rport_event event)
957a36c61f9SKrishna Gudipati {
958a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
959a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
960a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
961a36c61f9SKrishna Gudipati 
962a36c61f9SKrishna Gudipati 	switch (event) {
963a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
964a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
965a36c61f9SKrishna Gudipati 		if (rport->pid && (rport->prlo == BFA_TRUE))
966a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
967a36c61f9SKrishna Gudipati 		if (rport->pid && (rport->prlo == BFA_FALSE))
968a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_logo_acc(rport);
969a36c61f9SKrishna Gudipati 		/*
970a36c61f9SKrishna Gudipati 		 * If the lport is online and if the rport is not a well
971a36c61f9SKrishna Gudipati 		 * known address port,
972a36c61f9SKrishna Gudipati 		 * we try to re-discover the r-port.
973a36c61f9SKrishna Gudipati 		 */
974a36c61f9SKrishna Gudipati 		if (bfa_fcs_lport_is_online(rport->port) &&
975a36c61f9SKrishna Gudipati 			(!BFA_FCS_PID_IS_WKA(rport->pid))) {
976d7be54ccSKrishna Gudipati 			if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
977a36c61f9SKrishna Gudipati 				bfa_sm_set_state(rport,
978a36c61f9SKrishna Gudipati 					bfa_fcs_rport_sm_nsdisc_sending);
979a36c61f9SKrishna Gudipati 				rport->ns_retries = 0;
980a36c61f9SKrishna Gudipati 				bfa_fcs_rport_send_nsdisc(rport, NULL);
981a36c61f9SKrishna Gudipati 			} else {
982d7be54ccSKrishna Gudipati 				/* For N2N  Direct Attach, try to re-login */
983d7be54ccSKrishna Gudipati 				bfa_sm_set_state(rport,
984d7be54ccSKrishna Gudipati 					bfa_fcs_rport_sm_plogi_sending);
985d7be54ccSKrishna Gudipati 				rport->plogi_retries = 0;
986d7be54ccSKrishna Gudipati 				bfa_fcs_rport_send_plogi(rport, NULL);
987d7be54ccSKrishna Gudipati 			}
988d7be54ccSKrishna Gudipati 		} else {
989a36c61f9SKrishna Gudipati 			/*
990a36c61f9SKrishna Gudipati 			 * if it is not a well known address, reset the
991a36c61f9SKrishna Gudipati 			 * pid to 0.
992a36c61f9SKrishna Gudipati 			 */
993a36c61f9SKrishna Gudipati 			if (!BFA_FCS_PID_IS_WKA(rport->pid))
994a36c61f9SKrishna Gudipati 				rport->pid = 0;
995a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
996a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
997a36c61f9SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
998a36c61f9SKrishna Gudipati 					bfa_fcs_rport_del_timeout);
999a36c61f9SKrishna Gudipati 		}
1000a36c61f9SKrishna Gudipati 		break;
1001a36c61f9SKrishna Gudipati 
1002a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
1003a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
1004a36c61f9SKrishna Gudipati 		break;
1005a36c61f9SKrishna Gudipati 
1006a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
1007a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
1008a36c61f9SKrishna Gudipati 		break;
1009a36c61f9SKrishna Gudipati 
1010a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1011a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
10125fbe25c7SJing Huang 		/*
1013a36c61f9SKrishna Gudipati 		 * Ignore - already processing a LOGO.
1014a36c61f9SKrishna Gudipati 		 */
1015a36c61f9SKrishna Gudipati 		break;
1016a36c61f9SKrishna Gudipati 
1017a36c61f9SKrishna Gudipati 	default:
1018a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1019a36c61f9SKrishna Gudipati 	}
1020a36c61f9SKrishna Gudipati }
1021a36c61f9SKrishna Gudipati 
10225fbe25c7SJing Huang /*
1023a36c61f9SKrishna Gudipati  *		Rport is being deleted. FC-4s are offline.
1024a36c61f9SKrishna Gudipati  *  Awaiting BFA rport offline
1025a36c61f9SKrishna Gudipati  *		callback to send LOGO.
1026a36c61f9SKrishna Gudipati  */
1027a36c61f9SKrishna Gudipati static void
1028a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
1029a36c61f9SKrishna Gudipati 		 enum rport_event event)
1030a36c61f9SKrishna Gudipati {
1031a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1032a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1033a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1034a36c61f9SKrishna Gudipati 
1035a36c61f9SKrishna Gudipati 	switch (event) {
1036a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
1037a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_logo_sending);
1038a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_logo(rport, NULL);
1039a36c61f9SKrishna Gudipati 		break;
1040a36c61f9SKrishna Gudipati 
1041a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1042a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1043a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1044a36c61f9SKrishna Gudipati 		break;
1045a36c61f9SKrishna Gudipati 
1046a36c61f9SKrishna Gudipati 	default:
1047a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1048a36c61f9SKrishna Gudipati 	}
1049a36c61f9SKrishna Gudipati }
1050a36c61f9SKrishna Gudipati 
10515fbe25c7SJing Huang /*
1052a36c61f9SKrishna Gudipati  *		Rport is being deleted. FC-4s are offline. LOGO is being sent.
1053a36c61f9SKrishna Gudipati  */
1054a36c61f9SKrishna Gudipati static void
1055a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
1056a36c61f9SKrishna Gudipati 	 enum rport_event event)
1057a36c61f9SKrishna Gudipati {
1058a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1059a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1060a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1061a36c61f9SKrishna Gudipati 
1062a36c61f9SKrishna Gudipati 	switch (event) {
1063a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
1064a36c61f9SKrishna Gudipati 		/* Once LOGO is sent, we donot wait for the response */
1065a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1066a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1067a36c61f9SKrishna Gudipati 		break;
1068a36c61f9SKrishna Gudipati 
1069a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
1070a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1071a36c61f9SKrishna Gudipati 		break;
1072a36c61f9SKrishna Gudipati 
1073a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1074a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1075a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1076a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1077a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1078a36c61f9SKrishna Gudipati 		break;
1079a36c61f9SKrishna Gudipati 
1080a36c61f9SKrishna Gudipati 	default:
1081a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1082a36c61f9SKrishna Gudipati 	}
1083a36c61f9SKrishna Gudipati }
1084a36c61f9SKrishna Gudipati 
10855fbe25c7SJing Huang /*
1086a36c61f9SKrishna Gudipati  *		Rport is offline. FC-4s are offline. BFA rport is offline.
1087a36c61f9SKrishna Gudipati  *		Timer active to delete stale rport.
1088a36c61f9SKrishna Gudipati  */
1089a36c61f9SKrishna Gudipati static void
1090a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport, enum rport_event event)
1091a36c61f9SKrishna Gudipati {
1092a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1093a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1094a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1095a36c61f9SKrishna Gudipati 
1096a36c61f9SKrishna Gudipati 	switch (event) {
1097a36c61f9SKrishna Gudipati 	case RPSM_EVENT_TIMEOUT:
1098a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1099a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1100a36c61f9SKrishna Gudipati 		break;
1101a36c61f9SKrishna Gudipati 
1102a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
1103a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1104a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1105a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1106a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
1107a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
1108a36c61f9SKrishna Gudipati 		break;
1109a36c61f9SKrishna Gudipati 
1110a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
1111a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1112a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1113a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1114a36c61f9SKrishna Gudipati 		break;
1115a36c61f9SKrishna Gudipati 
1116a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
1117a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1118a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1119a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
1120a36c61f9SKrishna Gudipati 		break;
1121a36c61f9SKrishna Gudipati 
1122a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1123a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1124a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
1125a36c61f9SKrishna Gudipati 		break;
1126a36c61f9SKrishna Gudipati 
1127a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
1128a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
1129a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1130a36c61f9SKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
1131a36c61f9SKrishna Gudipati 		break;
1132a36c61f9SKrishna Gudipati 
1133a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_SEND:
1134a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1135a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1136a36c61f9SKrishna Gudipati 		rport->plogi_retries = 0;
1137a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogi(rport, NULL);
1138a36c61f9SKrishna Gudipati 		break;
1139a36c61f9SKrishna Gudipati 
1140a36c61f9SKrishna Gudipati 	default:
1141a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1142a36c61f9SKrishna Gudipati 	}
1143a36c61f9SKrishna Gudipati }
1144a36c61f9SKrishna Gudipati 
11455fbe25c7SJing Huang /*
1146a36c61f9SKrishna Gudipati  *	Rport address has changed. Nameserver discovery request is being sent.
1147a36c61f9SKrishna Gudipati  */
1148a36c61f9SKrishna Gudipati static void
1149a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
1150a36c61f9SKrishna Gudipati 	 enum rport_event event)
1151a36c61f9SKrishna Gudipati {
1152a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1153a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1154a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1155a36c61f9SKrishna Gudipati 
1156a36c61f9SKrishna Gudipati 	switch (event) {
1157a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
1158a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sent);
1159a36c61f9SKrishna Gudipati 		break;
1160a36c61f9SKrishna Gudipati 
1161a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
1162a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1163a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1164a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1165a36c61f9SKrishna Gudipati 		break;
1166a36c61f9SKrishna Gudipati 
1167a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
1168a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1169a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1170a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
1171a36c61f9SKrishna Gudipati 		break;
1172a36c61f9SKrishna Gudipati 
1173a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
1174a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1175a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1176a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_SEND:
1177a36c61f9SKrishna Gudipati 		break;
1178a36c61f9SKrishna Gudipati 
1179a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1180a36c61f9SKrishna Gudipati 		rport->ns_retries = 0; /* reset the retry count */
1181a36c61f9SKrishna Gudipati 		break;
1182a36c61f9SKrishna Gudipati 
1183a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
1184a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1185a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1186a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
1187a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
1188a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
1189a36c61f9SKrishna Gudipati 		break;
1190a36c61f9SKrishna Gudipati 
1191a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
1192a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
1193a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
1194a36c61f9SKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
1195a36c61f9SKrishna Gudipati 		break;
1196a36c61f9SKrishna Gudipati 
1197a36c61f9SKrishna Gudipati 	default:
1198a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1199a36c61f9SKrishna Gudipati 	}
1200a36c61f9SKrishna Gudipati }
1201a36c61f9SKrishna Gudipati 
12025fbe25c7SJing Huang /*
1203a36c61f9SKrishna Gudipati  *		Nameserver discovery failed. Waiting for timeout to retry.
1204a36c61f9SKrishna Gudipati  */
1205a36c61f9SKrishna Gudipati static void
1206a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
1207a36c61f9SKrishna Gudipati 	 enum rport_event event)
1208a36c61f9SKrishna Gudipati {
1209a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1210a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1211a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1212a36c61f9SKrishna Gudipati 
1213a36c61f9SKrishna Gudipati 	switch (event) {
1214a36c61f9SKrishna Gudipati 	case RPSM_EVENT_TIMEOUT:
1215a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1216a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
1217a36c61f9SKrishna Gudipati 		break;
1218a36c61f9SKrishna Gudipati 
1219a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
1220a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1221a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
1222a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1223a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
1224a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
1225a36c61f9SKrishna Gudipati 		break;
1226a36c61f9SKrishna Gudipati 
1227a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
1228a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1229a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1230a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1231a36c61f9SKrishna Gudipati 		break;
1232a36c61f9SKrishna Gudipati 
1233a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
1234a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1235a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1236a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
1237a36c61f9SKrishna Gudipati 		break;
1238a36c61f9SKrishna Gudipati 
1239a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
1240a36c61f9SKrishna Gudipati 		rport->pid = 0;
1241a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1242a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1243a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
1244a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
1245a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
1246a36c61f9SKrishna Gudipati 		break;
1247a36c61f9SKrishna Gudipati 
1248a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
1249a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
1250a36c61f9SKrishna Gudipati 		break;
1251a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1252a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_prlo_acc(rport);
1253a36c61f9SKrishna Gudipati 		break;
1254a36c61f9SKrishna Gudipati 
1255a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
1256a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
1257a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
1258a36c61f9SKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
1259a36c61f9SKrishna Gudipati 		break;
1260a36c61f9SKrishna Gudipati 
1261a36c61f9SKrishna Gudipati 	default:
1262a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1263a36c61f9SKrishna Gudipati 	}
1264a36c61f9SKrishna Gudipati }
1265a36c61f9SKrishna Gudipati 
12665fbe25c7SJing Huang /*
1267a36c61f9SKrishna Gudipati  *		Rport address has changed. Nameserver discovery request is sent.
1268a36c61f9SKrishna Gudipati  */
1269a36c61f9SKrishna Gudipati static void
1270a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
1271a36c61f9SKrishna Gudipati 			enum rport_event event)
1272a36c61f9SKrishna Gudipati {
1273a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1274a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1275a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
1276a36c61f9SKrishna Gudipati 
1277a36c61f9SKrishna Gudipati 	switch (event) {
1278a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ACCEPTED:
1279a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
1280a36c61f9SKrishna Gudipati 		if (rport->pid) {
1281a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
1282a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_plogi(rport, NULL);
1283a36c61f9SKrishna Gudipati 		} else {
1284a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
1285a36c61f9SKrishna Gudipati 				 bfa_fcs_rport_sm_nsdisc_sending);
1286a36c61f9SKrishna Gudipati 			rport->ns_retries = 0;
1287a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
1288a36c61f9SKrishna Gudipati 		}
1289a36c61f9SKrishna Gudipati 		break;
1290a36c61f9SKrishna Gudipati 
1291a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FAILED:
1292a36c61f9SKrishna Gudipati 		rport->ns_retries++;
1293a36c61f9SKrishna Gudipati 		if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
1294a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
1295a36c61f9SKrishna Gudipati 				 bfa_fcs_rport_sm_nsdisc_sending);
1296a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
1297a36c61f9SKrishna Gudipati 		} else {
1298a36c61f9SKrishna Gudipati 			rport->pid = 0;
1299a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1300a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
1301a36c61f9SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
1302a36c61f9SKrishna Gudipati 					bfa_fcs_rport_del_timeout);
1303a36c61f9SKrishna Gudipati 		};
1304a36c61f9SKrishna Gudipati 		break;
1305a36c61f9SKrishna Gudipati 
1306a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
1307a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
1308a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
1309a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
1310a36c61f9SKrishna Gudipati 		break;
1311a36c61f9SKrishna Gudipati 
1312a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
1313a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
1314a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
1315a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
1316a36c61f9SKrishna Gudipati 		break;
1317a36c61f9SKrishna Gudipati 
1318a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
1319a36c61f9SKrishna Gudipati 		rport->pid = 0;
1320a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
1321a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
1322a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
1323a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
1324a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
1325a36c61f9SKrishna Gudipati 		break;
1326a36c61f9SKrishna Gudipati 
1327a36c61f9SKrishna Gudipati 
1328a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
1329a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_prlo_acc(rport);
1330a36c61f9SKrishna Gudipati 		break;
1331a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
13325fbe25c7SJing Huang 		/*
1333a36c61f9SKrishna Gudipati 		 * ignore, wait for NS query response
1334a36c61f9SKrishna Gudipati 		 */
1335a36c61f9SKrishna Gudipati 		break;
1336a36c61f9SKrishna Gudipati 
1337a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
13385fbe25c7SJing Huang 		/*
1339a36c61f9SKrishna Gudipati 		 * Not logged-in yet. Accept LOGO.
1340a36c61f9SKrishna Gudipati 		 */
1341a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
1342a36c61f9SKrishna Gudipati 		break;
1343a36c61f9SKrishna Gudipati 
1344a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
1345a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
1346a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
1347a36c61f9SKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
1348a36c61f9SKrishna Gudipati 		break;
1349a36c61f9SKrishna Gudipati 
1350a36c61f9SKrishna Gudipati 	default:
1351a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
1352a36c61f9SKrishna Gudipati 	}
1353a36c61f9SKrishna Gudipati }
1354a36c61f9SKrishna Gudipati 
1355a36c61f9SKrishna Gudipati 
1356a36c61f9SKrishna Gudipati 
13575fbe25c7SJing Huang /*
1358a36c61f9SKrishna Gudipati  *  fcs_rport_private FCS RPORT provate functions
1359a36c61f9SKrishna Gudipati  */
1360a36c61f9SKrishna Gudipati 
1361a36c61f9SKrishna Gudipati static void
1362a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogi(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1363a36c61f9SKrishna Gudipati {
1364a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1365a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1366a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1367a36c61f9SKrishna Gudipati 	int		len;
1368a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1369a36c61f9SKrishna Gudipati 
1370a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1371a36c61f9SKrishna Gudipati 
1372a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1373a36c61f9SKrishna Gudipati 	if (!fcxp) {
1374a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1375a36c61f9SKrishna Gudipati 					bfa_fcs_rport_send_plogi, rport);
1376a36c61f9SKrishna Gudipati 		return;
1377a36c61f9SKrishna Gudipati 	}
1378a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1379a36c61f9SKrishna Gudipati 
1380a36c61f9SKrishna Gudipati 	len = fc_plogi_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1381a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0,
1382a36c61f9SKrishna Gudipati 				port->port_cfg.pwwn, port->port_cfg.nwwn,
1383be540a99SKrishna Gudipati 				bfa_fcport_get_maxfrsize(port->fcs->bfa),
1384be540a99SKrishna Gudipati 				bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
1385a36c61f9SKrishna Gudipati 
1386a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1387a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response,
1388a36c61f9SKrishna Gudipati 			(void *)rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1389a36c61f9SKrishna Gudipati 
1390a36c61f9SKrishna Gudipati 	rport->stats.plogis++;
1391a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1392a36c61f9SKrishna Gudipati }
1393a36c61f9SKrishna Gudipati 
1394a36c61f9SKrishna Gudipati static void
1395a36c61f9SKrishna Gudipati bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1396a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
1397a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs)
1398a36c61f9SKrishna Gudipati {
1399a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1400a36c61f9SKrishna Gudipati 	struct fc_logi_s	*plogi_rsp;
1401a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s	*ls_rjt;
1402a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *twin;
1403a36c61f9SKrishna Gudipati 	struct list_head	*qe;
1404a36c61f9SKrishna Gudipati 
1405a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1406a36c61f9SKrishna Gudipati 
1407a36c61f9SKrishna Gudipati 	/*
1408a36c61f9SKrishna Gudipati 	 * Sanity Checks
1409a36c61f9SKrishna Gudipati 	 */
1410a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
1411a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, req_status);
1412a36c61f9SKrishna Gudipati 		rport->stats.plogi_failed++;
1413a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1414a36c61f9SKrishna Gudipati 		return;
1415a36c61f9SKrishna Gudipati 	}
1416a36c61f9SKrishna Gudipati 
1417a36c61f9SKrishna Gudipati 	plogi_rsp = (struct fc_logi_s *) BFA_FCXP_RSP_PLD(fcxp);
1418a36c61f9SKrishna Gudipati 
14195fbe25c7SJing Huang 	/*
1420a36c61f9SKrishna Gudipati 	 * Check for failure first.
1421a36c61f9SKrishna Gudipati 	 */
1422a36c61f9SKrishna Gudipati 	if (plogi_rsp->els_cmd.els_code != FC_ELS_ACC) {
1423a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
1424a36c61f9SKrishna Gudipati 
1425a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, ls_rjt->reason_code);
1426a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1427a36c61f9SKrishna Gudipati 
1428a36c61f9SKrishna Gudipati 		if ((ls_rjt->reason_code == FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD) &&
1429a36c61f9SKrishna Gudipati 		 (ls_rjt->reason_code_expl == FC_LS_RJT_EXP_INSUFF_RES)) {
1430a36c61f9SKrishna Gudipati 			rport->stats.rjt_insuff_res++;
1431a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RETRY);
1432a36c61f9SKrishna Gudipati 			return;
1433a36c61f9SKrishna Gudipati 		}
1434a36c61f9SKrishna Gudipati 
1435a36c61f9SKrishna Gudipati 		rport->stats.plogi_rejects++;
1436a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1437a36c61f9SKrishna Gudipati 		return;
1438a36c61f9SKrishna Gudipati 	}
1439a36c61f9SKrishna Gudipati 
14405fbe25c7SJing Huang 	/*
1441a36c61f9SKrishna Gudipati 	 * PLOGI is complete. Make sure this device is not one of the known
1442a36c61f9SKrishna Gudipati 	 * device with a new FC port address.
1443a36c61f9SKrishna Gudipati 	 */
1444a36c61f9SKrishna Gudipati 	list_for_each(qe, &rport->port->rport_q) {
1445a36c61f9SKrishna Gudipati 		twin = (struct bfa_fcs_rport_s *) qe;
1446a36c61f9SKrishna Gudipati 		if (twin == rport)
1447a36c61f9SKrishna Gudipati 			continue;
1448a36c61f9SKrishna Gudipati 		if (!rport->pwwn && (plogi_rsp->port_name == twin->pwwn)) {
1449a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs, twin->pid);
1450a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs, rport->pid);
1451a36c61f9SKrishna Gudipati 
1452a36c61f9SKrishna Gudipati 			/* Update plogi stats in twin */
1453a36c61f9SKrishna Gudipati 			twin->stats.plogis  += rport->stats.plogis;
1454a36c61f9SKrishna Gudipati 			twin->stats.plogi_rejects  +=
1455a36c61f9SKrishna Gudipati 				 rport->stats.plogi_rejects;
1456a36c61f9SKrishna Gudipati 			twin->stats.plogi_timeouts  +=
1457a36c61f9SKrishna Gudipati 				 rport->stats.plogi_timeouts;
1458a36c61f9SKrishna Gudipati 			twin->stats.plogi_failed +=
1459a36c61f9SKrishna Gudipati 				 rport->stats.plogi_failed;
1460a36c61f9SKrishna Gudipati 			twin->stats.plogi_rcvd	  += rport->stats.plogi_rcvd;
1461a36c61f9SKrishna Gudipati 			twin->stats.plogi_accs++;
1462a36c61f9SKrishna Gudipati 
1463f7f73812SMaggie Zhang 			bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
1464a36c61f9SKrishna Gudipati 
1465a36c61f9SKrishna Gudipati 			bfa_fcs_rport_update(twin, plogi_rsp);
1466a36c61f9SKrishna Gudipati 			twin->pid = rsp_fchs->s_id;
1467a36c61f9SKrishna Gudipati 			bfa_sm_send_event(twin, RPSM_EVENT_PLOGI_COMP);
1468a36c61f9SKrishna Gudipati 			return;
1469a36c61f9SKrishna Gudipati 		}
1470a36c61f9SKrishna Gudipati 	}
1471a36c61f9SKrishna Gudipati 
14725fbe25c7SJing Huang 	/*
1473a36c61f9SKrishna Gudipati 	 * Normal login path -- no evil twins.
1474a36c61f9SKrishna Gudipati 	 */
1475a36c61f9SKrishna Gudipati 	rport->stats.plogi_accs++;
1476a36c61f9SKrishna Gudipati 	bfa_fcs_rport_update(rport, plogi_rsp);
1477a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1478a36c61f9SKrishna Gudipati }
1479a36c61f9SKrishna Gudipati 
1480a36c61f9SKrishna Gudipati static void
1481a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1482a36c61f9SKrishna Gudipati {
1483a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1484a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1485a36c61f9SKrishna Gudipati 	struct fchs_s		fchs;
1486a36c61f9SKrishna Gudipati 	int		len;
1487a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1488a36c61f9SKrishna Gudipati 
1489a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1490a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->reply_oxid);
1491a36c61f9SKrishna Gudipati 
1492a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1493a36c61f9SKrishna Gudipati 	if (!fcxp) {
1494a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1495a36c61f9SKrishna Gudipati 					bfa_fcs_rport_send_plogiacc, rport);
1496a36c61f9SKrishna Gudipati 		return;
1497a36c61f9SKrishna Gudipati 	}
1498a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1499a36c61f9SKrishna Gudipati 
1500a36c61f9SKrishna Gudipati 	len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1501a36c61f9SKrishna Gudipati 				 rport->pid, bfa_fcs_lport_get_fcid(port),
1502a36c61f9SKrishna Gudipati 				 rport->reply_oxid, port->port_cfg.pwwn,
1503a36c61f9SKrishna Gudipati 				 port->port_cfg.nwwn,
1504be540a99SKrishna Gudipati 				 bfa_fcport_get_maxfrsize(port->fcs->bfa),
1505be540a99SKrishna Gudipati 				 bfa_fcport_get_rx_bbcredit(port->fcs->bfa));
1506a36c61f9SKrishna Gudipati 
1507a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1508a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1509a36c61f9SKrishna Gudipati 
1510a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1511a36c61f9SKrishna Gudipati }
1512a36c61f9SKrishna Gudipati 
1513a36c61f9SKrishna Gudipati static void
1514a36c61f9SKrishna Gudipati bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1515a36c61f9SKrishna Gudipati {
1516a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1517a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1518a36c61f9SKrishna Gudipati 	struct fchs_s		fchs;
1519a36c61f9SKrishna Gudipati 	int		len;
1520a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1521a36c61f9SKrishna Gudipati 
1522a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1523a36c61f9SKrishna Gudipati 
1524a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1525a36c61f9SKrishna Gudipati 	if (!fcxp) {
1526a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1527a36c61f9SKrishna Gudipati 					bfa_fcs_rport_send_adisc, rport);
1528a36c61f9SKrishna Gudipati 		return;
1529a36c61f9SKrishna Gudipati 	}
1530a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1531a36c61f9SKrishna Gudipati 
1532a36c61f9SKrishna Gudipati 	len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1533a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0,
1534a36c61f9SKrishna Gudipati 				port->port_cfg.pwwn, port->port_cfg.nwwn);
1535a36c61f9SKrishna Gudipati 
1536a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1537a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, bfa_fcs_rport_adisc_response,
1538a36c61f9SKrishna Gudipati 			rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1539a36c61f9SKrishna Gudipati 
1540a36c61f9SKrishna Gudipati 	rport->stats.adisc_sent++;
1541a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1542a36c61f9SKrishna Gudipati }
1543a36c61f9SKrishna Gudipati 
1544a36c61f9SKrishna Gudipati static void
1545a36c61f9SKrishna Gudipati bfa_fcs_rport_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1546a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
1547a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs)
1548a36c61f9SKrishna Gudipati {
1549a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1550a36c61f9SKrishna Gudipati 	void		*pld = bfa_fcxp_get_rspbuf(fcxp);
1551a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s	*ls_rjt;
1552a36c61f9SKrishna Gudipati 
1553a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
1554a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, req_status);
1555a36c61f9SKrishna Gudipati 		rport->stats.adisc_failed++;
1556a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1557a36c61f9SKrishna Gudipati 		return;
1558a36c61f9SKrishna Gudipati 	}
1559a36c61f9SKrishna Gudipati 
1560a36c61f9SKrishna Gudipati 	if (fc_adisc_rsp_parse((struct fc_adisc_s *)pld, rsp_len, rport->pwwn,
1561a36c61f9SKrishna Gudipati 				rport->nwwn)  == FC_PARSE_OK) {
1562a36c61f9SKrishna Gudipati 		rport->stats.adisc_accs++;
1563a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1564a36c61f9SKrishna Gudipati 		return;
1565a36c61f9SKrishna Gudipati 	}
1566a36c61f9SKrishna Gudipati 
1567a36c61f9SKrishna Gudipati 	rport->stats.adisc_rejects++;
1568a36c61f9SKrishna Gudipati 	ls_rjt = pld;
1569a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, ls_rjt->els_cmd.els_code);
1570a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, ls_rjt->reason_code);
1571a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1572a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1573a36c61f9SKrishna Gudipati }
1574a36c61f9SKrishna Gudipati 
1575a36c61f9SKrishna Gudipati static void
1576a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1577a36c61f9SKrishna Gudipati {
1578a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1579a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1580a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1581a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1582a36c61f9SKrishna Gudipati 	int		len;
1583a36c61f9SKrishna Gudipati 	bfa_cb_fcxp_send_t cbfn;
1584a36c61f9SKrishna Gudipati 
1585a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1586a36c61f9SKrishna Gudipati 
1587a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1588a36c61f9SKrishna Gudipati 	if (!fcxp) {
1589a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1590a36c61f9SKrishna Gudipati 					bfa_fcs_rport_send_nsdisc, rport);
1591a36c61f9SKrishna Gudipati 		return;
1592a36c61f9SKrishna Gudipati 	}
1593a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1594a36c61f9SKrishna Gudipati 
1595a36c61f9SKrishna Gudipati 	if (rport->pwwn) {
1596a36c61f9SKrishna Gudipati 		len = fc_gidpn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1597a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0, rport->pwwn);
1598a36c61f9SKrishna Gudipati 		cbfn = bfa_fcs_rport_gidpn_response;
1599a36c61f9SKrishna Gudipati 	} else {
1600a36c61f9SKrishna Gudipati 		len = fc_gpnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1601a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0, rport->pid);
1602a36c61f9SKrishna Gudipati 		cbfn = bfa_fcs_rport_gpnid_response;
1603a36c61f9SKrishna Gudipati 	}
1604a36c61f9SKrishna Gudipati 
1605a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1606a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, cbfn,
1607a36c61f9SKrishna Gudipati 			(void *)rport, FC_MAX_PDUSZ, FC_FCCT_TOV);
1608a36c61f9SKrishna Gudipati 
1609a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1610a36c61f9SKrishna Gudipati }
1611a36c61f9SKrishna Gudipati 
1612a36c61f9SKrishna Gudipati static void
1613a36c61f9SKrishna Gudipati bfa_fcs_rport_gidpn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1614a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
1615a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs)
1616a36c61f9SKrishna Gudipati {
1617a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1618a36c61f9SKrishna Gudipati 	struct ct_hdr_s	*cthdr;
1619a36c61f9SKrishna Gudipati 	struct fcgs_gidpn_resp_s	*gidpn_rsp;
1620a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s	*twin;
1621a36c61f9SKrishna Gudipati 	struct list_head	*qe;
1622a36c61f9SKrishna Gudipati 
1623a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1624a36c61f9SKrishna Gudipati 
1625a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1626ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
1627a36c61f9SKrishna Gudipati 
1628a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1629a36c61f9SKrishna Gudipati 		/* Check if the pid is the same as before. */
1630a36c61f9SKrishna Gudipati 		gidpn_rsp = (struct fcgs_gidpn_resp_s *) (cthdr + 1);
1631a36c61f9SKrishna Gudipati 
1632a36c61f9SKrishna Gudipati 		if (gidpn_rsp->dap == rport->pid) {
1633a36c61f9SKrishna Gudipati 			/* Device is online  */
1634a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1635a36c61f9SKrishna Gudipati 		} else {
1636a36c61f9SKrishna Gudipati 			/*
1637a36c61f9SKrishna Gudipati 			 * Device's PID has changed. We need to cleanup
1638a36c61f9SKrishna Gudipati 			 * and re-login. If there is another device with
1639a36c61f9SKrishna Gudipati 			 * the the newly discovered pid, send an scn notice
1640a36c61f9SKrishna Gudipati 			 * so that its new pid can be discovered.
1641a36c61f9SKrishna Gudipati 			 */
1642a36c61f9SKrishna Gudipati 			list_for_each(qe, &rport->port->rport_q) {
1643a36c61f9SKrishna Gudipati 				twin = (struct bfa_fcs_rport_s *) qe;
1644a36c61f9SKrishna Gudipati 				if (twin == rport)
1645a36c61f9SKrishna Gudipati 					continue;
1646a36c61f9SKrishna Gudipati 				if (gidpn_rsp->dap == twin->pid) {
1647a36c61f9SKrishna Gudipati 					bfa_trc(rport->fcs, twin->pid);
1648a36c61f9SKrishna Gudipati 					bfa_trc(rport->fcs, rport->pid);
1649a36c61f9SKrishna Gudipati 
1650a36c61f9SKrishna Gudipati 					twin->pid = 0;
1651a36c61f9SKrishna Gudipati 					bfa_sm_send_event(twin,
1652a36c61f9SKrishna Gudipati 					 RPSM_EVENT_ADDRESS_CHANGE);
1653a36c61f9SKrishna Gudipati 				}
1654a36c61f9SKrishna Gudipati 			}
1655a36c61f9SKrishna Gudipati 			rport->pid = gidpn_rsp->dap;
1656a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_CHANGE);
1657a36c61f9SKrishna Gudipati 		}
1658a36c61f9SKrishna Gudipati 		return;
1659a36c61f9SKrishna Gudipati 	}
1660a36c61f9SKrishna Gudipati 
1661a36c61f9SKrishna Gudipati 	/*
1662a36c61f9SKrishna Gudipati 	 * Reject Response
1663a36c61f9SKrishna Gudipati 	 */
1664a36c61f9SKrishna Gudipati 	switch (cthdr->reason_code) {
1665a36c61f9SKrishna Gudipati 	case CT_RSN_LOGICAL_BUSY:
1666a36c61f9SKrishna Gudipati 		/*
1667a36c61f9SKrishna Gudipati 		 * Need to retry
1668a36c61f9SKrishna Gudipati 		 */
1669a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
1670a36c61f9SKrishna Gudipati 		break;
1671a36c61f9SKrishna Gudipati 
1672a36c61f9SKrishna Gudipati 	case CT_RSN_UNABLE_TO_PERF:
1673a36c61f9SKrishna Gudipati 		/*
1674a36c61f9SKrishna Gudipati 		 * device doesn't exist : Start timer to cleanup this later.
1675a36c61f9SKrishna Gudipati 		 */
1676a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1677a36c61f9SKrishna Gudipati 		break;
1678a36c61f9SKrishna Gudipati 
1679a36c61f9SKrishna Gudipati 	default:
1680a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1681a36c61f9SKrishna Gudipati 		break;
1682a36c61f9SKrishna Gudipati 	}
1683a36c61f9SKrishna Gudipati }
1684a36c61f9SKrishna Gudipati 
1685a36c61f9SKrishna Gudipati static void
1686a36c61f9SKrishna Gudipati bfa_fcs_rport_gpnid_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1687a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
1688a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs)
1689a36c61f9SKrishna Gudipati {
1690a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1691a36c61f9SKrishna Gudipati 	struct ct_hdr_s	*cthdr;
1692a36c61f9SKrishna Gudipati 
1693a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1694a36c61f9SKrishna Gudipati 
1695a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1696ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
1697a36c61f9SKrishna Gudipati 
1698a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1699a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1700a36c61f9SKrishna Gudipati 		return;
1701a36c61f9SKrishna Gudipati 	}
1702a36c61f9SKrishna Gudipati 
1703a36c61f9SKrishna Gudipati 	/*
1704a36c61f9SKrishna Gudipati 	 * Reject Response
1705a36c61f9SKrishna Gudipati 	 */
1706a36c61f9SKrishna Gudipati 	switch (cthdr->reason_code) {
1707a36c61f9SKrishna Gudipati 	case CT_RSN_LOGICAL_BUSY:
1708a36c61f9SKrishna Gudipati 		/*
1709a36c61f9SKrishna Gudipati 		 * Need to retry
1710a36c61f9SKrishna Gudipati 		 */
1711a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
1712a36c61f9SKrishna Gudipati 		break;
1713a36c61f9SKrishna Gudipati 
1714a36c61f9SKrishna Gudipati 	case CT_RSN_UNABLE_TO_PERF:
1715a36c61f9SKrishna Gudipati 		/*
1716a36c61f9SKrishna Gudipati 		 * device doesn't exist : Start timer to cleanup this later.
1717a36c61f9SKrishna Gudipati 		 */
1718a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1719a36c61f9SKrishna Gudipati 		break;
1720a36c61f9SKrishna Gudipati 
1721a36c61f9SKrishna Gudipati 	default:
1722a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1723a36c61f9SKrishna Gudipati 		break;
1724a36c61f9SKrishna Gudipati 	}
1725a36c61f9SKrishna Gudipati }
1726a36c61f9SKrishna Gudipati 
17275fbe25c7SJing Huang /*
1728a36c61f9SKrishna Gudipati  *	Called to send a logout to the rport.
1729a36c61f9SKrishna Gudipati  */
1730a36c61f9SKrishna Gudipati static void
1731a36c61f9SKrishna Gudipati bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1732a36c61f9SKrishna Gudipati {
1733a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1734a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port;
1735a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1736a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1737a36c61f9SKrishna Gudipati 	u16	len;
1738a36c61f9SKrishna Gudipati 
1739a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1740a36c61f9SKrishna Gudipati 
1741a36c61f9SKrishna Gudipati 	port = rport->port;
1742a36c61f9SKrishna Gudipati 
1743a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1744a36c61f9SKrishna Gudipati 	if (!fcxp) {
1745a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1746a36c61f9SKrishna Gudipati 					bfa_fcs_rport_send_logo, rport);
1747a36c61f9SKrishna Gudipati 		return;
1748a36c61f9SKrishna Gudipati 	}
1749a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1750a36c61f9SKrishna Gudipati 
1751a36c61f9SKrishna Gudipati 	len = fc_logo_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1752a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0,
1753a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_pwwn(port));
1754a36c61f9SKrishna Gudipati 
1755a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1756a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL,
1757a36c61f9SKrishna Gudipati 			rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1758a36c61f9SKrishna Gudipati 
1759a36c61f9SKrishna Gudipati 	rport->stats.logos++;
1760a36c61f9SKrishna Gudipati 	bfa_fcxp_discard(rport->fcxp);
1761a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1762a36c61f9SKrishna Gudipati }
1763a36c61f9SKrishna Gudipati 
17645fbe25c7SJing Huang /*
1765a36c61f9SKrishna Gudipati  *	Send ACC for a LOGO received.
1766a36c61f9SKrishna Gudipati  */
1767a36c61f9SKrishna Gudipati static void
1768a36c61f9SKrishna Gudipati bfa_fcs_rport_send_logo_acc(void *rport_cbarg)
1769a36c61f9SKrishna Gudipati {
1770a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1771a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port;
1772a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1773a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1774a36c61f9SKrishna Gudipati 	u16	len;
1775a36c61f9SKrishna Gudipati 
1776a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1777a36c61f9SKrishna Gudipati 
1778a36c61f9SKrishna Gudipati 	port = rport->port;
1779a36c61f9SKrishna Gudipati 
1780a36c61f9SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1781a36c61f9SKrishna Gudipati 	if (!fcxp)
1782a36c61f9SKrishna Gudipati 		return;
1783a36c61f9SKrishna Gudipati 
1784a36c61f9SKrishna Gudipati 	rport->stats.logo_rcvd++;
1785a36c61f9SKrishna Gudipati 	len = fc_logo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1786a36c61f9SKrishna Gudipati 				rport->pid, bfa_fcs_lport_get_fcid(port),
1787a36c61f9SKrishna Gudipati 				rport->reply_oxid);
1788a36c61f9SKrishna Gudipati 
1789a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1790a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1791a36c61f9SKrishna Gudipati }
1792a36c61f9SKrishna Gudipati 
17935fbe25c7SJing Huang /*
1794a36c61f9SKrishna Gudipati  *	brief
1795a36c61f9SKrishna Gudipati  *	This routine will be called by bfa_timer on timer timeouts.
1796a36c61f9SKrishna Gudipati  *
1797a36c61f9SKrishna Gudipati  *	param[in]	rport			- pointer to bfa_fcs_lport_ns_t.
1798a36c61f9SKrishna Gudipati  *	param[out]	rport_status	- pointer to return vport status in
1799a36c61f9SKrishna Gudipati  *
1800a36c61f9SKrishna Gudipati  *	return
1801a36c61f9SKrishna Gudipati  *		void
1802a36c61f9SKrishna Gudipati  *
1803a36c61f9SKrishna Gudipati  *	Special Considerations:
1804a36c61f9SKrishna Gudipati  *
1805a36c61f9SKrishna Gudipati  *	note
1806a36c61f9SKrishna Gudipati  */
1807a36c61f9SKrishna Gudipati static void
1808a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout(void *arg)
1809a36c61f9SKrishna Gudipati {
1810a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) arg;
1811a36c61f9SKrishna Gudipati 
1812a36c61f9SKrishna Gudipati 	rport->stats.plogi_timeouts++;
1813a36c61f9SKrishna Gudipati 	bfa_stats(rport->port, rport_plogi_timeouts);
1814a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
1815a36c61f9SKrishna Gudipati }
1816a36c61f9SKrishna Gudipati 
1817a36c61f9SKrishna Gudipati static void
1818a36c61f9SKrishna Gudipati bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
1819a36c61f9SKrishna Gudipati 			struct fchs_s *rx_fchs, u16 len)
1820a36c61f9SKrishna Gudipati {
1821a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1822a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1823a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1824a36c61f9SKrishna Gudipati 	struct fc_prli_s	*prli;
1825a36c61f9SKrishna Gudipati 
1826a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
1827a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
1828a36c61f9SKrishna Gudipati 
1829a36c61f9SKrishna Gudipati 	rport->stats.prli_rcvd++;
1830a36c61f9SKrishna Gudipati 
1831a36c61f9SKrishna Gudipati 	/*
1832a36c61f9SKrishna Gudipati 	 * We are in Initiator Mode
1833a36c61f9SKrishna Gudipati 	 */
1834a36c61f9SKrishna Gudipati 	prli = (struct fc_prli_s *) (rx_fchs + 1);
1835a36c61f9SKrishna Gudipati 
1836a36c61f9SKrishna Gudipati 	if (prli->parampage.servparams.target) {
1837a36c61f9SKrishna Gudipati 		/*
1838a36c61f9SKrishna Gudipati 		 * PRLI from a target ?
1839a36c61f9SKrishna Gudipati 		 * Send the Acc.
1840a36c61f9SKrishna Gudipati 		 * PRLI sent by us will be used to transition the IT nexus,
1841a36c61f9SKrishna Gudipati 		 * once the response is received from the target.
1842a36c61f9SKrishna Gudipati 		 */
1843a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, rx_fchs->s_id);
1844a36c61f9SKrishna Gudipati 		rport->scsi_function = BFA_RPORT_TARGET;
1845a36c61f9SKrishna Gudipati 	} else {
1846a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, prli->parampage.type);
1847a36c61f9SKrishna Gudipati 		rport->scsi_function = BFA_RPORT_INITIATOR;
1848a36c61f9SKrishna Gudipati 		bfa_fcs_itnim_is_initiator(rport->itnim);
1849a36c61f9SKrishna Gudipati 	}
1850a36c61f9SKrishna Gudipati 
1851a36c61f9SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1852a36c61f9SKrishna Gudipati 	if (!fcxp)
1853a36c61f9SKrishna Gudipati 		return;
1854a36c61f9SKrishna Gudipati 
1855a36c61f9SKrishna Gudipati 	len = fc_prli_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1856a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
1857a36c61f9SKrishna Gudipati 				rx_fchs->ox_id, port->port_cfg.roles);
1858a36c61f9SKrishna Gudipati 
1859a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1860a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1861a36c61f9SKrishna Gudipati }
1862a36c61f9SKrishna Gudipati 
1863a36c61f9SKrishna Gudipati static void
1864a36c61f9SKrishna Gudipati bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport,
1865a36c61f9SKrishna Gudipati 			struct fchs_s *rx_fchs, u16 len)
1866a36c61f9SKrishna Gudipati {
1867a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1868a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1869a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1870a36c61f9SKrishna Gudipati 	struct fc_rpsc_speed_info_s speeds;
1871a36c61f9SKrishna Gudipati 	struct bfa_port_attr_s pport_attr;
1872a36c61f9SKrishna Gudipati 
1873a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
1874a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
1875a36c61f9SKrishna Gudipati 
1876a36c61f9SKrishna Gudipati 	rport->stats.rpsc_rcvd++;
1877a36c61f9SKrishna Gudipati 	speeds.port_speed_cap =
1878a36c61f9SKrishna Gudipati 		RPSC_SPEED_CAP_1G | RPSC_SPEED_CAP_2G | RPSC_SPEED_CAP_4G |
1879a36c61f9SKrishna Gudipati 		RPSC_SPEED_CAP_8G;
1880a36c61f9SKrishna Gudipati 
1881a36c61f9SKrishna Gudipati 	/*
1882a36c61f9SKrishna Gudipati 	 * get curent speed from pport attributes from BFA
1883a36c61f9SKrishna Gudipati 	 */
1884a36c61f9SKrishna Gudipati 	bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
1885a36c61f9SKrishna Gudipati 
1886a36c61f9SKrishna Gudipati 	speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
1887a36c61f9SKrishna Gudipati 
1888a36c61f9SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1889a36c61f9SKrishna Gudipati 	if (!fcxp)
1890a36c61f9SKrishna Gudipati 		return;
1891a36c61f9SKrishna Gudipati 
1892a36c61f9SKrishna Gudipati 	len = fc_rpsc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1893a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
1894a36c61f9SKrishna Gudipati 				rx_fchs->ox_id, &speeds);
1895a36c61f9SKrishna Gudipati 
1896a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1897a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1898a36c61f9SKrishna Gudipati }
1899a36c61f9SKrishna Gudipati 
1900a36c61f9SKrishna Gudipati static void
1901a36c61f9SKrishna Gudipati bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
1902a36c61f9SKrishna Gudipati 			struct fchs_s *rx_fchs, u16 len)
1903a36c61f9SKrishna Gudipati {
1904a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1905a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1906a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1907a36c61f9SKrishna Gudipati 	struct fc_adisc_s	*adisc;
1908a36c61f9SKrishna Gudipati 
1909a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
1910a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
1911a36c61f9SKrishna Gudipati 
1912a36c61f9SKrishna Gudipati 	rport->stats.adisc_rcvd++;
1913a36c61f9SKrishna Gudipati 
1914a36c61f9SKrishna Gudipati 	adisc = (struct fc_adisc_s *) (rx_fchs + 1);
1915a36c61f9SKrishna Gudipati 
1916a36c61f9SKrishna Gudipati 	/*
1917a36c61f9SKrishna Gudipati 	 * Accept if the itnim for this rport is online.
1918a36c61f9SKrishna Gudipati 	 * Else reject the ADISC.
1919a36c61f9SKrishna Gudipati 	 */
1920a36c61f9SKrishna Gudipati 	if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) {
1921a36c61f9SKrishna Gudipati 
1922a36c61f9SKrishna Gudipati 		fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1923a36c61f9SKrishna Gudipati 		if (!fcxp)
1924a36c61f9SKrishna Gudipati 			return;
1925a36c61f9SKrishna Gudipati 
1926a36c61f9SKrishna Gudipati 		len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1927a36c61f9SKrishna Gudipati 			 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
1928a36c61f9SKrishna Gudipati 			 rx_fchs->ox_id, port->port_cfg.pwwn,
1929a36c61f9SKrishna Gudipati 			 port->port_cfg.nwwn);
1930a36c61f9SKrishna Gudipati 
1931a36c61f9SKrishna Gudipati 		bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
1932a36c61f9SKrishna Gudipati 				BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
1933a36c61f9SKrishna Gudipati 				FC_MAX_PDUSZ, 0);
1934a36c61f9SKrishna Gudipati 	} else {
1935a36c61f9SKrishna Gudipati 		rport->stats.adisc_rejected++;
1936a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_ls_rjt(rport, rx_fchs,
1937a36c61f9SKrishna Gudipati 					  FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD,
1938a36c61f9SKrishna Gudipati 					  FC_LS_RJT_EXP_LOGIN_REQUIRED);
1939a36c61f9SKrishna Gudipati 	}
1940a36c61f9SKrishna Gudipati }
1941a36c61f9SKrishna Gudipati 
1942a36c61f9SKrishna Gudipati static void
1943a36c61f9SKrishna Gudipati bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport)
1944a36c61f9SKrishna Gudipati {
1945a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1946a36c61f9SKrishna Gudipati 	struct bfa_rport_info_s rport_info;
1947a36c61f9SKrishna Gudipati 
1948a36c61f9SKrishna Gudipati 	rport_info.pid = rport->pid;
1949a36c61f9SKrishna Gudipati 	rport_info.local_pid = port->pid;
1950a36c61f9SKrishna Gudipati 	rport_info.lp_tag = port->lp_tag;
1951a36c61f9SKrishna Gudipati 	rport_info.vf_id = port->fabric->vf_id;
1952a36c61f9SKrishna Gudipati 	rport_info.vf_en = port->fabric->is_vf;
1953a36c61f9SKrishna Gudipati 	rport_info.fc_class = rport->fc_cos;
1954a36c61f9SKrishna Gudipati 	rport_info.cisc = rport->cisc;
1955a36c61f9SKrishna Gudipati 	rport_info.max_frmsz = rport->maxfrsize;
1956a36c61f9SKrishna Gudipati 	bfa_rport_online(rport->bfa_rport, &rport_info);
1957a36c61f9SKrishna Gudipati }
1958a36c61f9SKrishna Gudipati 
1959a36c61f9SKrishna Gudipati static struct bfa_fcs_rport_s *
1960a36c61f9SKrishna Gudipati bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
1961a36c61f9SKrishna Gudipati {
1962a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs = port->fcs;
1963a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
1964a36c61f9SKrishna Gudipati 	struct bfad_rport_s	*rport_drv;
1965a36c61f9SKrishna Gudipati 
19665fbe25c7SJing Huang 	/*
1967a36c61f9SKrishna Gudipati 	 * allocate rport
1968a36c61f9SKrishna Gudipati 	 */
1969a36c61f9SKrishna Gudipati 	if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv)
1970a36c61f9SKrishna Gudipati 		!= BFA_STATUS_OK) {
1971a36c61f9SKrishna Gudipati 		bfa_trc(fcs, rpid);
1972a36c61f9SKrishna Gudipati 		return NULL;
1973a36c61f9SKrishna Gudipati 	}
1974a36c61f9SKrishna Gudipati 
1975a36c61f9SKrishna Gudipati 	/*
1976a36c61f9SKrishna Gudipati 	 * Initialize r-port
1977a36c61f9SKrishna Gudipati 	 */
1978a36c61f9SKrishna Gudipati 	rport->port = port;
1979a36c61f9SKrishna Gudipati 	rport->fcs = fcs;
1980a36c61f9SKrishna Gudipati 	rport->rp_drv = rport_drv;
1981a36c61f9SKrishna Gudipati 	rport->pid = rpid;
1982a36c61f9SKrishna Gudipati 	rport->pwwn = pwwn;
1983a36c61f9SKrishna Gudipati 
19845fbe25c7SJing Huang 	/*
1985a36c61f9SKrishna Gudipati 	 * allocate BFA rport
1986a36c61f9SKrishna Gudipati 	 */
1987a36c61f9SKrishna Gudipati 	rport->bfa_rport = bfa_rport_create(port->fcs->bfa, rport);
1988a36c61f9SKrishna Gudipati 	if (!rport->bfa_rport) {
1989a36c61f9SKrishna Gudipati 		bfa_trc(fcs, rpid);
1990a36c61f9SKrishna Gudipati 		kfree(rport_drv);
1991a36c61f9SKrishna Gudipati 		return NULL;
1992a36c61f9SKrishna Gudipati 	}
1993a36c61f9SKrishna Gudipati 
19945fbe25c7SJing Huang 	/*
1995a36c61f9SKrishna Gudipati 	 * allocate FC-4s
1996a36c61f9SKrishna Gudipati 	 */
1997d4b671c5SJing Huang 	WARN_ON(!bfa_fcs_lport_is_initiator(port));
1998a36c61f9SKrishna Gudipati 
1999a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_is_initiator(port)) {
2000a36c61f9SKrishna Gudipati 		rport->itnim = bfa_fcs_itnim_create(rport);
2001a36c61f9SKrishna Gudipati 		if (!rport->itnim) {
2002a36c61f9SKrishna Gudipati 			bfa_trc(fcs, rpid);
2003da99dcc9SMaggie Zhang 			bfa_sm_send_event(rport->bfa_rport,
2004da99dcc9SMaggie Zhang 						BFA_RPORT_SM_DELETE);
2005a36c61f9SKrishna Gudipati 			kfree(rport_drv);
2006a36c61f9SKrishna Gudipati 			return NULL;
2007a36c61f9SKrishna Gudipati 		}
2008a36c61f9SKrishna Gudipati 	}
2009a36c61f9SKrishna Gudipati 
2010a36c61f9SKrishna Gudipati 	bfa_fcs_lport_add_rport(port, rport);
2011a36c61f9SKrishna Gudipati 
2012a36c61f9SKrishna Gudipati 	bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
2013a36c61f9SKrishna Gudipati 
2014a36c61f9SKrishna Gudipati 	/* Initialize the Rport Features(RPF) Sub Module  */
2015a36c61f9SKrishna Gudipati 	if (!BFA_FCS_PID_IS_WKA(rport->pid))
2016a36c61f9SKrishna Gudipati 		bfa_fcs_rpf_init(rport);
2017a36c61f9SKrishna Gudipati 
2018a36c61f9SKrishna Gudipati 	return rport;
2019a36c61f9SKrishna Gudipati }
2020a36c61f9SKrishna Gudipati 
2021a36c61f9SKrishna Gudipati 
2022a36c61f9SKrishna Gudipati static void
2023a36c61f9SKrishna Gudipati bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
2024a36c61f9SKrishna Gudipati {
2025a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2026a36c61f9SKrishna Gudipati 
20275fbe25c7SJing Huang 	/*
2028a36c61f9SKrishna Gudipati 	 * - delete FC-4s
2029a36c61f9SKrishna Gudipati 	 * - delete BFA rport
2030a36c61f9SKrishna Gudipati 	 * - remove from queue of rports
2031a36c61f9SKrishna Gudipati 	 */
2032a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_is_initiator(port)) {
2033a36c61f9SKrishna Gudipati 		bfa_fcs_itnim_delete(rport->itnim);
2034a36c61f9SKrishna Gudipati 		if (rport->pid != 0 && !BFA_FCS_PID_IS_WKA(rport->pid))
2035a36c61f9SKrishna Gudipati 			bfa_fcs_rpf_rport_offline(rport);
2036a36c61f9SKrishna Gudipati 	}
2037a36c61f9SKrishna Gudipati 
2038f7f73812SMaggie Zhang 	bfa_sm_send_event(rport->bfa_rport, BFA_RPORT_SM_DELETE);
2039a36c61f9SKrishna Gudipati 	bfa_fcs_lport_del_rport(port, rport);
2040a36c61f9SKrishna Gudipati 	kfree(rport->rp_drv);
2041a36c61f9SKrishna Gudipati }
2042a36c61f9SKrishna Gudipati 
2043a36c61f9SKrishna Gudipati static void
2044a36c61f9SKrishna Gudipati bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
2045a36c61f9SKrishna Gudipati {
2046a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2047a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2048a36c61f9SKrishna Gudipati 	char	lpwwn_buf[BFA_STRING_32];
2049a36c61f9SKrishna Gudipati 	char	rpwwn_buf[BFA_STRING_32];
2050a36c61f9SKrishna Gudipati 
2051a36c61f9SKrishna Gudipati 	rport->stats.onlines++;
2052a36c61f9SKrishna Gudipati 
2053d7be54ccSKrishna Gudipati 	if ((!rport->pid) || (!rport->pwwn)) {
2054d7be54ccSKrishna Gudipati 		bfa_trc(rport->fcs, rport->pid);
2055d7be54ccSKrishna Gudipati 		bfa_sm_fault(rport->fcs, rport->pid);
2056d7be54ccSKrishna Gudipati 	}
2057d7be54ccSKrishna Gudipati 
2058a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_is_initiator(port)) {
2059a36c61f9SKrishna Gudipati 		bfa_fcs_itnim_rport_online(rport->itnim);
2060a36c61f9SKrishna Gudipati 		if (!BFA_FCS_PID_IS_WKA(rport->pid))
2061a36c61f9SKrishna Gudipati 			bfa_fcs_rpf_rport_online(rport);
2062a36c61f9SKrishna Gudipati 	};
2063a36c61f9SKrishna Gudipati 
2064a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2065a36c61f9SKrishna Gudipati 	wwn2str(rpwwn_buf, rport->pwwn);
2066a36c61f9SKrishna Gudipati 	if (!BFA_FCS_PID_IS_WKA(rport->pid))
206788166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2068a36c61f9SKrishna Gudipati 		"Remote port (WWN = %s) online for logical port (WWN = %s)\n",
2069a36c61f9SKrishna Gudipati 		rpwwn_buf, lpwwn_buf);
2070a36c61f9SKrishna Gudipati }
2071a36c61f9SKrishna Gudipati 
2072a36c61f9SKrishna Gudipati static void
2073a36c61f9SKrishna Gudipati bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport)
2074a36c61f9SKrishna Gudipati {
2075a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2076a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2077a36c61f9SKrishna Gudipati 	char	lpwwn_buf[BFA_STRING_32];
2078a36c61f9SKrishna Gudipati 	char	rpwwn_buf[BFA_STRING_32];
2079a36c61f9SKrishna Gudipati 
2080a36c61f9SKrishna Gudipati 	rport->stats.offlines++;
2081d7be54ccSKrishna Gudipati 	rport->plogi_pending = BFA_FALSE;
2082a36c61f9SKrishna Gudipati 
2083a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2084a36c61f9SKrishna Gudipati 	wwn2str(rpwwn_buf, rport->pwwn);
2085a36c61f9SKrishna Gudipati 	if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
2086a36c61f9SKrishna Gudipati 		if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE)
208788166242SJing Huang 			BFA_LOG(KERN_ERR, bfad, bfa_log_level,
2088a36c61f9SKrishna Gudipati 				"Remote port (WWN = %s) connectivity lost for "
2089a36c61f9SKrishna Gudipati 				"logical port (WWN = %s)\n",
2090a36c61f9SKrishna Gudipati 				rpwwn_buf, lpwwn_buf);
2091a36c61f9SKrishna Gudipati 		else
209288166242SJing Huang 			BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2093a36c61f9SKrishna Gudipati 				"Remote port (WWN = %s) offlined by "
2094a36c61f9SKrishna Gudipati 				"logical port (WWN = %s)\n",
2095a36c61f9SKrishna Gudipati 				rpwwn_buf, lpwwn_buf);
2096a36c61f9SKrishna Gudipati 	}
2097a36c61f9SKrishna Gudipati 
2098a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_is_initiator(port)) {
2099a36c61f9SKrishna Gudipati 		bfa_fcs_itnim_rport_offline(rport->itnim);
2100a36c61f9SKrishna Gudipati 		if (!BFA_FCS_PID_IS_WKA(rport->pid))
2101a36c61f9SKrishna Gudipati 			bfa_fcs_rpf_rport_offline(rport);
2102a36c61f9SKrishna Gudipati 	}
2103a36c61f9SKrishna Gudipati }
2104a36c61f9SKrishna Gudipati 
21055fbe25c7SJing Huang /*
2106a36c61f9SKrishna Gudipati  * Update rport parameters from PLOGI or PLOGI accept.
2107a36c61f9SKrishna Gudipati  */
2108a36c61f9SKrishna Gudipati static void
2109a36c61f9SKrishna Gudipati bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
2110a36c61f9SKrishna Gudipati {
2111a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = rport->port;
2112a36c61f9SKrishna Gudipati 
21135fbe25c7SJing Huang 	/*
2114a36c61f9SKrishna Gudipati 	 * - port name
2115a36c61f9SKrishna Gudipati 	 * - node name
2116a36c61f9SKrishna Gudipati 	 */
2117a36c61f9SKrishna Gudipati 	rport->pwwn = plogi->port_name;
2118a36c61f9SKrishna Gudipati 	rport->nwwn = plogi->node_name;
2119a36c61f9SKrishna Gudipati 
21205fbe25c7SJing Huang 	/*
2121a36c61f9SKrishna Gudipati 	 * - class of service
2122a36c61f9SKrishna Gudipati 	 */
2123a36c61f9SKrishna Gudipati 	rport->fc_cos = 0;
2124a36c61f9SKrishna Gudipati 	if (plogi->class3.class_valid)
2125a36c61f9SKrishna Gudipati 		rport->fc_cos = FC_CLASS_3;
2126a36c61f9SKrishna Gudipati 
2127a36c61f9SKrishna Gudipati 	if (plogi->class2.class_valid)
2128a36c61f9SKrishna Gudipati 		rport->fc_cos |= FC_CLASS_2;
2129a36c61f9SKrishna Gudipati 
21305fbe25c7SJing Huang 	/*
2131a36c61f9SKrishna Gudipati 	 * - CISC
2132a36c61f9SKrishna Gudipati 	 * - MAX receive frame size
2133a36c61f9SKrishna Gudipati 	 */
2134a36c61f9SKrishna Gudipati 	rport->cisc = plogi->csp.cisc;
2135ba816ea8SJing Huang 	rport->maxfrsize = be16_to_cpu(plogi->class3.rxsz);
2136a36c61f9SKrishna Gudipati 
2137ba816ea8SJing Huang 	bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
2138a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->fabric->bb_credit);
21395fbe25c7SJing Huang 	/*
2140a36c61f9SKrishna Gudipati 	 * Direct Attach P2P mode :
2141a36c61f9SKrishna Gudipati 	 * This is to handle a bug (233476) in IBM targets in Direct Attach
2142a36c61f9SKrishna Gudipati 	 *  Mode. Basically, in FLOGI Accept the target would have
2143a36c61f9SKrishna Gudipati 	 * erroneously set the BB Credit to the value used in the FLOGI
2144a36c61f9SKrishna Gudipati 	 * sent by the HBA. It uses the correct value (its own BB credit)
2145a36c61f9SKrishna Gudipati 	 * in PLOGI.
2146a36c61f9SKrishna Gudipati 	 */
2147a36c61f9SKrishna Gudipati 	if ((!bfa_fcs_fabric_is_switched(port->fabric))	 &&
2148ba816ea8SJing Huang 		(be16_to_cpu(plogi->csp.bbcred) < port->fabric->bb_credit)) {
2149a36c61f9SKrishna Gudipati 
2150ba816ea8SJing Huang 		bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
2151a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, port->fabric->bb_credit);
2152a36c61f9SKrishna Gudipati 
2153ba816ea8SJing Huang 		port->fabric->bb_credit = be16_to_cpu(plogi->csp.bbcred);
2154a36c61f9SKrishna Gudipati 		bfa_fcport_set_tx_bbcredit(port->fcs->bfa,
2155be540a99SKrishna Gudipati 					  port->fabric->bb_credit, 0);
2156a36c61f9SKrishna Gudipati 	}
2157a36c61f9SKrishna Gudipati 
2158a36c61f9SKrishna Gudipati }
2159a36c61f9SKrishna Gudipati 
21605fbe25c7SJing Huang /*
2161a36c61f9SKrishna Gudipati  *	Called to handle LOGO received from an existing remote port.
2162a36c61f9SKrishna Gudipati  */
2163a36c61f9SKrishna Gudipati static void
2164a36c61f9SKrishna Gudipati bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs)
2165a36c61f9SKrishna Gudipati {
2166a36c61f9SKrishna Gudipati 	rport->reply_oxid = fchs->ox_id;
2167a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->reply_oxid);
2168a36c61f9SKrishna Gudipati 
2169a36c61f9SKrishna Gudipati 	rport->prlo = BFA_FALSE;
2170a36c61f9SKrishna Gudipati 	rport->stats.logo_rcvd++;
2171a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD);
2172a36c61f9SKrishna Gudipati }
2173a36c61f9SKrishna Gudipati 
2174a36c61f9SKrishna Gudipati 
2175a36c61f9SKrishna Gudipati 
21765fbe25c7SJing Huang /*
2177a36c61f9SKrishna Gudipati  *  fcs_rport_public FCS rport public interfaces
2178a36c61f9SKrishna Gudipati  */
2179a36c61f9SKrishna Gudipati 
21805fbe25c7SJing Huang /*
2181a36c61f9SKrishna Gudipati  *	Called by bport/vport to create a remote port instance for a discovered
2182a36c61f9SKrishna Gudipati  *	remote device.
2183a36c61f9SKrishna Gudipati  *
2184a36c61f9SKrishna Gudipati  * @param[in] port	- base port or vport
2185a36c61f9SKrishna Gudipati  * @param[in] rpid	- remote port ID
2186a36c61f9SKrishna Gudipati  *
2187a36c61f9SKrishna Gudipati  * @return None
2188a36c61f9SKrishna Gudipati  */
2189a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *
2190a36c61f9SKrishna Gudipati bfa_fcs_rport_create(struct bfa_fcs_lport_s *port, u32 rpid)
2191a36c61f9SKrishna Gudipati {
2192a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2193a36c61f9SKrishna Gudipati 
2194a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rpid);
2195a36c61f9SKrishna Gudipati 	rport = bfa_fcs_rport_alloc(port, WWN_NULL, rpid);
2196a36c61f9SKrishna Gudipati 	if (!rport)
2197a36c61f9SKrishna Gudipati 		return NULL;
2198a36c61f9SKrishna Gudipati 
2199a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
2200a36c61f9SKrishna Gudipati 	return rport;
2201a36c61f9SKrishna Gudipati }
2202a36c61f9SKrishna Gudipati 
22035fbe25c7SJing Huang /*
2204a36c61f9SKrishna Gudipati  * Called to create a rport for which only the wwn is known.
2205a36c61f9SKrishna Gudipati  *
2206a36c61f9SKrishna Gudipati  * @param[in] port	- base port
2207a36c61f9SKrishna Gudipati  * @param[in] rpwwn	- remote port wwn
2208a36c61f9SKrishna Gudipati  *
2209a36c61f9SKrishna Gudipati  * @return None
2210a36c61f9SKrishna Gudipati  */
2211a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *
2212a36c61f9SKrishna Gudipati bfa_fcs_rport_create_by_wwn(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
2213a36c61f9SKrishna Gudipati {
2214a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2215a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rpwwn);
2216a36c61f9SKrishna Gudipati 	rport = bfa_fcs_rport_alloc(port, rpwwn, 0);
2217a36c61f9SKrishna Gudipati 	if (!rport)
2218a36c61f9SKrishna Gudipati 		return NULL;
2219a36c61f9SKrishna Gudipati 
2220a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_DISC);
2221a36c61f9SKrishna Gudipati 	return rport;
2222a36c61f9SKrishna Gudipati }
22235fbe25c7SJing Huang /*
2224a36c61f9SKrishna Gudipati  * Called by bport in private loop topology to indicate that a
2225a36c61f9SKrishna Gudipati  * rport has been discovered and plogi has been completed.
2226a36c61f9SKrishna Gudipati  *
2227a36c61f9SKrishna Gudipati  * @param[in] port	- base port or vport
2228a36c61f9SKrishna Gudipati  * @param[in] rpid	- remote port ID
2229a36c61f9SKrishna Gudipati  */
2230a36c61f9SKrishna Gudipati void
2231a36c61f9SKrishna Gudipati bfa_fcs_rport_start(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
2232a36c61f9SKrishna Gudipati 	 struct fc_logi_s *plogi)
2233a36c61f9SKrishna Gudipati {
2234a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2235a36c61f9SKrishna Gudipati 
2236a36c61f9SKrishna Gudipati 	rport = bfa_fcs_rport_alloc(port, WWN_NULL, fchs->s_id);
2237a36c61f9SKrishna Gudipati 	if (!rport)
2238a36c61f9SKrishna Gudipati 		return;
2239a36c61f9SKrishna Gudipati 
2240a36c61f9SKrishna Gudipati 	bfa_fcs_rport_update(rport, plogi);
2241a36c61f9SKrishna Gudipati 
2242a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_COMP);
2243a36c61f9SKrishna Gudipati }
2244a36c61f9SKrishna Gudipati 
22455fbe25c7SJing Huang /*
2246a36c61f9SKrishna Gudipati  *	Called by bport/vport to handle PLOGI received from a new remote port.
2247a36c61f9SKrishna Gudipati  *	If an existing rport does a plogi, it will be handled separately.
2248a36c61f9SKrishna Gudipati  */
2249a36c61f9SKrishna Gudipati void
2250a36c61f9SKrishna Gudipati bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
2251a36c61f9SKrishna Gudipati 				struct fc_logi_s *plogi)
2252a36c61f9SKrishna Gudipati {
2253a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2254a36c61f9SKrishna Gudipati 
2255a36c61f9SKrishna Gudipati 	rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id);
2256a36c61f9SKrishna Gudipati 	if (!rport)
2257a36c61f9SKrishna Gudipati 		return;
2258a36c61f9SKrishna Gudipati 
2259a36c61f9SKrishna Gudipati 	bfa_fcs_rport_update(rport, plogi);
2260a36c61f9SKrishna Gudipati 
2261a36c61f9SKrishna Gudipati 	rport->reply_oxid = fchs->ox_id;
2262a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->reply_oxid);
2263a36c61f9SKrishna Gudipati 
2264a36c61f9SKrishna Gudipati 	rport->stats.plogi_rcvd++;
2265a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2266a36c61f9SKrishna Gudipati }
2267a36c61f9SKrishna Gudipati 
22685fbe25c7SJing Huang /*
2269a36c61f9SKrishna Gudipati  *	Called by bport/vport to handle PLOGI received from an existing
2270a36c61f9SKrishna Gudipati  *	 remote port.
2271a36c61f9SKrishna Gudipati  */
2272a36c61f9SKrishna Gudipati void
2273a36c61f9SKrishna Gudipati bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2274a36c61f9SKrishna Gudipati 			struct fc_logi_s *plogi)
2275a36c61f9SKrishna Gudipati {
22765fbe25c7SJing Huang 	/*
2277a36c61f9SKrishna Gudipati 	 * @todo Handle P2P and initiator-initiator.
2278a36c61f9SKrishna Gudipati 	 */
2279a36c61f9SKrishna Gudipati 
2280a36c61f9SKrishna Gudipati 	bfa_fcs_rport_update(rport, plogi);
2281a36c61f9SKrishna Gudipati 
2282a36c61f9SKrishna Gudipati 	rport->reply_oxid = rx_fchs->ox_id;
2283a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->reply_oxid);
2284a36c61f9SKrishna Gudipati 
2285d7be54ccSKrishna Gudipati 	rport->pid = rx_fchs->s_id;
2286d7be54ccSKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2287d7be54ccSKrishna Gudipati 
2288a36c61f9SKrishna Gudipati 	rport->stats.plogi_rcvd++;
2289a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2290a36c61f9SKrishna Gudipati }
2291a36c61f9SKrishna Gudipati 
2292a36c61f9SKrishna Gudipati 
22935fbe25c7SJing Huang /*
2294a36c61f9SKrishna Gudipati  *	Called by bport/vport to notify SCN for the remote port
2295a36c61f9SKrishna Gudipati  */
2296a36c61f9SKrishna Gudipati void
2297a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
2298a36c61f9SKrishna Gudipati {
2299a36c61f9SKrishna Gudipati 	rport->stats.rscns++;
2300a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_SCN);
2301a36c61f9SKrishna Gudipati }
2302a36c61f9SKrishna Gudipati 
2303a36c61f9SKrishna Gudipati 
23045fbe25c7SJing Huang /*
2305a36c61f9SKrishna Gudipati  *	brief
2306a36c61f9SKrishna Gudipati  *	This routine BFA callback for bfa_rport_online() call.
2307a36c61f9SKrishna Gudipati  *
2308a36c61f9SKrishna Gudipati  *	param[in]	cb_arg	-  rport struct.
2309a36c61f9SKrishna Gudipati  *
2310a36c61f9SKrishna Gudipati  *	return
2311a36c61f9SKrishna Gudipati  *		void
2312a36c61f9SKrishna Gudipati  *
2313a36c61f9SKrishna Gudipati  *	Special Considerations:
2314a36c61f9SKrishna Gudipati  *
2315a36c61f9SKrishna Gudipati  *	note
2316a36c61f9SKrishna Gudipati  */
2317a36c61f9SKrishna Gudipati void
2318a36c61f9SKrishna Gudipati bfa_cb_rport_online(void *cbarg)
2319a36c61f9SKrishna Gudipati {
2320a36c61f9SKrishna Gudipati 
2321a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2322a36c61f9SKrishna Gudipati 
2323a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2324a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_HCB_ONLINE);
2325a36c61f9SKrishna Gudipati }
2326a36c61f9SKrishna Gudipati 
23275fbe25c7SJing Huang /*
2328a36c61f9SKrishna Gudipati  *	brief
2329a36c61f9SKrishna Gudipati  *	This routine BFA callback for bfa_rport_offline() call.
2330a36c61f9SKrishna Gudipati  *
2331a36c61f9SKrishna Gudipati  *	param[in]	rport	-
2332a36c61f9SKrishna Gudipati  *
2333a36c61f9SKrishna Gudipati  *	return
2334a36c61f9SKrishna Gudipati  *		void
2335a36c61f9SKrishna Gudipati  *
2336a36c61f9SKrishna Gudipati  *	Special Considerations:
2337a36c61f9SKrishna Gudipati  *
2338a36c61f9SKrishna Gudipati  *	note
2339a36c61f9SKrishna Gudipati  */
2340a36c61f9SKrishna Gudipati void
2341a36c61f9SKrishna Gudipati bfa_cb_rport_offline(void *cbarg)
2342a36c61f9SKrishna Gudipati {
2343a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2344a36c61f9SKrishna Gudipati 
2345a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2346a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_HCB_OFFLINE);
2347a36c61f9SKrishna Gudipati }
2348a36c61f9SKrishna Gudipati 
23495fbe25c7SJing Huang /*
2350a36c61f9SKrishna Gudipati  *	brief
2351a36c61f9SKrishna Gudipati  *	This routine is a static BFA callback when there is a QoS flow_id
2352a36c61f9SKrishna Gudipati  *	change notification
2353a36c61f9SKrishna Gudipati  *
2354a36c61f9SKrishna Gudipati  *	param[in]	rport	-
2355a36c61f9SKrishna Gudipati  *
2356a36c61f9SKrishna Gudipati  *	return
2357a36c61f9SKrishna Gudipati  *		void
2358a36c61f9SKrishna Gudipati  *
2359a36c61f9SKrishna Gudipati  *	Special Considerations:
2360a36c61f9SKrishna Gudipati  *
2361a36c61f9SKrishna Gudipati  *	note
2362a36c61f9SKrishna Gudipati  */
2363a36c61f9SKrishna Gudipati void
2364a36c61f9SKrishna Gudipati bfa_cb_rport_qos_scn_flowid(void *cbarg,
2365a36c61f9SKrishna Gudipati 		struct bfa_rport_qos_attr_s old_qos_attr,
2366a36c61f9SKrishna Gudipati 		struct bfa_rport_qos_attr_s new_qos_attr)
2367a36c61f9SKrishna Gudipati {
2368a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2369a36c61f9SKrishna Gudipati 
2370a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2371a36c61f9SKrishna Gudipati }
2372a36c61f9SKrishna Gudipati 
23735fbe25c7SJing Huang /*
2374a36c61f9SKrishna Gudipati  *	brief
2375a36c61f9SKrishna Gudipati  *	This routine is a static BFA callback when there is a QoS priority
2376a36c61f9SKrishna Gudipati  *	change notification
2377a36c61f9SKrishna Gudipati  *
2378a36c61f9SKrishna Gudipati  *	param[in]	rport	-
2379a36c61f9SKrishna Gudipati  *
2380a36c61f9SKrishna Gudipati  *	return
2381a36c61f9SKrishna Gudipati  *		void
2382a36c61f9SKrishna Gudipati  *
2383a36c61f9SKrishna Gudipati  *	Special Considerations:
2384a36c61f9SKrishna Gudipati  *
2385a36c61f9SKrishna Gudipati  *	note
2386a36c61f9SKrishna Gudipati  */
2387a36c61f9SKrishna Gudipati void
2388a36c61f9SKrishna Gudipati bfa_cb_rport_qos_scn_prio(void *cbarg,
2389a36c61f9SKrishna Gudipati 		struct bfa_rport_qos_attr_s old_qos_attr,
2390a36c61f9SKrishna Gudipati 		struct bfa_rport_qos_attr_s new_qos_attr)
2391a36c61f9SKrishna Gudipati {
2392a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2393a36c61f9SKrishna Gudipati 
2394a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2395a36c61f9SKrishna Gudipati }
2396a36c61f9SKrishna Gudipati 
23975fbe25c7SJing Huang /*
2398a36c61f9SKrishna Gudipati  *		Called to process any unsolicted frames from this remote port
2399a36c61f9SKrishna Gudipati  */
2400a36c61f9SKrishna Gudipati void
2401a36c61f9SKrishna Gudipati bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport,
2402a36c61f9SKrishna Gudipati 			struct fchs_s *fchs, u16 len)
2403a36c61f9SKrishna Gudipati {
2404a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2405a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s	*els_cmd;
2406a36c61f9SKrishna Gudipati 
2407a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, fchs->s_id);
2408a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, fchs->d_id);
2409a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, fchs->type);
2410a36c61f9SKrishna Gudipati 
2411a36c61f9SKrishna Gudipati 	if (fchs->type != FC_TYPE_ELS)
2412a36c61f9SKrishna Gudipati 		return;
2413a36c61f9SKrishna Gudipati 
2414a36c61f9SKrishna Gudipati 	els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
2415a36c61f9SKrishna Gudipati 
2416a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, els_cmd->els_code);
2417a36c61f9SKrishna Gudipati 
2418a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
2419a36c61f9SKrishna Gudipati 	case FC_ELS_LOGO:
2420a36c61f9SKrishna Gudipati 		bfa_stats(port, plogi_rcvd);
2421a36c61f9SKrishna Gudipati 		bfa_fcs_rport_process_logo(rport, fchs);
2422a36c61f9SKrishna Gudipati 		break;
2423a36c61f9SKrishna Gudipati 
2424a36c61f9SKrishna Gudipati 	case FC_ELS_ADISC:
2425a36c61f9SKrishna Gudipati 		bfa_stats(port, adisc_rcvd);
2426a36c61f9SKrishna Gudipati 		bfa_fcs_rport_process_adisc(rport, fchs, len);
2427a36c61f9SKrishna Gudipati 		break;
2428a36c61f9SKrishna Gudipati 
2429a36c61f9SKrishna Gudipati 	case FC_ELS_PRLO:
2430a36c61f9SKrishna Gudipati 		bfa_stats(port, prlo_rcvd);
2431a36c61f9SKrishna Gudipati 		if (bfa_fcs_lport_is_initiator(port))
2432a36c61f9SKrishna Gudipati 			bfa_fcs_fcpim_uf_recv(rport->itnim, fchs, len);
2433a36c61f9SKrishna Gudipati 		break;
2434a36c61f9SKrishna Gudipati 
2435a36c61f9SKrishna Gudipati 	case FC_ELS_PRLI:
2436a36c61f9SKrishna Gudipati 		bfa_stats(port, prli_rcvd);
2437a36c61f9SKrishna Gudipati 		bfa_fcs_rport_process_prli(rport, fchs, len);
2438a36c61f9SKrishna Gudipati 		break;
2439a36c61f9SKrishna Gudipati 
2440a36c61f9SKrishna Gudipati 	case FC_ELS_RPSC:
2441a36c61f9SKrishna Gudipati 		bfa_stats(port, rpsc_rcvd);
2442a36c61f9SKrishna Gudipati 		bfa_fcs_rport_process_rpsc(rport, fchs, len);
2443a36c61f9SKrishna Gudipati 		break;
2444a36c61f9SKrishna Gudipati 
2445a36c61f9SKrishna Gudipati 	default:
2446a36c61f9SKrishna Gudipati 		bfa_stats(port, un_handled_els_rcvd);
2447a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_ls_rjt(rport, fchs,
2448a36c61f9SKrishna Gudipati 					  FC_LS_RJT_RSN_CMD_NOT_SUPP,
2449a36c61f9SKrishna Gudipati 					  FC_LS_RJT_EXP_NO_ADDL_INFO);
2450a36c61f9SKrishna Gudipati 		break;
2451a36c61f9SKrishna Gudipati 	}
2452a36c61f9SKrishna Gudipati }
2453a36c61f9SKrishna Gudipati 
2454a36c61f9SKrishna Gudipati /* send best case  acc to prlo */
2455a36c61f9SKrishna Gudipati static void
2456a36c61f9SKrishna Gudipati bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport)
2457a36c61f9SKrishna Gudipati {
2458a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2459a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2460a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2461a36c61f9SKrishna Gudipati 	int		len;
2462a36c61f9SKrishna Gudipati 
2463a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2464a36c61f9SKrishna Gudipati 
2465a36c61f9SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs);
2466a36c61f9SKrishna Gudipati 	if (!fcxp)
2467a36c61f9SKrishna Gudipati 		return;
2468a36c61f9SKrishna Gudipati 	len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2469a36c61f9SKrishna Gudipati 			rport->pid, bfa_fcs_lport_get_fcid(port),
2470a36c61f9SKrishna Gudipati 			rport->reply_oxid, 0);
2471a36c61f9SKrishna Gudipati 
2472a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id,
2473a36c61f9SKrishna Gudipati 		port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs,
2474a36c61f9SKrishna Gudipati 		NULL, NULL, FC_MAX_PDUSZ, 0);
2475a36c61f9SKrishna Gudipati }
2476a36c61f9SKrishna Gudipati 
2477a36c61f9SKrishna Gudipati /*
2478a36c61f9SKrishna Gudipati  * Send a LS reject
2479a36c61f9SKrishna Gudipati  */
2480a36c61f9SKrishna Gudipati static void
2481a36c61f9SKrishna Gudipati bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2482a36c61f9SKrishna Gudipati 			  u8 reason_code, u8 reason_code_expl)
2483a36c61f9SKrishna Gudipati {
2484a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2485a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2486a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2487a36c61f9SKrishna Gudipati 	int		len;
2488a36c61f9SKrishna Gudipati 
2489a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rx_fchs->s_id);
2490a36c61f9SKrishna Gudipati 
2491a36c61f9SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(rport->fcs);
2492a36c61f9SKrishna Gudipati 	if (!fcxp)
2493a36c61f9SKrishna Gudipati 		return;
2494a36c61f9SKrishna Gudipati 
2495a36c61f9SKrishna Gudipati 	len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2496a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2497a36c61f9SKrishna Gudipati 				rx_fchs->ox_id, reason_code, reason_code_expl);
2498a36c61f9SKrishna Gudipati 
2499a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
2500a36c61f9SKrishna Gudipati 			BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
2501a36c61f9SKrishna Gudipati 			FC_MAX_PDUSZ, 0);
2502a36c61f9SKrishna Gudipati }
2503a36c61f9SKrishna Gudipati 
25045fbe25c7SJing Huang /*
2505a36c61f9SKrishna Gudipati  * Return state of rport.
2506a36c61f9SKrishna Gudipati  */
2507a36c61f9SKrishna Gudipati int
2508a36c61f9SKrishna Gudipati bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport)
2509a36c61f9SKrishna Gudipati {
2510a36c61f9SKrishna Gudipati 	return bfa_sm_to_state(rport_sm_table, rport->sm);
2511a36c61f9SKrishna Gudipati }
2512a36c61f9SKrishna Gudipati 
2513f7f73812SMaggie Zhang 
25145fbe25c7SJing Huang /*
2515a36c61f9SKrishna Gudipati  *	brief
2516a36c61f9SKrishna Gudipati  *		 Called by the Driver to set rport delete/ageout timeout
2517a36c61f9SKrishna Gudipati  *
2518a36c61f9SKrishna Gudipati  *	param[in]		rport timeout value in seconds.
2519a36c61f9SKrishna Gudipati  *
2520a36c61f9SKrishna Gudipati  *	return None
2521a36c61f9SKrishna Gudipati  */
2522a36c61f9SKrishna Gudipati void
2523a36c61f9SKrishna Gudipati bfa_fcs_rport_set_del_timeout(u8 rport_tmo)
2524a36c61f9SKrishna Gudipati {
2525a36c61f9SKrishna Gudipati 	/* convert to Millisecs */
2526a36c61f9SKrishna Gudipati 	if (rport_tmo > 0)
2527a36c61f9SKrishna Gudipati 		bfa_fcs_rport_del_timeout = rport_tmo * 1000;
2528a36c61f9SKrishna Gudipati }
2529a36c61f9SKrishna Gudipati void
253050444a34SMaggie bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, __be16 ox_id)
2531a36c61f9SKrishna Gudipati {
2532a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2533a36c61f9SKrishna Gudipati 
2534a36c61f9SKrishna Gudipati 	rport->prlo = BFA_TRUE;
2535a36c61f9SKrishna Gudipati 	rport->reply_oxid = ox_id;
2536a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PRLO_RCVD);
2537a36c61f9SKrishna Gudipati }
2538a36c61f9SKrishna Gudipati 
253960138066SKrishna Gudipati void
254060138066SKrishna Gudipati bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
254160138066SKrishna Gudipati 		struct bfa_rport_attr_s *rport_attr)
254260138066SKrishna Gudipati {
254360138066SKrishna Gudipati 	struct bfa_rport_qos_attr_s qos_attr;
254460138066SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
254560138066SKrishna Gudipati 	bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed;
2546a36c61f9SKrishna Gudipati 
254760138066SKrishna Gudipati 	memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
254860138066SKrishna Gudipati 	memset(&qos_attr, 0, sizeof(struct bfa_rport_qos_attr_s));
254960138066SKrishna Gudipati 
255060138066SKrishna Gudipati 	rport_attr->pid = rport->pid;
255160138066SKrishna Gudipati 	rport_attr->pwwn = rport->pwwn;
255260138066SKrishna Gudipati 	rport_attr->nwwn = rport->nwwn;
255360138066SKrishna Gudipati 	rport_attr->cos_supported = rport->fc_cos;
255460138066SKrishna Gudipati 	rport_attr->df_sz = rport->maxfrsize;
255560138066SKrishna Gudipati 	rport_attr->state = bfa_fcs_rport_get_state(rport);
255660138066SKrishna Gudipati 	rport_attr->fc_cos = rport->fc_cos;
255760138066SKrishna Gudipati 	rport_attr->cisc = rport->cisc;
255860138066SKrishna Gudipati 	rport_attr->scsi_function = rport->scsi_function;
255960138066SKrishna Gudipati 	rport_attr->curr_speed  = rport->rpf.rpsc_speed;
256060138066SKrishna Gudipati 	rport_attr->assigned_speed  = rport->rpf.assigned_speed;
256160138066SKrishna Gudipati 
256260138066SKrishna Gudipati 	qos_attr.qos_priority = rport->bfa_rport->qos_attr.qos_priority;
256360138066SKrishna Gudipati 	qos_attr.qos_flow_id =
256460138066SKrishna Gudipati 		cpu_to_be32(rport->bfa_rport->qos_attr.qos_flow_id);
256560138066SKrishna Gudipati 	rport_attr->qos_attr = qos_attr;
256660138066SKrishna Gudipati 
256760138066SKrishna Gudipati 	rport_attr->trl_enforced = BFA_FALSE;
256860138066SKrishna Gudipati 	if (bfa_fcport_is_ratelim(port->fcs->bfa) &&
256960138066SKrishna Gudipati 	    (rport->scsi_function == BFA_RPORT_TARGET)) {
257060138066SKrishna Gudipati 		if (rport_speed == BFA_PORT_SPEED_UNKNOWN)
257160138066SKrishna Gudipati 			rport_speed =
257260138066SKrishna Gudipati 				bfa_fcport_get_ratelim_speed(rport->fcs->bfa);
257360138066SKrishna Gudipati 
257460138066SKrishna Gudipati 		if (rport_speed < bfa_fcs_lport_get_rport_max_speed(port))
257560138066SKrishna Gudipati 			rport_attr->trl_enforced = BFA_TRUE;
257660138066SKrishna Gudipati 	}
257760138066SKrishna Gudipati }
2578a36c61f9SKrishna Gudipati 
25795fbe25c7SJing Huang /*
2580a36c61f9SKrishna Gudipati  * Remote port implementation.
2581a36c61f9SKrishna Gudipati  */
2582a36c61f9SKrishna Gudipati 
25835fbe25c7SJing Huang /*
2584a36c61f9SKrishna Gudipati  *  fcs_rport_api FCS rport API.
2585a36c61f9SKrishna Gudipati  */
2586a36c61f9SKrishna Gudipati 
2587a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *
2588a36c61f9SKrishna Gudipati bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
2589a36c61f9SKrishna Gudipati {
2590a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2591a36c61f9SKrishna Gudipati 
2592a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn);
2593a36c61f9SKrishna Gudipati 	if (rport == NULL) {
2594a36c61f9SKrishna Gudipati 		/*
2595a36c61f9SKrishna Gudipati 		 * TBD Error handling
2596a36c61f9SKrishna Gudipati 		 */
2597a36c61f9SKrishna Gudipati 	}
2598a36c61f9SKrishna Gudipati 
2599a36c61f9SKrishna Gudipati 	return rport;
2600a36c61f9SKrishna Gudipati }
2601a36c61f9SKrishna Gudipati 
2602a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *
2603a36c61f9SKrishna Gudipati bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t rnwwn)
2604a36c61f9SKrishna Gudipati {
2605a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2606a36c61f9SKrishna Gudipati 
2607a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_nwwn(port, rnwwn);
2608a36c61f9SKrishna Gudipati 	if (rport == NULL) {
2609a36c61f9SKrishna Gudipati 		/*
2610a36c61f9SKrishna Gudipati 		 * TBD Error handling
2611a36c61f9SKrishna Gudipati 		 */
2612a36c61f9SKrishna Gudipati 	}
2613a36c61f9SKrishna Gudipati 
2614a36c61f9SKrishna Gudipati 	return rport;
2615a36c61f9SKrishna Gudipati }
2616a36c61f9SKrishna Gudipati 
2617a36c61f9SKrishna Gudipati /*
2618a36c61f9SKrishna Gudipati  * Remote port features (RPF) implementation.
2619a36c61f9SKrishna Gudipati  */
2620a36c61f9SKrishna Gudipati 
2621a36c61f9SKrishna Gudipati #define BFA_FCS_RPF_RETRIES	(3)
2622a36c61f9SKrishna Gudipati #define BFA_FCS_RPF_RETRY_TIMEOUT  (1000) /* 1 sec (In millisecs) */
2623a36c61f9SKrishna Gudipati 
2624a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_send_rpsc2(void *rport_cbarg,
2625a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp_alloced);
2626a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_rpsc2_response(void *fcsarg,
2627a36c61f9SKrishna Gudipati 			struct bfa_fcxp_s *fcxp,
2628a36c61f9SKrishna Gudipati 			void *cbarg,
2629a36c61f9SKrishna Gudipati 			bfa_status_t req_status,
2630a36c61f9SKrishna Gudipati 			u32 rsp_len,
2631a36c61f9SKrishna Gudipati 			u32 resid_len,
2632a36c61f9SKrishna Gudipati 			struct fchs_s *rsp_fchs);
2633a36c61f9SKrishna Gudipati 
2634a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_timeout(void *arg);
2635a36c61f9SKrishna Gudipati 
26365fbe25c7SJing Huang /*
2637a36c61f9SKrishna Gudipati  *  fcs_rport_ftrs_sm FCS rport state machine events
2638a36c61f9SKrishna Gudipati  */
2639a36c61f9SKrishna Gudipati 
2640a36c61f9SKrishna Gudipati enum rpf_event {
2641a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPORT_OFFLINE  = 1, /* Rport offline		*/
2642a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPORT_ONLINE   = 2,	/* Rport online			*/
2643a36c61f9SKrishna Gudipati 	RPFSM_EVENT_FCXP_SENT      = 3,	/* Frame from has been sent	*/
2644a36c61f9SKrishna Gudipati 	RPFSM_EVENT_TIMEOUT	   = 4, /* Rport SM timeout event	*/
2645a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPSC_COMP      = 5,
2646a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPSC_FAIL      = 6,
2647a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPSC_ERROR     = 7,
2648a36c61f9SKrishna Gudipati };
2649a36c61f9SKrishna Gudipati 
2650a36c61f9SKrishna Gudipati static void	bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf,
2651a36c61f9SKrishna Gudipati 					enum rpf_event event);
2652a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf,
2653a36c61f9SKrishna Gudipati 				       enum rpf_event event);
2654a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf,
2655a36c61f9SKrishna Gudipati 				       enum rpf_event event);
2656a36c61f9SKrishna Gudipati static void	bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf,
2657a36c61f9SKrishna Gudipati 					enum rpf_event event);
2658a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf,
2659a36c61f9SKrishna Gudipati 					enum rpf_event event);
2660a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf,
2661a36c61f9SKrishna Gudipati 					enum rpf_event event);
2662a36c61f9SKrishna Gudipati 
2663a36c61f9SKrishna Gudipati static void
2664a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2665a36c61f9SKrishna Gudipati {
2666a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2667a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = &rport->fcs->fabric;
2668a36c61f9SKrishna Gudipati 
2669a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2670a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2671a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
2672a36c61f9SKrishna Gudipati 
2673a36c61f9SKrishna Gudipati 	switch (event) {
2674a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_ONLINE:
2675a36c61f9SKrishna Gudipati 		/* Send RPSC2 to a Brocade fabric only. */
2676a36c61f9SKrishna Gudipati 		if ((!BFA_FCS_PID_IS_WKA(rport->pid)) &&
2677f7f73812SMaggie Zhang 			((rport->port->fabric->lps->brcd_switch) ||
2678a36c61f9SKrishna Gudipati 			(bfa_fcs_fabric_get_switch_oui(fabric) ==
2679a36c61f9SKrishna Gudipati 						BFA_FCS_BRCD_SWITCH_OUI))) {
2680a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
2681a36c61f9SKrishna Gudipati 			rpf->rpsc_retries = 0;
2682a36c61f9SKrishna Gudipati 			bfa_fcs_rpf_send_rpsc2(rpf, NULL);
2683a36c61f9SKrishna Gudipati 		}
2684a36c61f9SKrishna Gudipati 		break;
2685a36c61f9SKrishna Gudipati 
2686a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
2687a36c61f9SKrishna Gudipati 		break;
2688a36c61f9SKrishna Gudipati 
2689a36c61f9SKrishna Gudipati 	default:
2690a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
2691a36c61f9SKrishna Gudipati 	}
2692a36c61f9SKrishna Gudipati }
2693a36c61f9SKrishna Gudipati 
2694a36c61f9SKrishna Gudipati static void
2695a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2696a36c61f9SKrishna Gudipati {
2697a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2698a36c61f9SKrishna Gudipati 
2699a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
2700a36c61f9SKrishna Gudipati 
2701a36c61f9SKrishna Gudipati 	switch (event) {
2702a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_FCXP_SENT:
2703a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc);
2704a36c61f9SKrishna Gudipati 		break;
2705a36c61f9SKrishna Gudipati 
2706a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
2707a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
2708a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe);
2709a36c61f9SKrishna Gudipati 		rpf->rpsc_retries = 0;
2710a36c61f9SKrishna Gudipati 		break;
2711a36c61f9SKrishna Gudipati 
2712a36c61f9SKrishna Gudipati 	default:
2713a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
2714a36c61f9SKrishna Gudipati 	}
2715a36c61f9SKrishna Gudipati }
2716a36c61f9SKrishna Gudipati 
2717a36c61f9SKrishna Gudipati static void
2718a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2719a36c61f9SKrishna Gudipati {
2720a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2721a36c61f9SKrishna Gudipati 
2722a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2723a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
2724a36c61f9SKrishna Gudipati 
2725a36c61f9SKrishna Gudipati 	switch (event) {
2726a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPSC_COMP:
2727a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
2728a36c61f9SKrishna Gudipati 		/* Update speed info in f/w via BFA */
2729a36c61f9SKrishna Gudipati 		if (rpf->rpsc_speed != BFA_PORT_SPEED_UNKNOWN)
2730a36c61f9SKrishna Gudipati 			bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed);
2731a36c61f9SKrishna Gudipati 		else if (rpf->assigned_speed != BFA_PORT_SPEED_UNKNOWN)
2732a36c61f9SKrishna Gudipati 			bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed);
2733a36c61f9SKrishna Gudipati 		break;
2734a36c61f9SKrishna Gudipati 
2735a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPSC_FAIL:
2736a36c61f9SKrishna Gudipati 		/* RPSC not supported by rport */
2737a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
2738a36c61f9SKrishna Gudipati 		break;
2739a36c61f9SKrishna Gudipati 
2740a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPSC_ERROR:
2741a36c61f9SKrishna Gudipati 		/* need to retry...delayed a bit. */
2742a36c61f9SKrishna Gudipati 		if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) {
2743a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rpf->timer,
2744a36c61f9SKrishna Gudipati 				    bfa_fcs_rpf_timeout, rpf,
2745a36c61f9SKrishna Gudipati 				    BFA_FCS_RPF_RETRY_TIMEOUT);
2746a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry);
2747a36c61f9SKrishna Gudipati 		} else {
2748a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
2749a36c61f9SKrishna Gudipati 		}
2750a36c61f9SKrishna Gudipati 		break;
2751a36c61f9SKrishna Gudipati 
2752a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
2753a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
2754a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rpf->fcxp);
2755a36c61f9SKrishna Gudipati 		rpf->rpsc_retries = 0;
2756a36c61f9SKrishna Gudipati 		break;
2757a36c61f9SKrishna Gudipati 
2758a36c61f9SKrishna Gudipati 	default:
2759a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
2760a36c61f9SKrishna Gudipati 	}
2761a36c61f9SKrishna Gudipati }
2762a36c61f9SKrishna Gudipati 
2763a36c61f9SKrishna Gudipati static void
2764a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2765a36c61f9SKrishna Gudipati {
2766a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2767a36c61f9SKrishna Gudipati 
2768a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2769a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
2770a36c61f9SKrishna Gudipati 
2771a36c61f9SKrishna Gudipati 	switch (event) {
2772a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_TIMEOUT:
2773a36c61f9SKrishna Gudipati 		/* re-send the RPSC */
2774a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
2775a36c61f9SKrishna Gudipati 		bfa_fcs_rpf_send_rpsc2(rpf, NULL);
2776a36c61f9SKrishna Gudipati 		break;
2777a36c61f9SKrishna Gudipati 
2778a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
2779a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rpf->timer);
2780a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
2781a36c61f9SKrishna Gudipati 		rpf->rpsc_retries = 0;
2782a36c61f9SKrishna Gudipati 		break;
2783a36c61f9SKrishna Gudipati 
2784a36c61f9SKrishna Gudipati 	default:
2785a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
2786a36c61f9SKrishna Gudipati 	}
2787a36c61f9SKrishna Gudipati }
2788a36c61f9SKrishna Gudipati 
2789a36c61f9SKrishna Gudipati static void
2790a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2791a36c61f9SKrishna Gudipati {
2792a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2793a36c61f9SKrishna Gudipati 
2794a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2795a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2796a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
2797a36c61f9SKrishna Gudipati 
2798a36c61f9SKrishna Gudipati 	switch (event) {
2799a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
2800a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
2801a36c61f9SKrishna Gudipati 		rpf->rpsc_retries = 0;
2802a36c61f9SKrishna Gudipati 		break;
2803a36c61f9SKrishna Gudipati 
2804a36c61f9SKrishna Gudipati 	default:
2805a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
2806a36c61f9SKrishna Gudipati 	}
2807a36c61f9SKrishna Gudipati }
2808a36c61f9SKrishna Gudipati 
2809a36c61f9SKrishna Gudipati static void
2810a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2811a36c61f9SKrishna Gudipati {
2812a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2813a36c61f9SKrishna Gudipati 
2814a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2815a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2816a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
2817a36c61f9SKrishna Gudipati 
2818a36c61f9SKrishna Gudipati 	switch (event) {
2819a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_ONLINE:
2820a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
2821a36c61f9SKrishna Gudipati 		bfa_fcs_rpf_send_rpsc2(rpf, NULL);
2822a36c61f9SKrishna Gudipati 		break;
2823a36c61f9SKrishna Gudipati 
2824a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
2825a36c61f9SKrishna Gudipati 		break;
2826a36c61f9SKrishna Gudipati 
2827a36c61f9SKrishna Gudipati 	default:
2828a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
2829a36c61f9SKrishna Gudipati 	}
2830a36c61f9SKrishna Gudipati }
28315fbe25c7SJing Huang /*
2832a36c61f9SKrishna Gudipati  * Called when Rport is created.
2833a36c61f9SKrishna Gudipati  */
2834a36c61f9SKrishna Gudipati void
2835a36c61f9SKrishna Gudipati bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport)
2836a36c61f9SKrishna Gudipati {
2837a36c61f9SKrishna Gudipati 	struct bfa_fcs_rpf_s *rpf = &rport->rpf;
2838a36c61f9SKrishna Gudipati 
2839a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2840a36c61f9SKrishna Gudipati 	rpf->rport = rport;
2841a36c61f9SKrishna Gudipati 
2842a36c61f9SKrishna Gudipati 	bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit);
2843a36c61f9SKrishna Gudipati }
2844a36c61f9SKrishna Gudipati 
28455fbe25c7SJing Huang /*
2846a36c61f9SKrishna Gudipati  * Called when Rport becomes online
2847a36c61f9SKrishna Gudipati  */
2848a36c61f9SKrishna Gudipati void
2849a36c61f9SKrishna Gudipati bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport)
2850a36c61f9SKrishna Gudipati {
2851a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2852a36c61f9SKrishna Gudipati 
2853a36c61f9SKrishna Gudipati 	if (__fcs_min_cfg(rport->port->fcs))
2854a36c61f9SKrishna Gudipati 		return;
2855a36c61f9SKrishna Gudipati 
2856a36c61f9SKrishna Gudipati 	if (bfa_fcs_fabric_is_switched(rport->port->fabric))
2857a36c61f9SKrishna Gudipati 		bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE);
2858a36c61f9SKrishna Gudipati }
2859a36c61f9SKrishna Gudipati 
28605fbe25c7SJing Huang /*
2861a36c61f9SKrishna Gudipati  * Called when Rport becomes offline
2862a36c61f9SKrishna Gudipati  */
2863a36c61f9SKrishna Gudipati void
2864a36c61f9SKrishna Gudipati bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport)
2865a36c61f9SKrishna Gudipati {
2866a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2867a36c61f9SKrishna Gudipati 
2868a36c61f9SKrishna Gudipati 	if (__fcs_min_cfg(rport->port->fcs))
2869a36c61f9SKrishna Gudipati 		return;
2870a36c61f9SKrishna Gudipati 
2871a36c61f9SKrishna Gudipati 	rport->rpf.rpsc_speed = 0;
2872a36c61f9SKrishna Gudipati 	bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE);
2873a36c61f9SKrishna Gudipati }
2874a36c61f9SKrishna Gudipati 
2875a36c61f9SKrishna Gudipati static void
2876a36c61f9SKrishna Gudipati bfa_fcs_rpf_timeout(void *arg)
2877a36c61f9SKrishna Gudipati {
2878a36c61f9SKrishna Gudipati 	struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg;
2879a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2880a36c61f9SKrishna Gudipati 
2881a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2882a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rpf, RPFSM_EVENT_TIMEOUT);
2883a36c61f9SKrishna Gudipati }
2884a36c61f9SKrishna Gudipati 
2885a36c61f9SKrishna Gudipati static void
2886a36c61f9SKrishna Gudipati bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced)
2887a36c61f9SKrishna Gudipati {
2888a36c61f9SKrishna Gudipati 	struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg;
2889a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2890a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2891a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2892a36c61f9SKrishna Gudipati 	int		len;
2893a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2894a36c61f9SKrishna Gudipati 
2895a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2896a36c61f9SKrishna Gudipati 
2897a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
2898a36c61f9SKrishna Gudipati 	if (!fcxp) {
2899a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe,
2900a36c61f9SKrishna Gudipati 					bfa_fcs_rpf_send_rpsc2, rpf);
2901a36c61f9SKrishna Gudipati 		return;
2902a36c61f9SKrishna Gudipati 	}
2903a36c61f9SKrishna Gudipati 	rpf->fcxp = fcxp;
2904a36c61f9SKrishna Gudipati 
2905a36c61f9SKrishna Gudipati 	len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
2906a36c61f9SKrishna Gudipati 			    bfa_fcs_lport_get_fcid(port), &rport->pid, 1);
2907a36c61f9SKrishna Gudipati 
2908a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
2909a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response,
2910a36c61f9SKrishna Gudipati 			  rpf, FC_MAX_PDUSZ, FC_ELS_TOV);
2911a36c61f9SKrishna Gudipati 	rport->stats.rpsc_sent++;
2912a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT);
2913a36c61f9SKrishna Gudipati 
2914a36c61f9SKrishna Gudipati }
2915a36c61f9SKrishna Gudipati 
2916a36c61f9SKrishna Gudipati static void
2917a36c61f9SKrishna Gudipati bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
2918a36c61f9SKrishna Gudipati 			    bfa_status_t req_status, u32 rsp_len,
2919a36c61f9SKrishna Gudipati 			    u32 resid_len, struct fchs_s *rsp_fchs)
2920a36c61f9SKrishna Gudipati {
2921a36c61f9SKrishna Gudipati 	struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg;
2922a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2923a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s *ls_rjt;
2924a36c61f9SKrishna Gudipati 	struct fc_rpsc2_acc_s *rpsc2_acc;
2925a36c61f9SKrishna Gudipati 	u16	num_ents;
2926a36c61f9SKrishna Gudipati 
2927a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, req_status);
2928a36c61f9SKrishna Gudipati 
2929a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
2930a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, req_status);
2931a36c61f9SKrishna Gudipati 		if (req_status == BFA_STATUS_ETIMER)
2932a36c61f9SKrishna Gudipati 			rport->stats.rpsc_failed++;
2933a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
2934a36c61f9SKrishna Gudipati 		return;
2935a36c61f9SKrishna Gudipati 	}
2936a36c61f9SKrishna Gudipati 
2937a36c61f9SKrishna Gudipati 	rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp);
2938a36c61f9SKrishna Gudipati 	if (rpsc2_acc->els_cmd == FC_ELS_ACC) {
2939a36c61f9SKrishna Gudipati 		rport->stats.rpsc_accs++;
2940ba816ea8SJing Huang 		num_ents = be16_to_cpu(rpsc2_acc->num_pids);
2941a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, num_ents);
2942a36c61f9SKrishna Gudipati 		if (num_ents > 0) {
2943d4b671c5SJing Huang 			WARN_ON(rpsc2_acc->port_info[0].pid == rport->pid);
2944a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs,
2945ba816ea8SJing Huang 				be16_to_cpu(rpsc2_acc->port_info[0].pid));
2946a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs,
2947ba816ea8SJing Huang 				be16_to_cpu(rpsc2_acc->port_info[0].speed));
2948a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs,
2949ba816ea8SJing Huang 				be16_to_cpu(rpsc2_acc->port_info[0].index));
2950a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs,
2951a36c61f9SKrishna Gudipati 				rpsc2_acc->port_info[0].type);
2952a36c61f9SKrishna Gudipati 
2953a36c61f9SKrishna Gudipati 			if (rpsc2_acc->port_info[0].speed == 0) {
2954a36c61f9SKrishna Gudipati 				bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
2955a36c61f9SKrishna Gudipati 				return;
2956a36c61f9SKrishna Gudipati 			}
2957a36c61f9SKrishna Gudipati 
2958a36c61f9SKrishna Gudipati 			rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed(
2959ba816ea8SJing Huang 				be16_to_cpu(rpsc2_acc->port_info[0].speed));
2960a36c61f9SKrishna Gudipati 
2961a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP);
2962a36c61f9SKrishna Gudipati 		}
2963a36c61f9SKrishna Gudipati 	} else {
2964a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
2965a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, ls_rjt->reason_code);
2966a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
2967a36c61f9SKrishna Gudipati 		rport->stats.rpsc_rejects++;
2968a36c61f9SKrishna Gudipati 		if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP)
2969a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL);
2970a36c61f9SKrishna Gudipati 		else
2971a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
2972a36c61f9SKrishna Gudipati 	}
2973a36c61f9SKrishna Gudipati }
2974