xref: /openbmc/linux/drivers/scsi/bfa/bfa_svc.c (revision bd5a0260)
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 
18f16a1750SMaggie Zhang #include "bfad_drv.h"
197826f304SKrishna Gudipati #include "bfad_im.h"
20a36c61f9SKrishna Gudipati #include "bfa_plog.h"
21a36c61f9SKrishna Gudipati #include "bfa_cs.h"
22a36c61f9SKrishna Gudipati #include "bfa_modules.h"
23a36c61f9SKrishna Gudipati 
24a36c61f9SKrishna Gudipati BFA_TRC_FILE(HAL, FCXP);
253d7fc66dSKrishna Gudipati BFA_MODULE(fcdiag);
26a36c61f9SKrishna Gudipati BFA_MODULE(fcxp);
27a36c61f9SKrishna Gudipati BFA_MODULE(sgpg);
28a36c61f9SKrishna Gudipati BFA_MODULE(lps);
29a36c61f9SKrishna Gudipati BFA_MODULE(fcport);
30a36c61f9SKrishna Gudipati BFA_MODULE(rport);
31a36c61f9SKrishna Gudipati BFA_MODULE(uf);
32a36c61f9SKrishna Gudipati 
335fbe25c7SJing Huang /*
34a36c61f9SKrishna Gudipati  * LPS related definitions
35a36c61f9SKrishna Gudipati  */
36a36c61f9SKrishna Gudipati #define BFA_LPS_MIN_LPORTS      (1)
37a36c61f9SKrishna Gudipati #define BFA_LPS_MAX_LPORTS      (256)
38a36c61f9SKrishna Gudipati 
39a36c61f9SKrishna Gudipati /*
40a36c61f9SKrishna Gudipati  * Maximum Vports supported per physical port or vf.
41a36c61f9SKrishna Gudipati  */
42a36c61f9SKrishna Gudipati #define BFA_LPS_MAX_VPORTS_SUPP_CB  255
43a36c61f9SKrishna Gudipati #define BFA_LPS_MAX_VPORTS_SUPP_CT  190
44a36c61f9SKrishna Gudipati 
45a36c61f9SKrishna Gudipati 
465fbe25c7SJing Huang /*
47a36c61f9SKrishna Gudipati  * FC PORT related definitions
48a36c61f9SKrishna Gudipati  */
49a36c61f9SKrishna Gudipati /*
50a36c61f9SKrishna Gudipati  * The port is considered disabled if corresponding physical port or IOC are
51a36c61f9SKrishna Gudipati  * disabled explicitly
52a36c61f9SKrishna Gudipati  */
53a36c61f9SKrishna Gudipati #define BFA_PORT_IS_DISABLED(bfa) \
54a36c61f9SKrishna Gudipati 	((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \
55a36c61f9SKrishna Gudipati 	(bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
56a36c61f9SKrishna Gudipati 
575fbe25c7SJing Huang /*
58a36c61f9SKrishna Gudipati  * BFA port state machine events
59a36c61f9SKrishna Gudipati  */
60a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event {
61a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_START	= 1,	/*  start port state machine	*/
62a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_STOP	= 2,	/*  stop port state machine	*/
63a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_ENABLE	= 3,	/*  enable port		*/
64a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_DISABLE	= 4,	/*  disable port state machine */
65a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_FWRSP	= 5,	/*  firmware enable/disable rsp */
66a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_LINKUP	= 6,	/*  firmware linkup event	*/
67a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_LINKDOWN	= 7,	/*  firmware linkup down	*/
68a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_QRESUME	= 8,	/*  CQ space available	*/
69a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_HWFAIL	= 9,	/*  IOC h/w failure		*/
70a36c61f9SKrishna Gudipati };
71a36c61f9SKrishna Gudipati 
725fbe25c7SJing Huang /*
73a36c61f9SKrishna Gudipati  * BFA port link notification state machine events
74a36c61f9SKrishna Gudipati  */
75a36c61f9SKrishna Gudipati 
76a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event {
77a36c61f9SKrishna Gudipati 	BFA_FCPORT_LN_SM_LINKUP		= 1,	/*  linkup event	*/
78a36c61f9SKrishna Gudipati 	BFA_FCPORT_LN_SM_LINKDOWN	= 2,	/*  linkdown event	*/
79a36c61f9SKrishna Gudipati 	BFA_FCPORT_LN_SM_NOTIFICATION	= 3	/*  done notification	*/
80a36c61f9SKrishna Gudipati };
81a36c61f9SKrishna Gudipati 
825fbe25c7SJing Huang /*
83a36c61f9SKrishna Gudipati  * RPORT related definitions
84a36c61f9SKrishna Gudipati  */
85a36c61f9SKrishna Gudipati #define bfa_rport_offline_cb(__rp) do {					\
86a36c61f9SKrishna Gudipati 	if ((__rp)->bfa->fcs)						\
87a36c61f9SKrishna Gudipati 		bfa_cb_rport_offline((__rp)->rport_drv);      \
88a36c61f9SKrishna Gudipati 	else {								\
89a36c61f9SKrishna Gudipati 		bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe,		\
90a36c61f9SKrishna Gudipati 				__bfa_cb_rport_offline, (__rp));      \
91a36c61f9SKrishna Gudipati 	}								\
92a36c61f9SKrishna Gudipati } while (0)
93a36c61f9SKrishna Gudipati 
94a36c61f9SKrishna Gudipati #define bfa_rport_online_cb(__rp) do {					\
95a36c61f9SKrishna Gudipati 	if ((__rp)->bfa->fcs)						\
96a36c61f9SKrishna Gudipati 		bfa_cb_rport_online((__rp)->rport_drv);      \
97a36c61f9SKrishna Gudipati 	else {								\
98a36c61f9SKrishna Gudipati 		bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe,		\
99a36c61f9SKrishna Gudipati 				  __bfa_cb_rport_online, (__rp));      \
100a36c61f9SKrishna Gudipati 		}							\
101a36c61f9SKrishna Gudipati } while (0)
102a36c61f9SKrishna Gudipati 
1035fbe25c7SJing Huang /*
104a36c61f9SKrishna Gudipati  * forward declarations FCXP related functions
105a36c61f9SKrishna Gudipati  */
106a36c61f9SKrishna Gudipati static void	__bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete);
107a36c61f9SKrishna Gudipati static void	hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp,
108a36c61f9SKrishna Gudipati 				struct bfi_fcxp_send_rsp_s *fcxp_rsp);
109a36c61f9SKrishna Gudipati static void	hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen,
110a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp, struct fchs_s *fchs);
111a36c61f9SKrishna Gudipati static void	bfa_fcxp_qresume(void *cbarg);
112a36c61f9SKrishna Gudipati static void	bfa_fcxp_queue(struct bfa_fcxp_s *fcxp,
113a36c61f9SKrishna Gudipati 				struct bfi_fcxp_send_req_s *send_req);
114a36c61f9SKrishna Gudipati 
1155fbe25c7SJing Huang /*
116a36c61f9SKrishna Gudipati  * forward declarations for LPS functions
117a36c61f9SKrishna Gudipati  */
1184507025dSKrishna Gudipati static void bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg,
1194507025dSKrishna Gudipati 		struct bfa_meminfo_s *minfo, struct bfa_s *bfa);
120a36c61f9SKrishna Gudipati static void bfa_lps_attach(struct bfa_s *bfa, void *bfad,
121a36c61f9SKrishna Gudipati 				struct bfa_iocfc_cfg_s *cfg,
122a36c61f9SKrishna Gudipati 				struct bfa_pcidev_s *pcidev);
123a36c61f9SKrishna Gudipati static void bfa_lps_detach(struct bfa_s *bfa);
124a36c61f9SKrishna Gudipati static void bfa_lps_start(struct bfa_s *bfa);
125a36c61f9SKrishna Gudipati static void bfa_lps_stop(struct bfa_s *bfa);
126a36c61f9SKrishna Gudipati static void bfa_lps_iocdisable(struct bfa_s *bfa);
127a36c61f9SKrishna Gudipati static void bfa_lps_login_rsp(struct bfa_s *bfa,
128a36c61f9SKrishna Gudipati 				struct bfi_lps_login_rsp_s *rsp);
1293fd45980SKrishna Gudipati static void bfa_lps_no_res(struct bfa_lps_s *first_lps, u8 count);
130a36c61f9SKrishna Gudipati static void bfa_lps_logout_rsp(struct bfa_s *bfa,
131a36c61f9SKrishna Gudipati 				struct bfi_lps_logout_rsp_s *rsp);
132a36c61f9SKrishna Gudipati static void bfa_lps_reqq_resume(void *lps_arg);
133a36c61f9SKrishna Gudipati static void bfa_lps_free(struct bfa_lps_s *lps);
134a36c61f9SKrishna Gudipati static void bfa_lps_send_login(struct bfa_lps_s *lps);
135a36c61f9SKrishna Gudipati static void bfa_lps_send_logout(struct bfa_lps_s *lps);
136b704495cSKrishna Gudipati static void bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps);
137a36c61f9SKrishna Gudipati static void bfa_lps_login_comp(struct bfa_lps_s *lps);
138a36c61f9SKrishna Gudipati static void bfa_lps_logout_comp(struct bfa_lps_s *lps);
139a36c61f9SKrishna Gudipati static void bfa_lps_cvl_event(struct bfa_lps_s *lps);
140a36c61f9SKrishna Gudipati 
1415fbe25c7SJing Huang /*
142a36c61f9SKrishna Gudipati  * forward declaration for LPS state machine
143a36c61f9SKrishna Gudipati  */
144a36c61f9SKrishna Gudipati static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event);
145a36c61f9SKrishna Gudipati static void bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event);
146a36c61f9SKrishna Gudipati static void bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event
147a36c61f9SKrishna Gudipati 					event);
148a36c61f9SKrishna Gudipati static void bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event);
149b704495cSKrishna Gudipati static void bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps,
150b704495cSKrishna Gudipati 					enum bfa_lps_event event);
151a36c61f9SKrishna Gudipati static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event);
152a36c61f9SKrishna Gudipati static void bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event
153a36c61f9SKrishna Gudipati 					event);
154a36c61f9SKrishna Gudipati 
1555fbe25c7SJing Huang /*
156a36c61f9SKrishna Gudipati  * forward declaration for FC Port functions
157a36c61f9SKrishna Gudipati  */
158a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport);
159a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_fcport_send_disable(struct bfa_fcport_s *fcport);
160a36c61f9SKrishna Gudipati static void bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport);
161a36c61f9SKrishna Gudipati static void bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport);
162a36c61f9SKrishna Gudipati static void bfa_fcport_set_wwns(struct bfa_fcport_s *fcport);
163a36c61f9SKrishna Gudipati static void __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete);
164a36c61f9SKrishna Gudipati static void bfa_fcport_scn(struct bfa_fcport_s *fcport,
165a36c61f9SKrishna Gudipati 			enum bfa_port_linkstate event, bfa_boolean_t trunk);
166a36c61f9SKrishna Gudipati static void bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln,
167a36c61f9SKrishna Gudipati 				enum bfa_port_linkstate event);
168a36c61f9SKrishna Gudipati static void __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete);
169a36c61f9SKrishna Gudipati static void bfa_fcport_stats_get_timeout(void *cbarg);
170a36c61f9SKrishna Gudipati static void bfa_fcport_stats_clr_timeout(void *cbarg);
171a36c61f9SKrishna Gudipati static void bfa_trunk_iocdisable(struct bfa_s *bfa);
172a36c61f9SKrishna Gudipati 
1735fbe25c7SJing Huang /*
174a36c61f9SKrishna Gudipati  * forward declaration for FC PORT state machine
175a36c61f9SKrishna Gudipati  */
176a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
177a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
178a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
179a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
180a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
181a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
182a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
183a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
184a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
185a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
186a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
187a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
188a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
189a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
190a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_toggling_qwait(struct bfa_fcport_s *fcport,
191a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
192a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
193a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
194a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
195a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
196a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
197a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
198a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
199a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
200a36c61f9SKrishna Gudipati 
201a36c61f9SKrishna Gudipati static void     bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
202a36c61f9SKrishna Gudipati 					enum bfa_fcport_ln_sm_event event);
203a36c61f9SKrishna Gudipati static void     bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
204a36c61f9SKrishna Gudipati 					enum bfa_fcport_ln_sm_event event);
205a36c61f9SKrishna Gudipati static void     bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
206a36c61f9SKrishna Gudipati 					enum bfa_fcport_ln_sm_event event);
207a36c61f9SKrishna Gudipati static void     bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
208a36c61f9SKrishna Gudipati 					enum bfa_fcport_ln_sm_event event);
209a36c61f9SKrishna Gudipati static void     bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
210a36c61f9SKrishna Gudipati 					enum bfa_fcport_ln_sm_event event);
211a36c61f9SKrishna Gudipati static void     bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
212a36c61f9SKrishna Gudipati 					enum bfa_fcport_ln_sm_event event);
213a36c61f9SKrishna Gudipati static void     bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
214a36c61f9SKrishna Gudipati 					enum bfa_fcport_ln_sm_event event);
215a36c61f9SKrishna Gudipati 
216a36c61f9SKrishna Gudipati static struct bfa_sm_table_s hal_port_sm_table[] = {
217a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_uninit), BFA_PORT_ST_UNINIT},
218a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_enabling_qwait), BFA_PORT_ST_ENABLING_QWAIT},
219a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_enabling), BFA_PORT_ST_ENABLING},
220a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_linkdown), BFA_PORT_ST_LINKDOWN},
221a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_linkup), BFA_PORT_ST_LINKUP},
222a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_disabling_qwait), BFA_PORT_ST_DISABLING_QWAIT},
223a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_toggling_qwait), BFA_PORT_ST_TOGGLING_QWAIT},
224a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_disabling), BFA_PORT_ST_DISABLING},
225a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_disabled), BFA_PORT_ST_DISABLED},
226a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_stopped), BFA_PORT_ST_STOPPED},
227a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN},
228a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN},
229a36c61f9SKrishna Gudipati };
230a36c61f9SKrishna Gudipati 
231a36c61f9SKrishna Gudipati 
2325fbe25c7SJing Huang /*
233a36c61f9SKrishna Gudipati  * forward declaration for RPORT related functions
234a36c61f9SKrishna Gudipati  */
235a36c61f9SKrishna Gudipati static struct bfa_rport_s *bfa_rport_alloc(struct bfa_rport_mod_s *rp_mod);
236a36c61f9SKrishna Gudipati static void		bfa_rport_free(struct bfa_rport_s *rport);
237a36c61f9SKrishna Gudipati static bfa_boolean_t	bfa_rport_send_fwcreate(struct bfa_rport_s *rp);
238a36c61f9SKrishna Gudipati static bfa_boolean_t	bfa_rport_send_fwdelete(struct bfa_rport_s *rp);
239a36c61f9SKrishna Gudipati static bfa_boolean_t	bfa_rport_send_fwspeed(struct bfa_rport_s *rp);
240a36c61f9SKrishna Gudipati static void		__bfa_cb_rport_online(void *cbarg,
241a36c61f9SKrishna Gudipati 						bfa_boolean_t complete);
242a36c61f9SKrishna Gudipati static void		__bfa_cb_rport_offline(void *cbarg,
243a36c61f9SKrishna Gudipati 						bfa_boolean_t complete);
244a36c61f9SKrishna Gudipati 
2455fbe25c7SJing Huang /*
246a36c61f9SKrishna Gudipati  * forward declaration for RPORT state machine
247a36c61f9SKrishna Gudipati  */
248a36c61f9SKrishna Gudipati static void     bfa_rport_sm_uninit(struct bfa_rport_s *rp,
249a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
250a36c61f9SKrishna Gudipati static void     bfa_rport_sm_created(struct bfa_rport_s *rp,
251a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
252a36c61f9SKrishna Gudipati static void     bfa_rport_sm_fwcreate(struct bfa_rport_s *rp,
253a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
254a36c61f9SKrishna Gudipati static void     bfa_rport_sm_online(struct bfa_rport_s *rp,
255a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
256a36c61f9SKrishna Gudipati static void     bfa_rport_sm_fwdelete(struct bfa_rport_s *rp,
257a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
258a36c61f9SKrishna Gudipati static void     bfa_rport_sm_offline(struct bfa_rport_s *rp,
259a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
260a36c61f9SKrishna Gudipati static void     bfa_rport_sm_deleting(struct bfa_rport_s *rp,
261a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
262a36c61f9SKrishna Gudipati static void     bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
263a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
264a36c61f9SKrishna Gudipati static void     bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
265a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
266a36c61f9SKrishna Gudipati static void     bfa_rport_sm_iocdisable(struct bfa_rport_s *rp,
267a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
268a36c61f9SKrishna Gudipati static void     bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp,
269a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
270a36c61f9SKrishna Gudipati static void     bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp,
271a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
272a36c61f9SKrishna Gudipati static void     bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp,
273a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
274a36c61f9SKrishna Gudipati 
2755fbe25c7SJing Huang /*
276a36c61f9SKrishna Gudipati  * PLOG related definitions
277a36c61f9SKrishna Gudipati  */
278a36c61f9SKrishna Gudipati static int
279a36c61f9SKrishna Gudipati plkd_validate_logrec(struct bfa_plog_rec_s *pl_rec)
280a36c61f9SKrishna Gudipati {
281a36c61f9SKrishna Gudipati 	if ((pl_rec->log_type != BFA_PL_LOG_TYPE_INT) &&
282a36c61f9SKrishna Gudipati 		(pl_rec->log_type != BFA_PL_LOG_TYPE_STRING))
283a36c61f9SKrishna Gudipati 		return 1;
284a36c61f9SKrishna Gudipati 
285a36c61f9SKrishna Gudipati 	if ((pl_rec->log_type != BFA_PL_LOG_TYPE_INT) &&
286a36c61f9SKrishna Gudipati 		(pl_rec->log_num_ints > BFA_PL_INT_LOG_SZ))
287a36c61f9SKrishna Gudipati 		return 1;
288a36c61f9SKrishna Gudipati 
289a36c61f9SKrishna Gudipati 	return 0;
290a36c61f9SKrishna Gudipati }
291a36c61f9SKrishna Gudipati 
292f16a1750SMaggie Zhang static u64
293f16a1750SMaggie Zhang bfa_get_log_time(void)
294f16a1750SMaggie Zhang {
295f16a1750SMaggie Zhang 	u64 system_time = 0;
296f16a1750SMaggie Zhang 	struct timeval tv;
297f16a1750SMaggie Zhang 	do_gettimeofday(&tv);
298f16a1750SMaggie Zhang 
299f16a1750SMaggie Zhang 	/* We are interested in seconds only. */
300f16a1750SMaggie Zhang 	system_time = tv.tv_sec;
301f16a1750SMaggie Zhang 	return system_time;
302f16a1750SMaggie Zhang }
303f16a1750SMaggie Zhang 
304a36c61f9SKrishna Gudipati static void
305a36c61f9SKrishna Gudipati bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec)
306a36c61f9SKrishna Gudipati {
307a36c61f9SKrishna Gudipati 	u16 tail;
308a36c61f9SKrishna Gudipati 	struct bfa_plog_rec_s *pl_recp;
309a36c61f9SKrishna Gudipati 
310a36c61f9SKrishna Gudipati 	if (plog->plog_enabled == 0)
311a36c61f9SKrishna Gudipati 		return;
312a36c61f9SKrishna Gudipati 
313a36c61f9SKrishna Gudipati 	if (plkd_validate_logrec(pl_rec)) {
314d4b671c5SJing Huang 		WARN_ON(1);
315a36c61f9SKrishna Gudipati 		return;
316a36c61f9SKrishna Gudipati 	}
317a36c61f9SKrishna Gudipati 
318a36c61f9SKrishna Gudipati 	tail = plog->tail;
319a36c61f9SKrishna Gudipati 
320a36c61f9SKrishna Gudipati 	pl_recp = &(plog->plog_recs[tail]);
321a36c61f9SKrishna Gudipati 
3226a18b167SJing Huang 	memcpy(pl_recp, pl_rec, sizeof(struct bfa_plog_rec_s));
323a36c61f9SKrishna Gudipati 
324f16a1750SMaggie Zhang 	pl_recp->tv = bfa_get_log_time();
325a36c61f9SKrishna Gudipati 	BFA_PL_LOG_REC_INCR(plog->tail);
326a36c61f9SKrishna Gudipati 
327a36c61f9SKrishna Gudipati 	if (plog->head == plog->tail)
328a36c61f9SKrishna Gudipati 		BFA_PL_LOG_REC_INCR(plog->head);
329a36c61f9SKrishna Gudipati }
330a36c61f9SKrishna Gudipati 
331a36c61f9SKrishna Gudipati void
332a36c61f9SKrishna Gudipati bfa_plog_init(struct bfa_plog_s *plog)
333a36c61f9SKrishna Gudipati {
3346a18b167SJing Huang 	memset((char *)plog, 0, sizeof(struct bfa_plog_s));
335a36c61f9SKrishna Gudipati 
3366a18b167SJing Huang 	memcpy(plog->plog_sig, BFA_PL_SIG_STR, BFA_PL_SIG_LEN);
337a36c61f9SKrishna Gudipati 	plog->head = plog->tail = 0;
338a36c61f9SKrishna Gudipati 	plog->plog_enabled = 1;
339a36c61f9SKrishna Gudipati }
340a36c61f9SKrishna Gudipati 
341a36c61f9SKrishna Gudipati void
342a36c61f9SKrishna Gudipati bfa_plog_str(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
343a36c61f9SKrishna Gudipati 		enum bfa_plog_eid event,
344a36c61f9SKrishna Gudipati 		u16 misc, char *log_str)
345a36c61f9SKrishna Gudipati {
346a36c61f9SKrishna Gudipati 	struct bfa_plog_rec_s  lp;
347a36c61f9SKrishna Gudipati 
348a36c61f9SKrishna Gudipati 	if (plog->plog_enabled) {
3496a18b167SJing Huang 		memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
350a36c61f9SKrishna Gudipati 		lp.mid = mid;
351a36c61f9SKrishna Gudipati 		lp.eid = event;
352a36c61f9SKrishna Gudipati 		lp.log_type = BFA_PL_LOG_TYPE_STRING;
353a36c61f9SKrishna Gudipati 		lp.misc = misc;
354a36c61f9SKrishna Gudipati 		strncpy(lp.log_entry.string_log, log_str,
355a36c61f9SKrishna Gudipati 			BFA_PL_STRING_LOG_SZ - 1);
356a36c61f9SKrishna Gudipati 		lp.log_entry.string_log[BFA_PL_STRING_LOG_SZ - 1] = '\0';
357a36c61f9SKrishna Gudipati 		bfa_plog_add(plog, &lp);
358a36c61f9SKrishna Gudipati 	}
359a36c61f9SKrishna Gudipati }
360a36c61f9SKrishna Gudipati 
361a36c61f9SKrishna Gudipati void
362a36c61f9SKrishna Gudipati bfa_plog_intarr(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
363a36c61f9SKrishna Gudipati 		enum bfa_plog_eid event,
364a36c61f9SKrishna Gudipati 		u16 misc, u32 *intarr, u32 num_ints)
365a36c61f9SKrishna Gudipati {
366a36c61f9SKrishna Gudipati 	struct bfa_plog_rec_s  lp;
367a36c61f9SKrishna Gudipati 	u32 i;
368a36c61f9SKrishna Gudipati 
369a36c61f9SKrishna Gudipati 	if (num_ints > BFA_PL_INT_LOG_SZ)
370a36c61f9SKrishna Gudipati 		num_ints = BFA_PL_INT_LOG_SZ;
371a36c61f9SKrishna Gudipati 
372a36c61f9SKrishna Gudipati 	if (plog->plog_enabled) {
3736a18b167SJing Huang 		memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
374a36c61f9SKrishna Gudipati 		lp.mid = mid;
375a36c61f9SKrishna Gudipati 		lp.eid = event;
376a36c61f9SKrishna Gudipati 		lp.log_type = BFA_PL_LOG_TYPE_INT;
377a36c61f9SKrishna Gudipati 		lp.misc = misc;
378a36c61f9SKrishna Gudipati 
379a36c61f9SKrishna Gudipati 		for (i = 0; i < num_ints; i++)
3806a18b167SJing Huang 			lp.log_entry.int_log[i] = intarr[i];
381a36c61f9SKrishna Gudipati 
382a36c61f9SKrishna Gudipati 		lp.log_num_ints = (u8) num_ints;
383a36c61f9SKrishna Gudipati 
384a36c61f9SKrishna Gudipati 		bfa_plog_add(plog, &lp);
385a36c61f9SKrishna Gudipati 	}
386a36c61f9SKrishna Gudipati }
387a36c61f9SKrishna Gudipati 
388a36c61f9SKrishna Gudipati void
389a36c61f9SKrishna Gudipati bfa_plog_fchdr(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
390a36c61f9SKrishna Gudipati 			enum bfa_plog_eid event,
391a36c61f9SKrishna Gudipati 			u16 misc, struct fchs_s *fchdr)
392a36c61f9SKrishna Gudipati {
393a36c61f9SKrishna Gudipati 	struct bfa_plog_rec_s  lp;
394a36c61f9SKrishna Gudipati 	u32	*tmp_int = (u32 *) fchdr;
395a36c61f9SKrishna Gudipati 	u32	ints[BFA_PL_INT_LOG_SZ];
396a36c61f9SKrishna Gudipati 
397a36c61f9SKrishna Gudipati 	if (plog->plog_enabled) {
3986a18b167SJing Huang 		memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
399a36c61f9SKrishna Gudipati 
400a36c61f9SKrishna Gudipati 		ints[0] = tmp_int[0];
401a36c61f9SKrishna Gudipati 		ints[1] = tmp_int[1];
402a36c61f9SKrishna Gudipati 		ints[2] = tmp_int[4];
403a36c61f9SKrishna Gudipati 
404a36c61f9SKrishna Gudipati 		bfa_plog_intarr(plog, mid, event, misc, ints, 3);
405a36c61f9SKrishna Gudipati 	}
406a36c61f9SKrishna Gudipati }
407a36c61f9SKrishna Gudipati 
408a36c61f9SKrishna Gudipati void
409a36c61f9SKrishna Gudipati bfa_plog_fchdr_and_pl(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
410a36c61f9SKrishna Gudipati 		      enum bfa_plog_eid event, u16 misc, struct fchs_s *fchdr,
411a36c61f9SKrishna Gudipati 		      u32 pld_w0)
412a36c61f9SKrishna Gudipati {
413a36c61f9SKrishna Gudipati 	struct bfa_plog_rec_s  lp;
414a36c61f9SKrishna Gudipati 	u32	*tmp_int = (u32 *) fchdr;
415a36c61f9SKrishna Gudipati 	u32	ints[BFA_PL_INT_LOG_SZ];
416a36c61f9SKrishna Gudipati 
417a36c61f9SKrishna Gudipati 	if (plog->plog_enabled) {
4186a18b167SJing Huang 		memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
419a36c61f9SKrishna Gudipati 
420a36c61f9SKrishna Gudipati 		ints[0] = tmp_int[0];
421a36c61f9SKrishna Gudipati 		ints[1] = tmp_int[1];
422a36c61f9SKrishna Gudipati 		ints[2] = tmp_int[4];
423a36c61f9SKrishna Gudipati 		ints[3] = pld_w0;
424a36c61f9SKrishna Gudipati 
425a36c61f9SKrishna Gudipati 		bfa_plog_intarr(plog, mid, event, misc, ints, 4);
426a36c61f9SKrishna Gudipati 	}
427a36c61f9SKrishna Gudipati }
428a36c61f9SKrishna Gudipati 
429a36c61f9SKrishna Gudipati 
4305fbe25c7SJing Huang /*
431a36c61f9SKrishna Gudipati  *  fcxp_pvt BFA FCXP private functions
432a36c61f9SKrishna Gudipati  */
433a36c61f9SKrishna Gudipati 
434a36c61f9SKrishna Gudipati static void
4354507025dSKrishna Gudipati claim_fcxps_mem(struct bfa_fcxp_mod_s *mod)
436a36c61f9SKrishna Gudipati {
437a36c61f9SKrishna Gudipati 	u16	i;
438a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
439a36c61f9SKrishna Gudipati 
4404507025dSKrishna Gudipati 	fcxp = (struct bfa_fcxp_s *) bfa_mem_kva_curp(mod);
4416a18b167SJing Huang 	memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps);
442a36c61f9SKrishna Gudipati 
443a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->fcxp_free_q);
444a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->fcxp_active_q);
4453fd45980SKrishna Gudipati 	INIT_LIST_HEAD(&mod->fcxp_unused_q);
446a36c61f9SKrishna Gudipati 
447a36c61f9SKrishna Gudipati 	mod->fcxp_list = fcxp;
448a36c61f9SKrishna Gudipati 
449a36c61f9SKrishna Gudipati 	for (i = 0; i < mod->num_fcxps; i++) {
450a36c61f9SKrishna Gudipati 		fcxp->fcxp_mod = mod;
451a36c61f9SKrishna Gudipati 		fcxp->fcxp_tag = i;
452a36c61f9SKrishna Gudipati 
453a36c61f9SKrishna Gudipati 		list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
454a36c61f9SKrishna Gudipati 		bfa_reqq_winit(&fcxp->reqq_wqe, bfa_fcxp_qresume, fcxp);
455a36c61f9SKrishna Gudipati 		fcxp->reqq_waiting = BFA_FALSE;
456a36c61f9SKrishna Gudipati 
457a36c61f9SKrishna Gudipati 		fcxp = fcxp + 1;
458a36c61f9SKrishna Gudipati 	}
459a36c61f9SKrishna Gudipati 
4604507025dSKrishna Gudipati 	bfa_mem_kva_curp(mod) = (void *)fcxp;
461a36c61f9SKrishna Gudipati }
462a36c61f9SKrishna Gudipati 
463a36c61f9SKrishna Gudipati static void
4644507025dSKrishna Gudipati bfa_fcxp_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo,
4654507025dSKrishna Gudipati 		struct bfa_s *bfa)
466a36c61f9SKrishna Gudipati {
4674507025dSKrishna Gudipati 	struct bfa_fcxp_mod_s *fcxp_mod = BFA_FCXP_MOD(bfa);
4684507025dSKrishna Gudipati 	struct bfa_mem_kva_s *fcxp_kva = BFA_MEM_FCXP_KVA(bfa);
4694507025dSKrishna Gudipati 	struct bfa_mem_dma_s *seg_ptr;
4704507025dSKrishna Gudipati 	u16	nsegs, idx, per_seg_fcxp;
4714507025dSKrishna Gudipati 	u16	num_fcxps = cfg->fwcfg.num_fcxp_reqs;
4724507025dSKrishna Gudipati 	u32	per_fcxp_sz;
473a36c61f9SKrishna Gudipati 
4744507025dSKrishna Gudipati 	if (num_fcxps == 0)
475a36c61f9SKrishna Gudipati 		return;
476a36c61f9SKrishna Gudipati 
477a36c61f9SKrishna Gudipati 	if (cfg->drvcfg.min_cfg)
4784507025dSKrishna Gudipati 		per_fcxp_sz = 2 * BFA_FCXP_MAX_IBUF_SZ;
479a36c61f9SKrishna Gudipati 	else
4804507025dSKrishna Gudipati 		per_fcxp_sz = BFA_FCXP_MAX_IBUF_SZ + BFA_FCXP_MAX_LBUF_SZ;
481a36c61f9SKrishna Gudipati 
4824507025dSKrishna Gudipati 	/* dma memory */
4834507025dSKrishna Gudipati 	nsegs = BFI_MEM_DMA_NSEGS(num_fcxps, per_fcxp_sz);
4844507025dSKrishna Gudipati 	per_seg_fcxp = BFI_MEM_NREQS_SEG(per_fcxp_sz);
4854507025dSKrishna Gudipati 
4864507025dSKrishna Gudipati 	bfa_mem_dma_seg_iter(fcxp_mod, seg_ptr, nsegs, idx) {
4874507025dSKrishna Gudipati 		if (num_fcxps >= per_seg_fcxp) {
4884507025dSKrishna Gudipati 			num_fcxps -= per_seg_fcxp;
4894507025dSKrishna Gudipati 			bfa_mem_dma_setup(minfo, seg_ptr,
4904507025dSKrishna Gudipati 				per_seg_fcxp * per_fcxp_sz);
4914507025dSKrishna Gudipati 		} else
4924507025dSKrishna Gudipati 			bfa_mem_dma_setup(minfo, seg_ptr,
4934507025dSKrishna Gudipati 				num_fcxps * per_fcxp_sz);
4944507025dSKrishna Gudipati 	}
4954507025dSKrishna Gudipati 
4964507025dSKrishna Gudipati 	/* kva memory */
4974507025dSKrishna Gudipati 	bfa_mem_kva_setup(minfo, fcxp_kva,
4984507025dSKrishna Gudipati 		cfg->fwcfg.num_fcxp_reqs * sizeof(struct bfa_fcxp_s));
499a36c61f9SKrishna Gudipati }
500a36c61f9SKrishna Gudipati 
501a36c61f9SKrishna Gudipati static void
502a36c61f9SKrishna Gudipati bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
5034507025dSKrishna Gudipati 		struct bfa_pcidev_s *pcidev)
504a36c61f9SKrishna Gudipati {
505a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
506a36c61f9SKrishna Gudipati 
507a36c61f9SKrishna Gudipati 	mod->bfa = bfa;
508a36c61f9SKrishna Gudipati 	mod->num_fcxps = cfg->fwcfg.num_fcxp_reqs;
509a36c61f9SKrishna Gudipati 
5105fbe25c7SJing Huang 	/*
511a36c61f9SKrishna Gudipati 	 * Initialize FCXP request and response payload sizes.
512a36c61f9SKrishna Gudipati 	 */
513a36c61f9SKrishna Gudipati 	mod->req_pld_sz = mod->rsp_pld_sz = BFA_FCXP_MAX_IBUF_SZ;
514a36c61f9SKrishna Gudipati 	if (!cfg->drvcfg.min_cfg)
515a36c61f9SKrishna Gudipati 		mod->rsp_pld_sz = BFA_FCXP_MAX_LBUF_SZ;
516a36c61f9SKrishna Gudipati 
517a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->wait_q);
518a36c61f9SKrishna Gudipati 
5194507025dSKrishna Gudipati 	claim_fcxps_mem(mod);
520a36c61f9SKrishna Gudipati }
521a36c61f9SKrishna Gudipati 
522a36c61f9SKrishna Gudipati static void
523a36c61f9SKrishna Gudipati bfa_fcxp_detach(struct bfa_s *bfa)
524a36c61f9SKrishna Gudipati {
525a36c61f9SKrishna Gudipati }
526a36c61f9SKrishna Gudipati 
527a36c61f9SKrishna Gudipati static void
528a36c61f9SKrishna Gudipati bfa_fcxp_start(struct bfa_s *bfa)
529a36c61f9SKrishna Gudipati {
530a36c61f9SKrishna Gudipati }
531a36c61f9SKrishna Gudipati 
532a36c61f9SKrishna Gudipati static void
533a36c61f9SKrishna Gudipati bfa_fcxp_stop(struct bfa_s *bfa)
534a36c61f9SKrishna Gudipati {
535a36c61f9SKrishna Gudipati }
536a36c61f9SKrishna Gudipati 
537a36c61f9SKrishna Gudipati static void
538a36c61f9SKrishna Gudipati bfa_fcxp_iocdisable(struct bfa_s *bfa)
539a36c61f9SKrishna Gudipati {
540a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
541a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
542a36c61f9SKrishna Gudipati 	struct list_head	      *qe, *qen;
543a36c61f9SKrishna Gudipati 
5443fd45980SKrishna Gudipati 	/* Enqueue unused fcxp resources to free_q */
5453fd45980SKrishna Gudipati 	list_splice_tail_init(&mod->fcxp_unused_q, &mod->fcxp_free_q);
5463fd45980SKrishna Gudipati 
547a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &mod->fcxp_active_q) {
548a36c61f9SKrishna Gudipati 		fcxp = (struct bfa_fcxp_s *) qe;
549a36c61f9SKrishna Gudipati 		if (fcxp->caller == NULL) {
550a36c61f9SKrishna Gudipati 			fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
551a36c61f9SKrishna Gudipati 					BFA_STATUS_IOC_FAILURE, 0, 0, NULL);
552a36c61f9SKrishna Gudipati 			bfa_fcxp_free(fcxp);
553a36c61f9SKrishna Gudipati 		} else {
554a36c61f9SKrishna Gudipati 			fcxp->rsp_status = BFA_STATUS_IOC_FAILURE;
555a36c61f9SKrishna Gudipati 			bfa_cb_queue(bfa, &fcxp->hcb_qe,
556a36c61f9SKrishna Gudipati 				     __bfa_fcxp_send_cbfn, fcxp);
557a36c61f9SKrishna Gudipati 		}
558a36c61f9SKrishna Gudipati 	}
559a36c61f9SKrishna Gudipati }
560a36c61f9SKrishna Gudipati 
561a36c61f9SKrishna Gudipati static struct bfa_fcxp_s *
562a36c61f9SKrishna Gudipati bfa_fcxp_get(struct bfa_fcxp_mod_s *fm)
563a36c61f9SKrishna Gudipati {
564a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
565a36c61f9SKrishna Gudipati 
566a36c61f9SKrishna Gudipati 	bfa_q_deq(&fm->fcxp_free_q, &fcxp);
567a36c61f9SKrishna Gudipati 
568a36c61f9SKrishna Gudipati 	if (fcxp)
569a36c61f9SKrishna Gudipati 		list_add_tail(&fcxp->qe, &fm->fcxp_active_q);
570a36c61f9SKrishna Gudipati 
571a36c61f9SKrishna Gudipati 	return fcxp;
572a36c61f9SKrishna Gudipati }
573a36c61f9SKrishna Gudipati 
574a36c61f9SKrishna Gudipati static void
575a36c61f9SKrishna Gudipati bfa_fcxp_init_reqrsp(struct bfa_fcxp_s *fcxp,
576a36c61f9SKrishna Gudipati 	       struct bfa_s *bfa,
577a36c61f9SKrishna Gudipati 	       u8 *use_ibuf,
578a36c61f9SKrishna Gudipati 	       u32 *nr_sgles,
579a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sgaddr_t *r_sga_cbfn,
580a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sglen_t *r_sglen_cbfn,
581a36c61f9SKrishna Gudipati 	       struct list_head *r_sgpg_q,
582a36c61f9SKrishna Gudipati 	       int n_sgles,
583a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sgaddr_t sga_cbfn,
584a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sglen_t sglen_cbfn)
585a36c61f9SKrishna Gudipati {
586a36c61f9SKrishna Gudipati 
587d4b671c5SJing Huang 	WARN_ON(bfa == NULL);
588a36c61f9SKrishna Gudipati 
589a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcxp->fcxp_tag);
590a36c61f9SKrishna Gudipati 
591a36c61f9SKrishna Gudipati 	if (n_sgles == 0) {
592a36c61f9SKrishna Gudipati 		*use_ibuf = 1;
593a36c61f9SKrishna Gudipati 	} else {
594d4b671c5SJing Huang 		WARN_ON(*sga_cbfn == NULL);
595d4b671c5SJing Huang 		WARN_ON(*sglen_cbfn == NULL);
596a36c61f9SKrishna Gudipati 
597a36c61f9SKrishna Gudipati 		*use_ibuf = 0;
598a36c61f9SKrishna Gudipati 		*r_sga_cbfn = sga_cbfn;
599a36c61f9SKrishna Gudipati 		*r_sglen_cbfn = sglen_cbfn;
600a36c61f9SKrishna Gudipati 
601a36c61f9SKrishna Gudipati 		*nr_sgles = n_sgles;
602a36c61f9SKrishna Gudipati 
603a36c61f9SKrishna Gudipati 		/*
604a36c61f9SKrishna Gudipati 		 * alloc required sgpgs
605a36c61f9SKrishna Gudipati 		 */
606a36c61f9SKrishna Gudipati 		if (n_sgles > BFI_SGE_INLINE)
607d4b671c5SJing Huang 			WARN_ON(1);
608a36c61f9SKrishna Gudipati 	}
609a36c61f9SKrishna Gudipati 
610a36c61f9SKrishna Gudipati }
611a36c61f9SKrishna Gudipati 
612a36c61f9SKrishna Gudipati static void
613a36c61f9SKrishna Gudipati bfa_fcxp_init(struct bfa_fcxp_s *fcxp,
614a36c61f9SKrishna Gudipati 	       void *caller, struct bfa_s *bfa, int nreq_sgles,
615a36c61f9SKrishna Gudipati 	       int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
616a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sglen_t req_sglen_cbfn,
617a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
618a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sglen_t rsp_sglen_cbfn)
619a36c61f9SKrishna Gudipati {
620a36c61f9SKrishna Gudipati 
621d4b671c5SJing Huang 	WARN_ON(bfa == NULL);
622a36c61f9SKrishna Gudipati 
623a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcxp->fcxp_tag);
624a36c61f9SKrishna Gudipati 
625a36c61f9SKrishna Gudipati 	fcxp->caller = caller;
626a36c61f9SKrishna Gudipati 
627a36c61f9SKrishna Gudipati 	bfa_fcxp_init_reqrsp(fcxp, bfa,
628a36c61f9SKrishna Gudipati 		&fcxp->use_ireqbuf, &fcxp->nreq_sgles, &fcxp->req_sga_cbfn,
629a36c61f9SKrishna Gudipati 		&fcxp->req_sglen_cbfn, &fcxp->req_sgpg_q,
630a36c61f9SKrishna Gudipati 		nreq_sgles, req_sga_cbfn, req_sglen_cbfn);
631a36c61f9SKrishna Gudipati 
632a36c61f9SKrishna Gudipati 	bfa_fcxp_init_reqrsp(fcxp, bfa,
633a36c61f9SKrishna Gudipati 		&fcxp->use_irspbuf, &fcxp->nrsp_sgles, &fcxp->rsp_sga_cbfn,
634a36c61f9SKrishna Gudipati 		&fcxp->rsp_sglen_cbfn, &fcxp->rsp_sgpg_q,
635a36c61f9SKrishna Gudipati 		nrsp_sgles, rsp_sga_cbfn, rsp_sglen_cbfn);
636a36c61f9SKrishna Gudipati 
637a36c61f9SKrishna Gudipati }
638a36c61f9SKrishna Gudipati 
639a36c61f9SKrishna Gudipati static void
640a36c61f9SKrishna Gudipati bfa_fcxp_put(struct bfa_fcxp_s *fcxp)
641a36c61f9SKrishna Gudipati {
642a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
643a36c61f9SKrishna Gudipati 	struct bfa_fcxp_wqe_s *wqe;
644a36c61f9SKrishna Gudipati 
645a36c61f9SKrishna Gudipati 	bfa_q_deq(&mod->wait_q, &wqe);
646a36c61f9SKrishna Gudipati 	if (wqe) {
647a36c61f9SKrishna Gudipati 		bfa_trc(mod->bfa, fcxp->fcxp_tag);
648a36c61f9SKrishna Gudipati 
649a36c61f9SKrishna Gudipati 		bfa_fcxp_init(fcxp, wqe->caller, wqe->bfa, wqe->nreq_sgles,
650a36c61f9SKrishna Gudipati 			wqe->nrsp_sgles, wqe->req_sga_cbfn,
651a36c61f9SKrishna Gudipati 			wqe->req_sglen_cbfn, wqe->rsp_sga_cbfn,
652a36c61f9SKrishna Gudipati 			wqe->rsp_sglen_cbfn);
653a36c61f9SKrishna Gudipati 
654a36c61f9SKrishna Gudipati 		wqe->alloc_cbfn(wqe->alloc_cbarg, fcxp);
655a36c61f9SKrishna Gudipati 		return;
656a36c61f9SKrishna Gudipati 	}
657a36c61f9SKrishna Gudipati 
658d4b671c5SJing Huang 	WARN_ON(!bfa_q_is_on_q(&mod->fcxp_active_q, fcxp));
659a36c61f9SKrishna Gudipati 	list_del(&fcxp->qe);
660a36c61f9SKrishna Gudipati 	list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
661a36c61f9SKrishna Gudipati }
662a36c61f9SKrishna Gudipati 
663a36c61f9SKrishna Gudipati static void
664a36c61f9SKrishna Gudipati bfa_fcxp_null_comp(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg,
665a36c61f9SKrishna Gudipati 		   bfa_status_t req_status, u32 rsp_len,
666a36c61f9SKrishna Gudipati 		   u32 resid_len, struct fchs_s *rsp_fchs)
667a36c61f9SKrishna Gudipati {
668a36c61f9SKrishna Gudipati 	/* discarded fcxp completion */
669a36c61f9SKrishna Gudipati }
670a36c61f9SKrishna Gudipati 
671a36c61f9SKrishna Gudipati static void
672a36c61f9SKrishna Gudipati __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete)
673a36c61f9SKrishna Gudipati {
674a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp = cbarg;
675a36c61f9SKrishna Gudipati 
676a36c61f9SKrishna Gudipati 	if (complete) {
677a36c61f9SKrishna Gudipati 		fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
678a36c61f9SKrishna Gudipati 				fcxp->rsp_status, fcxp->rsp_len,
679a36c61f9SKrishna Gudipati 				fcxp->residue_len, &fcxp->rsp_fchs);
680a36c61f9SKrishna Gudipati 	} else {
681a36c61f9SKrishna Gudipati 		bfa_fcxp_free(fcxp);
682a36c61f9SKrishna Gudipati 	}
683a36c61f9SKrishna Gudipati }
684a36c61f9SKrishna Gudipati 
685a36c61f9SKrishna Gudipati static void
686a36c61f9SKrishna Gudipati hal_fcxp_send_comp(struct bfa_s *bfa, struct bfi_fcxp_send_rsp_s *fcxp_rsp)
687a36c61f9SKrishna Gudipati {
688a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s	*mod = BFA_FCXP_MOD(bfa);
689a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s	*fcxp;
690ba816ea8SJing Huang 	u16		fcxp_tag = be16_to_cpu(fcxp_rsp->fcxp_tag);
691a36c61f9SKrishna Gudipati 
692a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcxp_tag);
693a36c61f9SKrishna Gudipati 
694ba816ea8SJing Huang 	fcxp_rsp->rsp_len = be32_to_cpu(fcxp_rsp->rsp_len);
695a36c61f9SKrishna Gudipati 
6965fbe25c7SJing Huang 	/*
697a36c61f9SKrishna Gudipati 	 * @todo f/w should not set residue to non-0 when everything
698a36c61f9SKrishna Gudipati 	 *	 is received.
699a36c61f9SKrishna Gudipati 	 */
700a36c61f9SKrishna Gudipati 	if (fcxp_rsp->req_status == BFA_STATUS_OK)
701a36c61f9SKrishna Gudipati 		fcxp_rsp->residue_len = 0;
702a36c61f9SKrishna Gudipati 	else
703ba816ea8SJing Huang 		fcxp_rsp->residue_len = be32_to_cpu(fcxp_rsp->residue_len);
704a36c61f9SKrishna Gudipati 
705a36c61f9SKrishna Gudipati 	fcxp = BFA_FCXP_FROM_TAG(mod, fcxp_tag);
706a36c61f9SKrishna Gudipati 
707d4b671c5SJing Huang 	WARN_ON(fcxp->send_cbfn == NULL);
708a36c61f9SKrishna Gudipati 
709a36c61f9SKrishna Gudipati 	hal_fcxp_rx_plog(mod->bfa, fcxp, fcxp_rsp);
710a36c61f9SKrishna Gudipati 
711a36c61f9SKrishna Gudipati 	if (fcxp->send_cbfn != NULL) {
712a36c61f9SKrishna Gudipati 		bfa_trc(mod->bfa, (NULL == fcxp->caller));
713a36c61f9SKrishna Gudipati 		if (fcxp->caller == NULL) {
714a36c61f9SKrishna Gudipati 			fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
715a36c61f9SKrishna Gudipati 					fcxp_rsp->req_status, fcxp_rsp->rsp_len,
716a36c61f9SKrishna Gudipati 					fcxp_rsp->residue_len, &fcxp_rsp->fchs);
717a36c61f9SKrishna Gudipati 			/*
718a36c61f9SKrishna Gudipati 			 * fcxp automatically freed on return from the callback
719a36c61f9SKrishna Gudipati 			 */
720a36c61f9SKrishna Gudipati 			bfa_fcxp_free(fcxp);
721a36c61f9SKrishna Gudipati 		} else {
722a36c61f9SKrishna Gudipati 			fcxp->rsp_status = fcxp_rsp->req_status;
723a36c61f9SKrishna Gudipati 			fcxp->rsp_len = fcxp_rsp->rsp_len;
724a36c61f9SKrishna Gudipati 			fcxp->residue_len = fcxp_rsp->residue_len;
725a36c61f9SKrishna Gudipati 			fcxp->rsp_fchs = fcxp_rsp->fchs;
726a36c61f9SKrishna Gudipati 
727a36c61f9SKrishna Gudipati 			bfa_cb_queue(bfa, &fcxp->hcb_qe,
728a36c61f9SKrishna Gudipati 					__bfa_fcxp_send_cbfn, fcxp);
729a36c61f9SKrishna Gudipati 		}
730a36c61f9SKrishna Gudipati 	} else {
731a36c61f9SKrishna Gudipati 		bfa_trc(bfa, (NULL == fcxp->send_cbfn));
732a36c61f9SKrishna Gudipati 	}
733a36c61f9SKrishna Gudipati }
734a36c61f9SKrishna Gudipati 
735a36c61f9SKrishna Gudipati static void
736a36c61f9SKrishna Gudipati hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, struct bfa_fcxp_s *fcxp,
737a36c61f9SKrishna Gudipati 		 struct fchs_s *fchs)
738a36c61f9SKrishna Gudipati {
739a36c61f9SKrishna Gudipati 	/*
740a36c61f9SKrishna Gudipati 	 * TODO: TX ox_id
741a36c61f9SKrishna Gudipati 	 */
742a36c61f9SKrishna Gudipati 	if (reqlen > 0) {
743a36c61f9SKrishna Gudipati 		if (fcxp->use_ireqbuf) {
744a36c61f9SKrishna Gudipati 			u32	pld_w0 =
745a36c61f9SKrishna Gudipati 				*((u32 *) BFA_FCXP_REQ_PLD(fcxp));
746a36c61f9SKrishna Gudipati 
747a36c61f9SKrishna Gudipati 			bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP,
748a36c61f9SKrishna Gudipati 					BFA_PL_EID_TX,
749a36c61f9SKrishna Gudipati 					reqlen + sizeof(struct fchs_s), fchs,
750a36c61f9SKrishna Gudipati 					pld_w0);
751a36c61f9SKrishna Gudipati 		} else {
752a36c61f9SKrishna Gudipati 			bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP,
753a36c61f9SKrishna Gudipati 					BFA_PL_EID_TX,
754a36c61f9SKrishna Gudipati 					reqlen + sizeof(struct fchs_s),
755a36c61f9SKrishna Gudipati 					fchs);
756a36c61f9SKrishna Gudipati 		}
757a36c61f9SKrishna Gudipati 	} else {
758a36c61f9SKrishna Gudipati 		bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_TX,
759a36c61f9SKrishna Gudipati 			       reqlen + sizeof(struct fchs_s), fchs);
760a36c61f9SKrishna Gudipati 	}
761a36c61f9SKrishna Gudipati }
762a36c61f9SKrishna Gudipati 
763a36c61f9SKrishna Gudipati static void
764a36c61f9SKrishna Gudipati hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp,
765a36c61f9SKrishna Gudipati 		 struct bfi_fcxp_send_rsp_s *fcxp_rsp)
766a36c61f9SKrishna Gudipati {
767a36c61f9SKrishna Gudipati 	if (fcxp_rsp->rsp_len > 0) {
768a36c61f9SKrishna Gudipati 		if (fcxp->use_irspbuf) {
769a36c61f9SKrishna Gudipati 			u32	pld_w0 =
770a36c61f9SKrishna Gudipati 				*((u32 *) BFA_FCXP_RSP_PLD(fcxp));
771a36c61f9SKrishna Gudipati 
772a36c61f9SKrishna Gudipati 			bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP,
773a36c61f9SKrishna Gudipati 					      BFA_PL_EID_RX,
774a36c61f9SKrishna Gudipati 					      (u16) fcxp_rsp->rsp_len,
775a36c61f9SKrishna Gudipati 					      &fcxp_rsp->fchs, pld_w0);
776a36c61f9SKrishna Gudipati 		} else {
777a36c61f9SKrishna Gudipati 			bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP,
778a36c61f9SKrishna Gudipati 				       BFA_PL_EID_RX,
779a36c61f9SKrishna Gudipati 				       (u16) fcxp_rsp->rsp_len,
780a36c61f9SKrishna Gudipati 				       &fcxp_rsp->fchs);
781a36c61f9SKrishna Gudipati 		}
782a36c61f9SKrishna Gudipati 	} else {
783a36c61f9SKrishna Gudipati 		bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_RX,
784a36c61f9SKrishna Gudipati 			       (u16) fcxp_rsp->rsp_len, &fcxp_rsp->fchs);
785a36c61f9SKrishna Gudipati 	}
786a36c61f9SKrishna Gudipati }
787a36c61f9SKrishna Gudipati 
7885fbe25c7SJing Huang /*
789a36c61f9SKrishna Gudipati  * Handler to resume sending fcxp when space in available in cpe queue.
790a36c61f9SKrishna Gudipati  */
791a36c61f9SKrishna Gudipati static void
792a36c61f9SKrishna Gudipati bfa_fcxp_qresume(void *cbarg)
793a36c61f9SKrishna Gudipati {
794a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s		*fcxp = cbarg;
795a36c61f9SKrishna Gudipati 	struct bfa_s			*bfa = fcxp->fcxp_mod->bfa;
796a36c61f9SKrishna Gudipati 	struct bfi_fcxp_send_req_s	*send_req;
797a36c61f9SKrishna Gudipati 
798a36c61f9SKrishna Gudipati 	fcxp->reqq_waiting = BFA_FALSE;
799a36c61f9SKrishna Gudipati 	send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
800a36c61f9SKrishna Gudipati 	bfa_fcxp_queue(fcxp, send_req);
801a36c61f9SKrishna Gudipati }
802a36c61f9SKrishna Gudipati 
8035fbe25c7SJing Huang /*
804a36c61f9SKrishna Gudipati  * Queue fcxp send request to foimrware.
805a36c61f9SKrishna Gudipati  */
806a36c61f9SKrishna Gudipati static void
807a36c61f9SKrishna Gudipati bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
808a36c61f9SKrishna Gudipati {
809a36c61f9SKrishna Gudipati 	struct bfa_s			*bfa = fcxp->fcxp_mod->bfa;
810a36c61f9SKrishna Gudipati 	struct bfa_fcxp_req_info_s	*reqi = &fcxp->req_info;
811a36c61f9SKrishna Gudipati 	struct bfa_fcxp_rsp_info_s	*rspi = &fcxp->rsp_info;
812a36c61f9SKrishna Gudipati 	struct bfa_rport_s		*rport = reqi->bfa_rport;
813a36c61f9SKrishna Gudipati 
814a36c61f9SKrishna Gudipati 	bfi_h2i_set(send_req->mh, BFI_MC_FCXP, BFI_FCXP_H2I_SEND_REQ,
8153fd45980SKrishna Gudipati 		    bfa_fn_lpu(bfa));
816a36c61f9SKrishna Gudipati 
817ba816ea8SJing Huang 	send_req->fcxp_tag = cpu_to_be16(fcxp->fcxp_tag);
818a36c61f9SKrishna Gudipati 	if (rport) {
819a36c61f9SKrishna Gudipati 		send_req->rport_fw_hndl = rport->fw_handle;
820ba816ea8SJing Huang 		send_req->max_frmsz = cpu_to_be16(rport->rport_info.max_frmsz);
821a36c61f9SKrishna Gudipati 		if (send_req->max_frmsz == 0)
822ba816ea8SJing Huang 			send_req->max_frmsz = cpu_to_be16(FC_MAX_PDUSZ);
823a36c61f9SKrishna Gudipati 	} else {
824a36c61f9SKrishna Gudipati 		send_req->rport_fw_hndl = 0;
825ba816ea8SJing Huang 		send_req->max_frmsz = cpu_to_be16(FC_MAX_PDUSZ);
826a36c61f9SKrishna Gudipati 	}
827a36c61f9SKrishna Gudipati 
828ba816ea8SJing Huang 	send_req->vf_id = cpu_to_be16(reqi->vf_id);
8293fd45980SKrishna Gudipati 	send_req->lp_fwtag = bfa_lps_get_fwtag(bfa, reqi->lp_tag);
830a36c61f9SKrishna Gudipati 	send_req->class = reqi->class;
831a36c61f9SKrishna Gudipati 	send_req->rsp_timeout = rspi->rsp_timeout;
832a36c61f9SKrishna Gudipati 	send_req->cts = reqi->cts;
833a36c61f9SKrishna Gudipati 	send_req->fchs = reqi->fchs;
834a36c61f9SKrishna Gudipati 
835ba816ea8SJing Huang 	send_req->req_len = cpu_to_be32(reqi->req_tot_len);
836ba816ea8SJing Huang 	send_req->rsp_maxlen = cpu_to_be32(rspi->rsp_maxlen);
837a36c61f9SKrishna Gudipati 
838a36c61f9SKrishna Gudipati 	/*
839a36c61f9SKrishna Gudipati 	 * setup req sgles
840a36c61f9SKrishna Gudipati 	 */
841a36c61f9SKrishna Gudipati 	if (fcxp->use_ireqbuf == 1) {
84285ce928dSKrishna Gudipati 		bfa_alen_set(&send_req->req_alen, reqi->req_tot_len,
843a36c61f9SKrishna Gudipati 					BFA_FCXP_REQ_PLD_PA(fcxp));
844a36c61f9SKrishna Gudipati 	} else {
845a36c61f9SKrishna Gudipati 		if (fcxp->nreq_sgles > 0) {
846d4b671c5SJing Huang 			WARN_ON(fcxp->nreq_sgles != 1);
84785ce928dSKrishna Gudipati 			bfa_alen_set(&send_req->req_alen, reqi->req_tot_len,
84885ce928dSKrishna Gudipati 				fcxp->req_sga_cbfn(fcxp->caller, 0));
849a36c61f9SKrishna Gudipati 		} else {
850d4b671c5SJing Huang 			WARN_ON(reqi->req_tot_len != 0);
85185ce928dSKrishna Gudipati 			bfa_alen_set(&send_req->rsp_alen, 0, 0);
852a36c61f9SKrishna Gudipati 		}
853a36c61f9SKrishna Gudipati 	}
854a36c61f9SKrishna Gudipati 
855a36c61f9SKrishna Gudipati 	/*
856a36c61f9SKrishna Gudipati 	 * setup rsp sgles
857a36c61f9SKrishna Gudipati 	 */
858a36c61f9SKrishna Gudipati 	if (fcxp->use_irspbuf == 1) {
859d4b671c5SJing Huang 		WARN_ON(rspi->rsp_maxlen > BFA_FCXP_MAX_LBUF_SZ);
860a36c61f9SKrishna Gudipati 
86185ce928dSKrishna Gudipati 		bfa_alen_set(&send_req->rsp_alen, rspi->rsp_maxlen,
862a36c61f9SKrishna Gudipati 					BFA_FCXP_RSP_PLD_PA(fcxp));
863a36c61f9SKrishna Gudipati 	} else {
864a36c61f9SKrishna Gudipati 		if (fcxp->nrsp_sgles > 0) {
865d4b671c5SJing Huang 			WARN_ON(fcxp->nrsp_sgles != 1);
86685ce928dSKrishna Gudipati 			bfa_alen_set(&send_req->rsp_alen, rspi->rsp_maxlen,
86785ce928dSKrishna Gudipati 				fcxp->rsp_sga_cbfn(fcxp->caller, 0));
86885ce928dSKrishna Gudipati 
869a36c61f9SKrishna Gudipati 		} else {
870d4b671c5SJing Huang 			WARN_ON(rspi->rsp_maxlen != 0);
87185ce928dSKrishna Gudipati 			bfa_alen_set(&send_req->rsp_alen, 0, 0);
872a36c61f9SKrishna Gudipati 		}
873a36c61f9SKrishna Gudipati 	}
874a36c61f9SKrishna Gudipati 
875a36c61f9SKrishna Gudipati 	hal_fcxp_tx_plog(bfa, reqi->req_tot_len, fcxp, &reqi->fchs);
876a36c61f9SKrishna Gudipati 
8773fd45980SKrishna Gudipati 	bfa_reqq_produce(bfa, BFA_REQQ_FCXP, send_req->mh);
878a36c61f9SKrishna Gudipati 
879a36c61f9SKrishna Gudipati 	bfa_trc(bfa, bfa_reqq_pi(bfa, BFA_REQQ_FCXP));
880a36c61f9SKrishna Gudipati 	bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP));
881a36c61f9SKrishna Gudipati }
882a36c61f9SKrishna Gudipati 
8835fbe25c7SJing Huang /*
884a36c61f9SKrishna Gudipati  * Allocate an FCXP instance to send a response or to send a request
885a36c61f9SKrishna Gudipati  * that has a response. Request/response buffers are allocated by caller.
886a36c61f9SKrishna Gudipati  *
887a36c61f9SKrishna Gudipati  * @param[in]	bfa		BFA bfa instance
888a36c61f9SKrishna Gudipati  * @param[in]	nreq_sgles	Number of SG elements required for request
889a36c61f9SKrishna Gudipati  *				buffer. 0, if fcxp internal buffers are	used.
890a36c61f9SKrishna Gudipati  *				Use bfa_fcxp_get_reqbuf() to get the
891a36c61f9SKrishna Gudipati  *				internal req buffer.
892a36c61f9SKrishna Gudipati  * @param[in]	req_sgles	SG elements describing request buffer. Will be
893a36c61f9SKrishna Gudipati  *				copied in by BFA and hence can be freed on
894a36c61f9SKrishna Gudipati  *				return from this function.
895a36c61f9SKrishna Gudipati  * @param[in]	get_req_sga	function ptr to be called to get a request SG
896a36c61f9SKrishna Gudipati  *				Address (given the sge index).
897a36c61f9SKrishna Gudipati  * @param[in]	get_req_sglen	function ptr to be called to get a request SG
898a36c61f9SKrishna Gudipati  *				len (given the sge index).
899a36c61f9SKrishna Gudipati  * @param[in]	get_rsp_sga	function ptr to be called to get a response SG
900a36c61f9SKrishna Gudipati  *				Address (given the sge index).
901a36c61f9SKrishna Gudipati  * @param[in]	get_rsp_sglen	function ptr to be called to get a response SG
902a36c61f9SKrishna Gudipati  *				len (given the sge index).
903a36c61f9SKrishna Gudipati  *
904a36c61f9SKrishna Gudipati  * @return FCXP instance. NULL on failure.
905a36c61f9SKrishna Gudipati  */
906a36c61f9SKrishna Gudipati struct bfa_fcxp_s *
907a36c61f9SKrishna Gudipati bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles,
908a36c61f9SKrishna Gudipati 	       int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
909a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sglen_t req_sglen_cbfn,
910a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
911a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sglen_t rsp_sglen_cbfn)
912a36c61f9SKrishna Gudipati {
913a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp = NULL;
914a36c61f9SKrishna Gudipati 
915d4b671c5SJing Huang 	WARN_ON(bfa == NULL);
916a36c61f9SKrishna Gudipati 
917a36c61f9SKrishna Gudipati 	fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa));
918a36c61f9SKrishna Gudipati 	if (fcxp == NULL)
919a36c61f9SKrishna Gudipati 		return NULL;
920a36c61f9SKrishna Gudipati 
921a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcxp->fcxp_tag);
922a36c61f9SKrishna Gudipati 
923a36c61f9SKrishna Gudipati 	bfa_fcxp_init(fcxp, caller, bfa, nreq_sgles, nrsp_sgles, req_sga_cbfn,
924a36c61f9SKrishna Gudipati 			req_sglen_cbfn, rsp_sga_cbfn, rsp_sglen_cbfn);
925a36c61f9SKrishna Gudipati 
926a36c61f9SKrishna Gudipati 	return fcxp;
927a36c61f9SKrishna Gudipati }
928a36c61f9SKrishna Gudipati 
9295fbe25c7SJing Huang /*
930a36c61f9SKrishna Gudipati  * Get the internal request buffer pointer
931a36c61f9SKrishna Gudipati  *
932a36c61f9SKrishna Gudipati  * @param[in]	fcxp	BFA fcxp pointer
933a36c61f9SKrishna Gudipati  *
934a36c61f9SKrishna Gudipati  * @return		pointer to the internal request buffer
935a36c61f9SKrishna Gudipati  */
936a36c61f9SKrishna Gudipati void *
937a36c61f9SKrishna Gudipati bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp)
938a36c61f9SKrishna Gudipati {
939a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
940a36c61f9SKrishna Gudipati 	void	*reqbuf;
941a36c61f9SKrishna Gudipati 
942d4b671c5SJing Huang 	WARN_ON(fcxp->use_ireqbuf != 1);
9434507025dSKrishna Gudipati 	reqbuf = bfa_mem_get_dmabuf_kva(mod, fcxp->fcxp_tag,
9444507025dSKrishna Gudipati 				mod->req_pld_sz + mod->rsp_pld_sz);
945a36c61f9SKrishna Gudipati 	return reqbuf;
946a36c61f9SKrishna Gudipati }
947a36c61f9SKrishna Gudipati 
948a36c61f9SKrishna Gudipati u32
949a36c61f9SKrishna Gudipati bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp)
950a36c61f9SKrishna Gudipati {
951a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
952a36c61f9SKrishna Gudipati 
953a36c61f9SKrishna Gudipati 	return mod->req_pld_sz;
954a36c61f9SKrishna Gudipati }
955a36c61f9SKrishna Gudipati 
9565fbe25c7SJing Huang /*
957a36c61f9SKrishna Gudipati  * Get the internal response buffer pointer
958a36c61f9SKrishna Gudipati  *
959a36c61f9SKrishna Gudipati  * @param[in]	fcxp	BFA fcxp pointer
960a36c61f9SKrishna Gudipati  *
961a36c61f9SKrishna Gudipati  * @return		pointer to the internal request buffer
962a36c61f9SKrishna Gudipati  */
963a36c61f9SKrishna Gudipati void *
964a36c61f9SKrishna Gudipati bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp)
965a36c61f9SKrishna Gudipati {
966a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
9674507025dSKrishna Gudipati 	void	*fcxp_buf;
968a36c61f9SKrishna Gudipati 
969d4b671c5SJing Huang 	WARN_ON(fcxp->use_irspbuf != 1);
970a36c61f9SKrishna Gudipati 
9714507025dSKrishna Gudipati 	fcxp_buf = bfa_mem_get_dmabuf_kva(mod, fcxp->fcxp_tag,
9724507025dSKrishna Gudipati 				mod->req_pld_sz + mod->rsp_pld_sz);
9734507025dSKrishna Gudipati 
9744507025dSKrishna Gudipati 	/* fcxp_buf = req_buf + rsp_buf :- add req_buf_sz to get to rsp_buf */
9754507025dSKrishna Gudipati 	return ((u8 *) fcxp_buf) + mod->req_pld_sz;
976a36c61f9SKrishna Gudipati }
977a36c61f9SKrishna Gudipati 
9785fbe25c7SJing Huang /*
979a36c61f9SKrishna Gudipati  * Free the BFA FCXP
980a36c61f9SKrishna Gudipati  *
981a36c61f9SKrishna Gudipati  * @param[in]	fcxp			BFA fcxp pointer
982a36c61f9SKrishna Gudipati  *
983a36c61f9SKrishna Gudipati  * @return		void
984a36c61f9SKrishna Gudipati  */
985a36c61f9SKrishna Gudipati void
986a36c61f9SKrishna Gudipati bfa_fcxp_free(struct bfa_fcxp_s *fcxp)
987a36c61f9SKrishna Gudipati {
988a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
989a36c61f9SKrishna Gudipati 
990d4b671c5SJing Huang 	WARN_ON(fcxp == NULL);
991a36c61f9SKrishna Gudipati 	bfa_trc(mod->bfa, fcxp->fcxp_tag);
992a36c61f9SKrishna Gudipati 	bfa_fcxp_put(fcxp);
993a36c61f9SKrishna Gudipati }
994a36c61f9SKrishna Gudipati 
9955fbe25c7SJing Huang /*
996a36c61f9SKrishna Gudipati  * Send a FCXP request
997a36c61f9SKrishna Gudipati  *
998a36c61f9SKrishna Gudipati  * @param[in]	fcxp	BFA fcxp pointer
999a36c61f9SKrishna Gudipati  * @param[in]	rport	BFA rport pointer. Could be left NULL for WKA rports
1000a36c61f9SKrishna Gudipati  * @param[in]	vf_id	virtual Fabric ID
1001a36c61f9SKrishna Gudipati  * @param[in]	lp_tag	lport tag
100225985edcSLucas De Marchi  * @param[in]	cts	use Continuous sequence
1003a36c61f9SKrishna Gudipati  * @param[in]	cos	fc Class of Service
1004a36c61f9SKrishna Gudipati  * @param[in]	reqlen	request length, does not include FCHS length
1005a36c61f9SKrishna Gudipati  * @param[in]	fchs	fc Header Pointer. The header content will be copied
1006a36c61f9SKrishna Gudipati  *			in by BFA.
1007a36c61f9SKrishna Gudipati  *
1008a36c61f9SKrishna Gudipati  * @param[in]	cbfn	call back function to be called on receiving
1009a36c61f9SKrishna Gudipati  *								the response
1010a36c61f9SKrishna Gudipati  * @param[in]	cbarg	arg for cbfn
1011a36c61f9SKrishna Gudipati  * @param[in]	rsp_timeout
1012a36c61f9SKrishna Gudipati  *			response timeout
1013a36c61f9SKrishna Gudipati  *
1014a36c61f9SKrishna Gudipati  * @return		bfa_status_t
1015a36c61f9SKrishna Gudipati  */
1016a36c61f9SKrishna Gudipati void
1017a36c61f9SKrishna Gudipati bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport,
1018a36c61f9SKrishna Gudipati 	      u16 vf_id, u8 lp_tag, bfa_boolean_t cts, enum fc_cos cos,
1019a36c61f9SKrishna Gudipati 	      u32 reqlen, struct fchs_s *fchs, bfa_cb_fcxp_send_t cbfn,
1020a36c61f9SKrishna Gudipati 	      void *cbarg, u32 rsp_maxlen, u8 rsp_timeout)
1021a36c61f9SKrishna Gudipati {
1022a36c61f9SKrishna Gudipati 	struct bfa_s			*bfa  = fcxp->fcxp_mod->bfa;
1023a36c61f9SKrishna Gudipati 	struct bfa_fcxp_req_info_s	*reqi = &fcxp->req_info;
1024a36c61f9SKrishna Gudipati 	struct bfa_fcxp_rsp_info_s	*rspi = &fcxp->rsp_info;
1025a36c61f9SKrishna Gudipati 	struct bfi_fcxp_send_req_s	*send_req;
1026a36c61f9SKrishna Gudipati 
1027a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcxp->fcxp_tag);
1028a36c61f9SKrishna Gudipati 
10295fbe25c7SJing Huang 	/*
1030a36c61f9SKrishna Gudipati 	 * setup request/response info
1031a36c61f9SKrishna Gudipati 	 */
1032a36c61f9SKrishna Gudipati 	reqi->bfa_rport = rport;
1033a36c61f9SKrishna Gudipati 	reqi->vf_id = vf_id;
1034a36c61f9SKrishna Gudipati 	reqi->lp_tag = lp_tag;
1035a36c61f9SKrishna Gudipati 	reqi->class = cos;
1036a36c61f9SKrishna Gudipati 	rspi->rsp_timeout = rsp_timeout;
1037a36c61f9SKrishna Gudipati 	reqi->cts = cts;
1038a36c61f9SKrishna Gudipati 	reqi->fchs = *fchs;
1039a36c61f9SKrishna Gudipati 	reqi->req_tot_len = reqlen;
1040a36c61f9SKrishna Gudipati 	rspi->rsp_maxlen = rsp_maxlen;
1041a36c61f9SKrishna Gudipati 	fcxp->send_cbfn = cbfn ? cbfn : bfa_fcxp_null_comp;
1042a36c61f9SKrishna Gudipati 	fcxp->send_cbarg = cbarg;
1043a36c61f9SKrishna Gudipati 
10445fbe25c7SJing Huang 	/*
1045a36c61f9SKrishna Gudipati 	 * If no room in CPE queue, wait for space in request queue
1046a36c61f9SKrishna Gudipati 	 */
1047a36c61f9SKrishna Gudipati 	send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
1048a36c61f9SKrishna Gudipati 	if (!send_req) {
1049a36c61f9SKrishna Gudipati 		bfa_trc(bfa, fcxp->fcxp_tag);
1050a36c61f9SKrishna Gudipati 		fcxp->reqq_waiting = BFA_TRUE;
1051a36c61f9SKrishna Gudipati 		bfa_reqq_wait(bfa, BFA_REQQ_FCXP, &fcxp->reqq_wqe);
1052a36c61f9SKrishna Gudipati 		return;
1053a36c61f9SKrishna Gudipati 	}
1054a36c61f9SKrishna Gudipati 
1055a36c61f9SKrishna Gudipati 	bfa_fcxp_queue(fcxp, send_req);
1056a36c61f9SKrishna Gudipati }
1057a36c61f9SKrishna Gudipati 
10585fbe25c7SJing Huang /*
1059a36c61f9SKrishna Gudipati  * Abort a BFA FCXP
1060a36c61f9SKrishna Gudipati  *
1061a36c61f9SKrishna Gudipati  * @param[in]	fcxp	BFA fcxp pointer
1062a36c61f9SKrishna Gudipati  *
1063a36c61f9SKrishna Gudipati  * @return		void
1064a36c61f9SKrishna Gudipati  */
1065a36c61f9SKrishna Gudipati bfa_status_t
1066a36c61f9SKrishna Gudipati bfa_fcxp_abort(struct bfa_fcxp_s *fcxp)
1067a36c61f9SKrishna Gudipati {
1068a36c61f9SKrishna Gudipati 	bfa_trc(fcxp->fcxp_mod->bfa, fcxp->fcxp_tag);
1069d4b671c5SJing Huang 	WARN_ON(1);
1070a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
1071a36c61f9SKrishna Gudipati }
1072a36c61f9SKrishna Gudipati 
1073a36c61f9SKrishna Gudipati void
1074a36c61f9SKrishna Gudipati bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
1075a36c61f9SKrishna Gudipati 	       bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *alloc_cbarg,
1076a36c61f9SKrishna Gudipati 	       void *caller, int nreq_sgles,
1077a36c61f9SKrishna Gudipati 	       int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
1078a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sglen_t req_sglen_cbfn,
1079a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
1080a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sglen_t rsp_sglen_cbfn)
1081a36c61f9SKrishna Gudipati {
1082a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
1083a36c61f9SKrishna Gudipati 
1084d4b671c5SJing Huang 	WARN_ON(!list_empty(&mod->fcxp_free_q));
1085a36c61f9SKrishna Gudipati 
1086a36c61f9SKrishna Gudipati 	wqe->alloc_cbfn = alloc_cbfn;
1087a36c61f9SKrishna Gudipati 	wqe->alloc_cbarg = alloc_cbarg;
1088a36c61f9SKrishna Gudipati 	wqe->caller = caller;
1089a36c61f9SKrishna Gudipati 	wqe->bfa = bfa;
1090a36c61f9SKrishna Gudipati 	wqe->nreq_sgles = nreq_sgles;
1091a36c61f9SKrishna Gudipati 	wqe->nrsp_sgles = nrsp_sgles;
1092a36c61f9SKrishna Gudipati 	wqe->req_sga_cbfn = req_sga_cbfn;
1093a36c61f9SKrishna Gudipati 	wqe->req_sglen_cbfn = req_sglen_cbfn;
1094a36c61f9SKrishna Gudipati 	wqe->rsp_sga_cbfn = rsp_sga_cbfn;
1095a36c61f9SKrishna Gudipati 	wqe->rsp_sglen_cbfn = rsp_sglen_cbfn;
1096a36c61f9SKrishna Gudipati 
1097a36c61f9SKrishna Gudipati 	list_add_tail(&wqe->qe, &mod->wait_q);
1098a36c61f9SKrishna Gudipati }
1099a36c61f9SKrishna Gudipati 
1100a36c61f9SKrishna Gudipati void
1101a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe)
1102a36c61f9SKrishna Gudipati {
1103a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
1104a36c61f9SKrishna Gudipati 
1105d4b671c5SJing Huang 	WARN_ON(!bfa_q_is_on_q(&mod->wait_q, wqe));
1106a36c61f9SKrishna Gudipati 	list_del(&wqe->qe);
1107a36c61f9SKrishna Gudipati }
1108a36c61f9SKrishna Gudipati 
1109a36c61f9SKrishna Gudipati void
1110a36c61f9SKrishna Gudipati bfa_fcxp_discard(struct bfa_fcxp_s *fcxp)
1111a36c61f9SKrishna Gudipati {
11125fbe25c7SJing Huang 	/*
1113a36c61f9SKrishna Gudipati 	 * If waiting for room in request queue, cancel reqq wait
1114a36c61f9SKrishna Gudipati 	 * and free fcxp.
1115a36c61f9SKrishna Gudipati 	 */
1116a36c61f9SKrishna Gudipati 	if (fcxp->reqq_waiting) {
1117a36c61f9SKrishna Gudipati 		fcxp->reqq_waiting = BFA_FALSE;
1118a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcxp->reqq_wqe);
1119a36c61f9SKrishna Gudipati 		bfa_fcxp_free(fcxp);
1120a36c61f9SKrishna Gudipati 		return;
1121a36c61f9SKrishna Gudipati 	}
1122a36c61f9SKrishna Gudipati 
1123a36c61f9SKrishna Gudipati 	fcxp->send_cbfn = bfa_fcxp_null_comp;
1124a36c61f9SKrishna Gudipati }
1125a36c61f9SKrishna Gudipati 
1126a36c61f9SKrishna Gudipati void
1127a36c61f9SKrishna Gudipati bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
1128a36c61f9SKrishna Gudipati {
1129a36c61f9SKrishna Gudipati 	switch (msg->mhdr.msg_id) {
1130a36c61f9SKrishna Gudipati 	case BFI_FCXP_I2H_SEND_RSP:
1131a36c61f9SKrishna Gudipati 		hal_fcxp_send_comp(bfa, (struct bfi_fcxp_send_rsp_s *) msg);
1132a36c61f9SKrishna Gudipati 		break;
1133a36c61f9SKrishna Gudipati 
1134a36c61f9SKrishna Gudipati 	default:
1135a36c61f9SKrishna Gudipati 		bfa_trc(bfa, msg->mhdr.msg_id);
1136d4b671c5SJing Huang 		WARN_ON(1);
1137a36c61f9SKrishna Gudipati 	}
1138a36c61f9SKrishna Gudipati }
1139a36c61f9SKrishna Gudipati 
1140a36c61f9SKrishna Gudipati u32
1141a36c61f9SKrishna Gudipati bfa_fcxp_get_maxrsp(struct bfa_s *bfa)
1142a36c61f9SKrishna Gudipati {
1143a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
1144a36c61f9SKrishna Gudipati 
1145a36c61f9SKrishna Gudipati 	return mod->rsp_pld_sz;
1146a36c61f9SKrishna Gudipati }
1147a36c61f9SKrishna Gudipati 
11483fd45980SKrishna Gudipati void
11493fd45980SKrishna Gudipati bfa_fcxp_res_recfg(struct bfa_s *bfa, u16 num_fcxp_fw)
11503fd45980SKrishna Gudipati {
11513fd45980SKrishna Gudipati 	struct bfa_fcxp_mod_s	*mod = BFA_FCXP_MOD(bfa);
11523fd45980SKrishna Gudipati 	struct list_head	*qe;
11533fd45980SKrishna Gudipati 	int	i;
11543fd45980SKrishna Gudipati 
11553fd45980SKrishna Gudipati 	for (i = 0; i < (mod->num_fcxps - num_fcxp_fw); i++) {
11563fd45980SKrishna Gudipati 		bfa_q_deq_tail(&mod->fcxp_free_q, &qe);
11573fd45980SKrishna Gudipati 		list_add_tail(qe, &mod->fcxp_unused_q);
11583fd45980SKrishna Gudipati 	}
11593fd45980SKrishna Gudipati }
1160a36c61f9SKrishna Gudipati 
11615fbe25c7SJing Huang /*
1162a36c61f9SKrishna Gudipati  *  BFA LPS state machine functions
1163a36c61f9SKrishna Gudipati  */
1164a36c61f9SKrishna Gudipati 
11655fbe25c7SJing Huang /*
1166a36c61f9SKrishna Gudipati  * Init state -- no login
1167a36c61f9SKrishna Gudipati  */
1168a36c61f9SKrishna Gudipati static void
1169a36c61f9SKrishna Gudipati bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
1170a36c61f9SKrishna Gudipati {
11713fd45980SKrishna Gudipati 	bfa_trc(lps->bfa, lps->bfa_tag);
1172a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, event);
1173a36c61f9SKrishna Gudipati 
1174a36c61f9SKrishna Gudipati 	switch (event) {
1175a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_LOGIN:
1176a36c61f9SKrishna Gudipati 		if (bfa_reqq_full(lps->bfa, lps->reqq)) {
1177a36c61f9SKrishna Gudipati 			bfa_sm_set_state(lps, bfa_lps_sm_loginwait);
1178a36c61f9SKrishna Gudipati 			bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe);
1179a36c61f9SKrishna Gudipati 		} else {
1180a36c61f9SKrishna Gudipati 			bfa_sm_set_state(lps, bfa_lps_sm_login);
1181a36c61f9SKrishna Gudipati 			bfa_lps_send_login(lps);
1182a36c61f9SKrishna Gudipati 		}
1183a36c61f9SKrishna Gudipati 
1184a36c61f9SKrishna Gudipati 		if (lps->fdisc)
1185a36c61f9SKrishna Gudipati 			bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1186a36c61f9SKrishna Gudipati 				BFA_PL_EID_LOGIN, 0, "FDISC Request");
1187a36c61f9SKrishna Gudipati 		else
1188a36c61f9SKrishna Gudipati 			bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1189a36c61f9SKrishna Gudipati 				BFA_PL_EID_LOGIN, 0, "FLOGI Request");
1190a36c61f9SKrishna Gudipati 		break;
1191a36c61f9SKrishna Gudipati 
1192a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_LOGOUT:
1193a36c61f9SKrishna Gudipati 		bfa_lps_logout_comp(lps);
1194a36c61f9SKrishna Gudipati 		break;
1195a36c61f9SKrishna Gudipati 
1196a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_DELETE:
1197a36c61f9SKrishna Gudipati 		bfa_lps_free(lps);
1198a36c61f9SKrishna Gudipati 		break;
1199a36c61f9SKrishna Gudipati 
1200a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_RX_CVL:
1201a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_OFFLINE:
1202a36c61f9SKrishna Gudipati 		break;
1203a36c61f9SKrishna Gudipati 
1204a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_FWRSP:
1205a36c61f9SKrishna Gudipati 		/*
1206a36c61f9SKrishna Gudipati 		 * Could happen when fabric detects loopback and discards
1207a36c61f9SKrishna Gudipati 		 * the lps request. Fw will eventually sent out the timeout
1208a36c61f9SKrishna Gudipati 		 * Just ignore
1209a36c61f9SKrishna Gudipati 		 */
1210a36c61f9SKrishna Gudipati 		break;
1211a36c61f9SKrishna Gudipati 
1212a36c61f9SKrishna Gudipati 	default:
1213a36c61f9SKrishna Gudipati 		bfa_sm_fault(lps->bfa, event);
1214a36c61f9SKrishna Gudipati 	}
1215a36c61f9SKrishna Gudipati }
1216a36c61f9SKrishna Gudipati 
12175fbe25c7SJing Huang /*
1218a36c61f9SKrishna Gudipati  * login is in progress -- awaiting response from firmware
1219a36c61f9SKrishna Gudipati  */
1220a36c61f9SKrishna Gudipati static void
1221a36c61f9SKrishna Gudipati bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
1222a36c61f9SKrishna Gudipati {
12233fd45980SKrishna Gudipati 	bfa_trc(lps->bfa, lps->bfa_tag);
1224a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, event);
1225a36c61f9SKrishna Gudipati 
1226a36c61f9SKrishna Gudipati 	switch (event) {
1227a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_FWRSP:
1228a36c61f9SKrishna Gudipati 		if (lps->status == BFA_STATUS_OK) {
1229a36c61f9SKrishna Gudipati 			bfa_sm_set_state(lps, bfa_lps_sm_online);
1230a36c61f9SKrishna Gudipati 			if (lps->fdisc)
1231a36c61f9SKrishna Gudipati 				bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1232a36c61f9SKrishna Gudipati 					BFA_PL_EID_LOGIN, 0, "FDISC Accept");
1233a36c61f9SKrishna Gudipati 			else
1234a36c61f9SKrishna Gudipati 				bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1235a36c61f9SKrishna Gudipati 					BFA_PL_EID_LOGIN, 0, "FLOGI Accept");
1236b704495cSKrishna Gudipati 			/* If N2N, send the assigned PID to FW */
1237b704495cSKrishna Gudipati 			bfa_trc(lps->bfa, lps->fport);
1238b704495cSKrishna Gudipati 			bfa_trc(lps->bfa, lps->lp_pid);
1239b704495cSKrishna Gudipati 
1240b704495cSKrishna Gudipati 			if (!lps->fport && lps->lp_pid)
1241b704495cSKrishna Gudipati 				bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID);
1242a36c61f9SKrishna Gudipati 		} else {
1243a36c61f9SKrishna Gudipati 			bfa_sm_set_state(lps, bfa_lps_sm_init);
1244a36c61f9SKrishna Gudipati 			if (lps->fdisc)
1245a36c61f9SKrishna Gudipati 				bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1246a36c61f9SKrishna Gudipati 					BFA_PL_EID_LOGIN, 0,
1247a36c61f9SKrishna Gudipati 					"FDISC Fail (RJT or timeout)");
1248a36c61f9SKrishna Gudipati 			else
1249a36c61f9SKrishna Gudipati 				bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1250a36c61f9SKrishna Gudipati 					BFA_PL_EID_LOGIN, 0,
1251a36c61f9SKrishna Gudipati 					"FLOGI Fail (RJT or timeout)");
1252a36c61f9SKrishna Gudipati 		}
1253a36c61f9SKrishna Gudipati 		bfa_lps_login_comp(lps);
1254a36c61f9SKrishna Gudipati 		break;
1255a36c61f9SKrishna Gudipati 
1256a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_OFFLINE:
1257be540a99SKrishna Gudipati 	case BFA_LPS_SM_DELETE:
1258a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1259a36c61f9SKrishna Gudipati 		break;
1260a36c61f9SKrishna Gudipati 
1261b704495cSKrishna Gudipati 	case BFA_LPS_SM_SET_N2N_PID:
1262b704495cSKrishna Gudipati 		bfa_trc(lps->bfa, lps->fport);
1263b704495cSKrishna Gudipati 		bfa_trc(lps->bfa, lps->lp_pid);
1264b704495cSKrishna Gudipati 		break;
1265b704495cSKrishna Gudipati 
1266a36c61f9SKrishna Gudipati 	default:
1267a36c61f9SKrishna Gudipati 		bfa_sm_fault(lps->bfa, event);
1268a36c61f9SKrishna Gudipati 	}
1269a36c61f9SKrishna Gudipati }
1270a36c61f9SKrishna Gudipati 
12715fbe25c7SJing Huang /*
1272a36c61f9SKrishna Gudipati  * login pending - awaiting space in request queue
1273a36c61f9SKrishna Gudipati  */
1274a36c61f9SKrishna Gudipati static void
1275a36c61f9SKrishna Gudipati bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event)
1276a36c61f9SKrishna Gudipati {
12773fd45980SKrishna Gudipati 	bfa_trc(lps->bfa, lps->bfa_tag);
1278a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, event);
1279a36c61f9SKrishna Gudipati 
1280a36c61f9SKrishna Gudipati 	switch (event) {
1281a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_RESUME:
1282a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_login);
1283ff179e0fSKrishna Gudipati 		bfa_lps_send_login(lps);
1284a36c61f9SKrishna Gudipati 		break;
1285a36c61f9SKrishna Gudipati 
1286a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_OFFLINE:
1287be540a99SKrishna Gudipati 	case BFA_LPS_SM_DELETE:
1288a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1289a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&lps->wqe);
1290a36c61f9SKrishna Gudipati 		break;
1291a36c61f9SKrishna Gudipati 
1292a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_RX_CVL:
1293a36c61f9SKrishna Gudipati 		/*
1294a36c61f9SKrishna Gudipati 		 * Login was not even sent out; so when getting out
1295a36c61f9SKrishna Gudipati 		 * of this state, it will appear like a login retry
1296a36c61f9SKrishna Gudipati 		 * after Clear virtual link
1297a36c61f9SKrishna Gudipati 		 */
1298a36c61f9SKrishna Gudipati 		break;
1299a36c61f9SKrishna Gudipati 
1300a36c61f9SKrishna Gudipati 	default:
1301a36c61f9SKrishna Gudipati 		bfa_sm_fault(lps->bfa, event);
1302a36c61f9SKrishna Gudipati 	}
1303a36c61f9SKrishna Gudipati }
1304a36c61f9SKrishna Gudipati 
13055fbe25c7SJing Huang /*
1306a36c61f9SKrishna Gudipati  * login complete
1307a36c61f9SKrishna Gudipati  */
1308a36c61f9SKrishna Gudipati static void
1309a36c61f9SKrishna Gudipati bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
1310a36c61f9SKrishna Gudipati {
13113fd45980SKrishna Gudipati 	bfa_trc(lps->bfa, lps->bfa_tag);
1312a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, event);
1313a36c61f9SKrishna Gudipati 
1314a36c61f9SKrishna Gudipati 	switch (event) {
1315a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_LOGOUT:
1316a36c61f9SKrishna Gudipati 		if (bfa_reqq_full(lps->bfa, lps->reqq)) {
1317a36c61f9SKrishna Gudipati 			bfa_sm_set_state(lps, bfa_lps_sm_logowait);
1318a36c61f9SKrishna Gudipati 			bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe);
1319a36c61f9SKrishna Gudipati 		} else {
1320a36c61f9SKrishna Gudipati 			bfa_sm_set_state(lps, bfa_lps_sm_logout);
1321a36c61f9SKrishna Gudipati 			bfa_lps_send_logout(lps);
1322a36c61f9SKrishna Gudipati 		}
1323a36c61f9SKrishna Gudipati 		bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1324a36c61f9SKrishna Gudipati 			BFA_PL_EID_LOGO, 0, "Logout");
1325a36c61f9SKrishna Gudipati 		break;
1326a36c61f9SKrishna Gudipati 
1327a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_RX_CVL:
1328a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1329a36c61f9SKrishna Gudipati 
1330a36c61f9SKrishna Gudipati 		/* Let the vport module know about this event */
1331a36c61f9SKrishna Gudipati 		bfa_lps_cvl_event(lps);
1332a36c61f9SKrishna Gudipati 		bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1333a36c61f9SKrishna Gudipati 			BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
1334a36c61f9SKrishna Gudipati 		break;
1335a36c61f9SKrishna Gudipati 
1336b704495cSKrishna Gudipati 	case BFA_LPS_SM_SET_N2N_PID:
1337b704495cSKrishna Gudipati 		if (bfa_reqq_full(lps->bfa, lps->reqq)) {
1338b704495cSKrishna Gudipati 			bfa_sm_set_state(lps, bfa_lps_sm_online_n2n_pid_wait);
1339b704495cSKrishna Gudipati 			bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe);
1340b704495cSKrishna Gudipati 		} else
1341b704495cSKrishna Gudipati 			bfa_lps_send_set_n2n_pid(lps);
1342b704495cSKrishna Gudipati 		break;
1343b704495cSKrishna Gudipati 
1344a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_OFFLINE:
1345a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_DELETE:
1346a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1347a36c61f9SKrishna Gudipati 		break;
1348a36c61f9SKrishna Gudipati 
1349a36c61f9SKrishna Gudipati 	default:
1350a36c61f9SKrishna Gudipati 		bfa_sm_fault(lps->bfa, event);
1351a36c61f9SKrishna Gudipati 	}
1352a36c61f9SKrishna Gudipati }
1353a36c61f9SKrishna Gudipati 
13548f4bfaddSJing Huang /*
1355b704495cSKrishna Gudipati  * login complete
1356b704495cSKrishna Gudipati  */
1357b704495cSKrishna Gudipati static void
1358b704495cSKrishna Gudipati bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, enum bfa_lps_event event)
1359b704495cSKrishna Gudipati {
13603fd45980SKrishna Gudipati 	bfa_trc(lps->bfa, lps->bfa_tag);
1361b704495cSKrishna Gudipati 	bfa_trc(lps->bfa, event);
1362b704495cSKrishna Gudipati 
1363b704495cSKrishna Gudipati 	switch (event) {
1364b704495cSKrishna Gudipati 	case BFA_LPS_SM_RESUME:
1365b704495cSKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_online);
1366b704495cSKrishna Gudipati 		bfa_lps_send_set_n2n_pid(lps);
1367b704495cSKrishna Gudipati 		break;
1368b704495cSKrishna Gudipati 
1369b704495cSKrishna Gudipati 	case BFA_LPS_SM_LOGOUT:
1370b704495cSKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_logowait);
1371b704495cSKrishna Gudipati 		bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1372b704495cSKrishna Gudipati 			BFA_PL_EID_LOGO, 0, "Logout");
1373b704495cSKrishna Gudipati 		break;
1374b704495cSKrishna Gudipati 
1375b704495cSKrishna Gudipati 	case BFA_LPS_SM_RX_CVL:
1376b704495cSKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1377b704495cSKrishna Gudipati 		bfa_reqq_wcancel(&lps->wqe);
1378b704495cSKrishna Gudipati 
1379b704495cSKrishna Gudipati 		/* Let the vport module know about this event */
1380b704495cSKrishna Gudipati 		bfa_lps_cvl_event(lps);
1381b704495cSKrishna Gudipati 		bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1382b704495cSKrishna Gudipati 			BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
1383b704495cSKrishna Gudipati 		break;
1384b704495cSKrishna Gudipati 
1385b704495cSKrishna Gudipati 	case BFA_LPS_SM_OFFLINE:
1386b704495cSKrishna Gudipati 	case BFA_LPS_SM_DELETE:
1387b704495cSKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1388b704495cSKrishna Gudipati 		bfa_reqq_wcancel(&lps->wqe);
1389b704495cSKrishna Gudipati 		break;
1390b704495cSKrishna Gudipati 
1391b704495cSKrishna Gudipati 	default:
1392b704495cSKrishna Gudipati 		bfa_sm_fault(lps->bfa, event);
1393b704495cSKrishna Gudipati 	}
1394b704495cSKrishna Gudipati }
1395b704495cSKrishna Gudipati 
13965fbe25c7SJing Huang /*
1397a36c61f9SKrishna Gudipati  * logout in progress - awaiting firmware response
1398a36c61f9SKrishna Gudipati  */
1399a36c61f9SKrishna Gudipati static void
1400a36c61f9SKrishna Gudipati bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event)
1401a36c61f9SKrishna Gudipati {
14023fd45980SKrishna Gudipati 	bfa_trc(lps->bfa, lps->bfa_tag);
1403a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, event);
1404a36c61f9SKrishna Gudipati 
1405a36c61f9SKrishna Gudipati 	switch (event) {
1406a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_FWRSP:
1407a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1408a36c61f9SKrishna Gudipati 		bfa_lps_logout_comp(lps);
1409a36c61f9SKrishna Gudipati 		break;
1410a36c61f9SKrishna Gudipati 
1411a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_OFFLINE:
1412be540a99SKrishna Gudipati 	case BFA_LPS_SM_DELETE:
1413a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1414a36c61f9SKrishna Gudipati 		break;
1415a36c61f9SKrishna Gudipati 
1416a36c61f9SKrishna Gudipati 	default:
1417a36c61f9SKrishna Gudipati 		bfa_sm_fault(lps->bfa, event);
1418a36c61f9SKrishna Gudipati 	}
1419a36c61f9SKrishna Gudipati }
1420a36c61f9SKrishna Gudipati 
14215fbe25c7SJing Huang /*
1422a36c61f9SKrishna Gudipati  * logout pending -- awaiting space in request queue
1423a36c61f9SKrishna Gudipati  */
1424a36c61f9SKrishna Gudipati static void
1425a36c61f9SKrishna Gudipati bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event)
1426a36c61f9SKrishna Gudipati {
14273fd45980SKrishna Gudipati 	bfa_trc(lps->bfa, lps->bfa_tag);
1428a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, event);
1429a36c61f9SKrishna Gudipati 
1430a36c61f9SKrishna Gudipati 	switch (event) {
1431a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_RESUME:
1432a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_logout);
1433a36c61f9SKrishna Gudipati 		bfa_lps_send_logout(lps);
1434a36c61f9SKrishna Gudipati 		break;
1435a36c61f9SKrishna Gudipati 
1436a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_OFFLINE:
1437be540a99SKrishna Gudipati 	case BFA_LPS_SM_DELETE:
1438a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1439a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&lps->wqe);
1440a36c61f9SKrishna Gudipati 		break;
1441a36c61f9SKrishna Gudipati 
1442a36c61f9SKrishna Gudipati 	default:
1443a36c61f9SKrishna Gudipati 		bfa_sm_fault(lps->bfa, event);
1444a36c61f9SKrishna Gudipati 	}
1445a36c61f9SKrishna Gudipati }
1446a36c61f9SKrishna Gudipati 
1447a36c61f9SKrishna Gudipati 
1448a36c61f9SKrishna Gudipati 
14495fbe25c7SJing Huang /*
1450a36c61f9SKrishna Gudipati  *  lps_pvt BFA LPS private functions
1451a36c61f9SKrishna Gudipati  */
1452a36c61f9SKrishna Gudipati 
14535fbe25c7SJing Huang /*
1454a36c61f9SKrishna Gudipati  * return memory requirement
1455a36c61f9SKrishna Gudipati  */
1456a36c61f9SKrishna Gudipati static void
14574507025dSKrishna Gudipati bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo,
14584507025dSKrishna Gudipati 		struct bfa_s *bfa)
1459a36c61f9SKrishna Gudipati {
14604507025dSKrishna Gudipati 	struct bfa_mem_kva_s *lps_kva = BFA_MEM_LPS_KVA(bfa);
14614507025dSKrishna Gudipati 
1462a36c61f9SKrishna Gudipati 	if (cfg->drvcfg.min_cfg)
14634507025dSKrishna Gudipati 		bfa_mem_kva_setup(minfo, lps_kva,
14644507025dSKrishna Gudipati 			sizeof(struct bfa_lps_s) * BFA_LPS_MIN_LPORTS);
1465a36c61f9SKrishna Gudipati 	else
14664507025dSKrishna Gudipati 		bfa_mem_kva_setup(minfo, lps_kva,
14674507025dSKrishna Gudipati 			sizeof(struct bfa_lps_s) * BFA_LPS_MAX_LPORTS);
1468a36c61f9SKrishna Gudipati }
1469a36c61f9SKrishna Gudipati 
14705fbe25c7SJing Huang /*
1471a36c61f9SKrishna Gudipati  * bfa module attach at initialization time
1472a36c61f9SKrishna Gudipati  */
1473a36c61f9SKrishna Gudipati static void
1474a36c61f9SKrishna Gudipati bfa_lps_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
14754507025dSKrishna Gudipati 	struct bfa_pcidev_s *pcidev)
1476a36c61f9SKrishna Gudipati {
1477a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
1478a36c61f9SKrishna Gudipati 	struct bfa_lps_s	*lps;
1479a36c61f9SKrishna Gudipati 	int			i;
1480a36c61f9SKrishna Gudipati 
1481a36c61f9SKrishna Gudipati 	mod->num_lps = BFA_LPS_MAX_LPORTS;
1482a36c61f9SKrishna Gudipati 	if (cfg->drvcfg.min_cfg)
1483a36c61f9SKrishna Gudipati 		mod->num_lps = BFA_LPS_MIN_LPORTS;
1484a36c61f9SKrishna Gudipati 	else
1485a36c61f9SKrishna Gudipati 		mod->num_lps = BFA_LPS_MAX_LPORTS;
14864507025dSKrishna Gudipati 	mod->lps_arr = lps = (struct bfa_lps_s *) bfa_mem_kva_curp(mod);
1487a36c61f9SKrishna Gudipati 
14884507025dSKrishna Gudipati 	bfa_mem_kva_curp(mod) += mod->num_lps * sizeof(struct bfa_lps_s);
1489a36c61f9SKrishna Gudipati 
1490a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->lps_free_q);
1491a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->lps_active_q);
14923fd45980SKrishna Gudipati 	INIT_LIST_HEAD(&mod->lps_login_q);
1493a36c61f9SKrishna Gudipati 
1494a36c61f9SKrishna Gudipati 	for (i = 0; i < mod->num_lps; i++, lps++) {
1495a36c61f9SKrishna Gudipati 		lps->bfa	= bfa;
14963fd45980SKrishna Gudipati 		lps->bfa_tag	= (u8) i;
1497a36c61f9SKrishna Gudipati 		lps->reqq	= BFA_REQQ_LPS;
1498a36c61f9SKrishna Gudipati 		bfa_reqq_winit(&lps->wqe, bfa_lps_reqq_resume, lps);
1499a36c61f9SKrishna Gudipati 		list_add_tail(&lps->qe, &mod->lps_free_q);
1500a36c61f9SKrishna Gudipati 	}
1501a36c61f9SKrishna Gudipati }
1502a36c61f9SKrishna Gudipati 
1503a36c61f9SKrishna Gudipati static void
1504a36c61f9SKrishna Gudipati bfa_lps_detach(struct bfa_s *bfa)
1505a36c61f9SKrishna Gudipati {
1506a36c61f9SKrishna Gudipati }
1507a36c61f9SKrishna Gudipati 
1508a36c61f9SKrishna Gudipati static void
1509a36c61f9SKrishna Gudipati bfa_lps_start(struct bfa_s *bfa)
1510a36c61f9SKrishna Gudipati {
1511a36c61f9SKrishna Gudipati }
1512a36c61f9SKrishna Gudipati 
1513a36c61f9SKrishna Gudipati static void
1514a36c61f9SKrishna Gudipati bfa_lps_stop(struct bfa_s *bfa)
1515a36c61f9SKrishna Gudipati {
1516a36c61f9SKrishna Gudipati }
1517a36c61f9SKrishna Gudipati 
15185fbe25c7SJing Huang /*
1519a36c61f9SKrishna Gudipati  * IOC in disabled state -- consider all lps offline
1520a36c61f9SKrishna Gudipati  */
1521a36c61f9SKrishna Gudipati static void
1522a36c61f9SKrishna Gudipati bfa_lps_iocdisable(struct bfa_s *bfa)
1523a36c61f9SKrishna Gudipati {
1524a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
1525a36c61f9SKrishna Gudipati 	struct bfa_lps_s	*lps;
1526a36c61f9SKrishna Gudipati 	struct list_head		*qe, *qen;
1527a36c61f9SKrishna Gudipati 
1528a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &mod->lps_active_q) {
1529a36c61f9SKrishna Gudipati 		lps = (struct bfa_lps_s *) qe;
1530a36c61f9SKrishna Gudipati 		bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE);
1531a36c61f9SKrishna Gudipati 	}
15323fd45980SKrishna Gudipati 	list_for_each_safe(qe, qen, &mod->lps_login_q) {
15333fd45980SKrishna Gudipati 		lps = (struct bfa_lps_s *) qe;
15343fd45980SKrishna Gudipati 		bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE);
15353fd45980SKrishna Gudipati 	}
15363fd45980SKrishna Gudipati 	list_splice_tail_init(&mod->lps_login_q, &mod->lps_active_q);
1537a36c61f9SKrishna Gudipati }
1538a36c61f9SKrishna Gudipati 
15395fbe25c7SJing Huang /*
1540a36c61f9SKrishna Gudipati  * Firmware login response
1541a36c61f9SKrishna Gudipati  */
1542a36c61f9SKrishna Gudipati static void
1543a36c61f9SKrishna Gudipati bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp)
1544a36c61f9SKrishna Gudipati {
1545a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
1546a36c61f9SKrishna Gudipati 	struct bfa_lps_s	*lps;
1547a36c61f9SKrishna Gudipati 
15483fd45980SKrishna Gudipati 	WARN_ON(rsp->bfa_tag >= mod->num_lps);
15493fd45980SKrishna Gudipati 	lps = BFA_LPS_FROM_TAG(mod, rsp->bfa_tag);
1550a36c61f9SKrishna Gudipati 
1551a36c61f9SKrishna Gudipati 	lps->status = rsp->status;
1552a36c61f9SKrishna Gudipati 	switch (rsp->status) {
1553a36c61f9SKrishna Gudipati 	case BFA_STATUS_OK:
15543fd45980SKrishna Gudipati 		lps->fw_tag	= rsp->fw_tag;
1555a36c61f9SKrishna Gudipati 		lps->fport	= rsp->f_port;
1556b704495cSKrishna Gudipati 		if (lps->fport)
1557a36c61f9SKrishna Gudipati 			lps->lp_pid = rsp->lp_pid;
1558b704495cSKrishna Gudipati 		lps->npiv_en	= rsp->npiv_en;
1559ba816ea8SJing Huang 		lps->pr_bbcred	= be16_to_cpu(rsp->bb_credit);
1560a36c61f9SKrishna Gudipati 		lps->pr_pwwn	= rsp->port_name;
1561a36c61f9SKrishna Gudipati 		lps->pr_nwwn	= rsp->node_name;
1562a36c61f9SKrishna Gudipati 		lps->auth_req	= rsp->auth_req;
1563a36c61f9SKrishna Gudipati 		lps->lp_mac	= rsp->lp_mac;
1564a36c61f9SKrishna Gudipati 		lps->brcd_switch = rsp->brcd_switch;
1565a36c61f9SKrishna Gudipati 		lps->fcf_mac	= rsp->fcf_mac;
1566be540a99SKrishna Gudipati 		lps->pr_bbscn	= rsp->bb_scn;
1567a36c61f9SKrishna Gudipati 
1568a36c61f9SKrishna Gudipati 		break;
1569a36c61f9SKrishna Gudipati 
1570a36c61f9SKrishna Gudipati 	case BFA_STATUS_FABRIC_RJT:
1571a36c61f9SKrishna Gudipati 		lps->lsrjt_rsn = rsp->lsrjt_rsn;
1572a36c61f9SKrishna Gudipati 		lps->lsrjt_expl = rsp->lsrjt_expl;
1573a36c61f9SKrishna Gudipati 
1574a36c61f9SKrishna Gudipati 		break;
1575a36c61f9SKrishna Gudipati 
1576a36c61f9SKrishna Gudipati 	case BFA_STATUS_EPROTOCOL:
1577a36c61f9SKrishna Gudipati 		lps->ext_status = rsp->ext_status;
1578a36c61f9SKrishna Gudipati 
1579a36c61f9SKrishna Gudipati 		break;
1580a36c61f9SKrishna Gudipati 
15813fd45980SKrishna Gudipati 	case BFA_STATUS_VPORT_MAX:
1582ff179e0fSKrishna Gudipati 		if (rsp->ext_status)
15833fd45980SKrishna Gudipati 			bfa_lps_no_res(lps, rsp->ext_status);
15843fd45980SKrishna Gudipati 		break;
15853fd45980SKrishna Gudipati 
1586a36c61f9SKrishna Gudipati 	default:
1587a36c61f9SKrishna Gudipati 		/* Nothing to do with other status */
1588a36c61f9SKrishna Gudipati 		break;
1589a36c61f9SKrishna Gudipati 	}
1590a36c61f9SKrishna Gudipati 
15913fd45980SKrishna Gudipati 	list_del(&lps->qe);
15923fd45980SKrishna Gudipati 	list_add_tail(&lps->qe, &mod->lps_active_q);
1593a36c61f9SKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
1594a36c61f9SKrishna Gudipati }
1595a36c61f9SKrishna Gudipati 
15963fd45980SKrishna Gudipati static void
15973fd45980SKrishna Gudipati bfa_lps_no_res(struct bfa_lps_s *first_lps, u8 count)
15983fd45980SKrishna Gudipati {
15993fd45980SKrishna Gudipati 	struct bfa_s		*bfa = first_lps->bfa;
16003fd45980SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
16013fd45980SKrishna Gudipati 	struct list_head	*qe, *qe_next;
16023fd45980SKrishna Gudipati 	struct bfa_lps_s	*lps;
16033fd45980SKrishna Gudipati 
16043fd45980SKrishna Gudipati 	bfa_trc(bfa, count);
16053fd45980SKrishna Gudipati 
16063fd45980SKrishna Gudipati 	qe = bfa_q_next(first_lps);
16073fd45980SKrishna Gudipati 
16083fd45980SKrishna Gudipati 	while (count && qe) {
16093fd45980SKrishna Gudipati 		qe_next = bfa_q_next(qe);
16103fd45980SKrishna Gudipati 		lps = (struct bfa_lps_s *)qe;
16113fd45980SKrishna Gudipati 		bfa_trc(bfa, lps->bfa_tag);
16123fd45980SKrishna Gudipati 		lps->status = first_lps->status;
16133fd45980SKrishna Gudipati 		list_del(&lps->qe);
16143fd45980SKrishna Gudipati 		list_add_tail(&lps->qe, &mod->lps_active_q);
16153fd45980SKrishna Gudipati 		bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
16163fd45980SKrishna Gudipati 		qe = qe_next;
16173fd45980SKrishna Gudipati 		count--;
16183fd45980SKrishna Gudipati 	}
16193fd45980SKrishna Gudipati }
16203fd45980SKrishna Gudipati 
16215fbe25c7SJing Huang /*
1622a36c61f9SKrishna Gudipati  * Firmware logout response
1623a36c61f9SKrishna Gudipati  */
1624a36c61f9SKrishna Gudipati static void
1625a36c61f9SKrishna Gudipati bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp)
1626a36c61f9SKrishna Gudipati {
1627a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
1628a36c61f9SKrishna Gudipati 	struct bfa_lps_s	*lps;
1629a36c61f9SKrishna Gudipati 
16303fd45980SKrishna Gudipati 	WARN_ON(rsp->bfa_tag >= mod->num_lps);
16313fd45980SKrishna Gudipati 	lps = BFA_LPS_FROM_TAG(mod, rsp->bfa_tag);
1632a36c61f9SKrishna Gudipati 
1633a36c61f9SKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
1634a36c61f9SKrishna Gudipati }
1635a36c61f9SKrishna Gudipati 
16365fbe25c7SJing Huang /*
1637a36c61f9SKrishna Gudipati  * Firmware received a Clear virtual link request (for FCoE)
1638a36c61f9SKrishna Gudipati  */
1639a36c61f9SKrishna Gudipati static void
1640a36c61f9SKrishna Gudipati bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl)
1641a36c61f9SKrishna Gudipati {
1642a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
1643a36c61f9SKrishna Gudipati 	struct bfa_lps_s	*lps;
1644a36c61f9SKrishna Gudipati 
16453fd45980SKrishna Gudipati 	lps = BFA_LPS_FROM_TAG(mod, cvl->bfa_tag);
1646a36c61f9SKrishna Gudipati 
1647a36c61f9SKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL);
1648a36c61f9SKrishna Gudipati }
1649a36c61f9SKrishna Gudipati 
16505fbe25c7SJing Huang /*
1651a36c61f9SKrishna Gudipati  * Space is available in request queue, resume queueing request to firmware.
1652a36c61f9SKrishna Gudipati  */
1653a36c61f9SKrishna Gudipati static void
1654a36c61f9SKrishna Gudipati bfa_lps_reqq_resume(void *lps_arg)
1655a36c61f9SKrishna Gudipati {
1656a36c61f9SKrishna Gudipati 	struct bfa_lps_s	*lps = lps_arg;
1657a36c61f9SKrishna Gudipati 
1658a36c61f9SKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_RESUME);
1659a36c61f9SKrishna Gudipati }
1660a36c61f9SKrishna Gudipati 
16615fbe25c7SJing Huang /*
1662a36c61f9SKrishna Gudipati  * lps is freed -- triggered by vport delete
1663a36c61f9SKrishna Gudipati  */
1664a36c61f9SKrishna Gudipati static void
1665a36c61f9SKrishna Gudipati bfa_lps_free(struct bfa_lps_s *lps)
1666a36c61f9SKrishna Gudipati {
1667a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(lps->bfa);
1668a36c61f9SKrishna Gudipati 
1669a36c61f9SKrishna Gudipati 	lps->lp_pid = 0;
1670a36c61f9SKrishna Gudipati 	list_del(&lps->qe);
1671a36c61f9SKrishna Gudipati 	list_add_tail(&lps->qe, &mod->lps_free_q);
1672a36c61f9SKrishna Gudipati }
1673a36c61f9SKrishna Gudipati 
16745fbe25c7SJing Huang /*
1675a36c61f9SKrishna Gudipati  * send login request to firmware
1676a36c61f9SKrishna Gudipati  */
1677a36c61f9SKrishna Gudipati static void
1678a36c61f9SKrishna Gudipati bfa_lps_send_login(struct bfa_lps_s *lps)
1679a36c61f9SKrishna Gudipati {
16803fd45980SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(lps->bfa);
1681a36c61f9SKrishna Gudipati 	struct bfi_lps_login_req_s	*m;
1682a36c61f9SKrishna Gudipati 
1683a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(lps->bfa, lps->reqq);
1684d4b671c5SJing Huang 	WARN_ON(!m);
1685a36c61f9SKrishna Gudipati 
1686a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGIN_REQ,
16873fd45980SKrishna Gudipati 		bfa_fn_lpu(lps->bfa));
1688a36c61f9SKrishna Gudipati 
16893fd45980SKrishna Gudipati 	m->bfa_tag	= lps->bfa_tag;
1690a36c61f9SKrishna Gudipati 	m->alpa		= lps->alpa;
1691ba816ea8SJing Huang 	m->pdu_size	= cpu_to_be16(lps->pdusz);
1692a36c61f9SKrishna Gudipati 	m->pwwn		= lps->pwwn;
1693a36c61f9SKrishna Gudipati 	m->nwwn		= lps->nwwn;
1694a36c61f9SKrishna Gudipati 	m->fdisc	= lps->fdisc;
1695a36c61f9SKrishna Gudipati 	m->auth_en	= lps->auth_en;
1696be540a99SKrishna Gudipati 	m->bb_scn	= lps->bb_scn;
1697a36c61f9SKrishna Gudipati 
16983fd45980SKrishna Gudipati 	bfa_reqq_produce(lps->bfa, lps->reqq, m->mh);
16993fd45980SKrishna Gudipati 	list_del(&lps->qe);
17003fd45980SKrishna Gudipati 	list_add_tail(&lps->qe, &mod->lps_login_q);
1701a36c61f9SKrishna Gudipati }
1702a36c61f9SKrishna Gudipati 
17035fbe25c7SJing Huang /*
1704a36c61f9SKrishna Gudipati  * send logout request to firmware
1705a36c61f9SKrishna Gudipati  */
1706a36c61f9SKrishna Gudipati static void
1707a36c61f9SKrishna Gudipati bfa_lps_send_logout(struct bfa_lps_s *lps)
1708a36c61f9SKrishna Gudipati {
1709a36c61f9SKrishna Gudipati 	struct bfi_lps_logout_req_s *m;
1710a36c61f9SKrishna Gudipati 
1711a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(lps->bfa, lps->reqq);
1712d4b671c5SJing Huang 	WARN_ON(!m);
1713a36c61f9SKrishna Gudipati 
1714a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGOUT_REQ,
17153fd45980SKrishna Gudipati 		bfa_fn_lpu(lps->bfa));
1716a36c61f9SKrishna Gudipati 
17173fd45980SKrishna Gudipati 	m->fw_tag = lps->fw_tag;
1718a36c61f9SKrishna Gudipati 	m->port_name = lps->pwwn;
17193fd45980SKrishna Gudipati 	bfa_reqq_produce(lps->bfa, lps->reqq, m->mh);
1720a36c61f9SKrishna Gudipati }
1721a36c61f9SKrishna Gudipati 
17228f4bfaddSJing Huang /*
1723b704495cSKrishna Gudipati  * send n2n pid set request to firmware
1724b704495cSKrishna Gudipati  */
1725b704495cSKrishna Gudipati static void
1726b704495cSKrishna Gudipati bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps)
1727b704495cSKrishna Gudipati {
1728b704495cSKrishna Gudipati 	struct bfi_lps_n2n_pid_req_s *m;
1729b704495cSKrishna Gudipati 
1730b704495cSKrishna Gudipati 	m = bfa_reqq_next(lps->bfa, lps->reqq);
1731d4b671c5SJing Huang 	WARN_ON(!m);
1732b704495cSKrishna Gudipati 
1733b704495cSKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_N2N_PID_REQ,
17343fd45980SKrishna Gudipati 		bfa_fn_lpu(lps->bfa));
1735b704495cSKrishna Gudipati 
17363fd45980SKrishna Gudipati 	m->fw_tag = lps->fw_tag;
1737b704495cSKrishna Gudipati 	m->lp_pid = lps->lp_pid;
17383fd45980SKrishna Gudipati 	bfa_reqq_produce(lps->bfa, lps->reqq, m->mh);
1739b704495cSKrishna Gudipati }
1740b704495cSKrishna Gudipati 
17415fbe25c7SJing Huang /*
1742a36c61f9SKrishna Gudipati  * Indirect login completion handler for non-fcs
1743a36c61f9SKrishna Gudipati  */
1744a36c61f9SKrishna Gudipati static void
1745a36c61f9SKrishna Gudipati bfa_lps_login_comp_cb(void *arg, bfa_boolean_t complete)
1746a36c61f9SKrishna Gudipati {
1747a36c61f9SKrishna Gudipati 	struct bfa_lps_s *lps	= arg;
1748a36c61f9SKrishna Gudipati 
1749a36c61f9SKrishna Gudipati 	if (!complete)
1750a36c61f9SKrishna Gudipati 		return;
1751a36c61f9SKrishna Gudipati 
1752a36c61f9SKrishna Gudipati 	if (lps->fdisc)
1753a36c61f9SKrishna Gudipati 		bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status);
1754a36c61f9SKrishna Gudipati 	else
1755a36c61f9SKrishna Gudipati 		bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status);
1756a36c61f9SKrishna Gudipati }
1757a36c61f9SKrishna Gudipati 
17585fbe25c7SJing Huang /*
1759a36c61f9SKrishna Gudipati  * Login completion handler -- direct call for fcs, queue for others
1760a36c61f9SKrishna Gudipati  */
1761a36c61f9SKrishna Gudipati static void
1762a36c61f9SKrishna Gudipati bfa_lps_login_comp(struct bfa_lps_s *lps)
1763a36c61f9SKrishna Gudipati {
1764a36c61f9SKrishna Gudipati 	if (!lps->bfa->fcs) {
1765a36c61f9SKrishna Gudipati 		bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_login_comp_cb,
1766a36c61f9SKrishna Gudipati 			lps);
1767a36c61f9SKrishna Gudipati 		return;
1768a36c61f9SKrishna Gudipati 	}
1769a36c61f9SKrishna Gudipati 
1770a36c61f9SKrishna Gudipati 	if (lps->fdisc)
1771a36c61f9SKrishna Gudipati 		bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status);
1772a36c61f9SKrishna Gudipati 	else
1773a36c61f9SKrishna Gudipati 		bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status);
1774a36c61f9SKrishna Gudipati }
1775a36c61f9SKrishna Gudipati 
17765fbe25c7SJing Huang /*
1777a36c61f9SKrishna Gudipati  * Indirect logout completion handler for non-fcs
1778a36c61f9SKrishna Gudipati  */
1779a36c61f9SKrishna Gudipati static void
1780a36c61f9SKrishna Gudipati bfa_lps_logout_comp_cb(void *arg, bfa_boolean_t complete)
1781a36c61f9SKrishna Gudipati {
1782a36c61f9SKrishna Gudipati 	struct bfa_lps_s *lps	= arg;
1783a36c61f9SKrishna Gudipati 
1784a36c61f9SKrishna Gudipati 	if (!complete)
1785a36c61f9SKrishna Gudipati 		return;
1786a36c61f9SKrishna Gudipati 
1787a36c61f9SKrishna Gudipati 	if (lps->fdisc)
1788a36c61f9SKrishna Gudipati 		bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg);
1789a36c61f9SKrishna Gudipati }
1790a36c61f9SKrishna Gudipati 
17915fbe25c7SJing Huang /*
1792a36c61f9SKrishna Gudipati  * Logout completion handler -- direct call for fcs, queue for others
1793a36c61f9SKrishna Gudipati  */
1794a36c61f9SKrishna Gudipati static void
1795a36c61f9SKrishna Gudipati bfa_lps_logout_comp(struct bfa_lps_s *lps)
1796a36c61f9SKrishna Gudipati {
1797a36c61f9SKrishna Gudipati 	if (!lps->bfa->fcs) {
1798a36c61f9SKrishna Gudipati 		bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_logout_comp_cb,
1799a36c61f9SKrishna Gudipati 			lps);
1800a36c61f9SKrishna Gudipati 		return;
1801a36c61f9SKrishna Gudipati 	}
1802a36c61f9SKrishna Gudipati 	if (lps->fdisc)
1803a36c61f9SKrishna Gudipati 		bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg);
1804a36c61f9SKrishna Gudipati }
1805a36c61f9SKrishna Gudipati 
18065fbe25c7SJing Huang /*
1807a36c61f9SKrishna Gudipati  * Clear virtual link completion handler for non-fcs
1808a36c61f9SKrishna Gudipati  */
1809a36c61f9SKrishna Gudipati static void
1810a36c61f9SKrishna Gudipati bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete)
1811a36c61f9SKrishna Gudipati {
1812a36c61f9SKrishna Gudipati 	struct bfa_lps_s *lps	= arg;
1813a36c61f9SKrishna Gudipati 
1814a36c61f9SKrishna Gudipati 	if (!complete)
1815a36c61f9SKrishna Gudipati 		return;
1816a36c61f9SKrishna Gudipati 
1817a36c61f9SKrishna Gudipati 	/* Clear virtual link to base port will result in link down */
1818a36c61f9SKrishna Gudipati 	if (lps->fdisc)
1819a36c61f9SKrishna Gudipati 		bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
1820a36c61f9SKrishna Gudipati }
1821a36c61f9SKrishna Gudipati 
18225fbe25c7SJing Huang /*
1823a36c61f9SKrishna Gudipati  * Received Clear virtual link event --direct call for fcs,
1824a36c61f9SKrishna Gudipati  * queue for others
1825a36c61f9SKrishna Gudipati  */
1826a36c61f9SKrishna Gudipati static void
1827a36c61f9SKrishna Gudipati bfa_lps_cvl_event(struct bfa_lps_s *lps)
1828a36c61f9SKrishna Gudipati {
1829a36c61f9SKrishna Gudipati 	if (!lps->bfa->fcs) {
1830a36c61f9SKrishna Gudipati 		bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb,
1831a36c61f9SKrishna Gudipati 			lps);
1832a36c61f9SKrishna Gudipati 		return;
1833a36c61f9SKrishna Gudipati 	}
1834a36c61f9SKrishna Gudipati 
1835a36c61f9SKrishna Gudipati 	/* Clear virtual link to base port will result in link down */
1836a36c61f9SKrishna Gudipati 	if (lps->fdisc)
1837a36c61f9SKrishna Gudipati 		bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
1838a36c61f9SKrishna Gudipati }
1839a36c61f9SKrishna Gudipati 
1840a36c61f9SKrishna Gudipati 
1841a36c61f9SKrishna Gudipati 
18425fbe25c7SJing Huang /*
1843a36c61f9SKrishna Gudipati  *  lps_public BFA LPS public functions
1844a36c61f9SKrishna Gudipati  */
1845a36c61f9SKrishna Gudipati 
1846a36c61f9SKrishna Gudipati u32
1847a36c61f9SKrishna Gudipati bfa_lps_get_max_vport(struct bfa_s *bfa)
1848a36c61f9SKrishna Gudipati {
1849a36c61f9SKrishna Gudipati 	if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT)
1850a36c61f9SKrishna Gudipati 		return BFA_LPS_MAX_VPORTS_SUPP_CT;
1851a36c61f9SKrishna Gudipati 	else
1852a36c61f9SKrishna Gudipati 		return BFA_LPS_MAX_VPORTS_SUPP_CB;
1853a36c61f9SKrishna Gudipati }
1854a36c61f9SKrishna Gudipati 
18555fbe25c7SJing Huang /*
1856a36c61f9SKrishna Gudipati  * Allocate a lport srvice tag.
1857a36c61f9SKrishna Gudipati  */
1858a36c61f9SKrishna Gudipati struct bfa_lps_s  *
1859a36c61f9SKrishna Gudipati bfa_lps_alloc(struct bfa_s *bfa)
1860a36c61f9SKrishna Gudipati {
1861a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
1862a36c61f9SKrishna Gudipati 	struct bfa_lps_s	*lps = NULL;
1863a36c61f9SKrishna Gudipati 
1864a36c61f9SKrishna Gudipati 	bfa_q_deq(&mod->lps_free_q, &lps);
1865a36c61f9SKrishna Gudipati 
1866a36c61f9SKrishna Gudipati 	if (lps == NULL)
1867a36c61f9SKrishna Gudipati 		return NULL;
1868a36c61f9SKrishna Gudipati 
1869a36c61f9SKrishna Gudipati 	list_add_tail(&lps->qe, &mod->lps_active_q);
1870a36c61f9SKrishna Gudipati 
1871a36c61f9SKrishna Gudipati 	bfa_sm_set_state(lps, bfa_lps_sm_init);
1872a36c61f9SKrishna Gudipati 	return lps;
1873a36c61f9SKrishna Gudipati }
1874a36c61f9SKrishna Gudipati 
18755fbe25c7SJing Huang /*
1876a36c61f9SKrishna Gudipati  * Free lport service tag. This can be called anytime after an alloc.
1877a36c61f9SKrishna Gudipati  * No need to wait for any pending login/logout completions.
1878a36c61f9SKrishna Gudipati  */
1879a36c61f9SKrishna Gudipati void
1880a36c61f9SKrishna Gudipati bfa_lps_delete(struct bfa_lps_s *lps)
1881a36c61f9SKrishna Gudipati {
1882a36c61f9SKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_DELETE);
1883a36c61f9SKrishna Gudipati }
1884a36c61f9SKrishna Gudipati 
18855fbe25c7SJing Huang /*
1886a36c61f9SKrishna Gudipati  * Initiate a lport login.
1887a36c61f9SKrishna Gudipati  */
1888a36c61f9SKrishna Gudipati void
1889a36c61f9SKrishna Gudipati bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz,
1890be540a99SKrishna Gudipati 	wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en, uint8_t bb_scn)
1891a36c61f9SKrishna Gudipati {
1892a36c61f9SKrishna Gudipati 	lps->uarg	= uarg;
1893a36c61f9SKrishna Gudipati 	lps->alpa	= alpa;
1894a36c61f9SKrishna Gudipati 	lps->pdusz	= pdusz;
1895a36c61f9SKrishna Gudipati 	lps->pwwn	= pwwn;
1896a36c61f9SKrishna Gudipati 	lps->nwwn	= nwwn;
1897a36c61f9SKrishna Gudipati 	lps->fdisc	= BFA_FALSE;
1898a36c61f9SKrishna Gudipati 	lps->auth_en	= auth_en;
1899be540a99SKrishna Gudipati 	lps->bb_scn	= bb_scn;
1900a36c61f9SKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN);
1901a36c61f9SKrishna Gudipati }
1902a36c61f9SKrishna Gudipati 
19035fbe25c7SJing Huang /*
1904a36c61f9SKrishna Gudipati  * Initiate a lport fdisc login.
1905a36c61f9SKrishna Gudipati  */
1906a36c61f9SKrishna Gudipati void
1907a36c61f9SKrishna Gudipati bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn,
1908a36c61f9SKrishna Gudipati 	wwn_t nwwn)
1909a36c61f9SKrishna Gudipati {
1910a36c61f9SKrishna Gudipati 	lps->uarg	= uarg;
1911a36c61f9SKrishna Gudipati 	lps->alpa	= 0;
1912a36c61f9SKrishna Gudipati 	lps->pdusz	= pdusz;
1913a36c61f9SKrishna Gudipati 	lps->pwwn	= pwwn;
1914a36c61f9SKrishna Gudipati 	lps->nwwn	= nwwn;
1915a36c61f9SKrishna Gudipati 	lps->fdisc	= BFA_TRUE;
1916a36c61f9SKrishna Gudipati 	lps->auth_en	= BFA_FALSE;
1917a36c61f9SKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN);
1918a36c61f9SKrishna Gudipati }
1919a36c61f9SKrishna Gudipati 
1920a36c61f9SKrishna Gudipati 
19215fbe25c7SJing Huang /*
1922a36c61f9SKrishna Gudipati  * Initiate a lport FDSIC logout.
1923a36c61f9SKrishna Gudipati  */
1924a36c61f9SKrishna Gudipati void
1925a36c61f9SKrishna Gudipati bfa_lps_fdisclogo(struct bfa_lps_s *lps)
1926a36c61f9SKrishna Gudipati {
1927a36c61f9SKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT);
1928a36c61f9SKrishna Gudipati }
1929a36c61f9SKrishna Gudipati 
19303fd45980SKrishna Gudipati u8
19313fd45980SKrishna Gudipati bfa_lps_get_fwtag(struct bfa_s *bfa, u8 lp_tag)
19323fd45980SKrishna Gudipati {
19333fd45980SKrishna Gudipati 	struct bfa_lps_mod_s    *mod = BFA_LPS_MOD(bfa);
19343fd45980SKrishna Gudipati 
19353fd45980SKrishna Gudipati 	return BFA_LPS_FROM_TAG(mod, lp_tag)->fw_tag;
19363fd45980SKrishna Gudipati }
1937a36c61f9SKrishna Gudipati 
19385fbe25c7SJing Huang /*
1939a36c61f9SKrishna Gudipati  * Return lport services tag given the pid
1940a36c61f9SKrishna Gudipati  */
1941a36c61f9SKrishna Gudipati u8
1942a36c61f9SKrishna Gudipati bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid)
1943a36c61f9SKrishna Gudipati {
1944a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
1945a36c61f9SKrishna Gudipati 	struct bfa_lps_s	*lps;
1946a36c61f9SKrishna Gudipati 	int			i;
1947a36c61f9SKrishna Gudipati 
1948a36c61f9SKrishna Gudipati 	for (i = 0, lps = mod->lps_arr; i < mod->num_lps; i++, lps++) {
1949a36c61f9SKrishna Gudipati 		if (lps->lp_pid == pid)
19503fd45980SKrishna Gudipati 			return lps->bfa_tag;
1951a36c61f9SKrishna Gudipati 	}
1952a36c61f9SKrishna Gudipati 
1953a36c61f9SKrishna Gudipati 	/* Return base port tag anyway */
1954a36c61f9SKrishna Gudipati 	return 0;
1955a36c61f9SKrishna Gudipati }
1956a36c61f9SKrishna Gudipati 
1957a36c61f9SKrishna Gudipati 
19585fbe25c7SJing Huang /*
1959a36c61f9SKrishna Gudipati  * return port id assigned to the base lport
1960a36c61f9SKrishna Gudipati  */
1961a36c61f9SKrishna Gudipati u32
1962a36c61f9SKrishna Gudipati bfa_lps_get_base_pid(struct bfa_s *bfa)
1963a36c61f9SKrishna Gudipati {
1964a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
1965a36c61f9SKrishna Gudipati 
1966a36c61f9SKrishna Gudipati 	return BFA_LPS_FROM_TAG(mod, 0)->lp_pid;
1967a36c61f9SKrishna Gudipati }
1968a36c61f9SKrishna Gudipati 
19698f4bfaddSJing Huang /*
1970b704495cSKrishna Gudipati  * Set PID in case of n2n (which is assigned during PLOGI)
1971b704495cSKrishna Gudipati  */
1972b704495cSKrishna Gudipati void
1973b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(struct bfa_lps_s *lps, uint32_t n2n_pid)
1974b704495cSKrishna Gudipati {
19753fd45980SKrishna Gudipati 	bfa_trc(lps->bfa, lps->bfa_tag);
1976b704495cSKrishna Gudipati 	bfa_trc(lps->bfa, n2n_pid);
1977b704495cSKrishna Gudipati 
1978b704495cSKrishna Gudipati 	lps->lp_pid = n2n_pid;
1979b704495cSKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID);
1980b704495cSKrishna Gudipati }
1981b704495cSKrishna Gudipati 
19825fbe25c7SJing Huang /*
1983a36c61f9SKrishna Gudipati  * LPS firmware message class handler.
1984a36c61f9SKrishna Gudipati  */
1985a36c61f9SKrishna Gudipati void
1986a36c61f9SKrishna Gudipati bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
1987a36c61f9SKrishna Gudipati {
1988a36c61f9SKrishna Gudipati 	union bfi_lps_i2h_msg_u	msg;
1989a36c61f9SKrishna Gudipati 
1990a36c61f9SKrishna Gudipati 	bfa_trc(bfa, m->mhdr.msg_id);
1991a36c61f9SKrishna Gudipati 	msg.msg = m;
1992a36c61f9SKrishna Gudipati 
1993a36c61f9SKrishna Gudipati 	switch (m->mhdr.msg_id) {
199443ffdf4dSKrishna Gudipati 	case BFI_LPS_I2H_LOGIN_RSP:
1995a36c61f9SKrishna Gudipati 		bfa_lps_login_rsp(bfa, msg.login_rsp);
1996a36c61f9SKrishna Gudipati 		break;
1997a36c61f9SKrishna Gudipati 
199843ffdf4dSKrishna Gudipati 	case BFI_LPS_I2H_LOGOUT_RSP:
1999a36c61f9SKrishna Gudipati 		bfa_lps_logout_rsp(bfa, msg.logout_rsp);
2000a36c61f9SKrishna Gudipati 		break;
2001a36c61f9SKrishna Gudipati 
200243ffdf4dSKrishna Gudipati 	case BFI_LPS_I2H_CVL_EVENT:
2003a36c61f9SKrishna Gudipati 		bfa_lps_rx_cvl_event(bfa, msg.cvl_event);
2004a36c61f9SKrishna Gudipati 		break;
2005a36c61f9SKrishna Gudipati 
2006a36c61f9SKrishna Gudipati 	default:
2007a36c61f9SKrishna Gudipati 		bfa_trc(bfa, m->mhdr.msg_id);
2008d4b671c5SJing Huang 		WARN_ON(1);
2009a36c61f9SKrishna Gudipati 	}
2010a36c61f9SKrishna Gudipati }
2011a36c61f9SKrishna Gudipati 
20127826f304SKrishna Gudipati static void
20137826f304SKrishna Gudipati bfa_fcport_aen_post(struct bfa_fcport_s *fcport, enum bfa_port_aen_event event)
20147826f304SKrishna Gudipati {
20157826f304SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad;
20167826f304SKrishna Gudipati 	struct bfa_aen_entry_s  *aen_entry;
20177826f304SKrishna Gudipati 
20187826f304SKrishna Gudipati 	bfad_get_aen_entry(bfad, aen_entry);
20197826f304SKrishna Gudipati 	if (!aen_entry)
20207826f304SKrishna Gudipati 		return;
20217826f304SKrishna Gudipati 
20227826f304SKrishna Gudipati 	aen_entry->aen_data.port.ioc_type = bfa_get_type(fcport->bfa);
20237826f304SKrishna Gudipati 	aen_entry->aen_data.port.pwwn = fcport->pwwn;
20247826f304SKrishna Gudipati 
20257826f304SKrishna Gudipati 	/* Send the AEN notification */
20267826f304SKrishna Gudipati 	bfad_im_post_vendor_event(aen_entry, bfad, ++fcport->bfa->bfa_aen_seq,
20277826f304SKrishna Gudipati 				  BFA_AEN_CAT_PORT, event);
20287826f304SKrishna Gudipati }
20297826f304SKrishna Gudipati 
20305fbe25c7SJing Huang /*
2031a36c61f9SKrishna Gudipati  * FC PORT state machine functions
2032a36c61f9SKrishna Gudipati  */
2033a36c61f9SKrishna Gudipati static void
2034a36c61f9SKrishna Gudipati bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
2035a36c61f9SKrishna Gudipati 			enum bfa_fcport_sm_event event)
2036a36c61f9SKrishna Gudipati {
2037a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2038a36c61f9SKrishna Gudipati 
2039a36c61f9SKrishna Gudipati 	switch (event) {
2040a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_START:
20415fbe25c7SJing Huang 		/*
2042a36c61f9SKrishna Gudipati 		 * Start event after IOC is configured and BFA is started.
2043a36c61f9SKrishna Gudipati 		 */
2044f3a060caSKrishna Gudipati 		fcport->use_flash_cfg = BFA_TRUE;
2045f3a060caSKrishna Gudipati 
2046a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_enable(fcport)) {
2047a36c61f9SKrishna Gudipati 			bfa_trc(fcport->bfa, BFA_TRUE);
2048a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
2049a36c61f9SKrishna Gudipati 		} else {
2050a36c61f9SKrishna Gudipati 			bfa_trc(fcport->bfa, BFA_FALSE);
2051a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2052a36c61f9SKrishna Gudipati 					bfa_fcport_sm_enabling_qwait);
2053a36c61f9SKrishna Gudipati 		}
2054a36c61f9SKrishna Gudipati 		break;
2055a36c61f9SKrishna Gudipati 
2056a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
20575fbe25c7SJing Huang 		/*
2058a36c61f9SKrishna Gudipati 		 * Port is persistently configured to be in enabled state. Do
2059a36c61f9SKrishna Gudipati 		 * not change state. Port enabling is done when START event is
2060a36c61f9SKrishna Gudipati 		 * received.
2061a36c61f9SKrishna Gudipati 		 */
2062a36c61f9SKrishna Gudipati 		break;
2063a36c61f9SKrishna Gudipati 
2064a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
20655fbe25c7SJing Huang 		/*
2066a36c61f9SKrishna Gudipati 		 * If a port is persistently configured to be disabled, the
2067a36c61f9SKrishna Gudipati 		 * first event will a port disable request.
2068a36c61f9SKrishna Gudipati 		 */
2069a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
2070a36c61f9SKrishna Gudipati 		break;
2071a36c61f9SKrishna Gudipati 
2072a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2073a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
2074a36c61f9SKrishna Gudipati 		break;
2075a36c61f9SKrishna Gudipati 
2076a36c61f9SKrishna Gudipati 	default:
2077a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2078a36c61f9SKrishna Gudipati 	}
2079a36c61f9SKrishna Gudipati }
2080a36c61f9SKrishna Gudipati 
2081a36c61f9SKrishna Gudipati static void
2082a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
2083a36c61f9SKrishna Gudipati 				enum bfa_fcport_sm_event event)
2084a36c61f9SKrishna Gudipati {
2085a36c61f9SKrishna Gudipati 	char pwwn_buf[BFA_STRING_32];
2086a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad;
2087a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2088a36c61f9SKrishna Gudipati 
2089a36c61f9SKrishna Gudipati 	switch (event) {
2090a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_QRESUME:
2091a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
2092a36c61f9SKrishna Gudipati 		bfa_fcport_send_enable(fcport);
2093a36c61f9SKrishna Gudipati 		break;
2094a36c61f9SKrishna Gudipati 
2095a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_STOP:
2096a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->reqq_wait);
2097a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2098a36c61f9SKrishna Gudipati 		break;
2099a36c61f9SKrishna Gudipati 
2100a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
21015fbe25c7SJing Huang 		/*
2102a36c61f9SKrishna Gudipati 		 * Already enable is in progress.
2103a36c61f9SKrishna Gudipati 		 */
2104a36c61f9SKrishna Gudipati 		break;
2105a36c61f9SKrishna Gudipati 
2106a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
21075fbe25c7SJing Huang 		/*
2108a36c61f9SKrishna Gudipati 		 * Just send disable request to firmware when room becomes
2109a36c61f9SKrishna Gudipati 		 * available in request queue.
2110a36c61f9SKrishna Gudipati 		 */
2111a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
2112a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->reqq_wait);
2113a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2114a36c61f9SKrishna Gudipati 				BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
2115a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
211688166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2117a36c61f9SKrishna Gudipati 			"Base port disabled: WWN = %s\n", pwwn_buf);
21187826f304SKrishna Gudipati 		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
2119a36c61f9SKrishna Gudipati 		break;
2120a36c61f9SKrishna Gudipati 
2121a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKUP:
2122a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKDOWN:
21235fbe25c7SJing Huang 		/*
2124a36c61f9SKrishna Gudipati 		 * Possible to get link events when doing back-to-back
2125a36c61f9SKrishna Gudipati 		 * enable/disables.
2126a36c61f9SKrishna Gudipati 		 */
2127a36c61f9SKrishna Gudipati 		break;
2128a36c61f9SKrishna Gudipati 
2129a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2130a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->reqq_wait);
2131a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
2132a36c61f9SKrishna Gudipati 		break;
2133a36c61f9SKrishna Gudipati 
2134a36c61f9SKrishna Gudipati 	default:
2135a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2136a36c61f9SKrishna Gudipati 	}
2137a36c61f9SKrishna Gudipati }
2138a36c61f9SKrishna Gudipati 
2139a36c61f9SKrishna Gudipati static void
2140a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
2141a36c61f9SKrishna Gudipati 						enum bfa_fcport_sm_event event)
2142a36c61f9SKrishna Gudipati {
2143a36c61f9SKrishna Gudipati 	char pwwn_buf[BFA_STRING_32];
2144a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad;
2145a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2146a36c61f9SKrishna Gudipati 
2147a36c61f9SKrishna Gudipati 	switch (event) {
2148a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_FWRSP:
2149a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKDOWN:
2150a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
2151a36c61f9SKrishna Gudipati 		break;
2152a36c61f9SKrishna Gudipati 
2153a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKUP:
2154a36c61f9SKrishna Gudipati 		bfa_fcport_update_linkinfo(fcport);
2155a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
2156a36c61f9SKrishna Gudipati 
2157d4b671c5SJing Huang 		WARN_ON(!fcport->event_cbfn);
2158a36c61f9SKrishna Gudipati 		bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE);
2159a36c61f9SKrishna Gudipati 		break;
2160a36c61f9SKrishna Gudipati 
2161a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
21625fbe25c7SJing Huang 		/*
2163a36c61f9SKrishna Gudipati 		 * Already being enabled.
2164a36c61f9SKrishna Gudipati 		 */
2165a36c61f9SKrishna Gudipati 		break;
2166a36c61f9SKrishna Gudipati 
2167a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
2168a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_disable(fcport))
2169a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
2170a36c61f9SKrishna Gudipati 		else
2171a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2172a36c61f9SKrishna Gudipati 					 bfa_fcport_sm_disabling_qwait);
2173a36c61f9SKrishna Gudipati 
2174a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2175a36c61f9SKrishna Gudipati 				BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
2176a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
217788166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2178a36c61f9SKrishna Gudipati 			"Base port disabled: WWN = %s\n", pwwn_buf);
21797826f304SKrishna Gudipati 		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
2180a36c61f9SKrishna Gudipati 		break;
2181a36c61f9SKrishna Gudipati 
2182a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_STOP:
2183a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2184a36c61f9SKrishna Gudipati 		break;
2185a36c61f9SKrishna Gudipati 
2186a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2187a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
2188a36c61f9SKrishna Gudipati 		break;
2189a36c61f9SKrishna Gudipati 
2190a36c61f9SKrishna Gudipati 	default:
2191a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2192a36c61f9SKrishna Gudipati 	}
2193a36c61f9SKrishna Gudipati }
2194a36c61f9SKrishna Gudipati 
2195a36c61f9SKrishna Gudipati static void
2196a36c61f9SKrishna Gudipati bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
2197a36c61f9SKrishna Gudipati 						enum bfa_fcport_sm_event event)
2198a36c61f9SKrishna Gudipati {
2199a36c61f9SKrishna Gudipati 	struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
2200a36c61f9SKrishna Gudipati 	char pwwn_buf[BFA_STRING_32];
2201a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad;
2202a36c61f9SKrishna Gudipati 
2203a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2204a36c61f9SKrishna Gudipati 
2205a36c61f9SKrishna Gudipati 	switch (event) {
2206a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKUP:
2207a36c61f9SKrishna Gudipati 		bfa_fcport_update_linkinfo(fcport);
2208a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
2209d4b671c5SJing Huang 		WARN_ON(!fcport->event_cbfn);
2210a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2211a36c61f9SKrishna Gudipati 				BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup");
2212a36c61f9SKrishna Gudipati 		if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
2213a36c61f9SKrishna Gudipati 
2214a36c61f9SKrishna Gudipati 			bfa_trc(fcport->bfa,
2215a36c61f9SKrishna Gudipati 				pevent->link_state.vc_fcf.fcf.fipenabled);
2216a36c61f9SKrishna Gudipati 			bfa_trc(fcport->bfa,
2217a36c61f9SKrishna Gudipati 				pevent->link_state.vc_fcf.fcf.fipfailed);
2218a36c61f9SKrishna Gudipati 
2219a36c61f9SKrishna Gudipati 			if (pevent->link_state.vc_fcf.fcf.fipfailed)
2220a36c61f9SKrishna Gudipati 				bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2221a36c61f9SKrishna Gudipati 					BFA_PL_EID_FIP_FCF_DISC, 0,
2222a36c61f9SKrishna Gudipati 					"FIP FCF Discovery Failed");
2223a36c61f9SKrishna Gudipati 			else
2224a36c61f9SKrishna Gudipati 				bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2225a36c61f9SKrishna Gudipati 					BFA_PL_EID_FIP_FCF_DISC, 0,
2226a36c61f9SKrishna Gudipati 					"FIP FCF Discovered");
2227a36c61f9SKrishna Gudipati 		}
2228a36c61f9SKrishna Gudipati 
2229a36c61f9SKrishna Gudipati 		bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE);
2230a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
223188166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2232a36c61f9SKrishna Gudipati 			"Base port online: WWN = %s\n", pwwn_buf);
22337826f304SKrishna Gudipati 		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ONLINE);
22343ec4f2c8SKrishna Gudipati 
22353ec4f2c8SKrishna Gudipati 		/* If QoS is enabled and it is not online, send AEN */
22363ec4f2c8SKrishna Gudipati 		if (fcport->cfg.qos_enabled &&
22373ec4f2c8SKrishna Gudipati 		    fcport->qos_attr.state != BFA_QOS_ONLINE)
22383ec4f2c8SKrishna Gudipati 			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_QOS_NEG);
2239a36c61f9SKrishna Gudipati 		break;
2240a36c61f9SKrishna Gudipati 
2241a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKDOWN:
22425fbe25c7SJing Huang 		/*
2243a36c61f9SKrishna Gudipati 		 * Possible to get link down event.
2244a36c61f9SKrishna Gudipati 		 */
2245a36c61f9SKrishna Gudipati 		break;
2246a36c61f9SKrishna Gudipati 
2247a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
22485fbe25c7SJing Huang 		/*
2249a36c61f9SKrishna Gudipati 		 * Already enabled.
2250a36c61f9SKrishna Gudipati 		 */
2251a36c61f9SKrishna Gudipati 		break;
2252a36c61f9SKrishna Gudipati 
2253a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
2254a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_disable(fcport))
2255a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
2256a36c61f9SKrishna Gudipati 		else
2257a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2258a36c61f9SKrishna Gudipati 					 bfa_fcport_sm_disabling_qwait);
2259a36c61f9SKrishna Gudipati 
2260a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2261a36c61f9SKrishna Gudipati 				BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
2262a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
226388166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2264a36c61f9SKrishna Gudipati 			"Base port disabled: WWN = %s\n", pwwn_buf);
22657826f304SKrishna Gudipati 		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
2266a36c61f9SKrishna Gudipati 		break;
2267a36c61f9SKrishna Gudipati 
2268a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_STOP:
2269a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2270a36c61f9SKrishna Gudipati 		break;
2271a36c61f9SKrishna Gudipati 
2272a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2273a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
2274a36c61f9SKrishna Gudipati 		break;
2275a36c61f9SKrishna Gudipati 
2276a36c61f9SKrishna Gudipati 	default:
2277a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2278a36c61f9SKrishna Gudipati 	}
2279a36c61f9SKrishna Gudipati }
2280a36c61f9SKrishna Gudipati 
2281a36c61f9SKrishna Gudipati static void
2282a36c61f9SKrishna Gudipati bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
2283a36c61f9SKrishna Gudipati 	enum bfa_fcport_sm_event event)
2284a36c61f9SKrishna Gudipati {
2285a36c61f9SKrishna Gudipati 	char pwwn_buf[BFA_STRING_32];
2286a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad;
2287a36c61f9SKrishna Gudipati 
2288a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2289a36c61f9SKrishna Gudipati 
2290a36c61f9SKrishna Gudipati 	switch (event) {
2291a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
22925fbe25c7SJing Huang 		/*
2293a36c61f9SKrishna Gudipati 		 * Already enabled.
2294a36c61f9SKrishna Gudipati 		 */
2295a36c61f9SKrishna Gudipati 		break;
2296a36c61f9SKrishna Gudipati 
2297a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
2298a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_disable(fcport))
2299a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
2300a36c61f9SKrishna Gudipati 		else
2301a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2302a36c61f9SKrishna Gudipati 					 bfa_fcport_sm_disabling_qwait);
2303a36c61f9SKrishna Gudipati 
2304a36c61f9SKrishna Gudipati 		bfa_fcport_reset_linkinfo(fcport);
2305a36c61f9SKrishna Gudipati 		bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE);
2306a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2307a36c61f9SKrishna Gudipati 				BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
2308a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
230988166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2310a36c61f9SKrishna Gudipati 			"Base port offline: WWN = %s\n", pwwn_buf);
23117826f304SKrishna Gudipati 		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
231288166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2313a36c61f9SKrishna Gudipati 			"Base port disabled: WWN = %s\n", pwwn_buf);
23147826f304SKrishna Gudipati 		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISABLE);
2315a36c61f9SKrishna Gudipati 		break;
2316a36c61f9SKrishna Gudipati 
2317a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKDOWN:
2318a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
2319a36c61f9SKrishna Gudipati 		bfa_fcport_reset_linkinfo(fcport);
2320a36c61f9SKrishna Gudipati 		bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE);
2321a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2322a36c61f9SKrishna Gudipati 				BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
2323a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
23247826f304SKrishna Gudipati 		if (BFA_PORT_IS_DISABLED(fcport->bfa)) {
232588166242SJing Huang 			BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2326a36c61f9SKrishna Gudipati 				"Base port offline: WWN = %s\n", pwwn_buf);
23277826f304SKrishna Gudipati 			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
23287826f304SKrishna Gudipati 		} else {
232988166242SJing Huang 			BFA_LOG(KERN_ERR, bfad, bfa_log_level,
2330a36c61f9SKrishna Gudipati 				"Base port (WWN = %s) "
2331a36c61f9SKrishna Gudipati 				"lost fabric connectivity\n", pwwn_buf);
23327826f304SKrishna Gudipati 			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
23337826f304SKrishna Gudipati 		}
2334a36c61f9SKrishna Gudipati 		break;
2335a36c61f9SKrishna Gudipati 
2336a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_STOP:
2337a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2338a36c61f9SKrishna Gudipati 		bfa_fcport_reset_linkinfo(fcport);
2339a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
23407826f304SKrishna Gudipati 		if (BFA_PORT_IS_DISABLED(fcport->bfa)) {
234188166242SJing Huang 			BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2342a36c61f9SKrishna Gudipati 				"Base port offline: WWN = %s\n", pwwn_buf);
23437826f304SKrishna Gudipati 			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
23447826f304SKrishna Gudipati 		} else {
234588166242SJing Huang 			BFA_LOG(KERN_ERR, bfad, bfa_log_level,
2346a36c61f9SKrishna Gudipati 				"Base port (WWN = %s) "
2347a36c61f9SKrishna Gudipati 				"lost fabric connectivity\n", pwwn_buf);
23487826f304SKrishna Gudipati 			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
23497826f304SKrishna Gudipati 		}
2350a36c61f9SKrishna Gudipati 		break;
2351a36c61f9SKrishna Gudipati 
2352a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2353a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
2354a36c61f9SKrishna Gudipati 		bfa_fcport_reset_linkinfo(fcport);
2355a36c61f9SKrishna Gudipati 		bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE);
2356a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
23577826f304SKrishna Gudipati 		if (BFA_PORT_IS_DISABLED(fcport->bfa)) {
235888166242SJing Huang 			BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2359a36c61f9SKrishna Gudipati 				"Base port offline: WWN = %s\n", pwwn_buf);
23607826f304SKrishna Gudipati 			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_OFFLINE);
23617826f304SKrishna Gudipati 		} else {
236288166242SJing Huang 			BFA_LOG(KERN_ERR, bfad, bfa_log_level,
2363a36c61f9SKrishna Gudipati 				"Base port (WWN = %s) "
2364a36c61f9SKrishna Gudipati 				"lost fabric connectivity\n", pwwn_buf);
23657826f304SKrishna Gudipati 			bfa_fcport_aen_post(fcport, BFA_PORT_AEN_DISCONNECT);
23667826f304SKrishna Gudipati 		}
2367a36c61f9SKrishna Gudipati 		break;
2368a36c61f9SKrishna Gudipati 
2369a36c61f9SKrishna Gudipati 	default:
2370a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2371a36c61f9SKrishna Gudipati 	}
2372a36c61f9SKrishna Gudipati }
2373a36c61f9SKrishna Gudipati 
2374a36c61f9SKrishna Gudipati static void
2375a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
2376a36c61f9SKrishna Gudipati 				 enum bfa_fcport_sm_event event)
2377a36c61f9SKrishna Gudipati {
2378a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2379a36c61f9SKrishna Gudipati 
2380a36c61f9SKrishna Gudipati 	switch (event) {
2381a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_QRESUME:
2382a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
2383a36c61f9SKrishna Gudipati 		bfa_fcport_send_disable(fcport);
2384a36c61f9SKrishna Gudipati 		break;
2385a36c61f9SKrishna Gudipati 
2386a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_STOP:
2387a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2388a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->reqq_wait);
2389a36c61f9SKrishna Gudipati 		break;
2390a36c61f9SKrishna Gudipati 
2391a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
2392a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_toggling_qwait);
2393a36c61f9SKrishna Gudipati 		break;
2394a36c61f9SKrishna Gudipati 
2395a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
23965fbe25c7SJing Huang 		/*
2397a36c61f9SKrishna Gudipati 		 * Already being disabled.
2398a36c61f9SKrishna Gudipati 		 */
2399a36c61f9SKrishna Gudipati 		break;
2400a36c61f9SKrishna Gudipati 
2401a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKUP:
2402a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKDOWN:
24035fbe25c7SJing Huang 		/*
2404a36c61f9SKrishna Gudipati 		 * Possible to get link events when doing back-to-back
2405a36c61f9SKrishna Gudipati 		 * enable/disables.
2406a36c61f9SKrishna Gudipati 		 */
2407a36c61f9SKrishna Gudipati 		break;
2408a36c61f9SKrishna Gudipati 
2409a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2410a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
2411a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->reqq_wait);
2412a36c61f9SKrishna Gudipati 		break;
2413a36c61f9SKrishna Gudipati 
2414a36c61f9SKrishna Gudipati 	default:
2415a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2416a36c61f9SKrishna Gudipati 	}
2417a36c61f9SKrishna Gudipati }
2418a36c61f9SKrishna Gudipati 
2419a36c61f9SKrishna Gudipati static void
2420a36c61f9SKrishna Gudipati bfa_fcport_sm_toggling_qwait(struct bfa_fcport_s *fcport,
2421a36c61f9SKrishna Gudipati 				 enum bfa_fcport_sm_event event)
2422a36c61f9SKrishna Gudipati {
2423a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2424a36c61f9SKrishna Gudipati 
2425a36c61f9SKrishna Gudipati 	switch (event) {
2426a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_QRESUME:
2427a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
2428a36c61f9SKrishna Gudipati 		bfa_fcport_send_disable(fcport);
2429a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_enable(fcport))
2430a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
2431a36c61f9SKrishna Gudipati 		else
2432a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2433a36c61f9SKrishna Gudipati 					 bfa_fcport_sm_enabling_qwait);
2434a36c61f9SKrishna Gudipati 		break;
2435a36c61f9SKrishna Gudipati 
2436a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_STOP:
2437a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2438a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->reqq_wait);
2439a36c61f9SKrishna Gudipati 		break;
2440a36c61f9SKrishna Gudipati 
2441a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
2442a36c61f9SKrishna Gudipati 		break;
2443a36c61f9SKrishna Gudipati 
2444a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
2445a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
2446a36c61f9SKrishna Gudipati 		break;
2447a36c61f9SKrishna Gudipati 
2448a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKUP:
2449a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKDOWN:
24505fbe25c7SJing Huang 		/*
2451a36c61f9SKrishna Gudipati 		 * Possible to get link events when doing back-to-back
2452a36c61f9SKrishna Gudipati 		 * enable/disables.
2453a36c61f9SKrishna Gudipati 		 */
2454a36c61f9SKrishna Gudipati 		break;
2455a36c61f9SKrishna Gudipati 
2456a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2457a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
2458a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->reqq_wait);
2459a36c61f9SKrishna Gudipati 		break;
2460a36c61f9SKrishna Gudipati 
2461a36c61f9SKrishna Gudipati 	default:
2462a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2463a36c61f9SKrishna Gudipati 	}
2464a36c61f9SKrishna Gudipati }
2465a36c61f9SKrishna Gudipati 
2466a36c61f9SKrishna Gudipati static void
2467a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
2468a36c61f9SKrishna Gudipati 						enum bfa_fcport_sm_event event)
2469a36c61f9SKrishna Gudipati {
2470a36c61f9SKrishna Gudipati 	char pwwn_buf[BFA_STRING_32];
2471a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad;
2472a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2473a36c61f9SKrishna Gudipati 
2474a36c61f9SKrishna Gudipati 	switch (event) {
2475a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_FWRSP:
2476a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
2477a36c61f9SKrishna Gudipati 		break;
2478a36c61f9SKrishna Gudipati 
2479a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
24805fbe25c7SJing Huang 		/*
2481a36c61f9SKrishna Gudipati 		 * Already being disabled.
2482a36c61f9SKrishna Gudipati 		 */
2483a36c61f9SKrishna Gudipati 		break;
2484a36c61f9SKrishna Gudipati 
2485a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
2486a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_enable(fcport))
2487a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
2488a36c61f9SKrishna Gudipati 		else
2489a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2490a36c61f9SKrishna Gudipati 					 bfa_fcport_sm_enabling_qwait);
2491a36c61f9SKrishna Gudipati 
2492a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2493a36c61f9SKrishna Gudipati 				BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
2494a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
249588166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2496a36c61f9SKrishna Gudipati 			"Base port enabled: WWN = %s\n", pwwn_buf);
24977826f304SKrishna Gudipati 		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
2498a36c61f9SKrishna Gudipati 		break;
2499a36c61f9SKrishna Gudipati 
2500a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_STOP:
2501a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2502a36c61f9SKrishna Gudipati 		break;
2503a36c61f9SKrishna Gudipati 
2504a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKUP:
2505a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKDOWN:
25065fbe25c7SJing Huang 		/*
2507a36c61f9SKrishna Gudipati 		 * Possible to get link events when doing back-to-back
2508a36c61f9SKrishna Gudipati 		 * enable/disables.
2509a36c61f9SKrishna Gudipati 		 */
2510a36c61f9SKrishna Gudipati 		break;
2511a36c61f9SKrishna Gudipati 
2512a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2513a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
2514a36c61f9SKrishna Gudipati 		break;
2515a36c61f9SKrishna Gudipati 
2516a36c61f9SKrishna Gudipati 	default:
2517a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2518a36c61f9SKrishna Gudipati 	}
2519a36c61f9SKrishna Gudipati }
2520a36c61f9SKrishna Gudipati 
2521a36c61f9SKrishna Gudipati static void
2522a36c61f9SKrishna Gudipati bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
2523a36c61f9SKrishna Gudipati 						enum bfa_fcport_sm_event event)
2524a36c61f9SKrishna Gudipati {
2525a36c61f9SKrishna Gudipati 	char pwwn_buf[BFA_STRING_32];
2526a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad;
2527a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2528a36c61f9SKrishna Gudipati 
2529a36c61f9SKrishna Gudipati 	switch (event) {
2530a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_START:
25315fbe25c7SJing Huang 		/*
2532a36c61f9SKrishna Gudipati 		 * Ignore start event for a port that is disabled.
2533a36c61f9SKrishna Gudipati 		 */
2534a36c61f9SKrishna Gudipati 		break;
2535a36c61f9SKrishna Gudipati 
2536a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_STOP:
2537a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2538a36c61f9SKrishna Gudipati 		break;
2539a36c61f9SKrishna Gudipati 
2540a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
2541a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_enable(fcport))
2542a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
2543a36c61f9SKrishna Gudipati 		else
2544a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2545a36c61f9SKrishna Gudipati 					 bfa_fcport_sm_enabling_qwait);
2546a36c61f9SKrishna Gudipati 
2547a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2548a36c61f9SKrishna Gudipati 				BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
2549a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
255088166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2551a36c61f9SKrishna Gudipati 			"Base port enabled: WWN = %s\n", pwwn_buf);
25527826f304SKrishna Gudipati 		bfa_fcport_aen_post(fcport, BFA_PORT_AEN_ENABLE);
2553a36c61f9SKrishna Gudipati 		break;
2554a36c61f9SKrishna Gudipati 
2555a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
25565fbe25c7SJing Huang 		/*
2557a36c61f9SKrishna Gudipati 		 * Already disabled.
2558a36c61f9SKrishna Gudipati 		 */
2559a36c61f9SKrishna Gudipati 		break;
2560a36c61f9SKrishna Gudipati 
2561a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2562a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
2563a36c61f9SKrishna Gudipati 		break;
2564a36c61f9SKrishna Gudipati 
2565a36c61f9SKrishna Gudipati 	default:
2566a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2567a36c61f9SKrishna Gudipati 	}
2568a36c61f9SKrishna Gudipati }
2569a36c61f9SKrishna Gudipati 
2570a36c61f9SKrishna Gudipati static void
2571a36c61f9SKrishna Gudipati bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
2572a36c61f9SKrishna Gudipati 			 enum bfa_fcport_sm_event event)
2573a36c61f9SKrishna Gudipati {
2574a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2575a36c61f9SKrishna Gudipati 
2576a36c61f9SKrishna Gudipati 	switch (event) {
2577a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_START:
2578a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_enable(fcport))
2579a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
2580a36c61f9SKrishna Gudipati 		else
2581a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2582a36c61f9SKrishna Gudipati 					 bfa_fcport_sm_enabling_qwait);
2583a36c61f9SKrishna Gudipati 		break;
2584a36c61f9SKrishna Gudipati 
2585a36c61f9SKrishna Gudipati 	default:
25865fbe25c7SJing Huang 		/*
2587a36c61f9SKrishna Gudipati 		 * Ignore all other events.
2588a36c61f9SKrishna Gudipati 		 */
2589a36c61f9SKrishna Gudipati 		;
2590a36c61f9SKrishna Gudipati 	}
2591a36c61f9SKrishna Gudipati }
2592a36c61f9SKrishna Gudipati 
25935fbe25c7SJing Huang /*
2594a36c61f9SKrishna Gudipati  * Port is enabled. IOC is down/failed.
2595a36c61f9SKrishna Gudipati  */
2596a36c61f9SKrishna Gudipati static void
2597a36c61f9SKrishna Gudipati bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
2598a36c61f9SKrishna Gudipati 			 enum bfa_fcport_sm_event event)
2599a36c61f9SKrishna Gudipati {
2600a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2601a36c61f9SKrishna Gudipati 
2602a36c61f9SKrishna Gudipati 	switch (event) {
2603a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_START:
2604a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_enable(fcport))
2605a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
2606a36c61f9SKrishna Gudipati 		else
2607a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2608a36c61f9SKrishna Gudipati 					 bfa_fcport_sm_enabling_qwait);
2609a36c61f9SKrishna Gudipati 		break;
2610a36c61f9SKrishna Gudipati 
2611a36c61f9SKrishna Gudipati 	default:
26125fbe25c7SJing Huang 		/*
2613a36c61f9SKrishna Gudipati 		 * Ignore all events.
2614a36c61f9SKrishna Gudipati 		 */
2615a36c61f9SKrishna Gudipati 		;
2616a36c61f9SKrishna Gudipati 	}
2617a36c61f9SKrishna Gudipati }
2618a36c61f9SKrishna Gudipati 
26195fbe25c7SJing Huang /*
2620a36c61f9SKrishna Gudipati  * Port is disabled. IOC is down/failed.
2621a36c61f9SKrishna Gudipati  */
2622a36c61f9SKrishna Gudipati static void
2623a36c61f9SKrishna Gudipati bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
2624a36c61f9SKrishna Gudipati 			 enum bfa_fcport_sm_event event)
2625a36c61f9SKrishna Gudipati {
2626a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2627a36c61f9SKrishna Gudipati 
2628a36c61f9SKrishna Gudipati 	switch (event) {
2629a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_START:
2630a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
2631a36c61f9SKrishna Gudipati 		break;
2632a36c61f9SKrishna Gudipati 
2633a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
2634a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
2635a36c61f9SKrishna Gudipati 		break;
2636a36c61f9SKrishna Gudipati 
2637a36c61f9SKrishna Gudipati 	default:
26385fbe25c7SJing Huang 		/*
2639a36c61f9SKrishna Gudipati 		 * Ignore all events.
2640a36c61f9SKrishna Gudipati 		 */
2641a36c61f9SKrishna Gudipati 		;
2642a36c61f9SKrishna Gudipati 	}
2643a36c61f9SKrishna Gudipati }
2644a36c61f9SKrishna Gudipati 
26455fbe25c7SJing Huang /*
2646a36c61f9SKrishna Gudipati  * Link state is down
2647a36c61f9SKrishna Gudipati  */
2648a36c61f9SKrishna Gudipati static void
2649a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
2650a36c61f9SKrishna Gudipati 		enum bfa_fcport_ln_sm_event event)
2651a36c61f9SKrishna Gudipati {
2652a36c61f9SKrishna Gudipati 	bfa_trc(ln->fcport->bfa, event);
2653a36c61f9SKrishna Gudipati 
2654a36c61f9SKrishna Gudipati 	switch (event) {
2655a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_LINKUP:
2656a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
2657a36c61f9SKrishna Gudipati 		bfa_fcport_queue_cb(ln, BFA_PORT_LINKUP);
2658a36c61f9SKrishna Gudipati 		break;
2659a36c61f9SKrishna Gudipati 
2660a36c61f9SKrishna Gudipati 	default:
2661a36c61f9SKrishna Gudipati 		bfa_sm_fault(ln->fcport->bfa, event);
2662a36c61f9SKrishna Gudipati 	}
2663a36c61f9SKrishna Gudipati }
2664a36c61f9SKrishna Gudipati 
26655fbe25c7SJing Huang /*
2666a36c61f9SKrishna Gudipati  * Link state is waiting for down notification
2667a36c61f9SKrishna Gudipati  */
2668a36c61f9SKrishna Gudipati static void
2669a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
2670a36c61f9SKrishna Gudipati 		enum bfa_fcport_ln_sm_event event)
2671a36c61f9SKrishna Gudipati {
2672a36c61f9SKrishna Gudipati 	bfa_trc(ln->fcport->bfa, event);
2673a36c61f9SKrishna Gudipati 
2674a36c61f9SKrishna Gudipati 	switch (event) {
2675a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_LINKUP:
2676a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
2677a36c61f9SKrishna Gudipati 		break;
2678a36c61f9SKrishna Gudipati 
2679a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_NOTIFICATION:
2680a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
2681a36c61f9SKrishna Gudipati 		break;
2682a36c61f9SKrishna Gudipati 
2683a36c61f9SKrishna Gudipati 	default:
2684a36c61f9SKrishna Gudipati 		bfa_sm_fault(ln->fcport->bfa, event);
2685a36c61f9SKrishna Gudipati 	}
2686a36c61f9SKrishna Gudipati }
2687a36c61f9SKrishna Gudipati 
26885fbe25c7SJing Huang /*
2689a36c61f9SKrishna Gudipati  * Link state is waiting for down notification and there is a pending up
2690a36c61f9SKrishna Gudipati  */
2691a36c61f9SKrishna Gudipati static void
2692a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
2693a36c61f9SKrishna Gudipati 		enum bfa_fcport_ln_sm_event event)
2694a36c61f9SKrishna Gudipati {
2695a36c61f9SKrishna Gudipati 	bfa_trc(ln->fcport->bfa, event);
2696a36c61f9SKrishna Gudipati 
2697a36c61f9SKrishna Gudipati 	switch (event) {
2698a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_LINKDOWN:
2699a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
2700a36c61f9SKrishna Gudipati 		break;
2701a36c61f9SKrishna Gudipati 
2702a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_NOTIFICATION:
2703a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
2704a36c61f9SKrishna Gudipati 		bfa_fcport_queue_cb(ln, BFA_PORT_LINKUP);
2705a36c61f9SKrishna Gudipati 		break;
2706a36c61f9SKrishna Gudipati 
2707a36c61f9SKrishna Gudipati 	default:
2708a36c61f9SKrishna Gudipati 		bfa_sm_fault(ln->fcport->bfa, event);
2709a36c61f9SKrishna Gudipati 	}
2710a36c61f9SKrishna Gudipati }
2711a36c61f9SKrishna Gudipati 
27125fbe25c7SJing Huang /*
2713a36c61f9SKrishna Gudipati  * Link state is up
2714a36c61f9SKrishna Gudipati  */
2715a36c61f9SKrishna Gudipati static void
2716a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
2717a36c61f9SKrishna Gudipati 		enum bfa_fcport_ln_sm_event event)
2718a36c61f9SKrishna Gudipati {
2719a36c61f9SKrishna Gudipati 	bfa_trc(ln->fcport->bfa, event);
2720a36c61f9SKrishna Gudipati 
2721a36c61f9SKrishna Gudipati 	switch (event) {
2722a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_LINKDOWN:
2723a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
2724a36c61f9SKrishna Gudipati 		bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN);
2725a36c61f9SKrishna Gudipati 		break;
2726a36c61f9SKrishna Gudipati 
2727a36c61f9SKrishna Gudipati 	default:
2728a36c61f9SKrishna Gudipati 		bfa_sm_fault(ln->fcport->bfa, event);
2729a36c61f9SKrishna Gudipati 	}
2730a36c61f9SKrishna Gudipati }
2731a36c61f9SKrishna Gudipati 
27325fbe25c7SJing Huang /*
2733a36c61f9SKrishna Gudipati  * Link state is waiting for up notification
2734a36c61f9SKrishna Gudipati  */
2735a36c61f9SKrishna Gudipati static void
2736a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
2737a36c61f9SKrishna Gudipati 		enum bfa_fcport_ln_sm_event event)
2738a36c61f9SKrishna Gudipati {
2739a36c61f9SKrishna Gudipati 	bfa_trc(ln->fcport->bfa, event);
2740a36c61f9SKrishna Gudipati 
2741a36c61f9SKrishna Gudipati 	switch (event) {
2742a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_LINKDOWN:
2743a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
2744a36c61f9SKrishna Gudipati 		break;
2745a36c61f9SKrishna Gudipati 
2746a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_NOTIFICATION:
2747a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up);
2748a36c61f9SKrishna Gudipati 		break;
2749a36c61f9SKrishna Gudipati 
2750a36c61f9SKrishna Gudipati 	default:
2751a36c61f9SKrishna Gudipati 		bfa_sm_fault(ln->fcport->bfa, event);
2752a36c61f9SKrishna Gudipati 	}
2753a36c61f9SKrishna Gudipati }
2754a36c61f9SKrishna Gudipati 
27555fbe25c7SJing Huang /*
2756a36c61f9SKrishna Gudipati  * Link state is waiting for up notification and there is a pending down
2757a36c61f9SKrishna Gudipati  */
2758a36c61f9SKrishna Gudipati static void
2759a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
2760a36c61f9SKrishna Gudipati 		enum bfa_fcport_ln_sm_event event)
2761a36c61f9SKrishna Gudipati {
2762a36c61f9SKrishna Gudipati 	bfa_trc(ln->fcport->bfa, event);
2763a36c61f9SKrishna Gudipati 
2764a36c61f9SKrishna Gudipati 	switch (event) {
2765a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_LINKUP:
2766a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_up_nf);
2767a36c61f9SKrishna Gudipati 		break;
2768a36c61f9SKrishna Gudipati 
2769a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_NOTIFICATION:
2770a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
2771a36c61f9SKrishna Gudipati 		bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN);
2772a36c61f9SKrishna Gudipati 		break;
2773a36c61f9SKrishna Gudipati 
2774a36c61f9SKrishna Gudipati 	default:
2775a36c61f9SKrishna Gudipati 		bfa_sm_fault(ln->fcport->bfa, event);
2776a36c61f9SKrishna Gudipati 	}
2777a36c61f9SKrishna Gudipati }
2778a36c61f9SKrishna Gudipati 
27795fbe25c7SJing Huang /*
2780a36c61f9SKrishna Gudipati  * Link state is waiting for up notification and there are pending down and up
2781a36c61f9SKrishna Gudipati  */
2782a36c61f9SKrishna Gudipati static void
2783a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
2784a36c61f9SKrishna Gudipati 			enum bfa_fcport_ln_sm_event event)
2785a36c61f9SKrishna Gudipati {
2786a36c61f9SKrishna Gudipati 	bfa_trc(ln->fcport->bfa, event);
2787a36c61f9SKrishna Gudipati 
2788a36c61f9SKrishna Gudipati 	switch (event) {
2789a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_LINKDOWN:
2790a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
2791a36c61f9SKrishna Gudipati 		break;
2792a36c61f9SKrishna Gudipati 
2793a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_NOTIFICATION:
2794a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
2795a36c61f9SKrishna Gudipati 		bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN);
2796a36c61f9SKrishna Gudipati 		break;
2797a36c61f9SKrishna Gudipati 
2798a36c61f9SKrishna Gudipati 	default:
2799a36c61f9SKrishna Gudipati 		bfa_sm_fault(ln->fcport->bfa, event);
2800a36c61f9SKrishna Gudipati 	}
2801a36c61f9SKrishna Gudipati }
2802a36c61f9SKrishna Gudipati 
2803a36c61f9SKrishna Gudipati static void
2804a36c61f9SKrishna Gudipati __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete)
2805a36c61f9SKrishna Gudipati {
2806a36c61f9SKrishna Gudipati 	struct bfa_fcport_ln_s *ln = cbarg;
2807a36c61f9SKrishna Gudipati 
2808a36c61f9SKrishna Gudipati 	if (complete)
2809a36c61f9SKrishna Gudipati 		ln->fcport->event_cbfn(ln->fcport->event_cbarg, ln->ln_event);
2810a36c61f9SKrishna Gudipati 	else
2811a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION);
2812a36c61f9SKrishna Gudipati }
2813a36c61f9SKrishna Gudipati 
28145fbe25c7SJing Huang /*
2815a36c61f9SKrishna Gudipati  * Send SCN notification to upper layers.
2816a36c61f9SKrishna Gudipati  * trunk - false if caller is fcport to ignore fcport event in trunked mode
2817a36c61f9SKrishna Gudipati  */
2818a36c61f9SKrishna Gudipati static void
2819a36c61f9SKrishna Gudipati bfa_fcport_scn(struct bfa_fcport_s *fcport, enum bfa_port_linkstate event,
2820a36c61f9SKrishna Gudipati 	bfa_boolean_t trunk)
2821a36c61f9SKrishna Gudipati {
2822a36c61f9SKrishna Gudipati 	if (fcport->cfg.trunked && !trunk)
2823a36c61f9SKrishna Gudipati 		return;
2824a36c61f9SKrishna Gudipati 
2825a36c61f9SKrishna Gudipati 	switch (event) {
2826a36c61f9SKrishna Gudipati 	case BFA_PORT_LINKUP:
2827a36c61f9SKrishna Gudipati 		bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP);
2828a36c61f9SKrishna Gudipati 		break;
2829a36c61f9SKrishna Gudipati 	case BFA_PORT_LINKDOWN:
2830a36c61f9SKrishna Gudipati 		bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN);
2831a36c61f9SKrishna Gudipati 		break;
2832a36c61f9SKrishna Gudipati 	default:
2833d4b671c5SJing Huang 		WARN_ON(1);
2834a36c61f9SKrishna Gudipati 	}
2835a36c61f9SKrishna Gudipati }
2836a36c61f9SKrishna Gudipati 
2837a36c61f9SKrishna Gudipati static void
2838a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_port_linkstate event)
2839a36c61f9SKrishna Gudipati {
2840a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = ln->fcport;
2841a36c61f9SKrishna Gudipati 
2842a36c61f9SKrishna Gudipati 	if (fcport->bfa->fcs) {
2843a36c61f9SKrishna Gudipati 		fcport->event_cbfn(fcport->event_cbarg, event);
2844a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION);
2845a36c61f9SKrishna Gudipati 	} else {
2846a36c61f9SKrishna Gudipati 		ln->ln_event = event;
2847a36c61f9SKrishna Gudipati 		bfa_cb_queue(fcport->bfa, &ln->ln_qe,
2848a36c61f9SKrishna Gudipati 			__bfa_cb_fcport_event, ln);
2849a36c61f9SKrishna Gudipati 	}
2850a36c61f9SKrishna Gudipati }
2851a36c61f9SKrishna Gudipati 
2852a36c61f9SKrishna Gudipati #define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \
2853a36c61f9SKrishna Gudipati 							BFA_CACHELINE_SZ))
2854a36c61f9SKrishna Gudipati 
2855a36c61f9SKrishna Gudipati static void
28564507025dSKrishna Gudipati bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo,
28574507025dSKrishna Gudipati 		   struct bfa_s *bfa)
2858a36c61f9SKrishna Gudipati {
28594507025dSKrishna Gudipati 	struct bfa_mem_dma_s *fcport_dma = BFA_MEM_FCPORT_DMA(bfa);
28604507025dSKrishna Gudipati 
28614507025dSKrishna Gudipati 	bfa_mem_dma_setup(minfo, fcport_dma, FCPORT_STATS_DMA_SZ);
2862a36c61f9SKrishna Gudipati }
2863a36c61f9SKrishna Gudipati 
2864a36c61f9SKrishna Gudipati static void
2865a36c61f9SKrishna Gudipati bfa_fcport_qresume(void *cbarg)
2866a36c61f9SKrishna Gudipati {
2867a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = cbarg;
2868a36c61f9SKrishna Gudipati 
2869a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fcport, BFA_FCPORT_SM_QRESUME);
2870a36c61f9SKrishna Gudipati }
2871a36c61f9SKrishna Gudipati 
2872a36c61f9SKrishna Gudipati static void
28734507025dSKrishna Gudipati bfa_fcport_mem_claim(struct bfa_fcport_s *fcport)
2874a36c61f9SKrishna Gudipati {
28754507025dSKrishna Gudipati 	struct bfa_mem_dma_s *fcport_dma = &fcport->fcport_dma;
2876a36c61f9SKrishna Gudipati 
28774507025dSKrishna Gudipati 	fcport->stats_kva = bfa_mem_dma_virt(fcport_dma);
28784507025dSKrishna Gudipati 	fcport->stats_pa  = bfa_mem_dma_phys(fcport_dma);
28794507025dSKrishna Gudipati 	fcport->stats = (union bfa_fcport_stats_u *)
28804507025dSKrishna Gudipati 				bfa_mem_dma_virt(fcport_dma);
2881a36c61f9SKrishna Gudipati }
2882a36c61f9SKrishna Gudipati 
28835fbe25c7SJing Huang /*
2884a36c61f9SKrishna Gudipati  * Memory initialization.
2885a36c61f9SKrishna Gudipati  */
2886a36c61f9SKrishna Gudipati static void
2887a36c61f9SKrishna Gudipati bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
28884507025dSKrishna Gudipati 		struct bfa_pcidev_s *pcidev)
2889a36c61f9SKrishna Gudipati {
2890a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
2891a36c61f9SKrishna Gudipati 	struct bfa_port_cfg_s *port_cfg = &fcport->cfg;
2892a36c61f9SKrishna Gudipati 	struct bfa_fcport_ln_s *ln = &fcport->ln;
2893f16a1750SMaggie Zhang 	struct timeval tv;
2894a36c61f9SKrishna Gudipati 
2895a36c61f9SKrishna Gudipati 	fcport->bfa = bfa;
2896a36c61f9SKrishna Gudipati 	ln->fcport = fcport;
2897a36c61f9SKrishna Gudipati 
28984507025dSKrishna Gudipati 	bfa_fcport_mem_claim(fcport);
2899a36c61f9SKrishna Gudipati 
2900a36c61f9SKrishna Gudipati 	bfa_sm_set_state(fcport, bfa_fcport_sm_uninit);
2901a36c61f9SKrishna Gudipati 	bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
2902a36c61f9SKrishna Gudipati 
29035fbe25c7SJing Huang 	/*
2904a36c61f9SKrishna Gudipati 	 * initialize time stamp for stats reset
2905a36c61f9SKrishna Gudipati 	 */
2906f16a1750SMaggie Zhang 	do_gettimeofday(&tv);
2907a36c61f9SKrishna Gudipati 	fcport->stats_reset_time = tv.tv_sec;
2908a36c61f9SKrishna Gudipati 
29095fbe25c7SJing Huang 	/*
2910a36c61f9SKrishna Gudipati 	 * initialize and set default configuration
2911a36c61f9SKrishna Gudipati 	 */
2912a36c61f9SKrishna Gudipati 	port_cfg->topology = BFA_PORT_TOPOLOGY_P2P;
2913a36c61f9SKrishna Gudipati 	port_cfg->speed = BFA_PORT_SPEED_AUTO;
2914a36c61f9SKrishna Gudipati 	port_cfg->trunked = BFA_FALSE;
2915a36c61f9SKrishna Gudipati 	port_cfg->maxfrsize = 0;
2916a36c61f9SKrishna Gudipati 
2917a36c61f9SKrishna Gudipati 	port_cfg->trl_def_speed = BFA_PORT_SPEED_1GBPS;
2918a36c61f9SKrishna Gudipati 
291937ea0558SKrishna Gudipati 	INIT_LIST_HEAD(&fcport->stats_pending_q);
292037ea0558SKrishna Gudipati 	INIT_LIST_HEAD(&fcport->statsclr_pending_q);
292137ea0558SKrishna Gudipati 
2922a36c61f9SKrishna Gudipati 	bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport);
2923a36c61f9SKrishna Gudipati }
2924a36c61f9SKrishna Gudipati 
2925a36c61f9SKrishna Gudipati static void
2926a36c61f9SKrishna Gudipati bfa_fcport_detach(struct bfa_s *bfa)
2927a36c61f9SKrishna Gudipati {
2928a36c61f9SKrishna Gudipati }
2929a36c61f9SKrishna Gudipati 
29305fbe25c7SJing Huang /*
2931a36c61f9SKrishna Gudipati  * Called when IOC is ready.
2932a36c61f9SKrishna Gudipati  */
2933a36c61f9SKrishna Gudipati static void
2934a36c61f9SKrishna Gudipati bfa_fcport_start(struct bfa_s *bfa)
2935a36c61f9SKrishna Gudipati {
2936a36c61f9SKrishna Gudipati 	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START);
2937a36c61f9SKrishna Gudipati }
2938a36c61f9SKrishna Gudipati 
29395fbe25c7SJing Huang /*
2940a36c61f9SKrishna Gudipati  * Called before IOC is stopped.
2941a36c61f9SKrishna Gudipati  */
2942a36c61f9SKrishna Gudipati static void
2943a36c61f9SKrishna Gudipati bfa_fcport_stop(struct bfa_s *bfa)
2944a36c61f9SKrishna Gudipati {
2945a36c61f9SKrishna Gudipati 	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_STOP);
2946a36c61f9SKrishna Gudipati 	bfa_trunk_iocdisable(bfa);
2947a36c61f9SKrishna Gudipati }
2948a36c61f9SKrishna Gudipati 
29495fbe25c7SJing Huang /*
2950a36c61f9SKrishna Gudipati  * Called when IOC failure is detected.
2951a36c61f9SKrishna Gudipati  */
2952a36c61f9SKrishna Gudipati static void
2953a36c61f9SKrishna Gudipati bfa_fcport_iocdisable(struct bfa_s *bfa)
2954a36c61f9SKrishna Gudipati {
2955a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
2956a36c61f9SKrishna Gudipati 
2957a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fcport, BFA_FCPORT_SM_HWFAIL);
2958a36c61f9SKrishna Gudipati 	bfa_trunk_iocdisable(bfa);
2959a36c61f9SKrishna Gudipati }
2960a36c61f9SKrishna Gudipati 
2961a36c61f9SKrishna Gudipati static void
2962a36c61f9SKrishna Gudipati bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
2963a36c61f9SKrishna Gudipati {
2964a36c61f9SKrishna Gudipati 	struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
2965a36c61f9SKrishna Gudipati 	struct bfa_fcport_trunk_s *trunk = &fcport->trunk;
2966a36c61f9SKrishna Gudipati 
2967a36c61f9SKrishna Gudipati 	fcport->speed = pevent->link_state.speed;
2968a36c61f9SKrishna Gudipati 	fcport->topology = pevent->link_state.topology;
2969a36c61f9SKrishna Gudipati 
2970a36c61f9SKrishna Gudipati 	if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)
2971a36c61f9SKrishna Gudipati 		fcport->myalpa = 0;
2972a36c61f9SKrishna Gudipati 
2973a36c61f9SKrishna Gudipati 	/* QoS Details */
29746a18b167SJing Huang 	fcport->qos_attr = pevent->link_state.qos_attr;
29756a18b167SJing Huang 	fcport->qos_vc_attr = pevent->link_state.vc_fcf.qos_vc_attr;
2976a36c61f9SKrishna Gudipati 
29775fbe25c7SJing Huang 	/*
2978a36c61f9SKrishna Gudipati 	 * update trunk state if applicable
2979a36c61f9SKrishna Gudipati 	 */
2980a36c61f9SKrishna Gudipati 	if (!fcport->cfg.trunked)
2981a36c61f9SKrishna Gudipati 		trunk->attr.state = BFA_TRUNK_DISABLED;
2982a36c61f9SKrishna Gudipati 
2983a36c61f9SKrishna Gudipati 	/* update FCoE specific */
2984ba816ea8SJing Huang 	fcport->fcoe_vlan = be16_to_cpu(pevent->link_state.vc_fcf.fcf.vlan);
2985a36c61f9SKrishna Gudipati 
2986a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, fcport->speed);
2987a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, fcport->topology);
2988a36c61f9SKrishna Gudipati }
2989a36c61f9SKrishna Gudipati 
2990a36c61f9SKrishna Gudipati static void
2991a36c61f9SKrishna Gudipati bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport)
2992a36c61f9SKrishna Gudipati {
2993a36c61f9SKrishna Gudipati 	fcport->speed = BFA_PORT_SPEED_UNKNOWN;
2994a36c61f9SKrishna Gudipati 	fcport->topology = BFA_PORT_TOPOLOGY_NONE;
2995be540a99SKrishna Gudipati 	fcport->bbsc_op_state = BFA_FALSE;
2996a36c61f9SKrishna Gudipati }
2997a36c61f9SKrishna Gudipati 
29985fbe25c7SJing Huang /*
2999a36c61f9SKrishna Gudipati  * Send port enable message to firmware.
3000a36c61f9SKrishna Gudipati  */
3001a36c61f9SKrishna Gudipati static bfa_boolean_t
3002a36c61f9SKrishna Gudipati bfa_fcport_send_enable(struct bfa_fcport_s *fcport)
3003a36c61f9SKrishna Gudipati {
3004a36c61f9SKrishna Gudipati 	struct bfi_fcport_enable_req_s *m;
3005a36c61f9SKrishna Gudipati 
30065fbe25c7SJing Huang 	/*
3007a36c61f9SKrishna Gudipati 	 * Increment message tag before queue check, so that responses to old
3008a36c61f9SKrishna Gudipati 	 * requests are discarded.
3009a36c61f9SKrishna Gudipati 	 */
3010a36c61f9SKrishna Gudipati 	fcport->msgtag++;
3011a36c61f9SKrishna Gudipati 
30125fbe25c7SJing Huang 	/*
3013a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
3014a36c61f9SKrishna Gudipati 	 */
3015a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
3016a36c61f9SKrishna Gudipati 	if (!m) {
3017a36c61f9SKrishna Gudipati 		bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
3018a36c61f9SKrishna Gudipati 							&fcport->reqq_wait);
3019a36c61f9SKrishna Gudipati 		return BFA_FALSE;
3020a36c61f9SKrishna Gudipati 	}
3021a36c61f9SKrishna Gudipati 
3022a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ,
30233fd45980SKrishna Gudipati 			bfa_fn_lpu(fcport->bfa));
3024a36c61f9SKrishna Gudipati 	m->nwwn = fcport->nwwn;
3025a36c61f9SKrishna Gudipati 	m->pwwn = fcport->pwwn;
3026a36c61f9SKrishna Gudipati 	m->port_cfg = fcport->cfg;
3027a36c61f9SKrishna Gudipati 	m->msgtag = fcport->msgtag;
3028ba816ea8SJing Huang 	m->port_cfg.maxfrsize = cpu_to_be16(fcport->cfg.maxfrsize);
3029f3a060caSKrishna Gudipati 	 m->use_flash_cfg = fcport->use_flash_cfg;
3030a36c61f9SKrishna Gudipati 	bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa);
3031a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo);
3032a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi);
3033a36c61f9SKrishna Gudipati 
30345fbe25c7SJing Huang 	/*
3035a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
3036a36c61f9SKrishna Gudipati 	 */
30373fd45980SKrishna Gudipati 	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, m->mh);
3038a36c61f9SKrishna Gudipati 	return BFA_TRUE;
3039a36c61f9SKrishna Gudipati }
3040a36c61f9SKrishna Gudipati 
30415fbe25c7SJing Huang /*
3042a36c61f9SKrishna Gudipati  * Send port disable message to firmware.
3043a36c61f9SKrishna Gudipati  */
3044a36c61f9SKrishna Gudipati static	bfa_boolean_t
3045a36c61f9SKrishna Gudipati bfa_fcport_send_disable(struct bfa_fcport_s *fcport)
3046a36c61f9SKrishna Gudipati {
3047a36c61f9SKrishna Gudipati 	struct bfi_fcport_req_s *m;
3048a36c61f9SKrishna Gudipati 
30495fbe25c7SJing Huang 	/*
3050a36c61f9SKrishna Gudipati 	 * Increment message tag before queue check, so that responses to old
3051a36c61f9SKrishna Gudipati 	 * requests are discarded.
3052a36c61f9SKrishna Gudipati 	 */
3053a36c61f9SKrishna Gudipati 	fcport->msgtag++;
3054a36c61f9SKrishna Gudipati 
30555fbe25c7SJing Huang 	/*
3056a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
3057a36c61f9SKrishna Gudipati 	 */
3058a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
3059a36c61f9SKrishna Gudipati 	if (!m) {
3060a36c61f9SKrishna Gudipati 		bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
3061a36c61f9SKrishna Gudipati 							&fcport->reqq_wait);
3062a36c61f9SKrishna Gudipati 		return BFA_FALSE;
3063a36c61f9SKrishna Gudipati 	}
3064a36c61f9SKrishna Gudipati 
3065a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ,
30663fd45980SKrishna Gudipati 			bfa_fn_lpu(fcport->bfa));
3067a36c61f9SKrishna Gudipati 	m->msgtag = fcport->msgtag;
3068a36c61f9SKrishna Gudipati 
30695fbe25c7SJing Huang 	/*
3070a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
3071a36c61f9SKrishna Gudipati 	 */
30723fd45980SKrishna Gudipati 	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, m->mh);
3073a36c61f9SKrishna Gudipati 
3074a36c61f9SKrishna Gudipati 	return BFA_TRUE;
3075a36c61f9SKrishna Gudipati }
3076a36c61f9SKrishna Gudipati 
3077a36c61f9SKrishna Gudipati static void
3078a36c61f9SKrishna Gudipati bfa_fcport_set_wwns(struct bfa_fcport_s *fcport)
3079a36c61f9SKrishna Gudipati {
3080f7f73812SMaggie Zhang 	fcport->pwwn = fcport->bfa->ioc.attr->pwwn;
3081f7f73812SMaggie Zhang 	fcport->nwwn = fcport->bfa->ioc.attr->nwwn;
3082a36c61f9SKrishna Gudipati 
3083a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, fcport->pwwn);
3084a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, fcport->nwwn);
3085a36c61f9SKrishna Gudipati }
3086a36c61f9SKrishna Gudipati 
3087a36c61f9SKrishna Gudipati static void
3088a36c61f9SKrishna Gudipati bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d,
3089a36c61f9SKrishna Gudipati 	struct bfa_qos_stats_s *s)
3090a36c61f9SKrishna Gudipati {
3091a36c61f9SKrishna Gudipati 	u32	*dip = (u32 *) d;
309250444a34SMaggie 	__be32	*sip = (__be32 *) s;
3093a36c61f9SKrishna Gudipati 	int		i;
3094a36c61f9SKrishna Gudipati 
3095a36c61f9SKrishna Gudipati 	/* Now swap the 32 bit fields */
3096a36c61f9SKrishna Gudipati 	for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i)
3097ba816ea8SJing Huang 		dip[i] = be32_to_cpu(sip[i]);
3098a36c61f9SKrishna Gudipati }
3099a36c61f9SKrishna Gudipati 
3100a36c61f9SKrishna Gudipati static void
3101a36c61f9SKrishna Gudipati bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d,
3102a36c61f9SKrishna Gudipati 	struct bfa_fcoe_stats_s *s)
3103a36c61f9SKrishna Gudipati {
3104a36c61f9SKrishna Gudipati 	u32	*dip = (u32 *) d;
310550444a34SMaggie 	__be32	*sip = (__be32 *) s;
3106a36c61f9SKrishna Gudipati 	int		i;
3107a36c61f9SKrishna Gudipati 
3108a36c61f9SKrishna Gudipati 	for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32));
3109a36c61f9SKrishna Gudipati 	     i = i + 2) {
3110f16a1750SMaggie Zhang #ifdef __BIG_ENDIAN
3111ba816ea8SJing Huang 		dip[i] = be32_to_cpu(sip[i]);
3112ba816ea8SJing Huang 		dip[i + 1] = be32_to_cpu(sip[i + 1]);
3113a36c61f9SKrishna Gudipati #else
3114ba816ea8SJing Huang 		dip[i] = be32_to_cpu(sip[i + 1]);
3115ba816ea8SJing Huang 		dip[i + 1] = be32_to_cpu(sip[i]);
3116a36c61f9SKrishna Gudipati #endif
3117a36c61f9SKrishna Gudipati 	}
3118a36c61f9SKrishna Gudipati }
3119a36c61f9SKrishna Gudipati 
3120a36c61f9SKrishna Gudipati static void
3121a36c61f9SKrishna Gudipati __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
3122a36c61f9SKrishna Gudipati {
312337ea0558SKrishna Gudipati 	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *)cbarg;
312437ea0558SKrishna Gudipati 	struct bfa_cb_pending_q_s *cb;
312537ea0558SKrishna Gudipati 	struct list_head *qe, *qen;
312637ea0558SKrishna Gudipati 	union bfa_fcport_stats_u *ret;
3127a36c61f9SKrishna Gudipati 
3128a36c61f9SKrishna Gudipati 	if (complete) {
3129f16a1750SMaggie Zhang 		struct timeval tv;
313037ea0558SKrishna Gudipati 		if (fcport->stats_status == BFA_STATUS_OK)
3131f16a1750SMaggie Zhang 			do_gettimeofday(&tv);
313237ea0558SKrishna Gudipati 
313337ea0558SKrishna Gudipati 		list_for_each_safe(qe, qen, &fcport->stats_pending_q) {
313437ea0558SKrishna Gudipati 			bfa_q_deq(&fcport->stats_pending_q, &qe);
313537ea0558SKrishna Gudipati 			cb = (struct bfa_cb_pending_q_s *)qe;
313637ea0558SKrishna Gudipati 			if (fcport->stats_status == BFA_STATUS_OK) {
313737ea0558SKrishna Gudipati 				ret = (union bfa_fcport_stats_u *)cb->data;
313837ea0558SKrishna Gudipati 				/* Swap FC QoS or FCoE stats */
313937ea0558SKrishna Gudipati 				if (bfa_ioc_get_fcmode(&fcport->bfa->ioc))
314037ea0558SKrishna Gudipati 					bfa_fcport_qos_stats_swap(&ret->fcqos,
314137ea0558SKrishna Gudipati 							&fcport->stats->fcqos);
314237ea0558SKrishna Gudipati 				else {
314337ea0558SKrishna Gudipati 					bfa_fcport_fcoe_stats_swap(&ret->fcoe,
314437ea0558SKrishna Gudipati 							&fcport->stats->fcoe);
314537ea0558SKrishna Gudipati 					ret->fcoe.secs_reset =
3146a36c61f9SKrishna Gudipati 					tv.tv_sec - fcport->stats_reset_time;
3147a36c61f9SKrishna Gudipati 				}
3148a36c61f9SKrishna Gudipati 			}
314937ea0558SKrishna Gudipati 			bfa_cb_queue_status(fcport->bfa, &cb->hcb_qe,
315037ea0558SKrishna Gudipati 					fcport->stats_status);
315137ea0558SKrishna Gudipati 		}
315237ea0558SKrishna Gudipati 		fcport->stats_status = BFA_STATUS_OK;
3153a36c61f9SKrishna Gudipati 	} else {
315437ea0558SKrishna Gudipati 		INIT_LIST_HEAD(&fcport->stats_pending_q);
3155a36c61f9SKrishna Gudipati 		fcport->stats_status = BFA_STATUS_OK;
3156a36c61f9SKrishna Gudipati 	}
3157a36c61f9SKrishna Gudipati }
3158a36c61f9SKrishna Gudipati 
3159a36c61f9SKrishna Gudipati static void
3160a36c61f9SKrishna Gudipati bfa_fcport_stats_get_timeout(void *cbarg)
3161a36c61f9SKrishna Gudipati {
3162a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
3163a36c61f9SKrishna Gudipati 
3164a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, fcport->stats_qfull);
3165a36c61f9SKrishna Gudipati 
3166a36c61f9SKrishna Gudipati 	if (fcport->stats_qfull) {
3167a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->stats_reqq_wait);
3168a36c61f9SKrishna Gudipati 		fcport->stats_qfull = BFA_FALSE;
3169a36c61f9SKrishna Gudipati 	}
3170a36c61f9SKrishna Gudipati 
3171a36c61f9SKrishna Gudipati 	fcport->stats_status = BFA_STATUS_ETIMER;
317237ea0558SKrishna Gudipati 	__bfa_cb_fcport_stats_get(fcport, BFA_TRUE);
3173a36c61f9SKrishna Gudipati }
3174a36c61f9SKrishna Gudipati 
3175a36c61f9SKrishna Gudipati static void
3176a36c61f9SKrishna Gudipati bfa_fcport_send_stats_get(void *cbarg)
3177a36c61f9SKrishna Gudipati {
3178a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
3179a36c61f9SKrishna Gudipati 	struct bfi_fcport_req_s *msg;
3180a36c61f9SKrishna Gudipati 
3181a36c61f9SKrishna Gudipati 	msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
3182a36c61f9SKrishna Gudipati 
3183a36c61f9SKrishna Gudipati 	if (!msg) {
3184a36c61f9SKrishna Gudipati 		fcport->stats_qfull = BFA_TRUE;
3185a36c61f9SKrishna Gudipati 		bfa_reqq_winit(&fcport->stats_reqq_wait,
3186a36c61f9SKrishna Gudipati 				bfa_fcport_send_stats_get, fcport);
3187a36c61f9SKrishna Gudipati 		bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
3188a36c61f9SKrishna Gudipati 				&fcport->stats_reqq_wait);
3189a36c61f9SKrishna Gudipati 		return;
3190a36c61f9SKrishna Gudipati 	}
3191a36c61f9SKrishna Gudipati 	fcport->stats_qfull = BFA_FALSE;
3192a36c61f9SKrishna Gudipati 
31936a18b167SJing Huang 	memset(msg, 0, sizeof(struct bfi_fcport_req_s));
3194a36c61f9SKrishna Gudipati 	bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ,
31953fd45980SKrishna Gudipati 			bfa_fn_lpu(fcport->bfa));
31963fd45980SKrishna Gudipati 	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, msg->mh);
3197a36c61f9SKrishna Gudipati }
3198a36c61f9SKrishna Gudipati 
3199a36c61f9SKrishna Gudipati static void
3200a36c61f9SKrishna Gudipati __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
3201a36c61f9SKrishna Gudipati {
320237ea0558SKrishna Gudipati 	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
320337ea0558SKrishna Gudipati 	struct bfa_cb_pending_q_s *cb;
320437ea0558SKrishna Gudipati 	struct list_head *qe, *qen;
3205a36c61f9SKrishna Gudipati 
3206a36c61f9SKrishna Gudipati 	if (complete) {
3207f16a1750SMaggie Zhang 		struct timeval tv;
3208a36c61f9SKrishna Gudipati 
32095fbe25c7SJing Huang 		/*
3210a36c61f9SKrishna Gudipati 		 * re-initialize time stamp for stats reset
3211a36c61f9SKrishna Gudipati 		 */
3212f16a1750SMaggie Zhang 		do_gettimeofday(&tv);
3213a36c61f9SKrishna Gudipati 		fcport->stats_reset_time = tv.tv_sec;
321437ea0558SKrishna Gudipati 		list_for_each_safe(qe, qen, &fcport->statsclr_pending_q) {
321537ea0558SKrishna Gudipati 			bfa_q_deq(&fcport->statsclr_pending_q, &qe);
321637ea0558SKrishna Gudipati 			cb = (struct bfa_cb_pending_q_s *)qe;
321737ea0558SKrishna Gudipati 			bfa_cb_queue_status(fcport->bfa, &cb->hcb_qe,
321837ea0558SKrishna Gudipati 						fcport->stats_status);
321937ea0558SKrishna Gudipati 		}
322037ea0558SKrishna Gudipati 		fcport->stats_status = BFA_STATUS_OK;
3221a36c61f9SKrishna Gudipati 	} else {
322237ea0558SKrishna Gudipati 		INIT_LIST_HEAD(&fcport->statsclr_pending_q);
3223a36c61f9SKrishna Gudipati 		fcport->stats_status = BFA_STATUS_OK;
3224a36c61f9SKrishna Gudipati 	}
3225a36c61f9SKrishna Gudipati }
3226a36c61f9SKrishna Gudipati 
3227a36c61f9SKrishna Gudipati static void
3228a36c61f9SKrishna Gudipati bfa_fcport_stats_clr_timeout(void *cbarg)
3229a36c61f9SKrishna Gudipati {
3230a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
3231a36c61f9SKrishna Gudipati 
3232a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, fcport->stats_qfull);
3233a36c61f9SKrishna Gudipati 
3234a36c61f9SKrishna Gudipati 	if (fcport->stats_qfull) {
3235a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->stats_reqq_wait);
3236a36c61f9SKrishna Gudipati 		fcport->stats_qfull = BFA_FALSE;
3237a36c61f9SKrishna Gudipati 	}
3238a36c61f9SKrishna Gudipati 
3239a36c61f9SKrishna Gudipati 	fcport->stats_status = BFA_STATUS_ETIMER;
324037ea0558SKrishna Gudipati 	__bfa_cb_fcport_stats_clr(fcport, BFA_TRUE);
3241a36c61f9SKrishna Gudipati }
3242a36c61f9SKrishna Gudipati 
3243a36c61f9SKrishna Gudipati static void
3244a36c61f9SKrishna Gudipati bfa_fcport_send_stats_clear(void *cbarg)
3245a36c61f9SKrishna Gudipati {
3246a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
3247a36c61f9SKrishna Gudipati 	struct bfi_fcport_req_s *msg;
3248a36c61f9SKrishna Gudipati 
3249a36c61f9SKrishna Gudipati 	msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
3250a36c61f9SKrishna Gudipati 
3251a36c61f9SKrishna Gudipati 	if (!msg) {
3252a36c61f9SKrishna Gudipati 		fcport->stats_qfull = BFA_TRUE;
3253a36c61f9SKrishna Gudipati 		bfa_reqq_winit(&fcport->stats_reqq_wait,
3254a36c61f9SKrishna Gudipati 				bfa_fcport_send_stats_clear, fcport);
3255a36c61f9SKrishna Gudipati 		bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
3256a36c61f9SKrishna Gudipati 						&fcport->stats_reqq_wait);
3257a36c61f9SKrishna Gudipati 		return;
3258a36c61f9SKrishna Gudipati 	}
3259a36c61f9SKrishna Gudipati 	fcport->stats_qfull = BFA_FALSE;
3260a36c61f9SKrishna Gudipati 
32616a18b167SJing Huang 	memset(msg, 0, sizeof(struct bfi_fcport_req_s));
3262a36c61f9SKrishna Gudipati 	bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ,
32633fd45980SKrishna Gudipati 			bfa_fn_lpu(fcport->bfa));
32643fd45980SKrishna Gudipati 	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT, msg->mh);
3265a36c61f9SKrishna Gudipati }
3266a36c61f9SKrishna Gudipati 
32675fbe25c7SJing Huang /*
3268a36c61f9SKrishna Gudipati  * Handle trunk SCN event from firmware.
3269a36c61f9SKrishna Gudipati  */
3270a36c61f9SKrishna Gudipati static void
3271a36c61f9SKrishna Gudipati bfa_trunk_scn(struct bfa_fcport_s *fcport, struct bfi_fcport_trunk_scn_s *scn)
3272a36c61f9SKrishna Gudipati {
3273a36c61f9SKrishna Gudipati 	struct bfa_fcport_trunk_s *trunk = &fcport->trunk;
3274a36c61f9SKrishna Gudipati 	struct bfi_fcport_trunk_link_s *tlink;
3275a36c61f9SKrishna Gudipati 	struct bfa_trunk_link_attr_s *lattr;
3276a36c61f9SKrishna Gudipati 	enum bfa_trunk_state state_prev;
3277a36c61f9SKrishna Gudipati 	int i;
3278a36c61f9SKrishna Gudipati 	int link_bm = 0;
3279a36c61f9SKrishna Gudipati 
3280a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, fcport->cfg.trunked);
3281d4b671c5SJing Huang 	WARN_ON(scn->trunk_state != BFA_TRUNK_ONLINE &&
3282d4b671c5SJing Huang 		   scn->trunk_state != BFA_TRUNK_OFFLINE);
3283a36c61f9SKrishna Gudipati 
3284a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, trunk->attr.state);
3285a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, scn->trunk_state);
3286a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, scn->trunk_speed);
3287a36c61f9SKrishna Gudipati 
32885fbe25c7SJing Huang 	/*
3289a36c61f9SKrishna Gudipati 	 * Save off new state for trunk attribute query
3290a36c61f9SKrishna Gudipati 	 */
3291a36c61f9SKrishna Gudipati 	state_prev = trunk->attr.state;
3292a36c61f9SKrishna Gudipati 	if (fcport->cfg.trunked && (trunk->attr.state != BFA_TRUNK_DISABLED))
3293a36c61f9SKrishna Gudipati 		trunk->attr.state = scn->trunk_state;
3294a36c61f9SKrishna Gudipati 	trunk->attr.speed = scn->trunk_speed;
3295a36c61f9SKrishna Gudipati 	for (i = 0; i < BFA_TRUNK_MAX_PORTS; i++) {
3296a36c61f9SKrishna Gudipati 		lattr = &trunk->attr.link_attr[i];
3297a36c61f9SKrishna Gudipati 		tlink = &scn->tlink[i];
3298a36c61f9SKrishna Gudipati 
3299a36c61f9SKrishna Gudipati 		lattr->link_state = tlink->state;
3300a36c61f9SKrishna Gudipati 		lattr->trunk_wwn  = tlink->trunk_wwn;
3301a36c61f9SKrishna Gudipati 		lattr->fctl	  = tlink->fctl;
3302a36c61f9SKrishna Gudipati 		lattr->speed	  = tlink->speed;
3303ba816ea8SJing Huang 		lattr->deskew	  = be32_to_cpu(tlink->deskew);
3304a36c61f9SKrishna Gudipati 
3305a36c61f9SKrishna Gudipati 		if (tlink->state == BFA_TRUNK_LINK_STATE_UP) {
3306a36c61f9SKrishna Gudipati 			fcport->speed	 = tlink->speed;
3307a36c61f9SKrishna Gudipati 			fcport->topology = BFA_PORT_TOPOLOGY_P2P;
3308a36c61f9SKrishna Gudipati 			link_bm |= 1 << i;
3309a36c61f9SKrishna Gudipati 		}
3310a36c61f9SKrishna Gudipati 
3311a36c61f9SKrishna Gudipati 		bfa_trc(fcport->bfa, lattr->link_state);
3312a36c61f9SKrishna Gudipati 		bfa_trc(fcport->bfa, lattr->trunk_wwn);
3313a36c61f9SKrishna Gudipati 		bfa_trc(fcport->bfa, lattr->fctl);
3314a36c61f9SKrishna Gudipati 		bfa_trc(fcport->bfa, lattr->speed);
3315a36c61f9SKrishna Gudipati 		bfa_trc(fcport->bfa, lattr->deskew);
3316a36c61f9SKrishna Gudipati 	}
3317a36c61f9SKrishna Gudipati 
3318a36c61f9SKrishna Gudipati 	switch (link_bm) {
3319a36c61f9SKrishna Gudipati 	case 3:
3320a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
3321a36c61f9SKrishna Gudipati 			BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(0,1)");
3322a36c61f9SKrishna Gudipati 		break;
3323a36c61f9SKrishna Gudipati 	case 2:
3324a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
3325a36c61f9SKrishna Gudipati 			BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(-,1)");
3326a36c61f9SKrishna Gudipati 		break;
3327a36c61f9SKrishna Gudipati 	case 1:
3328a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
3329a36c61f9SKrishna Gudipati 			BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(0,-)");
3330a36c61f9SKrishna Gudipati 		break;
3331a36c61f9SKrishna Gudipati 	default:
3332a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
3333a36c61f9SKrishna Gudipati 			BFA_PL_EID_TRUNK_SCN, 0, "Trunk down");
3334a36c61f9SKrishna Gudipati 	}
3335a36c61f9SKrishna Gudipati 
33365fbe25c7SJing Huang 	/*
3337a36c61f9SKrishna Gudipati 	 * Notify upper layers if trunk state changed.
3338a36c61f9SKrishna Gudipati 	 */
3339a36c61f9SKrishna Gudipati 	if ((state_prev != trunk->attr.state) ||
3340a36c61f9SKrishna Gudipati 		(scn->trunk_state == BFA_TRUNK_OFFLINE)) {
3341a36c61f9SKrishna Gudipati 		bfa_fcport_scn(fcport, (scn->trunk_state == BFA_TRUNK_ONLINE) ?
3342a36c61f9SKrishna Gudipati 			BFA_PORT_LINKUP : BFA_PORT_LINKDOWN, BFA_TRUE);
3343a36c61f9SKrishna Gudipati 	}
3344a36c61f9SKrishna Gudipati }
3345a36c61f9SKrishna Gudipati 
3346a36c61f9SKrishna Gudipati static void
3347a36c61f9SKrishna Gudipati bfa_trunk_iocdisable(struct bfa_s *bfa)
3348a36c61f9SKrishna Gudipati {
3349a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3350a36c61f9SKrishna Gudipati 	int i = 0;
3351a36c61f9SKrishna Gudipati 
33525fbe25c7SJing Huang 	/*
3353a36c61f9SKrishna Gudipati 	 * In trunked mode, notify upper layers that link is down
3354a36c61f9SKrishna Gudipati 	 */
3355a36c61f9SKrishna Gudipati 	if (fcport->cfg.trunked) {
3356a36c61f9SKrishna Gudipati 		if (fcport->trunk.attr.state == BFA_TRUNK_ONLINE)
3357a36c61f9SKrishna Gudipati 			bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_TRUE);
3358a36c61f9SKrishna Gudipati 
3359a36c61f9SKrishna Gudipati 		fcport->trunk.attr.state = BFA_TRUNK_OFFLINE;
3360a36c61f9SKrishna Gudipati 		fcport->trunk.attr.speed = BFA_PORT_SPEED_UNKNOWN;
3361a36c61f9SKrishna Gudipati 		for (i = 0; i < BFA_TRUNK_MAX_PORTS; i++) {
3362a36c61f9SKrishna Gudipati 			fcport->trunk.attr.link_attr[i].trunk_wwn = 0;
3363a36c61f9SKrishna Gudipati 			fcport->trunk.attr.link_attr[i].fctl =
3364a36c61f9SKrishna Gudipati 						BFA_TRUNK_LINK_FCTL_NORMAL;
3365a36c61f9SKrishna Gudipati 			fcport->trunk.attr.link_attr[i].link_state =
3366a36c61f9SKrishna Gudipati 						BFA_TRUNK_LINK_STATE_DN_LINKDN;
3367a36c61f9SKrishna Gudipati 			fcport->trunk.attr.link_attr[i].speed =
3368a36c61f9SKrishna Gudipati 						BFA_PORT_SPEED_UNKNOWN;
3369a36c61f9SKrishna Gudipati 			fcport->trunk.attr.link_attr[i].deskew = 0;
3370a36c61f9SKrishna Gudipati 		}
3371a36c61f9SKrishna Gudipati 	}
3372a36c61f9SKrishna Gudipati }
3373a36c61f9SKrishna Gudipati 
33745fbe25c7SJing Huang /*
3375a36c61f9SKrishna Gudipati  * Called to initialize port attributes
3376a36c61f9SKrishna Gudipati  */
3377a36c61f9SKrishna Gudipati void
3378a36c61f9SKrishna Gudipati bfa_fcport_init(struct bfa_s *bfa)
3379a36c61f9SKrishna Gudipati {
3380a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3381a36c61f9SKrishna Gudipati 
33825fbe25c7SJing Huang 	/*
3383a36c61f9SKrishna Gudipati 	 * Initialize port attributes from IOC hardware data.
3384a36c61f9SKrishna Gudipati 	 */
3385a36c61f9SKrishna Gudipati 	bfa_fcport_set_wwns(fcport);
3386a36c61f9SKrishna Gudipati 	if (fcport->cfg.maxfrsize == 0)
3387a36c61f9SKrishna Gudipati 		fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
3388a36c61f9SKrishna Gudipati 	fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
3389a36c61f9SKrishna Gudipati 	fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
3390a36c61f9SKrishna Gudipati 
339143ffdf4dSKrishna Gudipati 	if (bfa_fcport_is_pbcdisabled(bfa))
339243ffdf4dSKrishna Gudipati 		bfa->modules.port.pbc_disabled = BFA_TRUE;
339343ffdf4dSKrishna Gudipati 
3394d4b671c5SJing Huang 	WARN_ON(!fcport->cfg.maxfrsize);
3395d4b671c5SJing Huang 	WARN_ON(!fcport->cfg.rx_bbcredit);
3396d4b671c5SJing Huang 	WARN_ON(!fcport->speed_sup);
3397a36c61f9SKrishna Gudipati }
3398a36c61f9SKrishna Gudipati 
33995fbe25c7SJing Huang /*
3400a36c61f9SKrishna Gudipati  * Firmware message handler.
3401a36c61f9SKrishna Gudipati  */
3402a36c61f9SKrishna Gudipati void
3403a36c61f9SKrishna Gudipati bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
3404a36c61f9SKrishna Gudipati {
3405a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3406a36c61f9SKrishna Gudipati 	union bfi_fcport_i2h_msg_u i2hmsg;
3407a36c61f9SKrishna Gudipati 
3408a36c61f9SKrishna Gudipati 	i2hmsg.msg = msg;
3409a36c61f9SKrishna Gudipati 	fcport->event_arg.i2hmsg = i2hmsg;
3410a36c61f9SKrishna Gudipati 
3411a36c61f9SKrishna Gudipati 	bfa_trc(bfa, msg->mhdr.msg_id);
3412a36c61f9SKrishna Gudipati 	bfa_trc(bfa, bfa_sm_to_state(hal_port_sm_table, fcport->sm));
3413a36c61f9SKrishna Gudipati 
3414a36c61f9SKrishna Gudipati 	switch (msg->mhdr.msg_id) {
3415a36c61f9SKrishna Gudipati 	case BFI_FCPORT_I2H_ENABLE_RSP:
3416f3a060caSKrishna Gudipati 		if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) {
3417f3a060caSKrishna Gudipati 
3418f3a060caSKrishna Gudipati 			if (fcport->use_flash_cfg) {
3419f3a060caSKrishna Gudipati 				fcport->cfg = i2hmsg.penable_rsp->port_cfg;
3420f3a060caSKrishna Gudipati 				fcport->cfg.maxfrsize =
3421f3a060caSKrishna Gudipati 					cpu_to_be16(fcport->cfg.maxfrsize);
3422f3a060caSKrishna Gudipati 				fcport->cfg.path_tov =
3423f3a060caSKrishna Gudipati 					cpu_to_be16(fcport->cfg.path_tov);
3424f3a060caSKrishna Gudipati 				fcport->cfg.q_depth =
3425f3a060caSKrishna Gudipati 					cpu_to_be16(fcport->cfg.q_depth);
3426f3a060caSKrishna Gudipati 
3427f3a060caSKrishna Gudipati 				if (fcport->cfg.trunked)
3428f3a060caSKrishna Gudipati 					fcport->trunk.attr.state =
3429f3a060caSKrishna Gudipati 						BFA_TRUNK_OFFLINE;
3430f3a060caSKrishna Gudipati 				else
3431f3a060caSKrishna Gudipati 					fcport->trunk.attr.state =
3432f3a060caSKrishna Gudipati 						BFA_TRUNK_DISABLED;
3433f3a060caSKrishna Gudipati 				fcport->use_flash_cfg = BFA_FALSE;
3434f3a060caSKrishna Gudipati 			}
3435f3a060caSKrishna Gudipati 
34363ec4f2c8SKrishna Gudipati 			if (fcport->cfg.qos_enabled)
34373ec4f2c8SKrishna Gudipati 				fcport->qos_attr.state = BFA_QOS_OFFLINE;
34383ec4f2c8SKrishna Gudipati 			else
34393ec4f2c8SKrishna Gudipati 				fcport->qos_attr.state = BFA_QOS_DISABLED;
34403ec4f2c8SKrishna Gudipati 
3441a36c61f9SKrishna Gudipati 			bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
3442f3a060caSKrishna Gudipati 		}
3443a36c61f9SKrishna Gudipati 		break;
3444a36c61f9SKrishna Gudipati 
3445a36c61f9SKrishna Gudipati 	case BFI_FCPORT_I2H_DISABLE_RSP:
3446a36c61f9SKrishna Gudipati 		if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
3447a36c61f9SKrishna Gudipati 			bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
3448a36c61f9SKrishna Gudipati 		break;
3449a36c61f9SKrishna Gudipati 
3450a36c61f9SKrishna Gudipati 	case BFI_FCPORT_I2H_EVENT:
3451a36c61f9SKrishna Gudipati 		if (i2hmsg.event->link_state.linkstate == BFA_PORT_LINKUP)
3452a36c61f9SKrishna Gudipati 			bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP);
3453a36c61f9SKrishna Gudipati 		else
3454a36c61f9SKrishna Gudipati 			bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN);
3455a36c61f9SKrishna Gudipati 		break;
3456a36c61f9SKrishna Gudipati 
3457a36c61f9SKrishna Gudipati 	case BFI_FCPORT_I2H_TRUNK_SCN:
3458a36c61f9SKrishna Gudipati 		bfa_trunk_scn(fcport, i2hmsg.trunk_scn);
3459a36c61f9SKrishna Gudipati 		break;
3460a36c61f9SKrishna Gudipati 
3461a36c61f9SKrishna Gudipati 	case BFI_FCPORT_I2H_STATS_GET_RSP:
3462a36c61f9SKrishna Gudipati 		/*
3463a36c61f9SKrishna Gudipati 		 * check for timer pop before processing the rsp
3464a36c61f9SKrishna Gudipati 		 */
346537ea0558SKrishna Gudipati 		if (list_empty(&fcport->stats_pending_q) ||
346637ea0558SKrishna Gudipati 		    (fcport->stats_status == BFA_STATUS_ETIMER))
3467a36c61f9SKrishna Gudipati 			break;
3468a36c61f9SKrishna Gudipati 
3469a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fcport->timer);
3470a36c61f9SKrishna Gudipati 		fcport->stats_status = i2hmsg.pstatsget_rsp->status;
347137ea0558SKrishna Gudipati 		__bfa_cb_fcport_stats_get(fcport, BFA_TRUE);
3472a36c61f9SKrishna Gudipati 		break;
3473a36c61f9SKrishna Gudipati 
3474a36c61f9SKrishna Gudipati 	case BFI_FCPORT_I2H_STATS_CLEAR_RSP:
3475a36c61f9SKrishna Gudipati 		/*
3476a36c61f9SKrishna Gudipati 		 * check for timer pop before processing the rsp
3477a36c61f9SKrishna Gudipati 		 */
347837ea0558SKrishna Gudipati 		if (list_empty(&fcport->statsclr_pending_q) ||
347937ea0558SKrishna Gudipati 		    (fcport->stats_status == BFA_STATUS_ETIMER))
3480a36c61f9SKrishna Gudipati 			break;
3481a36c61f9SKrishna Gudipati 
3482a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fcport->timer);
3483a36c61f9SKrishna Gudipati 		fcport->stats_status = BFA_STATUS_OK;
348437ea0558SKrishna Gudipati 		__bfa_cb_fcport_stats_clr(fcport, BFA_TRUE);
3485a36c61f9SKrishna Gudipati 		break;
3486a36c61f9SKrishna Gudipati 
3487a36c61f9SKrishna Gudipati 	case BFI_FCPORT_I2H_ENABLE_AEN:
3488a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fcport, BFA_FCPORT_SM_ENABLE);
3489a36c61f9SKrishna Gudipati 		break;
3490a36c61f9SKrishna Gudipati 
3491a36c61f9SKrishna Gudipati 	case BFI_FCPORT_I2H_DISABLE_AEN:
3492a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fcport, BFA_FCPORT_SM_DISABLE);
3493a36c61f9SKrishna Gudipati 		break;
3494a36c61f9SKrishna Gudipati 
3495a36c61f9SKrishna Gudipati 	default:
3496d4b671c5SJing Huang 		WARN_ON(1);
3497a36c61f9SKrishna Gudipati 	break;
3498a36c61f9SKrishna Gudipati 	}
3499a36c61f9SKrishna Gudipati }
3500a36c61f9SKrishna Gudipati 
35015fbe25c7SJing Huang /*
3502a36c61f9SKrishna Gudipati  * Registered callback for port events.
3503a36c61f9SKrishna Gudipati  */
3504a36c61f9SKrishna Gudipati void
3505a36c61f9SKrishna Gudipati bfa_fcport_event_register(struct bfa_s *bfa,
3506a36c61f9SKrishna Gudipati 				void (*cbfn) (void *cbarg,
3507a36c61f9SKrishna Gudipati 				enum bfa_port_linkstate event),
3508a36c61f9SKrishna Gudipati 				void *cbarg)
3509a36c61f9SKrishna Gudipati {
3510a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3511a36c61f9SKrishna Gudipati 
3512a36c61f9SKrishna Gudipati 	fcport->event_cbfn = cbfn;
3513a36c61f9SKrishna Gudipati 	fcport->event_cbarg = cbarg;
3514a36c61f9SKrishna Gudipati }
3515a36c61f9SKrishna Gudipati 
3516a36c61f9SKrishna Gudipati bfa_status_t
3517a36c61f9SKrishna Gudipati bfa_fcport_enable(struct bfa_s *bfa)
3518a36c61f9SKrishna Gudipati {
3519a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3520a36c61f9SKrishna Gudipati 
352143ffdf4dSKrishna Gudipati 	if (bfa_fcport_is_pbcdisabled(bfa))
352243ffdf4dSKrishna Gudipati 		return BFA_STATUS_PBC;
352343ffdf4dSKrishna Gudipati 
3524a36c61f9SKrishna Gudipati 	if (bfa_ioc_is_disabled(&bfa->ioc))
3525a36c61f9SKrishna Gudipati 		return BFA_STATUS_IOC_DISABLED;
3526a36c61f9SKrishna Gudipati 
3527a36c61f9SKrishna Gudipati 	if (fcport->diag_busy)
3528a36c61f9SKrishna Gudipati 		return BFA_STATUS_DIAG_BUSY;
3529a36c61f9SKrishna Gudipati 
3530a36c61f9SKrishna Gudipati 	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_ENABLE);
3531a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3532a36c61f9SKrishna Gudipati }
3533a36c61f9SKrishna Gudipati 
3534a36c61f9SKrishna Gudipati bfa_status_t
3535a36c61f9SKrishna Gudipati bfa_fcport_disable(struct bfa_s *bfa)
3536a36c61f9SKrishna Gudipati {
353743ffdf4dSKrishna Gudipati 	if (bfa_fcport_is_pbcdisabled(bfa))
353843ffdf4dSKrishna Gudipati 		return BFA_STATUS_PBC;
3539a36c61f9SKrishna Gudipati 
3540a36c61f9SKrishna Gudipati 	if (bfa_ioc_is_disabled(&bfa->ioc))
3541a36c61f9SKrishna Gudipati 		return BFA_STATUS_IOC_DISABLED;
3542a36c61f9SKrishna Gudipati 
3543a36c61f9SKrishna Gudipati 	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE);
3544a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3545a36c61f9SKrishna Gudipati }
3546a36c61f9SKrishna Gudipati 
354743ffdf4dSKrishna Gudipati /* If PBC is disabled on port, return error */
354843ffdf4dSKrishna Gudipati bfa_status_t
354943ffdf4dSKrishna Gudipati bfa_fcport_is_pbcdisabled(struct bfa_s *bfa)
355043ffdf4dSKrishna Gudipati {
355143ffdf4dSKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
355243ffdf4dSKrishna Gudipati 	struct bfa_iocfc_s *iocfc = &bfa->iocfc;
355343ffdf4dSKrishna Gudipati 	struct bfi_iocfc_cfgrsp_s *cfgrsp = iocfc->cfgrsp;
355443ffdf4dSKrishna Gudipati 
355543ffdf4dSKrishna Gudipati 	if (cfgrsp->pbc_cfg.port_enabled == BFI_PBC_PORT_DISABLED) {
355643ffdf4dSKrishna Gudipati 		bfa_trc(bfa, fcport->pwwn);
355743ffdf4dSKrishna Gudipati 		return BFA_STATUS_PBC;
355843ffdf4dSKrishna Gudipati 	}
355943ffdf4dSKrishna Gudipati 	return BFA_STATUS_OK;
356043ffdf4dSKrishna Gudipati }
356143ffdf4dSKrishna Gudipati 
35625fbe25c7SJing Huang /*
3563a36c61f9SKrishna Gudipati  * Configure port speed.
3564a36c61f9SKrishna Gudipati  */
3565a36c61f9SKrishna Gudipati bfa_status_t
3566a36c61f9SKrishna Gudipati bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_port_speed speed)
3567a36c61f9SKrishna Gudipati {
3568a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3569a36c61f9SKrishna Gudipati 
3570a36c61f9SKrishna Gudipati 	bfa_trc(bfa, speed);
3571a36c61f9SKrishna Gudipati 
3572a36c61f9SKrishna Gudipati 	if (fcport->cfg.trunked == BFA_TRUE)
3573a36c61f9SKrishna Gudipati 		return BFA_STATUS_TRUNK_ENABLED;
3574a36c61f9SKrishna Gudipati 	if ((speed != BFA_PORT_SPEED_AUTO) && (speed > fcport->speed_sup)) {
3575a36c61f9SKrishna Gudipati 		bfa_trc(bfa, fcport->speed_sup);
3576a36c61f9SKrishna Gudipati 		return BFA_STATUS_UNSUPP_SPEED;
3577a36c61f9SKrishna Gudipati 	}
3578a36c61f9SKrishna Gudipati 
3579bd5a0260SKrishna Gudipati 	/* Port speed entered needs to be checked */
3580a714134aSKrishna Gudipati 	if (bfa_ioc_get_type(&fcport->bfa->ioc) == BFA_IOC_TYPE_FC) {
3581a714134aSKrishna Gudipati 		/* For CT2, 1G is not supported */
3582a714134aSKrishna Gudipati 		if ((speed == BFA_PORT_SPEED_1GBPS) &&
3583a714134aSKrishna Gudipati 		    (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)))
3584a714134aSKrishna Gudipati 			return BFA_STATUS_UNSUPP_SPEED;
3585a714134aSKrishna Gudipati 
3586a714134aSKrishna Gudipati 		/* Already checked for Auto Speed and Max Speed supp */
3587a714134aSKrishna Gudipati 		if (!(speed == BFA_PORT_SPEED_1GBPS ||
3588a714134aSKrishna Gudipati 		      speed == BFA_PORT_SPEED_2GBPS ||
3589a714134aSKrishna Gudipati 		      speed == BFA_PORT_SPEED_4GBPS ||
3590a714134aSKrishna Gudipati 		      speed == BFA_PORT_SPEED_8GBPS ||
3591a714134aSKrishna Gudipati 		      speed == BFA_PORT_SPEED_16GBPS ||
3592a714134aSKrishna Gudipati 		      speed == BFA_PORT_SPEED_AUTO))
3593a714134aSKrishna Gudipati 			return BFA_STATUS_UNSUPP_SPEED;
3594a714134aSKrishna Gudipati 	} else {
3595a714134aSKrishna Gudipati 		if (speed != BFA_PORT_SPEED_10GBPS)
3596a714134aSKrishna Gudipati 			return BFA_STATUS_UNSUPP_SPEED;
3597a714134aSKrishna Gudipati 	}
3598a714134aSKrishna Gudipati 
3599a36c61f9SKrishna Gudipati 	fcport->cfg.speed = speed;
3600a36c61f9SKrishna Gudipati 
3601a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3602a36c61f9SKrishna Gudipati }
3603a36c61f9SKrishna Gudipati 
36045fbe25c7SJing Huang /*
3605a36c61f9SKrishna Gudipati  * Get current speed.
3606a36c61f9SKrishna Gudipati  */
3607a36c61f9SKrishna Gudipati enum bfa_port_speed
3608a36c61f9SKrishna Gudipati bfa_fcport_get_speed(struct bfa_s *bfa)
3609a36c61f9SKrishna Gudipati {
3610a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3611a36c61f9SKrishna Gudipati 
3612a36c61f9SKrishna Gudipati 	return fcport->speed;
3613a36c61f9SKrishna Gudipati }
3614a36c61f9SKrishna Gudipati 
36155fbe25c7SJing Huang /*
3616a36c61f9SKrishna Gudipati  * Configure port topology.
3617a36c61f9SKrishna Gudipati  */
3618a36c61f9SKrishna Gudipati bfa_status_t
3619a36c61f9SKrishna Gudipati bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology)
3620a36c61f9SKrishna Gudipati {
3621a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3622a36c61f9SKrishna Gudipati 
3623a36c61f9SKrishna Gudipati 	bfa_trc(bfa, topology);
3624a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcport->cfg.topology);
3625a36c61f9SKrishna Gudipati 
3626a36c61f9SKrishna Gudipati 	switch (topology) {
3627a36c61f9SKrishna Gudipati 	case BFA_PORT_TOPOLOGY_P2P:
3628a36c61f9SKrishna Gudipati 	case BFA_PORT_TOPOLOGY_LOOP:
3629a36c61f9SKrishna Gudipati 	case BFA_PORT_TOPOLOGY_AUTO:
3630a36c61f9SKrishna Gudipati 		break;
3631a36c61f9SKrishna Gudipati 
3632a36c61f9SKrishna Gudipati 	default:
3633a36c61f9SKrishna Gudipati 		return BFA_STATUS_EINVAL;
3634a36c61f9SKrishna Gudipati 	}
3635a36c61f9SKrishna Gudipati 
3636a36c61f9SKrishna Gudipati 	fcport->cfg.topology = topology;
3637a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3638a36c61f9SKrishna Gudipati }
3639a36c61f9SKrishna Gudipati 
36405fbe25c7SJing Huang /*
3641a36c61f9SKrishna Gudipati  * Get current topology.
3642a36c61f9SKrishna Gudipati  */
3643a36c61f9SKrishna Gudipati enum bfa_port_topology
3644a36c61f9SKrishna Gudipati bfa_fcport_get_topology(struct bfa_s *bfa)
3645a36c61f9SKrishna Gudipati {
3646a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3647a36c61f9SKrishna Gudipati 
3648a36c61f9SKrishna Gudipati 	return fcport->topology;
3649a36c61f9SKrishna Gudipati }
3650a36c61f9SKrishna Gudipati 
3651a36c61f9SKrishna Gudipati bfa_status_t
3652a36c61f9SKrishna Gudipati bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
3653a36c61f9SKrishna Gudipati {
3654a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3655a36c61f9SKrishna Gudipati 
3656a36c61f9SKrishna Gudipati 	bfa_trc(bfa, alpa);
3657a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
3658a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcport->cfg.hardalpa);
3659a36c61f9SKrishna Gudipati 
3660a36c61f9SKrishna Gudipati 	fcport->cfg.cfg_hardalpa = BFA_TRUE;
3661a36c61f9SKrishna Gudipati 	fcport->cfg.hardalpa = alpa;
3662a36c61f9SKrishna Gudipati 
3663a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3664a36c61f9SKrishna Gudipati }
3665a36c61f9SKrishna Gudipati 
3666a36c61f9SKrishna Gudipati bfa_status_t
3667a36c61f9SKrishna Gudipati bfa_fcport_clr_hardalpa(struct bfa_s *bfa)
3668a36c61f9SKrishna Gudipati {
3669a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3670a36c61f9SKrishna Gudipati 
3671a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
3672a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcport->cfg.hardalpa);
3673a36c61f9SKrishna Gudipati 
3674a36c61f9SKrishna Gudipati 	fcport->cfg.cfg_hardalpa = BFA_FALSE;
3675a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3676a36c61f9SKrishna Gudipati }
3677a36c61f9SKrishna Gudipati 
3678a36c61f9SKrishna Gudipati bfa_boolean_t
3679a36c61f9SKrishna Gudipati bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
3680a36c61f9SKrishna Gudipati {
3681a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3682a36c61f9SKrishna Gudipati 
3683a36c61f9SKrishna Gudipati 	*alpa = fcport->cfg.hardalpa;
3684a36c61f9SKrishna Gudipati 	return fcport->cfg.cfg_hardalpa;
3685a36c61f9SKrishna Gudipati }
3686a36c61f9SKrishna Gudipati 
3687a36c61f9SKrishna Gudipati u8
3688a36c61f9SKrishna Gudipati bfa_fcport_get_myalpa(struct bfa_s *bfa)
3689a36c61f9SKrishna Gudipati {
3690a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3691a36c61f9SKrishna Gudipati 
3692a36c61f9SKrishna Gudipati 	return fcport->myalpa;
3693a36c61f9SKrishna Gudipati }
3694a36c61f9SKrishna Gudipati 
3695a36c61f9SKrishna Gudipati bfa_status_t
3696a36c61f9SKrishna Gudipati bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
3697a36c61f9SKrishna Gudipati {
3698a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3699a36c61f9SKrishna Gudipati 
3700a36c61f9SKrishna Gudipati 	bfa_trc(bfa, maxfrsize);
3701a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcport->cfg.maxfrsize);
3702a36c61f9SKrishna Gudipati 
3703a36c61f9SKrishna Gudipati 	/* with in range */
3704a36c61f9SKrishna Gudipati 	if ((maxfrsize > FC_MAX_PDUSZ) || (maxfrsize < FC_MIN_PDUSZ))
3705a36c61f9SKrishna Gudipati 		return BFA_STATUS_INVLD_DFSZ;
3706a36c61f9SKrishna Gudipati 
3707a36c61f9SKrishna Gudipati 	/* power of 2, if not the max frame size of 2112 */
3708a36c61f9SKrishna Gudipati 	if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1)))
3709a36c61f9SKrishna Gudipati 		return BFA_STATUS_INVLD_DFSZ;
3710a36c61f9SKrishna Gudipati 
3711a36c61f9SKrishna Gudipati 	fcport->cfg.maxfrsize = maxfrsize;
3712a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3713a36c61f9SKrishna Gudipati }
3714a36c61f9SKrishna Gudipati 
3715a36c61f9SKrishna Gudipati u16
3716a36c61f9SKrishna Gudipati bfa_fcport_get_maxfrsize(struct bfa_s *bfa)
3717a36c61f9SKrishna Gudipati {
3718a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3719a36c61f9SKrishna Gudipati 
3720a36c61f9SKrishna Gudipati 	return fcport->cfg.maxfrsize;
3721a36c61f9SKrishna Gudipati }
3722a36c61f9SKrishna Gudipati 
3723a36c61f9SKrishna Gudipati u8
3724a36c61f9SKrishna Gudipati bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa)
3725a36c61f9SKrishna Gudipati {
3726a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3727a36c61f9SKrishna Gudipati 
3728a36c61f9SKrishna Gudipati 	return fcport->cfg.rx_bbcredit;
3729a36c61f9SKrishna Gudipati }
3730a36c61f9SKrishna Gudipati 
3731a36c61f9SKrishna Gudipati void
3732be540a99SKrishna Gudipati bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit, u8 bb_scn)
3733a36c61f9SKrishna Gudipati {
3734a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3735a36c61f9SKrishna Gudipati 
3736a36c61f9SKrishna Gudipati 	fcport->cfg.tx_bbcredit = (u8)tx_bbcredit;
3737be540a99SKrishna Gudipati 	fcport->cfg.bb_scn = bb_scn;
3738be540a99SKrishna Gudipati 	if (bb_scn)
3739be540a99SKrishna Gudipati 		fcport->bbsc_op_state = BFA_TRUE;
3740a36c61f9SKrishna Gudipati }
3741a36c61f9SKrishna Gudipati 
37425fbe25c7SJing Huang /*
3743a36c61f9SKrishna Gudipati  * Get port attributes.
3744a36c61f9SKrishna Gudipati  */
3745a36c61f9SKrishna Gudipati 
3746a36c61f9SKrishna Gudipati wwn_t
3747a36c61f9SKrishna Gudipati bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
3748a36c61f9SKrishna Gudipati {
3749a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3750a36c61f9SKrishna Gudipati 	if (node)
3751a36c61f9SKrishna Gudipati 		return fcport->nwwn;
3752a36c61f9SKrishna Gudipati 	else
3753a36c61f9SKrishna Gudipati 		return fcport->pwwn;
3754a36c61f9SKrishna Gudipati }
3755a36c61f9SKrishna Gudipati 
3756a36c61f9SKrishna Gudipati void
3757a36c61f9SKrishna Gudipati bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr)
3758a36c61f9SKrishna Gudipati {
3759a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3760a36c61f9SKrishna Gudipati 
37616a18b167SJing Huang 	memset(attr, 0, sizeof(struct bfa_port_attr_s));
3762a36c61f9SKrishna Gudipati 
3763a36c61f9SKrishna Gudipati 	attr->nwwn = fcport->nwwn;
3764a36c61f9SKrishna Gudipati 	attr->pwwn = fcport->pwwn;
3765a36c61f9SKrishna Gudipati 
3766f7f73812SMaggie Zhang 	attr->factorypwwn =  bfa->ioc.attr->mfg_pwwn;
3767f7f73812SMaggie Zhang 	attr->factorynwwn =  bfa->ioc.attr->mfg_nwwn;
3768a36c61f9SKrishna Gudipati 
37696a18b167SJing Huang 	memcpy(&attr->pport_cfg, &fcport->cfg,
3770a36c61f9SKrishna Gudipati 		sizeof(struct bfa_port_cfg_s));
3771a36c61f9SKrishna Gudipati 	/* speed attributes */
3772a36c61f9SKrishna Gudipati 	attr->pport_cfg.speed = fcport->cfg.speed;
3773a36c61f9SKrishna Gudipati 	attr->speed_supported = fcport->speed_sup;
3774a36c61f9SKrishna Gudipati 	attr->speed = fcport->speed;
3775a36c61f9SKrishna Gudipati 	attr->cos_supported = FC_CLASS_3;
3776a36c61f9SKrishna Gudipati 
3777a36c61f9SKrishna Gudipati 	/* topology attributes */
3778a36c61f9SKrishna Gudipati 	attr->pport_cfg.topology = fcport->cfg.topology;
3779a36c61f9SKrishna Gudipati 	attr->topology = fcport->topology;
3780a36c61f9SKrishna Gudipati 	attr->pport_cfg.trunked = fcport->cfg.trunked;
3781a36c61f9SKrishna Gudipati 
3782a36c61f9SKrishna Gudipati 	/* beacon attributes */
3783a36c61f9SKrishna Gudipati 	attr->beacon = fcport->beacon;
3784a36c61f9SKrishna Gudipati 	attr->link_e2e_beacon = fcport->link_e2e_beacon;
3785a36c61f9SKrishna Gudipati 
3786a36c61f9SKrishna Gudipati 	attr->pport_cfg.path_tov  = bfa_fcpim_path_tov_get(bfa);
3787a36c61f9SKrishna Gudipati 	attr->pport_cfg.q_depth  = bfa_fcpim_qdepth_get(bfa);
3788a36c61f9SKrishna Gudipati 	attr->port_state = bfa_sm_to_state(hal_port_sm_table, fcport->sm);
3789be540a99SKrishna Gudipati 	attr->bbsc_op_status =  fcport->bbsc_op_state;
379043ffdf4dSKrishna Gudipati 
379143ffdf4dSKrishna Gudipati 	/* PBC Disabled State */
379243ffdf4dSKrishna Gudipati 	if (bfa_fcport_is_pbcdisabled(bfa))
379343ffdf4dSKrishna Gudipati 		attr->port_state = BFA_PORT_ST_PREBOOT_DISABLED;
379443ffdf4dSKrishna Gudipati 	else {
3795a36c61f9SKrishna Gudipati 		if (bfa_ioc_is_disabled(&fcport->bfa->ioc))
3796a36c61f9SKrishna Gudipati 			attr->port_state = BFA_PORT_ST_IOCDIS;
3797a36c61f9SKrishna Gudipati 		else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc))
3798a36c61f9SKrishna Gudipati 			attr->port_state = BFA_PORT_ST_FWMISMATCH;
379943ffdf4dSKrishna Gudipati 	}
3800a36c61f9SKrishna Gudipati 
3801a36c61f9SKrishna Gudipati 	/* FCoE vlan */
3802a36c61f9SKrishna Gudipati 	attr->fcoe_vlan = fcport->fcoe_vlan;
3803a36c61f9SKrishna Gudipati }
3804a36c61f9SKrishna Gudipati 
3805a36c61f9SKrishna Gudipati #define BFA_FCPORT_STATS_TOV	1000
3806a36c61f9SKrishna Gudipati 
38075fbe25c7SJing Huang /*
3808a36c61f9SKrishna Gudipati  * Fetch port statistics (FCQoS or FCoE).
3809a36c61f9SKrishna Gudipati  */
3810a36c61f9SKrishna Gudipati bfa_status_t
381137ea0558SKrishna Gudipati bfa_fcport_get_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb)
3812a36c61f9SKrishna Gudipati {
3813a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3814a36c61f9SKrishna Gudipati 
381537ea0558SKrishna Gudipati 	if (bfa_ioc_is_disabled(&bfa->ioc))
381637ea0558SKrishna Gudipati 		return BFA_STATUS_IOC_DISABLED;
381737ea0558SKrishna Gudipati 
381837ea0558SKrishna Gudipati 	if (!list_empty(&fcport->statsclr_pending_q))
3819a36c61f9SKrishna Gudipati 		return BFA_STATUS_DEVBUSY;
3820a36c61f9SKrishna Gudipati 
382137ea0558SKrishna Gudipati 	if (list_empty(&fcport->stats_pending_q)) {
382237ea0558SKrishna Gudipati 		list_add_tail(&cb->hcb_qe.qe, &fcport->stats_pending_q);
3823a36c61f9SKrishna Gudipati 		bfa_fcport_send_stats_get(fcport);
382437ea0558SKrishna Gudipati 		bfa_timer_start(bfa, &fcport->timer,
382537ea0558SKrishna Gudipati 				bfa_fcport_stats_get_timeout,
3826a36c61f9SKrishna Gudipati 				fcport, BFA_FCPORT_STATS_TOV);
382737ea0558SKrishna Gudipati 	} else
382837ea0558SKrishna Gudipati 		list_add_tail(&cb->hcb_qe.qe, &fcport->stats_pending_q);
382937ea0558SKrishna Gudipati 
3830a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3831a36c61f9SKrishna Gudipati }
3832a36c61f9SKrishna Gudipati 
38335fbe25c7SJing Huang /*
3834a36c61f9SKrishna Gudipati  * Reset port statistics (FCQoS or FCoE).
3835a36c61f9SKrishna Gudipati  */
3836a36c61f9SKrishna Gudipati bfa_status_t
383737ea0558SKrishna Gudipati bfa_fcport_clear_stats(struct bfa_s *bfa, struct bfa_cb_pending_q_s *cb)
3838a36c61f9SKrishna Gudipati {
3839a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3840a36c61f9SKrishna Gudipati 
384137ea0558SKrishna Gudipati 	if (!list_empty(&fcport->stats_pending_q))
3842a36c61f9SKrishna Gudipati 		return BFA_STATUS_DEVBUSY;
3843a36c61f9SKrishna Gudipati 
384437ea0558SKrishna Gudipati 	if (list_empty(&fcport->statsclr_pending_q)) {
384537ea0558SKrishna Gudipati 		list_add_tail(&cb->hcb_qe.qe, &fcport->statsclr_pending_q);
3846a36c61f9SKrishna Gudipati 		bfa_fcport_send_stats_clear(fcport);
384737ea0558SKrishna Gudipati 		bfa_timer_start(bfa, &fcport->timer,
384837ea0558SKrishna Gudipati 				bfa_fcport_stats_clr_timeout,
3849a36c61f9SKrishna Gudipati 				fcport, BFA_FCPORT_STATS_TOV);
385037ea0558SKrishna Gudipati 	} else
385137ea0558SKrishna Gudipati 		list_add_tail(&cb->hcb_qe.qe, &fcport->statsclr_pending_q);
385237ea0558SKrishna Gudipati 
3853a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3854a36c61f9SKrishna Gudipati }
3855a36c61f9SKrishna Gudipati 
38565fbe25c7SJing Huang /*
3857a36c61f9SKrishna Gudipati  * Fetch port attributes.
3858a36c61f9SKrishna Gudipati  */
3859a36c61f9SKrishna Gudipati bfa_boolean_t
3860a36c61f9SKrishna Gudipati bfa_fcport_is_disabled(struct bfa_s *bfa)
3861a36c61f9SKrishna Gudipati {
3862a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3863a36c61f9SKrishna Gudipati 
3864a36c61f9SKrishna Gudipati 	return bfa_sm_to_state(hal_port_sm_table, fcport->sm) ==
3865a36c61f9SKrishna Gudipati 		BFA_PORT_ST_DISABLED;
3866a36c61f9SKrishna Gudipati 
3867a36c61f9SKrishna Gudipati }
3868a36c61f9SKrishna Gudipati 
3869a36c61f9SKrishna Gudipati bfa_boolean_t
3870a36c61f9SKrishna Gudipati bfa_fcport_is_ratelim(struct bfa_s *bfa)
3871a36c61f9SKrishna Gudipati {
3872a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3873a36c61f9SKrishna Gudipati 
3874a36c61f9SKrishna Gudipati 	return fcport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
3875a36c61f9SKrishna Gudipati 
3876a36c61f9SKrishna Gudipati }
3877a36c61f9SKrishna Gudipati 
38785fbe25c7SJing Huang /*
3879a714134aSKrishna Gudipati  *	Enable/Disable FAA feature in port config
3880a714134aSKrishna Gudipati  */
3881a714134aSKrishna Gudipati void
3882a714134aSKrishna Gudipati bfa_fcport_cfg_faa(struct bfa_s *bfa, u8 state)
3883a714134aSKrishna Gudipati {
3884a714134aSKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3885a714134aSKrishna Gudipati 
3886a714134aSKrishna Gudipati 	bfa_trc(bfa, state);
3887a714134aSKrishna Gudipati 	fcport->cfg.faa_state = state;
3888a714134aSKrishna Gudipati }
3889a714134aSKrishna Gudipati 
3890a714134aSKrishna Gudipati /*
3891a36c61f9SKrishna Gudipati  * Get default minimum ratelim speed
3892a36c61f9SKrishna Gudipati  */
3893a36c61f9SKrishna Gudipati enum bfa_port_speed
3894a36c61f9SKrishna Gudipati bfa_fcport_get_ratelim_speed(struct bfa_s *bfa)
3895a36c61f9SKrishna Gudipati {
3896a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3897a36c61f9SKrishna Gudipati 
3898a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcport->cfg.trl_def_speed);
3899a36c61f9SKrishna Gudipati 	return fcport->cfg.trl_def_speed;
3900a36c61f9SKrishna Gudipati 
3901a36c61f9SKrishna Gudipati }
3902a36c61f9SKrishna Gudipati 
39033d7fc66dSKrishna Gudipati void
39043d7fc66dSKrishna Gudipati bfa_fcport_beacon(void *dev, bfa_boolean_t beacon,
39053d7fc66dSKrishna Gudipati 		  bfa_boolean_t link_e2e_beacon)
39063d7fc66dSKrishna Gudipati {
39073d7fc66dSKrishna Gudipati 	struct bfa_s *bfa = dev;
39083d7fc66dSKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
39093d7fc66dSKrishna Gudipati 
39103d7fc66dSKrishna Gudipati 	bfa_trc(bfa, beacon);
39113d7fc66dSKrishna Gudipati 	bfa_trc(bfa, link_e2e_beacon);
39123d7fc66dSKrishna Gudipati 	bfa_trc(bfa, fcport->beacon);
39133d7fc66dSKrishna Gudipati 	bfa_trc(bfa, fcport->link_e2e_beacon);
39143d7fc66dSKrishna Gudipati 
39153d7fc66dSKrishna Gudipati 	fcport->beacon = beacon;
39163d7fc66dSKrishna Gudipati 	fcport->link_e2e_beacon = link_e2e_beacon;
39173d7fc66dSKrishna Gudipati }
39183d7fc66dSKrishna Gudipati 
3919a36c61f9SKrishna Gudipati bfa_boolean_t
3920a36c61f9SKrishna Gudipati bfa_fcport_is_linkup(struct bfa_s *bfa)
3921a36c61f9SKrishna Gudipati {
3922a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3923a36c61f9SKrishna Gudipati 
3924a36c61f9SKrishna Gudipati 	return	(!fcport->cfg.trunked &&
3925a36c61f9SKrishna Gudipati 		 bfa_sm_cmp_state(fcport, bfa_fcport_sm_linkup)) ||
3926a36c61f9SKrishna Gudipati 		(fcport->cfg.trunked &&
3927a36c61f9SKrishna Gudipati 		 fcport->trunk.attr.state == BFA_TRUNK_ONLINE);
3928a36c61f9SKrishna Gudipati }
3929a36c61f9SKrishna Gudipati 
3930a36c61f9SKrishna Gudipati bfa_boolean_t
3931a36c61f9SKrishna Gudipati bfa_fcport_is_qos_enabled(struct bfa_s *bfa)
3932a36c61f9SKrishna Gudipati {
3933a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3934a36c61f9SKrishna Gudipati 
3935a36c61f9SKrishna Gudipati 	return fcport->cfg.qos_enabled;
3936a36c61f9SKrishna Gudipati }
3937a36c61f9SKrishna Gudipati 
3938be540a99SKrishna Gudipati bfa_boolean_t
3939be540a99SKrishna Gudipati bfa_fcport_is_trunk_enabled(struct bfa_s *bfa)
3940be540a99SKrishna Gudipati {
3941be540a99SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3942be540a99SKrishna Gudipati 
3943be540a99SKrishna Gudipati 	return fcport->cfg.trunked;
3944be540a99SKrishna Gudipati }
3945be540a99SKrishna Gudipati 
39465fbe25c7SJing Huang /*
3947a36c61f9SKrishna Gudipati  * Rport State machine functions
3948a36c61f9SKrishna Gudipati  */
39495fbe25c7SJing Huang /*
3950a36c61f9SKrishna Gudipati  * Beginning state, only online event expected.
3951a36c61f9SKrishna Gudipati  */
3952a36c61f9SKrishna Gudipati static void
3953a36c61f9SKrishna Gudipati bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event)
3954a36c61f9SKrishna Gudipati {
3955a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
3956a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
3957a36c61f9SKrishna Gudipati 
3958a36c61f9SKrishna Gudipati 	switch (event) {
3959a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_CREATE:
3960a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_un_cr);
3961a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_created);
3962a36c61f9SKrishna Gudipati 		break;
3963a36c61f9SKrishna Gudipati 
3964a36c61f9SKrishna Gudipati 	default:
3965a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_un_unexp);
3966a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
3967a36c61f9SKrishna Gudipati 	}
3968a36c61f9SKrishna Gudipati }
3969a36c61f9SKrishna Gudipati 
3970a36c61f9SKrishna Gudipati static void
3971a36c61f9SKrishna Gudipati bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event)
3972a36c61f9SKrishna Gudipati {
3973a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
3974a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
3975a36c61f9SKrishna Gudipati 
3976a36c61f9SKrishna Gudipati 	switch (event) {
3977a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_ONLINE:
3978a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_cr_on);
3979a36c61f9SKrishna Gudipati 		if (bfa_rport_send_fwcreate(rp))
3980a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
3981a36c61f9SKrishna Gudipati 		else
3982a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
3983a36c61f9SKrishna Gudipati 		break;
3984a36c61f9SKrishna Gudipati 
3985a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
3986a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_cr_del);
3987a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
3988a36c61f9SKrishna Gudipati 		bfa_rport_free(rp);
3989a36c61f9SKrishna Gudipati 		break;
3990a36c61f9SKrishna Gudipati 
3991a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
3992a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_cr_hwf);
3993a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
3994a36c61f9SKrishna Gudipati 		break;
3995a36c61f9SKrishna Gudipati 
3996a36c61f9SKrishna Gudipati 	default:
3997a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_cr_unexp);
3998a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
3999a36c61f9SKrishna Gudipati 	}
4000a36c61f9SKrishna Gudipati }
4001a36c61f9SKrishna Gudipati 
40025fbe25c7SJing Huang /*
4003a36c61f9SKrishna Gudipati  * Waiting for rport create response from firmware.
4004a36c61f9SKrishna Gudipati  */
4005a36c61f9SKrishna Gudipati static void
4006a36c61f9SKrishna Gudipati bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event)
4007a36c61f9SKrishna Gudipati {
4008a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4009a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4010a36c61f9SKrishna Gudipati 
4011a36c61f9SKrishna Gudipati 	switch (event) {
4012a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_FWRSP:
4013a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_rsp);
4014a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_online);
4015a36c61f9SKrishna Gudipati 		bfa_rport_online_cb(rp);
4016a36c61f9SKrishna Gudipati 		break;
4017a36c61f9SKrishna Gudipati 
4018a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
4019a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_del);
4020a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_delete_pending);
4021a36c61f9SKrishna Gudipati 		break;
4022a36c61f9SKrishna Gudipati 
4023a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_OFFLINE:
4024a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_off);
4025a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_offline_pending);
4026a36c61f9SKrishna Gudipati 		break;
4027a36c61f9SKrishna Gudipati 
4028a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4029a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_hwf);
4030a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
4031a36c61f9SKrishna Gudipati 		break;
4032a36c61f9SKrishna Gudipati 
4033a36c61f9SKrishna Gudipati 	default:
4034a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_unexp);
4035a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4036a36c61f9SKrishna Gudipati 	}
4037a36c61f9SKrishna Gudipati }
4038a36c61f9SKrishna Gudipati 
40395fbe25c7SJing Huang /*
4040a36c61f9SKrishna Gudipati  * Request queue is full, awaiting queue resume to send create request.
4041a36c61f9SKrishna Gudipati  */
4042a36c61f9SKrishna Gudipati static void
4043a36c61f9SKrishna Gudipati bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
4044a36c61f9SKrishna Gudipati {
4045a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4046a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4047a36c61f9SKrishna Gudipati 
4048a36c61f9SKrishna Gudipati 	switch (event) {
4049a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_QRESUME:
4050a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
4051a36c61f9SKrishna Gudipati 		bfa_rport_send_fwcreate(rp);
4052a36c61f9SKrishna Gudipati 		break;
4053a36c61f9SKrishna Gudipati 
4054a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
4055a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_del);
4056a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
4057a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&rp->reqq_wait);
4058a36c61f9SKrishna Gudipati 		bfa_rport_free(rp);
4059a36c61f9SKrishna Gudipati 		break;
4060a36c61f9SKrishna Gudipati 
4061a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_OFFLINE:
4062a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_off);
4063a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_offline);
4064a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&rp->reqq_wait);
4065a36c61f9SKrishna Gudipati 		bfa_rport_offline_cb(rp);
4066a36c61f9SKrishna Gudipati 		break;
4067a36c61f9SKrishna Gudipati 
4068a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4069a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_hwf);
4070a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
4071a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&rp->reqq_wait);
4072a36c61f9SKrishna Gudipati 		break;
4073a36c61f9SKrishna Gudipati 
4074a36c61f9SKrishna Gudipati 	default:
4075a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_unexp);
4076a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4077a36c61f9SKrishna Gudipati 	}
4078a36c61f9SKrishna Gudipati }
4079a36c61f9SKrishna Gudipati 
40805fbe25c7SJing Huang /*
4081a36c61f9SKrishna Gudipati  * Online state - normal parking state.
4082a36c61f9SKrishna Gudipati  */
4083a36c61f9SKrishna Gudipati static void
4084a36c61f9SKrishna Gudipati bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event)
4085a36c61f9SKrishna Gudipati {
4086a36c61f9SKrishna Gudipati 	struct bfi_rport_qos_scn_s *qos_scn;
4087a36c61f9SKrishna Gudipati 
4088a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4089a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4090a36c61f9SKrishna Gudipati 
4091a36c61f9SKrishna Gudipati 	switch (event) {
4092a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_OFFLINE:
4093a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_on_off);
4094a36c61f9SKrishna Gudipati 		if (bfa_rport_send_fwdelete(rp))
4095a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
4096a36c61f9SKrishna Gudipati 		else
4097a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull);
4098a36c61f9SKrishna Gudipati 		break;
4099a36c61f9SKrishna Gudipati 
4100a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
4101a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_on_del);
4102a36c61f9SKrishna Gudipati 		if (bfa_rport_send_fwdelete(rp))
4103a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_deleting);
4104a36c61f9SKrishna Gudipati 		else
4105a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
4106a36c61f9SKrishna Gudipati 		break;
4107a36c61f9SKrishna Gudipati 
4108a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4109a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_on_hwf);
4110a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
4111a36c61f9SKrishna Gudipati 		break;
4112a36c61f9SKrishna Gudipati 
4113a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_SET_SPEED:
4114a36c61f9SKrishna Gudipati 		bfa_rport_send_fwspeed(rp);
4115a36c61f9SKrishna Gudipati 		break;
4116a36c61f9SKrishna Gudipati 
4117a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_QOS_SCN:
4118a36c61f9SKrishna Gudipati 		qos_scn = (struct bfi_rport_qos_scn_s *) rp->event_arg.fw_msg;
4119a36c61f9SKrishna Gudipati 		rp->qos_attr = qos_scn->new_qos_attr;
4120a36c61f9SKrishna Gudipati 		bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_flow_id);
4121a36c61f9SKrishna Gudipati 		bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_flow_id);
4122a36c61f9SKrishna Gudipati 		bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_priority);
4123a36c61f9SKrishna Gudipati 		bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_priority);
4124a36c61f9SKrishna Gudipati 
4125a36c61f9SKrishna Gudipati 		qos_scn->old_qos_attr.qos_flow_id  =
4126ba816ea8SJing Huang 			be32_to_cpu(qos_scn->old_qos_attr.qos_flow_id);
4127a36c61f9SKrishna Gudipati 		qos_scn->new_qos_attr.qos_flow_id  =
4128ba816ea8SJing Huang 			be32_to_cpu(qos_scn->new_qos_attr.qos_flow_id);
4129a36c61f9SKrishna Gudipati 
4130a36c61f9SKrishna Gudipati 		if (qos_scn->old_qos_attr.qos_flow_id !=
4131a36c61f9SKrishna Gudipati 			qos_scn->new_qos_attr.qos_flow_id)
4132a36c61f9SKrishna Gudipati 			bfa_cb_rport_qos_scn_flowid(rp->rport_drv,
4133a36c61f9SKrishna Gudipati 						    qos_scn->old_qos_attr,
4134a36c61f9SKrishna Gudipati 						    qos_scn->new_qos_attr);
4135a36c61f9SKrishna Gudipati 		if (qos_scn->old_qos_attr.qos_priority !=
4136a36c61f9SKrishna Gudipati 			qos_scn->new_qos_attr.qos_priority)
4137a36c61f9SKrishna Gudipati 			bfa_cb_rport_qos_scn_prio(rp->rport_drv,
4138a36c61f9SKrishna Gudipati 						  qos_scn->old_qos_attr,
4139a36c61f9SKrishna Gudipati 						  qos_scn->new_qos_attr);
4140a36c61f9SKrishna Gudipati 		break;
4141a36c61f9SKrishna Gudipati 
4142a36c61f9SKrishna Gudipati 	default:
4143a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_on_unexp);
4144a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4145a36c61f9SKrishna Gudipati 	}
4146a36c61f9SKrishna Gudipati }
4147a36c61f9SKrishna Gudipati 
41485fbe25c7SJing Huang /*
4149a36c61f9SKrishna Gudipati  * Firmware rport is being deleted - awaiting f/w response.
4150a36c61f9SKrishna Gudipati  */
4151a36c61f9SKrishna Gudipati static void
4152a36c61f9SKrishna Gudipati bfa_rport_sm_fwdelete(struct bfa_rport_s *rp, enum bfa_rport_event event)
4153a36c61f9SKrishna Gudipati {
4154a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4155a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4156a36c61f9SKrishna Gudipati 
4157a36c61f9SKrishna Gudipati 	switch (event) {
4158a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_FWRSP:
4159a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwd_rsp);
4160a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_offline);
4161a36c61f9SKrishna Gudipati 		bfa_rport_offline_cb(rp);
4162a36c61f9SKrishna Gudipati 		break;
4163a36c61f9SKrishna Gudipati 
4164a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
4165a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwd_del);
4166a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_deleting);
4167a36c61f9SKrishna Gudipati 		break;
4168a36c61f9SKrishna Gudipati 
4169a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4170a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwd_hwf);
4171a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
4172a36c61f9SKrishna Gudipati 		bfa_rport_offline_cb(rp);
4173a36c61f9SKrishna Gudipati 		break;
4174a36c61f9SKrishna Gudipati 
4175a36c61f9SKrishna Gudipati 	default:
4176a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwd_unexp);
4177a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4178a36c61f9SKrishna Gudipati 	}
4179a36c61f9SKrishna Gudipati }
4180a36c61f9SKrishna Gudipati 
4181a36c61f9SKrishna Gudipati static void
4182a36c61f9SKrishna Gudipati bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
4183a36c61f9SKrishna Gudipati {
4184a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4185a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4186a36c61f9SKrishna Gudipati 
4187a36c61f9SKrishna Gudipati 	switch (event) {
4188a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_QRESUME:
4189a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
4190a36c61f9SKrishna Gudipati 		bfa_rport_send_fwdelete(rp);
4191a36c61f9SKrishna Gudipati 		break;
4192a36c61f9SKrishna Gudipati 
4193a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
4194a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwd_del);
4195a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
4196a36c61f9SKrishna Gudipati 		break;
4197a36c61f9SKrishna Gudipati 
4198a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4199a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwd_hwf);
4200a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
4201a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&rp->reqq_wait);
4202a36c61f9SKrishna Gudipati 		bfa_rport_offline_cb(rp);
4203a36c61f9SKrishna Gudipati 		break;
4204a36c61f9SKrishna Gudipati 
4205a36c61f9SKrishna Gudipati 	default:
4206a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwd_unexp);
4207a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4208a36c61f9SKrishna Gudipati 	}
4209a36c61f9SKrishna Gudipati }
4210a36c61f9SKrishna Gudipati 
42115fbe25c7SJing Huang /*
4212a36c61f9SKrishna Gudipati  * Offline state.
4213a36c61f9SKrishna Gudipati  */
4214a36c61f9SKrishna Gudipati static void
4215a36c61f9SKrishna Gudipati bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event)
4216a36c61f9SKrishna Gudipati {
4217a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4218a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4219a36c61f9SKrishna Gudipati 
4220a36c61f9SKrishna Gudipati 	switch (event) {
4221a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
4222a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_off_del);
4223a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
4224a36c61f9SKrishna Gudipati 		bfa_rport_free(rp);
4225a36c61f9SKrishna Gudipati 		break;
4226a36c61f9SKrishna Gudipati 
4227a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_ONLINE:
4228a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_off_on);
4229a36c61f9SKrishna Gudipati 		if (bfa_rport_send_fwcreate(rp))
4230a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
4231a36c61f9SKrishna Gudipati 		else
4232a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
4233a36c61f9SKrishna Gudipati 		break;
4234a36c61f9SKrishna Gudipati 
4235a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4236a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_off_hwf);
4237a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
4238a36c61f9SKrishna Gudipati 		break;
4239a36c61f9SKrishna Gudipati 
4240a36c61f9SKrishna Gudipati 	default:
4241a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_off_unexp);
4242a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4243a36c61f9SKrishna Gudipati 	}
4244a36c61f9SKrishna Gudipati }
4245a36c61f9SKrishna Gudipati 
42465fbe25c7SJing Huang /*
4247a36c61f9SKrishna Gudipati  * Rport is deleted, waiting for firmware response to delete.
4248a36c61f9SKrishna Gudipati  */
4249a36c61f9SKrishna Gudipati static void
4250a36c61f9SKrishna Gudipati bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event)
4251a36c61f9SKrishna Gudipati {
4252a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4253a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4254a36c61f9SKrishna Gudipati 
4255a36c61f9SKrishna Gudipati 	switch (event) {
4256a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_FWRSP:
4257a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_del_fwrsp);
4258a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
4259a36c61f9SKrishna Gudipati 		bfa_rport_free(rp);
4260a36c61f9SKrishna Gudipati 		break;
4261a36c61f9SKrishna Gudipati 
4262a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4263a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_del_hwf);
4264a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
4265a36c61f9SKrishna Gudipati 		bfa_rport_free(rp);
4266a36c61f9SKrishna Gudipati 		break;
4267a36c61f9SKrishna Gudipati 
4268a36c61f9SKrishna Gudipati 	default:
4269a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4270a36c61f9SKrishna Gudipati 	}
4271a36c61f9SKrishna Gudipati }
4272a36c61f9SKrishna Gudipati 
4273a36c61f9SKrishna Gudipati static void
4274a36c61f9SKrishna Gudipati bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
4275a36c61f9SKrishna Gudipati {
4276a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4277a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4278a36c61f9SKrishna Gudipati 
4279a36c61f9SKrishna Gudipati 	switch (event) {
4280a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_QRESUME:
4281a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_del_fwrsp);
4282a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_deleting);
4283a36c61f9SKrishna Gudipati 		bfa_rport_send_fwdelete(rp);
4284a36c61f9SKrishna Gudipati 		break;
4285a36c61f9SKrishna Gudipati 
4286a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4287a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_del_hwf);
4288a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
4289a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&rp->reqq_wait);
4290a36c61f9SKrishna Gudipati 		bfa_rport_free(rp);
4291a36c61f9SKrishna Gudipati 		break;
4292a36c61f9SKrishna Gudipati 
4293a36c61f9SKrishna Gudipati 	default:
4294a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4295a36c61f9SKrishna Gudipati 	}
4296a36c61f9SKrishna Gudipati }
4297a36c61f9SKrishna Gudipati 
42985fbe25c7SJing Huang /*
4299a36c61f9SKrishna Gudipati  * Waiting for rport create response from firmware. A delete is pending.
4300a36c61f9SKrishna Gudipati  */
4301a36c61f9SKrishna Gudipati static void
4302a36c61f9SKrishna Gudipati bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
4303a36c61f9SKrishna Gudipati 				enum bfa_rport_event event)
4304a36c61f9SKrishna Gudipati {
4305a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4306a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4307a36c61f9SKrishna Gudipati 
4308a36c61f9SKrishna Gudipati 	switch (event) {
4309a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_FWRSP:
4310a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_delp_fwrsp);
4311a36c61f9SKrishna Gudipati 		if (bfa_rport_send_fwdelete(rp))
4312a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_deleting);
4313a36c61f9SKrishna Gudipati 		else
4314a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
4315a36c61f9SKrishna Gudipati 		break;
4316a36c61f9SKrishna Gudipati 
4317a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4318a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_delp_hwf);
4319a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
4320a36c61f9SKrishna Gudipati 		bfa_rport_free(rp);
4321a36c61f9SKrishna Gudipati 		break;
4322a36c61f9SKrishna Gudipati 
4323a36c61f9SKrishna Gudipati 	default:
4324a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_delp_unexp);
4325a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4326a36c61f9SKrishna Gudipati 	}
4327a36c61f9SKrishna Gudipati }
4328a36c61f9SKrishna Gudipati 
43295fbe25c7SJing Huang /*
4330a36c61f9SKrishna Gudipati  * Waiting for rport create response from firmware. Rport offline is pending.
4331a36c61f9SKrishna Gudipati  */
4332a36c61f9SKrishna Gudipati static void
4333a36c61f9SKrishna Gudipati bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
4334a36c61f9SKrishna Gudipati 				 enum bfa_rport_event event)
4335a36c61f9SKrishna Gudipati {
4336a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4337a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4338a36c61f9SKrishna Gudipati 
4339a36c61f9SKrishna Gudipati 	switch (event) {
4340a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_FWRSP:
4341a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_offp_fwrsp);
4342a36c61f9SKrishna Gudipati 		if (bfa_rport_send_fwdelete(rp))
4343a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
4344a36c61f9SKrishna Gudipati 		else
4345a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull);
4346a36c61f9SKrishna Gudipati 		break;
4347a36c61f9SKrishna Gudipati 
4348a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
4349a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_offp_del);
4350a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_delete_pending);
4351a36c61f9SKrishna Gudipati 		break;
4352a36c61f9SKrishna Gudipati 
4353a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4354a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_offp_hwf);
4355a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
4356a36c61f9SKrishna Gudipati 		break;
4357a36c61f9SKrishna Gudipati 
4358a36c61f9SKrishna Gudipati 	default:
4359a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_offp_unexp);
4360a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4361a36c61f9SKrishna Gudipati 	}
4362a36c61f9SKrishna Gudipati }
4363a36c61f9SKrishna Gudipati 
43645fbe25c7SJing Huang /*
4365a36c61f9SKrishna Gudipati  * IOC h/w failed.
4366a36c61f9SKrishna Gudipati  */
4367a36c61f9SKrishna Gudipati static void
4368a36c61f9SKrishna Gudipati bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event)
4369a36c61f9SKrishna Gudipati {
4370a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4371a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4372a36c61f9SKrishna Gudipati 
4373a36c61f9SKrishna Gudipati 	switch (event) {
4374a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_OFFLINE:
4375a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_iocd_off);
4376a36c61f9SKrishna Gudipati 		bfa_rport_offline_cb(rp);
4377a36c61f9SKrishna Gudipati 		break;
4378a36c61f9SKrishna Gudipati 
4379a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
4380a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_iocd_del);
4381a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
4382a36c61f9SKrishna Gudipati 		bfa_rport_free(rp);
4383a36c61f9SKrishna Gudipati 		break;
4384a36c61f9SKrishna Gudipati 
4385a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_ONLINE:
4386a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_iocd_on);
4387a36c61f9SKrishna Gudipati 		if (bfa_rport_send_fwcreate(rp))
4388a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
4389a36c61f9SKrishna Gudipati 		else
4390a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
4391a36c61f9SKrishna Gudipati 		break;
4392a36c61f9SKrishna Gudipati 
4393a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4394a36c61f9SKrishna Gudipati 		break;
4395a36c61f9SKrishna Gudipati 
4396a36c61f9SKrishna Gudipati 	default:
4397a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_iocd_unexp);
4398a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4399a36c61f9SKrishna Gudipati 	}
4400a36c61f9SKrishna Gudipati }
4401a36c61f9SKrishna Gudipati 
4402a36c61f9SKrishna Gudipati 
4403a36c61f9SKrishna Gudipati 
44045fbe25c7SJing Huang /*
4405a36c61f9SKrishna Gudipati  *  bfa_rport_private BFA rport private functions
4406a36c61f9SKrishna Gudipati  */
4407a36c61f9SKrishna Gudipati 
4408a36c61f9SKrishna Gudipati static void
4409a36c61f9SKrishna Gudipati __bfa_cb_rport_online(void *cbarg, bfa_boolean_t complete)
4410a36c61f9SKrishna Gudipati {
4411a36c61f9SKrishna Gudipati 	struct bfa_rport_s *rp = cbarg;
4412a36c61f9SKrishna Gudipati 
4413a36c61f9SKrishna Gudipati 	if (complete)
4414a36c61f9SKrishna Gudipati 		bfa_cb_rport_online(rp->rport_drv);
4415a36c61f9SKrishna Gudipati }
4416a36c61f9SKrishna Gudipati 
4417a36c61f9SKrishna Gudipati static void
4418a36c61f9SKrishna Gudipati __bfa_cb_rport_offline(void *cbarg, bfa_boolean_t complete)
4419a36c61f9SKrishna Gudipati {
4420a36c61f9SKrishna Gudipati 	struct bfa_rport_s *rp = cbarg;
4421a36c61f9SKrishna Gudipati 
4422a36c61f9SKrishna Gudipati 	if (complete)
4423a36c61f9SKrishna Gudipati 		bfa_cb_rport_offline(rp->rport_drv);
4424a36c61f9SKrishna Gudipati }
4425a36c61f9SKrishna Gudipati 
4426a36c61f9SKrishna Gudipati static void
4427a36c61f9SKrishna Gudipati bfa_rport_qresume(void *cbarg)
4428a36c61f9SKrishna Gudipati {
4429a36c61f9SKrishna Gudipati 	struct bfa_rport_s	*rp = cbarg;
4430a36c61f9SKrishna Gudipati 
4431a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rp, BFA_RPORT_SM_QRESUME);
4432a36c61f9SKrishna Gudipati }
4433a36c61f9SKrishna Gudipati 
4434a36c61f9SKrishna Gudipati static void
44354507025dSKrishna Gudipati bfa_rport_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo,
44364507025dSKrishna Gudipati 		struct bfa_s *bfa)
4437a36c61f9SKrishna Gudipati {
44384507025dSKrishna Gudipati 	struct bfa_mem_kva_s *rport_kva = BFA_MEM_RPORT_KVA(bfa);
44394507025dSKrishna Gudipati 
4440a36c61f9SKrishna Gudipati 	if (cfg->fwcfg.num_rports < BFA_RPORT_MIN)
4441a36c61f9SKrishna Gudipati 		cfg->fwcfg.num_rports = BFA_RPORT_MIN;
4442a36c61f9SKrishna Gudipati 
44434507025dSKrishna Gudipati 	/* kva memory */
44444507025dSKrishna Gudipati 	bfa_mem_kva_setup(minfo, rport_kva,
44454507025dSKrishna Gudipati 		cfg->fwcfg.num_rports * sizeof(struct bfa_rport_s));
4446a36c61f9SKrishna Gudipati }
4447a36c61f9SKrishna Gudipati 
4448a36c61f9SKrishna Gudipati static void
4449a36c61f9SKrishna Gudipati bfa_rport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
44504507025dSKrishna Gudipati 		struct bfa_pcidev_s *pcidev)
4451a36c61f9SKrishna Gudipati {
4452a36c61f9SKrishna Gudipati 	struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa);
4453a36c61f9SKrishna Gudipati 	struct bfa_rport_s *rp;
4454a36c61f9SKrishna Gudipati 	u16 i;
4455a36c61f9SKrishna Gudipati 
4456a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->rp_free_q);
4457a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->rp_active_q);
44583fd45980SKrishna Gudipati 	INIT_LIST_HEAD(&mod->rp_unused_q);
4459a36c61f9SKrishna Gudipati 
44604507025dSKrishna Gudipati 	rp = (struct bfa_rport_s *) bfa_mem_kva_curp(mod);
4461a36c61f9SKrishna Gudipati 	mod->rps_list = rp;
4462a36c61f9SKrishna Gudipati 	mod->num_rports = cfg->fwcfg.num_rports;
4463a36c61f9SKrishna Gudipati 
4464d4b671c5SJing Huang 	WARN_ON(!mod->num_rports ||
4465d4b671c5SJing Huang 		   (mod->num_rports & (mod->num_rports - 1)));
4466a36c61f9SKrishna Gudipati 
4467a36c61f9SKrishna Gudipati 	for (i = 0; i < mod->num_rports; i++, rp++) {
44686a18b167SJing Huang 		memset(rp, 0, sizeof(struct bfa_rport_s));
4469a36c61f9SKrishna Gudipati 		rp->bfa = bfa;
4470a36c61f9SKrishna Gudipati 		rp->rport_tag = i;
4471a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
4472a36c61f9SKrishna Gudipati 
44735fbe25c7SJing Huang 		/*
4474a36c61f9SKrishna Gudipati 		 *  - is unused
4475a36c61f9SKrishna Gudipati 		 */
4476a36c61f9SKrishna Gudipati 		if (i)
4477a36c61f9SKrishna Gudipati 			list_add_tail(&rp->qe, &mod->rp_free_q);
4478a36c61f9SKrishna Gudipati 
4479a36c61f9SKrishna Gudipati 		bfa_reqq_winit(&rp->reqq_wait, bfa_rport_qresume, rp);
4480a36c61f9SKrishna Gudipati 	}
4481a36c61f9SKrishna Gudipati 
44825fbe25c7SJing Huang 	/*
4483a36c61f9SKrishna Gudipati 	 * consume memory
4484a36c61f9SKrishna Gudipati 	 */
44854507025dSKrishna Gudipati 	bfa_mem_kva_curp(mod) = (u8 *) rp;
4486a36c61f9SKrishna Gudipati }
4487a36c61f9SKrishna Gudipati 
4488a36c61f9SKrishna Gudipati static void
4489a36c61f9SKrishna Gudipati bfa_rport_detach(struct bfa_s *bfa)
4490a36c61f9SKrishna Gudipati {
4491a36c61f9SKrishna Gudipati }
4492a36c61f9SKrishna Gudipati 
4493a36c61f9SKrishna Gudipati static void
4494a36c61f9SKrishna Gudipati bfa_rport_start(struct bfa_s *bfa)
4495a36c61f9SKrishna Gudipati {
4496a36c61f9SKrishna Gudipati }
4497a36c61f9SKrishna Gudipati 
4498a36c61f9SKrishna Gudipati static void
4499a36c61f9SKrishna Gudipati bfa_rport_stop(struct bfa_s *bfa)
4500a36c61f9SKrishna Gudipati {
4501a36c61f9SKrishna Gudipati }
4502a36c61f9SKrishna Gudipati 
4503a36c61f9SKrishna Gudipati static void
4504a36c61f9SKrishna Gudipati bfa_rport_iocdisable(struct bfa_s *bfa)
4505a36c61f9SKrishna Gudipati {
4506a36c61f9SKrishna Gudipati 	struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa);
4507a36c61f9SKrishna Gudipati 	struct bfa_rport_s *rport;
4508a36c61f9SKrishna Gudipati 	struct list_head *qe, *qen;
4509a36c61f9SKrishna Gudipati 
45103fd45980SKrishna Gudipati 	/* Enqueue unused rport resources to free_q */
45113fd45980SKrishna Gudipati 	list_splice_tail_init(&mod->rp_unused_q, &mod->rp_free_q);
45123fd45980SKrishna Gudipati 
4513a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &mod->rp_active_q) {
4514a36c61f9SKrishna Gudipati 		rport = (struct bfa_rport_s *) qe;
4515a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, BFA_RPORT_SM_HWFAIL);
4516a36c61f9SKrishna Gudipati 	}
4517a36c61f9SKrishna Gudipati }
4518a36c61f9SKrishna Gudipati 
4519a36c61f9SKrishna Gudipati static struct bfa_rport_s *
4520a36c61f9SKrishna Gudipati bfa_rport_alloc(struct bfa_rport_mod_s *mod)
4521a36c61f9SKrishna Gudipati {
4522a36c61f9SKrishna Gudipati 	struct bfa_rport_s *rport;
4523a36c61f9SKrishna Gudipati 
4524a36c61f9SKrishna Gudipati 	bfa_q_deq(&mod->rp_free_q, &rport);
4525a36c61f9SKrishna Gudipati 	if (rport)
4526a36c61f9SKrishna Gudipati 		list_add_tail(&rport->qe, &mod->rp_active_q);
4527a36c61f9SKrishna Gudipati 
4528a36c61f9SKrishna Gudipati 	return rport;
4529a36c61f9SKrishna Gudipati }
4530a36c61f9SKrishna Gudipati 
4531a36c61f9SKrishna Gudipati static void
4532a36c61f9SKrishna Gudipati bfa_rport_free(struct bfa_rport_s *rport)
4533a36c61f9SKrishna Gudipati {
4534a36c61f9SKrishna Gudipati 	struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(rport->bfa);
4535a36c61f9SKrishna Gudipati 
4536d4b671c5SJing Huang 	WARN_ON(!bfa_q_is_on_q(&mod->rp_active_q, rport));
4537a36c61f9SKrishna Gudipati 	list_del(&rport->qe);
4538a36c61f9SKrishna Gudipati 	list_add_tail(&rport->qe, &mod->rp_free_q);
4539a36c61f9SKrishna Gudipati }
4540a36c61f9SKrishna Gudipati 
4541a36c61f9SKrishna Gudipati static bfa_boolean_t
4542a36c61f9SKrishna Gudipati bfa_rport_send_fwcreate(struct bfa_rport_s *rp)
4543a36c61f9SKrishna Gudipati {
4544a36c61f9SKrishna Gudipati 	struct bfi_rport_create_req_s *m;
4545a36c61f9SKrishna Gudipati 
45465fbe25c7SJing Huang 	/*
4547a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
4548a36c61f9SKrishna Gudipati 	 */
4549a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
4550a36c61f9SKrishna Gudipati 	if (!m) {
4551a36c61f9SKrishna Gudipati 		bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait);
4552a36c61f9SKrishna Gudipati 		return BFA_FALSE;
4553a36c61f9SKrishna Gudipati 	}
4554a36c61f9SKrishna Gudipati 
4555a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_CREATE_REQ,
45563fd45980SKrishna Gudipati 			bfa_fn_lpu(rp->bfa));
4557a36c61f9SKrishna Gudipati 	m->bfa_handle = rp->rport_tag;
4558ba816ea8SJing Huang 	m->max_frmsz = cpu_to_be16(rp->rport_info.max_frmsz);
4559a36c61f9SKrishna Gudipati 	m->pid = rp->rport_info.pid;
45603fd45980SKrishna Gudipati 	m->lp_fwtag = bfa_lps_get_fwtag(rp->bfa, (u8)rp->rport_info.lp_tag);
4561a36c61f9SKrishna Gudipati 	m->local_pid = rp->rport_info.local_pid;
4562a36c61f9SKrishna Gudipati 	m->fc_class = rp->rport_info.fc_class;
4563a36c61f9SKrishna Gudipati 	m->vf_en = rp->rport_info.vf_en;
4564a36c61f9SKrishna Gudipati 	m->vf_id = rp->rport_info.vf_id;
4565a36c61f9SKrishna Gudipati 	m->cisc = rp->rport_info.cisc;
4566a36c61f9SKrishna Gudipati 
45675fbe25c7SJing Huang 	/*
4568a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
4569a36c61f9SKrishna Gudipati 	 */
45703fd45980SKrishna Gudipati 	bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT, m->mh);
4571a36c61f9SKrishna Gudipati 	return BFA_TRUE;
4572a36c61f9SKrishna Gudipati }
4573a36c61f9SKrishna Gudipati 
4574a36c61f9SKrishna Gudipati static bfa_boolean_t
4575a36c61f9SKrishna Gudipati bfa_rport_send_fwdelete(struct bfa_rport_s *rp)
4576a36c61f9SKrishna Gudipati {
4577a36c61f9SKrishna Gudipati 	struct bfi_rport_delete_req_s *m;
4578a36c61f9SKrishna Gudipati 
45795fbe25c7SJing Huang 	/*
4580a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
4581a36c61f9SKrishna Gudipati 	 */
4582a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
4583a36c61f9SKrishna Gudipati 	if (!m) {
4584a36c61f9SKrishna Gudipati 		bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait);
4585a36c61f9SKrishna Gudipati 		return BFA_FALSE;
4586a36c61f9SKrishna Gudipati 	}
4587a36c61f9SKrishna Gudipati 
4588a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_DELETE_REQ,
45893fd45980SKrishna Gudipati 			bfa_fn_lpu(rp->bfa));
4590a36c61f9SKrishna Gudipati 	m->fw_handle = rp->fw_handle;
4591a36c61f9SKrishna Gudipati 
45925fbe25c7SJing Huang 	/*
4593a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
4594a36c61f9SKrishna Gudipati 	 */
45953fd45980SKrishna Gudipati 	bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT, m->mh);
4596a36c61f9SKrishna Gudipati 	return BFA_TRUE;
4597a36c61f9SKrishna Gudipati }
4598a36c61f9SKrishna Gudipati 
4599a36c61f9SKrishna Gudipati static bfa_boolean_t
4600a36c61f9SKrishna Gudipati bfa_rport_send_fwspeed(struct bfa_rport_s *rp)
4601a36c61f9SKrishna Gudipati {
4602a36c61f9SKrishna Gudipati 	struct bfa_rport_speed_req_s *m;
4603a36c61f9SKrishna Gudipati 
46045fbe25c7SJing Huang 	/*
4605a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
4606a36c61f9SKrishna Gudipati 	 */
4607a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
4608a36c61f9SKrishna Gudipati 	if (!m) {
4609a36c61f9SKrishna Gudipati 		bfa_trc(rp->bfa, rp->rport_info.speed);
4610a36c61f9SKrishna Gudipati 		return BFA_FALSE;
4611a36c61f9SKrishna Gudipati 	}
4612a36c61f9SKrishna Gudipati 
4613a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_SET_SPEED_REQ,
46143fd45980SKrishna Gudipati 			bfa_fn_lpu(rp->bfa));
4615a36c61f9SKrishna Gudipati 	m->fw_handle = rp->fw_handle;
4616a36c61f9SKrishna Gudipati 	m->speed = (u8)rp->rport_info.speed;
4617a36c61f9SKrishna Gudipati 
46185fbe25c7SJing Huang 	/*
4619a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
4620a36c61f9SKrishna Gudipati 	 */
46213fd45980SKrishna Gudipati 	bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT, m->mh);
4622a36c61f9SKrishna Gudipati 	return BFA_TRUE;
4623a36c61f9SKrishna Gudipati }
4624a36c61f9SKrishna Gudipati 
4625a36c61f9SKrishna Gudipati 
4626a36c61f9SKrishna Gudipati 
46275fbe25c7SJing Huang /*
4628a36c61f9SKrishna Gudipati  *  bfa_rport_public
4629a36c61f9SKrishna Gudipati  */
4630a36c61f9SKrishna Gudipati 
46315fbe25c7SJing Huang /*
4632a36c61f9SKrishna Gudipati  * Rport interrupt processing.
4633a36c61f9SKrishna Gudipati  */
4634a36c61f9SKrishna Gudipati void
4635a36c61f9SKrishna Gudipati bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
4636a36c61f9SKrishna Gudipati {
4637a36c61f9SKrishna Gudipati 	union bfi_rport_i2h_msg_u msg;
4638a36c61f9SKrishna Gudipati 	struct bfa_rport_s *rp;
4639a36c61f9SKrishna Gudipati 
4640a36c61f9SKrishna Gudipati 	bfa_trc(bfa, m->mhdr.msg_id);
4641a36c61f9SKrishna Gudipati 
4642a36c61f9SKrishna Gudipati 	msg.msg = m;
4643a36c61f9SKrishna Gudipati 
4644a36c61f9SKrishna Gudipati 	switch (m->mhdr.msg_id) {
4645a36c61f9SKrishna Gudipati 	case BFI_RPORT_I2H_CREATE_RSP:
4646a36c61f9SKrishna Gudipati 		rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle);
4647a36c61f9SKrishna Gudipati 		rp->fw_handle = msg.create_rsp->fw_handle;
4648a36c61f9SKrishna Gudipati 		rp->qos_attr = msg.create_rsp->qos_attr;
464983763d59SKrishna Gudipati 		bfa_rport_set_lunmask(bfa, rp);
4650d4b671c5SJing Huang 		WARN_ON(msg.create_rsp->status != BFA_STATUS_OK);
4651a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
4652a36c61f9SKrishna Gudipati 		break;
4653a36c61f9SKrishna Gudipati 
4654a36c61f9SKrishna Gudipati 	case BFI_RPORT_I2H_DELETE_RSP:
4655a36c61f9SKrishna Gudipati 		rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle);
4656d4b671c5SJing Huang 		WARN_ON(msg.delete_rsp->status != BFA_STATUS_OK);
465783763d59SKrishna Gudipati 		bfa_rport_unset_lunmask(bfa, rp);
4658a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
4659a36c61f9SKrishna Gudipati 		break;
4660a36c61f9SKrishna Gudipati 
4661a36c61f9SKrishna Gudipati 	case BFI_RPORT_I2H_QOS_SCN:
4662a36c61f9SKrishna Gudipati 		rp = BFA_RPORT_FROM_TAG(bfa, msg.qos_scn_evt->bfa_handle);
4663a36c61f9SKrishna Gudipati 		rp->event_arg.fw_msg = msg.qos_scn_evt;
4664a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN);
4665a36c61f9SKrishna Gudipati 		break;
4666a36c61f9SKrishna Gudipati 
4667a36c61f9SKrishna Gudipati 	default:
4668a36c61f9SKrishna Gudipati 		bfa_trc(bfa, m->mhdr.msg_id);
4669d4b671c5SJing Huang 		WARN_ON(1);
4670a36c61f9SKrishna Gudipati 	}
4671a36c61f9SKrishna Gudipati }
4672a36c61f9SKrishna Gudipati 
46733fd45980SKrishna Gudipati void
46743fd45980SKrishna Gudipati bfa_rport_res_recfg(struct bfa_s *bfa, u16 num_rport_fw)
46753fd45980SKrishna Gudipati {
46763fd45980SKrishna Gudipati 	struct bfa_rport_mod_s	*mod = BFA_RPORT_MOD(bfa);
46773fd45980SKrishna Gudipati 	struct list_head	*qe;
46783fd45980SKrishna Gudipati 	int	i;
4679a36c61f9SKrishna Gudipati 
46803fd45980SKrishna Gudipati 	for (i = 0; i < (mod->num_rports - num_rport_fw); i++) {
46813fd45980SKrishna Gudipati 		bfa_q_deq_tail(&mod->rp_free_q, &qe);
46823fd45980SKrishna Gudipati 		list_add_tail(qe, &mod->rp_unused_q);
46833fd45980SKrishna Gudipati 	}
46843fd45980SKrishna Gudipati }
4685a36c61f9SKrishna Gudipati 
46865fbe25c7SJing Huang /*
4687a36c61f9SKrishna Gudipati  *  bfa_rport_api
4688a36c61f9SKrishna Gudipati  */
4689a36c61f9SKrishna Gudipati 
4690a36c61f9SKrishna Gudipati struct bfa_rport_s *
4691a36c61f9SKrishna Gudipati bfa_rport_create(struct bfa_s *bfa, void *rport_drv)
4692a36c61f9SKrishna Gudipati {
4693a36c61f9SKrishna Gudipati 	struct bfa_rport_s *rp;
4694a36c61f9SKrishna Gudipati 
4695a36c61f9SKrishna Gudipati 	rp = bfa_rport_alloc(BFA_RPORT_MOD(bfa));
4696a36c61f9SKrishna Gudipati 
4697a36c61f9SKrishna Gudipati 	if (rp == NULL)
4698a36c61f9SKrishna Gudipati 		return NULL;
4699a36c61f9SKrishna Gudipati 
4700a36c61f9SKrishna Gudipati 	rp->bfa = bfa;
4701a36c61f9SKrishna Gudipati 	rp->rport_drv = rport_drv;
4702f7f73812SMaggie Zhang 	memset(&rp->stats, 0, sizeof(rp->stats));
4703a36c61f9SKrishna Gudipati 
4704d4b671c5SJing Huang 	WARN_ON(!bfa_sm_cmp_state(rp, bfa_rport_sm_uninit));
4705a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rp, BFA_RPORT_SM_CREATE);
4706a36c61f9SKrishna Gudipati 
4707a36c61f9SKrishna Gudipati 	return rp;
4708a36c61f9SKrishna Gudipati }
4709a36c61f9SKrishna Gudipati 
4710a36c61f9SKrishna Gudipati void
4711a36c61f9SKrishna Gudipati bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info)
4712a36c61f9SKrishna Gudipati {
4713d4b671c5SJing Huang 	WARN_ON(rport_info->max_frmsz == 0);
4714a36c61f9SKrishna Gudipati 
47155fbe25c7SJing Huang 	/*
4716a36c61f9SKrishna Gudipati 	 * Some JBODs are seen to be not setting PDU size correctly in PLOGI
4717a36c61f9SKrishna Gudipati 	 * responses. Default to minimum size.
4718a36c61f9SKrishna Gudipati 	 */
4719a36c61f9SKrishna Gudipati 	if (rport_info->max_frmsz == 0) {
4720a36c61f9SKrishna Gudipati 		bfa_trc(rport->bfa, rport->rport_tag);
4721a36c61f9SKrishna Gudipati 		rport_info->max_frmsz = FC_MIN_PDUSZ;
4722a36c61f9SKrishna Gudipati 	}
4723a36c61f9SKrishna Gudipati 
47246a18b167SJing Huang 	rport->rport_info = *rport_info;
4725a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, BFA_RPORT_SM_ONLINE);
4726a36c61f9SKrishna Gudipati }
4727a36c61f9SKrishna Gudipati 
4728a36c61f9SKrishna Gudipati void
4729a36c61f9SKrishna Gudipati bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_port_speed speed)
4730a36c61f9SKrishna Gudipati {
4731d4b671c5SJing Huang 	WARN_ON(speed == 0);
4732d4b671c5SJing Huang 	WARN_ON(speed == BFA_PORT_SPEED_AUTO);
4733a36c61f9SKrishna Gudipati 
4734a36c61f9SKrishna Gudipati 	rport->rport_info.speed = speed;
4735a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED);
4736a36c61f9SKrishna Gudipati }
4737a36c61f9SKrishna Gudipati 
473883763d59SKrishna Gudipati /* Set Rport LUN Mask */
473983763d59SKrishna Gudipati void
474083763d59SKrishna Gudipati bfa_rport_set_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp)
474183763d59SKrishna Gudipati {
474283763d59SKrishna Gudipati 	struct bfa_lps_mod_s	*lps_mod = BFA_LPS_MOD(bfa);
474383763d59SKrishna Gudipati 	wwn_t	lp_wwn, rp_wwn;
474483763d59SKrishna Gudipati 	u8 lp_tag = (u8)rp->rport_info.lp_tag;
474583763d59SKrishna Gudipati 
474683763d59SKrishna Gudipati 	rp_wwn = ((struct bfa_fcs_rport_s *)rp->rport_drv)->pwwn;
474783763d59SKrishna Gudipati 	lp_wwn = (BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag))->pwwn;
474883763d59SKrishna Gudipati 
474983763d59SKrishna Gudipati 	BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag)->lun_mask =
475083763d59SKrishna Gudipati 					rp->lun_mask = BFA_TRUE;
475183763d59SKrishna Gudipati 	bfa_fcpim_lunmask_rp_update(bfa, lp_wwn, rp_wwn, rp->rport_tag, lp_tag);
475283763d59SKrishna Gudipati }
475383763d59SKrishna Gudipati 
475483763d59SKrishna Gudipati /* Unset Rport LUN mask */
475583763d59SKrishna Gudipati void
475683763d59SKrishna Gudipati bfa_rport_unset_lunmask(struct bfa_s *bfa, struct bfa_rport_s *rp)
475783763d59SKrishna Gudipati {
475883763d59SKrishna Gudipati 	struct bfa_lps_mod_s	*lps_mod = BFA_LPS_MOD(bfa);
475983763d59SKrishna Gudipati 	wwn_t	lp_wwn, rp_wwn;
476083763d59SKrishna Gudipati 
476183763d59SKrishna Gudipati 	rp_wwn = ((struct bfa_fcs_rport_s *)rp->rport_drv)->pwwn;
476283763d59SKrishna Gudipati 	lp_wwn = (BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag))->pwwn;
476383763d59SKrishna Gudipati 
476483763d59SKrishna Gudipati 	BFA_LPS_FROM_TAG(lps_mod, rp->rport_info.lp_tag)->lun_mask =
476583763d59SKrishna Gudipati 				rp->lun_mask = BFA_FALSE;
476683763d59SKrishna Gudipati 	bfa_fcpim_lunmask_rp_update(bfa, lp_wwn, rp_wwn,
476783763d59SKrishna Gudipati 			BFA_RPORT_TAG_INVALID, BFA_LP_TAG_INVALID);
476883763d59SKrishna Gudipati }
4769a36c61f9SKrishna Gudipati 
47705fbe25c7SJing Huang /*
4771a36c61f9SKrishna Gudipati  * SGPG related functions
4772a36c61f9SKrishna Gudipati  */
4773a36c61f9SKrishna Gudipati 
47745fbe25c7SJing Huang /*
4775a36c61f9SKrishna Gudipati  * Compute and return memory needed by FCP(im) module.
4776a36c61f9SKrishna Gudipati  */
4777a36c61f9SKrishna Gudipati static void
47784507025dSKrishna Gudipati bfa_sgpg_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo,
47794507025dSKrishna Gudipati 		struct bfa_s *bfa)
4780a36c61f9SKrishna Gudipati {
47814507025dSKrishna Gudipati 	struct bfa_sgpg_mod_s *sgpg_mod = BFA_SGPG_MOD(bfa);
47824507025dSKrishna Gudipati 	struct bfa_mem_kva_s *sgpg_kva = BFA_MEM_SGPG_KVA(bfa);
47834507025dSKrishna Gudipati 	struct bfa_mem_dma_s *seg_ptr;
47844507025dSKrishna Gudipati 	u16	nsegs, idx, per_seg_sgpg, num_sgpg;
47854507025dSKrishna Gudipati 	u32	sgpg_sz = sizeof(struct bfi_sgpg_s);
47864507025dSKrishna Gudipati 
4787a36c61f9SKrishna Gudipati 	if (cfg->drvcfg.num_sgpgs < BFA_SGPG_MIN)
4788a36c61f9SKrishna Gudipati 		cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN;
47894507025dSKrishna Gudipati 	else if (cfg->drvcfg.num_sgpgs > BFA_SGPG_MAX)
47904507025dSKrishna Gudipati 		cfg->drvcfg.num_sgpgs = BFA_SGPG_MAX;
4791a36c61f9SKrishna Gudipati 
47924507025dSKrishna Gudipati 	num_sgpg = cfg->drvcfg.num_sgpgs;
47934507025dSKrishna Gudipati 
47944507025dSKrishna Gudipati 	nsegs = BFI_MEM_DMA_NSEGS(num_sgpg, sgpg_sz);
47954507025dSKrishna Gudipati 	per_seg_sgpg = BFI_MEM_NREQS_SEG(sgpg_sz);
47964507025dSKrishna Gudipati 
47974507025dSKrishna Gudipati 	bfa_mem_dma_seg_iter(sgpg_mod, seg_ptr, nsegs, idx) {
47984507025dSKrishna Gudipati 		if (num_sgpg >= per_seg_sgpg) {
47994507025dSKrishna Gudipati 			num_sgpg -= per_seg_sgpg;
48004507025dSKrishna Gudipati 			bfa_mem_dma_setup(minfo, seg_ptr,
48014507025dSKrishna Gudipati 					per_seg_sgpg * sgpg_sz);
48024507025dSKrishna Gudipati 		} else
48034507025dSKrishna Gudipati 			bfa_mem_dma_setup(minfo, seg_ptr,
48044507025dSKrishna Gudipati 					num_sgpg * sgpg_sz);
4805a36c61f9SKrishna Gudipati 	}
4806a36c61f9SKrishna Gudipati 
48074507025dSKrishna Gudipati 	/* kva memory */
48084507025dSKrishna Gudipati 	bfa_mem_kva_setup(minfo, sgpg_kva,
48094507025dSKrishna Gudipati 		cfg->drvcfg.num_sgpgs * sizeof(struct bfa_sgpg_s));
48104507025dSKrishna Gudipati }
4811a36c61f9SKrishna Gudipati 
4812a36c61f9SKrishna Gudipati static void
4813a36c61f9SKrishna Gudipati bfa_sgpg_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
48144507025dSKrishna Gudipati 		struct bfa_pcidev_s *pcidev)
4815a36c61f9SKrishna Gudipati {
4816a36c61f9SKrishna Gudipati 	struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
4817a36c61f9SKrishna Gudipati 	struct bfa_sgpg_s *hsgpg;
4818a36c61f9SKrishna Gudipati 	struct bfi_sgpg_s *sgpg;
4819a36c61f9SKrishna Gudipati 	u64 align_len;
48204507025dSKrishna Gudipati 	struct bfa_mem_dma_s *seg_ptr;
48214507025dSKrishna Gudipati 	u32	sgpg_sz = sizeof(struct bfi_sgpg_s);
48224507025dSKrishna Gudipati 	u16	i, idx, nsegs, per_seg_sgpg, num_sgpg;
4823a36c61f9SKrishna Gudipati 
4824a36c61f9SKrishna Gudipati 	union {
4825a36c61f9SKrishna Gudipati 		u64 pa;
4826a36c61f9SKrishna Gudipati 		union bfi_addr_u addr;
4827a36c61f9SKrishna Gudipati 	} sgpg_pa, sgpg_pa_tmp;
4828a36c61f9SKrishna Gudipati 
4829a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->sgpg_q);
4830a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->sgpg_wait_q);
4831a36c61f9SKrishna Gudipati 
4832a36c61f9SKrishna Gudipati 	bfa_trc(bfa, cfg->drvcfg.num_sgpgs);
4833a36c61f9SKrishna Gudipati 
48344507025dSKrishna Gudipati 	mod->free_sgpgs = mod->num_sgpgs = cfg->drvcfg.num_sgpgs;
4835a36c61f9SKrishna Gudipati 
48364507025dSKrishna Gudipati 	num_sgpg = cfg->drvcfg.num_sgpgs;
48374507025dSKrishna Gudipati 	nsegs = BFI_MEM_DMA_NSEGS(num_sgpg, sgpg_sz);
4838a36c61f9SKrishna Gudipati 
48394507025dSKrishna Gudipati 	/* dma/kva mem claim */
48404507025dSKrishna Gudipati 	hsgpg = (struct bfa_sgpg_s *) bfa_mem_kva_curp(mod);
4841a36c61f9SKrishna Gudipati 
48424507025dSKrishna Gudipati 	bfa_mem_dma_seg_iter(mod, seg_ptr, nsegs, idx) {
48434507025dSKrishna Gudipati 
48444507025dSKrishna Gudipati 		if (!bfa_mem_dma_virt(seg_ptr))
48454507025dSKrishna Gudipati 			break;
48464507025dSKrishna Gudipati 
48474507025dSKrishna Gudipati 		align_len = BFA_SGPG_ROUNDUP(bfa_mem_dma_phys(seg_ptr)) -
48484507025dSKrishna Gudipati 					     bfa_mem_dma_phys(seg_ptr);
48494507025dSKrishna Gudipati 
48504507025dSKrishna Gudipati 		sgpg = (struct bfi_sgpg_s *)
48514507025dSKrishna Gudipati 			(((u8 *) bfa_mem_dma_virt(seg_ptr)) + align_len);
48524507025dSKrishna Gudipati 		sgpg_pa.pa = bfa_mem_dma_phys(seg_ptr) + align_len;
48534507025dSKrishna Gudipati 		WARN_ON(sgpg_pa.pa & (sgpg_sz - 1));
48544507025dSKrishna Gudipati 
48554507025dSKrishna Gudipati 		per_seg_sgpg = (seg_ptr->mem_len - (u32)align_len) / sgpg_sz;
48564507025dSKrishna Gudipati 
48574507025dSKrishna Gudipati 		for (i = 0; num_sgpg > 0 && i < per_seg_sgpg; i++, num_sgpg--) {
48586a18b167SJing Huang 			memset(hsgpg, 0, sizeof(*hsgpg));
48596a18b167SJing Huang 			memset(sgpg, 0, sizeof(*sgpg));
4860a36c61f9SKrishna Gudipati 
4861a36c61f9SKrishna Gudipati 			hsgpg->sgpg = sgpg;
4862a36c61f9SKrishna Gudipati 			sgpg_pa_tmp.pa = bfa_sgaddr_le(sgpg_pa.pa);
4863a36c61f9SKrishna Gudipati 			hsgpg->sgpg_pa = sgpg_pa_tmp.addr;
4864a36c61f9SKrishna Gudipati 			list_add_tail(&hsgpg->qe, &mod->sgpg_q);
4865a36c61f9SKrishna Gudipati 
4866a36c61f9SKrishna Gudipati 			sgpg++;
48674507025dSKrishna Gudipati 			hsgpg++;
48684507025dSKrishna Gudipati 			sgpg_pa.pa += sgpg_sz;
48694507025dSKrishna Gudipati 		}
4870a36c61f9SKrishna Gudipati 	}
4871a36c61f9SKrishna Gudipati 
48724507025dSKrishna Gudipati 	bfa_mem_kva_curp(mod) = (u8 *) hsgpg;
4873a36c61f9SKrishna Gudipati }
4874a36c61f9SKrishna Gudipati 
4875a36c61f9SKrishna Gudipati static void
4876a36c61f9SKrishna Gudipati bfa_sgpg_detach(struct bfa_s *bfa)
4877a36c61f9SKrishna Gudipati {
4878a36c61f9SKrishna Gudipati }
4879a36c61f9SKrishna Gudipati 
4880a36c61f9SKrishna Gudipati static void
4881a36c61f9SKrishna Gudipati bfa_sgpg_start(struct bfa_s *bfa)
4882a36c61f9SKrishna Gudipati {
4883a36c61f9SKrishna Gudipati }
4884a36c61f9SKrishna Gudipati 
4885a36c61f9SKrishna Gudipati static void
4886a36c61f9SKrishna Gudipati bfa_sgpg_stop(struct bfa_s *bfa)
4887a36c61f9SKrishna Gudipati {
4888a36c61f9SKrishna Gudipati }
4889a36c61f9SKrishna Gudipati 
4890a36c61f9SKrishna Gudipati static void
4891a36c61f9SKrishna Gudipati bfa_sgpg_iocdisable(struct bfa_s *bfa)
4892a36c61f9SKrishna Gudipati {
4893a36c61f9SKrishna Gudipati }
4894a36c61f9SKrishna Gudipati 
4895a36c61f9SKrishna Gudipati bfa_status_t
4896a36c61f9SKrishna Gudipati bfa_sgpg_malloc(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpgs)
4897a36c61f9SKrishna Gudipati {
4898a36c61f9SKrishna Gudipati 	struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
4899a36c61f9SKrishna Gudipati 	struct bfa_sgpg_s *hsgpg;
4900a36c61f9SKrishna Gudipati 	int i;
4901a36c61f9SKrishna Gudipati 
4902a36c61f9SKrishna Gudipati 	if (mod->free_sgpgs < nsgpgs)
4903a36c61f9SKrishna Gudipati 		return BFA_STATUS_ENOMEM;
4904a36c61f9SKrishna Gudipati 
4905a36c61f9SKrishna Gudipati 	for (i = 0; i < nsgpgs; i++) {
4906a36c61f9SKrishna Gudipati 		bfa_q_deq(&mod->sgpg_q, &hsgpg);
4907d4b671c5SJing Huang 		WARN_ON(!hsgpg);
4908a36c61f9SKrishna Gudipati 		list_add_tail(&hsgpg->qe, sgpg_q);
4909a36c61f9SKrishna Gudipati 	}
4910a36c61f9SKrishna Gudipati 
4911a36c61f9SKrishna Gudipati 	mod->free_sgpgs -= nsgpgs;
4912a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
4913a36c61f9SKrishna Gudipati }
4914a36c61f9SKrishna Gudipati 
4915a36c61f9SKrishna Gudipati void
4916a36c61f9SKrishna Gudipati bfa_sgpg_mfree(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpg)
4917a36c61f9SKrishna Gudipati {
4918a36c61f9SKrishna Gudipati 	struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
4919a36c61f9SKrishna Gudipati 	struct bfa_sgpg_wqe_s *wqe;
4920a36c61f9SKrishna Gudipati 
4921a36c61f9SKrishna Gudipati 	mod->free_sgpgs += nsgpg;
4922d4b671c5SJing Huang 	WARN_ON(mod->free_sgpgs > mod->num_sgpgs);
4923a36c61f9SKrishna Gudipati 
4924a36c61f9SKrishna Gudipati 	list_splice_tail_init(sgpg_q, &mod->sgpg_q);
4925a36c61f9SKrishna Gudipati 
4926a36c61f9SKrishna Gudipati 	if (list_empty(&mod->sgpg_wait_q))
4927a36c61f9SKrishna Gudipati 		return;
4928a36c61f9SKrishna Gudipati 
49295fbe25c7SJing Huang 	/*
4930a36c61f9SKrishna Gudipati 	 * satisfy as many waiting requests as possible
4931a36c61f9SKrishna Gudipati 	 */
4932a36c61f9SKrishna Gudipati 	do {
4933a36c61f9SKrishna Gudipati 		wqe = bfa_q_first(&mod->sgpg_wait_q);
4934a36c61f9SKrishna Gudipati 		if (mod->free_sgpgs < wqe->nsgpg)
4935a36c61f9SKrishna Gudipati 			nsgpg = mod->free_sgpgs;
4936a36c61f9SKrishna Gudipati 		else
4937a36c61f9SKrishna Gudipati 			nsgpg = wqe->nsgpg;
4938a36c61f9SKrishna Gudipati 		bfa_sgpg_malloc(bfa, &wqe->sgpg_q, nsgpg);
4939a36c61f9SKrishna Gudipati 		wqe->nsgpg -= nsgpg;
4940a36c61f9SKrishna Gudipati 		if (wqe->nsgpg == 0) {
4941a36c61f9SKrishna Gudipati 			list_del(&wqe->qe);
4942a36c61f9SKrishna Gudipati 			wqe->cbfn(wqe->cbarg);
4943a36c61f9SKrishna Gudipati 		}
4944a36c61f9SKrishna Gudipati 	} while (mod->free_sgpgs && !list_empty(&mod->sgpg_wait_q));
4945a36c61f9SKrishna Gudipati }
4946a36c61f9SKrishna Gudipati 
4947a36c61f9SKrishna Gudipati void
4948a36c61f9SKrishna Gudipati bfa_sgpg_wait(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe, int nsgpg)
4949a36c61f9SKrishna Gudipati {
4950a36c61f9SKrishna Gudipati 	struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
4951a36c61f9SKrishna Gudipati 
4952d4b671c5SJing Huang 	WARN_ON(nsgpg <= 0);
4953d4b671c5SJing Huang 	WARN_ON(nsgpg <= mod->free_sgpgs);
4954a36c61f9SKrishna Gudipati 
4955a36c61f9SKrishna Gudipati 	wqe->nsgpg_total = wqe->nsgpg = nsgpg;
4956a36c61f9SKrishna Gudipati 
49575fbe25c7SJing Huang 	/*
4958a36c61f9SKrishna Gudipati 	 * allocate any left to this one first
4959a36c61f9SKrishna Gudipati 	 */
4960a36c61f9SKrishna Gudipati 	if (mod->free_sgpgs) {
49615fbe25c7SJing Huang 		/*
4962a36c61f9SKrishna Gudipati 		 * no one else is waiting for SGPG
4963a36c61f9SKrishna Gudipati 		 */
4964d4b671c5SJing Huang 		WARN_ON(!list_empty(&mod->sgpg_wait_q));
4965a36c61f9SKrishna Gudipati 		list_splice_tail_init(&mod->sgpg_q, &wqe->sgpg_q);
4966a36c61f9SKrishna Gudipati 		wqe->nsgpg -= mod->free_sgpgs;
4967a36c61f9SKrishna Gudipati 		mod->free_sgpgs = 0;
4968a36c61f9SKrishna Gudipati 	}
4969a36c61f9SKrishna Gudipati 
4970a36c61f9SKrishna Gudipati 	list_add_tail(&wqe->qe, &mod->sgpg_wait_q);
4971a36c61f9SKrishna Gudipati }
4972a36c61f9SKrishna Gudipati 
4973a36c61f9SKrishna Gudipati void
4974a36c61f9SKrishna Gudipati bfa_sgpg_wcancel(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe)
4975a36c61f9SKrishna Gudipati {
4976a36c61f9SKrishna Gudipati 	struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
4977a36c61f9SKrishna Gudipati 
4978d4b671c5SJing Huang 	WARN_ON(!bfa_q_is_on_q(&mod->sgpg_wait_q, wqe));
4979a36c61f9SKrishna Gudipati 	list_del(&wqe->qe);
4980a36c61f9SKrishna Gudipati 
4981a36c61f9SKrishna Gudipati 	if (wqe->nsgpg_total != wqe->nsgpg)
4982a36c61f9SKrishna Gudipati 		bfa_sgpg_mfree(bfa, &wqe->sgpg_q,
4983a36c61f9SKrishna Gudipati 				   wqe->nsgpg_total - wqe->nsgpg);
4984a36c61f9SKrishna Gudipati }
4985a36c61f9SKrishna Gudipati 
4986a36c61f9SKrishna Gudipati void
4987a36c61f9SKrishna Gudipati bfa_sgpg_winit(struct bfa_sgpg_wqe_s *wqe, void (*cbfn) (void *cbarg),
4988a36c61f9SKrishna Gudipati 		   void *cbarg)
4989a36c61f9SKrishna Gudipati {
4990a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&wqe->sgpg_q);
4991a36c61f9SKrishna Gudipati 	wqe->cbfn = cbfn;
4992a36c61f9SKrishna Gudipati 	wqe->cbarg = cbarg;
4993a36c61f9SKrishna Gudipati }
4994a36c61f9SKrishna Gudipati 
49955fbe25c7SJing Huang /*
4996a36c61f9SKrishna Gudipati  *  UF related functions
4997a36c61f9SKrishna Gudipati  */
4998a36c61f9SKrishna Gudipati /*
4999a36c61f9SKrishna Gudipati  *****************************************************************************
5000a36c61f9SKrishna Gudipati  * Internal functions
5001a36c61f9SKrishna Gudipati  *****************************************************************************
5002a36c61f9SKrishna Gudipati  */
5003a36c61f9SKrishna Gudipati static void
5004a36c61f9SKrishna Gudipati __bfa_cb_uf_recv(void *cbarg, bfa_boolean_t complete)
5005a36c61f9SKrishna Gudipati {
5006a36c61f9SKrishna Gudipati 	struct bfa_uf_s   *uf = cbarg;
5007a36c61f9SKrishna Gudipati 	struct bfa_uf_mod_s *ufm = BFA_UF_MOD(uf->bfa);
5008a36c61f9SKrishna Gudipati 
5009a36c61f9SKrishna Gudipati 	if (complete)
5010a36c61f9SKrishna Gudipati 		ufm->ufrecv(ufm->cbarg, uf);
5011a36c61f9SKrishna Gudipati }
5012a36c61f9SKrishna Gudipati 
5013a36c61f9SKrishna Gudipati static void
50144507025dSKrishna Gudipati claim_uf_post_msgs(struct bfa_uf_mod_s *ufm)
5015a36c61f9SKrishna Gudipati {
5016a36c61f9SKrishna Gudipati 	struct bfi_uf_buf_post_s *uf_bp_msg;
5017a36c61f9SKrishna Gudipati 	u16 i;
5018a36c61f9SKrishna Gudipati 	u16 buf_len;
5019a36c61f9SKrishna Gudipati 
50204507025dSKrishna Gudipati 	ufm->uf_buf_posts = (struct bfi_uf_buf_post_s *) bfa_mem_kva_curp(ufm);
5021a36c61f9SKrishna Gudipati 	uf_bp_msg = ufm->uf_buf_posts;
5022a36c61f9SKrishna Gudipati 
5023a36c61f9SKrishna Gudipati 	for (i = 0, uf_bp_msg = ufm->uf_buf_posts; i < ufm->num_ufs;
5024a36c61f9SKrishna Gudipati 	     i++, uf_bp_msg++) {
50256a18b167SJing Huang 		memset(uf_bp_msg, 0, sizeof(struct bfi_uf_buf_post_s));
5026a36c61f9SKrishna Gudipati 
5027a36c61f9SKrishna Gudipati 		uf_bp_msg->buf_tag = i;
5028a36c61f9SKrishna Gudipati 		buf_len = sizeof(struct bfa_uf_buf_s);
5029ba816ea8SJing Huang 		uf_bp_msg->buf_len = cpu_to_be16(buf_len);
5030a36c61f9SKrishna Gudipati 		bfi_h2i_set(uf_bp_msg->mh, BFI_MC_UF, BFI_UF_H2I_BUF_POST,
50313fd45980SKrishna Gudipati 			    bfa_fn_lpu(ufm->bfa));
503285ce928dSKrishna Gudipati 		bfa_alen_set(&uf_bp_msg->alen, buf_len, ufm_pbs_pa(ufm, i));
5033a36c61f9SKrishna Gudipati 	}
5034a36c61f9SKrishna Gudipati 
50355fbe25c7SJing Huang 	/*
5036a36c61f9SKrishna Gudipati 	 * advance pointer beyond consumed memory
5037a36c61f9SKrishna Gudipati 	 */
50384507025dSKrishna Gudipati 	bfa_mem_kva_curp(ufm) = (u8 *) uf_bp_msg;
5039a36c61f9SKrishna Gudipati }
5040a36c61f9SKrishna Gudipati 
5041a36c61f9SKrishna Gudipati static void
50424507025dSKrishna Gudipati claim_ufs(struct bfa_uf_mod_s *ufm)
5043a36c61f9SKrishna Gudipati {
5044a36c61f9SKrishna Gudipati 	u16 i;
5045a36c61f9SKrishna Gudipati 	struct bfa_uf_s   *uf;
5046a36c61f9SKrishna Gudipati 
5047a36c61f9SKrishna Gudipati 	/*
5048a36c61f9SKrishna Gudipati 	 * Claim block of memory for UF list
5049a36c61f9SKrishna Gudipati 	 */
50504507025dSKrishna Gudipati 	ufm->uf_list = (struct bfa_uf_s *) bfa_mem_kva_curp(ufm);
5051a36c61f9SKrishna Gudipati 
5052a36c61f9SKrishna Gudipati 	/*
5053a36c61f9SKrishna Gudipati 	 * Initialize UFs and queue it in UF free queue
5054a36c61f9SKrishna Gudipati 	 */
5055a36c61f9SKrishna Gudipati 	for (i = 0, uf = ufm->uf_list; i < ufm->num_ufs; i++, uf++) {
50566a18b167SJing Huang 		memset(uf, 0, sizeof(struct bfa_uf_s));
5057a36c61f9SKrishna Gudipati 		uf->bfa = ufm->bfa;
5058a36c61f9SKrishna Gudipati 		uf->uf_tag = i;
50594507025dSKrishna Gudipati 		uf->pb_len = BFA_PER_UF_DMA_SZ;
50604507025dSKrishna Gudipati 		uf->buf_kva = bfa_mem_get_dmabuf_kva(ufm, i, BFA_PER_UF_DMA_SZ);
5061a36c61f9SKrishna Gudipati 		uf->buf_pa = ufm_pbs_pa(ufm, i);
5062a36c61f9SKrishna Gudipati 		list_add_tail(&uf->qe, &ufm->uf_free_q);
5063a36c61f9SKrishna Gudipati 	}
5064a36c61f9SKrishna Gudipati 
50655fbe25c7SJing Huang 	/*
5066a36c61f9SKrishna Gudipati 	 * advance memory pointer
5067a36c61f9SKrishna Gudipati 	 */
50684507025dSKrishna Gudipati 	bfa_mem_kva_curp(ufm) = (u8 *) uf;
5069a36c61f9SKrishna Gudipati }
5070a36c61f9SKrishna Gudipati 
5071a36c61f9SKrishna Gudipati static void
50724507025dSKrishna Gudipati uf_mem_claim(struct bfa_uf_mod_s *ufm)
5073a36c61f9SKrishna Gudipati {
50744507025dSKrishna Gudipati 	claim_ufs(ufm);
50754507025dSKrishna Gudipati 	claim_uf_post_msgs(ufm);
5076a36c61f9SKrishna Gudipati }
5077a36c61f9SKrishna Gudipati 
5078a36c61f9SKrishna Gudipati static void
50794507025dSKrishna Gudipati bfa_uf_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *minfo,
50804507025dSKrishna Gudipati 		struct bfa_s *bfa)
5081a36c61f9SKrishna Gudipati {
50824507025dSKrishna Gudipati 	struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
50834507025dSKrishna Gudipati 	struct bfa_mem_kva_s *uf_kva = BFA_MEM_UF_KVA(bfa);
5084a36c61f9SKrishna Gudipati 	u32	num_ufs = cfg->fwcfg.num_uf_bufs;
50854507025dSKrishna Gudipati 	struct bfa_mem_dma_s *seg_ptr;
50864507025dSKrishna Gudipati 	u16	nsegs, idx, per_seg_uf = 0;
5087a36c61f9SKrishna Gudipati 
50884507025dSKrishna Gudipati 	nsegs = BFI_MEM_DMA_NSEGS(num_ufs, BFA_PER_UF_DMA_SZ);
50894507025dSKrishna Gudipati 	per_seg_uf = BFI_MEM_NREQS_SEG(BFA_PER_UF_DMA_SZ);
5090a36c61f9SKrishna Gudipati 
50914507025dSKrishna Gudipati 	bfa_mem_dma_seg_iter(ufm, seg_ptr, nsegs, idx) {
50924507025dSKrishna Gudipati 		if (num_ufs >= per_seg_uf) {
50934507025dSKrishna Gudipati 			num_ufs -= per_seg_uf;
50944507025dSKrishna Gudipati 			bfa_mem_dma_setup(minfo, seg_ptr,
50954507025dSKrishna Gudipati 				per_seg_uf * BFA_PER_UF_DMA_SZ);
50964507025dSKrishna Gudipati 		} else
50974507025dSKrishna Gudipati 			bfa_mem_dma_setup(minfo, seg_ptr,
50984507025dSKrishna Gudipati 				num_ufs * BFA_PER_UF_DMA_SZ);
50994507025dSKrishna Gudipati 	}
51004507025dSKrishna Gudipati 
51014507025dSKrishna Gudipati 	/* kva memory */
51024507025dSKrishna Gudipati 	bfa_mem_kva_setup(minfo, uf_kva, cfg->fwcfg.num_uf_bufs *
51034507025dSKrishna Gudipati 		(sizeof(struct bfa_uf_s) + sizeof(struct bfi_uf_buf_post_s)));
5104a36c61f9SKrishna Gudipati }
5105a36c61f9SKrishna Gudipati 
5106a36c61f9SKrishna Gudipati static void
5107a36c61f9SKrishna Gudipati bfa_uf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
51084507025dSKrishna Gudipati 		struct bfa_pcidev_s *pcidev)
5109a36c61f9SKrishna Gudipati {
5110a36c61f9SKrishna Gudipati 	struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
5111a36c61f9SKrishna Gudipati 
5112a36c61f9SKrishna Gudipati 	ufm->bfa = bfa;
5113a36c61f9SKrishna Gudipati 	ufm->num_ufs = cfg->fwcfg.num_uf_bufs;
5114a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&ufm->uf_free_q);
5115a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&ufm->uf_posted_q);
51163fd45980SKrishna Gudipati 	INIT_LIST_HEAD(&ufm->uf_unused_q);
5117a36c61f9SKrishna Gudipati 
51184507025dSKrishna Gudipati 	uf_mem_claim(ufm);
5119a36c61f9SKrishna Gudipati }
5120a36c61f9SKrishna Gudipati 
5121a36c61f9SKrishna Gudipati static void
5122a36c61f9SKrishna Gudipati bfa_uf_detach(struct bfa_s *bfa)
5123a36c61f9SKrishna Gudipati {
5124a36c61f9SKrishna Gudipati }
5125a36c61f9SKrishna Gudipati 
5126a36c61f9SKrishna Gudipati static struct bfa_uf_s *
5127a36c61f9SKrishna Gudipati bfa_uf_get(struct bfa_uf_mod_s *uf_mod)
5128a36c61f9SKrishna Gudipati {
5129a36c61f9SKrishna Gudipati 	struct bfa_uf_s   *uf;
5130a36c61f9SKrishna Gudipati 
5131a36c61f9SKrishna Gudipati 	bfa_q_deq(&uf_mod->uf_free_q, &uf);
5132a36c61f9SKrishna Gudipati 	return uf;
5133a36c61f9SKrishna Gudipati }
5134a36c61f9SKrishna Gudipati 
5135a36c61f9SKrishna Gudipati static void
5136a36c61f9SKrishna Gudipati bfa_uf_put(struct bfa_uf_mod_s *uf_mod, struct bfa_uf_s *uf)
5137a36c61f9SKrishna Gudipati {
5138a36c61f9SKrishna Gudipati 	list_add_tail(&uf->qe, &uf_mod->uf_free_q);
5139a36c61f9SKrishna Gudipati }
5140a36c61f9SKrishna Gudipati 
5141a36c61f9SKrishna Gudipati static bfa_status_t
5142a36c61f9SKrishna Gudipati bfa_uf_post(struct bfa_uf_mod_s *ufm, struct bfa_uf_s *uf)
5143a36c61f9SKrishna Gudipati {
5144a36c61f9SKrishna Gudipati 	struct bfi_uf_buf_post_s *uf_post_msg;
5145a36c61f9SKrishna Gudipati 
5146a36c61f9SKrishna Gudipati 	uf_post_msg = bfa_reqq_next(ufm->bfa, BFA_REQQ_FCXP);
5147a36c61f9SKrishna Gudipati 	if (!uf_post_msg)
5148a36c61f9SKrishna Gudipati 		return BFA_STATUS_FAILED;
5149a36c61f9SKrishna Gudipati 
51506a18b167SJing Huang 	memcpy(uf_post_msg, &ufm->uf_buf_posts[uf->uf_tag],
5151a36c61f9SKrishna Gudipati 		      sizeof(struct bfi_uf_buf_post_s));
51523fd45980SKrishna Gudipati 	bfa_reqq_produce(ufm->bfa, BFA_REQQ_FCXP, uf_post_msg->mh);
5153a36c61f9SKrishna Gudipati 
5154a36c61f9SKrishna Gudipati 	bfa_trc(ufm->bfa, uf->uf_tag);
5155a36c61f9SKrishna Gudipati 
5156a36c61f9SKrishna Gudipati 	list_add_tail(&uf->qe, &ufm->uf_posted_q);
5157a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
5158a36c61f9SKrishna Gudipati }
5159a36c61f9SKrishna Gudipati 
5160a36c61f9SKrishna Gudipati static void
5161a36c61f9SKrishna Gudipati bfa_uf_post_all(struct bfa_uf_mod_s *uf_mod)
5162a36c61f9SKrishna Gudipati {
5163a36c61f9SKrishna Gudipati 	struct bfa_uf_s   *uf;
5164a36c61f9SKrishna Gudipati 
5165a36c61f9SKrishna Gudipati 	while ((uf = bfa_uf_get(uf_mod)) != NULL) {
5166a36c61f9SKrishna Gudipati 		if (bfa_uf_post(uf_mod, uf) != BFA_STATUS_OK)
5167a36c61f9SKrishna Gudipati 			break;
5168a36c61f9SKrishna Gudipati 	}
5169a36c61f9SKrishna Gudipati }
5170a36c61f9SKrishna Gudipati 
5171a36c61f9SKrishna Gudipati static void
5172a36c61f9SKrishna Gudipati uf_recv(struct bfa_s *bfa, struct bfi_uf_frm_rcvd_s *m)
5173a36c61f9SKrishna Gudipati {
5174a36c61f9SKrishna Gudipati 	struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
5175a36c61f9SKrishna Gudipati 	u16 uf_tag = m->buf_tag;
5176a36c61f9SKrishna Gudipati 	struct bfa_uf_s *uf = &ufm->uf_list[uf_tag];
51774507025dSKrishna Gudipati 	struct bfa_uf_buf_s *uf_buf;
51784507025dSKrishna Gudipati 	uint8_t *buf;
5179a36c61f9SKrishna Gudipati 	struct fchs_s *fchs;
5180a36c61f9SKrishna Gudipati 
51814507025dSKrishna Gudipati 	uf_buf = (struct bfa_uf_buf_s *)
51824507025dSKrishna Gudipati 			bfa_mem_get_dmabuf_kva(ufm, uf_tag, uf->pb_len);
51834507025dSKrishna Gudipati 	buf = &uf_buf->d[0];
51844507025dSKrishna Gudipati 
5185ba816ea8SJing Huang 	m->frm_len = be16_to_cpu(m->frm_len);
5186ba816ea8SJing Huang 	m->xfr_len = be16_to_cpu(m->xfr_len);
5187a36c61f9SKrishna Gudipati 
5188a36c61f9SKrishna Gudipati 	fchs = (struct fchs_s *)uf_buf;
5189a36c61f9SKrishna Gudipati 
5190a36c61f9SKrishna Gudipati 	list_del(&uf->qe);	/* dequeue from posted queue */
5191a36c61f9SKrishna Gudipati 
5192a36c61f9SKrishna Gudipati 	uf->data_ptr = buf;
5193a36c61f9SKrishna Gudipati 	uf->data_len = m->xfr_len;
5194a36c61f9SKrishna Gudipati 
5195d4b671c5SJing Huang 	WARN_ON(uf->data_len < sizeof(struct fchs_s));
5196a36c61f9SKrishna Gudipati 
5197a36c61f9SKrishna Gudipati 	if (uf->data_len == sizeof(struct fchs_s)) {
5198a36c61f9SKrishna Gudipati 		bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_UF, BFA_PL_EID_RX,
5199a36c61f9SKrishna Gudipati 			       uf->data_len, (struct fchs_s *)buf);
5200a36c61f9SKrishna Gudipati 	} else {
5201a36c61f9SKrishna Gudipati 		u32 pld_w0 = *((u32 *) (buf + sizeof(struct fchs_s)));
5202a36c61f9SKrishna Gudipati 		bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_UF,
5203a36c61f9SKrishna Gudipati 				      BFA_PL_EID_RX, uf->data_len,
5204a36c61f9SKrishna Gudipati 				      (struct fchs_s *)buf, pld_w0);
5205a36c61f9SKrishna Gudipati 	}
5206a36c61f9SKrishna Gudipati 
5207a36c61f9SKrishna Gudipati 	if (bfa->fcs)
5208a36c61f9SKrishna Gudipati 		__bfa_cb_uf_recv(uf, BFA_TRUE);
5209a36c61f9SKrishna Gudipati 	else
5210a36c61f9SKrishna Gudipati 		bfa_cb_queue(bfa, &uf->hcb_qe, __bfa_cb_uf_recv, uf);
5211a36c61f9SKrishna Gudipati }
5212a36c61f9SKrishna Gudipati 
5213a36c61f9SKrishna Gudipati static void
5214a36c61f9SKrishna Gudipati bfa_uf_stop(struct bfa_s *bfa)
5215a36c61f9SKrishna Gudipati {
5216a36c61f9SKrishna Gudipati }
5217a36c61f9SKrishna Gudipati 
5218a36c61f9SKrishna Gudipati static void
5219a36c61f9SKrishna Gudipati bfa_uf_iocdisable(struct bfa_s *bfa)
5220a36c61f9SKrishna Gudipati {
5221a36c61f9SKrishna Gudipati 	struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
5222a36c61f9SKrishna Gudipati 	struct bfa_uf_s *uf;
5223a36c61f9SKrishna Gudipati 	struct list_head *qe, *qen;
5224a36c61f9SKrishna Gudipati 
52253fd45980SKrishna Gudipati 	/* Enqueue unused uf resources to free_q */
52263fd45980SKrishna Gudipati 	list_splice_tail_init(&ufm->uf_unused_q, &ufm->uf_free_q);
52273fd45980SKrishna Gudipati 
5228a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &ufm->uf_posted_q) {
5229a36c61f9SKrishna Gudipati 		uf = (struct bfa_uf_s *) qe;
5230a36c61f9SKrishna Gudipati 		list_del(&uf->qe);
5231a36c61f9SKrishna Gudipati 		bfa_uf_put(ufm, uf);
5232a36c61f9SKrishna Gudipati 	}
5233a36c61f9SKrishna Gudipati }
5234a36c61f9SKrishna Gudipati 
5235a36c61f9SKrishna Gudipati static void
5236a36c61f9SKrishna Gudipati bfa_uf_start(struct bfa_s *bfa)
5237a36c61f9SKrishna Gudipati {
5238a36c61f9SKrishna Gudipati 	bfa_uf_post_all(BFA_UF_MOD(bfa));
5239a36c61f9SKrishna Gudipati }
5240a36c61f9SKrishna Gudipati 
52415fbe25c7SJing Huang /*
524225985edcSLucas De Marchi  * Register handler for all unsolicted receive frames.
5243a36c61f9SKrishna Gudipati  *
5244a36c61f9SKrishna Gudipati  * @param[in]	bfa		BFA instance
5245a36c61f9SKrishna Gudipati  * @param[in]	ufrecv	receive handler function
5246a36c61f9SKrishna Gudipati  * @param[in]	cbarg	receive handler arg
5247a36c61f9SKrishna Gudipati  */
5248a36c61f9SKrishna Gudipati void
5249a36c61f9SKrishna Gudipati bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv, void *cbarg)
5250a36c61f9SKrishna Gudipati {
5251a36c61f9SKrishna Gudipati 	struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
5252a36c61f9SKrishna Gudipati 
5253a36c61f9SKrishna Gudipati 	ufm->ufrecv = ufrecv;
5254a36c61f9SKrishna Gudipati 	ufm->cbarg = cbarg;
5255a36c61f9SKrishna Gudipati }
5256a36c61f9SKrishna Gudipati 
52575fbe25c7SJing Huang /*
5258a36c61f9SKrishna Gudipati  *	Free an unsolicited frame back to BFA.
5259a36c61f9SKrishna Gudipati  *
5260a36c61f9SKrishna Gudipati  * @param[in]		uf		unsolicited frame to be freed
5261a36c61f9SKrishna Gudipati  *
5262a36c61f9SKrishna Gudipati  * @return None
5263a36c61f9SKrishna Gudipati  */
5264a36c61f9SKrishna Gudipati void
5265a36c61f9SKrishna Gudipati bfa_uf_free(struct bfa_uf_s *uf)
5266a36c61f9SKrishna Gudipati {
5267a36c61f9SKrishna Gudipati 	bfa_uf_put(BFA_UF_MOD(uf->bfa), uf);
5268a36c61f9SKrishna Gudipati 	bfa_uf_post_all(BFA_UF_MOD(uf->bfa));
5269a36c61f9SKrishna Gudipati }
5270a36c61f9SKrishna Gudipati 
5271a36c61f9SKrishna Gudipati 
5272a36c61f9SKrishna Gudipati 
52735fbe25c7SJing Huang /*
5274a36c61f9SKrishna Gudipati  *  uf_pub BFA uf module public functions
5275a36c61f9SKrishna Gudipati  */
5276a36c61f9SKrishna Gudipati void
5277a36c61f9SKrishna Gudipati bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
5278a36c61f9SKrishna Gudipati {
5279a36c61f9SKrishna Gudipati 	bfa_trc(bfa, msg->mhdr.msg_id);
5280a36c61f9SKrishna Gudipati 
5281a36c61f9SKrishna Gudipati 	switch (msg->mhdr.msg_id) {
5282a36c61f9SKrishna Gudipati 	case BFI_UF_I2H_FRM_RCVD:
5283a36c61f9SKrishna Gudipati 		uf_recv(bfa, (struct bfi_uf_frm_rcvd_s *) msg);
5284a36c61f9SKrishna Gudipati 		break;
5285a36c61f9SKrishna Gudipati 
5286a36c61f9SKrishna Gudipati 	default:
5287a36c61f9SKrishna Gudipati 		bfa_trc(bfa, msg->mhdr.msg_id);
5288d4b671c5SJing Huang 		WARN_ON(1);
5289a36c61f9SKrishna Gudipati 	}
5290a36c61f9SKrishna Gudipati }
5291a36c61f9SKrishna Gudipati 
52923fd45980SKrishna Gudipati void
52933fd45980SKrishna Gudipati bfa_uf_res_recfg(struct bfa_s *bfa, u16 num_uf_fw)
52943fd45980SKrishna Gudipati {
52953fd45980SKrishna Gudipati 	struct bfa_uf_mod_s	*mod = BFA_UF_MOD(bfa);
52963fd45980SKrishna Gudipati 	struct list_head	*qe;
52973fd45980SKrishna Gudipati 	int	i;
5298a36c61f9SKrishna Gudipati 
52993fd45980SKrishna Gudipati 	for (i = 0; i < (mod->num_ufs - num_uf_fw); i++) {
53003fd45980SKrishna Gudipati 		bfa_q_deq_tail(&mod->uf_free_q, &qe);
53013fd45980SKrishna Gudipati 		list_add_tail(qe, &mod->uf_unused_q);
53023fd45980SKrishna Gudipati 	}
53033fd45980SKrishna Gudipati }
53043d7fc66dSKrishna Gudipati 
53053d7fc66dSKrishna Gudipati /*
53063d7fc66dSKrishna Gudipati  *	BFA fcdiag module
53073d7fc66dSKrishna Gudipati  */
53083d7fc66dSKrishna Gudipati #define BFA_DIAG_QTEST_TOV	1000    /* msec */
53093d7fc66dSKrishna Gudipati 
53103d7fc66dSKrishna Gudipati /*
53113d7fc66dSKrishna Gudipati  *	Set port status to busy
53123d7fc66dSKrishna Gudipati  */
53133d7fc66dSKrishna Gudipati static void
53143d7fc66dSKrishna Gudipati bfa_fcdiag_set_busy_status(struct bfa_fcdiag_s *fcdiag)
53153d7fc66dSKrishna Gudipati {
53163d7fc66dSKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(fcdiag->bfa);
53173d7fc66dSKrishna Gudipati 
53183d7fc66dSKrishna Gudipati 	if (fcdiag->lb.lock)
53193d7fc66dSKrishna Gudipati 		fcport->diag_busy = BFA_TRUE;
53203d7fc66dSKrishna Gudipati 	else
53213d7fc66dSKrishna Gudipati 		fcport->diag_busy = BFA_FALSE;
53223d7fc66dSKrishna Gudipati }
53233d7fc66dSKrishna Gudipati 
53243d7fc66dSKrishna Gudipati static void
53253d7fc66dSKrishna Gudipati bfa_fcdiag_meminfo(struct bfa_iocfc_cfg_s *cfg, struct bfa_meminfo_s *meminfo,
53263d7fc66dSKrishna Gudipati 		struct bfa_s *bfa)
53273d7fc66dSKrishna Gudipati {
53283d7fc66dSKrishna Gudipati }
53293d7fc66dSKrishna Gudipati 
53303d7fc66dSKrishna Gudipati static void
53313d7fc66dSKrishna Gudipati bfa_fcdiag_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
53323d7fc66dSKrishna Gudipati 		struct bfa_pcidev_s *pcidev)
53333d7fc66dSKrishna Gudipati {
53343d7fc66dSKrishna Gudipati 	struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
53353d7fc66dSKrishna Gudipati 	fcdiag->bfa             = bfa;
53363d7fc66dSKrishna Gudipati 	fcdiag->trcmod  = bfa->trcmod;
53373d7fc66dSKrishna Gudipati 	/* The common DIAG attach bfa_diag_attach() will do all memory claim */
53383d7fc66dSKrishna Gudipati }
53393d7fc66dSKrishna Gudipati 
53403d7fc66dSKrishna Gudipati static void
53413d7fc66dSKrishna Gudipati bfa_fcdiag_iocdisable(struct bfa_s *bfa)
53423d7fc66dSKrishna Gudipati {
53433d7fc66dSKrishna Gudipati 	struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
53443d7fc66dSKrishna Gudipati 	bfa_trc(fcdiag, fcdiag->lb.lock);
53453d7fc66dSKrishna Gudipati 	if (fcdiag->lb.lock) {
53463d7fc66dSKrishna Gudipati 		fcdiag->lb.status = BFA_STATUS_IOC_FAILURE;
53473d7fc66dSKrishna Gudipati 		fcdiag->lb.cbfn(fcdiag->lb.cbarg, fcdiag->lb.status);
53483d7fc66dSKrishna Gudipati 		fcdiag->lb.lock = 0;
53493d7fc66dSKrishna Gudipati 		bfa_fcdiag_set_busy_status(fcdiag);
53503d7fc66dSKrishna Gudipati 	}
53513d7fc66dSKrishna Gudipati }
53523d7fc66dSKrishna Gudipati 
53533d7fc66dSKrishna Gudipati static void
53543d7fc66dSKrishna Gudipati bfa_fcdiag_detach(struct bfa_s *bfa)
53553d7fc66dSKrishna Gudipati {
53563d7fc66dSKrishna Gudipati }
53573d7fc66dSKrishna Gudipati 
53583d7fc66dSKrishna Gudipati static void
53593d7fc66dSKrishna Gudipati bfa_fcdiag_start(struct bfa_s *bfa)
53603d7fc66dSKrishna Gudipati {
53613d7fc66dSKrishna Gudipati }
53623d7fc66dSKrishna Gudipati 
53633d7fc66dSKrishna Gudipati static void
53643d7fc66dSKrishna Gudipati bfa_fcdiag_stop(struct bfa_s *bfa)
53653d7fc66dSKrishna Gudipati {
53663d7fc66dSKrishna Gudipati }
53673d7fc66dSKrishna Gudipati 
53683d7fc66dSKrishna Gudipati static void
53693d7fc66dSKrishna Gudipati bfa_fcdiag_queuetest_timeout(void *cbarg)
53703d7fc66dSKrishna Gudipati {
53713d7fc66dSKrishna Gudipati 	struct bfa_fcdiag_s       *fcdiag = cbarg;
53723d7fc66dSKrishna Gudipati 	struct bfa_diag_qtest_result_s *res = fcdiag->qtest.result;
53733d7fc66dSKrishna Gudipati 
53743d7fc66dSKrishna Gudipati 	bfa_trc(fcdiag, fcdiag->qtest.all);
53753d7fc66dSKrishna Gudipati 	bfa_trc(fcdiag, fcdiag->qtest.count);
53763d7fc66dSKrishna Gudipati 
53773d7fc66dSKrishna Gudipati 	fcdiag->qtest.timer_active = 0;
53783d7fc66dSKrishna Gudipati 
53793d7fc66dSKrishna Gudipati 	res->status = BFA_STATUS_ETIMER;
53803d7fc66dSKrishna Gudipati 	res->count  = QTEST_CNT_DEFAULT - fcdiag->qtest.count;
53813d7fc66dSKrishna Gudipati 	if (fcdiag->qtest.all)
53823d7fc66dSKrishna Gudipati 		res->queue  = fcdiag->qtest.all;
53833d7fc66dSKrishna Gudipati 
53843d7fc66dSKrishna Gudipati 	bfa_trc(fcdiag, BFA_STATUS_ETIMER);
53853d7fc66dSKrishna Gudipati 	fcdiag->qtest.status = BFA_STATUS_ETIMER;
53863d7fc66dSKrishna Gudipati 	fcdiag->qtest.cbfn(fcdiag->qtest.cbarg, fcdiag->qtest.status);
53873d7fc66dSKrishna Gudipati 	fcdiag->qtest.lock = 0;
53883d7fc66dSKrishna Gudipati }
53893d7fc66dSKrishna Gudipati 
53903d7fc66dSKrishna Gudipati static bfa_status_t
53913d7fc66dSKrishna Gudipati bfa_fcdiag_queuetest_send(struct bfa_fcdiag_s *fcdiag)
53923d7fc66dSKrishna Gudipati {
53933d7fc66dSKrishna Gudipati 	u32	i;
53943d7fc66dSKrishna Gudipati 	struct bfi_diag_qtest_req_s *req;
53953d7fc66dSKrishna Gudipati 
53963d7fc66dSKrishna Gudipati 	req = bfa_reqq_next(fcdiag->bfa, fcdiag->qtest.queue);
53973d7fc66dSKrishna Gudipati 	if (!req)
53983d7fc66dSKrishna Gudipati 		return BFA_STATUS_DEVBUSY;
53993d7fc66dSKrishna Gudipati 
54003d7fc66dSKrishna Gudipati 	/* build host command */
54013d7fc66dSKrishna Gudipati 	bfi_h2i_set(req->mh, BFI_MC_DIAG, BFI_DIAG_H2I_QTEST,
54023d7fc66dSKrishna Gudipati 		bfa_fn_lpu(fcdiag->bfa));
54033d7fc66dSKrishna Gudipati 
54043d7fc66dSKrishna Gudipati 	for (i = 0; i < BFI_LMSG_PL_WSZ; i++)
54053d7fc66dSKrishna Gudipati 		req->data[i] = QTEST_PAT_DEFAULT;
54063d7fc66dSKrishna Gudipati 
54073d7fc66dSKrishna Gudipati 	bfa_trc(fcdiag, fcdiag->qtest.queue);
54083d7fc66dSKrishna Gudipati 	/* ring door bell */
54093d7fc66dSKrishna Gudipati 	bfa_reqq_produce(fcdiag->bfa, fcdiag->qtest.queue, req->mh);
54103d7fc66dSKrishna Gudipati 	return BFA_STATUS_OK;
54113d7fc66dSKrishna Gudipati }
54123d7fc66dSKrishna Gudipati 
54133d7fc66dSKrishna Gudipati static void
54143d7fc66dSKrishna Gudipati bfa_fcdiag_queuetest_comp(struct bfa_fcdiag_s *fcdiag,
54153d7fc66dSKrishna Gudipati 			bfi_diag_qtest_rsp_t *rsp)
54163d7fc66dSKrishna Gudipati {
54173d7fc66dSKrishna Gudipati 	struct bfa_diag_qtest_result_s *res = fcdiag->qtest.result;
54183d7fc66dSKrishna Gudipati 	bfa_status_t status = BFA_STATUS_OK;
54193d7fc66dSKrishna Gudipati 	int i;
54203d7fc66dSKrishna Gudipati 
54213d7fc66dSKrishna Gudipati 	/* Check timer, should still be active   */
54223d7fc66dSKrishna Gudipati 	if (!fcdiag->qtest.timer_active) {
54233d7fc66dSKrishna Gudipati 		bfa_trc(fcdiag, fcdiag->qtest.timer_active);
54243d7fc66dSKrishna Gudipati 		return;
54253d7fc66dSKrishna Gudipati 	}
54263d7fc66dSKrishna Gudipati 
54273d7fc66dSKrishna Gudipati 	/* update count */
54283d7fc66dSKrishna Gudipati 	fcdiag->qtest.count--;
54293d7fc66dSKrishna Gudipati 
54303d7fc66dSKrishna Gudipati 	/* Check result */
54313d7fc66dSKrishna Gudipati 	for (i = 0; i < BFI_LMSG_PL_WSZ; i++) {
54323d7fc66dSKrishna Gudipati 		if (rsp->data[i] != ~(QTEST_PAT_DEFAULT)) {
54333d7fc66dSKrishna Gudipati 			res->status = BFA_STATUS_DATACORRUPTED;
54343d7fc66dSKrishna Gudipati 			break;
54353d7fc66dSKrishna Gudipati 		}
54363d7fc66dSKrishna Gudipati 	}
54373d7fc66dSKrishna Gudipati 
54383d7fc66dSKrishna Gudipati 	if (res->status == BFA_STATUS_OK) {
54393d7fc66dSKrishna Gudipati 		if (fcdiag->qtest.count > 0) {
54403d7fc66dSKrishna Gudipati 			status = bfa_fcdiag_queuetest_send(fcdiag);
54413d7fc66dSKrishna Gudipati 			if (status == BFA_STATUS_OK)
54423d7fc66dSKrishna Gudipati 				return;
54433d7fc66dSKrishna Gudipati 			else
54443d7fc66dSKrishna Gudipati 				res->status = status;
54453d7fc66dSKrishna Gudipati 		} else if (fcdiag->qtest.all > 0 &&
54463d7fc66dSKrishna Gudipati 			fcdiag->qtest.queue < (BFI_IOC_MAX_CQS - 1)) {
54473d7fc66dSKrishna Gudipati 			fcdiag->qtest.count = QTEST_CNT_DEFAULT;
54483d7fc66dSKrishna Gudipati 			fcdiag->qtest.queue++;
54493d7fc66dSKrishna Gudipati 			status = bfa_fcdiag_queuetest_send(fcdiag);
54503d7fc66dSKrishna Gudipati 			if (status == BFA_STATUS_OK)
54513d7fc66dSKrishna Gudipati 				return;
54523d7fc66dSKrishna Gudipati 			else
54533d7fc66dSKrishna Gudipati 				res->status = status;
54543d7fc66dSKrishna Gudipati 		}
54553d7fc66dSKrishna Gudipati 	}
54563d7fc66dSKrishna Gudipati 
54573d7fc66dSKrishna Gudipati 	/* Stop timer when we comp all queue */
54583d7fc66dSKrishna Gudipati 	if (fcdiag->qtest.timer_active) {
54593d7fc66dSKrishna Gudipati 		bfa_timer_stop(&fcdiag->qtest.timer);
54603d7fc66dSKrishna Gudipati 		fcdiag->qtest.timer_active = 0;
54613d7fc66dSKrishna Gudipati 	}
54623d7fc66dSKrishna Gudipati 	res->queue = fcdiag->qtest.queue;
54633d7fc66dSKrishna Gudipati 	res->count = QTEST_CNT_DEFAULT - fcdiag->qtest.count;
54643d7fc66dSKrishna Gudipati 	bfa_trc(fcdiag, res->count);
54653d7fc66dSKrishna Gudipati 	bfa_trc(fcdiag, res->status);
54663d7fc66dSKrishna Gudipati 	fcdiag->qtest.status = res->status;
54673d7fc66dSKrishna Gudipati 	fcdiag->qtest.cbfn(fcdiag->qtest.cbarg, fcdiag->qtest.status);
54683d7fc66dSKrishna Gudipati 	fcdiag->qtest.lock = 0;
54693d7fc66dSKrishna Gudipati }
54703d7fc66dSKrishna Gudipati 
54713d7fc66dSKrishna Gudipati static void
54723d7fc66dSKrishna Gudipati bfa_fcdiag_loopback_comp(struct bfa_fcdiag_s *fcdiag,
54733d7fc66dSKrishna Gudipati 			struct bfi_diag_lb_rsp_s *rsp)
54743d7fc66dSKrishna Gudipati {
54753d7fc66dSKrishna Gudipati 	struct bfa_diag_loopback_result_s *res = fcdiag->lb.result;
54763d7fc66dSKrishna Gudipati 
54773d7fc66dSKrishna Gudipati 	res->numtxmfrm  = be32_to_cpu(rsp->res.numtxmfrm);
54783d7fc66dSKrishna Gudipati 	res->numosffrm  = be32_to_cpu(rsp->res.numosffrm);
54793d7fc66dSKrishna Gudipati 	res->numrcvfrm  = be32_to_cpu(rsp->res.numrcvfrm);
54803d7fc66dSKrishna Gudipati 	res->badfrminf  = be32_to_cpu(rsp->res.badfrminf);
54813d7fc66dSKrishna Gudipati 	res->badfrmnum  = be32_to_cpu(rsp->res.badfrmnum);
54823d7fc66dSKrishna Gudipati 	res->status     = rsp->res.status;
54833d7fc66dSKrishna Gudipati 	fcdiag->lb.status = rsp->res.status;
54843d7fc66dSKrishna Gudipati 	bfa_trc(fcdiag, fcdiag->lb.status);
54853d7fc66dSKrishna Gudipati 	fcdiag->lb.cbfn(fcdiag->lb.cbarg, fcdiag->lb.status);
54863d7fc66dSKrishna Gudipati 	fcdiag->lb.lock = 0;
54873d7fc66dSKrishna Gudipati 	bfa_fcdiag_set_busy_status(fcdiag);
54883d7fc66dSKrishna Gudipati }
54893d7fc66dSKrishna Gudipati 
54903d7fc66dSKrishna Gudipati static bfa_status_t
54913d7fc66dSKrishna Gudipati bfa_fcdiag_loopback_send(struct bfa_fcdiag_s *fcdiag,
54923d7fc66dSKrishna Gudipati 			struct bfa_diag_loopback_s *loopback)
54933d7fc66dSKrishna Gudipati {
54943d7fc66dSKrishna Gudipati 	struct bfi_diag_lb_req_s *lb_req;
54953d7fc66dSKrishna Gudipati 
54963d7fc66dSKrishna Gudipati 	lb_req = bfa_reqq_next(fcdiag->bfa, BFA_REQQ_DIAG);
54973d7fc66dSKrishna Gudipati 	if (!lb_req)
54983d7fc66dSKrishna Gudipati 		return BFA_STATUS_DEVBUSY;
54993d7fc66dSKrishna Gudipati 
55003d7fc66dSKrishna Gudipati 	/* build host command */
55013d7fc66dSKrishna Gudipati 	bfi_h2i_set(lb_req->mh, BFI_MC_DIAG, BFI_DIAG_H2I_LOOPBACK,
55023d7fc66dSKrishna Gudipati 		bfa_fn_lpu(fcdiag->bfa));
55033d7fc66dSKrishna Gudipati 
55043d7fc66dSKrishna Gudipati 	lb_req->lb_mode = loopback->lb_mode;
55053d7fc66dSKrishna Gudipati 	lb_req->speed = loopback->speed;
55063d7fc66dSKrishna Gudipati 	lb_req->loopcnt = loopback->loopcnt;
55073d7fc66dSKrishna Gudipati 	lb_req->pattern = loopback->pattern;
55083d7fc66dSKrishna Gudipati 
55093d7fc66dSKrishna Gudipati 	/* ring door bell */
55103d7fc66dSKrishna Gudipati 	bfa_reqq_produce(fcdiag->bfa, BFA_REQQ_DIAG, lb_req->mh);
55113d7fc66dSKrishna Gudipati 
55123d7fc66dSKrishna Gudipati 	bfa_trc(fcdiag, loopback->lb_mode);
55133d7fc66dSKrishna Gudipati 	bfa_trc(fcdiag, loopback->speed);
55143d7fc66dSKrishna Gudipati 	bfa_trc(fcdiag, loopback->loopcnt);
55153d7fc66dSKrishna Gudipati 	bfa_trc(fcdiag, loopback->pattern);
55163d7fc66dSKrishna Gudipati 	return BFA_STATUS_OK;
55173d7fc66dSKrishna Gudipati }
55183d7fc66dSKrishna Gudipati 
55193d7fc66dSKrishna Gudipati /*
55203d7fc66dSKrishna Gudipati  *	cpe/rme intr handler
55213d7fc66dSKrishna Gudipati  */
55223d7fc66dSKrishna Gudipati void
55233d7fc66dSKrishna Gudipati bfa_fcdiag_intr(struct bfa_s *bfa, struct bfi_msg_s *msg)
55243d7fc66dSKrishna Gudipati {
55253d7fc66dSKrishna Gudipati 	struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
55263d7fc66dSKrishna Gudipati 
55273d7fc66dSKrishna Gudipati 	switch (msg->mhdr.msg_id) {
55283d7fc66dSKrishna Gudipati 	case BFI_DIAG_I2H_LOOPBACK:
55293d7fc66dSKrishna Gudipati 		bfa_fcdiag_loopback_comp(fcdiag,
55303d7fc66dSKrishna Gudipati 				(struct bfi_diag_lb_rsp_s *) msg);
55313d7fc66dSKrishna Gudipati 		break;
55323d7fc66dSKrishna Gudipati 	case BFI_DIAG_I2H_QTEST:
55333d7fc66dSKrishna Gudipati 		bfa_fcdiag_queuetest_comp(fcdiag, (bfi_diag_qtest_rsp_t *)msg);
55343d7fc66dSKrishna Gudipati 		break;
55353d7fc66dSKrishna Gudipati 	default:
55363d7fc66dSKrishna Gudipati 		bfa_trc(fcdiag, msg->mhdr.msg_id);
55373d7fc66dSKrishna Gudipati 		WARN_ON(1);
55383d7fc66dSKrishna Gudipati 	}
55393d7fc66dSKrishna Gudipati }
55403d7fc66dSKrishna Gudipati 
55413d7fc66dSKrishna Gudipati /*
55423d7fc66dSKrishna Gudipati  *	Loopback test
55433d7fc66dSKrishna Gudipati  *
55443d7fc66dSKrishna Gudipati  *   @param[in] *bfa            - bfa data struct
55453d7fc66dSKrishna Gudipati  *   @param[in] opmode          - port operation mode
55463d7fc66dSKrishna Gudipati  *   @param[in] speed           - port speed
55473d7fc66dSKrishna Gudipati  *   @param[in] lpcnt           - loop count
55483d7fc66dSKrishna Gudipati  *   @param[in] pat                     - pattern to build packet
55493d7fc66dSKrishna Gudipati  *   @param[in] *result         - pt to bfa_diag_loopback_result_t data struct
55503d7fc66dSKrishna Gudipati  *   @param[in] cbfn            - callback function
55513d7fc66dSKrishna Gudipati  *   @param[in] cbarg           - callback functioin arg
55523d7fc66dSKrishna Gudipati  *
55533d7fc66dSKrishna Gudipati  *   @param[out]
55543d7fc66dSKrishna Gudipati  */
55553d7fc66dSKrishna Gudipati bfa_status_t
55563d7fc66dSKrishna Gudipati bfa_fcdiag_loopback(struct bfa_s *bfa, enum bfa_port_opmode opmode,
55573d7fc66dSKrishna Gudipati 		enum bfa_port_speed speed, u32 lpcnt, u32 pat,
55583d7fc66dSKrishna Gudipati 		struct bfa_diag_loopback_result_s *result, bfa_cb_diag_t cbfn,
55593d7fc66dSKrishna Gudipati 		void *cbarg)
55603d7fc66dSKrishna Gudipati {
55613d7fc66dSKrishna Gudipati 	struct  bfa_diag_loopback_s loopback;
55623d7fc66dSKrishna Gudipati 	struct bfa_port_attr_s attr;
55633d7fc66dSKrishna Gudipati 	bfa_status_t status;
55643d7fc66dSKrishna Gudipati 	struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
55653d7fc66dSKrishna Gudipati 
55663d7fc66dSKrishna Gudipati 	if (!bfa_iocfc_is_operational(bfa))
55673d7fc66dSKrishna Gudipati 		return BFA_STATUS_IOC_NON_OP;
55683d7fc66dSKrishna Gudipati 
55693d7fc66dSKrishna Gudipati 	/* if port is PBC disabled, return error */
55703d7fc66dSKrishna Gudipati 	if (bfa_fcport_is_pbcdisabled(bfa)) {
55713d7fc66dSKrishna Gudipati 		bfa_trc(fcdiag, BFA_STATUS_PBC);
55723d7fc66dSKrishna Gudipati 		return BFA_STATUS_PBC;
55733d7fc66dSKrishna Gudipati 	}
55743d7fc66dSKrishna Gudipati 
55753d7fc66dSKrishna Gudipati 	if (bfa_fcport_is_disabled(bfa) == BFA_FALSE) {
55763d7fc66dSKrishna Gudipati 		bfa_trc(fcdiag, opmode);
55773d7fc66dSKrishna Gudipati 		return BFA_STATUS_PORT_NOT_DISABLED;
55783d7fc66dSKrishna Gudipati 	}
55793d7fc66dSKrishna Gudipati 
5580fb778b06SKrishna Gudipati 	/*
5581fb778b06SKrishna Gudipati 	 * Check if input speed is supported by the port mode
5582fb778b06SKrishna Gudipati 	 */
5583fb778b06SKrishna Gudipati 	if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) {
5584fb778b06SKrishna Gudipati 		if (!(speed == BFA_PORT_SPEED_1GBPS ||
5585fb778b06SKrishna Gudipati 		      speed == BFA_PORT_SPEED_2GBPS ||
5586fb778b06SKrishna Gudipati 		      speed == BFA_PORT_SPEED_4GBPS ||
5587fb778b06SKrishna Gudipati 		      speed == BFA_PORT_SPEED_8GBPS ||
5588fb778b06SKrishna Gudipati 		      speed == BFA_PORT_SPEED_16GBPS ||
5589fb778b06SKrishna Gudipati 		      speed == BFA_PORT_SPEED_AUTO)) {
5590fb778b06SKrishna Gudipati 			bfa_trc(fcdiag, speed);
5591fb778b06SKrishna Gudipati 			return BFA_STATUS_UNSUPP_SPEED;
5592fb778b06SKrishna Gudipati 		}
55933d7fc66dSKrishna Gudipati 		bfa_fcport_get_attr(bfa, &attr);
55943d7fc66dSKrishna Gudipati 		bfa_trc(fcdiag, attr.speed_supported);
55953d7fc66dSKrishna Gudipati 		if (speed > attr.speed_supported)
55963d7fc66dSKrishna Gudipati 			return BFA_STATUS_UNSUPP_SPEED;
5597fb778b06SKrishna Gudipati 	} else {
5598fb778b06SKrishna Gudipati 		if (speed != BFA_PORT_SPEED_10GBPS) {
5599fb778b06SKrishna Gudipati 			bfa_trc(fcdiag, speed);
5600fb778b06SKrishna Gudipati 			return BFA_STATUS_UNSUPP_SPEED;
5601fb778b06SKrishna Gudipati 		}
5602fb778b06SKrishna Gudipati 	}
56033d7fc66dSKrishna Gudipati 
56043d7fc66dSKrishna Gudipati 	/* For Mezz card, port speed entered needs to be checked */
56053d7fc66dSKrishna Gudipati 	if (bfa_mfg_is_mezz(bfa->ioc.attr->card_type)) {
56063d7fc66dSKrishna Gudipati 		if (bfa_ioc_get_type(&bfa->ioc) == BFA_IOC_TYPE_FC) {
56073d7fc66dSKrishna Gudipati 			if ((speed == BFA_PORT_SPEED_1GBPS) &&
56083d7fc66dSKrishna Gudipati 			    (bfa_asic_id_ct2(bfa->ioc.pcidev.device_id)))
56093d7fc66dSKrishna Gudipati 				return BFA_STATUS_UNSUPP_SPEED;
56103d7fc66dSKrishna Gudipati 			if (!(speed == BFA_PORT_SPEED_1GBPS ||
56113d7fc66dSKrishna Gudipati 			      speed == BFA_PORT_SPEED_2GBPS ||
56123d7fc66dSKrishna Gudipati 			      speed == BFA_PORT_SPEED_4GBPS ||
56133d7fc66dSKrishna Gudipati 			      speed == BFA_PORT_SPEED_8GBPS ||
56143d7fc66dSKrishna Gudipati 			      speed == BFA_PORT_SPEED_16GBPS ||
56153d7fc66dSKrishna Gudipati 			      speed == BFA_PORT_SPEED_AUTO))
56163d7fc66dSKrishna Gudipati 				return BFA_STATUS_UNSUPP_SPEED;
56173d7fc66dSKrishna Gudipati 		} else {
56183d7fc66dSKrishna Gudipati 			if (speed != BFA_PORT_SPEED_10GBPS)
56193d7fc66dSKrishna Gudipati 				return BFA_STATUS_UNSUPP_SPEED;
56203d7fc66dSKrishna Gudipati 		}
56213d7fc66dSKrishna Gudipati 	}
56223d7fc66dSKrishna Gudipati 
56233d7fc66dSKrishna Gudipati 	/* check to see if there is another destructive diag cmd running */
56243d7fc66dSKrishna Gudipati 	if (fcdiag->lb.lock) {
56253d7fc66dSKrishna Gudipati 		bfa_trc(fcdiag, fcdiag->lb.lock);
56263d7fc66dSKrishna Gudipati 		return BFA_STATUS_DEVBUSY;
56273d7fc66dSKrishna Gudipati 	}
56283d7fc66dSKrishna Gudipati 
56293d7fc66dSKrishna Gudipati 	fcdiag->lb.lock = 1;
56303d7fc66dSKrishna Gudipati 	loopback.lb_mode = opmode;
56313d7fc66dSKrishna Gudipati 	loopback.speed = speed;
56323d7fc66dSKrishna Gudipati 	loopback.loopcnt = lpcnt;
56333d7fc66dSKrishna Gudipati 	loopback.pattern = pat;
56343d7fc66dSKrishna Gudipati 	fcdiag->lb.result = result;
56353d7fc66dSKrishna Gudipati 	fcdiag->lb.cbfn = cbfn;
56363d7fc66dSKrishna Gudipati 	fcdiag->lb.cbarg = cbarg;
56373d7fc66dSKrishna Gudipati 	memset(result, 0, sizeof(struct bfa_diag_loopback_result_s));
56383d7fc66dSKrishna Gudipati 	bfa_fcdiag_set_busy_status(fcdiag);
56393d7fc66dSKrishna Gudipati 
56403d7fc66dSKrishna Gudipati 	/* Send msg to fw */
56413d7fc66dSKrishna Gudipati 	status = bfa_fcdiag_loopback_send(fcdiag, &loopback);
56423d7fc66dSKrishna Gudipati 	return status;
56433d7fc66dSKrishna Gudipati }
56443d7fc66dSKrishna Gudipati 
56453d7fc66dSKrishna Gudipati /*
56463d7fc66dSKrishna Gudipati  *	DIAG queue test command
56473d7fc66dSKrishna Gudipati  *
56483d7fc66dSKrishna Gudipati  *   @param[in] *bfa            - bfa data struct
56493d7fc66dSKrishna Gudipati  *   @param[in] force           - 1: don't do ioc op checking
56503d7fc66dSKrishna Gudipati  *   @param[in] queue           - queue no. to test
56513d7fc66dSKrishna Gudipati  *   @param[in] *result         - pt to bfa_diag_qtest_result_t data struct
56523d7fc66dSKrishna Gudipati  *   @param[in] cbfn            - callback function
56533d7fc66dSKrishna Gudipati  *   @param[in] *cbarg          - callback functioin arg
56543d7fc66dSKrishna Gudipati  *
56553d7fc66dSKrishna Gudipati  *   @param[out]
56563d7fc66dSKrishna Gudipati  */
56573d7fc66dSKrishna Gudipati bfa_status_t
56583d7fc66dSKrishna Gudipati bfa_fcdiag_queuetest(struct bfa_s *bfa, u32 force, u32 queue,
56593d7fc66dSKrishna Gudipati 		struct bfa_diag_qtest_result_s *result, bfa_cb_diag_t cbfn,
56603d7fc66dSKrishna Gudipati 		void *cbarg)
56613d7fc66dSKrishna Gudipati {
56623d7fc66dSKrishna Gudipati 	struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
56633d7fc66dSKrishna Gudipati 	bfa_status_t status;
56643d7fc66dSKrishna Gudipati 	bfa_trc(fcdiag, force);
56653d7fc66dSKrishna Gudipati 	bfa_trc(fcdiag, queue);
56663d7fc66dSKrishna Gudipati 
56673d7fc66dSKrishna Gudipati 	if (!force && !bfa_iocfc_is_operational(bfa))
56683d7fc66dSKrishna Gudipati 		return BFA_STATUS_IOC_NON_OP;
56693d7fc66dSKrishna Gudipati 
56703d7fc66dSKrishna Gudipati 	/* check to see if there is another destructive diag cmd running */
56713d7fc66dSKrishna Gudipati 	if (fcdiag->qtest.lock) {
56723d7fc66dSKrishna Gudipati 		bfa_trc(fcdiag, fcdiag->qtest.lock);
56733d7fc66dSKrishna Gudipati 		return BFA_STATUS_DEVBUSY;
56743d7fc66dSKrishna Gudipati 	}
56753d7fc66dSKrishna Gudipati 
56763d7fc66dSKrishna Gudipati 	/* Initialization */
56773d7fc66dSKrishna Gudipati 	fcdiag->qtest.lock = 1;
56783d7fc66dSKrishna Gudipati 	fcdiag->qtest.cbfn = cbfn;
56793d7fc66dSKrishna Gudipati 	fcdiag->qtest.cbarg = cbarg;
56803d7fc66dSKrishna Gudipati 	fcdiag->qtest.result = result;
56813d7fc66dSKrishna Gudipati 	fcdiag->qtest.count = QTEST_CNT_DEFAULT;
56823d7fc66dSKrishna Gudipati 
56833d7fc66dSKrishna Gudipati 	/* Init test results */
56843d7fc66dSKrishna Gudipati 	fcdiag->qtest.result->status = BFA_STATUS_OK;
56853d7fc66dSKrishna Gudipati 	fcdiag->qtest.result->count  = 0;
56863d7fc66dSKrishna Gudipati 
56873d7fc66dSKrishna Gudipati 	/* send */
56883d7fc66dSKrishna Gudipati 	if (queue < BFI_IOC_MAX_CQS) {
56893d7fc66dSKrishna Gudipati 		fcdiag->qtest.result->queue  = (u8)queue;
56903d7fc66dSKrishna Gudipati 		fcdiag->qtest.queue = (u8)queue;
56913d7fc66dSKrishna Gudipati 		fcdiag->qtest.all   = 0;
56923d7fc66dSKrishna Gudipati 	} else {
56933d7fc66dSKrishna Gudipati 		fcdiag->qtest.result->queue  = 0;
56943d7fc66dSKrishna Gudipati 		fcdiag->qtest.queue = 0;
56953d7fc66dSKrishna Gudipati 		fcdiag->qtest.all   = 1;
56963d7fc66dSKrishna Gudipati 	}
56973d7fc66dSKrishna Gudipati 	status = bfa_fcdiag_queuetest_send(fcdiag);
56983d7fc66dSKrishna Gudipati 
56993d7fc66dSKrishna Gudipati 	/* Start a timer */
57003d7fc66dSKrishna Gudipati 	if (status == BFA_STATUS_OK) {
57013d7fc66dSKrishna Gudipati 		bfa_timer_start(bfa, &fcdiag->qtest.timer,
57023d7fc66dSKrishna Gudipati 				bfa_fcdiag_queuetest_timeout, fcdiag,
57033d7fc66dSKrishna Gudipati 				BFA_DIAG_QTEST_TOV);
57043d7fc66dSKrishna Gudipati 		fcdiag->qtest.timer_active = 1;
57053d7fc66dSKrishna Gudipati 	}
57063d7fc66dSKrishna Gudipati 	return status;
57073d7fc66dSKrishna Gudipati }
57083d7fc66dSKrishna Gudipati 
57093d7fc66dSKrishna Gudipati /*
57103d7fc66dSKrishna Gudipati  * DIAG PLB is running
57113d7fc66dSKrishna Gudipati  *
57123d7fc66dSKrishna Gudipati  *   @param[in] *bfa    - bfa data struct
57133d7fc66dSKrishna Gudipati  *
57143d7fc66dSKrishna Gudipati  *   @param[out]
57153d7fc66dSKrishna Gudipati  */
57163d7fc66dSKrishna Gudipati bfa_status_t
57173d7fc66dSKrishna Gudipati bfa_fcdiag_lb_is_running(struct bfa_s *bfa)
57183d7fc66dSKrishna Gudipati {
57193d7fc66dSKrishna Gudipati 	struct bfa_fcdiag_s *fcdiag = BFA_FCDIAG_MOD(bfa);
57203d7fc66dSKrishna Gudipati 	return fcdiag->lb.lock ?  BFA_STATUS_DIAG_BUSY : BFA_STATUS_OK;
57213d7fc66dSKrishna Gudipati }
5722