xref: /openbmc/linux/drivers/scsi/bfa/bfa_fcs_rport.c (revision 5fbe25c7)
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 
22a36c61f9SKrishna Gudipati #include "bfa_fcs.h"
23a36c61f9SKrishna Gudipati #include "bfa_fcbuild.h"
24a36c61f9SKrishna Gudipati #include "bfad_drv.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);
785fbe25c7SJing Huang /*
79a36c61f9SKrishna Gudipati  *  fcs_rport_sm FCS rport state machine events
80a36c61f9SKrishna Gudipati  */
81a36c61f9SKrishna Gudipati 
82a36c61f9SKrishna Gudipati enum rport_event {
83a36c61f9SKrishna Gudipati 	RPSM_EVENT_PLOGI_SEND	= 1,	/*  new rport; start with PLOGI */
84a36c61f9SKrishna Gudipati 	RPSM_EVENT_PLOGI_RCVD	= 2,	/*  Inbound PLOGI from remote port */
85a36c61f9SKrishna Gudipati 	RPSM_EVENT_PLOGI_COMP	= 3,	/*  PLOGI completed to rport	*/
86a36c61f9SKrishna Gudipati 	RPSM_EVENT_LOGO_RCVD	= 4,	/*  LOGO from remote device	*/
87a36c61f9SKrishna Gudipati 	RPSM_EVENT_LOGO_IMP	= 5,	/*  implicit logo for SLER	*/
88a36c61f9SKrishna Gudipati 	RPSM_EVENT_FCXP_SENT	= 6,	/*  Frame from has been sent	*/
89a36c61f9SKrishna Gudipati 	RPSM_EVENT_DELETE	= 7,	/*  RPORT delete request	*/
90a36c61f9SKrishna Gudipati 	RPSM_EVENT_SCN		= 8,	/*  state change notification	*/
91a36c61f9SKrishna Gudipati 	RPSM_EVENT_ACCEPTED	= 9,	/*  Good response from remote device */
92a36c61f9SKrishna Gudipati 	RPSM_EVENT_FAILED	= 10,	/*  Request to rport failed.	*/
93a36c61f9SKrishna Gudipati 	RPSM_EVENT_TIMEOUT	= 11,	/*  Rport SM timeout event	*/
94a36c61f9SKrishna Gudipati 	RPSM_EVENT_HCB_ONLINE  = 12,	/*  BFA rport online callback	*/
95a36c61f9SKrishna Gudipati 	RPSM_EVENT_HCB_OFFLINE = 13,	/*  BFA rport offline callback	*/
96a36c61f9SKrishna Gudipati 	RPSM_EVENT_FC4_OFFLINE = 14,	/*  FC-4 offline complete	*/
97a36c61f9SKrishna Gudipati 	RPSM_EVENT_ADDRESS_CHANGE = 15,	/*  Rport's PID has changed	*/
98a36c61f9SKrishna Gudipati 	RPSM_EVENT_ADDRESS_DISC = 16,	/*  Need to Discover rport's PID */
99a36c61f9SKrishna Gudipati 	RPSM_EVENT_PRLO_RCVD   = 17,	/*  PRLO from remote device	*/
100a36c61f9SKrishna Gudipati 	RPSM_EVENT_PLOGI_RETRY = 18,	/*  Retry PLOGI continously */
101a36c61f9SKrishna Gudipati };
102a36c61f9SKrishna Gudipati 
103a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport,
104a36c61f9SKrishna Gudipati 					enum rport_event event);
105a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
106a36c61f9SKrishna Gudipati 						enum rport_event event);
107a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
108a36c61f9SKrishna Gudipati 						  enum rport_event event);
109a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
110a36c61f9SKrishna Gudipati 						enum rport_event event);
111a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport,
112a36c61f9SKrishna Gudipati 					enum rport_event event);
113a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
114a36c61f9SKrishna Gudipati 						enum rport_event event);
115a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport,
116a36c61f9SKrishna Gudipati 					enum rport_event event);
117a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
118a36c61f9SKrishna Gudipati 						 enum rport_event event);
119a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport,
120a36c61f9SKrishna Gudipati 					 enum rport_event event);
121a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
122a36c61f9SKrishna Gudipati 						enum rport_event event);
123a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport,
124a36c61f9SKrishna Gudipati 					enum rport_event event);
125a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
126a36c61f9SKrishna Gudipati 						enum rport_event event);
127a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_fc4_logosend(struct bfa_fcs_rport_s *rport,
128a36c61f9SKrishna Gudipati 						enum rport_event event);
129a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
130a36c61f9SKrishna Gudipati 						enum rport_event event);
131a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
132a36c61f9SKrishna Gudipati 						enum rport_event event);
133a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
134a36c61f9SKrishna Gudipati 						enum rport_event event);
135a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_hcb_logosend(struct bfa_fcs_rport_s *rport,
136a36c61f9SKrishna Gudipati 						enum rport_event event);
137a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_logo_sending(struct bfa_fcs_rport_s *rport,
138a36c61f9SKrishna Gudipati 						enum rport_event event);
139a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_offline(struct bfa_fcs_rport_s *rport,
140a36c61f9SKrishna Gudipati 					 enum rport_event event);
141a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsdisc_sending(struct bfa_fcs_rport_s *rport,
142a36c61f9SKrishna Gudipati 						enum rport_event event);
143a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsdisc_retry(struct bfa_fcs_rport_s *rport,
144a36c61f9SKrishna Gudipati 						enum rport_event event);
145a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
146a36c61f9SKrishna Gudipati 						enum rport_event event);
147a36c61f9SKrishna Gudipati static void	bfa_fcs_rport_sm_nsdisc_sent(struct bfa_fcs_rport_s *rport,
148a36c61f9SKrishna Gudipati 						enum rport_event event);
149a36c61f9SKrishna Gudipati 
150a36c61f9SKrishna Gudipati static struct bfa_sm_table_s rport_sm_table[] = {
151a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_uninit), BFA_RPORT_UNINIT},
152a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_plogi_sending), BFA_RPORT_PLOGI},
153a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_plogiacc_sending), BFA_RPORT_ONLINE},
154a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_plogi_retry), BFA_RPORT_PLOGI_RETRY},
155a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_plogi), BFA_RPORT_PLOGI},
156a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_hal_online), BFA_RPORT_ONLINE},
157a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_online), BFA_RPORT_ONLINE},
158a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsquery_sending), BFA_RPORT_NSQUERY},
159a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsquery), BFA_RPORT_NSQUERY},
160a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_adisc_sending), BFA_RPORT_ADISC},
161a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_adisc), BFA_RPORT_ADISC},
162a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_fc4_logorcv), BFA_RPORT_LOGORCV},
163a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_fc4_logosend), BFA_RPORT_LOGO},
164a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_fc4_offline), BFA_RPORT_OFFLINE},
165a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_hcb_offline), BFA_RPORT_OFFLINE},
166a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_hcb_logorcv), BFA_RPORT_LOGORCV},
167a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_hcb_logosend), BFA_RPORT_LOGO},
168a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_logo_sending), BFA_RPORT_LOGO},
169a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_offline), BFA_RPORT_OFFLINE},
170a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsdisc_sending), BFA_RPORT_NSDISC},
171a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsdisc_retry), BFA_RPORT_NSDISC},
172a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcs_rport_sm_nsdisc_sent), BFA_RPORT_NSDISC},
173a36c61f9SKrishna Gudipati };
174a36c61f9SKrishna Gudipati 
1755fbe25c7SJing Huang /*
176a36c61f9SKrishna Gudipati  *		Beginning state.
177a36c61f9SKrishna Gudipati  */
178a36c61f9SKrishna Gudipati static void
179a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_uninit(struct bfa_fcs_rport_s *rport, enum rport_event event)
180a36c61f9SKrishna Gudipati {
181a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
182a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
183a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
184a36c61f9SKrishna Gudipati 
185a36c61f9SKrishna Gudipati 	switch (event) {
186a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_SEND:
187a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
188a36c61f9SKrishna Gudipati 		rport->plogi_retries = 0;
189a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogi(rport, NULL);
190a36c61f9SKrishna Gudipati 		break;
191a36c61f9SKrishna Gudipati 
192a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
193a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
194a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
195a36c61f9SKrishna Gudipati 		break;
196a36c61f9SKrishna Gudipati 
197a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
198a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
199a36c61f9SKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
200a36c61f9SKrishna Gudipati 		break;
201a36c61f9SKrishna Gudipati 
202a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
203a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_DISC:
204a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
205a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
206a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
207a36c61f9SKrishna Gudipati 		break;
208a36c61f9SKrishna Gudipati 	default:
209a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
210a36c61f9SKrishna Gudipati 	}
211a36c61f9SKrishna Gudipati }
212a36c61f9SKrishna Gudipati 
2135fbe25c7SJing Huang /*
214a36c61f9SKrishna Gudipati  *		PLOGI is being sent.
215a36c61f9SKrishna Gudipati  */
216a36c61f9SKrishna Gudipati static void
217a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogi_sending(struct bfa_fcs_rport_s *rport,
218a36c61f9SKrishna Gudipati 	 enum rport_event event)
219a36c61f9SKrishna Gudipati {
220a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
221a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
222a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
223a36c61f9SKrishna Gudipati 
224a36c61f9SKrishna Gudipati 	switch (event) {
225a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
226a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi);
227a36c61f9SKrishna Gudipati 		break;
228a36c61f9SKrishna Gudipati 
229a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
230a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
231a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
232a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
233a36c61f9SKrishna Gudipati 		break;
234a36c61f9SKrishna Gudipati 
235a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
236a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
237a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
238a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
239a36c61f9SKrishna Gudipati 		break;
240a36c61f9SKrishna Gudipati 
241a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
242a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
243a36c61f9SKrishna Gudipati 		/* query the NS */
244a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
245a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
246a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
247a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
248a36c61f9SKrishna Gudipati 		break;
249a36c61f9SKrishna Gudipati 
250a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
251a36c61f9SKrishna Gudipati 		rport->pid = 0;
252a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
253a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
254a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
255a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
256a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
257a36c61f9SKrishna Gudipati 		break;
258a36c61f9SKrishna Gudipati 
259a36c61f9SKrishna Gudipati 
260a36c61f9SKrishna Gudipati 	default:
261a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
262a36c61f9SKrishna Gudipati 	}
263a36c61f9SKrishna Gudipati }
264a36c61f9SKrishna Gudipati 
2655fbe25c7SJing Huang /*
266a36c61f9SKrishna Gudipati  *		PLOGI is being sent.
267a36c61f9SKrishna Gudipati  */
268a36c61f9SKrishna Gudipati static void
269a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogiacc_sending(struct bfa_fcs_rport_s *rport,
270a36c61f9SKrishna Gudipati 	 enum rport_event event)
271a36c61f9SKrishna Gudipati {
272a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
273a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
274a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
275a36c61f9SKrishna Gudipati 
276a36c61f9SKrishna Gudipati 	switch (event) {
277a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
278a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
279a36c61f9SKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
280a36c61f9SKrishna Gudipati 		break;
281a36c61f9SKrishna Gudipati 
282a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
283a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
284a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
285a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
286a36c61f9SKrishna Gudipati 		break;
287a36c61f9SKrishna Gudipati 
288a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
289a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
2905fbe25c7SJing Huang 		/*
291a36c61f9SKrishna Gudipati 		 * Ignore, SCN is possibly online notification.
292a36c61f9SKrishna Gudipati 		 */
293a36c61f9SKrishna Gudipati 		break;
294a36c61f9SKrishna Gudipati 
295a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
296a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
297a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
298a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
299a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
300a36c61f9SKrishna Gudipati 		break;
301a36c61f9SKrishna Gudipati 
302a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
303a36c61f9SKrishna Gudipati 		rport->pid = 0;
304a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
305a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
306a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
307a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
308a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
309a36c61f9SKrishna Gudipati 		break;
310a36c61f9SKrishna Gudipati 
311a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
3125fbe25c7SJing Huang 		/*
313a36c61f9SKrishna Gudipati 		 * Ignore BFA callback, on a PLOGI receive we call bfa offline.
314a36c61f9SKrishna Gudipati 		 */
315a36c61f9SKrishna Gudipati 		break;
316a36c61f9SKrishna Gudipati 
317a36c61f9SKrishna Gudipati 	default:
318a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
319a36c61f9SKrishna Gudipati 	}
320a36c61f9SKrishna Gudipati }
321a36c61f9SKrishna Gudipati 
3225fbe25c7SJing Huang /*
323a36c61f9SKrishna Gudipati  *		PLOGI is sent.
324a36c61f9SKrishna Gudipati  */
325a36c61f9SKrishna Gudipati static void
326a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogi_retry(struct bfa_fcs_rport_s *rport,
327a36c61f9SKrishna Gudipati 			enum rport_event event)
328a36c61f9SKrishna Gudipati {
329a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
330a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
331a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
332a36c61f9SKrishna Gudipati 
333a36c61f9SKrishna Gudipati 	switch (event) {
334a36c61f9SKrishna Gudipati 	case RPSM_EVENT_TIMEOUT:
335a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_sending);
336a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogi(rport, NULL);
337a36c61f9SKrishna Gudipati 		break;
338a36c61f9SKrishna Gudipati 
339a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
340a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
341a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
342a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
343a36c61f9SKrishna Gudipati 		break;
344a36c61f9SKrishna Gudipati 
345a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
346a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
347a36c61f9SKrishna Gudipati 		break;
348a36c61f9SKrishna Gudipati 
349a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
350a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
351a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
352a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
353a36c61f9SKrishna Gudipati 		break;
354a36c61f9SKrishna Gudipati 
355a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
356a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
357a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
358a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
359a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
360a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
361a36c61f9SKrishna Gudipati 		break;
362a36c61f9SKrishna Gudipati 
363a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
364a36c61f9SKrishna Gudipati 		rport->pid = 0;
365a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
366a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
367a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
368a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
369a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
370a36c61f9SKrishna Gudipati 		break;
371a36c61f9SKrishna Gudipati 
372a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
373a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
374a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rport->timer);
375a36c61f9SKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
376a36c61f9SKrishna Gudipati 		break;
377a36c61f9SKrishna Gudipati 
378a36c61f9SKrishna Gudipati 	default:
379a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
380a36c61f9SKrishna Gudipati 	}
381a36c61f9SKrishna Gudipati }
382a36c61f9SKrishna Gudipati 
3835fbe25c7SJing Huang /*
384a36c61f9SKrishna Gudipati  *		PLOGI is sent.
385a36c61f9SKrishna Gudipati  */
386a36c61f9SKrishna Gudipati static void
387a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_plogi(struct bfa_fcs_rport_s *rport, enum rport_event event)
388a36c61f9SKrishna Gudipati {
389a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
390a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
391a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
392a36c61f9SKrishna Gudipati 
393a36c61f9SKrishna Gudipati 	switch (event) {
394a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ACCEPTED:
395a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
396a36c61f9SKrishna Gudipati 		rport->plogi_retries = 0;
397a36c61f9SKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
398a36c61f9SKrishna Gudipati 		break;
399a36c61f9SKrishna Gudipati 
400a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
401a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_logo_acc(rport);
402a36c61f9SKrishna Gudipati 		/*
403a36c61f9SKrishna Gudipati 		 * !! fall through !!
404a36c61f9SKrishna Gudipati 		 */
405a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
406a36c61f9SKrishna Gudipati 		if (rport->prlo == BFA_TRUE)
407a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
408a36c61f9SKrishna Gudipati 
409a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
410a36c61f9SKrishna Gudipati 		/*
411a36c61f9SKrishna Gudipati 		 * !! fall through !!
412a36c61f9SKrishna Gudipati 		 */
413a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FAILED:
414a36c61f9SKrishna Gudipati 		if (rport->plogi_retries < BFA_FCS_RPORT_MAX_RETRIES) {
415a36c61f9SKrishna Gudipati 			rport->plogi_retries++;
416a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
417a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
418a36c61f9SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
419a36c61f9SKrishna Gudipati 					BFA_FCS_RETRY_TIMEOUT);
420a36c61f9SKrishna Gudipati 		} else {
421a36c61f9SKrishna Gudipati 			bfa_stats(rport->port, rport_del_max_plogi_retry);
422a36c61f9SKrishna Gudipati 			rport->pid = 0;
423a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
424a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
425a36c61f9SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
426a36c61f9SKrishna Gudipati 					bfa_fcs_rport_del_timeout);
427a36c61f9SKrishna Gudipati 		}
428a36c61f9SKrishna Gudipati 		break;
429a36c61f9SKrishna Gudipati 
430a36c61f9SKrishna Gudipati 	case	RPSM_EVENT_PLOGI_RETRY:
431a36c61f9SKrishna Gudipati 		rport->plogi_retries = 0;
432a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogi_retry);
433a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
434a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
435a36c61f9SKrishna Gudipati 				(FC_RA_TOV * 1000));
436a36c61f9SKrishna Gudipati 		break;
437a36c61f9SKrishna Gudipati 
438a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
439a36c61f9SKrishna Gudipati 		rport->pid = 0;
440a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
441a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
442a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
443a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
444a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
445a36c61f9SKrishna Gudipati 		break;
446a36c61f9SKrishna Gudipati 
447a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
448a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
449a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
450a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsdisc_sending);
451a36c61f9SKrishna Gudipati 		rport->ns_retries = 0;
452a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_nsdisc(rport, NULL);
453a36c61f9SKrishna Gudipati 		break;
454a36c61f9SKrishna Gudipati 
455a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
456a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
457a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
458a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
459a36c61f9SKrishna Gudipati 		break;
460a36c61f9SKrishna Gudipati 
461a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
462a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
463a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
464a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
465a36c61f9SKrishna Gudipati 		break;
466a36c61f9SKrishna Gudipati 
467a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
468a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hal_online);
469a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
470a36c61f9SKrishna Gudipati 		bfa_fcs_rport_hal_online(rport);
471a36c61f9SKrishna Gudipati 		break;
472a36c61f9SKrishna Gudipati 
473a36c61f9SKrishna Gudipati 	default:
474a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
475a36c61f9SKrishna Gudipati 	}
476a36c61f9SKrishna Gudipati }
477a36c61f9SKrishna Gudipati 
4785fbe25c7SJing Huang /*
479a36c61f9SKrishna Gudipati  *		PLOGI is complete. Awaiting BFA rport online callback. FC-4s
480a36c61f9SKrishna Gudipati  *		are offline.
481a36c61f9SKrishna Gudipati  */
482a36c61f9SKrishna Gudipati static void
483a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hal_online(struct bfa_fcs_rport_s *rport,
484a36c61f9SKrishna Gudipati 			enum rport_event event)
485a36c61f9SKrishna Gudipati {
486a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
487a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
488a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
489a36c61f9SKrishna Gudipati 
490a36c61f9SKrishna Gudipati 	switch (event) {
491a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_ONLINE:
492a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
493a36c61f9SKrishna Gudipati 		bfa_fcs_rport_online_action(rport);
494a36c61f9SKrishna Gudipati 		break;
495a36c61f9SKrishna Gudipati 
496a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
497a36c61f9SKrishna Gudipati 		break;
498a36c61f9SKrishna Gudipati 
499a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
500a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
501a36c61f9SKrishna Gudipati 		bfa_rport_offline(rport->bfa_rport);
502a36c61f9SKrishna Gudipati 		break;
503a36c61f9SKrishna Gudipati 
504a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
505a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
506a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
507a36c61f9SKrishna Gudipati 		bfa_rport_offline(rport->bfa_rport);
508a36c61f9SKrishna Gudipati 		break;
509a36c61f9SKrishna Gudipati 
510a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
511a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_plogiacc_sending);
512a36c61f9SKrishna Gudipati 		bfa_rport_offline(rport->bfa_rport);
513a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_plogiacc(rport, NULL);
514a36c61f9SKrishna Gudipati 		break;
515a36c61f9SKrishna Gudipati 
516a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
517a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logosend);
518a36c61f9SKrishna Gudipati 		bfa_rport_offline(rport->bfa_rport);
519a36c61f9SKrishna Gudipati 		break;
520a36c61f9SKrishna Gudipati 
521a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
5225fbe25c7SJing Huang 		/*
523a36c61f9SKrishna Gudipati 		 * @todo
524a36c61f9SKrishna Gudipati 		 * Ignore SCN - PLOGI just completed, FC-4 login should detect
525a36c61f9SKrishna Gudipati 		 * device failures.
526a36c61f9SKrishna Gudipati 		 */
527a36c61f9SKrishna Gudipati 		break;
528a36c61f9SKrishna Gudipati 
529a36c61f9SKrishna Gudipati 	default:
530a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
531a36c61f9SKrishna Gudipati 	}
532a36c61f9SKrishna Gudipati }
533a36c61f9SKrishna Gudipati 
5345fbe25c7SJing Huang /*
535a36c61f9SKrishna Gudipati  *		Rport is ONLINE. FC-4s active.
536a36c61f9SKrishna Gudipati  */
537a36c61f9SKrishna Gudipati static void
538a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_online(struct bfa_fcs_rport_s *rport, enum rport_event event)
539a36c61f9SKrishna Gudipati {
540a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
541a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
542a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
543a36c61f9SKrishna Gudipati 
544a36c61f9SKrishna Gudipati 	switch (event) {
545a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
546a36c61f9SKrishna Gudipati 		if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
547a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
548a36c61f9SKrishna Gudipati 					 bfa_fcs_rport_sm_nsquery_sending);
549a36c61f9SKrishna Gudipati 			rport->ns_retries = 0;
550a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
551a36c61f9SKrishna Gudipati 		} else {
552a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
553a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_adisc(rport, NULL);
554a36c61f9SKrishna Gudipati 		}
555a36c61f9SKrishna Gudipati 		break;
556a36c61f9SKrishna Gudipati 
557a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
558a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
559a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
560a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
561a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
562a36c61f9SKrishna Gudipati 		break;
563a36c61f9SKrishna Gudipati 
564a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
565a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
566a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
567a36c61f9SKrishna Gudipati 		break;
568a36c61f9SKrishna Gudipati 
569a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
570a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
571a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
572a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
573a36c61f9SKrishna Gudipati 		break;
574a36c61f9SKrishna Gudipati 
575a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
576a36c61f9SKrishna Gudipati 		break;
577a36c61f9SKrishna Gudipati 
578a36c61f9SKrishna Gudipati 	default:
579a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
580a36c61f9SKrishna Gudipati 	}
581a36c61f9SKrishna Gudipati }
582a36c61f9SKrishna Gudipati 
5835fbe25c7SJing Huang /*
584a36c61f9SKrishna Gudipati  *		An SCN event is received in ONLINE state. NS query is being sent
585a36c61f9SKrishna Gudipati  *		prior to ADISC authentication with rport. FC-4s are paused.
586a36c61f9SKrishna Gudipati  */
587a36c61f9SKrishna Gudipati static void
588a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsquery_sending(struct bfa_fcs_rport_s *rport,
589a36c61f9SKrishna Gudipati 	 enum rport_event event)
590a36c61f9SKrishna Gudipati {
591a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
592a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
593a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
594a36c61f9SKrishna Gudipati 
595a36c61f9SKrishna Gudipati 	switch (event) {
596a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
597a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_nsquery);
598a36c61f9SKrishna Gudipati 		break;
599a36c61f9SKrishna Gudipati 
600a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
601a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
602a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
603a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
604a36c61f9SKrishna Gudipati 		break;
605a36c61f9SKrishna Gudipati 
606a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
6075fbe25c7SJing Huang 		/*
608a36c61f9SKrishna Gudipati 		 * ignore SCN, wait for response to query itself
609a36c61f9SKrishna Gudipati 		 */
610a36c61f9SKrishna Gudipati 		break;
611a36c61f9SKrishna Gudipati 
612a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
613a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
614a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
615a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
616a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
617a36c61f9SKrishna Gudipati 		break;
618a36c61f9SKrishna Gudipati 
619a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
620a36c61f9SKrishna Gudipati 		rport->pid = 0;
621a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
622a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
623a36c61f9SKrishna Gudipati 		bfa_timer_start(rport->fcs->bfa, &rport->timer,
624a36c61f9SKrishna Gudipati 				bfa_fcs_rport_timeout, rport,
625a36c61f9SKrishna Gudipati 				bfa_fcs_rport_del_timeout);
626a36c61f9SKrishna Gudipati 		break;
627a36c61f9SKrishna Gudipati 
628a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
629a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
630a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
631a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
632a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
633a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
634a36c61f9SKrishna Gudipati 		break;
635a36c61f9SKrishna Gudipati 
636a36c61f9SKrishna Gudipati 	default:
637a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
638a36c61f9SKrishna Gudipati 	}
639a36c61f9SKrishna Gudipati }
640a36c61f9SKrishna Gudipati 
6415fbe25c7SJing Huang /*
642a36c61f9SKrishna Gudipati  *	An SCN event is received in ONLINE state. NS query is sent to rport.
643a36c61f9SKrishna Gudipati  *	FC-4s are paused.
644a36c61f9SKrishna Gudipati  */
645a36c61f9SKrishna Gudipati static void
646a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_nsquery(struct bfa_fcs_rport_s *rport, enum rport_event event)
647a36c61f9SKrishna Gudipati {
648a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
649a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
650a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
651a36c61f9SKrishna Gudipati 
652a36c61f9SKrishna Gudipati 	switch (event) {
653a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ACCEPTED:
654a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc_sending);
655a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_adisc(rport, NULL);
656a36c61f9SKrishna Gudipati 		break;
657a36c61f9SKrishna Gudipati 
658a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FAILED:
659a36c61f9SKrishna Gudipati 		rport->ns_retries++;
660a36c61f9SKrishna Gudipati 		if (rport->ns_retries < BFA_FCS_RPORT_MAX_RETRIES) {
661a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
662a36c61f9SKrishna Gudipati 					 bfa_fcs_rport_sm_nsquery_sending);
663a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
664a36c61f9SKrishna Gudipati 		} else {
665a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
666a36c61f9SKrishna Gudipati 			bfa_fcs_rport_offline_action(rport);
667a36c61f9SKrishna Gudipati 		}
668a36c61f9SKrishna Gudipati 		break;
669a36c61f9SKrishna Gudipati 
670a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
671a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
672a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
673a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
674a36c61f9SKrishna Gudipati 		break;
675a36c61f9SKrishna Gudipati 
676a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
677a36c61f9SKrishna Gudipati 		break;
678a36c61f9SKrishna Gudipati 
679a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
680a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
681a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
682a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
683a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
684a36c61f9SKrishna Gudipati 		break;
685a36c61f9SKrishna Gudipati 
686a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_COMP:
687a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
688a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
689a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
690a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
691a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
692a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
693a36c61f9SKrishna Gudipati 		break;
694a36c61f9SKrishna Gudipati 
695a36c61f9SKrishna Gudipati 	default:
696a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
697a36c61f9SKrishna Gudipati 	}
698a36c61f9SKrishna Gudipati }
699a36c61f9SKrishna Gudipati 
7005fbe25c7SJing Huang /*
701a36c61f9SKrishna Gudipati  *	An SCN event is received in ONLINE state. ADISC is being sent for
702a36c61f9SKrishna Gudipati  *	authenticating with rport. FC-4s are paused.
703a36c61f9SKrishna Gudipati  */
704a36c61f9SKrishna Gudipati static void
705a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_adisc_sending(struct bfa_fcs_rport_s *rport,
706a36c61f9SKrishna Gudipati 	 enum rport_event event)
707a36c61f9SKrishna Gudipati {
708a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
709a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
710a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
711a36c61f9SKrishna Gudipati 
712a36c61f9SKrishna Gudipati 	switch (event) {
713a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FCXP_SENT:
714a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_adisc);
715a36c61f9SKrishna Gudipati 		break;
716a36c61f9SKrishna Gudipati 
717a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
718a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
719a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
720a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
721a36c61f9SKrishna Gudipati 		break;
722a36c61f9SKrishna Gudipati 
723a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
724a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
725a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
726a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
727a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
728a36c61f9SKrishna Gudipati 		break;
729a36c61f9SKrishna Gudipati 
730a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
731a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
732a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
733a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
734a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
735a36c61f9SKrishna Gudipati 		break;
736a36c61f9SKrishna Gudipati 
737a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
738a36c61f9SKrishna Gudipati 		break;
739a36c61f9SKrishna Gudipati 
740a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
741a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
742a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rport->fcxp_wqe);
743a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
744a36c61f9SKrishna Gudipati 		break;
745a36c61f9SKrishna Gudipati 
746a36c61f9SKrishna Gudipati 	default:
747a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
748a36c61f9SKrishna Gudipati 	}
749a36c61f9SKrishna Gudipati }
750a36c61f9SKrishna Gudipati 
7515fbe25c7SJing Huang /*
752a36c61f9SKrishna Gudipati  *		An SCN event is received in ONLINE state. ADISC is to rport.
753a36c61f9SKrishna Gudipati  *		FC-4s are paused.
754a36c61f9SKrishna Gudipati  */
755a36c61f9SKrishna Gudipati static void
756a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_adisc(struct bfa_fcs_rport_s *rport, enum rport_event event)
757a36c61f9SKrishna Gudipati {
758a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
759a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
760a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
761a36c61f9SKrishna Gudipati 
762a36c61f9SKrishna Gudipati 	switch (event) {
763a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ACCEPTED:
764a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_online);
765a36c61f9SKrishna Gudipati 		break;
766a36c61f9SKrishna Gudipati 
767a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PLOGI_RCVD:
7685fbe25c7SJing Huang 		/*
769a36c61f9SKrishna Gudipati 		 * Too complex to cleanup FC-4 & rport and then acc to PLOGI.
770a36c61f9SKrishna Gudipati 		 * At least go offline when a PLOGI is received.
771a36c61f9SKrishna Gudipati 		 */
772a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
773a36c61f9SKrishna Gudipati 		/*
774a36c61f9SKrishna Gudipati 		 * !!! fall through !!!
775a36c61f9SKrishna Gudipati 		 */
776a36c61f9SKrishna Gudipati 
777a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FAILED:
778a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
779a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
780a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
781a36c61f9SKrishna Gudipati 		break;
782a36c61f9SKrishna Gudipati 
783a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
784a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
785a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
786a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
787a36c61f9SKrishna Gudipati 		break;
788a36c61f9SKrishna Gudipati 
789a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
7905fbe25c7SJing Huang 		/*
791a36c61f9SKrishna Gudipati 		 * already processing RSCN
792a36c61f9SKrishna Gudipati 		 */
793a36c61f9SKrishna Gudipati 		break;
794a36c61f9SKrishna Gudipati 
795a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
796a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_offline);
797a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
798a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
799a36c61f9SKrishna Gudipati 		break;
800a36c61f9SKrishna Gudipati 
801a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
802a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
803a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logorcv);
804a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rport->fcxp);
805a36c61f9SKrishna Gudipati 		bfa_fcs_rport_offline_action(rport);
806a36c61f9SKrishna Gudipati 		break;
807a36c61f9SKrishna Gudipati 
808a36c61f9SKrishna Gudipati 	default:
809a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
810a36c61f9SKrishna Gudipati 	}
811a36c61f9SKrishna Gudipati }
812a36c61f9SKrishna Gudipati 
8135fbe25c7SJing Huang /*
814a36c61f9SKrishna Gudipati  *		Rport has sent LOGO. Awaiting FC-4 offline completion callback.
815a36c61f9SKrishna Gudipati  */
816a36c61f9SKrishna Gudipati static void
817a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_fc4_logorcv(struct bfa_fcs_rport_s *rport,
818a36c61f9SKrishna Gudipati 			enum rport_event event)
819a36c61f9SKrishna Gudipati {
820a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
821a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
822a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
823a36c61f9SKrishna Gudipati 
824a36c61f9SKrishna Gudipati 	switch (event) {
825a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FC4_OFFLINE:
826a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_logorcv);
827a36c61f9SKrishna Gudipati 		bfa_rport_offline(rport->bfa_rport);
828a36c61f9SKrishna Gudipati 		break;
829a36c61f9SKrishna Gudipati 
830a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
831a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
832a36c61f9SKrishna Gudipati 		break;
833a36c61f9SKrishna Gudipati 
834a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
835a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
836a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
837a36c61f9SKrishna Gudipati 		break;
838a36c61f9SKrishna Gudipati 
839a36c61f9SKrishna Gudipati 	default:
840a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
841a36c61f9SKrishna Gudipati 	}
842a36c61f9SKrishna Gudipati }
843a36c61f9SKrishna Gudipati 
8445fbe25c7SJing Huang /*
845a36c61f9SKrishna Gudipati  *		LOGO needs to be sent to rport. Awaiting FC-4 offline completion
846a36c61f9SKrishna Gudipati  *		callback.
847a36c61f9SKrishna Gudipati  */
848a36c61f9SKrishna Gudipati static void
849a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_fc4_logosend(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_logosend);
859a36c61f9SKrishna Gudipati 		bfa_rport_offline(rport->bfa_rport);
860a36c61f9SKrishna Gudipati 		break;
861a36c61f9SKrishna Gudipati 
862a36c61f9SKrishna Gudipati 	default:
863a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
864a36c61f9SKrishna Gudipati 	}
865a36c61f9SKrishna Gudipati }
866a36c61f9SKrishna Gudipati 
8675fbe25c7SJing Huang /*
868a36c61f9SKrishna Gudipati  *	Rport is going offline. Awaiting FC-4 offline completion callback.
869a36c61f9SKrishna Gudipati  */
870a36c61f9SKrishna Gudipati static void
871a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_fc4_offline(struct bfa_fcs_rport_s *rport,
872a36c61f9SKrishna Gudipati 			enum rport_event event)
873a36c61f9SKrishna Gudipati {
874a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
875a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
876a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
877a36c61f9SKrishna Gudipati 
878a36c61f9SKrishna Gudipati 	switch (event) {
879a36c61f9SKrishna Gudipati 	case RPSM_EVENT_FC4_OFFLINE:
880a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_hcb_offline);
881a36c61f9SKrishna Gudipati 		bfa_rport_offline(rport->bfa_rport);
882a36c61f9SKrishna Gudipati 		break;
883a36c61f9SKrishna Gudipati 
884a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
885a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_IMP:
886a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
887a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
888a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
8895fbe25c7SJing Huang 		/*
890a36c61f9SKrishna Gudipati 		 * rport is already going offline.
891a36c61f9SKrishna Gudipati 		 * SCN - ignore and wait till transitioning to offline state
892a36c61f9SKrishna Gudipati 		 */
893a36c61f9SKrishna Gudipati 		break;
894a36c61f9SKrishna Gudipati 
895a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
896a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_fc4_logosend);
897a36c61f9SKrishna Gudipati 		break;
898a36c61f9SKrishna Gudipati 
899a36c61f9SKrishna Gudipati 	default:
900a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
901a36c61f9SKrishna Gudipati 	}
902a36c61f9SKrishna Gudipati }
903a36c61f9SKrishna Gudipati 
9045fbe25c7SJing Huang /*
905a36c61f9SKrishna Gudipati  *		Rport is offline. FC-4s are offline. Awaiting BFA rport offline
906a36c61f9SKrishna Gudipati  *		callback.
907a36c61f9SKrishna Gudipati  */
908a36c61f9SKrishna Gudipati static void
909a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hcb_offline(struct bfa_fcs_rport_s *rport,
910a36c61f9SKrishna Gudipati 				enum rport_event event)
911a36c61f9SKrishna Gudipati {
912a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
913a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
914a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
915a36c61f9SKrishna Gudipati 
916a36c61f9SKrishna Gudipati 	switch (event) {
917a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
918a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
919a36c61f9SKrishna Gudipati 		if (bfa_fcs_lport_is_online(rport->port)) {
920a36c61f9SKrishna Gudipati 			if (bfa_fcs_fabric_is_switched(rport->port->fabric)) {
921a36c61f9SKrishna Gudipati 				bfa_sm_set_state(rport,
922a36c61f9SKrishna Gudipati 					bfa_fcs_rport_sm_nsdisc_sending);
923a36c61f9SKrishna Gudipati 				rport->ns_retries = 0;
924a36c61f9SKrishna Gudipati 				bfa_fcs_rport_send_nsdisc(rport, NULL);
925a36c61f9SKrishna Gudipati 			} else {
926a36c61f9SKrishna Gudipati 				bfa_sm_set_state(rport,
927a36c61f9SKrishna Gudipati 					bfa_fcs_rport_sm_plogi_sending);
928a36c61f9SKrishna Gudipati 				rport->plogi_retries = 0;
929a36c61f9SKrishna Gudipati 				bfa_fcs_rport_send_plogi(rport, NULL);
930a36c61f9SKrishna Gudipati 			}
931a36c61f9SKrishna Gudipati 		} else {
932a36c61f9SKrishna Gudipati 			rport->pid = 0;
933a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport, bfa_fcs_rport_sm_offline);
934a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rport->timer,
935a36c61f9SKrishna Gudipati 					bfa_fcs_rport_timeout, rport,
936a36c61f9SKrishna Gudipati 					bfa_fcs_rport_del_timeout);
937a36c61f9SKrishna Gudipati 		}
938a36c61f9SKrishna Gudipati 		break;
939a36c61f9SKrishna Gudipati 
940a36c61f9SKrishna Gudipati 	case RPSM_EVENT_DELETE:
941a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
942a36c61f9SKrishna Gudipati 		bfa_fcs_rport_free(rport);
943a36c61f9SKrishna Gudipati 		break;
944a36c61f9SKrishna Gudipati 
945a36c61f9SKrishna Gudipati 	case RPSM_EVENT_SCN:
946a36c61f9SKrishna Gudipati 	case RPSM_EVENT_LOGO_RCVD:
947a36c61f9SKrishna Gudipati 	case RPSM_EVENT_PRLO_RCVD:
9485fbe25c7SJing Huang 		/*
949a36c61f9SKrishna Gudipati 		 * Ignore, already offline.
950a36c61f9SKrishna Gudipati 		 */
951a36c61f9SKrishna Gudipati 		break;
952a36c61f9SKrishna Gudipati 
953a36c61f9SKrishna Gudipati 	default:
954a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
955a36c61f9SKrishna Gudipati 	}
956a36c61f9SKrishna Gudipati }
957a36c61f9SKrishna Gudipati 
9585fbe25c7SJing Huang /*
959a36c61f9SKrishna Gudipati  *		Rport is offline. FC-4s are offline. Awaiting BFA rport offline
960a36c61f9SKrishna Gudipati  *		callback to send LOGO accept.
961a36c61f9SKrishna Gudipati  */
962a36c61f9SKrishna Gudipati static void
963a36c61f9SKrishna Gudipati bfa_fcs_rport_sm_hcb_logorcv(struct bfa_fcs_rport_s *rport,
964a36c61f9SKrishna Gudipati 			enum rport_event event)
965a36c61f9SKrishna Gudipati {
966a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
967a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
968a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
969a36c61f9SKrishna Gudipati 
970a36c61f9SKrishna Gudipati 	switch (event) {
971a36c61f9SKrishna Gudipati 	case RPSM_EVENT_HCB_OFFLINE:
972a36c61f9SKrishna Gudipati 	case RPSM_EVENT_ADDRESS_CHANGE:
973a36c61f9SKrishna Gudipati 		if (rport->pid && (rport->prlo == BFA_TRUE))
974a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_prlo_acc(rport);
975a36c61f9SKrishna Gudipati 		if (rport->pid && (rport->prlo == BFA_FALSE))
976a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_logo_acc(rport);
977a36c61f9SKrishna Gudipati 		/*
978a36c61f9SKrishna Gudipati 		 * If the lport is online and if the rport is not a well
979a36c61f9SKrishna Gudipati 		 * known address port,
980a36c61f9SKrishna Gudipati 		 * we try to re-discover the r-port.
981a36c61f9SKrishna Gudipati 		 */
982a36c61f9SKrishna Gudipati 		if (bfa_fcs_lport_is_online(rport->port) &&
983a36c61f9SKrishna Gudipati 			(!BFA_FCS_PID_IS_WKA(rport->pid))) {
984a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rport,
985a36c61f9SKrishna Gudipati 				bfa_fcs_rport_sm_nsdisc_sending);
986a36c61f9SKrishna Gudipati 			rport->ns_retries = 0;
987a36c61f9SKrishna Gudipati 			bfa_fcs_rport_send_nsdisc(rport, NULL);
988a36c61f9SKrishna 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,
1383a36c61f9SKrishna Gudipati 				bfa_fcport_get_maxfrsize(port->fcs->bfa));
1384a36c61f9SKrishna Gudipati 
1385a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1386a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, bfa_fcs_rport_plogi_response,
1387a36c61f9SKrishna Gudipati 			(void *)rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1388a36c61f9SKrishna Gudipati 
1389a36c61f9SKrishna Gudipati 	rport->stats.plogis++;
1390a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1391a36c61f9SKrishna Gudipati }
1392a36c61f9SKrishna Gudipati 
1393a36c61f9SKrishna Gudipati static void
1394a36c61f9SKrishna Gudipati bfa_fcs_rport_plogi_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1395a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
1396a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs)
1397a36c61f9SKrishna Gudipati {
1398a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1399a36c61f9SKrishna Gudipati 	struct fc_logi_s	*plogi_rsp;
1400a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s	*ls_rjt;
1401a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *twin;
1402a36c61f9SKrishna Gudipati 	struct list_head	*qe;
1403a36c61f9SKrishna Gudipati 
1404a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1405a36c61f9SKrishna Gudipati 
1406a36c61f9SKrishna Gudipati 	/*
1407a36c61f9SKrishna Gudipati 	 * Sanity Checks
1408a36c61f9SKrishna Gudipati 	 */
1409a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
1410a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, req_status);
1411a36c61f9SKrishna Gudipati 		rport->stats.plogi_failed++;
1412a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1413a36c61f9SKrishna Gudipati 		return;
1414a36c61f9SKrishna Gudipati 	}
1415a36c61f9SKrishna Gudipati 
1416a36c61f9SKrishna Gudipati 	plogi_rsp = (struct fc_logi_s *) BFA_FCXP_RSP_PLD(fcxp);
1417a36c61f9SKrishna Gudipati 
14185fbe25c7SJing Huang 	/*
1419a36c61f9SKrishna Gudipati 	 * Check for failure first.
1420a36c61f9SKrishna Gudipati 	 */
1421a36c61f9SKrishna Gudipati 	if (plogi_rsp->els_cmd.els_code != FC_ELS_ACC) {
1422a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
1423a36c61f9SKrishna Gudipati 
1424a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, ls_rjt->reason_code);
1425a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1426a36c61f9SKrishna Gudipati 
1427a36c61f9SKrishna Gudipati 		if ((ls_rjt->reason_code == FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD) &&
1428a36c61f9SKrishna Gudipati 		 (ls_rjt->reason_code_expl == FC_LS_RJT_EXP_INSUFF_RES)) {
1429a36c61f9SKrishna Gudipati 			rport->stats.rjt_insuff_res++;
1430a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RETRY);
1431a36c61f9SKrishna Gudipati 			return;
1432a36c61f9SKrishna Gudipati 		}
1433a36c61f9SKrishna Gudipati 
1434a36c61f9SKrishna Gudipati 		rport->stats.plogi_rejects++;
1435a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1436a36c61f9SKrishna Gudipati 		return;
1437a36c61f9SKrishna Gudipati 	}
1438a36c61f9SKrishna Gudipati 
14395fbe25c7SJing Huang 	/*
1440a36c61f9SKrishna Gudipati 	 * PLOGI is complete. Make sure this device is not one of the known
1441a36c61f9SKrishna Gudipati 	 * device with a new FC port address.
1442a36c61f9SKrishna Gudipati 	 */
1443a36c61f9SKrishna Gudipati 	list_for_each(qe, &rport->port->rport_q) {
1444a36c61f9SKrishna Gudipati 		twin = (struct bfa_fcs_rport_s *) qe;
1445a36c61f9SKrishna Gudipati 		if (twin == rport)
1446a36c61f9SKrishna Gudipati 			continue;
1447a36c61f9SKrishna Gudipati 		if (!rport->pwwn && (plogi_rsp->port_name == twin->pwwn)) {
1448a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs, twin->pid);
1449a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs, rport->pid);
1450a36c61f9SKrishna Gudipati 
1451a36c61f9SKrishna Gudipati 			/* Update plogi stats in twin */
1452a36c61f9SKrishna Gudipati 			twin->stats.plogis  += rport->stats.plogis;
1453a36c61f9SKrishna Gudipati 			twin->stats.plogi_rejects  +=
1454a36c61f9SKrishna Gudipati 				 rport->stats.plogi_rejects;
1455a36c61f9SKrishna Gudipati 			twin->stats.plogi_timeouts  +=
1456a36c61f9SKrishna Gudipati 				 rport->stats.plogi_timeouts;
1457a36c61f9SKrishna Gudipati 			twin->stats.plogi_failed +=
1458a36c61f9SKrishna Gudipati 				 rport->stats.plogi_failed;
1459a36c61f9SKrishna Gudipati 			twin->stats.plogi_rcvd	  += rport->stats.plogi_rcvd;
1460a36c61f9SKrishna Gudipati 			twin->stats.plogi_accs++;
1461a36c61f9SKrishna Gudipati 
1462a36c61f9SKrishna Gudipati 			bfa_fcs_rport_delete(rport);
1463a36c61f9SKrishna Gudipati 
1464a36c61f9SKrishna Gudipati 			bfa_fcs_rport_update(twin, plogi_rsp);
1465a36c61f9SKrishna Gudipati 			twin->pid = rsp_fchs->s_id;
1466a36c61f9SKrishna Gudipati 			bfa_sm_send_event(twin, RPSM_EVENT_PLOGI_COMP);
1467a36c61f9SKrishna Gudipati 			return;
1468a36c61f9SKrishna Gudipati 		}
1469a36c61f9SKrishna Gudipati 	}
1470a36c61f9SKrishna Gudipati 
14715fbe25c7SJing Huang 	/*
1472a36c61f9SKrishna Gudipati 	 * Normal login path -- no evil twins.
1473a36c61f9SKrishna Gudipati 	 */
1474a36c61f9SKrishna Gudipati 	rport->stats.plogi_accs++;
1475a36c61f9SKrishna Gudipati 	bfa_fcs_rport_update(rport, plogi_rsp);
1476a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1477a36c61f9SKrishna Gudipati }
1478a36c61f9SKrishna Gudipati 
1479a36c61f9SKrishna Gudipati static void
1480a36c61f9SKrishna Gudipati bfa_fcs_rport_send_plogiacc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1481a36c61f9SKrishna Gudipati {
1482a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1483a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1484a36c61f9SKrishna Gudipati 	struct fchs_s		fchs;
1485a36c61f9SKrishna Gudipati 	int		len;
1486a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1487a36c61f9SKrishna Gudipati 
1488a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1489a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->reply_oxid);
1490a36c61f9SKrishna Gudipati 
1491a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1492a36c61f9SKrishna Gudipati 	if (!fcxp) {
1493a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1494a36c61f9SKrishna Gudipati 					bfa_fcs_rport_send_plogiacc, rport);
1495a36c61f9SKrishna Gudipati 		return;
1496a36c61f9SKrishna Gudipati 	}
1497a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1498a36c61f9SKrishna Gudipati 
1499a36c61f9SKrishna Gudipati 	len = fc_plogi_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1500a36c61f9SKrishna Gudipati 				 rport->pid, bfa_fcs_lport_get_fcid(port),
1501a36c61f9SKrishna Gudipati 				 rport->reply_oxid, port->port_cfg.pwwn,
1502a36c61f9SKrishna Gudipati 				 port->port_cfg.nwwn,
1503a36c61f9SKrishna Gudipati 				 bfa_fcport_get_maxfrsize(port->fcs->bfa));
1504a36c61f9SKrishna Gudipati 
1505a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1506a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1507a36c61f9SKrishna Gudipati 
1508a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1509a36c61f9SKrishna Gudipati }
1510a36c61f9SKrishna Gudipati 
1511a36c61f9SKrishna Gudipati static void
1512a36c61f9SKrishna Gudipati bfa_fcs_rport_send_adisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1513a36c61f9SKrishna Gudipati {
1514a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1515a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1516a36c61f9SKrishna Gudipati 	struct fchs_s		fchs;
1517a36c61f9SKrishna Gudipati 	int		len;
1518a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1519a36c61f9SKrishna Gudipati 
1520a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1521a36c61f9SKrishna Gudipati 
1522a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1523a36c61f9SKrishna Gudipati 	if (!fcxp) {
1524a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1525a36c61f9SKrishna Gudipati 					bfa_fcs_rport_send_adisc, rport);
1526a36c61f9SKrishna Gudipati 		return;
1527a36c61f9SKrishna Gudipati 	}
1528a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1529a36c61f9SKrishna Gudipati 
1530a36c61f9SKrishna Gudipati 	len = fc_adisc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1531a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0,
1532a36c61f9SKrishna Gudipati 				port->port_cfg.pwwn, port->port_cfg.nwwn);
1533a36c61f9SKrishna Gudipati 
1534a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1535a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, bfa_fcs_rport_adisc_response,
1536a36c61f9SKrishna Gudipati 			rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1537a36c61f9SKrishna Gudipati 
1538a36c61f9SKrishna Gudipati 	rport->stats.adisc_sent++;
1539a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1540a36c61f9SKrishna Gudipati }
1541a36c61f9SKrishna Gudipati 
1542a36c61f9SKrishna Gudipati static void
1543a36c61f9SKrishna Gudipati bfa_fcs_rport_adisc_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1544a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
1545a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs)
1546a36c61f9SKrishna Gudipati {
1547a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1548a36c61f9SKrishna Gudipati 	void		*pld = bfa_fcxp_get_rspbuf(fcxp);
1549a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s	*ls_rjt;
1550a36c61f9SKrishna Gudipati 
1551a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
1552a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, req_status);
1553a36c61f9SKrishna Gudipati 		rport->stats.adisc_failed++;
1554a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1555a36c61f9SKrishna Gudipati 		return;
1556a36c61f9SKrishna Gudipati 	}
1557a36c61f9SKrishna Gudipati 
1558a36c61f9SKrishna Gudipati 	if (fc_adisc_rsp_parse((struct fc_adisc_s *)pld, rsp_len, rport->pwwn,
1559a36c61f9SKrishna Gudipati 				rport->nwwn)  == FC_PARSE_OK) {
1560a36c61f9SKrishna Gudipati 		rport->stats.adisc_accs++;
1561a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1562a36c61f9SKrishna Gudipati 		return;
1563a36c61f9SKrishna Gudipati 	}
1564a36c61f9SKrishna Gudipati 
1565a36c61f9SKrishna Gudipati 	rport->stats.adisc_rejects++;
1566a36c61f9SKrishna Gudipati 	ls_rjt = pld;
1567a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, ls_rjt->els_cmd.els_code);
1568a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, ls_rjt->reason_code);
1569a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
1570a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1571a36c61f9SKrishna Gudipati }
1572a36c61f9SKrishna Gudipati 
1573a36c61f9SKrishna Gudipati static void
1574a36c61f9SKrishna Gudipati bfa_fcs_rport_send_nsdisc(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1575a36c61f9SKrishna Gudipati {
1576a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1577a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1578a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1579a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1580a36c61f9SKrishna Gudipati 	int		len;
1581a36c61f9SKrishna Gudipati 	bfa_cb_fcxp_send_t cbfn;
1582a36c61f9SKrishna Gudipati 
1583a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1584a36c61f9SKrishna Gudipati 
1585a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1586a36c61f9SKrishna Gudipati 	if (!fcxp) {
1587a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1588a36c61f9SKrishna Gudipati 					bfa_fcs_rport_send_nsdisc, rport);
1589a36c61f9SKrishna Gudipati 		return;
1590a36c61f9SKrishna Gudipati 	}
1591a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1592a36c61f9SKrishna Gudipati 
1593a36c61f9SKrishna Gudipati 	if (rport->pwwn) {
1594a36c61f9SKrishna Gudipati 		len = fc_gidpn_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1595a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0, rport->pwwn);
1596a36c61f9SKrishna Gudipati 		cbfn = bfa_fcs_rport_gidpn_response;
1597a36c61f9SKrishna Gudipati 	} else {
1598a36c61f9SKrishna Gudipati 		len = fc_gpnid_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1599a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0, rport->pid);
1600a36c61f9SKrishna Gudipati 		cbfn = bfa_fcs_rport_gpnid_response;
1601a36c61f9SKrishna Gudipati 	}
1602a36c61f9SKrishna Gudipati 
1603a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1604a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, cbfn,
1605a36c61f9SKrishna Gudipati 			(void *)rport, FC_MAX_PDUSZ, FC_FCCT_TOV);
1606a36c61f9SKrishna Gudipati 
1607a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1608a36c61f9SKrishna Gudipati }
1609a36c61f9SKrishna Gudipati 
1610a36c61f9SKrishna Gudipati static void
1611a36c61f9SKrishna Gudipati bfa_fcs_rport_gidpn_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1612a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
1613a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs)
1614a36c61f9SKrishna Gudipati {
1615a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1616a36c61f9SKrishna Gudipati 	struct ct_hdr_s	*cthdr;
1617a36c61f9SKrishna Gudipati 	struct fcgs_gidpn_resp_s	*gidpn_rsp;
1618a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s	*twin;
1619a36c61f9SKrishna Gudipati 	struct list_head	*qe;
1620a36c61f9SKrishna Gudipati 
1621a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1622a36c61f9SKrishna Gudipati 
1623a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1624ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
1625a36c61f9SKrishna Gudipati 
1626a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1627a36c61f9SKrishna Gudipati 		/* Check if the pid is the same as before. */
1628a36c61f9SKrishna Gudipati 		gidpn_rsp = (struct fcgs_gidpn_resp_s *) (cthdr + 1);
1629a36c61f9SKrishna Gudipati 
1630a36c61f9SKrishna Gudipati 		if (gidpn_rsp->dap == rport->pid) {
1631a36c61f9SKrishna Gudipati 			/* Device is online  */
1632a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1633a36c61f9SKrishna Gudipati 		} else {
1634a36c61f9SKrishna Gudipati 			/*
1635a36c61f9SKrishna Gudipati 			 * Device's PID has changed. We need to cleanup
1636a36c61f9SKrishna Gudipati 			 * and re-login. If there is another device with
1637a36c61f9SKrishna Gudipati 			 * the the newly discovered pid, send an scn notice
1638a36c61f9SKrishna Gudipati 			 * so that its new pid can be discovered.
1639a36c61f9SKrishna Gudipati 			 */
1640a36c61f9SKrishna Gudipati 			list_for_each(qe, &rport->port->rport_q) {
1641a36c61f9SKrishna Gudipati 				twin = (struct bfa_fcs_rport_s *) qe;
1642a36c61f9SKrishna Gudipati 				if (twin == rport)
1643a36c61f9SKrishna Gudipati 					continue;
1644a36c61f9SKrishna Gudipati 				if (gidpn_rsp->dap == twin->pid) {
1645a36c61f9SKrishna Gudipati 					bfa_trc(rport->fcs, twin->pid);
1646a36c61f9SKrishna Gudipati 					bfa_trc(rport->fcs, rport->pid);
1647a36c61f9SKrishna Gudipati 
1648a36c61f9SKrishna Gudipati 					twin->pid = 0;
1649a36c61f9SKrishna Gudipati 					bfa_sm_send_event(twin,
1650a36c61f9SKrishna Gudipati 					 RPSM_EVENT_ADDRESS_CHANGE);
1651a36c61f9SKrishna Gudipati 				}
1652a36c61f9SKrishna Gudipati 			}
1653a36c61f9SKrishna Gudipati 			rport->pid = gidpn_rsp->dap;
1654a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_CHANGE);
1655a36c61f9SKrishna Gudipati 		}
1656a36c61f9SKrishna Gudipati 		return;
1657a36c61f9SKrishna Gudipati 	}
1658a36c61f9SKrishna Gudipati 
1659a36c61f9SKrishna Gudipati 	/*
1660a36c61f9SKrishna Gudipati 	 * Reject Response
1661a36c61f9SKrishna Gudipati 	 */
1662a36c61f9SKrishna Gudipati 	switch (cthdr->reason_code) {
1663a36c61f9SKrishna Gudipati 	case CT_RSN_LOGICAL_BUSY:
1664a36c61f9SKrishna Gudipati 		/*
1665a36c61f9SKrishna Gudipati 		 * Need to retry
1666a36c61f9SKrishna Gudipati 		 */
1667a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
1668a36c61f9SKrishna Gudipati 		break;
1669a36c61f9SKrishna Gudipati 
1670a36c61f9SKrishna Gudipati 	case CT_RSN_UNABLE_TO_PERF:
1671a36c61f9SKrishna Gudipati 		/*
1672a36c61f9SKrishna Gudipati 		 * device doesn't exist : Start timer to cleanup this later.
1673a36c61f9SKrishna Gudipati 		 */
1674a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1675a36c61f9SKrishna Gudipati 		break;
1676a36c61f9SKrishna Gudipati 
1677a36c61f9SKrishna Gudipati 	default:
1678a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1679a36c61f9SKrishna Gudipati 		break;
1680a36c61f9SKrishna Gudipati 	}
1681a36c61f9SKrishna Gudipati }
1682a36c61f9SKrishna Gudipati 
1683a36c61f9SKrishna Gudipati static void
1684a36c61f9SKrishna Gudipati bfa_fcs_rport_gpnid_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
1685a36c61f9SKrishna Gudipati 				bfa_status_t req_status, u32 rsp_len,
1686a36c61f9SKrishna Gudipati 				u32 resid_len, struct fchs_s *rsp_fchs)
1687a36c61f9SKrishna Gudipati {
1688a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
1689a36c61f9SKrishna Gudipati 	struct ct_hdr_s	*cthdr;
1690a36c61f9SKrishna Gudipati 
1691a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
1692a36c61f9SKrishna Gudipati 
1693a36c61f9SKrishna Gudipati 	cthdr = (struct ct_hdr_s *) BFA_FCXP_RSP_PLD(fcxp);
1694ba816ea8SJing Huang 	cthdr->cmd_rsp_code = be16_to_cpu(cthdr->cmd_rsp_code);
1695a36c61f9SKrishna Gudipati 
1696a36c61f9SKrishna Gudipati 	if (cthdr->cmd_rsp_code == CT_RSP_ACCEPT) {
1697a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_ACCEPTED);
1698a36c61f9SKrishna Gudipati 		return;
1699a36c61f9SKrishna Gudipati 	}
1700a36c61f9SKrishna Gudipati 
1701a36c61f9SKrishna Gudipati 	/*
1702a36c61f9SKrishna Gudipati 	 * Reject Response
1703a36c61f9SKrishna Gudipati 	 */
1704a36c61f9SKrishna Gudipati 	switch (cthdr->reason_code) {
1705a36c61f9SKrishna Gudipati 	case CT_RSN_LOGICAL_BUSY:
1706a36c61f9SKrishna Gudipati 		/*
1707a36c61f9SKrishna Gudipati 		 * Need to retry
1708a36c61f9SKrishna Gudipati 		 */
1709a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
1710a36c61f9SKrishna Gudipati 		break;
1711a36c61f9SKrishna Gudipati 
1712a36c61f9SKrishna Gudipati 	case CT_RSN_UNABLE_TO_PERF:
1713a36c61f9SKrishna Gudipati 		/*
1714a36c61f9SKrishna Gudipati 		 * device doesn't exist : Start timer to cleanup this later.
1715a36c61f9SKrishna Gudipati 		 */
1716a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1717a36c61f9SKrishna Gudipati 		break;
1718a36c61f9SKrishna Gudipati 
1719a36c61f9SKrishna Gudipati 	default:
1720a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, RPSM_EVENT_FAILED);
1721a36c61f9SKrishna Gudipati 		break;
1722a36c61f9SKrishna Gudipati 	}
1723a36c61f9SKrishna Gudipati }
1724a36c61f9SKrishna Gudipati 
17255fbe25c7SJing Huang /*
1726a36c61f9SKrishna Gudipati  *	Called to send a logout to the rport.
1727a36c61f9SKrishna Gudipati  */
1728a36c61f9SKrishna Gudipati static void
1729a36c61f9SKrishna Gudipati bfa_fcs_rport_send_logo(void *rport_cbarg, struct bfa_fcxp_s *fcxp_alloced)
1730a36c61f9SKrishna Gudipati {
1731a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1732a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port;
1733a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1734a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1735a36c61f9SKrishna Gudipati 	u16	len;
1736a36c61f9SKrishna Gudipati 
1737a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1738a36c61f9SKrishna Gudipati 
1739a36c61f9SKrishna Gudipati 	port = rport->port;
1740a36c61f9SKrishna Gudipati 
1741a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
1742a36c61f9SKrishna Gudipati 	if (!fcxp) {
1743a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rport->fcxp_wqe,
1744a36c61f9SKrishna Gudipati 					bfa_fcs_rport_send_logo, rport);
1745a36c61f9SKrishna Gudipati 		return;
1746a36c61f9SKrishna Gudipati 	}
1747a36c61f9SKrishna Gudipati 	rport->fcxp = fcxp;
1748a36c61f9SKrishna Gudipati 
1749a36c61f9SKrishna Gudipati 	len = fc_logo_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
1750a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_fcid(port), 0,
1751a36c61f9SKrishna Gudipati 				bfa_fcs_lport_get_pwwn(port));
1752a36c61f9SKrishna Gudipati 
1753a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1754a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL,
1755a36c61f9SKrishna Gudipati 			rport, FC_MAX_PDUSZ, FC_ELS_TOV);
1756a36c61f9SKrishna Gudipati 
1757a36c61f9SKrishna Gudipati 	rport->stats.logos++;
1758a36c61f9SKrishna Gudipati 	bfa_fcxp_discard(rport->fcxp);
1759a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FCXP_SENT);
1760a36c61f9SKrishna Gudipati }
1761a36c61f9SKrishna Gudipati 
17625fbe25c7SJing Huang /*
1763a36c61f9SKrishna Gudipati  *	Send ACC for a LOGO received.
1764a36c61f9SKrishna Gudipati  */
1765a36c61f9SKrishna Gudipati static void
1766a36c61f9SKrishna Gudipati bfa_fcs_rport_send_logo_acc(void *rport_cbarg)
1767a36c61f9SKrishna Gudipati {
1768a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rport_cbarg;
1769a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port;
1770a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1771a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1772a36c61f9SKrishna Gudipati 	u16	len;
1773a36c61f9SKrishna Gudipati 
1774a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
1775a36c61f9SKrishna Gudipati 
1776a36c61f9SKrishna Gudipati 	port = rport->port;
1777a36c61f9SKrishna Gudipati 
1778a36c61f9SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1779a36c61f9SKrishna Gudipati 	if (!fcxp)
1780a36c61f9SKrishna Gudipati 		return;
1781a36c61f9SKrishna Gudipati 
1782a36c61f9SKrishna Gudipati 	rport->stats.logo_rcvd++;
1783a36c61f9SKrishna Gudipati 	len = fc_logo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1784a36c61f9SKrishna Gudipati 				rport->pid, bfa_fcs_lport_get_fcid(port),
1785a36c61f9SKrishna Gudipati 				rport->reply_oxid);
1786a36c61f9SKrishna Gudipati 
1787a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1788a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1789a36c61f9SKrishna Gudipati }
1790a36c61f9SKrishna Gudipati 
17915fbe25c7SJing Huang /*
1792a36c61f9SKrishna Gudipati  *	brief
1793a36c61f9SKrishna Gudipati  *	This routine will be called by bfa_timer on timer timeouts.
1794a36c61f9SKrishna Gudipati  *
1795a36c61f9SKrishna Gudipati  *	param[in]	rport			- pointer to bfa_fcs_lport_ns_t.
1796a36c61f9SKrishna Gudipati  *	param[out]	rport_status	- pointer to return vport status in
1797a36c61f9SKrishna Gudipati  *
1798a36c61f9SKrishna Gudipati  *	return
1799a36c61f9SKrishna Gudipati  *		void
1800a36c61f9SKrishna Gudipati  *
1801a36c61f9SKrishna Gudipati  *	Special Considerations:
1802a36c61f9SKrishna Gudipati  *
1803a36c61f9SKrishna Gudipati  *	note
1804a36c61f9SKrishna Gudipati  */
1805a36c61f9SKrishna Gudipati static void
1806a36c61f9SKrishna Gudipati bfa_fcs_rport_timeout(void *arg)
1807a36c61f9SKrishna Gudipati {
1808a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) arg;
1809a36c61f9SKrishna Gudipati 
1810a36c61f9SKrishna Gudipati 	rport->stats.plogi_timeouts++;
1811a36c61f9SKrishna Gudipati 	bfa_stats(rport->port, rport_plogi_timeouts);
1812a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_TIMEOUT);
1813a36c61f9SKrishna Gudipati }
1814a36c61f9SKrishna Gudipati 
1815a36c61f9SKrishna Gudipati static void
1816a36c61f9SKrishna Gudipati bfa_fcs_rport_process_prli(struct bfa_fcs_rport_s *rport,
1817a36c61f9SKrishna Gudipati 			struct fchs_s *rx_fchs, u16 len)
1818a36c61f9SKrishna Gudipati {
1819a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1820a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1821a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1822a36c61f9SKrishna Gudipati 	struct fc_prli_s	*prli;
1823a36c61f9SKrishna Gudipati 
1824a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
1825a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
1826a36c61f9SKrishna Gudipati 
1827a36c61f9SKrishna Gudipati 	rport->stats.prli_rcvd++;
1828a36c61f9SKrishna Gudipati 
1829a36c61f9SKrishna Gudipati 	/*
1830a36c61f9SKrishna Gudipati 	 * We are in Initiator Mode
1831a36c61f9SKrishna Gudipati 	 */
1832a36c61f9SKrishna Gudipati 	prli = (struct fc_prli_s *) (rx_fchs + 1);
1833a36c61f9SKrishna Gudipati 
1834a36c61f9SKrishna Gudipati 	if (prli->parampage.servparams.target) {
1835a36c61f9SKrishna Gudipati 		/*
1836a36c61f9SKrishna Gudipati 		 * PRLI from a target ?
1837a36c61f9SKrishna Gudipati 		 * Send the Acc.
1838a36c61f9SKrishna Gudipati 		 * PRLI sent by us will be used to transition the IT nexus,
1839a36c61f9SKrishna Gudipati 		 * once the response is received from the target.
1840a36c61f9SKrishna Gudipati 		 */
1841a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, rx_fchs->s_id);
1842a36c61f9SKrishna Gudipati 		rport->scsi_function = BFA_RPORT_TARGET;
1843a36c61f9SKrishna Gudipati 	} else {
1844a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, prli->parampage.type);
1845a36c61f9SKrishna Gudipati 		rport->scsi_function = BFA_RPORT_INITIATOR;
1846a36c61f9SKrishna Gudipati 		bfa_fcs_itnim_is_initiator(rport->itnim);
1847a36c61f9SKrishna Gudipati 	}
1848a36c61f9SKrishna Gudipati 
1849a36c61f9SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1850a36c61f9SKrishna Gudipati 	if (!fcxp)
1851a36c61f9SKrishna Gudipati 		return;
1852a36c61f9SKrishna Gudipati 
1853a36c61f9SKrishna Gudipati 	len = fc_prli_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1854a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
1855a36c61f9SKrishna Gudipati 				rx_fchs->ox_id, port->port_cfg.roles);
1856a36c61f9SKrishna Gudipati 
1857a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1858a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1859a36c61f9SKrishna Gudipati }
1860a36c61f9SKrishna Gudipati 
1861a36c61f9SKrishna Gudipati static void
1862a36c61f9SKrishna Gudipati bfa_fcs_rport_process_rpsc(struct bfa_fcs_rport_s *rport,
1863a36c61f9SKrishna Gudipati 			struct fchs_s *rx_fchs, u16 len)
1864a36c61f9SKrishna Gudipati {
1865a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1866a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1867a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1868a36c61f9SKrishna Gudipati 	struct fc_rpsc_speed_info_s speeds;
1869a36c61f9SKrishna Gudipati 	struct bfa_port_attr_s pport_attr;
1870a36c61f9SKrishna Gudipati 
1871a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
1872a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
1873a36c61f9SKrishna Gudipati 
1874a36c61f9SKrishna Gudipati 	rport->stats.rpsc_rcvd++;
1875a36c61f9SKrishna Gudipati 	speeds.port_speed_cap =
1876a36c61f9SKrishna Gudipati 		RPSC_SPEED_CAP_1G | RPSC_SPEED_CAP_2G | RPSC_SPEED_CAP_4G |
1877a36c61f9SKrishna Gudipati 		RPSC_SPEED_CAP_8G;
1878a36c61f9SKrishna Gudipati 
1879a36c61f9SKrishna Gudipati 	/*
1880a36c61f9SKrishna Gudipati 	 * get curent speed from pport attributes from BFA
1881a36c61f9SKrishna Gudipati 	 */
1882a36c61f9SKrishna Gudipati 	bfa_fcport_get_attr(port->fcs->bfa, &pport_attr);
1883a36c61f9SKrishna Gudipati 
1884a36c61f9SKrishna Gudipati 	speeds.port_op_speed = fc_bfa_speed_to_rpsc_operspeed(pport_attr.speed);
1885a36c61f9SKrishna Gudipati 
1886a36c61f9SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1887a36c61f9SKrishna Gudipati 	if (!fcxp)
1888a36c61f9SKrishna Gudipati 		return;
1889a36c61f9SKrishna Gudipati 
1890a36c61f9SKrishna Gudipati 	len = fc_rpsc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1891a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
1892a36c61f9SKrishna Gudipati 				rx_fchs->ox_id, &speeds);
1893a36c61f9SKrishna Gudipati 
1894a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
1895a36c61f9SKrishna Gudipati 			FC_CLASS_3, len, &fchs, NULL, NULL, FC_MAX_PDUSZ, 0);
1896a36c61f9SKrishna Gudipati }
1897a36c61f9SKrishna Gudipati 
1898a36c61f9SKrishna Gudipati static void
1899a36c61f9SKrishna Gudipati bfa_fcs_rport_process_adisc(struct bfa_fcs_rport_s *rport,
1900a36c61f9SKrishna Gudipati 			struct fchs_s *rx_fchs, u16 len)
1901a36c61f9SKrishna Gudipati {
1902a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
1903a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
1904a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1905a36c61f9SKrishna Gudipati 	struct fc_adisc_s	*adisc;
1906a36c61f9SKrishna Gudipati 
1907a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->s_id);
1908a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rx_fchs->d_id);
1909a36c61f9SKrishna Gudipati 
1910a36c61f9SKrishna Gudipati 	rport->stats.adisc_rcvd++;
1911a36c61f9SKrishna Gudipati 
1912a36c61f9SKrishna Gudipati 	adisc = (struct fc_adisc_s *) (rx_fchs + 1);
1913a36c61f9SKrishna Gudipati 
1914a36c61f9SKrishna Gudipati 	/*
1915a36c61f9SKrishna Gudipati 	 * Accept if the itnim for this rport is online.
1916a36c61f9SKrishna Gudipati 	 * Else reject the ADISC.
1917a36c61f9SKrishna Gudipati 	 */
1918a36c61f9SKrishna Gudipati 	if (bfa_fcs_itnim_get_online_state(rport->itnim) == BFA_STATUS_OK) {
1919a36c61f9SKrishna Gudipati 
1920a36c61f9SKrishna Gudipati 		fcxp = bfa_fcs_fcxp_alloc(port->fcs);
1921a36c61f9SKrishna Gudipati 		if (!fcxp)
1922a36c61f9SKrishna Gudipati 			return;
1923a36c61f9SKrishna Gudipati 
1924a36c61f9SKrishna Gudipati 		len = fc_adisc_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
1925a36c61f9SKrishna Gudipati 			 rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
1926a36c61f9SKrishna Gudipati 			 rx_fchs->ox_id, port->port_cfg.pwwn,
1927a36c61f9SKrishna Gudipati 			 port->port_cfg.nwwn);
1928a36c61f9SKrishna Gudipati 
1929a36c61f9SKrishna Gudipati 		bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
1930a36c61f9SKrishna Gudipati 				BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
1931a36c61f9SKrishna Gudipati 				FC_MAX_PDUSZ, 0);
1932a36c61f9SKrishna Gudipati 	} else {
1933a36c61f9SKrishna Gudipati 		rport->stats.adisc_rejected++;
1934a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_ls_rjt(rport, rx_fchs,
1935a36c61f9SKrishna Gudipati 					  FC_LS_RJT_RSN_UNABLE_TO_PERF_CMD,
1936a36c61f9SKrishna Gudipati 					  FC_LS_RJT_EXP_LOGIN_REQUIRED);
1937a36c61f9SKrishna Gudipati 	}
1938a36c61f9SKrishna Gudipati }
1939a36c61f9SKrishna Gudipati 
1940a36c61f9SKrishna Gudipati static void
1941a36c61f9SKrishna Gudipati bfa_fcs_rport_hal_online(struct bfa_fcs_rport_s *rport)
1942a36c61f9SKrishna Gudipati {
1943a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
1944a36c61f9SKrishna Gudipati 	struct bfa_rport_info_s rport_info;
1945a36c61f9SKrishna Gudipati 
1946a36c61f9SKrishna Gudipati 	rport_info.pid = rport->pid;
1947a36c61f9SKrishna Gudipati 	rport_info.local_pid = port->pid;
1948a36c61f9SKrishna Gudipati 	rport_info.lp_tag = port->lp_tag;
1949a36c61f9SKrishna Gudipati 	rport_info.vf_id = port->fabric->vf_id;
1950a36c61f9SKrishna Gudipati 	rport_info.vf_en = port->fabric->is_vf;
1951a36c61f9SKrishna Gudipati 	rport_info.fc_class = rport->fc_cos;
1952a36c61f9SKrishna Gudipati 	rport_info.cisc = rport->cisc;
1953a36c61f9SKrishna Gudipati 	rport_info.max_frmsz = rport->maxfrsize;
1954a36c61f9SKrishna Gudipati 	bfa_rport_online(rport->bfa_rport, &rport_info);
1955a36c61f9SKrishna Gudipati }
1956a36c61f9SKrishna Gudipati 
1957a36c61f9SKrishna Gudipati static struct bfa_fcs_rport_s *
1958a36c61f9SKrishna Gudipati bfa_fcs_rport_alloc(struct bfa_fcs_lport_s *port, wwn_t pwwn, u32 rpid)
1959a36c61f9SKrishna Gudipati {
1960a36c61f9SKrishna Gudipati 	struct bfa_fcs_s	*fcs = port->fcs;
1961a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
1962a36c61f9SKrishna Gudipati 	struct bfad_rport_s	*rport_drv;
1963a36c61f9SKrishna Gudipati 
19645fbe25c7SJing Huang 	/*
1965a36c61f9SKrishna Gudipati 	 * allocate rport
1966a36c61f9SKrishna Gudipati 	 */
1967a36c61f9SKrishna Gudipati 	if (bfa_fcb_rport_alloc(fcs->bfad, &rport, &rport_drv)
1968a36c61f9SKrishna Gudipati 		!= BFA_STATUS_OK) {
1969a36c61f9SKrishna Gudipati 		bfa_trc(fcs, rpid);
1970a36c61f9SKrishna Gudipati 		return NULL;
1971a36c61f9SKrishna Gudipati 	}
1972a36c61f9SKrishna Gudipati 
1973a36c61f9SKrishna Gudipati 	/*
1974a36c61f9SKrishna Gudipati 	 * Initialize r-port
1975a36c61f9SKrishna Gudipati 	 */
1976a36c61f9SKrishna Gudipati 	rport->port = port;
1977a36c61f9SKrishna Gudipati 	rport->fcs = fcs;
1978a36c61f9SKrishna Gudipati 	rport->rp_drv = rport_drv;
1979a36c61f9SKrishna Gudipati 	rport->pid = rpid;
1980a36c61f9SKrishna Gudipati 	rport->pwwn = pwwn;
1981a36c61f9SKrishna Gudipati 
19825fbe25c7SJing Huang 	/*
1983a36c61f9SKrishna Gudipati 	 * allocate BFA rport
1984a36c61f9SKrishna Gudipati 	 */
1985a36c61f9SKrishna Gudipati 	rport->bfa_rport = bfa_rport_create(port->fcs->bfa, rport);
1986a36c61f9SKrishna Gudipati 	if (!rport->bfa_rport) {
1987a36c61f9SKrishna Gudipati 		bfa_trc(fcs, rpid);
1988a36c61f9SKrishna Gudipati 		kfree(rport_drv);
1989a36c61f9SKrishna Gudipati 		return NULL;
1990a36c61f9SKrishna Gudipati 	}
1991a36c61f9SKrishna Gudipati 
19925fbe25c7SJing Huang 	/*
1993a36c61f9SKrishna Gudipati 	 * allocate FC-4s
1994a36c61f9SKrishna Gudipati 	 */
1995a36c61f9SKrishna Gudipati 	bfa_assert(bfa_fcs_lport_is_initiator(port));
1996a36c61f9SKrishna Gudipati 
1997a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_is_initiator(port)) {
1998a36c61f9SKrishna Gudipati 		rport->itnim = bfa_fcs_itnim_create(rport);
1999a36c61f9SKrishna Gudipati 		if (!rport->itnim) {
2000a36c61f9SKrishna Gudipati 			bfa_trc(fcs, rpid);
2001a36c61f9SKrishna Gudipati 			bfa_rport_delete(rport->bfa_rport);
2002a36c61f9SKrishna Gudipati 			kfree(rport_drv);
2003a36c61f9SKrishna Gudipati 			return NULL;
2004a36c61f9SKrishna Gudipati 		}
2005a36c61f9SKrishna Gudipati 	}
2006a36c61f9SKrishna Gudipati 
2007a36c61f9SKrishna Gudipati 	bfa_fcs_lport_add_rport(port, rport);
2008a36c61f9SKrishna Gudipati 
2009a36c61f9SKrishna Gudipati 	bfa_sm_set_state(rport, bfa_fcs_rport_sm_uninit);
2010a36c61f9SKrishna Gudipati 
2011a36c61f9SKrishna Gudipati 	/* Initialize the Rport Features(RPF) Sub Module  */
2012a36c61f9SKrishna Gudipati 	if (!BFA_FCS_PID_IS_WKA(rport->pid))
2013a36c61f9SKrishna Gudipati 		bfa_fcs_rpf_init(rport);
2014a36c61f9SKrishna Gudipati 
2015a36c61f9SKrishna Gudipati 	return rport;
2016a36c61f9SKrishna Gudipati }
2017a36c61f9SKrishna Gudipati 
2018a36c61f9SKrishna Gudipati 
2019a36c61f9SKrishna Gudipati static void
2020a36c61f9SKrishna Gudipati bfa_fcs_rport_free(struct bfa_fcs_rport_s *rport)
2021a36c61f9SKrishna Gudipati {
2022a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2023a36c61f9SKrishna Gudipati 
20245fbe25c7SJing Huang 	/*
2025a36c61f9SKrishna Gudipati 	 * - delete FC-4s
2026a36c61f9SKrishna Gudipati 	 * - delete BFA rport
2027a36c61f9SKrishna Gudipati 	 * - remove from queue of rports
2028a36c61f9SKrishna Gudipati 	 */
2029a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_is_initiator(port)) {
2030a36c61f9SKrishna Gudipati 		bfa_fcs_itnim_delete(rport->itnim);
2031a36c61f9SKrishna Gudipati 		if (rport->pid != 0 && !BFA_FCS_PID_IS_WKA(rport->pid))
2032a36c61f9SKrishna Gudipati 			bfa_fcs_rpf_rport_offline(rport);
2033a36c61f9SKrishna Gudipati 	}
2034a36c61f9SKrishna Gudipati 
2035a36c61f9SKrishna Gudipati 	bfa_rport_delete(rport->bfa_rport);
2036a36c61f9SKrishna Gudipati 	bfa_fcs_lport_del_rport(port, rport);
2037a36c61f9SKrishna Gudipati 	kfree(rport->rp_drv);
2038a36c61f9SKrishna Gudipati }
2039a36c61f9SKrishna Gudipati 
2040a36c61f9SKrishna Gudipati static void
2041a36c61f9SKrishna Gudipati bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport)
2042a36c61f9SKrishna Gudipati {
2043a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2044a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2045a36c61f9SKrishna Gudipati 	char	lpwwn_buf[BFA_STRING_32];
2046a36c61f9SKrishna Gudipati 	char	rpwwn_buf[BFA_STRING_32];
2047a36c61f9SKrishna Gudipati 
2048a36c61f9SKrishna Gudipati 	rport->stats.onlines++;
2049a36c61f9SKrishna Gudipati 
2050a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_is_initiator(port)) {
2051a36c61f9SKrishna Gudipati 		bfa_fcs_itnim_rport_online(rport->itnim);
2052a36c61f9SKrishna Gudipati 		if (!BFA_FCS_PID_IS_WKA(rport->pid))
2053a36c61f9SKrishna Gudipati 			bfa_fcs_rpf_rport_online(rport);
2054a36c61f9SKrishna Gudipati 	};
2055a36c61f9SKrishna Gudipati 
2056a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2057a36c61f9SKrishna Gudipati 	wwn2str(rpwwn_buf, rport->pwwn);
2058a36c61f9SKrishna Gudipati 	if (!BFA_FCS_PID_IS_WKA(rport->pid))
2059a36c61f9SKrishna Gudipati 		BFA_LOG(KERN_INFO, bfad, log_level,
2060a36c61f9SKrishna Gudipati 		"Remote port (WWN = %s) online for logical port (WWN = %s)\n",
2061a36c61f9SKrishna Gudipati 		rpwwn_buf, lpwwn_buf);
2062a36c61f9SKrishna Gudipati }
2063a36c61f9SKrishna Gudipati 
2064a36c61f9SKrishna Gudipati static void
2065a36c61f9SKrishna Gudipati bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport)
2066a36c61f9SKrishna Gudipati {
2067a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2068a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)port->fcs->bfad;
2069a36c61f9SKrishna Gudipati 	char	lpwwn_buf[BFA_STRING_32];
2070a36c61f9SKrishna Gudipati 	char	rpwwn_buf[BFA_STRING_32];
2071a36c61f9SKrishna Gudipati 
2072a36c61f9SKrishna Gudipati 	rport->stats.offlines++;
2073a36c61f9SKrishna Gudipati 
2074a36c61f9SKrishna Gudipati 	wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port));
2075a36c61f9SKrishna Gudipati 	wwn2str(rpwwn_buf, rport->pwwn);
2076a36c61f9SKrishna Gudipati 	if (!BFA_FCS_PID_IS_WKA(rport->pid)) {
2077a36c61f9SKrishna Gudipati 		if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE)
2078a36c61f9SKrishna Gudipati 			BFA_LOG(KERN_ERR, bfad, log_level,
2079a36c61f9SKrishna Gudipati 				"Remote port (WWN = %s) connectivity lost for "
2080a36c61f9SKrishna Gudipati 				"logical port (WWN = %s)\n",
2081a36c61f9SKrishna Gudipati 				rpwwn_buf, lpwwn_buf);
2082a36c61f9SKrishna Gudipati 		else
2083a36c61f9SKrishna Gudipati 			BFA_LOG(KERN_INFO, bfad, log_level,
2084a36c61f9SKrishna Gudipati 				"Remote port (WWN = %s) offlined by "
2085a36c61f9SKrishna Gudipati 				"logical port (WWN = %s)\n",
2086a36c61f9SKrishna Gudipati 				rpwwn_buf, lpwwn_buf);
2087a36c61f9SKrishna Gudipati 	}
2088a36c61f9SKrishna Gudipati 
2089a36c61f9SKrishna Gudipati 	if (bfa_fcs_lport_is_initiator(port)) {
2090a36c61f9SKrishna Gudipati 		bfa_fcs_itnim_rport_offline(rport->itnim);
2091a36c61f9SKrishna Gudipati 		if (!BFA_FCS_PID_IS_WKA(rport->pid))
2092a36c61f9SKrishna Gudipati 			bfa_fcs_rpf_rport_offline(rport);
2093a36c61f9SKrishna Gudipati 	}
2094a36c61f9SKrishna Gudipati }
2095a36c61f9SKrishna Gudipati 
20965fbe25c7SJing Huang /*
2097a36c61f9SKrishna Gudipati  * Update rport parameters from PLOGI or PLOGI accept.
2098a36c61f9SKrishna Gudipati  */
2099a36c61f9SKrishna Gudipati static void
2100a36c61f9SKrishna Gudipati bfa_fcs_rport_update(struct bfa_fcs_rport_s *rport, struct fc_logi_s *plogi)
2101a36c61f9SKrishna Gudipati {
2102a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = rport->port;
2103a36c61f9SKrishna Gudipati 
21045fbe25c7SJing Huang 	/*
2105a36c61f9SKrishna Gudipati 	 * - port name
2106a36c61f9SKrishna Gudipati 	 * - node name
2107a36c61f9SKrishna Gudipati 	 */
2108a36c61f9SKrishna Gudipati 	rport->pwwn = plogi->port_name;
2109a36c61f9SKrishna Gudipati 	rport->nwwn = plogi->node_name;
2110a36c61f9SKrishna Gudipati 
21115fbe25c7SJing Huang 	/*
2112a36c61f9SKrishna Gudipati 	 * - class of service
2113a36c61f9SKrishna Gudipati 	 */
2114a36c61f9SKrishna Gudipati 	rport->fc_cos = 0;
2115a36c61f9SKrishna Gudipati 	if (plogi->class3.class_valid)
2116a36c61f9SKrishna Gudipati 		rport->fc_cos = FC_CLASS_3;
2117a36c61f9SKrishna Gudipati 
2118a36c61f9SKrishna Gudipati 	if (plogi->class2.class_valid)
2119a36c61f9SKrishna Gudipati 		rport->fc_cos |= FC_CLASS_2;
2120a36c61f9SKrishna Gudipati 
21215fbe25c7SJing Huang 	/*
2122a36c61f9SKrishna Gudipati 	 * - CISC
2123a36c61f9SKrishna Gudipati 	 * - MAX receive frame size
2124a36c61f9SKrishna Gudipati 	 */
2125a36c61f9SKrishna Gudipati 	rport->cisc = plogi->csp.cisc;
2126ba816ea8SJing Huang 	rport->maxfrsize = be16_to_cpu(plogi->class3.rxsz);
2127a36c61f9SKrishna Gudipati 
2128ba816ea8SJing Huang 	bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
2129a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, port->fabric->bb_credit);
21305fbe25c7SJing Huang 	/*
2131a36c61f9SKrishna Gudipati 	 * Direct Attach P2P mode :
2132a36c61f9SKrishna Gudipati 	 * This is to handle a bug (233476) in IBM targets in Direct Attach
2133a36c61f9SKrishna Gudipati 	 *  Mode. Basically, in FLOGI Accept the target would have
2134a36c61f9SKrishna Gudipati 	 * erroneously set the BB Credit to the value used in the FLOGI
2135a36c61f9SKrishna Gudipati 	 * sent by the HBA. It uses the correct value (its own BB credit)
2136a36c61f9SKrishna Gudipati 	 * in PLOGI.
2137a36c61f9SKrishna Gudipati 	 */
2138a36c61f9SKrishna Gudipati 	if ((!bfa_fcs_fabric_is_switched(port->fabric))	 &&
2139ba816ea8SJing Huang 		(be16_to_cpu(plogi->csp.bbcred) < port->fabric->bb_credit)) {
2140a36c61f9SKrishna Gudipati 
2141ba816ea8SJing Huang 		bfa_trc(port->fcs, be16_to_cpu(plogi->csp.bbcred));
2142a36c61f9SKrishna Gudipati 		bfa_trc(port->fcs, port->fabric->bb_credit);
2143a36c61f9SKrishna Gudipati 
2144ba816ea8SJing Huang 		port->fabric->bb_credit = be16_to_cpu(plogi->csp.bbcred);
2145a36c61f9SKrishna Gudipati 		bfa_fcport_set_tx_bbcredit(port->fcs->bfa,
2146a36c61f9SKrishna Gudipati 					  port->fabric->bb_credit);
2147a36c61f9SKrishna Gudipati 	}
2148a36c61f9SKrishna Gudipati 
2149a36c61f9SKrishna Gudipati }
2150a36c61f9SKrishna Gudipati 
21515fbe25c7SJing Huang /*
2152a36c61f9SKrishna Gudipati  *	Called to handle LOGO received from an existing remote port.
2153a36c61f9SKrishna Gudipati  */
2154a36c61f9SKrishna Gudipati static void
2155a36c61f9SKrishna Gudipati bfa_fcs_rport_process_logo(struct bfa_fcs_rport_s *rport, struct fchs_s *fchs)
2156a36c61f9SKrishna Gudipati {
2157a36c61f9SKrishna Gudipati 	rport->reply_oxid = fchs->ox_id;
2158a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->reply_oxid);
2159a36c61f9SKrishna Gudipati 
2160a36c61f9SKrishna Gudipati 	rport->prlo = BFA_FALSE;
2161a36c61f9SKrishna Gudipati 	rport->stats.logo_rcvd++;
2162a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_LOGO_RCVD);
2163a36c61f9SKrishna Gudipati }
2164a36c61f9SKrishna Gudipati 
2165a36c61f9SKrishna Gudipati 
2166a36c61f9SKrishna Gudipati 
21675fbe25c7SJing Huang /*
2168a36c61f9SKrishna Gudipati  *  fcs_rport_public FCS rport public interfaces
2169a36c61f9SKrishna Gudipati  */
2170a36c61f9SKrishna Gudipati 
21715fbe25c7SJing Huang /*
2172a36c61f9SKrishna Gudipati  *	Called by bport/vport to create a remote port instance for a discovered
2173a36c61f9SKrishna Gudipati  *	remote device.
2174a36c61f9SKrishna Gudipati  *
2175a36c61f9SKrishna Gudipati  * @param[in] port	- base port or vport
2176a36c61f9SKrishna Gudipati  * @param[in] rpid	- remote port ID
2177a36c61f9SKrishna Gudipati  *
2178a36c61f9SKrishna Gudipati  * @return None
2179a36c61f9SKrishna Gudipati  */
2180a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *
2181a36c61f9SKrishna Gudipati bfa_fcs_rport_create(struct bfa_fcs_lport_s *port, u32 rpid)
2182a36c61f9SKrishna Gudipati {
2183a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2184a36c61f9SKrishna Gudipati 
2185a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rpid);
2186a36c61f9SKrishna Gudipati 	rport = bfa_fcs_rport_alloc(port, WWN_NULL, rpid);
2187a36c61f9SKrishna Gudipati 	if (!rport)
2188a36c61f9SKrishna Gudipati 		return NULL;
2189a36c61f9SKrishna Gudipati 
2190a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
2191a36c61f9SKrishna Gudipati 	return rport;
2192a36c61f9SKrishna Gudipati }
2193a36c61f9SKrishna Gudipati 
21945fbe25c7SJing Huang /*
2195a36c61f9SKrishna Gudipati  * Called to create a rport for which only the wwn is known.
2196a36c61f9SKrishna Gudipati  *
2197a36c61f9SKrishna Gudipati  * @param[in] port	- base port
2198a36c61f9SKrishna Gudipati  * @param[in] rpwwn	- remote port wwn
2199a36c61f9SKrishna Gudipati  *
2200a36c61f9SKrishna Gudipati  * @return None
2201a36c61f9SKrishna Gudipati  */
2202a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *
2203a36c61f9SKrishna Gudipati bfa_fcs_rport_create_by_wwn(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
2204a36c61f9SKrishna Gudipati {
2205a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2206a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, rpwwn);
2207a36c61f9SKrishna Gudipati 	rport = bfa_fcs_rport_alloc(port, rpwwn, 0);
2208a36c61f9SKrishna Gudipati 	if (!rport)
2209a36c61f9SKrishna Gudipati 		return NULL;
2210a36c61f9SKrishna Gudipati 
2211a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_ADDRESS_DISC);
2212a36c61f9SKrishna Gudipati 	return rport;
2213a36c61f9SKrishna Gudipati }
22145fbe25c7SJing Huang /*
2215a36c61f9SKrishna Gudipati  * Called by bport in private loop topology to indicate that a
2216a36c61f9SKrishna Gudipati  * rport has been discovered and plogi has been completed.
2217a36c61f9SKrishna Gudipati  *
2218a36c61f9SKrishna Gudipati  * @param[in] port	- base port or vport
2219a36c61f9SKrishna Gudipati  * @param[in] rpid	- remote port ID
2220a36c61f9SKrishna Gudipati  */
2221a36c61f9SKrishna Gudipati void
2222a36c61f9SKrishna Gudipati bfa_fcs_rport_start(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
2223a36c61f9SKrishna Gudipati 	 struct fc_logi_s *plogi)
2224a36c61f9SKrishna Gudipati {
2225a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2226a36c61f9SKrishna Gudipati 
2227a36c61f9SKrishna Gudipati 	rport = bfa_fcs_rport_alloc(port, WWN_NULL, fchs->s_id);
2228a36c61f9SKrishna Gudipati 	if (!rport)
2229a36c61f9SKrishna Gudipati 		return;
2230a36c61f9SKrishna Gudipati 
2231a36c61f9SKrishna Gudipati 	bfa_fcs_rport_update(rport, plogi);
2232a36c61f9SKrishna Gudipati 
2233a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_COMP);
2234a36c61f9SKrishna Gudipati }
2235a36c61f9SKrishna Gudipati 
22365fbe25c7SJing Huang /*
2237a36c61f9SKrishna Gudipati  *	Called by bport/vport to handle PLOGI received from a new remote port.
2238a36c61f9SKrishna Gudipati  *	If an existing rport does a plogi, it will be handled separately.
2239a36c61f9SKrishna Gudipati  */
2240a36c61f9SKrishna Gudipati void
2241a36c61f9SKrishna Gudipati bfa_fcs_rport_plogi_create(struct bfa_fcs_lport_s *port, struct fchs_s *fchs,
2242a36c61f9SKrishna Gudipati 				struct fc_logi_s *plogi)
2243a36c61f9SKrishna Gudipati {
2244a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2245a36c61f9SKrishna Gudipati 
2246a36c61f9SKrishna Gudipati 	rport = bfa_fcs_rport_alloc(port, plogi->port_name, fchs->s_id);
2247a36c61f9SKrishna Gudipati 	if (!rport)
2248a36c61f9SKrishna Gudipati 		return;
2249a36c61f9SKrishna Gudipati 
2250a36c61f9SKrishna Gudipati 	bfa_fcs_rport_update(rport, plogi);
2251a36c61f9SKrishna Gudipati 
2252a36c61f9SKrishna Gudipati 	rport->reply_oxid = fchs->ox_id;
2253a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->reply_oxid);
2254a36c61f9SKrishna Gudipati 
2255a36c61f9SKrishna Gudipati 	rport->stats.plogi_rcvd++;
2256a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2257a36c61f9SKrishna Gudipati }
2258a36c61f9SKrishna Gudipati 
2259a36c61f9SKrishna Gudipati static int
2260a36c61f9SKrishna Gudipati wwn_compare(wwn_t wwn1, wwn_t wwn2)
2261a36c61f9SKrishna Gudipati {
2262a36c61f9SKrishna Gudipati 	u8		*b1 = (u8 *) &wwn1;
2263a36c61f9SKrishna Gudipati 	u8		*b2 = (u8 *) &wwn2;
2264a36c61f9SKrishna Gudipati 	int		i;
2265a36c61f9SKrishna Gudipati 
2266a36c61f9SKrishna Gudipati 	for (i = 0; i < sizeof(wwn_t); i++) {
2267a36c61f9SKrishna Gudipati 		if (b1[i] < b2[i])
2268a36c61f9SKrishna Gudipati 			return -1;
2269a36c61f9SKrishna Gudipati 		if (b1[i] > b2[i])
2270a36c61f9SKrishna Gudipati 			return 1;
2271a36c61f9SKrishna Gudipati 	}
2272a36c61f9SKrishna Gudipati 	return 0;
2273a36c61f9SKrishna Gudipati }
2274a36c61f9SKrishna Gudipati 
22755fbe25c7SJing Huang /*
2276a36c61f9SKrishna Gudipati  *	Called by bport/vport to handle PLOGI received from an existing
2277a36c61f9SKrishna Gudipati  *	 remote port.
2278a36c61f9SKrishna Gudipati  */
2279a36c61f9SKrishna Gudipati void
2280a36c61f9SKrishna Gudipati bfa_fcs_rport_plogi(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2281a36c61f9SKrishna Gudipati 			struct fc_logi_s *plogi)
2282a36c61f9SKrishna Gudipati {
22835fbe25c7SJing Huang 	/*
2284a36c61f9SKrishna Gudipati 	 * @todo Handle P2P and initiator-initiator.
2285a36c61f9SKrishna Gudipati 	 */
2286a36c61f9SKrishna Gudipati 
2287a36c61f9SKrishna Gudipati 	bfa_fcs_rport_update(rport, plogi);
2288a36c61f9SKrishna Gudipati 
2289a36c61f9SKrishna Gudipati 	rport->reply_oxid = rx_fchs->ox_id;
2290a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->reply_oxid);
2291a36c61f9SKrishna Gudipati 
22925fbe25c7SJing Huang 	/*
2293a36c61f9SKrishna Gudipati 	 * In Switched fabric topology,
2294a36c61f9SKrishna Gudipati 	 * PLOGI to each other. If our pwwn is smaller, ignore it,
2295a36c61f9SKrishna Gudipati 	 * if it is not a well known address.
2296a36c61f9SKrishna Gudipati 	 * If the link topology is N2N,
2297a36c61f9SKrishna Gudipati 	 * this Plogi should be accepted.
2298a36c61f9SKrishna Gudipati 	 */
2299a36c61f9SKrishna Gudipati 	if ((wwn_compare(rport->port->port_cfg.pwwn, rport->pwwn) == -1) &&
2300a36c61f9SKrishna Gudipati 		(bfa_fcs_fabric_is_switched(rport->port->fabric)) &&
2301a36c61f9SKrishna Gudipati 		(!BFA_FCS_PID_IS_WKA(rport->pid))) {
2302a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, rport->pid);
2303a36c61f9SKrishna Gudipati 		return;
2304a36c61f9SKrishna Gudipati 	}
2305a36c61f9SKrishna Gudipati 
2306a36c61f9SKrishna Gudipati 	rport->stats.plogi_rcvd++;
2307a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_RCVD);
2308a36c61f9SKrishna Gudipati }
2309a36c61f9SKrishna Gudipati 
23105fbe25c7SJing Huang /*
2311a36c61f9SKrishna Gudipati  * Called by bport/vport to delete a remote port instance.
2312a36c61f9SKrishna Gudipati  *
2313a36c61f9SKrishna Gudipati  * Rport delete is called under the following conditions:
2314a36c61f9SKrishna Gudipati  *		- vport is deleted
2315a36c61f9SKrishna Gudipati  *		- vf is deleted
2316a36c61f9SKrishna Gudipati  *		- explicit request from OS to delete rport
2317a36c61f9SKrishna Gudipati  */
2318a36c61f9SKrishna Gudipati void
2319a36c61f9SKrishna Gudipati bfa_fcs_rport_delete(struct bfa_fcs_rport_s *rport)
2320a36c61f9SKrishna Gudipati {
2321a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_DELETE);
2322a36c61f9SKrishna Gudipati }
2323a36c61f9SKrishna Gudipati 
23245fbe25c7SJing Huang /*
2325a36c61f9SKrishna Gudipati  * Called by bport/vport to  when a target goes offline.
2326a36c61f9SKrishna Gudipati  *
2327a36c61f9SKrishna Gudipati  */
2328a36c61f9SKrishna Gudipati void
2329a36c61f9SKrishna Gudipati bfa_fcs_rport_offline(struct bfa_fcs_rport_s *rport)
2330a36c61f9SKrishna Gudipati {
2331a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
2332a36c61f9SKrishna Gudipati }
2333a36c61f9SKrishna Gudipati 
23345fbe25c7SJing Huang /*
2335a36c61f9SKrishna Gudipati  * Called by bport in n2n when a target (attached port) becomes online.
2336a36c61f9SKrishna Gudipati  *
2337a36c61f9SKrishna Gudipati  */
2338a36c61f9SKrishna Gudipati void
2339a36c61f9SKrishna Gudipati bfa_fcs_rport_online(struct bfa_fcs_rport_s *rport)
2340a36c61f9SKrishna Gudipati {
2341a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PLOGI_SEND);
2342a36c61f9SKrishna Gudipati }
23435fbe25c7SJing Huang /*
2344a36c61f9SKrishna Gudipati  *	Called by bport/vport to notify SCN for the remote port
2345a36c61f9SKrishna Gudipati  */
2346a36c61f9SKrishna Gudipati void
2347a36c61f9SKrishna Gudipati bfa_fcs_rport_scn(struct bfa_fcs_rport_s *rport)
2348a36c61f9SKrishna Gudipati {
2349a36c61f9SKrishna Gudipati 	rport->stats.rscns++;
2350a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_SCN);
2351a36c61f9SKrishna Gudipati }
2352a36c61f9SKrishna Gudipati 
23535fbe25c7SJing Huang /*
2354a36c61f9SKrishna Gudipati  *	Called by	fcpim to notify that the ITN cleanup is done.
2355a36c61f9SKrishna Gudipati  */
2356a36c61f9SKrishna Gudipati void
2357a36c61f9SKrishna Gudipati bfa_fcs_rport_itnim_ack(struct bfa_fcs_rport_s *rport)
2358a36c61f9SKrishna Gudipati {
2359a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FC4_OFFLINE);
2360a36c61f9SKrishna Gudipati }
2361a36c61f9SKrishna Gudipati 
23625fbe25c7SJing Huang /*
2363a36c61f9SKrishna Gudipati  *	Called by fcptm to notify that the ITN cleanup is done.
2364a36c61f9SKrishna Gudipati  */
2365a36c61f9SKrishna Gudipati void
2366a36c61f9SKrishna Gudipati bfa_fcs_rport_tin_ack(struct bfa_fcs_rport_s *rport)
2367a36c61f9SKrishna Gudipati {
2368a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_FC4_OFFLINE);
2369a36c61f9SKrishna Gudipati }
2370a36c61f9SKrishna Gudipati 
23715fbe25c7SJing Huang /*
2372a36c61f9SKrishna Gudipati  *	brief
2373a36c61f9SKrishna Gudipati  *	This routine BFA callback for bfa_rport_online() call.
2374a36c61f9SKrishna Gudipati  *
2375a36c61f9SKrishna Gudipati  *	param[in]	cb_arg	-  rport struct.
2376a36c61f9SKrishna Gudipati  *
2377a36c61f9SKrishna Gudipati  *	return
2378a36c61f9SKrishna Gudipati  *		void
2379a36c61f9SKrishna Gudipati  *
2380a36c61f9SKrishna Gudipati  *	Special Considerations:
2381a36c61f9SKrishna Gudipati  *
2382a36c61f9SKrishna Gudipati  *	note
2383a36c61f9SKrishna Gudipati  */
2384a36c61f9SKrishna Gudipati void
2385a36c61f9SKrishna Gudipati bfa_cb_rport_online(void *cbarg)
2386a36c61f9SKrishna Gudipati {
2387a36c61f9SKrishna Gudipati 
2388a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2389a36c61f9SKrishna Gudipati 
2390a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2391a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_HCB_ONLINE);
2392a36c61f9SKrishna Gudipati }
2393a36c61f9SKrishna Gudipati 
23945fbe25c7SJing Huang /*
2395a36c61f9SKrishna Gudipati  *	brief
2396a36c61f9SKrishna Gudipati  *	This routine BFA callback for bfa_rport_offline() call.
2397a36c61f9SKrishna Gudipati  *
2398a36c61f9SKrishna Gudipati  *	param[in]	rport	-
2399a36c61f9SKrishna Gudipati  *
2400a36c61f9SKrishna Gudipati  *	return
2401a36c61f9SKrishna Gudipati  *		void
2402a36c61f9SKrishna Gudipati  *
2403a36c61f9SKrishna Gudipati  *	Special Considerations:
2404a36c61f9SKrishna Gudipati  *
2405a36c61f9SKrishna Gudipati  *	note
2406a36c61f9SKrishna Gudipati  */
2407a36c61f9SKrishna Gudipati void
2408a36c61f9SKrishna Gudipati bfa_cb_rport_offline(void *cbarg)
2409a36c61f9SKrishna Gudipati {
2410a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2411a36c61f9SKrishna Gudipati 
2412a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2413a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_HCB_OFFLINE);
2414a36c61f9SKrishna Gudipati }
2415a36c61f9SKrishna Gudipati 
24165fbe25c7SJing Huang /*
2417a36c61f9SKrishna Gudipati  *	brief
2418a36c61f9SKrishna Gudipati  *	This routine is a static BFA callback when there is a QoS flow_id
2419a36c61f9SKrishna Gudipati  *	change notification
2420a36c61f9SKrishna Gudipati  *
2421a36c61f9SKrishna Gudipati  *	param[in]	rport	-
2422a36c61f9SKrishna Gudipati  *
2423a36c61f9SKrishna Gudipati  *	return
2424a36c61f9SKrishna Gudipati  *		void
2425a36c61f9SKrishna Gudipati  *
2426a36c61f9SKrishna Gudipati  *	Special Considerations:
2427a36c61f9SKrishna Gudipati  *
2428a36c61f9SKrishna Gudipati  *	note
2429a36c61f9SKrishna Gudipati  */
2430a36c61f9SKrishna Gudipati void
2431a36c61f9SKrishna Gudipati bfa_cb_rport_qos_scn_flowid(void *cbarg,
2432a36c61f9SKrishna Gudipati 		struct bfa_rport_qos_attr_s old_qos_attr,
2433a36c61f9SKrishna Gudipati 		struct bfa_rport_qos_attr_s new_qos_attr)
2434a36c61f9SKrishna Gudipati {
2435a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2436a36c61f9SKrishna Gudipati 
2437a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2438a36c61f9SKrishna Gudipati }
2439a36c61f9SKrishna Gudipati 
24405fbe25c7SJing Huang /*
2441a36c61f9SKrishna Gudipati  *	brief
2442a36c61f9SKrishna Gudipati  *	This routine is a static BFA callback when there is a QoS priority
2443a36c61f9SKrishna Gudipati  *	change notification
2444a36c61f9SKrishna Gudipati  *
2445a36c61f9SKrishna Gudipati  *	param[in]	rport	-
2446a36c61f9SKrishna Gudipati  *
2447a36c61f9SKrishna Gudipati  *	return
2448a36c61f9SKrishna Gudipati  *		void
2449a36c61f9SKrishna Gudipati  *
2450a36c61f9SKrishna Gudipati  *	Special Considerations:
2451a36c61f9SKrishna Gudipati  *
2452a36c61f9SKrishna Gudipati  *	note
2453a36c61f9SKrishna Gudipati  */
2454a36c61f9SKrishna Gudipati void
2455a36c61f9SKrishna Gudipati bfa_cb_rport_qos_scn_prio(void *cbarg,
2456a36c61f9SKrishna Gudipati 		struct bfa_rport_qos_attr_s old_qos_attr,
2457a36c61f9SKrishna Gudipati 		struct bfa_rport_qos_attr_s new_qos_attr)
2458a36c61f9SKrishna Gudipati {
2459a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = (struct bfa_fcs_rport_s *) cbarg;
2460a36c61f9SKrishna Gudipati 
2461a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2462a36c61f9SKrishna Gudipati }
2463a36c61f9SKrishna Gudipati 
24645fbe25c7SJing Huang /*
2465a36c61f9SKrishna Gudipati  *		Called to process any unsolicted frames from this remote port
2466a36c61f9SKrishna Gudipati  */
2467a36c61f9SKrishna Gudipati void
2468a36c61f9SKrishna Gudipati bfa_fcs_rport_logo_imp(struct bfa_fcs_rport_s *rport)
2469a36c61f9SKrishna Gudipati {
2470a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_LOGO_IMP);
2471a36c61f9SKrishna Gudipati }
2472a36c61f9SKrishna Gudipati 
24735fbe25c7SJing Huang /*
2474a36c61f9SKrishna Gudipati  *		Called to process any unsolicted frames from this remote port
2475a36c61f9SKrishna Gudipati  */
2476a36c61f9SKrishna Gudipati void
2477a36c61f9SKrishna Gudipati bfa_fcs_rport_uf_recv(struct bfa_fcs_rport_s *rport,
2478a36c61f9SKrishna Gudipati 			struct fchs_s *fchs, u16 len)
2479a36c61f9SKrishna Gudipati {
2480a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2481a36c61f9SKrishna Gudipati 	struct fc_els_cmd_s	*els_cmd;
2482a36c61f9SKrishna Gudipati 
2483a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, fchs->s_id);
2484a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, fchs->d_id);
2485a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, fchs->type);
2486a36c61f9SKrishna Gudipati 
2487a36c61f9SKrishna Gudipati 	if (fchs->type != FC_TYPE_ELS)
2488a36c61f9SKrishna Gudipati 		return;
2489a36c61f9SKrishna Gudipati 
2490a36c61f9SKrishna Gudipati 	els_cmd = (struct fc_els_cmd_s *) (fchs + 1);
2491a36c61f9SKrishna Gudipati 
2492a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, els_cmd->els_code);
2493a36c61f9SKrishna Gudipati 
2494a36c61f9SKrishna Gudipati 	switch (els_cmd->els_code) {
2495a36c61f9SKrishna Gudipati 	case FC_ELS_LOGO:
2496a36c61f9SKrishna Gudipati 		bfa_stats(port, plogi_rcvd);
2497a36c61f9SKrishna Gudipati 		bfa_fcs_rport_process_logo(rport, fchs);
2498a36c61f9SKrishna Gudipati 		break;
2499a36c61f9SKrishna Gudipati 
2500a36c61f9SKrishna Gudipati 	case FC_ELS_ADISC:
2501a36c61f9SKrishna Gudipati 		bfa_stats(port, adisc_rcvd);
2502a36c61f9SKrishna Gudipati 		bfa_fcs_rport_process_adisc(rport, fchs, len);
2503a36c61f9SKrishna Gudipati 		break;
2504a36c61f9SKrishna Gudipati 
2505a36c61f9SKrishna Gudipati 	case FC_ELS_PRLO:
2506a36c61f9SKrishna Gudipati 		bfa_stats(port, prlo_rcvd);
2507a36c61f9SKrishna Gudipati 		if (bfa_fcs_lport_is_initiator(port))
2508a36c61f9SKrishna Gudipati 			bfa_fcs_fcpim_uf_recv(rport->itnim, fchs, len);
2509a36c61f9SKrishna Gudipati 		break;
2510a36c61f9SKrishna Gudipati 
2511a36c61f9SKrishna Gudipati 	case FC_ELS_PRLI:
2512a36c61f9SKrishna Gudipati 		bfa_stats(port, prli_rcvd);
2513a36c61f9SKrishna Gudipati 		bfa_fcs_rport_process_prli(rport, fchs, len);
2514a36c61f9SKrishna Gudipati 		break;
2515a36c61f9SKrishna Gudipati 
2516a36c61f9SKrishna Gudipati 	case FC_ELS_RPSC:
2517a36c61f9SKrishna Gudipati 		bfa_stats(port, rpsc_rcvd);
2518a36c61f9SKrishna Gudipati 		bfa_fcs_rport_process_rpsc(rport, fchs, len);
2519a36c61f9SKrishna Gudipati 		break;
2520a36c61f9SKrishna Gudipati 
2521a36c61f9SKrishna Gudipati 	default:
2522a36c61f9SKrishna Gudipati 		bfa_stats(port, un_handled_els_rcvd);
2523a36c61f9SKrishna Gudipati 		bfa_fcs_rport_send_ls_rjt(rport, fchs,
2524a36c61f9SKrishna Gudipati 					  FC_LS_RJT_RSN_CMD_NOT_SUPP,
2525a36c61f9SKrishna Gudipati 					  FC_LS_RJT_EXP_NO_ADDL_INFO);
2526a36c61f9SKrishna Gudipati 		break;
2527a36c61f9SKrishna Gudipati 	}
2528a36c61f9SKrishna Gudipati }
2529a36c61f9SKrishna Gudipati 
2530a36c61f9SKrishna Gudipati /* send best case  acc to prlo */
2531a36c61f9SKrishna Gudipati static void
2532a36c61f9SKrishna Gudipati bfa_fcs_rport_send_prlo_acc(struct bfa_fcs_rport_s *rport)
2533a36c61f9SKrishna Gudipati {
2534a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2535a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2536a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2537a36c61f9SKrishna Gudipati 	int		len;
2538a36c61f9SKrishna Gudipati 
2539a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2540a36c61f9SKrishna Gudipati 
2541a36c61f9SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(port->fcs);
2542a36c61f9SKrishna Gudipati 	if (!fcxp)
2543a36c61f9SKrishna Gudipati 		return;
2544a36c61f9SKrishna Gudipati 	len = fc_prlo_acc_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2545a36c61f9SKrishna Gudipati 			rport->pid, bfa_fcs_lport_get_fcid(port),
2546a36c61f9SKrishna Gudipati 			rport->reply_oxid, 0);
2547a36c61f9SKrishna Gudipati 
2548a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, rport->bfa_rport, port->fabric->vf_id,
2549a36c61f9SKrishna Gudipati 		port->lp_tag, BFA_FALSE, FC_CLASS_3, len, &fchs,
2550a36c61f9SKrishna Gudipati 		NULL, NULL, FC_MAX_PDUSZ, 0);
2551a36c61f9SKrishna Gudipati }
2552a36c61f9SKrishna Gudipati 
2553a36c61f9SKrishna Gudipati /*
2554a36c61f9SKrishna Gudipati  * Send a LS reject
2555a36c61f9SKrishna Gudipati  */
2556a36c61f9SKrishna Gudipati static void
2557a36c61f9SKrishna Gudipati bfa_fcs_rport_send_ls_rjt(struct bfa_fcs_rport_s *rport, struct fchs_s *rx_fchs,
2558a36c61f9SKrishna Gudipati 			  u8 reason_code, u8 reason_code_expl)
2559a36c61f9SKrishna Gudipati {
2560a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
2561a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
2562a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
2563a36c61f9SKrishna Gudipati 	int		len;
2564a36c61f9SKrishna Gudipati 
2565a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rx_fchs->s_id);
2566a36c61f9SKrishna Gudipati 
2567a36c61f9SKrishna Gudipati 	fcxp = bfa_fcs_fcxp_alloc(rport->fcs);
2568a36c61f9SKrishna Gudipati 	if (!fcxp)
2569a36c61f9SKrishna Gudipati 		return;
2570a36c61f9SKrishna Gudipati 
2571a36c61f9SKrishna Gudipati 	len = fc_ls_rjt_build(&fchs, bfa_fcxp_get_reqbuf(fcxp),
2572a36c61f9SKrishna Gudipati 				rx_fchs->s_id, bfa_fcs_lport_get_fcid(port),
2573a36c61f9SKrishna Gudipati 				rx_fchs->ox_id, reason_code, reason_code_expl);
2574a36c61f9SKrishna Gudipati 
2575a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag,
2576a36c61f9SKrishna Gudipati 			BFA_FALSE, FC_CLASS_3, len, &fchs, NULL, NULL,
2577a36c61f9SKrishna Gudipati 			FC_MAX_PDUSZ, 0);
2578a36c61f9SKrishna Gudipati }
2579a36c61f9SKrishna Gudipati 
25805fbe25c7SJing Huang /*
2581a36c61f9SKrishna Gudipati  * Return state of rport.
2582a36c61f9SKrishna Gudipati  */
2583a36c61f9SKrishna Gudipati int
2584a36c61f9SKrishna Gudipati bfa_fcs_rport_get_state(struct bfa_fcs_rport_s *rport)
2585a36c61f9SKrishna Gudipati {
2586a36c61f9SKrishna Gudipati 	return bfa_sm_to_state(rport_sm_table, rport->sm);
2587a36c61f9SKrishna Gudipati }
2588a36c61f9SKrishna Gudipati 
25895fbe25c7SJing Huang /*
2590a36c61f9SKrishna Gudipati  *	brief
2591a36c61f9SKrishna Gudipati  *		 Called by the Driver to set rport delete/ageout timeout
2592a36c61f9SKrishna Gudipati  *
2593a36c61f9SKrishna Gudipati  *	param[in]		rport timeout value in seconds.
2594a36c61f9SKrishna Gudipati  *
2595a36c61f9SKrishna Gudipati  *	return None
2596a36c61f9SKrishna Gudipati  */
2597a36c61f9SKrishna Gudipati void
2598a36c61f9SKrishna Gudipati bfa_fcs_rport_set_del_timeout(u8 rport_tmo)
2599a36c61f9SKrishna Gudipati {
2600a36c61f9SKrishna Gudipati 	/* convert to Millisecs */
2601a36c61f9SKrishna Gudipati 	if (rport_tmo > 0)
2602a36c61f9SKrishna Gudipati 		bfa_fcs_rport_del_timeout = rport_tmo * 1000;
2603a36c61f9SKrishna Gudipati }
2604a36c61f9SKrishna Gudipati void
2605a36c61f9SKrishna Gudipati bfa_fcs_rport_prlo(struct bfa_fcs_rport_s *rport, u16 ox_id)
2606a36c61f9SKrishna Gudipati {
2607a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2608a36c61f9SKrishna Gudipati 
2609a36c61f9SKrishna Gudipati 	rport->prlo = BFA_TRUE;
2610a36c61f9SKrishna Gudipati 	rport->reply_oxid = ox_id;
2611a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, RPSM_EVENT_PRLO_RCVD);
2612a36c61f9SKrishna Gudipati }
2613a36c61f9SKrishna Gudipati 
2614a36c61f9SKrishna Gudipati 
2615a36c61f9SKrishna Gudipati 
26165fbe25c7SJing Huang /*
2617a36c61f9SKrishna Gudipati  * Remote port implementation.
2618a36c61f9SKrishna Gudipati  */
2619a36c61f9SKrishna Gudipati 
26205fbe25c7SJing Huang /*
2621a36c61f9SKrishna Gudipati  *  fcs_rport_api FCS rport API.
2622a36c61f9SKrishna Gudipati  */
2623a36c61f9SKrishna Gudipati 
26245fbe25c7SJing Huang /*
2625a36c61f9SKrishna Gudipati  *	Direct API to add a target by port wwn. This interface is used, for
2626a36c61f9SKrishna Gudipati  *	example, by bios when target pwwn is known from boot lun configuration.
2627a36c61f9SKrishna Gudipati  */
2628a36c61f9SKrishna Gudipati bfa_status_t
2629a36c61f9SKrishna Gudipati bfa_fcs_rport_add(struct bfa_fcs_lport_s *port, wwn_t *pwwn,
2630a36c61f9SKrishna Gudipati 		struct bfa_fcs_rport_s *rport, struct bfad_rport_s *rport_drv)
2631a36c61f9SKrishna Gudipati {
2632a36c61f9SKrishna Gudipati 	bfa_trc(port->fcs, *pwwn);
2633a36c61f9SKrishna Gudipati 
2634a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
2635a36c61f9SKrishna Gudipati }
2636a36c61f9SKrishna Gudipati 
26375fbe25c7SJing Huang /*
2638a36c61f9SKrishna Gudipati  *	Direct API to remove a target and its associated resources. This
2639a36c61f9SKrishna Gudipati  *	interface is used, for example, by driver to remove target
2640a36c61f9SKrishna Gudipati  *	ports from the target list for a VM.
2641a36c61f9SKrishna Gudipati  */
2642a36c61f9SKrishna Gudipati bfa_status_t
2643a36c61f9SKrishna Gudipati bfa_fcs_rport_remove(struct bfa_fcs_rport_s *rport_in)
2644a36c61f9SKrishna Gudipati {
2645a36c61f9SKrishna Gudipati 
2646a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2647a36c61f9SKrishna Gudipati 
2648a36c61f9SKrishna Gudipati 	bfa_trc(rport_in->fcs, rport_in->pwwn);
2649a36c61f9SKrishna Gudipati 
2650a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pwwn(rport_in->port, rport_in->pwwn);
2651a36c61f9SKrishna Gudipati 	if (rport == NULL) {
2652a36c61f9SKrishna Gudipati 		/*
2653a36c61f9SKrishna Gudipati 		 * TBD Error handling
2654a36c61f9SKrishna Gudipati 		 */
2655a36c61f9SKrishna Gudipati 		bfa_trc(rport_in->fcs, rport_in->pid);
2656a36c61f9SKrishna Gudipati 		return BFA_STATUS_UNKNOWN_RWWN;
2657a36c61f9SKrishna Gudipati 	}
2658a36c61f9SKrishna Gudipati 
2659a36c61f9SKrishna Gudipati 	/*
2660a36c61f9SKrishna Gudipati 	 * TBD if this remote port is online, send a logo
2661a36c61f9SKrishna Gudipati 	 */
2662a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
2663a36c61f9SKrishna Gudipati 
2664a36c61f9SKrishna Gudipati }
2665a36c61f9SKrishna Gudipati 
26665fbe25c7SJing Huang /*
2667a36c61f9SKrishna Gudipati  *	Remote device status for display/debug.
2668a36c61f9SKrishna Gudipati  */
2669a36c61f9SKrishna Gudipati void
2670a36c61f9SKrishna Gudipati bfa_fcs_rport_get_attr(struct bfa_fcs_rport_s *rport,
2671a36c61f9SKrishna Gudipati 			struct bfa_rport_attr_s *rport_attr)
2672a36c61f9SKrishna Gudipati {
2673a36c61f9SKrishna Gudipati 	struct bfa_rport_qos_attr_s qos_attr;
2674a36c61f9SKrishna Gudipati 	bfa_fcs_lport_t *port = rport->port;
2675a36c61f9SKrishna Gudipati 	bfa_port_speed_t rport_speed = rport->rpf.rpsc_speed;
2676a36c61f9SKrishna Gudipati 
26776a18b167SJing Huang 	memset(rport_attr, 0, sizeof(struct bfa_rport_attr_s));
2678a36c61f9SKrishna Gudipati 
2679a36c61f9SKrishna Gudipati 	rport_attr->pid = rport->pid;
2680a36c61f9SKrishna Gudipati 	rport_attr->pwwn = rport->pwwn;
2681a36c61f9SKrishna Gudipati 	rport_attr->nwwn = rport->nwwn;
2682a36c61f9SKrishna Gudipati 	rport_attr->cos_supported = rport->fc_cos;
2683a36c61f9SKrishna Gudipati 	rport_attr->df_sz = rport->maxfrsize;
2684a36c61f9SKrishna Gudipati 	rport_attr->state = bfa_fcs_rport_get_state(rport);
2685a36c61f9SKrishna Gudipati 	rport_attr->fc_cos = rport->fc_cos;
2686a36c61f9SKrishna Gudipati 	rport_attr->cisc = rport->cisc;
2687a36c61f9SKrishna Gudipati 	rport_attr->scsi_function = rport->scsi_function;
2688a36c61f9SKrishna Gudipati 	rport_attr->curr_speed  = rport->rpf.rpsc_speed;
2689a36c61f9SKrishna Gudipati 	rport_attr->assigned_speed  = rport->rpf.assigned_speed;
2690a36c61f9SKrishna Gudipati 
2691a36c61f9SKrishna Gudipati 	bfa_rport_get_qos_attr(rport->bfa_rport, &qos_attr);
2692a36c61f9SKrishna Gudipati 	rport_attr->qos_attr = qos_attr;
2693a36c61f9SKrishna Gudipati 
2694a36c61f9SKrishna Gudipati 	rport_attr->trl_enforced = BFA_FALSE;
2695a36c61f9SKrishna Gudipati 	if (bfa_fcport_is_ratelim(port->fcs->bfa)) {
2696a36c61f9SKrishna Gudipati 		if (rport_speed == BFA_PORT_SPEED_UNKNOWN) {
2697a36c61f9SKrishna Gudipati 			/* Use default ratelim speed setting */
2698a36c61f9SKrishna Gudipati 			rport_speed =
2699a36c61f9SKrishna Gudipati 				bfa_fcport_get_ratelim_speed(rport->fcs->bfa);
2700a36c61f9SKrishna Gudipati 		}
2701a36c61f9SKrishna Gudipati 
2702a36c61f9SKrishna Gudipati 		if (rport_speed < bfa_fcs_lport_get_rport_max_speed(port))
2703a36c61f9SKrishna Gudipati 			rport_attr->trl_enforced = BFA_TRUE;
2704a36c61f9SKrishna Gudipati 	}
2705a36c61f9SKrishna Gudipati }
2706a36c61f9SKrishna Gudipati 
27075fbe25c7SJing Huang /*
2708a36c61f9SKrishna Gudipati  *	Per remote device statistics.
2709a36c61f9SKrishna Gudipati  */
2710a36c61f9SKrishna Gudipati void
2711a36c61f9SKrishna Gudipati bfa_fcs_rport_get_stats(struct bfa_fcs_rport_s *rport,
2712a36c61f9SKrishna Gudipati 			struct bfa_rport_stats_s *stats)
2713a36c61f9SKrishna Gudipati {
2714a36c61f9SKrishna Gudipati 	*stats = rport->stats;
2715a36c61f9SKrishna Gudipati }
2716a36c61f9SKrishna Gudipati 
2717a36c61f9SKrishna Gudipati void
2718a36c61f9SKrishna Gudipati bfa_fcs_rport_clear_stats(struct bfa_fcs_rport_s *rport)
2719a36c61f9SKrishna Gudipati {
27206a18b167SJing Huang 	memset((char *)&rport->stats, 0,
2721a36c61f9SKrishna Gudipati 			sizeof(struct bfa_rport_stats_s));
2722a36c61f9SKrishna Gudipati }
2723a36c61f9SKrishna Gudipati 
2724a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *
2725a36c61f9SKrishna Gudipati bfa_fcs_rport_lookup(struct bfa_fcs_lport_s *port, wwn_t rpwwn)
2726a36c61f9SKrishna Gudipati {
2727a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2728a36c61f9SKrishna Gudipati 
2729a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_pwwn(port, rpwwn);
2730a36c61f9SKrishna Gudipati 	if (rport == NULL) {
2731a36c61f9SKrishna Gudipati 		/*
2732a36c61f9SKrishna Gudipati 		 * TBD Error handling
2733a36c61f9SKrishna Gudipati 		 */
2734a36c61f9SKrishna Gudipati 	}
2735a36c61f9SKrishna Gudipati 
2736a36c61f9SKrishna Gudipati 	return rport;
2737a36c61f9SKrishna Gudipati }
2738a36c61f9SKrishna Gudipati 
2739a36c61f9SKrishna Gudipati struct bfa_fcs_rport_s *
2740a36c61f9SKrishna Gudipati bfa_fcs_rport_lookup_by_nwwn(struct bfa_fcs_lport_s *port, wwn_t rnwwn)
2741a36c61f9SKrishna Gudipati {
2742a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport;
2743a36c61f9SKrishna Gudipati 
2744a36c61f9SKrishna Gudipati 	rport = bfa_fcs_lport_get_rport_by_nwwn(port, rnwwn);
2745a36c61f9SKrishna Gudipati 	if (rport == NULL) {
2746a36c61f9SKrishna Gudipati 		/*
2747a36c61f9SKrishna Gudipati 		 * TBD Error handling
2748a36c61f9SKrishna Gudipati 		 */
2749a36c61f9SKrishna Gudipati 	}
2750a36c61f9SKrishna Gudipati 
2751a36c61f9SKrishna Gudipati 	return rport;
2752a36c61f9SKrishna Gudipati }
2753a36c61f9SKrishna Gudipati 
2754a36c61f9SKrishna Gudipati /*
2755a36c61f9SKrishna Gudipati  * This API is to set the Rport's speed. Should be used when RPSC is not
2756a36c61f9SKrishna Gudipati  * supported by the rport.
2757a36c61f9SKrishna Gudipati  */
2758a36c61f9SKrishna Gudipati void
2759a36c61f9SKrishna Gudipati bfa_fcs_rport_set_speed(struct bfa_fcs_rport_s *rport, bfa_port_speed_t speed)
2760a36c61f9SKrishna Gudipati {
2761a36c61f9SKrishna Gudipati 	rport->rpf.assigned_speed  = speed;
2762a36c61f9SKrishna Gudipati 
2763a36c61f9SKrishna Gudipati 	/* Set this speed in f/w only if the RPSC speed is not available */
2764a36c61f9SKrishna Gudipati 	if (rport->rpf.rpsc_speed == BFA_PORT_SPEED_UNKNOWN)
2765a36c61f9SKrishna Gudipati 		bfa_rport_speed(rport->bfa_rport, speed);
2766a36c61f9SKrishna Gudipati }
2767a36c61f9SKrishna Gudipati 
2768a36c61f9SKrishna Gudipati 
2769a36c61f9SKrishna Gudipati 
27705fbe25c7SJing Huang /*
2771a36c61f9SKrishna Gudipati  * Remote port features (RPF) implementation.
2772a36c61f9SKrishna Gudipati  */
2773a36c61f9SKrishna Gudipati 
2774a36c61f9SKrishna Gudipati #define BFA_FCS_RPF_RETRIES	(3)
2775a36c61f9SKrishna Gudipati #define BFA_FCS_RPF_RETRY_TIMEOUT  (1000) /* 1 sec (In millisecs) */
2776a36c61f9SKrishna Gudipati 
2777a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_send_rpsc2(void *rport_cbarg,
2778a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp_alloced);
2779a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_rpsc2_response(void *fcsarg,
2780a36c61f9SKrishna Gudipati 			struct bfa_fcxp_s *fcxp,
2781a36c61f9SKrishna Gudipati 			void *cbarg,
2782a36c61f9SKrishna Gudipati 			bfa_status_t req_status,
2783a36c61f9SKrishna Gudipati 			u32 rsp_len,
2784a36c61f9SKrishna Gudipati 			u32 resid_len,
2785a36c61f9SKrishna Gudipati 			struct fchs_s *rsp_fchs);
2786a36c61f9SKrishna Gudipati 
2787a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_timeout(void *arg);
2788a36c61f9SKrishna Gudipati 
27895fbe25c7SJing Huang /*
2790a36c61f9SKrishna Gudipati  *  fcs_rport_ftrs_sm FCS rport state machine events
2791a36c61f9SKrishna Gudipati  */
2792a36c61f9SKrishna Gudipati 
2793a36c61f9SKrishna Gudipati enum rpf_event {
2794a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPORT_OFFLINE  = 1, /* Rport offline		*/
2795a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPORT_ONLINE   = 2,	/* Rport online			*/
2796a36c61f9SKrishna Gudipati 	RPFSM_EVENT_FCXP_SENT      = 3,	/* Frame from has been sent	*/
2797a36c61f9SKrishna Gudipati 	RPFSM_EVENT_TIMEOUT	   = 4, /* Rport SM timeout event	*/
2798a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPSC_COMP      = 5,
2799a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPSC_FAIL      = 6,
2800a36c61f9SKrishna Gudipati 	RPFSM_EVENT_RPSC_ERROR     = 7,
2801a36c61f9SKrishna Gudipati };
2802a36c61f9SKrishna Gudipati 
2803a36c61f9SKrishna Gudipati static void	bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf,
2804a36c61f9SKrishna Gudipati 					enum rpf_event event);
2805a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf,
2806a36c61f9SKrishna Gudipati 				       enum rpf_event event);
2807a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf,
2808a36c61f9SKrishna Gudipati 				       enum rpf_event event);
2809a36c61f9SKrishna Gudipati static void	bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf,
2810a36c61f9SKrishna Gudipati 					enum rpf_event event);
2811a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf,
2812a36c61f9SKrishna Gudipati 					enum rpf_event event);
2813a36c61f9SKrishna Gudipati static void     bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf,
2814a36c61f9SKrishna Gudipati 					enum rpf_event event);
2815a36c61f9SKrishna Gudipati 
2816a36c61f9SKrishna Gudipati static void
2817a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_uninit(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2818a36c61f9SKrishna Gudipati {
2819a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2820a36c61f9SKrishna Gudipati 	struct bfa_fcs_fabric_s *fabric = &rport->fcs->fabric;
2821a36c61f9SKrishna Gudipati 
2822a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2823a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2824a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
2825a36c61f9SKrishna Gudipati 
2826a36c61f9SKrishna Gudipati 	switch (event) {
2827a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_ONLINE:
2828a36c61f9SKrishna Gudipati 		/* Send RPSC2 to a Brocade fabric only. */
2829a36c61f9SKrishna Gudipati 		if ((!BFA_FCS_PID_IS_WKA(rport->pid)) &&
2830a36c61f9SKrishna Gudipati 			((bfa_lps_is_brcd_fabric(rport->port->fabric->lps)) ||
2831a36c61f9SKrishna Gudipati 			(bfa_fcs_fabric_get_switch_oui(fabric) ==
2832a36c61f9SKrishna Gudipati 						BFA_FCS_BRCD_SWITCH_OUI))) {
2833a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
2834a36c61f9SKrishna Gudipati 			rpf->rpsc_retries = 0;
2835a36c61f9SKrishna Gudipati 			bfa_fcs_rpf_send_rpsc2(rpf, NULL);
2836a36c61f9SKrishna Gudipati 		}
2837a36c61f9SKrishna Gudipati 		break;
2838a36c61f9SKrishna Gudipati 
2839a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
2840a36c61f9SKrishna Gudipati 		break;
2841a36c61f9SKrishna Gudipati 
2842a36c61f9SKrishna Gudipati 	default:
2843a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
2844a36c61f9SKrishna Gudipati 	}
2845a36c61f9SKrishna Gudipati }
2846a36c61f9SKrishna Gudipati 
2847a36c61f9SKrishna Gudipati static void
2848a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_rpsc_sending(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2849a36c61f9SKrishna Gudipati {
2850a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2851a36c61f9SKrishna Gudipati 
2852a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
2853a36c61f9SKrishna Gudipati 
2854a36c61f9SKrishna Gudipati 	switch (event) {
2855a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_FCXP_SENT:
2856a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc);
2857a36c61f9SKrishna Gudipati 		break;
2858a36c61f9SKrishna Gudipati 
2859a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
2860a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
2861a36c61f9SKrishna Gudipati 		bfa_fcxp_walloc_cancel(rport->fcs->bfa, &rpf->fcxp_wqe);
2862a36c61f9SKrishna Gudipati 		rpf->rpsc_retries = 0;
2863a36c61f9SKrishna Gudipati 		break;
2864a36c61f9SKrishna Gudipati 
2865a36c61f9SKrishna Gudipati 	default:
2866a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
2867a36c61f9SKrishna Gudipati 	}
2868a36c61f9SKrishna Gudipati }
2869a36c61f9SKrishna Gudipati 
2870a36c61f9SKrishna Gudipati static void
2871a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_rpsc(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2872a36c61f9SKrishna Gudipati {
2873a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2874a36c61f9SKrishna Gudipati 
2875a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2876a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
2877a36c61f9SKrishna Gudipati 
2878a36c61f9SKrishna Gudipati 	switch (event) {
2879a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPSC_COMP:
2880a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
2881a36c61f9SKrishna Gudipati 		/* Update speed info in f/w via BFA */
2882a36c61f9SKrishna Gudipati 		if (rpf->rpsc_speed != BFA_PORT_SPEED_UNKNOWN)
2883a36c61f9SKrishna Gudipati 			bfa_rport_speed(rport->bfa_rport, rpf->rpsc_speed);
2884a36c61f9SKrishna Gudipati 		else if (rpf->assigned_speed != BFA_PORT_SPEED_UNKNOWN)
2885a36c61f9SKrishna Gudipati 			bfa_rport_speed(rport->bfa_rport, rpf->assigned_speed);
2886a36c61f9SKrishna Gudipati 		break;
2887a36c61f9SKrishna Gudipati 
2888a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPSC_FAIL:
2889a36c61f9SKrishna Gudipati 		/* RPSC not supported by rport */
2890a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
2891a36c61f9SKrishna Gudipati 		break;
2892a36c61f9SKrishna Gudipati 
2893a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPSC_ERROR:
2894a36c61f9SKrishna Gudipati 		/* need to retry...delayed a bit. */
2895a36c61f9SKrishna Gudipati 		if (rpf->rpsc_retries++ < BFA_FCS_RPF_RETRIES) {
2896a36c61f9SKrishna Gudipati 			bfa_timer_start(rport->fcs->bfa, &rpf->timer,
2897a36c61f9SKrishna Gudipati 				    bfa_fcs_rpf_timeout, rpf,
2898a36c61f9SKrishna Gudipati 				    BFA_FCS_RPF_RETRY_TIMEOUT);
2899a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_retry);
2900a36c61f9SKrishna Gudipati 		} else {
2901a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_online);
2902a36c61f9SKrishna Gudipati 		}
2903a36c61f9SKrishna Gudipati 		break;
2904a36c61f9SKrishna Gudipati 
2905a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
2906a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
2907a36c61f9SKrishna Gudipati 		bfa_fcxp_discard(rpf->fcxp);
2908a36c61f9SKrishna Gudipati 		rpf->rpsc_retries = 0;
2909a36c61f9SKrishna Gudipati 		break;
2910a36c61f9SKrishna Gudipati 
2911a36c61f9SKrishna Gudipati 	default:
2912a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
2913a36c61f9SKrishna Gudipati 	}
2914a36c61f9SKrishna Gudipati }
2915a36c61f9SKrishna Gudipati 
2916a36c61f9SKrishna Gudipati static void
2917a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_rpsc_retry(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2918a36c61f9SKrishna Gudipati {
2919a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2920a36c61f9SKrishna Gudipati 
2921a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2922a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
2923a36c61f9SKrishna Gudipati 
2924a36c61f9SKrishna Gudipati 	switch (event) {
2925a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_TIMEOUT:
2926a36c61f9SKrishna Gudipati 		/* re-send the RPSC */
2927a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
2928a36c61f9SKrishna Gudipati 		bfa_fcs_rpf_send_rpsc2(rpf, NULL);
2929a36c61f9SKrishna Gudipati 		break;
2930a36c61f9SKrishna Gudipati 
2931a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
2932a36c61f9SKrishna Gudipati 		bfa_timer_stop(&rpf->timer);
2933a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
2934a36c61f9SKrishna Gudipati 		rpf->rpsc_retries = 0;
2935a36c61f9SKrishna Gudipati 		break;
2936a36c61f9SKrishna Gudipati 
2937a36c61f9SKrishna Gudipati 	default:
2938a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
2939a36c61f9SKrishna Gudipati 	}
2940a36c61f9SKrishna Gudipati }
2941a36c61f9SKrishna Gudipati 
2942a36c61f9SKrishna Gudipati static void
2943a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_online(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2944a36c61f9SKrishna Gudipati {
2945a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2946a36c61f9SKrishna Gudipati 
2947a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2948a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2949a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
2950a36c61f9SKrishna Gudipati 
2951a36c61f9SKrishna Gudipati 	switch (event) {
2952a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
2953a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_offline);
2954a36c61f9SKrishna Gudipati 		rpf->rpsc_retries = 0;
2955a36c61f9SKrishna Gudipati 		break;
2956a36c61f9SKrishna Gudipati 
2957a36c61f9SKrishna Gudipati 	default:
2958a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
2959a36c61f9SKrishna Gudipati 	}
2960a36c61f9SKrishna Gudipati }
2961a36c61f9SKrishna Gudipati 
2962a36c61f9SKrishna Gudipati static void
2963a36c61f9SKrishna Gudipati bfa_fcs_rpf_sm_offline(struct bfa_fcs_rpf_s *rpf, enum rpf_event event)
2964a36c61f9SKrishna Gudipati {
2965a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
2966a36c61f9SKrishna Gudipati 
2967a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
2968a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2969a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, event);
2970a36c61f9SKrishna Gudipati 
2971a36c61f9SKrishna Gudipati 	switch (event) {
2972a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_ONLINE:
2973a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_rpsc_sending);
2974a36c61f9SKrishna Gudipati 		bfa_fcs_rpf_send_rpsc2(rpf, NULL);
2975a36c61f9SKrishna Gudipati 		break;
2976a36c61f9SKrishna Gudipati 
2977a36c61f9SKrishna Gudipati 	case RPFSM_EVENT_RPORT_OFFLINE:
2978a36c61f9SKrishna Gudipati 		break;
2979a36c61f9SKrishna Gudipati 
2980a36c61f9SKrishna Gudipati 	default:
2981a36c61f9SKrishna Gudipati 		bfa_sm_fault(rport->fcs, event);
2982a36c61f9SKrishna Gudipati 	}
2983a36c61f9SKrishna Gudipati }
29845fbe25c7SJing Huang /*
2985a36c61f9SKrishna Gudipati  * Called when Rport is created.
2986a36c61f9SKrishna Gudipati  */
2987a36c61f9SKrishna Gudipati void
2988a36c61f9SKrishna Gudipati bfa_fcs_rpf_init(struct bfa_fcs_rport_s *rport)
2989a36c61f9SKrishna Gudipati {
2990a36c61f9SKrishna Gudipati 	struct bfa_fcs_rpf_s *rpf = &rport->rpf;
2991a36c61f9SKrishna Gudipati 
2992a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
2993a36c61f9SKrishna Gudipati 	rpf->rport = rport;
2994a36c61f9SKrishna Gudipati 
2995a36c61f9SKrishna Gudipati 	bfa_sm_set_state(rpf, bfa_fcs_rpf_sm_uninit);
2996a36c61f9SKrishna Gudipati }
2997a36c61f9SKrishna Gudipati 
29985fbe25c7SJing Huang /*
2999a36c61f9SKrishna Gudipati  * Called when Rport becomes online
3000a36c61f9SKrishna Gudipati  */
3001a36c61f9SKrishna Gudipati void
3002a36c61f9SKrishna Gudipati bfa_fcs_rpf_rport_online(struct bfa_fcs_rport_s *rport)
3003a36c61f9SKrishna Gudipati {
3004a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3005a36c61f9SKrishna Gudipati 
3006a36c61f9SKrishna Gudipati 	if (__fcs_min_cfg(rport->port->fcs))
3007a36c61f9SKrishna Gudipati 		return;
3008a36c61f9SKrishna Gudipati 
3009a36c61f9SKrishna Gudipati 	if (bfa_fcs_fabric_is_switched(rport->port->fabric))
3010a36c61f9SKrishna Gudipati 		bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_ONLINE);
3011a36c61f9SKrishna Gudipati }
3012a36c61f9SKrishna Gudipati 
30135fbe25c7SJing Huang /*
3014a36c61f9SKrishna Gudipati  * Called when Rport becomes offline
3015a36c61f9SKrishna Gudipati  */
3016a36c61f9SKrishna Gudipati void
3017a36c61f9SKrishna Gudipati bfa_fcs_rpf_rport_offline(struct bfa_fcs_rport_s *rport)
3018a36c61f9SKrishna Gudipati {
3019a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3020a36c61f9SKrishna Gudipati 
3021a36c61f9SKrishna Gudipati 	if (__fcs_min_cfg(rport->port->fcs))
3022a36c61f9SKrishna Gudipati 		return;
3023a36c61f9SKrishna Gudipati 
3024a36c61f9SKrishna Gudipati 	rport->rpf.rpsc_speed = 0;
3025a36c61f9SKrishna Gudipati 	bfa_sm_send_event(&rport->rpf, RPFSM_EVENT_RPORT_OFFLINE);
3026a36c61f9SKrishna Gudipati }
3027a36c61f9SKrishna Gudipati 
3028a36c61f9SKrishna Gudipati static void
3029a36c61f9SKrishna Gudipati bfa_fcs_rpf_timeout(void *arg)
3030a36c61f9SKrishna Gudipati {
3031a36c61f9SKrishna Gudipati 	struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) arg;
3032a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3033a36c61f9SKrishna Gudipati 
3034a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pid);
3035a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rpf, RPFSM_EVENT_TIMEOUT);
3036a36c61f9SKrishna Gudipati }
3037a36c61f9SKrishna Gudipati 
3038a36c61f9SKrishna Gudipati static void
3039a36c61f9SKrishna Gudipati bfa_fcs_rpf_send_rpsc2(void *rpf_cbarg, struct bfa_fcxp_s *fcxp_alloced)
3040a36c61f9SKrishna Gudipati {
3041a36c61f9SKrishna Gudipati 	struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *)rpf_cbarg;
3042a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3043a36c61f9SKrishna Gudipati 	struct bfa_fcs_lport_s *port = rport->port;
3044a36c61f9SKrishna Gudipati 	struct fchs_s	fchs;
3045a36c61f9SKrishna Gudipati 	int		len;
3046a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
3047a36c61f9SKrishna Gudipati 
3048a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, rport->pwwn);
3049a36c61f9SKrishna Gudipati 
3050a36c61f9SKrishna Gudipati 	fcxp = fcxp_alloced ? fcxp_alloced : bfa_fcs_fcxp_alloc(port->fcs);
3051a36c61f9SKrishna Gudipati 	if (!fcxp) {
3052a36c61f9SKrishna Gudipati 		bfa_fcs_fcxp_alloc_wait(port->fcs->bfa, &rpf->fcxp_wqe,
3053a36c61f9SKrishna Gudipati 					bfa_fcs_rpf_send_rpsc2, rpf);
3054a36c61f9SKrishna Gudipati 		return;
3055a36c61f9SKrishna Gudipati 	}
3056a36c61f9SKrishna Gudipati 	rpf->fcxp = fcxp;
3057a36c61f9SKrishna Gudipati 
3058a36c61f9SKrishna Gudipati 	len = fc_rpsc2_build(&fchs, bfa_fcxp_get_reqbuf(fcxp), rport->pid,
3059a36c61f9SKrishna Gudipati 			    bfa_fcs_lport_get_fcid(port), &rport->pid, 1);
3060a36c61f9SKrishna Gudipati 
3061a36c61f9SKrishna Gudipati 	bfa_fcxp_send(fcxp, NULL, port->fabric->vf_id, port->lp_tag, BFA_FALSE,
3062a36c61f9SKrishna Gudipati 			  FC_CLASS_3, len, &fchs, bfa_fcs_rpf_rpsc2_response,
3063a36c61f9SKrishna Gudipati 			  rpf, FC_MAX_PDUSZ, FC_ELS_TOV);
3064a36c61f9SKrishna Gudipati 	rport->stats.rpsc_sent++;
3065a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rpf, RPFSM_EVENT_FCXP_SENT);
3066a36c61f9SKrishna Gudipati 
3067a36c61f9SKrishna Gudipati }
3068a36c61f9SKrishna Gudipati 
3069a36c61f9SKrishna Gudipati static void
3070a36c61f9SKrishna Gudipati bfa_fcs_rpf_rpsc2_response(void *fcsarg, struct bfa_fcxp_s *fcxp, void *cbarg,
3071a36c61f9SKrishna Gudipati 			    bfa_status_t req_status, u32 rsp_len,
3072a36c61f9SKrishna Gudipati 			    u32 resid_len, struct fchs_s *rsp_fchs)
3073a36c61f9SKrishna Gudipati {
3074a36c61f9SKrishna Gudipati 	struct bfa_fcs_rpf_s *rpf = (struct bfa_fcs_rpf_s *) cbarg;
3075a36c61f9SKrishna Gudipati 	struct bfa_fcs_rport_s *rport = rpf->rport;
3076a36c61f9SKrishna Gudipati 	struct fc_ls_rjt_s *ls_rjt;
3077a36c61f9SKrishna Gudipati 	struct fc_rpsc2_acc_s *rpsc2_acc;
3078a36c61f9SKrishna Gudipati 	u16	num_ents;
3079a36c61f9SKrishna Gudipati 
3080a36c61f9SKrishna Gudipati 	bfa_trc(rport->fcs, req_status);
3081a36c61f9SKrishna Gudipati 
3082a36c61f9SKrishna Gudipati 	if (req_status != BFA_STATUS_OK) {
3083a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, req_status);
3084a36c61f9SKrishna Gudipati 		if (req_status == BFA_STATUS_ETIMER)
3085a36c61f9SKrishna Gudipati 			rport->stats.rpsc_failed++;
3086a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3087a36c61f9SKrishna Gudipati 		return;
3088a36c61f9SKrishna Gudipati 	}
3089a36c61f9SKrishna Gudipati 
3090a36c61f9SKrishna Gudipati 	rpsc2_acc = (struct fc_rpsc2_acc_s *) BFA_FCXP_RSP_PLD(fcxp);
3091a36c61f9SKrishna Gudipati 	if (rpsc2_acc->els_cmd == FC_ELS_ACC) {
3092a36c61f9SKrishna Gudipati 		rport->stats.rpsc_accs++;
3093ba816ea8SJing Huang 		num_ents = be16_to_cpu(rpsc2_acc->num_pids);
3094a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, num_ents);
3095a36c61f9SKrishna Gudipati 		if (num_ents > 0) {
3096a36c61f9SKrishna Gudipati 			bfa_assert(rpsc2_acc->port_info[0].pid != rport->pid);
3097a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs,
3098ba816ea8SJing Huang 				be16_to_cpu(rpsc2_acc->port_info[0].pid));
3099a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs,
3100ba816ea8SJing Huang 				be16_to_cpu(rpsc2_acc->port_info[0].speed));
3101a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs,
3102ba816ea8SJing Huang 				be16_to_cpu(rpsc2_acc->port_info[0].index));
3103a36c61f9SKrishna Gudipati 			bfa_trc(rport->fcs,
3104a36c61f9SKrishna Gudipati 				rpsc2_acc->port_info[0].type);
3105a36c61f9SKrishna Gudipati 
3106a36c61f9SKrishna Gudipati 			if (rpsc2_acc->port_info[0].speed == 0) {
3107a36c61f9SKrishna Gudipati 				bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3108a36c61f9SKrishna Gudipati 				return;
3109a36c61f9SKrishna Gudipati 			}
3110a36c61f9SKrishna Gudipati 
3111a36c61f9SKrishna Gudipati 			rpf->rpsc_speed = fc_rpsc_operspeed_to_bfa_speed(
3112ba816ea8SJing Huang 				be16_to_cpu(rpsc2_acc->port_info[0].speed));
3113a36c61f9SKrishna Gudipati 
3114a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_COMP);
3115a36c61f9SKrishna Gudipati 		}
3116a36c61f9SKrishna Gudipati 	} else {
3117a36c61f9SKrishna Gudipati 		ls_rjt = (struct fc_ls_rjt_s *) BFA_FCXP_RSP_PLD(fcxp);
3118a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, ls_rjt->reason_code);
3119a36c61f9SKrishna Gudipati 		bfa_trc(rport->fcs, ls_rjt->reason_code_expl);
3120a36c61f9SKrishna Gudipati 		rport->stats.rpsc_rejects++;
3121a36c61f9SKrishna Gudipati 		if (ls_rjt->reason_code == FC_LS_RJT_RSN_CMD_NOT_SUPP)
3122a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_FAIL);
3123a36c61f9SKrishna Gudipati 		else
3124a36c61f9SKrishna Gudipati 			bfa_sm_send_event(rpf, RPFSM_EVENT_RPSC_ERROR);
3125a36c61f9SKrishna Gudipati 	}
3126a36c61f9SKrishna Gudipati }
3127