xref: /openbmc/linux/drivers/scsi/bfa/bfa_svc.c (revision 25985edc)
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"
19a36c61f9SKrishna Gudipati #include "bfa_plog.h"
20a36c61f9SKrishna Gudipati #include "bfa_cs.h"
21a36c61f9SKrishna Gudipati #include "bfa_modules.h"
22a36c61f9SKrishna Gudipati 
23a36c61f9SKrishna Gudipati BFA_TRC_FILE(HAL, FCXP);
24a36c61f9SKrishna Gudipati BFA_MODULE(fcxp);
25a36c61f9SKrishna Gudipati BFA_MODULE(sgpg);
26a36c61f9SKrishna Gudipati BFA_MODULE(lps);
27a36c61f9SKrishna Gudipati BFA_MODULE(fcport);
28a36c61f9SKrishna Gudipati BFA_MODULE(rport);
29a36c61f9SKrishna Gudipati BFA_MODULE(uf);
30a36c61f9SKrishna Gudipati 
315fbe25c7SJing Huang /*
32a36c61f9SKrishna Gudipati  * LPS related definitions
33a36c61f9SKrishna Gudipati  */
34a36c61f9SKrishna Gudipati #define BFA_LPS_MIN_LPORTS      (1)
35a36c61f9SKrishna Gudipati #define BFA_LPS_MAX_LPORTS      (256)
36a36c61f9SKrishna Gudipati 
37a36c61f9SKrishna Gudipati /*
38a36c61f9SKrishna Gudipati  * Maximum Vports supported per physical port or vf.
39a36c61f9SKrishna Gudipati  */
40a36c61f9SKrishna Gudipati #define BFA_LPS_MAX_VPORTS_SUPP_CB  255
41a36c61f9SKrishna Gudipati #define BFA_LPS_MAX_VPORTS_SUPP_CT  190
42a36c61f9SKrishna Gudipati 
43a36c61f9SKrishna Gudipati 
445fbe25c7SJing Huang /*
45a36c61f9SKrishna Gudipati  * FC PORT related definitions
46a36c61f9SKrishna Gudipati  */
47a36c61f9SKrishna Gudipati /*
48a36c61f9SKrishna Gudipati  * The port is considered disabled if corresponding physical port or IOC are
49a36c61f9SKrishna Gudipati  * disabled explicitly
50a36c61f9SKrishna Gudipati  */
51a36c61f9SKrishna Gudipati #define BFA_PORT_IS_DISABLED(bfa) \
52a36c61f9SKrishna Gudipati 	((bfa_fcport_is_disabled(bfa) == BFA_TRUE) || \
53a36c61f9SKrishna Gudipati 	(bfa_ioc_is_disabled(&bfa->ioc) == BFA_TRUE))
54a36c61f9SKrishna Gudipati 
555fbe25c7SJing Huang /*
56a36c61f9SKrishna Gudipati  * BFA port state machine events
57a36c61f9SKrishna Gudipati  */
58a36c61f9SKrishna Gudipati enum bfa_fcport_sm_event {
59a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_START	= 1,	/*  start port state machine	*/
60a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_STOP	= 2,	/*  stop port state machine	*/
61a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_ENABLE	= 3,	/*  enable port		*/
62a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_DISABLE	= 4,	/*  disable port state machine */
63a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_FWRSP	= 5,	/*  firmware enable/disable rsp */
64a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_LINKUP	= 6,	/*  firmware linkup event	*/
65a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_LINKDOWN	= 7,	/*  firmware linkup down	*/
66a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_QRESUME	= 8,	/*  CQ space available	*/
67a36c61f9SKrishna Gudipati 	BFA_FCPORT_SM_HWFAIL	= 9,	/*  IOC h/w failure		*/
68a36c61f9SKrishna Gudipati };
69a36c61f9SKrishna Gudipati 
705fbe25c7SJing Huang /*
71a36c61f9SKrishna Gudipati  * BFA port link notification state machine events
72a36c61f9SKrishna Gudipati  */
73a36c61f9SKrishna Gudipati 
74a36c61f9SKrishna Gudipati enum bfa_fcport_ln_sm_event {
75a36c61f9SKrishna Gudipati 	BFA_FCPORT_LN_SM_LINKUP		= 1,	/*  linkup event	*/
76a36c61f9SKrishna Gudipati 	BFA_FCPORT_LN_SM_LINKDOWN	= 2,	/*  linkdown event	*/
77a36c61f9SKrishna Gudipati 	BFA_FCPORT_LN_SM_NOTIFICATION	= 3	/*  done notification	*/
78a36c61f9SKrishna Gudipati };
79a36c61f9SKrishna Gudipati 
805fbe25c7SJing Huang /*
81a36c61f9SKrishna Gudipati  * RPORT related definitions
82a36c61f9SKrishna Gudipati  */
83a36c61f9SKrishna Gudipati #define bfa_rport_offline_cb(__rp) do {					\
84a36c61f9SKrishna Gudipati 	if ((__rp)->bfa->fcs)						\
85a36c61f9SKrishna Gudipati 		bfa_cb_rport_offline((__rp)->rport_drv);      \
86a36c61f9SKrishna Gudipati 	else {								\
87a36c61f9SKrishna Gudipati 		bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe,		\
88a36c61f9SKrishna Gudipati 				__bfa_cb_rport_offline, (__rp));      \
89a36c61f9SKrishna Gudipati 	}								\
90a36c61f9SKrishna Gudipati } while (0)
91a36c61f9SKrishna Gudipati 
92a36c61f9SKrishna Gudipati #define bfa_rport_online_cb(__rp) do {					\
93a36c61f9SKrishna Gudipati 	if ((__rp)->bfa->fcs)						\
94a36c61f9SKrishna Gudipati 		bfa_cb_rport_online((__rp)->rport_drv);      \
95a36c61f9SKrishna Gudipati 	else {								\
96a36c61f9SKrishna Gudipati 		bfa_cb_queue((__rp)->bfa, &(__rp)->hcb_qe,		\
97a36c61f9SKrishna Gudipati 				  __bfa_cb_rport_online, (__rp));      \
98a36c61f9SKrishna Gudipati 		}							\
99a36c61f9SKrishna Gudipati } while (0)
100a36c61f9SKrishna Gudipati 
1015fbe25c7SJing Huang /*
102a36c61f9SKrishna Gudipati  * forward declarations FCXP related functions
103a36c61f9SKrishna Gudipati  */
104a36c61f9SKrishna Gudipati static void	__bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete);
105a36c61f9SKrishna Gudipati static void	hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp,
106a36c61f9SKrishna Gudipati 				struct bfi_fcxp_send_rsp_s *fcxp_rsp);
107a36c61f9SKrishna Gudipati static void	hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen,
108a36c61f9SKrishna Gudipati 				struct bfa_fcxp_s *fcxp, struct fchs_s *fchs);
109a36c61f9SKrishna Gudipati static void	bfa_fcxp_qresume(void *cbarg);
110a36c61f9SKrishna Gudipati static void	bfa_fcxp_queue(struct bfa_fcxp_s *fcxp,
111a36c61f9SKrishna Gudipati 				struct bfi_fcxp_send_req_s *send_req);
112a36c61f9SKrishna Gudipati 
1135fbe25c7SJing Huang /*
114a36c61f9SKrishna Gudipati  * forward declarations for LPS functions
115a36c61f9SKrishna Gudipati  */
116a36c61f9SKrishna Gudipati static void bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
117a36c61f9SKrishna Gudipati 				u32 *dm_len);
118a36c61f9SKrishna Gudipati static void bfa_lps_attach(struct bfa_s *bfa, void *bfad,
119a36c61f9SKrishna Gudipati 				struct bfa_iocfc_cfg_s *cfg,
120a36c61f9SKrishna Gudipati 				struct bfa_meminfo_s *meminfo,
121a36c61f9SKrishna Gudipati 				struct bfa_pcidev_s *pcidev);
122a36c61f9SKrishna Gudipati static void bfa_lps_detach(struct bfa_s *bfa);
123a36c61f9SKrishna Gudipati static void bfa_lps_start(struct bfa_s *bfa);
124a36c61f9SKrishna Gudipati static void bfa_lps_stop(struct bfa_s *bfa);
125a36c61f9SKrishna Gudipati static void bfa_lps_iocdisable(struct bfa_s *bfa);
126a36c61f9SKrishna Gudipati static void bfa_lps_login_rsp(struct bfa_s *bfa,
127a36c61f9SKrishna Gudipati 				struct bfi_lps_login_rsp_s *rsp);
128a36c61f9SKrishna Gudipati static void bfa_lps_logout_rsp(struct bfa_s *bfa,
129a36c61f9SKrishna Gudipati 				struct bfi_lps_logout_rsp_s *rsp);
130a36c61f9SKrishna Gudipati static void bfa_lps_reqq_resume(void *lps_arg);
131a36c61f9SKrishna Gudipati static void bfa_lps_free(struct bfa_lps_s *lps);
132a36c61f9SKrishna Gudipati static void bfa_lps_send_login(struct bfa_lps_s *lps);
133a36c61f9SKrishna Gudipati static void bfa_lps_send_logout(struct bfa_lps_s *lps);
134b704495cSKrishna Gudipati static void bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps);
135a36c61f9SKrishna Gudipati static void bfa_lps_login_comp(struct bfa_lps_s *lps);
136a36c61f9SKrishna Gudipati static void bfa_lps_logout_comp(struct bfa_lps_s *lps);
137a36c61f9SKrishna Gudipati static void bfa_lps_cvl_event(struct bfa_lps_s *lps);
138a36c61f9SKrishna Gudipati 
1395fbe25c7SJing Huang /*
140a36c61f9SKrishna Gudipati  * forward declaration for LPS state machine
141a36c61f9SKrishna Gudipati  */
142a36c61f9SKrishna Gudipati static void bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event);
143a36c61f9SKrishna Gudipati static void bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event);
144a36c61f9SKrishna Gudipati static void bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event
145a36c61f9SKrishna Gudipati 					event);
146a36c61f9SKrishna Gudipati static void bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event);
147b704495cSKrishna Gudipati static void bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps,
148b704495cSKrishna Gudipati 					enum bfa_lps_event event);
149a36c61f9SKrishna Gudipati static void bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event);
150a36c61f9SKrishna Gudipati static void bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event
151a36c61f9SKrishna Gudipati 					event);
152a36c61f9SKrishna Gudipati 
1535fbe25c7SJing Huang /*
154a36c61f9SKrishna Gudipati  * forward declaration for FC Port functions
155a36c61f9SKrishna Gudipati  */
156a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_fcport_send_enable(struct bfa_fcport_s *fcport);
157a36c61f9SKrishna Gudipati static bfa_boolean_t bfa_fcport_send_disable(struct bfa_fcport_s *fcport);
158a36c61f9SKrishna Gudipati static void bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport);
159a36c61f9SKrishna Gudipati static void bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport);
160a36c61f9SKrishna Gudipati static void bfa_fcport_set_wwns(struct bfa_fcport_s *fcport);
161a36c61f9SKrishna Gudipati static void __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete);
162a36c61f9SKrishna Gudipati static void bfa_fcport_scn(struct bfa_fcport_s *fcport,
163a36c61f9SKrishna Gudipati 			enum bfa_port_linkstate event, bfa_boolean_t trunk);
164a36c61f9SKrishna Gudipati static void bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln,
165a36c61f9SKrishna Gudipati 				enum bfa_port_linkstate event);
166a36c61f9SKrishna Gudipati static void __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete);
167a36c61f9SKrishna Gudipati static void bfa_fcport_stats_get_timeout(void *cbarg);
168a36c61f9SKrishna Gudipati static void bfa_fcport_stats_clr_timeout(void *cbarg);
169a36c61f9SKrishna Gudipati static void bfa_trunk_iocdisable(struct bfa_s *bfa);
170a36c61f9SKrishna Gudipati 
1715fbe25c7SJing Huang /*
172a36c61f9SKrishna Gudipati  * forward declaration for FC PORT state machine
173a36c61f9SKrishna Gudipati  */
174a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
175a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
176a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
177a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
178a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
179a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
180a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport,
181a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
182a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
183a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
184a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
185a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
186a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
187a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
188a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_toggling_qwait(struct bfa_fcport_s *fcport,
189a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
190a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
191a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
192a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
193a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
194a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
195a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
196a36c61f9SKrishna Gudipati static void     bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
197a36c61f9SKrishna Gudipati 					enum bfa_fcport_sm_event event);
198a36c61f9SKrishna Gudipati 
199a36c61f9SKrishna Gudipati static void     bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
200a36c61f9SKrishna Gudipati 					enum bfa_fcport_ln_sm_event event);
201a36c61f9SKrishna Gudipati static void     bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
202a36c61f9SKrishna Gudipati 					enum bfa_fcport_ln_sm_event event);
203a36c61f9SKrishna Gudipati static void     bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
204a36c61f9SKrishna Gudipati 					enum bfa_fcport_ln_sm_event event);
205a36c61f9SKrishna Gudipati static void     bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
206a36c61f9SKrishna Gudipati 					enum bfa_fcport_ln_sm_event event);
207a36c61f9SKrishna Gudipati static void     bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
208a36c61f9SKrishna Gudipati 					enum bfa_fcport_ln_sm_event event);
209a36c61f9SKrishna Gudipati static void     bfa_fcport_ln_sm_up_dn_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_up_nf(struct bfa_fcport_ln_s *ln,
212a36c61f9SKrishna Gudipati 					enum bfa_fcport_ln_sm_event event);
213a36c61f9SKrishna Gudipati 
214a36c61f9SKrishna Gudipati static struct bfa_sm_table_s hal_port_sm_table[] = {
215a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_uninit), BFA_PORT_ST_UNINIT},
216a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_enabling_qwait), BFA_PORT_ST_ENABLING_QWAIT},
217a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_enabling), BFA_PORT_ST_ENABLING},
218a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_linkdown), BFA_PORT_ST_LINKDOWN},
219a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_linkup), BFA_PORT_ST_LINKUP},
220a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_disabling_qwait), BFA_PORT_ST_DISABLING_QWAIT},
221a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_toggling_qwait), BFA_PORT_ST_TOGGLING_QWAIT},
222a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_disabling), BFA_PORT_ST_DISABLING},
223a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_disabled), BFA_PORT_ST_DISABLED},
224a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_stopped), BFA_PORT_ST_STOPPED},
225a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_iocdown), BFA_PORT_ST_IOCDOWN},
226a36c61f9SKrishna Gudipati 	{BFA_SM(bfa_fcport_sm_iocfail), BFA_PORT_ST_IOCDOWN},
227a36c61f9SKrishna Gudipati };
228a36c61f9SKrishna Gudipati 
229a36c61f9SKrishna Gudipati 
2305fbe25c7SJing Huang /*
231a36c61f9SKrishna Gudipati  * forward declaration for RPORT related functions
232a36c61f9SKrishna Gudipati  */
233a36c61f9SKrishna Gudipati static struct bfa_rport_s *bfa_rport_alloc(struct bfa_rport_mod_s *rp_mod);
234a36c61f9SKrishna Gudipati static void		bfa_rport_free(struct bfa_rport_s *rport);
235a36c61f9SKrishna Gudipati static bfa_boolean_t	bfa_rport_send_fwcreate(struct bfa_rport_s *rp);
236a36c61f9SKrishna Gudipati static bfa_boolean_t	bfa_rport_send_fwdelete(struct bfa_rport_s *rp);
237a36c61f9SKrishna Gudipati static bfa_boolean_t	bfa_rport_send_fwspeed(struct bfa_rport_s *rp);
238a36c61f9SKrishna Gudipati static void		__bfa_cb_rport_online(void *cbarg,
239a36c61f9SKrishna Gudipati 						bfa_boolean_t complete);
240a36c61f9SKrishna Gudipati static void		__bfa_cb_rport_offline(void *cbarg,
241a36c61f9SKrishna Gudipati 						bfa_boolean_t complete);
242a36c61f9SKrishna Gudipati 
2435fbe25c7SJing Huang /*
244a36c61f9SKrishna Gudipati  * forward declaration for RPORT state machine
245a36c61f9SKrishna Gudipati  */
246a36c61f9SKrishna Gudipati static void     bfa_rport_sm_uninit(struct bfa_rport_s *rp,
247a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
248a36c61f9SKrishna Gudipati static void     bfa_rport_sm_created(struct bfa_rport_s *rp,
249a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
250a36c61f9SKrishna Gudipati static void     bfa_rport_sm_fwcreate(struct bfa_rport_s *rp,
251a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
252a36c61f9SKrishna Gudipati static void     bfa_rport_sm_online(struct bfa_rport_s *rp,
253a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
254a36c61f9SKrishna Gudipati static void     bfa_rport_sm_fwdelete(struct bfa_rport_s *rp,
255a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
256a36c61f9SKrishna Gudipati static void     bfa_rport_sm_offline(struct bfa_rport_s *rp,
257a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
258a36c61f9SKrishna Gudipati static void     bfa_rport_sm_deleting(struct bfa_rport_s *rp,
259a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
260a36c61f9SKrishna Gudipati static void     bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
261a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
262a36c61f9SKrishna Gudipati static void     bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
263a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
264a36c61f9SKrishna Gudipati static void     bfa_rport_sm_iocdisable(struct bfa_rport_s *rp,
265a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
266a36c61f9SKrishna Gudipati static void     bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp,
267a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
268a36c61f9SKrishna Gudipati static void     bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp,
269a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
270a36c61f9SKrishna Gudipati static void     bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp,
271a36c61f9SKrishna Gudipati 					enum bfa_rport_event event);
272a36c61f9SKrishna Gudipati 
2735fbe25c7SJing Huang /*
274a36c61f9SKrishna Gudipati  * PLOG related definitions
275a36c61f9SKrishna Gudipati  */
276a36c61f9SKrishna Gudipati static int
277a36c61f9SKrishna Gudipati plkd_validate_logrec(struct bfa_plog_rec_s *pl_rec)
278a36c61f9SKrishna Gudipati {
279a36c61f9SKrishna Gudipati 	if ((pl_rec->log_type != BFA_PL_LOG_TYPE_INT) &&
280a36c61f9SKrishna Gudipati 		(pl_rec->log_type != BFA_PL_LOG_TYPE_STRING))
281a36c61f9SKrishna Gudipati 		return 1;
282a36c61f9SKrishna Gudipati 
283a36c61f9SKrishna Gudipati 	if ((pl_rec->log_type != BFA_PL_LOG_TYPE_INT) &&
284a36c61f9SKrishna Gudipati 		(pl_rec->log_num_ints > BFA_PL_INT_LOG_SZ))
285a36c61f9SKrishna Gudipati 		return 1;
286a36c61f9SKrishna Gudipati 
287a36c61f9SKrishna Gudipati 	return 0;
288a36c61f9SKrishna Gudipati }
289a36c61f9SKrishna Gudipati 
290f16a1750SMaggie Zhang static u64
291f16a1750SMaggie Zhang bfa_get_log_time(void)
292f16a1750SMaggie Zhang {
293f16a1750SMaggie Zhang 	u64 system_time = 0;
294f16a1750SMaggie Zhang 	struct timeval tv;
295f16a1750SMaggie Zhang 	do_gettimeofday(&tv);
296f16a1750SMaggie Zhang 
297f16a1750SMaggie Zhang 	/* We are interested in seconds only. */
298f16a1750SMaggie Zhang 	system_time = tv.tv_sec;
299f16a1750SMaggie Zhang 	return system_time;
300f16a1750SMaggie Zhang }
301f16a1750SMaggie Zhang 
302a36c61f9SKrishna Gudipati static void
303a36c61f9SKrishna Gudipati bfa_plog_add(struct bfa_plog_s *plog, struct bfa_plog_rec_s *pl_rec)
304a36c61f9SKrishna Gudipati {
305a36c61f9SKrishna Gudipati 	u16 tail;
306a36c61f9SKrishna Gudipati 	struct bfa_plog_rec_s *pl_recp;
307a36c61f9SKrishna Gudipati 
308a36c61f9SKrishna Gudipati 	if (plog->plog_enabled == 0)
309a36c61f9SKrishna Gudipati 		return;
310a36c61f9SKrishna Gudipati 
311a36c61f9SKrishna Gudipati 	if (plkd_validate_logrec(pl_rec)) {
312d4b671c5SJing Huang 		WARN_ON(1);
313a36c61f9SKrishna Gudipati 		return;
314a36c61f9SKrishna Gudipati 	}
315a36c61f9SKrishna Gudipati 
316a36c61f9SKrishna Gudipati 	tail = plog->tail;
317a36c61f9SKrishna Gudipati 
318a36c61f9SKrishna Gudipati 	pl_recp = &(plog->plog_recs[tail]);
319a36c61f9SKrishna Gudipati 
3206a18b167SJing Huang 	memcpy(pl_recp, pl_rec, sizeof(struct bfa_plog_rec_s));
321a36c61f9SKrishna Gudipati 
322f16a1750SMaggie Zhang 	pl_recp->tv = bfa_get_log_time();
323a36c61f9SKrishna Gudipati 	BFA_PL_LOG_REC_INCR(plog->tail);
324a36c61f9SKrishna Gudipati 
325a36c61f9SKrishna Gudipati 	if (plog->head == plog->tail)
326a36c61f9SKrishna Gudipati 		BFA_PL_LOG_REC_INCR(plog->head);
327a36c61f9SKrishna Gudipati }
328a36c61f9SKrishna Gudipati 
329a36c61f9SKrishna Gudipati void
330a36c61f9SKrishna Gudipati bfa_plog_init(struct bfa_plog_s *plog)
331a36c61f9SKrishna Gudipati {
3326a18b167SJing Huang 	memset((char *)plog, 0, sizeof(struct bfa_plog_s));
333a36c61f9SKrishna Gudipati 
3346a18b167SJing Huang 	memcpy(plog->plog_sig, BFA_PL_SIG_STR, BFA_PL_SIG_LEN);
335a36c61f9SKrishna Gudipati 	plog->head = plog->tail = 0;
336a36c61f9SKrishna Gudipati 	plog->plog_enabled = 1;
337a36c61f9SKrishna Gudipati }
338a36c61f9SKrishna Gudipati 
339a36c61f9SKrishna Gudipati void
340a36c61f9SKrishna Gudipati bfa_plog_str(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
341a36c61f9SKrishna Gudipati 		enum bfa_plog_eid event,
342a36c61f9SKrishna Gudipati 		u16 misc, char *log_str)
343a36c61f9SKrishna Gudipati {
344a36c61f9SKrishna Gudipati 	struct bfa_plog_rec_s  lp;
345a36c61f9SKrishna Gudipati 
346a36c61f9SKrishna Gudipati 	if (plog->plog_enabled) {
3476a18b167SJing Huang 		memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
348a36c61f9SKrishna Gudipati 		lp.mid = mid;
349a36c61f9SKrishna Gudipati 		lp.eid = event;
350a36c61f9SKrishna Gudipati 		lp.log_type = BFA_PL_LOG_TYPE_STRING;
351a36c61f9SKrishna Gudipati 		lp.misc = misc;
352a36c61f9SKrishna Gudipati 		strncpy(lp.log_entry.string_log, log_str,
353a36c61f9SKrishna Gudipati 			BFA_PL_STRING_LOG_SZ - 1);
354a36c61f9SKrishna Gudipati 		lp.log_entry.string_log[BFA_PL_STRING_LOG_SZ - 1] = '\0';
355a36c61f9SKrishna Gudipati 		bfa_plog_add(plog, &lp);
356a36c61f9SKrishna Gudipati 	}
357a36c61f9SKrishna Gudipati }
358a36c61f9SKrishna Gudipati 
359a36c61f9SKrishna Gudipati void
360a36c61f9SKrishna Gudipati bfa_plog_intarr(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
361a36c61f9SKrishna Gudipati 		enum bfa_plog_eid event,
362a36c61f9SKrishna Gudipati 		u16 misc, u32 *intarr, u32 num_ints)
363a36c61f9SKrishna Gudipati {
364a36c61f9SKrishna Gudipati 	struct bfa_plog_rec_s  lp;
365a36c61f9SKrishna Gudipati 	u32 i;
366a36c61f9SKrishna Gudipati 
367a36c61f9SKrishna Gudipati 	if (num_ints > BFA_PL_INT_LOG_SZ)
368a36c61f9SKrishna Gudipati 		num_ints = BFA_PL_INT_LOG_SZ;
369a36c61f9SKrishna Gudipati 
370a36c61f9SKrishna Gudipati 	if (plog->plog_enabled) {
3716a18b167SJing Huang 		memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
372a36c61f9SKrishna Gudipati 		lp.mid = mid;
373a36c61f9SKrishna Gudipati 		lp.eid = event;
374a36c61f9SKrishna Gudipati 		lp.log_type = BFA_PL_LOG_TYPE_INT;
375a36c61f9SKrishna Gudipati 		lp.misc = misc;
376a36c61f9SKrishna Gudipati 
377a36c61f9SKrishna Gudipati 		for (i = 0; i < num_ints; i++)
3786a18b167SJing Huang 			lp.log_entry.int_log[i] = intarr[i];
379a36c61f9SKrishna Gudipati 
380a36c61f9SKrishna Gudipati 		lp.log_num_ints = (u8) num_ints;
381a36c61f9SKrishna Gudipati 
382a36c61f9SKrishna Gudipati 		bfa_plog_add(plog, &lp);
383a36c61f9SKrishna Gudipati 	}
384a36c61f9SKrishna Gudipati }
385a36c61f9SKrishna Gudipati 
386a36c61f9SKrishna Gudipati void
387a36c61f9SKrishna Gudipati bfa_plog_fchdr(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
388a36c61f9SKrishna Gudipati 			enum bfa_plog_eid event,
389a36c61f9SKrishna Gudipati 			u16 misc, struct fchs_s *fchdr)
390a36c61f9SKrishna Gudipati {
391a36c61f9SKrishna Gudipati 	struct bfa_plog_rec_s  lp;
392a36c61f9SKrishna Gudipati 	u32	*tmp_int = (u32 *) fchdr;
393a36c61f9SKrishna Gudipati 	u32	ints[BFA_PL_INT_LOG_SZ];
394a36c61f9SKrishna Gudipati 
395a36c61f9SKrishna Gudipati 	if (plog->plog_enabled) {
3966a18b167SJing Huang 		memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
397a36c61f9SKrishna Gudipati 
398a36c61f9SKrishna Gudipati 		ints[0] = tmp_int[0];
399a36c61f9SKrishna Gudipati 		ints[1] = tmp_int[1];
400a36c61f9SKrishna Gudipati 		ints[2] = tmp_int[4];
401a36c61f9SKrishna Gudipati 
402a36c61f9SKrishna Gudipati 		bfa_plog_intarr(plog, mid, event, misc, ints, 3);
403a36c61f9SKrishna Gudipati 	}
404a36c61f9SKrishna Gudipati }
405a36c61f9SKrishna Gudipati 
406a36c61f9SKrishna Gudipati void
407a36c61f9SKrishna Gudipati bfa_plog_fchdr_and_pl(struct bfa_plog_s *plog, enum bfa_plog_mid mid,
408a36c61f9SKrishna Gudipati 		      enum bfa_plog_eid event, u16 misc, struct fchs_s *fchdr,
409a36c61f9SKrishna Gudipati 		      u32 pld_w0)
410a36c61f9SKrishna Gudipati {
411a36c61f9SKrishna Gudipati 	struct bfa_plog_rec_s  lp;
412a36c61f9SKrishna Gudipati 	u32	*tmp_int = (u32 *) fchdr;
413a36c61f9SKrishna Gudipati 	u32	ints[BFA_PL_INT_LOG_SZ];
414a36c61f9SKrishna Gudipati 
415a36c61f9SKrishna Gudipati 	if (plog->plog_enabled) {
4166a18b167SJing Huang 		memset(&lp, 0, sizeof(struct bfa_plog_rec_s));
417a36c61f9SKrishna Gudipati 
418a36c61f9SKrishna Gudipati 		ints[0] = tmp_int[0];
419a36c61f9SKrishna Gudipati 		ints[1] = tmp_int[1];
420a36c61f9SKrishna Gudipati 		ints[2] = tmp_int[4];
421a36c61f9SKrishna Gudipati 		ints[3] = pld_w0;
422a36c61f9SKrishna Gudipati 
423a36c61f9SKrishna Gudipati 		bfa_plog_intarr(plog, mid, event, misc, ints, 4);
424a36c61f9SKrishna Gudipati 	}
425a36c61f9SKrishna Gudipati }
426a36c61f9SKrishna Gudipati 
427a36c61f9SKrishna Gudipati 
4285fbe25c7SJing Huang /*
429a36c61f9SKrishna Gudipati  *  fcxp_pvt BFA FCXP private functions
430a36c61f9SKrishna Gudipati  */
431a36c61f9SKrishna Gudipati 
432a36c61f9SKrishna Gudipati static void
433a36c61f9SKrishna Gudipati claim_fcxp_req_rsp_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
434a36c61f9SKrishna Gudipati {
435a36c61f9SKrishna Gudipati 	u8	       *dm_kva = NULL;
436a36c61f9SKrishna Gudipati 	u64	dm_pa;
437a36c61f9SKrishna Gudipati 	u32	buf_pool_sz;
438a36c61f9SKrishna Gudipati 
439a36c61f9SKrishna Gudipati 	dm_kva = bfa_meminfo_dma_virt(mi);
440a36c61f9SKrishna Gudipati 	dm_pa = bfa_meminfo_dma_phys(mi);
441a36c61f9SKrishna Gudipati 
442a36c61f9SKrishna Gudipati 	buf_pool_sz = mod->req_pld_sz * mod->num_fcxps;
443a36c61f9SKrishna Gudipati 
444a36c61f9SKrishna Gudipati 	/*
445a36c61f9SKrishna Gudipati 	 * Initialize the fcxp req payload list
446a36c61f9SKrishna Gudipati 	 */
447a36c61f9SKrishna Gudipati 	mod->req_pld_list_kva = dm_kva;
448a36c61f9SKrishna Gudipati 	mod->req_pld_list_pa = dm_pa;
449a36c61f9SKrishna Gudipati 	dm_kva += buf_pool_sz;
450a36c61f9SKrishna Gudipati 	dm_pa += buf_pool_sz;
4516a18b167SJing Huang 	memset(mod->req_pld_list_kva, 0, buf_pool_sz);
452a36c61f9SKrishna Gudipati 
453a36c61f9SKrishna Gudipati 	/*
454a36c61f9SKrishna Gudipati 	 * Initialize the fcxp rsp payload list
455a36c61f9SKrishna Gudipati 	 */
456a36c61f9SKrishna Gudipati 	buf_pool_sz = mod->rsp_pld_sz * mod->num_fcxps;
457a36c61f9SKrishna Gudipati 	mod->rsp_pld_list_kva = dm_kva;
458a36c61f9SKrishna Gudipati 	mod->rsp_pld_list_pa = dm_pa;
459a36c61f9SKrishna Gudipati 	dm_kva += buf_pool_sz;
460a36c61f9SKrishna Gudipati 	dm_pa += buf_pool_sz;
4616a18b167SJing Huang 	memset(mod->rsp_pld_list_kva, 0, buf_pool_sz);
462a36c61f9SKrishna Gudipati 
463a36c61f9SKrishna Gudipati 	bfa_meminfo_dma_virt(mi) = dm_kva;
464a36c61f9SKrishna Gudipati 	bfa_meminfo_dma_phys(mi) = dm_pa;
465a36c61f9SKrishna Gudipati }
466a36c61f9SKrishna Gudipati 
467a36c61f9SKrishna Gudipati static void
468a36c61f9SKrishna Gudipati claim_fcxps_mem(struct bfa_fcxp_mod_s *mod, struct bfa_meminfo_s *mi)
469a36c61f9SKrishna Gudipati {
470a36c61f9SKrishna Gudipati 	u16	i;
471a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
472a36c61f9SKrishna Gudipati 
473a36c61f9SKrishna Gudipati 	fcxp = (struct bfa_fcxp_s *) bfa_meminfo_kva(mi);
4746a18b167SJing Huang 	memset(fcxp, 0, sizeof(struct bfa_fcxp_s) * mod->num_fcxps);
475a36c61f9SKrishna Gudipati 
476a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->fcxp_free_q);
477a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->fcxp_active_q);
478a36c61f9SKrishna Gudipati 
479a36c61f9SKrishna Gudipati 	mod->fcxp_list = fcxp;
480a36c61f9SKrishna Gudipati 
481a36c61f9SKrishna Gudipati 	for (i = 0; i < mod->num_fcxps; i++) {
482a36c61f9SKrishna Gudipati 		fcxp->fcxp_mod = mod;
483a36c61f9SKrishna Gudipati 		fcxp->fcxp_tag = i;
484a36c61f9SKrishna Gudipati 
485a36c61f9SKrishna Gudipati 		list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
486a36c61f9SKrishna Gudipati 		bfa_reqq_winit(&fcxp->reqq_wqe, bfa_fcxp_qresume, fcxp);
487a36c61f9SKrishna Gudipati 		fcxp->reqq_waiting = BFA_FALSE;
488a36c61f9SKrishna Gudipati 
489a36c61f9SKrishna Gudipati 		fcxp = fcxp + 1;
490a36c61f9SKrishna Gudipati 	}
491a36c61f9SKrishna Gudipati 
492a36c61f9SKrishna Gudipati 	bfa_meminfo_kva(mi) = (void *)fcxp;
493a36c61f9SKrishna Gudipati }
494a36c61f9SKrishna Gudipati 
495a36c61f9SKrishna Gudipati static void
496a36c61f9SKrishna Gudipati bfa_fcxp_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
497a36c61f9SKrishna Gudipati 		 u32 *dm_len)
498a36c61f9SKrishna Gudipati {
499a36c61f9SKrishna Gudipati 	u16	num_fcxp_reqs = cfg->fwcfg.num_fcxp_reqs;
500a36c61f9SKrishna Gudipati 
501a36c61f9SKrishna Gudipati 	if (num_fcxp_reqs == 0)
502a36c61f9SKrishna Gudipati 		return;
503a36c61f9SKrishna Gudipati 
504a36c61f9SKrishna Gudipati 	/*
505a36c61f9SKrishna Gudipati 	 * Account for req/rsp payload
506a36c61f9SKrishna Gudipati 	 */
507a36c61f9SKrishna Gudipati 	*dm_len += BFA_FCXP_MAX_IBUF_SZ * num_fcxp_reqs;
508a36c61f9SKrishna Gudipati 	if (cfg->drvcfg.min_cfg)
509a36c61f9SKrishna Gudipati 		*dm_len += BFA_FCXP_MAX_IBUF_SZ * num_fcxp_reqs;
510a36c61f9SKrishna Gudipati 	else
511a36c61f9SKrishna Gudipati 		*dm_len += BFA_FCXP_MAX_LBUF_SZ * num_fcxp_reqs;
512a36c61f9SKrishna Gudipati 
513a36c61f9SKrishna Gudipati 	/*
514a36c61f9SKrishna Gudipati 	 * Account for fcxp structs
515a36c61f9SKrishna Gudipati 	 */
516a36c61f9SKrishna Gudipati 	*ndm_len += sizeof(struct bfa_fcxp_s) * num_fcxp_reqs;
517a36c61f9SKrishna Gudipati }
518a36c61f9SKrishna Gudipati 
519a36c61f9SKrishna Gudipati static void
520a36c61f9SKrishna Gudipati bfa_fcxp_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
521a36c61f9SKrishna Gudipati 		struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
522a36c61f9SKrishna Gudipati {
523a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
524a36c61f9SKrishna Gudipati 
5256a18b167SJing Huang 	memset(mod, 0, sizeof(struct bfa_fcxp_mod_s));
526a36c61f9SKrishna Gudipati 	mod->bfa = bfa;
527a36c61f9SKrishna Gudipati 	mod->num_fcxps = cfg->fwcfg.num_fcxp_reqs;
528a36c61f9SKrishna Gudipati 
5295fbe25c7SJing Huang 	/*
530a36c61f9SKrishna Gudipati 	 * Initialize FCXP request and response payload sizes.
531a36c61f9SKrishna Gudipati 	 */
532a36c61f9SKrishna Gudipati 	mod->req_pld_sz = mod->rsp_pld_sz = BFA_FCXP_MAX_IBUF_SZ;
533a36c61f9SKrishna Gudipati 	if (!cfg->drvcfg.min_cfg)
534a36c61f9SKrishna Gudipati 		mod->rsp_pld_sz = BFA_FCXP_MAX_LBUF_SZ;
535a36c61f9SKrishna Gudipati 
536a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->wait_q);
537a36c61f9SKrishna Gudipati 
538a36c61f9SKrishna Gudipati 	claim_fcxp_req_rsp_mem(mod, meminfo);
539a36c61f9SKrishna Gudipati 	claim_fcxps_mem(mod, meminfo);
540a36c61f9SKrishna Gudipati }
541a36c61f9SKrishna Gudipati 
542a36c61f9SKrishna Gudipati static void
543a36c61f9SKrishna Gudipati bfa_fcxp_detach(struct bfa_s *bfa)
544a36c61f9SKrishna Gudipati {
545a36c61f9SKrishna Gudipati }
546a36c61f9SKrishna Gudipati 
547a36c61f9SKrishna Gudipati static void
548a36c61f9SKrishna Gudipati bfa_fcxp_start(struct bfa_s *bfa)
549a36c61f9SKrishna Gudipati {
550a36c61f9SKrishna Gudipati }
551a36c61f9SKrishna Gudipati 
552a36c61f9SKrishna Gudipati static void
553a36c61f9SKrishna Gudipati bfa_fcxp_stop(struct bfa_s *bfa)
554a36c61f9SKrishna Gudipati {
555a36c61f9SKrishna Gudipati }
556a36c61f9SKrishna Gudipati 
557a36c61f9SKrishna Gudipati static void
558a36c61f9SKrishna Gudipati bfa_fcxp_iocdisable(struct bfa_s *bfa)
559a36c61f9SKrishna Gudipati {
560a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
561a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
562a36c61f9SKrishna Gudipati 	struct list_head	      *qe, *qen;
563a36c61f9SKrishna Gudipati 
564a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &mod->fcxp_active_q) {
565a36c61f9SKrishna Gudipati 		fcxp = (struct bfa_fcxp_s *) qe;
566a36c61f9SKrishna Gudipati 		if (fcxp->caller == NULL) {
567a36c61f9SKrishna Gudipati 			fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
568a36c61f9SKrishna Gudipati 					BFA_STATUS_IOC_FAILURE, 0, 0, NULL);
569a36c61f9SKrishna Gudipati 			bfa_fcxp_free(fcxp);
570a36c61f9SKrishna Gudipati 		} else {
571a36c61f9SKrishna Gudipati 			fcxp->rsp_status = BFA_STATUS_IOC_FAILURE;
572a36c61f9SKrishna Gudipati 			bfa_cb_queue(bfa, &fcxp->hcb_qe,
573a36c61f9SKrishna Gudipati 				     __bfa_fcxp_send_cbfn, fcxp);
574a36c61f9SKrishna Gudipati 		}
575a36c61f9SKrishna Gudipati 	}
576a36c61f9SKrishna Gudipati }
577a36c61f9SKrishna Gudipati 
578a36c61f9SKrishna Gudipati static struct bfa_fcxp_s *
579a36c61f9SKrishna Gudipati bfa_fcxp_get(struct bfa_fcxp_mod_s *fm)
580a36c61f9SKrishna Gudipati {
581a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp;
582a36c61f9SKrishna Gudipati 
583a36c61f9SKrishna Gudipati 	bfa_q_deq(&fm->fcxp_free_q, &fcxp);
584a36c61f9SKrishna Gudipati 
585a36c61f9SKrishna Gudipati 	if (fcxp)
586a36c61f9SKrishna Gudipati 		list_add_tail(&fcxp->qe, &fm->fcxp_active_q);
587a36c61f9SKrishna Gudipati 
588a36c61f9SKrishna Gudipati 	return fcxp;
589a36c61f9SKrishna Gudipati }
590a36c61f9SKrishna Gudipati 
591a36c61f9SKrishna Gudipati static void
592a36c61f9SKrishna Gudipati bfa_fcxp_init_reqrsp(struct bfa_fcxp_s *fcxp,
593a36c61f9SKrishna Gudipati 	       struct bfa_s *bfa,
594a36c61f9SKrishna Gudipati 	       u8 *use_ibuf,
595a36c61f9SKrishna Gudipati 	       u32 *nr_sgles,
596a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sgaddr_t *r_sga_cbfn,
597a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sglen_t *r_sglen_cbfn,
598a36c61f9SKrishna Gudipati 	       struct list_head *r_sgpg_q,
599a36c61f9SKrishna Gudipati 	       int n_sgles,
600a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sgaddr_t sga_cbfn,
601a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sglen_t sglen_cbfn)
602a36c61f9SKrishna Gudipati {
603a36c61f9SKrishna Gudipati 
604d4b671c5SJing Huang 	WARN_ON(bfa == NULL);
605a36c61f9SKrishna Gudipati 
606a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcxp->fcxp_tag);
607a36c61f9SKrishna Gudipati 
608a36c61f9SKrishna Gudipati 	if (n_sgles == 0) {
609a36c61f9SKrishna Gudipati 		*use_ibuf = 1;
610a36c61f9SKrishna Gudipati 	} else {
611d4b671c5SJing Huang 		WARN_ON(*sga_cbfn == NULL);
612d4b671c5SJing Huang 		WARN_ON(*sglen_cbfn == NULL);
613a36c61f9SKrishna Gudipati 
614a36c61f9SKrishna Gudipati 		*use_ibuf = 0;
615a36c61f9SKrishna Gudipati 		*r_sga_cbfn = sga_cbfn;
616a36c61f9SKrishna Gudipati 		*r_sglen_cbfn = sglen_cbfn;
617a36c61f9SKrishna Gudipati 
618a36c61f9SKrishna Gudipati 		*nr_sgles = n_sgles;
619a36c61f9SKrishna Gudipati 
620a36c61f9SKrishna Gudipati 		/*
621a36c61f9SKrishna Gudipati 		 * alloc required sgpgs
622a36c61f9SKrishna Gudipati 		 */
623a36c61f9SKrishna Gudipati 		if (n_sgles > BFI_SGE_INLINE)
624d4b671c5SJing Huang 			WARN_ON(1);
625a36c61f9SKrishna Gudipati 	}
626a36c61f9SKrishna Gudipati 
627a36c61f9SKrishna Gudipati }
628a36c61f9SKrishna Gudipati 
629a36c61f9SKrishna Gudipati static void
630a36c61f9SKrishna Gudipati bfa_fcxp_init(struct bfa_fcxp_s *fcxp,
631a36c61f9SKrishna Gudipati 	       void *caller, struct bfa_s *bfa, int nreq_sgles,
632a36c61f9SKrishna Gudipati 	       int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
633a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sglen_t req_sglen_cbfn,
634a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
635a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sglen_t rsp_sglen_cbfn)
636a36c61f9SKrishna Gudipati {
637a36c61f9SKrishna Gudipati 
638d4b671c5SJing Huang 	WARN_ON(bfa == NULL);
639a36c61f9SKrishna Gudipati 
640a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcxp->fcxp_tag);
641a36c61f9SKrishna Gudipati 
642a36c61f9SKrishna Gudipati 	fcxp->caller = caller;
643a36c61f9SKrishna Gudipati 
644a36c61f9SKrishna Gudipati 	bfa_fcxp_init_reqrsp(fcxp, bfa,
645a36c61f9SKrishna Gudipati 		&fcxp->use_ireqbuf, &fcxp->nreq_sgles, &fcxp->req_sga_cbfn,
646a36c61f9SKrishna Gudipati 		&fcxp->req_sglen_cbfn, &fcxp->req_sgpg_q,
647a36c61f9SKrishna Gudipati 		nreq_sgles, req_sga_cbfn, req_sglen_cbfn);
648a36c61f9SKrishna Gudipati 
649a36c61f9SKrishna Gudipati 	bfa_fcxp_init_reqrsp(fcxp, bfa,
650a36c61f9SKrishna Gudipati 		&fcxp->use_irspbuf, &fcxp->nrsp_sgles, &fcxp->rsp_sga_cbfn,
651a36c61f9SKrishna Gudipati 		&fcxp->rsp_sglen_cbfn, &fcxp->rsp_sgpg_q,
652a36c61f9SKrishna Gudipati 		nrsp_sgles, rsp_sga_cbfn, rsp_sglen_cbfn);
653a36c61f9SKrishna Gudipati 
654a36c61f9SKrishna Gudipati }
655a36c61f9SKrishna Gudipati 
656a36c61f9SKrishna Gudipati static void
657a36c61f9SKrishna Gudipati bfa_fcxp_put(struct bfa_fcxp_s *fcxp)
658a36c61f9SKrishna Gudipati {
659a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
660a36c61f9SKrishna Gudipati 	struct bfa_fcxp_wqe_s *wqe;
661a36c61f9SKrishna Gudipati 
662a36c61f9SKrishna Gudipati 	bfa_q_deq(&mod->wait_q, &wqe);
663a36c61f9SKrishna Gudipati 	if (wqe) {
664a36c61f9SKrishna Gudipati 		bfa_trc(mod->bfa, fcxp->fcxp_tag);
665a36c61f9SKrishna Gudipati 
666a36c61f9SKrishna Gudipati 		bfa_fcxp_init(fcxp, wqe->caller, wqe->bfa, wqe->nreq_sgles,
667a36c61f9SKrishna Gudipati 			wqe->nrsp_sgles, wqe->req_sga_cbfn,
668a36c61f9SKrishna Gudipati 			wqe->req_sglen_cbfn, wqe->rsp_sga_cbfn,
669a36c61f9SKrishna Gudipati 			wqe->rsp_sglen_cbfn);
670a36c61f9SKrishna Gudipati 
671a36c61f9SKrishna Gudipati 		wqe->alloc_cbfn(wqe->alloc_cbarg, fcxp);
672a36c61f9SKrishna Gudipati 		return;
673a36c61f9SKrishna Gudipati 	}
674a36c61f9SKrishna Gudipati 
675d4b671c5SJing Huang 	WARN_ON(!bfa_q_is_on_q(&mod->fcxp_active_q, fcxp));
676a36c61f9SKrishna Gudipati 	list_del(&fcxp->qe);
677a36c61f9SKrishna Gudipati 	list_add_tail(&fcxp->qe, &mod->fcxp_free_q);
678a36c61f9SKrishna Gudipati }
679a36c61f9SKrishna Gudipati 
680a36c61f9SKrishna Gudipati static void
681a36c61f9SKrishna Gudipati bfa_fcxp_null_comp(void *bfad_fcxp, struct bfa_fcxp_s *fcxp, void *cbarg,
682a36c61f9SKrishna Gudipati 		   bfa_status_t req_status, u32 rsp_len,
683a36c61f9SKrishna Gudipati 		   u32 resid_len, struct fchs_s *rsp_fchs)
684a36c61f9SKrishna Gudipati {
685a36c61f9SKrishna Gudipati 	/* discarded fcxp completion */
686a36c61f9SKrishna Gudipati }
687a36c61f9SKrishna Gudipati 
688a36c61f9SKrishna Gudipati static void
689a36c61f9SKrishna Gudipati __bfa_fcxp_send_cbfn(void *cbarg, bfa_boolean_t complete)
690a36c61f9SKrishna Gudipati {
691a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp = cbarg;
692a36c61f9SKrishna Gudipati 
693a36c61f9SKrishna Gudipati 	if (complete) {
694a36c61f9SKrishna Gudipati 		fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
695a36c61f9SKrishna Gudipati 				fcxp->rsp_status, fcxp->rsp_len,
696a36c61f9SKrishna Gudipati 				fcxp->residue_len, &fcxp->rsp_fchs);
697a36c61f9SKrishna Gudipati 	} else {
698a36c61f9SKrishna Gudipati 		bfa_fcxp_free(fcxp);
699a36c61f9SKrishna Gudipati 	}
700a36c61f9SKrishna Gudipati }
701a36c61f9SKrishna Gudipati 
702a36c61f9SKrishna Gudipati static void
703a36c61f9SKrishna Gudipati hal_fcxp_send_comp(struct bfa_s *bfa, struct bfi_fcxp_send_rsp_s *fcxp_rsp)
704a36c61f9SKrishna Gudipati {
705a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s	*mod = BFA_FCXP_MOD(bfa);
706a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s	*fcxp;
707ba816ea8SJing Huang 	u16		fcxp_tag = be16_to_cpu(fcxp_rsp->fcxp_tag);
708a36c61f9SKrishna Gudipati 
709a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcxp_tag);
710a36c61f9SKrishna Gudipati 
711ba816ea8SJing Huang 	fcxp_rsp->rsp_len = be32_to_cpu(fcxp_rsp->rsp_len);
712a36c61f9SKrishna Gudipati 
7135fbe25c7SJing Huang 	/*
714a36c61f9SKrishna Gudipati 	 * @todo f/w should not set residue to non-0 when everything
715a36c61f9SKrishna Gudipati 	 *	 is received.
716a36c61f9SKrishna Gudipati 	 */
717a36c61f9SKrishna Gudipati 	if (fcxp_rsp->req_status == BFA_STATUS_OK)
718a36c61f9SKrishna Gudipati 		fcxp_rsp->residue_len = 0;
719a36c61f9SKrishna Gudipati 	else
720ba816ea8SJing Huang 		fcxp_rsp->residue_len = be32_to_cpu(fcxp_rsp->residue_len);
721a36c61f9SKrishna Gudipati 
722a36c61f9SKrishna Gudipati 	fcxp = BFA_FCXP_FROM_TAG(mod, fcxp_tag);
723a36c61f9SKrishna Gudipati 
724d4b671c5SJing Huang 	WARN_ON(fcxp->send_cbfn == NULL);
725a36c61f9SKrishna Gudipati 
726a36c61f9SKrishna Gudipati 	hal_fcxp_rx_plog(mod->bfa, fcxp, fcxp_rsp);
727a36c61f9SKrishna Gudipati 
728a36c61f9SKrishna Gudipati 	if (fcxp->send_cbfn != NULL) {
729a36c61f9SKrishna Gudipati 		bfa_trc(mod->bfa, (NULL == fcxp->caller));
730a36c61f9SKrishna Gudipati 		if (fcxp->caller == NULL) {
731a36c61f9SKrishna Gudipati 			fcxp->send_cbfn(fcxp->caller, fcxp, fcxp->send_cbarg,
732a36c61f9SKrishna Gudipati 					fcxp_rsp->req_status, fcxp_rsp->rsp_len,
733a36c61f9SKrishna Gudipati 					fcxp_rsp->residue_len, &fcxp_rsp->fchs);
734a36c61f9SKrishna Gudipati 			/*
735a36c61f9SKrishna Gudipati 			 * fcxp automatically freed on return from the callback
736a36c61f9SKrishna Gudipati 			 */
737a36c61f9SKrishna Gudipati 			bfa_fcxp_free(fcxp);
738a36c61f9SKrishna Gudipati 		} else {
739a36c61f9SKrishna Gudipati 			fcxp->rsp_status = fcxp_rsp->req_status;
740a36c61f9SKrishna Gudipati 			fcxp->rsp_len = fcxp_rsp->rsp_len;
741a36c61f9SKrishna Gudipati 			fcxp->residue_len = fcxp_rsp->residue_len;
742a36c61f9SKrishna Gudipati 			fcxp->rsp_fchs = fcxp_rsp->fchs;
743a36c61f9SKrishna Gudipati 
744a36c61f9SKrishna Gudipati 			bfa_cb_queue(bfa, &fcxp->hcb_qe,
745a36c61f9SKrishna Gudipati 					__bfa_fcxp_send_cbfn, fcxp);
746a36c61f9SKrishna Gudipati 		}
747a36c61f9SKrishna Gudipati 	} else {
748a36c61f9SKrishna Gudipati 		bfa_trc(bfa, (NULL == fcxp->send_cbfn));
749a36c61f9SKrishna Gudipati 	}
750a36c61f9SKrishna Gudipati }
751a36c61f9SKrishna Gudipati 
752a36c61f9SKrishna Gudipati static void
753a36c61f9SKrishna Gudipati hal_fcxp_set_local_sges(struct bfi_sge_s *sge, u32 reqlen, u64 req_pa)
754a36c61f9SKrishna Gudipati {
755a36c61f9SKrishna Gudipati 	union bfi_addr_u      sga_zero = { {0} };
756a36c61f9SKrishna Gudipati 
757a36c61f9SKrishna Gudipati 	sge->sg_len = reqlen;
758a36c61f9SKrishna Gudipati 	sge->flags = BFI_SGE_DATA_LAST;
759a36c61f9SKrishna Gudipati 	bfa_dma_addr_set(sge[0].sga, req_pa);
760a36c61f9SKrishna Gudipati 	bfa_sge_to_be(sge);
761a36c61f9SKrishna Gudipati 	sge++;
762a36c61f9SKrishna Gudipati 
763a36c61f9SKrishna Gudipati 	sge->sga = sga_zero;
764a36c61f9SKrishna Gudipati 	sge->sg_len = reqlen;
765a36c61f9SKrishna Gudipati 	sge->flags = BFI_SGE_PGDLEN;
766a36c61f9SKrishna Gudipati 	bfa_sge_to_be(sge);
767a36c61f9SKrishna Gudipati }
768a36c61f9SKrishna Gudipati 
769a36c61f9SKrishna Gudipati static void
770a36c61f9SKrishna Gudipati hal_fcxp_tx_plog(struct bfa_s *bfa, u32 reqlen, struct bfa_fcxp_s *fcxp,
771a36c61f9SKrishna Gudipati 		 struct fchs_s *fchs)
772a36c61f9SKrishna Gudipati {
773a36c61f9SKrishna Gudipati 	/*
774a36c61f9SKrishna Gudipati 	 * TODO: TX ox_id
775a36c61f9SKrishna Gudipati 	 */
776a36c61f9SKrishna Gudipati 	if (reqlen > 0) {
777a36c61f9SKrishna Gudipati 		if (fcxp->use_ireqbuf) {
778a36c61f9SKrishna Gudipati 			u32	pld_w0 =
779a36c61f9SKrishna Gudipati 				*((u32 *) BFA_FCXP_REQ_PLD(fcxp));
780a36c61f9SKrishna Gudipati 
781a36c61f9SKrishna Gudipati 			bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP,
782a36c61f9SKrishna Gudipati 					BFA_PL_EID_TX,
783a36c61f9SKrishna Gudipati 					reqlen + sizeof(struct fchs_s), fchs,
784a36c61f9SKrishna Gudipati 					pld_w0);
785a36c61f9SKrishna Gudipati 		} else {
786a36c61f9SKrishna Gudipati 			bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP,
787a36c61f9SKrishna Gudipati 					BFA_PL_EID_TX,
788a36c61f9SKrishna Gudipati 					reqlen + sizeof(struct fchs_s),
789a36c61f9SKrishna Gudipati 					fchs);
790a36c61f9SKrishna Gudipati 		}
791a36c61f9SKrishna Gudipati 	} else {
792a36c61f9SKrishna Gudipati 		bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_TX,
793a36c61f9SKrishna Gudipati 			       reqlen + sizeof(struct fchs_s), fchs);
794a36c61f9SKrishna Gudipati 	}
795a36c61f9SKrishna Gudipati }
796a36c61f9SKrishna Gudipati 
797a36c61f9SKrishna Gudipati static void
798a36c61f9SKrishna Gudipati hal_fcxp_rx_plog(struct bfa_s *bfa, struct bfa_fcxp_s *fcxp,
799a36c61f9SKrishna Gudipati 		 struct bfi_fcxp_send_rsp_s *fcxp_rsp)
800a36c61f9SKrishna Gudipati {
801a36c61f9SKrishna Gudipati 	if (fcxp_rsp->rsp_len > 0) {
802a36c61f9SKrishna Gudipati 		if (fcxp->use_irspbuf) {
803a36c61f9SKrishna Gudipati 			u32	pld_w0 =
804a36c61f9SKrishna Gudipati 				*((u32 *) BFA_FCXP_RSP_PLD(fcxp));
805a36c61f9SKrishna Gudipati 
806a36c61f9SKrishna Gudipati 			bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_FCXP,
807a36c61f9SKrishna Gudipati 					      BFA_PL_EID_RX,
808a36c61f9SKrishna Gudipati 					      (u16) fcxp_rsp->rsp_len,
809a36c61f9SKrishna Gudipati 					      &fcxp_rsp->fchs, pld_w0);
810a36c61f9SKrishna Gudipati 		} else {
811a36c61f9SKrishna Gudipati 			bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP,
812a36c61f9SKrishna Gudipati 				       BFA_PL_EID_RX,
813a36c61f9SKrishna Gudipati 				       (u16) fcxp_rsp->rsp_len,
814a36c61f9SKrishna Gudipati 				       &fcxp_rsp->fchs);
815a36c61f9SKrishna Gudipati 		}
816a36c61f9SKrishna Gudipati 	} else {
817a36c61f9SKrishna Gudipati 		bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_FCXP, BFA_PL_EID_RX,
818a36c61f9SKrishna Gudipati 			       (u16) fcxp_rsp->rsp_len, &fcxp_rsp->fchs);
819a36c61f9SKrishna Gudipati 	}
820a36c61f9SKrishna Gudipati }
821a36c61f9SKrishna Gudipati 
8225fbe25c7SJing Huang /*
823a36c61f9SKrishna Gudipati  * Handler to resume sending fcxp when space in available in cpe queue.
824a36c61f9SKrishna Gudipati  */
825a36c61f9SKrishna Gudipati static void
826a36c61f9SKrishna Gudipati bfa_fcxp_qresume(void *cbarg)
827a36c61f9SKrishna Gudipati {
828a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s		*fcxp = cbarg;
829a36c61f9SKrishna Gudipati 	struct bfa_s			*bfa = fcxp->fcxp_mod->bfa;
830a36c61f9SKrishna Gudipati 	struct bfi_fcxp_send_req_s	*send_req;
831a36c61f9SKrishna Gudipati 
832a36c61f9SKrishna Gudipati 	fcxp->reqq_waiting = BFA_FALSE;
833a36c61f9SKrishna Gudipati 	send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
834a36c61f9SKrishna Gudipati 	bfa_fcxp_queue(fcxp, send_req);
835a36c61f9SKrishna Gudipati }
836a36c61f9SKrishna Gudipati 
8375fbe25c7SJing Huang /*
838a36c61f9SKrishna Gudipati  * Queue fcxp send request to foimrware.
839a36c61f9SKrishna Gudipati  */
840a36c61f9SKrishna Gudipati static void
841a36c61f9SKrishna Gudipati bfa_fcxp_queue(struct bfa_fcxp_s *fcxp, struct bfi_fcxp_send_req_s *send_req)
842a36c61f9SKrishna Gudipati {
843a36c61f9SKrishna Gudipati 	struct bfa_s			*bfa = fcxp->fcxp_mod->bfa;
844a36c61f9SKrishna Gudipati 	struct bfa_fcxp_req_info_s	*reqi = &fcxp->req_info;
845a36c61f9SKrishna Gudipati 	struct bfa_fcxp_rsp_info_s	*rspi = &fcxp->rsp_info;
846a36c61f9SKrishna Gudipati 	struct bfa_rport_s		*rport = reqi->bfa_rport;
847a36c61f9SKrishna Gudipati 
848a36c61f9SKrishna Gudipati 	bfi_h2i_set(send_req->mh, BFI_MC_FCXP, BFI_FCXP_H2I_SEND_REQ,
849a36c61f9SKrishna Gudipati 		    bfa_lpuid(bfa));
850a36c61f9SKrishna Gudipati 
851ba816ea8SJing Huang 	send_req->fcxp_tag = cpu_to_be16(fcxp->fcxp_tag);
852a36c61f9SKrishna Gudipati 	if (rport) {
853a36c61f9SKrishna Gudipati 		send_req->rport_fw_hndl = rport->fw_handle;
854ba816ea8SJing Huang 		send_req->max_frmsz = cpu_to_be16(rport->rport_info.max_frmsz);
855a36c61f9SKrishna Gudipati 		if (send_req->max_frmsz == 0)
856ba816ea8SJing Huang 			send_req->max_frmsz = cpu_to_be16(FC_MAX_PDUSZ);
857a36c61f9SKrishna Gudipati 	} else {
858a36c61f9SKrishna Gudipati 		send_req->rport_fw_hndl = 0;
859ba816ea8SJing Huang 		send_req->max_frmsz = cpu_to_be16(FC_MAX_PDUSZ);
860a36c61f9SKrishna Gudipati 	}
861a36c61f9SKrishna Gudipati 
862ba816ea8SJing Huang 	send_req->vf_id = cpu_to_be16(reqi->vf_id);
863a36c61f9SKrishna Gudipati 	send_req->lp_tag = reqi->lp_tag;
864a36c61f9SKrishna Gudipati 	send_req->class = reqi->class;
865a36c61f9SKrishna Gudipati 	send_req->rsp_timeout = rspi->rsp_timeout;
866a36c61f9SKrishna Gudipati 	send_req->cts = reqi->cts;
867a36c61f9SKrishna Gudipati 	send_req->fchs = reqi->fchs;
868a36c61f9SKrishna Gudipati 
869ba816ea8SJing Huang 	send_req->req_len = cpu_to_be32(reqi->req_tot_len);
870ba816ea8SJing Huang 	send_req->rsp_maxlen = cpu_to_be32(rspi->rsp_maxlen);
871a36c61f9SKrishna Gudipati 
872a36c61f9SKrishna Gudipati 	/*
873a36c61f9SKrishna Gudipati 	 * setup req sgles
874a36c61f9SKrishna Gudipati 	 */
875a36c61f9SKrishna Gudipati 	if (fcxp->use_ireqbuf == 1) {
876a36c61f9SKrishna Gudipati 		hal_fcxp_set_local_sges(send_req->req_sge, reqi->req_tot_len,
877a36c61f9SKrishna Gudipati 					BFA_FCXP_REQ_PLD_PA(fcxp));
878a36c61f9SKrishna Gudipati 	} else {
879a36c61f9SKrishna Gudipati 		if (fcxp->nreq_sgles > 0) {
880d4b671c5SJing Huang 			WARN_ON(fcxp->nreq_sgles != 1);
881a36c61f9SKrishna Gudipati 			hal_fcxp_set_local_sges(send_req->req_sge,
882a36c61f9SKrishna Gudipati 						reqi->req_tot_len,
883a36c61f9SKrishna Gudipati 						fcxp->req_sga_cbfn(fcxp->caller,
884a36c61f9SKrishna Gudipati 								   0));
885a36c61f9SKrishna Gudipati 		} else {
886d4b671c5SJing Huang 			WARN_ON(reqi->req_tot_len != 0);
887a36c61f9SKrishna Gudipati 			hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0);
888a36c61f9SKrishna Gudipati 		}
889a36c61f9SKrishna Gudipati 	}
890a36c61f9SKrishna Gudipati 
891a36c61f9SKrishna Gudipati 	/*
892a36c61f9SKrishna Gudipati 	 * setup rsp sgles
893a36c61f9SKrishna Gudipati 	 */
894a36c61f9SKrishna Gudipati 	if (fcxp->use_irspbuf == 1) {
895d4b671c5SJing Huang 		WARN_ON(rspi->rsp_maxlen > BFA_FCXP_MAX_LBUF_SZ);
896a36c61f9SKrishna Gudipati 
897a36c61f9SKrishna Gudipati 		hal_fcxp_set_local_sges(send_req->rsp_sge, rspi->rsp_maxlen,
898a36c61f9SKrishna Gudipati 					BFA_FCXP_RSP_PLD_PA(fcxp));
899a36c61f9SKrishna Gudipati 
900a36c61f9SKrishna Gudipati 	} else {
901a36c61f9SKrishna Gudipati 		if (fcxp->nrsp_sgles > 0) {
902d4b671c5SJing Huang 			WARN_ON(fcxp->nrsp_sgles != 1);
903a36c61f9SKrishna Gudipati 			hal_fcxp_set_local_sges(send_req->rsp_sge,
904a36c61f9SKrishna Gudipati 						rspi->rsp_maxlen,
905a36c61f9SKrishna Gudipati 						fcxp->rsp_sga_cbfn(fcxp->caller,
906a36c61f9SKrishna Gudipati 								   0));
907a36c61f9SKrishna Gudipati 		} else {
908d4b671c5SJing Huang 			WARN_ON(rspi->rsp_maxlen != 0);
909a36c61f9SKrishna Gudipati 			hal_fcxp_set_local_sges(send_req->rsp_sge, 0, 0);
910a36c61f9SKrishna Gudipati 		}
911a36c61f9SKrishna Gudipati 	}
912a36c61f9SKrishna Gudipati 
913a36c61f9SKrishna Gudipati 	hal_fcxp_tx_plog(bfa, reqi->req_tot_len, fcxp, &reqi->fchs);
914a36c61f9SKrishna Gudipati 
915a36c61f9SKrishna Gudipati 	bfa_reqq_produce(bfa, BFA_REQQ_FCXP);
916a36c61f9SKrishna Gudipati 
917a36c61f9SKrishna Gudipati 	bfa_trc(bfa, bfa_reqq_pi(bfa, BFA_REQQ_FCXP));
918a36c61f9SKrishna Gudipati 	bfa_trc(bfa, bfa_reqq_ci(bfa, BFA_REQQ_FCXP));
919a36c61f9SKrishna Gudipati }
920a36c61f9SKrishna Gudipati 
9215fbe25c7SJing Huang /*
922a36c61f9SKrishna Gudipati  * Allocate an FCXP instance to send a response or to send a request
923a36c61f9SKrishna Gudipati  * that has a response. Request/response buffers are allocated by caller.
924a36c61f9SKrishna Gudipati  *
925a36c61f9SKrishna Gudipati  * @param[in]	bfa		BFA bfa instance
926a36c61f9SKrishna Gudipati  * @param[in]	nreq_sgles	Number of SG elements required for request
927a36c61f9SKrishna Gudipati  *				buffer. 0, if fcxp internal buffers are	used.
928a36c61f9SKrishna Gudipati  *				Use bfa_fcxp_get_reqbuf() to get the
929a36c61f9SKrishna Gudipati  *				internal req buffer.
930a36c61f9SKrishna Gudipati  * @param[in]	req_sgles	SG elements describing request buffer. Will be
931a36c61f9SKrishna Gudipati  *				copied in by BFA and hence can be freed on
932a36c61f9SKrishna Gudipati  *				return from this function.
933a36c61f9SKrishna Gudipati  * @param[in]	get_req_sga	function ptr to be called to get a request SG
934a36c61f9SKrishna Gudipati  *				Address (given the sge index).
935a36c61f9SKrishna Gudipati  * @param[in]	get_req_sglen	function ptr to be called to get a request SG
936a36c61f9SKrishna Gudipati  *				len (given the sge index).
937a36c61f9SKrishna Gudipati  * @param[in]	get_rsp_sga	function ptr to be called to get a response SG
938a36c61f9SKrishna Gudipati  *				Address (given the sge index).
939a36c61f9SKrishna Gudipati  * @param[in]	get_rsp_sglen	function ptr to be called to get a response SG
940a36c61f9SKrishna Gudipati  *				len (given the sge index).
941a36c61f9SKrishna Gudipati  *
942a36c61f9SKrishna Gudipati  * @return FCXP instance. NULL on failure.
943a36c61f9SKrishna Gudipati  */
944a36c61f9SKrishna Gudipati struct bfa_fcxp_s *
945a36c61f9SKrishna Gudipati bfa_fcxp_alloc(void *caller, struct bfa_s *bfa, int nreq_sgles,
946a36c61f9SKrishna Gudipati 	       int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
947a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sglen_t req_sglen_cbfn,
948a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
949a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sglen_t rsp_sglen_cbfn)
950a36c61f9SKrishna Gudipati {
951a36c61f9SKrishna Gudipati 	struct bfa_fcxp_s *fcxp = NULL;
952a36c61f9SKrishna Gudipati 
953d4b671c5SJing Huang 	WARN_ON(bfa == NULL);
954a36c61f9SKrishna Gudipati 
955a36c61f9SKrishna Gudipati 	fcxp = bfa_fcxp_get(BFA_FCXP_MOD(bfa));
956a36c61f9SKrishna Gudipati 	if (fcxp == NULL)
957a36c61f9SKrishna Gudipati 		return NULL;
958a36c61f9SKrishna Gudipati 
959a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcxp->fcxp_tag);
960a36c61f9SKrishna Gudipati 
961a36c61f9SKrishna Gudipati 	bfa_fcxp_init(fcxp, caller, bfa, nreq_sgles, nrsp_sgles, req_sga_cbfn,
962a36c61f9SKrishna Gudipati 			req_sglen_cbfn, rsp_sga_cbfn, rsp_sglen_cbfn);
963a36c61f9SKrishna Gudipati 
964a36c61f9SKrishna Gudipati 	return fcxp;
965a36c61f9SKrishna Gudipati }
966a36c61f9SKrishna Gudipati 
9675fbe25c7SJing Huang /*
968a36c61f9SKrishna Gudipati  * Get the internal request buffer pointer
969a36c61f9SKrishna Gudipati  *
970a36c61f9SKrishna Gudipati  * @param[in]	fcxp	BFA fcxp pointer
971a36c61f9SKrishna Gudipati  *
972a36c61f9SKrishna Gudipati  * @return		pointer to the internal request buffer
973a36c61f9SKrishna Gudipati  */
974a36c61f9SKrishna Gudipati void *
975a36c61f9SKrishna Gudipati bfa_fcxp_get_reqbuf(struct bfa_fcxp_s *fcxp)
976a36c61f9SKrishna Gudipati {
977a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
978a36c61f9SKrishna Gudipati 	void	*reqbuf;
979a36c61f9SKrishna Gudipati 
980d4b671c5SJing Huang 	WARN_ON(fcxp->use_ireqbuf != 1);
981a36c61f9SKrishna Gudipati 	reqbuf = ((u8 *)mod->req_pld_list_kva) +
982a36c61f9SKrishna Gudipati 		fcxp->fcxp_tag * mod->req_pld_sz;
983a36c61f9SKrishna Gudipati 	return reqbuf;
984a36c61f9SKrishna Gudipati }
985a36c61f9SKrishna Gudipati 
986a36c61f9SKrishna Gudipati u32
987a36c61f9SKrishna Gudipati bfa_fcxp_get_reqbufsz(struct bfa_fcxp_s *fcxp)
988a36c61f9SKrishna Gudipati {
989a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
990a36c61f9SKrishna Gudipati 
991a36c61f9SKrishna Gudipati 	return mod->req_pld_sz;
992a36c61f9SKrishna Gudipati }
993a36c61f9SKrishna Gudipati 
9945fbe25c7SJing Huang /*
995a36c61f9SKrishna Gudipati  * Get the internal response buffer pointer
996a36c61f9SKrishna Gudipati  *
997a36c61f9SKrishna Gudipati  * @param[in]	fcxp	BFA fcxp pointer
998a36c61f9SKrishna Gudipati  *
999a36c61f9SKrishna Gudipati  * @return		pointer to the internal request buffer
1000a36c61f9SKrishna Gudipati  */
1001a36c61f9SKrishna Gudipati void *
1002a36c61f9SKrishna Gudipati bfa_fcxp_get_rspbuf(struct bfa_fcxp_s *fcxp)
1003a36c61f9SKrishna Gudipati {
1004a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
1005a36c61f9SKrishna Gudipati 	void	*rspbuf;
1006a36c61f9SKrishna Gudipati 
1007d4b671c5SJing Huang 	WARN_ON(fcxp->use_irspbuf != 1);
1008a36c61f9SKrishna Gudipati 
1009a36c61f9SKrishna Gudipati 	rspbuf = ((u8 *)mod->rsp_pld_list_kva) +
1010a36c61f9SKrishna Gudipati 		fcxp->fcxp_tag * mod->rsp_pld_sz;
1011a36c61f9SKrishna Gudipati 	return rspbuf;
1012a36c61f9SKrishna Gudipati }
1013a36c61f9SKrishna Gudipati 
10145fbe25c7SJing Huang /*
1015a36c61f9SKrishna Gudipati  * Free the BFA FCXP
1016a36c61f9SKrishna Gudipati  *
1017a36c61f9SKrishna Gudipati  * @param[in]	fcxp			BFA fcxp pointer
1018a36c61f9SKrishna Gudipati  *
1019a36c61f9SKrishna Gudipati  * @return		void
1020a36c61f9SKrishna Gudipati  */
1021a36c61f9SKrishna Gudipati void
1022a36c61f9SKrishna Gudipati bfa_fcxp_free(struct bfa_fcxp_s *fcxp)
1023a36c61f9SKrishna Gudipati {
1024a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = fcxp->fcxp_mod;
1025a36c61f9SKrishna Gudipati 
1026d4b671c5SJing Huang 	WARN_ON(fcxp == NULL);
1027a36c61f9SKrishna Gudipati 	bfa_trc(mod->bfa, fcxp->fcxp_tag);
1028a36c61f9SKrishna Gudipati 	bfa_fcxp_put(fcxp);
1029a36c61f9SKrishna Gudipati }
1030a36c61f9SKrishna Gudipati 
10315fbe25c7SJing Huang /*
1032a36c61f9SKrishna Gudipati  * Send a FCXP request
1033a36c61f9SKrishna Gudipati  *
1034a36c61f9SKrishna Gudipati  * @param[in]	fcxp	BFA fcxp pointer
1035a36c61f9SKrishna Gudipati  * @param[in]	rport	BFA rport pointer. Could be left NULL for WKA rports
1036a36c61f9SKrishna Gudipati  * @param[in]	vf_id	virtual Fabric ID
1037a36c61f9SKrishna Gudipati  * @param[in]	lp_tag	lport tag
103825985edcSLucas De Marchi  * @param[in]	cts	use Continuous sequence
1039a36c61f9SKrishna Gudipati  * @param[in]	cos	fc Class of Service
1040a36c61f9SKrishna Gudipati  * @param[in]	reqlen	request length, does not include FCHS length
1041a36c61f9SKrishna Gudipati  * @param[in]	fchs	fc Header Pointer. The header content will be copied
1042a36c61f9SKrishna Gudipati  *			in by BFA.
1043a36c61f9SKrishna Gudipati  *
1044a36c61f9SKrishna Gudipati  * @param[in]	cbfn	call back function to be called on receiving
1045a36c61f9SKrishna Gudipati  *								the response
1046a36c61f9SKrishna Gudipati  * @param[in]	cbarg	arg for cbfn
1047a36c61f9SKrishna Gudipati  * @param[in]	rsp_timeout
1048a36c61f9SKrishna Gudipati  *			response timeout
1049a36c61f9SKrishna Gudipati  *
1050a36c61f9SKrishna Gudipati  * @return		bfa_status_t
1051a36c61f9SKrishna Gudipati  */
1052a36c61f9SKrishna Gudipati void
1053a36c61f9SKrishna Gudipati bfa_fcxp_send(struct bfa_fcxp_s *fcxp, struct bfa_rport_s *rport,
1054a36c61f9SKrishna Gudipati 	      u16 vf_id, u8 lp_tag, bfa_boolean_t cts, enum fc_cos cos,
1055a36c61f9SKrishna Gudipati 	      u32 reqlen, struct fchs_s *fchs, bfa_cb_fcxp_send_t cbfn,
1056a36c61f9SKrishna Gudipati 	      void *cbarg, u32 rsp_maxlen, u8 rsp_timeout)
1057a36c61f9SKrishna Gudipati {
1058a36c61f9SKrishna Gudipati 	struct bfa_s			*bfa  = fcxp->fcxp_mod->bfa;
1059a36c61f9SKrishna Gudipati 	struct bfa_fcxp_req_info_s	*reqi = &fcxp->req_info;
1060a36c61f9SKrishna Gudipati 	struct bfa_fcxp_rsp_info_s	*rspi = &fcxp->rsp_info;
1061a36c61f9SKrishna Gudipati 	struct bfi_fcxp_send_req_s	*send_req;
1062a36c61f9SKrishna Gudipati 
1063a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcxp->fcxp_tag);
1064a36c61f9SKrishna Gudipati 
10655fbe25c7SJing Huang 	/*
1066a36c61f9SKrishna Gudipati 	 * setup request/response info
1067a36c61f9SKrishna Gudipati 	 */
1068a36c61f9SKrishna Gudipati 	reqi->bfa_rport = rport;
1069a36c61f9SKrishna Gudipati 	reqi->vf_id = vf_id;
1070a36c61f9SKrishna Gudipati 	reqi->lp_tag = lp_tag;
1071a36c61f9SKrishna Gudipati 	reqi->class = cos;
1072a36c61f9SKrishna Gudipati 	rspi->rsp_timeout = rsp_timeout;
1073a36c61f9SKrishna Gudipati 	reqi->cts = cts;
1074a36c61f9SKrishna Gudipati 	reqi->fchs = *fchs;
1075a36c61f9SKrishna Gudipati 	reqi->req_tot_len = reqlen;
1076a36c61f9SKrishna Gudipati 	rspi->rsp_maxlen = rsp_maxlen;
1077a36c61f9SKrishna Gudipati 	fcxp->send_cbfn = cbfn ? cbfn : bfa_fcxp_null_comp;
1078a36c61f9SKrishna Gudipati 	fcxp->send_cbarg = cbarg;
1079a36c61f9SKrishna Gudipati 
10805fbe25c7SJing Huang 	/*
1081a36c61f9SKrishna Gudipati 	 * If no room in CPE queue, wait for space in request queue
1082a36c61f9SKrishna Gudipati 	 */
1083a36c61f9SKrishna Gudipati 	send_req = bfa_reqq_next(bfa, BFA_REQQ_FCXP);
1084a36c61f9SKrishna Gudipati 	if (!send_req) {
1085a36c61f9SKrishna Gudipati 		bfa_trc(bfa, fcxp->fcxp_tag);
1086a36c61f9SKrishna Gudipati 		fcxp->reqq_waiting = BFA_TRUE;
1087a36c61f9SKrishna Gudipati 		bfa_reqq_wait(bfa, BFA_REQQ_FCXP, &fcxp->reqq_wqe);
1088a36c61f9SKrishna Gudipati 		return;
1089a36c61f9SKrishna Gudipati 	}
1090a36c61f9SKrishna Gudipati 
1091a36c61f9SKrishna Gudipati 	bfa_fcxp_queue(fcxp, send_req);
1092a36c61f9SKrishna Gudipati }
1093a36c61f9SKrishna Gudipati 
10945fbe25c7SJing Huang /*
1095a36c61f9SKrishna Gudipati  * Abort a BFA FCXP
1096a36c61f9SKrishna Gudipati  *
1097a36c61f9SKrishna Gudipati  * @param[in]	fcxp	BFA fcxp pointer
1098a36c61f9SKrishna Gudipati  *
1099a36c61f9SKrishna Gudipati  * @return		void
1100a36c61f9SKrishna Gudipati  */
1101a36c61f9SKrishna Gudipati bfa_status_t
1102a36c61f9SKrishna Gudipati bfa_fcxp_abort(struct bfa_fcxp_s *fcxp)
1103a36c61f9SKrishna Gudipati {
1104a36c61f9SKrishna Gudipati 	bfa_trc(fcxp->fcxp_mod->bfa, fcxp->fcxp_tag);
1105d4b671c5SJing Huang 	WARN_ON(1);
1106a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
1107a36c61f9SKrishna Gudipati }
1108a36c61f9SKrishna Gudipati 
1109a36c61f9SKrishna Gudipati void
1110a36c61f9SKrishna Gudipati bfa_fcxp_alloc_wait(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe,
1111a36c61f9SKrishna Gudipati 	       bfa_fcxp_alloc_cbfn_t alloc_cbfn, void *alloc_cbarg,
1112a36c61f9SKrishna Gudipati 	       void *caller, int nreq_sgles,
1113a36c61f9SKrishna Gudipati 	       int nrsp_sgles, bfa_fcxp_get_sgaddr_t req_sga_cbfn,
1114a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sglen_t req_sglen_cbfn,
1115a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sgaddr_t rsp_sga_cbfn,
1116a36c61f9SKrishna Gudipati 	       bfa_fcxp_get_sglen_t rsp_sglen_cbfn)
1117a36c61f9SKrishna Gudipati {
1118a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
1119a36c61f9SKrishna Gudipati 
1120d4b671c5SJing Huang 	WARN_ON(!list_empty(&mod->fcxp_free_q));
1121a36c61f9SKrishna Gudipati 
1122a36c61f9SKrishna Gudipati 	wqe->alloc_cbfn = alloc_cbfn;
1123a36c61f9SKrishna Gudipati 	wqe->alloc_cbarg = alloc_cbarg;
1124a36c61f9SKrishna Gudipati 	wqe->caller = caller;
1125a36c61f9SKrishna Gudipati 	wqe->bfa = bfa;
1126a36c61f9SKrishna Gudipati 	wqe->nreq_sgles = nreq_sgles;
1127a36c61f9SKrishna Gudipati 	wqe->nrsp_sgles = nrsp_sgles;
1128a36c61f9SKrishna Gudipati 	wqe->req_sga_cbfn = req_sga_cbfn;
1129a36c61f9SKrishna Gudipati 	wqe->req_sglen_cbfn = req_sglen_cbfn;
1130a36c61f9SKrishna Gudipati 	wqe->rsp_sga_cbfn = rsp_sga_cbfn;
1131a36c61f9SKrishna Gudipati 	wqe->rsp_sglen_cbfn = rsp_sglen_cbfn;
1132a36c61f9SKrishna Gudipati 
1133a36c61f9SKrishna Gudipati 	list_add_tail(&wqe->qe, &mod->wait_q);
1134a36c61f9SKrishna Gudipati }
1135a36c61f9SKrishna Gudipati 
1136a36c61f9SKrishna Gudipati void
1137a36c61f9SKrishna Gudipati bfa_fcxp_walloc_cancel(struct bfa_s *bfa, struct bfa_fcxp_wqe_s *wqe)
1138a36c61f9SKrishna Gudipati {
1139a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
1140a36c61f9SKrishna Gudipati 
1141d4b671c5SJing Huang 	WARN_ON(!bfa_q_is_on_q(&mod->wait_q, wqe));
1142a36c61f9SKrishna Gudipati 	list_del(&wqe->qe);
1143a36c61f9SKrishna Gudipati }
1144a36c61f9SKrishna Gudipati 
1145a36c61f9SKrishna Gudipati void
1146a36c61f9SKrishna Gudipati bfa_fcxp_discard(struct bfa_fcxp_s *fcxp)
1147a36c61f9SKrishna Gudipati {
11485fbe25c7SJing Huang 	/*
1149a36c61f9SKrishna Gudipati 	 * If waiting for room in request queue, cancel reqq wait
1150a36c61f9SKrishna Gudipati 	 * and free fcxp.
1151a36c61f9SKrishna Gudipati 	 */
1152a36c61f9SKrishna Gudipati 	if (fcxp->reqq_waiting) {
1153a36c61f9SKrishna Gudipati 		fcxp->reqq_waiting = BFA_FALSE;
1154a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcxp->reqq_wqe);
1155a36c61f9SKrishna Gudipati 		bfa_fcxp_free(fcxp);
1156a36c61f9SKrishna Gudipati 		return;
1157a36c61f9SKrishna Gudipati 	}
1158a36c61f9SKrishna Gudipati 
1159a36c61f9SKrishna Gudipati 	fcxp->send_cbfn = bfa_fcxp_null_comp;
1160a36c61f9SKrishna Gudipati }
1161a36c61f9SKrishna Gudipati 
1162a36c61f9SKrishna Gudipati void
1163a36c61f9SKrishna Gudipati bfa_fcxp_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
1164a36c61f9SKrishna Gudipati {
1165a36c61f9SKrishna Gudipati 	switch (msg->mhdr.msg_id) {
1166a36c61f9SKrishna Gudipati 	case BFI_FCXP_I2H_SEND_RSP:
1167a36c61f9SKrishna Gudipati 		hal_fcxp_send_comp(bfa, (struct bfi_fcxp_send_rsp_s *) msg);
1168a36c61f9SKrishna Gudipati 		break;
1169a36c61f9SKrishna Gudipati 
1170a36c61f9SKrishna Gudipati 	default:
1171a36c61f9SKrishna Gudipati 		bfa_trc(bfa, msg->mhdr.msg_id);
1172d4b671c5SJing Huang 		WARN_ON(1);
1173a36c61f9SKrishna Gudipati 	}
1174a36c61f9SKrishna Gudipati }
1175a36c61f9SKrishna Gudipati 
1176a36c61f9SKrishna Gudipati u32
1177a36c61f9SKrishna Gudipati bfa_fcxp_get_maxrsp(struct bfa_s *bfa)
1178a36c61f9SKrishna Gudipati {
1179a36c61f9SKrishna Gudipati 	struct bfa_fcxp_mod_s *mod = BFA_FCXP_MOD(bfa);
1180a36c61f9SKrishna Gudipati 
1181a36c61f9SKrishna Gudipati 	return mod->rsp_pld_sz;
1182a36c61f9SKrishna Gudipati }
1183a36c61f9SKrishna Gudipati 
1184a36c61f9SKrishna Gudipati 
11855fbe25c7SJing Huang /*
1186a36c61f9SKrishna Gudipati  *  BFA LPS state machine functions
1187a36c61f9SKrishna Gudipati  */
1188a36c61f9SKrishna Gudipati 
11895fbe25c7SJing Huang /*
1190a36c61f9SKrishna Gudipati  * Init state -- no login
1191a36c61f9SKrishna Gudipati  */
1192a36c61f9SKrishna Gudipati static void
1193a36c61f9SKrishna Gudipati bfa_lps_sm_init(struct bfa_lps_s *lps, enum bfa_lps_event event)
1194a36c61f9SKrishna Gudipati {
1195a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, lps->lp_tag);
1196a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, event);
1197a36c61f9SKrishna Gudipati 
1198a36c61f9SKrishna Gudipati 	switch (event) {
1199a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_LOGIN:
1200a36c61f9SKrishna Gudipati 		if (bfa_reqq_full(lps->bfa, lps->reqq)) {
1201a36c61f9SKrishna Gudipati 			bfa_sm_set_state(lps, bfa_lps_sm_loginwait);
1202a36c61f9SKrishna Gudipati 			bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe);
1203a36c61f9SKrishna Gudipati 		} else {
1204a36c61f9SKrishna Gudipati 			bfa_sm_set_state(lps, bfa_lps_sm_login);
1205a36c61f9SKrishna Gudipati 			bfa_lps_send_login(lps);
1206a36c61f9SKrishna Gudipati 		}
1207a36c61f9SKrishna Gudipati 
1208a36c61f9SKrishna Gudipati 		if (lps->fdisc)
1209a36c61f9SKrishna Gudipati 			bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1210a36c61f9SKrishna Gudipati 				BFA_PL_EID_LOGIN, 0, "FDISC Request");
1211a36c61f9SKrishna Gudipati 		else
1212a36c61f9SKrishna Gudipati 			bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1213a36c61f9SKrishna Gudipati 				BFA_PL_EID_LOGIN, 0, "FLOGI Request");
1214a36c61f9SKrishna Gudipati 		break;
1215a36c61f9SKrishna Gudipati 
1216a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_LOGOUT:
1217a36c61f9SKrishna Gudipati 		bfa_lps_logout_comp(lps);
1218a36c61f9SKrishna Gudipati 		break;
1219a36c61f9SKrishna Gudipati 
1220a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_DELETE:
1221a36c61f9SKrishna Gudipati 		bfa_lps_free(lps);
1222a36c61f9SKrishna Gudipati 		break;
1223a36c61f9SKrishna Gudipati 
1224a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_RX_CVL:
1225a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_OFFLINE:
1226a36c61f9SKrishna Gudipati 		break;
1227a36c61f9SKrishna Gudipati 
1228a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_FWRSP:
1229a36c61f9SKrishna Gudipati 		/*
1230a36c61f9SKrishna Gudipati 		 * Could happen when fabric detects loopback and discards
1231a36c61f9SKrishna Gudipati 		 * the lps request. Fw will eventually sent out the timeout
1232a36c61f9SKrishna Gudipati 		 * Just ignore
1233a36c61f9SKrishna Gudipati 		 */
1234a36c61f9SKrishna Gudipati 		break;
1235a36c61f9SKrishna Gudipati 
1236a36c61f9SKrishna Gudipati 	default:
1237a36c61f9SKrishna Gudipati 		bfa_sm_fault(lps->bfa, event);
1238a36c61f9SKrishna Gudipati 	}
1239a36c61f9SKrishna Gudipati }
1240a36c61f9SKrishna Gudipati 
12415fbe25c7SJing Huang /*
1242a36c61f9SKrishna Gudipati  * login is in progress -- awaiting response from firmware
1243a36c61f9SKrishna Gudipati  */
1244a36c61f9SKrishna Gudipati static void
1245a36c61f9SKrishna Gudipati bfa_lps_sm_login(struct bfa_lps_s *lps, enum bfa_lps_event event)
1246a36c61f9SKrishna Gudipati {
1247a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, lps->lp_tag);
1248a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, event);
1249a36c61f9SKrishna Gudipati 
1250a36c61f9SKrishna Gudipati 	switch (event) {
1251a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_FWRSP:
1252a36c61f9SKrishna Gudipati 		if (lps->status == BFA_STATUS_OK) {
1253a36c61f9SKrishna Gudipati 			bfa_sm_set_state(lps, bfa_lps_sm_online);
1254a36c61f9SKrishna Gudipati 			if (lps->fdisc)
1255a36c61f9SKrishna Gudipati 				bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1256a36c61f9SKrishna Gudipati 					BFA_PL_EID_LOGIN, 0, "FDISC Accept");
1257a36c61f9SKrishna Gudipati 			else
1258a36c61f9SKrishna Gudipati 				bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1259a36c61f9SKrishna Gudipati 					BFA_PL_EID_LOGIN, 0, "FLOGI Accept");
1260b704495cSKrishna Gudipati 			/* If N2N, send the assigned PID to FW */
1261b704495cSKrishna Gudipati 			bfa_trc(lps->bfa, lps->fport);
1262b704495cSKrishna Gudipati 			bfa_trc(lps->bfa, lps->lp_pid);
1263b704495cSKrishna Gudipati 
1264b704495cSKrishna Gudipati 			if (!lps->fport && lps->lp_pid)
1265b704495cSKrishna Gudipati 				bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID);
1266a36c61f9SKrishna Gudipati 		} else {
1267a36c61f9SKrishna Gudipati 			bfa_sm_set_state(lps, bfa_lps_sm_init);
1268a36c61f9SKrishna Gudipati 			if (lps->fdisc)
1269a36c61f9SKrishna Gudipati 				bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1270a36c61f9SKrishna Gudipati 					BFA_PL_EID_LOGIN, 0,
1271a36c61f9SKrishna Gudipati 					"FDISC Fail (RJT or timeout)");
1272a36c61f9SKrishna Gudipati 			else
1273a36c61f9SKrishna Gudipati 				bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1274a36c61f9SKrishna Gudipati 					BFA_PL_EID_LOGIN, 0,
1275a36c61f9SKrishna Gudipati 					"FLOGI Fail (RJT or timeout)");
1276a36c61f9SKrishna Gudipati 		}
1277a36c61f9SKrishna Gudipati 		bfa_lps_login_comp(lps);
1278a36c61f9SKrishna Gudipati 		break;
1279a36c61f9SKrishna Gudipati 
1280a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_OFFLINE:
1281a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1282a36c61f9SKrishna Gudipati 		break;
1283a36c61f9SKrishna Gudipati 
1284b704495cSKrishna Gudipati 	case BFA_LPS_SM_SET_N2N_PID:
1285b704495cSKrishna Gudipati 		bfa_trc(lps->bfa, lps->fport);
1286b704495cSKrishna Gudipati 		bfa_trc(lps->bfa, lps->lp_pid);
1287b704495cSKrishna Gudipati 		break;
1288b704495cSKrishna Gudipati 
1289a36c61f9SKrishna Gudipati 	default:
1290a36c61f9SKrishna Gudipati 		bfa_sm_fault(lps->bfa, event);
1291a36c61f9SKrishna Gudipati 	}
1292a36c61f9SKrishna Gudipati }
1293a36c61f9SKrishna Gudipati 
12945fbe25c7SJing Huang /*
1295a36c61f9SKrishna Gudipati  * login pending - awaiting space in request queue
1296a36c61f9SKrishna Gudipati  */
1297a36c61f9SKrishna Gudipati static void
1298a36c61f9SKrishna Gudipati bfa_lps_sm_loginwait(struct bfa_lps_s *lps, enum bfa_lps_event event)
1299a36c61f9SKrishna Gudipati {
1300a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, lps->lp_tag);
1301a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, event);
1302a36c61f9SKrishna Gudipati 
1303a36c61f9SKrishna Gudipati 	switch (event) {
1304a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_RESUME:
1305a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_login);
1306a36c61f9SKrishna Gudipati 		break;
1307a36c61f9SKrishna Gudipati 
1308a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_OFFLINE:
1309a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1310a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&lps->wqe);
1311a36c61f9SKrishna Gudipati 		break;
1312a36c61f9SKrishna Gudipati 
1313a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_RX_CVL:
1314a36c61f9SKrishna Gudipati 		/*
1315a36c61f9SKrishna Gudipati 		 * Login was not even sent out; so when getting out
1316a36c61f9SKrishna Gudipati 		 * of this state, it will appear like a login retry
1317a36c61f9SKrishna Gudipati 		 * after Clear virtual link
1318a36c61f9SKrishna Gudipati 		 */
1319a36c61f9SKrishna Gudipati 		break;
1320a36c61f9SKrishna Gudipati 
1321a36c61f9SKrishna Gudipati 	default:
1322a36c61f9SKrishna Gudipati 		bfa_sm_fault(lps->bfa, event);
1323a36c61f9SKrishna Gudipati 	}
1324a36c61f9SKrishna Gudipati }
1325a36c61f9SKrishna Gudipati 
13265fbe25c7SJing Huang /*
1327a36c61f9SKrishna Gudipati  * login complete
1328a36c61f9SKrishna Gudipati  */
1329a36c61f9SKrishna Gudipati static void
1330a36c61f9SKrishna Gudipati bfa_lps_sm_online(struct bfa_lps_s *lps, enum bfa_lps_event event)
1331a36c61f9SKrishna Gudipati {
1332a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, lps->lp_tag);
1333a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, event);
1334a36c61f9SKrishna Gudipati 
1335a36c61f9SKrishna Gudipati 	switch (event) {
1336a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_LOGOUT:
1337a36c61f9SKrishna Gudipati 		if (bfa_reqq_full(lps->bfa, lps->reqq)) {
1338a36c61f9SKrishna Gudipati 			bfa_sm_set_state(lps, bfa_lps_sm_logowait);
1339a36c61f9SKrishna Gudipati 			bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe);
1340a36c61f9SKrishna Gudipati 		} else {
1341a36c61f9SKrishna Gudipati 			bfa_sm_set_state(lps, bfa_lps_sm_logout);
1342a36c61f9SKrishna Gudipati 			bfa_lps_send_logout(lps);
1343a36c61f9SKrishna Gudipati 		}
1344a36c61f9SKrishna Gudipati 		bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1345a36c61f9SKrishna Gudipati 			BFA_PL_EID_LOGO, 0, "Logout");
1346a36c61f9SKrishna Gudipati 		break;
1347a36c61f9SKrishna Gudipati 
1348a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_RX_CVL:
1349a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1350a36c61f9SKrishna Gudipati 
1351a36c61f9SKrishna Gudipati 		/* Let the vport module know about this event */
1352a36c61f9SKrishna Gudipati 		bfa_lps_cvl_event(lps);
1353a36c61f9SKrishna Gudipati 		bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1354a36c61f9SKrishna Gudipati 			BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
1355a36c61f9SKrishna Gudipati 		break;
1356a36c61f9SKrishna Gudipati 
1357b704495cSKrishna Gudipati 	case BFA_LPS_SM_SET_N2N_PID:
1358b704495cSKrishna Gudipati 		if (bfa_reqq_full(lps->bfa, lps->reqq)) {
1359b704495cSKrishna Gudipati 			bfa_sm_set_state(lps, bfa_lps_sm_online_n2n_pid_wait);
1360b704495cSKrishna Gudipati 			bfa_reqq_wait(lps->bfa, lps->reqq, &lps->wqe);
1361b704495cSKrishna Gudipati 		} else
1362b704495cSKrishna Gudipati 			bfa_lps_send_set_n2n_pid(lps);
1363b704495cSKrishna Gudipati 		break;
1364b704495cSKrishna Gudipati 
1365a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_OFFLINE:
1366a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_DELETE:
1367a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1368a36c61f9SKrishna Gudipati 		break;
1369a36c61f9SKrishna Gudipati 
1370a36c61f9SKrishna Gudipati 	default:
1371a36c61f9SKrishna Gudipati 		bfa_sm_fault(lps->bfa, event);
1372a36c61f9SKrishna Gudipati 	}
1373a36c61f9SKrishna Gudipati }
1374a36c61f9SKrishna Gudipati 
13758f4bfaddSJing Huang /*
1376b704495cSKrishna Gudipati  * login complete
1377b704495cSKrishna Gudipati  */
1378b704495cSKrishna Gudipati static void
1379b704495cSKrishna Gudipati bfa_lps_sm_online_n2n_pid_wait(struct bfa_lps_s *lps, enum bfa_lps_event event)
1380b704495cSKrishna Gudipati {
1381b704495cSKrishna Gudipati 	bfa_trc(lps->bfa, lps->lp_tag);
1382b704495cSKrishna Gudipati 	bfa_trc(lps->bfa, event);
1383b704495cSKrishna Gudipati 
1384b704495cSKrishna Gudipati 	switch (event) {
1385b704495cSKrishna Gudipati 	case BFA_LPS_SM_RESUME:
1386b704495cSKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_online);
1387b704495cSKrishna Gudipati 		bfa_lps_send_set_n2n_pid(lps);
1388b704495cSKrishna Gudipati 		break;
1389b704495cSKrishna Gudipati 
1390b704495cSKrishna Gudipati 	case BFA_LPS_SM_LOGOUT:
1391b704495cSKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_logowait);
1392b704495cSKrishna Gudipati 		bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1393b704495cSKrishna Gudipati 			BFA_PL_EID_LOGO, 0, "Logout");
1394b704495cSKrishna Gudipati 		break;
1395b704495cSKrishna Gudipati 
1396b704495cSKrishna Gudipati 	case BFA_LPS_SM_RX_CVL:
1397b704495cSKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1398b704495cSKrishna Gudipati 		bfa_reqq_wcancel(&lps->wqe);
1399b704495cSKrishna Gudipati 
1400b704495cSKrishna Gudipati 		/* Let the vport module know about this event */
1401b704495cSKrishna Gudipati 		bfa_lps_cvl_event(lps);
1402b704495cSKrishna Gudipati 		bfa_plog_str(lps->bfa->plog, BFA_PL_MID_LPS,
1403b704495cSKrishna Gudipati 			BFA_PL_EID_FIP_FCF_CVL, 0, "FCF Clear Virt. Link Rx");
1404b704495cSKrishna Gudipati 		break;
1405b704495cSKrishna Gudipati 
1406b704495cSKrishna Gudipati 	case BFA_LPS_SM_OFFLINE:
1407b704495cSKrishna Gudipati 	case BFA_LPS_SM_DELETE:
1408b704495cSKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1409b704495cSKrishna Gudipati 		bfa_reqq_wcancel(&lps->wqe);
1410b704495cSKrishna Gudipati 		break;
1411b704495cSKrishna Gudipati 
1412b704495cSKrishna Gudipati 	default:
1413b704495cSKrishna Gudipati 		bfa_sm_fault(lps->bfa, event);
1414b704495cSKrishna Gudipati 	}
1415b704495cSKrishna Gudipati }
1416b704495cSKrishna Gudipati 
14175fbe25c7SJing Huang /*
1418a36c61f9SKrishna Gudipati  * logout in progress - awaiting firmware response
1419a36c61f9SKrishna Gudipati  */
1420a36c61f9SKrishna Gudipati static void
1421a36c61f9SKrishna Gudipati bfa_lps_sm_logout(struct bfa_lps_s *lps, enum bfa_lps_event event)
1422a36c61f9SKrishna Gudipati {
1423a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, lps->lp_tag);
1424a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, event);
1425a36c61f9SKrishna Gudipati 
1426a36c61f9SKrishna Gudipati 	switch (event) {
1427a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_FWRSP:
1428a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1429a36c61f9SKrishna Gudipati 		bfa_lps_logout_comp(lps);
1430a36c61f9SKrishna Gudipati 		break;
1431a36c61f9SKrishna Gudipati 
1432a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_OFFLINE:
1433a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1434a36c61f9SKrishna Gudipati 		break;
1435a36c61f9SKrishna Gudipati 
1436a36c61f9SKrishna Gudipati 	default:
1437a36c61f9SKrishna Gudipati 		bfa_sm_fault(lps->bfa, event);
1438a36c61f9SKrishna Gudipati 	}
1439a36c61f9SKrishna Gudipati }
1440a36c61f9SKrishna Gudipati 
14415fbe25c7SJing Huang /*
1442a36c61f9SKrishna Gudipati  * logout pending -- awaiting space in request queue
1443a36c61f9SKrishna Gudipati  */
1444a36c61f9SKrishna Gudipati static void
1445a36c61f9SKrishna Gudipati bfa_lps_sm_logowait(struct bfa_lps_s *lps, enum bfa_lps_event event)
1446a36c61f9SKrishna Gudipati {
1447a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, lps->lp_tag);
1448a36c61f9SKrishna Gudipati 	bfa_trc(lps->bfa, event);
1449a36c61f9SKrishna Gudipati 
1450a36c61f9SKrishna Gudipati 	switch (event) {
1451a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_RESUME:
1452a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_logout);
1453a36c61f9SKrishna Gudipati 		bfa_lps_send_logout(lps);
1454a36c61f9SKrishna Gudipati 		break;
1455a36c61f9SKrishna Gudipati 
1456a36c61f9SKrishna Gudipati 	case BFA_LPS_SM_OFFLINE:
1457a36c61f9SKrishna Gudipati 		bfa_sm_set_state(lps, bfa_lps_sm_init);
1458a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&lps->wqe);
1459a36c61f9SKrishna Gudipati 		break;
1460a36c61f9SKrishna Gudipati 
1461a36c61f9SKrishna Gudipati 	default:
1462a36c61f9SKrishna Gudipati 		bfa_sm_fault(lps->bfa, event);
1463a36c61f9SKrishna Gudipati 	}
1464a36c61f9SKrishna Gudipati }
1465a36c61f9SKrishna Gudipati 
1466a36c61f9SKrishna Gudipati 
1467a36c61f9SKrishna Gudipati 
14685fbe25c7SJing Huang /*
1469a36c61f9SKrishna Gudipati  *  lps_pvt BFA LPS private functions
1470a36c61f9SKrishna Gudipati  */
1471a36c61f9SKrishna Gudipati 
14725fbe25c7SJing Huang /*
1473a36c61f9SKrishna Gudipati  * return memory requirement
1474a36c61f9SKrishna Gudipati  */
1475a36c61f9SKrishna Gudipati static void
1476a36c61f9SKrishna Gudipati bfa_lps_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
1477a36c61f9SKrishna Gudipati 	u32 *dm_len)
1478a36c61f9SKrishna Gudipati {
1479a36c61f9SKrishna Gudipati 	if (cfg->drvcfg.min_cfg)
1480a36c61f9SKrishna Gudipati 		*ndm_len += sizeof(struct bfa_lps_s) * BFA_LPS_MIN_LPORTS;
1481a36c61f9SKrishna Gudipati 	else
1482a36c61f9SKrishna Gudipati 		*ndm_len += sizeof(struct bfa_lps_s) * BFA_LPS_MAX_LPORTS;
1483a36c61f9SKrishna Gudipati }
1484a36c61f9SKrishna Gudipati 
14855fbe25c7SJing Huang /*
1486a36c61f9SKrishna Gudipati  * bfa module attach at initialization time
1487a36c61f9SKrishna Gudipati  */
1488a36c61f9SKrishna Gudipati static void
1489a36c61f9SKrishna Gudipati bfa_lps_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
1490a36c61f9SKrishna Gudipati 	struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
1491a36c61f9SKrishna Gudipati {
1492a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
1493a36c61f9SKrishna Gudipati 	struct bfa_lps_s	*lps;
1494a36c61f9SKrishna Gudipati 	int			i;
1495a36c61f9SKrishna Gudipati 
14966a18b167SJing Huang 	memset(mod, 0, sizeof(struct bfa_lps_mod_s));
1497a36c61f9SKrishna Gudipati 	mod->num_lps = BFA_LPS_MAX_LPORTS;
1498a36c61f9SKrishna Gudipati 	if (cfg->drvcfg.min_cfg)
1499a36c61f9SKrishna Gudipati 		mod->num_lps = BFA_LPS_MIN_LPORTS;
1500a36c61f9SKrishna Gudipati 	else
1501a36c61f9SKrishna Gudipati 		mod->num_lps = BFA_LPS_MAX_LPORTS;
1502a36c61f9SKrishna Gudipati 	mod->lps_arr = lps = (struct bfa_lps_s *) bfa_meminfo_kva(meminfo);
1503a36c61f9SKrishna Gudipati 
1504a36c61f9SKrishna Gudipati 	bfa_meminfo_kva(meminfo) += mod->num_lps * sizeof(struct bfa_lps_s);
1505a36c61f9SKrishna Gudipati 
1506a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->lps_free_q);
1507a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->lps_active_q);
1508a36c61f9SKrishna Gudipati 
1509a36c61f9SKrishna Gudipati 	for (i = 0; i < mod->num_lps; i++, lps++) {
1510a36c61f9SKrishna Gudipati 		lps->bfa	= bfa;
1511a36c61f9SKrishna Gudipati 		lps->lp_tag	= (u8) i;
1512a36c61f9SKrishna Gudipati 		lps->reqq	= BFA_REQQ_LPS;
1513a36c61f9SKrishna Gudipati 		bfa_reqq_winit(&lps->wqe, bfa_lps_reqq_resume, lps);
1514a36c61f9SKrishna Gudipati 		list_add_tail(&lps->qe, &mod->lps_free_q);
1515a36c61f9SKrishna Gudipati 	}
1516a36c61f9SKrishna Gudipati }
1517a36c61f9SKrishna Gudipati 
1518a36c61f9SKrishna Gudipati static void
1519a36c61f9SKrishna Gudipati bfa_lps_detach(struct bfa_s *bfa)
1520a36c61f9SKrishna Gudipati {
1521a36c61f9SKrishna Gudipati }
1522a36c61f9SKrishna Gudipati 
1523a36c61f9SKrishna Gudipati static void
1524a36c61f9SKrishna Gudipati bfa_lps_start(struct bfa_s *bfa)
1525a36c61f9SKrishna Gudipati {
1526a36c61f9SKrishna Gudipati }
1527a36c61f9SKrishna Gudipati 
1528a36c61f9SKrishna Gudipati static void
1529a36c61f9SKrishna Gudipati bfa_lps_stop(struct bfa_s *bfa)
1530a36c61f9SKrishna Gudipati {
1531a36c61f9SKrishna Gudipati }
1532a36c61f9SKrishna Gudipati 
15335fbe25c7SJing Huang /*
1534a36c61f9SKrishna Gudipati  * IOC in disabled state -- consider all lps offline
1535a36c61f9SKrishna Gudipati  */
1536a36c61f9SKrishna Gudipati static void
1537a36c61f9SKrishna Gudipati bfa_lps_iocdisable(struct bfa_s *bfa)
1538a36c61f9SKrishna Gudipati {
1539a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
1540a36c61f9SKrishna Gudipati 	struct bfa_lps_s	*lps;
1541a36c61f9SKrishna Gudipati 	struct list_head		*qe, *qen;
1542a36c61f9SKrishna Gudipati 
1543a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &mod->lps_active_q) {
1544a36c61f9SKrishna Gudipati 		lps = (struct bfa_lps_s *) qe;
1545a36c61f9SKrishna Gudipati 		bfa_sm_send_event(lps, BFA_LPS_SM_OFFLINE);
1546a36c61f9SKrishna Gudipati 	}
1547a36c61f9SKrishna Gudipati }
1548a36c61f9SKrishna Gudipati 
15495fbe25c7SJing Huang /*
1550a36c61f9SKrishna Gudipati  * Firmware login response
1551a36c61f9SKrishna Gudipati  */
1552a36c61f9SKrishna Gudipati static void
1553a36c61f9SKrishna Gudipati bfa_lps_login_rsp(struct bfa_s *bfa, struct bfi_lps_login_rsp_s *rsp)
1554a36c61f9SKrishna Gudipati {
1555a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
1556a36c61f9SKrishna Gudipati 	struct bfa_lps_s	*lps;
1557a36c61f9SKrishna Gudipati 
1558d4b671c5SJing Huang 	WARN_ON(rsp->lp_tag >= mod->num_lps);
1559a36c61f9SKrishna Gudipati 	lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag);
1560a36c61f9SKrishna Gudipati 
1561a36c61f9SKrishna Gudipati 	lps->status = rsp->status;
1562a36c61f9SKrishna Gudipati 	switch (rsp->status) {
1563a36c61f9SKrishna Gudipati 	case BFA_STATUS_OK:
1564a36c61f9SKrishna Gudipati 		lps->fport	= rsp->f_port;
1565b704495cSKrishna Gudipati 		if (lps->fport)
1566a36c61f9SKrishna Gudipati 			lps->lp_pid = rsp->lp_pid;
1567b704495cSKrishna Gudipati 		lps->npiv_en	= rsp->npiv_en;
1568ba816ea8SJing Huang 		lps->pr_bbcred	= be16_to_cpu(rsp->bb_credit);
1569a36c61f9SKrishna Gudipati 		lps->pr_pwwn	= rsp->port_name;
1570a36c61f9SKrishna Gudipati 		lps->pr_nwwn	= rsp->node_name;
1571a36c61f9SKrishna Gudipati 		lps->auth_req	= rsp->auth_req;
1572a36c61f9SKrishna Gudipati 		lps->lp_mac	= rsp->lp_mac;
1573a36c61f9SKrishna Gudipati 		lps->brcd_switch = rsp->brcd_switch;
1574a36c61f9SKrishna Gudipati 		lps->fcf_mac	= rsp->fcf_mac;
1575a36c61f9SKrishna Gudipati 
1576a36c61f9SKrishna Gudipati 		break;
1577a36c61f9SKrishna Gudipati 
1578a36c61f9SKrishna Gudipati 	case BFA_STATUS_FABRIC_RJT:
1579a36c61f9SKrishna Gudipati 		lps->lsrjt_rsn = rsp->lsrjt_rsn;
1580a36c61f9SKrishna Gudipati 		lps->lsrjt_expl = rsp->lsrjt_expl;
1581a36c61f9SKrishna Gudipati 
1582a36c61f9SKrishna Gudipati 		break;
1583a36c61f9SKrishna Gudipati 
1584a36c61f9SKrishna Gudipati 	case BFA_STATUS_EPROTOCOL:
1585a36c61f9SKrishna Gudipati 		lps->ext_status = rsp->ext_status;
1586a36c61f9SKrishna Gudipati 
1587a36c61f9SKrishna Gudipati 		break;
1588a36c61f9SKrishna Gudipati 
1589a36c61f9SKrishna Gudipati 	default:
1590a36c61f9SKrishna Gudipati 		/* Nothing to do with other status */
1591a36c61f9SKrishna Gudipati 		break;
1592a36c61f9SKrishna Gudipati 	}
1593a36c61f9SKrishna Gudipati 
1594a36c61f9SKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
1595a36c61f9SKrishna Gudipati }
1596a36c61f9SKrishna Gudipati 
15975fbe25c7SJing Huang /*
1598a36c61f9SKrishna Gudipati  * Firmware logout response
1599a36c61f9SKrishna Gudipati  */
1600a36c61f9SKrishna Gudipati static void
1601a36c61f9SKrishna Gudipati bfa_lps_logout_rsp(struct bfa_s *bfa, struct bfi_lps_logout_rsp_s *rsp)
1602a36c61f9SKrishna Gudipati {
1603a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
1604a36c61f9SKrishna Gudipati 	struct bfa_lps_s	*lps;
1605a36c61f9SKrishna Gudipati 
1606d4b671c5SJing Huang 	WARN_ON(rsp->lp_tag >= mod->num_lps);
1607a36c61f9SKrishna Gudipati 	lps = BFA_LPS_FROM_TAG(mod, rsp->lp_tag);
1608a36c61f9SKrishna Gudipati 
1609a36c61f9SKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_FWRSP);
1610a36c61f9SKrishna Gudipati }
1611a36c61f9SKrishna Gudipati 
16125fbe25c7SJing Huang /*
1613a36c61f9SKrishna Gudipati  * Firmware received a Clear virtual link request (for FCoE)
1614a36c61f9SKrishna Gudipati  */
1615a36c61f9SKrishna Gudipati static void
1616a36c61f9SKrishna Gudipati bfa_lps_rx_cvl_event(struct bfa_s *bfa, struct bfi_lps_cvl_event_s *cvl)
1617a36c61f9SKrishna Gudipati {
1618a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
1619a36c61f9SKrishna Gudipati 	struct bfa_lps_s	*lps;
1620a36c61f9SKrishna Gudipati 
1621a36c61f9SKrishna Gudipati 	lps = BFA_LPS_FROM_TAG(mod, cvl->lp_tag);
1622a36c61f9SKrishna Gudipati 
1623a36c61f9SKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_RX_CVL);
1624a36c61f9SKrishna Gudipati }
1625a36c61f9SKrishna Gudipati 
16265fbe25c7SJing Huang /*
1627a36c61f9SKrishna Gudipati  * Space is available in request queue, resume queueing request to firmware.
1628a36c61f9SKrishna Gudipati  */
1629a36c61f9SKrishna Gudipati static void
1630a36c61f9SKrishna Gudipati bfa_lps_reqq_resume(void *lps_arg)
1631a36c61f9SKrishna Gudipati {
1632a36c61f9SKrishna Gudipati 	struct bfa_lps_s	*lps = lps_arg;
1633a36c61f9SKrishna Gudipati 
1634a36c61f9SKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_RESUME);
1635a36c61f9SKrishna Gudipati }
1636a36c61f9SKrishna Gudipati 
16375fbe25c7SJing Huang /*
1638a36c61f9SKrishna Gudipati  * lps is freed -- triggered by vport delete
1639a36c61f9SKrishna Gudipati  */
1640a36c61f9SKrishna Gudipati static void
1641a36c61f9SKrishna Gudipati bfa_lps_free(struct bfa_lps_s *lps)
1642a36c61f9SKrishna Gudipati {
1643a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(lps->bfa);
1644a36c61f9SKrishna Gudipati 
1645a36c61f9SKrishna Gudipati 	lps->lp_pid = 0;
1646a36c61f9SKrishna Gudipati 	list_del(&lps->qe);
1647a36c61f9SKrishna Gudipati 	list_add_tail(&lps->qe, &mod->lps_free_q);
1648a36c61f9SKrishna Gudipati }
1649a36c61f9SKrishna Gudipati 
16505fbe25c7SJing Huang /*
1651a36c61f9SKrishna Gudipati  * send login request to firmware
1652a36c61f9SKrishna Gudipati  */
1653a36c61f9SKrishna Gudipati static void
1654a36c61f9SKrishna Gudipati bfa_lps_send_login(struct bfa_lps_s *lps)
1655a36c61f9SKrishna Gudipati {
1656a36c61f9SKrishna Gudipati 	struct bfi_lps_login_req_s	*m;
1657a36c61f9SKrishna Gudipati 
1658a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(lps->bfa, lps->reqq);
1659d4b671c5SJing Huang 	WARN_ON(!m);
1660a36c61f9SKrishna Gudipati 
1661a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_LOGIN_REQ,
1662a36c61f9SKrishna Gudipati 		bfa_lpuid(lps->bfa));
1663a36c61f9SKrishna Gudipati 
1664a36c61f9SKrishna Gudipati 	m->lp_tag	= lps->lp_tag;
1665a36c61f9SKrishna Gudipati 	m->alpa		= lps->alpa;
1666ba816ea8SJing Huang 	m->pdu_size	= cpu_to_be16(lps->pdusz);
1667a36c61f9SKrishna Gudipati 	m->pwwn		= lps->pwwn;
1668a36c61f9SKrishna Gudipati 	m->nwwn		= lps->nwwn;
1669a36c61f9SKrishna Gudipati 	m->fdisc	= lps->fdisc;
1670a36c61f9SKrishna Gudipati 	m->auth_en	= lps->auth_en;
1671a36c61f9SKrishna Gudipati 
1672a36c61f9SKrishna Gudipati 	bfa_reqq_produce(lps->bfa, lps->reqq);
1673a36c61f9SKrishna Gudipati }
1674a36c61f9SKrishna Gudipati 
16755fbe25c7SJing Huang /*
1676a36c61f9SKrishna Gudipati  * send logout request to firmware
1677a36c61f9SKrishna Gudipati  */
1678a36c61f9SKrishna Gudipati static void
1679a36c61f9SKrishna Gudipati bfa_lps_send_logout(struct bfa_lps_s *lps)
1680a36c61f9SKrishna Gudipati {
1681a36c61f9SKrishna Gudipati 	struct bfi_lps_logout_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_LOGOUT_REQ,
1687a36c61f9SKrishna Gudipati 		bfa_lpuid(lps->bfa));
1688a36c61f9SKrishna Gudipati 
1689a36c61f9SKrishna Gudipati 	m->lp_tag    = lps->lp_tag;
1690a36c61f9SKrishna Gudipati 	m->port_name = lps->pwwn;
1691a36c61f9SKrishna Gudipati 	bfa_reqq_produce(lps->bfa, lps->reqq);
1692a36c61f9SKrishna Gudipati }
1693a36c61f9SKrishna Gudipati 
16948f4bfaddSJing Huang /*
1695b704495cSKrishna Gudipati  * send n2n pid set request to firmware
1696b704495cSKrishna Gudipati  */
1697b704495cSKrishna Gudipati static void
1698b704495cSKrishna Gudipati bfa_lps_send_set_n2n_pid(struct bfa_lps_s *lps)
1699b704495cSKrishna Gudipati {
1700b704495cSKrishna Gudipati 	struct bfi_lps_n2n_pid_req_s *m;
1701b704495cSKrishna Gudipati 
1702b704495cSKrishna Gudipati 	m = bfa_reqq_next(lps->bfa, lps->reqq);
1703d4b671c5SJing Huang 	WARN_ON(!m);
1704b704495cSKrishna Gudipati 
1705b704495cSKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_LPS, BFI_LPS_H2I_N2N_PID_REQ,
1706b704495cSKrishna Gudipati 		bfa_lpuid(lps->bfa));
1707b704495cSKrishna Gudipati 
1708b704495cSKrishna Gudipati 	m->lp_tag = lps->lp_tag;
1709b704495cSKrishna Gudipati 	m->lp_pid = lps->lp_pid;
1710b704495cSKrishna Gudipati 	bfa_reqq_produce(lps->bfa, lps->reqq);
1711b704495cSKrishna Gudipati }
1712b704495cSKrishna Gudipati 
17135fbe25c7SJing Huang /*
1714a36c61f9SKrishna Gudipati  * Indirect login completion handler for non-fcs
1715a36c61f9SKrishna Gudipati  */
1716a36c61f9SKrishna Gudipati static void
1717a36c61f9SKrishna Gudipati bfa_lps_login_comp_cb(void *arg, bfa_boolean_t complete)
1718a36c61f9SKrishna Gudipati {
1719a36c61f9SKrishna Gudipati 	struct bfa_lps_s *lps	= arg;
1720a36c61f9SKrishna Gudipati 
1721a36c61f9SKrishna Gudipati 	if (!complete)
1722a36c61f9SKrishna Gudipati 		return;
1723a36c61f9SKrishna Gudipati 
1724a36c61f9SKrishna Gudipati 	if (lps->fdisc)
1725a36c61f9SKrishna Gudipati 		bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status);
1726a36c61f9SKrishna Gudipati 	else
1727a36c61f9SKrishna Gudipati 		bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status);
1728a36c61f9SKrishna Gudipati }
1729a36c61f9SKrishna Gudipati 
17305fbe25c7SJing Huang /*
1731a36c61f9SKrishna Gudipati  * Login completion handler -- direct call for fcs, queue for others
1732a36c61f9SKrishna Gudipati  */
1733a36c61f9SKrishna Gudipati static void
1734a36c61f9SKrishna Gudipati bfa_lps_login_comp(struct bfa_lps_s *lps)
1735a36c61f9SKrishna Gudipati {
1736a36c61f9SKrishna Gudipati 	if (!lps->bfa->fcs) {
1737a36c61f9SKrishna Gudipati 		bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_login_comp_cb,
1738a36c61f9SKrishna Gudipati 			lps);
1739a36c61f9SKrishna Gudipati 		return;
1740a36c61f9SKrishna Gudipati 	}
1741a36c61f9SKrishna Gudipati 
1742a36c61f9SKrishna Gudipati 	if (lps->fdisc)
1743a36c61f9SKrishna Gudipati 		bfa_cb_lps_fdisc_comp(lps->bfa->bfad, lps->uarg, lps->status);
1744a36c61f9SKrishna Gudipati 	else
1745a36c61f9SKrishna Gudipati 		bfa_cb_lps_flogi_comp(lps->bfa->bfad, lps->uarg, lps->status);
1746a36c61f9SKrishna Gudipati }
1747a36c61f9SKrishna Gudipati 
17485fbe25c7SJing Huang /*
1749a36c61f9SKrishna Gudipati  * Indirect logout completion handler for non-fcs
1750a36c61f9SKrishna Gudipati  */
1751a36c61f9SKrishna Gudipati static void
1752a36c61f9SKrishna Gudipati bfa_lps_logout_comp_cb(void *arg, bfa_boolean_t complete)
1753a36c61f9SKrishna Gudipati {
1754a36c61f9SKrishna Gudipati 	struct bfa_lps_s *lps	= arg;
1755a36c61f9SKrishna Gudipati 
1756a36c61f9SKrishna Gudipati 	if (!complete)
1757a36c61f9SKrishna Gudipati 		return;
1758a36c61f9SKrishna Gudipati 
1759a36c61f9SKrishna Gudipati 	if (lps->fdisc)
1760a36c61f9SKrishna Gudipati 		bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg);
1761a36c61f9SKrishna Gudipati }
1762a36c61f9SKrishna Gudipati 
17635fbe25c7SJing Huang /*
1764a36c61f9SKrishna Gudipati  * Logout completion handler -- direct call for fcs, queue for others
1765a36c61f9SKrishna Gudipati  */
1766a36c61f9SKrishna Gudipati static void
1767a36c61f9SKrishna Gudipati bfa_lps_logout_comp(struct bfa_lps_s *lps)
1768a36c61f9SKrishna Gudipati {
1769a36c61f9SKrishna Gudipati 	if (!lps->bfa->fcs) {
1770a36c61f9SKrishna Gudipati 		bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_logout_comp_cb,
1771a36c61f9SKrishna Gudipati 			lps);
1772a36c61f9SKrishna Gudipati 		return;
1773a36c61f9SKrishna Gudipati 	}
1774a36c61f9SKrishna Gudipati 	if (lps->fdisc)
1775a36c61f9SKrishna Gudipati 		bfa_cb_lps_fdisclogo_comp(lps->bfa->bfad, lps->uarg);
1776a36c61f9SKrishna Gudipati }
1777a36c61f9SKrishna Gudipati 
17785fbe25c7SJing Huang /*
1779a36c61f9SKrishna Gudipati  * Clear virtual link completion handler for non-fcs
1780a36c61f9SKrishna Gudipati  */
1781a36c61f9SKrishna Gudipati static void
1782a36c61f9SKrishna Gudipati bfa_lps_cvl_event_cb(void *arg, bfa_boolean_t complete)
1783a36c61f9SKrishna Gudipati {
1784a36c61f9SKrishna Gudipati 	struct bfa_lps_s *lps	= arg;
1785a36c61f9SKrishna Gudipati 
1786a36c61f9SKrishna Gudipati 	if (!complete)
1787a36c61f9SKrishna Gudipati 		return;
1788a36c61f9SKrishna Gudipati 
1789a36c61f9SKrishna Gudipati 	/* Clear virtual link to base port will result in link down */
1790a36c61f9SKrishna Gudipati 	if (lps->fdisc)
1791a36c61f9SKrishna Gudipati 		bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
1792a36c61f9SKrishna Gudipati }
1793a36c61f9SKrishna Gudipati 
17945fbe25c7SJing Huang /*
1795a36c61f9SKrishna Gudipati  * Received Clear virtual link event --direct call for fcs,
1796a36c61f9SKrishna Gudipati  * queue for others
1797a36c61f9SKrishna Gudipati  */
1798a36c61f9SKrishna Gudipati static void
1799a36c61f9SKrishna Gudipati bfa_lps_cvl_event(struct bfa_lps_s *lps)
1800a36c61f9SKrishna Gudipati {
1801a36c61f9SKrishna Gudipati 	if (!lps->bfa->fcs) {
1802a36c61f9SKrishna Gudipati 		bfa_cb_queue(lps->bfa, &lps->hcb_qe, bfa_lps_cvl_event_cb,
1803a36c61f9SKrishna Gudipati 			lps);
1804a36c61f9SKrishna Gudipati 		return;
1805a36c61f9SKrishna Gudipati 	}
1806a36c61f9SKrishna Gudipati 
1807a36c61f9SKrishna Gudipati 	/* Clear virtual link to base port will result in link down */
1808a36c61f9SKrishna Gudipati 	if (lps->fdisc)
1809a36c61f9SKrishna Gudipati 		bfa_cb_lps_cvl_event(lps->bfa->bfad, lps->uarg);
1810a36c61f9SKrishna Gudipati }
1811a36c61f9SKrishna Gudipati 
1812a36c61f9SKrishna Gudipati 
1813a36c61f9SKrishna Gudipati 
18145fbe25c7SJing Huang /*
1815a36c61f9SKrishna Gudipati  *  lps_public BFA LPS public functions
1816a36c61f9SKrishna Gudipati  */
1817a36c61f9SKrishna Gudipati 
1818a36c61f9SKrishna Gudipati u32
1819a36c61f9SKrishna Gudipati bfa_lps_get_max_vport(struct bfa_s *bfa)
1820a36c61f9SKrishna Gudipati {
1821a36c61f9SKrishna Gudipati 	if (bfa_ioc_devid(&bfa->ioc) == BFA_PCI_DEVICE_ID_CT)
1822a36c61f9SKrishna Gudipati 		return BFA_LPS_MAX_VPORTS_SUPP_CT;
1823a36c61f9SKrishna Gudipati 	else
1824a36c61f9SKrishna Gudipati 		return BFA_LPS_MAX_VPORTS_SUPP_CB;
1825a36c61f9SKrishna Gudipati }
1826a36c61f9SKrishna Gudipati 
18275fbe25c7SJing Huang /*
1828a36c61f9SKrishna Gudipati  * Allocate a lport srvice tag.
1829a36c61f9SKrishna Gudipati  */
1830a36c61f9SKrishna Gudipati struct bfa_lps_s  *
1831a36c61f9SKrishna Gudipati bfa_lps_alloc(struct bfa_s *bfa)
1832a36c61f9SKrishna Gudipati {
1833a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
1834a36c61f9SKrishna Gudipati 	struct bfa_lps_s	*lps = NULL;
1835a36c61f9SKrishna Gudipati 
1836a36c61f9SKrishna Gudipati 	bfa_q_deq(&mod->lps_free_q, &lps);
1837a36c61f9SKrishna Gudipati 
1838a36c61f9SKrishna Gudipati 	if (lps == NULL)
1839a36c61f9SKrishna Gudipati 		return NULL;
1840a36c61f9SKrishna Gudipati 
1841a36c61f9SKrishna Gudipati 	list_add_tail(&lps->qe, &mod->lps_active_q);
1842a36c61f9SKrishna Gudipati 
1843a36c61f9SKrishna Gudipati 	bfa_sm_set_state(lps, bfa_lps_sm_init);
1844a36c61f9SKrishna Gudipati 	return lps;
1845a36c61f9SKrishna Gudipati }
1846a36c61f9SKrishna Gudipati 
18475fbe25c7SJing Huang /*
1848a36c61f9SKrishna Gudipati  * Free lport service tag. This can be called anytime after an alloc.
1849a36c61f9SKrishna Gudipati  * No need to wait for any pending login/logout completions.
1850a36c61f9SKrishna Gudipati  */
1851a36c61f9SKrishna Gudipati void
1852a36c61f9SKrishna Gudipati bfa_lps_delete(struct bfa_lps_s *lps)
1853a36c61f9SKrishna Gudipati {
1854a36c61f9SKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_DELETE);
1855a36c61f9SKrishna Gudipati }
1856a36c61f9SKrishna Gudipati 
18575fbe25c7SJing Huang /*
1858a36c61f9SKrishna Gudipati  * Initiate a lport login.
1859a36c61f9SKrishna Gudipati  */
1860a36c61f9SKrishna Gudipati void
1861a36c61f9SKrishna Gudipati bfa_lps_flogi(struct bfa_lps_s *lps, void *uarg, u8 alpa, u16 pdusz,
1862a36c61f9SKrishna Gudipati 	wwn_t pwwn, wwn_t nwwn, bfa_boolean_t auth_en)
1863a36c61f9SKrishna Gudipati {
1864a36c61f9SKrishna Gudipati 	lps->uarg	= uarg;
1865a36c61f9SKrishna Gudipati 	lps->alpa	= alpa;
1866a36c61f9SKrishna Gudipati 	lps->pdusz	= pdusz;
1867a36c61f9SKrishna Gudipati 	lps->pwwn	= pwwn;
1868a36c61f9SKrishna Gudipati 	lps->nwwn	= nwwn;
1869a36c61f9SKrishna Gudipati 	lps->fdisc	= BFA_FALSE;
1870a36c61f9SKrishna Gudipati 	lps->auth_en	= auth_en;
1871a36c61f9SKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN);
1872a36c61f9SKrishna Gudipati }
1873a36c61f9SKrishna Gudipati 
18745fbe25c7SJing Huang /*
1875a36c61f9SKrishna Gudipati  * Initiate a lport fdisc login.
1876a36c61f9SKrishna Gudipati  */
1877a36c61f9SKrishna Gudipati void
1878a36c61f9SKrishna Gudipati bfa_lps_fdisc(struct bfa_lps_s *lps, void *uarg, u16 pdusz, wwn_t pwwn,
1879a36c61f9SKrishna Gudipati 	wwn_t nwwn)
1880a36c61f9SKrishna Gudipati {
1881a36c61f9SKrishna Gudipati 	lps->uarg	= uarg;
1882a36c61f9SKrishna Gudipati 	lps->alpa	= 0;
1883a36c61f9SKrishna Gudipati 	lps->pdusz	= pdusz;
1884a36c61f9SKrishna Gudipati 	lps->pwwn	= pwwn;
1885a36c61f9SKrishna Gudipati 	lps->nwwn	= nwwn;
1886a36c61f9SKrishna Gudipati 	lps->fdisc	= BFA_TRUE;
1887a36c61f9SKrishna Gudipati 	lps->auth_en	= BFA_FALSE;
1888a36c61f9SKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_LOGIN);
1889a36c61f9SKrishna Gudipati }
1890a36c61f9SKrishna Gudipati 
1891a36c61f9SKrishna Gudipati 
18925fbe25c7SJing Huang /*
1893a36c61f9SKrishna Gudipati  * Initiate a lport FDSIC logout.
1894a36c61f9SKrishna Gudipati  */
1895a36c61f9SKrishna Gudipati void
1896a36c61f9SKrishna Gudipati bfa_lps_fdisclogo(struct bfa_lps_s *lps)
1897a36c61f9SKrishna Gudipati {
1898a36c61f9SKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_LOGOUT);
1899a36c61f9SKrishna Gudipati }
1900a36c61f9SKrishna Gudipati 
1901a36c61f9SKrishna Gudipati 
19025fbe25c7SJing Huang /*
1903a36c61f9SKrishna Gudipati  * Return lport services tag given the pid
1904a36c61f9SKrishna Gudipati  */
1905a36c61f9SKrishna Gudipati u8
1906a36c61f9SKrishna Gudipati bfa_lps_get_tag_from_pid(struct bfa_s *bfa, u32 pid)
1907a36c61f9SKrishna Gudipati {
1908a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
1909a36c61f9SKrishna Gudipati 	struct bfa_lps_s	*lps;
1910a36c61f9SKrishna Gudipati 	int			i;
1911a36c61f9SKrishna Gudipati 
1912a36c61f9SKrishna Gudipati 	for (i = 0, lps = mod->lps_arr; i < mod->num_lps; i++, lps++) {
1913a36c61f9SKrishna Gudipati 		if (lps->lp_pid == pid)
1914a36c61f9SKrishna Gudipati 			return lps->lp_tag;
1915a36c61f9SKrishna Gudipati 	}
1916a36c61f9SKrishna Gudipati 
1917a36c61f9SKrishna Gudipati 	/* Return base port tag anyway */
1918a36c61f9SKrishna Gudipati 	return 0;
1919a36c61f9SKrishna Gudipati }
1920a36c61f9SKrishna Gudipati 
1921a36c61f9SKrishna Gudipati 
19225fbe25c7SJing Huang /*
1923a36c61f9SKrishna Gudipati  * return port id assigned to the base lport
1924a36c61f9SKrishna Gudipati  */
1925a36c61f9SKrishna Gudipati u32
1926a36c61f9SKrishna Gudipati bfa_lps_get_base_pid(struct bfa_s *bfa)
1927a36c61f9SKrishna Gudipati {
1928a36c61f9SKrishna Gudipati 	struct bfa_lps_mod_s	*mod = BFA_LPS_MOD(bfa);
1929a36c61f9SKrishna Gudipati 
1930a36c61f9SKrishna Gudipati 	return BFA_LPS_FROM_TAG(mod, 0)->lp_pid;
1931a36c61f9SKrishna Gudipati }
1932a36c61f9SKrishna Gudipati 
19338f4bfaddSJing Huang /*
1934b704495cSKrishna Gudipati  * Set PID in case of n2n (which is assigned during PLOGI)
1935b704495cSKrishna Gudipati  */
1936b704495cSKrishna Gudipati void
1937b704495cSKrishna Gudipati bfa_lps_set_n2n_pid(struct bfa_lps_s *lps, uint32_t n2n_pid)
1938b704495cSKrishna Gudipati {
1939b704495cSKrishna Gudipati 	bfa_trc(lps->bfa, lps->lp_tag);
1940b704495cSKrishna Gudipati 	bfa_trc(lps->bfa, n2n_pid);
1941b704495cSKrishna Gudipati 
1942b704495cSKrishna Gudipati 	lps->lp_pid = n2n_pid;
1943b704495cSKrishna Gudipati 	bfa_sm_send_event(lps, BFA_LPS_SM_SET_N2N_PID);
1944b704495cSKrishna Gudipati }
1945b704495cSKrishna Gudipati 
19465fbe25c7SJing Huang /*
1947a36c61f9SKrishna Gudipati  * LPS firmware message class handler.
1948a36c61f9SKrishna Gudipati  */
1949a36c61f9SKrishna Gudipati void
1950a36c61f9SKrishna Gudipati bfa_lps_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
1951a36c61f9SKrishna Gudipati {
1952a36c61f9SKrishna Gudipati 	union bfi_lps_i2h_msg_u	msg;
1953a36c61f9SKrishna Gudipati 
1954a36c61f9SKrishna Gudipati 	bfa_trc(bfa, m->mhdr.msg_id);
1955a36c61f9SKrishna Gudipati 	msg.msg = m;
1956a36c61f9SKrishna Gudipati 
1957a36c61f9SKrishna Gudipati 	switch (m->mhdr.msg_id) {
1958a36c61f9SKrishna Gudipati 	case BFI_LPS_H2I_LOGIN_RSP:
1959a36c61f9SKrishna Gudipati 		bfa_lps_login_rsp(bfa, msg.login_rsp);
1960a36c61f9SKrishna Gudipati 		break;
1961a36c61f9SKrishna Gudipati 
1962a36c61f9SKrishna Gudipati 	case BFI_LPS_H2I_LOGOUT_RSP:
1963a36c61f9SKrishna Gudipati 		bfa_lps_logout_rsp(bfa, msg.logout_rsp);
1964a36c61f9SKrishna Gudipati 		break;
1965a36c61f9SKrishna Gudipati 
1966a36c61f9SKrishna Gudipati 	case BFI_LPS_H2I_CVL_EVENT:
1967a36c61f9SKrishna Gudipati 		bfa_lps_rx_cvl_event(bfa, msg.cvl_event);
1968a36c61f9SKrishna Gudipati 		break;
1969a36c61f9SKrishna Gudipati 
1970a36c61f9SKrishna Gudipati 	default:
1971a36c61f9SKrishna Gudipati 		bfa_trc(bfa, m->mhdr.msg_id);
1972d4b671c5SJing Huang 		WARN_ON(1);
1973a36c61f9SKrishna Gudipati 	}
1974a36c61f9SKrishna Gudipati }
1975a36c61f9SKrishna Gudipati 
19765fbe25c7SJing Huang /*
1977a36c61f9SKrishna Gudipati  * FC PORT state machine functions
1978a36c61f9SKrishna Gudipati  */
1979a36c61f9SKrishna Gudipati static void
1980a36c61f9SKrishna Gudipati bfa_fcport_sm_uninit(struct bfa_fcport_s *fcport,
1981a36c61f9SKrishna Gudipati 			enum bfa_fcport_sm_event event)
1982a36c61f9SKrishna Gudipati {
1983a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
1984a36c61f9SKrishna Gudipati 
1985a36c61f9SKrishna Gudipati 	switch (event) {
1986a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_START:
19875fbe25c7SJing Huang 		/*
1988a36c61f9SKrishna Gudipati 		 * Start event after IOC is configured and BFA is started.
1989a36c61f9SKrishna Gudipati 		 */
1990f3a060caSKrishna Gudipati 		fcport->use_flash_cfg = BFA_TRUE;
1991f3a060caSKrishna Gudipati 
1992a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_enable(fcport)) {
1993a36c61f9SKrishna Gudipati 			bfa_trc(fcport->bfa, BFA_TRUE);
1994a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
1995a36c61f9SKrishna Gudipati 		} else {
1996a36c61f9SKrishna Gudipati 			bfa_trc(fcport->bfa, BFA_FALSE);
1997a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
1998a36c61f9SKrishna Gudipati 					bfa_fcport_sm_enabling_qwait);
1999a36c61f9SKrishna Gudipati 		}
2000a36c61f9SKrishna Gudipati 		break;
2001a36c61f9SKrishna Gudipati 
2002a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
20035fbe25c7SJing Huang 		/*
2004a36c61f9SKrishna Gudipati 		 * Port is persistently configured to be in enabled state. Do
2005a36c61f9SKrishna Gudipati 		 * not change state. Port enabling is done when START event is
2006a36c61f9SKrishna Gudipati 		 * received.
2007a36c61f9SKrishna Gudipati 		 */
2008a36c61f9SKrishna Gudipati 		break;
2009a36c61f9SKrishna Gudipati 
2010a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
20115fbe25c7SJing Huang 		/*
2012a36c61f9SKrishna Gudipati 		 * If a port is persistently configured to be disabled, the
2013a36c61f9SKrishna Gudipati 		 * first event will a port disable request.
2014a36c61f9SKrishna Gudipati 		 */
2015a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
2016a36c61f9SKrishna Gudipati 		break;
2017a36c61f9SKrishna Gudipati 
2018a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2019a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
2020a36c61f9SKrishna Gudipati 		break;
2021a36c61f9SKrishna Gudipati 
2022a36c61f9SKrishna Gudipati 	default:
2023a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2024a36c61f9SKrishna Gudipati 	}
2025a36c61f9SKrishna Gudipati }
2026a36c61f9SKrishna Gudipati 
2027a36c61f9SKrishna Gudipati static void
2028a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport,
2029a36c61f9SKrishna Gudipati 				enum bfa_fcport_sm_event event)
2030a36c61f9SKrishna Gudipati {
2031a36c61f9SKrishna Gudipati 	char pwwn_buf[BFA_STRING_32];
2032a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad;
2033a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2034a36c61f9SKrishna Gudipati 
2035a36c61f9SKrishna Gudipati 	switch (event) {
2036a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_QRESUME:
2037a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
2038a36c61f9SKrishna Gudipati 		bfa_fcport_send_enable(fcport);
2039a36c61f9SKrishna Gudipati 		break;
2040a36c61f9SKrishna Gudipati 
2041a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_STOP:
2042a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->reqq_wait);
2043a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2044a36c61f9SKrishna Gudipati 		break;
2045a36c61f9SKrishna Gudipati 
2046a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
20475fbe25c7SJing Huang 		/*
2048a36c61f9SKrishna Gudipati 		 * Already enable is in progress.
2049a36c61f9SKrishna Gudipati 		 */
2050a36c61f9SKrishna Gudipati 		break;
2051a36c61f9SKrishna Gudipati 
2052a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
20535fbe25c7SJing Huang 		/*
2054a36c61f9SKrishna Gudipati 		 * Just send disable request to firmware when room becomes
2055a36c61f9SKrishna Gudipati 		 * available in request queue.
2056a36c61f9SKrishna Gudipati 		 */
2057a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
2058a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->reqq_wait);
2059a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2060a36c61f9SKrishna Gudipati 				BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
2061a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
206288166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2063a36c61f9SKrishna Gudipati 			"Base port disabled: WWN = %s\n", pwwn_buf);
2064a36c61f9SKrishna Gudipati 		break;
2065a36c61f9SKrishna Gudipati 
2066a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKUP:
2067a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKDOWN:
20685fbe25c7SJing Huang 		/*
2069a36c61f9SKrishna Gudipati 		 * Possible to get link events when doing back-to-back
2070a36c61f9SKrishna Gudipati 		 * enable/disables.
2071a36c61f9SKrishna Gudipati 		 */
2072a36c61f9SKrishna Gudipati 		break;
2073a36c61f9SKrishna Gudipati 
2074a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2075a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->reqq_wait);
2076a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
2077a36c61f9SKrishna Gudipati 		break;
2078a36c61f9SKrishna Gudipati 
2079a36c61f9SKrishna Gudipati 	default:
2080a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2081a36c61f9SKrishna Gudipati 	}
2082a36c61f9SKrishna Gudipati }
2083a36c61f9SKrishna Gudipati 
2084a36c61f9SKrishna Gudipati static void
2085a36c61f9SKrishna Gudipati bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport,
2086a36c61f9SKrishna Gudipati 						enum bfa_fcport_sm_event event)
2087a36c61f9SKrishna Gudipati {
2088a36c61f9SKrishna Gudipati 	char pwwn_buf[BFA_STRING_32];
2089a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad;
2090a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2091a36c61f9SKrishna Gudipati 
2092a36c61f9SKrishna Gudipati 	switch (event) {
2093a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_FWRSP:
2094a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKDOWN:
2095a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
2096a36c61f9SKrishna Gudipati 		break;
2097a36c61f9SKrishna Gudipati 
2098a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKUP:
2099a36c61f9SKrishna Gudipati 		bfa_fcport_update_linkinfo(fcport);
2100a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
2101a36c61f9SKrishna Gudipati 
2102d4b671c5SJing Huang 		WARN_ON(!fcport->event_cbfn);
2103a36c61f9SKrishna Gudipati 		bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE);
2104a36c61f9SKrishna Gudipati 		break;
2105a36c61f9SKrishna Gudipati 
2106a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
21075fbe25c7SJing Huang 		/*
2108a36c61f9SKrishna Gudipati 		 * Already being enabled.
2109a36c61f9SKrishna Gudipati 		 */
2110a36c61f9SKrishna Gudipati 		break;
2111a36c61f9SKrishna Gudipati 
2112a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
2113a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_disable(fcport))
2114a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
2115a36c61f9SKrishna Gudipati 		else
2116a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2117a36c61f9SKrishna Gudipati 					 bfa_fcport_sm_disabling_qwait);
2118a36c61f9SKrishna Gudipati 
2119a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2120a36c61f9SKrishna Gudipati 				BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
2121a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
212288166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2123a36c61f9SKrishna Gudipati 			"Base port disabled: WWN = %s\n", pwwn_buf);
2124a36c61f9SKrishna Gudipati 		break;
2125a36c61f9SKrishna Gudipati 
2126a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_STOP:
2127a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2128a36c61f9SKrishna Gudipati 		break;
2129a36c61f9SKrishna Gudipati 
2130a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
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_linkdown(struct bfa_fcport_s *fcport,
2141a36c61f9SKrishna Gudipati 						enum bfa_fcport_sm_event event)
2142a36c61f9SKrishna Gudipati {
2143a36c61f9SKrishna Gudipati 	struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
2144a36c61f9SKrishna Gudipati 	char pwwn_buf[BFA_STRING_32];
2145a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad;
2146a36c61f9SKrishna Gudipati 
2147a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2148a36c61f9SKrishna Gudipati 
2149a36c61f9SKrishna Gudipati 	switch (event) {
2150a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKUP:
2151a36c61f9SKrishna Gudipati 		bfa_fcport_update_linkinfo(fcport);
2152a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_linkup);
2153d4b671c5SJing Huang 		WARN_ON(!fcport->event_cbfn);
2154a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2155a36c61f9SKrishna Gudipati 				BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkup");
2156a36c61f9SKrishna Gudipati 		if (!bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
2157a36c61f9SKrishna Gudipati 
2158a36c61f9SKrishna Gudipati 			bfa_trc(fcport->bfa,
2159a36c61f9SKrishna Gudipati 				pevent->link_state.vc_fcf.fcf.fipenabled);
2160a36c61f9SKrishna Gudipati 			bfa_trc(fcport->bfa,
2161a36c61f9SKrishna Gudipati 				pevent->link_state.vc_fcf.fcf.fipfailed);
2162a36c61f9SKrishna Gudipati 
2163a36c61f9SKrishna Gudipati 			if (pevent->link_state.vc_fcf.fcf.fipfailed)
2164a36c61f9SKrishna Gudipati 				bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2165a36c61f9SKrishna Gudipati 					BFA_PL_EID_FIP_FCF_DISC, 0,
2166a36c61f9SKrishna Gudipati 					"FIP FCF Discovery Failed");
2167a36c61f9SKrishna Gudipati 			else
2168a36c61f9SKrishna Gudipati 				bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2169a36c61f9SKrishna Gudipati 					BFA_PL_EID_FIP_FCF_DISC, 0,
2170a36c61f9SKrishna Gudipati 					"FIP FCF Discovered");
2171a36c61f9SKrishna Gudipati 		}
2172a36c61f9SKrishna Gudipati 
2173a36c61f9SKrishna Gudipati 		bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE);
2174a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
217588166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2176a36c61f9SKrishna Gudipati 			"Base port online: WWN = %s\n", pwwn_buf);
2177a36c61f9SKrishna Gudipati 		break;
2178a36c61f9SKrishna Gudipati 
2179a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKDOWN:
21805fbe25c7SJing Huang 		/*
2181a36c61f9SKrishna Gudipati 		 * Possible to get link down event.
2182a36c61f9SKrishna Gudipati 		 */
2183a36c61f9SKrishna Gudipati 		break;
2184a36c61f9SKrishna Gudipati 
2185a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
21865fbe25c7SJing Huang 		/*
2187a36c61f9SKrishna Gudipati 		 * Already enabled.
2188a36c61f9SKrishna Gudipati 		 */
2189a36c61f9SKrishna Gudipati 		break;
2190a36c61f9SKrishna Gudipati 
2191a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
2192a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_disable(fcport))
2193a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
2194a36c61f9SKrishna Gudipati 		else
2195a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2196a36c61f9SKrishna Gudipati 					 bfa_fcport_sm_disabling_qwait);
2197a36c61f9SKrishna Gudipati 
2198a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2199a36c61f9SKrishna Gudipati 				BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
2200a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
220188166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2202a36c61f9SKrishna Gudipati 			"Base port disabled: WWN = %s\n", pwwn_buf);
2203a36c61f9SKrishna Gudipati 		break;
2204a36c61f9SKrishna Gudipati 
2205a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_STOP:
2206a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2207a36c61f9SKrishna Gudipati 		break;
2208a36c61f9SKrishna Gudipati 
2209a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2210a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
2211a36c61f9SKrishna Gudipati 		break;
2212a36c61f9SKrishna Gudipati 
2213a36c61f9SKrishna Gudipati 	default:
2214a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2215a36c61f9SKrishna Gudipati 	}
2216a36c61f9SKrishna Gudipati }
2217a36c61f9SKrishna Gudipati 
2218a36c61f9SKrishna Gudipati static void
2219a36c61f9SKrishna Gudipati bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport,
2220a36c61f9SKrishna Gudipati 	enum bfa_fcport_sm_event event)
2221a36c61f9SKrishna Gudipati {
2222a36c61f9SKrishna Gudipati 	char pwwn_buf[BFA_STRING_32];
2223a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad;
2224a36c61f9SKrishna Gudipati 
2225a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2226a36c61f9SKrishna Gudipati 
2227a36c61f9SKrishna Gudipati 	switch (event) {
2228a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
22295fbe25c7SJing Huang 		/*
2230a36c61f9SKrishna Gudipati 		 * Already enabled.
2231a36c61f9SKrishna Gudipati 		 */
2232a36c61f9SKrishna Gudipati 		break;
2233a36c61f9SKrishna Gudipati 
2234a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
2235a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_disable(fcport))
2236a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
2237a36c61f9SKrishna Gudipati 		else
2238a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2239a36c61f9SKrishna Gudipati 					 bfa_fcport_sm_disabling_qwait);
2240a36c61f9SKrishna Gudipati 
2241a36c61f9SKrishna Gudipati 		bfa_fcport_reset_linkinfo(fcport);
2242a36c61f9SKrishna Gudipati 		bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE);
2243a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2244a36c61f9SKrishna Gudipati 				BFA_PL_EID_PORT_DISABLE, 0, "Port Disable");
2245a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
224688166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2247a36c61f9SKrishna Gudipati 			"Base port offline: WWN = %s\n", pwwn_buf);
224888166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2249a36c61f9SKrishna Gudipati 			"Base port disabled: WWN = %s\n", pwwn_buf);
2250a36c61f9SKrishna Gudipati 		break;
2251a36c61f9SKrishna Gudipati 
2252a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKDOWN:
2253a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_linkdown);
2254a36c61f9SKrishna Gudipati 		bfa_fcport_reset_linkinfo(fcport);
2255a36c61f9SKrishna Gudipati 		bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE);
2256a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2257a36c61f9SKrishna Gudipati 				BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown");
2258a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
2259a36c61f9SKrishna Gudipati 		if (BFA_PORT_IS_DISABLED(fcport->bfa))
226088166242SJing Huang 			BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2261a36c61f9SKrishna Gudipati 				"Base port offline: WWN = %s\n", pwwn_buf);
2262a36c61f9SKrishna Gudipati 		else
226388166242SJing Huang 			BFA_LOG(KERN_ERR, bfad, bfa_log_level,
2264a36c61f9SKrishna Gudipati 				"Base port (WWN = %s) "
2265a36c61f9SKrishna Gudipati 				"lost fabric connectivity\n", pwwn_buf);
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 		bfa_fcport_reset_linkinfo(fcport);
2271a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
2272a36c61f9SKrishna Gudipati 		if (BFA_PORT_IS_DISABLED(fcport->bfa))
227388166242SJing Huang 			BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2274a36c61f9SKrishna Gudipati 				"Base port offline: WWN = %s\n", pwwn_buf);
2275a36c61f9SKrishna Gudipati 		else
227688166242SJing Huang 			BFA_LOG(KERN_ERR, bfad, bfa_log_level,
2277a36c61f9SKrishna Gudipati 				"Base port (WWN = %s) "
2278a36c61f9SKrishna Gudipati 				"lost fabric connectivity\n", pwwn_buf);
2279a36c61f9SKrishna Gudipati 		break;
2280a36c61f9SKrishna Gudipati 
2281a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2282a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
2283a36c61f9SKrishna Gudipati 		bfa_fcport_reset_linkinfo(fcport);
2284a36c61f9SKrishna Gudipati 		bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE);
2285a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
2286a36c61f9SKrishna Gudipati 		if (BFA_PORT_IS_DISABLED(fcport->bfa))
228788166242SJing Huang 			BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2288a36c61f9SKrishna Gudipati 				"Base port offline: WWN = %s\n", pwwn_buf);
2289a36c61f9SKrishna Gudipati 		else
229088166242SJing Huang 			BFA_LOG(KERN_ERR, bfad, bfa_log_level,
2291a36c61f9SKrishna Gudipati 				"Base port (WWN = %s) "
2292a36c61f9SKrishna Gudipati 				"lost fabric connectivity\n", pwwn_buf);
2293a36c61f9SKrishna Gudipati 		break;
2294a36c61f9SKrishna Gudipati 
2295a36c61f9SKrishna Gudipati 	default:
2296a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2297a36c61f9SKrishna Gudipati 	}
2298a36c61f9SKrishna Gudipati }
2299a36c61f9SKrishna Gudipati 
2300a36c61f9SKrishna Gudipati static void
2301a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling_qwait(struct bfa_fcport_s *fcport,
2302a36c61f9SKrishna Gudipati 				 enum bfa_fcport_sm_event event)
2303a36c61f9SKrishna Gudipati {
2304a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2305a36c61f9SKrishna Gudipati 
2306a36c61f9SKrishna Gudipati 	switch (event) {
2307a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_QRESUME:
2308a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
2309a36c61f9SKrishna Gudipati 		bfa_fcport_send_disable(fcport);
2310a36c61f9SKrishna Gudipati 		break;
2311a36c61f9SKrishna Gudipati 
2312a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_STOP:
2313a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2314a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->reqq_wait);
2315a36c61f9SKrishna Gudipati 		break;
2316a36c61f9SKrishna Gudipati 
2317a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
2318a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_toggling_qwait);
2319a36c61f9SKrishna Gudipati 		break;
2320a36c61f9SKrishna Gudipati 
2321a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
23225fbe25c7SJing Huang 		/*
2323a36c61f9SKrishna Gudipati 		 * Already being disabled.
2324a36c61f9SKrishna Gudipati 		 */
2325a36c61f9SKrishna Gudipati 		break;
2326a36c61f9SKrishna Gudipati 
2327a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKUP:
2328a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKDOWN:
23295fbe25c7SJing Huang 		/*
2330a36c61f9SKrishna Gudipati 		 * Possible to get link events when doing back-to-back
2331a36c61f9SKrishna Gudipati 		 * enable/disables.
2332a36c61f9SKrishna Gudipati 		 */
2333a36c61f9SKrishna Gudipati 		break;
2334a36c61f9SKrishna Gudipati 
2335a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2336a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
2337a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->reqq_wait);
2338a36c61f9SKrishna Gudipati 		break;
2339a36c61f9SKrishna Gudipati 
2340a36c61f9SKrishna Gudipati 	default:
2341a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2342a36c61f9SKrishna Gudipati 	}
2343a36c61f9SKrishna Gudipati }
2344a36c61f9SKrishna Gudipati 
2345a36c61f9SKrishna Gudipati static void
2346a36c61f9SKrishna Gudipati bfa_fcport_sm_toggling_qwait(struct bfa_fcport_s *fcport,
2347a36c61f9SKrishna Gudipati 				 enum bfa_fcport_sm_event event)
2348a36c61f9SKrishna Gudipati {
2349a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2350a36c61f9SKrishna Gudipati 
2351a36c61f9SKrishna Gudipati 	switch (event) {
2352a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_QRESUME:
2353a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_disabling);
2354a36c61f9SKrishna Gudipati 		bfa_fcport_send_disable(fcport);
2355a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_enable(fcport))
2356a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
2357a36c61f9SKrishna Gudipati 		else
2358a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2359a36c61f9SKrishna Gudipati 					 bfa_fcport_sm_enabling_qwait);
2360a36c61f9SKrishna Gudipati 		break;
2361a36c61f9SKrishna Gudipati 
2362a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_STOP:
2363a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2364a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->reqq_wait);
2365a36c61f9SKrishna Gudipati 		break;
2366a36c61f9SKrishna Gudipati 
2367a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
2368a36c61f9SKrishna Gudipati 		break;
2369a36c61f9SKrishna Gudipati 
2370a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
2371a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_disabling_qwait);
2372a36c61f9SKrishna Gudipati 		break;
2373a36c61f9SKrishna Gudipati 
2374a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKUP:
2375a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKDOWN:
23765fbe25c7SJing Huang 		/*
2377a36c61f9SKrishna Gudipati 		 * Possible to get link events when doing back-to-back
2378a36c61f9SKrishna Gudipati 		 * enable/disables.
2379a36c61f9SKrishna Gudipati 		 */
2380a36c61f9SKrishna Gudipati 		break;
2381a36c61f9SKrishna Gudipati 
2382a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2383a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
2384a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->reqq_wait);
2385a36c61f9SKrishna Gudipati 		break;
2386a36c61f9SKrishna Gudipati 
2387a36c61f9SKrishna Gudipati 	default:
2388a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2389a36c61f9SKrishna Gudipati 	}
2390a36c61f9SKrishna Gudipati }
2391a36c61f9SKrishna Gudipati 
2392a36c61f9SKrishna Gudipati static void
2393a36c61f9SKrishna Gudipati bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport,
2394a36c61f9SKrishna Gudipati 						enum bfa_fcport_sm_event event)
2395a36c61f9SKrishna Gudipati {
2396a36c61f9SKrishna Gudipati 	char pwwn_buf[BFA_STRING_32];
2397a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad;
2398a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2399a36c61f9SKrishna Gudipati 
2400a36c61f9SKrishna Gudipati 	switch (event) {
2401a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_FWRSP:
2402a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
2403a36c61f9SKrishna Gudipati 		break;
2404a36c61f9SKrishna Gudipati 
2405a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
24065fbe25c7SJing Huang 		/*
2407a36c61f9SKrishna Gudipati 		 * Already being disabled.
2408a36c61f9SKrishna Gudipati 		 */
2409a36c61f9SKrishna Gudipati 		break;
2410a36c61f9SKrishna Gudipati 
2411a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
2412a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_enable(fcport))
2413a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
2414a36c61f9SKrishna Gudipati 		else
2415a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2416a36c61f9SKrishna Gudipati 					 bfa_fcport_sm_enabling_qwait);
2417a36c61f9SKrishna Gudipati 
2418a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2419a36c61f9SKrishna Gudipati 				BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
2420a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
242188166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2422a36c61f9SKrishna Gudipati 			"Base port enabled: WWN = %s\n", pwwn_buf);
2423a36c61f9SKrishna Gudipati 		break;
2424a36c61f9SKrishna Gudipati 
2425a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_STOP:
2426a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2427a36c61f9SKrishna Gudipati 		break;
2428a36c61f9SKrishna Gudipati 
2429a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKUP:
2430a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_LINKDOWN:
24315fbe25c7SJing Huang 		/*
2432a36c61f9SKrishna Gudipati 		 * Possible to get link events when doing back-to-back
2433a36c61f9SKrishna Gudipati 		 * enable/disables.
2434a36c61f9SKrishna Gudipati 		 */
2435a36c61f9SKrishna Gudipati 		break;
2436a36c61f9SKrishna Gudipati 
2437a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2438a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
2439a36c61f9SKrishna Gudipati 		break;
2440a36c61f9SKrishna Gudipati 
2441a36c61f9SKrishna Gudipati 	default:
2442a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2443a36c61f9SKrishna Gudipati 	}
2444a36c61f9SKrishna Gudipati }
2445a36c61f9SKrishna Gudipati 
2446a36c61f9SKrishna Gudipati static void
2447a36c61f9SKrishna Gudipati bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport,
2448a36c61f9SKrishna Gudipati 						enum bfa_fcport_sm_event event)
2449a36c61f9SKrishna Gudipati {
2450a36c61f9SKrishna Gudipati 	char pwwn_buf[BFA_STRING_32];
2451a36c61f9SKrishna Gudipati 	struct bfad_s *bfad = (struct bfad_s *)fcport->bfa->bfad;
2452a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2453a36c61f9SKrishna Gudipati 
2454a36c61f9SKrishna Gudipati 	switch (event) {
2455a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_START:
24565fbe25c7SJing Huang 		/*
2457a36c61f9SKrishna Gudipati 		 * Ignore start event for a port that is disabled.
2458a36c61f9SKrishna Gudipati 		 */
2459a36c61f9SKrishna Gudipati 		break;
2460a36c61f9SKrishna Gudipati 
2461a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_STOP:
2462a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_stopped);
2463a36c61f9SKrishna Gudipati 		break;
2464a36c61f9SKrishna Gudipati 
2465a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
2466a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_enable(fcport))
2467a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
2468a36c61f9SKrishna Gudipati 		else
2469a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2470a36c61f9SKrishna Gudipati 					 bfa_fcport_sm_enabling_qwait);
2471a36c61f9SKrishna Gudipati 
2472a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
2473a36c61f9SKrishna Gudipati 				BFA_PL_EID_PORT_ENABLE, 0, "Port Enable");
2474a36c61f9SKrishna Gudipati 		wwn2str(pwwn_buf, fcport->pwwn);
247588166242SJing Huang 		BFA_LOG(KERN_INFO, bfad, bfa_log_level,
2476a36c61f9SKrishna Gudipati 			"Base port enabled: WWN = %s\n", pwwn_buf);
2477a36c61f9SKrishna Gudipati 		break;
2478a36c61f9SKrishna Gudipati 
2479a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_DISABLE:
24805fbe25c7SJing Huang 		/*
2481a36c61f9SKrishna Gudipati 		 * Already disabled.
2482a36c61f9SKrishna Gudipati 		 */
2483a36c61f9SKrishna Gudipati 		break;
2484a36c61f9SKrishna Gudipati 
2485a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_HWFAIL:
2486a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocfail);
2487a36c61f9SKrishna Gudipati 		break;
2488a36c61f9SKrishna Gudipati 
2489a36c61f9SKrishna Gudipati 	default:
2490a36c61f9SKrishna Gudipati 		bfa_sm_fault(fcport->bfa, event);
2491a36c61f9SKrishna Gudipati 	}
2492a36c61f9SKrishna Gudipati }
2493a36c61f9SKrishna Gudipati 
2494a36c61f9SKrishna Gudipati static void
2495a36c61f9SKrishna Gudipati bfa_fcport_sm_stopped(struct bfa_fcport_s *fcport,
2496a36c61f9SKrishna Gudipati 			 enum bfa_fcport_sm_event event)
2497a36c61f9SKrishna Gudipati {
2498a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2499a36c61f9SKrishna Gudipati 
2500a36c61f9SKrishna Gudipati 	switch (event) {
2501a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_START:
2502a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_enable(fcport))
2503a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
2504a36c61f9SKrishna Gudipati 		else
2505a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2506a36c61f9SKrishna Gudipati 					 bfa_fcport_sm_enabling_qwait);
2507a36c61f9SKrishna Gudipati 		break;
2508a36c61f9SKrishna Gudipati 
2509a36c61f9SKrishna Gudipati 	default:
25105fbe25c7SJing Huang 		/*
2511a36c61f9SKrishna Gudipati 		 * Ignore all other events.
2512a36c61f9SKrishna Gudipati 		 */
2513a36c61f9SKrishna Gudipati 		;
2514a36c61f9SKrishna Gudipati 	}
2515a36c61f9SKrishna Gudipati }
2516a36c61f9SKrishna Gudipati 
25175fbe25c7SJing Huang /*
2518a36c61f9SKrishna Gudipati  * Port is enabled. IOC is down/failed.
2519a36c61f9SKrishna Gudipati  */
2520a36c61f9SKrishna Gudipati static void
2521a36c61f9SKrishna Gudipati bfa_fcport_sm_iocdown(struct bfa_fcport_s *fcport,
2522a36c61f9SKrishna Gudipati 			 enum bfa_fcport_sm_event event)
2523a36c61f9SKrishna Gudipati {
2524a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2525a36c61f9SKrishna Gudipati 
2526a36c61f9SKrishna Gudipati 	switch (event) {
2527a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_START:
2528a36c61f9SKrishna Gudipati 		if (bfa_fcport_send_enable(fcport))
2529a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport, bfa_fcport_sm_enabling);
2530a36c61f9SKrishna Gudipati 		else
2531a36c61f9SKrishna Gudipati 			bfa_sm_set_state(fcport,
2532a36c61f9SKrishna Gudipati 					 bfa_fcport_sm_enabling_qwait);
2533a36c61f9SKrishna Gudipati 		break;
2534a36c61f9SKrishna Gudipati 
2535a36c61f9SKrishna Gudipati 	default:
25365fbe25c7SJing Huang 		/*
2537a36c61f9SKrishna Gudipati 		 * Ignore all events.
2538a36c61f9SKrishna Gudipati 		 */
2539a36c61f9SKrishna Gudipati 		;
2540a36c61f9SKrishna Gudipati 	}
2541a36c61f9SKrishna Gudipati }
2542a36c61f9SKrishna Gudipati 
25435fbe25c7SJing Huang /*
2544a36c61f9SKrishna Gudipati  * Port is disabled. IOC is down/failed.
2545a36c61f9SKrishna Gudipati  */
2546a36c61f9SKrishna Gudipati static void
2547a36c61f9SKrishna Gudipati bfa_fcport_sm_iocfail(struct bfa_fcport_s *fcport,
2548a36c61f9SKrishna Gudipati 			 enum bfa_fcport_sm_event event)
2549a36c61f9SKrishna Gudipati {
2550a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, event);
2551a36c61f9SKrishna Gudipati 
2552a36c61f9SKrishna Gudipati 	switch (event) {
2553a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_START:
2554a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_disabled);
2555a36c61f9SKrishna Gudipati 		break;
2556a36c61f9SKrishna Gudipati 
2557a36c61f9SKrishna Gudipati 	case BFA_FCPORT_SM_ENABLE:
2558a36c61f9SKrishna Gudipati 		bfa_sm_set_state(fcport, bfa_fcport_sm_iocdown);
2559a36c61f9SKrishna Gudipati 		break;
2560a36c61f9SKrishna Gudipati 
2561a36c61f9SKrishna Gudipati 	default:
25625fbe25c7SJing Huang 		/*
2563a36c61f9SKrishna Gudipati 		 * Ignore all events.
2564a36c61f9SKrishna Gudipati 		 */
2565a36c61f9SKrishna Gudipati 		;
2566a36c61f9SKrishna Gudipati 	}
2567a36c61f9SKrishna Gudipati }
2568a36c61f9SKrishna Gudipati 
25695fbe25c7SJing Huang /*
2570a36c61f9SKrishna Gudipati  * Link state is down
2571a36c61f9SKrishna Gudipati  */
2572a36c61f9SKrishna Gudipati static void
2573a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_dn(struct bfa_fcport_ln_s *ln,
2574a36c61f9SKrishna Gudipati 		enum bfa_fcport_ln_sm_event event)
2575a36c61f9SKrishna Gudipati {
2576a36c61f9SKrishna Gudipati 	bfa_trc(ln->fcport->bfa, event);
2577a36c61f9SKrishna Gudipati 
2578a36c61f9SKrishna Gudipati 	switch (event) {
2579a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_LINKUP:
2580a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
2581a36c61f9SKrishna Gudipati 		bfa_fcport_queue_cb(ln, BFA_PORT_LINKUP);
2582a36c61f9SKrishna Gudipati 		break;
2583a36c61f9SKrishna Gudipati 
2584a36c61f9SKrishna Gudipati 	default:
2585a36c61f9SKrishna Gudipati 		bfa_sm_fault(ln->fcport->bfa, event);
2586a36c61f9SKrishna Gudipati 	}
2587a36c61f9SKrishna Gudipati }
2588a36c61f9SKrishna Gudipati 
25895fbe25c7SJing Huang /*
2590a36c61f9SKrishna Gudipati  * Link state is waiting for down notification
2591a36c61f9SKrishna Gudipati  */
2592a36c61f9SKrishna Gudipati static void
2593a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_dn_nf(struct bfa_fcport_ln_s *ln,
2594a36c61f9SKrishna Gudipati 		enum bfa_fcport_ln_sm_event event)
2595a36c61f9SKrishna Gudipati {
2596a36c61f9SKrishna Gudipati 	bfa_trc(ln->fcport->bfa, event);
2597a36c61f9SKrishna Gudipati 
2598a36c61f9SKrishna Gudipati 	switch (event) {
2599a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_LINKUP:
2600a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
2601a36c61f9SKrishna Gudipati 		break;
2602a36c61f9SKrishna Gudipati 
2603a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_NOTIFICATION:
2604a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
2605a36c61f9SKrishna Gudipati 		break;
2606a36c61f9SKrishna Gudipati 
2607a36c61f9SKrishna Gudipati 	default:
2608a36c61f9SKrishna Gudipati 		bfa_sm_fault(ln->fcport->bfa, event);
2609a36c61f9SKrishna Gudipati 	}
2610a36c61f9SKrishna Gudipati }
2611a36c61f9SKrishna Gudipati 
26125fbe25c7SJing Huang /*
2613a36c61f9SKrishna Gudipati  * Link state is waiting for down notification and there is a pending up
2614a36c61f9SKrishna Gudipati  */
2615a36c61f9SKrishna Gudipati static void
2616a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_dn_up_nf(struct bfa_fcport_ln_s *ln,
2617a36c61f9SKrishna Gudipati 		enum bfa_fcport_ln_sm_event event)
2618a36c61f9SKrishna Gudipati {
2619a36c61f9SKrishna Gudipati 	bfa_trc(ln->fcport->bfa, event);
2620a36c61f9SKrishna Gudipati 
2621a36c61f9SKrishna Gudipati 	switch (event) {
2622a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_LINKDOWN:
2623a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
2624a36c61f9SKrishna Gudipati 		break;
2625a36c61f9SKrishna Gudipati 
2626a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_NOTIFICATION:
2627a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_nf);
2628a36c61f9SKrishna Gudipati 		bfa_fcport_queue_cb(ln, BFA_PORT_LINKUP);
2629a36c61f9SKrishna Gudipati 		break;
2630a36c61f9SKrishna Gudipati 
2631a36c61f9SKrishna Gudipati 	default:
2632a36c61f9SKrishna Gudipati 		bfa_sm_fault(ln->fcport->bfa, event);
2633a36c61f9SKrishna Gudipati 	}
2634a36c61f9SKrishna Gudipati }
2635a36c61f9SKrishna Gudipati 
26365fbe25c7SJing Huang /*
2637a36c61f9SKrishna Gudipati  * Link state is up
2638a36c61f9SKrishna Gudipati  */
2639a36c61f9SKrishna Gudipati static void
2640a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up(struct bfa_fcport_ln_s *ln,
2641a36c61f9SKrishna Gudipati 		enum bfa_fcport_ln_sm_event event)
2642a36c61f9SKrishna Gudipati {
2643a36c61f9SKrishna Gudipati 	bfa_trc(ln->fcport->bfa, event);
2644a36c61f9SKrishna Gudipati 
2645a36c61f9SKrishna Gudipati 	switch (event) {
2646a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_LINKDOWN:
2647a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
2648a36c61f9SKrishna Gudipati 		bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN);
2649a36c61f9SKrishna Gudipati 		break;
2650a36c61f9SKrishna Gudipati 
2651a36c61f9SKrishna Gudipati 	default:
2652a36c61f9SKrishna Gudipati 		bfa_sm_fault(ln->fcport->bfa, event);
2653a36c61f9SKrishna Gudipati 	}
2654a36c61f9SKrishna Gudipati }
2655a36c61f9SKrishna Gudipati 
26565fbe25c7SJing Huang /*
2657a36c61f9SKrishna Gudipati  * Link state is waiting for up notification
2658a36c61f9SKrishna Gudipati  */
2659a36c61f9SKrishna Gudipati static void
2660a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up_nf(struct bfa_fcport_ln_s *ln,
2661a36c61f9SKrishna Gudipati 		enum bfa_fcport_ln_sm_event event)
2662a36c61f9SKrishna Gudipati {
2663a36c61f9SKrishna Gudipati 	bfa_trc(ln->fcport->bfa, event);
2664a36c61f9SKrishna Gudipati 
2665a36c61f9SKrishna Gudipati 	switch (event) {
2666a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_LINKDOWN:
2667a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
2668a36c61f9SKrishna Gudipati 		break;
2669a36c61f9SKrishna Gudipati 
2670a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_NOTIFICATION:
2671a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up);
2672a36c61f9SKrishna Gudipati 		break;
2673a36c61f9SKrishna Gudipati 
2674a36c61f9SKrishna Gudipati 	default:
2675a36c61f9SKrishna Gudipati 		bfa_sm_fault(ln->fcport->bfa, event);
2676a36c61f9SKrishna Gudipati 	}
2677a36c61f9SKrishna Gudipati }
2678a36c61f9SKrishna Gudipati 
26795fbe25c7SJing Huang /*
2680a36c61f9SKrishna Gudipati  * Link state is waiting for up notification and there is a pending down
2681a36c61f9SKrishna Gudipati  */
2682a36c61f9SKrishna Gudipati static void
2683a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up_dn_nf(struct bfa_fcport_ln_s *ln,
2684a36c61f9SKrishna Gudipati 		enum bfa_fcport_ln_sm_event event)
2685a36c61f9SKrishna Gudipati {
2686a36c61f9SKrishna Gudipati 	bfa_trc(ln->fcport->bfa, event);
2687a36c61f9SKrishna Gudipati 
2688a36c61f9SKrishna Gudipati 	switch (event) {
2689a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_LINKUP:
2690a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_up_nf);
2691a36c61f9SKrishna Gudipati 		break;
2692a36c61f9SKrishna Gudipati 
2693a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_NOTIFICATION:
2694a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_nf);
2695a36c61f9SKrishna Gudipati 		bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN);
2696a36c61f9SKrishna Gudipati 		break;
2697a36c61f9SKrishna Gudipati 
2698a36c61f9SKrishna Gudipati 	default:
2699a36c61f9SKrishna Gudipati 		bfa_sm_fault(ln->fcport->bfa, event);
2700a36c61f9SKrishna Gudipati 	}
2701a36c61f9SKrishna Gudipati }
2702a36c61f9SKrishna Gudipati 
27035fbe25c7SJing Huang /*
2704a36c61f9SKrishna Gudipati  * Link state is waiting for up notification and there are pending down and up
2705a36c61f9SKrishna Gudipati  */
2706a36c61f9SKrishna Gudipati static void
2707a36c61f9SKrishna Gudipati bfa_fcport_ln_sm_up_dn_up_nf(struct bfa_fcport_ln_s *ln,
2708a36c61f9SKrishna Gudipati 			enum bfa_fcport_ln_sm_event event)
2709a36c61f9SKrishna Gudipati {
2710a36c61f9SKrishna Gudipati 	bfa_trc(ln->fcport->bfa, event);
2711a36c61f9SKrishna Gudipati 
2712a36c61f9SKrishna Gudipati 	switch (event) {
2713a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_LINKDOWN:
2714a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_up_dn_nf);
2715a36c61f9SKrishna Gudipati 		break;
2716a36c61f9SKrishna Gudipati 
2717a36c61f9SKrishna Gudipati 	case BFA_FCPORT_LN_SM_NOTIFICATION:
2718a36c61f9SKrishna Gudipati 		bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn_up_nf);
2719a36c61f9SKrishna Gudipati 		bfa_fcport_queue_cb(ln, BFA_PORT_LINKDOWN);
2720a36c61f9SKrishna Gudipati 		break;
2721a36c61f9SKrishna Gudipati 
2722a36c61f9SKrishna Gudipati 	default:
2723a36c61f9SKrishna Gudipati 		bfa_sm_fault(ln->fcport->bfa, event);
2724a36c61f9SKrishna Gudipati 	}
2725a36c61f9SKrishna Gudipati }
2726a36c61f9SKrishna Gudipati 
2727a36c61f9SKrishna Gudipati static void
2728a36c61f9SKrishna Gudipati __bfa_cb_fcport_event(void *cbarg, bfa_boolean_t complete)
2729a36c61f9SKrishna Gudipati {
2730a36c61f9SKrishna Gudipati 	struct bfa_fcport_ln_s *ln = cbarg;
2731a36c61f9SKrishna Gudipati 
2732a36c61f9SKrishna Gudipati 	if (complete)
2733a36c61f9SKrishna Gudipati 		ln->fcport->event_cbfn(ln->fcport->event_cbarg, ln->ln_event);
2734a36c61f9SKrishna Gudipati 	else
2735a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION);
2736a36c61f9SKrishna Gudipati }
2737a36c61f9SKrishna Gudipati 
27385fbe25c7SJing Huang /*
2739a36c61f9SKrishna Gudipati  * Send SCN notification to upper layers.
2740a36c61f9SKrishna Gudipati  * trunk - false if caller is fcport to ignore fcport event in trunked mode
2741a36c61f9SKrishna Gudipati  */
2742a36c61f9SKrishna Gudipati static void
2743a36c61f9SKrishna Gudipati bfa_fcport_scn(struct bfa_fcport_s *fcport, enum bfa_port_linkstate event,
2744a36c61f9SKrishna Gudipati 	bfa_boolean_t trunk)
2745a36c61f9SKrishna Gudipati {
2746a36c61f9SKrishna Gudipati 	if (fcport->cfg.trunked && !trunk)
2747a36c61f9SKrishna Gudipati 		return;
2748a36c61f9SKrishna Gudipati 
2749a36c61f9SKrishna Gudipati 	switch (event) {
2750a36c61f9SKrishna Gudipati 	case BFA_PORT_LINKUP:
2751a36c61f9SKrishna Gudipati 		bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKUP);
2752a36c61f9SKrishna Gudipati 		break;
2753a36c61f9SKrishna Gudipati 	case BFA_PORT_LINKDOWN:
2754a36c61f9SKrishna Gudipati 		bfa_sm_send_event(&fcport->ln, BFA_FCPORT_LN_SM_LINKDOWN);
2755a36c61f9SKrishna Gudipati 		break;
2756a36c61f9SKrishna Gudipati 	default:
2757d4b671c5SJing Huang 		WARN_ON(1);
2758a36c61f9SKrishna Gudipati 	}
2759a36c61f9SKrishna Gudipati }
2760a36c61f9SKrishna Gudipati 
2761a36c61f9SKrishna Gudipati static void
2762a36c61f9SKrishna Gudipati bfa_fcport_queue_cb(struct bfa_fcport_ln_s *ln, enum bfa_port_linkstate event)
2763a36c61f9SKrishna Gudipati {
2764a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = ln->fcport;
2765a36c61f9SKrishna Gudipati 
2766a36c61f9SKrishna Gudipati 	if (fcport->bfa->fcs) {
2767a36c61f9SKrishna Gudipati 		fcport->event_cbfn(fcport->event_cbarg, event);
2768a36c61f9SKrishna Gudipati 		bfa_sm_send_event(ln, BFA_FCPORT_LN_SM_NOTIFICATION);
2769a36c61f9SKrishna Gudipati 	} else {
2770a36c61f9SKrishna Gudipati 		ln->ln_event = event;
2771a36c61f9SKrishna Gudipati 		bfa_cb_queue(fcport->bfa, &ln->ln_qe,
2772a36c61f9SKrishna Gudipati 			__bfa_cb_fcport_event, ln);
2773a36c61f9SKrishna Gudipati 	}
2774a36c61f9SKrishna Gudipati }
2775a36c61f9SKrishna Gudipati 
2776a36c61f9SKrishna Gudipati #define FCPORT_STATS_DMA_SZ (BFA_ROUNDUP(sizeof(union bfa_fcport_stats_u), \
2777a36c61f9SKrishna Gudipati 							BFA_CACHELINE_SZ))
2778a36c61f9SKrishna Gudipati 
2779a36c61f9SKrishna Gudipati static void
2780a36c61f9SKrishna Gudipati bfa_fcport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len,
2781a36c61f9SKrishna Gudipati 		u32 *dm_len)
2782a36c61f9SKrishna Gudipati {
2783a36c61f9SKrishna Gudipati 	*dm_len += FCPORT_STATS_DMA_SZ;
2784a36c61f9SKrishna Gudipati }
2785a36c61f9SKrishna Gudipati 
2786a36c61f9SKrishna Gudipati static void
2787a36c61f9SKrishna Gudipati bfa_fcport_qresume(void *cbarg)
2788a36c61f9SKrishna Gudipati {
2789a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = cbarg;
2790a36c61f9SKrishna Gudipati 
2791a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fcport, BFA_FCPORT_SM_QRESUME);
2792a36c61f9SKrishna Gudipati }
2793a36c61f9SKrishna Gudipati 
2794a36c61f9SKrishna Gudipati static void
2795a36c61f9SKrishna Gudipati bfa_fcport_mem_claim(struct bfa_fcport_s *fcport, struct bfa_meminfo_s *meminfo)
2796a36c61f9SKrishna Gudipati {
2797a36c61f9SKrishna Gudipati 	u8		*dm_kva;
2798a36c61f9SKrishna Gudipati 	u64	dm_pa;
2799a36c61f9SKrishna Gudipati 
2800a36c61f9SKrishna Gudipati 	dm_kva = bfa_meminfo_dma_virt(meminfo);
2801a36c61f9SKrishna Gudipati 	dm_pa  = bfa_meminfo_dma_phys(meminfo);
2802a36c61f9SKrishna Gudipati 
2803a36c61f9SKrishna Gudipati 	fcport->stats_kva = dm_kva;
2804a36c61f9SKrishna Gudipati 	fcport->stats_pa  = dm_pa;
2805a36c61f9SKrishna Gudipati 	fcport->stats	  = (union bfa_fcport_stats_u *) dm_kva;
2806a36c61f9SKrishna Gudipati 
2807a36c61f9SKrishna Gudipati 	dm_kva += FCPORT_STATS_DMA_SZ;
2808a36c61f9SKrishna Gudipati 	dm_pa  += FCPORT_STATS_DMA_SZ;
2809a36c61f9SKrishna Gudipati 
2810a36c61f9SKrishna Gudipati 	bfa_meminfo_dma_virt(meminfo) = dm_kva;
2811a36c61f9SKrishna Gudipati 	bfa_meminfo_dma_phys(meminfo) = dm_pa;
2812a36c61f9SKrishna Gudipati }
2813a36c61f9SKrishna Gudipati 
28145fbe25c7SJing Huang /*
2815a36c61f9SKrishna Gudipati  * Memory initialization.
2816a36c61f9SKrishna Gudipati  */
2817a36c61f9SKrishna Gudipati static void
2818a36c61f9SKrishna Gudipati bfa_fcport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
2819a36c61f9SKrishna Gudipati 		struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
2820a36c61f9SKrishna Gudipati {
2821a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
2822a36c61f9SKrishna Gudipati 	struct bfa_port_cfg_s *port_cfg = &fcport->cfg;
2823a36c61f9SKrishna Gudipati 	struct bfa_fcport_ln_s *ln = &fcport->ln;
2824f16a1750SMaggie Zhang 	struct timeval tv;
2825a36c61f9SKrishna Gudipati 
28266a18b167SJing Huang 	memset(fcport, 0, sizeof(struct bfa_fcport_s));
2827a36c61f9SKrishna Gudipati 	fcport->bfa = bfa;
2828a36c61f9SKrishna Gudipati 	ln->fcport = fcport;
2829a36c61f9SKrishna Gudipati 
2830a36c61f9SKrishna Gudipati 	bfa_fcport_mem_claim(fcport, meminfo);
2831a36c61f9SKrishna Gudipati 
2832a36c61f9SKrishna Gudipati 	bfa_sm_set_state(fcport, bfa_fcport_sm_uninit);
2833a36c61f9SKrishna Gudipati 	bfa_sm_set_state(ln, bfa_fcport_ln_sm_dn);
2834a36c61f9SKrishna Gudipati 
28355fbe25c7SJing Huang 	/*
2836a36c61f9SKrishna Gudipati 	 * initialize time stamp for stats reset
2837a36c61f9SKrishna Gudipati 	 */
2838f16a1750SMaggie Zhang 	do_gettimeofday(&tv);
2839a36c61f9SKrishna Gudipati 	fcport->stats_reset_time = tv.tv_sec;
2840a36c61f9SKrishna Gudipati 
28415fbe25c7SJing Huang 	/*
2842a36c61f9SKrishna Gudipati 	 * initialize and set default configuration
2843a36c61f9SKrishna Gudipati 	 */
2844a36c61f9SKrishna Gudipati 	port_cfg->topology = BFA_PORT_TOPOLOGY_P2P;
2845a36c61f9SKrishna Gudipati 	port_cfg->speed = BFA_PORT_SPEED_AUTO;
2846a36c61f9SKrishna Gudipati 	port_cfg->trunked = BFA_FALSE;
2847a36c61f9SKrishna Gudipati 	port_cfg->maxfrsize = 0;
2848a36c61f9SKrishna Gudipati 
2849a36c61f9SKrishna Gudipati 	port_cfg->trl_def_speed = BFA_PORT_SPEED_1GBPS;
2850a36c61f9SKrishna Gudipati 
2851a36c61f9SKrishna Gudipati 	bfa_reqq_winit(&fcport->reqq_wait, bfa_fcport_qresume, fcport);
2852a36c61f9SKrishna Gudipati }
2853a36c61f9SKrishna Gudipati 
2854a36c61f9SKrishna Gudipati static void
2855a36c61f9SKrishna Gudipati bfa_fcport_detach(struct bfa_s *bfa)
2856a36c61f9SKrishna Gudipati {
2857a36c61f9SKrishna Gudipati }
2858a36c61f9SKrishna Gudipati 
28595fbe25c7SJing Huang /*
2860a36c61f9SKrishna Gudipati  * Called when IOC is ready.
2861a36c61f9SKrishna Gudipati  */
2862a36c61f9SKrishna Gudipati static void
2863a36c61f9SKrishna Gudipati bfa_fcport_start(struct bfa_s *bfa)
2864a36c61f9SKrishna Gudipati {
2865a36c61f9SKrishna Gudipati 	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_START);
2866a36c61f9SKrishna Gudipati }
2867a36c61f9SKrishna Gudipati 
28685fbe25c7SJing Huang /*
2869a36c61f9SKrishna Gudipati  * Called before IOC is stopped.
2870a36c61f9SKrishna Gudipati  */
2871a36c61f9SKrishna Gudipati static void
2872a36c61f9SKrishna Gudipati bfa_fcport_stop(struct bfa_s *bfa)
2873a36c61f9SKrishna Gudipati {
2874a36c61f9SKrishna Gudipati 	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_STOP);
2875a36c61f9SKrishna Gudipati 	bfa_trunk_iocdisable(bfa);
2876a36c61f9SKrishna Gudipati }
2877a36c61f9SKrishna Gudipati 
28785fbe25c7SJing Huang /*
2879a36c61f9SKrishna Gudipati  * Called when IOC failure is detected.
2880a36c61f9SKrishna Gudipati  */
2881a36c61f9SKrishna Gudipati static void
2882a36c61f9SKrishna Gudipati bfa_fcport_iocdisable(struct bfa_s *bfa)
2883a36c61f9SKrishna Gudipati {
2884a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
2885a36c61f9SKrishna Gudipati 
2886a36c61f9SKrishna Gudipati 	bfa_sm_send_event(fcport, BFA_FCPORT_SM_HWFAIL);
2887a36c61f9SKrishna Gudipati 	bfa_trunk_iocdisable(bfa);
2888a36c61f9SKrishna Gudipati }
2889a36c61f9SKrishna Gudipati 
2890a36c61f9SKrishna Gudipati static void
2891a36c61f9SKrishna Gudipati bfa_fcport_update_linkinfo(struct bfa_fcport_s *fcport)
2892a36c61f9SKrishna Gudipati {
2893a36c61f9SKrishna Gudipati 	struct bfi_fcport_event_s *pevent = fcport->event_arg.i2hmsg.event;
2894a36c61f9SKrishna Gudipati 	struct bfa_fcport_trunk_s *trunk = &fcport->trunk;
2895a36c61f9SKrishna Gudipati 
2896a36c61f9SKrishna Gudipati 	fcport->speed = pevent->link_state.speed;
2897a36c61f9SKrishna Gudipati 	fcport->topology = pevent->link_state.topology;
2898a36c61f9SKrishna Gudipati 
2899a36c61f9SKrishna Gudipati 	if (fcport->topology == BFA_PORT_TOPOLOGY_LOOP)
2900a36c61f9SKrishna Gudipati 		fcport->myalpa = 0;
2901a36c61f9SKrishna Gudipati 
2902a36c61f9SKrishna Gudipati 	/* QoS Details */
29036a18b167SJing Huang 	fcport->qos_attr = pevent->link_state.qos_attr;
29046a18b167SJing Huang 	fcport->qos_vc_attr = pevent->link_state.vc_fcf.qos_vc_attr;
2905a36c61f9SKrishna Gudipati 
29065fbe25c7SJing Huang 	/*
2907a36c61f9SKrishna Gudipati 	 * update trunk state if applicable
2908a36c61f9SKrishna Gudipati 	 */
2909a36c61f9SKrishna Gudipati 	if (!fcport->cfg.trunked)
2910a36c61f9SKrishna Gudipati 		trunk->attr.state = BFA_TRUNK_DISABLED;
2911a36c61f9SKrishna Gudipati 
2912a36c61f9SKrishna Gudipati 	/* update FCoE specific */
2913ba816ea8SJing Huang 	fcport->fcoe_vlan = be16_to_cpu(pevent->link_state.vc_fcf.fcf.vlan);
2914a36c61f9SKrishna Gudipati 
2915a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, fcport->speed);
2916a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, fcport->topology);
2917a36c61f9SKrishna Gudipati }
2918a36c61f9SKrishna Gudipati 
2919a36c61f9SKrishna Gudipati static void
2920a36c61f9SKrishna Gudipati bfa_fcport_reset_linkinfo(struct bfa_fcport_s *fcport)
2921a36c61f9SKrishna Gudipati {
2922a36c61f9SKrishna Gudipati 	fcport->speed = BFA_PORT_SPEED_UNKNOWN;
2923a36c61f9SKrishna Gudipati 	fcport->topology = BFA_PORT_TOPOLOGY_NONE;
2924a36c61f9SKrishna Gudipati }
2925a36c61f9SKrishna Gudipati 
29265fbe25c7SJing Huang /*
2927a36c61f9SKrishna Gudipati  * Send port enable message to firmware.
2928a36c61f9SKrishna Gudipati  */
2929a36c61f9SKrishna Gudipati static bfa_boolean_t
2930a36c61f9SKrishna Gudipati bfa_fcport_send_enable(struct bfa_fcport_s *fcport)
2931a36c61f9SKrishna Gudipati {
2932a36c61f9SKrishna Gudipati 	struct bfi_fcport_enable_req_s *m;
2933a36c61f9SKrishna Gudipati 
29345fbe25c7SJing Huang 	/*
2935a36c61f9SKrishna Gudipati 	 * Increment message tag before queue check, so that responses to old
2936a36c61f9SKrishna Gudipati 	 * requests are discarded.
2937a36c61f9SKrishna Gudipati 	 */
2938a36c61f9SKrishna Gudipati 	fcport->msgtag++;
2939a36c61f9SKrishna Gudipati 
29405fbe25c7SJing Huang 	/*
2941a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
2942a36c61f9SKrishna Gudipati 	 */
2943a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
2944a36c61f9SKrishna Gudipati 	if (!m) {
2945a36c61f9SKrishna Gudipati 		bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
2946a36c61f9SKrishna Gudipati 							&fcport->reqq_wait);
2947a36c61f9SKrishna Gudipati 		return BFA_FALSE;
2948a36c61f9SKrishna Gudipati 	}
2949a36c61f9SKrishna Gudipati 
2950a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_ENABLE_REQ,
2951a36c61f9SKrishna Gudipati 			bfa_lpuid(fcport->bfa));
2952a36c61f9SKrishna Gudipati 	m->nwwn = fcport->nwwn;
2953a36c61f9SKrishna Gudipati 	m->pwwn = fcport->pwwn;
2954a36c61f9SKrishna Gudipati 	m->port_cfg = fcport->cfg;
2955a36c61f9SKrishna Gudipati 	m->msgtag = fcport->msgtag;
2956ba816ea8SJing Huang 	m->port_cfg.maxfrsize = cpu_to_be16(fcport->cfg.maxfrsize);
2957f3a060caSKrishna Gudipati 	 m->use_flash_cfg = fcport->use_flash_cfg;
2958a36c61f9SKrishna Gudipati 	bfa_dma_be_addr_set(m->stats_dma_addr, fcport->stats_pa);
2959a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_lo);
2960a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, m->stats_dma_addr.a32.addr_hi);
2961a36c61f9SKrishna Gudipati 
29625fbe25c7SJing Huang 	/*
2963a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
2964a36c61f9SKrishna Gudipati 	 */
2965a36c61f9SKrishna Gudipati 	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
2966a36c61f9SKrishna Gudipati 	return BFA_TRUE;
2967a36c61f9SKrishna Gudipati }
2968a36c61f9SKrishna Gudipati 
29695fbe25c7SJing Huang /*
2970a36c61f9SKrishna Gudipati  * Send port disable message to firmware.
2971a36c61f9SKrishna Gudipati  */
2972a36c61f9SKrishna Gudipati static	bfa_boolean_t
2973a36c61f9SKrishna Gudipati bfa_fcport_send_disable(struct bfa_fcport_s *fcport)
2974a36c61f9SKrishna Gudipati {
2975a36c61f9SKrishna Gudipati 	struct bfi_fcport_req_s *m;
2976a36c61f9SKrishna Gudipati 
29775fbe25c7SJing Huang 	/*
2978a36c61f9SKrishna Gudipati 	 * Increment message tag before queue check, so that responses to old
2979a36c61f9SKrishna Gudipati 	 * requests are discarded.
2980a36c61f9SKrishna Gudipati 	 */
2981a36c61f9SKrishna Gudipati 	fcport->msgtag++;
2982a36c61f9SKrishna Gudipati 
29835fbe25c7SJing Huang 	/*
2984a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
2985a36c61f9SKrishna Gudipati 	 */
2986a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
2987a36c61f9SKrishna Gudipati 	if (!m) {
2988a36c61f9SKrishna Gudipati 		bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
2989a36c61f9SKrishna Gudipati 							&fcport->reqq_wait);
2990a36c61f9SKrishna Gudipati 		return BFA_FALSE;
2991a36c61f9SKrishna Gudipati 	}
2992a36c61f9SKrishna Gudipati 
2993a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_DISABLE_REQ,
2994a36c61f9SKrishna Gudipati 			bfa_lpuid(fcport->bfa));
2995a36c61f9SKrishna Gudipati 	m->msgtag = fcport->msgtag;
2996a36c61f9SKrishna Gudipati 
29975fbe25c7SJing Huang 	/*
2998a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
2999a36c61f9SKrishna Gudipati 	 */
3000a36c61f9SKrishna Gudipati 	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
3001a36c61f9SKrishna Gudipati 
3002a36c61f9SKrishna Gudipati 	return BFA_TRUE;
3003a36c61f9SKrishna Gudipati }
3004a36c61f9SKrishna Gudipati 
3005a36c61f9SKrishna Gudipati static void
3006a36c61f9SKrishna Gudipati bfa_fcport_set_wwns(struct bfa_fcport_s *fcport)
3007a36c61f9SKrishna Gudipati {
3008f7f73812SMaggie Zhang 	fcport->pwwn = fcport->bfa->ioc.attr->pwwn;
3009f7f73812SMaggie Zhang 	fcport->nwwn = fcport->bfa->ioc.attr->nwwn;
3010a36c61f9SKrishna Gudipati 
3011a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, fcport->pwwn);
3012a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, fcport->nwwn);
3013a36c61f9SKrishna Gudipati }
3014a36c61f9SKrishna Gudipati 
3015a36c61f9SKrishna Gudipati static void
3016a36c61f9SKrishna Gudipati bfa_fcport_send_txcredit(void *port_cbarg)
3017a36c61f9SKrishna Gudipati {
3018a36c61f9SKrishna Gudipati 
3019a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = port_cbarg;
3020a36c61f9SKrishna Gudipati 	struct bfi_fcport_set_svc_params_req_s *m;
3021a36c61f9SKrishna Gudipati 
30225fbe25c7SJing Huang 	/*
3023a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
3024a36c61f9SKrishna Gudipati 	 */
3025a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
3026a36c61f9SKrishna Gudipati 	if (!m) {
3027a36c61f9SKrishna Gudipati 		bfa_trc(fcport->bfa, fcport->cfg.tx_bbcredit);
3028a36c61f9SKrishna Gudipati 		return;
3029a36c61f9SKrishna Gudipati 	}
3030a36c61f9SKrishna Gudipati 
3031a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_SET_SVC_PARAMS_REQ,
3032a36c61f9SKrishna Gudipati 			bfa_lpuid(fcport->bfa));
3033ba816ea8SJing Huang 	m->tx_bbcredit = cpu_to_be16((u16)fcport->cfg.tx_bbcredit);
3034a36c61f9SKrishna Gudipati 
30355fbe25c7SJing Huang 	/*
3036a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
3037a36c61f9SKrishna Gudipati 	 */
3038a36c61f9SKrishna Gudipati 	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
3039a36c61f9SKrishna Gudipati }
3040a36c61f9SKrishna Gudipati 
3041a36c61f9SKrishna Gudipati static void
3042a36c61f9SKrishna Gudipati bfa_fcport_qos_stats_swap(struct bfa_qos_stats_s *d,
3043a36c61f9SKrishna Gudipati 	struct bfa_qos_stats_s *s)
3044a36c61f9SKrishna Gudipati {
3045a36c61f9SKrishna Gudipati 	u32	*dip = (u32 *) d;
304650444a34SMaggie 	__be32	*sip = (__be32 *) s;
3047a36c61f9SKrishna Gudipati 	int		i;
3048a36c61f9SKrishna Gudipati 
3049a36c61f9SKrishna Gudipati 	/* Now swap the 32 bit fields */
3050a36c61f9SKrishna Gudipati 	for (i = 0; i < (sizeof(struct bfa_qos_stats_s)/sizeof(u32)); ++i)
3051ba816ea8SJing Huang 		dip[i] = be32_to_cpu(sip[i]);
3052a36c61f9SKrishna Gudipati }
3053a36c61f9SKrishna Gudipati 
3054a36c61f9SKrishna Gudipati static void
3055a36c61f9SKrishna Gudipati bfa_fcport_fcoe_stats_swap(struct bfa_fcoe_stats_s *d,
3056a36c61f9SKrishna Gudipati 	struct bfa_fcoe_stats_s *s)
3057a36c61f9SKrishna Gudipati {
3058a36c61f9SKrishna Gudipati 	u32	*dip = (u32 *) d;
305950444a34SMaggie 	__be32	*sip = (__be32 *) s;
3060a36c61f9SKrishna Gudipati 	int		i;
3061a36c61f9SKrishna Gudipati 
3062a36c61f9SKrishna Gudipati 	for (i = 0; i < ((sizeof(struct bfa_fcoe_stats_s))/sizeof(u32));
3063a36c61f9SKrishna Gudipati 	     i = i + 2) {
3064f16a1750SMaggie Zhang #ifdef __BIG_ENDIAN
3065ba816ea8SJing Huang 		dip[i] = be32_to_cpu(sip[i]);
3066ba816ea8SJing Huang 		dip[i + 1] = be32_to_cpu(sip[i + 1]);
3067a36c61f9SKrishna Gudipati #else
3068ba816ea8SJing Huang 		dip[i] = be32_to_cpu(sip[i + 1]);
3069ba816ea8SJing Huang 		dip[i + 1] = be32_to_cpu(sip[i]);
3070a36c61f9SKrishna Gudipati #endif
3071a36c61f9SKrishna Gudipati 	}
3072a36c61f9SKrishna Gudipati }
3073a36c61f9SKrishna Gudipati 
3074a36c61f9SKrishna Gudipati static void
3075a36c61f9SKrishna Gudipati __bfa_cb_fcport_stats_get(void *cbarg, bfa_boolean_t complete)
3076a36c61f9SKrishna Gudipati {
3077a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = cbarg;
3078a36c61f9SKrishna Gudipati 
3079a36c61f9SKrishna Gudipati 	if (complete) {
3080a36c61f9SKrishna Gudipati 		if (fcport->stats_status == BFA_STATUS_OK) {
3081f16a1750SMaggie Zhang 			struct timeval tv;
3082a36c61f9SKrishna Gudipati 
3083a36c61f9SKrishna Gudipati 			/* Swap FC QoS or FCoE stats */
3084a36c61f9SKrishna Gudipati 			if (bfa_ioc_get_fcmode(&fcport->bfa->ioc)) {
3085a36c61f9SKrishna Gudipati 				bfa_fcport_qos_stats_swap(
3086a36c61f9SKrishna Gudipati 					&fcport->stats_ret->fcqos,
3087a36c61f9SKrishna Gudipati 					&fcport->stats->fcqos);
3088a36c61f9SKrishna Gudipati 			} else {
3089a36c61f9SKrishna Gudipati 				bfa_fcport_fcoe_stats_swap(
3090a36c61f9SKrishna Gudipati 					&fcport->stats_ret->fcoe,
3091a36c61f9SKrishna Gudipati 					&fcport->stats->fcoe);
3092a36c61f9SKrishna Gudipati 
3093f16a1750SMaggie Zhang 				do_gettimeofday(&tv);
3094a36c61f9SKrishna Gudipati 				fcport->stats_ret->fcoe.secs_reset =
3095a36c61f9SKrishna Gudipati 					tv.tv_sec - fcport->stats_reset_time;
3096a36c61f9SKrishna Gudipati 			}
3097a36c61f9SKrishna Gudipati 		}
3098a36c61f9SKrishna Gudipati 		fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
3099a36c61f9SKrishna Gudipati 	} else {
3100a36c61f9SKrishna Gudipati 		fcport->stats_busy = BFA_FALSE;
3101a36c61f9SKrishna Gudipati 		fcport->stats_status = BFA_STATUS_OK;
3102a36c61f9SKrishna Gudipati 	}
3103a36c61f9SKrishna Gudipati }
3104a36c61f9SKrishna Gudipati 
3105a36c61f9SKrishna Gudipati static void
3106a36c61f9SKrishna Gudipati bfa_fcport_stats_get_timeout(void *cbarg)
3107a36c61f9SKrishna Gudipati {
3108a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
3109a36c61f9SKrishna Gudipati 
3110a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, fcport->stats_qfull);
3111a36c61f9SKrishna Gudipati 
3112a36c61f9SKrishna Gudipati 	if (fcport->stats_qfull) {
3113a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->stats_reqq_wait);
3114a36c61f9SKrishna Gudipati 		fcport->stats_qfull = BFA_FALSE;
3115a36c61f9SKrishna Gudipati 	}
3116a36c61f9SKrishna Gudipati 
3117a36c61f9SKrishna Gudipati 	fcport->stats_status = BFA_STATUS_ETIMER;
3118a36c61f9SKrishna Gudipati 	bfa_cb_queue(fcport->bfa, &fcport->hcb_qe, __bfa_cb_fcport_stats_get,
3119a36c61f9SKrishna Gudipati 		fcport);
3120a36c61f9SKrishna Gudipati }
3121a36c61f9SKrishna Gudipati 
3122a36c61f9SKrishna Gudipati static void
3123a36c61f9SKrishna Gudipati bfa_fcport_send_stats_get(void *cbarg)
3124a36c61f9SKrishna Gudipati {
3125a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
3126a36c61f9SKrishna Gudipati 	struct bfi_fcport_req_s *msg;
3127a36c61f9SKrishna Gudipati 
3128a36c61f9SKrishna Gudipati 	msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
3129a36c61f9SKrishna Gudipati 
3130a36c61f9SKrishna Gudipati 	if (!msg) {
3131a36c61f9SKrishna Gudipati 		fcport->stats_qfull = BFA_TRUE;
3132a36c61f9SKrishna Gudipati 		bfa_reqq_winit(&fcport->stats_reqq_wait,
3133a36c61f9SKrishna Gudipati 				bfa_fcport_send_stats_get, fcport);
3134a36c61f9SKrishna Gudipati 		bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
3135a36c61f9SKrishna Gudipati 				&fcport->stats_reqq_wait);
3136a36c61f9SKrishna Gudipati 		return;
3137a36c61f9SKrishna Gudipati 	}
3138a36c61f9SKrishna Gudipati 	fcport->stats_qfull = BFA_FALSE;
3139a36c61f9SKrishna Gudipati 
31406a18b167SJing Huang 	memset(msg, 0, sizeof(struct bfi_fcport_req_s));
3141a36c61f9SKrishna Gudipati 	bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_GET_REQ,
3142a36c61f9SKrishna Gudipati 			bfa_lpuid(fcport->bfa));
3143a36c61f9SKrishna Gudipati 	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
3144a36c61f9SKrishna Gudipati }
3145a36c61f9SKrishna Gudipati 
3146a36c61f9SKrishna Gudipati static void
3147a36c61f9SKrishna Gudipati __bfa_cb_fcport_stats_clr(void *cbarg, bfa_boolean_t complete)
3148a36c61f9SKrishna Gudipati {
3149a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = cbarg;
3150a36c61f9SKrishna Gudipati 
3151a36c61f9SKrishna Gudipati 	if (complete) {
3152f16a1750SMaggie Zhang 		struct timeval tv;
3153a36c61f9SKrishna Gudipati 
31545fbe25c7SJing Huang 		/*
3155a36c61f9SKrishna Gudipati 		 * re-initialize time stamp for stats reset
3156a36c61f9SKrishna Gudipati 		 */
3157f16a1750SMaggie Zhang 		do_gettimeofday(&tv);
3158a36c61f9SKrishna Gudipati 		fcport->stats_reset_time = tv.tv_sec;
3159a36c61f9SKrishna Gudipati 
3160a36c61f9SKrishna Gudipati 		fcport->stats_cbfn(fcport->stats_cbarg, fcport->stats_status);
3161a36c61f9SKrishna Gudipati 	} else {
3162a36c61f9SKrishna Gudipati 		fcport->stats_busy = BFA_FALSE;
3163a36c61f9SKrishna Gudipati 		fcport->stats_status = BFA_STATUS_OK;
3164a36c61f9SKrishna Gudipati 	}
3165a36c61f9SKrishna Gudipati }
3166a36c61f9SKrishna Gudipati 
3167a36c61f9SKrishna Gudipati static void
3168a36c61f9SKrishna Gudipati bfa_fcport_stats_clr_timeout(void *cbarg)
3169a36c61f9SKrishna Gudipati {
3170a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
3171a36c61f9SKrishna Gudipati 
3172a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, fcport->stats_qfull);
3173a36c61f9SKrishna Gudipati 
3174a36c61f9SKrishna Gudipati 	if (fcport->stats_qfull) {
3175a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&fcport->stats_reqq_wait);
3176a36c61f9SKrishna Gudipati 		fcport->stats_qfull = BFA_FALSE;
3177a36c61f9SKrishna Gudipati 	}
3178a36c61f9SKrishna Gudipati 
3179a36c61f9SKrishna Gudipati 	fcport->stats_status = BFA_STATUS_ETIMER;
3180a36c61f9SKrishna Gudipati 	bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
3181a36c61f9SKrishna Gudipati 			__bfa_cb_fcport_stats_clr, fcport);
3182a36c61f9SKrishna Gudipati }
3183a36c61f9SKrishna Gudipati 
3184a36c61f9SKrishna Gudipati static void
3185a36c61f9SKrishna Gudipati bfa_fcport_send_stats_clear(void *cbarg)
3186a36c61f9SKrishna Gudipati {
3187a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = (struct bfa_fcport_s *) cbarg;
3188a36c61f9SKrishna Gudipati 	struct bfi_fcport_req_s *msg;
3189a36c61f9SKrishna Gudipati 
3190a36c61f9SKrishna Gudipati 	msg = bfa_reqq_next(fcport->bfa, BFA_REQQ_PORT);
3191a36c61f9SKrishna Gudipati 
3192a36c61f9SKrishna Gudipati 	if (!msg) {
3193a36c61f9SKrishna Gudipati 		fcport->stats_qfull = BFA_TRUE;
3194a36c61f9SKrishna Gudipati 		bfa_reqq_winit(&fcport->stats_reqq_wait,
3195a36c61f9SKrishna Gudipati 				bfa_fcport_send_stats_clear, fcport);
3196a36c61f9SKrishna Gudipati 		bfa_reqq_wait(fcport->bfa, BFA_REQQ_PORT,
3197a36c61f9SKrishna Gudipati 						&fcport->stats_reqq_wait);
3198a36c61f9SKrishna Gudipati 		return;
3199a36c61f9SKrishna Gudipati 	}
3200a36c61f9SKrishna Gudipati 	fcport->stats_qfull = BFA_FALSE;
3201a36c61f9SKrishna Gudipati 
32026a18b167SJing Huang 	memset(msg, 0, sizeof(struct bfi_fcport_req_s));
3203a36c61f9SKrishna Gudipati 	bfi_h2i_set(msg->mh, BFI_MC_FCPORT, BFI_FCPORT_H2I_STATS_CLEAR_REQ,
3204a36c61f9SKrishna Gudipati 			bfa_lpuid(fcport->bfa));
3205a36c61f9SKrishna Gudipati 	bfa_reqq_produce(fcport->bfa, BFA_REQQ_PORT);
3206a36c61f9SKrishna Gudipati }
3207a36c61f9SKrishna Gudipati 
32085fbe25c7SJing Huang /*
3209a36c61f9SKrishna Gudipati  * Handle trunk SCN event from firmware.
3210a36c61f9SKrishna Gudipati  */
3211a36c61f9SKrishna Gudipati static void
3212a36c61f9SKrishna Gudipati bfa_trunk_scn(struct bfa_fcport_s *fcport, struct bfi_fcport_trunk_scn_s *scn)
3213a36c61f9SKrishna Gudipati {
3214a36c61f9SKrishna Gudipati 	struct bfa_fcport_trunk_s *trunk = &fcport->trunk;
3215a36c61f9SKrishna Gudipati 	struct bfi_fcport_trunk_link_s *tlink;
3216a36c61f9SKrishna Gudipati 	struct bfa_trunk_link_attr_s *lattr;
3217a36c61f9SKrishna Gudipati 	enum bfa_trunk_state state_prev;
3218a36c61f9SKrishna Gudipati 	int i;
3219a36c61f9SKrishna Gudipati 	int link_bm = 0;
3220a36c61f9SKrishna Gudipati 
3221a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, fcport->cfg.trunked);
3222d4b671c5SJing Huang 	WARN_ON(scn->trunk_state != BFA_TRUNK_ONLINE &&
3223d4b671c5SJing Huang 		   scn->trunk_state != BFA_TRUNK_OFFLINE);
3224a36c61f9SKrishna Gudipati 
3225a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, trunk->attr.state);
3226a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, scn->trunk_state);
3227a36c61f9SKrishna Gudipati 	bfa_trc(fcport->bfa, scn->trunk_speed);
3228a36c61f9SKrishna Gudipati 
32295fbe25c7SJing Huang 	/*
3230a36c61f9SKrishna Gudipati 	 * Save off new state for trunk attribute query
3231a36c61f9SKrishna Gudipati 	 */
3232a36c61f9SKrishna Gudipati 	state_prev = trunk->attr.state;
3233a36c61f9SKrishna Gudipati 	if (fcport->cfg.trunked && (trunk->attr.state != BFA_TRUNK_DISABLED))
3234a36c61f9SKrishna Gudipati 		trunk->attr.state = scn->trunk_state;
3235a36c61f9SKrishna Gudipati 	trunk->attr.speed = scn->trunk_speed;
3236a36c61f9SKrishna Gudipati 	for (i = 0; i < BFA_TRUNK_MAX_PORTS; i++) {
3237a36c61f9SKrishna Gudipati 		lattr = &trunk->attr.link_attr[i];
3238a36c61f9SKrishna Gudipati 		tlink = &scn->tlink[i];
3239a36c61f9SKrishna Gudipati 
3240a36c61f9SKrishna Gudipati 		lattr->link_state = tlink->state;
3241a36c61f9SKrishna Gudipati 		lattr->trunk_wwn  = tlink->trunk_wwn;
3242a36c61f9SKrishna Gudipati 		lattr->fctl	  = tlink->fctl;
3243a36c61f9SKrishna Gudipati 		lattr->speed	  = tlink->speed;
3244ba816ea8SJing Huang 		lattr->deskew	  = be32_to_cpu(tlink->deskew);
3245a36c61f9SKrishna Gudipati 
3246a36c61f9SKrishna Gudipati 		if (tlink->state == BFA_TRUNK_LINK_STATE_UP) {
3247a36c61f9SKrishna Gudipati 			fcport->speed	 = tlink->speed;
3248a36c61f9SKrishna Gudipati 			fcport->topology = BFA_PORT_TOPOLOGY_P2P;
3249a36c61f9SKrishna Gudipati 			link_bm |= 1 << i;
3250a36c61f9SKrishna Gudipati 		}
3251a36c61f9SKrishna Gudipati 
3252a36c61f9SKrishna Gudipati 		bfa_trc(fcport->bfa, lattr->link_state);
3253a36c61f9SKrishna Gudipati 		bfa_trc(fcport->bfa, lattr->trunk_wwn);
3254a36c61f9SKrishna Gudipati 		bfa_trc(fcport->bfa, lattr->fctl);
3255a36c61f9SKrishna Gudipati 		bfa_trc(fcport->bfa, lattr->speed);
3256a36c61f9SKrishna Gudipati 		bfa_trc(fcport->bfa, lattr->deskew);
3257a36c61f9SKrishna Gudipati 	}
3258a36c61f9SKrishna Gudipati 
3259a36c61f9SKrishna Gudipati 	switch (link_bm) {
3260a36c61f9SKrishna Gudipati 	case 3:
3261a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
3262a36c61f9SKrishna Gudipati 			BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(0,1)");
3263a36c61f9SKrishna Gudipati 		break;
3264a36c61f9SKrishna Gudipati 	case 2:
3265a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
3266a36c61f9SKrishna Gudipati 			BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(-,1)");
3267a36c61f9SKrishna Gudipati 		break;
3268a36c61f9SKrishna Gudipati 	case 1:
3269a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
3270a36c61f9SKrishna Gudipati 			BFA_PL_EID_TRUNK_SCN, 0, "Trunk up(0,-)");
3271a36c61f9SKrishna Gudipati 		break;
3272a36c61f9SKrishna Gudipati 	default:
3273a36c61f9SKrishna Gudipati 		bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL,
3274a36c61f9SKrishna Gudipati 			BFA_PL_EID_TRUNK_SCN, 0, "Trunk down");
3275a36c61f9SKrishna Gudipati 	}
3276a36c61f9SKrishna Gudipati 
32775fbe25c7SJing Huang 	/*
3278a36c61f9SKrishna Gudipati 	 * Notify upper layers if trunk state changed.
3279a36c61f9SKrishna Gudipati 	 */
3280a36c61f9SKrishna Gudipati 	if ((state_prev != trunk->attr.state) ||
3281a36c61f9SKrishna Gudipati 		(scn->trunk_state == BFA_TRUNK_OFFLINE)) {
3282a36c61f9SKrishna Gudipati 		bfa_fcport_scn(fcport, (scn->trunk_state == BFA_TRUNK_ONLINE) ?
3283a36c61f9SKrishna Gudipati 			BFA_PORT_LINKUP : BFA_PORT_LINKDOWN, BFA_TRUE);
3284a36c61f9SKrishna Gudipati 	}
3285a36c61f9SKrishna Gudipati }
3286a36c61f9SKrishna Gudipati 
3287a36c61f9SKrishna Gudipati static void
3288a36c61f9SKrishna Gudipati bfa_trunk_iocdisable(struct bfa_s *bfa)
3289a36c61f9SKrishna Gudipati {
3290a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3291a36c61f9SKrishna Gudipati 	int i = 0;
3292a36c61f9SKrishna Gudipati 
32935fbe25c7SJing Huang 	/*
3294a36c61f9SKrishna Gudipati 	 * In trunked mode, notify upper layers that link is down
3295a36c61f9SKrishna Gudipati 	 */
3296a36c61f9SKrishna Gudipati 	if (fcport->cfg.trunked) {
3297a36c61f9SKrishna Gudipati 		if (fcport->trunk.attr.state == BFA_TRUNK_ONLINE)
3298a36c61f9SKrishna Gudipati 			bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_TRUE);
3299a36c61f9SKrishna Gudipati 
3300a36c61f9SKrishna Gudipati 		fcport->trunk.attr.state = BFA_TRUNK_OFFLINE;
3301a36c61f9SKrishna Gudipati 		fcport->trunk.attr.speed = BFA_PORT_SPEED_UNKNOWN;
3302a36c61f9SKrishna Gudipati 		for (i = 0; i < BFA_TRUNK_MAX_PORTS; i++) {
3303a36c61f9SKrishna Gudipati 			fcport->trunk.attr.link_attr[i].trunk_wwn = 0;
3304a36c61f9SKrishna Gudipati 			fcport->trunk.attr.link_attr[i].fctl =
3305a36c61f9SKrishna Gudipati 						BFA_TRUNK_LINK_FCTL_NORMAL;
3306a36c61f9SKrishna Gudipati 			fcport->trunk.attr.link_attr[i].link_state =
3307a36c61f9SKrishna Gudipati 						BFA_TRUNK_LINK_STATE_DN_LINKDN;
3308a36c61f9SKrishna Gudipati 			fcport->trunk.attr.link_attr[i].speed =
3309a36c61f9SKrishna Gudipati 						BFA_PORT_SPEED_UNKNOWN;
3310a36c61f9SKrishna Gudipati 			fcport->trunk.attr.link_attr[i].deskew = 0;
3311a36c61f9SKrishna Gudipati 		}
3312a36c61f9SKrishna Gudipati 	}
3313a36c61f9SKrishna Gudipati }
3314a36c61f9SKrishna Gudipati 
33155fbe25c7SJing Huang /*
3316a36c61f9SKrishna Gudipati  * Called to initialize port attributes
3317a36c61f9SKrishna Gudipati  */
3318a36c61f9SKrishna Gudipati void
3319a36c61f9SKrishna Gudipati bfa_fcport_init(struct bfa_s *bfa)
3320a36c61f9SKrishna Gudipati {
3321a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3322a36c61f9SKrishna Gudipati 
33235fbe25c7SJing Huang 	/*
3324a36c61f9SKrishna Gudipati 	 * Initialize port attributes from IOC hardware data.
3325a36c61f9SKrishna Gudipati 	 */
3326a36c61f9SKrishna Gudipati 	bfa_fcport_set_wwns(fcport);
3327a36c61f9SKrishna Gudipati 	if (fcport->cfg.maxfrsize == 0)
3328a36c61f9SKrishna Gudipati 		fcport->cfg.maxfrsize = bfa_ioc_maxfrsize(&bfa->ioc);
3329a36c61f9SKrishna Gudipati 	fcport->cfg.rx_bbcredit = bfa_ioc_rx_bbcredit(&bfa->ioc);
3330a36c61f9SKrishna Gudipati 	fcport->speed_sup = bfa_ioc_speed_sup(&bfa->ioc);
3331a36c61f9SKrishna Gudipati 
3332d4b671c5SJing Huang 	WARN_ON(!fcport->cfg.maxfrsize);
3333d4b671c5SJing Huang 	WARN_ON(!fcport->cfg.rx_bbcredit);
3334d4b671c5SJing Huang 	WARN_ON(!fcport->speed_sup);
3335a36c61f9SKrishna Gudipati }
3336a36c61f9SKrishna Gudipati 
33375fbe25c7SJing Huang /*
3338a36c61f9SKrishna Gudipati  * Firmware message handler.
3339a36c61f9SKrishna Gudipati  */
3340a36c61f9SKrishna Gudipati void
3341a36c61f9SKrishna Gudipati bfa_fcport_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
3342a36c61f9SKrishna Gudipati {
3343a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3344a36c61f9SKrishna Gudipati 	union bfi_fcport_i2h_msg_u i2hmsg;
3345a36c61f9SKrishna Gudipati 
3346a36c61f9SKrishna Gudipati 	i2hmsg.msg = msg;
3347a36c61f9SKrishna Gudipati 	fcport->event_arg.i2hmsg = i2hmsg;
3348a36c61f9SKrishna Gudipati 
3349a36c61f9SKrishna Gudipati 	bfa_trc(bfa, msg->mhdr.msg_id);
3350a36c61f9SKrishna Gudipati 	bfa_trc(bfa, bfa_sm_to_state(hal_port_sm_table, fcport->sm));
3351a36c61f9SKrishna Gudipati 
3352a36c61f9SKrishna Gudipati 	switch (msg->mhdr.msg_id) {
3353a36c61f9SKrishna Gudipati 	case BFI_FCPORT_I2H_ENABLE_RSP:
3354f3a060caSKrishna Gudipati 		if (fcport->msgtag == i2hmsg.penable_rsp->msgtag) {
3355f3a060caSKrishna Gudipati 
3356f3a060caSKrishna Gudipati 			if (fcport->use_flash_cfg) {
3357f3a060caSKrishna Gudipati 				fcport->cfg = i2hmsg.penable_rsp->port_cfg;
3358f3a060caSKrishna Gudipati 				fcport->cfg.maxfrsize =
3359f3a060caSKrishna Gudipati 					cpu_to_be16(fcport->cfg.maxfrsize);
3360f3a060caSKrishna Gudipati 				fcport->cfg.path_tov =
3361f3a060caSKrishna Gudipati 					cpu_to_be16(fcport->cfg.path_tov);
3362f3a060caSKrishna Gudipati 				fcport->cfg.q_depth =
3363f3a060caSKrishna Gudipati 					cpu_to_be16(fcport->cfg.q_depth);
3364f3a060caSKrishna Gudipati 
3365f3a060caSKrishna Gudipati 				if (fcport->cfg.trunked)
3366f3a060caSKrishna Gudipati 					fcport->trunk.attr.state =
3367f3a060caSKrishna Gudipati 						BFA_TRUNK_OFFLINE;
3368f3a060caSKrishna Gudipati 				else
3369f3a060caSKrishna Gudipati 					fcport->trunk.attr.state =
3370f3a060caSKrishna Gudipati 						BFA_TRUNK_DISABLED;
3371f3a060caSKrishna Gudipati 				fcport->use_flash_cfg = BFA_FALSE;
3372f3a060caSKrishna Gudipati 			}
3373f3a060caSKrishna Gudipati 
3374a36c61f9SKrishna Gudipati 			bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
3375f3a060caSKrishna Gudipati 		}
3376a36c61f9SKrishna Gudipati 		break;
3377a36c61f9SKrishna Gudipati 
3378a36c61f9SKrishna Gudipati 	case BFI_FCPORT_I2H_DISABLE_RSP:
3379a36c61f9SKrishna Gudipati 		if (fcport->msgtag == i2hmsg.penable_rsp->msgtag)
3380a36c61f9SKrishna Gudipati 			bfa_sm_send_event(fcport, BFA_FCPORT_SM_FWRSP);
3381a36c61f9SKrishna Gudipati 		break;
3382a36c61f9SKrishna Gudipati 
3383a36c61f9SKrishna Gudipati 	case BFI_FCPORT_I2H_EVENT:
3384a36c61f9SKrishna Gudipati 		if (i2hmsg.event->link_state.linkstate == BFA_PORT_LINKUP)
3385a36c61f9SKrishna Gudipati 			bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKUP);
3386a36c61f9SKrishna Gudipati 		else
3387a36c61f9SKrishna Gudipati 			bfa_sm_send_event(fcport, BFA_FCPORT_SM_LINKDOWN);
3388a36c61f9SKrishna Gudipati 		break;
3389a36c61f9SKrishna Gudipati 
3390a36c61f9SKrishna Gudipati 	case BFI_FCPORT_I2H_TRUNK_SCN:
3391a36c61f9SKrishna Gudipati 		bfa_trunk_scn(fcport, i2hmsg.trunk_scn);
3392a36c61f9SKrishna Gudipati 		break;
3393a36c61f9SKrishna Gudipati 
3394a36c61f9SKrishna Gudipati 	case BFI_FCPORT_I2H_STATS_GET_RSP:
3395a36c61f9SKrishna Gudipati 		/*
3396a36c61f9SKrishna Gudipati 		 * check for timer pop before processing the rsp
3397a36c61f9SKrishna Gudipati 		 */
3398a36c61f9SKrishna Gudipati 		if (fcport->stats_busy == BFA_FALSE ||
3399a36c61f9SKrishna Gudipati 		    fcport->stats_status == BFA_STATUS_ETIMER)
3400a36c61f9SKrishna Gudipati 			break;
3401a36c61f9SKrishna Gudipati 
3402a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fcport->timer);
3403a36c61f9SKrishna Gudipati 		fcport->stats_status = i2hmsg.pstatsget_rsp->status;
3404a36c61f9SKrishna Gudipati 		bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
3405a36c61f9SKrishna Gudipati 				__bfa_cb_fcport_stats_get, fcport);
3406a36c61f9SKrishna Gudipati 		break;
3407a36c61f9SKrishna Gudipati 
3408a36c61f9SKrishna Gudipati 	case BFI_FCPORT_I2H_STATS_CLEAR_RSP:
3409a36c61f9SKrishna Gudipati 		/*
3410a36c61f9SKrishna Gudipati 		 * check for timer pop before processing the rsp
3411a36c61f9SKrishna Gudipati 		 */
3412a36c61f9SKrishna Gudipati 		if (fcport->stats_busy == BFA_FALSE ||
3413a36c61f9SKrishna Gudipati 		    fcport->stats_status == BFA_STATUS_ETIMER)
3414a36c61f9SKrishna Gudipati 			break;
3415a36c61f9SKrishna Gudipati 
3416a36c61f9SKrishna Gudipati 		bfa_timer_stop(&fcport->timer);
3417a36c61f9SKrishna Gudipati 		fcport->stats_status = BFA_STATUS_OK;
3418a36c61f9SKrishna Gudipati 		bfa_cb_queue(fcport->bfa, &fcport->hcb_qe,
3419a36c61f9SKrishna Gudipati 				__bfa_cb_fcport_stats_clr, fcport);
3420a36c61f9SKrishna Gudipati 		break;
3421a36c61f9SKrishna Gudipati 
3422a36c61f9SKrishna Gudipati 	case BFI_FCPORT_I2H_ENABLE_AEN:
3423a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fcport, BFA_FCPORT_SM_ENABLE);
3424a36c61f9SKrishna Gudipati 		break;
3425a36c61f9SKrishna Gudipati 
3426a36c61f9SKrishna Gudipati 	case BFI_FCPORT_I2H_DISABLE_AEN:
3427a36c61f9SKrishna Gudipati 		bfa_sm_send_event(fcport, BFA_FCPORT_SM_DISABLE);
3428a36c61f9SKrishna Gudipati 		break;
3429a36c61f9SKrishna Gudipati 
3430a36c61f9SKrishna Gudipati 	default:
3431d4b671c5SJing Huang 		WARN_ON(1);
3432a36c61f9SKrishna Gudipati 	break;
3433a36c61f9SKrishna Gudipati 	}
3434a36c61f9SKrishna Gudipati }
3435a36c61f9SKrishna Gudipati 
34365fbe25c7SJing Huang /*
3437a36c61f9SKrishna Gudipati  * Registered callback for port events.
3438a36c61f9SKrishna Gudipati  */
3439a36c61f9SKrishna Gudipati void
3440a36c61f9SKrishna Gudipati bfa_fcport_event_register(struct bfa_s *bfa,
3441a36c61f9SKrishna Gudipati 				void (*cbfn) (void *cbarg,
3442a36c61f9SKrishna Gudipati 				enum bfa_port_linkstate event),
3443a36c61f9SKrishna Gudipati 				void *cbarg)
3444a36c61f9SKrishna Gudipati {
3445a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3446a36c61f9SKrishna Gudipati 
3447a36c61f9SKrishna Gudipati 	fcport->event_cbfn = cbfn;
3448a36c61f9SKrishna Gudipati 	fcport->event_cbarg = cbarg;
3449a36c61f9SKrishna Gudipati }
3450a36c61f9SKrishna Gudipati 
3451a36c61f9SKrishna Gudipati bfa_status_t
3452a36c61f9SKrishna Gudipati bfa_fcport_enable(struct bfa_s *bfa)
3453a36c61f9SKrishna Gudipati {
3454a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3455a36c61f9SKrishna Gudipati 
3456a36c61f9SKrishna Gudipati 	if (bfa_ioc_is_disabled(&bfa->ioc))
3457a36c61f9SKrishna Gudipati 		return BFA_STATUS_IOC_DISABLED;
3458a36c61f9SKrishna Gudipati 
3459a36c61f9SKrishna Gudipati 	if (fcport->diag_busy)
3460a36c61f9SKrishna Gudipati 		return BFA_STATUS_DIAG_BUSY;
3461a36c61f9SKrishna Gudipati 
3462a36c61f9SKrishna Gudipati 	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_ENABLE);
3463a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3464a36c61f9SKrishna Gudipati }
3465a36c61f9SKrishna Gudipati 
3466a36c61f9SKrishna Gudipati bfa_status_t
3467a36c61f9SKrishna Gudipati bfa_fcport_disable(struct bfa_s *bfa)
3468a36c61f9SKrishna Gudipati {
3469a36c61f9SKrishna Gudipati 
3470a36c61f9SKrishna Gudipati 	if (bfa_ioc_is_disabled(&bfa->ioc))
3471a36c61f9SKrishna Gudipati 		return BFA_STATUS_IOC_DISABLED;
3472a36c61f9SKrishna Gudipati 
3473a36c61f9SKrishna Gudipati 	bfa_sm_send_event(BFA_FCPORT_MOD(bfa), BFA_FCPORT_SM_DISABLE);
3474a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3475a36c61f9SKrishna Gudipati }
3476a36c61f9SKrishna Gudipati 
34775fbe25c7SJing Huang /*
3478a36c61f9SKrishna Gudipati  * Configure port speed.
3479a36c61f9SKrishna Gudipati  */
3480a36c61f9SKrishna Gudipati bfa_status_t
3481a36c61f9SKrishna Gudipati bfa_fcport_cfg_speed(struct bfa_s *bfa, enum bfa_port_speed speed)
3482a36c61f9SKrishna Gudipati {
3483a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3484a36c61f9SKrishna Gudipati 
3485a36c61f9SKrishna Gudipati 	bfa_trc(bfa, speed);
3486a36c61f9SKrishna Gudipati 
3487a36c61f9SKrishna Gudipati 	if (fcport->cfg.trunked == BFA_TRUE)
3488a36c61f9SKrishna Gudipati 		return BFA_STATUS_TRUNK_ENABLED;
3489a36c61f9SKrishna Gudipati 	if ((speed != BFA_PORT_SPEED_AUTO) && (speed > fcport->speed_sup)) {
3490a36c61f9SKrishna Gudipati 		bfa_trc(bfa, fcport->speed_sup);
3491a36c61f9SKrishna Gudipati 		return BFA_STATUS_UNSUPP_SPEED;
3492a36c61f9SKrishna Gudipati 	}
3493a36c61f9SKrishna Gudipati 
3494a36c61f9SKrishna Gudipati 	fcport->cfg.speed = speed;
3495a36c61f9SKrishna Gudipati 
3496a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3497a36c61f9SKrishna Gudipati }
3498a36c61f9SKrishna Gudipati 
34995fbe25c7SJing Huang /*
3500a36c61f9SKrishna Gudipati  * Get current speed.
3501a36c61f9SKrishna Gudipati  */
3502a36c61f9SKrishna Gudipati enum bfa_port_speed
3503a36c61f9SKrishna Gudipati bfa_fcport_get_speed(struct bfa_s *bfa)
3504a36c61f9SKrishna Gudipati {
3505a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3506a36c61f9SKrishna Gudipati 
3507a36c61f9SKrishna Gudipati 	return fcport->speed;
3508a36c61f9SKrishna Gudipati }
3509a36c61f9SKrishna Gudipati 
35105fbe25c7SJing Huang /*
3511a36c61f9SKrishna Gudipati  * Configure port topology.
3512a36c61f9SKrishna Gudipati  */
3513a36c61f9SKrishna Gudipati bfa_status_t
3514a36c61f9SKrishna Gudipati bfa_fcport_cfg_topology(struct bfa_s *bfa, enum bfa_port_topology topology)
3515a36c61f9SKrishna Gudipati {
3516a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3517a36c61f9SKrishna Gudipati 
3518a36c61f9SKrishna Gudipati 	bfa_trc(bfa, topology);
3519a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcport->cfg.topology);
3520a36c61f9SKrishna Gudipati 
3521a36c61f9SKrishna Gudipati 	switch (topology) {
3522a36c61f9SKrishna Gudipati 	case BFA_PORT_TOPOLOGY_P2P:
3523a36c61f9SKrishna Gudipati 	case BFA_PORT_TOPOLOGY_LOOP:
3524a36c61f9SKrishna Gudipati 	case BFA_PORT_TOPOLOGY_AUTO:
3525a36c61f9SKrishna Gudipati 		break;
3526a36c61f9SKrishna Gudipati 
3527a36c61f9SKrishna Gudipati 	default:
3528a36c61f9SKrishna Gudipati 		return BFA_STATUS_EINVAL;
3529a36c61f9SKrishna Gudipati 	}
3530a36c61f9SKrishna Gudipati 
3531a36c61f9SKrishna Gudipati 	fcport->cfg.topology = topology;
3532a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3533a36c61f9SKrishna Gudipati }
3534a36c61f9SKrishna Gudipati 
35355fbe25c7SJing Huang /*
3536a36c61f9SKrishna Gudipati  * Get current topology.
3537a36c61f9SKrishna Gudipati  */
3538a36c61f9SKrishna Gudipati enum bfa_port_topology
3539a36c61f9SKrishna Gudipati bfa_fcport_get_topology(struct bfa_s *bfa)
3540a36c61f9SKrishna Gudipati {
3541a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3542a36c61f9SKrishna Gudipati 
3543a36c61f9SKrishna Gudipati 	return fcport->topology;
3544a36c61f9SKrishna Gudipati }
3545a36c61f9SKrishna Gudipati 
3546a36c61f9SKrishna Gudipati bfa_status_t
3547a36c61f9SKrishna Gudipati bfa_fcport_cfg_hardalpa(struct bfa_s *bfa, u8 alpa)
3548a36c61f9SKrishna Gudipati {
3549a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3550a36c61f9SKrishna Gudipati 
3551a36c61f9SKrishna Gudipati 	bfa_trc(bfa, alpa);
3552a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
3553a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcport->cfg.hardalpa);
3554a36c61f9SKrishna Gudipati 
3555a36c61f9SKrishna Gudipati 	fcport->cfg.cfg_hardalpa = BFA_TRUE;
3556a36c61f9SKrishna Gudipati 	fcport->cfg.hardalpa = alpa;
3557a36c61f9SKrishna Gudipati 
3558a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3559a36c61f9SKrishna Gudipati }
3560a36c61f9SKrishna Gudipati 
3561a36c61f9SKrishna Gudipati bfa_status_t
3562a36c61f9SKrishna Gudipati bfa_fcport_clr_hardalpa(struct bfa_s *bfa)
3563a36c61f9SKrishna Gudipati {
3564a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3565a36c61f9SKrishna Gudipati 
3566a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcport->cfg.cfg_hardalpa);
3567a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcport->cfg.hardalpa);
3568a36c61f9SKrishna Gudipati 
3569a36c61f9SKrishna Gudipati 	fcport->cfg.cfg_hardalpa = BFA_FALSE;
3570a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3571a36c61f9SKrishna Gudipati }
3572a36c61f9SKrishna Gudipati 
3573a36c61f9SKrishna Gudipati bfa_boolean_t
3574a36c61f9SKrishna Gudipati bfa_fcport_get_hardalpa(struct bfa_s *bfa, u8 *alpa)
3575a36c61f9SKrishna Gudipati {
3576a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3577a36c61f9SKrishna Gudipati 
3578a36c61f9SKrishna Gudipati 	*alpa = fcport->cfg.hardalpa;
3579a36c61f9SKrishna Gudipati 	return fcport->cfg.cfg_hardalpa;
3580a36c61f9SKrishna Gudipati }
3581a36c61f9SKrishna Gudipati 
3582a36c61f9SKrishna Gudipati u8
3583a36c61f9SKrishna Gudipati bfa_fcport_get_myalpa(struct bfa_s *bfa)
3584a36c61f9SKrishna Gudipati {
3585a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3586a36c61f9SKrishna Gudipati 
3587a36c61f9SKrishna Gudipati 	return fcport->myalpa;
3588a36c61f9SKrishna Gudipati }
3589a36c61f9SKrishna Gudipati 
3590a36c61f9SKrishna Gudipati bfa_status_t
3591a36c61f9SKrishna Gudipati bfa_fcport_cfg_maxfrsize(struct bfa_s *bfa, u16 maxfrsize)
3592a36c61f9SKrishna Gudipati {
3593a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3594a36c61f9SKrishna Gudipati 
3595a36c61f9SKrishna Gudipati 	bfa_trc(bfa, maxfrsize);
3596a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcport->cfg.maxfrsize);
3597a36c61f9SKrishna Gudipati 
3598a36c61f9SKrishna Gudipati 	/* with in range */
3599a36c61f9SKrishna Gudipati 	if ((maxfrsize > FC_MAX_PDUSZ) || (maxfrsize < FC_MIN_PDUSZ))
3600a36c61f9SKrishna Gudipati 		return BFA_STATUS_INVLD_DFSZ;
3601a36c61f9SKrishna Gudipati 
3602a36c61f9SKrishna Gudipati 	/* power of 2, if not the max frame size of 2112 */
3603a36c61f9SKrishna Gudipati 	if ((maxfrsize != FC_MAX_PDUSZ) && (maxfrsize & (maxfrsize - 1)))
3604a36c61f9SKrishna Gudipati 		return BFA_STATUS_INVLD_DFSZ;
3605a36c61f9SKrishna Gudipati 
3606a36c61f9SKrishna Gudipati 	fcport->cfg.maxfrsize = maxfrsize;
3607a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3608a36c61f9SKrishna Gudipati }
3609a36c61f9SKrishna Gudipati 
3610a36c61f9SKrishna Gudipati u16
3611a36c61f9SKrishna Gudipati bfa_fcport_get_maxfrsize(struct bfa_s *bfa)
3612a36c61f9SKrishna Gudipati {
3613a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3614a36c61f9SKrishna Gudipati 
3615a36c61f9SKrishna Gudipati 	return fcport->cfg.maxfrsize;
3616a36c61f9SKrishna Gudipati }
3617a36c61f9SKrishna Gudipati 
3618a36c61f9SKrishna Gudipati u8
3619a36c61f9SKrishna Gudipati bfa_fcport_get_rx_bbcredit(struct bfa_s *bfa)
3620a36c61f9SKrishna Gudipati {
3621a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3622a36c61f9SKrishna Gudipati 
3623a36c61f9SKrishna Gudipati 	return fcport->cfg.rx_bbcredit;
3624a36c61f9SKrishna Gudipati }
3625a36c61f9SKrishna Gudipati 
3626a36c61f9SKrishna Gudipati void
3627a36c61f9SKrishna Gudipati bfa_fcport_set_tx_bbcredit(struct bfa_s *bfa, u16 tx_bbcredit)
3628a36c61f9SKrishna Gudipati {
3629a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3630a36c61f9SKrishna Gudipati 
3631a36c61f9SKrishna Gudipati 	fcport->cfg.tx_bbcredit = (u8)tx_bbcredit;
3632a36c61f9SKrishna Gudipati 	bfa_fcport_send_txcredit(fcport);
3633a36c61f9SKrishna Gudipati }
3634a36c61f9SKrishna Gudipati 
36355fbe25c7SJing Huang /*
3636a36c61f9SKrishna Gudipati  * Get port attributes.
3637a36c61f9SKrishna Gudipati  */
3638a36c61f9SKrishna Gudipati 
3639a36c61f9SKrishna Gudipati wwn_t
3640a36c61f9SKrishna Gudipati bfa_fcport_get_wwn(struct bfa_s *bfa, bfa_boolean_t node)
3641a36c61f9SKrishna Gudipati {
3642a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3643a36c61f9SKrishna Gudipati 	if (node)
3644a36c61f9SKrishna Gudipati 		return fcport->nwwn;
3645a36c61f9SKrishna Gudipati 	else
3646a36c61f9SKrishna Gudipati 		return fcport->pwwn;
3647a36c61f9SKrishna Gudipati }
3648a36c61f9SKrishna Gudipati 
3649a36c61f9SKrishna Gudipati void
3650a36c61f9SKrishna Gudipati bfa_fcport_get_attr(struct bfa_s *bfa, struct bfa_port_attr_s *attr)
3651a36c61f9SKrishna Gudipati {
3652a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3653a36c61f9SKrishna Gudipati 
36546a18b167SJing Huang 	memset(attr, 0, sizeof(struct bfa_port_attr_s));
3655a36c61f9SKrishna Gudipati 
3656a36c61f9SKrishna Gudipati 	attr->nwwn = fcport->nwwn;
3657a36c61f9SKrishna Gudipati 	attr->pwwn = fcport->pwwn;
3658a36c61f9SKrishna Gudipati 
3659f7f73812SMaggie Zhang 	attr->factorypwwn =  bfa->ioc.attr->mfg_pwwn;
3660f7f73812SMaggie Zhang 	attr->factorynwwn =  bfa->ioc.attr->mfg_nwwn;
3661a36c61f9SKrishna Gudipati 
36626a18b167SJing Huang 	memcpy(&attr->pport_cfg, &fcport->cfg,
3663a36c61f9SKrishna Gudipati 		sizeof(struct bfa_port_cfg_s));
3664a36c61f9SKrishna Gudipati 	/* speed attributes */
3665a36c61f9SKrishna Gudipati 	attr->pport_cfg.speed = fcport->cfg.speed;
3666a36c61f9SKrishna Gudipati 	attr->speed_supported = fcport->speed_sup;
3667a36c61f9SKrishna Gudipati 	attr->speed = fcport->speed;
3668a36c61f9SKrishna Gudipati 	attr->cos_supported = FC_CLASS_3;
3669a36c61f9SKrishna Gudipati 
3670a36c61f9SKrishna Gudipati 	/* topology attributes */
3671a36c61f9SKrishna Gudipati 	attr->pport_cfg.topology = fcport->cfg.topology;
3672a36c61f9SKrishna Gudipati 	attr->topology = fcport->topology;
3673a36c61f9SKrishna Gudipati 	attr->pport_cfg.trunked = fcport->cfg.trunked;
3674a36c61f9SKrishna Gudipati 
3675a36c61f9SKrishna Gudipati 	/* beacon attributes */
3676a36c61f9SKrishna Gudipati 	attr->beacon = fcport->beacon;
3677a36c61f9SKrishna Gudipati 	attr->link_e2e_beacon = fcport->link_e2e_beacon;
3678f7f73812SMaggie Zhang 	attr->plog_enabled = (bfa_boolean_t)fcport->bfa->plog->plog_enabled;
3679a36c61f9SKrishna Gudipati 	attr->io_profile = bfa_fcpim_get_io_profile(fcport->bfa);
3680a36c61f9SKrishna Gudipati 
3681a36c61f9SKrishna Gudipati 	attr->pport_cfg.path_tov  = bfa_fcpim_path_tov_get(bfa);
3682a36c61f9SKrishna Gudipati 	attr->pport_cfg.q_depth  = bfa_fcpim_qdepth_get(bfa);
3683a36c61f9SKrishna Gudipati 	attr->port_state = bfa_sm_to_state(hal_port_sm_table, fcport->sm);
3684a36c61f9SKrishna Gudipati 	if (bfa_ioc_is_disabled(&fcport->bfa->ioc))
3685a36c61f9SKrishna Gudipati 		attr->port_state = BFA_PORT_ST_IOCDIS;
3686a36c61f9SKrishna Gudipati 	else if (bfa_ioc_fw_mismatch(&fcport->bfa->ioc))
3687a36c61f9SKrishna Gudipati 		attr->port_state = BFA_PORT_ST_FWMISMATCH;
3688a36c61f9SKrishna Gudipati 
3689a36c61f9SKrishna Gudipati 	/* FCoE vlan */
3690a36c61f9SKrishna Gudipati 	attr->fcoe_vlan = fcport->fcoe_vlan;
3691a36c61f9SKrishna Gudipati }
3692a36c61f9SKrishna Gudipati 
3693a36c61f9SKrishna Gudipati #define BFA_FCPORT_STATS_TOV	1000
3694a36c61f9SKrishna Gudipati 
36955fbe25c7SJing Huang /*
3696a36c61f9SKrishna Gudipati  * Fetch port statistics (FCQoS or FCoE).
3697a36c61f9SKrishna Gudipati  */
3698a36c61f9SKrishna Gudipati bfa_status_t
3699a36c61f9SKrishna Gudipati bfa_fcport_get_stats(struct bfa_s *bfa, union bfa_fcport_stats_u *stats,
3700a36c61f9SKrishna Gudipati 	bfa_cb_port_t cbfn, void *cbarg)
3701a36c61f9SKrishna Gudipati {
3702a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3703a36c61f9SKrishna Gudipati 
3704a36c61f9SKrishna Gudipati 	if (fcport->stats_busy) {
3705a36c61f9SKrishna Gudipati 		bfa_trc(bfa, fcport->stats_busy);
3706a36c61f9SKrishna Gudipati 		return BFA_STATUS_DEVBUSY;
3707a36c61f9SKrishna Gudipati 	}
3708a36c61f9SKrishna Gudipati 
3709a36c61f9SKrishna Gudipati 	fcport->stats_busy  = BFA_TRUE;
3710a36c61f9SKrishna Gudipati 	fcport->stats_ret   = stats;
3711a36c61f9SKrishna Gudipati 	fcport->stats_cbfn  = cbfn;
3712a36c61f9SKrishna Gudipati 	fcport->stats_cbarg = cbarg;
3713a36c61f9SKrishna Gudipati 
3714a36c61f9SKrishna Gudipati 	bfa_fcport_send_stats_get(fcport);
3715a36c61f9SKrishna Gudipati 
3716a36c61f9SKrishna Gudipati 	bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_get_timeout,
3717a36c61f9SKrishna Gudipati 			fcport, BFA_FCPORT_STATS_TOV);
3718a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3719a36c61f9SKrishna Gudipati }
3720a36c61f9SKrishna Gudipati 
37215fbe25c7SJing Huang /*
3722a36c61f9SKrishna Gudipati  * Reset port statistics (FCQoS or FCoE).
3723a36c61f9SKrishna Gudipati  */
3724a36c61f9SKrishna Gudipati bfa_status_t
3725a36c61f9SKrishna Gudipati bfa_fcport_clear_stats(struct bfa_s *bfa, bfa_cb_port_t cbfn, void *cbarg)
3726a36c61f9SKrishna Gudipati {
3727a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3728a36c61f9SKrishna Gudipati 
3729a36c61f9SKrishna Gudipati 	if (fcport->stats_busy) {
3730a36c61f9SKrishna Gudipati 		bfa_trc(bfa, fcport->stats_busy);
3731a36c61f9SKrishna Gudipati 		return BFA_STATUS_DEVBUSY;
3732a36c61f9SKrishna Gudipati 	}
3733a36c61f9SKrishna Gudipati 
3734a36c61f9SKrishna Gudipati 	fcport->stats_busy  = BFA_TRUE;
3735a36c61f9SKrishna Gudipati 	fcport->stats_cbfn  = cbfn;
3736a36c61f9SKrishna Gudipati 	fcport->stats_cbarg = cbarg;
3737a36c61f9SKrishna Gudipati 
3738a36c61f9SKrishna Gudipati 	bfa_fcport_send_stats_clear(fcport);
3739a36c61f9SKrishna Gudipati 
3740a36c61f9SKrishna Gudipati 	bfa_timer_start(bfa, &fcport->timer, bfa_fcport_stats_clr_timeout,
3741a36c61f9SKrishna Gudipati 			fcport, BFA_FCPORT_STATS_TOV);
3742a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
3743a36c61f9SKrishna Gudipati }
3744a36c61f9SKrishna Gudipati 
3745a36c61f9SKrishna Gudipati 
37465fbe25c7SJing Huang /*
3747a36c61f9SKrishna Gudipati  * Fetch port attributes.
3748a36c61f9SKrishna Gudipati  */
3749a36c61f9SKrishna Gudipati bfa_boolean_t
3750a36c61f9SKrishna Gudipati bfa_fcport_is_disabled(struct bfa_s *bfa)
3751a36c61f9SKrishna Gudipati {
3752a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3753a36c61f9SKrishna Gudipati 
3754a36c61f9SKrishna Gudipati 	return bfa_sm_to_state(hal_port_sm_table, fcport->sm) ==
3755a36c61f9SKrishna Gudipati 		BFA_PORT_ST_DISABLED;
3756a36c61f9SKrishna Gudipati 
3757a36c61f9SKrishna Gudipati }
3758a36c61f9SKrishna Gudipati 
3759a36c61f9SKrishna Gudipati bfa_boolean_t
3760a36c61f9SKrishna Gudipati bfa_fcport_is_ratelim(struct bfa_s *bfa)
3761a36c61f9SKrishna Gudipati {
3762a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3763a36c61f9SKrishna Gudipati 
3764a36c61f9SKrishna Gudipati 	return fcport->cfg.ratelimit ? BFA_TRUE : BFA_FALSE;
3765a36c61f9SKrishna Gudipati 
3766a36c61f9SKrishna Gudipati }
3767a36c61f9SKrishna Gudipati 
37685fbe25c7SJing Huang /*
3769a36c61f9SKrishna Gudipati  * Get default minimum ratelim speed
3770a36c61f9SKrishna Gudipati  */
3771a36c61f9SKrishna Gudipati enum bfa_port_speed
3772a36c61f9SKrishna Gudipati bfa_fcport_get_ratelim_speed(struct bfa_s *bfa)
3773a36c61f9SKrishna Gudipati {
3774a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3775a36c61f9SKrishna Gudipati 
3776a36c61f9SKrishna Gudipati 	bfa_trc(bfa, fcport->cfg.trl_def_speed);
3777a36c61f9SKrishna Gudipati 	return fcport->cfg.trl_def_speed;
3778a36c61f9SKrishna Gudipati 
3779a36c61f9SKrishna Gudipati }
3780a36c61f9SKrishna Gudipati 
3781a36c61f9SKrishna Gudipati bfa_boolean_t
3782a36c61f9SKrishna Gudipati bfa_fcport_is_linkup(struct bfa_s *bfa)
3783a36c61f9SKrishna Gudipati {
3784a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3785a36c61f9SKrishna Gudipati 
3786a36c61f9SKrishna Gudipati 	return	(!fcport->cfg.trunked &&
3787a36c61f9SKrishna Gudipati 		 bfa_sm_cmp_state(fcport, bfa_fcport_sm_linkup)) ||
3788a36c61f9SKrishna Gudipati 		(fcport->cfg.trunked &&
3789a36c61f9SKrishna Gudipati 		 fcport->trunk.attr.state == BFA_TRUNK_ONLINE);
3790a36c61f9SKrishna Gudipati }
3791a36c61f9SKrishna Gudipati 
3792a36c61f9SKrishna Gudipati bfa_boolean_t
3793a36c61f9SKrishna Gudipati bfa_fcport_is_qos_enabled(struct bfa_s *bfa)
3794a36c61f9SKrishna Gudipati {
3795a36c61f9SKrishna Gudipati 	struct bfa_fcport_s *fcport = BFA_FCPORT_MOD(bfa);
3796a36c61f9SKrishna Gudipati 
3797a36c61f9SKrishna Gudipati 	return fcport->cfg.qos_enabled;
3798a36c61f9SKrishna Gudipati }
3799a36c61f9SKrishna Gudipati 
38005fbe25c7SJing Huang /*
3801a36c61f9SKrishna Gudipati  * Rport State machine functions
3802a36c61f9SKrishna Gudipati  */
38035fbe25c7SJing Huang /*
3804a36c61f9SKrishna Gudipati  * Beginning state, only online event expected.
3805a36c61f9SKrishna Gudipati  */
3806a36c61f9SKrishna Gudipati static void
3807a36c61f9SKrishna Gudipati bfa_rport_sm_uninit(struct bfa_rport_s *rp, enum bfa_rport_event event)
3808a36c61f9SKrishna Gudipati {
3809a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
3810a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
3811a36c61f9SKrishna Gudipati 
3812a36c61f9SKrishna Gudipati 	switch (event) {
3813a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_CREATE:
3814a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_un_cr);
3815a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_created);
3816a36c61f9SKrishna Gudipati 		break;
3817a36c61f9SKrishna Gudipati 
3818a36c61f9SKrishna Gudipati 	default:
3819a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_un_unexp);
3820a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
3821a36c61f9SKrishna Gudipati 	}
3822a36c61f9SKrishna Gudipati }
3823a36c61f9SKrishna Gudipati 
3824a36c61f9SKrishna Gudipati static void
3825a36c61f9SKrishna Gudipati bfa_rport_sm_created(struct bfa_rport_s *rp, enum bfa_rport_event event)
3826a36c61f9SKrishna Gudipati {
3827a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
3828a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
3829a36c61f9SKrishna Gudipati 
3830a36c61f9SKrishna Gudipati 	switch (event) {
3831a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_ONLINE:
3832a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_cr_on);
3833a36c61f9SKrishna Gudipati 		if (bfa_rport_send_fwcreate(rp))
3834a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
3835a36c61f9SKrishna Gudipati 		else
3836a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
3837a36c61f9SKrishna Gudipati 		break;
3838a36c61f9SKrishna Gudipati 
3839a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
3840a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_cr_del);
3841a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
3842a36c61f9SKrishna Gudipati 		bfa_rport_free(rp);
3843a36c61f9SKrishna Gudipati 		break;
3844a36c61f9SKrishna Gudipati 
3845a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
3846a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_cr_hwf);
3847a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
3848a36c61f9SKrishna Gudipati 		break;
3849a36c61f9SKrishna Gudipati 
3850a36c61f9SKrishna Gudipati 	default:
3851a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_cr_unexp);
3852a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
3853a36c61f9SKrishna Gudipati 	}
3854a36c61f9SKrishna Gudipati }
3855a36c61f9SKrishna Gudipati 
38565fbe25c7SJing Huang /*
3857a36c61f9SKrishna Gudipati  * Waiting for rport create response from firmware.
3858a36c61f9SKrishna Gudipati  */
3859a36c61f9SKrishna Gudipati static void
3860a36c61f9SKrishna Gudipati bfa_rport_sm_fwcreate(struct bfa_rport_s *rp, enum bfa_rport_event event)
3861a36c61f9SKrishna Gudipati {
3862a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
3863a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
3864a36c61f9SKrishna Gudipati 
3865a36c61f9SKrishna Gudipati 	switch (event) {
3866a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_FWRSP:
3867a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_rsp);
3868a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_online);
3869a36c61f9SKrishna Gudipati 		bfa_rport_online_cb(rp);
3870a36c61f9SKrishna Gudipati 		break;
3871a36c61f9SKrishna Gudipati 
3872a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
3873a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_del);
3874a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_delete_pending);
3875a36c61f9SKrishna Gudipati 		break;
3876a36c61f9SKrishna Gudipati 
3877a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_OFFLINE:
3878a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_off);
3879a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_offline_pending);
3880a36c61f9SKrishna Gudipati 		break;
3881a36c61f9SKrishna Gudipati 
3882a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
3883a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_hwf);
3884a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
3885a36c61f9SKrishna Gudipati 		break;
3886a36c61f9SKrishna Gudipati 
3887a36c61f9SKrishna Gudipati 	default:
3888a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_unexp);
3889a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
3890a36c61f9SKrishna Gudipati 	}
3891a36c61f9SKrishna Gudipati }
3892a36c61f9SKrishna Gudipati 
38935fbe25c7SJing Huang /*
3894a36c61f9SKrishna Gudipati  * Request queue is full, awaiting queue resume to send create request.
3895a36c61f9SKrishna Gudipati  */
3896a36c61f9SKrishna Gudipati static void
3897a36c61f9SKrishna Gudipati bfa_rport_sm_fwcreate_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
3898a36c61f9SKrishna Gudipati {
3899a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
3900a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
3901a36c61f9SKrishna Gudipati 
3902a36c61f9SKrishna Gudipati 	switch (event) {
3903a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_QRESUME:
3904a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
3905a36c61f9SKrishna Gudipati 		bfa_rport_send_fwcreate(rp);
3906a36c61f9SKrishna Gudipati 		break;
3907a36c61f9SKrishna Gudipati 
3908a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
3909a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_del);
3910a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
3911a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&rp->reqq_wait);
3912a36c61f9SKrishna Gudipati 		bfa_rport_free(rp);
3913a36c61f9SKrishna Gudipati 		break;
3914a36c61f9SKrishna Gudipati 
3915a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_OFFLINE:
3916a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_off);
3917a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_offline);
3918a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&rp->reqq_wait);
3919a36c61f9SKrishna Gudipati 		bfa_rport_offline_cb(rp);
3920a36c61f9SKrishna Gudipati 		break;
3921a36c61f9SKrishna Gudipati 
3922a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
3923a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_hwf);
3924a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
3925a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&rp->reqq_wait);
3926a36c61f9SKrishna Gudipati 		break;
3927a36c61f9SKrishna Gudipati 
3928a36c61f9SKrishna Gudipati 	default:
3929a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwc_unexp);
3930a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
3931a36c61f9SKrishna Gudipati 	}
3932a36c61f9SKrishna Gudipati }
3933a36c61f9SKrishna Gudipati 
39345fbe25c7SJing Huang /*
3935a36c61f9SKrishna Gudipati  * Online state - normal parking state.
3936a36c61f9SKrishna Gudipati  */
3937a36c61f9SKrishna Gudipati static void
3938a36c61f9SKrishna Gudipati bfa_rport_sm_online(struct bfa_rport_s *rp, enum bfa_rport_event event)
3939a36c61f9SKrishna Gudipati {
3940a36c61f9SKrishna Gudipati 	struct bfi_rport_qos_scn_s *qos_scn;
3941a36c61f9SKrishna Gudipati 
3942a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
3943a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
3944a36c61f9SKrishna Gudipati 
3945a36c61f9SKrishna Gudipati 	switch (event) {
3946a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_OFFLINE:
3947a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_on_off);
3948a36c61f9SKrishna Gudipati 		if (bfa_rport_send_fwdelete(rp))
3949a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
3950a36c61f9SKrishna Gudipati 		else
3951a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull);
3952a36c61f9SKrishna Gudipati 		break;
3953a36c61f9SKrishna Gudipati 
3954a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
3955a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_on_del);
3956a36c61f9SKrishna Gudipati 		if (bfa_rport_send_fwdelete(rp))
3957a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_deleting);
3958a36c61f9SKrishna Gudipati 		else
3959a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
3960a36c61f9SKrishna Gudipati 		break;
3961a36c61f9SKrishna Gudipati 
3962a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
3963a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_on_hwf);
3964a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
3965a36c61f9SKrishna Gudipati 		break;
3966a36c61f9SKrishna Gudipati 
3967a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_SET_SPEED:
3968a36c61f9SKrishna Gudipati 		bfa_rport_send_fwspeed(rp);
3969a36c61f9SKrishna Gudipati 		break;
3970a36c61f9SKrishna Gudipati 
3971a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_QOS_SCN:
3972a36c61f9SKrishna Gudipati 		qos_scn = (struct bfi_rport_qos_scn_s *) rp->event_arg.fw_msg;
3973a36c61f9SKrishna Gudipati 		rp->qos_attr = qos_scn->new_qos_attr;
3974a36c61f9SKrishna Gudipati 		bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_flow_id);
3975a36c61f9SKrishna Gudipati 		bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_flow_id);
3976a36c61f9SKrishna Gudipati 		bfa_trc(rp->bfa, qos_scn->old_qos_attr.qos_priority);
3977a36c61f9SKrishna Gudipati 		bfa_trc(rp->bfa, qos_scn->new_qos_attr.qos_priority);
3978a36c61f9SKrishna Gudipati 
3979a36c61f9SKrishna Gudipati 		qos_scn->old_qos_attr.qos_flow_id  =
3980ba816ea8SJing Huang 			be32_to_cpu(qos_scn->old_qos_attr.qos_flow_id);
3981a36c61f9SKrishna Gudipati 		qos_scn->new_qos_attr.qos_flow_id  =
3982ba816ea8SJing Huang 			be32_to_cpu(qos_scn->new_qos_attr.qos_flow_id);
3983a36c61f9SKrishna Gudipati 
3984a36c61f9SKrishna Gudipati 		if (qos_scn->old_qos_attr.qos_flow_id !=
3985a36c61f9SKrishna Gudipati 			qos_scn->new_qos_attr.qos_flow_id)
3986a36c61f9SKrishna Gudipati 			bfa_cb_rport_qos_scn_flowid(rp->rport_drv,
3987a36c61f9SKrishna Gudipati 						    qos_scn->old_qos_attr,
3988a36c61f9SKrishna Gudipati 						    qos_scn->new_qos_attr);
3989a36c61f9SKrishna Gudipati 		if (qos_scn->old_qos_attr.qos_priority !=
3990a36c61f9SKrishna Gudipati 			qos_scn->new_qos_attr.qos_priority)
3991a36c61f9SKrishna Gudipati 			bfa_cb_rport_qos_scn_prio(rp->rport_drv,
3992a36c61f9SKrishna Gudipati 						  qos_scn->old_qos_attr,
3993a36c61f9SKrishna Gudipati 						  qos_scn->new_qos_attr);
3994a36c61f9SKrishna Gudipati 		break;
3995a36c61f9SKrishna Gudipati 
3996a36c61f9SKrishna Gudipati 	default:
3997a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_on_unexp);
3998a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
3999a36c61f9SKrishna Gudipati 	}
4000a36c61f9SKrishna Gudipati }
4001a36c61f9SKrishna Gudipati 
40025fbe25c7SJing Huang /*
4003a36c61f9SKrishna Gudipati  * Firmware rport is being deleted - awaiting f/w response.
4004a36c61f9SKrishna Gudipati  */
4005a36c61f9SKrishna Gudipati static void
4006a36c61f9SKrishna Gudipati bfa_rport_sm_fwdelete(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_fwd_rsp);
4014a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_offline);
4015a36c61f9SKrishna Gudipati 		bfa_rport_offline_cb(rp);
4016a36c61f9SKrishna Gudipati 		break;
4017a36c61f9SKrishna Gudipati 
4018a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
4019a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwd_del);
4020a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_deleting);
4021a36c61f9SKrishna Gudipati 		break;
4022a36c61f9SKrishna Gudipati 
4023a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4024a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwd_hwf);
4025a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
4026a36c61f9SKrishna Gudipati 		bfa_rport_offline_cb(rp);
4027a36c61f9SKrishna Gudipati 		break;
4028a36c61f9SKrishna Gudipati 
4029a36c61f9SKrishna Gudipati 	default:
4030a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwd_unexp);
4031a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4032a36c61f9SKrishna Gudipati 	}
4033a36c61f9SKrishna Gudipati }
4034a36c61f9SKrishna Gudipati 
4035a36c61f9SKrishna Gudipati static void
4036a36c61f9SKrishna Gudipati bfa_rport_sm_fwdelete_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
4037a36c61f9SKrishna Gudipati {
4038a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4039a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4040a36c61f9SKrishna Gudipati 
4041a36c61f9SKrishna Gudipati 	switch (event) {
4042a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_QRESUME:
4043a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
4044a36c61f9SKrishna Gudipati 		bfa_rport_send_fwdelete(rp);
4045a36c61f9SKrishna Gudipati 		break;
4046a36c61f9SKrishna Gudipati 
4047a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
4048a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwd_del);
4049a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
4050a36c61f9SKrishna Gudipati 		break;
4051a36c61f9SKrishna Gudipati 
4052a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4053a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwd_hwf);
4054a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
4055a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&rp->reqq_wait);
4056a36c61f9SKrishna Gudipati 		bfa_rport_offline_cb(rp);
4057a36c61f9SKrishna Gudipati 		break;
4058a36c61f9SKrishna Gudipati 
4059a36c61f9SKrishna Gudipati 	default:
4060a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_fwd_unexp);
4061a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4062a36c61f9SKrishna Gudipati 	}
4063a36c61f9SKrishna Gudipati }
4064a36c61f9SKrishna Gudipati 
40655fbe25c7SJing Huang /*
4066a36c61f9SKrishna Gudipati  * Offline state.
4067a36c61f9SKrishna Gudipati  */
4068a36c61f9SKrishna Gudipati static void
4069a36c61f9SKrishna Gudipati bfa_rport_sm_offline(struct bfa_rport_s *rp, enum bfa_rport_event event)
4070a36c61f9SKrishna Gudipati {
4071a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4072a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4073a36c61f9SKrishna Gudipati 
4074a36c61f9SKrishna Gudipati 	switch (event) {
4075a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
4076a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_off_del);
4077a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
4078a36c61f9SKrishna Gudipati 		bfa_rport_free(rp);
4079a36c61f9SKrishna Gudipati 		break;
4080a36c61f9SKrishna Gudipati 
4081a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_ONLINE:
4082a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_off_on);
4083a36c61f9SKrishna Gudipati 		if (bfa_rport_send_fwcreate(rp))
4084a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
4085a36c61f9SKrishna Gudipati 		else
4086a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
4087a36c61f9SKrishna Gudipati 		break;
4088a36c61f9SKrishna Gudipati 
4089a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4090a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_off_hwf);
4091a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
4092a36c61f9SKrishna Gudipati 		break;
4093a36c61f9SKrishna Gudipati 
4094a36c61f9SKrishna Gudipati 	default:
4095a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_off_unexp);
4096a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4097a36c61f9SKrishna Gudipati 	}
4098a36c61f9SKrishna Gudipati }
4099a36c61f9SKrishna Gudipati 
41005fbe25c7SJing Huang /*
4101a36c61f9SKrishna Gudipati  * Rport is deleted, waiting for firmware response to delete.
4102a36c61f9SKrishna Gudipati  */
4103a36c61f9SKrishna Gudipati static void
4104a36c61f9SKrishna Gudipati bfa_rport_sm_deleting(struct bfa_rport_s *rp, enum bfa_rport_event event)
4105a36c61f9SKrishna Gudipati {
4106a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4107a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4108a36c61f9SKrishna Gudipati 
4109a36c61f9SKrishna Gudipati 	switch (event) {
4110a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_FWRSP:
4111a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_del_fwrsp);
4112a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
4113a36c61f9SKrishna Gudipati 		bfa_rport_free(rp);
4114a36c61f9SKrishna Gudipati 		break;
4115a36c61f9SKrishna Gudipati 
4116a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4117a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_del_hwf);
4118a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
4119a36c61f9SKrishna Gudipati 		bfa_rport_free(rp);
4120a36c61f9SKrishna Gudipati 		break;
4121a36c61f9SKrishna Gudipati 
4122a36c61f9SKrishna Gudipati 	default:
4123a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4124a36c61f9SKrishna Gudipati 	}
4125a36c61f9SKrishna Gudipati }
4126a36c61f9SKrishna Gudipati 
4127a36c61f9SKrishna Gudipati static void
4128a36c61f9SKrishna Gudipati bfa_rport_sm_deleting_qfull(struct bfa_rport_s *rp, enum bfa_rport_event event)
4129a36c61f9SKrishna Gudipati {
4130a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4131a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4132a36c61f9SKrishna Gudipati 
4133a36c61f9SKrishna Gudipati 	switch (event) {
4134a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_QRESUME:
4135a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_del_fwrsp);
4136a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_deleting);
4137a36c61f9SKrishna Gudipati 		bfa_rport_send_fwdelete(rp);
4138a36c61f9SKrishna Gudipati 		break;
4139a36c61f9SKrishna Gudipati 
4140a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4141a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_del_hwf);
4142a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
4143a36c61f9SKrishna Gudipati 		bfa_reqq_wcancel(&rp->reqq_wait);
4144a36c61f9SKrishna Gudipati 		bfa_rport_free(rp);
4145a36c61f9SKrishna Gudipati 		break;
4146a36c61f9SKrishna Gudipati 
4147a36c61f9SKrishna Gudipati 	default:
4148a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4149a36c61f9SKrishna Gudipati 	}
4150a36c61f9SKrishna Gudipati }
4151a36c61f9SKrishna Gudipati 
41525fbe25c7SJing Huang /*
4153a36c61f9SKrishna Gudipati  * Waiting for rport create response from firmware. A delete is pending.
4154a36c61f9SKrishna Gudipati  */
4155a36c61f9SKrishna Gudipati static void
4156a36c61f9SKrishna Gudipati bfa_rport_sm_delete_pending(struct bfa_rport_s *rp,
4157a36c61f9SKrishna Gudipati 				enum bfa_rport_event event)
4158a36c61f9SKrishna Gudipati {
4159a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4160a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4161a36c61f9SKrishna Gudipati 
4162a36c61f9SKrishna Gudipati 	switch (event) {
4163a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_FWRSP:
4164a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_delp_fwrsp);
4165a36c61f9SKrishna Gudipati 		if (bfa_rport_send_fwdelete(rp))
4166a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_deleting);
4167a36c61f9SKrishna Gudipati 		else
4168a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_deleting_qfull);
4169a36c61f9SKrishna Gudipati 		break;
4170a36c61f9SKrishna Gudipati 
4171a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4172a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_delp_hwf);
4173a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
4174a36c61f9SKrishna Gudipati 		bfa_rport_free(rp);
4175a36c61f9SKrishna Gudipati 		break;
4176a36c61f9SKrishna Gudipati 
4177a36c61f9SKrishna Gudipati 	default:
4178a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_delp_unexp);
4179a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4180a36c61f9SKrishna Gudipati 	}
4181a36c61f9SKrishna Gudipati }
4182a36c61f9SKrishna Gudipati 
41835fbe25c7SJing Huang /*
4184a36c61f9SKrishna Gudipati  * Waiting for rport create response from firmware. Rport offline is pending.
4185a36c61f9SKrishna Gudipati  */
4186a36c61f9SKrishna Gudipati static void
4187a36c61f9SKrishna Gudipati bfa_rport_sm_offline_pending(struct bfa_rport_s *rp,
4188a36c61f9SKrishna Gudipati 				 enum bfa_rport_event event)
4189a36c61f9SKrishna Gudipati {
4190a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4191a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4192a36c61f9SKrishna Gudipati 
4193a36c61f9SKrishna Gudipati 	switch (event) {
4194a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_FWRSP:
4195a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_offp_fwrsp);
4196a36c61f9SKrishna Gudipati 		if (bfa_rport_send_fwdelete(rp))
4197a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwdelete);
4198a36c61f9SKrishna Gudipati 		else
4199a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwdelete_qfull);
4200a36c61f9SKrishna Gudipati 		break;
4201a36c61f9SKrishna Gudipati 
4202a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
4203a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_offp_del);
4204a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_delete_pending);
4205a36c61f9SKrishna Gudipati 		break;
4206a36c61f9SKrishna Gudipati 
4207a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4208a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_offp_hwf);
4209a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_iocdisable);
4210a36c61f9SKrishna Gudipati 		break;
4211a36c61f9SKrishna Gudipati 
4212a36c61f9SKrishna Gudipati 	default:
4213a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_offp_unexp);
4214a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4215a36c61f9SKrishna Gudipati 	}
4216a36c61f9SKrishna Gudipati }
4217a36c61f9SKrishna Gudipati 
42185fbe25c7SJing Huang /*
4219a36c61f9SKrishna Gudipati  * IOC h/w failed.
4220a36c61f9SKrishna Gudipati  */
4221a36c61f9SKrishna Gudipati static void
4222a36c61f9SKrishna Gudipati bfa_rport_sm_iocdisable(struct bfa_rport_s *rp, enum bfa_rport_event event)
4223a36c61f9SKrishna Gudipati {
4224a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, rp->rport_tag);
4225a36c61f9SKrishna Gudipati 	bfa_trc(rp->bfa, event);
4226a36c61f9SKrishna Gudipati 
4227a36c61f9SKrishna Gudipati 	switch (event) {
4228a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_OFFLINE:
4229a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_iocd_off);
4230a36c61f9SKrishna Gudipati 		bfa_rport_offline_cb(rp);
4231a36c61f9SKrishna Gudipati 		break;
4232a36c61f9SKrishna Gudipati 
4233a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_DELETE:
4234a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_iocd_del);
4235a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
4236a36c61f9SKrishna Gudipati 		bfa_rport_free(rp);
4237a36c61f9SKrishna Gudipati 		break;
4238a36c61f9SKrishna Gudipati 
4239a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_ONLINE:
4240a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_iocd_on);
4241a36c61f9SKrishna Gudipati 		if (bfa_rport_send_fwcreate(rp))
4242a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwcreate);
4243a36c61f9SKrishna Gudipati 		else
4244a36c61f9SKrishna Gudipati 			bfa_sm_set_state(rp, bfa_rport_sm_fwcreate_qfull);
4245a36c61f9SKrishna Gudipati 		break;
4246a36c61f9SKrishna Gudipati 
4247a36c61f9SKrishna Gudipati 	case BFA_RPORT_SM_HWFAIL:
4248a36c61f9SKrishna Gudipati 		break;
4249a36c61f9SKrishna Gudipati 
4250a36c61f9SKrishna Gudipati 	default:
4251a36c61f9SKrishna Gudipati 		bfa_stats(rp, sm_iocd_unexp);
4252a36c61f9SKrishna Gudipati 		bfa_sm_fault(rp->bfa, event);
4253a36c61f9SKrishna Gudipati 	}
4254a36c61f9SKrishna Gudipati }
4255a36c61f9SKrishna Gudipati 
4256a36c61f9SKrishna Gudipati 
4257a36c61f9SKrishna Gudipati 
42585fbe25c7SJing Huang /*
4259a36c61f9SKrishna Gudipati  *  bfa_rport_private BFA rport private functions
4260a36c61f9SKrishna Gudipati  */
4261a36c61f9SKrishna Gudipati 
4262a36c61f9SKrishna Gudipati static void
4263a36c61f9SKrishna Gudipati __bfa_cb_rport_online(void *cbarg, bfa_boolean_t complete)
4264a36c61f9SKrishna Gudipati {
4265a36c61f9SKrishna Gudipati 	struct bfa_rport_s *rp = cbarg;
4266a36c61f9SKrishna Gudipati 
4267a36c61f9SKrishna Gudipati 	if (complete)
4268a36c61f9SKrishna Gudipati 		bfa_cb_rport_online(rp->rport_drv);
4269a36c61f9SKrishna Gudipati }
4270a36c61f9SKrishna Gudipati 
4271a36c61f9SKrishna Gudipati static void
4272a36c61f9SKrishna Gudipati __bfa_cb_rport_offline(void *cbarg, bfa_boolean_t complete)
4273a36c61f9SKrishna Gudipati {
4274a36c61f9SKrishna Gudipati 	struct bfa_rport_s *rp = cbarg;
4275a36c61f9SKrishna Gudipati 
4276a36c61f9SKrishna Gudipati 	if (complete)
4277a36c61f9SKrishna Gudipati 		bfa_cb_rport_offline(rp->rport_drv);
4278a36c61f9SKrishna Gudipati }
4279a36c61f9SKrishna Gudipati 
4280a36c61f9SKrishna Gudipati static void
4281a36c61f9SKrishna Gudipati bfa_rport_qresume(void *cbarg)
4282a36c61f9SKrishna Gudipati {
4283a36c61f9SKrishna Gudipati 	struct bfa_rport_s	*rp = cbarg;
4284a36c61f9SKrishna Gudipati 
4285a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rp, BFA_RPORT_SM_QRESUME);
4286a36c61f9SKrishna Gudipati }
4287a36c61f9SKrishna Gudipati 
4288a36c61f9SKrishna Gudipati static void
4289a36c61f9SKrishna Gudipati bfa_rport_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
4290a36c61f9SKrishna Gudipati 		u32 *dm_len)
4291a36c61f9SKrishna Gudipati {
4292a36c61f9SKrishna Gudipati 	if (cfg->fwcfg.num_rports < BFA_RPORT_MIN)
4293a36c61f9SKrishna Gudipati 		cfg->fwcfg.num_rports = BFA_RPORT_MIN;
4294a36c61f9SKrishna Gudipati 
4295a36c61f9SKrishna Gudipati 	*km_len += cfg->fwcfg.num_rports * sizeof(struct bfa_rport_s);
4296a36c61f9SKrishna Gudipati }
4297a36c61f9SKrishna Gudipati 
4298a36c61f9SKrishna Gudipati static void
4299a36c61f9SKrishna Gudipati bfa_rport_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
4300a36c61f9SKrishna Gudipati 		     struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
4301a36c61f9SKrishna Gudipati {
4302a36c61f9SKrishna Gudipati 	struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa);
4303a36c61f9SKrishna Gudipati 	struct bfa_rport_s *rp;
4304a36c61f9SKrishna Gudipati 	u16 i;
4305a36c61f9SKrishna Gudipati 
4306a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->rp_free_q);
4307a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->rp_active_q);
4308a36c61f9SKrishna Gudipati 
4309a36c61f9SKrishna Gudipati 	rp = (struct bfa_rport_s *) bfa_meminfo_kva(meminfo);
4310a36c61f9SKrishna Gudipati 	mod->rps_list = rp;
4311a36c61f9SKrishna Gudipati 	mod->num_rports = cfg->fwcfg.num_rports;
4312a36c61f9SKrishna Gudipati 
4313d4b671c5SJing Huang 	WARN_ON(!mod->num_rports ||
4314d4b671c5SJing Huang 		   (mod->num_rports & (mod->num_rports - 1)));
4315a36c61f9SKrishna Gudipati 
4316a36c61f9SKrishna Gudipati 	for (i = 0; i < mod->num_rports; i++, rp++) {
43176a18b167SJing Huang 		memset(rp, 0, sizeof(struct bfa_rport_s));
4318a36c61f9SKrishna Gudipati 		rp->bfa = bfa;
4319a36c61f9SKrishna Gudipati 		rp->rport_tag = i;
4320a36c61f9SKrishna Gudipati 		bfa_sm_set_state(rp, bfa_rport_sm_uninit);
4321a36c61f9SKrishna Gudipati 
43225fbe25c7SJing Huang 		/*
4323a36c61f9SKrishna Gudipati 		 *  - is unused
4324a36c61f9SKrishna Gudipati 		 */
4325a36c61f9SKrishna Gudipati 		if (i)
4326a36c61f9SKrishna Gudipati 			list_add_tail(&rp->qe, &mod->rp_free_q);
4327a36c61f9SKrishna Gudipati 
4328a36c61f9SKrishna Gudipati 		bfa_reqq_winit(&rp->reqq_wait, bfa_rport_qresume, rp);
4329a36c61f9SKrishna Gudipati 	}
4330a36c61f9SKrishna Gudipati 
43315fbe25c7SJing Huang 	/*
4332a36c61f9SKrishna Gudipati 	 * consume memory
4333a36c61f9SKrishna Gudipati 	 */
4334a36c61f9SKrishna Gudipati 	bfa_meminfo_kva(meminfo) = (u8 *) rp;
4335a36c61f9SKrishna Gudipati }
4336a36c61f9SKrishna Gudipati 
4337a36c61f9SKrishna Gudipati static void
4338a36c61f9SKrishna Gudipati bfa_rport_detach(struct bfa_s *bfa)
4339a36c61f9SKrishna Gudipati {
4340a36c61f9SKrishna Gudipati }
4341a36c61f9SKrishna Gudipati 
4342a36c61f9SKrishna Gudipati static void
4343a36c61f9SKrishna Gudipati bfa_rport_start(struct bfa_s *bfa)
4344a36c61f9SKrishna Gudipati {
4345a36c61f9SKrishna Gudipati }
4346a36c61f9SKrishna Gudipati 
4347a36c61f9SKrishna Gudipati static void
4348a36c61f9SKrishna Gudipati bfa_rport_stop(struct bfa_s *bfa)
4349a36c61f9SKrishna Gudipati {
4350a36c61f9SKrishna Gudipati }
4351a36c61f9SKrishna Gudipati 
4352a36c61f9SKrishna Gudipati static void
4353a36c61f9SKrishna Gudipati bfa_rport_iocdisable(struct bfa_s *bfa)
4354a36c61f9SKrishna Gudipati {
4355a36c61f9SKrishna Gudipati 	struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(bfa);
4356a36c61f9SKrishna Gudipati 	struct bfa_rport_s *rport;
4357a36c61f9SKrishna Gudipati 	struct list_head *qe, *qen;
4358a36c61f9SKrishna Gudipati 
4359a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &mod->rp_active_q) {
4360a36c61f9SKrishna Gudipati 		rport = (struct bfa_rport_s *) qe;
4361a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rport, BFA_RPORT_SM_HWFAIL);
4362a36c61f9SKrishna Gudipati 	}
4363a36c61f9SKrishna Gudipati }
4364a36c61f9SKrishna Gudipati 
4365a36c61f9SKrishna Gudipati static struct bfa_rport_s *
4366a36c61f9SKrishna Gudipati bfa_rport_alloc(struct bfa_rport_mod_s *mod)
4367a36c61f9SKrishna Gudipati {
4368a36c61f9SKrishna Gudipati 	struct bfa_rport_s *rport;
4369a36c61f9SKrishna Gudipati 
4370a36c61f9SKrishna Gudipati 	bfa_q_deq(&mod->rp_free_q, &rport);
4371a36c61f9SKrishna Gudipati 	if (rport)
4372a36c61f9SKrishna Gudipati 		list_add_tail(&rport->qe, &mod->rp_active_q);
4373a36c61f9SKrishna Gudipati 
4374a36c61f9SKrishna Gudipati 	return rport;
4375a36c61f9SKrishna Gudipati }
4376a36c61f9SKrishna Gudipati 
4377a36c61f9SKrishna Gudipati static void
4378a36c61f9SKrishna Gudipati bfa_rport_free(struct bfa_rport_s *rport)
4379a36c61f9SKrishna Gudipati {
4380a36c61f9SKrishna Gudipati 	struct bfa_rport_mod_s *mod = BFA_RPORT_MOD(rport->bfa);
4381a36c61f9SKrishna Gudipati 
4382d4b671c5SJing Huang 	WARN_ON(!bfa_q_is_on_q(&mod->rp_active_q, rport));
4383a36c61f9SKrishna Gudipati 	list_del(&rport->qe);
4384a36c61f9SKrishna Gudipati 	list_add_tail(&rport->qe, &mod->rp_free_q);
4385a36c61f9SKrishna Gudipati }
4386a36c61f9SKrishna Gudipati 
4387a36c61f9SKrishna Gudipati static bfa_boolean_t
4388a36c61f9SKrishna Gudipati bfa_rport_send_fwcreate(struct bfa_rport_s *rp)
4389a36c61f9SKrishna Gudipati {
4390a36c61f9SKrishna Gudipati 	struct bfi_rport_create_req_s *m;
4391a36c61f9SKrishna Gudipati 
43925fbe25c7SJing Huang 	/*
4393a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
4394a36c61f9SKrishna Gudipati 	 */
4395a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
4396a36c61f9SKrishna Gudipati 	if (!m) {
4397a36c61f9SKrishna Gudipati 		bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait);
4398a36c61f9SKrishna Gudipati 		return BFA_FALSE;
4399a36c61f9SKrishna Gudipati 	}
4400a36c61f9SKrishna Gudipati 
4401a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_CREATE_REQ,
4402a36c61f9SKrishna Gudipati 			bfa_lpuid(rp->bfa));
4403a36c61f9SKrishna Gudipati 	m->bfa_handle = rp->rport_tag;
4404ba816ea8SJing Huang 	m->max_frmsz = cpu_to_be16(rp->rport_info.max_frmsz);
4405a36c61f9SKrishna Gudipati 	m->pid = rp->rport_info.pid;
4406a36c61f9SKrishna Gudipati 	m->lp_tag = rp->rport_info.lp_tag;
4407a36c61f9SKrishna Gudipati 	m->local_pid = rp->rport_info.local_pid;
4408a36c61f9SKrishna Gudipati 	m->fc_class = rp->rport_info.fc_class;
4409a36c61f9SKrishna Gudipati 	m->vf_en = rp->rport_info.vf_en;
4410a36c61f9SKrishna Gudipati 	m->vf_id = rp->rport_info.vf_id;
4411a36c61f9SKrishna Gudipati 	m->cisc = rp->rport_info.cisc;
4412a36c61f9SKrishna Gudipati 
44135fbe25c7SJing Huang 	/*
4414a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
4415a36c61f9SKrishna Gudipati 	 */
4416a36c61f9SKrishna Gudipati 	bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
4417a36c61f9SKrishna Gudipati 	return BFA_TRUE;
4418a36c61f9SKrishna Gudipati }
4419a36c61f9SKrishna Gudipati 
4420a36c61f9SKrishna Gudipati static bfa_boolean_t
4421a36c61f9SKrishna Gudipati bfa_rport_send_fwdelete(struct bfa_rport_s *rp)
4422a36c61f9SKrishna Gudipati {
4423a36c61f9SKrishna Gudipati 	struct bfi_rport_delete_req_s *m;
4424a36c61f9SKrishna Gudipati 
44255fbe25c7SJing Huang 	/*
4426a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
4427a36c61f9SKrishna Gudipati 	 */
4428a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
4429a36c61f9SKrishna Gudipati 	if (!m) {
4430a36c61f9SKrishna Gudipati 		bfa_reqq_wait(rp->bfa, BFA_REQQ_RPORT, &rp->reqq_wait);
4431a36c61f9SKrishna Gudipati 		return BFA_FALSE;
4432a36c61f9SKrishna Gudipati 	}
4433a36c61f9SKrishna Gudipati 
4434a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_DELETE_REQ,
4435a36c61f9SKrishna Gudipati 			bfa_lpuid(rp->bfa));
4436a36c61f9SKrishna Gudipati 	m->fw_handle = rp->fw_handle;
4437a36c61f9SKrishna Gudipati 
44385fbe25c7SJing Huang 	/*
4439a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
4440a36c61f9SKrishna Gudipati 	 */
4441a36c61f9SKrishna Gudipati 	bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
4442a36c61f9SKrishna Gudipati 	return BFA_TRUE;
4443a36c61f9SKrishna Gudipati }
4444a36c61f9SKrishna Gudipati 
4445a36c61f9SKrishna Gudipati static bfa_boolean_t
4446a36c61f9SKrishna Gudipati bfa_rport_send_fwspeed(struct bfa_rport_s *rp)
4447a36c61f9SKrishna Gudipati {
4448a36c61f9SKrishna Gudipati 	struct bfa_rport_speed_req_s *m;
4449a36c61f9SKrishna Gudipati 
44505fbe25c7SJing Huang 	/*
4451a36c61f9SKrishna Gudipati 	 * check for room in queue to send request now
4452a36c61f9SKrishna Gudipati 	 */
4453a36c61f9SKrishna Gudipati 	m = bfa_reqq_next(rp->bfa, BFA_REQQ_RPORT);
4454a36c61f9SKrishna Gudipati 	if (!m) {
4455a36c61f9SKrishna Gudipati 		bfa_trc(rp->bfa, rp->rport_info.speed);
4456a36c61f9SKrishna Gudipati 		return BFA_FALSE;
4457a36c61f9SKrishna Gudipati 	}
4458a36c61f9SKrishna Gudipati 
4459a36c61f9SKrishna Gudipati 	bfi_h2i_set(m->mh, BFI_MC_RPORT, BFI_RPORT_H2I_SET_SPEED_REQ,
4460a36c61f9SKrishna Gudipati 			bfa_lpuid(rp->bfa));
4461a36c61f9SKrishna Gudipati 	m->fw_handle = rp->fw_handle;
4462a36c61f9SKrishna Gudipati 	m->speed = (u8)rp->rport_info.speed;
4463a36c61f9SKrishna Gudipati 
44645fbe25c7SJing Huang 	/*
4465a36c61f9SKrishna Gudipati 	 * queue I/O message to firmware
4466a36c61f9SKrishna Gudipati 	 */
4467a36c61f9SKrishna Gudipati 	bfa_reqq_produce(rp->bfa, BFA_REQQ_RPORT);
4468a36c61f9SKrishna Gudipati 	return BFA_TRUE;
4469a36c61f9SKrishna Gudipati }
4470a36c61f9SKrishna Gudipati 
4471a36c61f9SKrishna Gudipati 
4472a36c61f9SKrishna Gudipati 
44735fbe25c7SJing Huang /*
4474a36c61f9SKrishna Gudipati  *  bfa_rport_public
4475a36c61f9SKrishna Gudipati  */
4476a36c61f9SKrishna Gudipati 
44775fbe25c7SJing Huang /*
4478a36c61f9SKrishna Gudipati  * Rport interrupt processing.
4479a36c61f9SKrishna Gudipati  */
4480a36c61f9SKrishna Gudipati void
4481a36c61f9SKrishna Gudipati bfa_rport_isr(struct bfa_s *bfa, struct bfi_msg_s *m)
4482a36c61f9SKrishna Gudipati {
4483a36c61f9SKrishna Gudipati 	union bfi_rport_i2h_msg_u msg;
4484a36c61f9SKrishna Gudipati 	struct bfa_rport_s *rp;
4485a36c61f9SKrishna Gudipati 
4486a36c61f9SKrishna Gudipati 	bfa_trc(bfa, m->mhdr.msg_id);
4487a36c61f9SKrishna Gudipati 
4488a36c61f9SKrishna Gudipati 	msg.msg = m;
4489a36c61f9SKrishna Gudipati 
4490a36c61f9SKrishna Gudipati 	switch (m->mhdr.msg_id) {
4491a36c61f9SKrishna Gudipati 	case BFI_RPORT_I2H_CREATE_RSP:
4492a36c61f9SKrishna Gudipati 		rp = BFA_RPORT_FROM_TAG(bfa, msg.create_rsp->bfa_handle);
4493a36c61f9SKrishna Gudipati 		rp->fw_handle = msg.create_rsp->fw_handle;
4494a36c61f9SKrishna Gudipati 		rp->qos_attr = msg.create_rsp->qos_attr;
4495d4b671c5SJing Huang 		WARN_ON(msg.create_rsp->status != BFA_STATUS_OK);
4496a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
4497a36c61f9SKrishna Gudipati 		break;
4498a36c61f9SKrishna Gudipati 
4499a36c61f9SKrishna Gudipati 	case BFI_RPORT_I2H_DELETE_RSP:
4500a36c61f9SKrishna Gudipati 		rp = BFA_RPORT_FROM_TAG(bfa, msg.delete_rsp->bfa_handle);
4501d4b671c5SJing Huang 		WARN_ON(msg.delete_rsp->status != BFA_STATUS_OK);
4502a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rp, BFA_RPORT_SM_FWRSP);
4503a36c61f9SKrishna Gudipati 		break;
4504a36c61f9SKrishna Gudipati 
4505a36c61f9SKrishna Gudipati 	case BFI_RPORT_I2H_QOS_SCN:
4506a36c61f9SKrishna Gudipati 		rp = BFA_RPORT_FROM_TAG(bfa, msg.qos_scn_evt->bfa_handle);
4507a36c61f9SKrishna Gudipati 		rp->event_arg.fw_msg = msg.qos_scn_evt;
4508a36c61f9SKrishna Gudipati 		bfa_sm_send_event(rp, BFA_RPORT_SM_QOS_SCN);
4509a36c61f9SKrishna Gudipati 		break;
4510a36c61f9SKrishna Gudipati 
4511a36c61f9SKrishna Gudipati 	default:
4512a36c61f9SKrishna Gudipati 		bfa_trc(bfa, m->mhdr.msg_id);
4513d4b671c5SJing Huang 		WARN_ON(1);
4514a36c61f9SKrishna Gudipati 	}
4515a36c61f9SKrishna Gudipati }
4516a36c61f9SKrishna Gudipati 
4517a36c61f9SKrishna Gudipati 
4518a36c61f9SKrishna Gudipati 
45195fbe25c7SJing Huang /*
4520a36c61f9SKrishna Gudipati  *  bfa_rport_api
4521a36c61f9SKrishna Gudipati  */
4522a36c61f9SKrishna Gudipati 
4523a36c61f9SKrishna Gudipati struct bfa_rport_s *
4524a36c61f9SKrishna Gudipati bfa_rport_create(struct bfa_s *bfa, void *rport_drv)
4525a36c61f9SKrishna Gudipati {
4526a36c61f9SKrishna Gudipati 	struct bfa_rport_s *rp;
4527a36c61f9SKrishna Gudipati 
4528a36c61f9SKrishna Gudipati 	rp = bfa_rport_alloc(BFA_RPORT_MOD(bfa));
4529a36c61f9SKrishna Gudipati 
4530a36c61f9SKrishna Gudipati 	if (rp == NULL)
4531a36c61f9SKrishna Gudipati 		return NULL;
4532a36c61f9SKrishna Gudipati 
4533a36c61f9SKrishna Gudipati 	rp->bfa = bfa;
4534a36c61f9SKrishna Gudipati 	rp->rport_drv = rport_drv;
4535f7f73812SMaggie Zhang 	memset(&rp->stats, 0, sizeof(rp->stats));
4536a36c61f9SKrishna Gudipati 
4537d4b671c5SJing Huang 	WARN_ON(!bfa_sm_cmp_state(rp, bfa_rport_sm_uninit));
4538a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rp, BFA_RPORT_SM_CREATE);
4539a36c61f9SKrishna Gudipati 
4540a36c61f9SKrishna Gudipati 	return rp;
4541a36c61f9SKrishna Gudipati }
4542a36c61f9SKrishna Gudipati 
4543a36c61f9SKrishna Gudipati void
4544a36c61f9SKrishna Gudipati bfa_rport_online(struct bfa_rport_s *rport, struct bfa_rport_info_s *rport_info)
4545a36c61f9SKrishna Gudipati {
4546d4b671c5SJing Huang 	WARN_ON(rport_info->max_frmsz == 0);
4547a36c61f9SKrishna Gudipati 
45485fbe25c7SJing Huang 	/*
4549a36c61f9SKrishna Gudipati 	 * Some JBODs are seen to be not setting PDU size correctly in PLOGI
4550a36c61f9SKrishna Gudipati 	 * responses. Default to minimum size.
4551a36c61f9SKrishna Gudipati 	 */
4552a36c61f9SKrishna Gudipati 	if (rport_info->max_frmsz == 0) {
4553a36c61f9SKrishna Gudipati 		bfa_trc(rport->bfa, rport->rport_tag);
4554a36c61f9SKrishna Gudipati 		rport_info->max_frmsz = FC_MIN_PDUSZ;
4555a36c61f9SKrishna Gudipati 	}
4556a36c61f9SKrishna Gudipati 
45576a18b167SJing Huang 	rport->rport_info = *rport_info;
4558a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, BFA_RPORT_SM_ONLINE);
4559a36c61f9SKrishna Gudipati }
4560a36c61f9SKrishna Gudipati 
4561a36c61f9SKrishna Gudipati void
4562a36c61f9SKrishna Gudipati bfa_rport_speed(struct bfa_rport_s *rport, enum bfa_port_speed speed)
4563a36c61f9SKrishna Gudipati {
4564d4b671c5SJing Huang 	WARN_ON(speed == 0);
4565d4b671c5SJing Huang 	WARN_ON(speed == BFA_PORT_SPEED_AUTO);
4566a36c61f9SKrishna Gudipati 
4567a36c61f9SKrishna Gudipati 	rport->rport_info.speed = speed;
4568a36c61f9SKrishna Gudipati 	bfa_sm_send_event(rport, BFA_RPORT_SM_SET_SPEED);
4569a36c61f9SKrishna Gudipati }
4570a36c61f9SKrishna Gudipati 
4571a36c61f9SKrishna Gudipati 
45725fbe25c7SJing Huang /*
4573a36c61f9SKrishna Gudipati  * SGPG related functions
4574a36c61f9SKrishna Gudipati  */
4575a36c61f9SKrishna Gudipati 
45765fbe25c7SJing Huang /*
4577a36c61f9SKrishna Gudipati  * Compute and return memory needed by FCP(im) module.
4578a36c61f9SKrishna Gudipati  */
4579a36c61f9SKrishna Gudipati static void
4580a36c61f9SKrishna Gudipati bfa_sgpg_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *km_len,
4581a36c61f9SKrishna Gudipati 		u32 *dm_len)
4582a36c61f9SKrishna Gudipati {
4583a36c61f9SKrishna Gudipati 	if (cfg->drvcfg.num_sgpgs < BFA_SGPG_MIN)
4584a36c61f9SKrishna Gudipati 		cfg->drvcfg.num_sgpgs = BFA_SGPG_MIN;
4585a36c61f9SKrishna Gudipati 
4586a36c61f9SKrishna Gudipati 	*km_len += (cfg->drvcfg.num_sgpgs + 1) * sizeof(struct bfa_sgpg_s);
4587a36c61f9SKrishna Gudipati 	*dm_len += (cfg->drvcfg.num_sgpgs + 1) * sizeof(struct bfi_sgpg_s);
4588a36c61f9SKrishna Gudipati }
4589a36c61f9SKrishna Gudipati 
4590a36c61f9SKrishna Gudipati 
4591a36c61f9SKrishna Gudipati static void
4592a36c61f9SKrishna Gudipati bfa_sgpg_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
4593a36c61f9SKrishna Gudipati 		    struct bfa_meminfo_s *minfo, struct bfa_pcidev_s *pcidev)
4594a36c61f9SKrishna Gudipati {
4595a36c61f9SKrishna Gudipati 	struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
4596a36c61f9SKrishna Gudipati 	int i;
4597a36c61f9SKrishna Gudipati 	struct bfa_sgpg_s *hsgpg;
4598a36c61f9SKrishna Gudipati 	struct bfi_sgpg_s *sgpg;
4599a36c61f9SKrishna Gudipati 	u64 align_len;
4600a36c61f9SKrishna Gudipati 
4601a36c61f9SKrishna Gudipati 	union {
4602a36c61f9SKrishna Gudipati 		u64 pa;
4603a36c61f9SKrishna Gudipati 		union bfi_addr_u addr;
4604a36c61f9SKrishna Gudipati 	} sgpg_pa, sgpg_pa_tmp;
4605a36c61f9SKrishna Gudipati 
4606a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->sgpg_q);
4607a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&mod->sgpg_wait_q);
4608a36c61f9SKrishna Gudipati 
4609a36c61f9SKrishna Gudipati 	bfa_trc(bfa, cfg->drvcfg.num_sgpgs);
4610a36c61f9SKrishna Gudipati 
4611a36c61f9SKrishna Gudipati 	mod->num_sgpgs = cfg->drvcfg.num_sgpgs;
4612a36c61f9SKrishna Gudipati 	mod->sgpg_arr_pa = bfa_meminfo_dma_phys(minfo);
4613a36c61f9SKrishna Gudipati 	align_len = (BFA_SGPG_ROUNDUP(mod->sgpg_arr_pa) - mod->sgpg_arr_pa);
4614a36c61f9SKrishna Gudipati 	mod->sgpg_arr_pa += align_len;
4615a36c61f9SKrishna Gudipati 	mod->hsgpg_arr = (struct bfa_sgpg_s *) (bfa_meminfo_kva(minfo) +
4616a36c61f9SKrishna Gudipati 						align_len);
4617a36c61f9SKrishna Gudipati 	mod->sgpg_arr = (struct bfi_sgpg_s *) (bfa_meminfo_dma_virt(minfo) +
4618a36c61f9SKrishna Gudipati 						align_len);
4619a36c61f9SKrishna Gudipati 
4620a36c61f9SKrishna Gudipati 	hsgpg = mod->hsgpg_arr;
4621a36c61f9SKrishna Gudipati 	sgpg = mod->sgpg_arr;
4622a36c61f9SKrishna Gudipati 	sgpg_pa.pa = mod->sgpg_arr_pa;
4623a36c61f9SKrishna Gudipati 	mod->free_sgpgs = mod->num_sgpgs;
4624a36c61f9SKrishna Gudipati 
4625d4b671c5SJing Huang 	WARN_ON(sgpg_pa.pa & (sizeof(struct bfi_sgpg_s) - 1));
4626a36c61f9SKrishna Gudipati 
4627a36c61f9SKrishna Gudipati 	for (i = 0; i < mod->num_sgpgs; i++) {
46286a18b167SJing Huang 		memset(hsgpg, 0, sizeof(*hsgpg));
46296a18b167SJing Huang 		memset(sgpg, 0, sizeof(*sgpg));
4630a36c61f9SKrishna Gudipati 
4631a36c61f9SKrishna Gudipati 		hsgpg->sgpg = sgpg;
4632a36c61f9SKrishna Gudipati 		sgpg_pa_tmp.pa = bfa_sgaddr_le(sgpg_pa.pa);
4633a36c61f9SKrishna Gudipati 		hsgpg->sgpg_pa = sgpg_pa_tmp.addr;
4634a36c61f9SKrishna Gudipati 		list_add_tail(&hsgpg->qe, &mod->sgpg_q);
4635a36c61f9SKrishna Gudipati 
4636a36c61f9SKrishna Gudipati 		hsgpg++;
4637a36c61f9SKrishna Gudipati 		sgpg++;
4638a36c61f9SKrishna Gudipati 		sgpg_pa.pa += sizeof(struct bfi_sgpg_s);
4639a36c61f9SKrishna Gudipati 	}
4640a36c61f9SKrishna Gudipati 
4641a36c61f9SKrishna Gudipati 	bfa_meminfo_kva(minfo) = (u8 *) hsgpg;
4642a36c61f9SKrishna Gudipati 	bfa_meminfo_dma_virt(minfo) = (u8 *) sgpg;
4643a36c61f9SKrishna Gudipati 	bfa_meminfo_dma_phys(minfo) = sgpg_pa.pa;
4644a36c61f9SKrishna Gudipati }
4645a36c61f9SKrishna Gudipati 
4646a36c61f9SKrishna Gudipati static void
4647a36c61f9SKrishna Gudipati bfa_sgpg_detach(struct bfa_s *bfa)
4648a36c61f9SKrishna Gudipati {
4649a36c61f9SKrishna Gudipati }
4650a36c61f9SKrishna Gudipati 
4651a36c61f9SKrishna Gudipati static void
4652a36c61f9SKrishna Gudipati bfa_sgpg_start(struct bfa_s *bfa)
4653a36c61f9SKrishna Gudipati {
4654a36c61f9SKrishna Gudipati }
4655a36c61f9SKrishna Gudipati 
4656a36c61f9SKrishna Gudipati static void
4657a36c61f9SKrishna Gudipati bfa_sgpg_stop(struct bfa_s *bfa)
4658a36c61f9SKrishna Gudipati {
4659a36c61f9SKrishna Gudipati }
4660a36c61f9SKrishna Gudipati 
4661a36c61f9SKrishna Gudipati static void
4662a36c61f9SKrishna Gudipati bfa_sgpg_iocdisable(struct bfa_s *bfa)
4663a36c61f9SKrishna Gudipati {
4664a36c61f9SKrishna Gudipati }
4665a36c61f9SKrishna Gudipati 
4666a36c61f9SKrishna Gudipati bfa_status_t
4667a36c61f9SKrishna Gudipati bfa_sgpg_malloc(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpgs)
4668a36c61f9SKrishna Gudipati {
4669a36c61f9SKrishna Gudipati 	struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
4670a36c61f9SKrishna Gudipati 	struct bfa_sgpg_s *hsgpg;
4671a36c61f9SKrishna Gudipati 	int i;
4672a36c61f9SKrishna Gudipati 
4673a36c61f9SKrishna Gudipati 	if (mod->free_sgpgs < nsgpgs)
4674a36c61f9SKrishna Gudipati 		return BFA_STATUS_ENOMEM;
4675a36c61f9SKrishna Gudipati 
4676a36c61f9SKrishna Gudipati 	for (i = 0; i < nsgpgs; i++) {
4677a36c61f9SKrishna Gudipati 		bfa_q_deq(&mod->sgpg_q, &hsgpg);
4678d4b671c5SJing Huang 		WARN_ON(!hsgpg);
4679a36c61f9SKrishna Gudipati 		list_add_tail(&hsgpg->qe, sgpg_q);
4680a36c61f9SKrishna Gudipati 	}
4681a36c61f9SKrishna Gudipati 
4682a36c61f9SKrishna Gudipati 	mod->free_sgpgs -= nsgpgs;
4683a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
4684a36c61f9SKrishna Gudipati }
4685a36c61f9SKrishna Gudipati 
4686a36c61f9SKrishna Gudipati void
4687a36c61f9SKrishna Gudipati bfa_sgpg_mfree(struct bfa_s *bfa, struct list_head *sgpg_q, int nsgpg)
4688a36c61f9SKrishna Gudipati {
4689a36c61f9SKrishna Gudipati 	struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
4690a36c61f9SKrishna Gudipati 	struct bfa_sgpg_wqe_s *wqe;
4691a36c61f9SKrishna Gudipati 
4692a36c61f9SKrishna Gudipati 	mod->free_sgpgs += nsgpg;
4693d4b671c5SJing Huang 	WARN_ON(mod->free_sgpgs > mod->num_sgpgs);
4694a36c61f9SKrishna Gudipati 
4695a36c61f9SKrishna Gudipati 	list_splice_tail_init(sgpg_q, &mod->sgpg_q);
4696a36c61f9SKrishna Gudipati 
4697a36c61f9SKrishna Gudipati 	if (list_empty(&mod->sgpg_wait_q))
4698a36c61f9SKrishna Gudipati 		return;
4699a36c61f9SKrishna Gudipati 
47005fbe25c7SJing Huang 	/*
4701a36c61f9SKrishna Gudipati 	 * satisfy as many waiting requests as possible
4702a36c61f9SKrishna Gudipati 	 */
4703a36c61f9SKrishna Gudipati 	do {
4704a36c61f9SKrishna Gudipati 		wqe = bfa_q_first(&mod->sgpg_wait_q);
4705a36c61f9SKrishna Gudipati 		if (mod->free_sgpgs < wqe->nsgpg)
4706a36c61f9SKrishna Gudipati 			nsgpg = mod->free_sgpgs;
4707a36c61f9SKrishna Gudipati 		else
4708a36c61f9SKrishna Gudipati 			nsgpg = wqe->nsgpg;
4709a36c61f9SKrishna Gudipati 		bfa_sgpg_malloc(bfa, &wqe->sgpg_q, nsgpg);
4710a36c61f9SKrishna Gudipati 		wqe->nsgpg -= nsgpg;
4711a36c61f9SKrishna Gudipati 		if (wqe->nsgpg == 0) {
4712a36c61f9SKrishna Gudipati 			list_del(&wqe->qe);
4713a36c61f9SKrishna Gudipati 			wqe->cbfn(wqe->cbarg);
4714a36c61f9SKrishna Gudipati 		}
4715a36c61f9SKrishna Gudipati 	} while (mod->free_sgpgs && !list_empty(&mod->sgpg_wait_q));
4716a36c61f9SKrishna Gudipati }
4717a36c61f9SKrishna Gudipati 
4718a36c61f9SKrishna Gudipati void
4719a36c61f9SKrishna Gudipati bfa_sgpg_wait(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe, int nsgpg)
4720a36c61f9SKrishna Gudipati {
4721a36c61f9SKrishna Gudipati 	struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
4722a36c61f9SKrishna Gudipati 
4723d4b671c5SJing Huang 	WARN_ON(nsgpg <= 0);
4724d4b671c5SJing Huang 	WARN_ON(nsgpg <= mod->free_sgpgs);
4725a36c61f9SKrishna Gudipati 
4726a36c61f9SKrishna Gudipati 	wqe->nsgpg_total = wqe->nsgpg = nsgpg;
4727a36c61f9SKrishna Gudipati 
47285fbe25c7SJing Huang 	/*
4729a36c61f9SKrishna Gudipati 	 * allocate any left to this one first
4730a36c61f9SKrishna Gudipati 	 */
4731a36c61f9SKrishna Gudipati 	if (mod->free_sgpgs) {
47325fbe25c7SJing Huang 		/*
4733a36c61f9SKrishna Gudipati 		 * no one else is waiting for SGPG
4734a36c61f9SKrishna Gudipati 		 */
4735d4b671c5SJing Huang 		WARN_ON(!list_empty(&mod->sgpg_wait_q));
4736a36c61f9SKrishna Gudipati 		list_splice_tail_init(&mod->sgpg_q, &wqe->sgpg_q);
4737a36c61f9SKrishna Gudipati 		wqe->nsgpg -= mod->free_sgpgs;
4738a36c61f9SKrishna Gudipati 		mod->free_sgpgs = 0;
4739a36c61f9SKrishna Gudipati 	}
4740a36c61f9SKrishna Gudipati 
4741a36c61f9SKrishna Gudipati 	list_add_tail(&wqe->qe, &mod->sgpg_wait_q);
4742a36c61f9SKrishna Gudipati }
4743a36c61f9SKrishna Gudipati 
4744a36c61f9SKrishna Gudipati void
4745a36c61f9SKrishna Gudipati bfa_sgpg_wcancel(struct bfa_s *bfa, struct bfa_sgpg_wqe_s *wqe)
4746a36c61f9SKrishna Gudipati {
4747a36c61f9SKrishna Gudipati 	struct bfa_sgpg_mod_s *mod = BFA_SGPG_MOD(bfa);
4748a36c61f9SKrishna Gudipati 
4749d4b671c5SJing Huang 	WARN_ON(!bfa_q_is_on_q(&mod->sgpg_wait_q, wqe));
4750a36c61f9SKrishna Gudipati 	list_del(&wqe->qe);
4751a36c61f9SKrishna Gudipati 
4752a36c61f9SKrishna Gudipati 	if (wqe->nsgpg_total != wqe->nsgpg)
4753a36c61f9SKrishna Gudipati 		bfa_sgpg_mfree(bfa, &wqe->sgpg_q,
4754a36c61f9SKrishna Gudipati 				   wqe->nsgpg_total - wqe->nsgpg);
4755a36c61f9SKrishna Gudipati }
4756a36c61f9SKrishna Gudipati 
4757a36c61f9SKrishna Gudipati void
4758a36c61f9SKrishna Gudipati bfa_sgpg_winit(struct bfa_sgpg_wqe_s *wqe, void (*cbfn) (void *cbarg),
4759a36c61f9SKrishna Gudipati 		   void *cbarg)
4760a36c61f9SKrishna Gudipati {
4761a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&wqe->sgpg_q);
4762a36c61f9SKrishna Gudipati 	wqe->cbfn = cbfn;
4763a36c61f9SKrishna Gudipati 	wqe->cbarg = cbarg;
4764a36c61f9SKrishna Gudipati }
4765a36c61f9SKrishna Gudipati 
47665fbe25c7SJing Huang /*
4767a36c61f9SKrishna Gudipati  *  UF related functions
4768a36c61f9SKrishna Gudipati  */
4769a36c61f9SKrishna Gudipati /*
4770a36c61f9SKrishna Gudipati  *****************************************************************************
4771a36c61f9SKrishna Gudipati  * Internal functions
4772a36c61f9SKrishna Gudipati  *****************************************************************************
4773a36c61f9SKrishna Gudipati  */
4774a36c61f9SKrishna Gudipati static void
4775a36c61f9SKrishna Gudipati __bfa_cb_uf_recv(void *cbarg, bfa_boolean_t complete)
4776a36c61f9SKrishna Gudipati {
4777a36c61f9SKrishna Gudipati 	struct bfa_uf_s   *uf = cbarg;
4778a36c61f9SKrishna Gudipati 	struct bfa_uf_mod_s *ufm = BFA_UF_MOD(uf->bfa);
4779a36c61f9SKrishna Gudipati 
4780a36c61f9SKrishna Gudipati 	if (complete)
4781a36c61f9SKrishna Gudipati 		ufm->ufrecv(ufm->cbarg, uf);
4782a36c61f9SKrishna Gudipati }
4783a36c61f9SKrishna Gudipati 
4784a36c61f9SKrishna Gudipati static void
4785a36c61f9SKrishna Gudipati claim_uf_pbs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
4786a36c61f9SKrishna Gudipati {
4787a36c61f9SKrishna Gudipati 	u32 uf_pb_tot_sz;
4788a36c61f9SKrishna Gudipati 
4789a36c61f9SKrishna Gudipati 	ufm->uf_pbs_kva = (struct bfa_uf_buf_s *) bfa_meminfo_dma_virt(mi);
4790a36c61f9SKrishna Gudipati 	ufm->uf_pbs_pa = bfa_meminfo_dma_phys(mi);
4791a36c61f9SKrishna Gudipati 	uf_pb_tot_sz = BFA_ROUNDUP((sizeof(struct bfa_uf_buf_s) * ufm->num_ufs),
4792a36c61f9SKrishna Gudipati 							BFA_DMA_ALIGN_SZ);
4793a36c61f9SKrishna Gudipati 
4794a36c61f9SKrishna Gudipati 	bfa_meminfo_dma_virt(mi) += uf_pb_tot_sz;
4795a36c61f9SKrishna Gudipati 	bfa_meminfo_dma_phys(mi) += uf_pb_tot_sz;
4796a36c61f9SKrishna Gudipati 
47976a18b167SJing Huang 	memset((void *)ufm->uf_pbs_kva, 0, uf_pb_tot_sz);
4798a36c61f9SKrishna Gudipati }
4799a36c61f9SKrishna Gudipati 
4800a36c61f9SKrishna Gudipati static void
4801a36c61f9SKrishna Gudipati claim_uf_post_msgs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
4802a36c61f9SKrishna Gudipati {
4803a36c61f9SKrishna Gudipati 	struct bfi_uf_buf_post_s *uf_bp_msg;
4804a36c61f9SKrishna Gudipati 	struct bfi_sge_s      *sge;
4805a36c61f9SKrishna Gudipati 	union bfi_addr_u      sga_zero = { {0} };
4806a36c61f9SKrishna Gudipati 	u16 i;
4807a36c61f9SKrishna Gudipati 	u16 buf_len;
4808a36c61f9SKrishna Gudipati 
4809a36c61f9SKrishna Gudipati 	ufm->uf_buf_posts = (struct bfi_uf_buf_post_s *) bfa_meminfo_kva(mi);
4810a36c61f9SKrishna Gudipati 	uf_bp_msg = ufm->uf_buf_posts;
4811a36c61f9SKrishna Gudipati 
4812a36c61f9SKrishna Gudipati 	for (i = 0, uf_bp_msg = ufm->uf_buf_posts; i < ufm->num_ufs;
4813a36c61f9SKrishna Gudipati 	     i++, uf_bp_msg++) {
48146a18b167SJing Huang 		memset(uf_bp_msg, 0, sizeof(struct bfi_uf_buf_post_s));
4815a36c61f9SKrishna Gudipati 
4816a36c61f9SKrishna Gudipati 		uf_bp_msg->buf_tag = i;
4817a36c61f9SKrishna Gudipati 		buf_len = sizeof(struct bfa_uf_buf_s);
4818ba816ea8SJing Huang 		uf_bp_msg->buf_len = cpu_to_be16(buf_len);
4819a36c61f9SKrishna Gudipati 		bfi_h2i_set(uf_bp_msg->mh, BFI_MC_UF, BFI_UF_H2I_BUF_POST,
4820a36c61f9SKrishna Gudipati 			    bfa_lpuid(ufm->bfa));
4821a36c61f9SKrishna Gudipati 
4822a36c61f9SKrishna Gudipati 		sge = uf_bp_msg->sge;
4823a36c61f9SKrishna Gudipati 		sge[0].sg_len = buf_len;
4824a36c61f9SKrishna Gudipati 		sge[0].flags = BFI_SGE_DATA_LAST;
4825a36c61f9SKrishna Gudipati 		bfa_dma_addr_set(sge[0].sga, ufm_pbs_pa(ufm, i));
4826a36c61f9SKrishna Gudipati 		bfa_sge_to_be(sge);
4827a36c61f9SKrishna Gudipati 
4828a36c61f9SKrishna Gudipati 		sge[1].sg_len = buf_len;
4829a36c61f9SKrishna Gudipati 		sge[1].flags = BFI_SGE_PGDLEN;
4830a36c61f9SKrishna Gudipati 		sge[1].sga = sga_zero;
4831a36c61f9SKrishna Gudipati 		bfa_sge_to_be(&sge[1]);
4832a36c61f9SKrishna Gudipati 	}
4833a36c61f9SKrishna Gudipati 
48345fbe25c7SJing Huang 	/*
4835a36c61f9SKrishna Gudipati 	 * advance pointer beyond consumed memory
4836a36c61f9SKrishna Gudipati 	 */
4837a36c61f9SKrishna Gudipati 	bfa_meminfo_kva(mi) = (u8 *) uf_bp_msg;
4838a36c61f9SKrishna Gudipati }
4839a36c61f9SKrishna Gudipati 
4840a36c61f9SKrishna Gudipati static void
4841a36c61f9SKrishna Gudipati claim_ufs(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
4842a36c61f9SKrishna Gudipati {
4843a36c61f9SKrishna Gudipati 	u16 i;
4844a36c61f9SKrishna Gudipati 	struct bfa_uf_s   *uf;
4845a36c61f9SKrishna Gudipati 
4846a36c61f9SKrishna Gudipati 	/*
4847a36c61f9SKrishna Gudipati 	 * Claim block of memory for UF list
4848a36c61f9SKrishna Gudipati 	 */
4849a36c61f9SKrishna Gudipati 	ufm->uf_list = (struct bfa_uf_s *) bfa_meminfo_kva(mi);
4850a36c61f9SKrishna Gudipati 
4851a36c61f9SKrishna Gudipati 	/*
4852a36c61f9SKrishna Gudipati 	 * Initialize UFs and queue it in UF free queue
4853a36c61f9SKrishna Gudipati 	 */
4854a36c61f9SKrishna Gudipati 	for (i = 0, uf = ufm->uf_list; i < ufm->num_ufs; i++, uf++) {
48556a18b167SJing Huang 		memset(uf, 0, sizeof(struct bfa_uf_s));
4856a36c61f9SKrishna Gudipati 		uf->bfa = ufm->bfa;
4857a36c61f9SKrishna Gudipati 		uf->uf_tag = i;
4858a36c61f9SKrishna Gudipati 		uf->pb_len = sizeof(struct bfa_uf_buf_s);
4859a36c61f9SKrishna Gudipati 		uf->buf_kva = (void *)&ufm->uf_pbs_kva[i];
4860a36c61f9SKrishna Gudipati 		uf->buf_pa = ufm_pbs_pa(ufm, i);
4861a36c61f9SKrishna Gudipati 		list_add_tail(&uf->qe, &ufm->uf_free_q);
4862a36c61f9SKrishna Gudipati 	}
4863a36c61f9SKrishna Gudipati 
48645fbe25c7SJing Huang 	/*
4865a36c61f9SKrishna Gudipati 	 * advance memory pointer
4866a36c61f9SKrishna Gudipati 	 */
4867a36c61f9SKrishna Gudipati 	bfa_meminfo_kva(mi) = (u8 *) uf;
4868a36c61f9SKrishna Gudipati }
4869a36c61f9SKrishna Gudipati 
4870a36c61f9SKrishna Gudipati static void
4871a36c61f9SKrishna Gudipati uf_mem_claim(struct bfa_uf_mod_s *ufm, struct bfa_meminfo_s *mi)
4872a36c61f9SKrishna Gudipati {
4873a36c61f9SKrishna Gudipati 	claim_uf_pbs(ufm, mi);
4874a36c61f9SKrishna Gudipati 	claim_ufs(ufm, mi);
4875a36c61f9SKrishna Gudipati 	claim_uf_post_msgs(ufm, mi);
4876a36c61f9SKrishna Gudipati }
4877a36c61f9SKrishna Gudipati 
4878a36c61f9SKrishna Gudipati static void
4879a36c61f9SKrishna Gudipati bfa_uf_meminfo(struct bfa_iocfc_cfg_s *cfg, u32 *ndm_len, u32 *dm_len)
4880a36c61f9SKrishna Gudipati {
4881a36c61f9SKrishna Gudipati 	u32 num_ufs = cfg->fwcfg.num_uf_bufs;
4882a36c61f9SKrishna Gudipati 
4883a36c61f9SKrishna Gudipati 	/*
4884a36c61f9SKrishna Gudipati 	 * dma-able memory for UF posted bufs
4885a36c61f9SKrishna Gudipati 	 */
4886a36c61f9SKrishna Gudipati 	*dm_len += BFA_ROUNDUP((sizeof(struct bfa_uf_buf_s) * num_ufs),
4887a36c61f9SKrishna Gudipati 							BFA_DMA_ALIGN_SZ);
4888a36c61f9SKrishna Gudipati 
4889a36c61f9SKrishna Gudipati 	/*
4890a36c61f9SKrishna Gudipati 	 * kernel Virtual memory for UFs and UF buf post msg copies
4891a36c61f9SKrishna Gudipati 	 */
4892a36c61f9SKrishna Gudipati 	*ndm_len += sizeof(struct bfa_uf_s) * num_ufs;
4893a36c61f9SKrishna Gudipati 	*ndm_len += sizeof(struct bfi_uf_buf_post_s) * num_ufs;
4894a36c61f9SKrishna Gudipati }
4895a36c61f9SKrishna Gudipati 
4896a36c61f9SKrishna Gudipati static void
4897a36c61f9SKrishna Gudipati bfa_uf_attach(struct bfa_s *bfa, void *bfad, struct bfa_iocfc_cfg_s *cfg,
4898a36c61f9SKrishna Gudipati 		  struct bfa_meminfo_s *meminfo, struct bfa_pcidev_s *pcidev)
4899a36c61f9SKrishna Gudipati {
4900a36c61f9SKrishna Gudipati 	struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
4901a36c61f9SKrishna Gudipati 
49026a18b167SJing Huang 	memset(ufm, 0, sizeof(struct bfa_uf_mod_s));
4903a36c61f9SKrishna Gudipati 	ufm->bfa = bfa;
4904a36c61f9SKrishna Gudipati 	ufm->num_ufs = cfg->fwcfg.num_uf_bufs;
4905a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&ufm->uf_free_q);
4906a36c61f9SKrishna Gudipati 	INIT_LIST_HEAD(&ufm->uf_posted_q);
4907a36c61f9SKrishna Gudipati 
4908a36c61f9SKrishna Gudipati 	uf_mem_claim(ufm, meminfo);
4909a36c61f9SKrishna Gudipati }
4910a36c61f9SKrishna Gudipati 
4911a36c61f9SKrishna Gudipati static void
4912a36c61f9SKrishna Gudipati bfa_uf_detach(struct bfa_s *bfa)
4913a36c61f9SKrishna Gudipati {
4914a36c61f9SKrishna Gudipati }
4915a36c61f9SKrishna Gudipati 
4916a36c61f9SKrishna Gudipati static struct bfa_uf_s *
4917a36c61f9SKrishna Gudipati bfa_uf_get(struct bfa_uf_mod_s *uf_mod)
4918a36c61f9SKrishna Gudipati {
4919a36c61f9SKrishna Gudipati 	struct bfa_uf_s   *uf;
4920a36c61f9SKrishna Gudipati 
4921a36c61f9SKrishna Gudipati 	bfa_q_deq(&uf_mod->uf_free_q, &uf);
4922a36c61f9SKrishna Gudipati 	return uf;
4923a36c61f9SKrishna Gudipati }
4924a36c61f9SKrishna Gudipati 
4925a36c61f9SKrishna Gudipati static void
4926a36c61f9SKrishna Gudipati bfa_uf_put(struct bfa_uf_mod_s *uf_mod, struct bfa_uf_s *uf)
4927a36c61f9SKrishna Gudipati {
4928a36c61f9SKrishna Gudipati 	list_add_tail(&uf->qe, &uf_mod->uf_free_q);
4929a36c61f9SKrishna Gudipati }
4930a36c61f9SKrishna Gudipati 
4931a36c61f9SKrishna Gudipati static bfa_status_t
4932a36c61f9SKrishna Gudipati bfa_uf_post(struct bfa_uf_mod_s *ufm, struct bfa_uf_s *uf)
4933a36c61f9SKrishna Gudipati {
4934a36c61f9SKrishna Gudipati 	struct bfi_uf_buf_post_s *uf_post_msg;
4935a36c61f9SKrishna Gudipati 
4936a36c61f9SKrishna Gudipati 	uf_post_msg = bfa_reqq_next(ufm->bfa, BFA_REQQ_FCXP);
4937a36c61f9SKrishna Gudipati 	if (!uf_post_msg)
4938a36c61f9SKrishna Gudipati 		return BFA_STATUS_FAILED;
4939a36c61f9SKrishna Gudipati 
49406a18b167SJing Huang 	memcpy(uf_post_msg, &ufm->uf_buf_posts[uf->uf_tag],
4941a36c61f9SKrishna Gudipati 		      sizeof(struct bfi_uf_buf_post_s));
4942a36c61f9SKrishna Gudipati 	bfa_reqq_produce(ufm->bfa, BFA_REQQ_FCXP);
4943a36c61f9SKrishna Gudipati 
4944a36c61f9SKrishna Gudipati 	bfa_trc(ufm->bfa, uf->uf_tag);
4945a36c61f9SKrishna Gudipati 
4946a36c61f9SKrishna Gudipati 	list_add_tail(&uf->qe, &ufm->uf_posted_q);
4947a36c61f9SKrishna Gudipati 	return BFA_STATUS_OK;
4948a36c61f9SKrishna Gudipati }
4949a36c61f9SKrishna Gudipati 
4950a36c61f9SKrishna Gudipati static void
4951a36c61f9SKrishna Gudipati bfa_uf_post_all(struct bfa_uf_mod_s *uf_mod)
4952a36c61f9SKrishna Gudipati {
4953a36c61f9SKrishna Gudipati 	struct bfa_uf_s   *uf;
4954a36c61f9SKrishna Gudipati 
4955a36c61f9SKrishna Gudipati 	while ((uf = bfa_uf_get(uf_mod)) != NULL) {
4956a36c61f9SKrishna Gudipati 		if (bfa_uf_post(uf_mod, uf) != BFA_STATUS_OK)
4957a36c61f9SKrishna Gudipati 			break;
4958a36c61f9SKrishna Gudipati 	}
4959a36c61f9SKrishna Gudipati }
4960a36c61f9SKrishna Gudipati 
4961a36c61f9SKrishna Gudipati static void
4962a36c61f9SKrishna Gudipati uf_recv(struct bfa_s *bfa, struct bfi_uf_frm_rcvd_s *m)
4963a36c61f9SKrishna Gudipati {
4964a36c61f9SKrishna Gudipati 	struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
4965a36c61f9SKrishna Gudipati 	u16 uf_tag = m->buf_tag;
4966a36c61f9SKrishna Gudipati 	struct bfa_uf_buf_s *uf_buf = &ufm->uf_pbs_kva[uf_tag];
4967a36c61f9SKrishna Gudipati 	struct bfa_uf_s *uf = &ufm->uf_list[uf_tag];
4968a36c61f9SKrishna Gudipati 	u8 *buf = &uf_buf->d[0];
4969a36c61f9SKrishna Gudipati 	struct fchs_s *fchs;
4970a36c61f9SKrishna Gudipati 
4971ba816ea8SJing Huang 	m->frm_len = be16_to_cpu(m->frm_len);
4972ba816ea8SJing Huang 	m->xfr_len = be16_to_cpu(m->xfr_len);
4973a36c61f9SKrishna Gudipati 
4974a36c61f9SKrishna Gudipati 	fchs = (struct fchs_s *)uf_buf;
4975a36c61f9SKrishna Gudipati 
4976a36c61f9SKrishna Gudipati 	list_del(&uf->qe);	/* dequeue from posted queue */
4977a36c61f9SKrishna Gudipati 
4978a36c61f9SKrishna Gudipati 	uf->data_ptr = buf;
4979a36c61f9SKrishna Gudipati 	uf->data_len = m->xfr_len;
4980a36c61f9SKrishna Gudipati 
4981d4b671c5SJing Huang 	WARN_ON(uf->data_len < sizeof(struct fchs_s));
4982a36c61f9SKrishna Gudipati 
4983a36c61f9SKrishna Gudipati 	if (uf->data_len == sizeof(struct fchs_s)) {
4984a36c61f9SKrishna Gudipati 		bfa_plog_fchdr(bfa->plog, BFA_PL_MID_HAL_UF, BFA_PL_EID_RX,
4985a36c61f9SKrishna Gudipati 			       uf->data_len, (struct fchs_s *)buf);
4986a36c61f9SKrishna Gudipati 	} else {
4987a36c61f9SKrishna Gudipati 		u32 pld_w0 = *((u32 *) (buf + sizeof(struct fchs_s)));
4988a36c61f9SKrishna Gudipati 		bfa_plog_fchdr_and_pl(bfa->plog, BFA_PL_MID_HAL_UF,
4989a36c61f9SKrishna Gudipati 				      BFA_PL_EID_RX, uf->data_len,
4990a36c61f9SKrishna Gudipati 				      (struct fchs_s *)buf, pld_w0);
4991a36c61f9SKrishna Gudipati 	}
4992a36c61f9SKrishna Gudipati 
4993a36c61f9SKrishna Gudipati 	if (bfa->fcs)
4994a36c61f9SKrishna Gudipati 		__bfa_cb_uf_recv(uf, BFA_TRUE);
4995a36c61f9SKrishna Gudipati 	else
4996a36c61f9SKrishna Gudipati 		bfa_cb_queue(bfa, &uf->hcb_qe, __bfa_cb_uf_recv, uf);
4997a36c61f9SKrishna Gudipati }
4998a36c61f9SKrishna Gudipati 
4999a36c61f9SKrishna Gudipati static void
5000a36c61f9SKrishna Gudipati bfa_uf_stop(struct bfa_s *bfa)
5001a36c61f9SKrishna Gudipati {
5002a36c61f9SKrishna Gudipati }
5003a36c61f9SKrishna Gudipati 
5004a36c61f9SKrishna Gudipati static void
5005a36c61f9SKrishna Gudipati bfa_uf_iocdisable(struct bfa_s *bfa)
5006a36c61f9SKrishna Gudipati {
5007a36c61f9SKrishna Gudipati 	struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
5008a36c61f9SKrishna Gudipati 	struct bfa_uf_s *uf;
5009a36c61f9SKrishna Gudipati 	struct list_head *qe, *qen;
5010a36c61f9SKrishna Gudipati 
5011a36c61f9SKrishna Gudipati 	list_for_each_safe(qe, qen, &ufm->uf_posted_q) {
5012a36c61f9SKrishna Gudipati 		uf = (struct bfa_uf_s *) qe;
5013a36c61f9SKrishna Gudipati 		list_del(&uf->qe);
5014a36c61f9SKrishna Gudipati 		bfa_uf_put(ufm, uf);
5015a36c61f9SKrishna Gudipati 	}
5016a36c61f9SKrishna Gudipati }
5017a36c61f9SKrishna Gudipati 
5018a36c61f9SKrishna Gudipati static void
5019a36c61f9SKrishna Gudipati bfa_uf_start(struct bfa_s *bfa)
5020a36c61f9SKrishna Gudipati {
5021a36c61f9SKrishna Gudipati 	bfa_uf_post_all(BFA_UF_MOD(bfa));
5022a36c61f9SKrishna Gudipati }
5023a36c61f9SKrishna Gudipati 
50245fbe25c7SJing Huang /*
502525985edcSLucas De Marchi  * Register handler for all unsolicted receive frames.
5026a36c61f9SKrishna Gudipati  *
5027a36c61f9SKrishna Gudipati  * @param[in]	bfa		BFA instance
5028a36c61f9SKrishna Gudipati  * @param[in]	ufrecv	receive handler function
5029a36c61f9SKrishna Gudipati  * @param[in]	cbarg	receive handler arg
5030a36c61f9SKrishna Gudipati  */
5031a36c61f9SKrishna Gudipati void
5032a36c61f9SKrishna Gudipati bfa_uf_recv_register(struct bfa_s *bfa, bfa_cb_uf_recv_t ufrecv, void *cbarg)
5033a36c61f9SKrishna Gudipati {
5034a36c61f9SKrishna Gudipati 	struct bfa_uf_mod_s *ufm = BFA_UF_MOD(bfa);
5035a36c61f9SKrishna Gudipati 
5036a36c61f9SKrishna Gudipati 	ufm->ufrecv = ufrecv;
5037a36c61f9SKrishna Gudipati 	ufm->cbarg = cbarg;
5038a36c61f9SKrishna Gudipati }
5039a36c61f9SKrishna Gudipati 
50405fbe25c7SJing Huang /*
5041a36c61f9SKrishna Gudipati  *	Free an unsolicited frame back to BFA.
5042a36c61f9SKrishna Gudipati  *
5043a36c61f9SKrishna Gudipati  * @param[in]		uf		unsolicited frame to be freed
5044a36c61f9SKrishna Gudipati  *
5045a36c61f9SKrishna Gudipati  * @return None
5046a36c61f9SKrishna Gudipati  */
5047a36c61f9SKrishna Gudipati void
5048a36c61f9SKrishna Gudipati bfa_uf_free(struct bfa_uf_s *uf)
5049a36c61f9SKrishna Gudipati {
5050a36c61f9SKrishna Gudipati 	bfa_uf_put(BFA_UF_MOD(uf->bfa), uf);
5051a36c61f9SKrishna Gudipati 	bfa_uf_post_all(BFA_UF_MOD(uf->bfa));
5052a36c61f9SKrishna Gudipati }
5053a36c61f9SKrishna Gudipati 
5054a36c61f9SKrishna Gudipati 
5055a36c61f9SKrishna Gudipati 
50565fbe25c7SJing Huang /*
5057a36c61f9SKrishna Gudipati  *  uf_pub BFA uf module public functions
5058a36c61f9SKrishna Gudipati  */
5059a36c61f9SKrishna Gudipati void
5060a36c61f9SKrishna Gudipati bfa_uf_isr(struct bfa_s *bfa, struct bfi_msg_s *msg)
5061a36c61f9SKrishna Gudipati {
5062a36c61f9SKrishna Gudipati 	bfa_trc(bfa, msg->mhdr.msg_id);
5063a36c61f9SKrishna Gudipati 
5064a36c61f9SKrishna Gudipati 	switch (msg->mhdr.msg_id) {
5065a36c61f9SKrishna Gudipati 	case BFI_UF_I2H_FRM_RCVD:
5066a36c61f9SKrishna Gudipati 		uf_recv(bfa, (struct bfi_uf_frm_rcvd_s *) msg);
5067a36c61f9SKrishna Gudipati 		break;
5068a36c61f9SKrishna Gudipati 
5069a36c61f9SKrishna Gudipati 	default:
5070a36c61f9SKrishna Gudipati 		bfa_trc(bfa, msg->mhdr.msg_id);
5071d4b671c5SJing Huang 		WARN_ON(1);
5072a36c61f9SKrishna Gudipati 	}
5073a36c61f9SKrishna Gudipati }
5074a36c61f9SKrishna Gudipati 
5075a36c61f9SKrishna Gudipati 
5076